콘텐츠로 이동

Codex 프로바이더

AbstractAdapter는 의도적으로 작으며, 두 번째 어댑터가 존재하기 전까지 그대로 유지됩니다. 단일 구현에서 뽑아낸 계약은 추측입니다. 커밋할 가치가 있는 형태는 두 번째를 견뎌 낸 것입니다.

Codex는 그 두 번째 구현으로 가장 유력한 후보입니다. 옮겨 올 만큼 가깝고, 계약이 가장 약한 지점 — 세션 정체성, 인증, 권한의 어휘 — 을 밀어붙일 만큼 다르기 때문입니다.

여기 있는 어떤 것도 실제 바이너리를 상대로 검증되지 않았습니다. 아래는 이 CLI를 붙이는 통합들이 보통 어떤 파라미터로 매개변수화되는지에서 끌어온, 어댑터가 시험하게 될 예상입니다.

CLI send가 필요로 할 것으로 예상되는 파라미터
Claude sessionId, disableThinking, agentPrompt
Codex threadId, baseUrl, apiKey, serviceTier

여기서 두 가지 예상이 따라 나오며, 이 어댑터가 흥미로운 이유가 그것입니다.

  • Codex는 대화를 sessionId가 아니라 threadId로 식별할 것으로 예상됩니다. 이것이야말로 SpawnOptions가 흡수하기 위해 존재하는 종류의 차이입니다 — 어떤 CLI는 이것을 session이라 부르고 다른 CLI는 thread라 부른다는 사실을 알아야 하는 호출자는 추상화를 제공받고 있는 것이 아닙니다.
  • Codex는 baseUrl, apiKey, serviceTier를 받을 것으로 예상됩니다. Claude의 어댑터는 이 중 무엇도 받지 않습니다. 이것들이 SpawnOptions에 속하는지, 환경변수에 속하는지, 아직 존재하지 않는 어딘가에 속하는지는 결정되지 않았습니다.

커맨드 목록의 크기도 다를 것으로 예상되며, 이것이 계약이 밀리게 될 두 번째 지점입니다.

codex CLI에 관한 어떤 것도 실제 바이너리를 상대로 검증되지 않았습니다 — 위의 예상까지 포함해서입니다. 구체적으로 다음은 아직 조사되지 않았습니다.

  • 어느 플래그가 이것을 제어 가능한 양방향 스트림으로 만드는지, 그리고 --input-format stream-json에 해당하는 것이 있는지.
  • 출력이 type 판별자를 가진 NDJSON인지 — 그렇다면 EventParser가 그대로 동작합니다 — 아니면 parseLine에서 번역이 필요한 무언가인지.
  • 권한 또는 샌드박스 어휘, 그리고 PermissionMode의 모든 멤버를 그것으로 표기할 수 있는지.
  • mcp와 auth 서브커맨드를 드러내는지, 그리고 어떤 형태로인지.
  • 자신의 모드를 되보고하는지. reportedMode()가 이에 의존합니다.

이식 순서는 고정되어 있고, 3단계가 이 작업의 요점입니다.

  1. CLI의 실제 동작에 맞춰 어댑터를 정확히 이식한다.
  2. 기존 계약을 우회해야 했던 모든 지점을 기록한다 — 특히 Auth/와 Mcp/, 그리고 PermissionMode가 맞지 않았던 모든 곳.
  3. 두 구현에서 공통 형태를 추출한다.
  4. 그 뒤에야 AbstractAdapter를 넓힌다.

command.auth와 command.mcp가 압력이 가장 먼저 도달할 곳으로 예상됩니다. 이들은 현재 Claude 형태입니다. claude auth status --json과 claude mcp list를 실행하고 그 출력을 파싱합니다. 프로바이더의 name으로 생성되므로 다른 CLI를 상대로 실행되기는 하지만, 그 CLI가 서브커맨드를 다르게 표기한다면 쓸모 있는 것을 내놓지 못합니다.

그것은 우회할 일이 아니라 제기할 발견입니다. 파서를 포크하거나 그 안에서 프로바이더 이름을 특수 처리하는 것은 추상화 경계가 실제로 어디에 있어야 하는지에 대한 근거를 숨기는 일입니다.

Command는 가장 적게 바뀌어야 할 부분입니다. 이것은 의도로 말합니다 — 메시지, 모델, 권한 모드 — 그리고 그중 어느 단어도 Claude의 것이 아닙니다. Codex를 이식하면서 거기에 변경이 강요된다면, 그것이 이 작업 전체에서 가장 흥미로운 발견이며 기록해 둘 가치가 있습니다.