fix(voice-engine): resolve voice tool-call stalls and add per-tool result_mode control#56
fix(voice-engine): resolve voice tool-call stalls and add per-tool result_mode control#56
Conversation
4c473d4 to
9cca0e0
Compare
9cca0e0 to
98e3b6c
Compare
|
I do like the option of making global summarizer be a per-tool config. However I think the design too complex. Especially introducing extra burdens to the builder agent. Here's a better direction I think: Default: truncate everything. Hard-cap all tool results at 8,000 chars with a [result truncated] notice appended. Zero latency, deterministic, covers the vast majority of cases. For context growth over a session, that's what the context summarizer is for — no need to burn another LLM call per tool result on top of that. Per-tool summarizer: UI opt-in only. Users who have a specific tool that genuinely needs AI condensing can toggle it on per tool in the settings panel. Simple toggle, easy to ignore if you don't need it. This is strictly better than a global summarizer flag — finer-grained with no default overhead. Builder: no awareness. Removing result_mode from the schema example and the Tool Result Mode section from the builder prompt entirely. Output handling is an operator concern, not something the builder should reason about per tool. The 4-value enum and global summarizer flag will be dropped. The proto field becomes a simple bool summarize_result. |
487a02f to
f276800
Compare
Summary
This PR fixes voice-mode tool-call stalling and adds explicit per-tool control of post-processing for tool results (
result_mode), with end-to-end support in runtime, API, schema, and Studio UI.Background
During voice tests, tool calls intermittently appeared to hang at
ToolCallStartedin UI, while equivalent text tests completed normally.Observed characteristics:
Investigation timeline and findings
result_mode.Final solution
A) Voice stall mitigation
B) Per-tool post-processing policy (
result_mode)ToolResultModeenum in proto andToolDef.result_mode.tool_executorresolves mode:Unspecified(auto) -> current global behavior (tool_summarizeron/off)SummarizeTruncateNone(full)C) Config/API/UI end-to-end support
tool_result_modesmap (tool_id -> mode|null).nullmeansauto(unset field).1|2|3.agent-config-v1.schema.json.AutoSummaryTruncateFullD) Persistence fix
copy.deepcopy) to ensure SQLAlchemy JSON change detection works for nestedtools.*.result_modeupdates.Files touched (high-level)
proto/agent.protovoice/engine/crates/agent-kit/src/tool_executor.rsvoice/engine/crates/agent-kit/src/swarm.rsvoice/engine/crates/agent-kit/src/quickjs_engine.rsvoice/engine/crates/agent-kit/src/agent_backends/default.rsvoice/engine/crates/agent-kit/src/micro_tasks.rsvoice/engine/src/reactor/mod.rsstudio/api/app/api/agents.pystudio/api/app/agent_builder/edit_ops.pystudio/api/app/agent_builder/service.pystudio/api/app/schemas/agent_pb2.pystudio/api/app/schemas/agent_pb2.pyistudio/web/public/schemas/agent-config-v1.schema.jsonstudio/web/src/components/agent/agent-config-editor.tsxstudio/web/src/lib/api/agent.tsstudio/web/src/lib/api/client.tsVerification
cd voice/engine/crates/agent-kit && cargo test --quiet(pass)cd voice/engine && cargo test --quiet --no-run(pass; existingquickjscfg warning unchanged)ruff checkon modified API files (pass)pnpm -C studio/web run lint(pass)voice-servervia compose and validated logs for tool-start/tool-complete progression.Backward compatibility
result_modeis optional.result_modecontinue to behave with system/global default (auto).Follow-up