Skip to content

feat(components): preserve Gemini tool call IDs - #984

Open
shentongmartin wants to merge 2 commits into
mainfrom
feat/gemini-tool-call-id
Open

shentongmartin wants to merge 2 commits into
mainfrom
feat/gemini-tool-call-id

Conversation

@shentongmartin

Copy link
Copy Markdown
Contributor

Gemini Tool Call ID Passthrough

Problem

Gemini now returns opaque IDs in FunctionCall.id, but both the classic and
agentic adapters replaced or dropped them. Parallel calls to the same function
could therefore be paired with the wrong result when completion order differed
from call order or when persisted history was rebuilt.

Solution

Preserve Gemini's ID in schema.ToolCall.ID and
schema.FunctionToolCall.CallID, then send the same value back through
FunctionCall.id and FunctionResponse.id.

Models and gateways that omit IDs keep the existing compatibility behavior:
the adapter creates a unique UUID and Eino carries that value through the tool
result.

Decisions

  • Matching is ID-based; result order is not changed or inferred.
  • Existing Eino message types remain unchanged.
  • Thought signatures continue to use their existing independent path.

Key Insight

Gemini's function name identifies what to execute, while its opaque call ID
identifies which invocation a result belongs to. They must remain separate
when the same function is called concurrently.

Summary

Problem Solution
Provider IDs were replaced or dropped Preserve them through both Gemini adapters
Same-name results could be ambiguous Return both function name and matching call ID
Older models may omit IDs Generate a UUID only when the provider ID is empty

Gemini Tool Call ID 透传

问题

Gemini 已开始在 FunctionCall.id 中返回 opaque ID,但 classic 和 agentic
适配器此前会替换或丢弃该值。当同一个函数被并行调用,且结果完成顺序与调用顺序不一致,
或持久化历史被重新加载时,结果可能与错误的调用配对。

方案

将 Gemini ID 保留到 schema.ToolCall.ID
schema.FunctionToolCall.CallID,并通过 FunctionCall.id
FunctionResponse.id 原样回传。

对于不返回 ID 的旧模型或旧网关,继续使用兼容行为:适配器生成唯一 UUID,
并由 Eino 在工具结果中携带该值。

决策

  • 只通过 ID 关联调用与结果,不调整或推断结果顺序。
  • 不修改 Eino 公共消息结构。
  • thought signature 继续走现有独立透传链路。

核心认知

Gemini 的函数名表示“执行什么”,opaque call ID 表示“结果属于哪一次调用”。
同名函数并发执行时,两者不能互相替代。

总结

问题 方案
Provider ID 被替换或丢弃 在两套 Gemini 适配器中完整保留
同名调用的结果存在歧义 同时回传函数名和匹配的 call ID
旧模型可能不返回 ID 仅在 provider ID 为空时生成 UUID

Preserve provider-issued function call IDs across classic and agentic Gemini messages, while retaining UUID fallback for legacy responses without IDs.

Change-Id: Ie9bcdf87e932383c9fdafbf0f91186ea957c3694
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown

Need to create a new tag

The following modules have changes and may need version updates:

  • components/model/agenticgemini (Current: components/model/agenticgemini/v0.2.3)

  • components/model/gemini (Current: components/model/gemini/v0.1.34)

⚠️ Please create and push new version tags for these modules after merging this PR.

Change-Id: Ie4f78174b19cdc3c62ff10b76a2a8f5939327c7d
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown

Need to create a new tag

The following modules have changes and may need version updates:

  • components/model/agenticgemini (Current: components/model/agenticgemini/v0.2.3)

  • components/model/gemini (Current: components/model/gemini/v0.1.34)

⚠️ Please create and push new version tags for these modules after merging this PR.

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