Commit Graph

170 Commits

Author SHA1 Message Date
Luis Pater
31f4cfab3f feat: migrate CLIProxyAPI to version 8 2026-09-27 14:42:26 +08:00
Luis Pater
3de5709db1 fix(claude): preserve tool result adjacency for Antigravity requests
- Split function response parts from mixed user turns in Gemini payloads
- Hoist function response turns ahead of intervening text reminders following model calls
- Apply function response turn splitting and adjacent user turn merging for Claude models

Closes: #6129
2026-09-26 21:22:41 +08:00
sususu
75b854eb2e fix(translator): sanitize tool names for Claude and inject fallback schema for parameterless tools 2026-09-24 15:44:07 +08:00
Luis Pater
320100ecf7 fix(codex): strip octal NUL pattern escapes from tool schemas
- Strip octal NUL (`\0`) escapes in regex patterns to prevent rejection by strict upstream JSON Schema validators
- Update tool schema normalization fast-path to check for serialized `\0` escape sequences

Closes: #6025
2026-09-22 18:25:48 +08:00
sususu
2eb8dd11d2 fix(gemini): preserve items for uppercase ARRAY type in schema sanitizer 2026-09-22 09:34:04 +08:00
Luis Pater
ffe6ad3c5f fix(gemini): enforce array type for schema nodes declaring items
- Infer `array` type or remove `items` on non-array nodes to satisfy Gemini schema validation
- Prioritize `array` type when flattening union types for properties declaring `items`
- Infer `type: array` during tool schema normalization when `items` is defined without an explicit type

Closes: #6011
2026-09-21 22:38:13 +08:00
Luis Pater
b532db9c4b fix(translator): preserve constraints and additionalProperties in gemini parametersJsonSchema
- Add `CleanJSONSchemaForGeminiJSONSchema` to retain standard JSON schema constraints and `additionalProperties`
- Use the new schema cleaner for `parametersJsonSchema` across OpenAI and Claude Gemini translators

Closes: #5959
2026-09-19 16:37:28 +08:00
Luis Pater
c93978c4ea fix(schema): normalize true boolean subschemas and strip unsupported keywords
- Normalize boolean `true` subschemas across root, properties, items, definitions, and dependencies into empty object schemas `{}`
- Include `dependencies` in schema definition traversal and normalization
- Strip unsupported schema keywords including `additionalItems`, `unevaluatedProperties`, `unevaluatedItems`, and `contentSchema`

Closes: #3551
2026-09-19 03:07:33 +08:00
Luis Pater
ad088a8795 fix(devin): filter automation update tools and sanitize tool descriptions
- Filter out `automation_update` tools and sanitize tool descriptions in Devin wire requests and logs.
- Strip additional Codex prompt directives from system messages.
- Support `children` field fallback when collecting namespace tools.
2026-09-17 13:51:26 +08:00
Luis Pater
f668ac417d fix(schema): strip unsupported schema identifier keywords
- Remove `id`, `$anchor`, `$vocabulary`, `$dynamicRef`, and `$dynamicAnchor` when cleaning JSON schemas for Gemini.

Closes: #5888
2026-09-17 10:10:50 +08:00
sususu
ca159b303d fix(util): enforce strict devin/ prefix requirement for devin provider 2026-09-13 23:34:43 +08:00
sususu
6174174488 feat(devin): auto-namespace model IDs from clean devin_models.json 2026-09-13 23:34:43 +08:00
sususu
eed249072d feat(devin): prefix all Devin model IDs with devin/ namespace 2026-09-13 23:34:43 +08:00
Luis Pater
f702bc1ac2 feat(codex): preserve native fidelity for responses-lite requests
- Detect native responses-lite requests via headers and client metadata.
- Skip instructions normalization and synthetic session cloaking for native requests.
- Preserve upstream completion output during websocket response forwarding.

Closes: #5780
2026-09-13 15:05:03 +08:00
Luis Pater
3bf787fc1d feat(auth): propagate canonical session id for custom header expansion
- Initialize `util.SessionIDResolver` to resolve session IDs from request contexts, metadata, and headers.
- Ensure canonical session metadata is injected into execution options across execution flows.
- Propagate session context in executors to support `$CPA-SESSION-ID` expansion in custom headers.
- Sync cleared or updated session identities back to execution contexts during conductor execution.

Closes: #5690
2026-09-10 01:43:37 +08:00
sususu
e56abd56f1 fix(translator): strip unsupported unicode property escape patterns from tool schemas
- Add HasUnsupportedUnicodePropertyEscape in internal/util to detect \p{...} / \P{...} escapes that fail Python re compilation.
- Strip incompatible pattern attributes during tool parameter normalization in codex/claude and openai/claude translators.
- Provide schema-aware fallback stripping in codex executor helps to protect downstream Codex requests without mutating non-schema user data.
- Export unified schema keyword lists in internal/util to eliminate duplication.
- Add comprehensive unit tests covering Artifact fixtures, lookaheads, and user data preservation.

Closes: #5644
2026-09-09 17:49:13 +08:00
Luis Pater
5ff4a31eaf feat(claude): support advisor tool beta header
- Add `advisor-tool-2026-03-01` beta header support when advisor server tools are declared or explicitly requested.
- Ensure proper ordering of the advisor tool beta before advanced tool use and effort betas.
- Inject and preserve advisor tool beta across token counting and fingerprint preservation paths.

Closes: #5330
2026-08-29 14:47:51 +08:00
Luis Pater
b5cde4ba42 fix(gemini): add default items schema for tool array definitions
- Populate a default string `items` schema on tool array definitions missing an items property for Gemini and Antigravity.
- Add helper to identify array declarations across single strings and type lists during schema normalization.

Closes: #5292
2026-08-28 13:21:50 +08:00
Luis Pater
d36b776c79 fix(test): improve cross-platform compatibility across unit tests
- Support CRLF line endings and skip hidden dot directories in nocopy invariant tests.
- Handle environment variable overrides and skip case-sensitive token priority tests on Windows.
- Use static OS and architecture values in Claude header fingerprint assertions for deterministic test results.

Closes: #5295
2026-08-28 05:01:42 +08:00
Luis Pater
adac1e5816 fix(gemini): improve schema normalization for unions and unsupported constraints
- Avoid overwriting parent properties when resolving `anyOf`/`oneOf` unions on object schemas, merging branch properties instead.
- Add `contains` to unsupported constraints and preserve object/array constraint hints in descriptions.
- Strip `required` arrays when the schema does not define a `properties` object.

Closes: #5219
2026-08-27 02:14:40 +08:00
Luis Pater
2555cde2f1 fix(xai): inline local refs and broaden codex app tool normalization
- Export `InlineLocalRefs` utility to resolve local JSON Pointer references.
- Inline local definitions and remove `$defs`/`definitions` in tool function parameters.
- Support `mcp__` prefixes and `codex_apps` namespace variations when identifying Codex app automation update tools.
- Handle `$ref` entries when inspecting and normalizing root union schema branches.
2026-08-26 23:41:44 +08:00
Luis Pater
e1bf893956 feat(github): resolve GitHub token for release checks and asset updates
- Add `util.ResolveGitHubToken` to resolve GitHub API tokens with priority order (`GITHUB_TOKEN`, `github_token`, and `GITSTORE_GIT_TOKEN` for GitHub repositories).
- Set GitHub `Authorization` headers in management version check and asset updater requests when a token is resolved.

Closes: #5189
2026-08-25 04:22:46 +08:00
Luis Pater
a7e3596b7e fix(gemini): normalize malformed schema nodes before cleanup
- Added a preprocessing pass to repair malformed MCP-style JSON schemas.
- Wraps bare property maps as object schemas, promotes `required: true` flags to parent `required` arrays, and removes boolean `required` from properties.
- Recurses through nested schema containers and skips known API request envelopes to avoid rewriting non-schema docs.
- Switched schema decoding/serialization path to preserve large numeric values and avoid HTML-escaping side effects.

Closes: #5178
2026-08-22 22:39:03 +08:00
Luis Pater
556328c122 feat(gemini): add namespace-aware OpenAI Responses tool resolution and custom tool call conversion
- Add shared tool descriptor collection and winner selection for Responses tools (top-level vs `additional_tools`, direct vs namespace child, and ordering rules).
- Introduce sanitized Gemini function name mapping with collision disambiguation and 64-char-safe truncation.
- Build forward/reverse tool identity maps for restoring original tool identity (`name`, `namespace`, `custom`) during translation.
- Update Gemini→Responses streaming conversion to emit proper custom tool call events and identity-aware function call events.
- Add helpers for translating `tool_choice` to Gemini config and unwrapping custom tool input payloads.

Closes: #5088
2026-08-20 13:47:15 +08:00
sususu
ac0d1888c0 fix(gemini): strip 'encrypted' metadata from tool parameters schemas (#5065) 2026-08-19 19:13:56 +08:00
Luis Pater
e424bfad00 feat(executor): support $-based custom headers from downstream request headers
- Propagate request headers into custom-header resolution for OpenAI/Gemini/XAI/Codex execution and websocket flows.
- Resolve auth `header:` values like `$ABC` from incoming request headers at request time and omit headers when no value is available.
- Add documentation for the dynamic custom-header behavior in `config.example.yaml`.

Closes: #5053
2026-08-18 19:33:50 +08:00
sususu98
f1b0431c77 feat(claude): add fingerprint-profile=claude-code-cli for API keys and delegated providers (#5047)
* feat(config): add fingerprint-profile to Claude keys and auth JSON

- Add FingerprintProfile to ClaudeKey configuration struct and normalizer
- Track fingerprint-profile in config diff
- Map fingerprint-profile / fingerprint_profile to auth attributes in file and config synthesizers
- Support fingerprint-profile in Management API PatchClaudeKey and normalization
- Add Claude billing attribution string manipulation utilities in internal/util
- Document fingerprint-profile options in config.example.yaml

* feat(claude): add fingerprint policy and request-local CLI identity

- Centralize Claude fingerprint policy resolution in claude_fingerprint_policy.go
- Support stable Claude CLI identity synthesis (UUIDv5 account_uuid and SHA-256 device_id)
  seeded from API keys or stable OAuth IDs, keeping access tokens isolated
- Warn on unrecognized fingerprint-profile values

* feat(claude): apply CLI fingerprint to Messages and keep API keys caller-owned

- Wire centralized fingerprint policy into Claude and Kimi executors
- Keep first-party Anthropic API keys and delegated providers caller-owned by default
- Apply Claude Code CLI wire profile (betas, metadata, diagnostics, MCP aliases)
  when fingerprint-profile=claude-code-cli is configured
- Strictly align CCH signing with native Claude Code 2.1.220: only first-party
  api.anthropic.com and Vertex sign dynamic CCH; third-party gateways and Kimi
  receive billing header without cch= to avoid prompt cache busting
- Respect caller-owned count_tokens bodies by default while aligning CLI shape on opt-in
- Fall back to CLIProxyAPI/<version> User-Agent when caller sends no UA in caller-owned mode
- Scope custom operator header overrides accurately in caller-owned mode
- Add comprehensive test coverage for policy resolution, gateway opt-in, Kimi, and token counting
2026-08-18 17:29:26 +08:00
shengyy
7d55d0da0d fix(antigravity): preserve schema semantics 2026-08-16 13:00:59 +08:00
shengyy
e23395a92b test(antigravity): cover schema sanitizer semantics 2026-08-16 13:00:50 +08:00
Luis Pater
f53a2b6e80 fix(gemini): merge conditional schema branches during JSON schema cleanup
- Add a cleanup pass to hoist `then`/`else` properties into the containing schema path (including nested and `allOf` cases).
- Remove `if`/`then`/`else` from the unsupported keyword list so sanitized schemas no longer retain conditional keywords.

Closes: #4984
2026-08-15 17:24:48 +08:00
Luis Pater
61c4fd87f5 fix(gemini): preserve additionalProperties:false for Antigravity response schemas
- Add a sanitizer option to keep `additionalProperties: false` in response paths instead of converting it to description hints.
- Skip dropping `additionalProperties: false` in `removeUnsupportedKeywords` when response mode is enabled, while still removing non-false `additionalProperties`.
- Keep tool-schema behavior unchanged by continuing to remove `additionalProperties` and emit compatibility hints for non-response conversions.

Closes: #4961
2026-08-15 04:48:42 +08:00
sususu
b921b5d032 Review: tighten the in-place byte write guard
Reviewing the guard against itself surfaced two defects. The allowlist was keyed
by file, so a new in-place write inside an already reviewed file passed silently,
and internal/wsrelay/manager.go was listed without ever matching a pattern.

Record the reviewed occurrence count per file and reject any deviation in either
direction: an added write in a reviewed file now fails, and a stale entry whose
writes disappeared fails too. Drop the entry that never matched.
2026-08-09 00:40:57 +08:00
sususu
1737596e02 Make the payload-reuse guards able to fail
TestConvertGeminiRequestToGeminiReusesLargeNormalizedPayload asserted the reuse
invariant with b.Fatal inside testing.Benchmark. A failing benchmark aborts
before completing an iteration and returns a zero BenchmarkResult, so
AllocedBytesPerOp reported 0 and the allocation check passed exactly when the
payload was being copied. Injecting a full copy into the translator left the
test green. Assert the invariant with t.Fatal and reject a zero-iteration
benchmark result; both injected regressions now fail the test.

Add two static guards for the no-copy invariant. Results handed out by the
no-copy helpers alias the caller's buffer, and mutating those bytes corrupts
already-derived values in a way the race detector cannot see. One guard rejects
in-place sjson options, the other keeps the set of in-place byte writes small
and documented: each reviewed site records why it cannot corrupt a no-copy
result, and a new site fails the test until it is justified.
2026-08-09 00:40:57 +08:00
sususu
ea8882bf26 Add a no-copy GJSON parse helper
gjson.ParseBytes copies the entire document before returning a result, which
is prohibitive for multi-megabyte requests. ParseGJSONBytesNoCopy mirrors the
existing GetGJSONBytesNoCopy contract: the returned result references the
caller's bytes, so callers must neither retain it nor mutate the buffer while
it is in use.
2026-08-09 00:40:57 +08:00
sususu
3904c40d65 fix(antigravity): strip propertyNames inside a property named "properties"
A Claude Messages request carrying MCP-style tool schemas failed before
inference when routed to Antigravity/Gemini: the private backend parses
function declarations as a limited proto-JSON Schema and rejects unknown
fields, so `propertyNames` produced

  Unknown name "propertyNames" at
  'request.tools[0].function_declarations[0].parameters.properties[0].value'

The cleaner already lists `propertyNames` as unsupported, but every
cleaning pass is skipped for nodes classified as property maps, and that
classification matched any path ending in ".properties". A tool may
declare a property named "properties" — Notion's page tools do — and the
schema for that property then sits at ".properties.properties", so it was
mistaken for a property map and nothing inside it was cleaned. The 400
above points at exactly that node.

Replace the suffix match with a parity check over the trailing run of
name-map keywords: the node a keyword names is a map only when its own
parent is a schema, so "properties" is a map, "properties.properties" is
the schema of a property named "properties", and a third repetition is a
map again. Only the trailing run is inspected, so a schema nested under
any prefix by the caller is classified the same way.

Codex/OpenAI egress is untouched: it converts input_schema separately,
uses non-strict tool mode, and accepts this shape.
2026-08-03 16:09:22 +08:00
Luis Pater
2b63d6bcda refactor(util): use structured options for JSON schema cleaning
- Replaced boolean parameters with a `jsonSchemaCleanOptions` struct in `cleanJSONSchema` to improve readability and scalability.
- Updated `CleanJSONSchemaForAntigravity` and related methods to utilize the new options struct.
- Enhanced flexibility for schema transformations with fine-grained control over operations like union flattening, enum type enforcement, and metadata removal.
- Added comprehensive tests to verify correct handling of unions and enum types in schemas.

Closes: #4666
2026-07-30 03:40:04 +08:00
Luis Pater
5dedb303f1 feat(util, executor, translator): enhance Antigravity schema handling and response formatting
- Introduced `CleanJSONSchemaForAntigravityResponse` to process schemas without adding tool-specific placeholders.
- Updated `cleanJSONSchema` with `removeGeminiMetadata` parameter for improved schema control.
- Refactored Antigravity schema sanitization to handle declaration and generation paths independently.
- Mapped OpenAI `response_format` to Antigravity settings, ensuring proper response schema cleaning.
- Expanded tests to verify proper placeholder-free response schema handling and metadata preservation.

Closes: #4652
2026-07-29 17:35:29 +08:00
Luis Pater
59aa35a434 feat(util): add NormalizeClaudeToolInputSchema for input schema normalization
- Introduced `NormalizeClaudeToolInputSchema` in `util` package to standardize tool input schemas for compatibility with Claude.
- Replaced local `normalizeClaudeToolInputSchema` implementations in translator functions with the new utility method.
- Improved handling of schema validation, union elimination, and property merging.
- Removed redundant code in response and chat-completions translators, streamlining schema normalization logic.

Closes: #4428
2026-07-27 06:06:26 +08:00
sususu98
a4d18cb04a fix(antigravity): scope schema sanitization (#4571) 2026-07-26 01:52:20 +08:00
sususu98
72886356dd fix(antigravity): preserve complete reasoning replay (#4525) 2026-07-25 14:07:31 +08:00
Luis Pater
0296600be6 feat(models): add Claude client model catalog and response builder
- Introduced a new `models` package for organizing Claude client model templates and building responses.
- Migrated Claude response handling to `claudemodels.BuildResponse`.
- Added comprehensive tests for model ID transformation, sorting, and metadata validation.
- Removed redundant utility functions and simplified integration with the API server.
2026-07-25 01:41:07 +08:00
Luis Pater
53c1e7e2dd perf(util): introduce GetGJSONBytesNoCopy for efficient JSON parsing without data duplication
- Added `GetGJSONBytesNoCopy` in `internal/util` for safe, no-copy JSON parse operations leveraging `unsafe`.
- Replaced `gjson.GetBytes` with the new helper in key payload processing paths (`kimi_executor`, `vertex_payload_helpers`, etc.) to improve performance.
- Added unit tests for behavior validation, including edge cases with empty input.
2026-07-20 15:37:55 +08:00
Luis Pater
c8803713c9 feat(translator): disambiguate and deduplicate tool names in request/response workflows
- Introduced `SanitizedFunctionNameMap` and `DisambiguatedToolNameMap` for consistent mapping between sanitized and original tool names.
- Added collision handling with deterministic hash suffixes for name disambiguation within character limits.
- Implemented logic to deduplicate and map tool and function names across translator components, including Interactions, Claude, and Gemini.
- Updated test cases to validate name restoration, deduplication, disambiguation, and mapping behaviors.

Closes: #4244
2026-07-15 04:49:30 +08:00
Luis Pater
ee71dc52b7 feat(auth/models): implement Claude model ID prefix handling and plugin auth disabled state support
- Added `EnsureClaudeModelIDPrefix` and `ResolveClaudeModelIDPrefix` utilities for standardizing and decoding Claude model IDs.
- Updated handling of `claude-fable-5-dd-<reversed>` model IDs for request routing and response formatting.
- Incorporated logic to enforce disabled states for plugin virtual auths and their expanded children.
- Refactored code for applying and persisting disabled state metadata in plugin multi-auth scenarios.
- Implemented and extended unit tests to validate expected behavior.
2026-07-09 22:39:59 +08:00
Luis Pater
4c78e40da4 feat(auth): unify provider key handling with OpenAI compatibility support
- Replaced direct `strings.ToLower` usage with `util.OpenAICompatibleProviderKey` for generating provider keys.
- Updated auth and executor workflows to use namespaced keys for OpenAI-compatible providers.
- Adjusted tests to validate namespaced key handling, including new test cases for provider registration and execution logic.
- Added `OpenAICompatibleProviderKey` helper in `util` for consistent key transformations.

Closes: #3600
2026-06-20 00:58:20 +08:00
Luis Pater
c44d4fcc7c feat(schema): add removal of $comment and enumDescriptions in JSON schema processing
- Updated JSON schema handling to remove `$comment` and `enumDescriptions` fields during schema transformations.
- Adjusted test cases to validate the removal of these fields both at root and nested levels.
- Expanded unsupported schema keywords to include `$comment` and `enumDescriptions` for Gemini compatibility.

Closes: #3512
2026-06-20 00:22:08 +08:00
Luis Pater
2406daf3ef feat(util): normalize Claude tool_result content and improve Gemini integration
- Added `ConvertClaudeToolResultContent` to standardize Claude tool_result content, preserving JSON structure and splitting out base64-encoded images.
- Updated Gemini and Gemini-CLI translators to use the new utility for generating deterministic function responses and inline image parts.
- Added comprehensive test cases for content types and edge cases, ensuring correct handling of string, JSON, and image blocks.

Closes: #2781
2026-06-16 08:09:30 +08:00
Mad Wiki
d606faa99c fix: strip Claude Code attribution from non-Anthropic translations 2026-05-17 04:21:53 +08:00
Luis Pater
a44e5eb1ab Merge branch 'v7' into dev 2026-05-10 02:33:42 +08:00
lihan3238
4cbe172934 refactor: extract DefaultAuthDir constant per review feedback 2026-05-08 22:28:38 +08:00