Commit Graph

3966 Commits

Author SHA1 Message Date
terence71-glitch
e2ad12d090 fix(proxy): show registry provider proxies in dashboard (#2963)
Integrated into release/v3.8.8
2026-05-30 22:14:53 -03:00
diegosouzapw
4536aabe23 Merge PR 2959 into release/v3.8.8 2026-05-30 22:02:49 -03:00
diegosouzapw
ff255c4582 Merge PR 2958 into release/v3.8.8 2026-05-30 22:02:09 -03:00
diegosouzapw
c90bed0043 Merge PR 2957 into release/v3.8.8 2026-05-30 22:01:07 -03:00
diegosouzapw
fa4bd6c68c Merge PR 2951 into release/v3.8.8 2026-05-30 22:01:04 -03:00
diegosouzapw
4e51bc686c Merge PR 2946 into release/v3.8.8 2026-05-30 22:00:41 -03:00
diegosouzapw
1a9b2bfd85 Merge PR 2943 into release/v3.8.8 2026-05-30 22:00:38 -03:00
diegosouzapw
266c145ee4 Merge PR 2940 into release/v3.8.8 2026-05-30 22:00:34 -03:00
diegosouzapw
8dafe78d79 Merge PR 2938 into release/v3.8.8 2026-05-30 22:00:31 -03:00
diegosouzapw
606b7092b6 Merge PR 2937 into release/v3.8.8 2026-05-30 22:00:29 -03:00
diegosouzapw
cf3600de11 Merge PR 2931 into release/v3.8.8 2026-05-30 22:00:20 -03:00
diegosouzapw
856603ecb7 Merge PR 2927 into release/v3.8.8 2026-05-30 21:59:50 -03:00
Raxxoor
3dd4a3b6f8 fix(antigravity): avoid visible signatureless tool history (#2927)
Integrated into release/v3.8.8
2026-05-30 21:59:20 -03:00
diegosouzapw
ba340f18a5 Merge branch 'fix/nextcloud-json-stream-default' into release/v3.8.8 2026-05-30 21:19:50 -03:00
diegosouzapw
e7870132db Merge release/v3.8.8 2026-05-30 21:19:17 -03:00
Diego Rodrigues de Sa e Souza
697946381d fix(auth): prevent Codex multi-account refresh_token family revocation (#2941)
Integrated into release/v3.8.8
2026-05-30 21:18:33 -03:00
Diego Rodrigues de Sa e Souza
2fb5979118 fix(dashboard): v3.8.8 screen fixes — agent-bridge SSR + audit/logs/memory/playground (#2944)
Integrated into release/v3.8.8
2026-05-30 21:18:25 -03:00
Paijo
7a0e803c01 feat: add Qwen Web (chat.qwen.ai) cookie provider (#2947)
Integrated into release/v3.8.8
2026-05-30 21:18:16 -03:00
terence71-glitch
52503064a8 fix(skills): avoid Claude assistant tool_result blocks (#2956)
Integrated into release/v3.8.8
2026-05-30 21:18:08 -03:00
terence71-glitch
187bc509bb fix(sse): bypass web-search fallback on Claude -> Claude passthrough (#2960)
Integrated into release/v3.8.8
2026-05-30 21:17:52 -03:00
Brandon Bennett
8dff29c760 docs: update CHANGELOG and MCP-SERVER.md for scope fix and Notion context source 2026-05-30 19:33:50 -04:00
Brandon Bennett
58eb093a2e docs: update CHANGELOG and MCP-SERVER.md for scope fix and Notion context source 2026-05-30 19:33:49 -04:00
Brandon Bennett
8cd77b0f49 feat(notion): add Notion MCP context source with 6 tools, dashboard tab, and 20 tests 2026-05-30 19:11:58 -04:00
Brandon Bennett
0c9345f75e fix: move enforceScopes guard before MCP_TOOL_MAP lookup, add scopes to all dynamic tool definitions
- Move !enforceScopes guard before MCP_TOOL_MAP lookup in evaluateToolScopes()
- Add inlineScopes parameter for dynamic tool scope resolution
- Add scopes to all 33 dynamic tool definitions across 5 tool files
- Wire toolDef.scopes through withScopeEnforcement in server.ts
- Preserves existing behavior: tool_definition_missing returned when
  enforceScopes=true and no scopes found anywhere
2026-05-30 19:11:52 -04:00
ReqX
ff7a9069f0 fix(routing): add agy to executor map so it uses AntigravityExecutor
The agy provider was registered in providerRegistry.ts with
executor: "antigravity" but the executor map in executors/index.ts
only had an "antigravity" entry. getExecutor("agy") fell through to
DefaultExecutor, which returned undefined for baseUrl (agy only has
baseUrls), causing fetch(undefined) → TypeError: Cannot read properties
of undefined (reading 'toString').

Closes diegosouzapw/OmniRoute#2932
2026-05-30 22:01:00 +00:00
soyelmismo
a91f352fde test: add unit tests for CPU leak fixes and registry changes
5 new test files covering all 13 changed production files:
- estimateSizeFast.test.ts: 16 tests for fast size estimator (circular ref
  protection, early exit, nested structures, Map safety)
- eviction-guards-apiKeyRotator.test.ts: 5 tests for Map eviction guards
  (!has() check prevents evicting existing keys on update)
- eviction-guards-codexQuotaFetcher.test.ts: 4 tests for connectionRegistry
  and quotaCache eviction guards
- rateLimitManager-idle-eviction.test.ts: 6 tests for idle limiter cleanup,
  limiterLastUsed tracking, and shutdown behavior
- registry-direct-exports.test.ts: 20 tests verifying all 8 registries export
  plain objects (no Proxy traps, no lazy getters, mutable entries)

Extract estimateSizeFast/isSmallEnoughForSemanticCache into standalone
open-sse/utils/estimateSize.ts to make them testable without importing
the entire chatCore.ts dependency tree.
2026-05-30 14:02:27 -05:00
soyelmismo
6cdf69e077 fix: address Kilo Code review feedback on PR #2951
- estimateSizeFast: add WeakSet cycle detection to prevent infinite
  loop on circular object references
- trace(): wrap JSON.stringify(extra) in try-catch to handle BigInt,
  circular refs, or other non-serializable values gracefully
- Registry API change (Comment 3): verified all callers already use
  new getter functions — no broken call sites
2026-05-30 13:34:57 -05:00
soyelmismo
b4c0ce6519 fix: address Gemini Code Review feedback on PR #2951
- Add !has(key) guard before eviction to avoid evicting entries
  that are about to be updated (combo.ts, apiKeyRotator.ts,
  codexQuotaFetcher.ts)
- Use optional chaining for provider?.toUpperCase() null safety
- Replace Object.values() with for-in in estimateSizeFast hot path
2026-05-30 13:03:02 -05:00
Jan Leon
664a606bfb fix(dashboard/api-manager): scroll to key name error in create modal 2026-05-30 18:54:26 +02:00
Jan Leon
99d673fe5b feat(stream): add per-key JSON stream default mode 2026-05-30 18:33:47 +02:00
oyi77
d698e957fb fix: combo credential resolution ignores target.providerId — prefer combo target's providerId over model-inferred provider
Root cause: model string provider prefix (e.g. "xiaomi" from
"xiaomi/mimo-v2-flash") differs from the credential DB provider ID
(e.g. "opengate") when a combo target has a custom providerId. The
pre-selection and execution flows both looked up credentials using the
model-inferred provider, which didn't match any DB entry.

Fix A (chat.ts): checkModelAvailable now uses target.providerId when
available, falling back to modelInfo.provider.

Fix B (chat.ts): handleSingleModelChat now accepts runtimeOptions.providerId
and preferentially uses it for credential lookup instead of re-resolving
the provider from the model string.

Fix C (model.ts): add "xiaomi" alias for "xiaomi-mimo" so direct
(non-combo) model requests to xiaomi/mimo-* also resolve correctly.
2026-05-30 22:21:29 +07:00
NomenAK
dd6104ea38 test(cliproxyapi): update executor test for the broadened tool-name cloak
The CPA executor now cloaks non-Claude-Code tool names (not just mcp_*), so the
prior "does not rewrite non-mcp_ tool names" assertion no longer holds:
my_tool is aliased to MyTool and restored on the response via _toolNameMap.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 15:00:01 +00:00
NomenAK
a1e0bc7469 fix(claude): harden tool cloak + schema sanitizer (adversarial review round)
Addresses confirmed findings from an adversarial review of the prior commits:

- schema sanitizer: a truncation placeholder in a SCALAR annotation keyword
  (description/title/pattern/format) was coerced to {}, which is itself invalid
  draft-2020-12 and re-triggered the exact "input_schema is invalid" 400 the
  sanitizer exists to prevent. Placeholders are now only coerced to {} in
  subschema-expecting positions; scalar keywords are left untouched.
- schema sanitizer: numeric-string coercion is folded into
  stripInvalidSchemaConstructs so it also covers contains / propertyNames /
  additionalItems (which coerceSchemaNumericFields never visited).
- schema sanitizer: stop stripping the valid `default` keyword on the Claude
  native/passthrough surface (the #1782 default-strip is a translator concern;
  tool schemas here were previously forwarded verbatim). sanitizeClaudeToolSchema
  is now a single stripInvalidSchemaConstructs pass.
- tool-name cloak: consult TOOL_RENAME_MAP / EXTRA_TOOL_RENAME_MAP before the
  generic PascalCase fallback, so the CLIProxyAPI path uses the established
  fingerprint-evasion aliases (subagents->SubDispatch, session_status->CheckStatus,
  webfetch->WebFetch, ...) identically to the native path instead of weaker
  first-letter casing.
- kill-switch: CLAUDE_DISABLE_TOOL_NAME_CLOAK is now honoured inside
  cloakThirdPartyToolNames, so BOTH the native and CLIProxyAPI executor paths
  respect it (previously only base.ts did); .env.example + ENVIRONMENT.md updated.

Regression tests added for each. Verified end-to-end through the live CPA path:
mixture_of_agents, subagents, and a tool carrying placeholder descriptions and
`default` values all return 200 with original names restored on the response.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 14:35:53 +00:00
Jan Leon
31a734966c test(reasoning-cache): authenticate reasoning cache API route requests 2026-05-30 16:19:12 +02:00
Jan Leon
ce039778da test(chatcore): avoid pending metadata race in upstream timeout test 2026-05-30 16:13:30 +02:00
Jan Leon
27e56f6bb2 test(chatcore): wait longer for upstream timeout metadata 2026-05-30 16:07:53 +02:00
NomenAK
23dad7d93d fix(claude): apply tool cloak + schema sanitize on the CLIProxyAPI executor path
The native Claude OAuth guard in executors/base.ts is bypassed when
`upstream_proxy_config.mode = cliproxyapi` routes the request through the
CliproxyAPI executor — it has its own execute()/transformRequest() and never
reaches BaseExecutor.execute(), so the cloak/sanitizer never ran for that
(common) deployment. Wire the same guards into
CliproxyapiExecutor.transformRequest (Anthropic-shape branch), composing with
the existing bisected `mcp_*` reserved-namespace rewrite:

- sanitizeClaudeToolSchemas() on transformed.tools.
- cloakThirdPartyToolNames() with skip = mcp-reserved, so applyMcpToolNameRewrite
  keeps authority over `mcp_*` (its bisected `Mcp_X` form) and the two reverse
  maps stay disjoint / single-hop. Both merge into the non-enumerable
  _toolNameMap the response stream already uses to restore the caller's names.

cloakThirdPartyToolNames is now non-mutating (clones changed entries) to respect
transformRequest's no-input-mutation contract, and takes an optional `skip`
predicate.

Verified end-to-end through the live CPA path: a real ~100-tool harness payload
that returned the "out of extra usage" placeholder now returns 200 with original
tool names restored on the response stream; `mcp_*` tools and genuine PascalCase
Claude Code tools are unaffected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 13:59:36 +00:00
Jan Leon
57aff12781 fix(stream): default Nextcloud integration to JSON 2026-05-30 15:59:23 +02:00
NomenAK
3b2d075402 fix(claude): address tool-cloak PR review — preserve boolean schemas, null-guards, docs
Follow-up commit on PR #2943 review:

- Preserve boolean schemas in `sanitizeClaudeToolSchemas` (Gemini Code Assist,
  high severity). `additionalProperties: false` is the canonical JSON Schema
  lock-down for object tools; the previous coercion silently turned it into the
  permissive `{}`, which would invite models to hallucinate extra arguments
  during tool calling. Same rule now applies to per-property boolean schemas
  under `properties`. Placeholder strings still get the permissive `{}` slot —
  booleans get preserved verbatim.

- Defensive null guards in `cloakThirdPartyToolNames` for `tools[]` and
  `messages[]` entries that might be `null`/`undefined`. Prevents a runtime
  `TypeError` if a malformed payload reaches the cloak.

- Document `CLAUDE_DISABLE_TOOL_NAME_CLOAK` in `.env.example` and
  `docs/reference/ENVIRONMENT.md` (env/docs contract was failing in CI).

- Regression tests covering all of the above (5 boolean preservation cases,
  2 null-tolerance cases).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 13:30:04 +00:00
diegosouzapw
468354f8ff clean 2026-05-30 10:06:02 -03:00
soyelmismo
31e11aa8d8 perf: extract optimizations from perf/cpu-optimization-chat-completions
Extract 3 high-value CPU/RAM optimizations from perf branch:

1. estimateSizeFast() — fast object-tree size estimator replacing
   JSON.stringify().length in isSmallEnoughForSemanticCache(). Walks
   object tree with a stack, zero string allocation, early exit at 256KB.

2. Consolidate settings reads — move getCachedSettings() to a single
   early read in handleChatCore(), eliminating a redundant second read
   200 lines later. Also removes the isDetailedLoggingEnabled() wrapper
   call (reads settings internally) in favor of direct field check.

3. Registry Proxy→direct export — convert 8 registries from lazy
   Proxy+getOrCreate pattern to simple exported const objects. Eliminates
   Proxy trap overhead on every provider property access during routing.
   Affected: audio, embedding, image, moderation, music, rerank, search,
   video registries (-451 lines of Proxy boilerplate).

These changes are independent of the CPU leak fix (limiter eviction)
and complement it by reducing per-request CPU overhead.
2026-05-30 07:59:04 -05:00
NomenAK
7e7faad079 fix(claude): sanitize tool schemas + cloak third-party tool names on native Claude OAuth
Native Claude OAuth (claude->claude passthrough) forwards client tool
definitions verbatim. Anthropic's first-party Messages API then rejects:
  - invalid tool input_schemas (deep-truncation placeholders such as
    `enum: "[MaxDepth]"`, or index-keyed objects where arrays are required), and
  - tool names it fingerprints as a third-party agent harness (specific
    blacklisted names like `mixture_of_agents`, or a large enough set of
    recognizable snake_case agent tool names),
both surfaced as a misleading `400 You're out of extra usage` placeholder
(the SSE stream is refused — not a real billing event). The same request
succeeds on translator-backed providers (OpenAI/Codex), which already sanitize
and re-shape tool payloads — so the gap is specific to the native passthrough.

Adds the missing guards on the native Claude OAuth path (executors/base.ts):
  - sanitizeClaudeToolSchemas(): coerce/drop invalid draft-2020-12 constructs
    (non-array enum/required/anyOf/..., placeholder schema slots -> {}).
  - cloakThirdPartyToolNames(): deterministically alias non-Claude-Code tool
    names (Claude Code canonical mapping where one exists, else PascalCase),
    tracked in the existing per-request _toolNameMap so remapToolNamesInResponse
    restores the caller's original names. Opt out via
    CLAUDE_DISABLE_TOOL_NAME_CLOAK=true.

Genuine Claude Code tool names (PascalCase) and already-valid schemas are
left untouched, so existing first-party traffic is unaffected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 12:56:35 +00:00
soyelmismo
c6f17d8e78 fix: resolve CPU leak from Bottleneck limiter accumulation and unbounded in-memory caches
Root cause: Bottleneck rate limiter instances in rateLimitManager accumulate
without cleanup. Each instance runs an internal heartbeat setInterval every
250ms. Under heavy load with many provider:connection:model combinations,
hundreds of limiters accumulate causing CPU to grow ~0.1%/min until server
collapse (~2% after 5 minutes of intensive use).

Changes:
- rateLimitManager: Add idle limiter eviction in watchdogTick() using the
  previously defined but unused INACTIVE_LIMITER_MS threshold. Populate
  limiterLastUsed on every getLimiter() call. Clean up all 3 Maps
  (limiters, lastDispatchAt, limiterLastUsed) consistently.
- combo.ts: Add size-based FIFO eviction to rrCounters, resetAwareConnectionCache,
  and resetAwareQuotaCache Maps. Convert per-target log.info calls in combo
  execution loops to log.debug?. to reduce serialization overhead.
- chatCore.ts: Fix double-serialization in estimateTokens(JSON.stringify(x))
  calls (estimateTokens already handles objects). Make trace() conditional
  on OMNIRROUTE_TRACE/DEBUG env vars. Make per-request usage logging conditional.
- apiKeyRotator.ts: Add eviction guards to _keyHealth and _connectionExtraKeys
  Maps (MAX 500 entries each). Ensure removeConnectionIndex cleans all 3 Maps.
- codexQuotaFetcher.ts: Add eviction guard to connectionRegistry and quotaCache
  Maps (MAX 200 entries each).
2026-05-30 07:28:16 -05:00
diegosouzapw
37890ba007 chore: remove audit logs tab from logs page
Remove the AuditLogTab from the dashboard logs page now that audit logs
live under the dedicated /dashboard/audit route. Update integration wiring
expectations and add metadata frontmatter to studio framework docs.
2026-05-30 09:11:17 -03:00
edutvlanka
7ffc56b7e0 fix combo vision and codex tool history 2026-05-30 16:29:36 +05:30
Maxim Ivanov
d25e32326d fix: scope JSON-string cleanup to Read tool
Keep existing object-argument cleanup behavior, but avoid parsing and stripping arbitrary JSON-string arguments for unrelated tools where empty strings or arrays may be valid payloads. Add regression coverage for non-Read and non-object Read arguments.
2026-05-30 10:24:18 +00:00
Maxim Ivanov
2b99d7ba7f fix: gate Claude WebSearch native mapping by target format
Only translate Claude Code web_search_YYYYMMDD server tools to native Responses web_search when the final target is OpenAI Responses. Keep the Chat Completions target on function-tool shape and cover the full translateRequest path.
2026-05-30 10:23:38 +00:00
Maxim Ivanov
a7330b4fb1 fix: harden Claude WebSearch tool parsing 2026-05-30 08:58:15 +00:00
Maxim Ivanov
3767e130ea fix: preserve falsy tool argument values 2026-05-30 08:58:13 +00:00
Maxim Ivanov
5600dcd2d2 fix(claude): map WebSearch to Responses web_search
Translate Claude Code web_search_YYYYMMDD server tools to the native OpenAI Responses web_search tool and preserve filters/location. Convert forced Claude tool_choice for web_search to the native Responses tool choice while leaving ordinary custom functions unchanged.

Closes #2936
2026-05-30 08:51:04 +00:00