Skip to content

Agent yield-and-resume flow for intent veto window #186

@marcus-sa

Description

@marcus-sa

Problem

When an agent creates an intent that requires human review (veto window), the agent has no protocol for pausing and resuming. The current options are all suboptimal:

  • Polling: Burns tokens/compute while waiting minutes to hours
  • Blocking: Keeps an LLM session alive unnecessarily
  • Fire-and-forget: Agent loses context about why it initiated the action

Design

Yield-and-resume within the same agent session — the agent yields its current turn when an intent enters pending_veto, and Brain re-invokes it in the same session (new turn, full conversation context preserved) when the human approves or rejects.

Flow

Agent: creates intent → gets { status: "pending_veto", intent_id: "abc" }
Agent: yields turn, tells user "Awaiting approval for Stripe refund of $50"
Human: approves/rejects in feed UI
Brain: re-invokes agent in same session with { event: "intent_authorized", intent_id: "abc" }
Agent: exchanges intent for RAR token → calls MCP tool → completes

On rejection:

Human: rejects in feed UI
Brain: re-invokes agent in same session with { event: "intent_vetoed", intent_id: "abc", reason: "..." }
Agent: acknowledges rejection, communicates to user, adjusts approach

Key decisions

  • Same session, new turn: Agent retains full conversation context (why it was refunding, what the user asked for). No need to re-explain.
  • Re-invocation trigger: SurrealDB EVENT on intent status transition (pending_veto → authorized or pending_veto → vetoed) fires a callback that pushes a new turn into the agent session.
  • No polling: The agent does not check intent status. The platform pushes the resolution event.
  • Structured yield response: The intent creation tool returns a structured result that the LLM recognizes as "pause here" — not an error, but a signal that this action requires async approval.

Open questions

  • How does the re-invocation interact with SSE streaming? Does the agent session's SSE connection stay open during the veto window, or does the client reconnect?
  • Should the agent be able to do other work while waiting (e.g., answer follow-up questions), or is the session paused entirely?
  • What's the maximum veto window duration before the session context is considered stale?
  • How does this interact with composite intents (multi-step tool chains where step 2 needs approval)?

Context

  • Research doc: docs/research/intent-rar-mcp-tool-gating.md
  • Intent state machine: app/src/server/intent/status-machine.ts
  • Veto manager: app/src/server/intent/veto-manager.ts
  • Agent session model: app/src/server/agents/

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions