From a18cc9065aeff9c7ceccb9cafe23d90a23bbb1eb Mon Sep 17 00:00:00 2001 From: toki Date: Wed, 24 Jun 2026 23:59:04 +0900 Subject: [PATCH] update test docs and edge local dev guide --- agent-test/dev/edge-smoke.md | 16 ++++++++++-- agent-test/dev/inventory.yaml | 48 +++++++++++++++++++++++++++++++++-- agent-test/dev/node-smoke.md | 15 ++++++++++- agent-test/dev/rules.md | 4 +-- docs/edge-local-dev-guide.md | 44 +++++++++++++++++++++++++++++--- 5 files changed, 116 insertions(+), 11 deletions(-) diff --git a/agent-test/dev/edge-smoke.md b/agent-test/dev/edge-smoke.md index adee6e8..24cec70 100644 --- a/agent-test/dev/edge-smoke.md +++ b/agent-test/dev/edge-smoke.md @@ -43,7 +43,7 @@ last_rule_updated_at: 2026-06-24 ## dev-runtime provider pool 인벤토리 -dev-runtime provider pool과 3-node 연결 상태를 점검할 때는 `agent-test/dev/inventory.yaml`의 machine-readable 값을 우선하고, 원격 runner `ssh toki@toki-labs.com`의 `/Users/toki/agent-work/iop-dev` checkout을 기준으로 한다. +dev-runtime provider pool과 4-node 연결 상태를 점검할 때는 `agent-test/dev/inventory.yaml`의 machine-readable 값을 우선하고, 원격 runner `ssh toki@toki-labs.com`의 `/Users/toki/agent-work/iop-dev` checkout을 기준으로 한다. - Edge config: `build/dev-runtime/edge.yaml` - Edge id: `edge-toki-labs-dev` @@ -73,11 +73,22 @@ dev-runtime provider pool과 3-node 연결 상태를 점검할 때는 `agent-tes - capacity baseline: `3` - load baseline: backend `vulkan`, ctx size `786432`, `llamacpp_args="--spec-type none -np 3 -cb -fa on -b 4096 -ub 1024"`, `save_options=true` - workspace: `C:/Users/r0bin/iop-field` +- Mac MLX vLLM node: `mac-mlx-vllm-node` / `mac-mlx-vllm` + - SSH/user: `ssh toki@toki-labs.com` + - provider endpoint: `http://127.0.0.1:8002/v1` + - served model: `mlx-community/Qwen3.6-35B-A3B-4bit` + - capacity baseline: `3` + - workdir: `/Users/toki/agent-work/iop-mlx-vllm` + - runtime baseline: `vllm-mlx`, `--max-num-seqs 3`, `--max-kv-size 262144`, `--max-request-tokens 262144`, `--use-paged-cache --paged-cache-block-size 64 --max-cache-blocks 8192` + - KV policy: per-call window bound `262144`, total paged KV budget `524288` tokens, equivalent to two full context windows + - workspace: `/Users/toki/agent-work/iop-mlx-vllm` OneXPlayer Lemonade는 `Qwen3.6-35B-A3B-MTP-GGUF` artifact를 사용하되 runtime MTP speculative decoding은 켜지 않는다. dev long-context baseline은 `/v1/load`에 `llamacpp_backend=vulkan`, `ctx_size=786432`, `--spec-type none -np 3 -cb -fa on -b 4096 -ub 1024`를 `save_options=true`로 저장한 상태다. llama.cpp backend의 `/slots`에서 slot 3개가 각각 `n_ctx=262144`로 보여야 한다. OneXPlayer Lemonade Node는 원격 runner나 Edge host에서 다시 SSH하거나 proxy process로 띄우지 않는다. 현재 작업 호스트에서 OneXPlayer Windows host에 `ssh r0bin@192.168.0.59`로 직접 접속한 뒤 generated PowerShell bootstrap을 실행한다. +Mac MLX vLLM node는 Edge host와 같은 macOS host에서 실행한다. vllm-mlx API는 외부에 직접 노출하지 않고 `127.0.0.1:8002`에 bind하며, Edge OpenAI-compatible adapter가 local bearer header로 호출한다. 운영 파일은 `/Users/toki/agent-work/iop-mlx-vllm/vllm-mlx.pid`, `logs/vllm-mlx.stdout.log`, `logs/vllm-mlx.stderr.log`를 기준으로 한다. Docker와 macOS 여유 메모리를 고려해 capacity는 `3`을 기본선으로 유지한다. + ## 명령 - setup: @@ -106,8 +117,9 @@ OneXPlayer Lemonade Node는 원격 runner나 Edge host에서 다시 SSH하거나 - node 로컬 `[node-message]` payload 라인 목록과 edge `[node-*-message]` payload 라인 목록이 run별로 내용/순서까지 동일해야 한다. - edge complete는 같은 run의 마지막 `[node-*-message]` 이후에만 정상이다. - OpenAI-compatible smoke에서 `/healthz`, `/v1/models`, `/v1/responses`가 기대 상태로 응답한다. -- dev-runtime capacity smoke는 `/v1/responses`와 `/v1/chat/completions` 각각에 provider capacity 총합 + 1개 동시 요청을 보내고, Control Plane status의 `provider_snapshots`에서 총 `in_flight`가 capacity 총합에 도달하며 `queued`가 1 이상 잡히는지 확인한다. 현재 `gx10-vllm=4`, `onexplayer-lemonade=3`이면 endpoint별 8개 동시 요청에서 총 `in_flight=7`, `queued>=1` 관측을 기준으로 한다. +- dev-runtime capacity smoke는 `/v1/responses`와 `/v1/chat/completions` 각각에 provider capacity 총합 + 1개 동시 요청을 보내고, Control Plane status의 `provider_snapshots`에서 총 `in_flight`가 capacity 총합에 도달하며 `queued`가 1 이상 잡히는지 확인한다. 현재 `gx10-vllm=4`, `onexplayer-lemonade=3`, `mac-mlx-vllm=3`이면 endpoint별 11개 동시 요청에서 총 `in_flight=10`, `queued>=1` 관측을 기준으로 한다. 13개 동시 확장 smoke에서는 총 `in_flight=10`, `queued>=3` 관측을 기대한다. - capacity smoke 완료 후 대상 provider의 `in_flight=0`, `queued=0` 회복을 확인한다. +- 2026-06-24 dev 13-way 확장 smoke의 관측 결과는 `/v1/chat/completions` 13개 요청 성공, peak `in_flight=10`, 실제 queue 대기 `3`개, 최종 회복 `in_flight=0`, `queued=0`이다. 초기 peak는 `gx10-vllm=4`, `onexplayer-lemonade=3`, `mac-mlx-vllm=3`으로 채워졌고, 대기 요청은 먼저 slot이 빈 provider로 dispatch될 수 있다. - Qwen 계열 provider-pool smoke는 thinking/reasoning 텍스트가 포함될 수 있다. 추론 출력 자체를 실패로 보지 말고 HTTP 성공, model alias, final marker 포함 여부, provider node log/run count 증가로 판정한다. 응답 전체가 특정 token과 정확히 같은지 비교하는 strict exact-match는 이 profile의 기본 판정으로 쓰지 않는다. - bootstrap 사용자 명령은 완성된 URL과 positional token 하나만 포함한다. diff --git a/agent-test/dev/inventory.yaml b/agent-test/dev/inventory.yaml index ccf58a3..ec5a864 100644 --- a/agent-test/dev/inventory.yaml +++ b/agent-test/dev/inventory.yaml @@ -32,14 +32,16 @@ build: model: alias: qwen3.6:35b - provider_capacity_total: 7 + provider_capacity_total: 10 capacity_smoke: endpoints: - /v1/responses - /v1/chat/completions concurrent_requests: capacity_plus_one - expected_total_in_flight: 7 + expected_total_in_flight: 10 expected_min_queued: 1 + extended_concurrent_requests: 13 + extended_expected_min_queued: 3 prompt_policy: long_reasoning_allowed exact_output_match: false @@ -64,6 +66,48 @@ nodes: endpoint: http://192.168.0.91:8001/v1 served_model: nvidia/Qwen3.6-35B-A3B-NVFP4 capacity: 4 + - id: mac-mlx-vllm-node + alias: mac-mlx-vllm + role: vllm-mlx-provider + ssh: toki@toki-labs.com + workspace: /Users/toki/agent-work/iop-mlx-vllm + provider_pool_candidate: true + provider: + id: mac-mlx-vllm + type: vllm-mlx + endpoint: http://127.0.0.1:8002/v1 + served_model: mlx-community/Qwen3.6-35B-A3B-4bit + capacity: 3 + runtime: + api_key_policy: local_bearer_from_edge_yaml + workdir: /Users/toki/agent-work/iop-mlx-vllm + python: .venv/bin/python + package_baseline: + vllm_mlx: 0.3.0 + mlx: 0.31.2 + mlx_lm: 0.31.3 + model_cache: /Users/toki/agent-work/iop-mlx-vllm/hf-cache + pid_file: /Users/toki/agent-work/iop-mlx-vllm/vllm-mlx.pid + stdout_log: /Users/toki/agent-work/iop-mlx-vllm/logs/vllm-mlx.stdout.log + stderr_log: /Users/toki/agent-work/iop-mlx-vllm/logs/vllm-mlx.stderr.log + max_num_seqs: 3 + max_kv_size: 262144 + max_request_tokens: 262144 + paged_cache_block_size: 64 + max_cache_blocks: 8192 + total_kv_tokens: 524288 + default_chat_template_kwargs: + enable_thinking: false + observed_direct_throughput_2026_06_24: + max_tokens: 192 + completion_token_basis: true + concurrency: + 1: + total_tok_s: 59.66 + 2: + total_tok_s: 87.31 + 3: + total_tok_s: 98.13 - id: onexplayer-lemonade-node alias: onexplayer-lemonade role: lemonade-provider diff --git a/agent-test/dev/node-smoke.md b/agent-test/dev/node-smoke.md index e0cd199..51bd74d 100644 --- a/agent-test/dev/node-smoke.md +++ b/agent-test/dev/node-smoke.md @@ -42,7 +42,7 @@ last_rule_updated_at: 2026-06-24 ## dev-runtime Node 접속 기준 -dev-runtime의 실제 3-node 연결을 점검할 때는 원격 runner `ssh toki@toki-labs.com`의 `/Users/toki/agent-work/iop-dev` checkout과 `build/dev-runtime/edge.yaml`을 기준으로 한다. Node는 dev-runtime provider pool 기준에서 Edge-Node TCP `toki-labs.com:18084`로 붙는다. +dev-runtime의 실제 4-node 연결을 점검할 때는 원격 runner `ssh toki@toki-labs.com`의 `/Users/toki/agent-work/iop-dev` checkout과 `build/dev-runtime/edge.yaml`을 기준으로 한다. Node는 dev-runtime provider pool 기준에서 Edge-Node TCP `toki-labs.com:18084`로 붙는다. - mac CLI node: `mac-codex-node` / `mac-codex` - SSH/user: `ssh toki@toki-labs.com` @@ -52,19 +52,32 @@ dev-runtime의 실제 3-node 연결을 점검할 때는 원격 runner `ssh toki@ - SSH/user: `ssh toki@192.168.0.91` - provider endpoint: `http://192.168.0.91:8001/v1` - served model: `nvidia/Qwen3.6-35B-A3B-NVFP4` + - capacity baseline: `4` - workspace: `/home/toki/iop-gx10-vllm` - OneXPlayer Lemonade node: `onexplayer-lemonade-node` / `onexplayer-lemonade` - SSH/user: `ssh r0bin@192.168.0.59` - 접속 기준: 현재 작업 호스트에서 직접 SSH - provider endpoint: `http://192.168.0.59:13305/v1` - served model: `Qwen3.6-35B-A3B-MTP-GGUF` + - capacity baseline: `3` - load baseline: backend `vulkan`, ctx size `786432`, `llamacpp_args="--spec-type none -np 3 -cb -fa on -b 4096 -ub 1024"`, `save_options=true` - workspace: `C:/Users/r0bin/iop-field` +- Mac MLX vLLM node: `mac-mlx-vllm-node` / `mac-mlx-vllm` + - SSH/user: `ssh toki@toki-labs.com` + - provider endpoint: `http://127.0.0.1:8002/v1` + - served model: `mlx-community/Qwen3.6-35B-A3B-4bit` + - capacity baseline: `3` + - workdir: `/Users/toki/agent-work/iop-mlx-vllm` + - runtime baseline: `vllm-mlx`, `--max-num-seqs 3`, `--max-kv-size 262144`, `--max-request-tokens 262144`, `--use-paged-cache --paged-cache-block-size 64 --max-cache-blocks 8192` + - KV policy: per-call window bound `262144`, total paged KV budget `524288` tokens, equivalent to two full context windows + - workspace: `/Users/toki/agent-work/iop-mlx-vllm` OneXPlayer Lemonade는 `Qwen3.6-35B-A3B-MTP-GGUF` artifact를 사용하되 runtime MTP speculative decoding은 끈 상태를 dev 기준으로 삼는다. Node 검증 전 `/v1/load`의 `recipe_options`가 Vulkan, `ctx_size=786432`, `--spec-type none -np 3 -cb -fa on -b 4096 -ub 1024`를 포함하는지 확인한다. backend `/slots`에서는 slot 3개가 각각 `n_ctx=262144`로 보여야 한다. GX10은 Linux/ARM64 bootstrap, OneXPlayer는 Windows native PowerShell bootstrap을 기본으로 한다. OneXPlayer는 현재 작업 호스트에서 직접 접속해 세팅하며, 원격 runner나 Edge host에서 `node-onexplayer-lemonade.yaml`로 proxy 실행하지 않는다. +Mac MLX vLLM node는 Edge host와 같은 macOS host에서 실행한다. vllm-mlx API는 외부에 직접 노출하지 않고 `127.0.0.1:8002`에 bind하며, Edge의 OpenAI-compatible adapter가 local bearer header로 호출한다. 운영 확인은 `/Users/toki/agent-work/iop-mlx-vllm/vllm-mlx.pid`, `logs/vllm-mlx.stdout.log`, `logs/vllm-mlx.stderr.log`, dev-runtime의 `build/dev-runtime/logs/node-mac-mlx-vllm.*.log`를 기준으로 한다. Docker와 macOS 여유 메모리를 고려해 capacity는 `3`을 기본선으로 유지한다. + OneXPlayer에서 SSH 세션 안의 `Start-Process`로 `iop-node.exe`를 띄우면 SSH 세션 종료와 함께 process가 정리될 수 있다. dev 반복 배포에서는 `Win32_Process.Create` 또는 동등한 세션 독립 실행 방식으로 `C:/Users/r0bin/iop-field`에서 `iop-node.exe --config node.yaml serve`를 시작하고, WMI/process query와 `iop-node.log`의 `connected to edge` 로그로 유지 여부를 확인한다. ## 명령 diff --git a/agent-test/dev/rules.md b/agent-test/dev/rules.md index fee28a3..d25033b 100644 --- a/agent-test/dev/rules.md +++ b/agent-test/dev/rules.md @@ -59,7 +59,7 @@ dev-runtime provider pool은 compose Edge-Node TCP `19003`이 아니라 native E - remote runner: dev runtime evidence, Flutter client, Docker compose, field/bootstrap, 외부 runtime evidence는 `ssh toki@toki-labs.com`의 `/Users/toki/agent-work/iop-dev` 기준으로 수행한다. - compose dev stack: `.env.dev.example`, `COMPOSE_PROJECT_NAME=iop-dev-agent`, `IOP_COMPOSE_NETWORK=iop-dev-agent-net`, Edge-Node TCP `19003`을 사용한다. - Edge direct dev profile: artifact/bootstrap `18082`, OpenAI-compatible `18083`, metrics `19101`을 필요할 때만 사용한다. -- dev-runtime provider pool: `/Users/toki/agent-work/iop-dev/build/dev-runtime/edge.yaml`과 Edge-Node TCP `toki-labs.com:18084`를 사용한다. 3-node/provider 세부는 `agent-test/dev/edge-smoke.md`와 `agent-test/dev/node-smoke.md`를 따른다. +- dev-runtime provider pool: `/Users/toki/agent-work/iop-dev/build/dev-runtime/edge.yaml`과 Edge-Node TCP `toki-labs.com:18084`를 사용한다. 4-node/provider 세부는 `agent-test/dev/edge-smoke.md`와 `agent-test/dev/node-smoke.md`를 따른다. - external provider field: GX10 vLLM은 `ssh toki@192.168.0.91`, OneXPlayer Lemonade는 현재 작업 호스트에서 `ssh r0bin@192.168.0.59`로 직접 접속해 확인한다. OneXPlayer 접속은 원격 runner 경유를 필수 조건으로 보지 않는다. ## 프리플라이트 @@ -91,7 +91,7 @@ dev-runtime provider pool은 compose Edge-Node TCP `19003`이 아니라 native E - node / smoke / node 실행 파이프라인 baseline: `agent-test/dev/node-smoke.md` - edge / smoke / edge 실행 그룹과 입력 표면 baseline: `agent-test/dev/edge-smoke.md` -- dev-runtime provider pool, 3-node 연결, GX10 vLLM, OneXPlayer Lemonade, mac CLI node 점검: `agent-test/dev/edge-smoke.md`, `agent-test/dev/node-smoke.md` +- dev-runtime provider pool, 4-node 연결, GX10 vLLM, OneXPlayer Lemonade, Mac MLX vLLM, mac CLI node 점검: `agent-test/dev/edge-smoke.md`, `agent-test/dev/node-smoke.md` - control-plane / smoke / control-plane health와 wire baseline: `agent-test/dev/control-plane-smoke.md` - client / smoke / Flutter client와 IOP console package baseline: `agent-test/dev/client-smoke.md` - platform-common / smoke / 공통 설정과 protobuf 계약 baseline: `agent-test/dev/platform-common-smoke.md` diff --git a/docs/edge-local-dev-guide.md b/docs/edge-local-dev-guide.md index a673745..5ca3874 100644 --- a/docs/edge-local-dev-guide.md +++ b/docs/edge-local-dev-guide.md @@ -101,7 +101,7 @@ curl -fsS http://toki-labs.com:18000/edges/edge-toki-labs/status ## 6. dev-runtime provider pool 반복 기준 -현재 GX10 vLLM과 OneXPlayer Lemonade를 같은 model alias로 묶어 검증하는 dev-runtime 기준은 원격 runner의 동기화된 iop checkout과 `build/dev-runtime/edge.yaml`이다. +현재 GX10 vLLM, OneXPlayer Lemonade, Mac MLX vLLM을 같은 model alias로 묶어 검증하는 dev-runtime 기준은 원격 runner의 동기화된 iop checkout과 `build/dev-runtime/edge.yaml`이다. 배포 전 원격 runner checkout은 보존 대상이 아니다. 항상 clean sync 후 dev-runtime binary를 다시 빌드한다. @@ -132,6 +132,7 @@ GOOS=windows GOARCH=amd64 go build -trimpath -o build/dev-runtime/bin/iop-node-w - model alias: `qwen3.6:35b` - provider candidate: `gx10-vllm` on `gx10-vllm-node`, capacity `4` - provider candidate: `onexplayer-lemonade` on `onexplayer-lemonade-node`, capacity `3` +- provider candidate: `mac-mlx-vllm` on `mac-mlx-vllm-node`, capacity `3` - connected non-candidate: `mac-codex-node` OneXPlayer Lemonade Node는 원격 runner나 Edge host에서 다시 SSH하거나 proxy process로 띄우지 않는다. 현재 작업 호스트에서 Windows host에 `ssh r0bin@192.168.0.59`로 직접 접속한 뒤, 그 host 안에서 generated PowerShell bootstrap 명령을 실행한다. 이때 Node 작업 경로는 `$HOME\iop-field`이며, Lemonade provider endpoint는 Windows host 로컬에서 접근 가능한 값을 기준으로 검증한다. @@ -144,6 +145,39 @@ curl -fsS http://192.168.0.59:13305/v1/load \ -d '{"model_name":"Qwen3.6-35B-A3B-MTP-GGUF","ctx_size":786432,"llamacpp_backend":"vulkan","llamacpp_args":"--spec-type none -np 3 -cb -fa on -b 4096 -ub 1024","save_options":true}' ``` +Mac MLX provider는 Edge host 자신에서 `vllm-mlx`로 띄운다. dev 기준 endpoint는 `http://127.0.0.1:8002/v1`, served model은 `mlx-community/Qwen3.6-35B-A3B-4bit`, provider capacity는 `3`이다. 작업 경로는 `/Users/toki/agent-work/iop-mlx-vllm`, Python 환경은 `.venv`의 Homebrew Python 3.12, 모델 cache는 `hf-cache`를 사용한다. 확인된 package baseline은 `vllm-mlx 0.3.0`, `mlx 0.31.2`, `mlx-lm 0.31.3`이다. + +vllm-mlx process는 `--max-num-seqs 3`, `--max-kv-size 262144`, `--max-request-tokens 262144`, `--use-paged-cache --paged-cache-block-size 64 --max-cache-blocks 8192`로 고정한다. 이 설정은 각 호출 window bound를 `262144`로 두고, 전체 paged KV 예산은 `524288` tokens, 즉 full context window 2개분으로 제한한다. Mac host는 Docker와 다른 dev process도 함께 돌리므로 provider capacity를 `3`보다 높이지 않는 것을 기본선으로 둔다. + +```bash +cd /Users/toki/agent-work/iop-mlx-vllm +export HF_HOME="$PWD/hf-cache" +export IOP_MLX_API_KEY="" +nohup .venv/bin/vllm-mlx serve mlx-community/Qwen3.6-35B-A3B-4bit \ + --served-model-name mlx-community/Qwen3.6-35B-A3B-4bit \ + --host 127.0.0.1 \ + --port 8002 \ + --api-key "$IOP_MLX_API_KEY" \ + --max-num-seqs 3 \ + --max-kv-size 262144 \ + --max-request-tokens 262144 \ + --max-tokens 32768 \ + --continuous-batching \ + --use-paged-cache \ + --paged-cache-block-size 64 \ + --max-cache-blocks 8192 \ + --cache-memory-percent 0.20 \ + --gpu-memory-utilization 0.85 \ + --chunked-prefill-tokens 4096 \ + --enable-metrics \ + --timeout 300 \ + --default-chat-template-kwargs '{"enable_thinking": false}' \ + > logs/vllm-mlx.stdout.log 2> logs/vllm-mlx.stderr.log & +echo $! > vllm-mlx.pid +``` + +Mac MLX provider의 주요 운영 파일은 `vllm-mlx.pid`, `logs/vllm-mlx.stdout.log`, `logs/vllm-mlx.stderr.log`, Node 로그 `build/dev-runtime/logs/node-mac-mlx-vllm.*.log`다. 2026-06-24 직접 호출 측정 기준으로 `max_tokens=192`, `enable_thinking=false`에서 1/2/3 동시 총합은 약 `59.66`, `87.31`, `98.13 tok/s`였다. + SSH 세션 안의 `Start-Process`는 세션 종료와 함께 `iop-node.exe`가 정리될 수 있다. 반복 배포에서는 Windows host에서 `Win32_Process.Create` 방식으로 세션 독립 실행한다. ```powershell @@ -169,13 +203,15 @@ Node host OS 재부팅은 필요하지 않다. Edge process 재시작이나 일 1. Control Plane status에서 `edge-toki-labs-dev`의 connected node 수와 node id를 확인한다. 2. Edge host에서 `toki-labs.com:18084`의 established node TCP connection 수를 확인한다. -3. Edge process를 재시작하고 bootstrap 재실행 없이 3개 Node 연결이 회복되는지 확인한다. +3. Edge process를 재시작하고 bootstrap 재실행 없이 4개 Node 연결이 회복되는지 확인한다. 4. `http://toki-labs.com:18083/healthz`와 `/v1/models`를 확인한다. -5. capacity를 `gx10-vllm=4`, `onexplayer-lemonade=3`로 맞춘 후보 config를 refresh apply하고 Edge process가 유지되는지 확인한다. Node adapter capacity 변경이 `restart_required`로 반환되면 Edge process를 새 config로 재시작한 뒤 Node reconnect 상태를 확인한다. +5. capacity를 `gx10-vllm=4`, `onexplayer-lemonade=3`, `mac-mlx-vllm=3`으로 맞춘 후보 config를 refresh apply하고 Edge process가 유지되는지 확인한다. Node adapter capacity 변경이 `restart_required`로 반환되면 Edge process를 새 config로 재시작한 뒤 Node reconnect 상태를 확인한다. 6. `qwen3.6:35b`로 `/v1/responses`와 `/v1/chat/completions` 각각에 provider capacity 총합 + 1개 동시 요청을 보낸다. -7. capacity `gx10-vllm=4`, `onexplayer-lemonade=3` 기준이면 endpoint별 8개 동시 요청에서 Control Plane status의 provider snapshot이 총 `in_flight=7`, `queued>=1`을 한 번 이상 보여야 한다. +7. capacity `gx10-vllm=4`, `onexplayer-lemonade=3`, `mac-mlx-vllm=3` 기준이면 endpoint별 11개 동시 요청에서 Control Plane status의 provider snapshot이 총 `in_flight=10`, `queued>=1`을 한 번 이상 보여야 한다. 13개 동시 확장 smoke에서는 `in_flight=10`, `queued>=3`을 기대한다. 8. 요청 완료 후 provider snapshot이 `in_flight=0`, `queued=0`으로 회복되는지 확인한다. +2026-06-24 dev 13-way 확장 smoke에서는 `/v1/chat/completions` 13개 요청이 모두 성공했고 peak `in_flight=10`, 실제 queue 대기 `3`개가 관측되었다. 초기 peak는 `gx10-vllm=4`, `onexplayer-lemonade=3`, `mac-mlx-vllm=3`으로 꽉 찼고, 초과 대기분은 slot이 먼저 빈 provider로 dispatch되었다. 같은 run에서 최종 처리 건수는 GX10 4건, OneXPlayer 3건, Mac MLX 6건이었다. + Qwen 계열 모델은 thinking/reasoning 텍스트를 포함해 응답할 수 있다. 이 dev smoke에서는 thinking 출력을 실패로 보지 않고, HTTP 성공, final marker 포함, provider log/run count 증가를 기준으로 판정한다. 현재 공개 API는 개별 request의 최종 `node_id`를 응답에 노출하지 않는다. 요청별 배정을 확정해야 할 때는 Edge dispatch trace/log를 추가한 뒤 판정한다.