Files
Sayt-0 a3dc1a8ed6 feat: add force_handoff for deterministic agent routing on natural stop
When an agent's config names a force_handoff target, the runtime
intercepts the agent's natural stop and routes the conversation to
that agent deterministically, bypassing the LLM's tool-calling. This
makes strict pipelines (extractor -> summarizer) reliable even when
the model would forget to call the handoff tool.

- config: new force_handoff field on agents (latest schema only),
  validated for existence, self-reference, and cycles
- runtime: forced switch on stop with an implicit handoff notice
  message; skipped for pinned sessions to avoid infinite loops
- hooks: on_agent_switch now reports kind "force_handoff";
  turn_end reports reason "force_handoff"
- docs, JSON schema, and examples/force_handoff.yaml updated

Closes #3078
2026-06-12 17:21:20 +02:00

31 lines
1.2 KiB
YAML

#!/usr/bin/env cagent run
# Deterministic pipeline using force_handoff:
#
# extractor ──(always)──> summarizer
#
# Unlike `handoffs` (where the LLM decides whether to call the handoff
# tool), `force_handoff` is enforced by the runtime: whenever the agent
# produces a final response, the conversation is unconditionally routed
# to the named agent, carrying over the full context. This guarantees
# the pipeline order even when the model would otherwise "forget" to
# hand off.
agents:
root:
model: anthropic/claude-sonnet-4-5
description: Extracts the key facts and entities from the user's input
instruction: |
You are the first stage of a two-stage pipeline.
Extract the key facts, entities, and figures from the user's input
as a concise bullet list. Do not summarize or editorialize - the
next agent in the pipeline will do that.
force_handoff: summarizer
summarizer:
model: anthropic/claude-sonnet-4-5
description: Produces the final summary from the extracted facts
instruction: |
You are the final stage of a two-stage pipeline.
Using the extracted facts from the conversation history, write a
short, well-structured summary for the user.