105 lines
5.5 KiB
Markdown
105 lines
5.5 KiB
Markdown
---
|
|
spec_doc_type: spec
|
|
spec_id: input/openai-compatible-surface
|
|
status: 부분
|
|
source_evidence:
|
|
- type: contract
|
|
path: agent-contract/outer/openai-compatible-api.md
|
|
notes: OpenAI-compatible 외부 HTTP 계약
|
|
- type: code
|
|
path: apps/edge/internal/openai/routes.go
|
|
notes: OpenAI-compatible route와 bearer auth 처리
|
|
- type: code
|
|
path: apps/edge/internal/openai/chat_handler.go
|
|
notes: Chat Completions request validation, route dispatch, tool/reasoning 정책
|
|
- type: code
|
|
path: apps/edge/internal/openai/responses_handler.go
|
|
notes: Responses API request validation, metadata/workspace 처리, non-stream completion
|
|
- type: code
|
|
path: apps/edge/internal/openai/run_result.go
|
|
notes: RunEvent stream을 OpenAI-compatible result로 수집
|
|
- type: test
|
|
path: apps/edge/internal/openai/server_test.go
|
|
notes: OpenAI-compatible route, provider-pool, workspace, tool handling 검증
|
|
---
|
|
|
|
# 스펙: OpenAI-Compatible 입력 표면
|
|
|
|
## 목적
|
|
|
|
Edge가 OpenAI-compatible HTTP 요청을 받아 내부 `adapter + target` 실행으로 넘기는 현재 동작을 설명한다.
|
|
|
|
## 기능 목록
|
|
|
|
| 기능 | 설명 |
|
|
|------|------|
|
|
| OpenAI-compatible HTTP server | `openai.enabled=true`이면 Edge input manager가 `/healthz`, `/v1/models`, `/v1/chat/completions`, `/v1/responses`, `/api/` route를 제공한다. |
|
|
| bearer auth | `openai.bearer_token`이 있으면 matching bearer authorization header를 요구한다. |
|
|
| model catalog | `/v1/models`는 provider-pool `models[]`, legacy `openai.model_routes[]`, `openai.models` 또는 `openai.target` 순서로 노출 모델을 만든다. |
|
|
| model dispatch | request `model`은 provider-pool catalog, legacy model route, single target fallback 순서로 해석된다. |
|
|
| provider-pool handoff | provider-pool catalog에 model이 있으면 service 요청은 `ProviderPool=true`로 전달되고 adapter/target은 provider selection 이후 확정된다. |
|
|
| legacy route 변환 | legacy route는 외부 `model`을 route entry의 `adapter`, `target`, `node`, `session_id`, queue policy로 변환한다. |
|
|
| metadata/workspace 처리 | `metadata.workspace`는 `RunRequest.workspace`로 분리하고, 일반 metadata는 최대 16개 string key/value만 허용한다. |
|
|
| Chat Completions | `/v1/chat/completions`는 non-streaming과 streaming SSE를 지원한다. |
|
|
| Responses API | `/v1/responses`는 현재 string input의 non-streaming 요청만 지원한다. |
|
|
| strict output | strict output이 켜져 있으면 XML completion contract 기반 instruction 또는 prompt prefix를 추가할 수 있다. |
|
|
| tool call 처리 | Chat Completions `tools`는 provider native metadata 복원 또는 text tool-call synthesis/validation 경로를 사용한다. |
|
|
| cancel 전파 | HTTP caller timeout/cancel이 cancel-worthy error이면 Node `CancelRun`으로 전파한다. |
|
|
|
|
## 범위
|
|
|
|
- 포함: OpenAI-compatible HTTP auth, request validation, route resolution, metadata/workspace 처리, chat/responses 변환, provider-pool dispatch handoff, tool/reasoning/strict output 처리.
|
|
- 제외: OpenAI 원문 API 전체 호환, legacy `/v1/completions`, A2A JSON-RPC, Node adapter별 provider HTTP 세부, Control Plane 운영 API.
|
|
|
|
## 주요 흐름
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant Caller
|
|
participant OpenAI as OpenAI handler
|
|
participant Service as Edge service
|
|
participant Runtime as Edge-Node runtime
|
|
|
|
Caller->>OpenAI: chat/responses request(model)
|
|
OpenAI->>OpenAI: auth, metadata, route 검증
|
|
OpenAI->>Service: SubmitRun(adapter/target or ProviderPool)
|
|
Service->>Runtime: RunRequest
|
|
Runtime-->>Service: RunEvent stream
|
|
Service-->>OpenAI: run stream
|
|
OpenAI-->>Caller: OpenAI-compatible response or SSE
|
|
```
|
|
|
|
## 계약
|
|
|
|
- `iop.openai-compatible-api`: `agent-contract/outer/openai-compatible-api.md`
|
|
- 내부 실행 wire: `agent-contract/inner/edge-node-runtime-wire.md`
|
|
- config/provider pool: `agent-contract/inner/edge-config-runtime-refresh.md`
|
|
|
|
## 설정/데이터/이벤트
|
|
|
|
- `configs/edge.yaml`의 `openai` 섹션이 listener, bearer token, legacy adapter/target, model routes, strict output을 제공한다.
|
|
- top-level `models[]`가 있으면 OpenAI model list와 provider-pool dispatch에서 legacy route보다 우선한다.
|
|
- OpenAI request의 `metadata.workspace`는 absolute path가 필요한 route에서만 필수 검증된다.
|
|
- run metadata에는 `openai_model`, `openai_stream`, `strict_output`, `estimated_input_tokens`, `context_class`가 들어갈 수 있다.
|
|
- Node complete event metadata의 `openai_tool_calls`와 `openai_text_tool_fallback`은 response tool call 복원에 쓰인다.
|
|
|
|
## 검증
|
|
|
|
- `go test ./apps/edge/internal/openai`
|
|
- `go test ./apps/edge/internal/service`
|
|
- `make test-openai-ollama`
|
|
- provider별 실제 runtime smoke는 환경별 agent-test/dev 또는 dev-corp profile을 따른다.
|
|
|
|
## 한계와 주의사항
|
|
|
|
- `/v1/responses`는 현재 non-streaming string input만 지원한다.
|
|
- `/v1/completions`는 제공하지 않는다.
|
|
- OpenAI-compatible request에 provider/Ollama 전용 root field를 추가하지 않는다.
|
|
- workspace는 prompt 본문에 섞지 않고 metadata에서 분리한다.
|
|
- text tool-call synthesis는 요청 `tools[]` schema를 기준으로만 수행한다. 자연어 추론으로 tool call을 만들지 않는다.
|
|
- private token이나 endpoint 원문은 tracked spec/docs에 남기지 않는다.
|
|
|
|
## 변경 기록
|
|
|
|
- 2026-07-07: 현재 코드와 OpenAI-compatible 계약 기준으로 bootstrap spec 작성.
|
|
- 2026-07-07: 기능 목록 중심으로 축소하고 주요 흐름을 Mermaid sequence diagram으로 정리.
|