# Milestone: Model Group Long-Context Admission

## 위치

- Roadmap: `agent-roadmap/ROADMAP.md`
- Phase: `agent-roadmap/phase/operational-observability-provider-management/PHASE.md`

## 목표

Model group의 단일 요청 context window 계약을 유지하면서, 입력 토큰 기준 long-context 요청을 별도 admission slot으로 제어한다.
일반 요청은 기존 provider capacity와 priority 기반으로 적극 배정하되, long-context 요청은 provider별 long slot과 model group 전체 long slot 여유가 있을 때만 배정해 256k급 요청이 서로 몰려 전체 사용성을 떨어뜨리지 않게 한다.
long slot이 찬 provider도 일반 capacity가 남아 있으면 normal 요청 후보로 유지한다.

## 상태

[완료]

## 승격 조건

- 없음

## 구현 잠금

- 상태: 해제
- SDD: 필요
- SDD 문서: `agent-roadmap/sdd/operational-observability-provider-management/model-group-long-context-admission/SDD.md`
- SDD 사유: model group routing, queue admission, provider runtime config, dev provider pool smoke 기준을 함께 바꾸는 설계 Milestone이다.
- 잠금 해제 조건: 없음
- 결정 필요: 없음

## 범위

- Edge root 설정의 `long_context_threshold_tokens` 도입. 초기 기준은 입력 토큰 추정치 `100000` 이상이다.
- model group의 `context_window_tokens`를 단일 요청 최대 context 계약으로 둔다. `qwen3.6:35b` 기준은 `262144`이며 같은 model group provider가 이를 낮춰 다르게 해석하지 않는다.
- provider별 `total_context_tokens` 또는 이에 대응하는 runtime KV/context budget 기준을 명시하고, `long_context_capacity`와 비례 검증한다. 기본 검증식은 `total_context_tokens >= context_window_tokens * long_context_capacity`이다.
- provider별 `long_context_capacity` 도입. long slot은 provider가 확보한 전체 KV/context budget을 `context_window_tokens * long_context_capacity`로 해석하며, 일반 동시성 capacity와 별도로 관리한다.
- long-context 판별은 요청 입력 기준으로만 수행한다. output 길이와 hidden thinking은 사전 분류 기준에 넣지 않고, provider fit과 timeout/usage 관측은 별도 운영 지표로 둔다.
- long-context 요청은 일반 `in_flight` capacity도 점유하고, 별도 `long_in_flight`도 점유한다.
- 할당 직전 queue item의 long flag를 보고 long slot이 꽉 찬 provider는 후보에서 제외한다. model group 전체 long slot이 모두 찼으면 long 요청은 대기한다.
- long slot full은 long 요청에 대한 후보 제외 조건이며, 해당 provider의 일반 capacity가 남아 있으면 normal 요청 후보에서는 제외하지 않는다.
- queue 앞 long 요청이 long slot을 기다리는 동안, 뒤의 normal 요청이 빈 일반 capacity로 처리 가능하면 normal 요청을 먼저 dispatch한다.
- dev 기준 OneXPlayer는 `ctx_size=524288`, `long_context_capacity=2`, `-np 3`을 유지한다. `-np`는 단순 최대 동시 요청 수로 취급하며, `ctx_size`를 `262144 * 3 = 786432`로 키우는 방향은 제외한다.
- GX10, OneXPlayer, mac-mlx-vllm provider pool에서 long-context admission 상태와 queue 회복을 smoke로 검증한다.

## 기능

### Epic: [long-admission] Long-Context Admission Policy

long-context 요청을 model group과 provider의 별도 slot 기준으로 admission하는 capability를 묶는다.

- [x] [threshold-config] Edge root 설정에 `long_context_threshold_tokens`를 추가하고 dev 기준 `100000`으로 설정한다. 검증: 설정 로딩과 config check에서 threshold가 반영된다.
- [x] [model-window] model group에 `context_window_tokens=262144` 계약을 명시하고 같은 model group provider가 provider별 단일 요청 최대 context를 낮춰 해석하지 않도록 한다. 검증: `qwen3.6:35b` catalog/config에서 context window가 단일 기준으로 조회된다.
- [x] [provider-long-capacity] provider별 `total_context_tokens` 또는 runtime KV/context budget 기준, `long_context_capacity`, `long_in_flight` 상태를 추가하고, long 요청이 일반 capacity와 long capacity를 함께 점유하도록 한다. 검증: `total_context_tokens >= context_window_tokens * long_context_capacity` 검증과 long 요청 dispatch 중 `long_in_flight` 증가가 확인된다.
- [x] [input-estimator] OpenAI-compatible chat/responses 요청의 system/developer/user messages, tool schema, metadata payload를 입력 기준으로 토큰 근사 추정해 long flag를 붙인다. 검증: 100k 이상 입력은 long, 작은 설명형 요청은 normal로 분류된다.
- [x] [queue-skip] queue head의 long 요청이 long slot 부족으로 대기 중이어도 뒤의 normal 요청이 빈 일반 capacity로 dispatch될 수 있게 한다. 검증: long queue 대기 중 normal 요청이 head-of-line blocking 없이 완료된다.
- [x] [provider-exclusion] long 요청 배정 시 이미 long slot이 찬 provider를 long 후보에서 제외하고, model group 전체 long slot이 모두 차면 long 요청을 대기시킨다. 검증: long 요청이 같은 provider에 과밀 배정되지 않고, normal 요청은 남은 일반 capacity로 계속 dispatch되며, long slot 회복 뒤 long 요청이 dispatch된다.
- [x] [dev-runtime-policy] dev provider pool에서 GX10, OneXPlayer, mac-mlx-vllm의 `context_window_tokens`, `long_context_capacity`, 실제 runtime context/KV 설정을 인벤토리와 config에 맞춘다. 검증: OneXPlayer는 `ctx_size=524288`, `-np 3`, long slot 2 기준을 유지하며 `786432`로 변경하지 않는다.
- [x] [status-logs] status/log에 `estimated_input_tokens`, `context_class`, `long_context_capacity`, `long_in_flight`, long queue reason을 남긴다. 검증: Control Plane status 또는 Edge log로 long admission 판단을 재구성할 수 있다.
- [x] [capacity-smoke] dev 환경에서 normal 10-way, mixed long/normal, all-long-slot-full queue 시나리오를 수행하고 완료 후 `in_flight=0`, `queued=0`, `long_in_flight=0` 회복 근거를 남긴다.

## 완료 리뷰

- 상태: 통과
- 요청일: 2026-07-06
- 완료 근거: `agent-task/archive/2026/07/m-model-group-long-context-admission/**/complete.log` 6개가 `input-estimator`, `provider-long-capacity`, `provider-exclusion`, `queue-skip`, `status-logs`, `dev-runtime-policy`, `capacity-smoke` PASS와 SDD S03-S09 evidence를 남겼다.
- 완료 근거: `threshold-config`, `model-window`는 2026-07-05 직접 처리 근거와 현재 파일/git sanity pass로 SDD S01-S02 기준을 재확인했다.
- 완료 근거: 종료 전 코드 레벨 검토에서 `input_estimator` float schema 직렬화 panic 가능성을 작은 이슈로 수정했고, `go test -count=1 ./...`, `go run ./apps/edge/cmd/edge config check --config configs/edge.yaml`, `bash -n scripts/e2e-long-context-admission-smoke.sh`, `git diff --check`가 통과했다.
- 검토 항목:
  - [x] long-context 분류가 입력 기준으로만 수행된다.
  - [x] 같은 model group provider는 `context_window_tokens=262144` 단일 요청 계약을 공유한다.
  - [x] long slot이 찬 provider는 long 요청 후보에서 제외되지만 일반 capacity가 남으면 normal 요청 후보로 유지된다.
  - [x] OneXPlayer는 `ctx_size=524288`, `-np 3`, long slot 2 기준을 유지하며 `786432`로 키우지 않는다.
- agent-ui 상태 반영: 해당 없음
- 리뷰 코멘트: 모든 기능 Task와 SDD Evidence Map 연결이 충족되고 종료 전 코드 레벨 검토의 작은 보완까지 반영되어 `[완료]` archive 대상으로 확정했다.

## 범위 제외

- output 길이나 hidden thinking budget을 이용한 사전 long-context 분류
- provider별 단일 요청 최대 context를 model group 계약보다 낮게 허용하는 혼합 model group
- OneXPlayer `ctx_size`를 `786432`로 올리는 설정 변경
- billing/chargeback, 장기 usage ledger 저장, 품질 기반 route recommendation
- tokenizer별 완전 정확한 토큰 계산기 구현. 초기 분류는 보수적 근사 추정으로 시작한다.

## 작업 컨텍스트

- 관련 경로: `apps/edge/internal/service`, `apps/edge/internal/openai`, `apps/node/internal/adapters/openai_compat`, `packages/go/config`, `configs/edge.yaml`, `agent-test/dev/inventory.yaml`, `agent-test/dev/edge-smoke.md`, `agent-test/dev/node-smoke.md`
- 2026-07-05 직접 처리 완료: `threshold-config`, `model-window`. 근거: `packages/go/config/config.go`, `apps/edge/internal/configrefresh/classify.go`, `configs/edge.yaml`, `agent-contract/inner/edge-config-runtime-refresh.md`, 관련 Go tests 갱신. 검증: `go test ./apps/edge/... ./packages/go/config`, `go run ./apps/edge/cmd/edge config check --config configs/edge.yaml`.
- 2026-07-05 plan 생성: 남은 long-admission 큰 작업은 `agent-task/m-model-group-long-context-admission/01_input_estimator`부터 `06+01,02,03,04,05_capacity_smoke`까지 split plan으로 분리했다.
- 표준선(선택): model group의 `context_window_tokens`가 단일 요청 최대 context 계약을 소유하고, provider는 이를 낮춰 해석하지 않는다.
- 표준선(선택): `long_context_capacity`는 provider가 가진 전체 KV/context budget을 model group context window 몇 개분으로 운영할지 나타내며, 일반 `capacity`와 분리한다.
- 표준선(선택): provider runtime의 ctx/KV budget은 `total_context_tokens >= context_window_tokens * long_context_capacity` 기준으로 검증한다.
- 표준선(선택): OneXPlayer에서 `-np 3`은 단순 최대 동시 요청 수로 다루고, long slot 산정은 `ctx_size=524288 = 262144 * 2` 기준으로 고정한다.
- 선행 작업: Model Alias Provider Pool과 Provider Catalog, Node Resource Model Unification, Node Provider-First Config Surface
- 후속 작업: 요청 실행 로그와 Usage Ledger 기반, Provider-Device-Model Qualification 리포트와 Lifecycle 관리
- 확인 필요: 없음
