Custom completion tools
An Agent can now finish through a typed tool of your own instead of the built-in finish tool. Pass it as completionTool: and it replaces finish in the definitions sent to the model, executes through the normal tool path — typed decoding, approval, timeout, MCP and sub-agent dispatch — and terminates the run only on an exact successful result, which becomes result.content verbatim. A completion call arriving beside other tool calls executes nothing and feeds corrective error results back to the model, bounded by maxIterations. Committed completions persist as identity-bound terminal checkpoints: resuming one replays the exact outcome with no live work, and an agent completing through a different tool is refused with AgentCheckpointError.completionToolMismatch.
Supporting changes: a public ToolCallSurfacingClient capability marks the clients that can drive custom completion (every HTTP provider client and MLXClient; FoundationModelsClient executes tools inside its own session and is excluded); TestLLMClient drives completion flows offline via completionToolName: and now mints turn-scoped, unique-per-conversation tool-call ids; the Swift tools floor is declared 6.1 to match the dependency graph.
Upgrading to 5.5
Three deliberate changes for existing code:
AgentCheckpointErrorgainedcompletionToolMismatch(checkpointed:live:), thrown when a terminal checkpoint is resumed by an agent that completes through a different tool. A switch overAgentCheckpointErrorwithout adefaultmust handle the new case.TestLLMClientinAgentRunKitTestinggained a defaultedcompletionToolName:initializer parameter. Existing call sites compile unchanged.- A sub-agent's nested
.finished,.iterationCompleted, and.budgetUpdatedevents no longer write to the parentAgentStream'stokenUsage,finishReason,history,content,iterationUsages,iterationsReplayed, orcontextBudget. A parent that emitted no content deltas previously displayed the last child's finish content and now displays its own. Nested events remain fully observable, andtoolCallsstill flattens them.
Full Changelog: v5.4.1...v5.5.0