Commit Graph

92 Commits

Author SHA1 Message Date
Juan Camilo
858f06d964 fix: strip Anthropic-specific params from 3P provider paths
Three silent failure modes affecting all third-party provider users:

1. Thinking blocks serialized as <thinking> text corrupt multi-turn
   context — strip them instead of converting to raw text tags.

2. Unknown models fall through to 200k context window default, so
   auto-compact never triggers — use conservative 8k for unknown
   3P models with a warning log.

3. Session resume with thinking blocks causes 400 or context corruption
   on 3P providers — strip thinking/redacted_thinking content blocks
   from deserialized messages when resuming against a non-Anthropic
   provider.

Addresses findings 2, 3, and 5 from #248.
2026-04-07 15:02:13 +02:00
ibaaaaal
600c01faf7 fix: restore Grep and Glob reliability on OpenAI paths (#461)
* fix: restore Grep and Glob reliability on OpenAI paths

Preserve Grep and Glob pattern fields during OpenAI/Codex schema sanitization, and fall back to system ripgrep when the packaged binary is missing. This keeps search tool schemas intact and improves Linux usability for npm/source installs.

Co-Authored-By: Claude Opus 4.6 <noreply@openclaude.dev>

* test: clean up ripgrep fallback test helpers

Remove the unused ripgrepCommand import and normalize mocked builtin ripgrep paths so the test behaves consistently across platforms.

Co-Authored-By: Claude Opus 4.6 <noreply@openclaude.dev>

* test: remove duplicate Codex URI schema case

Drop the duplicated WebFetch URI-format test in codexShim.test.ts so test names stay unique and failures remain easier to read.

Co-Authored-By: Claude Opus 4.6 <noreply@openclaude.dev>

* test: stabilize ripgrep fallback coverage

Avoid fs/module mocking in ripgrep fallback tests by extracting the config selection logic into a pure helper. This preserves the fallback coverage while removing the test interaction that caused the narrowed Bun hang repro.

Co-Authored-By: Claude Opus 4.6 <noreply@openclaude.dev>

* test: tighten ripgrep and schema coverage

Align the ripgrep fallback test with the actual auto-fallback branch, clean up strict typing in schema sanitizer tests, and tighten ripgrep error narrowing for type safety.

Co-Authored-By: Claude Opus 4.6 <noreply@openclaude.dev>

---------

Co-authored-by: Claude Opus 4.6 <noreply@openclaude.dev>
2026-04-07 17:26:00 +08:00
Vasanth T
e365cb4010 fix: address code scanning alerts (#434)
* fix: address code scanning alerts

Parse Gemini hostnames instead of matching raw URL substrings, redact gRPC error logs, and harden the Finder drag-drop test escape helper so the flagged paths are fixed without regressing working behavior.

* Potential fix for pull request finding 'CodeQL / Clear-text logging of sensitive information'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* fix: restore safe grpc error summaries

A later autofix commit removed the exported gRPC error summarizer while the new regression test still imported it. Restore the safe name/code-only summary so CI stays green without reintroducing clear-text logging.

* fix: keep grpc logging generic

Remove the stale helper/test pair and keep the gRPC startup and stream logs free of error-derived data so the CodeQL clear-text logging alert stays closed while the rest of the security fixes remain intact.

---------

Co-authored-by: OpenClaude Worker 3 <worker-3@openclaude.local>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-04-07 00:43:09 +08:00
KRATOS
b4bd95b477 fix: normalize malformed Bash tool arguments from OpenAI-compatible providers (#385)
* fix: normalize malformed Bash tool arguments from OpenAI-compatible providers

* fix: keep invalid Bash tool args from becoming commands

* fix: preserve malformed Bash JSON literals

* test: stabilize rebased PR 385 checks

* test: isolate provider profile env assertions

* fix: extend tool argument normalization to all tools and harden edge cases

- Extend STRING_ARGUMENT_TOOL_FIELDS to normalize Read, Write, Edit,
  Glob, and Grep plain-string arguments (fixes "Invalid tool parameters"
  errors reported by VennDev)
- Normalize streaming Bash args regardless of finish_reason, not only
  when finish_reason is 'tool_calls'
- Broaden isLikelyStructuredObjectLiteral to catch malformed object-shaped
  strings like {command:"pwd"} and {'command':'pwd'} (fixes CR2 from
  Vasanthdev2004)
- Apply blank/object-literal guard to all tools, not just Bash
- Extract duplicated JSON repair suffix combinations into shared constant
- Add 32 isolated unit tests for toolArgumentNormalization

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: skip streaming normalization on finish_reason length

Truncated tool calls (finish_reason: 'length') now preserve the raw
buffer instead of normalizing into executable commands, preventing
incomplete commands from becoming runnable.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: comprehensive tool argument normalization hardening

- Remove all { raw: ... } returns that caused InputValidationError with
  z.strictObject schemas — return {} instead for clean Zod errors
- Extend normalizeAtStop buffering to all mapped tools (Read, Write,
  Edit, Glob, Grep) so streaming paths also get normalized
- Make repairPossiblyTruncatedObjectJson generic — repair any valid
  JSON object, not just ones with a command field
- Export hasToolFieldMapping for streaming normalizeAtStop decision
- Skip normalization on finish_reason: length to preserve raw truncated
  buffer
- Update all test expectations to match new behavior

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 22:08:45 +08:00
Otávio Carvalho
1e057025d6 Fix GLM-5 and other reasoning models appearing to hang via OpenAI shim (#365)
* Fix GLM-5 and other reasoning models appearing to hang via OpenAI shim

Reasoning models like GLM-5 and DeepSeek stream chain-of-thought in
`reasoning_content` while `content` stays empty (""). The OpenAI shim
only read `delta.content`, so it saw empty strings and never emitted
any Anthropic stream events — causing the UI to appear frozen.

- Add `reasoning_content` to streaming chunk and non-streaming response types
- Emit `reasoning_content` as thinking blocks (thinking_delta) in streaming mode
- Properly transition from thinking to text blocks when content phase begins
- Fall back to `reasoning_content` in non-streaming mode when content is null

Fixes #214

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix non-streaming reasoning_content fallback and add tests

- Use explicit empty-string check instead of || for content fallback
  so content: "" doesn't leak reasoning_content as visible text
- Close thinking block before tool call blocks in streaming path
- Add non-streaming and streaming reasoning_content tests

Co-Authored-By: GLM-5.1 <noreply@openclaude.dev>

* Fix flaky Ink reconciler tests caused by react-compiler memoization

Remove hard throw in createTextInstance that crashed when hostContext.isInsideText
was stale due to react-compiler element caching. Add timeout guards to prevent
test hangs when render errors prevent exit() from firing.

Co-Authored-By: Claude GLM-5.1 <noreply@openclaude.dev>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: GLM-5.1 <noreply@openclaude.dev>
2026-04-06 22:02:29 +08:00
hsain9357
72e6a945fe Fixed gemini error Function call is missing a thought_signature in functionCall parts (#426)
* docs(docs): add agent guidance and repository instructions

- Created `AGENTS.md` and `CLAUDE.md` to provide high-signal guidance for AI agents and developers working in the repository.
- Outlined critical developer commands for building, testing, and running diagnostics using `bun`.
- Documented the repository architecture, source entrypoints, and core service logic.
- Defined framework-specific quirks, including module stubbing for internal modules and macro versioning.
- Established style and workflow guidelines regarding telemetry, environment variables, and security scan requirements.

* feat(api): support gemini thought signatures in openai shim

- Added `isGeminiMode` utility to detect Gemini backends via `CLAUDE_CODE_USE_GEMINI` or `OPENAI_BASE_URL`.
- Updated `convertMessages` to extract `thought_signature` from thinking blocks and inject them into tool calls.
- Implemented a fallback mechanism that provides a `skip_thought_signature_validator` string to avoid 400 validation errors when a signature is missing.
- Enhanced `openaiStreamToAnthropic` and `OpenAIShimMessages` to correctly preserve and pass through Gemini-specific metadata in `extra_content`.

* refactor(api): improve gemini metadata handling and remove redundant docs

- Updated `src/services/api/openaiShim.ts` to merge existing `google`-specific metadata within `extra_content` instead of overwriting it.
- Simplified the `thought_signature` assignment logic to use a fallback value of `skip_thought_signature_validator` when no signature is provided.
- Deleted `AGENTS.md` and `CLAUDE.md` files to eliminate redundant agent guidance documentation.

* fix(api): propagate gemini thought signatures to all parallel tool calls

- Removed the index constraint when assigning the `signature` from a `thinkingBlock` to tool calls in `openaiShim.ts`.
- Ensured that the `thought_signature` is applied to every tool call in a parallel set, rather than just the first one.
- Aligned the shim with Gemini API requirements, which mandate that the same signature must be present on every replayed function call part within an assistant turn.
2026-04-06 21:04:49 +08:00
Juan Camilo Auriti
d5852ca73d fix: coalesce consecutive same-role messages for strict template models (#241)
Models served through Ollama/vLLM with strict Jinja templates (Devstral,
Mistral, etc.) require strict user↔assistant role alternation and reject
requests with consecutive messages of the same role.

convertMessages() could produce consecutive user or assistant messages in
three scenarios: batched user input, text-only + tool_use assistant turns,
and tool result remainders followed by another user message.

Added a coalescing pass at the end of convertMessages() that merges
consecutive same-role messages (string concat or array concat), preserving
tool_calls on assistant messages. Tool and system messages are excluded
from coalescing as they have their own alternation rules.

Includes regression tests for both user and assistant coalescing.

Fixes #202
2026-04-06 06:47:11 +08:00
Technomancer702
c534aa5771 Feature: Add local OpenAI-compatible model discovery to /model (#201)
* Add local OpenAI-compatible model discovery to /model

* Guard local OpenAI model discovery from Codex routing

* Preserve remote OpenAI Codex alias behavior
2026-04-06 06:46:06 +08:00
CRABHIVE
4ac7367733 fix: include retry timing in 429 error messages (#366)
## Summary

- Extract retry-after header from 429 API errors and include timing
  guidance in the user-facing error message
- Previously, non-quota 429 errors showed a generic message with no
  guidance on when to retry, only a link to status.anthropic.com

## Impact

- user-facing impact: 429 error messages now tell users when to retry
  instead of just linking to a status page
- developer/maintainer impact: none

## Testing

- [x] `bun run build`
- [ ] `bun run smoke`
- [ ] focused tests: error formatting is pure string construction,
  verified via build + manual inspection

## Notes

- provider/model path tested: applies to all providers returning 429
- screenshots attached (if UI changed): n/a
- follow-up work or known limitations: 529 errors could get similar
  treatment in a follow-up

https://claude.ai/code/session_01D7kprMn4c66a5WrZscF7rv

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-06 06:36:14 +08:00
Kevin Codex
5ef79546e9 test: stabilize suite and add coverage heatmap (#373)
* test: stabilize suite and add coverage heatmap

* ci: run full bun test suite in pr checks
2026-04-05 12:44:54 +08:00
Anandan
0d27ca596a Neutralize remaining internal-only diagnostic labels (#359)
This pass rewrites a small set of ant-only diagnostic and UI labels to
neutral internal wording while leaving command definitions, flags, and
runtime logic untouched. It focuses on internal debug output, dead UI
branches, and noninteractive headings rather than broader product text.

Constraint: Label cleanup only; do not change command semantics or ant-only logic gates
Rejected: Renaming ant-only command descriptions in main.tsx | broader UX surface better handled in a separate reviewed pass
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Remaining ANT-ONLY hits are mostly command descriptions and intentionally deferred user-facing strings
Tested: bun run build
Tested: bun run smoke
Tested: bun run verify:privacy
Tested: bun run test:provider
Tested: bun run test:provider-recommendation
Not-tested: Full repo typecheck (upstream baseline remains noisy)

Co-authored-by: anandh8x <test@example.com>
2026-04-04 23:50:15 +05:30
Anandan
2f162af60c Reduce internal-only labeling noise in source comments (#355)
This pass rewrites comment-only ANT-ONLY markers to neutral internal-only
language across the source tree without changing runtime strings, flags,
commands, or protocol identifiers. The goal is to lower obvious internal
prose leakage while keeping the diff mechanically safe and easy to review.

Constraint: Phase B is limited to comments/prose only; runtime strings and user-facing labels remain deferred
Rejected: Broad search-and-replace across strings and command descriptions | too risky for a prose-only pass
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Remaining ANT-ONLY hits are mostly runtime/user-facing strings and should be handled separately from comment cleanup
Tested: bun run build
Tested: bun run smoke
Tested: bun run verify:privacy
Tested: bun run test:provider
Tested: bun run test:provider-recommendation
Not-tested: Full repo typecheck (upstream baseline remains noisy)

Co-authored-by: anandh8x <test@example.com>
2026-04-04 23:26:14 +05:30
Anandan
9e84d2fddc Remove internal-only tooling from the external build (#352)
* Remove internal-only tooling without changing external runtime contracts

This trims the lowest-risk internal-only surfaces first: deleted internal
modules are replaced by build-time no-op stubs, the bundled stuck skill is
removed, and the insights S3 upload path now stays local-only. The privacy
verifier is expanded and the remaining bundled internal Slack/Artifactory
strings are neutralized without broad repo-wide renames.

Constraint: Keep the first PR deletion-heavy and avoid mass rewrites of USER_TYPE, tengu, or claude_code identifiers
Rejected: One-shot DMCA cleanup branch | too much semantic risk for a first PR
Confidence: medium
Scope-risk: moderate
Reversibility: clean
Directive: Treat full-repo typecheck as a baseline issue on this upstream snapshot; do not claim this commit introduced the existing non-Phase-A errors without isolating them first
Tested: bun run build
Tested: bun run smoke
Tested: bun run verify:privacy
Not-tested: Full repo typecheck (currently fails on widespread pre-existing upstream errors outside this change set)

* Keep minimal source shims so CI can import Phase A cleanup paths

The first PR removed internal-only source files entirely, but CI provider
and context tests import those modules directly from source rather than
through the build-time no-telemetry stubs. This restores tiny no-op source
shims so tests and local source imports resolve while preserving the same
external runtime behavior.

Constraint: GitHub Actions runs source-level tests in addition to bundled build/privacy checks
Rejected: Revert the entire deletion pass | unnecessary once the import contract is satisfied by small shims
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: For later cleanup phases, treat build-time stubs and source-test imports as separate compatibility surfaces
Tested: bun run build
Tested: bun run smoke
Tested: bun run verify:privacy
Tested: bun run test:provider
Tested: bun run test:provider-recommendation
Not-tested: Full repo typecheck (still noisy on this upstream snapshot)

---------

Co-authored-by: anandh8x <test@example.com>
2026-04-04 23:04:34 +05:30
KRATOS
75d2543854 fix: remove internal Anthropic tooling from external build (#345)
Remove debug systems, employee detection, and internal logging
that have no function in a community fork.

Changes:
- Remove logPermissionContextForAnts import and calls (main.tsx, compact.ts)
  Reads Kubernetes namespace and container IDs from internal infra paths.
  Dead code for all external users.

- Remove createDumpPromptsFetch import and gate (query.ts)
  Internal prompt dump system for employee debugging.
  Replace gate with unconditional undefined — normal fetch always used.

- Remove stripSignatureBlocks ant-only block (query.ts)
  Was behind USER_TYPE === 'ant' guard, never ran for external users.

- Hardcode isAnt: false (query/config.ts)
  Employee detection flag has no place in a community fork.
  config.gates.isAnt had exactly one consumer (dumpPromptsFetch, now removed).

- Gut logClassifierResultForAnts body (bashPermissions.ts)
  Replace with empty no-op. Still called from 4 sites, zero execution.
  Remove ANT-ONLY comments describing internal security model.

- Gate status.anthropic.com behind firstParty check (errors.ts)
  429 error hint now only shown when using Anthropic directly.
  Third-party provider users see a generic capacity message.

Build: passes
Typecheck: clean (no new errors)
Tests: 196 pass, same 6 pre-existing failures unrelated to these changes
2026-04-04 21:23:17 +05:30
JiayuWang(王嘉宇)
e4cf810e14 fix: guard rawBaseUrl against the literal string "undefined" from env vars (#340)
On Windows, shells can set OPENAI_BASE_URL to the literal string
"undefined" when the variable is referenced without quotes while unset.
The nullish-coalescing operator (??) does not catch this because
"undefined" is a truthy string, causing resolveProviderRequest() to
treat it as a real base URL. This broke the Codex transport check:
(!rawBaseUrl && isCodexAlias(model)) evaluated as (false || true) = false
so the transport was incorrectly set to chat_completions (issue #336).

Fix: introduce asEnvUrl() which trims the value and rejects both empty
strings and the sentinel string "undefined". Use it for all three
rawBaseUrl sources (options.baseUrl, OPENAI_BASE_URL, OPENAI_API_BASE).

Tests: add three new cases to the 'Codex provider config' describe block
covering the empty-string, "undefined"-string, and options-override
scenarios. Also add beforeEach/afterEach guards so individual tests
cannot contaminate each other via env var state.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 22:37:59 +08:00
Juan Camilo Auriti
fbf3385395 fix: prevent cross-provider model env var leaks and sync Codex detection (#243)
Two provider routing bugs that cause silent wrong-model failures:

1. model.ts: getUserSpecifiedModelSetting() read ANTHROPIC_MODEL ||
   GEMINI_MODEL || OPENAI_MODEL with no provider check. A user
   switching from Anthropic to OpenAI with ANTHROPIC_MODEL still set
   would silently send the Anthropic model name to the OpenAI API.
   Now gates each env var behind the active provider from
   getAPIProvider().

2. providers.ts: isCodexModel() maintained a hardcoded list of 8 model
   names that was missing gpt-5.4-mini and gpt-5.2 from the canonical
   CODEX_ALIAS_MODELS table in providerConfig.ts. This caused a
   split-brain: getAPIProvider() returned 'openai' while
   resolveProviderRequest() selected 'codex_responses' transport.
   Now delegates to the exported isCodexAlias() to keep both detection
   systems in sync.
2026-04-04 17:38:47 +08:00
Vasanth T
ea335aeddc feat: add Gemini ADC and access token auth (#312)
* feat: add Gemini ADC and access token auth

* feat: add Gemini token and ADC provider setup

* feat: add Gemini token and ADC provider setup

* fix: honor Gemini auth mode on restart
2026-04-04 17:37:17 +08:00
KRATOS
27e6505bfd hardening: isolate third-party paths and clean external-build metadata (#311)
* hardening: isolate third-party paths and clean external-build metadata

* fix: restore external feedback flow and make privacy check portable
2026-04-04 14:22:33 +08:00
KRATOS
c52245fc0a fix: restore image paste and image tool-result handling (#308) 2026-04-04 14:10:26 +08:00
step325
70cfa61582 fix: disable experimental API betas by default, reduce side query token usage, standardize Headers type (#281)
* fix: disable experimental API betas by default to prevent 500 errors

Tool search (defer_loading), global cache scope, and context management
betas require internal Anthropic server-side support. External accounts
receive 500 Internal Server Error when these are sent.

Set CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=true by default in the CLI
entrypoint. Users with internal access can opt back in with =false.

Also includes: cache key stability fixes (Sonnet 1M latch, system-before-
messages key ordering, resume fingerprint isMeta skip), sideQuery default
cleanup, and /dream command.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: standardize API headers to Headers type and enable tengu feature flags by default

* fix: address PR review — dream lock, MCP betas guard, redundant Partial

- Call recordConsolidation() programmatically in /dream instead of
  delegating to model prompt (unreliable)
- Add CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS guard to MCP entrypoint
  (was only in CLI entrypoint, causing 500s in MCP server mode)
- Remove redundant ? markers from SecretValueSource Partial<{}> type

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 01:40:07 +08:00
KRATOS
8ce09ae743 fix: disable cache_control injection for third-party providers (#276)
getPromptCachingEnabled() returned true for all providers including
Azure Foundry, OpenAI, Gemini, and GitHub. This caused cache_control
blocks to be injected into every request sent to 3P endpoints.

Azure Foundry's strict Responsible AI content filter treats unexpected
Anthropic-specific fields (cache_control: { type: "ephemeral" }) as
a jailbreak signal and rejects the request with a 400 error — even
for a simple prompt like "hi".

Fix: return false early when provider is not firstParty, bedrock, or
vertex — the only providers that understand and support prompt caching.

Fixes #273
Related: #267 (Finding 1)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 22:53:14 +08:00
JasonVon
fb32e3f829 feat: per-agent model routing — route different agents to different providers (#238)
* feat: add agentModels and agentRouting to SettingsSchema

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add agentRouting module for per-agent provider resolution

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: thread providerOverride through OpenAI shim for per-agent routing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: getAnthropicClient accepts providerOverride for agent routing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: thread providerOverride through Options and queryModel calls

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: thread providerOverride through query loop and ToolUseContext

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: resolve agent routing in runAgent and inject providerOverride

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: add Agent Routing configuration guide to README

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test: add unit tests for resolveAgentProvider + plaintext api_key note

- 15 tests covering priority chain (name > subagentType > default > null)
- normalize() case-insensitive and hyphen/underscore equivalence
- Edge cases: null settings, missing config sections, non-existent model
- README note about api_key stored in plaintext

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* security: address code review — SSRF, credential leak, key collision

- base_url schema now uses z.string().url() for SSRF mitigation
- Strip auth headers (Authorization, x-api-key, api-key) from
  defaultHeaders when providerOverride is active, preventing
  Anthropic credentials from leaking to third-party endpoints
- Warn on duplicate normalized routing keys to prevent silent shadowing
- providerOverride.apiKey is never logged (verified via grep)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: 冯俊辉 <fengjunhui@shiyanjia.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 21:47:26 +08:00
Shivam singh
36d1c45954 fix(retry): prevent retries on quota-exhausted 429 errors (#249)
* fix(retry): prevent retries on quota-exhausted 429 errors

- Detect hard quota exhaustion (e.g. 'limit: 0')
- Short-circuit retry loop with CannotRetryError
- Align shouldRetry() to avoid inconsistent behavior

This prevents unnecessary retries and improves error clarity.

* fix(retry): prevent retries on quota-exhausted 429 errors

* fix(retry): prevent retries on quota-exhausted 429 errors
2026-04-03 21:20:17 +08:00
KRATOS
6919d774f2 fix: custom OPENAI_BASE_URL always wins over Codex model alias detection (#222)
* feat: add --provider CLI flag for multi-provider support

Adds a --provider flag that maps friendly provider names to the
environment variables the codebase uses for provider detection.
No more manual env-var configuration — users can now simply run:

  openclaude --provider openai --model gpt-4o
  openclaude --provider gemini --model gemini-2.0-flash
  openclaude --provider ollama --model llama3.2
  openclaude --provider bedrock
  openclaude --provider vertex

Implementation details:
- providerFlag.ts: core logic — maps provider names to env vars,
  uses ??= so explicit env vars always win over the flag defaults
- providerFlag.test.ts: 18 tests covering all 7 providers,
  error messages, model passthrough, and env-var precedence
- cli.tsx: early fast-path (mirrors --bare pattern) — sets env
  vars before Commander option-building and module constants run
- main.tsx: adds --provider to Commander option chain for --help

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: custom OPENAI_BASE_URL always wins over Codex model alias detection

When OPENAI_MODEL=gpt-5.4 (or gpt-5.4-mini) and a custom OPENAI_BASE_URL
is set (Azure, OpenRouter, etc), the transport was incorrectly forced to
codex_responses because gpt-5.4 is in CODEX_ALIAS_MODELS. This caused
requests to be sent with Codex auth instead of the user's API key,
resulting in 401 Unauthorized errors.

Fix: only use codex_responses when the base URL is explicitly the Codex
endpoint, OR when no custom base URL is set and the model is a Codex
alias. An explicit OPENAI_BASE_URL always takes priority over model-name
based Codex detection.

Verified locally: gpt-5.4 via OpenRouter now correctly shows
Provider=OpenRouter, Endpoint=https://openrouter.ai/api/v1 instead of
routing to chatgpt.com/backend-api/codex.

Fixes #200, #203

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 11:11:10 +08:00
Kevin Codex
cdf4bad95b Merge pull request #182 from wrenchpilot/development
Enhance local provider URL validation for private IP addresses
2026-04-03 01:56:20 +08:00
Kevin Codex
a6ed57d0f4 Merge pull request #161 from auriti/fix/block-update-for-3p-providers
fix: block update command for 3P providers, align thinking block handling
2026-04-03 01:52:54 +08:00
James Shawn Carnley
7b68eb1acb Enhance local provider URL detection for IPv6 and loopback ranges 2026-04-02 13:46:10 -04:00
Kevin Codex
a287597273 Merge pull request #162 from auriti/fix/provider-aware-error-messages
fix: provider-aware error messages and skip Anthropic key approval for 3P
2026-04-03 01:42:15 +08:00
Kevin Codex
47c53a18e8 Merge pull request #174 from gnanam1990/feat/provider-aware-rate-limit
feat: provider-aware rate limit reset delay for OpenAI/GitHub/Codex providers
2026-04-03 01:16:58 +08:00
James Shawn Carnley
5e77d82620 Merge branch 'Gitlawb:main' into development 2026-04-02 12:55:59 -04:00
Kevin Codex
1a57335d74 Merge pull request #160 from auriti/fix/shim-ids-azure-safety
fix: crypto.randomUUID for IDs, Azure Foundry detection, safety filter visibility
2026-04-03 00:54:49 +08:00
Kevin Codex
4c22de2585 Merge pull request #179 from gnanam1990/fix/gemini-routing
fix: route CLAUDE_CODE_USE_GEMINI through OpenAI-compatible shim
2026-04-03 00:50:21 +08:00
James Shawn Carnley
2ee43d7ee8 Merge branch 'Gitlawb:main' into development 2026-04-02 12:43:24 -04:00
Kevin Codex
3581d3f83f Merge pull request #142 from skfallin/fix/anthropic-schema-format
Strip incompatible JSON Schema keywords from tool schemas
2026-04-03 00:26:45 +08:00
James Shawn Carnley
4a4394bb65 feat: enhance local provider URL validation to include private IPv4 and IPv6 addresses 2026-04-02 12:26:23 -04:00
gnanam1990
b4aa27183d fix: route CLAUDE_CODE_USE_GEMINI through OpenAI-compatible shim
The Gemini provider uses Google's OpenAI-compatible endpoint
(generativelanguage.googleapis.com/v1beta/openai) but the client
routing condition in client.ts only checked CLAUDE_CODE_USE_OPENAI
and CLAUDE_CODE_USE_GITHUB — CLAUDE_CODE_USE_GEMINI was missing.

This caused every Gemini request to fall through to the Anthropic
client path. Since ANTHROPIC_API_KEY is not set when using Gemini,
the Anthropic SDK threw:

  "Could not resolve authentication method. Expected either apiKey
   or authToken to be set."

Fix: add CLAUDE_CODE_USE_GEMINI to the OpenAI shim routing condition
so Gemini requests correctly reach createOpenAIShimClient(), which
maps GEMINI_API_KEY → OPENAI_API_KEY and sets OPENAI_BASE_URL to
the Google endpoint.

Closes #176

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 21:51:26 +05:30
gnanam1990
8501786852 feat: provider-aware rate limit reset delay
Previously getRateLimitResetDelayMs only read the Anthropic-specific
'anthropic-ratelimit-unified-reset' header (Unix timestamp), returning
null for every other provider. This meant OpenAI, GitHub, and Codex
users in persistent retry mode (CLAUDE_CODE_UNATTENDED_RETRY=1) always
fell back to dumb exponential backoff even when the server included an
exact reset time in the response headers.

This change makes the function provider-aware:

- firstParty (Anthropic): existing behaviour preserved — reads
  'anthropic-ratelimit-unified-reset' Unix timestamp
- openai / codex / github: reads 'x-ratelimit-reset-requests' and
  'x-ratelimit-reset-tokens' (OpenAI relative duration strings like
  "1s", "6m0s", "1h30m0s"), picks the larger of the two so retries
  don't fire before both token and request limits have reset
- bedrock / vertex / foundry / gemini: returns null (no standard
  reset header for these providers)

Adds parseOpenAIDuration() as an exported helper to convert OpenAI's
duration format into milliseconds.

16 new tests covering all provider paths and edge cases.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 21:30:05 +05:30
skfallin
37d4c21739 fix: make schema sanitization provider-specific 2026-04-02 17:57:42 +02:00
Kevin Codex
73db9b5fd3 Merge pull request #163 from erdemozyol/feat/codex-status-usage
Add Codex usage to /status
2026-04-02 23:54:07 +08:00
erdemozyol
5c25ac4e9a Add Codex usage to /status 2026-04-02 17:37:07 +03:00
Juan Camilo
c66b859342 fix: provider-aware error messages and skip Anthropic key approval for 3P
1. errors.ts: Add getCustomOffSwitchMessage() that returns a
   provider-neutral message for 3P users instead of the hardcoded
   "Opus is experiencing high load, please use /model to switch to
   Sonnet" which is misleading for OpenAI/Gemini/Ollama users.
   The original constant is preserved for backward-compatible string
   matching in error handlers.

2. Onboarding.tsx: Skip the "approve API key" step when a 3P provider
   is active. Previously, having ANTHROPIC_API_KEY in the environment
   (e.g., from a previous Anthropic setup) triggered an irrelevant
   Anthropic key approval UI even when using Gemini or OpenAI.
2026-04-02 16:23:12 +02:00
Juan Camilo
1709f5c098 fix: block update command for 3P providers, align thinking block handling
1. cli/update.ts: Block the update command for third-party providers.
   The update mechanism downloads from Anthropic's GCS bucket, which
   would silently replace the OpenClaude build (with the OpenAI shim)
   with the upstream Claude Code binary (without it). Now shows an
   actionable message directing users to rebuild from source.

2. codexShim.ts: Filter thinking blocks from assistant history, matching
   the openaiShim behavior. Without this, thinking blocks were included
   as plain text in assistant messages for the Codex transport but
   excluded for the OpenAI transport — causing inconsistent history
   when switching providers mid-session.
2026-04-02 16:18:10 +02:00
Juan Camilo
5d6443799a fix: crypto.randomUUID for IDs, Azure Foundry detection, safety filter visibility
Three targeted fixes:

1. Replace Math.random() with crypto.randomUUID() for message and tool
   call IDs in both openaiShim.ts and codexShim.ts. Math.random() is
   not cryptographically secure and predictable in seeded environments.

2. Anchor Azure endpoint detection to parsed hostname instead of raw
   URL regex. Adds support for Azure AI Foundry (services.ai.azure.com)
   alongside existing cognitiveservices and openai Azure endpoints.
   Prevents SSRF-style bypass via path segments.

3. Surface content safety filter blocks to the user. When Gemini or
   Azure returns finish_reason 'content_filter' or 'safety', emit a
   visible text block '[Content blocked by provider safety filter]'
   instead of silently returning empty/truncated content with
   stop_reason 'end_turn'. Applied to both streaming and non-streaming.
2026-04-02 16:14:35 +02:00
skfallin
0fe8551d33 Merge branch 'main' into fix/anthropic-schema-format 2026-04-02 15:50:16 +02:00
Kevin Codex
145c99b297 Merge pull request #151 from auriti/fix/gemini-auth-dummy-key-bypass
fix: prevent ANTHROPIC_API_KEY from interfering with Gemini provider auth
2026-04-02 21:43:04 +08:00
skfallin
6319df02f0 Merge upstream/main into fix/anthropic-schema-format 2026-04-02 15:42:28 +02:00
Kevin Codex
3c8c63a78e Merge pull request #153 from auriti/fix/report-openai-cached-tokens
fix: report cached tokens from OpenAI prompt_tokens_details
2026-04-02 21:41:47 +08:00
Kevin Codex
35676be381 Merge pull request #143 from sooth/codex/repl-memory-and-schema-hardening
[codex] fix: trim persisted tool results and sanitize MCP schemas
2026-04-02 21:41:30 +08:00
Juan Camilo
d430ddd568 fix: prevent ANTHROPIC_API_KEY from interfering with Gemini provider auth
Two fixes for issue #133 where setting ANTHROPIC_API_KEY=dummy alongside
CLAUDE_CODE_USE_GEMINI=1 causes "Invalid API key" errors:

1. auth.ts: In the CI branch of getAnthropicApiKeyWithSource(), the
   ANTHROPIC_API_KEY value was returned without checking isUsing3PServices().
   A dummy key leaked into the Anthropic key resolution pipeline even when
   Gemini was the active provider. Now guards with isUsing3PServices().

2. errors.ts: The x-api-key error handler surfaced "Invalid API key" for
   any provider. Added getAPIProvider() === 'firstParty' guard so 3P users
   see the real underlying error instead of a misleading auth message.

Note: The cli.tsx Gemini validation fix (originally part of this PR) was
independently implemented in PR #121 and is already on main.
2026-04-02 15:40:07 +02:00
Juan Camilo
708a0a18fe fix: report cached tokens from OpenAI prompt_tokens_details
OpenAI returns cached token counts in usage.prompt_tokens_details.cached_tokens
but the shim hardcoded cache_read_input_tokens to 0. This made prompt
caching invisible to the cost tracker and session summary even when
OpenAI's automatic caching was actively reducing costs.

Changes:
- Extend OpenAIStreamChunk usage interface with prompt_tokens_details
- Map cached_tokens to cache_read_input_tokens in convertChunkUsage()
- Same fix in _convertNonStreamingResponse() for non-streaming path
- cache_creation_input_tokens remains 0 (OpenAI auto-caching has no
  creation cost — it is free and automatic)
2026-04-02 15:21:37 +02:00