Skip to content

feat(examples/chat): executable approval tools behind the hero's pause - #1011

Merged
blove merged 17 commits into
mainfrom
blove/hero-executable-approval-design-23b7b3
Sep 5, 2026
Merged

feat(examples/chat): executable approval tools behind the hero's pause#1011
blove merged 17 commits into
mainfrom
blove/hero-executable-approval-design-23b7b3

Conversation

@blove

@blove blove commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Why

The hero's approval beat replayed an authored narration describing behaviour the product did not have: after approval the graph had nothing to execute, so the model either asked clarifying questions or wrote a 5,800-character ops document. Spec: docs/superpowers/specs/2026-09-04-hero-executable-approval-tools-design.md; plan: docs/superpowers/plans/2026-09-05-hero-executable-approval-tools.md.

What

  • examples/chat/python/src/backups.py: a demo-owned inventory seeded into the graph State (rides the checkpoint, frozen clock so every thread starts identically), list_backups, and delete_backups whose FIRST statement is interrupt() — approval is enforced by code, not by the system prompt. Retained or unknown ids are refused before any interrupt; anything but an unambiguous yes deletes nothing and hands the human's words back to the model.
  • libs/chat chat-tool-views: a JSON-object string result (how a LangGraph ToolMessage carries a dict return) is parsed into view props. Without this a LangGraph tool view only ever saw args and status.
  • BackupTableComponent registered as the list_backups tool view on the hero and all three demo modes via one demoViews() registry; the "Approve before a destructive action" chip now runs the hero's scenario verbatim.
  • The hero fixture is recorded live only (aimock cannot stage list → delete → resume); hero-replay.json and both posters re-recorded.

Two things the new recording exposed

  • The replay transport's 30 ms per-event floor existed for near-atomic aimock recordings. A real live stream has ~700 token events in the GenUI run, so the floor stretched a 5 s stream to 23 s. The floor is now 0; the 600 ms ceiling stays.
  • The hero's two agents never set transcriptNodeNames: ['generate'] the way the demo shell does. The thread title only generates once the interrupted run completes, so its tokens landed on the just-finished answer and tripped the streaming-markdown contract, which stopped the next turn from rendering. This affected the live takeover path too.

Measurement gate (10 live runs, gpt-5-mini)

{
  "runs": 10,
  "interrupted": 10,
  "list_backups_first": 10,
  "delete_backups_called": 10,
  "used_request_approval": 0,
  "median_chars": 196.0,
  "max_chars": 228,
  "remaining_rows_after_approval": [5]
}

Shipped narration was 482 chars; the pre-tools plan was a median 5,802. In 4/10 runs the model's first delete_backups call included a retained id, was refused, and it re-called correctly; the committed take has a single call.

Tests

  • Python: seeding, filtering, retain/unknown refusal, approval wording, and test_delete_without_approval_interrupts_and_deletes_nothing — mutation-checked by replacing the interrupt() call, which turns it red. 82 passing.
  • Angular: tool view's three states; registry composition; chip pinned to the hero prompt; replay pacing; replay-fixture spec now requires list_backups + delete_backups in the prompt run and a compact resume answer. 192 passing; chat lib 1159 passing; website suite green.
  • e2e (aimock-backed): hero (now also asserts the backup table renders before the pause), interrupt-approval, initial-render — 6/6, zero console errors.
  • Production build of the example: initial bundle 1.65 MB, +0.3 KB over main (the 1.6 MB warning predates this PR).

🤖 Generated with Claude Code

@vercel

vercel Bot commented Sep 5, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
threadplane Ready Ready Preview Sep 5, 2026 7:16pm UTC

Request Review

@github-actions github-actions Bot left a comment

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.

Automated approval: this PR received an intelligent (AI) code review. See the review comments on this PR.

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Claude finished @blove's task in 0s —— View job


I'll analyze this and get back to you.

blove and others added 14 commits September 5, 2026 10:15
The hero's approval beat replays an authored narration depicting behaviour the
product does not have: measured live, the model produces either clarifying
questions (0/14 plans) or a 5,800-character ops document (22/22 plans), against
a 482-character shipped narration. The cause is structural — after approval the
graph has no tools to call, so describing is its only move.

Design: seed a backup inventory into the graph State so it rides the
checkpoint, add list_backups and delete_backups, and put the interrupt inside
the destructive tool so approval is enforced by code rather than by the system
prompt. Render the inventory as a registered tool view.

Blocked on the duplicate-submit HTTP 400, which lands first as its own change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…h State

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…dState

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… can delete

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…leanup requests to them

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…s and empty states

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…very demo mode

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…re is recorded live only

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…the result

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The recording is a real live stream now, so the replay drops its 30ms
per-event floor (a 5s GenUI stream would have taken 23s) and the hero's two
agents filter transcript tokens to the generate node the way the demo shell
already does — the thread title, which only generates once the interrupted
run completes, was landing on the finished answer and tripping the
streaming-markdown contract.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…val turn

The mobile capture moves to 5000ms after the panel detaches: the resumed
answer is longer now, so the old 2800ms frame parked the cursor's arrowhead
on the delete_backups chip. Timeline measured by sampling the DOM.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@blove
blove force-pushed the blove/hero-executable-approval-design-23b7b3 branch from 1e8c345 to 8502a6c Compare September 5, 2026 17:15
@blove
blove enabled auto-merge (squash) September 5, 2026 17:15
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Claude finished @blove's task in 0s —— View job


I'll analyze this and get back to you.

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Claude finished @blove's task in 0s —— View job


I'll analyze this and get back to you.

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Claude finished @blove's task in 0s —— View job


I'll analyze this and get back to you.

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Claude finished @blove's task in 0s —— View job


I'll analyze this and get back to you.

@blove
blove merged commit 8900e18 into main Sep 5, 2026
78 checks passed
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