refactor: archive openai-compatible-provider-passthrough files and update configs
- Move openai-compatible-provider-passthrough contract sync milestone and SDD to archive - Update agent-spec for openai-compatible surface and edge-node-execution - Update routing policy model orchestration phase - Sync agent-test/dev/inventory.yaml - Update .env.example files - Update configs/edge.yaml and docker-compose.yml
This commit is contained in:
parent
c839ea7c66
commit
0239ae9063
12 changed files with 42 additions and 43 deletions
|
|
@ -11,6 +11,7 @@ IOP_EDGE_METRICS_PORT=19102
|
|||
IOP_WEB_PORT=13002
|
||||
IOP_PROMETHEUS_PORT=19112
|
||||
IOP_PROMETHEUS_CONFIG=./configs/prometheus/prometheus.dev-corp.yml
|
||||
IOP_PROMETHEUS_RETENTION_TIME=400d
|
||||
IOP_GRAFANA_BIND=127.0.0.1
|
||||
IOP_GRAFANA_PORT=19122
|
||||
IOP_GRAFANA_ADMIN_USER=admin
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ IOP_EDGE_METRICS_PORT=19101
|
|||
IOP_WEB_PORT=13001
|
||||
IOP_PROMETHEUS_PORT=19111
|
||||
IOP_PROMETHEUS_CONFIG=./configs/prometheus/prometheus.dev.yml
|
||||
IOP_PROMETHEUS_RETENTION_TIME=400d
|
||||
IOP_GRAFANA_BIND=127.0.0.1
|
||||
IOP_GRAFANA_PORT=19121
|
||||
IOP_GRAFANA_ADMIN_USER=admin
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ IOP_EDGE_NODE_PORT=19090
|
|||
IOP_EDGE_METRICS_PORT=19092
|
||||
IOP_WEB_PORT=13000
|
||||
IOP_PROMETHEUS_PORT=19110
|
||||
IOP_PROMETHEUS_RETENTION_TIME=400d
|
||||
IOP_GRAFANA_BIND=127.0.0.1
|
||||
IOP_GRAFANA_PORT=19120
|
||||
IOP_GRAFANA_ADMIN_USER=admin
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
## 위치
|
||||
|
||||
- Roadmap: [ROADMAP.md](../../../ROADMAP.md)
|
||||
- Phase: [PHASE.md](../PHASE.md)
|
||||
- Roadmap: [ROADMAP.md](../../../../ROADMAP.md)
|
||||
- Phase: [PHASE.md](../../../../phase/routing-policy-model-orchestration/PHASE.md)
|
||||
|
||||
## 목표
|
||||
|
||||
|
|
@ -12,7 +12,7 @@ OpenAI-compatible provider 경로를 request `model`이 가리키는 provider ca
|
|||
|
||||
## 상태
|
||||
|
||||
[검토중]
|
||||
[완료]
|
||||
|
||||
## 승격 조건
|
||||
|
||||
|
|
@ -68,15 +68,15 @@ vLLM, vLLM-MLX, Lemonade, SGLang, Seulgivibe 같은 OpenAI-compatible provider
|
|||
|
||||
## 완료 리뷰
|
||||
|
||||
- 상태: 검토중
|
||||
- 상태: 통과
|
||||
- 요청일: 2026-07-14
|
||||
- 완료 근거: `provider-error`, `policy-priority`는 local fake provider/fixture 기반 회귀 테스트와 `GOCACHE=/tmp/iop-go-cache go test ./apps/edge/internal/openai ./apps/edge/internal/service ./apps/node/internal/adapters/openai_compat` 통과로 충족했다. `devcorp-smoke`는 사용자 승인 동등 환경인 dev gx10에서 direct provider와 IOP dev Edge 경유 모두 `chat_template_kwargs.enable_thinking=false` streaming smoke가 HTTP 200, first content 약 0.1s, reasoning chunk 0개, finish_reason `stop`으로 통과했고 Edge 로그가 `provider_id=gx10-vllm`, `execution_path=provider_tunnel`을 기록했다.
|
||||
- 완료 근거: `provider-error`, `policy-priority`는 local fake provider/fixture 기반 회귀 테스트와 `GOCACHE=/tmp/iop-go-cache go test ./apps/edge/internal/openai ./apps/edge/internal/service ./apps/node/internal/adapters/openai_compat` 통과로 충족했다. `devcorp-smoke`는 사용자 승인 동등 환경인 dev gx10에서 direct provider와 IOP dev Edge 경유 모두 `chat_template_kwargs.enable_thinking=false` streaming smoke가 HTTP 200, first content 약 0.1s, reasoning chunk 0개, finish_reason `stop`으로 통과했고 Edge 로그가 `provider_id=gx10-vllm`, `execution_path=provider_tunnel`을 기록했다. 2026-07-14 종료 감사에서 selector surface 검색, 대상 Go 테스트, 전체 `go test ./...`, `git diff --check`가 통과했고 agent-spec 동기화를 완료했다.
|
||||
- 검토 항목:
|
||||
- [x] 모든 기능 Task와 Task별 검증 evidence가 `Roadmap Completion` 또는 완료 리뷰 수동 검증 evidence에 남아 있다.
|
||||
- [x] SDD Evidence Map이 최종 검증 evidence와 일치한다.
|
||||
- [x] dev gx10 smoke 결과가 문서화되어 있다.
|
||||
- agent-ui 상태 반영: 해당 없음
|
||||
- 리뷰 코멘트: 남은 완료 차단 항목 없음. `[완료]` 전환과 archive는 별도 Milestone 종료 검토 흐름에서 처리한다.
|
||||
- 리뷰 코멘트: 남은 완료 차단 항목 없음. Spec sync: Spec updated ([openai-compatible-surface](../../../../../agent-spec/input/openai-compatible-surface.md), [index](../../../../../agent-spec/index.md)).
|
||||
|
||||
## 범위 제외
|
||||
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
## 위치
|
||||
|
||||
- Milestone: [Milestone 문서](../../../phase/routing-policy-model-orchestration/milestones/openai-compatible-provider-passthrough-contract-sync.md)
|
||||
- Phase: [PHASE.md](../../../phase/routing-policy-model-orchestration/PHASE.md)
|
||||
- Phase: [PHASE.md](../../../../phase/routing-policy-model-orchestration/PHASE.md)
|
||||
|
||||
## 상태
|
||||
|
||||
|
|
@ -30,8 +30,8 @@
|
|||
| 영역 | 기준 | 메모 |
|
||||
|------|------|------|
|
||||
| Roadmap | [Milestone 문서](../../../phase/routing-policy-model-orchestration/milestones/openai-compatible-provider-passthrough-contract-sync.md) | 목표, 범위, 기능 Task, 완료 evidence 기준 |
|
||||
| Outer Contract | [openai-compatible-api.md](../../../../agent-contract/outer/openai-compatible-api.md) | OpenAI-compatible public request/response 계약 |
|
||||
| Inner Wire Contract | [edge-node-runtime-wire.md](../../../../agent-contract/inner/edge-node-runtime-wire.md) | Edge-Node provider tunnel body/frame 책임 |
|
||||
| Outer Contract | [openai-compatible-api.md](../../../../../agent-contract/outer/openai-compatible-api.md) | OpenAI-compatible public request/response 계약 |
|
||||
| Inner Wire Contract | [edge-node-runtime-wire.md](../../../../../agent-contract/inner/edge-node-runtime-wire.md) | Edge-Node provider tunnel body/frame 책임 |
|
||||
| Code | `apps/edge/internal/openai`, `apps/edge/internal/service`, `apps/node/internal/adapters/openai_compat` | 구현 source of truth |
|
||||
| External Provider | dev-corp Spark Ornith/vLLM provider 또는 dev gx10 Ornith/vLLM provider | provider-native field passthrough smoke 대상. 사용자가 dev gx10 동등 검증을 허용했다. |
|
||||
| User Decision | 현재 사용자 설계 의도 | `model` 기반 route, metadata known-key read-only 발췌, provider-native payload 보존 |
|
||||
|
|
@ -50,7 +50,7 @@
|
|||
|
||||
## Interface Contract
|
||||
|
||||
- 계약 원문: [openai-compatible-api.md](../../../../agent-contract/outer/openai-compatible-api.md)
|
||||
- 계약 원문: [openai-compatible-api.md](../../../../../agent-contract/outer/openai-compatible-api.md)
|
||||
- 입력:
|
||||
- `model`: route/provider capability 선택의 1차 source of truth
|
||||
- `messages` 또는 `input`: endpoint별 OpenAI-compatible request payload
|
||||
|
|
@ -28,9 +28,9 @@ IOP의 OpenAI-compatible, A2A, IOP native 입력 표면에서 들어온 요청
|
|||
- 경로: [model-group-mixed-provider-dispatch](../../archive/phase/routing-policy-model-orchestration/milestones/model-group-mixed-provider-dispatch.md)
|
||||
- 요약: model group provider pool에서 OpenAI-compatible provider와 Ollama/CLI 같은 normalized provider를 같은 후보군으로 두고, 기존 capacity+priority 선택 뒤 OpenAI-compatible 지원 provider는 모두 passthrough, native provider는 normalized 실행 경로로 자동 결정한다.
|
||||
|
||||
- [검토중] OpenAI-compatible Provider Passthrough 계약 동기화
|
||||
- 경로: [openai-compatible-provider-passthrough-contract-sync](milestones/openai-compatible-provider-passthrough-contract-sync.md)
|
||||
- 요약: 사용자 설계 의도에 맞춰 `model` 기반 provider capability routing을 source of truth로 두고, OpenAI-compatible provider의 provider-native payload를 Edge allowlist 없이 raw tunnel로 보존하며, metadata는 IOP known-key를 read-only로 발췌하는 container로만 정리한다.
|
||||
- [완료] OpenAI-compatible Provider Passthrough 계약 동기화
|
||||
- 경로: [openai-compatible-provider-passthrough-contract-sync](../../archive/phase/routing-policy-model-orchestration/milestones/openai-compatible-provider-passthrough-contract-sync.md)
|
||||
- 요약: 사용자 설계 의도에 맞춰 `model` 기반 provider capability routing을 source of truth로 두고, OpenAI-compatible provider의 provider-native payload를 Edge allowlist 없이 raw tunnel로 보존하며, metadata는 IOP known-key를 read-only로 발췌하는 container로만 정리했다. 종료 감사에서 code audit, local Go tests, spec sync를 통과해 archive했다.
|
||||
|
||||
- [스케치] OpenAI-compatible 하이브리드 라우팅과 컨텍스트 최적화
|
||||
- 경로: [openai-compatible-hybrid-routing-context-optimization](milestones/openai-compatible-hybrid-routing-context-optimization.md)
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ AI agent가 작업 전에 읽는 지도이기도 하지만, 사람도 "지금
|
|||
|
||||
- 실행 경로: Edge와 Node 사이의 등록, 실행, 이벤트, provider raw tunnel, 취소, command 흐름은 `runtime/edge-node-execution`에서 본다.
|
||||
- 런타임 라우팅/설정: provider-pool, `models[]`, `nodes[].providers[]`, live config refresh는 `runtime/provider-pool-config-refresh`에서 본다.
|
||||
- 외부 HTTP 입력: OpenAI-compatible 호출, response mode/raw tunnel은 `input/openai-compatible-surface`, A2A JSON-RPC 호출은 `input/a2a-json-rpc-surface`에서 본다.
|
||||
- 외부 HTTP 입력: OpenAI-compatible 호출, model-driven raw tunnel은 `input/openai-compatible-surface`, A2A JSON-RPC 호출은 `input/a2a-json-rpc-surface`에서 본다.
|
||||
- 운영 제어: Control Plane, Edge enrollment, fleet/edge status, Flutter Client 상태 소비는 `control/control-plane-operations`에서 본다.
|
||||
|
||||
## 스펙 목록
|
||||
|
|
@ -33,7 +33,7 @@ AI agent가 작업 전에 읽는 지도이기도 하지만, 사람도 "지금
|
|||
|----|------|-----------|------|-----------|
|
||||
| `runtime/edge-node-execution` | 부분 | Edge-Node TCP/protobuf transport, Node 등록, run/cancel/command, provider raw tunnel, adapter 실행, Node local run store를 확인할 때 | `agent-spec/runtime/edge-node-execution.md` | `agent-contract/inner/edge-node-runtime-wire.md`, `apps/edge/internal/service/run_dispatch.go`, `apps/node/internal/node/node.go` |
|
||||
| `runtime/provider-pool-config-refresh` | 부분 | `models[]`, `nodes[].providers[]`, provider-pool dispatch, long-context admission, Edge/Node config refresh를 확인할 때 | `agent-spec/runtime/provider-pool-config-refresh.md` | `agent-contract/inner/edge-config-runtime-refresh.md`, `packages/go/config/config.go`, `apps/edge/internal/configrefresh/classify.go` |
|
||||
| `input/openai-compatible-surface` | 부분 | `/v1/models`, `/v1/chat/completions`, `/v1/responses`, OpenAI-compatible auth/metadata/workspace/tool handling, response mode/raw tunnel, usage metric, 외부 `model` route를 확인할 때 | `agent-spec/input/openai-compatible-surface.md` | `agent-contract/outer/openai-compatible-api.md`, `apps/edge/internal/openai/chat_handler.go`, `apps/edge/internal/openai/stream.go`, `apps/edge/internal/openai/usage_metrics.go` |
|
||||
| `input/openai-compatible-surface` | 부분 | `/v1/models`, `/v1/chat/completions`, `/v1/responses`, OpenAI-compatible auth/metadata/workspace/tool handling, model-driven raw tunnel, usage metric, 외부 `model` route를 확인할 때 | `agent-spec/input/openai-compatible-surface.md` | `agent-contract/outer/openai-compatible-api.md`, `apps/edge/internal/openai/chat_handler.go`, `apps/edge/internal/openai/stream.go`, `apps/edge/internal/openai/usage_metrics.go` |
|
||||
| `input/a2a-json-rpc-surface` | 부분 | Edge A2A JSON-RPC, `message/send`, `tasks/get`, `tasks/cancel`, A2A task store와 bearer auth를 확인할 때 | `agent-spec/input/a2a-json-rpc-surface.md` | `agent-contract/outer/a2a-json-rpc-api.md`, `apps/edge/internal/input/a2a/server.go`, `apps/edge/internal/input/a2a/task_store.go` |
|
||||
| `control/control-plane-operations` | 부분 | Control Plane-Edge wire, Client-Control Plane wire, Control Plane HTTP Edge/fleet status view, Flutter Client status consumer를 확인할 때 | `agent-spec/control/control-plane-operations.md` | `agent-contract/inner/control-plane-edge-wire.md`, `agent-contract/inner/client-control-plane-wire.md`, `apps/control-plane/internal/wire/edge_server.go` |
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ source_evidence:
|
|||
notes: Chat Completions request validation, route dispatch, tool/reasoning 정책
|
||||
- type: code
|
||||
path: apps/edge/internal/openai/stream.go
|
||||
notes: Chat Completions streaming, provider raw tunnel passthrough, sideband/transformed response mode 처리
|
||||
notes: Chat Completions streaming, provider raw tunnel passthrough 처리
|
||||
- type: code
|
||||
path: apps/edge/internal/openai/responses_handler.go
|
||||
notes: Responses API request validation, metadata/workspace 처리, non-stream completion
|
||||
|
|
@ -60,14 +60,14 @@ Edge가 OpenAI-compatible HTTP 요청을 받아 내부 `adapter + target` 실행
|
|||
| 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를 지원한다. |
|
||||
| Chat Completions response mode | provider-pool model group route는 `metadata.iop_response_mode` 생략 시 `passthrough`로 동작하고, 명시적 selector는 값과 무관하게 거부한다. direct legacy provider route는 명시적 `passthrough+sideband` extension을 지원하며 `transformed`는 거부한다. |
|
||||
| provider raw passthrough | `passthrough`는 provider status/header/body bytes를 기존 Edge-Node tunnel로 relay하고 pure response body에 IOP sideband를 섞지 않는다. |
|
||||
| sideband extension | direct legacy provider route의 `passthrough+sideband`는 provider body와 IOP route/usage/assembled observation을 명시적 extension stream/envelope로 함께 노출한다. Responses `passthrough+sideband`는 응답 `metadata` 또는 `event: iop.sideband`를 확장 지점으로 사용한다. 둘 다 provider-original byte identity로 표시하지 않는다. |
|
||||
| model-driven response path | request `model`이 가리키는 provider capability가 provider raw tunnel 또는 normalized RunEvent path를 결정한다. caller metadata는 route나 response shape를 선택하지 않는다. |
|
||||
| provider raw passthrough | `passthrough`는 provider status/header/body bytes를 기존 Edge-Node tunnel로 relay하고 pure response body에 IOP 확장 envelope를 섞지 않는다. |
|
||||
| provider-native field 보존 | provider raw tunnel route는 `model` served target rewrite와 auth/header 처리 외에 selected provider가 지원하는 OpenAI-compatible 표준 field와 provider extension field를 보존한다. |
|
||||
| OpenAI usage metering | Edge는 OpenAI-compatible request terminal status와 provider-reported `input`, `output`, `reasoning`, `cached_input` token usage를 Prometheus counter로 집계한다. |
|
||||
| reasoning observation metric | provider가 reasoning token을 보고하지 않고 reasoning text만 관측되면 token 추정 없이 관측 횟수와 character count 보조 metric만 emit한다. |
|
||||
| Grafana usage surface | 1차 조회 표면은 Prometheus/Grafana query guide이며 daily/monthly rollup, usage origin breakdown, operator-managed cloud price baseline, cloud-equivalent cost, avoided-cost ROI 기준을 문서로 제공한다. Control Plane/Client dashboard와 request-level ledger는 후속 범위다. |
|
||||
| Responses API | normalized(non-provider) `/v1/responses`는 string input의 non-streaming 요청만 지원한다. provider model group route는 `/v1/responses`를 raw passthrough로 provider `POST /v1/responses`에 전달한다. |
|
||||
| Responses provider passthrough | provider-pool model group route의 `/v1/responses`는 `metadata.iop_response_mode` 명시를 거부하고, 생략 시 `model`만 served target으로 rewrite해 unknown/Codex field와 `stream:true` raw SSE를 provider로 relay한다. direct legacy provider route의 명시적 `passthrough+sideband`는 non-stream 응답의 top-level `metadata` 또는 streaming `event: iop.sideband`를 확장 지점으로 사용한다. usage metric은 endpoint=`responses`, response_mode=`passthrough` 또는 direct sideband route의 `passthrough+sideband`, model_group=request alias로 집계한다. |
|
||||
| Responses provider passthrough | provider-pool model group route와 direct OpenAI-compatible provider route의 `/v1/responses`는 provider raw tunnel을 사용한다. Edge는 `model`만 served target으로 rewrite하고 unknown/Codex field와 `stream:true` raw SSE를 provider로 relay한다. usage metric은 endpoint=`responses`, response_mode=`passthrough`, model_group=request alias로 집계한다. |
|
||||
| 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`으로 전파한다. |
|
||||
|
|
@ -88,13 +88,13 @@ sequenceDiagram
|
|||
|
||||
Caller->>OpenAI: chat/responses request(model)
|
||||
OpenAI->>OpenAI: auth, metadata, route 검증
|
||||
alt provider route + passthrough mode
|
||||
alt selected provider supports OpenAI-compatible passthrough
|
||||
OpenAI->>Service: SubmitProviderTunnel(ProviderPool/direct)
|
||||
Service->>Runtime: ProviderTunnelRequest
|
||||
Runtime-->>Service: ProviderTunnelFrame stream
|
||||
Service-->>OpenAI: tunnel frames
|
||||
OpenAI-->>Caller: provider-original bytes or sideband extension
|
||||
else transformed/normalized path
|
||||
OpenAI-->>Caller: provider status/header/body bytes
|
||||
else selected provider uses normalized execution
|
||||
OpenAI->>Service: SubmitRun(adapter/target or ProviderPool)
|
||||
Service->>Runtime: RunRequest
|
||||
Runtime-->>Service: RunEvent stream
|
||||
|
|
@ -116,10 +116,9 @@ sequenceDiagram
|
|||
- provider-pool model group은 capacity + priority + availability 기준으로 provider candidate를 먼저 선택하고, 선택된 provider가 OpenAI-compatible 호출 방식을 지원하면 raw tunnel passthrough로 dispatch한다. Ollama/CLI/native provider가 선택되면 normalized `RunRequest` path로 dispatch한다.
|
||||
- `openai.provider_auth`는 provider tunnel forwarding rule만 저장하고 raw provider token 값은 request-time header에서만 읽는다. inbound IOP `Authorization` header를 provider token source로 재사용하지 않는다.
|
||||
- OpenAI request의 `metadata.workspace`는 absolute path가 필요한 route에서만 필수 검증된다.
|
||||
- provider-pool model group Chat Completions와 Responses request는 `metadata.iop_response_mode`를 명시하면 `passthrough`, `passthrough+sideband`, `transformed`, unknown 모두 거부한다. 생략하면 `passthrough`다.
|
||||
- direct legacy provider route는 `metadata.iop_response_mode` 생략 또는 `passthrough`를 raw tunnel로 처리하고, `passthrough+sideband`를 extension surface로 지원한다. provider tunnel route의 `transformed`는 지원하지 않는다.
|
||||
- Chat Completions와 Responses request는 caller metadata로 provider raw tunnel과 normalized response shape를 선택하지 않는다. route/provider capability만 실행 경로를 결정한다.
|
||||
- run metadata에는 `openai_model`, `openai_stream`, `strict_output`, `estimated_input_tokens`, `context_class`가 들어갈 수 있다.
|
||||
- provider tunnel metadata에는 response mode와 routing context가 들어가고, direct sideband mode는 route/usage/assembled observation을 확장 surface로 만든다.
|
||||
- provider tunnel metadata에는 routing context와 관측 후보가 들어갈 수 있으며, provider body에는 합쳐지지 않는다.
|
||||
- Node complete event metadata의 `openai_tool_calls`와 `openai_text_tool_fallback`은 response tool call 복원에 쓰인다.
|
||||
- usage metric은 `iop_openai_requests_total`, `iop_openai_usage_tokens_total`, `iop_openai_reasoning_observed_total`, `iop_openai_reasoning_chars_total`로 emit된다.
|
||||
- usage label은 `edge_id`, `principal_ref`, `principal_alias`, `token_ref`, `model_group`, `endpoint`, `response_mode`, `status`, `usage_source`, `token_type`처럼 낮은 cardinality 값만 사용한다.
|
||||
|
|
@ -131,7 +130,7 @@ sequenceDiagram
|
|||
|
||||
- `go test ./apps/edge/internal/openai`
|
||||
- `go test ./apps/edge/internal/service`
|
||||
- `go test ./apps/edge/internal/openai -run 'Sideband|UsageMetrics|ToolValidation|Dispatch|Reasoning|Retry'`
|
||||
- `go test ./apps/edge/internal/openai -run 'Tunnel|UsageMetrics|ToolValidation|Dispatch|Reasoning|Retry'`
|
||||
- `rg --fixed-strings "cloud_equivalent_cost" docs/openai-usage-grafana.md`
|
||||
- `make test-openai-ollama`
|
||||
- provider별 실제 runtime smoke는 환경별 agent-test/dev 또는 dev-corp profile을 따른다.
|
||||
|
|
@ -142,10 +141,8 @@ sequenceDiagram
|
|||
- `/v1/completions`는 제공하지 않는다.
|
||||
- OpenAI-compatible request에 provider/Ollama 전용 root field를 추가하지 않는다.
|
||||
- workspace는 prompt 본문에 섞지 않고 metadata에서 분리한다.
|
||||
- pure `passthrough` body는 provider-original byte stream이며 IOP sideband나 transformed label을 포함하지 않는다.
|
||||
- direct legacy provider route의 `passthrough+sideband`와 non-provider normalized route의 `transformed`는 provider-original byte identity로 취급하지 않는다.
|
||||
- provider-pool model group route는 `metadata.iop_response_mode`를 request selector로 받지 않는다.
|
||||
- direct legacy Responses provider route의 `passthrough+sideband`는 Chat Completions sideband envelope를 쓰지 않는다. non-streaming JSON object 응답은 `metadata` object를 병합하고, streaming 응답은 `event: iop.sideband`를 끼운다.
|
||||
- pure `passthrough` body는 provider-original byte stream이며 IOP 확장 envelope나 normalized label을 포함하지 않는다.
|
||||
- provider route와 non-provider normalized route의 차이는 selected provider capability에서 파생되며 caller metadata selector로 고르지 않는다.
|
||||
- text tool-call synthesis는 요청 `tools[]` schema를 기준으로만 수행한다. 자연어 추론으로 tool call을 만들지 않는다.
|
||||
- private token이나 endpoint 원문은 tracked spec/docs에 남기지 않는다.
|
||||
- `metadata.user`는 identity source가 아니며 사용되지 않는다.
|
||||
|
|
@ -160,11 +157,11 @@ sequenceDiagram
|
|||
|
||||
- 2026-07-07: 현재 코드와 OpenAI-compatible 계약 기준으로 bootstrap spec 작성.
|
||||
- 2026-07-07: 기능 목록 중심으로 축소하고 주요 흐름을 Mermaid sequence diagram으로 정리.
|
||||
- 2026-07-08: Chat Completions provider raw tunnel, response mode, sideband/transformed semantics를 현재 코드와 계약 기준으로 반영.
|
||||
- 2026-07-08: Chat Completions provider raw tunnel과 normalized execution semantics를 현재 코드와 계약 기준으로 반영.
|
||||
- 2026-07-10: principal token 기반 usage metering, Prometheus metric, Grafana query guide, reasoning/cached token breakdown을 Milestone completion evidence 기준으로 반영.
|
||||
- 2026-07-10: 일별 Usage 비용/ROI 리포트 MVP 종료 검토에서 daily/monthly rollup, usage origin breakdown, cloud-equivalent cost, avoided-cost ROI 문서 표면을 반영.
|
||||
- 2026-07-11: provider model group `/v1/responses` raw passthrough 동작(모델 rewrite, unknown/Codex field 보존, streaming relay, provider auth forwarding)과 endpoint=`responses` usage metric label을 현재 코드 기준으로 반영.
|
||||
- 2026-07-11: Responses provider route의 명시적 `passthrough+sideband` 동작을 반영. non-stream은 응답 `metadata`, stream은 `event: iop.sideband`를 확장 지점으로 사용한다.
|
||||
- 2026-07-11: Responses provider route의 provider raw tunnel 동작을 반영했다.
|
||||
- 2026-07-11: provider auth forwarding과 Seulgivibe OpenAI-compatible provider family surface를 종료 검토 기준으로 보강.
|
||||
- 2026-07-12: provider-pool model group route에서 명시적 `metadata.iop_response_mode`를 거부하고, direct legacy provider route에서만 sideband extension selector를 유지하는 현재 surface를 반영.
|
||||
- 2026-07-12: Model Group Mixed Provider Dispatch 종료 검토 기준으로 selected provider capability 기반 passthrough/normalized 실행 경로를 반영.
|
||||
- 2026-07-14: OpenAI-compatible Provider Passthrough 계약 동기화 종료 검토 기준으로 caller-facing response selector 설명을 제거하고, `model` 기반 route와 provider-native field 보존 기준을 반영.
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ sequenceDiagram
|
|||
- Edge의 node source of truth는 `configs/edge.yaml`과 `packages/go/config`의 `nodes[]` 구조다.
|
||||
- `RunEvent`는 adapter execution stream이고, `EdgeNodeEvent`는 node lifecycle/control event다.
|
||||
- `ProviderTunnelFrame.body`는 OpenAI-compatible provider passthrough의 source of truth이며 `RunEvent.delta`나 Edge event bus payload로 보내지 않는다.
|
||||
- `ProviderTunnelFrame.usage`와 `metadata`는 sideband observation 후보이며 pure passthrough body에 합쳐지지 않는다.
|
||||
- `ProviderTunnelFrame.usage`와 `metadata`는 관측 후보이며 pure passthrough body에 합쳐지지 않는다.
|
||||
- provider-pool mixed dispatch에서 `ProviderTunnelRequest`와 `RunRequest` 중 어느 wire를 사용할지는 selected provider capability에서 파생되며, client request metadata selector로 결정하지 않는다.
|
||||
- `Usage.reasoning_tokens`와 `Usage.cached_input_tokens`는 provider가 별도 보고한 경우에만 채워지는 optional breakdown이다.
|
||||
- Node local DB는 기본 `file:iop.db?cache=shared&mode=rwc`로 열린다.
|
||||
|
|
|
|||
|
|
@ -350,10 +350,10 @@ model:
|
|||
expected_long_context_capacity: 2
|
||||
validation_basis: Same Lemonade llama.cpp backend and current Ornith Q5 runtime validated --kv-unified with auto slots reporting n_ctx 262144; Qwen still needs smoke validation after it is reloaded.
|
||||
separation_note: These alignment rules are for the dev Qwen3.6 provider pool only. Gemma4 and DiffusionGemma use separate provider/model profiles and must not inherit Qwen parser/template/context assumptions.
|
||||
response_mode:
|
||||
provider_passthrough:
|
||||
default: pure_passthrough
|
||||
selector: metadata.iop_response_mode omitted or passthrough
|
||||
verification: Chat Completions streaming probe returned HTTP 200 with no X-IOP-Response-Mode header and no iop.sideband marker; the same endpoint with metadata.iop_response_mode=passthrough+sideband returned X-IOP-Response-Mode=passthrough+sideband and iop.sideband, confirming mode separation.
|
||||
selector: none; request model/provider capability determines passthrough vs normalized execution
|
||||
verification: Chat Completions streaming probe returned HTTP 200 through the provider tunnel with provider body preserved and no IOP response envelope injected.
|
||||
provider_pool_routing:
|
||||
observed_at: "2026-07-09"
|
||||
caller_shape: Pi-compatible OpenAI Chat Completions streaming requests to provider/model iop/qwen3.6:35b
|
||||
|
|
|
|||
|
|
@ -82,11 +82,9 @@ openai:
|
|||
# target_header: "Authorization"
|
||||
# scheme: "Bearer"
|
||||
# required: true
|
||||
# Provider-pool model group routes do not accept metadata.iop_response_mode
|
||||
# as a caller selector. The selected provider determines the execution path:
|
||||
# OpenAI-compatible providers use passthrough, Ollama/CLI/native providers use
|
||||
# normalized execution. Direct legacy provider routes may still opt into the
|
||||
# documented passthrough+sideband extension per request metadata.
|
||||
# The selected provider determines the execution path: OpenAI-compatible
|
||||
# providers use passthrough, while Ollama/CLI/native providers use normalized
|
||||
# execution. Caller metadata does not select the route or response shape.
|
||||
node: ""
|
||||
adapter: "ollama"
|
||||
target: ""
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ services:
|
|||
command:
|
||||
- "--config.file=/etc/prometheus/prometheus.yml"
|
||||
- "--storage.tsdb.path=/prometheus"
|
||||
- "--storage.tsdb.retention.time=${IOP_PROMETHEUS_RETENTION_TIME:-400d}"
|
||||
- "--web.enable-lifecycle"
|
||||
ports:
|
||||
- "${IOP_PROMETHEUS_BIND:-127.0.0.1}:${IOP_PROMETHEUS_PORT:-19110}:9090"
|
||||
|
|
|
|||
Loading…
Reference in a new issue