Users do not speak in single intents. "Email Kinshuok about the doc and schedule a sync for Thursday" is one message. If your agent stops after the first tool call, half the request vanishes — and users blame the product, not the model's laziness.
Multi-tool support spans Bedrock instructions, runtime prompt, API response shape, trace extraction, and chat UI rendering. Remove any layer and combined requests regress silently.
Combined requests are normal
Early agent versions had hardcoded single-intent bypasses — compose OR meeting, detected by regex before Bedrock. That broke combined requests and duplicated logic. Everything now flows through the agent: tools return structured payloads; the web app maps them to UI cards.
Prompt contract
System and alias instructions include explicit MULTI-TOOL language: invoke every applicable tool in the same turn. Runtime prompt repeats with name-resolution hint — pass raw attendee names, backend resolves emails.
Also instruct: do not emit JSON tool results in assistant prose after calls; Kvika reads trace output. Model obedience reduces dual-path extraction bugs.
API response shape
const toolResult = extractToolResultsFromTrace(result.traces)
if (toolResult.clientActions.length > 0) {
return {
message: toolResult.message,
clientAction: toolResult.clientAction, // last — backwards compat
clientActions: toolResult.clientActions, // all — multi-tool
clientActionMessages: toolResult.messages, // one string per card
}
}Chat drawer loops clientActions and renders compose card + meeting scheduler in one assistant turn. Single clientAction field preserved for older clients.
Mapper registry
agent-tool-mappers.ts maps Lambda payload action strings to typed AgentClientAction unions — show_new_email_draft, show_meeting_scheduler, show_jira_ticket_draft, etc. Adding a tool means four coordinated edits documented at the top of the file: OpenAPI, Lambda, mapper, UI component.
Trace dedupe still required
Multi-tool increases trace size. Same payload echoed in nested nodes still produces duplicate cards without fingerprint dedupe — see trace deduplication post. Fingerprints are per action type; email drafts hash to + subject + body prefix.
Related: agent architecture · name resolution. Join the Kvika beta.