Skip to content

feat(agent-builder): follow-mode auto-refresh of viewed revision#2977

Draft
benjackwhite wants to merge 1 commit into
mainfrom
ben/agent-builder-follow-revision-edits
Draft

feat(agent-builder): follow-mode auto-refresh of viewed revision#2977
benjackwhite wants to merge 1 commit into
mainfrom
ben/agent-builder-follow-revision-edits

Conversation

@benjackwhite

Copy link
Copy Markdown
Contributor

What

When the agent builder edits an agent in follow mode, the configuration view it just changed now refreshes automatically. Previously the agent's edit only appeared after a manual refresh, because revision queries are 30s-stale with no polling.

A new useFollowSpecEdits hook, mounted in the always-on agent-builder dock, watches the builder's live /listen stream (via the core agentChatStore) for a completed revision-writing posthog MCP call and — when follow mode is on — invalidates the revision-view query caches so the viewed revision refetches.

Why this path

The agent builder is a remote ingress agent: its tool calls arrive over the SSE /listen stream into agentChatStore, not the local workspace-server McpAppsService path (that's only for local task sessions). So the observer taps the chat store rather than the MCP-apps tRPC subscription. It reuses the existing followMode flag (today it gates focus_* navigation) so "follow" now also keeps the viewed data fresh.

Which tools trigger it

Drawn from the agent-builder spec's mcps[].tools allowlist — the revision/app write tools only:

spec-update, partial-update, agent-md-update, tools-update, tools-destroy, skill-refs-set, new-draft-create, clone-from-create, create, freeze-create, promote-create, archive-create, agent-applications-partial-update.

Reads (-retrieve/-list), validate, sessions and skill tools are excluded. Matching is prefix-agnostic (posthog__… / mcp__posthog__…), compares the segment after the last __.

Detection correlates start→completion by toolCallId, fires once per call, and skips the resumed backlog so a remount never replays past edits. Follow mode is read at fire time, so toggling it never resubscribes.

Scope / boundaries

  • Refresh-in-place only. If an edit creates a new draft (vs. patching the viewed one), this refreshes the picker/list so it appears; jumping to the new draft remains the builder's job via focus_*.
  • Reuses the existing followMode flag rather than adding a separate toggle — one-liner to split later if we want them independent.

Testing

  • New unit test useFollowSpecEdits.test.ts over the pure detector: fires once on completion, reacts to the whole write family (not just spec-update), ignores reads/validate, skips resumed backlog, resets on new chat (5 cases).
  • Verified live against the running dev app over CDP: hot-reloads cleanly, dock renders and streams, no new console errors.
  • pnpm --filter @posthog/ui typecheck clean; Biome clean; pre-commit hook (typecheck + biome) passed.

🤖 Generated with Claude Code

When the agent builder edits an agent in follow mode, the configuration
view it just changed stayed stale — revision queries are 30s-stale with
no polling, so the agent's edit only showed after a manual refresh.

Add `useFollowSpecEdits`, mounted in the always-on dock: it watches the
agent-builder's live `/listen` stream (via the core `agentChatStore`) for
a completed revision-writing posthog MCP call and, when follow mode is on,
invalidates the revision-view query caches so the viewed revision refetches.

The reacted-to tool set is drawn from the agent-builder spec's
`mcps[].tools` allowlist — the write tools (spec/agent-md/tools/skill-refs
edits, new-draft/clone, freeze/promote/archive); reads and `validate` are
excluded. Matching is prefix-agnostic (`posthog__…` / `mcp__posthog__…`).

Detection correlates start→completion by toolCallId, fires once per call,
and skips the resumed backlog so a remount never replays past edits.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

React Doctor found no issues in the changed files. 🎉

Reviewed by React Doctor for commit d491d54.

@greptile-apps

greptile-apps Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Reviews (1): Last reviewed commit: "feat(agent-builder): follow-mode auto-re..." | Re-trigger Greptile

Comment on lines +55 to +56
expect(d.scan([start("c2", VALIDATE), done("c2")])).toBe(0);
expect(d.scan([start("c3", "posthog__insight-query"), done("c3")])).toBe(0);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Exclusion assertions pass vacuously

After d.scan([start("c1", RETRIEVE), done("c1")]) the detector's processed is 2. The second scan receives [start("c2", VALIDATE), done("c2")] — also 2 messages — so the loop runs from i = 2 to messages.length (2): an empty range. It returns 0 because nothing was processed, not because VALIDATE was excluded. The same applies to the third assertion. Adding VALIDATE or "posthog__insight-query" to REVISION_WRITE_TOOLS would not break either assertion, so this gives no regression protection. Each excluded-tool check needs its own fresh detector (or a growing accumulation array) to be meaningful.

Comment on lines +37 to +57
it("reacts to the whole write family, not just spec-update", () => {
const d = createRevisionEditDetector();
d.scan([]);
expect(d.scan([start("c1", AGENT_MD), done("c1")])).toBe(1);
expect(
d.scan([
start("c1", AGENT_MD),
done("c1"),
start("c2", PROMOTE),
done("c2"),
]),
).toBe(1);
});

it("ignores reads and validate (non-mutating tools)", () => {
const d = createRevisionEditDetector();
d.scan([]);
expect(d.scan([start("c1", RETRIEVE), done("c1")])).toBe(0);
expect(d.scan([start("c2", VALIDATE), done("c2")])).toBe(0);
expect(d.scan([start("c3", "posthog__insight-query"), done("c3")])).toBe(0);
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Tests not parameterised; write-family coverage limited to 2 of 13 tools

The project prefers it.each for tests that share the same logic across multiple inputs. Both the write-family check and the exclusion check are natural candidates: the write family has 13 entries but only AGENT_MD and PROMOTE are exercised, while the exclusion test covers only RETRIEVE, VALIDATE, and one ad-hoc name. A typo in the remaining 10 allowlist entries would go unnoticed. Using it.each would also fix the vacuous-assertion problem in the exclusion test (each case gets a fresh detector).

Context Used: Do not attempt to comment on incorrect alphabetica... (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant