feat(agent-builder): follow-mode auto-refresh of viewed revision#2977
feat(agent-builder): follow-mode auto-refresh of viewed revision#2977benjackwhite wants to merge 1 commit into
Conversation
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>
|
React Doctor found no issues in the changed files. 🎉 Reviewed by React Doctor for commit |
|
Reviews (1): Last reviewed commit: "feat(agent-builder): follow-mode auto-re..." | Re-trigger Greptile |
| expect(d.scan([start("c2", VALIDATE), done("c2")])).toBe(0); | ||
| expect(d.scan([start("c3", "posthog__insight-query"), done("c3")])).toBe(0); |
There was a problem hiding this comment.
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.
| 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); | ||
| }); |
There was a problem hiding this comment.
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!
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
useFollowSpecEditshook, mounted in the always-on agent-builder dock, watches the builder's live/listenstream (via the coreagentChatStore) 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
/listenstream intoagentChatStore, not the local workspace-serverMcpAppsServicepath (that's only for local task sessions). So the observer taps the chat store rather than the MCP-apps tRPC subscription. It reuses the existingfollowModeflag (today it gatesfocus_*navigation) so "follow" now also keeps the viewed data fresh.Which tools trigger it
Drawn from the agent-builder spec's
mcps[].toolsallowlist — 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
focus_*.followModeflag rather than adding a separate toggle — one-liner to split later if we want them independent.Testing
useFollowSpecEdits.test.tsover the pure detector: fires once on completion, reacts to the whole write family (not justspec-update), ignores reads/validate, skips resumed backlog, resets on new chat (5 cases).pnpm --filter @posthog/ui typecheckclean; Biome clean; pre-commit hook (typecheck + biome) passed.🤖 Generated with Claude Code