[PR #20] [MERGED] fix: stabilize thinking streams, multimodal parsing, and token accounting #15

Closed
opened 2026-02-27 15:47:41 +03:00 by kerem · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/Quorinex/Kiro-Go/pull/20
Author: @edxeth
Created: 2/21/2026
Status: Merged
Merged: 2/23/2026
Merged by: @Quorinex

Base: mainHead: fix/thinking-multimodal-token-accounting


📝 Commits (5)

  • 95845dc fix: stabilize multimodal image compatibility across OpenCode flows
  • c969f34 fix: deduplicate thinking streams and trim injected prompt noise
  • 7c0737f fix: align /v1/messages thinking blocks and message_start usage
  • 1b25869 fix: reduce repetitive thinking across tool turns
  • 07e08ad fix: unify token counting on existing API endpoints

📊 Changes

7 files changed (+1413 additions, -326 deletions)

View changed files

📝 proxy/handler.go (+390 -178)
proxy/handler_test.go (+50 -0)
📝 proxy/kiro.go (+162 -31)
proxy/kiro_test.go (+37 -0)
proxy/token_estimator.go (+196 -0)
📝 proxy/translator.go (+380 -117)
proxy/translator_test.go (+198 -0)

📄 Description

Summary

This branch hardens proxy behavior for long-running tool workflows and mixed text+image prompts in Anthropic and OpenAI-compatible clients. The focus is stream correctness, multimodal translation resilience, and consistent token usage reporting across existing API endpoints.

Key changes

1) Multimodal compatibility and model capability signaling

  • Normalized /v1/models metadata to expose vision support consistently (supports_image, modality/capability fields).
  • Made model matching deterministic for common aliases and 4.6 variants.
  • Expanded OpenAI-side content parsing to accept more attachment shapes (image_url, input_image, file, input_file, nested source/file, data URLs/base64 payloads).
  • Sanitized synthetic placeholders like [Image N] and ensured image-only follow-up turns still send non-empty user content.

2) Thinking stream stability and event alignment

  • Enforced single-source reasoning emission per stream (reasoningContentEvent or <thinking> tags, not both).
  • Improved stream buffer/tag handling in both Claude and OpenAI paths, including clean open/close and flush behavior.
  • Kept /v1/messages stream lifecycle coherent (message_start -> content blocks -> message_delta -> message_stop) while preserving tool-use transitions.

3) Tool-loop continuity and replay prevention

  • Added chunk normalization in Kiro event parsing so only unseen deltas are emitted (handles overlap and rewind patterns).
  • Preserved structured assistant/tool content through translation so tool loops retain context.
  • Stabilized conversation ID derivation from anchor content so multi-turn sessions remain on consistent lineage.

4) Unified deterministic token accounting

  • Added proxy/token_estimator.go and wired shared estimation into:
    • POST /v1/messages
    • POST /v1/chat/completions
    • POST /v1/messages/count_tokens
  • Centralized accounting for input/output text, thinking/reasoning content, tool calls, and structured payloads.
  • Kept robust upstream usage parsing in proxy/kiro.go without relying on sparse upstream metering fields as the only source.

Commit walkthrough

  1. 95845dc — stabilize multimodal image compatibility and model capability signaling.
  2. c969f34 — deduplicate thinking streams and trim injected prompt noise.
  3. 7c0737f — align /v1/messages thinking blocks and message_start usage behavior.
  4. 1b25869 — reduce repetitive thinking across tool turns; add tests for stream source gating and chunk replay handling.
  5. 07e08ad — unify token counting on existing endpoints with shared estimator logic.

Validation

  • go test ./... (pass)
  • go build ./... (pass)

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/Quorinex/Kiro-Go/pull/20 **Author:** [@edxeth](https://github.com/edxeth) **Created:** 2/21/2026 **Status:** ✅ Merged **Merged:** 2/23/2026 **Merged by:** [@Quorinex](https://github.com/Quorinex) **Base:** `main` ← **Head:** `fix/thinking-multimodal-token-accounting` --- ### 📝 Commits (5) - [`95845dc`](https://github.com/Quorinex/Kiro-Go/commit/95845dc835fa71dfdfc80179b26ff9caf1c30524) fix: stabilize multimodal image compatibility across OpenCode flows - [`c969f34`](https://github.com/Quorinex/Kiro-Go/commit/c969f34aefa9c5de59e4a1d2e60da220c3e0b66a) fix: deduplicate thinking streams and trim injected prompt noise - [`7c0737f`](https://github.com/Quorinex/Kiro-Go/commit/7c0737f71a149ce1d856591eae3c0cdd3b2f7b3d) fix: align /v1/messages thinking blocks and message_start usage - [`1b25869`](https://github.com/Quorinex/Kiro-Go/commit/1b25869b24886f165d55e3d2eb0a4e654f0ff9f3) fix: reduce repetitive thinking across tool turns - [`07e08ad`](https://github.com/Quorinex/Kiro-Go/commit/07e08ada784d53ac070a3fd7728eea286f3e1a01) fix: unify token counting on existing API endpoints ### 📊 Changes **7 files changed** (+1413 additions, -326 deletions) <details> <summary>View changed files</summary> 📝 `proxy/handler.go` (+390 -178) ➕ `proxy/handler_test.go` (+50 -0) 📝 `proxy/kiro.go` (+162 -31) ➕ `proxy/kiro_test.go` (+37 -0) ➕ `proxy/token_estimator.go` (+196 -0) 📝 `proxy/translator.go` (+380 -117) ➕ `proxy/translator_test.go` (+198 -0) </details> ### 📄 Description ## Summary This branch hardens proxy behavior for long-running tool workflows and mixed text+image prompts in Anthropic and OpenAI-compatible clients. The focus is stream correctness, multimodal translation resilience, and consistent token usage reporting across existing API endpoints. ## Key changes ### 1) Multimodal compatibility and model capability signaling - Normalized `/v1/models` metadata to expose vision support consistently (`supports_image`, modality/capability fields). - Made model matching deterministic for common aliases and 4.6 variants. - Expanded OpenAI-side content parsing to accept more attachment shapes (`image_url`, `input_image`, `file`, `input_file`, nested `source`/`file`, data URLs/base64 payloads). - Sanitized synthetic placeholders like `[Image N]` and ensured image-only follow-up turns still send non-empty user content. ### 2) Thinking stream stability and event alignment - Enforced single-source reasoning emission per stream (`reasoningContentEvent` or `<thinking>` tags, not both). - Improved stream buffer/tag handling in both Claude and OpenAI paths, including clean open/close and flush behavior. - Kept `/v1/messages` stream lifecycle coherent (`message_start` -> content blocks -> `message_delta` -> `message_stop`) while preserving tool-use transitions. ### 3) Tool-loop continuity and replay prevention - Added chunk normalization in Kiro event parsing so only unseen deltas are emitted (handles overlap and rewind patterns). - Preserved structured assistant/tool content through translation so tool loops retain context. - Stabilized conversation ID derivation from anchor content so multi-turn sessions remain on consistent lineage. ### 4) Unified deterministic token accounting - Added `proxy/token_estimator.go` and wired shared estimation into: - `POST /v1/messages` - `POST /v1/chat/completions` - `POST /v1/messages/count_tokens` - Centralized accounting for input/output text, thinking/reasoning content, tool calls, and structured payloads. - Kept robust upstream usage parsing in `proxy/kiro.go` without relying on sparse upstream metering fields as the only source. ## Commit walkthrough 1. `95845dc` — stabilize multimodal image compatibility and model capability signaling. 2. `c969f34` — deduplicate thinking streams and trim injected prompt noise. 3. `7c0737f` — align `/v1/messages` thinking blocks and `message_start` usage behavior. 4. `1b25869` — reduce repetitive thinking across tool turns; add tests for stream source gating and chunk replay handling. 5. `07e08ad` — unify token counting on existing endpoints with shared estimator logic. ## Validation - `go test ./...` (pass) - `go build ./...` (pass) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
kerem 2026-02-27 15:47:41 +03:00
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/Kiro-Go#15
No description provided.