Skip to content

fix: health checker IDC support + compaction error fix + OpenAI error format + code optimization#38

Open
poboll wants to merge 9 commits intoaliom-v:mainfrom
poboll:fix/health-checker-idc
Open

fix: health checker IDC support + compaction error fix + OpenAI error format + code optimization#38
poboll wants to merge 9 commits intoaliom-v:mainfrom
poboll:fix/health-checker-idc

Conversation

@poboll
Copy link
Copy Markdown

@poboll poboll commented Mar 7, 2026

Summary

本 PR 包含 5 大改动:健康检查器 IDC 修复、工具配对验证修复、OpenAI 兼容错误格式、请求重试机制、代码优化重构。


Changes

1. Health Checker IDC Token Support (health_checker.py)

  • 健康检查器传递 client_idclient_secret 以支持 IDC token 刷新
  • 同时检查 active 和 invalid 状态的 token
  • 自动恢复被误标为 invalid 的有效 token

2. Tool Pairs 验证修复 (converters.py)

问题: OpenCode 执行 compaction(上下文裁剪)后,历史消息中可能出现:

  • assistant 消息有 toolUses 但对应的 user toolResults 被删除
  • user 消息有 toolResults 但对应的 assistant toolUses 被删除

Kiro API 要求每个 toolUse 必须有对应的 toolResult,否则返回 "Improperly formed request"

修复:

  • validate_and_fix_tool_pairs() — 双向验证,移除所有孤立的 tool_calls 和 tool_results
  • _split_last_message_tool_results() — 当最后一条消息同时包含 tool_results 和文本时,将 tool_results 拆分到历史中(与 toolUse 配对),文本作为 currentMessage
  • trim_history_to_fit() — 历史消息过长时自动裁剪,保持 tool_use/tool_result 配对完整
  • build_kiro_payload() 调用顺序:validate → trim → merge → split

3. OpenAI 兼容错误格式 (exceptions.py, main.py)

问题: FastAPI 默认的 HTTPException 返回 {"detail": "..."} 格式,但 OpenCode (@ai-sdk/openai-compatible) 和 OpenClaw (openai-completions 模式) 都期望 OpenAI 标准格式:

{"error": {"message": "...", "type": "...", "code": ...}}

修复:

  • 新增 http_exception_handler() — 对所有 /v1/ 端点的错误返回 OpenAI 格式
  • HTTP 状态码映射:400→invalid_request_error, 401→authentication_error, 429→rate_limit_error 等
  • validation_exception_handler() 也对 /v1/ 端点返回 OpenAI 格式
  • main.py 注册全局异常处理器

4. 请求重试机制 (request_handler.py)

  • CONTENT_LENGTH_EXCEEDS_THRESHOLD 错误:自动将历史裁剪到 1/3 后重试
  • Improperly formed request 错误:移除全部历史和孤立 toolResults 后重试
  • 重试逻辑提取为 _maybe_build_retry_payload() 函数

5. 代码优化重构

converters.py:

  • trim_history_to_fit(): 从 O(n²) 优化到 O(n),预计算 sizes 数组做增量减法
  • validate_and_fix_tool_pairs(): 提取 _get_tc_id() 消除重复的 ID 提取逻辑,合并两个收集 pass
  • build_kiro_payload(): 30+ 行的 split 逻辑提取为独立的 _split_last_message_tool_results() 函数

request_handler.py:

  • 两个重试分支提取为 _maybe_build_retry_payload() 函数
  • 修复 from kiro_gateway.config import settings 重复导入
  • 删除定义但未使用的 reduced_threshold 变量

6. 其他

  • 新增 Claude 4.6 模型支持(opus/sonnet 及 thinking 变体)
  • Docker Compose 配置凭证文件挂载
  • .gitignore 添加 kiro_creds.json

Files Changed

File Changes
kiro_gateway/converters.py +344 -24 — 工具配对验证、历史裁剪、split 逻辑、O(n) 优化
kiro_gateway/health_checker.py +105 -6 — IDC token 健康检查修复
kiro_gateway/exceptions.py +83 — OpenAI 兼容错误格式处理器
kiro_gateway/request_handler.py +73 -2 — 重试逻辑提取、重复导入修复
kiro_gateway/config.py +36 -3 — 新模型、新配置项
docker-compose.yml +9 -4 — 凭证文件挂载
main.py +5 -1 — 注册异常处理器
kiro_gateway/__init__.py +2 — 导出新函数
.gitignore +1 — 忽略凭证文件

Testing

基础请求测试

curl -X POST http://localhost:8833/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"claude-haiku-4-5","messages":[{"role":"user","content":"Hi"}],"max_tokens":50}'

Tool Calls 测试(验证 tool pairs 修复)

curl -X POST http://localhost:8833/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model":"claude-haiku-4-5",
    "messages":[
      {"role":"user","content":"What is 2+2?"},
      {"role":"assistant","content":"Let me calculate.","tool_calls":[{"id":"call_1","type":"function","function":{"name":"calc","arguments":"{\"expr\":\"2+2\"}"}}]},
      {"role":"tool","tool_call_id":"call_1","content":"4"},
      {"role":"user","content":"Thanks! Now 3+3?"}
    ],
    "max_tokens":50
  }'

错误格式测试(验证 OpenAI 兼容)

curl -s http://localhost:8833/v1/chat/completions \
  -H "Authorization: Bearer wrong-key" \
  -H "Content-Type: application/json" \
  -d '{"model":"claude-haiku-4-5","messages":[{"role":"user","content":"hi"}]}'
# Expected: {"error":{"message":"...","type":"authentication_error","code":401}}

Anthropic 格式测试

curl -X POST http://localhost:8833/v1/messages \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "anthropic-version: 2023-06-01" \
  -d '{"model":"claude-sonnet-4-6","max_tokens":50,"messages":[{"role":"user","content":"Hi"}]}'

所有测试均已通过验证。

poboll added 2 commits March 7, 2026 11:18
- Add client_id and client_secret support to health checker for IDC tokens
- Check both active and invalid tokens during health checks
- Automatically restore valid tokens to 'active' status
- Add new Claude 4.6 models (opus/sonnet and thinking variants)
- Add missing inject_output_limit_warning config setting

Fixes: Token health checker incorrectly marks IDC tokens as invalid
- Add validate_and_fix_tool_pairs function to check for orphan toolUses
- Remove toolUses without matching toolResults to prevent 'Improperly formed request' error
- This fixes the issue when OpenCode compaction removes toolResults but leaves toolUses
@poboll poboll changed the title fix: health checker IDC token support + new models fix: health checker IDC support + new models + compaction error fix Mar 7, 2026
- Fix AttributeError when tool_calls contains dict instead of objects
- Use hasattr and isinstance to handle both formats
@poboll poboll force-pushed the fix/health-checker-idc branch from 749e92a to 10ff82e Compare March 7, 2026 06:14
poboll added 5 commits March 7, 2026 15:46
…licate tool ID extraction

- trim_history_to_fit: pre-compute sizes array to avoid O(n²) recalculation
- Extract _split_last_message_tool_results from build_kiro_payload (30+ lines → clean function)
- validate_and_fix_tool_pairs: extract _get_tc_id helper, merge collection passes
- Fix tool_results/text split in last message for Kiro API compatibility
…plicate imports

- Extract CONTENT_LENGTH_EXCEEDS_THRESHOLD and Improperly formed request retry into helper function
- Remove duplicate 'from kiro_gateway.config import settings' import
- Remove unused reduced_threshold variable
- Eliminate redundant response.aclose() and retry call patterns
- Add http_exception_handler for OpenAI SDK compatibility (OpenCode, OpenClaw)
- Map HTTP status codes to OpenAI error types (authentication_error, rate_limit_error, etc.)
- Update validation_exception_handler to also return OpenAI format for /v1/ endpoints
- Register handler in main.py, update __init__.py exports
@poboll poboll changed the title fix: health checker IDC support + new models + compaction error fix fix: health checker IDC support + compaction error fix + OpenAI error format + code optimization Mar 7, 2026
- Add __pycache__/, *.pyc, *.pyo for Python cache
- Add debug_logs/ for debug output
- Add kirogate-progress.md for local notes
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.

1 participant