chore: update test rules, docs, and client configuration

This commit is contained in:
toki 2026-07-13 13:50:35 +09:00
parent bb367055aa
commit 83c26c4ac3
11 changed files with 89 additions and 48 deletions

View file

@ -3,10 +3,11 @@
기존 Seulgivibe Claude 설정이 되어 있는 macOS 환경에서 Claude TUI `/model`에 아래 모델을 함께 노출한다.
```text
claude-seulgivibe-sonnet-4-5
claude-seulgivibe-opus-4-8
claude-seulgivibe-mythos-5
claude-dev-corp-gemma4-26b
claude-seulgivibe-sonnet-4-5 Claude Sonnet 4.5 - coding agents
claude-seulgivibe-opus-4-8 Claude Opus 4.8 - browser agents
claude-seulgivibe-mythos-5 Claude Fable 5 - autonomous work
claude-dev-corp-gemma4-26b Gemma4 26B - gemma4:26b
claude-dev-corp-ornith35b Ornith 35B - ornith35b
```
## 설치
@ -26,5 +27,7 @@ cd agent-client/claude
- `~/.claude/dev-corp-openai-api-key`
- `~/.pi/agent/dev-corp-openai-api-key`
- 없으면 `~/.claude/anthropic_key.sh` 출력값을 fallback으로 사용한다.
- `claude-dev-corp-gemma4-26b`는 Claude 표시용 alias이며 upstream 호출 모델은 `gemma4:26b`다.
- `claude-dev-corp-ornith35b`는 Claude 표시용 alias이며 upstream 호출 모델은 `ornith:35b`다.
JWT/API key 원문은 이 폴더에 포함하지 않는다.

View file

@ -107,7 +107,7 @@ models = [
"claude-seulgivibe-sonnet-4-5",
"claude-seulgivibe-opus-4-8",
"claude-seulgivibe-mythos-5",
"claude-dev-corp-gemma4-26b",
"gemma4:26b",
]
settings["apiKeyHelper"] = settings.get("apiKeyHelper") or "~/.claude/anthropic_key.sh"
@ -125,6 +125,8 @@ for key in [
]:
env.pop(key, None)
if settings.get("model") == "claude-dev-corp-gemma4-26b":
settings["model"] = "gemma4:26b"
if settings.get("model") not in models:
settings["model"] = "claude-seulgivibe-mythos-5"
settings["availableModels"] = models
@ -141,7 +143,7 @@ cache = {
{"id": "claude-seulgivibe-sonnet-4-5", "display_name": "Seulgivibe Sonnet 4.5"},
{"id": "claude-seulgivibe-opus-4-8", "display_name": "Seulgivibe Opus 4.8"},
{"id": "claude-seulgivibe-mythos-5", "display_name": "Seulgivibe Fable 5"},
{"id": "claude-dev-corp-gemma4-26b", "display_name": "dev-corp gemma4:26b"},
{"id": "gemma4:26b", "display_name": "dev-corp gemma4:26b"},
],
}
cache_path.write_text(json.dumps(cache, ensure_ascii=False, separators=(",", ":")) + "\n")

View file

@ -17,7 +17,7 @@ SEULGIVIBE_HOST = os.environ.get("SEULGIVIBE_HOST", "seulgivibe.lgudax.cool")
SEULGIVIBE_PREFIX = os.environ.get("SEULGIVIBE_ANTHROPIC_PREFIX", "/anthropic")
SEULGIVIBE_KEY_HELPER = os.path.expanduser("~/.claude/anthropic_key.sh")
DEV_CORP_OPENAI_BASE_URL = os.environ.get(
DEFAULT_DEV_CORP_OPENAI_BASE_URL = os.environ.get(
"DEV_CORP_OPENAI_BASE_URL",
"http://digitalplatform.iop.ai.kr:18086/v1",
).rstrip("/")
@ -26,9 +26,37 @@ DEV_CORP_TOKEN_FILES = [
os.path.expanduser("~/.claude/dev-corp-openai-api-key"),
os.path.expanduser("~/.pi/agent/dev-corp-openai-api-key"),
]
DEV_CORP_MODEL = "claude-dev-corp-gemma4-26b"
DEV_CORP_UPSTREAM_MODEL = "gemma4:26b"
DEV_CORP_MIN_MAX_TOKENS = int(os.environ.get("DEV_CORP_UPSTREAM_MIN_MAX_TOKENS", "1024"))
GEMMA_MODEL = "gemma4:26b"
ORNITH_MODEL = "ornith35b"
CLAUDE_GEMMA_MODEL = "claude-dev-corp-gemma4-26b"
CLAUDE_ORNITH_MODEL = "claude-dev-corp-ornith35b"
GEMMA_OPENAI_BASE_URL = os.environ.get(
"DEV_CORP_GEMMA_OPENAI_BASE_URL",
DEFAULT_DEV_CORP_OPENAI_BASE_URL,
).rstrip("/")
ORNITH_OPENAI_BASE_URL = os.environ.get(
"DEV_CORP_ORNITH_OPENAI_BASE_URL",
"http://172.24.63.178:18003/v1",
).rstrip("/")
DEV_CORP_MODEL_CONFIGS = {
GEMMA_MODEL: {
"upstream_model": "gemma4:26b",
"base_url": GEMMA_OPENAI_BASE_URL,
},
CLAUDE_GEMMA_MODEL: {
"upstream_model": "gemma4:26b",
"base_url": GEMMA_OPENAI_BASE_URL,
},
ORNITH_MODEL: {
"upstream_model": "ornith:35b",
"base_url": ORNITH_OPENAI_BASE_URL,
},
CLAUDE_ORNITH_MODEL: {
"upstream_model": "ornith:35b",
"base_url": ORNITH_OPENAI_BASE_URL,
},
}
SEULGIVIBE_ALIASES = {
"claude-seulgivibe-sonnet-4-5": "claude-sonnet-4-5-20250929",
@ -40,29 +68,36 @@ MODELS = [
{
"id": "claude-seulgivibe-sonnet-4-5",
"type": "model",
"display_name": "Seulgivibe Sonnet 4.5",
"description": "Seulgivibe Sonnet 4.5",
"display_name": "Claude Sonnet 4.5 - coding agents",
"description": "Seulgivibe Claude Sonnet 4.5 for coding, complex agents, computer use, and long-horizon tasks.",
"created_at": "2026-05-13T00:00:00Z",
},
{
"id": "claude-seulgivibe-opus-4-8",
"type": "model",
"display_name": "Seulgivibe Opus 4.8",
"description": "Seulgivibe Opus 4.8",
"display_name": "Claude Opus 4.8 - browser agents",
"description": "Seulgivibe Claude Opus 4.8 for deeper agent work, browser and computer-use tasks, and long-session collaboration.",
"created_at": "2026-05-13T00:00:00Z",
},
{
"id": "claude-seulgivibe-mythos-5",
"type": "model",
"display_name": "Seulgivibe Fable 5",
"description": "Fable 5 · Most capable for your hardest and longest-running tasks · $10/$50 per Mtok",
"display_name": "Claude Fable 5 - autonomous work",
"description": "Seulgivibe Claude Fable 5 for complex knowledge work, coding, multi-day autonomous tasks, staged planning, delegation, and self-verification.",
"created_at": "2026-05-13T00:00:00Z",
},
{
"id": DEV_CORP_MODEL,
"id": CLAUDE_GEMMA_MODEL,
"type": "model",
"display_name": "dev-corp gemma4:26b",
"description": "dev-corp gemma4:26b via OpenAI-compatible gateway",
"display_name": "Gemma4 26B - gemma4:26b",
"description": "dev-corp Gemma 4 26B A4B IT NVFP4 via MLX/OpenAI-compatible, tuned here for image-text and local code workflows.",
"created_at": "2026-07-10T00:00:00Z",
},
{
"id": CLAUDE_ORNITH_MODEL,
"type": "model",
"display_name": "Ornith 35B - ornith35b",
"description": "dev-corp Ornith 1.0 35B 8-bit MLX open coding agent, routed to upstream ornith:35b.",
"created_at": "2026-07-10T00:00:00Z",
},
]
@ -328,9 +363,9 @@ def anthropic_tools_to_openai(payload):
return tools
def build_openai_payload(payload):
def build_openai_payload(payload, model_config):
body = {
"model": DEV_CORP_UPSTREAM_MODEL,
"model": model_config["upstream_model"],
"messages": anthropic_messages_to_openai(payload),
"temperature": payload.get("temperature", 0.2),
"top_p": payload.get("top_p", 0.95),
@ -347,8 +382,8 @@ def build_openai_payload(payload):
return body
def parse_openai_url(path):
parsed = urlsplit(DEV_CORP_OPENAI_BASE_URL)
def parse_openai_url(base_url, path):
parsed = urlsplit(base_url)
scheme = parsed.scheme or "http"
host = parsed.hostname or ""
port = parsed.port
@ -356,8 +391,8 @@ def parse_openai_url(path):
return scheme, host, port, f"{prefix}{path}"
def call_dev_corp(openai_payload, inbound_headers):
scheme, host, port, path = parse_openai_url("/chat/completions")
def call_dev_corp(openai_payload, inbound_headers, model_config):
scheme, host, port, path = parse_openai_url(model_config["base_url"], "/chat/completions")
body = json.dumps(openai_payload, ensure_ascii=False, separators=(",", ":")).encode("utf-8")
headers = {
"content-type": "application/json",
@ -427,7 +462,7 @@ def openai_to_anthropic(openai_payload, requested_model):
"id": openai_payload.get("id") or f"msg_{uuid.uuid4().hex}",
"type": "message",
"role": "assistant",
"model": requested_model or DEV_CORP_MODEL,
"model": requested_model or GEMMA_MODEL,
"content": content or [{"type": "text", "text": ""}],
"stop_reason": stop_reason,
"stop_sequence": None,
@ -585,12 +620,13 @@ class Handler(BaseHTTPRequestHandler):
return
headers = {key.lower(): value for key, value in self.headers.items()}
if payload.get("model") == DEV_CORP_MODEL:
model_config = DEV_CORP_MODEL_CONFIGS.get(payload.get("model"))
if model_config:
if is_count_tokens:
self.write_json(200, {"input_tokens": estimate_tokens(payload)})
return
openai_payload = build_openai_payload(payload)
status, _, body = call_dev_corp(openai_payload, headers)
openai_payload = build_openai_payload(payload, model_config)
status, _, body = call_dev_corp(openai_payload, headers, model_config)
if status < 200 or status >= 300:
try:
detail = json.loads(body.decode("utf-8"))

View file

@ -61,7 +61,7 @@ dev-corp provider pool을 현재 dev-runtime과 같은 구조로 배포한다.
- 2026-07-13 기준 Spark Gemma4 `8002`/`8004` runtime은 내린 상태로 보고, Spark 01/02는 Ornith `8003`/`8005`를 IOP provider로 둔다. Gemma4는 Mac Studio `192.168.2.3:8004` provider만 기본 대상으로 둔다.
- 2026-07-13 재확인 기준 DGX Spark 01 Ornith는 Docker `iop-vllm-ornith35b-fp8`, host `8003`, `--gpu-memory-utilization 0.47`로 동작하며 startup log에서 GPU KV cache `783,347` tokens, full-context concurrency `2.99x`를 확인했다. DGX Spark 02 Ornith는 host `8005`, `--gpu-memory-utilization 0.50`으로 동작하며 GPU KV cache `1,074,276` tokens, full-context concurrency `4.10x`를 확인했다.
- 2026-07-02 mac-mini native Control Plane `18002/19004/19005` 관측값은 historical evidence다. 2026-07-09 현재 dev-corp Edge source of truth는 public `iop.ai.kr`이고, current runner에서 public host SSH와 public Control Plane status 접근은 확인되지 않았다.
- 2026-07-13 기준 dev-corp provider-pool Edge OpenAI-compatible capacity smoke 표준은 public `http://digitalplatform.iop.ai.kr:18086/v1/chat/completions`에서 `ornith:35b` 9/6, `gemma4:26b` 9/6 동시 요청이다. `/v1/responses`는 OpenAI-compatible provider model group raw passthrough parity 전까지 미지원이므로 성공 기준에서 제외한다.
- 2026-07-13 기준 dev-corp provider-pool Edge OpenAI-compatible capacity smoke 표준은 public `https://digitalplatform.iop.ai.kr/v1/chat/completions`에서 `ornith:35b` 9/6, `gemma4:26b` 9/6 동시 요청이다. Direct Edge listener `http://digitalplatform.iop.ai.kr:18086/v1`도 같은 backend로 동작하지만 사용자-facing 기본값으로 쓰지 않는다. `/v1/responses`는 OpenAI-compatible provider model group raw passthrough parity 전까지 미지원이므로 성공 기준에서 제외한다.
- 2026-07-13 live status 기준 DGX Spark 01/02와 Mac Studio node는 `iop.ai.kr:18087`로 연결되어 있으며, provider snapshot은 Spark01 Ornith capacity `4`, Spark02 Ornith capacity `4`, Mac Studio Gemma4 capacity `5`이다. 같은 날 model-specific smoke에서 `ornith:35b` 9/6, `gemma4:26b` 9/6 요청이 모두 성공했고 완료 후 `in_flight=0`, `queued=0`, `healthy`로 회복했다.
## 실행 절차

View file

@ -40,7 +40,7 @@ last_rule_updated_at: 2026-07-13
- 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://iop.ai.kr:18085`, dev-corp Edge runtime 기본 후보 `iop.ai.kr:18087`; mac-mini local endpoint는 dev-corp Edge 경로로 사용하지 않는다.
- model endpoint: dev-corp OpenAI-compatible base URL 기본 후보 `http://digitalplatform.iop.ai.kr:18086/v1`
- model endpoint: dev-corp OpenAI-compatible base URL 기본 후보 `https://digitalplatform.iop.ai.kr/v1`; direct Edge listener 확인이 필요할 때만 `http://digitalplatform.iop.ai.kr:18086/v1`
- credential: token/secret/API key 원문은 문서에 기록하지 않는다.
## dev-corp provider pool 인벤토리
@ -53,7 +53,7 @@ dev-corp provider pool과 3-node 연결 상태를 점검할 때는 `agent-test/d
- Control Plane HTTP/status 후보: `http://iop.ai.kr:18002`, `http://iop.ai.kr:18002/edges/dev-corp-edge/status` when the public port is enabled
- Control Plane-Edge wire 후보: `iop.ai.kr:19005` when the public port is enabled
- bootstrap HTTP 기본 후보: `http://iop.ai.kr:18085`
- Edge OpenAI-compatible base URL 기본 후보: `http://digitalplatform.iop.ai.kr:18086/v1`
- Edge OpenAI-compatible base URL 기본 후보: `https://digitalplatform.iop.ai.kr/v1`
- Edge-Node TCP transport 기본 후보: `iop.ai.kr:18087`
- mac-mini/internal 후보는 dev-corp Edge 경로가 아니다. Node `edge_addr``iop.ai.kr:18087`이어야 한다.
- model alias 후보: `gemma4:26b`, `ornith:35b`
@ -113,7 +113,7 @@ Mac Studio의 `http://192.168.2.3:8005/v1` mlx-vlm DiffusionGemma endpoint는
- 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 historical aggregate 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 historical aggregate concurrency 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 표준: public `http://digitalplatform.iop.ai.kr:18086/v1`에서 `ornith:35b`는 9개/6개 동시 요청, `gemma4:26b`는 9개/6개 동시 요청을 확인한다. 2026-07-13 live smoke에서는 네 시나리오 모두 성공했고 완료 후 provider `in_flight=0`, `queued=0`, `healthy`로 회복했다.
- `/v1/chat/completions` capacity smoke 표준: public `https://digitalplatform.iop.ai.kr/v1`에서 `ornith:35b`는 9개/6개 동시 요청, `gemma4:26b`는 9개/6개 동시 요청을 확인한다. Direct Edge listener `http://digitalplatform.iop.ai.kr:18086/v1`도 같은 backend로 동작하지만 사용자-facing 기본값으로 쓰지 않는다. 2026-07-13 live smoke에서는 네 시나리오 모두 성공했고 완료 후 provider `in_flight=0`, `queued=0`, `healthy`로 회복했다.
- `/v1/responses`는 OpenAI-compatible provider model group raw passthrough parity 전까지 미지원이므로 provider-pool capacity 성공 기준에서 제외한다.
## 명령
@ -123,7 +123,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을 띄운 경우 `gemma4:26b``ornith:35b`를 각각 public `http://digitalplatform.iop.ai.kr:18086/v1/chat/completions`로 확인한다.
- model: dev-corp OpenAI-compatible profile을 띄운 경우 `gemma4:26b``ornith:35b`를 각각 public `https://digitalplatform.iop.ai.kr/v1/chat/completions`로 확인한다.
- direct-provider: mac-mini에서 `curl -fsS http://192.168.2.2:8003/v1/models`, `curl -fsS http://192.168.2.4:8005/v1/models`, `curl -fsS http://192.168.2.3:8004/v1/models`
- full-cycle: repo 내부 edge-node 진단, `iop-edge smoke openai`, OpenAI-compatible 입력 표면 수동 검증

View file

@ -35,9 +35,11 @@ edge:
control_plane_client_ws_public: ws://iop.ai.kr:19004/client
bootstrap_http_public: http://iop.ai.kr:18085
bootstrap_http_node_internal: http://iop.ai.kr:18085
openai_base_url_public: http://digitalplatform.iop.ai.kr:18086/v1
openai_base_url_public: https://digitalplatform.iop.ai.kr/v1
openai_base_url_public_http: http://digitalplatform.iop.ai.kr/v1
openai_base_url_direct_edge_listener: http://digitalplatform.iop.ai.kr:18086/v1
openai_base_url_node_internal: http://digitalplatform.iop.ai.kr:18086/v1
openai_base_url_runner: http://digitalplatform.iop.ai.kr:18086/v1
openai_base_url_runner: https://digitalplatform.iop.ai.kr/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

View file

@ -39,7 +39,7 @@ last_rule_updated_at: 2026-07-13
- package manager: Go modules / Makefile
- docker: unit/smoke quick check는 Docker를 요구하지 않는다. compose dev-corp 검증은 mac-mini에서 수행한다.
- external service: dev-corp Edge runtime 후보는 `iop.ai.kr:18087`이다. mac-mini local endpoint와 reverse tunnel은 dev-corp Edge 경로로 사용하지 않는다.
- model endpoint: dev-corp OpenAI-compatible base URL 기본 후보 `http://digitalplatform.iop.ai.kr:18086/v1`
- model endpoint: dev-corp OpenAI-compatible base URL 기본 후보 `https://digitalplatform.iop.ai.kr/v1`; direct Edge listener 확인이 필요할 때만 `http://digitalplatform.iop.ai.kr:18086/v1`
- credential: token/secret/API key 원문은 문서에 기록하지 않는다.
## dev-corp Node 접속 기준
@ -108,7 +108,7 @@ Mac Studio의 secondary `http://192.168.2.3:8005/v1` endpoint는 기본 Node/pro
## 2026-07-09 연결/용량 검증 상태
- DGX Spark 01, DGX Spark 02, Mac Studio Node는 각 host의 `~/iop-dev-corp-field/node.yaml`에서 `edge_addr: "iop.ai.kr:18087"`로 실행된다.
- 2026-07-13 live status 기준 세 Node 모두 connected이며 provider snapshot은 Spark01 Ornith capacity `4`, Spark02 Ornith capacity `4`, Mac Studio Gemma4 capacity `5`이다. Public `http://digitalplatform.iop.ai.kr:18086/v1/chat/completions`에서 `ornith:35b` 9/6, `gemma4:26b` 9/6 동시 요청이 모두 성공했고 완료 후 `in_flight=0`, `queued=0`, `healthy`로 회복했다.
- 2026-07-13 live status 기준 세 Node 모두 connected이며 provider snapshot은 Spark01 Ornith capacity `4`, Spark02 Ornith capacity `4`, Mac Studio Gemma4 capacity `5`이다. Public OpenAI-compatible route에서 `ornith:35b` 9/6, `gemma4:26b` 9/6 동시 요청이 모두 성공했고 완료 후 `in_flight=0`, `queued=0`, `healthy`로 회복했다. 사용자-facing 기본 base URL은 `https://digitalplatform.iop.ai.kr/v1`이다.
- `/v1/responses`는 OpenAI-compatible provider model group raw passthrough parity 전까지 미지원이므로 provider-pool capacity 성공 기준에서 제외한다.
## 명령

View file

@ -35,7 +35,7 @@ last_rule_updated_at: 2026-07-11
- package manager: Go modules / Makefile
- docker: unit/codegen quick check는 Docker를 요구하지 않는다. compose dev-corp 검증은 mac-mini에서 수행한다.
- external service: dev-corp artifact/base URL 기본 후보 `http://iop.ai.kr:18085`; mac-mini runner/local legacy 경로는 bootstrap 기본 URL로 쓰지 않는다.
- model endpoint: dev-corp OpenAI-compatible base URL 기본 후보 `http://digitalplatform.iop.ai.kr:18086/v1`
- model endpoint: dev-corp OpenAI-compatible base URL 기본 후보 `https://digitalplatform.iop.ai.kr/v1`; direct Edge listener 확인이 필요할 때만 `http://digitalplatform.iop.ai.kr:18086/v1`
- credential: token/secret/API key 원문은 문서에 기록하지 않는다.
## 명령

View file

@ -40,8 +40,8 @@ last_rule_updated_at: 2026-07-13
- 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 Edge 후보는 `http://iop.ai.kr:18085`, `http://digitalplatform.iop.ai.kr:18086/v1`, `iop.ai.kr:18087`이다. Control Plane/Client public 후보는 해당 public host 포트가 실제로 열려 있을 때만 검증 대상으로 삼는다.
- model endpoint: Edge 배포 후 기본 외부 후보 `http://digitalplatform.iop.ai.kr:18086/v1`; 직접 provider 확인은 `agent-test/dev-corp/inventory.yaml`의 provider endpoint를 따른다.
- external service: dev-corp Edge 후보는 `http://iop.ai.kr:18085`, `https://digitalplatform.iop.ai.kr/v1`, `iop.ai.kr:18087`이다. Control Plane/Client public 후보는 해당 public host 포트가 실제로 열려 있을 때만 검증 대상으로 삼는다.
- model endpoint: Edge 배포 후 기본 외부 후보 `https://digitalplatform.iop.ai.kr/v1`; `http://digitalplatform.iop.ai.kr:18086/v1`은 direct Edge listener 확인용으로만 쓴다. 직접 provider 확인은 `agent-test/dev-corp/inventory.yaml`의 provider endpoint를 따른다.
- credential: secret/token/API key 원문은 문서에 기록하지 않는다.
## 포트 매핑

View file

@ -33,13 +33,12 @@ last_rule_updated_at: 2026-07-13
## 환경
- host: local checkout. Flutter client 포함 검증, Docker compose, field/bootstrap, artifact server, external provider evidence가 필요하면 mac-mini runner를 사용한다.
- port: web/dev preview `13002`, artifact/bootstrap HTTP 후보 `18085`, Edge OpenAI-compatible HTTP 후보 `18086`, Client WS `19004`, CP-Edge wire `19005`, compose Edge-Node TCP transport `19006`, native Edge-Node TCP 후보 `18087`, Edge metrics 후보 `19102`, Control Plane metrics `19104`, Prometheus `19112`, Grafana `19122`.
- port: web/dev preview `13002`, artifact/bootstrap HTTP 후보 `18085`, Edge OpenAI-compatible HTTP 후보 `18086`, Client WS `19004`, CP-Edge wire `19005`, compose Edge-Node TCP transport `19006`, native Edge-Node TCP 후보 `18087`, Edge metrics 후보 `19102`.
- 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://iop.ai.kr:18002`이다. Client wire 후보는 mac-mini local 기준 `ws://127.0.0.1:19004/client`, 기본 외부 후보 `ws://iop.ai.kr:19004/client`이다. dev-corp Edge runtime 기본 후보는 `iop.ai.kr:18087`이며, mac-mini runner/local legacy 경로를 Edge runtime 또는 Node `edge_addr`로 쓰지 않는다.
- model endpoint: dev-corp OpenAI-compatible base URL 기본 후보 `http://digitalplatform.iop.ai.kr:18086/v1`
- operator notice: 기존 dev-corp 사용자-facing URL은 변경하지 않는다. 현재 세션에서는 dev-corp runner 접근이 불가하므로 이 문서는 port/profile 정의와 향후 검증 절차만 기록한다.
- model endpoint: dev-corp OpenAI-compatible base URL 기본 후보 `https://digitalplatform.iop.ai.kr/v1`; direct Edge listener 확인이 필요할 때만 `http://digitalplatform.iop.ai.kr:18086/v1`
- credential: token/secret/API key 원문은 문서에 기록하지 않는다.
## 명령
@ -48,7 +47,7 @@ last_rule_updated_at: 2026-07-13
- lint:
- unit: `make test`
- smoke: `./scripts/e2e-smoke.sh`
- compose-smoke: mac-mini 환경에서 `IOP_EDGE_NODE_TOKEN`을 안전하게 주입한 뒤 `docker compose --env-file .env.dev-corp.example up -d postgres redis control-plane web prometheus grafana`
- compose-smoke: mac-mini 환경에서 `IOP_EDGE_NODE_TOKEN`을 안전하게 주입한 뒤 `docker compose --env-file .env.dev-corp.example up -d postgres redis control-plane edge web`
- compose-health: `curl -fsS http://127.0.0.1:18002/healthz`
- control-plane-status: mac-mini에서 `curl -fsS http://127.0.0.1:18002/edges/dev-corp-edge/status`
- provider-health: mac-mini에서 `curl -fsS http://192.168.2.2:8003/health`, `curl -fsS http://192.168.2.4:8005/health`, `curl -fsS http://192.168.2.3:8004/health`
@ -74,9 +73,8 @@ last_rule_updated_at: 2026-07-13
## 판정 기준
- dev-corp compose는 `COMPOSE_PROJECT_NAME=iop-dev-corp-agent`, `IOP_COMPOSE_NETWORK=iop-dev-corp-agent-net`, `IOP_COMPOSE_SUBNET=10.89.2.0/24` 사용한다.
- dev-corp compose는 `COMPOSE_PROJECT_NAME=iop-dev-corp-agent``IOP_COMPOSE_NETWORK=iop-dev-corp-agent-net` 사용한다.
- dev-corp compose가 local/test/dev 포트를 점유하지 않는다.
- dev-corp Control Plane 관측 그룹은 `control-plane`, `web`, `postgres`, `redis`, `prometheus`, `grafana`를 한 compose project로 묶고, Edge는 연결 검증이 필요할 때 같은 compose의 인접 service로 붙인다.
- edge console에서 메시지 2회가 각각 기대 payload를 포함한 `[node-*-message]`로 표시되고, command 결과가 edge 화면에 도착한다.
- node 로컬 `[node-message]` payload 라인 목록과 edge `[node-*-message]` payload 라인 목록이 run별로 내용/순서까지 동일해야 한다.
- Node bootstrap UX는 Edge가 출력한 완성된 bootstrap URL과 실제 positional token 값 하나만 포함하는 한 줄 명령 형태를 유지한다.

View file

@ -137,7 +137,7 @@ http://<edge-host>:18081/v1
- 현재 dev-corp provider-pool device mapping은 `gemma4:26b` -> Mac Studio provider capacity `5`, `ornith:35b` -> DGX Spark 01/02 provider 합산 capacity `8`이다. 세부 endpoint와 runtime args는 `agent-test/dev-corp/inventory.yaml`을 기준으로 한다.
- dev-corp provider-pool 안정 smoke: `think`, `reasoning_effort`, `thinking_token_budget`을 생략하고 현재 provider 기본값을 유지한다.
- 현재 dev-corp public capacity smoke 표준은 public OpenAI-compatible base `http://digitalplatform.iop.ai.kr:18086/v1`의 `/chat/completions`에서 `ornith:35b` 9/6 동시 요청과 `gemma4:26b` 9/6 동시 요청을 각각 확인하는 방식이다.
- 현재 dev-corp public capacity smoke 표준은 public OpenAI-compatible base `https://digitalplatform.iop.ai.kr/v1`의 `/chat/completions`에서 `ornith:35b` 9/6 동시 요청과 `gemma4:26b` 9/6 동시 요청을 각각 확인하는 방식이다.
- 일반 표준 caller의 `stream=false` 측정은 `/v1/chat/completions`에서 요청 파라미터만으로 확인한다.
- `include_reasoning=false`는 non-provider normalized route의 hide 동작 기준이다. dev-corp provider-pool pure `passthrough`에서는 client가 reasoning field를 선택적으로 무시/제거한다.
- `think=false` 또는 `reasoning_effort=none`은 hide-only 옵션이 아니라 thinking disable 요청이다. dev-corp 기본 안정 smoke에서는 쓰지 않는다.
@ -145,7 +145,7 @@ http://<edge-host>:18081/v1
예시 (dev-corp `gemma4:26b` provider-pool non-stream 측정, think 생략):
아래 `18081` 포트는 local Edge 예시다. dev-corp public smoke에서는 base URL을 `http://digitalplatform.iop.ai.kr:18086/v1`로 바꾼다.
아래 `18081` 포트는 local Edge 예시다. dev-corp public smoke에서는 base URL을 `https://digitalplatform.iop.ai.kr/v1`로 바꾼다. Direct Edge listener `http://digitalplatform.iop.ai.kr:18086/v1`도 동작하지만 사용자-facing 기본값은 포트 없는 public URL이다.
```bash
curl -fsS http://<edge-host>:18081/v1/chat/completions \