feat(buzz-agent): emit agent_thought_chunk for reasoning content#1436
Merged
Conversation
buzz-agent never emitted agent_thought_chunk, so the observer feed's Thinking block was always absent even with a reasoning model — unlike goose/claude/codex which all emit it. Add a `reasoning` field to `LlmResponse` and populate it in all three provider parse paths: - Responses API: concatenated summary[].text from type=="reasoning" items - Anthropic: concatenated thinking blocks (type=="thinking") - OpenAI chat/completions: always empty (reasoning not exposed) Emit agent_thought_chunk before agent_message_chunk in agent.rs when reasoning is non-empty. Tests cover both the Anthropic and Responses API paths and verify no thought chunk is emitted for plain text responses. Also fix two stale comments in acp.rs claiming session_info_update is goose-only; buzz-agent emits it too (lib.rs:510). Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Per Thufir review pass 1: 1. parse_openai now extracts reasoning_content (DeepSeek) and reasoning (other compat hosts) from the message object. OPENAI_COMPAT_API=auto routes non-openai.com hosts to chat/completions, so self-hosted reasoning models (DeepSeek, vLLM) now emit agent_thought_chunk. 2. Fix remaining stale acp.rs struct-field doc (active_run_id field): was 'Goose-specific / other agents will never populate this'. Now correctly states goose AND buzz-agent both emit session_info_update with _meta.goose.activeRunId; other agents may leave it unset. 3. cargo fmt --all (golden_transcripts.rs:610 assert_eq! wrap). Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
buzz-agent never emitted
agent_thought_chunk, so the observer feed showed no Thinking block even with a reasoning model. goose, claude, and codex all emit it. This closes the parity gap.What changed
crates/buzz-agent/src/types.rs— Addpub reasoning: StringtoLlmResponse. Empty string means no reasoning (consistent with thetextfield style).crates/buzz-agent/src/llm.rs— Populatereasoningin all three provider parse paths:parse_responses: collectsummary[].textfromtype == "reasoning"output items (Responses API)parse_anthropic: collectthinkingfromtype == "thinking"content blocks (extended thinking)parse_openai: alwaysString::new()— chat/completions does not expose reasoning tokenscrates/buzz-agent/src/agent.rs— Before emittingagent_message_chunk, emitagent_thought_chunkwhenresponse.reasoningis non-empty. Thought precedes message, matching goose/claude/codex wire order.crates/buzz-acp/src/acp.rs— Fix two stale comments claimingsession_info_updateis goose-only; buzz-agent has always emitted it too (lib.rs:510).crates/buzz-agent/tests/golden_transcripts.rs— Three new end-to-end tests using the credential-free fake LLM harness:test_thought_chunk_emitted_before_message_chunk_anthropic— Anthropic provider, thinking block → thought chunk precedes message chunktest_thought_chunk_emitted_before_message_chunk_responses_api— OpenAI Responses API, reasoning item → thought chunk precedes message chunktest_no_reasoning_no_thought_chunk— plain text response → no thought chunk emittedRelated: #1412