Commit Graph

210 Commits

Author SHA1 Message Date
Luis Pater
e5729872fa Merge pull request #4522 from sususu98/fix/responses-ws-continuity 2026-07-23 14:31:41 +08:00
Luis Pater
3ecd4afe80 feat: add Home credential concurrency support 2026-07-23 13:42:08 +08:00
sususu
a661172b1f fix(responses): commit websocket tool cache atomically 2026-07-23 13:07:57 +08:00
sususu
e05ae09425 fix(responses): preserve context across websocket transport changes 2026-07-23 13:07:23 +08:00
Luis Pater
a007ad69f2 test(websocket): add robust unit tests for tool call handling and reconciliation
- Implemented tests for scenarios involving incomplete, conflicting, and reconciled tool calls in response payloads.
- Enhanced coverage for `restoreResponsesWebsocketCompletionOutput` and `responseCompletedOutputFromPayload` logic.
- Refactored `isCompleteResponsesWebsocketToolCall` to validate string fields in tool calls.
- Improved caching behavior to skip incomplete tool calls and ensure reconciliation logic aligns with expected outputs.

Closes: #4447
2026-07-20 16:47:22 +08:00
sususu98
7329437297 fix(websocket): propagate upstream 1009 without credential fallback (#4444)
Preserve Codex and XAI upstream message-too-big closes across the Responses WebSocket boundary while treating them as request-scoped errors. Prevent CPA reconnect and credential cooldown/fallback, scope close state to the active connection, retain terminal errors under backpressure, and ensure downstream disconnect cleanup cannot wait behind a blocked writer.
2026-07-20 16:18:13 +08:00
Luis Pater
fbe116071a feat(websockets): implement active connection tracking for websocket sessions
- Introduced per-connection active channel management for Codex and XAI websocket sessions.
- Enhanced session behavior to support clearing and reassigning active channels tied to specific connections.
- Added support for detecting and detaching stale connections upon session target changes.
- Refactored websocket message handling logic to ensure connection-specific channel consistency.
- Extended test coverage for websocket session behaviors, including reconnections, target switching, and pinned auth transitions.
2026-07-18 00:40:56 +08:00
Luis Pater
366271969a feat(logging): add CPA trace ID middleware and enhance metadata handling
- Introduced CPA trace ID middleware to inject trace IDs in response headers.
- Added support for CPA trace ID generation and validation.
- Updated metadata handling to include stable auth indices and trace ID callbacks for enhanced request tracking.
- Enhanced tests to verify CPA trace ID propagation and reserved header handling across middleware, metadata, and handlers.

Closes: #4370
2026-07-17 22:58:28 +08:00
Luis Pater
768b4c49fd feat(usage): track generate flag with backward-compatible defaults
Propagate client generate metadata through usage records while keeping
legacy callers that omit the field enabled by default. Preserve an
existing context generate=false when metadata does not set the value,
and normalize omission to true only at publishing boundaries.
2026-07-15 21:30:09 +08:00
sususu98
03d58c4402 fix(usage): collapse OpenAI service tier metadata (#4275)
* fix(usage): preserve request service tier metadata

* fix(usage): collapse request tier metadata

* fix(usage): emit only service_tier and response_service_tier

Collapse request tier to service_tier for usage records and queue payloads. Keep RequestServiceTier as a deprecated input-only alias for older plugin callers.
2026-07-14 14:19:13 +08:00
huahai0202
e73aad2e0a fix(codex): require model template for tool search 2026-07-13 19:35:16 +08:00
huahai0202
ceaeb75d53 fix(codex): gate tool search by model providers 2026-07-13 19:22:58 +08:00
sususu98
4fe2c60c51 feat(registry): remote-refresh Codex client model catalog (#4276)
Load codex_client_models.json like models.json with validation, revisioned
handler reloads, CI bake, and Home-aware updater gates so list IDs still
come from Home while templates can refresh on the edge.
2026-07-13 17:47:35 +08:00
Luis Pater
e0a0b5a4b7 feat(codex): add summary detection and processing for local compaction in websocket input
Closes: #4227
2026-07-13 03:22:47 +08:00
Luis Pater
3586d3e750 feat(config): add support for configurable model display names across all APIs
- Added `DisplayName` to model configuration for Codex, Claude, Gemini, Vertex, and OpenAI compatibility.
- Updated hash computation and model summary to account for `DisplayName`.
- Enhanced API handlers to use `DisplayName` for client-facing catalogs.
- Expanded tests to verify `DisplayName` usage, preservation, and fallback mechanisms.
- Updated documentation and configuration examples for `DisplayName` field.

Closes: #4245
2026-07-12 22:13:23 +08:00
Luis Pater
042f1fea68 feat(handlers): update method names for image execution with auth manager
- Replaced `ExecuteWithAuthManager` with `ExecuteImageWithAuthManager`.
- Replaced `ExecuteStreamWithAuthManager` with `ExecuteImageStreamWithAuthManager` for improved clarity and specificity.
2026-07-12 20:15:43 +08:00
Luis Pater
aa05fb27f3 feat(executor, handlers): enhance websocket output restoration and compact compaction logic
- Refactored websocket output collection to restore completed events using fallback items and indexed payloads.
- Updated `CodexExecutorCompact` tests to ensure no injection of `image_generation` tools and maintain compact input order.
- Added new tests to validate sustained reasoning, proper output restoration, and compaction replay behavior.
- Improved logic to handle incremental response appends and preserved reasoning continuations.
- Enhanced test coverage for normalization, tool calls, and downstream payload restoration scenarios.

Closes: #4176
2026-07-11 11:42:51 +08:00
Luis Pater
045a96428f feat(handlers): extend image-only model support with grok-imagine-image and grok-imagine-image-quality
Closes: #4201
2026-07-11 00:36:58 +08:00
Luis Pater
20e61f281f Merge pull request #4160 from kogekiplay/fix/codex-client-ultra-reasoning
fix: preserve ultra reasoning effort for Codex clients
2026-07-10 12:52:24 +08:00
Luis Pater
15f3037161 feat(models): restrict Codex input modalities to text and image
- Updated Codex client to validate and restrict input modalities to "text" and "image" only.
- Added deduplication logic for input modalities in `codex_client_models.go`.
- Introduced test cases to verify behavior with mixed and invalid modalities.
2026-07-10 03:21:01 +08:00
kogekiplay
ed2933443d fix: expose ultra reasoning effort to Codex clients 2026-07-10 02:42:04 +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
078ed1787b feat(openai): add support for input/output modalities in Codex client models
- Added handling of input/output modalities metadata for Codex and compatibility clients.
- Updated model registry and configurations to support "text" and "image" modalities.
- Introduced new tests to validate input/output modalities registration and processing.

Closes: #3976
2026-07-08 00:21:03 +08:00
Luis Pater
8b9c4da245 feat(interactions): add support for Google Interactions
- Introduced API handlers and executor logic for Google Interactions
- Added request and response transformations for OpenAI and Claude Interactions.
- Integrated Gemini API with Interactions support.
- Updated tests to validate Interactions request parsing and error handling.
- Refactored translator logic for Interactions data flows.
2026-07-07 02:39:13 +08:00
sususu98
8f686345b9 fix(responses): full transcript replay on WS-to-SSE Codex paths
For downstream websocket with CPA-mediated HTTP/SSE upstream (non-passthrough),
always merge the full conversation transcript instead of sending incremental
previous_response_id turns. Release pinned websocket auths after timeout and
gateway failures, and after WS bootstrap failover pin the successful SSE
credential so the next turn keeps merged context instead of retrying a
suspended websocket auth.

Fixes #4048
2026-06-29 18:47:55 +08:00
Luis Pater
87e6d9cf25 feat(videos): add model binding and propagation for video auth management
- Introduced `model` field in `videoAuthBinding` for model tracking.
- Enhanced binding store with `setWithModel` and `getBinding` methods for binding models.
- Updated handlers to propagate execution models during video processing.
- Added tests to verify model binding, retrieval, and propagation logic.
2026-06-24 16:10:53 +08:00
Luis Pater
9a8098d2d5 feat(api): prioritize non-template Codex client models and adjust priority calculation logic
- Added `applyCodexClientNonTemplatePriorities` to assign higher priorities to non-template Codex client models dynamically.
- Implemented `maxCodexClientTemplatePriority` to set base priority for non-template models relative to template models.
- Updated unit tests to validate priority calculation for custom models.
2026-06-21 00:10:03 +08:00
Luis Pater
bb414de33f feat(api): add "max" reasoning depth and service_tiers to Codex client models
- Introduced a new "max" level for reasoning depth in Codex client model configuration, providing maximum problem-solving capability.
- Added `service_tiers` field to model responses for better tier categorization.
- Updated unit tests to validate the inclusion and default behavior of `service_tiers` and the new "max" reasoning depth.
2026-06-20 22:49:43 +08:00
Luis Pater
041a065b2f Merge branch 'remove-gemini-cli' into dev
# Conflicts:
#	internal/api/handlers/management/auth_files.go
#	internal/thinking/provider/geminicli/apply.go
2026-06-19 14:40:29 +08:00
Luis Pater
ae6c5eaea5 feat(runtime): add support for gpt-image-1.5 and direct image API proxying
- Introduced the `gpt-image-2` model in Codex built-ins and updated visibility logic in the registry.
- Added direct proxy support for OpenAI image generation and editing endpoints.
- Implemented new execution paths for `/images/generations` and `/images/edit`, ensuring seamless handling for both JSON and multipart payloads.
- Expanded test coverage to validate the new model and direct proxy features, including streaming scenarios and error handling.
2026-06-19 00:06:12 +08:00
Luis Pater
78ba8ba731 chore: remove Gemini CLI-related translator packages and logic
- Deleted `geminicli` provider and related `Apply` logic.
- Removed all translator packages specific to Gemini CLI (Claude, Codex integrations).
- Purged associated test files for Gemini CLI translation.
- Removed `GeminiAuthenticator` and all associated authentication logic (OAuth flows, token handling, refresh logic).
- Deleted internal/executor Gemini OAuth support, including bearer token handling and runtime API logic.
- Purged all tests, configs, and command-line flags specific to Gemini OAuth flows.
- Updated documentation and aliases to reflect Gemini removal.
- Renamed `parseRetryDelay` to `ParseRetryDelay` and `deleteJSONField` to `DeleteJSONField`.
- Updated references in `antigravity_executor` and tests to use the new `helps` package.
- Adjusted import paths and test cases to ensure compatibility with the new location.
- Updated README files to reflect changes in the retry logic references.
- Updated `.github/ISSUE_TEMPLATE/bug_report.md` to remove deprecated Gemini CLI mention.
2026-06-18 13:33:10 +08:00
Luis Pater
644ba74bff feat(videos): implement auth binding for video requests and enhance proxy handling
- Added auth binding logic to tie video requests to specific authentication IDs.
- Enhanced video content handlers to support proxy configuration based on selected auth.
- Introduced helper functions for creating HTTP clients with direct or global proxy fallback.
- Expanded unit tests to validate auth binding, proxy usage, and fallback behavior.
2026-06-17 13:10:07 +08:00
Luis Pater
2884a67ed0 feat(videos): add support for video_url extraction and validation in handlers
- Updated `openai_videos_handlers` to extract and set `video_url` from payloads when available.
- Enhanced unit tests to validate correct `video_url` extraction and inclusion in responses.
2026-06-16 21:06:27 +08:00
sususu98
87132e54d7 feat(plugin): add ModelRouter before auth with single-slot routing targets (#3865)
* feat(plugin): add ModelRouter before auth with single-slot routing targets

## Motivation

Plugins that need to change execution based on the **original inbound request**
(protocol format, raw body, headers, query, stream flag, metadata, etc.) often
resorted to virtual/trampoline models or routing inside interceptors. This
commit adds **ModelRouter**: a pluggable layer **before** model-to-provider
resolution and AuthManager credential selection, so plugins can declare who
executes a request without spoofing the client model name.

This is a **new capability**, not a bugfix on the existing chain. With no
ModelRouter plugins loaded, behavior matches upstream.

## Pipeline placement

- `execute`, `stream`, and `count` (and image paths via AuthManager) call
  `applyModelRouter()` before building `coreexecutor.Request`.
- Routing runs **before** the request interceptor (before auth), so routers see
  the client’s original context. After a plugin executor is chosen, the existing
  **after-auth interceptor → response/stream interceptor** chain still applies.
- Internal `ExecuteModel` / `ExecuteModelStream` (host callbacks) support
  `SkipRouterPluginID` so nested calls do not re-enter the same router.

## Routing API (single slot, mutually exclusive)

`ModelRouteResponse` uses **one target slot** to avoid ambiguity when both
`TargetExecutorPluginID` and `TargetProvider` were set and the host ignored one:

| Field | Meaning |
|-------|---------|
| `Handled` | `false`: this router declines; try the next router or default path |
| `TargetKind` | `self` \| `executor` \| `provider` (pick one) |
| `Target` | `self`/`executor`: plugin ID; `provider`: built-in provider key |
| `TargetModel` | Optional on `provider` only; empty keeps client `RequestedModel` |
| `Reason` | Optional diagnostic text |

- **self**: the router plugin’s own executor (`Target` normalized to the router’s plugin ID).
- **executor**: another plugin’s executor; host pre-checks with `executorPluginReady()`
  (executor declared and provider identifier resolvable) to avoid handled routes that 500 at execution.
- **provider**: skip registry model resolution; fixed built-in AuthManager path; optional
  `TargetModel` for execution model only—**does not** change outward requested-model metadata.

Routers run in **descending plugin priority** (tie-break: ascending plugin ID). Panic, error,
invalid target, or unavailable executor/provider → log and **fall through to the next router**;
if none handle, use the original provider+auth flow.

## Context exposed to routers

`ModelRouteRequest` includes:

- `SourceFormat`, `RequestedModel`, `Stream`
- `Headers`, `Query`, `Body` (defensive copies)
- `Metadata` (best-effort read-only context snapshot)
- `AvailableProviders`: built-in provider keys with at least one **non-disabled** auth
  (`AuthManager.AvailableProviders()`). **Does not** reflect per-model cooldown or transient
  unavailability—treat as an optimistic snapshot.

Adds `AuthManager.HasProviderAuth()` and `AvailableProviders()`, excluding `Disabled` and
`StatusDisabled` auths consistently with credential selection.

## Host and RPC

- Go plugins: `pluginapi.ModelRouter` + `RouteModel()`.
- RPC plugins: `pluginabi.MethodModelRoute` (`model.route`), capability flag `model_router`.
- `pluginhost.Host` implements `RouteModel` / `RouteModelExcept`; handlers use
  `SetModelRouterHost` or a `PluginHost` type assertion; **direct executor** paths use
  `ExecutePluginExecutor*` / `CountPluginExecutor`.
- No bundled example ModelRouter plugin; capability is active only when a third-party plugin
  declares `model_router` and loads.

## Plugin RPC schema (policy A, upstream-aligned)

- `pluginabi.SchemaVersion` stays **1**: capability additions (`model_router`, `model.route`)
  do not bump the number; increment only on breaking RPC JSON changes.
- Host sends `schema_version` at register; reject only if the plugin declares a **higher**
  version than the host.
- No unpublished “ModelRouter requires schema ≥ 3” gate (v3 single-slot API was never public).
- Existing plugins and examples without `model_router` (`schema_version: 1`) need no changes.
- RPC ModelRouter: `schema_version: 1` + `model_router: true` + implement `model.route`.

## Path consistency within this commit

- Provider routes reuse image-only model checks (e.g. `gpt-image-2`) on the normalized model,
  same as the default AuthManager path.
- `count` aligned with execute/stream: `SkipRouterPluginID`, query/headers injection,
  interceptor skip semantics.
- Handlers: `modelRoutersEnabled` treats hosts without `HasModelRouters` as disabled
  (same as before ModelRouter existed); `pluginhost.Host` implements the detector.
- API docs: `ModelRouter` explicitly includes built-in **provider** targets (in addition to
  plugin executors and the router’s own executor).

## Testing

go test ./internal/pluginhost ./sdk/api/handlers ./sdk/pluginapi ./sdk/pluginabi ./sdk/cliproxy/auth
go build -o test-output ./cmd/server && rm test-output
go test ./...

* fix(handlers): address ModelRouter review feedback

- Use modelExecutionQuery for plugin executor and AuthManager paths so
  inbound URL query matches router/header behavior
- Guard queryFromContext when gin Request.URL is nil
- Read plugin executor stream chunks via nextStreamChunk to exit on cancel
- Drop redundant clonePluginMetadata on capability record meta

Tests cover query propagation, stream cancel, and nil URL safety.

* feat(plugin): add Claude web search router example

Add a Claude Code web_search ModelRouter example that can route matching Claude requests through Antigravity, Codex, xAI, or Tavily.

The plugin includes executor orchestration, backend fallback/penalty handling, Tavily API key support, Claude-compatible response assembly, stream forwarding, and focused unit coverage for detection, fallback routing, model resolution, penalties, stream forwarding, and Tavily behavior.

Verification: go test -count=1 ./... in examples/plugin/claude-web-search-router/go; go build -buildmode=c-shared for the plugin; go build ./cmd/server; live local CPA curl coverage for plugin load, four explicit routes, fallback, and Codex spark routing.

* fix(pluginhost): validate executor routes before fallback

* fix(pluginhost): skip oauth-only executor routes
2026-06-16 19:15:34 +08:00
Luis Pater
bbef8da454 feat(videos): add video authentication binding and update handler behavior
- Introduced `videoAuthBindingStore` for managing mappings of video IDs to credentials with TTL support.
- Updated video creation and retrieval handlers to bind and utilize credentials for authentication.
- Enhanced response models to include upstream models and adjusted request preparation logic.
- Added test coverage for video auth binding, TTL configuration, and expiration handling.
2026-06-15 13:38:40 +08:00
Luis Pater
ea90ab6f77 feat(websockets): implement XAIWebsocketsExecutor with enhanced execution and ID mapping
- Developed `XAIWebsocketsExecutor` for handling xAI Responses via WebSocket transport.
- Introduced session and state management with `codexWebsocketSessionStore` and `xaiWebsocketIDStateStore`.
- Added robust ID mapping for upstream and downstream request/response sequences.
- Enhanced error propagation and handling of WebSocket terminal events.
- Included utility methods for WebSocket request preparation, connection management, and state tracking.
- Added foundational support for compact and streamed responses via enhanced session tracking.
2026-06-15 08:22:07 +08:00
Luis Pater
56988aea0f feat(websockets): add Codex websocket passthrough support with tests
- Implemented `websocketDirectCaptureExecutor` for Codex websocket passthrough functionality.
- Added logic to bypass incremental state handling for passthrough models.
- Updated normalization, compaction, and replay handling to support passthrough mode.
- Introduced `responsesWebsocketUsesCodexWebsocketPassthrough` utility for model-specific passthrough determination.
- Expanded test coverage for websocket passthrough scenarios, including compaction and response validation.
2026-06-15 02:31:05 +08:00
Luis Pater
7de9757c82 feat: add OpenAI video support with improved error handling and response normalization
- Introduced `/openai/v1/videos` endpoint to support OpenAI-specific video generation.
- Added error normalization and handling for OpenAI video resources, including detailed error propagation.
- Enhanced response structure to include OpenAI-specific fields for status, progress, and model mappings.
- Implemented new handlers for video content retrieval and error scenarios.
- Expanded test coverage to validate OpenAI video support, error handling, and backend compatibility.
2026-06-15 01:53:52 +08:00
Luis Pater
3b96119050 feat(websockets): handle terminal events and improve error propagation
- Enhanced Codex Websockets Executor to capture `response.done` as a terminal event, alongside `response.completed` and `error`.
- Improved error propagation for upstream websocket errors with comprehensive message handling.
- Introduced utility functions for recognizing terminal events and extracting error messages.
- Expanded tests to validate new websocket event logic, including terminal event handling and upstream error propagation.
2026-06-15 01:03:19 +08:00
hkfires
8122b9fe4b feat!: remove amp integration support
BREAKING CHANGE: ampcode configuration, management endpoints, provider
routing, and X-Amp-Thread-Id session affinity are no longer supported
2026-06-14 20:31:00 +08:00
Luis Pater
ed52c6147c test(websocket, api): add unit tests for response ID injection and handling of pending tool calls
- Introduced test scenarios to validate `previous_response_id` injection during incremental and non-incremental requests.
- Verified behavior for pending tool calls, including proper inclusion or exclusion in websocket requests.
- Updated websocket handling logic to track `lastResponseID` and `pendingToolCallIDs`.
- Added utility functions for pending tool call validation and cleanup.
2026-06-12 04:25:44 +08:00
Luis Pater
538e3416db feat(plugin, api): prevent plugin recursion on host model callbacks, enable targeted interceptor skipping
- Updated host model callback logic to skip originating plugin's interceptors during nested model executions.
- Added `SkipInterceptorPluginID` field to plugin API structs for controlling interceptor bypass behavior.
- Introduced supporting logic in host API handlers, plugin host registry, and callback contexts to identify and skip specific plugins.
- Enhanced unit tests across plugin host, API handlers, and execution paths to verify interceptor skipping behavior and plugin isolation.
- Revised documentation to clarify non-recursive behavior of host model callbacks and the use of `SkipInterceptorPluginID`.
2026-06-12 02:38:51 +08:00
Luis Pater
8e39db2ec7 feat(plugin, api): introduce host model callback support with Go example and API handlers
- Added an example plugin `host-model-callback` in Go to summarize host model callbacks.
- Implemented `cliproxy_plugin_init`, `cliproxyPluginCall`, and other plugin functions for callback handling.
- Introduced API handlers for `ModelExecution` and `ModelExecutionStream` with support for both streaming and non-streaming requests.
- Included unit tests (`model_execution_test.go`) to validate execution logic and streaming responses.
2026-06-12 02:22:23 +08:00
Luis Pater
1ca048abdc feat(auth, interceptor, jshandler): add post-auth request interceptors and enhance format handling
- Introduced `applyRequestAfterAuthInterceptor` to modify requests after credential selection and before executor translation.
- Added `InterceptRequestAfterAuth` method across plugin adapters with corresponding tests for context validation.
- Enhanced format resolution logic (`requestToFormat`) to support additional providers and formats.
- Updated JavaScript handler to include a new `on_after_auth_request` hook for post-auth request handling.
- Refactored interceptor methods for clarity and better encapsulation of request/response lifecycles.
2026-06-10 20:58:59 +08:00
Luis Pater
556f50aa2a feat(interceptor, jshandler): enhance request/response handling with original request support
- Added `opts.OriginalRequest` handling to `applyResponseInterceptors` for improved context passing.
- Introduced new test `TestApplyJSBeforeRequestUsesReturnedCtxBody` to validate JavaScript interceptor behavior.
- Updated JavaScript-based handler to safely rewrite sensitive content and headers in requests.
- Refined interceptor logic to ensure consistent state retention across request processing.
2026-06-09 13:57:38 +08:00
Luis Pater
1762ee0d2e feat(pluginhost): add support for interceptors and metadata sanitization
- Implemented `RequestInterceptor`, `ResponseInterceptor`, and `StreamChunkInterceptor` capabilities.
- Added `sanitizePluginMetadata` to clean metadata for RPC compatibility.
- Enhanced interceptor chaining, error handling, and test coverage.
- Updated plugin configuration to register and dispatch interceptor methods.
2026-06-09 01:41:46 +08:00
Luis Pater
5753d1a089 feat(logging): enable file-backed request/response sources for enhanced API logging
- Introduced support for file-backed logging of API requests and responses to handle large payloads efficiently.
- Refactored `attachWebsocketLogSources` to `attachRequestLogSources` for broader request and response handling.
- Added new methods for appending request/response data to file-backed sources and updated existing logging workflows for compatibility.
- Improved cleanup and merge logic for file-backed sources during request processing.
- Updated tests to cover newly introduced file-backed logging functionality.
2026-06-05 01:48:05 +08:00
cat
f05d68d4ec refactor(openai): parse dedupe input item metadata in a single pass
Address review feedback: parse each item's type/id/call_id once with
gjson.GetManyBytes and reuse it across the dedupe loops instead of
rescanning every item up to five times. Behavior is unchanged.
2026-06-01 15:01:31 +08:00
cat
e7f4dd470d fix(openai): keep referenced tool call when deduping websocket input IDs
The input item ID dedupe added in #3620 keeps only the last occurrence of
each item id. When an upstream reuses the same item id across a re-sent or
repaired tool call (so two function_call items share an id but carry
different call_ids), the last-wins rule can drop the function_call whose
call_id still has a matching function_call_output. The upstream then rejects
the request with HTTP 400 "No tool call found for function call output with
call_id ...", breaking every subsequent turn over the Codex WebSocket path.

Make the dedupe orphan-aware: when several input items share an id, never
replace an item whose call_id is still referenced by a tool-call output with
one that is not. This keeps a single item per id (preserving the original
intent) while ensuring retained tool calls stay paired with their outputs.

Adds a regression test covering two function_call items that share an id
where only the earlier call_id has a surviving output.
2026-06-01 13:10:41 +08:00
Luis Pater
05b972479a feat(executor): refine session and conversation header handling for Codex
- Updated session handling to replace `Session_id` and `Conversation_id` headers with new logic ensuring consistent use of `Cache.ID` and prompt keys.
- Restored `Session_id` as a priority extraction source for `ExtractSessionID`.
- Added tests to validate case-sensitive and case-insensitive headers, canonical account header usage, and session key preservation.
- Removed legacy support for deprecated `Conversation_id` header to clean up API.
2026-06-01 11:27:10 +08:00