Commit Graph

327 Commits

Author SHA1 Message Date
diegosouzapw
28123355b4 Merge branch 'feat/issue-660-qoder' into main
# Conflicts:
#	docs/i18n/ar/README.md
#	docs/i18n/bg/README.md
#	docs/i18n/da/README.md
#	docs/i18n/de/README.md
#	docs/i18n/es/README.md
#	docs/i18n/fi/README.md
#	docs/i18n/fr/README.md
#	docs/i18n/he/README.md
#	docs/i18n/hu/README.md
#	docs/i18n/id/README.md
#	docs/i18n/in/README.md
#	docs/i18n/it/README.md
#	docs/i18n/ja/README.md
#	docs/i18n/ko/README.md
#	docs/i18n/ms/README.md
#	docs/i18n/nl/README.md
#	docs/i18n/no/README.md
#	docs/i18n/phi/README.md
#	docs/i18n/pl/README.md
#	docs/i18n/pt-BR/README.md
#	docs/i18n/pt/README.md
#	docs/i18n/ro/README.md
#	docs/i18n/ru/README.md
#	docs/i18n/sk/README.md
#	docs/i18n/sv/README.md
#	docs/i18n/th/README.md
#	docs/i18n/uk-UA/README.md
#	docs/i18n/vi/README.md
#	docs/i18n/zh-CN/README.md
2026-03-30 20:39:31 -03:00
diegosouzapw
e7c73c76dd chore(release): bump version to v3.3.7 2026-03-30 19:28:20 -03:00
diegosouzapw
0b2c488a61 chore(release): bump version to v3.3.6 2026-03-30 18:24:15 -03:00
diegosouzapw
76e135077b Resolve merge conflicts with main natively built Prompt Cache UI 2026-03-30 18:20:19 -03:00
diegosouzapw
04d0c350db build: sync monorepo package versions across electron and open-sse 2026-03-30 18:02:33 -03:00
oyi77
6780485051 feat(cache): persistent metrics, cache entry browser, settings UI, MCP tools, prefix analyzer
Implements remaining features from #813:

Phase 1 - Persistent Metrics:
- Add cache_metrics table for persistent hit/miss tracking
- Semantic cache stats now survive server restarts

Phase 2 - Cache Entry Browser:
- /api/cache/entries endpoint with search, pagination, delete
- CacheEntriesTab component for browsing cached entries

Phase 3 - Settings UI:
- CacheSettingsTab for semantic/prompt cache configuration
- /api/settings/cache-config endpoint

Phase 4 - Prefix Analyzer:
- src/lib/promptCache/prefixAnalyzer.ts for intelligent caching
- Analyzes message arrays to find stable prefixes

Phase 5 - Provider Support:
- Added deepseek to CACHING_PROVIDERS

Phase 6 - MCP Tools:
- omniroute_cache_stats tool
- omniroute_cache_flush tool

Phase 7 - Retention:
- cleanOldMetrics() for auto-purge of old entries

Closes #813
2026-03-30 17:32:45 -03:00
Chris Staley
c5d9b5f51d fix: apply PR review feedback for Gemini CLI quota
- Add early return guard for missing accessToken in getGeminiUsage
- Add 10s fetch timeout (AbortSignal.timeout) on retrieveUserQuota calls
- Clamp used value with Math.max(0, ...) for non-negative display
- Use full accessToken as cache key instead of truncated prefix
- Replace catch(err: any) with instanceof Error check in models route
2026-03-30 17:32:42 -03:00
Chris Staley
35e2892b98 feat: add real Gemini CLI quota tracking via retrieveUserQuota API
Replace stub getGeminiUsage() with per-model quota fetching from Google
Cloud Code Assist's retrieveUserQuota endpoint (same API the official
Gemini CLI /stats command uses). Fixes OAuth env var name, aligns model
list with official Gemini CLI VALID_GEMINI_MODELS, and makes "Import
from /models" discover new models via the quota endpoint.
2026-03-30 17:32:42 -03:00
tombii
c6eadc504b fix(usage): include cache tokens in input token counts
- Fix getLoggedInputTokens to return full prompt_tokens (input + cache_read + cache_creation)
- Fix usageExtractor for non-streaming Claude responses to calculate total correctly
- Add formatUsageLog helper to show CR=<cache_read> in logs
- Add migration 012 to fix historical token counts in usage_history
- Move prompt cache metrics from Settings to /dashboard/cache page

Per Claude API docs:
Total input tokens = input_tokens + cache_creation_input_tokens + cache_read_input_tokens

Fixes issue where totalInputTokens (71k) was less than totalCacheCreationTokens (1.35M).

Tested:
- All 1134 unit tests pass
- Cache metrics API returns correct totals
- Migration is idempotent and tracked in _omniroute_migrations
- Logs show cache read tokens: 'in=6055 | out=211 | CR=22399'

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 19:24:26 +02:00
diegosouzapw
a864258cb8 feat(ui): integrate FSM, adaptive routing, and provider diversity 2026-03-30 12:58:45 -03:00
Diego Rodrigues de Sa e Souza
04a0b07bf6 Merge pull request #793 from igormorais123/feat/provider-diversity-scoring
feat(sse): add provider diversity scoring via Shannon entropy
2026-03-30 11:07:03 -03:00
Diego Rodrigues de Sa e Souza
59e48ca91a Merge pull request #794 from igormorais123/feat/adaptive-volume-routing
feat(sse): add adaptive volume/complexity detector for routing strategy override
2026-03-30 11:07:00 -03:00
Diego Rodrigues de Sa e Souza
5887da0229 Merge pull request #805 from igormorais123/feat/fsm-workflow-orchestrator
feat(sse): add deterministic FSM orchestrator for multi-step workflows
2026-03-30 11:06:46 -03:00
diegosouzapw
f810b13bca fix: complete bugfixes for UI, OAuth fallbacks, cliRuntime Windows constraints and Codex non-streaming integration 2026-03-30 11:01:55 -03:00
diegosouzapw
5ad687c6d8 fix(ui/ci): use ProviderIcon for Provider header breadcrumbs and add permissions to electron-release.yml (#745, #761)
- Use ProviderIcon for internal .png paths solving SVG provider 404 images (#745).
- Add id-token: write and packages: write permissions to .github/workflows/electron-release.yml to fix permissions denied failure when calling the reusable workflow npm-publish.yml (#761).
- Fix tests and ESM resolution for autoUpdate.ts override logic.
2026-03-30 07:38:30 -03:00
igormorais123
ae96fb6f63 feat(sse): add deterministic FSM orchestrator for multi-step workflows
Risk-based phase skipping: high=all 9 phases, medium=skip planner, low=execute+test.
Veto authority, pause/resume, retry limits, full audit trail.

Closes #800, closes #802
2026-03-30 01:28:45 -03:00
igormorais123
a427d215e3 feat(sse): add adaptive volume/complexity detector for routing strategy override
Add volumeDetector module that analyzes request characteristics (batch
size, token count, tool usage, browser signals, complexity keywords)
and recommends routing strategy overrides.

Rules:
- Batch >= 50 items → round-robin with economy models
- Critical complexity (many tools, browser, deploy) → priority premium-first
- Browser/UI interaction → force premium priority
- Short requests (<200 tokens) → flag for economy tier

Closes #789
2026-03-30 00:46:55 -03:00
igormorais123
271cf37b8a feat(sse): add provider diversity scoring via Shannon entropy
Add a providerDiversity module that tracks provider usage distribution
using a rolling time window and calculates Shannon entropy normalized
to [0..1]. This enables the auto-combo scoring engine to factor in
provider diversity — boosting underrepresented providers to reduce
single-point-of-failure risk.

Key features:
- Rolling window with configurable size and TTL
- Shannon entropy calculation normalized to [0..1]
- Per-provider diversity boost for auto-combo integration
- Diversity report for dashboard display
- Full test coverage

Closes #788
2026-03-30 00:45:17 -03:00
diegosouzapw
1c070d16a6 fix: add missing i18n keys for windsurf/copilot and apply fetch timeout to streaming requests (#748, #769)
- Add windsurf and copilot entries to toolDescriptions in all 33 locale files
  to fix MISSING_MESSAGE errors on the CLI Tools page (#748)
- Apply FETCH_TIMEOUT_MS to streaming requests' initial fetch() call to prevent
  300s TCP default timeout causing silent failures on long-running requests (#769)
- Previously only non-streaming requests had timeout protection; streaming requests
  relied solely on stream idle detection which doesn't cover initial connection hangs
2026-03-29 19:43:21 -03:00
Diego Rodrigues de Sa e Souza
f9690d40d3 Merge pull request #778 from christopher-s/glm-coding-audit
feat: GLM Coding provider enhancements and fixes
2026-03-29 19:36:52 -03:00
Diego Rodrigues de Sa e Souza
aa5ab55b14 Merge pull request #777 from diegosouzapw/release/v3.3.1
chore(release): v3.3.1 — bug fixes and schema adjustments
2026-03-29 19:36:11 -03:00
Chris Staley
9195b18981 fix: resolve t11 any-budget lint failures and remove audit doc from tracking
Pre-existing any-budget violations in chatCore.ts (6), combo.ts (2), and
embeddings.ts (1 false positive in comment) — none introduced by GLM work.
Replace `as any` with `Record<string, unknown>` casts and reword comment.

Also removes docs/superpowers audit worksheet from git tracking (not part
of GLM Coding provider changes).
2026-03-29 15:35:55 -06:00
Chris Staley
231a02eb10 fix: correct GLM context windows for glm-4.6v (128K) and glm-4.5v (16K) per Z.AI docs 2026-03-29 15:13:07 -06:00
Chris Staley
d01266c642 fix: remove glm-4.7-flashx from GLM Coding provider (429 insufficient balance)
Live-tested all GLM Coding models against the /api/coding/paas/v4
endpoint. glm-4.7-flashx returns 429 "Insufficient balance or no
resource package" and is not listed on the /models endpoint.

All other models (glm-5.1, glm-5, glm-5-turbo, glm-4.7, glm-4.7-flash,
glm-4.6v, glm-4.6, glm-4.5v, glm-4.5, glm-4.5-air) return 200.
2026-03-29 15:13:07 -06:00
Chris Staley
14bf3645d6 fix: validate GLM coding provider settings
Record the family-by-family GLM Coding audit, add regression coverage, and fix the documented GLM-5.1 context window override.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 15:13:07 -06:00
Chris Staley
0f4a7b2405 fix: add GLM-4.7-FlashX model and correct GLM-4.7 tool calling support
- Add missing glm-4.7-flashx variant to provider registry (confirmed in
  Z.AI official GLM-4.7 overview docs as one of three variants)
- Remove glm-4.7/glm4.7 from tool calling denylist — official docs
  explicitly show GLM-4.7 supporting function calling with tools param
- Add estimated pricing for glm-4.7-flashx ($0.3/$1.1) between free
  Flash and standard 4.7 tiers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 15:13:07 -06:00
Chris Staley
681e49a4cc fix: set correct 128k context length for GLM 4.5 and GLM 4.5 Air
Official docs at https://docs.z.ai/guides/llm/glm-4.5 confirm both models
have 128k token context, not the 200k provider default.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 15:13:07 -06:00
diegosouzapw
6e9c97fbff chore(release): v3.3.1 — bug fixes and schema adjustments 2026-03-29 16:39:10 -03:00
mikhailsal
370070f489 fix(stream): normalize delta.reasoning alias and separate reasoning in client response (#771)
* fix(stream): normalize delta.reasoning to reasoning_content in SSE streaming

NVIDIA kimi-k2.5 (and potentially other providers) send reasoning
tokens as `delta.reasoning` in SSE streaming chunks instead of the
standard OpenAI `delta.reasoning_content` field. This caused reasoning
content to be silently dropped during stream passthrough — clients
received only the final answer with no reasoning separation.

The non-streaming sanitizer (responseSanitizer.ts) already handled this
alias, but the streaming pipeline did not.

Fix applied in 4 locations:
- stream.ts passthrough: normalize + force re-serialize sanitized chunk
- stream.ts translate: accumulate reasoning from delta.reasoning
- sseParser.ts: collect delta.reasoning in parseSSEToOpenAIResponse
- streamPayloadCollector.ts: collect delta.reasoning in buildOpenAISummary

* fix: eliminate injectedUsage reuse bug and add reasoning alias tests

- Detect delta.reasoning alias before sanitizeStreamingChunk() which
  already normalizes it, removing dead post-sanitization normalization
- Replace injectedUsage reuse with separate needsReserialization flag
  so reasoning re-serialization cannot block finish_reason/usage
  mutations on the same SSE chunk (fixes CRITICAL review finding)
- Add unit test for parseSSEToOpenAIResponse reasoning alias
- Add unit test for buildStreamSummaryFromEvents reasoning alias

* fix(stream): separate reasoning from content in passthrough response body

The passthroughAccumulatedContent variable was mixing delta.content and
delta.reasoning_content into one string, causing the client_response
log and responseBody to lose reasoning separation.

- Add passthroughAccumulatedReasoning accumulator for reasoning deltas
- Set message.reasoning_content in responseBody when reasoning exists
- Only accumulate delta.content into passthroughAccumulatedContent

* fix: trim leading whitespace from assembled content in log summaries

NVIDIA and other providers emit token deltas with leading spaces
(e.g. ' The', ' user'). When joined, these produce a leading space in
the provider_response and parsed non-streaming response logs. Trim
the joined content and reasoning_content in both buildOpenAISummary
and parseSSEToOpenAIResponse for consistent log output.

* fix(stream): split combined reasoning+content deltas into separate SSE events

Some providers (e.g. NVIDIA NIM) send transition chunks with both
`delta.reasoning` and `delta.content` in the same SSE event.
After sanitization this becomes `reasoning_content` + `content`,
which violates the standard OpenAI streaming contract where these
fields are never mixed. Clients using if/else logic (LobeChat, etc.)
skip content when reasoning_content is present, losing the first
content token.

Split such combined chunks into two separate SSE events:
1. Reasoning-only event (finish_reason=null, no usage)
2. Content-only event (carries finish_reason and usage)
2026-03-29 16:12:22 -03:00
Paijo
7168f4014d fix: strip reasoning/thinking params for models that don't support them (#766)
Models like antigravity/claude-sonnet-4-6 route through Google's internal
Cloud Code API which returns HTTP 400 when thinking/reasoning parameters
are included in the request body.

Changes:
- open-sse/services/modelCapabilities.ts: add supportsReasoning() function
  with a denylist of known-unsupported patterns (antigravity/claude-sonnet-*)
  and a registry-based lookup hook (supportsReasoning flag per model)
- open-sse/services/thinkingBudget.ts: in applyThinkingBudget(), add early
  exit before the mode switch — if model string is present and
  supportsReasoning() returns false, call stripThinkingConfig() immediately
  regardless of the configured ThinkingMode

This is fully backward-compatible: models not in the denylist are unaffected,
and the supportsReasoning registry flag defaults to null (pass-through).

Fixes: HTTP 400 errors on antigravity provider when client sends requests
with thinking/reasoning budget parameters (e.g. claude-sonnet-4-6 via AG).

Co-authored-by: oyi77 <oyi77@github.com>
Co-authored-by: oyi77 <oyi77@users.noreply.github.com>
2026-03-29 16:12:19 -03:00
Paijo
f0912feefb feat: auto-disable permanently banned provider accounts (with Settings toggle) (#765)
* feat: auto-disable banned accounts setting with UI toggle

Add a configurable setting to automatically disable provider accounts
that return permanent/terminal errors (403 banned, ToS violation, etc.)

Changes:
- open-sse/services/accountFallback.ts: extend ACCOUNT_DEACTIVATED_SIGNALS
  with AG-specific ban messages ('verify your account', 'service disabled
  for violation')
- src/app/api/settings/auto-disable-accounts/route.ts: new GET/PUT endpoint
  for the setting (enabled bool + threshold int)
- src/shared/validation/schemas.ts: updateAutoDisableAccountsSchema
- src/sse/services/auth.ts: in markAccountUnavailable(), capture result.permanent
  from checkFallbackError() and — when autoDisableBannedAccounts is enabled and
  backoffLevel >= threshold — set isActive=false on the connection

Default: disabled (backward-compatible). Enable via Settings UI or PUT
/api/settings/auto-disable-accounts { "enabled": true, "threshold": 3 }

Fixes: antigravity accounts with 403/Verify-your-account errors being
retried indefinitely in the rotation pool.

Co-authored-by: oyi77 <oyi77@users.noreply.github.com>

* fix: address reviewer comments for auto-disable (use getCachedSettings, immediate disable on permanent bans)

---------

Co-authored-by: oyi77 <oyi77@github.com>
Co-authored-by: oyi77 <oyi77@users.noreply.github.com>
2026-03-29 16:12:17 -03:00
diegosouzapw
1d51d8ff27 chore(release): v3.2.9 — combo diagnostics, quality gates, Gemini tool fix 2026-03-29 14:16:37 -03:00
Randi
8af9bd1ac3 Force real upstream combo live tests (#759) 2026-03-29 13:21:53 -03:00
LASTHXH
9fc3845d92 Fix Gemini API error with integer enum in tool parameters (#760)
Gemini API returns 400 error when tools have enum constraints on integer/number types:
"enum: only allowed for STRING type"

This fix removes enum constraints for integer and number types in JSON schemas
before sending to Gemini API, while keeping enum for string types.

Fixes tools like mcp__pointer__get-pointed-element that use integer enums
for cssLevel and textDetail parameters.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 13:21:51 -03:00
Gorchakov-Pressure
93bbe8e7a8 feat(combo): response quality validation, circuit breaker fix, Cursor 4.6 models (#762)
- Add `validateResponseQuality()` to detect empty/invalid 200 responses from
  upstream providers in combo routing. Non-streaming responses with empty body,
  invalid JSON, or missing content/tool_calls now trigger circuit breaker
  failure and fallback to the next model instead of being returned to the client.

- Add missing `breaker._onSuccess()` calls in both priority and round-robin
  combo paths. Previously failures accumulated without reset, causing premature
  circuit breaker trips on healthy models.

- Update Cursor provider registry with Claude 4.6 model IDs (opus-high,
  sonnet-high, haiku, opus + thinking variants). Keep 4.5 IDs for backward
  compatibility.

- Update free-stack preset: replace duplicate qw/qwen3-coder-plus with
  if/deepseek-v3.2 for better model diversity.

- Add paid-premium combo template for round-robin load distribution across
  paid subscription providers (Cursor, Antigravity).

Made-with: Cursor
2026-03-29 13:21:48 -03:00
Diego Rodrigues de Sa e Souza
46acd16999 chore(release): v3.2.8 — Docker Auto-Update & Analytics Fixes (#755)
* chore(release): v3.2.8 — Docker auto-update UI and cache analytics fixes

* fix(sse): remove race condition in cache metrics tracking (#758)

- Remove in-memory metrics tracking (currentMetrics, trackCacheMetrics, updateCacheMetrics)
- Cache metrics now computed on-the-fly from usage_history table (single source of truth)
- Fixes CRITICAL issue from code review: concurrent requests overwriting metrics
- Fixes WARNING: duplicate metric tracking logic in streaming/non-streaming paths

Ref: PR #752 (merged before this fix was included)

* fix: handle allRateLimited credentials & forward extra body keys in embeddings/images routes (#757)

* fix: handle allRateLimited credentials in embeddings and images routes

When getProviderCredentials() returns an allRateLimited object (truthy,
but without apiKey/accessToken), the embeddings and images routes
incorrectly passed it to handlers as valid credentials. The handlers
then sent upstream requests without Authorization headers, causing
401 errors from providers (e.g. NVIDIA NIM).

This only manifested under concurrent requests: a chat/completions
call could trigger rate limiting on a provider account, and a
simultaneous embeddings request would receive the allRateLimited
sentinel — but treat it as valid credentials.

The chat pipeline already handled this case correctly. This commit
adds the same allRateLimited guard to all affected routes:
- POST /v1/embeddings
- POST /v1/providers/{provider}/embeddings
- POST /v1/images/generations
- POST /v1/providers/{provider}/images/generations

Also adds a defense-in-depth guard in the embeddings handler itself:
if no auth token is available for a non-local provider, return 401
immediately instead of sending an unauthenticated request upstream.

Made-with: Cursor

* fix(embeddings): forward extra body keys to upstream providers

The embeddings handler only forwarded model, input, dimensions, and
encoding_format to upstream providers, silently dropping any additional
fields. This broke asymmetric embedding APIs (e.g. NVIDIA NIM
nv-embedqa-e5-v5) that require input_type, and other providers
expecting user or truncate parameters.

Add a KNOWN_FIELDS exclusion set and forward all unrecognized body
keys to the upstream request, matching the passthrough pattern used
by the chat pipeline's DefaultExecutor.transformRequest().

Made-with: Cursor

* fix(auth): redirect and unconditional 401 on disabled requireLogin + fix test cases

* fix(build): remove legacy proxy.ts causing Next.js build collision

* fix(build): revert middleware.ts rename to proxy.ts because of Next.js Edge constraints

---------

Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
Co-authored-by: tombii <tombii@users.noreply.github.com>
Co-authored-by: Gorchakov-Pressure <117600961+Gorchakov-Pressure@users.noreply.github.com>
2026-03-29 13:09:38 -03:00
Diego Rodrigues de Sa e Souza
d5781d60bd Merge pull request #752 from tombii/feat/preserve-client-cache-control
feat: preserve client cache_control with deterministic routing + metrics dashboard
2026-03-29 11:23:22 -03:00
Diego Rodrigues de Sa e Souza
e464a95c5a Merge pull request #747 from AveryanAlex/fix/responses-chat-translation-bugs
Improve responses<->chat translation
2026-03-29 11:23:19 -03:00
Diego Rodrigues de Sa e Souza
a50ea4bb9e Merge pull request #746 from AveryanAlex/fix/codex-passthrough-store-instructions
fix: ensure Codex passthrough path sets instructions and store=false
2026-03-29 11:23:05 -03:00
tombii
26f7b36ce4 feat: add cache control settings and token-based metrics
Settings:
- Add `alwaysPreserveClientCache` setting with modes: auto/always/never
- UI toggle in Dashboard > Settings > Routing tab
- Auto mode preserves cache_control for Claude Code clients with deterministic routing

Metrics:
- Track prompt cache token usage (input, cached, creation)
- Display cache reuse ratio (cached/input tokens)
- Breakdown by provider and routing strategy
- Shows tokens saved and estimated cost savings

API Endpoints:
- GET /api/settings/cache-metrics - retrieve metrics
- DELETE /api/settings/cache-metrics - reset metrics

Files:
- open-sse/utils/cacheControlPolicy.ts: CacheControlMetrics interface, trackCacheMetrics, updateCacheTokenMetrics
- open-sse/handlers/chatCore.ts: Track cache tokens from provider responses
- src/lib/db/settings.ts: Database functions for metrics persistence
- src/lib/cacheControlSettings.ts: Cached settings accessor
- src/app/(dashboard)/dashboard/settings/components/CacheStatsCard.tsx: Metrics dashboard UI
- tests/unit/*.test.mjs: Unit tests (41 tests pass)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 14:37:55 +02:00
tombii
0bc557fb8b feat(sse): preserve client cache_control for Claude Code with deterministic routing
Adds intelligent cache control preservation for Claude Code clients:

- New cacheControlPolicy.ts module with detection logic:
  - isClaudeCodeClient(): Detects Claude Code via User-Agent
  - providerSupportsCaching(): Checks provider (claude, anthropic, zai, qwen)
  - isDeterministicStrategy(): Identifies priority/cost-optimized strategies
  - shouldPreserveCacheControl(): Main policy decision

- Cache control is preserved when:
  1. Client is Claude Code (detected via User-Agent)
  2. Provider supports prompt caching
  3. Request routing is deterministic:
     - Single model requests (always)
     - Combo with priority or cost-optimized strategy only

- Updated translator to accept preserveCacheControl option
- Updated chatCore and chat handler to propagate combo strategy
- Added comprehensive unit tests (24 tests)

Non-deterministic combo strategies (weighted, round-robin, random, etc.)
continue to use OmniRoute's managed caching strategy.

Refs: #cache-control-preservation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 12:24:44 +02:00
Randi
7690b364e7 fix detailed log summaries for streamed responses (#734) 2026-03-29 04:30:03 -03:00
Otto G
b94c0c7d04 fix(sse): use x-api-key for opencode-go minimax messages requests (#733)
OpenCode Go mixes request protocols by model family:

   - `glm-5` and `kimi-k2.5` use OpenAI-style `/chat/completions`
   - `minimax-m2.5` and `minimax-m2.7` use Anthropic-style `/messages`

   OmniRoute already routed MiniMax Go models to `/messages`, but the
   executor still sent `Authorization: Bearer ...`, which caused upstream
   `401 Missing API key` errors.

   This changes `OpencodeExecutor` to send:
   - `x-api-key` + `anthropic-version` for Claude-targeted OpenCode Go requests
   - `Authorization: Bearer ...` for the remaining OpenCode Go request formats

   Also updates unit coverage to assert the correct header behavior for
   MiniMax Go models.

   Validated with:
   - direct curl repro against OpenCode Go endpoints
   - `node --import tsx/esm --test tests/unit/opencode-executor.test.mjs`
   - `npm run typecheck:core`
   - `npm run build`
2026-03-29 04:29:59 -03:00
Diego Rodrigues de Sa e Souza
f11ec4e142 Merge pull request #731 from oyi77/fix/tool-call-invalid-argument-400
fix(translator): remove thoughtSignature from functionCall parts in all Gemini translators
2026-03-28 23:43:34 -03:00
diegosouzapw
a5393a3ec4 feat: migrate iFlow provider to Qoder AI (#660) 2026-03-28 23:35:59 -03:00
diegosouzapw
b9c7fd879f fix(core): resolve routing schemas, CLI streaming leaks, and thinking tag extraction 2026-03-28 23:11:22 -03:00
oyi77
c5003665c3 fix(translator): remove thoughtSignature from functionCall parts in all Gemini translators
HTTP 400 "invalid argument" was triggered when OmniRoute translated tool calls
to Gemini format, because thoughtSignature was injected onto every functionCall
part unconditionally. Affects two code paths:

1. openai-to-gemini.ts — OpenAI tool_calls → Gemini functionCall
2. claude-to-gemini.ts — Claude tool_use blocks → Gemini functionCall

thoughtSignature is only valid on thinking/reasoning parts (those with
thought: true or thoughtSignature as their primary field). When present on a
functionCall part, the Gemini API returns HTTP 400 'invalid argument'.

The thinking parts that legitimately carry thoughtSignature (emitted when a
message has reasoning_content / thinking blocks) are untouched.

Regression tests (T43) cover:
- single tool call: no thoughtSignature on functionCall part (openai path)
- multiple tool calls: none carry thoughtSignature (openai path)
- thinking regression guard: thoughtSignature still on thought parts
- claude-to-gemini path: tool_use blocks produce clean functionCall parts

Fixes #724
2026-03-29 08:48:58 +07:00
R.D.
04de492019 fix: add four-stage request log payloads 2026-03-28 22:09:27 -03:00
diegosouzapw
b6bbfe063b fix(sse): preserve cache_control in Claude passthrough mode (#708) 2026-03-28 22:01:38 -03:00
oyi77
48182edbd5 fix(translator): remove thoughtSignature from functionCall parts in Gemini translation
HTTP 400 "invalid argument" was triggered when OmniRoute translated OpenAI
tool_calls to Gemini format, because thoughtSignature was injected onto every
functionCall part unconditionally.

thoughtSignature is only valid on thinking/reasoning parts (those with
thought: true). The Gemini API rejects any request where a functionCall
part carries a thoughtSignature field, returning HTTP 400.

Fix: remove the thoughtSignature field from functionCall parts. The thinking
parts that legitimately require thoughtSignature (emitted when a message has
reasoning_content) are unchanged.

Adds regression test (T43) with three cases:
- single tool call: no thoughtSignature on functionCall part
- multiple tool calls: none carry thoughtSignature
- thinking part regression guard: thoughtSignature still present on thought parts

Fixes #725
2026-03-28 21:57:15 -03:00