Skip to content

Conversation

@lifeizhou-ap
Copy link
Collaborator

@lifeizhou-ap lifeizhou-ap commented Jan 20, 2026

Summary

Fix wrong accumulated token count for databricks claude models.

Why
For Databricks Claude models, the usage is in all the chunks with same prompt_token. But only the last one with finish_reason has completion_token.

With the change in this PR #6493, for each api,
Actual: we adds prompt_token in all the chunks
Expected: we should only add once, which can use the chunk with finish_reason.

What

  • Only use the usage with completion_token. If completion_token is null, this means we don't have the usage yet.
  • Added usage in the tool_call_chunk too (I think this was an existing issue)
  • Added tests with api response test data

Type of Change

  • Feature
  • Bug fix
  • Refactor / Code quality
  • Performance improvement
  • Documentation
  • Tests
  • Security fix
  • Build / Release
  • Other (specify below)

AI Assistance

  • This PR was created or reviewed with AI assistance

Testing

Unit tests and manual tests

Copilot AI review requested due to automatic review settings January 20, 2026 09:46
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes an issue with accumulated token count in streaming responses from OpenAI-compatible providers. The changes extract and update usage information from streaming chunks, ensuring that usage data with output tokens is correctly captured and yielded only once.

Changes:

  • Added extract_usage_with_output_tokens helper function to filter usage data that includes output tokens
  • Modified streaming response handler to accumulate usage from chunks during tool call processing
  • Refactored tests with helper functions and added comprehensive test coverage for multiple providers (OpenRouter, OpenAI GPT-5, Tetrate Claude)

let tool_chunk: StreamingChunk = serde_json::from_str(line)
.map_err(|e| anyhow!("Failed to parse streaming chunk: {}: {:?}", e, &line))?;

if let Some(chunk_usage) = extract_usage_witqh_output_tokens(&tool_chunk) {
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in function name: "extract_usage_witqh_output_tokens" should be "extract_usage_with_output_tokens".

Suggested change
if let Some(chunk_usage) = extract_usage_witqh_output_tokens(&tool_chunk) {
if let Some(chunk_usage) = extract_usage_with_output_tokens(&tool_chunk) {

Copilot uses AI. Check for mistakes.
#[tokio::test]
async fn test_streamed_multi_tool_response_to_messages() -> anyhow::Result<()> {
let response_lines = r#"
let responqse_lines = r#"
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in variable name: "responqse_lines" should be "response_lines".

Suggested change
let responqse_lines = r#"
let response_lines = r#"

Copilot uses AI. Check for mistakes.
assert_eq!(usage.usage.total_tokens, Some(expected_total));
}

#[tokio::test]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't looked at the details since this just feels like a large dump, but not sure we need three tests here to verify that we are now doing the right thing?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bug is caused by different structures of the streaming chunks in api response. So I added the tests with the test data with variations for different providers. This will provide harness when we changing the logic in the future.

Copy link
Collaborator

@jamadeo jamadeo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it the same across all providers @lifeizhou-ap ? You mention databricks/claude but since this code is in formats/openai.rs I'd be worried if we're missing some specific logic per-provider for token tracking

@lifeizhou-ap
Copy link
Collaborator Author

Is it the same across all providers @lifeizhou-ap ? You mention databricks/claude but since this code is in formats/openai.rs I'd be worried if we're missing some specific logic per-provider for token tracking

Yes, I was worrying about this too including the last PR. I manually tested with different providers again. Also I added the chunk payload in new tests to make sure future change won't break this.

I am not sure whether I understand your question correctly, happy to have a chat!

@lifeizhou-ap lifeizhou-ap merged commit f26ffed into main Jan 21, 2026
20 checks passed
@lifeizhou-ap lifeizhou-ap deleted the lifei/fixed-accumulated-token-count branch January 21, 2026 16:27
zanesq added a commit that referenced this pull request Jan 21, 2026
…ased

* 'main' of github.com:block/goose:
  Lifei/fixed accumulated token count (#6587)
  Dont show MCP UI/Apps until tool is approved (#6492)
katzdave added a commit that referenced this pull request Jan 21, 2026
…ovider

* 'main' of github.com:block/goose:
  increase worker threads for ci (#6614)
  docs: todo tutorial update (#6613)
  Added goose doc map md file for goose agent to find relevant doc easily. (#6598)
  add back goose branding to home (#6617)
  fix: actually set the working dir for extensions from session (#6612)
  Multi chat (#6428)
  Lifei/fixed accumulated token count (#6587)
  Dont show MCP UI/Apps until tool is approved (#6492)
  docs: max tokens config (#6596)
  User configurable templates (#6420)
  docs: http proxy environment variables (#6594)
  feat: exclude subagent tool from code_execution filtering (#6531)
michaelneale added a commit that referenced this pull request Jan 21, 2026
* main:
  increase worker threads for ci (#6614)
  docs: todo tutorial update (#6613)
  Added goose doc map md file for goose agent to find relevant doc easily. (#6598)
  add back goose branding to home (#6617)
  fix: actually set the working dir for extensions from session (#6612)
  Multi chat (#6428)
  Lifei/fixed accumulated token count (#6587)
  Dont show MCP UI/Apps until tool is approved (#6492)
  docs: max tokens config (#6596)
  User configurable templates (#6420)
  docs: http proxy environment variables (#6594)
  feat: exclude subagent tool from code_execution filtering (#6531)
  Fix path for global agent skills (#6591)
  recipes: add mcp server (#6552)
  feat(gcp-vertex): add model list with org policy filtering (#6393)
  chore: encourage extension searching (#6582)
  blog: mobile apps consolidation and roadmap (#6580)
  chore: remove unused dependencies in cargo.toml (#6561)
  resolved all the extensions to load in cli (#6464)
michaelneale added a commit that referenced this pull request Jan 21, 2026
* main:
  increase worker threads for ci (#6614)
  docs: todo tutorial update (#6613)
  Added goose doc map md file for goose agent to find relevant doc easily. (#6598)
  add back goose branding to home (#6617)
  fix: actually set the working dir for extensions from session (#6612)
  Multi chat (#6428)
  Lifei/fixed accumulated token count (#6587)
  Dont show MCP UI/Apps until tool is approved (#6492)
michaelneale added a commit that referenced this pull request Jan 21, 2026
* main:
  increase worker threads for ci (#6614)
  docs: todo tutorial update (#6613)
  Added goose doc map md file for goose agent to find relevant doc easily. (#6598)
  add back goose branding to home (#6617)
  fix: actually set the working dir for extensions from session (#6612)
  Multi chat (#6428)
  Lifei/fixed accumulated token count (#6587)
  Dont show MCP UI/Apps until tool is approved (#6492)
lifeizhou-ap added a commit that referenced this pull request Jan 22, 2026
* main: (41 commits)
  chore: tweak release docs (#6571)
  fix(goose): propagate session_id across providers and MCP (#6584)
  increase worker threads for ci (#6614)
  docs: todo tutorial update (#6613)
  Added goose doc map md file for goose agent to find relevant doc easily. (#6598)
  add back goose branding to home (#6617)
  fix: actually set the working dir for extensions from session (#6612)
  Multi chat (#6428)
  Lifei/fixed accumulated token count (#6587)
  Dont show MCP UI/Apps until tool is approved (#6492)
  docs: max tokens config (#6596)
  User configurable templates (#6420)
  docs: http proxy environment variables (#6594)
  feat: exclude subagent tool from code_execution filtering (#6531)
  Fix path for global agent skills (#6591)
  recipes: add mcp server (#6552)
  feat(gcp-vertex): add model list with org policy filtering (#6393)
  chore: encourage extension searching (#6582)
  blog: mobile apps consolidation and roadmap (#6580)
  chore: remove unused dependencies in cargo.toml (#6561)
  ...
wpfleger96 added a commit that referenced this pull request Jan 22, 2026
* main: (68 commits)
  fix(docs): use dynamic import for globby ESM module (#6636)
  chore: trigger CI
  Document tab completion (#6635)
  Install goose-mcp crate dependencies (#6632)
  feat(goose): standardize agent-session-id for session correlation (#6626)
  chore: tweak release docs (#6571)
  fix(goose): propagate session_id across providers and MCP (#6584)
  increase worker threads for ci (#6614)
  docs: todo tutorial update (#6613)
  Added goose doc map md file for goose agent to find relevant doc easily. (#6598)
  add back goose branding to home (#6617)
  fix: actually set the working dir for extensions from session (#6612)
  Multi chat (#6428)
  Lifei/fixed accumulated token count (#6587)
  Dont show MCP UI/Apps until tool is approved (#6492)
  docs: max tokens config (#6596)
  User configurable templates (#6420)
  docs: http proxy environment variables (#6594)
  feat: exclude subagent tool from code_execution filtering (#6531)
  Fix path for global agent skills (#6591)
  ...
wpfleger96 added a commit that referenced this pull request Jan 22, 2026
* main: (68 commits)
  fix(docs): use dynamic import for globby ESM module (#6636)
  chore: trigger CI
  Document tab completion (#6635)
  Install goose-mcp crate dependencies (#6632)
  feat(goose): standardize agent-session-id for session correlation (#6626)
  chore: tweak release docs (#6571)
  fix(goose): propagate session_id across providers and MCP (#6584)
  increase worker threads for ci (#6614)
  docs: todo tutorial update (#6613)
  Added goose doc map md file for goose agent to find relevant doc easily. (#6598)
  add back goose branding to home (#6617)
  fix: actually set the working dir for extensions from session (#6612)
  Multi chat (#6428)
  Lifei/fixed accumulated token count (#6587)
  Dont show MCP UI/Apps until tool is approved (#6492)
  docs: max tokens config (#6596)
  User configurable templates (#6420)
  docs: http proxy environment variables (#6594)
  feat: exclude subagent tool from code_execution filtering (#6531)
  Fix path for global agent skills (#6591)
  ...
wpfleger96 added a commit that referenced this pull request Jan 22, 2026
* main: (68 commits)
  fix(docs): use dynamic import for globby ESM module (#6636)
  chore: trigger CI
  Document tab completion (#6635)
  Install goose-mcp crate dependencies (#6632)
  feat(goose): standardize agent-session-id for session correlation (#6626)
  chore: tweak release docs (#6571)
  fix(goose): propagate session_id across providers and MCP (#6584)
  increase worker threads for ci (#6614)
  docs: todo tutorial update (#6613)
  Added goose doc map md file for goose agent to find relevant doc easily. (#6598)
  add back goose branding to home (#6617)
  fix: actually set the working dir for extensions from session (#6612)
  Multi chat (#6428)
  Lifei/fixed accumulated token count (#6587)
  Dont show MCP UI/Apps until tool is approved (#6492)
  docs: max tokens config (#6596)
  User configurable templates (#6420)
  docs: http proxy environment variables (#6594)
  feat: exclude subagent tool from code_execution filtering (#6531)
  Fix path for global agent skills (#6591)
  ...
fbalicchia pushed a commit to fbalicchia/goose that referenced this pull request Jan 23, 2026
Signed-off-by: fbalicchia <fbalicchia@cuebiq.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants