Skip to content

Commit baafced

Browse files
author
Mateusz
committed
Fix Codex continuation keying and delta reuse
1 parent 11a705a commit baafced

14 files changed

Lines changed: 4555 additions & 2468 deletions

src/connectors/_openai_codex_connector.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,15 @@
4848
from src.connectors._openai_codex_request_translator import CodexRequestTranslator
4949
from src.connectors._openai_codex_session_detector import SessionDetector
5050
from src.connectors.base import add_vendor_prefix, strip_vendor_prefix
51-
from src.connectors.contracts import ConnectorChatCompletionsRequest
51+
from src.connectors.contracts import (
52+
ConnectorChatCompletionsRequest,
53+
ConnectorRequestContext,
54+
)
5255
from src.connectors.openai import OpenAIConnector
5356
from src.connectors.openai_codex.compat import CompatibilityLayer
57+
from src.connectors.openai_codex.continuation import (
58+
InMemoryCodexContinuationCoordinator,
59+
)
5460
from src.connectors.openai_codex.contracts import (
5561
CodexConnectorDependencies,
5662
CodexConnectorSettings,
@@ -272,6 +278,7 @@ def __init__(
272278
and self._dependencies.tool_execution_service is not None
273279
else ToolExecutionService()
274280
)
281+
self._continuation_coordinator = InMemoryCodexContinuationCoordinator()
275282

276283
self._compatibility_layer = (
277284
self._dependencies.compatibility_layer
@@ -324,6 +331,7 @@ def __init__(
324331
max_retries=max_retries,
325332
retry_backoff_seconds=retry_backoff_seconds,
326333
compatibility_layer=self._compatibility_layer,
334+
continuation_coordinator=self._continuation_coordinator,
327335
use_websocket=use_websocket,
328336
)
329337
)
@@ -1342,6 +1350,7 @@ async def _call_codex_responses_api(
13421350
domain_request: Any,
13431351
*,
13441352
options_metadata: Mapping[str, Any] | None = None,
1353+
request_context: ConnectorRequestContext | None = None,
13451354
) -> Any:
13461355
"""Call the Codex-specific Responses API endpoint."""
13471356
capabilities = self._resolve_capabilities(request_data)
@@ -1469,6 +1478,11 @@ async def _call_codex_responses_api(
14691478
if executor_metadata is None:
14701479
executor_metadata = {}
14711480
executor_metadata["compatibility_state"] = compatibility_state
1481+
if request_context is not None:
1482+
if executor_metadata is None:
1483+
executor_metadata = {}
1484+
executor_metadata["connector_request_context"] = request_context
1485+
executor_metadata["capture_key_name"] = self.backend_type
14721486

14731487
executor_context = CodexRequestContext.model_construct(
14741488
request=request_data,
@@ -2065,6 +2079,7 @@ async def chat_completions(
20652079
if isinstance((md_raw := kwargs.get("metadata")), Mapping)
20662080
else None
20672081
),
2082+
request_context=request.context,
20682083
),
20692084
)
20702085
if not self.is_functional:

src/connectors/openai_codex/client_families/opencode_adapter.py

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -73,15 +73,11 @@ def adapt_payload_dict(
7373
if not isinstance(instructions, str) or not instructions.strip():
7474
instructions = resolved_instructions or ""
7575

76-
bridge_prompt = self._build_bridge_prompt()
77-
if bridge_prompt in instructions:
78-
result["instructions"] = instructions
79-
return result
80-
81-
if instructions.strip():
82-
result["instructions"] = f"{instructions.rstrip()}\n\n{bridge_prompt}"
83-
else:
84-
result["instructions"] = bridge_prompt
76+
result["instructions"] = self._append_instruction_block(
77+
instructions,
78+
marker=_OPENCODE_BRIDGE_MARKER,
79+
block=self._build_bridge_prompt(),
80+
)
8581
return result
8682

8783
def _adapt_input_items(
@@ -144,15 +140,6 @@ def _normalize_input_item(item: object) -> dict[str, Any] | None:
144140
else:
145141
return None
146142

147-
if str(normalized.get("type") or "").strip().lower() == "item_reference":
148-
return None
149-
150-
normalized.pop("id", None)
151-
nested_item = normalized.get("item")
152-
if isinstance(nested_item, Mapping):
153-
nested_copy = dict(nested_item)
154-
nested_copy.pop("id", None)
155-
normalized["item"] = nested_copy
156143
return normalized
157144

158145
def _is_opencode_system_prompt_item(self, item: Mapping[str, Any]) -> bool:
@@ -299,12 +286,16 @@ def append_incompatible_tool_steering(
299286
context,
300287
)
301288
instructions = result.get("instructions")
302-
if isinstance(instructions, str) and steering in instructions:
289+
if (
290+
isinstance(instructions, str)
291+
and _OPENCODE_INCOMPATIBLE_MARKER in instructions
292+
):
303293
return result
304-
if isinstance(instructions, str) and instructions.strip():
305-
result["instructions"] = f"{instructions.rstrip()}\n\n{steering}"
306-
else:
307-
result["instructions"] = steering
294+
result["instructions"] = self._append_instruction_block(
295+
instructions if isinstance(instructions, str) else "",
296+
marker=_OPENCODE_INCOMPATIBLE_MARKER,
297+
block=steering,
298+
)
308299
return result
309300

310301
def _resolve_supported_tool_names(self, context: CodexRequestContext) -> set[str]:
@@ -360,3 +351,16 @@ def _build_incompatible_tool_steering(
360351
"- For shell execution, arguments MUST be a JSON object with string "
361352
"`command` and string `description`."
362353
)
354+
355+
@staticmethod
356+
def _append_instruction_block(
357+
instructions: str,
358+
*,
359+
marker: str,
360+
block: str,
361+
) -> str:
362+
if marker in instructions:
363+
return instructions
364+
if instructions.strip():
365+
return f"{instructions.rstrip()}\n\n{block}"
366+
return block

0 commit comments

Comments
 (0)