feat(gemini): 支持 Gemini Thinking 并持久化 thought signature#2335
Conversation
- 新增 ContentBlockMetadataKeys 常量类统一管理 metadata 键 - ToolUseBlock 改用 THOUGHT_SIGNATURE 常量替代硬编码字符串 - 新增 GeminiThoughtSignatureUtils 工具类处理 byte[] 与 Base64 转换 - GeminiMessageConverter 支持 ThinkingBlock 转换及 thoughtSignature 恢复 - GeminiResponseParser 将 thoughtSignature 解析到 ContentBlock metadata - TextBlock 新增 metadata 字段支持 JSON 序列化 - ThinkingAccumulator 和 TextAccumulator 新增 metadata 积累逻辑 - GenerateOptions 新增 includeThoughts 和 thinkingLevel 字段 - GeminiChatFormatter 按字段构建 ThinkingConfig(thinkingBudget / thinkingLevel / includeThoughts) - 新增端到端测试验证 signature 在流式聚合、JSON 持久化、回放中的完整性 - 更新中英文文档
|
武志立 seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
- 修改 TextAccumulator 与 ThinkingAccumulator,在元数据包含 THOUGHT_SIGNATURE 时立即结束当前分区,从而维持签名边界独立 - 新增 buildAllTextBlocks() / buildAllThinkingBlocks() 方法,返回保留原始顺序的多分区列表 - 更新 ReasoningContext.buildFinalMessage(),使用 addAll 替代此前合并的单个块,使多个签名分区能够被正确序列化与重放 - 修正 GeminiResponseParser 对空文本但携带签名的处理,允许空字符串的 thinking/text 部分仅凭 signed metadata 保留 - 新增测试用例覆盖:空签名分区、非助手消息跳过 ThinkingBlock、签名边界保留、Base64 编解码及非法签名拒绝等场景
|
CLA Not Signed The Contributor License Agreement (CLA) check is currently pending on this PR ( @wzl521 please sign the CLA via the CLA assistant badge in the comment above, or visit https://cla-assistant.io/agentscope-ai/agentscope-java. Once signed, the Automated check by github-manager-bot |
|
I have signed the CLA,please retry it! |
I have signed the CLA,please retry it! |
Background
#2240 — The Gemini model adapter lacked first-class support for Gemini's built-in thinking capability. There were several gaps:
"low", "medium", "high") for the latest models.
ToolUseBlock.METADATA_THOUGHT_SIGNATURE), not on TextBlock or ThinkingBlock. After a JSON serialization round-trip, the byte-array signature was lost or corrupted.
were destroyed, making it impossible to reconstruct distinct signed parts in the next request.
Changes
Core (agentscope-core)
content block types.
and a new one begins. The existing buildAggregated() method continues to return a single merged block for backward compatibility.
Gemini Extension (agentscope-extensions-model-gemini)
preserving existing behavior. When includeThoughts is explicitly set, it always takes precedence.
functionCall Part) via GeminiThoughtSignatureUtils.applyMetadata.
Documentation
answer / tool call / persistent history replay).