Commit Graph

790 Commits

Author SHA1 Message Date
sususu
fb2c1c1afa fix(devin): transport reuse, interleaved stream steps, strings.Builder panic, and updater URL 2026-09-13 23:34:43 +08:00
sususu
98b106f0e8 fix(devin): store transient quota metrics strictly in Quota.Signals and keep Metadata static 2026-09-13 23:34:43 +08:00
sususu
5d0c77cf3f fix(devin): enforce Connect-RPC EOS trailer invariant, validate frame flag, and bind OAuth callback to ctx 2026-09-13 23:34:43 +08:00
sususu
d754298a8b fix(devin): bound tool call indices against OOM, set Refresh timeout, and check manual callback state 2026-09-13 23:34:43 +08:00
sususu
f1f5506c0b fix(devin): align wire protocol, harden streaming, and resolve multi-turn tool/signature parity
- Wire parity: align Connect-RPC Sentry-Trace, User-Agent suppression, float32 double pattern, and dynamic 732-char hex device fingerprint
- Session ordinal & cache: implement process-scoped Field 15.2 with bounded LRU (5000 entries) and Field 15.4=14 user boundary; prioritize stable session_id over previous_interaction_id to preserve prompt caching
- Streaming robustness: unblock hung TCP reads on client cancellation via context watcher; accurately propagate stream read errors and trailer errors instead of swallowing truncated frames
- Thought signature & reasoning: emit raw delta signatures directly in active thought steps; eliminate redundant tail base64 re-encoding; ensure 1:1 assistant signature and thinking alignment across multi-turn history
- Tool call de-multiplexing: route parallel tool calls by tc.Index in both streaming step events and non-streaming aggregations
- Security & transport: escape OAuth callback error HTML against reflected XSS, enforce strict state validation, and isolate Devin HTTP transport with tr.Clone()
2026-09-13 23:34:43 +08:00
sususu
7b5741c639 feat(devin): support credential quota and seat status query via GetUserStatus
- Implement Connect-RPC GetUserStatus serialization and response parsing in internal/auth/devin/user_status.go.
- Extract user email, plan, username, user_id, team_id, org_id, daily/weekly quota percentages, and reset timestamps.
- Wire user status into DevinExecutor.Refresh to update auth metadata and Quota.Signals.
- Add devin to ProviderSupportsQuotaObservation so CPA management endpoints surface quota observations.
- Enrich Devin OAuth login flow with user status, email, and quota information, and add CSRF state verification.
- Support base_url override in DevinAuthService for mock testing and custom gateways.
2026-09-13 23:34:43 +08:00
sususu
f94752762b feat(devin): add Devin/Cognition provider integration and CLI OAuth
Implement the full Devin/Cognition Connect-RPC provider support across all CPA endpoints (/v1/chat/completions, /v1/messages, /v1/responses), complete with binary protobuf wire framing, streaming tools/arguments delta handling, thinking/reasoning replay, and CLI OAuth authentication.

Key highlights:
- Wire Protocol & Streaming:
  * Implemented Connect-RPC uncompressed 5-byte framing (0x00 + 4-byte length + protobuf) for ApiServerService/GetChatMessage.
  * Implemented Devin protobuf encoder/decoder in internal/runtime/executor/helps/devin_wire.go, including ClientMetadata, prompts, tools, completion_config, and multimodal image handling (Prompt Field #10).
  * Stream frame consumption via interactions protocol, correctly mapping arguments_delta and tracking multiple sequential tool calls (currentToolCallActive).
  * Streaming thought summary and sealed.v1 signature deltas targeting the thinking step.

- Model Registration & Thinking Clamping:
  * Registered static fallback models in model_definitions.go (swe-2, claude-fable-5-1, gpt-6-astra, swe-1-7-lightning, glm-5-2, glm-5-3).
  * Configured ThinkingSupport with discrete levels per model family.
  * Implemented CPA-standard nearest-neighbor clamping for thinking levels (minimal/low -> medium, xhigh -> max for swe-2).
  * Mapped thinking effort to Devin upstream model UID (e.g. swe-2-medium, swe-2-high, swe-2-max).

- Sensitive Words & System Prompt Sanitization:
  * Added devin.sensitive-words configuration in internal/config/config_types.go and config.go, matching Antigravity conventions.
  * Supported zero-width space (\u200b) obfuscation in prompts, tools, and system instructions via SensitiveWordMatcher.
  * Stripped Claude Code billing headers (x-anthropic-billing-header:) and CLI identity signatures from system instructions and tool descriptions to avoid upstream content filter rejections.

- Signature Compatibility:
  * Added SignatureProviderSWE = "swe" recognizing sealed.v1.* reasoning signatures in internal/signature/provider_compatibility.go.
  * Propagated reasoning.encrypted_content on Responses API and thinking.signature on Messages API.

- Authentication:
  * Implemented Devin PKCE OAuth flow with loopback callback server and headless manual token/code paste (--no-browser).
  * Registered Devin authenticator in SDK and CLI (-devin-login flag).
  * Integrated with management OAuth session endpoints and credentials manager.
2026-09-13 23:34:43 +08:00
Supra4E8C
1ca975dfc0 feat(cooldowns): add cooldown snapshot feature for management auth files 2026-09-13 18:50:21 +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
3c3938feb1 feat(plugins): forward query parameters as metadata in auth provider start login
- Accept optional metadata parameters in SDK and internal plugin host `StartLogin` methods.
- Clone and pass metadata to the auth provider's `AuthLoginStartRequest`.
- Convert management auth URL query parameters into metadata before initiating plugin login flows.

Closes: #5760
2026-09-12 20:05:34 +08:00
Luis Pater
b192f6550c feat(management): add plugin quota and declarative probe endpoints
- Add endpoints to list quota providers and fetch or reset credential quotas via plugins.
- Support declarative metadata quota probes with token substitution and response mapping.
- Clear core routing quota state when provider quota reset succeeds.

Closes: #5752
2026-09-12 19:07:43 +08:00
Luis Pater
e30de3d561 perf(antigravity): cache and deduplicate model capability probe requests
- Deduplicate concurrent capability probe requests using singleflight.
- Cache capability hints with TTL and apply backoff for transient failures.
- Track authentication failures per account to avoid poisoning shared endpoint caches.
- Restrict default model capability base URL to the daily endpoint.

Closes: #5749
2026-09-12 14:06:44 +08:00
Luis Pater
5b2785617d feat(plugins): expose model list responses to plugin interceptors
- Add `WriteModelListResponse` to `BaseAPIHandler` to apply plugin interceptors and record request lifecycles for model catalog responses.
- Update OpenAI, Claude, Gemini, Grok, and Codex model listing endpoints to route responses through the unified interceptor helper.

Closes: #5742
2026-09-12 00:04:11 +08:00
Luis Pater
456d4c371b fix(auth): clear unauthorized cooldowns on credential changes and sync codex plan type
- Reset unauthorized errors and model cooldowns in lifecycle updates when credentials change.
- Sync `plan_type` attribute from metadata or JWT `id_token` in auth file handlers and synthesizer.
- Invoke `postAuthPersistHook` after auth file upload and field patch operations.

Closes: #5736
2026-09-11 23:31:48 +08:00
Luis Pater
d1702fdffd fix(auth): drop stale auth updates using monotonic watcher revisions
- Track monotonic watcher revisions across persisted auth updates to filter out out-of-order events.
- Validate registration epochs before applying auth updates and deletions to prevent stale state overwrites.
- Synchronize auth status patches through post-persist hooks using detached background contexts.
- Guard auth status modifications with a dedicated handler mutex.

Closes: #5729
2026-09-11 08:18:51 +08:00
Luis Pater
fc96a87fa6 feat(auth): support organization-hashed claude credentials and legacy migration
- Disambiguate Claude credential filenames using organization and account UUID hashes to keep multiple organizations distinct.
- Migrate legacy Claude credentials during login and save flows while preserving existing metadata and deleting obsolete files.
- Introduce `WithAuthCreationIntent` context policy across token stores to allow creating missing disabled credentials during login and migration.
- Preserve existing `disabled` status during auth metadata merges when not explicitly specified.

Closes: #5709
2026-09-11 03:58:23 +08:00
Luis Pater
2912516cea feat(auth): support execution result policy before quota and cooldown mutations
- Introduce `ResultPolicy` interface and adapter to inspect and mutate execution results.
- Apply result policy in `MarkResult` prior to in-memory quota mutation, cooldown persistence, and hook invocation.
- Expose result policy configuration across auth `Manager`, SDK `Builder`, and `Service`.

Closes: #5705
2026-09-11 02:19:22 +08:00
Luis Pater
8f23ad0291 fix(codex): inherit template metadata for model aliases and restrict provider capabilities
- Resolve canonical templates using metadata model IDs for model aliases and prefixed routes.
- Apply descriptions, base instructions, and thinking support overrides to matched templates.
- Restrict protocol capabilities and reasoning levels based on provider support.

Closes: #5699
2026-09-11 01:42:30 +08:00
Luis Pater
c8f723e0fb feat(usage): propagate upstream base_url across usage records and plugin auth
- Add `BaseURL` field to usage records and host auth file entries.
- Extract `base_url` from auth attributes and metadata during usage reporting.
- Propagate `base_url` through plugin usage adapters and runtime auth callbacks.

Closes: #5693
2026-09-11 00:25:17 +08:00
Luis Pater
6dce78673f fix(auth): bound force refresh all concurrency using worker pool
- Limit concurrent credential refreshes in `ForceRefreshAll` using a worker pool bounded by `AuthAutoRefreshWorkers`.
- Centralize refresh worker pool size resolution in `refreshWorkers`.
- Check context cancellation prior to refreshing to fast-fail queued credentials.

Closes: #5687
2026-09-10 20:21:11 +08:00
Luis Pater
9fad505505 fix(auth): treat cloudflare 520-526 origin errors as transient upstream failures
- Exclude HTTP 5xx status codes from Cloudflare challenge classification to avoid treating origin errors as challenges.
- Tighten Cloudflare challenge detection pattern to require challenge indicators instead of generic HTML tags.
- Include HTTP 520-526 status codes in transient error cooldown handling across auth and model states.
- Support upstream `RetryAfter` hints when calculating recoverable failure cooldown durations.

Closes: #5681
2026-09-10 19:31:08 +08:00
Luis Pater
638ed7e1cc fix(stream): handle split CRLF across chunk boundaries in SSE validation
- Track trailing carriage returns across chunk boundaries in `sseJSONValidationState`.
- Strip leading newline in subsequent chunks to prevent duplicate newline insertion from split CRLF sequences.
- Reset trailing carriage return state upon stream completion.

Closes: #5657
2026-09-10 17:53:25 +08:00
Luis Pater
dde250f1c3 fix(auth): enable model cooldown and rotation for model not found errors
- Map upstream `model_not_found` errors to HTTP 404 before evaluating generic invalid request types in Codex terminal error handling.
- Prevent treating structured model not found responses as client request faults to preserve credential rotation.
- Recognize model access denial errors to apply model-level cooldown and failover.
- Respect `disable_cooling` configuration during model-level cooldown processing.

Closes: #5635
2026-09-10 12:35:07 +08:00
Luis Pater
3ae9093da8 fix(codex): treat model capacity errors as bootstrap overload failures
- Broaden pattern matching for Codex model capacity errors.
- Classify model capacity rejections as overload bootstrap failures to enable failover.

Closes: #5634
2026-09-10 12:06:01 +08:00
Luis Pater
259130863d fix(openai): preserve nested error details and sequence numbers in responses stream
- Format streaming error payloads with nested error objects matching official OpenAI Responses SSE specifications.
- Extract and propagate sequence numbers from upstream terminal events and framer states.
- Use `json.Number` to prevent precision loss for large integers and token metrics.
- Sanitize sensitive keys recursively across nested error objects without dropping custom fields.
2026-09-10 11:58:36 +08:00
Luis Pater
bd03aabcf1 fix(openai): preserve prewarm input and allow named tool outputs in responses websocket
- Track pending synthetic prewarm response IDs to merge warmup inputs into subsequent delta followups.
- Normalize transcript replacements when followups do not reference the prewarm parent response ID.
- Validate that the `input` field is an array for `response.create` requests.
- Allow `function_call_output` items without a `call_id` when a non-empty tool name is present.

Closes: #5631
2026-09-10 11:20:49 +08:00
Luis Pater
d1a024e940 feat(codex): add support for gpt-image-2.5 models
- Register builtin model definitions for `gpt-image-2.5`, `gpt-image-2.5-flare`, and `gpt-image-2.5-sunburst`.
- Update OpenAI image handlers and request routing to recognize GPT Image 2.5 models.
- Support direct image generation and edit execution for GPT Image 2.5 variants in the Codex executor.
- Apply client visibility overrides to hide new builtin image models where appropriate.
2026-09-10 10:40:53 +08:00
Luis Pater
aedc9e6a39 fix(auth): classify terminal upstream auth failures as non-retryable errors
- Introduce `IsTerminalAuthError` and `NewTerminalAuthError` to identify permanent upstream authentication failures.
- Return terminal auth errors from candidate selection and scheduling when all available credentials fail with unauthorized errors.
- Support `BuildErrorResponseBodyWithError` to format terminal upstream auth errors as non-retryable `upstream_authentication_required` responses.
- Propagate terminal error classifications and the `retryable` field across HTTP and WebSocket response handlers.

Closes: #5645
2026-09-10 10:02:08 +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
Luis Pater
60e5b8bd43 feat(management): add endpoint to refresh auth files
- Add `RefreshAuthFiles` handler to trigger active refresh for single or all auth files.
- Support specifying refresh targets via query parameters or JSON request body.
- Invoke auth manager force refresh operations and return refreshed credential states.

Closes: #5628
2026-09-09 20:05:33 +08:00
Luis Pater
0796d6d133 feat(plugin): add host session affinity lookup callback
- Decode and validate host affinity lookup requests for provider, model, and session ID.
- Query the active auth manager for session affinity bindings and status.
- Return lookup responses containing the auth index, observation timestamp, and credential availability state.

Closes: #5604
2026-09-09 03:25:42 +08:00
Luis Pater
c6327a86c9 feat(plugin): preserve raw json in management responses on schema version 6
- Bump plugin ABI `SchemaVersion` to 6 and add `SchemaVersionRawManagementResponse`.
- Skip HTML entity escaping for plugin management JSON responses on schema version 6 and above.
- Retain legacy HTML escaping behavior for plugins with schema versions prior to 6.

Closes: #5605
2026-09-09 00:45:45 +08:00
Luis Pater
f39702a2c4 Merge pull request #5625 from router-for-me/fix/issue-5608-plugin-store-rate-limit
fix(plugin-store): reduce release checks and honor shared GitHub rate-limit cooldowns
2026-09-09 00:03:04 +08:00
sususu
1119ef1424 fix(session): harden canonical UUIDv8 normalization for empty prefixes and context roots
- Reject bare/empty session prefixes after unwrapping rather than projecting an empty string into a shared ghost UUIDv8.
- Include ctx:v1: and ctx: in knownSessionPrefixes to ensure identical canonical UUIDv8 projection for context root hashes.
- Strip known prefixes iteratively to support layered prefixes such as derived:ctx:v1:.
- Document knownSessionPrefixes as a transitional compatibility table slated for deprecation when session extractors emit canonical UUIDv8 directly.
- Add regression unit test coverage for empty prefixes, context root prefix parity, chained prefix unwrapping, and golden UUIDv8 assertion.
2026-09-08 19:12:48 +08:00
Supra4E8C
3639d92421 fix(plugin-store): add network scope handling for shared GitHub API cooldowns 2026-09-08 18:35:32 +08:00
Luis Pater
20e3f731ea feat(auth): export helper functions for headless antigravity oauth
- Add `ExchangeAntigravityCode`, `FetchAntigravityUserInfo`, and `CompleteAntigravityOAuth` helpers for programmatic authentication.
- Introduce `BuildAntigravityAuthURL` and `AntigravityDefaultCallbackURI` to support custom and default redirect flows.
- Refactor Antigravity credential record assembly into `BuildAntigravityAuth`.

Closes: #5593
2026-09-08 18:22:01 +08:00
Luis Pater
1d5f7b2ac3 fix(auth): strip monotonic clock reading from quota cooldown deadlines
- Strip monotonic clock readings using `Round(0)` on calculated quota retry and recover deadlines.
- Ensure quota cooldown times rely on wall-clock timestamps across model and auth states.

Closes: #5590
2026-09-08 17:58:56 +08:00
sususu
6b187e778c feat(usage): normalize reported session hierarchy to canonical UUIDv8 2026-09-08 17:04:58 +08:00
sususu
390589159e feat(session): enhance harness hierarchy recognition and deduplicate selector extraction 2026-09-08 17:04:58 +08:00
Luis Pater
48e5e9e03d fix(auth): cap refresh loop timer wait duration
- Cap the timer sleep duration to 30 seconds to wake promptly after system suspend.
- Factor out `nextWait` to clamp the maximum wait duration for scheduled credential refreshes.

Closes: #5584
2026-09-08 12:07:57 +08:00
Luis Pater
1c22598d0b fix(auth): preserve active cooldown deadlines on subsequent failures
- Ensure subsequent failure updates only extend and do not shorten active model-level or credential-level retry deadlines.
- Retain longer per-model retry deadlines when propagating credential-scoped quota failures across sibling models.
- Avoid promoting sibling non-quota retry deadlines into quota recovery states during credential failure propagation.
- Reflect credential-wide cooldowns in client model projections when no per-model states exist.

Closes: #5501
2026-09-07 02:34:39 +08:00
Luis Pater
00c63a5669 feat(pluginhost): expose outbound HTTP wire profile to plugin requests
- Add HTTPWireProfile to sdk/pluginapi on HTTPRequest with wire_profile JSON tag
- Decode wire_profile in host callbacks for flat and nested RPC payloads
- Match header casing in httpwire ordered_conn and allow non-HTTP handshakes
- Apply wire profile settings (HTTP/1.1 enforcement, auto compression disable, header ordering) in plugin host HTTP client
- Preserve proxy configuration, custom TLS dialers, redirect handling, and connection lifecycle

Closes: #5062
2026-09-06 20:41:58 +08:00
Luis Pater
fa01468e95 perf(auth): optimize scheduler result updates with targeted model shards
- Add `upsertAuthResult` to incrementally update only affected model shards after request completion.
- Cache supported model sets per auth using registry epoch tracking to avoid redundant lookups.
- Preserve full shard synchronization for auth lifecycle events and credential-scoped results.

Closes: #5061
2026-09-06 16:42:59 +08:00
sususu
580df36423 feat(usage): propagate session and parent session hierarchy to usage reporting queue
- Reuse coresession.ExtractSessionInfo across HTTP headers and request payloads to unify canonical session prefix namespaces with the scheduler.
- Extract hierarchical session identities in two phases: initial extraction from request headers on entry, and authoritative deep extraction once request payloads and metadata are available.
- Support Claude Code multi-level subagents (X-Claude-Code-Agent-Id, metadata.agent_id) and Codex thread fork lineages.
- Propagate SessionID and ParentSessionID across ClientRequestMetadata, UsageReporter, and coreusage.Record without root_session_id.
- Include session_id and parent_session_id in queuedUsageDetail for Home LPushUsage forwarding and Redis consumption with self-loop guards.
- Add comprehensive test coverage for canonical headers, body extraction, ghost parent elimination, and self-referential loop guards.
2026-09-06 10:45:32 +08:00
Luis Pater
5ab0bca040 fix(codex): scope usage limit errors to credentials and parse flexible quota resets
- Mark Codex usage limit errors as credential-scoped across HTTP and WebSocket executors.
- Support both top-level and nested error structures with case-insensitive matching when parsing retry-after resets.
- Propagate prevalidated candidate context to session affinity and built-in selectors during auth selection.

Closes: #5529
2026-09-06 06:20:20 +08:00
Luis Pater
4c1bebe837 fix(auth): preserve concurrent modifications during auth refresh and preparation
- Implement three-way merge for refreshed and prepared auth updates against base and current runtime state.
- Retain user modifications to metadata, attributes, proxy URL, and error/cooldown status across background refresh operations.
- Guard against stale registration epochs and enforce per-auth generation ordering during persistence.

Closes: #5465
2026-09-04 07:03:40 +08:00
Luis Pater
649a8bdb6f feat(plugin): omit stream chunk history on payload chunks for schema v5
- Bump plugin schema version to 5 and introduce `SchemaVersionStreamChunkOmitHistory`.
- Omit `HistoryChunks` on payload stream chunks for schema version 5+ to avoid per-chunk cloning and serialization overhead.
- Conditionally accumulate and clone history chunks only when legacy plugins with schema version < 5 are active.

Closes: #5451
2026-09-04 01:19:50 +08:00
Luis Pater
2a6b87aca0 feat(openai): send periodic ping control frames during responses websocket streaming
- Add `writePing` to responses websocket writer to emit Ping control frames.
- Send periodic keep-alive Ping frames based on streaming configuration during response forwarding.
- Reset keep-alive interval upon receiving data chunks and abort session if ping write fails.

Closes: #5413
2026-09-03 21:27:23 +08:00
Luis Pater
291cfb87ef feat(codex): support orphan delegation compatibility via orphan-delegation-compatibility
- Add `codex.orphan-delegation-compatibility` configuration option and mirror it to SDK configuration.
- Convert orphan Codex delegation outputs into standard user messages for requests with `X-Openai-Subagent: collab_spawn`.
- Integrate orphan delegation rewriting into OpenAI responses request handling pipeline.

Closes: #5401
2026-09-03 20:21:24 +08:00
sususu98
e899f0e539 feat(session): derive distinct branch session ID, parent lineage on Merkle LCP forks, and enhance Codex fork/subagent affinity (#5418) (#5454) 2026-09-03 17:52:40 +08:00