fix(dev-runtime): 배포 검증 실패를 수정한다
원격 macOS에서 빈 prompt 인자가 oneshot CLI에 전달되어 cwd 테스트가 실패했고, app-server cwd 검증은 고정 sleep 레이스에 의존했다. dev 배포가 같은 기준으로 반복되도록 inventory와 capacity smoke 절차도 함께 정리한다.
This commit is contained in:
parent
36d8393a10
commit
a47331f21d
13 changed files with 662 additions and 16 deletions
|
|
@ -94,6 +94,7 @@
|
||||||
|
|
||||||
## 스킬 라우팅
|
## 스킬 라우팅
|
||||||
|
|
||||||
|
- 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`
|
- 사용자 실행 파이프라인 검증, 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`를 따른다.
|
- field 테스트 포트, artifact/bootstrap HTTP, 외부 테스트 환경: `agent-test/local/rules.md`를 따른다.
|
||||||
- bootstrap/install UX, Agent Bootstrap, specialized agent 등록, Control Plane enrollment: `testing` domain rule과 `agent-test/local/rules.md`를 따른다.
|
- bootstrap/install UX, Agent Bootstrap, specialized agent 등록, Control Plane enrollment: `testing` domain rule과 `agent-test/local/rules.md`를 따른다.
|
||||||
|
|
|
||||||
130
agent-ops/skills/project/dev-runtime-deploy/SKILL.md
Normal file
130
agent-ops/skills/project/dev-runtime-deploy/SKILL.md
Normal file
|
|
@ -0,0 +1,130 @@
|
||||||
|
---
|
||||||
|
name: dev-runtime-deploy
|
||||||
|
version: 1.0.0
|
||||||
|
description: dev 배포, dev-runtime 배포, Edge/Node dev 환경 배포 요청에서 clean sync, 전체 테스트, rebuild, 원격 배포, OpenAI-compatible capacity smoke를 수행하는 절차
|
||||||
|
---
|
||||||
|
|
||||||
|
# dev-runtime-deploy
|
||||||
|
|
||||||
|
## 목적
|
||||||
|
|
||||||
|
dev-runtime provider pool을 제품 검증이 끝난 상태로 배포한다. 배포는 원격 checkout 동기화, 전체 테스트, 전체 rebuild, Edge/Node 재시작, provider snapshot 기반 capacity 검증까지 포함한다.
|
||||||
|
|
||||||
|
## 언제 호출할지
|
||||||
|
|
||||||
|
- 사용자가 `dev 배포`, `dev-runtime 배포`, `배포해봐`처럼 dev 환경 배포를 요청할 때
|
||||||
|
- Edge, mac CLI node, GX10 vLLM node, OneXPlayer Lemonade node로 이루어진 dev-runtime provider pool을 갱신할 때
|
||||||
|
- OpenAI-compatible `/v1/responses` 또는 `/v1/chat/completions` 경로가 provider capacity만큼 채워지는지 검증할 때
|
||||||
|
- dev 환경의 remote runner, node 접속 정보, provider capacity, model alias 변경을 배포 절차에 반영할 때
|
||||||
|
|
||||||
|
## 입력
|
||||||
|
|
||||||
|
- `env`: 배포 대상 환경. 기본값은 `dev`이다.
|
||||||
|
- `model`: OpenAI-compatible model alias. 지정하지 않으면 dev 환경 문서의 기준 model을 사용한다.
|
||||||
|
- `capacity_targets`: provider별 기대 capacity. 지정하지 않으면 dev 환경 인벤토리 또는 `agent-test/dev/*` 문서에서 읽는다.
|
||||||
|
- `source_ref`: 배포할 git ref. 지정하지 않으면 원격 runner의 기본 배포 branch 기준을 따른다.
|
||||||
|
|
||||||
|
## 먼저 확인할 것
|
||||||
|
|
||||||
|
- [ ] `agent-ops/rules/project/domain/testing/rules.md`를 읽고 사용자 실행 파이프라인 검증 기준을 확인한다.
|
||||||
|
- [ ] dev 환경은 `agent-test/dev/inventory.yaml`을 먼저 읽는다. 파일이 없으면 `agent-test/dev/rules.md`, `agent-test/dev/edge-smoke.md`, `agent-test/dev/node-smoke.md`로 fallback하고, 구조화 inventory 누락을 보고한다.
|
||||||
|
- [ ] dev-runtime provider pool과 compose/local profile을 섞지 않는다. dev-runtime은 native Edge/Node runtime과 dev-runtime config를 기준으로 한다.
|
||||||
|
- [ ] OneXPlayer SSH 접속 정보는 현재 host 기준 `ssh r0bin@192.168.0.59`이다. `toki` 사용자명 또는 remote runner를 경유한 OneXPlayer 접속을 사용하지 않는다.
|
||||||
|
- [ ] 현재 구현의 completion 검증 대상은 legacy `/v1/completions`가 아니라 `/v1/chat/completions`이다. `/v1/completions`는 route가 구현되어 있을 때만 별도 검증한다.
|
||||||
|
- [ ] token, secret header, bootstrap token, private key 경로는 최종 보고에 원문으로 출력하지 않는다.
|
||||||
|
|
||||||
|
## 실행 절차
|
||||||
|
|
||||||
|
1. **환경 인벤토리 확정**
|
||||||
|
- 배포 대상 runner, repo path, Edge id, Control Plane status URL, OpenAI base URL, Edge admin URL, Node SSH 정보를 문서에서 확정한다.
|
||||||
|
- provider pool 대상 model alias와 provider별 capacity를 확정한다.
|
||||||
|
- 필수 정보가 없거나 서로 충돌하면 배포를 시작하지 말고 누락/충돌 항목을 보고한다.
|
||||||
|
|
||||||
|
2. **원격 checkout clean sync**
|
||||||
|
- 원격 runner checkout에서 `git fetch` 후 배포 기준 ref로 `git reset --hard`를 수행한다.
|
||||||
|
- dirty 파일은 보존 대상으로 보지 않는다. 배포 전 clean 상태를 만든다.
|
||||||
|
- 기본 cleanup은 `git clean -fd`이다. `git clean -fdx`는 config, token, secret, runtime artifact까지 삭제할 수 있으므로 사용하지 않는다.
|
||||||
|
- sync 후 `git status --short --branch`와 `git log --oneline -1`을 기록한다.
|
||||||
|
|
||||||
|
3. **빌드 전 전체 테스트**
|
||||||
|
- clean source 기준으로 `go test ./...`를 실행한다.
|
||||||
|
- client/Flutter, proto, Makefile, script, config 변경이 배포 범위에 포함되면 해당 도메인 규칙의 전체 테스트도 추가한다.
|
||||||
|
- 전체 테스트가 실패하면 build/deploy를 진행하지 않고 실패 패키지와 핵심 오류를 보고한다.
|
||||||
|
|
||||||
|
4. **전체 rebuild**
|
||||||
|
- 같은 source ref에서 dev-runtime Edge binary, mac node binary, Linux ARM64 node binary, Windows AMD64 node binary를 모두 다시 빌드한다.
|
||||||
|
- stale binary가 의심되거나 `config refresh` subcommand, admin port, version 출력이 맞지 않으면 clean sync부터 다시 시작한다.
|
||||||
|
- 빌드 산출물 경로, timestamp, 크기, 실행 가능 여부를 기록한다.
|
||||||
|
|
||||||
|
5. **빌드 후 기본 동작 테스트**
|
||||||
|
- 빌드된 Edge binary로 `config check`, `config refresh --help`, `config refresh --mode dry-run`을 실행한다.
|
||||||
|
- 빌드 후에도 `go test ./...`를 실행한다. 실행하지 못하면 사유와 남은 위험을 보고한다.
|
||||||
|
- dry-run이 `rejected` 또는 예상 밖 `restart_required`를 반환하면 배포를 멈추고 config diff를 보고한다.
|
||||||
|
|
||||||
|
6. **배포와 재시작**
|
||||||
|
- Edge와 mac CLI node는 원격 runner에서 빌드 산출물 기준으로 재시작한다.
|
||||||
|
- GX10 node는 Linux ARM64 node binary를 배포하고 기존 node process를 재시작한다.
|
||||||
|
- OneXPlayer node는 현재 host에서 `ssh r0bin@192.168.0.59`로 접속한다. artifact가 remote runner에 있으면 현재 host를 통해 전달한 뒤 Windows host에서 교체한다.
|
||||||
|
- OneXPlayer에서는 SSH 세션 안의 `Start-Process`로 장기 실행을 시작하지 않는다. `Win32_Process.Create` 또는 동등한 세션 독립 실행 방식으로 `iop-node.exe --config node.yaml serve`를 시작한다.
|
||||||
|
|
||||||
|
7. **배포 후 연결 검증**
|
||||||
|
- Edge, OpenAI-compatible listener, Node TCP, admin port, Control Plane status port가 열려 있는지 확인한다.
|
||||||
|
- Control Plane status에서 Edge가 connected이고 dev-runtime 기준 3개 node가 connected인지 확인한다.
|
||||||
|
- 각 node의 `provider_snapshots`에서 provider `id`, `capacity`, `in_flight`, `queued`, `health`, `served_models`를 확인한다.
|
||||||
|
- `/v1/models`가 대상 model alias를 노출하는지 확인한다.
|
||||||
|
|
||||||
|
8. **OpenAI-compatible capacity smoke**
|
||||||
|
- `/v1/responses`와 `/v1/chat/completions`를 각각 검증한다. legacy `/v1/completions`는 구현되어 있지 않으면 실패로 보지 않는다.
|
||||||
|
- 표준 부하 프롬프트는 짧은 토큰 응답을 요구하지 않는다. 700~1200 token 수준의 구조화된 답변을 유도해 요청이 동시에 관측될 시간을 만든다.
|
||||||
|
- endpoint별로 총 provider capacity + 1개 요청을 동시에 보낸다. 예: capacity가 `4 + 3 = 7`이면 8개 동시 호출을 보낸다.
|
||||||
|
- 환경 문서에 더 작은 aggregate smoke 기준이 남아 있더라도, 배포 완료 판정은 이 capacity+1 기준을 우선한다.
|
||||||
|
- 요청 실행 중 Control Plane status를 반복 polling하여 대상 provider들의 `in_flight` 합이 총 capacity에 도달하고 `queued` 합이 1 이상이 되는 순간을 증거로 남긴다.
|
||||||
|
- 각 provider의 `in_flight`가 자기 capacity를 넘지 않고, 적어도 한 번은 기대 capacity까지 차는지 확인한다.
|
||||||
|
- 모든 요청 완료 후 같은 status에서 대상 provider들의 `in_flight=0`, `queued=0`으로 돌아오는지 확인한다.
|
||||||
|
- Qwen 계열 reasoning/thinking 텍스트는 정상 응답으로 허용한다. exact-output match를 smoke 성공 기준으로 삼지 않는다.
|
||||||
|
|
||||||
|
9. **결과 보고**
|
||||||
|
- source ref, clean sync 결과, 테스트 결과, 빌드 산출물, process/port 상태, connected node 목록, provider capacity snapshot, capacity smoke 관측값을 보고한다.
|
||||||
|
- 실패한 단계가 있으면 다음 단계를 진행했는지 여부를 명확히 구분한다.
|
||||||
|
- capacity smoke가 타이밍 문제로 관측 실패했으면 요청 성공과 별도로 `capacity 관측 미충족`으로 보고하고, 프롬프트 길이 또는 status polling 간격 조정을 제안한다.
|
||||||
|
|
||||||
|
## 실행 결과 검증
|
||||||
|
|
||||||
|
- [ ] 원격 runner checkout이 배포 기준 ref로 clean sync되었는가
|
||||||
|
- [ ] 빌드 전 `go test ./...`와 필요한 추가 전체 테스트가 통과했는가
|
||||||
|
- [ ] dev-runtime Edge/mac/Linux ARM64/Windows AMD64 binary가 같은 source ref에서 rebuild되었는가
|
||||||
|
- [ ] 빌드 후 config check, refresh help, refresh dry-run, 전체 테스트가 통과했는가
|
||||||
|
- [ ] Edge, mac CLI node, GX10 vLLM node, OneXPlayer Lemonade node가 재시작되고 3개 node가 connected 상태인가
|
||||||
|
- [ ] OneXPlayer 접속과 실행이 `r0bin@192.168.0.59` 및 세션 독립 실행 방식으로 수행되었는가
|
||||||
|
- [ ] `/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, 진행 중단 여부를 보고한다.
|
||||||
|
|
||||||
|
## 출력 형식
|
||||||
|
|
||||||
|
```text
|
||||||
|
dev-runtime 배포 결과
|
||||||
|
- Source: <branch/ref/commit>, clean=<yes|no>
|
||||||
|
- Pre-build tests: <command> - <pass|fail|not-run>
|
||||||
|
- Build: edge=<path>, mac-node=<path>, linux-arm64-node=<path>, windows-amd64-node=<path>
|
||||||
|
- Post-build checks: config-check=<pass|fail>, refresh-help=<pass|fail>, refresh-dry-run=<status>, tests=<pass|fail|not-run>
|
||||||
|
- Deployment: edge=<pid/status>, mac-node=<pid/status>, gx10=<pid/status>, onexplayer=<pid/status>
|
||||||
|
- Ports: <port summary>
|
||||||
|
- Nodes: <node_id connected summary>
|
||||||
|
- Providers: <provider_id capacity/in_flight/queued/health summary>
|
||||||
|
- OpenAI-compatible: models=<pass|fail>, responses-capacity=<pass|fail>, chat-completions-capacity=<pass|fail>
|
||||||
|
- Capacity evidence: <endpoint별 max in_flight/queued snapshot>
|
||||||
|
- Blockers/Risk: <없음 또는 내용>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 금지 사항
|
||||||
|
|
||||||
|
- dirty checkout이나 stale binary를 그대로 배포하지 않는다.
|
||||||
|
- `git clean -fdx`를 기본 cleanup으로 사용하지 않는다.
|
||||||
|
- 빌드 전 전체 테스트 실패 후 배포를 계속하지 않는다.
|
||||||
|
- OneXPlayer에 `toki` 사용자명으로 접속하거나 remote runner에서 다시 OneXPlayer로 SSH 접속하지 않는다.
|
||||||
|
- OneXPlayer 장기 실행을 Windows OpenSSH 세션 내부 `Start-Process`에 의존하지 않는다.
|
||||||
|
- Qwen reasoning/thinking 출력을 실패로 판정하거나 exact-output smoke를 기본 성공 기준으로 삼지 않는다.
|
||||||
|
- OpenAI-compatible 요청 성공만으로 capacity 검증 성공을 선언하지 않는다. provider snapshot의 `in_flight/queued` 관측을 함께 남긴다.
|
||||||
|
- 이 프로젝트 전용 배포 절차를 `agent-ops/rules/common/_templates` 또는 common skill에 넣지 않는다.
|
||||||
56
agent-test/README.md
Normal file
56
agent-test/README.md
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
# agent-test 환경 확장 기준
|
||||||
|
|
||||||
|
이 디렉터리는 테스트 환경별 실행 기준과 도메인/검증 시나리오별 profile을 둔다.
|
||||||
|
새 환경(`qa`, `staging`, `dev-gpu`, `dev-team-a` 등)을 추가할 때는 기존 환경을 임의로 복사하지 말고 이 기준과 `_templates/`를 먼저 따른다.
|
||||||
|
|
||||||
|
## 환경 디렉터리
|
||||||
|
|
||||||
|
- 환경 디렉터리는 `agent-test/<env>/` 형식을 사용한다.
|
||||||
|
- `<env>`는 소문자 영문, 숫자, 하이픈만 사용한다.
|
||||||
|
- 각 환경에는 반드시 `agent-test/<env>/rules.md`를 둔다.
|
||||||
|
- 도메인/검증 시나리오별 문서는 `agent-test/<env>/<test-profile>.md` 형식을 사용한다.
|
||||||
|
- 기본 도메인 smoke profile은 기존 도메인 이름을 유지해 `node-smoke.md`, `edge-smoke.md`, `control-plane-smoke.md`, `client-smoke.md`, `platform-common-smoke.md`, `testing-smoke.md`처럼 둔다.
|
||||||
|
|
||||||
|
## rules.md 표준 섹션
|
||||||
|
|
||||||
|
새 `rules.md`는 아래 섹션 순서를 유지한다.
|
||||||
|
|
||||||
|
1. `공통 규칙`
|
||||||
|
2. `기본 환경`
|
||||||
|
3. `포트 매핑`
|
||||||
|
4. `런타임 프로필`
|
||||||
|
5. `프리플라이트`
|
||||||
|
6. `노드/Provider 인벤토리 위치`
|
||||||
|
7. `Field/bootstrap 반복 테스트 기준`
|
||||||
|
8. `라우팅`
|
||||||
|
9. `라우팅 규칙`
|
||||||
|
|
||||||
|
섹션이 해당 환경에 직접 필요하지 않더라도 삭제하지 말고 `없음`, `해당 없음`, 또는 대상 profile 링크를 남긴다.
|
||||||
|
|
||||||
|
## 확장 원칙
|
||||||
|
|
||||||
|
- 환경 공통값은 `rules.md`에 둔다.
|
||||||
|
- 실제 노드, provider, bootstrap, model endpoint, workspace, SSH user/IP 같은 상세 인벤토리는 agent가 구조적으로 읽어야 하면 `inventory.yaml`에 두고, 사람용 설명과 도메인별 판정 기준은 해당 도메인 profile에 둔다.
|
||||||
|
- 상위 `rules.md`에는 상세값을 복제하지 말고 `노드/Provider 인벤토리 위치`와 `라우팅`으로 연결한다.
|
||||||
|
- compose, native Edge, dev-runtime provider pool처럼 같은 환경 안의 실행 모드는 `런타임 프로필`에서 분리한다.
|
||||||
|
- 같은 포트 이름은 모든 환경에서 같은 행 이름을 쓴다. 값이 없으면 `해당 없음` 또는 `후보 <port>`로 둔다.
|
||||||
|
- shared remote runner를 쓰는 환경은 `repo root`, `sync 기준`, `프리플라이트`를 반드시 명시한다.
|
||||||
|
- secret, token, API key, private credential 원문은 `agent-test/`, `docs/`, `agent-roadmap/`에 기록하지 않는다.
|
||||||
|
- private IP와 SSH user는 테스트 접속에 필요한 환경값이면 기록할 수 있다. 단, 잘못된 user가 발견되면 해당 env rules/profile과 사람용 guide를 함께 정정한다.
|
||||||
|
- `agent-test/local/`은 local/private 기준이라 git 추적 제외될 수 있다. 추적 여부와 상관없이 현재 workspace의 운영 기준으로는 같은 구조를 유지한다.
|
||||||
|
|
||||||
|
## 새 환경 추가 절차
|
||||||
|
|
||||||
|
1. `_templates/env-rules-template.md`를 `agent-test/<env>/rules.md`로 복사한다.
|
||||||
|
2. `<env>`, 날짜, runner, repo root, 포트, runtime profile을 채운다.
|
||||||
|
3. agent가 반복해서 읽어야 하는 host/node/provider 값이 있으면 `_templates/inventory-template.yaml`을 사용해 `agent-test/<env>/inventory.yaml`을 만든다.
|
||||||
|
4. 기존 도메인 smoke profile이 필요하면 `_templates/test-profile-template.md`를 사용해 `agent-test/<env>/<domain>-smoke.md`를 만든다.
|
||||||
|
5. `rules.md`의 `노드/Provider 인벤토리 위치`와 `라우팅`에 생성한 inventory와 profile을 연결한다.
|
||||||
|
6. remote runner나 external provider를 쓰면 `프리플라이트`에 확인할 항목을 구체화한다.
|
||||||
|
7. local/test/dev 등 기존 환경과 공존해야 하면 `포트 매핑`에 충돌하지 않는 값을 기록한다.
|
||||||
|
8. `rg --no-ignore`로 잘못된 SSH user, workspace, port 재사용, secret 원문이 없는지 확인한다.
|
||||||
|
|
||||||
|
## 현재 표준 구현
|
||||||
|
|
||||||
|
- `agent-test/local/rules.md`
|
||||||
|
- `agent-test/dev/rules.md`
|
||||||
101
agent-test/_templates/env-rules-template.md
Normal file
101
agent-test/_templates/env-rules-template.md
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
---
|
||||||
|
test_env: <env>
|
||||||
|
last_rule_updated_at: <YYYY-MM-DD>
|
||||||
|
---
|
||||||
|
|
||||||
|
# <env> 테스트 규칙
|
||||||
|
|
||||||
|
**현재 문서를 반드시 끝까지 정독하고 작업한다. 다 읽지 않고 즉각 작업은 금지한다.**
|
||||||
|
**<env> 테스트 환경의 핵심 실행 모드와 local/dev/qa 등 다른 환경과의 공존 기준을 이 문서에 둔다.**
|
||||||
|
|
||||||
|
## 공통 규칙
|
||||||
|
|
||||||
|
- <env> 테스트/검증은 이 파일을 기준으로 판단한다.
|
||||||
|
- 작업 완료 검증은 변경 범위 기준으로 선택한다.
|
||||||
|
- 필수 검증을 실행하지 못하면 차단 사유로 보고한다.
|
||||||
|
- 최종 보고에는 실행 명령, 결과, 생략 사유, 남은 위험을 남긴다.
|
||||||
|
- 환경값, secret, 개인 endpoint는 tracked docs/roadmap에 쓰지 않는다.
|
||||||
|
- token/secret 원문은 원격 환경에서 주입하고, shell stdout/stderr와 최종 보고에 출력하지 않는다.
|
||||||
|
- 테스트용 Docker 환경을 작성/수정할 때는 Docker Compose `networks`, IPAM subnet, static IPv4, `extra_hosts`, host publish 문서 어디에도 host LAN/VPN과 충돌하는 대역을 사용하지 않는다.
|
||||||
|
|
||||||
|
## 기본 환경
|
||||||
|
|
||||||
|
- host: <기본 실행 host 또는 runner SSH>
|
||||||
|
- repo root: <원격/로컬 repo root>
|
||||||
|
- sync 기준: <source sync 판단 기준>
|
||||||
|
- env file: <compose/env file 기준 또는 해당 없음>
|
||||||
|
- compose identity: <COMPOSE_PROJECT_NAME / network 또는 해당 없음>
|
||||||
|
- port: <핵심 포트 요약>
|
||||||
|
- optional field ports: <선택 포트 또는 해당 없음>
|
||||||
|
- runtime: <Go/Flutter/Docker/외부 runtime>
|
||||||
|
- package manager: <Go modules / Makefile / Flutter pub 등>
|
||||||
|
- docker: <Docker 사용 기준>
|
||||||
|
- external service: <외부 서비스 URL/host 요약>
|
||||||
|
- model endpoint: <OpenAI-compatible 등 모델 endpoint>
|
||||||
|
- credential: secret/token/API key 원문은 문서에 기록하지 않는다.
|
||||||
|
|
||||||
|
## 포트 매핑
|
||||||
|
|
||||||
|
| 용도 | local/test | dev | <env> |
|
||||||
|
|---|---:|---:|---:|
|
||||||
|
| Web preview | `13000-13099` | `13001` | `<port 또는 해당 없음>` |
|
||||||
|
| Control Plane HTTP | `18000` | `18001` | `<port 또는 해당 없음>` |
|
||||||
|
| CP Client WS | `19080` | `19001` | `<port 또는 해당 없음>` |
|
||||||
|
| CP-Edge wire | `19081` | `19002` | `<port 또는 해당 없음>` |
|
||||||
|
| Edge-Node TCP | `19090` | `19003` | `<port 또는 해당 없음>` |
|
||||||
|
| Edge artifact/bootstrap | `18080` | `18082` | `<port 또는 해당 없음>` |
|
||||||
|
| Edge OpenAI-compatible | `18081` | `18083` | `<port 또는 해당 없음>` |
|
||||||
|
| Edge metrics | `19092` | `19101` | `<port 또는 해당 없음>` |
|
||||||
|
| PostgreSQL host publish | `15400` | `15401` | `<port 또는 해당 없음>` |
|
||||||
|
| Redis host publish | `16300` | `16301` | `<port 또는 해당 없음>` |
|
||||||
|
|
||||||
|
<환경 안에서 compose/native/dev-runtime처럼 Edge-Node TCP가 갈라지면 여기에 명시한다.>
|
||||||
|
|
||||||
|
## 런타임 프로필
|
||||||
|
|
||||||
|
- local quick check: 현재 checkout에서 가능한 quick check를 우선 실행한다.
|
||||||
|
- remote runner: <SSH, repo root, 어떤 evidence에 쓰는지>
|
||||||
|
- compose <env> stack: <compose file/env file/project/network/주요 포트>
|
||||||
|
- native/direct Edge profile: <필요 시 artifact/openai/metrics/edge-node 포트>
|
||||||
|
- provider pool profile: <필요 시 config path, model alias, Edge-Node TCP>
|
||||||
|
- external provider field: <필요 시 SSH/user/IP/provider endpoint>
|
||||||
|
|
||||||
|
## 프리플라이트
|
||||||
|
|
||||||
|
- plan 작성 시 필수 검증이 현재 checkout을 벗어나 원격 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 가정을 포함한다.
|
||||||
|
- 프리플라이트에서 dirty/divergent checkout, stale artifact, 잘못된 identity, missing command, closed port, host OS 불일치, source 미동기화가 확인되면 plan은 먼저 setup/sync/rebuild 단계를 만들거나 blocker로 보고한다. remote deploy 환경에서 dirty 변경을 보존하지 않는 정책이면 배포 전 clean sync와 rebuild를 기본 단계로 둔다. profile 값을 이미 참이라고 가정한 검증 명령만 쓰지 않는다.
|
||||||
|
|
||||||
|
## 노드/Provider 인벤토리 위치
|
||||||
|
|
||||||
|
- machine-readable 인벤토리 기준: `agent-test/<env>/inventory.yaml` 또는 `해당 없음`
|
||||||
|
- Edge/OpenAI-compatible 입력 표면 상세 기준: `agent-test/<env>/edge-smoke.md`
|
||||||
|
- Node 접속과 bootstrap 상세 기준: `agent-test/<env>/node-smoke.md`
|
||||||
|
- 공통 provider config 계약 기준: `agent-test/<env>/platform-common-smoke.md`
|
||||||
|
- compose stack 기준: `agent-test/<env>/control-plane-smoke.md`, `agent-test/<env>/client-smoke.md`, `agent-test/<env>/testing-smoke.md`
|
||||||
|
|
||||||
|
## Field/bootstrap 반복 테스트 기준
|
||||||
|
|
||||||
|
- field/bootstrap 검증은 이 환경의 runner, checkout, artifact 기준으로 수행한다. 세부 Edge/Node profile은 해당 env의 `edge-smoke.md`와 `node-smoke.md`를 따른다.
|
||||||
|
- compose stack과 native/provider-pool profile이 서로 다른 Edge-Node TCP를 쓰면 두 프로필을 섞어서 판정하지 않는다.
|
||||||
|
- Node bootstrap은 Edge의 `node register`가 출력한 OS별 완성 명령을 그대로 사용한다. 사용자에게 안내하는 명령에는 임의 placeholder, 수동 token 치환, `IOP_*=` named environment parameter를 넣지 않는다.
|
||||||
|
- token, API key, private credential 원문은 tracked docs, roadmap, 테스트 규칙에 기록하지 않는다. 실행 증거에는 token을 마스킹하거나 명령 생성 사실만 남긴다.
|
||||||
|
- Linux/macOS Node는 생성된 `curl | bash` 계열 명령을 사용한다. Windows Node는 native PowerShell bootstrap을 기본으로 사용한다.
|
||||||
|
- provider capacity, model/provider mapping의 live apply는 해당 Edge binary가 `config refresh`를 제공하는 경우에만 사용한다. refresh 지원이 필요한 환경에서 subcommand나 admin port가 없으면 stale binary로 보고 clean sync/rebuild를 먼저 수행한다.
|
||||||
|
- Edge process restart 또는 일시 단절 후에는 Node reconnect 정책을 검증한다. retry 한계를 넘겨 Node process가 종료된 경우에만 해당 Node host에서 새 bootstrap 실행이 필요하다.
|
||||||
|
|
||||||
|
## 라우팅
|
||||||
|
|
||||||
|
- node / smoke / node 실행 파이프라인 baseline: `agent-test/<env>/node-smoke.md`
|
||||||
|
- edge / smoke / edge 실행 그룹과 입력 표면 baseline: `agent-test/<env>/edge-smoke.md`
|
||||||
|
- control-plane / smoke / control-plane health와 wire baseline: `agent-test/<env>/control-plane-smoke.md`
|
||||||
|
- client / smoke / Flutter client와 IOP console package baseline: `agent-test/<env>/client-smoke.md`
|
||||||
|
- platform-common / smoke / 공통 설정과 protobuf 계약 baseline: `agent-test/<env>/platform-common-smoke.md`
|
||||||
|
- testing / smoke / 테스트 도구와 full-cycle 검증 baseline: `agent-test/<env>/testing-smoke.md`
|
||||||
|
|
||||||
|
## 라우팅 규칙
|
||||||
|
|
||||||
|
- 여러 항목이 맞으면 모두 읽는다.
|
||||||
|
- 도메인 매핑이나 domain rule이 있으면 각 도메인의 `<domain>-smoke` 문서를 기본 baseline으로 둔다.
|
||||||
|
- 도메인이 아직 없을 때만 `project-smoke`를 fallback baseline으로 둔다.
|
||||||
|
- 도메인/검증 시나리오별 문서는 다른 테스트 문서로 라우팅하지 않는다.
|
||||||
57
agent-test/_templates/inventory-template.yaml
Normal file
57
agent-test/_templates/inventory-template.yaml
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
test_env: <env>
|
||||||
|
profile: <profile-name>
|
||||||
|
last_updated_at: <YYYY-MM-DD>
|
||||||
|
|
||||||
|
source:
|
||||||
|
remote_runner:
|
||||||
|
ssh: <user@host 또는 해당 없음>
|
||||||
|
repo_root: <repo root 또는 해당 없음>
|
||||||
|
clean_sync:
|
||||||
|
- <sync command 또는 해당 없음>
|
||||||
|
dirty_policy: <preserve|discard|manual-review>
|
||||||
|
|
||||||
|
edge:
|
||||||
|
id: <edge-id 또는 해당 없음>
|
||||||
|
config_path: <edge config path 또는 해당 없음>
|
||||||
|
control_plane_http: <url 또는 해당 없음>
|
||||||
|
control_plane_status_url: <url 또는 해당 없음>
|
||||||
|
bootstrap_http_public: <url 또는 해당 없음>
|
||||||
|
openai_base_url_public: <url 또는 해당 없음>
|
||||||
|
openai_base_url_runner: <url 또는 해당 없음>
|
||||||
|
edge_node_tcp_public: <host:port 또는 해당 없음>
|
||||||
|
admin_addr_runner: <host:port 또는 해당 없음>
|
||||||
|
|
||||||
|
build:
|
||||||
|
binaries:
|
||||||
|
edge: <path 또는 해당 없음>
|
||||||
|
node_macos: <path 또는 해당 없음>
|
||||||
|
node_linux_arm64: <path 또는 해당 없음>
|
||||||
|
node_windows_amd64: <path 또는 해당 없음>
|
||||||
|
|
||||||
|
model:
|
||||||
|
alias: <model alias 또는 해당 없음>
|
||||||
|
provider_capacity_total: <number 또는 0>
|
||||||
|
capacity_smoke:
|
||||||
|
endpoints:
|
||||||
|
- /v1/responses
|
||||||
|
- /v1/chat/completions
|
||||||
|
concurrent_requests: capacity_plus_one
|
||||||
|
expected_total_in_flight: <number 또는 0>
|
||||||
|
expected_min_queued: 1
|
||||||
|
prompt_policy: long_reasoning_allowed
|
||||||
|
exact_output_match: false
|
||||||
|
|
||||||
|
nodes:
|
||||||
|
- id: <node-id>
|
||||||
|
alias: <node-alias>
|
||||||
|
role: <role>
|
||||||
|
ssh: <user@host 또는 해당 없음>
|
||||||
|
ssh_origin: <current_host|remote_runner|not_applicable>
|
||||||
|
workspace: <path 또는 해당 없음>
|
||||||
|
provider_pool_candidate: <true|false>
|
||||||
|
provider:
|
||||||
|
id: <provider-id 또는 해당 없음>
|
||||||
|
type: <provider type 또는 해당 없음>
|
||||||
|
endpoint: <url 또는 해당 없음>
|
||||||
|
served_model: <served model 또는 해당 없음>
|
||||||
|
capacity: <number 또는 0>
|
||||||
79
agent-test/_templates/test-profile-template.md
Normal file
79
agent-test/_templates/test-profile-template.md
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
---
|
||||||
|
test_env: <env>
|
||||||
|
test_profile: <test-profile>
|
||||||
|
domain: <domain|project-wide>
|
||||||
|
verification_type: <smoke|unit|integration|e2e|model|migration|manual|full-cycle>
|
||||||
|
last_rule_updated_at: <YYYY-MM-DD>
|
||||||
|
---
|
||||||
|
|
||||||
|
# <test-profile> <env> 테스트
|
||||||
|
|
||||||
|
## 읽기 조건
|
||||||
|
|
||||||
|
- <이 도메인/검증 시나리오의 테스트, 검증, 실행 조건 판단이 필요한 경우>
|
||||||
|
|
||||||
|
## 적용 범위
|
||||||
|
|
||||||
|
- <검증 대상 entrypoint, command, API, UX, profile, service>
|
||||||
|
|
||||||
|
## 분류
|
||||||
|
|
||||||
|
- domain: <domain|project-wide>
|
||||||
|
- verification_type: <smoke|unit|integration|e2e|model|migration|manual|full-cycle>
|
||||||
|
- scope: <검증 대상 변경 범위 요약>
|
||||||
|
|
||||||
|
## 환경
|
||||||
|
|
||||||
|
- host:
|
||||||
|
- port:
|
||||||
|
- runtime:
|
||||||
|
- package manager:
|
||||||
|
- docker:
|
||||||
|
- external service:
|
||||||
|
- model endpoint:
|
||||||
|
- credential: secret/token/API key 원문은 문서에 기록하지 않는다.
|
||||||
|
|
||||||
|
## 명령
|
||||||
|
|
||||||
|
- setup:
|
||||||
|
- lint:
|
||||||
|
- unit:
|
||||||
|
- smoke:
|
||||||
|
- e2e:
|
||||||
|
- model:
|
||||||
|
- full-cycle:
|
||||||
|
|
||||||
|
## 필수 검증
|
||||||
|
|
||||||
|
- <작업 완료 전 반드시 실행하거나 판단해야 하는 검증>
|
||||||
|
|
||||||
|
## 보조 검증
|
||||||
|
|
||||||
|
- <실행하면 좋지만 필수 검증을 대체하지 않는 smoke/helper 검증>
|
||||||
|
|
||||||
|
## 판정 기준
|
||||||
|
|
||||||
|
- <통과로 판단할 출력, 상태, UX, artifact, endpoint 조건>
|
||||||
|
|
||||||
|
## 기준 출력 예시
|
||||||
|
|
||||||
|
```text
|
||||||
|
<필요한 경우 기대 출력 예시>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 차단 기준
|
||||||
|
|
||||||
|
- <테스트를 계속할 수 없는 환경/권한/도구/서비스 조건>
|
||||||
|
|
||||||
|
## 보고 항목
|
||||||
|
|
||||||
|
- 실행한 명령:
|
||||||
|
- 성공한 검증:
|
||||||
|
- 실패/차단된 검증:
|
||||||
|
- 생략 사유:
|
||||||
|
- 남은 위험:
|
||||||
|
|
||||||
|
## 금지 사항
|
||||||
|
|
||||||
|
- secret, token, 개인 endpoint 원문은 tracked 파일에 기록하지 않는다.
|
||||||
|
|
||||||
|
|
@ -3,7 +3,7 @@ test_env: dev
|
||||||
test_profile: edge-smoke
|
test_profile: edge-smoke
|
||||||
domain: edge
|
domain: edge
|
||||||
verification_type: smoke
|
verification_type: smoke
|
||||||
last_rule_updated_at: 2026-06-12
|
last_rule_updated_at: 2026-06-24
|
||||||
---
|
---
|
||||||
|
|
||||||
# edge-smoke dev 테스트
|
# edge-smoke dev 테스트
|
||||||
|
|
@ -41,6 +41,40 @@ last_rule_updated_at: 2026-06-12
|
||||||
- model endpoint: dev OpenAI-compatible base URL 후보 `http://toki-labs.com:18083/v1`
|
- model endpoint: dev OpenAI-compatible base URL 후보 `http://toki-labs.com:18083/v1`
|
||||||
- credential: token/secret 원문은 문서에 기록하지 않는다.
|
- credential: token/secret 원문은 문서에 기록하지 않는다.
|
||||||
|
|
||||||
|
## dev-runtime provider pool 인벤토리
|
||||||
|
|
||||||
|
dev-runtime provider pool과 3-node 연결 상태를 점검할 때는 `agent-test/dev/inventory.yaml`의 machine-readable 값을 우선하고, 원격 runner `ssh toki@toki-labs.com`의 `/Users/toki/agent-work/iop-dev` checkout을 기준으로 한다.
|
||||||
|
|
||||||
|
- Edge config: `build/dev-runtime/edge.yaml`
|
||||||
|
- Edge id: `edge-toki-labs-dev`
|
||||||
|
- Control Plane HTTP: `http://127.0.0.1:18001`
|
||||||
|
- bootstrap HTTP: `http://toki-labs.com:18082`
|
||||||
|
- Edge OpenAI-compatible base URL: `http://toki-labs.com:18083/v1`
|
||||||
|
- Edge-Node TCP transport: `toki-labs.com:18084`
|
||||||
|
- model alias: `qwen3.6:35b`
|
||||||
|
|
||||||
|
노드 후보:
|
||||||
|
|
||||||
|
- mac CLI node: `mac-codex-node` / `mac-codex`
|
||||||
|
- SSH/user: `ssh toki@toki-labs.com`
|
||||||
|
- 목적: `cli` adapter, `codex app-server`
|
||||||
|
- workspace: `/Users/toki/agent-work/iop-workspace/nomadcode`
|
||||||
|
- GX10 vLLM node: `gx10-vllm-node` / `gx10-vllm`
|
||||||
|
- SSH/user: `ssh toki@192.168.0.91`
|
||||||
|
- provider endpoint: `http://192.168.0.91:8001/v1`
|
||||||
|
- served model: `nvidia/Qwen3.6-35B-A3B-NVFP4`
|
||||||
|
- capacity baseline: `4`
|
||||||
|
- workspace: `/home/toki/iop-gx10-vllm`
|
||||||
|
- OneXPlayer Lemonade node: `onexplayer-lemonade-node` / `onexplayer-lemonade`
|
||||||
|
- SSH/user: `ssh r0bin@192.168.0.59`
|
||||||
|
- 접속 기준: 현재 작업 호스트에서 직접 SSH
|
||||||
|
- provider endpoint: `http://192.168.0.59:13305/v1`
|
||||||
|
- served model: `Qwen3.6-35B-A3B-MTP-GGUF`
|
||||||
|
- capacity baseline: `3`
|
||||||
|
- workspace: `C:/Users/r0bin/iop-field`
|
||||||
|
|
||||||
|
OneXPlayer Lemonade Node는 원격 runner나 Edge host에서 다시 SSH하거나 proxy process로 띄우지 않는다. 현재 작업 호스트에서 OneXPlayer Windows host에 `ssh r0bin@192.168.0.59`로 직접 접속한 뒤 generated PowerShell bootstrap을 실행한다.
|
||||||
|
|
||||||
## 명령
|
## 명령
|
||||||
|
|
||||||
- setup:
|
- setup:
|
||||||
|
|
@ -69,6 +103,9 @@ last_rule_updated_at: 2026-06-12
|
||||||
- node 로컬 `[node-message]` payload 라인 목록과 edge `[node-*-message]` payload 라인 목록이 run별로 내용/순서까지 동일해야 한다.
|
- node 로컬 `[node-message]` payload 라인 목록과 edge `[node-*-message]` payload 라인 목록이 run별로 내용/순서까지 동일해야 한다.
|
||||||
- edge complete는 같은 run의 마지막 `[node-*-message]` 이후에만 정상이다.
|
- edge complete는 같은 run의 마지막 `[node-*-message]` 이후에만 정상이다.
|
||||||
- OpenAI-compatible smoke에서 `/healthz`, `/v1/models`, `/v1/responses`가 기대 상태로 응답한다.
|
- OpenAI-compatible smoke에서 `/healthz`, `/v1/models`, `/v1/responses`가 기대 상태로 응답한다.
|
||||||
|
- dev-runtime capacity smoke는 `/v1/responses`와 `/v1/chat/completions` 각각에 provider capacity 총합 + 1개 동시 요청을 보내고, Control Plane status의 `provider_snapshots`에서 총 `in_flight`가 capacity 총합에 도달하며 `queued`가 1 이상 잡히는지 확인한다. 현재 `gx10-vllm=4`, `onexplayer-lemonade=3`이면 endpoint별 8개 동시 요청에서 총 `in_flight=7`, `queued>=1` 관측을 기준으로 한다.
|
||||||
|
- capacity smoke 완료 후 대상 provider의 `in_flight=0`, `queued=0` 회복을 확인한다.
|
||||||
|
- Qwen 계열 provider-pool smoke는 thinking/reasoning 텍스트가 포함될 수 있다. 추론 출력 자체를 실패로 보지 말고 HTTP 성공, model alias, final marker 포함 여부, provider node log/run count 증가로 판정한다. 응답 전체가 특정 token과 정확히 같은지 비교하는 strict exact-match는 이 profile의 기본 판정으로 쓰지 않는다.
|
||||||
- bootstrap 사용자 명령은 완성된 URL과 positional token 하나만 포함한다.
|
- bootstrap 사용자 명령은 완성된 URL과 positional token 하나만 포함한다.
|
||||||
|
|
||||||
## 기준 출력 예시
|
## 기준 출력 예시
|
||||||
|
|
|
||||||
80
agent-test/dev/inventory.yaml
Normal file
80
agent-test/dev/inventory.yaml
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
test_env: dev
|
||||||
|
profile: dev-runtime-provider-pool
|
||||||
|
last_updated_at: "2026-06-24"
|
||||||
|
|
||||||
|
source:
|
||||||
|
remote_runner:
|
||||||
|
ssh: toki@toki-labs.com
|
||||||
|
repo_root: /Users/toki/agent-work/iop-dev
|
||||||
|
clean_sync:
|
||||||
|
- git fetch origin main
|
||||||
|
- git reset --hard origin/main
|
||||||
|
- git clean -fd
|
||||||
|
dirty_policy: discard
|
||||||
|
|
||||||
|
edge:
|
||||||
|
id: edge-toki-labs-dev
|
||||||
|
config_path: build/dev-runtime/edge.yaml
|
||||||
|
control_plane_http: http://127.0.0.1:18001
|
||||||
|
control_plane_status_url: http://127.0.0.1:18001/edges/edge-toki-labs-dev/status
|
||||||
|
bootstrap_http_public: http://toki-labs.com:18082
|
||||||
|
openai_base_url_public: http://toki-labs.com:18083/v1
|
||||||
|
openai_base_url_runner: http://127.0.0.1:18083/v1
|
||||||
|
edge_node_tcp_public: toki-labs.com:18084
|
||||||
|
admin_addr_runner: 127.0.0.1:19093
|
||||||
|
|
||||||
|
build:
|
||||||
|
binaries:
|
||||||
|
edge: build/dev-runtime/bin/edge
|
||||||
|
node_macos: build/dev-runtime/bin/iop-node
|
||||||
|
node_linux_arm64: build/dev-runtime/bin/iop-node-linux-arm64
|
||||||
|
node_windows_amd64: build/dev-runtime/bin/iop-node-windows-amd64.exe
|
||||||
|
|
||||||
|
model:
|
||||||
|
alias: qwen3.6:35b
|
||||||
|
provider_capacity_total: 7
|
||||||
|
capacity_smoke:
|
||||||
|
endpoints:
|
||||||
|
- /v1/responses
|
||||||
|
- /v1/chat/completions
|
||||||
|
concurrent_requests: capacity_plus_one
|
||||||
|
expected_total_in_flight: 7
|
||||||
|
expected_min_queued: 1
|
||||||
|
prompt_policy: long_reasoning_allowed
|
||||||
|
exact_output_match: false
|
||||||
|
|
||||||
|
nodes:
|
||||||
|
- id: mac-codex-node
|
||||||
|
alias: mac-codex
|
||||||
|
role: cli
|
||||||
|
ssh: toki@toki-labs.com
|
||||||
|
workspace: /Users/toki/agent-work/iop-workspace/nomadcode
|
||||||
|
provider_pool_candidate: false
|
||||||
|
adapters:
|
||||||
|
- cli
|
||||||
|
- id: gx10-vllm-node
|
||||||
|
alias: gx10-vllm
|
||||||
|
role: vllm-provider
|
||||||
|
ssh: toki@192.168.0.91
|
||||||
|
workspace: /home/toki/iop-gx10-vllm
|
||||||
|
provider_pool_candidate: true
|
||||||
|
provider:
|
||||||
|
id: gx10-vllm
|
||||||
|
type: vllm
|
||||||
|
endpoint: http://192.168.0.91:8001/v1
|
||||||
|
served_model: nvidia/Qwen3.6-35B-A3B-NVFP4
|
||||||
|
capacity: 4
|
||||||
|
- id: onexplayer-lemonade-node
|
||||||
|
alias: onexplayer-lemonade
|
||||||
|
role: lemonade-provider
|
||||||
|
ssh: r0bin@192.168.0.59
|
||||||
|
ssh_origin: current_host
|
||||||
|
workspace: C:/Users/r0bin/iop-field
|
||||||
|
provider_pool_candidate: true
|
||||||
|
provider:
|
||||||
|
id: onexplayer-lemonade
|
||||||
|
type: lemonade
|
||||||
|
endpoint: http://192.168.0.59:13305/v1
|
||||||
|
served_model: Qwen3.6-35B-A3B-MTP-GGUF
|
||||||
|
capacity: 3
|
||||||
|
windows_process_start: Win32_Process.Create
|
||||||
|
|
@ -3,7 +3,7 @@ test_env: dev
|
||||||
test_profile: node-smoke
|
test_profile: node-smoke
|
||||||
domain: node
|
domain: node
|
||||||
verification_type: smoke
|
verification_type: smoke
|
||||||
last_rule_updated_at: 2026-06-12
|
last_rule_updated_at: 2026-06-24
|
||||||
---
|
---
|
||||||
|
|
||||||
# node-smoke dev 테스트
|
# node-smoke dev 테스트
|
||||||
|
|
@ -40,6 +40,30 @@ last_rule_updated_at: 2026-06-12
|
||||||
- model endpoint: dev OpenAI-compatible base URL 후보 `http://toki-labs.com:18083/v1`
|
- model endpoint: dev OpenAI-compatible base URL 후보 `http://toki-labs.com:18083/v1`
|
||||||
- credential: token/secret 원문은 문서에 기록하지 않는다.
|
- credential: token/secret 원문은 문서에 기록하지 않는다.
|
||||||
|
|
||||||
|
## dev-runtime Node 접속 기준
|
||||||
|
|
||||||
|
dev-runtime의 실제 3-node 연결을 점검할 때는 원격 runner `ssh toki@toki-labs.com`의 `/Users/toki/agent-work/iop-dev` checkout과 `build/dev-runtime/edge.yaml`을 기준으로 한다. Node는 dev-runtime provider pool 기준에서 Edge-Node TCP `toki-labs.com:18084`로 붙는다.
|
||||||
|
|
||||||
|
- mac CLI node: `mac-codex-node` / `mac-codex`
|
||||||
|
- SSH/user: `ssh toki@toki-labs.com`
|
||||||
|
- 목적: `cli` adapter, `codex app-server`
|
||||||
|
- workspace: `/Users/toki/agent-work/iop-workspace/nomadcode`
|
||||||
|
- GX10 vLLM node: `gx10-vllm-node` / `gx10-vllm`
|
||||||
|
- SSH/user: `ssh toki@192.168.0.91`
|
||||||
|
- provider endpoint: `http://192.168.0.91:8001/v1`
|
||||||
|
- served model: `nvidia/Qwen3.6-35B-A3B-NVFP4`
|
||||||
|
- workspace: `/home/toki/iop-gx10-vllm`
|
||||||
|
- OneXPlayer Lemonade node: `onexplayer-lemonade-node` / `onexplayer-lemonade`
|
||||||
|
- SSH/user: `ssh r0bin@192.168.0.59`
|
||||||
|
- 접속 기준: 현재 작업 호스트에서 직접 SSH
|
||||||
|
- provider endpoint: `http://192.168.0.59:13305/v1`
|
||||||
|
- served model: `Qwen3.6-35B-A3B-MTP-GGUF`
|
||||||
|
- workspace: `C:/Users/r0bin/iop-field`
|
||||||
|
|
||||||
|
GX10은 Linux/ARM64 bootstrap, OneXPlayer는 Windows native PowerShell bootstrap을 기본으로 한다. OneXPlayer는 현재 작업 호스트에서 직접 접속해 세팅하며, 원격 runner나 Edge host에서 `node-onexplayer-lemonade.yaml`로 proxy 실행하지 않는다.
|
||||||
|
|
||||||
|
OneXPlayer에서 SSH 세션 안의 `Start-Process`로 `iop-node.exe`를 띄우면 SSH 세션 종료와 함께 process가 정리될 수 있다. dev 반복 배포에서는 `Win32_Process.Create` 또는 동등한 세션 독립 실행 방식으로 `C:/Users/r0bin/iop-field`에서 `iop-node.exe --config node.yaml serve`를 시작하고, WMI/process query와 `iop-node.log`의 `connected to edge` 로그로 유지 여부를 확인한다.
|
||||||
|
|
||||||
## 명령
|
## 명령
|
||||||
|
|
||||||
- setup:
|
- setup:
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
test_env: dev
|
test_env: dev
|
||||||
last_rule_updated_at: 2026-06-12
|
last_rule_updated_at: 2026-06-24
|
||||||
---
|
---
|
||||||
|
|
||||||
# dev 테스트 규칙
|
# dev 테스트 규칙
|
||||||
|
|
@ -13,6 +13,7 @@ last_rule_updated_at: 2026-06-12
|
||||||
- dev 테스트/검증은 이 파일을 기준으로 판단한다.
|
- dev 테스트/검증은 이 파일을 기준으로 판단한다.
|
||||||
- 작업 완료 검증은 변경 범위 기준으로 선택한다.
|
- 작업 완료 검증은 변경 범위 기준으로 선택한다.
|
||||||
- 필수 검증을 실행하지 못하면 차단 사유로 보고한다.
|
- 필수 검증을 실행하지 못하면 차단 사유로 보고한다.
|
||||||
|
- 새 테스트 환경을 추가하거나 환경 구조를 바꿀 때는 `agent-test/README.md`와 `agent-test/_templates/`의 확장 기준을 따른다.
|
||||||
- 최종 보고에는 실행 명령, 결과, 생략 사유, 남은 위험을 남긴다.
|
- 최종 보고에는 실행 명령, 결과, 생략 사유, 남은 위험을 남긴다.
|
||||||
- 환경값, secret, 개인 endpoint는 tracked docs/roadmap에 쓰지 않는다.
|
- 환경값, secret, 개인 endpoint는 tracked docs/roadmap에 쓰지 않는다.
|
||||||
- token/secret 원문은 원격 환경에서 주입하고, shell stdout/stderr와 최종 보고에 출력하지 않는다.
|
- token/secret 원문은 원격 환경에서 주입하고, shell stdout/stderr와 최종 보고에 출력하지 않는다.
|
||||||
|
|
@ -23,7 +24,7 @@ last_rule_updated_at: 2026-06-12
|
||||||
|
|
||||||
- host: dev runtime evidence는 원격 runner `ssh toki@toki-labs.com`의 `/Users/toki/agent-work/iop-dev` 기준으로 수행한다.
|
- host: dev runtime evidence는 원격 runner `ssh toki@toki-labs.com`의 `/Users/toki/agent-work/iop-dev` 기준으로 수행한다.
|
||||||
- repo root: 명령은 원격 checkout `/Users/toki/agent-work/iop-dev` 기준으로 실행한다.
|
- repo root: 명령은 원격 checkout `/Users/toki/agent-work/iop-dev` 기준으로 실행한다.
|
||||||
- sync 기준: 원격 runner를 사용하는 경우 local uncommitted 변경은 원격 repo에 자동 반영되지 않는다. 동기화되지 않았으면 현재 변경분 검증으로 보지 않는다.
|
- sync 기준: dev 배포 전 원격 runner checkout은 `git fetch origin main`, `git reset --hard origin/main`, `git clean -fd`로 clean 상태를 만든 뒤 빌드한다. dev runner의 dirty 변경은 보존 대상으로 보지 않는다.
|
||||||
- env file: dev stack은 `docker compose --env-file .env.dev.example ...`로 명시한다.
|
- env file: dev stack은 `docker compose --env-file .env.dev.example ...`로 명시한다.
|
||||||
- compose identity: `COMPOSE_PROJECT_NAME=iop-dev-agent`, `IOP_COMPOSE_NETWORK=iop-dev-agent-net`.
|
- compose identity: `COMPOSE_PROJECT_NAME=iop-dev-agent`, `IOP_COMPOSE_NETWORK=iop-dev-agent-net`.
|
||||||
- port: web/dev preview `13001`, Control Plane HTTP `18001`, Portal/Control Plane wire test endpoint `19001`, CP-Edge wire `19002`, Edge-Node TCP transport `19003`, Postgres host publish `15401`, Redis host publish `16301`.
|
- port: web/dev preview `13001`, Control Plane HTTP `18001`, Portal/Control Plane wire test endpoint `19001`, CP-Edge wire `19002`, Edge-Node TCP transport `19003`, Postgres host publish `15401`, Redis host publish `16301`.
|
||||||
|
|
@ -50,10 +51,47 @@ last_rule_updated_at: 2026-06-12
|
||||||
| PostgreSQL host publish | `15400` | `15401` |
|
| PostgreSQL host publish | `15400` | `15401` |
|
||||||
| Redis host publish | `16300` | `16301` |
|
| Redis host publish | `16300` | `16301` |
|
||||||
|
|
||||||
|
dev-runtime provider pool은 compose Edge-Node TCP `19003`이 아니라 native Edge listen `18084`를 사용한다. 세부 기준은 `agent-test/dev/edge-smoke.md`와 `agent-test/dev/node-smoke.md`를 따른다.
|
||||||
|
|
||||||
|
## 런타임 프로필
|
||||||
|
|
||||||
|
- local quick check: 현재 checkout에서 Go quick check를 우선 실행한다.
|
||||||
|
- remote runner: dev runtime evidence, Flutter client, Docker compose, field/bootstrap, 외부 runtime evidence는 `ssh toki@toki-labs.com`의 `/Users/toki/agent-work/iop-dev` 기준으로 수행한다.
|
||||||
|
- compose dev stack: `.env.dev.example`, `COMPOSE_PROJECT_NAME=iop-dev-agent`, `IOP_COMPOSE_NETWORK=iop-dev-agent-net`, Edge-Node TCP `19003`을 사용한다.
|
||||||
|
- Edge direct dev profile: artifact/bootstrap `18082`, OpenAI-compatible `18083`, metrics `19101`을 필요할 때만 사용한다.
|
||||||
|
- dev-runtime provider pool: `/Users/toki/agent-work/iop-dev/build/dev-runtime/edge.yaml`과 Edge-Node TCP `toki-labs.com:18084`를 사용한다. 3-node/provider 세부는 `agent-test/dev/edge-smoke.md`와 `agent-test/dev/node-smoke.md`를 따른다.
|
||||||
|
- external provider field: GX10 vLLM은 `ssh toki@192.168.0.91`, OneXPlayer Lemonade는 현재 작업 호스트에서 `ssh r0bin@192.168.0.59`로 직접 접속해 확인한다. OneXPlayer 접속은 원격 runner 경유를 필수 조건으로 보지 않는다.
|
||||||
|
|
||||||
|
## 프리플라이트
|
||||||
|
|
||||||
|
- plan 작성 시 필수 검증이 현재 checkout을 벗어나 원격 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 가정을 포함한다.
|
||||||
|
- 프리플라이트에서 dirty/divergent checkout 또는 stale artifact가 확인되면 dev 배포에서는 먼저 원격 checkout을 clean sync하고 dev-runtime 바이너리를 rebuild한다. 잘못된 identity, missing command, closed port, host OS 불일치, source 미동기화가 확인되면 plan은 setup/sync/rebuild 단계를 만들거나 blocker로 보고한다. profile 값을 이미 참이라고 가정한 검증 명령만 쓰지 않는다.
|
||||||
|
|
||||||
|
## 노드/Provider 인벤토리 위치
|
||||||
|
|
||||||
|
- dev-runtime provider pool machine-readable 기준: `agent-test/dev/inventory.yaml`
|
||||||
|
- dev-runtime provider pool과 Edge/OpenAI-compatible 입력 표면 상세 기준: `agent-test/dev/edge-smoke.md`
|
||||||
|
- dev-runtime Node 접속과 bootstrap 상세 기준: `agent-test/dev/node-smoke.md`
|
||||||
|
- 공통 provider config 계약 기준: `agent-test/dev/platform-common-smoke.md`
|
||||||
|
- compose dev stack 기준: `agent-test/dev/control-plane-smoke.md`, `agent-test/dev/client-smoke.md`, `agent-test/dev/testing-smoke.md`
|
||||||
|
|
||||||
|
## Field/bootstrap 반복 테스트 기준
|
||||||
|
|
||||||
|
- field/bootstrap 검증은 원격 runner의 `/Users/toki/agent-work/iop-dev` checkout과 dev-runtime artifact를 기준으로 수행한다. 세부 Edge/Node profile은 `agent-test/dev/edge-smoke.md`와 `agent-test/dev/node-smoke.md`를 따른다.
|
||||||
|
- compose dev stack은 Edge-Node TCP `19003`을 사용하고, dev-runtime provider pool은 native Edge listen `18084`를 사용한다. 두 프로필을 섞어서 판정하지 않는다.
|
||||||
|
- Node bootstrap은 Edge의 `node register`가 출력한 OS별 완성 명령을 그대로 사용한다. 사용자에게 안내하는 명령에는 임의 placeholder, 수동 token 치환, `IOP_*=` named environment parameter를 넣지 않는다.
|
||||||
|
- token, API key, private credential 원문은 tracked docs, roadmap, 테스트 규칙에 기록하지 않는다. 실행 증거에는 token을 마스킹하거나 명령 생성 사실만 남긴다.
|
||||||
|
- Linux/macOS Node는 생성된 `curl | bash` 계열 명령을 사용한다. Windows Node는 native PowerShell bootstrap을 기본으로 사용한다.
|
||||||
|
- dev-runtime 배포는 clean sync 후 `build/dev-runtime/bin/edge`, mac node, Linux/Windows node binary를 같은 source 기준으로 rebuild한다. 배포 후 `edge config refresh --help`, `19093` port, `config refresh --mode dry-run`을 확인한다.
|
||||||
|
- provider capacity, model/provider mapping은 `config check`와 `config refresh --mode dry-run`을 통과한 뒤 `config refresh --mode apply`로 반영한다. refresh subcommand 또는 `19093` admin port가 없으면 바이너리 rebuild 누락으로 보고 먼저 rebuild한다.
|
||||||
|
- Edge process restart 또는 일시 단절 후에는 Node reconnect 정책을 검증한다. retry 한계를 넘겨 Node process가 종료된 경우에만 해당 Node host에서 새 bootstrap 실행이 필요하다.
|
||||||
|
|
||||||
## 라우팅
|
## 라우팅
|
||||||
|
|
||||||
- node / smoke / node 실행 파이프라인 baseline: `agent-test/dev/node-smoke.md`
|
- node / smoke / node 실행 파이프라인 baseline: `agent-test/dev/node-smoke.md`
|
||||||
- edge / smoke / edge 실행 그룹과 입력 표면 baseline: `agent-test/dev/edge-smoke.md`
|
- edge / smoke / edge 실행 그룹과 입력 표면 baseline: `agent-test/dev/edge-smoke.md`
|
||||||
|
- dev-runtime provider pool, 3-node 연결, GX10 vLLM, OneXPlayer Lemonade, mac CLI node 점검: `agent-test/dev/edge-smoke.md`, `agent-test/dev/node-smoke.md`
|
||||||
- control-plane / smoke / control-plane health와 wire baseline: `agent-test/dev/control-plane-smoke.md`
|
- control-plane / smoke / control-plane health와 wire baseline: `agent-test/dev/control-plane-smoke.md`
|
||||||
- client / smoke / Flutter client와 IOP console package baseline: `agent-test/dev/client-smoke.md`
|
- client / smoke / Flutter client와 IOP console package baseline: `agent-test/dev/client-smoke.md`
|
||||||
- platform-common / smoke / 공통 설정과 protobuf 계약 baseline: `agent-test/dev/platform-common-smoke.md`
|
- platform-common / smoke / 공통 설정과 protobuf 계약 baseline: `agent-test/dev/platform-common-smoke.md`
|
||||||
|
|
|
||||||
|
|
@ -1077,13 +1077,8 @@ echo '{"id":1,"result":{"protocolVersion":"2024-11-05","capabilities":{}}}'
|
||||||
}
|
}
|
||||||
defer proc.close()
|
defer proc.close()
|
||||||
|
|
||||||
time.Sleep(150 * time.Millisecond)
|
|
||||||
|
|
||||||
markerPath := filepath.Join(workspace, "cwd.txt")
|
markerPath := filepath.Join(workspace, "cwd.txt")
|
||||||
cwdBytes, err := os.ReadFile(markerPath)
|
cwdBytes := readFileEventually(t, markerPath, 2*time.Second)
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to read marker file: %v", err)
|
|
||||||
}
|
|
||||||
cwd := strings.TrimSpace(string(cwdBytes))
|
cwd := strings.TrimSpace(string(cwdBytes))
|
||||||
|
|
||||||
resolvedWorkspace, err := os.Readlink(workspace)
|
resolvedWorkspace, err := os.Readlink(workspace)
|
||||||
|
|
@ -1095,3 +1090,21 @@ echo '{"id":1,"result":{"protocolVersion":"2024-11-05","capabilities":{}}}'
|
||||||
t.Errorf("expected process cwd to be %q or %q, got %q", workspace, resolvedWorkspace, cwd)
|
t.Errorf("expected process cwd to be %q or %q, got %q", workspace, resolvedWorkspace, cwd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func readFileEventually(t *testing.T, path string, timeout time.Duration) []byte {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
deadline := time.Now().Add(timeout)
|
||||||
|
var lastErr error
|
||||||
|
for {
|
||||||
|
b, err := os.ReadFile(path)
|
||||||
|
if err == nil {
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
lastErr = err
|
||||||
|
if time.Now().After(deadline) {
|
||||||
|
t.Fatalf("failed to read file %s within %s: %v", path, timeout, lastErr)
|
||||||
|
}
|
||||||
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,10 @@ import (
|
||||||
|
|
||||||
func (c *CLI) executeOneShot(ctx context.Context, spec runtime.ExecutionSpec, profile config.CLIProfileConf, sink runtime.EventSink) error {
|
func (c *CLI) executeOneShot(ctx context.Context, spec runtime.ExecutionSpec, profile config.CLIProfileConf, sink runtime.EventSink) error {
|
||||||
prompt := extractPrompt(spec.Input)
|
prompt := extractPrompt(spec.Input)
|
||||||
args := append(append([]string{}, profile.Args...), prompt)
|
args := append([]string{}, profile.Args...)
|
||||||
|
if prompt != "" {
|
||||||
|
args = append(args, prompt)
|
||||||
|
}
|
||||||
_, err := c.executeCommand(ctx, spec, profile, args, prompt, sink)
|
_, err := c.executeCommand(ctx, spec, profile, args, prompt, sink)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,20 @@ curl -fsS http://toki-labs.com:18000/edges/edge-toki-labs/status
|
||||||
|
|
||||||
현재 GX10 vLLM과 OneXPlayer Lemonade를 같은 model alias로 묶어 검증하는 dev-runtime 기준은 원격 runner의 동기화된 iop checkout과 `build/dev-runtime/edge.yaml`이다.
|
현재 GX10 vLLM과 OneXPlayer Lemonade를 같은 model alias로 묶어 검증하는 dev-runtime 기준은 원격 runner의 동기화된 iop checkout과 `build/dev-runtime/edge.yaml`이다.
|
||||||
|
|
||||||
|
배포 전 원격 runner checkout은 보존 대상이 아니다. 항상 clean sync 후 dev-runtime binary를 다시 빌드한다.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /Users/toki/agent-work/iop-dev
|
||||||
|
git fetch origin main
|
||||||
|
git reset --hard origin/main
|
||||||
|
git clean -fd
|
||||||
|
|
||||||
|
go build -trimpath -o build/dev-runtime/bin/edge ./apps/edge/cmd/edge
|
||||||
|
go build -trimpath -o build/dev-runtime/bin/iop-node ./apps/node/cmd/node
|
||||||
|
GOOS=linux GOARCH=arm64 go build -trimpath -o build/dev-runtime/bin/iop-node-linux-arm64 ./apps/node/cmd/node
|
||||||
|
GOOS=windows GOARCH=amd64 go build -trimpath -o build/dev-runtime/bin/iop-node-windows-amd64.exe ./apps/node/cmd/node
|
||||||
|
```
|
||||||
|
|
||||||
기준 주소:
|
기준 주소:
|
||||||
|
|
||||||
- Control Plane status: 원격 host의 `http://127.0.0.1:18001`
|
- Control Plane status: 원격 host의 `http://127.0.0.1:18001`
|
||||||
|
|
@ -118,9 +132,17 @@ curl -fsS http://toki-labs.com:18000/edges/edge-toki-labs/status
|
||||||
- provider candidate: `onexplayer-lemonade` on `onexplayer-lemonade-node`, capacity `3`
|
- provider candidate: `onexplayer-lemonade` on `onexplayer-lemonade-node`, capacity `3`
|
||||||
- connected non-candidate: `mac-codex-node`
|
- connected non-candidate: `mac-codex-node`
|
||||||
|
|
||||||
OneXPlayer Lemonade Node는 원격 runner나 Edge host에서 proxy process로 띄우지 않는다. Windows host에 직접 SSH로 접속한 뒤, 그 host 안에서 generated PowerShell bootstrap 명령을 실행한다. 이때 Lemonade provider endpoint는 Windows host 로컬에서 접근 가능한 값을 기준으로 검증한다.
|
OneXPlayer Lemonade Node는 원격 runner나 Edge host에서 다시 SSH하거나 proxy process로 띄우지 않는다. 현재 작업 호스트에서 Windows host에 `ssh r0bin@192.168.0.59`로 직접 접속한 뒤, 그 host 안에서 generated PowerShell bootstrap 명령을 실행한다. 이때 Node 작업 경로는 `$HOME\iop-field`이며, Lemonade provider endpoint는 Windows host 로컬에서 접근 가능한 값을 기준으로 검증한다.
|
||||||
|
|
||||||
capacity, provider mapping, model alias 변경은 실행 중 Edge에 `config refresh`로 반영한다. 후보 `edge.yaml` 수정 후 `config check`, dry-run, apply 순서로 진행한다. listen port, Edge identity, bootstrap artifact dir처럼 live apply가 위험한 값은 `restart_required`로 보고되며 Edge process 재시작이 필요하다.
|
SSH 세션 안의 `Start-Process`는 세션 종료와 함께 `iop-node.exe`가 정리될 수 있다. 반복 배포에서는 Windows host에서 `Win32_Process.Create` 방식으로 세션 독립 실행한다.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$work = "$HOME\iop-field"
|
||||||
|
$cmd = 'cmd.exe /c "cd /d C:\Users\r0bin\iop-field && iop-node.exe --config node.yaml serve >> iop-node.wmi.stdout.log 2>> iop-node.wmi.stderr.log"'
|
||||||
|
Invoke-CimMethod -ClassName Win32_Process -MethodName Create -Arguments @{ CommandLine = $cmd; CurrentDirectory = $work }
|
||||||
|
```
|
||||||
|
|
||||||
|
capacity, provider mapping, model alias 변경은 후보 `edge.yaml` 수정 후 `config check`, refresh dry-run, refresh apply 순서로 반영한다. `config refresh` subcommand나 `19093` admin port가 없으면 dev-runtime binary rebuild 누락으로 보고 clean sync/rebuild부터 다시 수행한다.
|
||||||
|
|
||||||
dev-runtime 번들은 바이너리를 `build/dev-runtime/bin/edge`에 둔다. 명령은 그 경로를 `EDGE_BIN`으로 잡고 실행한다.
|
dev-runtime 번들은 바이너리를 `build/dev-runtime/bin/edge`에 둔다. 명령은 그 경로를 `EDGE_BIN`으로 잡고 실행한다.
|
||||||
|
|
||||||
|
|
@ -140,12 +162,17 @@ Node host OS 재부팅은 필요하지 않다. Edge process 재시작이나 일
|
||||||
3. Edge process를 재시작하고 bootstrap 재실행 없이 3개 Node 연결이 회복되는지 확인한다.
|
3. Edge process를 재시작하고 bootstrap 재실행 없이 3개 Node 연결이 회복되는지 확인한다.
|
||||||
4. `http://toki-labs.com:18083/healthz`와 `/v1/models`를 확인한다.
|
4. `http://toki-labs.com:18083/healthz`와 `/v1/models`를 확인한다.
|
||||||
5. capacity를 `gx10-vllm=4`, `onexplayer-lemonade=3`로 맞춘 후보 config를 refresh apply하고 Edge process가 유지되는지 확인한다.
|
5. capacity를 `gx10-vllm=4`, `onexplayer-lemonade=3`로 맞춘 후보 config를 refresh apply하고 Edge process가 유지되는지 확인한다.
|
||||||
6. `qwen3.6:35b`로 동시 4개 `/v1/chat/completions` 요청을 보낸다.
|
6. `qwen3.6:35b`로 `/v1/responses`와 `/v1/chat/completions` 각각에 provider capacity 총합 + 1개 동시 요청을 보낸다.
|
||||||
7. capacity `4/3` 기준이면 동시 in-flight 전제에서 aggregate 배정 기대값은 `gx10-vllm` 2개, `onexplayer-lemonade` 2개다.
|
7. capacity `gx10-vllm=4`, `onexplayer-lemonade=3` 기준이면 endpoint별 8개 동시 요청에서 Control Plane status의 provider snapshot이 총 `in_flight=7`, `queued>=1`을 한 번 이상 보여야 한다.
|
||||||
|
8. 요청 완료 후 provider snapshot이 `in_flight=0`, `queued=0`으로 회복되는지 확인한다.
|
||||||
|
|
||||||
|
Qwen 계열 모델은 thinking/reasoning 텍스트를 포함해 응답할 수 있다. 이 dev smoke에서는 thinking 출력을 실패로 보지 않고, HTTP 성공, final marker 포함, provider log/run count 증가를 기준으로 판정한다.
|
||||||
|
|
||||||
현재 공개 API는 개별 request의 최종 `node_id`를 응답에 노출하지 않는다. 요청별 배정을 확정해야 할 때는 Edge dispatch trace/log를 추가한 뒤 판정한다.
|
현재 공개 API는 개별 request의 최종 `node_id`를 응답에 노출하지 않는다. 요청별 배정을 확정해야 할 때는 Edge dispatch trace/log를 추가한 뒤 판정한다.
|
||||||
|
|
||||||
## 7. Smoke
|
## 7. 기본 Smoke
|
||||||
|
|
||||||
|
아래는 dev-runtime provider pool이 아니라 기본 field/local OpenAI-compatible profile 기준 예시다. dev-runtime provider pool 검증은 위의 `18083`/`qwen3.6:35b` 기준을 따른다.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -fsS http://toki-labs.com:18081/v1/models
|
curl -fsS http://toki-labs.com:18081/v1/models
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue