Repository navigation
[EPIC-D][LOU-D21] createAgent agents can pause for approval and resume - #75
Merged
Merged
Conversation
A needsApproval tool no longer fails a createAgent() run with "requires
approval but no approvalStore". Each agent now runs with an approval store
(a new InMemoryApprovalStore per agent, or the `approvalStore` option), so
the run pauses with finishReason 'awaiting-approval' and an approvalId.
- agent.approvals.list() returns the calls the agent is paused on;
agent.approvals.resolve({ id, approved, note? }) calls
resumeAfterApproval() with the agent's store, registry, provider and
options and returns the continued run's result. A pause inside
agent.session() continues in that session (AgentSession.continueTurn).
- `approve` option: decides each pause at once by resuming with the
callback's answer (send(), sessions and approvals.resolve()).
- Executor, resume and ApprovalGate are untouched.
- serveMcp test updated: a createAgent() agent now pauses (and MCP reports
the pause) instead of throwing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016bY29ibQgv3MDdjAbUT4YR
Resolve docs/api-overview.md (keep both new table rows) and regenerate llms files. Note createAgent approvals in docs/sessions.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016bY29ibQgv3MDdjAbUT4YR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
createAgent()now runs every agent with anApprovalStore: a newInMemoryApprovalStoreper agent (added insrc/execution/InMemoryApprovalStore.ts, exported from the root) or the newapprovalStoreoption. AneedsApprovaltool pauses the run instead of throwing "requires approval but no approvalStore".SimpleAgent.approvals:list()returns thePendingApprovals this agent is paused on.resolve({ id, approved, note? })takes the existingApprovalDecisionshape, callsresumeAfterApproval()with the agent's store, registry, provider and run options (skills, subagents, maxSteps, toolConcurrency), and returns the continued run'sExecutionResult.approve?: (call: PendingApproval) => boolean | Promise<boolean>option (open-harness style). It is a thin loop on top of the same pause/resume path, with no new executor code path. When a run pauses, the callback decides the call and the run resumes with that answer:trueruns the tool,falsesends the model the existing structured rejection. It applies tosend(), sessions andapprovals.resolve().agent.session()is continued in that session when its approval is resolved. A new protectedAgentSession.continueTurn()queues the continuation as the session's next turn and records its transcript.finishReason: 'awaiting-approval'plusapprovalId.createAgentsnippet.docs/api-overview.md(new Approvals section),docs/sessions.mdanddocs/sub-agents.mdupdated.Addedentry.Why
createAgent()is the zero-config path, but anyneedsApprovaltool made its runs fail because no approval store was ever passed. eve pauses durably onneedsApprovaland open-harness has anapprovecallback. This brings the simple API to parity.Acceptance criteria
createAgent({ approvalStore?: ApprovalStore }). When it is omitted, each agent gets its ownInMemoryApprovalStore; none existed before, so it was added in the execution/approvals module, not in createAgent.ts.approvecallback auto-decides with no pause, built on top of the store/resume path.send()resolves with the existingawaiting-approval/approvalIdshape.agent.approvals.list()/agent.approvals.resolve({ id, approved, note? })work, mirroringApprovalDecisionand delegating toresumeAfterApproval.src/createAgentApprovals.test.ts(mockModel) cover:approveauto-approve and auto-denyapprovalStorestream()pausingNotes:
src/execution/AgentExecutor.ts,resume.ts,toolCallExecution.tsandApprovalGate.tsare not touched.serveMcp.test.tshad one test that relied on the old throw. It now expects the MCP server's existing "needs human approval ... cannot be approved over MCP" error.stream()pauses but does not applyapprove. A paused stream is continued withagent.approvals.resolve(), which does not stream.list()covers pauses made by this agent in this process. With a durable store,resolve()by id still works after a restart, but it cannot re-attach the result to a session.How verified
Ran after merging the latest
origin/main(including #68):npx tsc --noEmit: no errorsnpm run lint:✖ 433 problems (0 errors, 433 warnings). Same count as before the change; the changed files have 0 warnings.npm run test:types:Type Errors no errorsnpx vitest run:Test Files 134 passed (134),Tests 1986 passed | 3 skipped (1989)npm run build && npm run build --workspace=packages/create-loushy-agent: exit 0npm run docs:verify-snippets -- --skip-build:all 89 snippet(s) type-check against src/; 6 also run cleanlynpm run docs:llms:check: exit 0npm run test:coverage: exit 0 (134 files, 1986 passed)npm run fallow: exit 0. Dead code:✓ No issues found;0 above threshold. The only duplication reported is the existing Anthropic/OpenAI provider clone.🤖 Generated with Claude Code
https://claude.ai/code/session_016bY29ibQgv3MDdjAbUT4YR
Generated by Claude Code