Files
free-claude-code/cli/adapters/base.py
T
Ali Khokhar 8d2e5b95f7 Refactor OpenAI Responses into modular adapter facade (#847)
## Summary

- Split monolithic `core/openai_responses/conversion.py` and `sse.py`
into focused protocol modules (input, output, stream, tools, reasoning,
events, etc.) behind an `OpenAIResponsesAdapter` facade.
- Wire `ClaudeProxyService.create_response()` through the adapter
instead of importing conversion helpers directly, tightening the
API/import boundary.
- Add Codex bridging for Responses `custom_tool_call` items and document
the adapter architecture in `ARCHITECTURE.md`.

## Test plan

- [x] `uv run pytest tests/core/openai_responses/
tests/api/test_openai_responses.py tests/cli/test_adapters.py
tests/contracts/test_import_boundaries.py`
- [x] Full CI via `.\scripts\ci.ps1`
2026-06-17 20:19:51 -07:00

93 lines
2.6 KiB
Python

"""Shared contracts for client CLI subprocess adapters."""
from __future__ import annotations
from collections.abc import Iterable, Mapping
from dataclasses import dataclass, field
from typing import Any, Protocol
@dataclass(frozen=True, slots=True)
class CliTaskRequest:
"""A single prompt execution request for a managed client CLI process."""
prompt: str
session_id: str | None = None
fork_session: bool = False
@dataclass(frozen=True, slots=True)
class CliInvocation:
"""Concrete subprocess invocation assembled by a client CLI adapter."""
argv: tuple[str, ...]
env: dict[str, str]
cwd: str
trace_metadata: dict[str, Any] = field(default_factory=dict)
@dataclass(slots=True)
class CliParseState:
"""Mutable line-parser state for a single client CLI process run."""
log_raw_cli_diagnostics: bool = False
session_id_extracted: bool = False
responses_seen_output_keys: set[str] = field(default_factory=set)
responses_current_output_scope: str | None = None
responses_next_implicit_output_scope: int = 0
class ClientCliAdapter(Protocol):
"""Adapter boundary for client CLI command/env construction and output parsing."""
id: str
display_name: str
default_binary: str
install_hint: str
trace_stage: str
process_launch_event: str
trace_source: str
def build_task_invocation(
self,
*,
config: Any,
request: CliTaskRequest,
base_env: Mapping[str, str],
) -> CliInvocation:
"""Build the subprocess invocation for a managed task run."""
...
def parse_stdout_line(self, line: str, state: CliParseState) -> Iterable[Any]:
"""Parse one stdout line into parser-ready internal CLI events."""
...
def extract_session_id(self, event: Any) -> str | None:
"""Extract a persistent client CLI session id from a parsed event."""
...
def get_launcher_binary_name(self, settings: Any) -> str:
"""Return the configured executable name for a wrapper entrypoint."""
...
def build_launcher_command(
self,
*,
binary_path: str,
argv: Iterable[str],
settings: Any,
proxy_root_url: str,
) -> list[str]:
"""Build the wrapper subprocess command for a client CLI launch."""
...
def build_launcher_env(
self,
*,
proxy_root_url: str,
auth_token: str,
base_env: Mapping[str, str],
) -> dict[str, str]:
"""Build environment variables for a wrapper-launched client CLI."""
...