# Milestone: OpenAI-compatible Think 제어 MVP ## 위치 - Roadmap: `agent-roadmap/ROADMAP.md` - Phase: `agent-roadmap/phase/knowledge-tool-optimization-extension/PHASE.md` ## 목표 OpenAI-compatible Chat Completions 요청에서 thinking/reasoning 생성을 요청별로 켜고 끌 수 있게 한다. provider runtime은 reasoning-capable 상태로 유지하되, Edge가 공개 요청 필드를 검증하고 Node provider adapter가 vLLM, vLLM-MLX, Lemonade의 지원 필드로 매핑한다. 호출자가 reasoning 생성을 끄거나 reasoning 응답 노출만 숨길 수 있어야 하며, 지원하지 않는 조합은 조용히 무시하지 않고 명확한 compatibility error 또는 정의된 fallback으로 처리한다. ## 상태 [완료] ## 승격 조건 - 없음 ## 구현 잠금 - 상태: 해제 - SDD: 필요 - SDD 문서: `agent-roadmap/archive/sdd/knowledge-tool-optimization-extension/openai-compatible-think-control/SDD.md` - SDD 사유: OpenAI-compatible request schema, provider option 매핑, streaming response 노출 정책이 바뀌는 API 계약 Milestone이다. - 잠금 해제 조건: - [x] SDD 잠금이 해제되어 있다. - [x] SDD 사용자 리뷰가 없거나 승인/해결되었다. - [x] Acceptance Scenario가 Milestone 기능 Task와 연결되어 있다. - [x] Evidence Map이 완료 시 `Roadmap Completion`과 최종 검증 evidence로 검증 가능하게 연결되어 있다. - 결정 필요: 없음 ## 범위 - `/v1/chat/completions` 요청의 thinking/reasoning 제어 field 수신, 검증, 내부 run input 전달 - `think`, `reasoning_effort`, `thinking_token_budget`, `include_reasoning`의 의미와 충돌 정책 - raw `chat_template_kwargs`는 공개 request field로 직접 열지 않고, Edge/Node가 provider별 내부 option으로 생성하는 매핑 정책 - vLLM Qwen3, vLLM-MLX Qwen3, Lemonade provider의 reasoning-capable runtime에 대한 요청별 option 매핑 - streaming/non-streaming 응답의 `reasoning_content` 노출/억제 정책 - OpenAI-compatible 계약 문서, edge/node 단위 테스트, dev-runtime smoke ## 기능 ### Epic: [think-control] Request-Level Think Control OpenAI-compatible 호출자가 요청 단위로 thinking/reasoning 생성과 노출을 제어하는 capability를 묶는다. - [x] [request-contract] `/v1/chat/completions`가 `think`, `reasoning_effort`, `thinking_token_budget`, `include_reasoning`을 허용하고 타입, 범위, 충돌 조합을 검증한다. 검증: 알 수 없는 provider 전용 wrapper는 계속 400으로 거부되고, 허용 필드는 Edge request decoder와 계약 테스트를 통과한다. - [x] [provider-mapping] Edge run input과 Node `openai_compat` adapter가 요청별 think 설정을 provider별 top-level field 또는 내부 `chat_template_kwargs.enable_thinking`으로 매핑한다. 검증: vLLM Qwen3, vLLM-MLX, Lemonade mock이 같은 요청 플래그에 대해 기대 request body를 받는다. - [x] [reasoning-visibility] `include_reasoning=false`가 provider reasoning 생성 여부와 별개로 OpenAI-compatible 응답의 `reasoning_content` 노출을 억제한다. 검증: stream과 non-stream 응답 모두 reasoning delta/message field가 빠지고 content/tool output은 유지된다. - [x] [default-compat] think 관련 필드가 생략된 기존 요청은 현재 provider 기본 thinking 동작을 유지한다. 검증: 기존 chat completion, tool calling, provider pool 테스트가 회귀 없이 통과한다. - [x] [dev-smoke] dev-runtime 세 provider(mac vLLM-MLX, GX10 vLLM, OneXPlayer Lemonade)에서 `think=false`, 기본값, `include_reasoning=false` smoke가 통과한다. 검증: provider raw trace와 Edge OpenAI-compatible SSE를 비교해 reasoning 생성/노출 상태가 기대와 일치한다. - [x] [contract-docs] OpenAI-compatible 계약 문서와 dev 운영 문서가 요청별 thinking/reasoning 제어 field, provider별 unsupported 정책, 기본값을 설명한다. ## 완료 리뷰 - 상태: 통과 - 요청일: 2026-07-04 - 완료 근거: `agent-task/archive/2026/07/m-openai-compatible-think-control/**/complete.log` 5개가 모든 기능 Task의 `Roadmap Completion` PASS를 기록했고, 종료 전 코드레벨 감사에서 provider-first OpenAI-compatible provider label 기본값과 README 계약 문구 드리프트를 보정했다. - 검토 항목: `go test -count=1 ./apps/edge/internal/node ./apps/edge/internal/openai ./apps/node/internal/adapters/openai_compat`, `go test -count=1 ./apps/edge/internal/bootstrap ./apps/edge/internal/configrefresh ./packages/go/config`, `go test ./...`, `make test-e2e` 통과. 남은 기능 Task와 구현 잠금 차단 항목 없음. - agent-ui 상태 반영: 해당 없음 - 리뷰 코멘트: 코드레벨 종료 감사 통과. 큰 이슈나 별도 plan 필요 없음. ## 범위 제외 - `/v1/responses`의 streaming 지원 또는 reasoning output item 확장 - provider runtime 기동 옵션 자동 조정과 lifecycle 관리 - hidden reasoning token의 정확한 usage 산출 - 단계 호출 planner/generator/verifier 모드 전반의 제품 UX - raw provider payload 장기 저장과 운영 ledger schema 구현 ## 작업 컨텍스트 - 관련 경로: `apps/edge/internal/openai`, `apps/node/internal/adapters/openai_compat`, `agent-contract/outer/openai-compatible-api.md`, `docs/openai-compatible-api-contract.md`, `agent-test/dev` - 표준선(선택): provider runtime은 reasoning-capable 상태로 띄우고, 요청별 제어는 OpenAI-compatible Edge request 계약에서 검증한 뒤 provider별 지원 option으로 매핑한다. - 표준선(선택): 공개 request 표면은 provider raw wrapper를 그대로 열지 않고, IOP가 검증 가능한 OpenAI-compatible field와 내부 provider option 매핑으로 둔다. - 선행 작업: OpenAI-compatible reasoning raw trace와 dev-runtime provider reasoning 활성화 - 후속 작업: 단계 호출과 검증 최적화 MVP, 요청 실행 로그와 Usage Ledger 기반 - 확인 필요: 없음