Skip to content

feat(agenticclaude): expose cache_creation_input_tokens + Vertex explicit credentials - #970

Open
sin-bufan wants to merge 4 commits into
cloudwego:mainfrom
sin-bufan:feat/agenticclaude-cache-creation-and-vertex-creds
Open

feat(agenticclaude): expose cache_creation_input_tokens + Vertex explicit credentials#970
sin-bufan wants to merge 4 commits into
cloudwego:mainfrom
sin-bufan:feat/agenticclaude-cache-creation-and-vertex-creds

Conversation

@sin-bufan

Copy link
Copy Markdown
Contributor

Summary

  • cache_creation_input_tokens: Expose Anthropic's cache_creation_input_tokens in AgenticMessage.Extra using the same key as the legacy claude adapter (_eino_claude_cache_creation_input_tokens). Without this, the value is summed into PromptTokens and the breakdown is lost, making accurate cost calculation impossible.
  • Vertex credentials: Add optional *google.Credentials field to GoogleVertexAIConfig. When set, uses vertex.WithCredentials instead of ambient ADC (vertex.WithGoogleAuth), avoiding process-global os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", ...) which is unsafe under concurrency.

Changes

File Change
consts.go Add KeyOfCacheCreationInputTokens constant
convertor.go Populate msg.Extra in toAgenticMessage (non-streaming)
event_convertor.go Populate msg.Extra in MessageDeltaEvent handler (streaming)
model.go Add Credentials *google.Credentials to GoogleVertexAIConfig; use vertex.WithCredentials when set

Test plan

  • go build ./... passes
  • go test ./... passes (all existing tests green)
  • Integration test with real Claude API verifying cache_creation_input_tokens appears in Extra
  • Integration test with Vertex AI using explicit credentials

Made with Cursor

sin-bufan and others added 4 commits August 26, 2026 12:42
…icit credentials

1. Expose cache_creation_input_tokens in AgenticMessage.Extra

   The Anthropic API reports cache_creation_input_tokens separately from
   input_tokens, but toTokenUsage() sums them into PromptTokens and the
   breakdown is lost. This makes accurate cost calculation impossible for
   consumers (e.g. Langfuse).

   Fix: populate msg.Extra["_eino_claude_cache_creation_input_tokens"]
   in both non-streaming (toAgenticMessage) and streaming
   (MessageDeltaEvent) paths. The key matches the legacy claude adapter
   for downstream compatibility.

2. Add Credentials field to GoogleVertexAIConfig

   The Vertex path previously only supported ambient ADC via
   vertex.WithGoogleAuth, forcing callers to use os.Setenv which is
   process-global and unsafe under concurrency or hot-reload.

   Fix: add optional *google.Credentials field. When set, use
   vertex.WithCredentials instead. Falls back to WithGoogleAuth when nil.

Co-authored-by: Cursor <cursoragent@cursor.com>
When Gemini returns consecutive chunks each containing a single
function_tool_call, they shared the same streaming index because
populateStreamingMeta only incremented the index on block type change.
ConcatAgenticMessages then tried to merge different tool calls
(e.g. 'skill' and 'read_file') and failed with:
  "expected tool name 'skill' for function tool call, but got 'read_file'"

Fix: advance curIndex after the last block if it is a discrete type
(function_tool_call, function_tool_result, server_tool_*, mcp_tool_*).
These types are self-contained and should never be concatenated across
chunks.

Co-authored-by: Cursor <cursoragent@cursor.com>
convFunctionToolCall now treats empty string Arguments as an empty
object instead of failing with unmarshal error. This prevents
NodeRunError when a model returns a tool call with no arguments
(e.g. task_complete).

Co-authored-by: Cursor <cursoragent@cursor.com>
Fall back to CallID when Name is missing so Gemini API requests
with function_response parts remain valid.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant