From e8c240ea23a29f1568326b6d162913863b3dca33 Mon Sep 17 00:00:00 2001 From: leedongmyun Date: Thu, 9 Jul 2026 18:07:18 +0900 Subject: [PATCH 1/4] =?UTF-8?q?chore(dev-corp):=20dev-corp=20=ED=99=98?= =?UTF-8?q?=EA=B2=BD=EC=9D=98=20=EA=B7=9C=EC=B9=99=20=EB=B0=8F=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=8A=A4=EB=AA=A8=ED=81=AC=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EB=A5=BC=20=EC=97=85=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=8A=B8=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- agent-ops/rules/project/rules.md | 2 +- .../project/dev-corp-runtime-deploy/SKILL.md | 51 +++-- agent-test/dev-corp/control-plane-smoke.md | 2 +- agent-test/dev-corp/edge-smoke.md | 50 ++--- agent-test/dev-corp/inventory.yaml | 177 ++++++++++++------ agent-test/dev-corp/node-smoke.md | 34 ++-- agent-test/dev-corp/platform-common-smoke.md | 4 +- agent-test/dev-corp/rules.md | 24 +-- agent-test/dev-corp/testing-smoke.md | 4 +- 9 files changed, 204 insertions(+), 144 deletions(-) diff --git a/agent-ops/rules/project/rules.md b/agent-ops/rules/project/rules.md index 02d06cb..4c5ca4c 100644 --- a/agent-ops/rules/project/rules.md +++ b/agent-ops/rules/project/rules.md @@ -94,7 +94,7 @@ ## 스킬 라우팅 -- dev-corp 배포, dev-corp runtime 배포, 회사망 mac-mini Edge/Node dev-corp 환경 배포, dev-corp provider pool 배포, dev-corp OpenAI-compatible capacity smoke 검증: `agent-ops/skills/project/dev-corp-runtime-deploy/SKILL.md` +- dev-corp 배포, dev-corp runtime 배포, public digitalplatform Edge/내부 Node dev-corp 환경 배포, dev-corp provider pool 배포, dev-corp OpenAI-compatible capacity smoke 검증: `agent-ops/skills/project/dev-corp-runtime-deploy/SKILL.md` - dev 배포, dev-runtime 배포, Edge/Node dev 환경 배포, provider pool 배포, OpenAI-compatible capacity smoke 검증: `agent-ops/skills/project/dev-runtime-deploy/SKILL.md` - 사용자 실행 파이프라인 검증, repo 내부 edge-node 진단, 메시지 2회 왕복, edge command 응답, 보조 E2E smoke, full-cycle 실제 구동, `scripts/dev/edge.sh`/`scripts/dev/node.sh` 진단 테스트: `agent-ops/skills/project/e2e-smoke/SKILL.md` - field 테스트 포트, artifact/bootstrap HTTP, 외부 테스트 환경: `agent-test/local/rules.md`를 따른다. diff --git a/agent-ops/skills/project/dev-corp-runtime-deploy/SKILL.md b/agent-ops/skills/project/dev-corp-runtime-deploy/SKILL.md index 3b6873f..3896439 100644 --- a/agent-ops/skills/project/dev-corp-runtime-deploy/SKILL.md +++ b/agent-ops/skills/project/dev-corp-runtime-deploy/SKILL.md @@ -1,21 +1,21 @@ --- name: dev-corp-runtime-deploy -version: 1.0.4 -description: dev-corp 배포, 회사망 mac-mini Edge와 내부 DGX/Mac Studio provider pool 배포 및 OpenAI-compatible capacity smoke 절차 +version: 1.0.7 +description: dev-corp 배포, public digitalplatform Edge와 내부 DGX/Mac Studio provider pool 배포 및 OpenAI-compatible capacity smoke 절차 --- # dev-corp-runtime-deploy ## 목적 -dev-corp provider pool을 현재 dev-runtime과 같은 구조로 배포한다. 배포는 mac-mini checkout 준비, source clean sync, 테스트, dev-corp runtime rebuild, native Control Plane 활성화, Edge/Node 재시작, provider snapshot 기반 capacity 검증까지 포함한다. +dev-corp provider pool을 현재 dev-runtime과 같은 구조로 배포한다. 배포는 runner checkout 준비, source clean sync, 테스트, dev-corp runtime rebuild, public Edge/Node 재시작, provider snapshot 기반 capacity 검증까지 포함한다. 현재 dev-corp Edge runtime은 `digitalplatform-iop.cloud`이며, mac-mini는 source/build/provider SSH runner로만 사용한다. ## 언제 호출할지 - 사용자가 `dev-corp 배포`, `dev-corp runtime 배포`, `회사 dev 환경 배포`처럼 dev-corp 환경 배포를 요청할 때 -- mac-mini Edge와 DGX Spark 01/02 vLLM node, Mac Studio vLLM-MLX node로 이루어진 provider pool을 갱신할 때 +- public `digitalplatform-iop.cloud` Edge와 DGX Spark 01/02 vLLM node, Mac Studio vLLM-MLX node로 이루어진 provider pool을 갱신할 때 - dev-corp model alias, provider endpoint, provider capacity, node 접속 정보를 배포 절차에 반영할 때 -- dev-corp OpenAI-compatible `/v1/responses` 또는 `/v1/chat/completions` 경로가 provider capacity만큼 채워지는지 검증할 때 +- dev-corp OpenAI-compatible `/v1/chat/completions` 경로가 provider capacity만큼 채워지는지 검증할 때 ## 입력 @@ -28,12 +28,12 @@ dev-corp provider pool을 현재 dev-runtime과 같은 구조로 배포한다. - [ ] `agent-ops/rules/project/domain/testing/rules.md`를 읽고 사용자 실행 파이프라인 검증 기준을 확인한다. - [ ] `agent-test/dev-corp/inventory.yaml`을 먼저 읽는다. 파일이 없으면 `agent-test/dev-corp/rules.md`, `agent-test/dev-corp/edge-smoke.md`, `agent-test/dev-corp/node-smoke.md`로 fallback하고, 구조화 inventory 누락을 보고한다. -- [ ] dev-corp 기본 외부 배포/검증 통로는 `digitalplatform-iop.cloud`이다. `172.24.63.178`은 mac-mini runner와 node-only/internal 경로로만 보고, 사용자가 172 Edge 경로를 명시 요청하지 않으면 Edge 배포, OpenAI-compatible smoke, public endpoint 기본값으로 잡지 않는다. -- [ ] dev-corp provider pool과 compose/local/dev-runtime profile을 섞지 않는다. dev-corp provider pool은 mac-mini Edge와 dev-corp config를 기준으로 한다. +- [ ] dev-corp Edge 배포/검증 통로는 `digitalplatform-iop.cloud`이다. mac-mini runner/provider 관리 경유지를 Edge 배포, OpenAI-compatible smoke, Node `edge_addr`, bootstrap 기본 URL로 잡지 않는다. +- [ ] dev-corp provider pool과 compose/local/dev-runtime profile을 섞지 않는다. dev-corp provider pool은 public `digitalplatform-iop.cloud` Edge와 dev-corp config를 기준으로 한다. - [ ] mac-mini에 `/Users/fe/agent-work/iop-dev-corp` checkout이 없으면 배포를 시작하지 말고 checkout 생성과 source sync를 setup blocker로 보고한다. - [ ] mac-mini에서 `192.168.2.2:8002`, `192.168.2.4:8004`, `192.168.2.3:8004`의 `/health`와 `/v1/models`가 성공하는지 확인한다. - [ ] Edge config의 OpenAI-compatible adapter endpoint는 각 Node process 기준으로 평가된다. direct preflight는 `192.168.2.x` 주소로 하되, Edge가 Node에 내려주는 provider endpoint는 node-local `127.0.0.1:`를 우선한다. -- [ ] DGX Spark 01/02가 node-only/internal mac-mini 경로 `172.24.63.178:18085/18086/18087`에 직접 접근하지 못하면 mac-mini에서 reverse SSH tunnel을 유지하고 해당 Node Edge addr을 tunnel local port로 설정한다. 이 경로는 172 명시 요청 또는 Node 연결 예외 처리에만 사용한다. +- [ ] DGX Spark 01/02와 Mac Studio Node의 Edge addr은 `digitalplatform-iop.cloud:18087`이다. mac-mini local route 또는 reverse SSH tunnel은 현재 기준 잘못된 Edge addr이며 명시적인 rollback/장애 비교 외에는 사용하지 않는다. - [ ] `gemma4:26b` alias와 총 capacity `13`은 `agent-test/dev-corp/inventory.yaml`의 최신 검증 상태를 기준으로 판단한다. 새 배포에서 Edge config 반영과 capacity smoke가 통과하기 전에는 새 결과를 확정값으로 보고하지 않는다. - [ ] DGX Spark vLLM provider는 capacity `4`, 호출당 최대 context window `262144`, requested KV `262144x2` 이상을 기준으로 한다. vLLM에는 vLLM-MLX식 `--max-kv-size`가 없으므로 실제 KV cache는 `gpu_memory_utilization` 적용 후 startup log의 `GPU KV cache size`와 `Maximum concurrency for 262,144 tokens per request`로 검증한다. DGX01/02 검증 기준은 `vllm=0.24.0`, `--max-num-seqs 4`, `--max-model-len 262144`, `--gpu-memory-utilization 0.40`이고, FP4 MoE 커널 한계 보정을 위해 `VLLM_MAX_TOKENS_PER_EXPERT_FP4_MOE=4194304`도 함께 둔다. Gemma4 agent/tool-call profile은 `--enforce-eager`, `--skip-mm-profiling`, `--limit-mm-per-prompt '{"image": 0, "video": 0}'`, `--mm-processor-cache-gb 0`, `--enable-auto-tool-choice`, `--tool-call-parser gemma4`, Gemma4 tool chat template, `--reasoning-parser gemma4`, `--default-chat-template-kwargs '{"enable_thinking":true}'`를 함께 둔다. - [ ] DGX Spark 02 endpoint는 Docker publish 때문에 `192.168.2.4:8004`이다. `8000`, `8001`, `8002`를 기본 endpoint로 쓰지 않는다. @@ -52,21 +52,21 @@ dev-corp provider pool을 현재 dev-runtime과 같은 구조로 배포한다. - DGX Spark 02 Docker image `vllm/vllm-openai:v0.24.0`의 entrypoint는 이미 `vllm serve`이다. container command에는 `serve`를 중복으로 넣지 말고 positional model `/models/gemma-4-26B-A4B-it-NVFP4`부터 둔다. 현재 Docker publish는 host `8004` -> container `8004` 기준이다. - Gemma4 tool-call/parser profile은 capacity/KV 튜닝과 별개로 agent 동작 가능성을 결정한다. DGX Spark 01은 `/home/digitalcommerce_dgx_spark_01/tool_chat_template_gemma4.jinja`, DGX Spark 02는 `/vllm-workspace/examples/tool_chat_template_gemma4.jinja`를 `--chat-template`로 사용하고, 둘 다 `--enforce-eager --skip-mm-profiling --limit-mm-per-prompt '{"image": 0, "video": 0}' --mm-processor-cache-gb 0 --enable-auto-tool-choice --tool-call-parser gemma4 --reasoning-parser gemma4 --default-chat-template-kwargs '{"enable_thinking":true}'`를 둔다. Mac Studio vLLM-MLX는 별도 chat template override 없이 `--continuous-batching --disable-prefix-cache --enable-auto-tool-choice --tool-call-parser gemma4 --reasoning-parser gemma4 --default-chat-template-kwargs '{"enable_thinking":true}'`를 둔다. - 모델별 parser/template 값은 섞지 않는다. Gemma 계열은 `tool_call_parser=gemma4`, `reasoning_parser=gemma4`, Gemma4 tool chat template 또는 vLLM-MLX 기본 template kwargs를 사용한다. Qwen 계열은 dev-runtime 문서의 `tool_call_parser=qwen`, `reasoning_parser=qwen3`, Qwen 전용 chat template 검증값을 따르며 Gemma4 parser/template을 재사용하지 않는다. -- Pi agent dev-corp profile은 `agent-test/dev-corp/inventory.yaml`의 `model.pi_agent_profile`을 기준으로 한다. 2026-07-09 현재 host-local Pi 기본 경로는 Edge OpenAI-compatible alias route인 `dev-corp` / `gemma4:26b` / thinking `high`이고, base URL은 `http://172.24.63.178:18086/v1`이다. Mac Studio direct provider `dev-corp-direct` / `mlx-community/gemma-4-26b-a4b-it-nvfp4`와 DGX Spark 01 direct provider `dev-corp-spark01` / `gemma-4-26B-A4B-it-NVFP4`는 non-default direct/fallback profile로 둔다. +- Pi agent dev-corp profile은 `agent-test/dev-corp/inventory.yaml`의 `model.pi_agent_profile`을 기준으로 한다. 2026-07-09 현재 Pi 기본 경로는 Edge OpenAI-compatible alias route인 `dev-corp` / `gemma4:26b` / thinking `high`이고, base URL은 `http://digitalplatform-iop.cloud:18086/v1`이다. Mac Studio direct provider `dev-corp-direct` / `mlx-community/gemma-4-26b-a4b-it-nvfp4`와 DGX Spark 01 direct provider `dev-corp-spark01` / `gemma-4-26B-A4B-it-NVFP4`는 non-default direct/fallback profile로 둔다. - Mac Studio는 `DYLD_LIBRARY_PATH=/opt/homebrew/opt/expat/lib` 없이 Python `pyexpat` import가 실패할 수 있다. `screen` session `vllm_mlx_8004` 안에서 이 환경변수를 export한 뒤 시작한다. - 2026-07-08 재확인 기준 Mac Studio vLLM-MLX는 `/Users/dc_dev/vllm-env-0.4.0/bin/python` 환경의 `vllm-mlx=0.4.0`, `mlx=0.32.0`, `mlx-lm=0.31.3`, `mlx-vlm=0.6.4`, `transformers=5.12.1`, `huggingface-hub=1.22.0`로 동작한다. `--continuous-batching`은 유지하고 `--disable-prefix-cache`를 추가했으며, `/health`, `/v1/models`, 직접 API non-stream/stream auto tool-call, streaming multi-turn tool-result final answer, Pi `-p` tool-call, Pi TUI 초기 프롬프트 tool-call 로그 종료를 확인했다. - Mac Studio vLLM-MLX의 현 값은 "구동 가능한 최종 체크포인트"로 취급한다. 추가 미세 조정은 새 포트/새 venv 또는 명시적 rollback 지점을 둔 별도 실험으로만 수행하고, Spark 01/02 vLLM 설정이나 Pi 기본 provider/model을 함께 변경하지 않는다. 알려진 잔여 이슈는 Gemma4 thought channel delimiter가 최종 content에 누수될 수 있는 점이며, 이 경우 serving 옵션을 계속 흔들기보다 Pi extension/provider adapter에서 vLLM-MLX Gemma 전용 sanitizer로 containment 하는 방향을 우선 검토한다. - 2026-07-08 재확인 기준 DGX Spark 01은 vLLM 0.24.0 text-only/eager profile과 `default_chat_template_kwargs.enable_thinking=true`로 재기동 후 mac-mini 내부 endpoint `http://192.168.2.2:8002`에서 `/health` 200과 `/v1/models`, 직접 API forced/auto/streaming tool-call smoke, 로컬 Pi TUI bash/git-push tool-call 흐름을 통과했고 startup log에서 GPU KV cache `1,453,705` tokens, full-context concurrency `5.55x`를 확인했다. - 2026-07-08 재확인 기준 DGX Spark 02는 Docker `vllm-gemma4` image `vllm/vllm-openai:v0.24.0`, host/container `8004`, text-only/eager profile과 `default_chat_template_kwargs.enable_thinking=true`로 동작하며 mac-mini와 node-local `/health`, `/v1/models`, 직접 API auto/streaming tool-call smoke를 통과했다. startup log에서 GPU KV cache `1,452,633` tokens, full-context concurrency `5.54x`를 확인했다. -- 2026-07-02 기준 native Control Plane은 mac-mini provider-pool runtime에서 `18002/19004/19005`를 listen하고, Edge id `dev-corp-edge`가 `127.0.0.1:19005`로 connected 상태다. status URL은 `http://127.0.0.1:18002/edges/dev-corp-edge/status`이다. -- 2026-07-08 기준 dev-corp provider-pool Edge OpenAI-compatible capacity smoke 표준은 `/v1/responses`와 `/v1/chat/completions` 각각 15개 동시 요청이다. provider capacity 합은 `4 + 4 + 5 = 13`으로 유지하고, Control Plane provider snapshot에서 peak total `in_flight=13`, `queued>=2`, 완료 후 provider별 `in_flight=0`, `queued=0` 회복을 성공 기준으로 본다. -- 2026-07-08 source ref `c2437aaedefbac4312d69dfd10aa017c2739e187` 재배포 검증에서 `/v1/responses`와 `/v1/chat/completions` 모두 15/15 성공했다. 두 endpoint 모두 peak total `in_flight=13`, `queued=6`, provider별 max queued `2`, 최종 회복 `in_flight=0`, `queued=0`으로 통과했으며 원격 evidence는 mac-mini `build/dev-corp-runtime/logs/capacity_15_20260708_155027.json`이다. +- 2026-07-02 mac-mini native Control Plane `18002/19004/19005` 관측값은 historical evidence다. 2026-07-09 현재 dev-corp Edge source of truth는 public `digitalplatform-iop.cloud`이고, current runner에서 public host SSH와 public Control Plane status 접근은 확인되지 않았다. +- 2026-07-09 기준 dev-corp provider-pool Edge OpenAI-compatible capacity smoke 표준은 public `http://digitalplatform-iop.cloud:18086/v1/chat/completions` 15개 동시 요청이다. `/v1/responses`는 OpenAI-compatible provider model group raw passthrough parity 전까지 미지원이므로 성공 기준에서 제외한다. +- 2026-07-09 public Edge 재연결 검증에서 DGX Spark 01/02와 Mac Studio node를 `digitalplatform-iop.cloud:18087`로 변경한 뒤 `/v1/chat/completions` 15개 동시 요청이 15/15 성공했다. 같은 날 current passthrough source로 public Edge를 재빌드/재시작한 뒤 기본 streaming `/v1/chat/completions` 15/15에서 provider reasoning delta가 유지됐고 transformed `chatcmpl-manual` ID는 0/15였다. 원격 evidence는 `build/dev-corp-runtime/logs/public_passthrough_chat_15_20260709_180115.json`이다. 2026-07-08 `/v1/responses` 통과 기록은 mac-mini provider-pool runtime 기준 legacy evidence로만 본다. ## 실행 절차 1. **환경 인벤토리 확정** - 배포 대상 runner, repo path, Edge id, Control Plane status URL, OpenAI base URL, Edge admin URL, Node SSH 정보를 `agent-test/dev-corp/inventory.yaml`에서 확정한다. - - public OpenAI/base, bootstrap/artifact, Control Plane/Client 외부 후보는 기본적으로 `digitalplatform-iop.cloud` 경로를 사용한다. `172.24.63.178`로 Edge를 배포하는 것은 기본 금지이며, 사용자가 172 Edge 경로를 명시 요청한 경우에만 진행한다. + - public OpenAI/base, bootstrap/artifact, Edge-Node TCP는 기본적으로 `digitalplatform-iop.cloud` 경로를 사용한다. mac-mini runner/provider 관리 경로로 Edge를 배포하거나 Node를 붙이는 것은 기본 금지이며, 사용자가 mac-mini local 비교를 명시 요청한 경우에만 별도 비교로 진행한다. - provider pool 대상 model alias와 provider별 capacity target을 확정한다. - 필수 정보가 없거나 서로 충돌하면 배포를 시작하지 말고 누락/충돌 항목을 보고한다. @@ -100,28 +100,28 @@ dev-corp provider pool을 현재 dev-runtime과 같은 구조로 배포한다. - dry-run이 `rejected` 또는 예상 밖 `restart_required`를 반환하면 배포를 멈추고 config diff를 보고한다. 7. **배포와 재시작** - - Control Plane은 mac-mini에서 `build/dev-corp-runtime/bin/control-plane` 기준으로 `18002/19004/19005` dev-corp port를 listen하게 재시작한다. - - Edge는 mac-mini에서 빌드 산출물 기준으로 재시작하고, Edge config의 `control_plane.enabled=true`, `wire_addr=127.0.0.1:19005`를 확인한다. + - Control Plane이 public host에서 운용되는 경우 `digitalplatform-iop.cloud:18002/19004/19005` dev-corp port를 기준으로 확인한다. mac-mini local Control Plane은 dev-corp Edge source of truth가 아니다. + - Edge는 public `digitalplatform-iop.cloud` host에서 `18085/18086/18087`을 기준으로 재시작/확인한다. mac-mini runner runtime은 dev-corp Edge source of truth가 아니다. - DGX Spark 01/02는 Linux ARM64 node binary를 mac-mini 경유로 배포하고 기존 node process를 재시작한다. - Mac Studio는 macOS node binary를 mac-mini 경유로 배포하고 기존 node process를 재시작한다. - provider runtime 옵션을 갱신하는 배포라면 DGX Spark 01은 `/home/digitalcommerce_dgx_spark_01/start_vllm_8002.sh`의 `PATH=/home/digitalcommerce_dgx_spark_01/vllm_env_0_24_0/bin:$PATH`, `VLLM_MAX_TOKENS_PER_EXPERT_FP4_MOE=4194304`, `--max-num-seqs 4`, `--max-model-len 262144`, `--gpu-memory-utilization 0.40`, `--enforce-eager`, `--skip-mm-profiling`, `--limit-mm-per-prompt '{"image": 0, "video": 0}'`, `--mm-processor-cache-gb 0`, `--enable-auto-tool-choice`, `--tool-call-parser gemma4`, `--chat-template /home/digitalcommerce_dgx_spark_01/tool_chat_template_gemma4.jinja`, `--reasoning-parser gemma4`, `--default-chat-template-kwargs '{"enable_thinking":true}'`를 확인하고 tmux `vllm_server_8002`를 재기동한다. - provider runtime 옵션을 갱신하는 배포라면 DGX Spark 02는 Docker container `vllm-gemma4`를 image `vllm/vllm-openai:v0.24.0` entrypoint `vllm serve` 기준으로 재생성한다. container env에는 `VLLM_MAX_TOKENS_PER_EXPERT_FP4_MOE=4194304`를 넣고, container args는 positional model `/models/gemma-4-26B-A4B-it-NVFP4` 뒤에 `--max-model-len 262144`, `--gpu-memory-utilization 0.40`, `--max-num-seqs 4`, `--port 8004`, `--enforce-eager`, `--skip-mm-profiling`, `--limit-mm-per-prompt '{"image": 0, "video": 0}'`, `--mm-processor-cache-gb 0`, `--enable-auto-tool-choice`, `--tool-call-parser gemma4`, `--chat-template /vllm-workspace/examples/tool_chat_template_gemma4.jinja`, `--reasoning-parser gemma4`, `--default-chat-template-kwargs '{"enable_thinking":true}'`를 둔다. - provider runtime 옵션을 갱신하는 배포라면 Mac Studio는 `screen -dmS vllm_mlx_8004` 안에서 `DYLD_LIBRARY_PATH=/opt/homebrew/opt/expat/lib`를 export한 뒤 `/Users/dc_dev/vllm-env-0.4.0/bin/python -m vllm_mlx.cli serve`를 `--continuous-batching`, `--max-num-seqs 6`, `--prefill-batch-size 6`, `--completion-batch-size 6`, `--chunked-prefill-tokens 1024`, `--disable-prefix-cache`, `--max-kv-size 786432`, `--max-request-tokens 262144`, `--enable-auto-tool-choice`, `--tool-call-parser gemma4`, `--reasoning-parser gemma4`, `--default-chat-template-kwargs '{"enable_thinking":true}'`로 재기동한다. - - Node bootstrap은 Edge의 `node register`가 출력한 OS별 완성 명령을 우선한다. 다만 node-local provider endpoint, 별도 `IOP_HOME`, 또는 DGX Spark 01/02 reverse tunnel처럼 host별 Edge addr이 필요한 경우에는 `~/iop-dev-corp-field/node.yaml`을 수동 배치할 수 있고, token 원문은 로그/보고에 남기지 않는다. + - Node bootstrap은 Edge의 `node register`가 출력한 OS별 완성 명령을 우선한다. Node `edge_addr`는 `digitalplatform-iop.cloud:18087`이어야 한다. node-local provider endpoint 또는 별도 `IOP_HOME`이 필요한 경우에는 `~/iop-dev-corp-field/node.yaml`을 수동 배치할 수 있고, token 원문은 로그/보고에 남기지 않는다. 8. **배포 후 연결 검증** - Edge, OpenAI-compatible listener, Node TCP, admin port, Control Plane status port가 열려 있는지 확인한다. - - Control Plane status에서 Edge가 connected이고 dev-corp 기준 3개 provider node가 connected인지 확인한다. - - 각 node의 `provider_snapshots`에서 provider `id`, `capacity`, `in_flight`, `queued`, `health`, `served_models`를 확인한다. + - public Control Plane status가 접근 가능하면 Edge가 connected이고 dev-corp 기준 3개 provider node가 connected인지 확인한다. + - public Control Plane status가 접근 가능하면 각 node의 `provider_snapshots`에서 provider `id`, `capacity`, `in_flight`, `queued`, `health`, `served_models`를 확인한다. 접근할 수 없으면 Node log의 `registered with edge`/`connected to edge`와 public OpenAI-compatible smoke 결과를 연결 증거로 분리 보고한다. - `/v1/models`가 대상 model alias를 노출하는지 확인한다. 9. **OpenAI-compatible capacity smoke** - - `/v1/responses`와 `/v1/chat/completions`를 각각 검증한다. legacy `/v1/completions`는 구현되어 있지 않으면 실패로 보지 않는다. + - `/v1/chat/completions`를 검증한다. `/v1/responses`는 OpenAI-compatible provider model group raw passthrough parity 전까지 미지원이므로 provider-pool capacity 성공 기준에서 제외한다. legacy `/v1/completions`는 route가 구현되어 있지 않으면 실패로 보지 않는다. - 표준 부하 프롬프트는 700~1200 token 수준의 구조화된 답변을 유도해 요청이 동시에 관측될 시간을 만든다. - endpoint별로 15개 요청을 동시에 보낸다. Edge config에서 기본 dev-corp 후보 capacity `4 + 4 + 5 = 13`을 확정한 경우 15개 동시 호출에서 capacity 초과분 2개 이상이 queue에 잡혀야 한다. - - 요청 실행 중 Control Plane status를 반복 polling하여 대상 provider들의 `in_flight` 합이 총 capacity에 도달하고 `queued` 합이 2 이상이 되는 순간을 증거로 남긴다. - - 각 provider의 `in_flight`가 자기 capacity를 넘지 않고, 적어도 한 번은 기대 capacity까지 차는지 확인한다. - - 모든 요청 완료 후 같은 status에서 대상 provider들의 `in_flight=0`, `queued=0`으로 돌아오는지 확인한다. + - public Control Plane status가 접근 가능하면 요청 실행 중 반복 polling하여 대상 provider들의 `in_flight` 합이 총 capacity에 도달하고 `queued` 합이 2 이상이 되는 순간을 증거로 남긴다. + - public Control Plane status가 접근 가능하면 각 provider의 `in_flight`가 자기 capacity를 넘지 않고, 적어도 한 번은 기대 capacity까지 차는지 확인한다. + - public Control Plane status가 접근 가능하면 모든 요청 완료 후 같은 status에서 대상 provider들의 `in_flight=0`, `queued=0`으로 돌아오는지 확인한다. 접근할 수 없으면 HTTP 15/15 결과와 Node 연결 로그만으로 smoke 통과와 capacity snapshot 미관측을 구분한다. - Gemma 계열 reasoning/tool-parser 텍스트는 정상 응답으로 허용한다. exact-output match를 smoke 성공 기준으로 삼지 않는다. - Pi/Cline형 agent/tool-call 경계를 검증할 때는 forced tool call, auto tool call, streaming `delta.tool_calls`, multi-turn tool result 후 최종 답변을 provider direct와 Edge OpenAI-compatible 경로에서 나눠 확인한다. provider direct가 통과하고 Edge 경유만 실패하면 provider runtime option 문제가 아니라 Edge/Node relay 또는 validation 경계 문제로 분리한다. @@ -138,7 +138,6 @@ dev-corp provider pool을 현재 dev-runtime과 같은 구조로 배포한다. - [ ] dev-corp Control Plane/Edge/mac/Linux ARM64 binary가 같은 source ref에서 rebuild되었는가 - [ ] 빌드 후 config check, refresh help, refresh dry-run이 통과했는가 - [ ] Edge와 3개 provider node가 재시작되고 connected 상태인가 -- [ ] `/v1/responses` capacity smoke에서 총 capacity만큼 `in_flight`가 차고 초과 요청이 queue에 잡혔는가 - [ ] `/v1/chat/completions` capacity smoke에서 총 capacity만큼 `in_flight`가 차고 초과 요청이 queue에 잡혔는가 - [ ] 완료 후 provider `in_flight=0`, `queued=0`으로 회복되었는가 - 검증 실패 시: 실패 단계, 실패한 host/provider/endpoint, 관측된 snapshot, 진행 중단 여부를 보고한다. @@ -156,7 +155,7 @@ dev-corp runtime 배포 결과 - Ports: - Nodes: - Providers: -- OpenAI-compatible: models=, responses-capacity=, chat-completions-capacity= +- OpenAI-compatible: models=, chat-completions-capacity=, responses-provider-pool= - Capacity evidence: - Blockers/Risk: <없음 또는 내용> ``` @@ -164,7 +163,7 @@ dev-corp runtime 배포 결과 ## 금지 사항 - mac-mini checkout이 없거나 dirty/divergent 상태인데 배포를 계속하지 않는다. -- 사용자가 명시적으로 요청하지 않았는데 `172.24.63.178`로 Edge를 배포하거나 `172.24.63.178`을 dev-corp 기본 public 배포/검증 경로로 사용하지 않는다. +- 사용자가 명시적으로 요청하지 않았는데 mac-mini runner/provider 관리 경로를 dev-corp Edge runtime, Node `edge_addr`, bootstrap 기본 URL, OpenAI-compatible base URL로 사용하지 않는다. - `git clean -fdx`를 기본 cleanup으로 사용하지 않는다. - 빌드 전 테스트 실패 후 배포를 계속하지 않는다. - DGX Spark 02 provider endpoint를 `192.168.2.4:8000`, `8001`, `8002`로 잘못 사용하지 않는다. @@ -172,5 +171,5 @@ dev-corp runtime 배포 결과 - Mac Studio `8004` vLLM-MLX runtime 재시작 방식을 확인하지 않고 provider process를 임의 종료하지 않는다. - node02처럼 tunnel 예외가 필요한 경우를 제외하고 Node bootstrap 기본 경로에서 수동 token 치환, named env parameter, 수동 `node.yaml` 작성을 요구하지 않는다. - Gemma reasoning/tool-parser 출력을 실패로 판정하거나 exact-output smoke를 기본 성공 기준으로 삼지 않는다. -- OpenAI-compatible 요청 성공만으로 capacity 검증 성공을 선언하지 않는다. provider snapshot의 `in_flight/queued` 관측을 함께 남긴다. +- OpenAI-compatible 요청 성공만으로 provider snapshot capacity 관측 성공을 선언하지 않는다. public Control Plane status가 접근 가능할 때만 `in_flight/queued` 관측 성공을 함께 남기고, 접근할 수 없으면 capacity snapshot 미관측으로 분리 보고한다. - 이 프로젝트 전용 배포 절차를 `agent-ops/rules/common/_templates` 또는 common skill에 넣지 않는다. diff --git a/agent-test/dev-corp/control-plane-smoke.md b/agent-test/dev-corp/control-plane-smoke.md index 426be42..446b7bb 100644 --- a/agent-test/dev-corp/control-plane-smoke.md +++ b/agent-test/dev-corp/control-plane-smoke.md @@ -67,7 +67,7 @@ last_rule_updated_at: 2026-07-02 - Edge config는 `control_plane.enabled=true`, `wire_addr=127.0.0.1:19005`이며 Edge id는 `dev-corp-edge`다. - `/edges`에서 `dev-corp-edge`가 `connected=true`로 관측된다. - `/edges/dev-corp-edge/status`는 Edge-owned snapshot을 반환하며 3개 provider node의 `provider_snapshots`를 포함한다. 이 status는 provider capacity smoke의 `in_flight`/`queued` evidence 기준이다. -- 2026-07-02 capacity smoke에서 `/v1/responses`와 `/v1/chat/completions` 모두 peak total `in_flight=13`, `queued=3`, 완료 후 provider별 `in_flight=0`, `queued=0` 회복을 확인했다. +- 2026-07-02 mac-mini runtime capacity smoke에서 `/v1/responses`와 `/v1/chat/completions` 모두 peak total `in_flight=13`, `queued=3`, 완료 후 provider별 `in_flight=0`, `queued=0` 회복을 확인했다. 이 기록은 historical evidence이며, current public Edge provider-pool 표준 smoke는 `/v1/chat/completions`만 사용한다. ## 판정 기준 diff --git a/agent-test/dev-corp/edge-smoke.md b/agent-test/dev-corp/edge-smoke.md index d679c52..d4463c5 100644 --- a/agent-test/dev-corp/edge-smoke.md +++ b/agent-test/dev-corp/edge-smoke.md @@ -3,7 +3,7 @@ test_env: dev-corp test_profile: edge-smoke domain: edge verification_type: smoke -last_rule_updated_at: 2026-07-08 +last_rule_updated_at: 2026-07-09 --- # edge-smoke dev-corp 테스트 @@ -33,30 +33,31 @@ last_rule_updated_at: 2026-07-08 ## 환경 -- host: local checkout. dev-corp runtime, provider pool, shared port evidence가 필요하면 mac-mini `ssh fe@172.24.63.178`의 `/Users/fe/agent-work/iop-dev-corp` checkout을 사용한다. +- host: local checkout. provider pool과 source/build evidence가 필요하면 mac-mini `ssh fe@172.24.63.178`의 `/Users/fe/agent-work/iop-dev-corp` checkout을 사용한다. +- Edge runtime evidence: public `digitalplatform-iop.cloud` host를 기준으로 한다. - port: compose Edge-Node TCP transport `19006`; native provider-pool Edge-Node TCP 후보 `18087`; artifact/bootstrap HTTP 후보 `18085`; Edge OpenAI-compatible HTTP 후보 `18086`; Edge metrics 후보 `19102`; admin 후보 `19094`. - runtime: Go `1.24` - package manager: Go modules / Makefile - docker: unit/smoke quick check는 Docker를 요구하지 않는다. compose dev-corp 검증은 mac-mini에서 `.env.dev-corp.example` 기준으로 수행한다. -- external service: dev-corp artifact/base URL 기본 후보 `http://digitalplatform-iop.cloud:18085`, dev-corp Edge runtime 기본 후보 `digitalplatform-iop.cloud:18087`; `172.24.63.178:18085/18087`로 Edge를 배포하는 것은 기본 금지이며, 사용자가 172 Edge 경로를 명시 요청한 경우에만 사용한다. +- external service: dev-corp artifact/base URL 기본 후보 `http://digitalplatform-iop.cloud:18085`, dev-corp Edge runtime 기본 후보 `digitalplatform-iop.cloud:18087`; mac-mini local endpoint는 dev-corp Edge 경로로 사용하지 않는다. - model endpoint: dev-corp OpenAI-compatible base URL 기본 후보 `http://digitalplatform-iop.cloud:18086/v1` - credential: token/secret/API key 원문은 문서에 기록하지 않는다. ## dev-corp provider pool 인벤토리 -dev-corp provider pool과 3-node 연결 상태를 점검할 때는 `agent-test/dev-corp/inventory.yaml`의 machine-readable 값을 우선하고, mac-mini `ssh fe@172.24.63.178`의 `/Users/fe/agent-work/iop-dev-corp` checkout을 기준으로 한다. +dev-corp provider pool과 3-node 연결 상태를 점검할 때는 `agent-test/dev-corp/inventory.yaml`의 machine-readable 값을 우선한다. Edge runtime은 public `digitalplatform-iop.cloud`이며, mac-mini checkout은 source/build/provider SSH runner로만 사용한다. -- Edge host: `Mac-mini.local`, `fe@172.24.63.178`, Apple M2 Pro / 16GB -- Edge config: `build/dev-corp-runtime/edge.yaml` +- Edge host: `digitalplatform-iop.cloud` / `115.21.224.82` +- Edge config: public host runtime config at `/Users/toki/agent-work/iop-dev-corp/build/dev-corp-runtime/edge.yaml`. - Edge id: `dev-corp-edge` -- Control Plane HTTP/status 후보: `http://127.0.0.1:18002`, `http://127.0.0.1:18002/edges/dev-corp-edge/status` -- Control Plane-Edge wire 후보: `127.0.0.1:19005` +- Control Plane HTTP/status 후보: `http://digitalplatform-iop.cloud:18002`, `http://digitalplatform-iop.cloud:18002/edges/dev-corp-edge/status` when the public port is enabled +- Control Plane-Edge wire 후보: `digitalplatform-iop.cloud:19005` when the public port is enabled - bootstrap HTTP 기본 후보: `http://digitalplatform-iop.cloud:18085` - Edge OpenAI-compatible base URL 기본 후보: `http://digitalplatform-iop.cloud:18086/v1` - Edge-Node TCP transport 기본 후보: `digitalplatform-iop.cloud:18087` -- node-only/internal 후보: `172.24.63.178:18085/18086/18087`은 기본 Edge 배포 후보가 아니다. 사용자가 172 Edge 경로를 명시 요청했거나 host별 reverse SSH tunnel이 필요한 경우에만 사용한다. +- mac-mini/internal 후보는 dev-corp Edge 경로가 아니다. Node `edge_addr`는 `digitalplatform-iop.cloud:18087`이어야 한다. - model alias 후보: `gemma4:26b` -- host Pi dev-corp profile: `agent-test/dev-corp/inventory.yaml`의 `model.pi_agent_profile` 기준. 2026-07-09 현재 이 host의 Pi 기본 provider/model/thinking level은 `dev-corp` / `gemma4:26b` / `high`이며, base URL은 host-local node-internal Edge route `http://172.24.63.178:18086/v1`이다. 기본 public smoke/deploy route는 계속 `http://digitalplatform-iop.cloud:18086/v1`이고, dev `qwen3.6:35b` Pi profile은 `agent-test/dev/inventory.yaml`에서 별도로 관리한다. +- host Pi dev-corp profile: `agent-test/dev-corp/inventory.yaml`의 `model.pi_agent_profile` 기준. 2026-07-09 현재 Pi 기본 provider/model/thinking level은 `dev-corp` / `gemma4:26b` / `high`이며, base URL은 public Edge route `http://digitalplatform-iop.cloud:18086/v1`이다. dev `qwen3.6:35b` Pi profile은 `agent-test/dev/inventory.yaml`에서 별도로 관리한다. 노드 후보: @@ -64,7 +65,7 @@ dev-corp provider pool과 3-node 연결 상태를 점검할 때는 `agent-test/d - SSH/user: mac-mini에서 `ssh digitalcommerce_dgx_spark_01@192.168.2.2` - provider endpoint: `http://192.168.2.2:8002/v1` - Edge adapter endpoint: node-local `http://127.0.0.1:8002/v1` - - Edge connectivity: current native runtime uses mac-mini reverse SSH tunnel `127.0.0.1:28085/28087`; tunnel pid file is `build/dev-corp-runtime/node01-tunnel.pid`. + - Edge connectivity: direct public Edge `digitalplatform-iop.cloud:18087`. - served model: `gemma-4-26B-A4B-it-NVFP4` - capacity baseline 후보: `4` - runtime: tmux `vllm_server_8002`, start script `/home/digitalcommerce_dgx_spark_01/start_vllm_8002.sh`, `vllm=0.24.0`, `PATH=/home/digitalcommerce_dgx_spark_01/vllm_env_0_24_0/bin:$PATH`, `--max-num-seqs 4`, `--max-model-len 262144`, `--gpu-memory-utilization 0.40`, `--enforce-eager`, `--skip-mm-profiling`, `--limit-mm-per-prompt '{"image": 0, "video": 0}'`, `--mm-processor-cache-gb 0`, `--enable-auto-tool-choice`, `--tool-call-parser gemma4`, `--chat-template /home/digitalcommerce_dgx_spark_01/tool_chat_template_gemma4.jinja`, `--reasoning-parser gemma4`, `--default-chat-template-kwargs '{"enable_thinking":true}'`, 2026-07-08 startup log GPU KV cache `1,453,705` tokens / full-context concurrency `5.55x`, `VLLM_MAX_TOKENS_PER_EXPERT_FP4_MOE=4194304` @@ -72,7 +73,7 @@ dev-corp provider pool과 3-node 연결 상태를 점검할 때는 `agent-test/d - SSH/user: mac-mini에서 `ssh dplab@192.168.2.4` - provider endpoint: `http://192.168.2.4:8004/v1` - Edge adapter endpoint: node-local `http://127.0.0.1:8004/v1` - - Edge connectivity: node02는 mac-mini `172.24.63.178:18085/18086/18087` 직접 접근이 timeout이므로 mac-mini의 reverse SSH tunnel `127.0.0.1:28085/28087`을 사용한다. + - Edge connectivity: direct public Edge `digitalplatform-iop.cloud:18087`. - served model: `gemma-4-26B-A4B-it-NVFP4` - capacity baseline 후보: `4` - runtime: Docker container `vllm-gemma4`, start script `/home/dplab/start_vllm_gemma4_8004.sh`, host `8004` -> container `8004`, image `vllm/vllm-openai:v0.24.0`, `vllm=0.24.0`, `--max-num-seqs 4`, `--max-model-len 262144`, `--gpu-memory-utilization 0.40`, `--enforce-eager`, `--skip-mm-profiling`, `--limit-mm-per-prompt '{"image": 0, "video": 0}'`, `--mm-processor-cache-gb 0`, `--enable-auto-tool-choice`, `--tool-call-parser gemma4`, `--chat-template /vllm-workspace/examples/tool_chat_template_gemma4.jinja`, `--reasoning-parser gemma4`, `--default-chat-template-kwargs '{"enable_thinking":true}'`, 2026-07-08 startup log GPU KV cache `1,452,633` tokens / full-context concurrency `5.54x`, `VLLM_MAX_TOKENS_PER_EXPERT_FP4_MOE=4194304` @@ -96,19 +97,20 @@ Mac Studio의 `http://192.168.2.3:8005/v1` mlx-vlm DiffusionGemma endpoint는 - Gemma4 agent/tool-call compatibility profile은 DGX Spark 01/02 vLLM에서 `--enable-auto-tool-choice`, `--tool-call-parser gemma4`, Gemma4 tool chat template, `--reasoning-parser gemma4`, `--default-chat-template-kwargs '{"enable_thinking":true}'`, `--enforce-eager`, `--skip-mm-profiling`, `--limit-mm-per-prompt '{"image": 0, "video": 0}'`, `--mm-processor-cache-gb 0`을 함께 둔다. Mac Studio vLLM-MLX는 별도 chat template override 없이 `--continuous-batching`, `--disable-prefix-cache`, `--enable-auto-tool-choice`, `--tool-call-parser gemma4`, `--reasoning-parser gemma4`, `--default-chat-template-kwargs '{"enable_thinking":true}'`를 둔다. Qwen provider는 dev-runtime 문서의 Qwen 전용 parser/template 값을 따른다. - Mac Studio provider runtime은 `vllm-mlx=0.4.0`, provider catalog capacity `5`, context window `262144`, requested KV `262144x3` 기준으로 `--continuous-batching`, runtime headroom `--max-num-seqs 6`, `--prefill-batch-size 6`, `--completion-batch-size 6`, `--chunked-prefill-tokens 1024`, `--disable-prefix-cache`, `--max-request-tokens 262144`, `--max-kv-size 786432`, `--enable-auto-tool-choice`, `--tool-call-parser gemma4`, `--reasoning-parser gemma4`, `--default-chat-template-kwargs '{"enable_thinking":true}'`를 적용했고 `/health`, `/v1/models`, 직접 API non-stream/stream auto tool-call, streaming multi-turn tool-result final answer, Pi `-p` tool-call, Pi TUI 초기 프롬프트 tool-call 로그 종료를 확인했다. - Mac Studio vLLM-MLX의 위 값은 2026-07-08 기준 구동 가능한 최종 체크포인트다. 잔여 이슈로 Gemma4 thought channel delimiter가 최종 content에 누수될 수 있으며, 이 경우 runtime option 미세 조정보다 vLLM-MLX Gemma provider 전용 Pi extension/provider adapter sanitizer를 우선 검토한다. 추가 튜닝은 Spark vLLM 설정과 분리된 별도 실험으로만 수행한다. -- 2026-07-08 재확인 기준 DGX Spark 01은 mac-mini 내부 endpoint `http://192.168.2.2:8002`에서 `/health` 200과 `/v1/models`, 직접 API forced/auto/streaming tool-call smoke, 로컬 Pi TUI bash/git-push tool-call 흐름을 통과했다. DGX Spark 02는 mac-mini 내부 endpoint `http://192.168.2.4:8004`에서 `/health` 200과 `/v1/models`, 직접 API auto/streaming tool-call smoke를 통과했다. Edge OpenAI-compatible capacity smoke는 source ref `c2437aaedefbac4312d69dfd10aa017c2739e187` 재배포 후 `/v1/responses`, `/v1/chat/completions` 각각 15개 동시 요청으로 통과했다. +- 2026-07-08 재확인 기준 DGX Spark 01은 mac-mini 내부 endpoint `http://192.168.2.2:8002`에서 `/health` 200과 `/v1/models`, 직접 API forced/auto/streaming tool-call smoke, 로컬 Pi TUI bash/git-push tool-call 흐름을 통과했다. DGX Spark 02는 mac-mini 내부 endpoint `http://192.168.2.4:8004`에서 `/health` 200과 `/v1/models`, 직접 API auto/streaming tool-call smoke를 통과했다. 이때의 `/v1/responses` capacity 결과는 mac-mini provider-pool runtime 기준 legacy evidence이며, 2026-07-09 public Edge 표준 smoke는 `/v1/chat/completions` 15개 동시 요청이다. - Gemma provider-pool `gemma4:26b`는 `default_thinking_token_budget: 1024` 기준으로 thinking을 기본 활성화한다. Edge strict output이 켜져 있어도 provider-pool catalog의 thinking policy가 우선하며, vLLM/vLLM-MLX adapter에는 `chat_template_kwargs.enable_thinking=true`로 전달되는지 확인한다. - Gemma provider를 Pi/Cline형 agent/tool-call 용도로 검증할 때는 일반 chat smoke와 별도로 forced tool call, auto tool call, streaming `delta.tool_calls`, multi-turn tool result 후 최종 답변을 확인한다. raw `<|tool_call>`/`<|"|>` marker나 thought channel text가 assistant content로 새면 provider parser/template profile 또는 Edge relay 경계 문제로 판정한다. - Gemma provider-pool의 IOP queue timeout은 두지 않는다. config 값은 `queue_timeout_ms=0`이며, caller context cancellation 또는 연결 종료로만 queued request를 중단한다. OpenAI run timeout과 backend request timeout은 long reasoning/long-context 요청을 위해 각각 `openai.timeout_sec=1800`, `request_timeout_ms=1800000`으로 둔다. -## 2026-07-08 dev-corp native runtime 상태 +## 2026-07-09 dev-corp public Edge runtime 상태 -- mac-mini checkout은 `c2437aaedefbac4312d69dfd10aa017c2739e187` 기준으로 clean sync/rebuild/redeploy되었고, runtime 경로는 `/Users/fe/agent-work/iop-dev-corp/build/dev-corp-runtime`이다. -- Control Plane native runtime이 활성화되어 `18002` HTTP, `19004` Client WS, `19005` CP-Edge wire를 listen한다. Edge config의 `control_plane.enabled=true`, `wire_addr=127.0.0.1:19005`로 `dev-corp-edge`가 connected 상태다. -- Edge native runtime은 `18085` bootstrap, `18086` OpenAI-compatible, `18087` Edge-Node TCP, `19094` refresh admin을 listen한다. +- Active Edge runtime is `digitalplatform-iop.cloud` (`115.21.224.82`) with public `18085` bootstrap, `18086` OpenAI-compatible, and `18087` Edge-Node TCP. +- mac-mini checkout/runtime is a runner and must not be used as Edge source of truth unless explicitly doing a local-runner comparison. +- On 2026-07-09 the three provider nodes were moved from mac-mini/reverse-tunnel Edge addresses to `digitalplatform-iop.cloud:18087`, and public `/v1/chat/completions` 15-concurrency smoke passed 15/15. +- On 2026-07-09 after rebuilding the public Edge from the current passthrough source, default streaming `/v1/chat/completions` preserved provider reasoning deltas for 15/15 concurrent requests; transformed `chatcmpl-manual` IDs were 0/15. Evidence: `build/dev-corp-runtime/logs/public_passthrough_chat_15_20260709_180115.json`. - Mac Studio provider catalog `type`은 최신 config validator 기준으로 `openai_compat`를 사용한다. 실제 provider runtime은 vLLM-MLX이고 `runtime_type: vllm-mlx`로 추적한다. -- `/v1/responses` capacity smoke 표준: 15개 동시 요청, Control Plane `provider_snapshots` peak total `in_flight=13`, `queued>=2`, provider별 `in_flight`가 DGX01 `4`, DGX02 `4`, Mac Studio `5`를 넘지 않고 완료 후 모두 `in_flight=0`, `queued=0`으로 회복해야 한다. 2026-07-08 검증에서는 15/15 성공, peak total `in_flight=13`, `queued=6`, provider별 max queued `2`로 통과했다. -- `/v1/chat/completions` capacity smoke 표준: 15개 동시 요청, Control Plane `provider_snapshots` peak total `in_flight=13`, `queued>=2`, provider별 `in_flight`가 DGX01 `4`, DGX02 `4`, Mac Studio `5`를 넘지 않고 완료 후 모두 `in_flight=0`, `queued=0`으로 회복해야 한다. 2026-07-08 검증에서는 15/15 성공, peak total `in_flight=13`, `queued=6`, provider별 max queued `2`로 통과했다. +- `/v1/chat/completions` capacity smoke 표준: 15개 동시 요청을 public `http://digitalplatform-iop.cloud:18086/v1`로 보낸다. 2026-07-09 public Edge 재연결 검증에서는 15/15 성공했다. +- `/v1/responses`는 OpenAI-compatible provider model group raw passthrough parity 전까지 미지원이므로 provider-pool capacity 성공 기준에서 제외한다. ## 명령 @@ -117,7 +119,7 @@ Mac Studio의 `http://192.168.2.3:8005/v1` mlx-vlm DiffusionGemma endpoint는 - unit: `go test ./apps/edge/...` - smoke: `./scripts/e2e-smoke.sh`는 기본 포트 임시 설정을 쓰는 보조 smoke이므로 dev-corp 포트 override 필요 여부를 먼저 확인한다. - e2e: `make test-e2e`는 보조 smoke이며 full-cycle 실제 구동을 대체하지 않는다. -- model: dev-corp OpenAI-compatible profile을 띄운 경우 `OPENAI_API_KEY=$(cat build/dev-corp-runtime/.secrets/openai_api_key) iop-edge smoke openai --model gemma4:26b --base-url http://127.0.0.1:18086` +- model: dev-corp OpenAI-compatible profile을 띄운 경우 `OPENAI_API_KEY=$(cat build/dev-corp-runtime/.secrets/openai_api_key) iop-edge smoke openai --model gemma4:26b --base-url http://digitalplatform-iop.cloud:18086` - direct-provider: mac-mini에서 `curl -fsS http://192.168.2.2:8002/v1/models`, `curl -fsS http://192.168.2.4:8004/v1/models`, `curl -fsS http://192.168.2.3:8004/v1/models` - full-cycle: repo 내부 edge-node 진단, `iop-edge smoke openai`, OpenAI-compatible 입력 표면 수동 검증 @@ -125,7 +127,7 @@ Mac Studio의 `http://192.168.2.3:8005/v1` mlx-vlm DiffusionGemma endpoint는 - 변경한 edge 패키지 또는 `go test ./apps/edge/...`를 실행한다. - registry, service, transport, console, HTTP/A2A 입력 표면을 바꾼 경우 edge-node 메시지 2회 왕복과 command 응답을 확인한다. -- OpenAI-compatible 경계를 바꾼 경우 dev-corp `18086` 기준 `iop-edge smoke openai` 또는 동등한 `/healthz`, `/v1/models`, `/v1/responses` 확인으로 edge service와 node adapter 경로 수렴을 확인한다. +- OpenAI-compatible 경계를 바꾼 경우 dev-corp `18086` 기준 `iop-edge smoke openai` 또는 동등한 `/healthz`, `/v1/models`, `/v1/chat/completions` 확인으로 edge service와 node adapter 경로 수렴을 확인한다. provider-pool `/v1/responses` 미지원은 실패로 보지 않는다. - provider pool config 변경 전 mac-mini에서 세 기본 provider endpoint의 `/health`와 `/v1/models`가 성공하는지 확인한다. - DGX Spark 02가 provider port down과 SSH banner exchange timeout을 동시에 보이면 provider runtime 추가 조작을 보류하고, SSH 회복 후 process/log, `/health`, `/v1/models`, Edge OpenAI-compatible smoke를 순서대로 재검증한다. - bootstrap/artifact 경계를 바꾼 경우 dev-corp artifact/base URL 후보 `18085`가 local/test/dev field baseline을 덮어쓰지 않는지 확인한다. @@ -140,8 +142,8 @@ Mac Studio의 `http://192.168.2.3:8005/v1` mlx-vlm DiffusionGemma endpoint는 - node 등록, `/nodes`, console 메시지 전송, 기대 payload를 포함한 `[node-*-message]` 출력, 같은 run의 complete event가 확인된다. - node 로컬 `[node-message]` payload 라인 목록과 edge `[node-*-message]` payload 라인 목록이 run별로 내용/순서까지 동일해야 한다. - edge complete는 같은 run의 마지막 `[node-*-message]` 이후에만 정상이다. -- OpenAI-compatible smoke에서 `/healthz`, `/v1/models`, `/v1/responses`가 기대 상태로 응답한다. -- dev-corp capacity smoke는 `/v1/responses`와 `/v1/chat/completions` 각각에 15개 동시 요청을 보낸다. Edge config에서 기본 후보 capacity `4 + 4 + 5 = 13`을 확정한 경우 Control Plane status의 `provider_snapshots`에서 총 `in_flight=13`, `queued>=2` 관측을 기준으로 한다. +- OpenAI-compatible smoke에서 `/healthz`, `/v1/models`, `/v1/chat/completions`가 기대 상태로 응답한다. provider-pool `/v1/responses`는 현재 미지원이다. +- dev-corp provider-pool capacity smoke는 현재 `/v1/chat/completions`에 15개 동시 요청을 보낸다. `/v1/responses`는 OpenAI-compatible provider model group raw passthrough parity 전까지 미지원이므로 capacity 성공 기준에서 제외한다. - capacity smoke 완료 후 대상 provider의 `in_flight=0`, `queued=0` 회복을 확인한다. - Gemma 계열 provider-pool smoke는 thinking enabled 기준이며 reasoning/tool-parser 관련 텍스트가 포함될 수 있다. exact-output match를 기본 판정으로 쓰지 않는다. @@ -173,5 +175,5 @@ curl -fsS http://192.168.2.3:8004/v1/models - secret, token, API key 원문은 tracked 파일에 기록하지 않는다. - mac-mini에서 다시 도달 가능한 provider endpoint를 확인하지 않고 Edge provider config 성공을 선언하지 않는다. -- 사용자가 명시적으로 요청하지 않았는데 `172.24.63.178`로 Edge를 배포하거나 `172.24.63.178`을 Edge public runtime 기본 후보로 사용하지 않는다. +- 사용자가 명시적으로 요청하지 않았는데 mac-mini local endpoint를 Edge runtime, Node `edge_addr`, bootstrap 기본 URL, OpenAI-compatible base URL로 사용하지 않는다. - field baseline 포트(`18080`, `18081`, `19090`, `19092`)나 dev 포트(`18082`, `18083`, `19003`, `19101`)를 dev-corp 전용 포트로 재사용하지 않는다. diff --git a/agent-test/dev-corp/inventory.yaml b/agent-test/dev-corp/inventory.yaml index 1b75548..93394b2 100644 --- a/agent-test/dev-corp/inventory.yaml +++ b/agent-test/dev-corp/inventory.yaml @@ -8,7 +8,7 @@ source: repo_root: /Users/fe/agent-work/iop-dev-corp setup_required: true setup_status: deployed - current_observation: /Users/fe/agent-work/iop-dev-corp checkout and build/dev-corp-runtime runtime were created on 2026-06-25, clean-synced/rebuilt at source ref 2d08d24 on 2026-07-06, then clean-synced/rebuilt/redeployed at source ref c2437aa on 2026-07-08 with 15-concurrency capacity smoke passed for /v1/responses and /v1/chat/completions; /Users/fe/iop-field remains unrelated legacy field state + current_observation: /Users/fe/agent-work/iop-dev-corp checkout is the mac-mini source/build/provider SSH runner only. As of 2026-07-09 the active dev-corp Edge is the public host digitalplatform-iop.cloud (115.21.224.82), and provider nodes must use digitalplatform-iop.cloud:18087 directly. clean_sync: - git fetch origin main - git reset --hard origin/main @@ -17,32 +17,65 @@ source: edge: id: dev-corp-edge - host: mac-mini - ssh: fe@172.24.63.178 - os: macOS 26.2 - hardware: Apple M2 Pro / 16GB - config_path: build/dev-corp-runtime/edge.yaml - control_plane_enabled_current_runtime: true - control_plane_http: http://127.0.0.1:18002 - control_plane_status_url: http://127.0.0.1:18002/edges/dev-corp-edge/status - control_plane_client_ws_runner: ws://127.0.0.1:19004/client - control_plane_edge_wire_addr_runner: 127.0.0.1:19005 - public_route_policy: default_dev_corp_external_route_uses_digitalplatform_iop_cloud - edge_deploy_172_policy: explicit_user_request_only - public_route_note: digitalplatform-iop.cloud is the default dev-corp Edge deployment and smoke route; Edge deployment to 172.24.63.178 is prohibited by default and allowed only when the user explicitly requests the 172 route. 172.24.63.178 otherwise remains the mac-mini runner and node-only/internal route. + host: digitalplatform-iop.cloud + public_ip: 115.21.224.82 + ssh: toki@digitalplatform-iop.cloud + runtime_root: /Users/toki/agent-work/iop-dev-corp + config_path: /Users/toki/agent-work/iop-dev-corp/build/dev-corp-runtime/edge.yaml + config_note: public Edge config and bootstrap artifacts were normalized to digitalplatform-iop.cloud on 2026-07-09. + control_plane_enabled_current_runtime: unknown + control_plane_http: http://digitalplatform-iop.cloud:18002 + control_plane_status_url: http://digitalplatform-iop.cloud:18002/edges/dev-corp-edge/status + control_plane_client_ws_runner: ws://digitalplatform-iop.cloud:19004/client + control_plane_edge_wire_addr_runner: digitalplatform-iop.cloud:19005 + public_route_policy: active_dev_corp_edge_uses_digitalplatform_iop_cloud + runner_route_policy: mac-mini is source/build/provider management only, not an Edge route. + public_route_note: digitalplatform-iop.cloud is the dev-corp Edge runtime and the only default route for bootstrap, OpenAI-compatible base URL, and Node edge_addr. control_plane_http_public: http://digitalplatform-iop.cloud:18002 control_plane_client_ws_public: ws://digitalplatform-iop.cloud:19004/client bootstrap_http_public: http://digitalplatform-iop.cloud:18085 - bootstrap_http_node_internal: http://172.24.63.178:18085 + bootstrap_http_node_internal: http://digitalplatform-iop.cloud:18085 openai_base_url_public: http://digitalplatform-iop.cloud:18086/v1 - openai_base_url_node_internal: http://172.24.63.178:18086/v1 - openai_base_url_runner: http://127.0.0.1:18086/v1 + openai_base_url_node_internal: http://digitalplatform-iop.cloud:18086/v1 + openai_base_url_runner: http://digitalplatform-iop.cloud:18086/v1 openai_api_key_required_current_runtime: true openai_api_key_secret_path_remote: build/dev-corp-runtime/.secrets/openai_api_key openai_api_key_value_tracked: false edge_node_tcp_public: digitalplatform-iop.cloud:18087 - edge_node_tcp_node_internal: 172.24.63.178:18087 + edge_node_tcp_node_internal: digitalplatform-iop.cloud:18087 admin_addr_runner: 127.0.0.1:19094 + latest_public_edge_reconnect: + observed_at: "2026-07-09" + node_edge_addr: digitalplatform-iop.cloud:18087 + moved_from: + - retired reverse tunnel route + - retired mac-mini local route + nodes_registered: + - corp-dgx-spark-01-vllm-node + - corp-dgx-spark-02-vllm-node + - corp-mac-studio-mlx-vllm-node + public_chat_completions_15: + ok: 15 + concurrent_requests: 15 + elapsed_sec: 5.721 + passthrough_reasoning_stream_seen: 15 + transformed_manual_id_count: 0 + remote_log: build/dev-corp-runtime/logs/public_passthrough_chat_15_20260709_180115.json + note: public /v1/responses remains unsupported for OpenAI-compatible provider model groups until raw passthrough parity is implemented; use /v1/chat/completions for provider-pool capacity smoke. + latest_bootstrap_domain_fix: + observed_at: "2026-07-09" + public_host: digitalplatform-iop.cloud + runtime_pid_after_restart: 86504 + config: + advertise_host: digitalplatform-iop.cloud + artifact_base_url: http://digitalplatform-iop.cloud:18085 + bootstrap_defaults: + artifact_base_url: http://digitalplatform-iop.cloud:18085 + edge_addr: digitalplatform-iop.cloud:18087 + verification: + public_bootstrap_defaults: passed + public_chat_completions_single: passed + public_chat_completions_default_passthrough_15: passed build: binaries: @@ -80,7 +113,7 @@ model: current_default_provider: dev-corp current_default_model: gemma4:26b current_default_runtime: edge_openai_compatible_provider_pool - current_default_base_url: http://172.24.63.178:18086/v1 + current_default_base_url: http://digitalplatform-iop.cloud:18086/v1 current_default_api: openai-completions current_default_auth_header: true current_default_thinking_level: high @@ -94,7 +127,7 @@ model: - dev-corp-spark01/** - dev-corp/* api_key_value_tracked: false - route_policy: current host-local Pi default uses the 172.24.63.178 node-internal Edge route because this host can reach the mac-mini directly; this does not replace the default dev-corp public smoke/deploy route digitalplatform-iop.cloud + route_policy: current dev-corp Pi default must use the public Edge route digitalplatform-iop.cloud. pi_model_parameters: provider: dev-corp model_id: gemma4:26b @@ -198,11 +231,12 @@ model: kv_size_basis: requested 262144x3 mapped to vLLM-MLX max_kv_size capacity_smoke: endpoints: - - /v1/responses - /v1/chat/completions + unsupported_endpoints: + /v1/responses: OpenAI-compatible provider model group raw passthrough parity 전까지 미지원 concurrent_requests: 15 expected_total_in_flight: 13 - expected_total_in_flight_status: verified_15_concurrency_2026_07_08 + expected_total_in_flight_status: public_control_plane_status_required_for_current_snapshot; legacy_verified_15_concurrency_2026_07_08 expected_min_queued: 2 previous_capacity_plus_one_concurrent_requests: 14 previous_capacity_plus_one_expected_min_queued: 1 @@ -210,20 +244,47 @@ model: think_policy: enabled_for_provider_pool exact_output_match: false latest_capacity_verification: - date: "2026-07-08" - source_ref: c2437aaedefbac4312d69dfd10aa017c2739e187 - edge_runtime_patch: docs_15_concurrency_standard_redeploy + date: "2026-07-09" + route: public_digitalplatform_edge + host: digitalplatform-iop.cloud + edge_addr: digitalplatform-iop.cloud:18087 + source_ref: public_edge_source_ref_not_confirmed_by_current_runner default_thinking_token_budget: 1024 - control_plane_enabled: true - control_plane_status_url: http://127.0.0.1:18002/edges/dev-corp-edge/status + control_plane_enabled: unknown + control_plane_status_url: http://digitalplatform-iop.cloud:18002/edges/dev-corp-edge/status + capacity_snapshot_observed: false + capacity_snapshot_note: public Control Plane status was not accessible from the current runner; HTTP 15/15 smoke and node connection logs are current evidence, while in_flight/queued snapshot evidence remains legacy 2026-07-08 mac-mini runtime data. runtime: runner_checkout: /Users/fe/agent-work/iop-dev-corp - remote_log: build/dev-corp-runtime/logs/capacity_15_20260708_155027.json - control_plane_pid: 1446 - edge_pid: 1481 - rebuild_time: "2026-07-08 15:48" - post_build_config_check: passed - post_build_refresh_dry_run: no_changes_detected + remote_log: build/dev-corp-runtime/logs/public_domain_chat_15_20260709_172253.json + node_connection: + node_edge_addr: digitalplatform-iop.cloud:18087 + moved_from: + - retired reverse tunnel route + - retired mac-mini local route + nodes_registered: + - corp-dgx-spark-01-vllm-node + - corp-dgx-spark-02-vllm-node + - corp-mac-studio-mlx-vllm-node + chat_completions: + concurrent_requests: 15 + ok: 15 + timeout_errors: 0 + http_errors: 0 + elapsed_sec: 25.516 + request_median_sec: 22.933 + text_length_median: 2338 + responses: + supported: false + observed_http_status: 400 + reason: /v1/responses is not supported for OpenAI-compatible provider model groups until raw passthrough parity is implemented + legacy_capacity_verification_2026_07_08: + date: "2026-07-08" + source_ref: c2437aaedefbac4312d69dfd10aa017c2739e187 + route: mac_mini_provider_pool_runtime + edge_runtime_patch: docs_15_concurrency_standard_redeploy + control_plane_status_url: http://127.0.0.1:18002/edges/dev-corp-edge/status + remote_log: build/dev-corp-runtime/logs/capacity_15_20260708_155027.json provider_snapshot_baseline: total_capacity: 13 providers: @@ -239,25 +300,6 @@ model: capacity: 5 health: healthy status: available - responses: - concurrent_requests: 15 - ok: 15 - timeout_errors: 0 - http_errors: 0 - max_total_in_flight: 13 - max_total_queued: 6 - elapsed_sec: 22.563 - provider_max: - corp-dgx-spark-01-vllm: - max_in_flight: 4 - max_queued: 2 - corp-dgx-spark-02-vllm: - max_in_flight: 4 - max_queued: 2 - corp-mac-studio-mlx-vllm: - max_in_flight: 5 - max_queued: 2 - final_recovery: in_flight_0_queued_0 chat_completions: concurrent_requests: 15 ok: 15 @@ -277,6 +319,13 @@ model: max_in_flight: 5 max_queued: 2 final_recovery: in_flight_0_queued_0 + responses: + legacy_supported_in_mac_mini_runtime: true + current_public_provider_pool_supported: false + concurrent_requests: 15 + ok: 15 + max_total_in_flight: 13 + max_total_queued: 6 latest_runtime_update: date: "2026-06-25" reason: user requested dev-corp node capacity/context/KV alignment @@ -330,12 +379,12 @@ nodes: queue_timeout_ms: 0 request_timeout_ms: 1800000 edge_connectivity: - mode: reverse_ssh_tunnel - reason: current node.yaml uses tunnel-local Edge addr in the native provider-pool runtime + mode: direct_public_edge + edge_addr: digitalplatform-iop.cloud:18087 + reason: active dev-corp Edge is the public digitalplatform-iop.cloud host tunnel_pid_file: /Users/fe/agent-work/iop-dev-corp/build/dev-corp-runtime/node01-tunnel.pid - remote_forwards: - artifact: 127.0.0.1:28085 -> mac-mini 127.0.0.1:18085 - edge_node_tcp: 127.0.0.1:28087 -> mac-mini 127.0.0.1:18087 + tunnel_status: stopped_obsolete_2026_07_09 + retired_reverse_tunnels: true runtime: host: spark-0b30 os: Ubuntu 24.04.3 LTS / aarch64 @@ -402,12 +451,12 @@ nodes: queue_timeout_ms: 0 request_timeout_ms: 1800000 edge_connectivity: - mode: reverse_ssh_tunnel - reason: node02 cannot reach mac-mini 172.24.63.178:18085/18086 directly from 192.168.2.4 + mode: direct_public_edge + edge_addr: digitalplatform-iop.cloud:18087 + reason: active dev-corp Edge is the public digitalplatform-iop.cloud host tunnel_pid_file: /Users/fe/agent-work/iop-dev-corp/build/dev-corp-runtime/node02-tunnel.pid - remote_forwards: - artifact: 127.0.0.1:28085 -> mac-mini 127.0.0.1:18085 - edge_node_tcp: 127.0.0.1:28087 -> mac-mini 127.0.0.1:18087 + tunnel_status: stopped_obsolete_2026_07_09 + retired_reverse_tunnels: true runtime: host: spark-fb94 os: Ubuntu 24.04.3 LTS / aarch64 @@ -464,6 +513,10 @@ nodes: runtime_type: vllm-mlx endpoint: http://192.168.2.3:8004/v1 edge_adapter_endpoint: http://127.0.0.1:8004/v1 + edge_connectivity: + mode: direct_public_edge + edge_addr: digitalplatform-iop.cloud:18087 + reason: active dev-corp Edge is the public digitalplatform-iop.cloud host health: http://192.168.2.3:8004/health served_model: mlx-community/gemma-4-26b-a4b-it-nvfp4 capacity: 5 diff --git a/agent-test/dev-corp/node-smoke.md b/agent-test/dev-corp/node-smoke.md index faf246f..0edf0e7 100644 --- a/agent-test/dev-corp/node-smoke.md +++ b/agent-test/dev-corp/node-smoke.md @@ -3,7 +3,7 @@ test_env: dev-corp test_profile: node-smoke domain: node verification_type: smoke -last_rule_updated_at: 2026-07-08 +last_rule_updated_at: 2026-07-09 --- # node-smoke dev-corp 테스트 @@ -32,25 +32,29 @@ last_rule_updated_at: 2026-07-08 ## 환경 -- host: local checkout. dev-corp host, provider, shared Edge runtime evidence가 필요하면 mac-mini `ssh fe@172.24.63.178`을 사용한다. +- host: local checkout. provider evidence가 필요하면 mac-mini `ssh fe@172.24.63.178`을 사용한다. +- Edge runtime evidence: public `digitalplatform-iop.cloud`를 기준으로 한다. - port: compose Edge-Node TCP transport `19006`, native provider-pool Edge-Node TCP 후보 `18087` - runtime: Go `1.24` - package manager: Go modules / Makefile - docker: unit/smoke quick check는 Docker를 요구하지 않는다. compose dev-corp 검증은 mac-mini에서 수행한다. -- external service: dev-corp node-only/internal Edge runtime 후보 `172.24.63.178:18087`; 기본 외부 dev-corp 배포/검증 경로는 `digitalplatform-iop.cloud`이다. `172.24.63.178`로 Edge 배포는 사용자 명시 요청 전까지 금지한다. +- external service: dev-corp Edge runtime 후보는 `digitalplatform-iop.cloud:18087`이다. mac-mini local endpoint와 reverse tunnel은 dev-corp Edge 경로로 사용하지 않는다. - model endpoint: dev-corp OpenAI-compatible base URL 기본 후보 `http://digitalplatform-iop.cloud:18086/v1` - credential: token/secret/API key 원문은 문서에 기록하지 않는다. ## dev-corp Node 접속 기준 -dev-corp의 실제 3-node 연결을 점검할 때는 mac-mini `ssh fe@172.24.63.178`의 `/Users/fe/agent-work/iop-dev-corp` checkout과 `build/dev-corp-runtime/edge.yaml`을 기준으로 한다. Node는 provider pool 기준에서 node-only/internal Edge-Node TCP `172.24.63.178:18087` 또는 host별 reverse SSH tunnel로 붙을 수 있다. 이 172 경로는 기본 외부 dev-corp serving/smoke 경로가 아니며, Edge 배포 대상도 아니다. 사용자가 172 Edge 경로를 명시 요청한 경우에만 172 Edge 배포/검증으로 취급한다. -2026-07-02 현재 DGX Spark 01/02는 `127.0.0.1:28087 -> mac-mini 127.0.0.1:18087` reverse SSH tunnel로 붙고, Mac Studio는 직접 Edge TCP 후보를 사용한다. tunnel pid file은 mac-mini runtime의 `build/dev-corp-runtime/node01-tunnel.pid`, `build/dev-corp-runtime/node02-tunnel.pid`다. +dev-corp의 실제 3-node 연결을 점검할 때는 각 provider host의 `~/iop-dev-corp-field/node.yaml`을 확인하고, `transport.edge_addr`가 `digitalplatform-iop.cloud:18087`인지 검증한다. + +mac-mini `ssh fe@172.24.63.178`의 `/Users/fe/agent-work/iop-dev-corp` checkout은 provider SSH runner로만 사용한다. + +retired mac-mini local route와 reverse tunnel route는 Edge 연결로 사용하지 않는다. - DGX Spark 01 vLLM node: `corp-dgx-spark-01-vllm-node` / `corp-dgx-spark-01-vllm` - SSH/user: mac-mini에서 `ssh digitalcommerce_dgx_spark_01@192.168.2.2` - provider endpoint: `http://192.168.2.2:8002/v1` - Edge adapter endpoint: node-local `http://127.0.0.1:8002/v1` - - Edge addr: `127.0.0.1:28087` via mac-mini reverse SSH tunnel in the current native runtime + - Edge addr: `digitalplatform-iop.cloud:18087` - served model: `gemma-4-26B-A4B-it-NVFP4` - capacity baseline 후보: `4` - runtime capacity/context/KV: `vllm=0.24.0`, `--max-num-seqs 4`, `--max-model-len 262144`, `--gpu-memory-utilization 0.40`; agent/tool-call profile `--enforce-eager`, `--skip-mm-profiling`, `--limit-mm-per-prompt '{"image": 0, "video": 0}'`, `--mm-processor-cache-gb 0`, `--enable-auto-tool-choice`, `--tool-call-parser gemma4`, `--chat-template /home/digitalcommerce_dgx_spark_01/tool_chat_template_gemma4.jinja`, `--reasoning-parser gemma4`, `--default-chat-template-kwargs '{"enable_thinking":true}'`; 2026-07-08 startup log 기준 GPU KV cache `1,453,705` tokens, `262144` full-context concurrency `5.55x`; FP4 MoE env `VLLM_MAX_TOKENS_PER_EXPERT_FP4_MOE=4194304` @@ -61,7 +65,7 @@ dev-corp의 실제 3-node 연결을 점검할 때는 mac-mini `ssh fe@172.24.63. - SSH/user: mac-mini에서 `ssh dplab@192.168.2.4` - provider endpoint: `http://192.168.2.4:8004/v1` - Edge adapter endpoint: node-local `http://127.0.0.1:8004/v1` - - Edge addr: `127.0.0.1:28087` via mac-mini reverse SSH tunnel + - Edge addr: `digitalplatform-iop.cloud:18087` - served model: `gemma-4-26B-A4B-it-NVFP4` - capacity baseline 후보: `4` - runtime capacity/context/KV: image `vllm/vllm-openai:v0.24.0`, `vllm=0.24.0`, `--max-num-seqs 4`, `--max-model-len 262144`, `--gpu-memory-utilization 0.40`; agent/tool-call profile `--enforce-eager`, `--skip-mm-profiling`, `--limit-mm-per-prompt '{"image": 0, "video": 0}'`, `--mm-processor-cache-gb 0`, `--enable-auto-tool-choice`, `--tool-call-parser gemma4`, `--chat-template /vllm-workspace/examples/tool_chat_template_gemma4.jinja`, `--reasoning-parser gemma4`, `--default-chat-template-kwargs '{"enable_thinking":true}'`; 2026-07-08 startup log 기준 GPU KV cache `1,452,633` tokens, `262144` full-context concurrency `5.54x`; FP4 MoE env `VLLM_MAX_TOKENS_PER_EXPERT_FP4_MOE=4194304` @@ -72,6 +76,7 @@ dev-corp의 실제 3-node 연결을 점검할 때는 mac-mini `ssh fe@172.24.63. - SSH/user: mac-mini에서 `ssh dc_dev@192.168.2.3` - provider endpoint: `http://192.168.2.3:8004/v1` - Edge adapter endpoint: node-local `http://127.0.0.1:8004/v1` + - Edge addr: `digitalplatform-iop.cloud:18087` - Edge provider catalog type: `openai_compat`; provider runtime type remains `vllm-mlx`. - served model: `mlx-community/gemma-4-26b-a4b-it-nvfp4` - capacity baseline 후보: `5` (provider catalog capacity; current runtime headroom `--max-num-seqs 6`) @@ -97,14 +102,13 @@ Mac Studio의 secondary `http://192.168.2.3:8005/v1` endpoint는 기본 Node/pro - Mac Studio vLLM-MLX의 위 값은 2026-07-08 기준 구동 가능한 최종 체크포인트다. 잔여 이슈로 Gemma4 thought channel delimiter가 최종 content에 누수될 수 있으며, 이 경우 runtime option 미세 조정보다 vLLM-MLX Gemma provider 전용 Pi extension/provider adapter sanitizer를 우선 검토한다. 추가 튜닝은 Spark vLLM 설정과 분리된 별도 실험으로만 수행한다. - Gemma provider를 Pi/Cline형 agent/tool-call 용도로 검증할 때는 일반 chat smoke와 별도로 forced tool call, auto tool call, streaming `delta.tool_calls`, multi-turn tool result 후 최종 답변을 확인한다. raw `<|tool_call>`/`<|"|>` marker나 thought channel text가 assistant content로 새면 provider parser/template profile 또는 Edge relay 경계 문제로 판정한다. - Gemma provider-pool의 provider queue timeout은 두지 않는다. config 값은 `queue_timeout_ms=0`이며, backend request timeout은 30분 기준인 `request_timeout_ms=1800000`으로 맞춘다. -- 2026-07-08 재확인 기준 DGX Spark 02는 mac-mini에서 SSH, provider `/health`, `/v1/models`가 회복됐고 직접 API auto/streaming tool-call smoke를 통과했다. Edge OpenAI-compatible capacity smoke는 source ref `c2437aaedefbac4312d69dfd10aa017c2739e187` 재배포 후 `/v1/responses`, `/v1/chat/completions` 각각 15개 동시 요청으로 통과했다. +- 2026-07-08 재확인 기준 DGX Spark 02는 mac-mini에서 SSH, provider `/health`, `/v1/models`가 회복됐고 직접 API auto/streaming tool-call smoke를 통과했다. 이때의 `/v1/responses` capacity 결과는 mac-mini provider-pool runtime 기준 legacy evidence이며, 2026-07-09 public Edge 표준 smoke는 `/v1/chat/completions` 15개 동시 요청이다. -## 2026-07-08 연결/용량 검증 상태 +## 2026-07-09 연결/용량 검증 상태 -- dev-corp Control Plane native runtime이 활성화되어 `http://127.0.0.1:18002/edges/dev-corp-edge/status`에서 3개 provider node가 connected로 관측된다. -- DGX Spark 01, DGX Spark 02, Mac Studio Node binary는 source ref `c2437aaedefbac4312d69dfd10aa017c2739e187` 기준으로 재배포되었고 각 host의 `iop-dev-corp-field/iop-node`로 실행된다. -- Control Plane `provider_snapshots` 기준 provider 상태는 DGX01 capacity `4`, DGX02 capacity `4`, Mac Studio capacity `5`, 모두 `health=healthy`, `status=available`이다. -- dev-corp capacity smoke 표준은 `/v1/responses`와 `/v1/chat/completions` 각각 15개 동시 요청이다. provider capacity 합 `13` 기준 peak total `in_flight=13`, `queued>=2`를 관측하고, 완료 후 모든 provider가 `in_flight=0`, `queued=0`으로 회복해야 한다. 2026-07-08 검증에서는 두 endpoint 모두 15/15 성공, peak total `in_flight=13`, `queued=6`, provider별 max queued `2`, 최종 회복 `in_flight=0`, `queued=0`으로 통과했다. +- DGX Spark 01, DGX Spark 02, Mac Studio Node는 각 host의 `~/iop-dev-corp-field/node.yaml`에서 `edge_addr: "digitalplatform-iop.cloud:18087"`로 실행된다. +- 2026-07-09 재연결 후 세 Node 모두 `registered with edge`와 `connected to edge` 로그를 남겼고 public `http://digitalplatform-iop.cloud:18086/v1/chat/completions` 15개 동시 요청이 15/15 성공했다. +- `/v1/responses`는 OpenAI-compatible provider model group raw passthrough parity 전까지 미지원이므로 provider-pool capacity 성공 기준에서 제외한다. ## 명령 @@ -121,7 +125,7 @@ Mac Studio의 secondary `http://192.168.2.3:8005/v1` endpoint는 기본 Node/pro - 변경한 node 패키지 또는 `go test ./apps/node/...`를 실행한다. - 실행 요청, stream, cancel, status, session, adapter registry 경로를 바꾼 경우 repo 내부 edge-node 진단과 full-cycle 실제 구동 기준을 함께 적용한다. - vLLM/OpenAI-compatible adapter 설정을 바꾼 경우 mac-mini에서 provider `/health`와 `/v1/models`를 먼저 확인하고, 이후 Edge OpenAI-compatible 경로에서 model alias 후보 `gemma4:26b` 또는 작업에서 확정한 alias가 노출되는지 확인한다. -- dev-corp Edge runtime으로 연결하는 경우 Node가 `18087` native provider-pool TCP를 사용하고 local/test/dev baseline으로 붙지 않는지 확인한다. +- dev-corp Edge runtime으로 연결하는 경우 Node가 `digitalplatform-iop.cloud:18087` native provider-pool TCP를 사용하고 mac-mini local route, reverse tunnel route, local/test/dev baseline으로 붙지 않는지 확인한다. - Node bootstrap UX는 Edge가 출력한 완성 명령을 사용하고, 사용자에게 수동 `node.yaml` 편집이나 named env parameter를 기본 경로로 요구하지 않는다. ## 보조 검증 @@ -167,5 +171,5 @@ curl -fsS http://192.168.2.3:8004/health - 사용자 실행 파이프라인 변경을 unit test만으로 완료 처리하지 않는다. - `proto/gen/iop/*.pb.go` 생성 파일을 직접 수정하지 않는다. -- 사용자가 명시적으로 요청하지 않았는데 `172.24.63.178`로 Edge를 배포하거나 Node smoke의 172 내부 경로를 Edge public runtime 기본값으로 승격하지 않는다. +- 사용자가 명시적으로 요청하지 않았는데 mac-mini 내부 경로를 Edge runtime 또는 Node `edge_addr` 기본값으로 승격하지 않는다. - secret, token, API key 원문은 tracked 파일에 기록하지 않는다. diff --git a/agent-test/dev-corp/platform-common-smoke.md b/agent-test/dev-corp/platform-common-smoke.md index f757ceb..ad99404 100644 --- a/agent-test/dev-corp/platform-common-smoke.md +++ b/agent-test/dev-corp/platform-common-smoke.md @@ -34,7 +34,7 @@ last_rule_updated_at: 2026-07-08 - runtime: Go `1.24` - package manager: Go modules / Makefile - docker: unit/codegen quick check는 Docker를 요구하지 않는다. compose dev-corp 검증은 mac-mini에서 수행한다. -- external service: dev-corp artifact/base URL 기본 후보 `http://digitalplatform-iop.cloud:18085`; `172.24.63.178:18085`는 node-only/internal 경로다. 172 Edge 배포/검증은 사용자 명시 요청 전까지 금지한다. +- external service: dev-corp artifact/base URL 기본 후보 `http://digitalplatform-iop.cloud:18085`; mac-mini runner/local legacy 경로는 bootstrap 기본 URL로 쓰지 않는다. - model endpoint: dev-corp OpenAI-compatible base URL 기본 후보 `http://digitalplatform-iop.cloud:18086/v1` - credential: token/secret/API key 원문은 문서에 기록하지 않는다. @@ -95,5 +95,5 @@ go test ./packages/go/... ./proto/gen/... - `proto/gen/iop/*.pb.go` 생성 파일을 직접 수정하지 않는다. - 앱 하나만을 위한 임시 타입을 충분한 근거 없이 공통 패키지로 승격하지 않는다. -- 사용자가 명시적으로 요청하지 않았는데 `172.24.63.178`을 Edge public runtime/config 기본값으로 사용하지 않는다. +- 사용자가 명시적으로 요청하지 않았는데 mac-mini runner/local legacy 경로를 Edge public runtime/config 기본값으로 사용하지 않는다. - secret, token, API key 원문은 tracked 파일에 기록하지 않는다. diff --git a/agent-test/dev-corp/rules.md b/agent-test/dev-corp/rules.md index 24f6525..2dc5c3f 100644 --- a/agent-test/dev-corp/rules.md +++ b/agent-test/dev-corp/rules.md @@ -1,12 +1,12 @@ --- test_env: dev-corp -last_rule_updated_at: 2026-07-08 +last_rule_updated_at: 2026-07-09 --- # dev-corp 테스트 규칙 **현재 문서를 반드시 끝까지 정독하고 작업한다. 다 읽지 않고 즉각 작업은 금지한다.** -**dev-corp 테스트 환경은 회사망 내부 mac-mini Edge host와 내부 provider nodes를 기준으로 하며, local/dev stack과 공존하도록 host publish 포트와 runtime profile을 분리한다.** +**dev-corp 테스트 환경은 public `digitalplatform-iop.cloud` Edge와 내부 provider nodes를 기준으로 하며, mac-mini는 source/build/provider SSH runner로만 사용한다. local/dev stack과 공존하도록 host publish 포트와 runtime profile을 분리한다.** ## 공통 규칙 @@ -21,14 +21,15 @@ last_rule_updated_at: 2026-07-08 ## 기본 배포 통로 -- dev-corp 기본 외부 배포/검증 통로는 `digitalplatform-iop.cloud`이다. Control Plane public 후보, Client WS public 후보, artifact/bootstrap public 후보, Edge OpenAI-compatible public 후보는 이 경로를 우선한다. -- `172.24.63.178`은 mac-mini SSH runner와 node-only/internal Edge-Node 경로로만 본다. 사용자가 172 경로를 명시적으로 요청하지 않으면 기본 dev-corp 배포 방향이나 OpenAI-compatible smoke 대상에 사용하지 않는다. -- `172.24.63.178`로 Edge를 배포하는 것은 기본 금지다. 사용자가 “172로 Edge 배포” 또는 같은 의미의 명시 요청을 한 경우에만 172 Edge 배포/검증을 진행한다. +- dev-corp Edge의 기본 배포/검증 통로는 `digitalplatform-iop.cloud`이다. artifact/bootstrap, Edge OpenAI-compatible, Edge-Node TCP는 같은 host의 dev-corp 포트 `18085/18086/18087`을 사용한다. +- mac-mini는 source sync/build/provider 점검 경유지로만 사용한다. dev-corp Edge 주소, Node `edge_addr`, OpenAI-compatible smoke 대상, bootstrap 기본 URL은 public domain 값으로만 둔다. +- mac-mini local endpoint로 Edge를 배포/검증하지 않는다. 사용자가 “mac-mini local Edge로 검증” 또는 같은 의미의 명시 요청을 한 경우에만 별도 local-runner 비교로 진행한다. - provider direct 확인은 기존처럼 mac-mini에서 내부 provider endpoint `192.168.2.2:8002`, `192.168.2.4:8004`, `192.168.2.3:8004`를 확인한다. ## 기본 환경 -- host: Edge runner 후보는 `ssh fe@172.24.63.178` mac-mini이다. +- host: Edge public runtime은 `digitalplatform-iop.cloud`(`115.21.224.82`)이다. +- remote runner: `ssh fe@172.24.63.178` mac-mini는 source sync/build/provider SSH runner다. - repo root: 목표 checkout은 `/Users/fe/agent-work/iop-dev-corp`이다. 2026-07-02 기준 해당 checkout과 `build/dev-corp-runtime` runtime이 배포되어 있으며, `/Users/fe/iop-field`는 unrelated legacy field state로 본다. - sync 기준: dev-corp 배포 전 mac-mini checkout은 배포 기준 ref로 clean sync하고 dirty 변경은 보존 대상으로 보지 않는다. - env file: compose stack을 만들면 `.env.dev-corp.example`로 분리한다. 파일 생성 전에는 native/provider-pool profile만 기준으로 삼는다. @@ -38,7 +39,7 @@ last_rule_updated_at: 2026-07-08 - runtime: Go quick check는 local toolchain을 우선한다. Docker/Flutter/client/field/bootstrap/provider-pool evidence는 mac-mini와 내부 provider nodes를 사용한다. - package manager: Go modules / Makefile / Flutter pub - docker: 현재 작업 컨테이너에서는 Docker-in-Docker를 사용하지 않는다. Docker compose 검증은 mac-mini checkout에서 수행한다. -- external service: dev-corp Control Plane 후보는 mac-mini local 기준 `http://127.0.0.1:18002`, 기본 외부 후보 `http://digitalplatform-iop.cloud:18002`이다. Client wire 후보는 mac-mini local 기준 `ws://127.0.0.1:19004/client`, 기본 외부 후보 `ws://digitalplatform-iop.cloud:19004/client`이다. +- external service: dev-corp Edge 후보는 `http://digitalplatform-iop.cloud:18085`, `http://digitalplatform-iop.cloud:18086/v1`, `digitalplatform-iop.cloud:18087`이다. Control Plane/Client public 후보는 해당 public host 포트가 실제로 열려 있을 때만 검증 대상으로 삼는다. - model endpoint: Edge 배포 후 기본 외부 후보 `http://digitalplatform-iop.cloud:18086/v1`; 직접 provider 확인은 `agent-test/dev-corp/inventory.yaml`의 provider endpoint를 따른다. - credential: secret/token/API key 원문은 문서에 기록하지 않는다. @@ -57,15 +58,16 @@ last_rule_updated_at: 2026-07-08 | PostgreSQL host publish | `15400` | `15401` | `15402` | | Redis host publish | `16300` | `16301` | `16302` | -dev-corp native/provider-pool profile은 compose Edge-Node TCP `19006`이 아니라 native Edge listen 후보 `18087`을 사용한다. DGX Spark 01/02처럼 직접 접근이 막힌 host는 mac-mini reverse SSH tunnel의 `127.0.0.1:28087`을 Node Edge addr로 사용할 수 있다. 세부 provider endpoint와 Node 접속 기준은 `agent-test/dev-corp/inventory.yaml`, `agent-test/dev-corp/edge-smoke.md`, `agent-test/dev-corp/node-smoke.md`를 따른다. +dev-corp native/provider-pool profile은 compose Edge-Node TCP `19006`이 아니라 public native Edge listen 후보 `digitalplatform-iop.cloud:18087`을 사용한다. DGX Spark 01/02와 Mac Studio Node도 기본적으로 이 public Edge addr에 직접 붙는다. mac-mini reverse SSH tunnel은 dev-corp Edge 기준으로 사용하지 않는다. 세부 provider endpoint와 Node 접속 기준은 `agent-test/dev-corp/inventory.yaml`, `agent-test/dev-corp/edge-smoke.md`, `agent-test/dev-corp/node-smoke.md`를 따른다. ## 런타임 프로필 - local quick check: 현재 checkout에서 Go quick check를 우선 실행한다. -- remote runner: dev-corp runtime evidence, Flutter client, Docker compose, field/bootstrap, provider-pool evidence는 `ssh fe@172.24.63.178`의 `/Users/fe/agent-work/iop-dev-corp` 기준으로 수행한다. +- remote runner: source sync/build/provider SSH 조작은 `ssh fe@172.24.63.178`의 `/Users/fe/agent-work/iop-dev-corp` 기준으로 수행할 수 있다. +- public Edge evidence: Edge runtime evidence와 OpenAI-compatible smoke는 public `digitalplatform-iop.cloud` 경로로 판정한다. - compose dev-corp stack: `.env.dev-corp.example`, `COMPOSE_PROJECT_NAME=iop-dev-corp-agent`, `IOP_COMPOSE_NETWORK=iop-dev-corp-agent-net`, Edge-Node TCP `19006`을 사용한다. - Edge direct dev-corp profile: artifact/bootstrap `18085`, OpenAI-compatible `18086`, metrics `19102`, admin `19094`를 사용한다. -- dev-corp provider pool: `/Users/fe/agent-work/iop-dev-corp/build/dev-corp-runtime/edge.yaml`과 기본 public Edge-Node TCP `digitalplatform-iop.cloud:18087`을 기준으로 한다. `172.24.63.178:18087`은 Edge 배포 대상이 아니라 node-only/internal 경로 또는 host별 reverse SSH tunnel이 필요한 경우에만 사용한다. 172 Edge 배포는 사용자 명시 요청 전까지 진행하지 않는다. 3-node/provider 세부는 `agent-test/dev-corp/edge-smoke.md`와 `agent-test/dev-corp/node-smoke.md`를 따른다. +- dev-corp provider pool: 기본 public Edge-Node TCP `digitalplatform-iop.cloud:18087`을 기준으로 한다. `/Users/fe/agent-work/iop-dev-corp/build/dev-corp-runtime/edge.yaml`은 mac-mini runner의 보조 산출물일 뿐 dev-corp Edge source of truth로 판정하지 않는다. retired reverse tunnel route는 Edge addr로 사용하지 않는다. 3-node/provider 세부는 `agent-test/dev-corp/edge-smoke.md`와 `agent-test/dev-corp/node-smoke.md`를 따른다. - current native Control Plane: 2026-07-02 기준 provider-pool runtime에서 `build/dev-corp-runtime/bin/control-plane`이 `18002/19004/19005`를 listen하고, Edge id `dev-corp-edge`가 `127.0.0.1:19005`로 연결된다. provider snapshot status 기준은 `http://127.0.0.1:18002/edges/dev-corp-edge/status`다. - external provider field: DGX Spark 01/02와 Mac Studio는 mac-mini에서 내부 SSH로 접속한다. 직접 접속 경로와 provider endpoint는 `agent-test/dev-corp/inventory.yaml`을 따른다. @@ -74,7 +76,7 @@ dev-corp native/provider-pool profile은 compose Edge-Node TCP `19006`이 아니 - plan 작성 시 필수 검증이 현재 checkout을 벗어나 mac-mini runner, field/bootstrap, 외부 provider, Docker/code-server, emulator/device, 공유 장기 runtime을 사용하면 먼저 테스트 환경 프리플라이트를 계획에 기록한다. - 테스트 환경 프리플라이트에는 runner, repo root/workdir, branch/HEAD/dirty 상태, local 변경과 원격 source 동기화 여부, binary/artifact 경로와 필요한 help/version 출력, config path, runtime identity, port/process 상태, 외부 host, OS/arch 가정을 포함한다. - mac-mini에 `/Users/fe/agent-work/iop-dev-corp` checkout이 없으면 배포/검증을 시작하지 말고 checkout 생성과 source sync를 setup blocker로 보고한다. -- provider pool 검증 전 mac-mini에서 `192.168.2.2:8002`, `192.168.2.4:8004`, `192.168.2.3:8004`의 `/health`와 `/v1/models`를 먼저 확인한다. +- provider pool 검증 전 mac-mini에서 내부 provider endpoint `192.168.2.2:8002`, `192.168.2.4:8004`, `192.168.2.3:8004`의 `/health`와 `/v1/models`를 먼저 확인하고, 각 Node의 `edge_addr`가 `digitalplatform-iop.cloud:18087`인지 확인한다. - `gemma4:26b` alias와 총 capacity `13`은 `agent-test/dev-corp/inventory.yaml`의 최신 검증 상태를 기준으로 판단한다. 새 배포에서 Edge config 반영과 capacity smoke가 통과하기 전에는 새 결과를 확정값으로 보고하지 않는다. - 프리플라이트에서 dirty/divergent checkout 또는 stale artifact가 확인되면 dev-corp 배포에서는 먼저 원격 checkout을 clean sync하고 dev-corp runtime 바이너리를 rebuild한다. 잘못된 identity, missing command, closed port, host OS 불일치, source 미동기화가 확인되면 plan은 setup/sync/rebuild 단계를 만들거나 blocker로 보고한다. diff --git a/agent-test/dev-corp/testing-smoke.md b/agent-test/dev-corp/testing-smoke.md index b97ef4e..828f0ba 100644 --- a/agent-test/dev-corp/testing-smoke.md +++ b/agent-test/dev-corp/testing-smoke.md @@ -37,7 +37,7 @@ last_rule_updated_at: 2026-07-08 - runtime: Go `1.24` - package manager: Go modules / Makefile - docker: quick check는 Docker를 요구하지 않는다. 현재 작업 컨테이너에서는 Docker-in-Docker를 사용하지 않으며, Docker compose 검증은 mac-mini 환경에서 수행한다. -- external service: dev-corp Control Plane 후보는 mac-mini local 기준 `http://127.0.0.1:18002`, 기본 외부 후보 `http://digitalplatform-iop.cloud:18002`이다. Client wire 후보는 mac-mini local 기준 `ws://127.0.0.1:19004/client`, 기본 외부 후보 `ws://digitalplatform-iop.cloud:19004/client`이다. dev-corp Edge runtime 기본 후보는 `digitalplatform-iop.cloud:18087`이며, `172.24.63.178:18087`은 node-only/internal 또는 host별 reverse SSH tunnel 경로다. 172 Edge 배포/검증은 사용자 명시 요청 전까지 금지한다. +- external service: dev-corp Control Plane 후보는 mac-mini local 기준 `http://127.0.0.1:18002`, 기본 외부 후보 `http://digitalplatform-iop.cloud:18002`이다. Client wire 후보는 mac-mini local 기준 `ws://127.0.0.1:19004/client`, 기본 외부 후보 `ws://digitalplatform-iop.cloud:19004/client`이다. dev-corp Edge runtime 기본 후보는 `digitalplatform-iop.cloud:18087`이며, mac-mini runner/local legacy 경로를 Edge runtime 또는 Node `edge_addr`로 쓰지 않는다. - model endpoint: dev-corp OpenAI-compatible base URL 기본 후보 `http://digitalplatform-iop.cloud:18086/v1` - credential: token/secret/API key 원문은 문서에 기록하지 않는다. @@ -108,7 +108,7 @@ curl -fsS http://192.168.2.2:8002/v1/models - 보조 E2E smoke 통과만으로 완료 처리하지 않는다. - 사용자 기본 경로에서 `IOP_ARTIFACT_BASE_URL=...`, `IOP_EDGE_ADDR=...`, `IOP_NODE_TOKEN=...` 같은 named environment parameter를 요구하지 않는다. -- 사용자가 명시적으로 요청하지 않았는데 `172.24.63.178`로 Edge를 배포하거나 `172.24.63.178`을 dev-corp Edge public runtime 기본 후보로 사용하지 않는다. +- 사용자가 명시적으로 요청하지 않았는데 mac-mini runner/local legacy 경로를 dev-corp Edge public runtime 기본 후보로 사용하지 않는다. - 사용자가 명시하지 않으면 code-server 컨테이너를 재시작하지 않는다. - 환경값을 사람용 docs나 roadmap에 복사하지 않는다. - secret, token, API key 원문은 tracked 파일에 기록하지 않는다. From 6d2de5bd1c27656254c91d890ab39c9d42b1f624 Mon Sep 17 00:00:00 2001 From: leedongmyun Date: Thu, 9 Jul 2026 18:18:29 +0900 Subject: [PATCH 2/4] docs: update dev-corp runtime deploy skill, edge smoke and inventory --- .../project/dev-corp-runtime-deploy/SKILL.md | 2 +- agent-test/dev-corp/edge-smoke.md | 1 + agent-test/dev-corp/inventory.yaml | 30 ++++++++++++++----- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/agent-ops/skills/project/dev-corp-runtime-deploy/SKILL.md b/agent-ops/skills/project/dev-corp-runtime-deploy/SKILL.md index 3896439..a74e443 100644 --- a/agent-ops/skills/project/dev-corp-runtime-deploy/SKILL.md +++ b/agent-ops/skills/project/dev-corp-runtime-deploy/SKILL.md @@ -60,7 +60,7 @@ dev-corp provider pool을 현재 dev-runtime과 같은 구조로 배포한다. - 2026-07-08 재확인 기준 DGX Spark 02는 Docker `vllm-gemma4` image `vllm/vllm-openai:v0.24.0`, host/container `8004`, text-only/eager profile과 `default_chat_template_kwargs.enable_thinking=true`로 동작하며 mac-mini와 node-local `/health`, `/v1/models`, 직접 API auto/streaming tool-call smoke를 통과했다. startup log에서 GPU KV cache `1,452,633` tokens, full-context concurrency `5.54x`를 확인했다. - 2026-07-02 mac-mini native Control Plane `18002/19004/19005` 관측값은 historical evidence다. 2026-07-09 현재 dev-corp Edge source of truth는 public `digitalplatform-iop.cloud`이고, current runner에서 public host SSH와 public Control Plane status 접근은 확인되지 않았다. - 2026-07-09 기준 dev-corp provider-pool Edge OpenAI-compatible capacity smoke 표준은 public `http://digitalplatform-iop.cloud:18086/v1/chat/completions` 15개 동시 요청이다. `/v1/responses`는 OpenAI-compatible provider model group raw passthrough parity 전까지 미지원이므로 성공 기준에서 제외한다. -- 2026-07-09 public Edge 재연결 검증에서 DGX Spark 01/02와 Mac Studio node를 `digitalplatform-iop.cloud:18087`로 변경한 뒤 `/v1/chat/completions` 15개 동시 요청이 15/15 성공했다. 같은 날 current passthrough source로 public Edge를 재빌드/재시작한 뒤 기본 streaming `/v1/chat/completions` 15/15에서 provider reasoning delta가 유지됐고 transformed `chatcmpl-manual` ID는 0/15였다. 원격 evidence는 `build/dev-corp-runtime/logs/public_passthrough_chat_15_20260709_180115.json`이다. 2026-07-08 `/v1/responses` 통과 기록은 mac-mini provider-pool runtime 기준 legacy evidence로만 본다. +- 2026-07-09 public Edge 재연결 검증에서 DGX Spark 01/02와 Mac Studio node를 `digitalplatform-iop.cloud:18087`로 변경한 뒤 `/v1/chat/completions` 15개 동시 요청이 15/15 성공했다. 같은 날 current passthrough source로 public Edge를 재빌드/재시작하고 최신 node 바이너리를 DGX Spark 01/02와 Mac Studio에 배포한 뒤 기본 streaming `/v1/chat/completions` 15/15에서 provider reasoning delta가 유지됐고 transformed `chatcmpl-manual` ID는 0/15였다. 원격 evidence는 `build/dev-corp-runtime/logs/public_latest_edge_node_chat_15_20260709_181222.json`이다. 2026-07-08 `/v1/responses` 통과 기록은 mac-mini provider-pool runtime 기준 legacy evidence로만 본다. ## 실행 절차 diff --git a/agent-test/dev-corp/edge-smoke.md b/agent-test/dev-corp/edge-smoke.md index d4463c5..95cde38 100644 --- a/agent-test/dev-corp/edge-smoke.md +++ b/agent-test/dev-corp/edge-smoke.md @@ -108,6 +108,7 @@ Mac Studio의 `http://192.168.2.3:8005/v1` mlx-vlm DiffusionGemma endpoint는 - mac-mini checkout/runtime is a runner and must not be used as Edge source of truth unless explicitly doing a local-runner comparison. - On 2026-07-09 the three provider nodes were moved from mac-mini/reverse-tunnel Edge addresses to `digitalplatform-iop.cloud:18087`, and public `/v1/chat/completions` 15-concurrency smoke passed 15/15. - On 2026-07-09 after rebuilding the public Edge from the current passthrough source, default streaming `/v1/chat/completions` preserved provider reasoning deltas for 15/15 concurrent requests; transformed `chatcmpl-manual` IDs were 0/15. Evidence: `build/dev-corp-runtime/logs/public_passthrough_chat_15_20260709_180115.json`. +- On 2026-07-09 after deploying latest node binaries to DGX Spark 01/02 and Mac Studio, public streaming `/v1/chat/completions` again passed 15/15 with provider reasoning deltas preserved and transformed `chatcmpl-manual` IDs 0/15. Evidence: `build/dev-corp-runtime/logs/public_latest_edge_node_chat_15_20260709_181222.json`. - Mac Studio provider catalog `type`은 최신 config validator 기준으로 `openai_compat`를 사용한다. 실제 provider runtime은 vLLM-MLX이고 `runtime_type: vllm-mlx`로 추적한다. - `/v1/chat/completions` capacity smoke 표준: 15개 동시 요청을 public `http://digitalplatform-iop.cloud:18086/v1`로 보낸다. 2026-07-09 public Edge 재연결 검증에서는 15/15 성공했다. - `/v1/responses`는 OpenAI-compatible provider model group raw passthrough parity 전까지 미지원이므로 provider-pool capacity 성공 기준에서 제외한다. diff --git a/agent-test/dev-corp/inventory.yaml b/agent-test/dev-corp/inventory.yaml index 93394b2..596737f 100644 --- a/agent-test/dev-corp/inventory.yaml +++ b/agent-test/dev-corp/inventory.yaml @@ -57,10 +57,25 @@ edge: public_chat_completions_15: ok: 15 concurrent_requests: 15 - elapsed_sec: 5.721 + elapsed_sec: 5.678 passthrough_reasoning_stream_seen: 15 transformed_manual_id_count: 0 - remote_log: build/dev-corp-runtime/logs/public_passthrough_chat_15_20260709_180115.json + remote_log: build/dev-corp-runtime/logs/public_latest_edge_node_chat_15_20260709_181222.json + latest_node_binary_deploy: + observed_at: "2026-07-09T18:12:22+09:00" + source_ref: e8c240ea23a29f1568326b6d162913863b3dca33 + linux_arm64_sha256: 02441a57f97238bd650a568896c876fb32c94fcace0073f6068509ef90ac4327 + darwin_arm64_sha256: 95c59ee0dacb134dc2c6d46fb34f2dac49c33d7da38abe96157583822364f57a + nodes: + corp-dgx-spark-01-vllm-node: + pid_after_restart: 545848 + binary_sha256: 02441a57f97238bd650a568896c876fb32c94fcace0073f6068509ef90ac4327 + corp-dgx-spark-02-vllm-node: + pid_after_restart: 701517 + binary_sha256: 02441a57f97238bd650a568896c876fb32c94fcace0073f6068509ef90ac4327 + corp-mac-studio-mlx-vllm-node: + pid_after_restart: 87325 + binary_sha256: 95c59ee0dacb134dc2c6d46fb34f2dac49c33d7da38abe96157583822364f57a note: public /v1/responses remains unsupported for OpenAI-compatible provider model groups until raw passthrough parity is implemented; use /v1/chat/completions for provider-pool capacity smoke. latest_bootstrap_domain_fix: observed_at: "2026-07-09" @@ -248,7 +263,7 @@ model: route: public_digitalplatform_edge host: digitalplatform-iop.cloud edge_addr: digitalplatform-iop.cloud:18087 - source_ref: public_edge_source_ref_not_confirmed_by_current_runner + source_ref: e8c240ea23a29f1568326b6d162913863b3dca33 default_thinking_token_budget: 1024 control_plane_enabled: unknown control_plane_status_url: http://digitalplatform-iop.cloud:18002/edges/dev-corp-edge/status @@ -256,7 +271,7 @@ model: capacity_snapshot_note: public Control Plane status was not accessible from the current runner; HTTP 15/15 smoke and node connection logs are current evidence, while in_flight/queued snapshot evidence remains legacy 2026-07-08 mac-mini runtime data. runtime: runner_checkout: /Users/fe/agent-work/iop-dev-corp - remote_log: build/dev-corp-runtime/logs/public_domain_chat_15_20260709_172253.json + remote_log: build/dev-corp-runtime/logs/public_latest_edge_node_chat_15_20260709_181222.json node_connection: node_edge_addr: digitalplatform-iop.cloud:18087 moved_from: @@ -271,9 +286,10 @@ model: ok: 15 timeout_errors: 0 http_errors: 0 - elapsed_sec: 25.516 - request_median_sec: 22.933 - text_length_median: 2338 + elapsed_sec: 5.678 + request_median_sec: 2.98 + passthrough_reasoning_stream_seen: 15 + transformed_manual_id_count: 0 responses: supported: false observed_http_status: 400 From a709db02513a41cdbba70b8932ee1ca81cf8d2da Mon Sep 17 00:00:00 2001 From: leedongmyun Date: Thu, 9 Jul 2026 20:48:05 +0900 Subject: [PATCH 3/4] =?UTF-8?q?docs(contract):=20dev-corp=20gemma4:26b=20?= =?UTF-8?q?=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20=EB=B2=94=EC=9C=84=20?= =?UTF-8?q?=EB=B0=8F=20=EA=B0=80=EC=9D=B4=EB=93=9C=20=EB=AC=B8=EC=84=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- agent-contract/outer/openai-compatible-api.md | 25 ++- docs/dev-corp-openai-compatible-call-guide.md | 146 +++++++++++++ docs/dev-corp-pi-settings-guide.md | 204 ++++++++++++++++++ docs/edge-local-dev-guide.md | 19 +- docs/openai-compatible-api-contract.md | 3 + 5 files changed, 386 insertions(+), 11 deletions(-) create mode 100644 docs/dev-corp-openai-compatible-call-guide.md create mode 100644 docs/dev-corp-pi-settings-guide.md diff --git a/agent-contract/outer/openai-compatible-api.md b/agent-contract/outer/openai-compatible-api.md index 4d025c8..ac025e5 100644 --- a/agent-contract/outer/openai-compatible-api.md +++ b/agent-contract/outer/openai-compatible-api.md @@ -187,17 +187,38 @@ Think 제어 field: - `think` (bool, optional): thinking/reasoning 생성 활성화 여부. 생략하면 provider 기본값을 유지한다. `false`는 thinking 생성을 끄도록 요청하고, `true`는 provider가 지원하면 thinking 생성을 명시 활성화한다. - `reasoning_effort` (string, optional): `none`, `low`, `medium`, `high` 중 하나. `none`은 `think=false`와 같은 disable 의미로 처리한다. `low`/`medium`/`high`는 provider가 지원하는 경우에만 전달한다. - `thinking_token_budget` (int, optional): thinking token budget. 0 이상이어야 한다. -- `include_reasoning` (bool, optional): OpenAI-compatible 응답에서 `reasoning_content` 노출 여부. 생략하거나 `true`이면 provider reasoning delta/message를 노출할 수 있고, `false`이면 provider가 reasoning을 생성해도 response의 `reasoning_content`를 제거한다. +- `include_reasoning` (bool, optional): OpenAI-compatible 응답에서 `reasoning_content` 노출 여부. non-provider normalized route에서는 생략하거나 `true`이면 provider reasoning delta/message를 노출할 수 있고, `false`이면 provider가 reasoning을 생성해도 response의 `reasoning_content`를 제거한다. provider-pool pure `passthrough`는 provider body 보존이 우선이며, 현재 IOP가 이 field만으로 reasoning field를 제거한다고 보장하지 않는다. -Reasoning-only 완료 처리: +### dev-corp `gemma4:26b` provider-pool passthrough 파라미터 범위 + +이 표는 dev-corp의 `gemma4:26b` provider-pool route에서, 현재 IOP 설정과 provider/vLLM 최적화 값을 변경하지 않고 standard OpenAI-compatible caller가 요청 파라미터만 바꿔 측정할 때의 현재 계약 범위다. Pi TUI의 고정 호출 방식이나 다른 model/provider route의 동작으로 일반화하지 않는다. + +| 요청 파라미터 | 현재 기대 동작 | 권장 판정 | +| --- | --- | --- | +| `stream=false`, `think` 생략 | provider에 non-stream Chat Completions 요청으로 전달되고 Edge는 provider JSON body를 relay한다. reasoning field가 있으면 보존될 수 있다. | standard OpenAI-compatible caller에서 non-stream 동작 측정 가능. reasoning을 숨기려면 client에서 `choices[].message.reasoning_content`, `reasoning` 등 provider reasoning field를 제거한다. | +| `stream=true`, `think` 생략 | provider SSE body를 relay한다. reasoning delta가 있으면 보존될 수 있다. | streaming 동작 측정 가능. client는 `choices[].delta.reasoning_content`, `reasoning`, `reasoning_text` 같은 reasoning delta를 선택적으로 무시한다. | +| `include_reasoning=false` | field는 수신/전달될 수 있지만 pure `passthrough`에서 IOP-side filtering을 보장하지 않는다. provider가 무시하면 reasoning field가 그대로 올 수 있다. | 현재 IOP 설정을 바꾸지 않는 조건에서는 hide-only 스위치로 보지 않는다. client-side filtering을 기준으로 둔다. | +| `think=false` | Edge validation conflict가 없으면 요청은 통과하고 model catalog의 default thinking budget 주입은 억제된다. 이후 provider body에 `think:false`가 반영될 수 있으나, 현재 `gemma4:26b` provider 최적화 값과 충돌하거나 backend별로 무시/실패/품질 저하가 날 수 있다. | “숨기기만” 하는 옵션이 아니다. dev-corp `gemma4:26b` 기본 안정 호출에서는 생략한다. | +| `reasoning_effort="none"` | `think=false`와 같은 disable 의도로 해석되어 default thinking budget 주입을 억제한다. provider tunnel에서는 runtime/provider 지원 여부에 의존한다. | `think=false`와 같은 이유로 기본 안정 호출에서는 생략한다. | +| 명시적 `thinking_token_budget` | 0 이상이면 conflict validation 후 provider tunnel body에 반영될 수 있다. catalog 기본 budget 대신 caller 값으로 provider thinking budget을 바꾸는 요청이다. | 최적화된 `gemma4:26b` 기본값을 바꾸는 측정으로만 사용한다. 일반 표준 안정 호출에서는 생략한다. | +| `metadata.iop_response_mode="passthrough+sideband"` | provider content는 보존하고 IOP sideband observation만 추가한다. reasoning hide를 수행하지 않는다. | route/usage 관측이 필요할 때만 사용한다. | +| `metadata.iop_response_mode="transformed"` | provider model group route에서는 `400 invalid_request_error`로 거부한다. | dev-corp `gemma4:26b` provider-pool에서는 사용하지 않는다. | +| `/v1/responses` 호출 | provider model group raw passthrough parity 전까지 지원하지 않는다. | `gemma4:26b` provider-pool 외부 호출은 `/v1/chat/completions` 기준으로 측정한다. | + +현재 구현에서 `think=false`를 “provider에는 기본 think를 유지하되 IOP가 응답에서 reasoning만 감추는 hide-only 모드”로 해석하지 않는다. 그런 동작이 필요하면 provider/vLLM 설정 변경이 아니라 Edge provider-pool passthrough 응답 filtering 정책을 별도 구현/계약 갱신해야 한다. + +Reasoning-only 완료 처리 (non-provider normalized route): - provider가 reasoning은 생성했지만 최종 assistant `content`와 `tool_calls` 없이 완료하면 Edge는 성공 응답을 빈 content로 끝내지 않는다. - `include_reasoning` 생략 또는 `true`인 요청은 기존 reasoning 본문을 `reasoning_content`에 유지하고, `content`가 비어 있으면 reasoning 본문을 fallback content로도 반환한다. `finish_reason`이 `stop`이 아니면 fallback content 뒤에 IOP notice를 붙인다. - `include_reasoning=false`인 요청은 reasoning 본문을 노출하지 않는다. 대신 `content`에 IOP notice를 넣어 "reasoning was hidden" 상태와 `finish_reason`을 알린다. - streaming 응답도 같은 정책을 따른다. reasoning-only 완료 시 최종 finish chunk와 `[DONE]` 전에 fallback 또는 hidden-reasoning notice를 `content` delta로 한 번 전송한다. +- Chat Completions provider-pool pure `passthrough` 응답 body에는 이 normalized fallback/filtering 정책을 적용하지 않는다. Provider별 think-control 정책: +아래 정책은 normalized adapter execution path 기준이다. Chat Completions provider-pool pure `passthrough`는 Node adapter의 normalized `Execute`/request-body builder를 거치지 않고 provider HTTP body를 tunnel로 전달하므로, dev-corp `gemma4:26b` 측정 범위는 위 표를 우선한다. + - `vLLM`: - `think=false` 또는 `reasoning_effort=none` -> 내부 `chat_template_kwargs.enable_thinking=false` - `think=true` 또는 budget-only -> 내부 `chat_template_kwargs.enable_thinking=true` diff --git a/docs/dev-corp-openai-compatible-call-guide.md b/docs/dev-corp-openai-compatible-call-guide.md new file mode 100644 index 0000000..98c0781 --- /dev/null +++ b/docs/dev-corp-openai-compatible-call-guide.md @@ -0,0 +1,146 @@ +# dev-corp OpenAI-Compatible Direct Call Guide + +이 문서는 dev-corp public Edge를 OpenAI-compatible HTTP client에서 직접 호출할 때의 사람용 가이드다. 계약 원문은 `agent-contract/outer/openai-compatible-api.md`이며, 여기서는 `digitalplatform-iop.cloud` 외부 호출에 필요한 값과 dev-corp `gemma4:26b` provider-pool 한계만 정리한다. Pi coding agent 설정은 `docs/dev-corp-pi-settings-guide.md`를 따른다. + +## 대상 범위 + +- 환경: dev-corp public Edge +- Base URL: `http://digitalplatform-iop.cloud:18086/v1` +- 기본 endpoint: `POST /v1/chat/completions` +- 모델 alias: `gemma4:26b` +- 인증: `Authorization: Bearer ` +- 기준 호출 방식: OpenAI-compatible Chat Completions 표준 HTTP 요청 + +`/v1/responses`는 dev-corp `gemma4:26b` provider-pool에서 raw passthrough parity 전까지 지원하지 않는다. 외부 표준 호출은 `/v1/chat/completions`를 기준으로 한다. + +## 기본 설정 + +| 항목 | 값 | +| --- | --- | +| Base URL | `http://digitalplatform-iop.cloud:18086/v1` | +| Models endpoint | `GET /v1/models` | +| Chat endpoint | `POST /v1/chat/completions` | +| Model | `gemma4:26b` | +| Content-Type | `application/json` | +| Authorization | `Bearer ` | +| Response mode | `metadata.iop_response_mode` 생략, 기본 `passthrough` | +| Streaming | client가 SSE를 처리할 수 있으면 `stream:true`, 아니면 `stream:false` | + +토큰 원문은 tracked 문서, 예시 파일, 로그에 남기지 않는다. + +## 권장 요청 + +가장 안정적인 기본 요청은 `think`, `reasoning_effort`, `thinking_token_budget`을 직접 지정하지 않는 형태다. 이렇게 호출하면 dev-corp `gemma4:26b` provider-pool의 현재 catalog/runtime 기본값을 유지한다. + +```bash +curl -fsS http://digitalplatform-iop.cloud:18086/v1/chat/completions \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer ' \ + -d '{ + "model": "gemma4:26b", + "messages": [ + { + "role": "user", + "content": "간단히 현재 호출이 정상인지 확인해줘." + } + ], + "stream": false + }' +``` + +Streaming이 필요한 client는 `stream:true`를 명시하고 SSE `data:` chunk를 처리한다. + +```bash +curl -N http://digitalplatform-iop.cloud:18086/v1/chat/completions \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer ' \ + -d '{ + "model": "gemma4:26b", + "messages": [ + { + "role": "user", + "content": "한 문장으로 응답해줘." + } + ], + "stream": true + }' +``` + +## 파라미터 기준 + +| 파라미터 | 권장값 | 이유 | +| --- | --- | --- | +| `model` | `gemma4:26b` | dev-corp provider-pool의 외부 alias다. | +| `stream` | client 처리 방식에 맞게 `false` 또는 `true` | `false`는 JSON body, `true`는 SSE stream을 반환한다. | +| `think` | 생략 | 현재 Gemma4 runtime은 thinking enabled 기준으로 튜닝되어 있다. | +| `reasoning_effort` | 생략 | `none`은 thinking disable 의도라 기본 안정 호출에 맞지 않는다. | +| `thinking_token_budget` | 생략 | 생략하면 IOP catalog의 dev-corp `gemma4:26b` 기본 thinking budget을 사용한다. 명시하면 최적화된 기본값을 바꾸는 측정이 된다. | +| `include_reasoning` | hide 보장용으로 사용하지 않음 | provider-pool pure `passthrough`는 provider body 보존이 우선이라 IOP-side reasoning 제거를 보장하지 않는다. | +| `metadata.iop_response_mode` | 생략 또는 `passthrough` | provider-original 응답을 relay한다. | +| `metadata.iop_response_mode="passthrough+sideband"` | 관측이 필요할 때만 사용 | provider body에 IOP sideband가 추가되며 hide 동작은 아니다. | +| `metadata.iop_response_mode="transformed"` | 사용하지 않음 | provider model group route에서는 `400 invalid_request_error`로 거부된다. | + +Provider 전용 field인 `chat_template_kwargs`, `format`, `keep_alive`, `options`는 Chat Completions 외부 요청 body에 넣지 않는다. 이 값들은 dev-corp provider runtime 쪽 최적화 영역이며, OpenAI-compatible public Edge 호출자가 직접 조작하는 계약이 아니다. + +## Reasoning 처리 + +dev-corp `gemma4:26b` provider-pool은 pure `passthrough`를 기본으로 한다. 따라서 provider가 reasoning field를 반환하면 Edge는 그 field를 보존할 수 있다. + +Non-stream 응답에서 client가 숨길 수 있는 대표 field: + +- `choices[].message.reasoning_content` +- `choices[].message.reasoning` +- `choices[].message.reasoning_text` + +Streaming 응답에서 client가 숨길 수 있는 대표 delta field: + +- `choices[].delta.reasoning_content` +- `choices[].delta.reasoning` +- `choices[].delta.reasoning_text` + +사용자에게 reasoning을 보여주지 않아야 하는 client는 위 field를 표시/저장/후속 prompt에 주입하지 않도록 client 쪽에서 필터링한다. `include_reasoning=false`만으로 dev-corp `gemma4:26b` provider-pool에서 reasoning이 제거된다고 가정하지 않는다. + +## Gemma4 설정으로 인한 한계 + +dev-corp `gemma4:26b` provider-pool은 Gemma4 agent/tool-call 호환성을 위해 vLLM/vLLM-MLX runtime을 thinking enabled, Gemma4 parser/template, long-context 기준으로 맞춰 둔 상태다. 이 설정은 현재 동작 가능한 최적값에 가깝기 때문에 외부 caller가 요청 파라미터로 thinking 동작을 끄거나 budget을 바꾸면 backend별로 무시, 오류, 품질 저하, tool-call drift가 날 수 있다. + +현재 한계: + +- `think=false`는 “응답에서 reasoning만 숨김”이 아니라 thinking disable 요청이다. +- `reasoning_effort="none"`도 thinking disable 의도로 해석된다. +- 명시적 `thinking_token_budget`은 dev-corp 기본 budget을 바꾸는 요청이다. +- `include_reasoning=false`는 provider-pool pure `passthrough`에서 hide-only 스위치가 아니다. +- streaming 응답에는 reasoning delta가 먼저 오고 최종 content가 뒤따를 수 있다. +- provider-pool은 여러 runtime 후보를 사용하므로 token 단위 출력, reasoning field 이름, chunk 경계가 완전히 동일하다고 가정하지 않는다. +- exact-output match보다 HTTP 성공, 정상 JSON/SSE 구조, 최종 assistant content 존재 여부를 우선 판정한다. + +Reasoning을 provider에서 생성하게 두되 외부 사용자에게 보이지 않게 하려면, 현재 안정 기준은 `think` 관련 파라미터를 생략하고 client에서 reasoning field를 무시하는 것이다. + +## 검증 순서 + +1. Model 목록 확인: + +```bash +curl -fsS http://digitalplatform-iop.cloud:18086/v1/models \ + -H 'Authorization: Bearer ' +``` + +2. Non-stream Chat Completions 확인: + +```bash +curl -fsS http://digitalplatform-iop.cloud:18086/v1/chat/completions \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer ' \ + -d '{"model":"gemma4:26b","messages":[{"role":"user","content":"ok만 응답해줘."}],"stream":false}' +``` + +3. Streaming Chat Completions 확인: + +```bash +curl -N http://digitalplatform-iop.cloud:18086/v1/chat/completions \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer ' \ + -d '{"model":"gemma4:26b","messages":[{"role":"user","content":"ok만 응답해줘."}],"stream":true}' +``` + +성공 판정은 HTTP 200, OpenAI-compatible `choices[]` 구조, 최종 assistant 응답 수신 기준으로 한다. Reasoning field가 포함되는 것만으로 실패로 보지 않는다. diff --git a/docs/dev-corp-pi-settings-guide.md b/docs/dev-corp-pi-settings-guide.md new file mode 100644 index 0000000..2a49327 --- /dev/null +++ b/docs/dev-corp-pi-settings-guide.md @@ -0,0 +1,204 @@ +# dev-corp Pi Settings Guide + +이 문서는 host-local Pi coding agent를 dev-corp `gemma4:26b` provider-pool에 맞춰 설정할 때의 기준이다. 일반 OpenAI-compatible HTTP 직접 호출은 `docs/dev-corp-openai-compatible-call-guide.md`를 따른다. + +## 대상 범위 + +- Pi package: `pi-coding-agent` +- 확인된 Pi version: `0.80.3` +- Pi binary: `pi` +- 설정 디렉터리: `~/.pi/agent` +- 설정 파일: + - `~/.pi/agent/settings.json` + - `~/.pi/agent/models.json` +- 대상 provider: `dev-corp` +- 대상 model: `gemma4:26b` +- Base URL: `http://digitalplatform-iop.cloud:18086/v1` + +이 가이드는 dev-corp Gemma4 Pi profile 전용이다. dev/Qwen profile, direct provider 실험 profile, IOP Edge/Node/provider/vLLM runtime 설정으로 일반화하지 않는다. + +## 핵심 원칙 + +- Pi 쪽 설정만 바꾼다. IOP Edge config, Node config, provider runtime, vLLM/vLLM-MLX launch option은 건드리지 않는다. +- `apiKey`, `authHeader` 같은 secret 값은 새로 출력하거나 tracked 문서에 기록하지 않는다. +- `dev-corp` provider가 기본값이어야 하며 direct provider profile을 기본값으로 두지 않는다. +- Pi의 `openai-completions` 경로는 Chat Completions streaming 호출 기준이다. 일반 HTTP `stream:false` 측정은 Pi가 아니라 표준 caller 가이드에서 다룬다. +- dev-corp `gemma4:26b`는 provider-pool catalog와 provider runtime이 thinking enabled 기준으로 맞춰져 있다. Pi에서 thinking disable을 시도하지 않는다. + +## settings.json 기준 + +`~/.pi/agent/settings.json`의 dev-corp 기준값: + +```json +{ + "defaultProvider": "dev-corp", + "defaultModel": "gemma4:26b", + "defaultThinkingLevel": "high", + "hideThinkingBlock": false, + "httpIdleTimeoutMs": 300000, + "retry": { + "provider": { + "timeoutMs": 300000, + "maxRetries": 0, + "maxRetryDelayMs": 60000 + } + }, + "enabledModels": [ + "dev-corp-direct/**", + "dev-corp-spark01/**", + "dev-corp/*" + ] +} +``` + +`lastChangelogVersion`, `theme` 같은 Pi UI/local preference field는 기존 값을 보존한다. + +## models.json 기준 + +`~/.pi/agent/models.json`에는 최소한 `providers.dev-corp`가 아래 의미를 가져야 한다. 예시의 ``은 새 값으로 덮어쓰지 말고 기존 값을 유지한다는 뜻이다. + +```json +{ + "providers": { + "dev-corp": { + "baseUrl": "http://digitalplatform-iop.cloud:18086/v1", + "api": "openai-completions", + "apiKey": "", + "authHeader": "", + "compat": { + "supportsStore": false, + "supportsDeveloperRole": false, + "supportsReasoningEffort": false, + "supportsUsageInStreaming": false, + "maxTokensField": "max_tokens", + "requiresToolResultName": true, + "requiresAssistantAfterToolResult": true, + "supportsStrictMode": false + }, + "models": [ + { + "id": "gemma4:26b", + "name": "dev-corp gemma4:26b", + "reasoning": true, + "input": ["text"], + "contextWindow": 262144, + "maxTokens": 32768, + "cost": { + "input": 0, + "output": 0, + "cacheRead": 0, + "cacheWrite": 0 + } + } + ] + } + } +} +``` + +`dev-corp-direct`와 `dev-corp-spark01` provider가 있더라도 fallback/실험용으로만 둔다. 기본 provider/model은 항상 `dev-corp` / `gemma4:26b`다. + +## Gemma4 한계와 Pi 설정 의미 + +현재 dev-corp `gemma4:26b` provider-pool은 Gemma4 agent/tool-call 호환성을 위해 provider runtime을 `reasoning_parser=gemma4`, `tool_call_parser=gemma4`, thinking enabled, long-context 기준으로 맞춰 둔 상태다. 이 값들은 provider 쪽 최적화 지점이므로 Pi 설정에서 우회하지 않는다. + +주의할 점: + +- `supportsReasoningEffort`는 `false`로 둔다. `true`로 바꾸면 Pi가 `reasoning_effort`를 보낼 수 있고, 현재 provider-pool 안정 경로와 어긋날 수 있다. +- `defaultThinkingLevel`은 `high`로 둔다. 단, dev-corp `supportsReasoningEffort=false` 기준에서는 Pi가 top-level `reasoning_effort=high`를 보내는 용도가 아니라 profile alignment와 UI 기준값이다. +- `hideThinkingBlock`은 현재 기준 `false`다. reasoning이 흘러오는지 관측 가능한 baseline을 유지한다. UI에서 숨김이 필요하더라도 provider thinking disable과 혼동하지 않는다. +- `thinking_token_budget`, `think=false`, `reasoning_effort=none` 같은 요청 파라미터를 Pi 설정으로 강제하지 않는다. +- Pi가 보는 context window는 `262144`, max output token 기준은 `32768`이다. provider runtime과 IOP catalog도 이 범위에 맞춰져 있어야 한다. + +Reasoning을 생성하게 두되 사용자에게 노출하지 않는 정책은 Pi UI/rendering 또는 별도 client filtering 문제다. provider/vLLM 설정이나 IOP provider-pool 기본 파라미터를 바꿔 해결하지 않는다. + +## 검증 + +설정 후 secret을 출력하지 않는 범위에서 아래를 확인한다. + +```bash +pi --version +jq '{defaultProvider, defaultModel, defaultThinkingLevel, hideThinkingBlock, httpIdleTimeoutMs, retry, enabledModels}' ~/.pi/agent/settings.json +jq '.providers["dev-corp"] | { + baseUrl, + api, + hasApiKey: has("apiKey"), + hasAuthHeader: has("authHeader"), + compat, + models +}' ~/.pi/agent/models.json +``` + +기대값: + +- `pi --version`은 현재 기준 `0.80.3` +- `defaultProvider`는 `dev-corp` +- `defaultModel`은 `gemma4:26b` +- `defaultThinkingLevel`은 `high` +- `providers.dev-corp.baseUrl`은 `http://digitalplatform-iop.cloud:18086/v1` +- `providers.dev-corp.api`는 `openai-completions` +- `providers.dev-corp.compat.supportsReasoningEffort`는 `false` +- `providers.dev-corp.compat.maxTokensField`는 `max_tokens` +- `providers.dev-corp.models[0].contextWindow`는 `262144` +- `providers.dev-corp.models[0].maxTokens`는 `32768` + +실제 호출 검증은 짧은 prompt로 수행한다. tool-call 검증이 목적이면 일반 chat smoke와 별도로 forced tool call, auto tool call, streaming `delta.tool_calls`, tool result 후 최종 답변을 확인한다. + +## Codex/Claude 작업 프롬프트 + +아래 프롬프트는 Codex나 Claude에게 host-local Pi 설정을 맡길 때 그대로 전달하는 기준이다. + +```text +현재 호스트의 Pi coding agent를 dev-corp Gemma4 provider-pool 기준으로 맞춰줘. + +범위: +- 수정 가능: ~/.pi/agent/settings.json, ~/.pi/agent/models.json +- 수정 금지: IOP repo 설정, Edge config, Node config, provider runtime, vLLM/vLLM-MLX start script, secret 원문 출력 +- 현재 기준 provider/model: dev-corp / gemma4:26b +- Base URL: http://digitalplatform-iop.cloud:18086/v1 +- Pi API: openai-completions + +작업 규칙: +1. 먼저 pi --version, ~/.pi/agent/settings.json, ~/.pi/agent/models.json 구조를 확인해. +2. apiKey, authHeader, token, secret 값은 화면에 출력하지 말고 기존 값을 보존해. +3. 편집 전 settings.json과 models.json을 timestamp가 붙은 백업 파일로 복사해. +4. settings.json에는 아래 기준을 반영해: + - defaultProvider: dev-corp + - defaultModel: gemma4:26b + - defaultThinkingLevel: high + - hideThinkingBlock: false + - httpIdleTimeoutMs: 300000 + - retry.provider.timeoutMs: 300000 + - retry.provider.maxRetries: 0 + - retry.provider.maxRetryDelayMs: 60000 + - enabledModels: ["dev-corp-direct/**", "dev-corp-spark01/**", "dev-corp/*"] + - theme, lastChangelogVersion 등 기존 UI/local preference는 보존 +5. models.json의 providers.dev-corp는 아래 기준을 반영해: + - baseUrl: http://digitalplatform-iop.cloud:18086/v1 + - api: openai-completions + - 기존 apiKey/authHeader는 보존 + - compat.supportsStore: false + - compat.supportsDeveloperRole: false + - compat.supportsReasoningEffort: false + - compat.supportsUsageInStreaming: false + - compat.maxTokensField: max_tokens + - compat.requiresToolResultName: true + - compat.requiresAssistantAfterToolResult: true + - compat.supportsStrictMode: false + - model id: gemma4:26b + - model name: dev-corp gemma4:26b + - reasoning: true + - input: ["text"] + - contextWindow: 262144 + - maxTokens: 32768 + - cost input/output/cacheRead/cacheWrite: 0 +6. dev-corp-direct 또는 dev-corp-spark01 provider가 있으면 삭제하지 말고 fallback/실험용으로 보존해. 단 defaultProvider/defaultModel은 dev-corp/gemma4:26b로 둬. +7. supportsReasoningEffort를 true로 바꾸거나 think=false, reasoning_effort=none, thinking_token_budget 강제 설정을 추가하지 마. dev-corp Gemma4 provider-pool은 현재 thinking enabled 기준으로 튜닝되어 있고, reasoning hide는 provider 설정 변경이 아니라 client/UI 처리 문제야. +8. 변경 후 jq로 secret 없이 핵심 값만 출력해서 검증해. + +검증 출력에는 apiKey/authHeader 원문을 절대 포함하지 말고, hasApiKey/hasAuthHeader boolean 정도만 보여줘. +``` + +## 실패 시 되돌리기 + +백업한 파일로 `settings.json`과 `models.json`을 되돌린 뒤 Pi를 다시 실행한다. 실패가 `think=false`, `reasoning_effort`, `thinking_token_budget`, direct provider URL 변경과 관련되어 보이면 해당 변경을 제거하고 dev-corp public Edge route 기준으로 복원한다. diff --git a/docs/edge-local-dev-guide.md b/docs/edge-local-dev-guide.md index 79e6e00..f0fe85e 100644 --- a/docs/edge-local-dev-guide.md +++ b/docs/edge-local-dev-guide.md @@ -133,23 +133,24 @@ http://:18081/v1 ## 7. Thinking/Reasoning 제어 smoke -`/v1/chat/completions` 요청은 `think`, `reasoning_effort`, `thinking_token_budget`, `include_reasoning`으로 thinking/reasoning 동작과 응답 노출을 제어할 수 있다. +`/v1/chat/completions` 요청은 `think`, `reasoning_effort`, `thinking_token_budget`, `include_reasoning`으로 thinking/reasoning 동작과 응답 노출을 제어할 수 있다. 단, provider-pool pure `passthrough`는 provider body 보존이 우선이므로 `include_reasoning=false`만으로 IOP-side reasoning 제거를 보장하지 않는다. -- 공통 안정 smoke: `think` 생략, `include_reasoning=false`, 또는 budget-only `thinking_token_budget` -- `think=false`: reasoning 생성을 끄고 content stream이 유지되어야 한다. -- `include_reasoning=false`: thinking 생성은 허용하고 response reasoning_content만 숨김. -- `reasoning_effort=low|medium|high`: provider 매핑에 따라 unsupported error를 반환할 수 있다. +- dev-corp `gemma4:26b` provider-pool 안정 smoke: `think`, `reasoning_effort`, `thinking_token_budget`을 생략하고 현재 provider/vLLM 기본값을 유지한다. +- 일반 표준 caller의 `stream=false` 측정은 `/v1/chat/completions`에서 요청 파라미터만으로 확인한다. +- `include_reasoning=false`는 non-provider normalized route의 hide 동작 기준이다. dev-corp `gemma4:26b` provider-pool pure `passthrough`에서는 client가 reasoning field를 선택적으로 무시/제거한다. +- `think=false` 또는 `reasoning_effort=none`은 hide-only 옵션이 아니라 thinking disable 요청이다. dev-corp `gemma4:26b` 기본 안정 smoke에서는 쓰지 않는다. +- 세부 표와 금지/허용 범위는 `agent-contract/outer/openai-compatible-api.md`의 dev-corp `gemma4:26b` provider-pool passthrough 파라미터 범위를 기준으로 한다. -예시 (thinking 비활성화): +예시 (dev-corp `gemma4:26b` provider-pool non-stream 측정, think 생략): ```bash curl -fsS http://:18081/v1/chat/completions \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer ' \ - -d '{"model":"","messages":[{"role":"user","content":"hello"}],"think":false}' + -d '{"model":"gemma4:26b","messages":[{"role":"user","content":"hello"}],"stream":false}' ``` -예시 (thinking 생성은 허용하고 response reasoning_content만 숨김): +예시 (non-provider normalized route에서 response reasoning_content 숨김): ```bash curl -fsS http://:18081/v1/chat/completions \ @@ -169,4 +170,4 @@ Pi/Cline형 긴 agent prompt와 `tools[]` 요청은 provider가 native `tool_cal - 요청 `tools[]`에 있는 valid tool-call은 `message.tool_calls` 또는 stream `delta.tool_calls`와 `finish_reason: "tool_calls"`로 정규화된다. - 요청 `tools[]`에 없는 unknown tool hallucination이나 malformed 블록은 success content가 아니라 `tool_validation_error`로 끝난다. -evidence는 tracked 문서가 아니라 ignored run 위치(`agent-test/runs/**`) 또는 code-review output path에 저장한다. \ No newline at end of file +evidence는 tracked 문서가 아니라 ignored run 위치(`agent-test/runs/**`) 또는 code-review output path에 저장한다. diff --git a/docs/openai-compatible-api-contract.md b/docs/openai-compatible-api-contract.md index 7af644e..3b1cd14 100644 --- a/docs/openai-compatible-api-contract.md +++ b/docs/openai-compatible-api-contract.md @@ -9,5 +9,8 @@ - Chat Completions provider route의 기본 응답 mode는 provider-original `passthrough`다. - caller는 `metadata.iop_response_mode`에 `passthrough`, `passthrough+sideband`, `transformed` 중 하나를 넣어 응답 경로를 선택할 수 있다. - `passthrough+sideband`와 `transformed`는 IOP 확장/변환 응답이며 provider-original byte identity로 취급하지 않는다. +- dev-corp `gemma4:26b` provider-pool에서 `think`/`stream`/`include_reasoning` 요청 파라미터만 바꿔 측정하는 범위는 계약 원문의 `dev-corp gemma4:26b provider-pool passthrough 파라미터 범위` 표를 기준으로 한다. +- dev-corp `digitalplatform-iop.cloud` 직접 호출 가이드는 [dev-corp-openai-compatible-call-guide.md](./dev-corp-openai-compatible-call-guide.md)를 기준으로 한다. +- dev-corp Pi coding agent 설정 가이드는 [dev-corp-pi-settings-guide.md](./dev-corp-pi-settings-guide.md)를 기준으로 한다. 에이전트 작업에서는 [agent-contract/index.md](../agent-contract/index.md)의 라우팅 규칙을 먼저 따른다. From ef236878ffbbe93ac94235e515fb2f349b4e3590 Mon Sep 17 00:00:00 2001 From: leedongmyun Date: Thu, 9 Jul 2026 21:02:50 +0900 Subject: [PATCH 4/4] docs: update dev-corp openai-compatible call and pi settings guide --- docs/dev-corp-openai-compatible-call-guide.md | 134 +++--------- docs/dev-corp-pi-settings-guide.md | 197 ++++++++---------- 2 files changed, 110 insertions(+), 221 deletions(-) diff --git a/docs/dev-corp-openai-compatible-call-guide.md b/docs/dev-corp-openai-compatible-call-guide.md index 98c0781..c6d6c82 100644 --- a/docs/dev-corp-openai-compatible-call-guide.md +++ b/docs/dev-corp-openai-compatible-call-guide.md @@ -1,54 +1,22 @@ -# dev-corp OpenAI-Compatible Direct Call Guide +# dev-corp OpenAI-Compatible Call Guide -이 문서는 dev-corp public Edge를 OpenAI-compatible HTTP client에서 직접 호출할 때의 사람용 가이드다. 계약 원문은 `agent-contract/outer/openai-compatible-api.md`이며, 여기서는 `digitalplatform-iop.cloud` 외부 호출에 필요한 값과 dev-corp `gemma4:26b` provider-pool 한계만 정리한다. Pi coding agent 설정은 `docs/dev-corp-pi-settings-guide.md`를 따른다. +dev-corp `gemma4:26b` 모델을 OpenAI-compatible 방식으로 직접 호출할 때 필요한 최소 설정이다. -## 대상 범위 - -- 환경: dev-corp public Edge -- Base URL: `http://digitalplatform-iop.cloud:18086/v1` -- 기본 endpoint: `POST /v1/chat/completions` -- 모델 alias: `gemma4:26b` -- 인증: `Authorization: Bearer ` -- 기준 호출 방식: OpenAI-compatible Chat Completions 표준 HTTP 요청 - -`/v1/responses`는 dev-corp `gemma4:26b` provider-pool에서 raw passthrough parity 전까지 지원하지 않는다. 외부 표준 호출은 `/v1/chat/completions`를 기준으로 한다. - -## 기본 설정 +## 기본값 | 항목 | 값 | | --- | --- | | Base URL | `http://digitalplatform-iop.cloud:18086/v1` | -| Models endpoint | `GET /v1/models` | | Chat endpoint | `POST /v1/chat/completions` | +| Models endpoint | `GET /v1/models` | | Model | `gemma4:26b` | -| Content-Type | `application/json` | -| Authorization | `Bearer ` | -| Response mode | `metadata.iop_response_mode` 생략, 기본 `passthrough` | -| Streaming | client가 SSE를 처리할 수 있으면 `stream:true`, 아니면 `stream:false` | +| Auth header | `Authorization: Bearer ` | -토큰 원문은 tracked 문서, 예시 파일, 로그에 남기지 않는다. +`/v1/responses`가 아니라 `/v1/chat/completions`를 사용한다. ## 권장 요청 -가장 안정적인 기본 요청은 `think`, `reasoning_effort`, `thinking_token_budget`을 직접 지정하지 않는 형태다. 이렇게 호출하면 dev-corp `gemma4:26b` provider-pool의 현재 catalog/runtime 기본값을 유지한다. - -```bash -curl -fsS http://digitalplatform-iop.cloud:18086/v1/chat/completions \ - -H 'Content-Type: application/json' \ - -H 'Authorization: Bearer ' \ - -d '{ - "model": "gemma4:26b", - "messages": [ - { - "role": "user", - "content": "간단히 현재 호출이 정상인지 확인해줘." - } - ], - "stream": false - }' -``` - -Streaming이 필요한 client는 `stream:true`를 명시하고 SSE `data:` chunk를 처리한다. +기본 권장 호출은 `stream:true`다. `think`, `reasoning_effort`, `thinking_token_budget`은 보내지 않는다. ```bash curl -N http://digitalplatform-iop.cloud:18086/v1/chat/completions \ @@ -59,73 +27,14 @@ curl -N http://digitalplatform-iop.cloud:18086/v1/chat/completions \ "messages": [ { "role": "user", - "content": "한 문장으로 응답해줘." + "content": "간단히 응답해줘." } ], "stream": true }' ``` -## 파라미터 기준 - -| 파라미터 | 권장값 | 이유 | -| --- | --- | --- | -| `model` | `gemma4:26b` | dev-corp provider-pool의 외부 alias다. | -| `stream` | client 처리 방식에 맞게 `false` 또는 `true` | `false`는 JSON body, `true`는 SSE stream을 반환한다. | -| `think` | 생략 | 현재 Gemma4 runtime은 thinking enabled 기준으로 튜닝되어 있다. | -| `reasoning_effort` | 생략 | `none`은 thinking disable 의도라 기본 안정 호출에 맞지 않는다. | -| `thinking_token_budget` | 생략 | 생략하면 IOP catalog의 dev-corp `gemma4:26b` 기본 thinking budget을 사용한다. 명시하면 최적화된 기본값을 바꾸는 측정이 된다. | -| `include_reasoning` | hide 보장용으로 사용하지 않음 | provider-pool pure `passthrough`는 provider body 보존이 우선이라 IOP-side reasoning 제거를 보장하지 않는다. | -| `metadata.iop_response_mode` | 생략 또는 `passthrough` | provider-original 응답을 relay한다. | -| `metadata.iop_response_mode="passthrough+sideband"` | 관측이 필요할 때만 사용 | provider body에 IOP sideband가 추가되며 hide 동작은 아니다. | -| `metadata.iop_response_mode="transformed"` | 사용하지 않음 | provider model group route에서는 `400 invalid_request_error`로 거부된다. | - -Provider 전용 field인 `chat_template_kwargs`, `format`, `keep_alive`, `options`는 Chat Completions 외부 요청 body에 넣지 않는다. 이 값들은 dev-corp provider runtime 쪽 최적화 영역이며, OpenAI-compatible public Edge 호출자가 직접 조작하는 계약이 아니다. - -## Reasoning 처리 - -dev-corp `gemma4:26b` provider-pool은 pure `passthrough`를 기본으로 한다. 따라서 provider가 reasoning field를 반환하면 Edge는 그 field를 보존할 수 있다. - -Non-stream 응답에서 client가 숨길 수 있는 대표 field: - -- `choices[].message.reasoning_content` -- `choices[].message.reasoning` -- `choices[].message.reasoning_text` - -Streaming 응답에서 client가 숨길 수 있는 대표 delta field: - -- `choices[].delta.reasoning_content` -- `choices[].delta.reasoning` -- `choices[].delta.reasoning_text` - -사용자에게 reasoning을 보여주지 않아야 하는 client는 위 field를 표시/저장/후속 prompt에 주입하지 않도록 client 쪽에서 필터링한다. `include_reasoning=false`만으로 dev-corp `gemma4:26b` provider-pool에서 reasoning이 제거된다고 가정하지 않는다. - -## Gemma4 설정으로 인한 한계 - -dev-corp `gemma4:26b` provider-pool은 Gemma4 agent/tool-call 호환성을 위해 vLLM/vLLM-MLX runtime을 thinking enabled, Gemma4 parser/template, long-context 기준으로 맞춰 둔 상태다. 이 설정은 현재 동작 가능한 최적값에 가깝기 때문에 외부 caller가 요청 파라미터로 thinking 동작을 끄거나 budget을 바꾸면 backend별로 무시, 오류, 품질 저하, tool-call drift가 날 수 있다. - -현재 한계: - -- `think=false`는 “응답에서 reasoning만 숨김”이 아니라 thinking disable 요청이다. -- `reasoning_effort="none"`도 thinking disable 의도로 해석된다. -- 명시적 `thinking_token_budget`은 dev-corp 기본 budget을 바꾸는 요청이다. -- `include_reasoning=false`는 provider-pool pure `passthrough`에서 hide-only 스위치가 아니다. -- streaming 응답에는 reasoning delta가 먼저 오고 최종 content가 뒤따를 수 있다. -- provider-pool은 여러 runtime 후보를 사용하므로 token 단위 출력, reasoning field 이름, chunk 경계가 완전히 동일하다고 가정하지 않는다. -- exact-output match보다 HTTP 성공, 정상 JSON/SSE 구조, 최종 assistant content 존재 여부를 우선 판정한다. - -Reasoning을 provider에서 생성하게 두되 외부 사용자에게 보이지 않게 하려면, 현재 안정 기준은 `think` 관련 파라미터를 생략하고 client에서 reasoning field를 무시하는 것이다. - -## 검증 순서 - -1. Model 목록 확인: - -```bash -curl -fsS http://digitalplatform-iop.cloud:18086/v1/models \ - -H 'Authorization: Bearer ' -``` - -2. Non-stream Chat Completions 확인: +Streaming을 처리하지 않는 client에서는 선택적으로 `stream:false`를 사용할 수 있다. ```bash curl -fsS http://digitalplatform-iop.cloud:18086/v1/chat/completions \ @@ -134,13 +43,22 @@ curl -fsS http://digitalplatform-iop.cloud:18086/v1/chat/completions \ -d '{"model":"gemma4:26b","messages":[{"role":"user","content":"ok만 응답해줘."}],"stream":false}' ``` -3. Streaming Chat Completions 확인: +## 파라미터 -```bash -curl -N http://digitalplatform-iop.cloud:18086/v1/chat/completions \ - -H 'Content-Type: application/json' \ - -H 'Authorization: Bearer ' \ - -d '{"model":"gemma4:26b","messages":[{"role":"user","content":"ok만 응답해줘."}],"stream":true}' -``` +| 파라미터 | 권장 | +| --- | --- | +| `model` | `gemma4:26b` | +| `stream` | 기본 `true`, 필요하면 `false` | +| `think` | 생략 | +| `reasoning_effort` | 생략 | +| `thinking_token_budget` | 생략 | +| `include_reasoning` | 숨김 보장용으로 쓰지 않음 | -성공 판정은 HTTP 200, OpenAI-compatible `choices[]` 구조, 최종 assistant 응답 수신 기준으로 한다. Reasoning field가 포함되는 것만으로 실패로 보지 않는다. +## Reasoning 표시 옵션 + +응답에 reasoning field가 포함될 수 있다. 표시하지 않는 UX가 필요하면 호출하는 client에서 아래 field를 렌더링 대상에서 제외하는 방식으로 처리할 수 있다. + +- non-stream: `choices[].message.reasoning_content`, `choices[].message.reasoning`, `choices[].message.reasoning_text` +- stream: `choices[].delta.reasoning_content`, `choices[].delta.reasoning`, `choices[].delta.reasoning_text` + +`include_reasoning=false`만으로 reasoning 표시 여부가 항상 제어된다고 가정하지 않는다. diff --git a/docs/dev-corp-pi-settings-guide.md b/docs/dev-corp-pi-settings-guide.md index 2a49327..f06d518 100644 --- a/docs/dev-corp-pi-settings-guide.md +++ b/docs/dev-corp-pi-settings-guide.md @@ -1,33 +1,36 @@ # dev-corp Pi Settings Guide -이 문서는 host-local Pi coding agent를 dev-corp `gemma4:26b` provider-pool에 맞춰 설정할 때의 기준이다. 일반 OpenAI-compatible HTTP 직접 호출은 `docs/dev-corp-openai-compatible-call-guide.md`를 따른다. +Pi를 dev-corp `gemma4:26b`로 사용하기 위한 최소 설치/설정 기준이다. -## 대상 범위 +## 설치 -- Pi package: `pi-coding-agent` -- 확인된 Pi version: `0.80.3` -- Pi binary: `pi` -- 설정 디렉터리: `~/.pi/agent` -- 설정 파일: - - `~/.pi/agent/settings.json` - - `~/.pi/agent/models.json` -- 대상 provider: `dev-corp` -- 대상 model: `gemma4:26b` -- Base URL: `http://digitalplatform-iop.cloud:18086/v1` +Pi `0.80.3`은 Node.js `22.19.0` 이상이 필요하다. -이 가이드는 dev-corp Gemma4 Pi profile 전용이다. dev/Qwen profile, direct provider 실험 profile, IOP Edge/Node/provider/vLLM runtime 설정으로 일반화하지 않는다. +```bash +node --version +npm --version +npm install -g @earendil-works/pi-coding-agent@0.80.3 +pi --version +``` -## 핵심 원칙 +`pi --version`이 `0.80.3`이면 정상이다. -- Pi 쪽 설정만 바꾼다. IOP Edge config, Node config, provider runtime, vLLM/vLLM-MLX launch option은 건드리지 않는다. -- `apiKey`, `authHeader` 같은 secret 값은 새로 출력하거나 tracked 문서에 기록하지 않는다. -- `dev-corp` provider가 기본값이어야 하며 direct provider profile을 기본값으로 두지 않는다. -- Pi의 `openai-completions` 경로는 Chat Completions streaming 호출 기준이다. 일반 HTTP `stream:false` 측정은 Pi가 아니라 표준 caller 가이드에서 다룬다. -- dev-corp `gemma4:26b`는 provider-pool catalog와 provider runtime이 thinking enabled 기준으로 맞춰져 있다. Pi에서 thinking disable을 시도하지 않는다. +## 설정 파일 -## settings.json 기준 +설정 위치: -`~/.pi/agent/settings.json`의 dev-corp 기준값: +```text +~/.pi/agent/settings.json +~/.pi/agent/models.json +``` + +디렉터리가 없으면 만든다. + +```bash +mkdir -p ~/.pi/agent +``` + +## settings.json ```json { @@ -44,18 +47,16 @@ } }, "enabledModels": [ - "dev-corp-direct/**", - "dev-corp-spark01/**", "dev-corp/*" ] } ``` -`lastChangelogVersion`, `theme` 같은 Pi UI/local preference field는 기존 값을 보존한다. +기존 `theme`, `lastChangelogVersion` 같은 개인 설정은 유지해도 된다. -## models.json 기준 +## models.json -`~/.pi/agent/models.json`에는 최소한 `providers.dev-corp`가 아래 의미를 가져야 한다. 예시의 ``은 새 값으로 덮어쓰지 말고 기존 값을 유지한다는 뜻이다. +`apiKey`에는 실제 토큰을 넣는다. 토큰은 문서, 로그, 공유 화면에 남기지 않는다. ```json { @@ -63,8 +64,8 @@ "dev-corp": { "baseUrl": "http://digitalplatform-iop.cloud:18086/v1", "api": "openai-completions", - "apiKey": "", - "authHeader": "", + "apiKey": "", + "authHeader": true, "compat": { "supportsStore": false, "supportsDeveloperRole": false, @@ -96,109 +97,79 @@ } ``` -`dev-corp-direct`와 `dev-corp-spark01` provider가 있더라도 fallback/실험용으로만 둔다. 기본 provider/model은 항상 `dev-corp` / `gemma4:26b`다. +## 주의 -## Gemma4 한계와 Pi 설정 의미 +- `supportsReasoningEffort`는 `false`로 둔다. +- `think=false`, `reasoning_effort=none`, `thinking_token_budget`을 강제로 추가하지 않는다. +- Pi는 `openai-completions` 기준으로 streaming 호출을 기본 사용한다. non-stream이 필요한 경우는 Pi가 아니라 일반 OpenAI-compatible 호출에서 `stream:false`로 선택한다. +- reasoning 표시 여부는 Pi UI나 client 표시 정책에서 선택적으로 처리한다. -현재 dev-corp `gemma4:26b` provider-pool은 Gemma4 agent/tool-call 호환성을 위해 provider runtime을 `reasoning_parser=gemma4`, `tool_call_parser=gemma4`, thinking enabled, long-context 기준으로 맞춰 둔 상태다. 이 값들은 provider 쪽 최적화 지점이므로 Pi 설정에서 우회하지 않는다. - -주의할 점: - -- `supportsReasoningEffort`는 `false`로 둔다. `true`로 바꾸면 Pi가 `reasoning_effort`를 보낼 수 있고, 현재 provider-pool 안정 경로와 어긋날 수 있다. -- `defaultThinkingLevel`은 `high`로 둔다. 단, dev-corp `supportsReasoningEffort=false` 기준에서는 Pi가 top-level `reasoning_effort=high`를 보내는 용도가 아니라 profile alignment와 UI 기준값이다. -- `hideThinkingBlock`은 현재 기준 `false`다. reasoning이 흘러오는지 관측 가능한 baseline을 유지한다. UI에서 숨김이 필요하더라도 provider thinking disable과 혼동하지 않는다. -- `thinking_token_budget`, `think=false`, `reasoning_effort=none` 같은 요청 파라미터를 Pi 설정으로 강제하지 않는다. -- Pi가 보는 context window는 `262144`, max output token 기준은 `32768`이다. provider runtime과 IOP catalog도 이 범위에 맞춰져 있어야 한다. - -Reasoning을 생성하게 두되 사용자에게 노출하지 않는 정책은 Pi UI/rendering 또는 별도 client filtering 문제다. provider/vLLM 설정이나 IOP provider-pool 기본 파라미터를 바꿔 해결하지 않는다. - -## 검증 - -설정 후 secret을 출력하지 않는 범위에서 아래를 확인한다. +## 확인 ```bash pi --version -jq '{defaultProvider, defaultModel, defaultThinkingLevel, hideThinkingBlock, httpIdleTimeoutMs, retry, enabledModels}' ~/.pi/agent/settings.json +jq '{defaultProvider, defaultModel, defaultThinkingLevel, hideThinkingBlock}' ~/.pi/agent/settings.json jq '.providers["dev-corp"] | { baseUrl, api, hasApiKey: has("apiKey"), - hasAuthHeader: has("authHeader"), + authHeader, compat, models }' ~/.pi/agent/models.json ``` -기대값: - -- `pi --version`은 현재 기준 `0.80.3` -- `defaultProvider`는 `dev-corp` -- `defaultModel`은 `gemma4:26b` -- `defaultThinkingLevel`은 `high` -- `providers.dev-corp.baseUrl`은 `http://digitalplatform-iop.cloud:18086/v1` -- `providers.dev-corp.api`는 `openai-completions` -- `providers.dev-corp.compat.supportsReasoningEffort`는 `false` -- `providers.dev-corp.compat.maxTokensField`는 `max_tokens` -- `providers.dev-corp.models[0].contextWindow`는 `262144` -- `providers.dev-corp.models[0].maxTokens`는 `32768` - -실제 호출 검증은 짧은 prompt로 수행한다. tool-call 검증이 목적이면 일반 chat smoke와 별도로 forced tool call, auto tool call, streaming `delta.tool_calls`, tool result 후 최종 답변을 확인한다. - ## Codex/Claude 작업 프롬프트 -아래 프롬프트는 Codex나 Claude에게 host-local Pi 설정을 맡길 때 그대로 전달하는 기준이다. - ```text -현재 호스트의 Pi coding agent를 dev-corp Gemma4 provider-pool 기준으로 맞춰줘. +현재 호스트의 Pi를 dev-corp gemma4:26b 기준으로 설치/설정해줘. -범위: -- 수정 가능: ~/.pi/agent/settings.json, ~/.pi/agent/models.json -- 수정 금지: IOP repo 설정, Edge config, Node config, provider runtime, vLLM/vLLM-MLX start script, secret 원문 출력 -- 현재 기준 provider/model: dev-corp / gemma4:26b -- Base URL: http://digitalplatform-iop.cloud:18086/v1 -- Pi API: openai-completions +수정 가능: +- Pi 설치 +- ~/.pi/agent/settings.json +- ~/.pi/agent/models.json -작업 규칙: -1. 먼저 pi --version, ~/.pi/agent/settings.json, ~/.pi/agent/models.json 구조를 확인해. -2. apiKey, authHeader, token, secret 값은 화면에 출력하지 말고 기존 값을 보존해. -3. 편집 전 settings.json과 models.json을 timestamp가 붙은 백업 파일로 복사해. -4. settings.json에는 아래 기준을 반영해: - - defaultProvider: dev-corp - - defaultModel: gemma4:26b - - defaultThinkingLevel: high - - hideThinkingBlock: false - - httpIdleTimeoutMs: 300000 - - retry.provider.timeoutMs: 300000 - - retry.provider.maxRetries: 0 - - retry.provider.maxRetryDelayMs: 60000 - - enabledModels: ["dev-corp-direct/**", "dev-corp-spark01/**", "dev-corp/*"] - - theme, lastChangelogVersion 등 기존 UI/local preference는 보존 -5. models.json의 providers.dev-corp는 아래 기준을 반영해: - - baseUrl: http://digitalplatform-iop.cloud:18086/v1 - - api: openai-completions - - 기존 apiKey/authHeader는 보존 - - compat.supportsStore: false - - compat.supportsDeveloperRole: false - - compat.supportsReasoningEffort: false - - compat.supportsUsageInStreaming: false - - compat.maxTokensField: max_tokens - - compat.requiresToolResultName: true - - compat.requiresAssistantAfterToolResult: true - - compat.supportsStrictMode: false - - model id: gemma4:26b - - model name: dev-corp gemma4:26b - - reasoning: true - - input: ["text"] - - contextWindow: 262144 - - maxTokens: 32768 - - cost input/output/cacheRead/cacheWrite: 0 -6. dev-corp-direct 또는 dev-corp-spark01 provider가 있으면 삭제하지 말고 fallback/실험용으로 보존해. 단 defaultProvider/defaultModel은 dev-corp/gemma4:26b로 둬. -7. supportsReasoningEffort를 true로 바꾸거나 think=false, reasoning_effort=none, thinking_token_budget 강제 설정을 추가하지 마. dev-corp Gemma4 provider-pool은 현재 thinking enabled 기준으로 튜닝되어 있고, reasoning hide는 provider 설정 변경이 아니라 client/UI 처리 문제야. -8. 변경 후 jq로 secret 없이 핵심 값만 출력해서 검증해. +수정 금지: +- 이 저장소 코드와 설정 +- 서버/모델 실행 설정 +- 토큰 원문 출력 -검증 출력에는 apiKey/authHeader 원문을 절대 포함하지 말고, hasApiKey/hasAuthHeader boolean 정도만 보여줘. +설치: +- Node.js >=22.19.0 확인 +- npm install -g @earendil-works/pi-coding-agent@0.80.3 +- pi --version이 0.80.3인지 확인 + +settings.json: +- defaultProvider: dev-corp +- defaultModel: gemma4:26b +- defaultThinkingLevel: high +- hideThinkingBlock: false +- httpIdleTimeoutMs: 300000 +- retry.provider.timeoutMs: 300000 +- retry.provider.maxRetries: 0 +- retry.provider.maxRetryDelayMs: 60000 +- enabledModels: ["dev-corp/*"] + +models.json: +- providers.dev-corp.baseUrl: http://digitalplatform-iop.cloud:18086/v1 +- providers.dev-corp.api: openai-completions +- providers.dev-corp.apiKey: 기존 값이 있으면 보존하고, 없으면 사용자에게 토큰을 요청 +- providers.dev-corp.authHeader: true +- compat.supportsStore: false +- compat.supportsDeveloperRole: false +- compat.supportsReasoningEffort: false +- compat.supportsUsageInStreaming: false +- compat.maxTokensField: max_tokens +- compat.requiresToolResultName: true +- compat.requiresAssistantAfterToolResult: true +- compat.supportsStrictMode: false +- model id: gemma4:26b +- model name: dev-corp gemma4:26b +- reasoning: true +- input: ["text"] +- contextWindow: 262144 +- maxTokens: 32768 + +think=false, reasoning_effort=none, thinking_token_budget 설정은 추가하지 마. +검증 출력에는 apiKey 원문을 포함하지 말고 hasApiKey boolean만 보여줘. ``` - -## 실패 시 되돌리기 - -백업한 파일로 `settings.json`과 `models.json`을 되돌린 뒤 Pi를 다시 실행한다. 실패가 `think=false`, `reasoning_effort`, `thinking_token_budget`, direct provider URL 변경과 관련되어 보이면 해당 변경을 제거하고 dev-corp public Edge route 기준으로 복원한다.