Update phase status and add new milestone for openai-compatible tool call boundary hardening

This commit is contained in:
toki 2026-07-04 10:04:25 +09:00
parent 77ab36cbd1
commit 001365a05f
2 changed files with 83 additions and 0 deletions

View file

@ -23,6 +23,10 @@ Ollama serving 경로와 운영 기반이 안정화된 뒤, 단계 호출, tool/
- 경로: `agent-roadmap/phase/knowledge-tool-optimization-extension/milestones/openai-compatible-think-control.md`
- 요약: OpenAI-compatible Chat Completions 요청에서 thinking/reasoning 생성과 응답 노출을 요청별로 제어하고 provider별 option 매핑과 unsupported 정책을 구현한다.
- [계획] OpenAI-compatible Tool Call Boundary Hardening
- 경로: `agent-roadmap/phase/knowledge-tool-optimization-extension/milestones/openai-compatible-tool-call-boundary-hardening.md`
- 요약: provider-pool/OpenAI-compatible 응답에서 raw text tool-call block, unknown tool name, chat-template sentinel token이 클라이언트 화면으로 새지 않도록 Edge tool-call 경계를 검증/정규화한다.
- [스케치] 단계 호출과 검증 최적화 MVP
- 경로: `agent-roadmap/phase/knowledge-tool-optimization-extension/milestones/knowledge-tool-validation-optimization.md`
- 요약: 요청 의도 분석, 실제 작업, 검증/schema 강제, 오류 시 회귀를 단계 호출 실행 모드의 MVP 후보로 스케치한다.

View file

@ -0,0 +1,79 @@
# Milestone: OpenAI-compatible Tool Call Boundary Hardening
## 위치
- Roadmap: `agent-roadmap/ROADMAP.md`
- Phase: `agent-roadmap/phase/knowledge-tool-optimization-extension/PHASE.md`
## 목표
OpenAI-compatible `tools[]`가 있는 요청에서 provider-pool 또는 provider route가 raw text `<tool_call>` block을 반환하더라도, Edge가 이를 요청 tool schema와 대조해 구조화된 `tool_calls` 또는 명확한 validation error/retry로 처리한다.
존재하지 않는 tool name, schema 불일치, chat-template sentinel token이 Pi/Cline 같은 클라이언트 화면으로 그대로 노출되지 않게 한다.
## 상태
[계획]
## 승격 조건
- 없음
## 구현 잠금
- 상태: 해제
- SDD: 불필요
- SDD 문서: 없음
- SDD 사유: 기존 OpenAI-compatible `tools[]`, `tool_calls`, text-tool fallback, validation retry 계약을 강화하는 호환성 보정이며 새 공개 request/response field를 만들지 않는다.
- 잠금 해제 조건: 없음
- 결정 필요: 없음
## 범위
- `/v1/chat/completions` provider-pool/provider route의 stream/non-stream tool-call 경계 검증
- 요청 `tools[]` schema가 있는 경우 raw `<tool_call>` text block을 기존 text tool-call parser로 대조하고, schema-valid block은 OpenAI-compatible `tool_calls`로 정규화
- 요청 tool 목록에 없는 function name, schema 불일치, malformed arguments를 성공 content로 flush하지 않고 validation error 또는 bounded retry로 처리
- `<|mask_end|>` 같은 chat-template sentinel token이 최종 assistant content/reasoning에 남지 않도록 출력 정규화
- Pi/Cline처럼 OpenAI-compatible tools를 사용하는 클라이언트에서 raw tool-call leak이 재현되지 않는 dev smoke와 회귀 테스트
## 기능
### Epic: [tool-boundary] Tool Call Boundary Guard
OpenAI-compatible provider 응답의 tool-call 후보를 요청 schema 기준으로 구조화하거나 차단하는 capability를 묶는다.
- [ ] [provider-raw-parse] provider-pool/provider route에서도 요청 `tools[]`가 있고 assistant content에 raw `<tool_call>` block이 있으면 기존 text tool-call parser를 적용한다. 검증: `bash` raw block은 `message.tool_calls` 또는 stream `delta.tool_calls`로 정규화되고 raw block이 content에 남지 않는다.
- [ ] [unknown-tool-error] raw tool-call block의 function name이 요청 tool 목록에 없으면 일반 assistant text로 flush하지 않고 validation error 또는 bounded retry로 처리한다. 검증: `TOOL_CALLS.push_changes` 형태의 unknown tool output이 Pi/Cline 화면으로 노출되지 않는다.
- [ ] [stream-flush-guard] streaming 경로에서 tool-call 후보를 보류한 뒤 terminal event에서 구조화/차단하며, 실패한 raw block을 마지막 flush로 내보내지 않는다. 검증: live SSE와 buffered SSE 테스트가 모두 raw `<tool_call>` leak 없이 `tool_calls` 또는 error로 종료된다.
- [ ] [sentinel-sanitize] provider output normalization이 `<|mask_end|>` 같은 알려진 chat-template sentinel token을 assistant content/reasoning 최종 출력에서 제거한다. 검증: sentinel token이 tool-call 뒤나 단독 content로 들어와도 OpenAI-compatible 응답에 남지 않는다.
- [ ] [native-preserve] provider가 이미 native OpenAI-compatible `tool_calls`를 반환하는 경로는 기존 pass-through와 schema-normalization 동작을 유지한다. 검증: native `tool_calls` server tests와 forced/auto direct tool-call smoke가 회귀 없이 통과한다.
- [ ] [client-smoke] Pi/Cline형 긴 agent prompt와 `tools[]` 요청을 직접 Edge에 호출해 unknown tool hallucination이 raw text로 노출되지 않는 근거를 남긴다. 검증: 재현 요청, response finish reason/error type, Edge trace를 `agent-test/dev`에 기록한다.
- [ ] [contract-docs] OpenAI-compatible 계약 문서와 dev 운영 문서가 provider raw tool-call 후보의 정규화/차단, unknown tool 처리, sentinel sanitize 정책을 설명한다.
## 완료 리뷰
- 상태: 없음
- 요청일: 없음
- 완료 근거: 계획 Milestone이며 기능 Task가 아직 충족되지 않았다.
- 검토 항목:
- [ ] valid raw text tool call은 구조화되고 raw block이 노출되지 않는다
- [ ] unknown/malformed tool call은 성공 content로 노출되지 않는다
- [ ] Pi/Cline형 OpenAI-compatible tools smoke 근거가 남아 있다
- agent-ui 상태 반영: 해당 없음
- 리뷰 코멘트: 없음
## 범위 제외
- `tools[]`가 없는 요청에서 임의 자연어를 tool call로 추론하는 모델-assisted gate
- Pi 자체 provider/model 설정 파일의 소유권 이전 또는 자동 생성
- CLI `adapter=cli,target=pi` profile 구현과 Pi JSON stream emitter
- 요청 실행 로그/usage ledger의 장기 저장 schema 구현
- provider별 chat template 전체 교체나 모델별 fine-tune/prompt policy 변경
## 작업 컨텍스트
- 관련 경로: `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`
- 표준선(선택): 명시적 `tools[]`가 있는 요청은 runtime-only validation을 우선한다. 요청 schema에 없는 tool name은 client-visible 성공 content가 아니라 validation failure로 다룬다.
- 표준선(선택): provider-pool은 native `tool_calls`만 신뢰하지 않고, raw text tool-call 후보가 보이면 같은 OpenAI-compatible boundary 정책으로 검증한다.
- 선행 작업: Tool Call Runtime 검증 재시도 MVP, OpenAI-compatible Think 제어 MVP에서 확인된 provider-pool/Pi raw leak 진단
- 후속 작업: Tool Call 판정 모델 Gate 리뷰, 요청 실행 로그와 Usage Ledger 기반
- 확인 필요: 없음