# edge — Edge API Gateway 외부 클라이언트에 OpenAI-compatible HTTP API를 노출하고, IOP 내부 TCP 프로토콜을 통해 node로 요청을 라우팅한다. **현재 상태: 초기 구현** node 등록/레지스트리/transport와 edge 콘솔 기반 수동 통신 테스트가 구현되어 있다. ## 원격 Codex CLI 수동 테스트 `bin/edge.sh`는 edge 서버를 열고 입력 프롬프트를 제공한다. `bin/node.sh`는 원격 edge 주소로 접속해 등록한 뒤, edge에서 보낸 `RunRequest`를 cli/codex one-shot process로 실행한다. 테스트 파라미터는 `configs/edge.yaml`, `configs/node.yaml`에 하드코딩한다. **전제 조건**: node 호스트의 PATH에 `claude` 명령이 있어야 한다. 같은 `cli` 어댑터 안에 `gemini`, `codex`, `opencode` profile도 포함할 수 있으며, 각각 `gemini --approval-mode yolo -p `, `codex exec --dangerously-bypass-approvals-and-sandbox`, `opencode run --model ollama-dgx/qwen3.6:35b-a3b-bf16 --format default --dangerously-skip-permissions `처럼 headless 조합으로 설정한다. Claude는 `claude -p --dangerously-skip-permissions --output-format stream-json --include-partial-messages --verbose ` 형태로 호출되어 token-level streaming이 활성화된다. 실행 순서: 1. edge 호스트에서 `configs/edge.yaml`의 `server.listen`, `nodes[].token`을 확인한다. `console.adapter=cli`, `console.agent=claude`, `console.session_id=default`가 기본값이다. 2. node 호스트에서 `configs/node.yaml`의 `transport.edge_addr`를 edge 호스트 주소로, `transport.token`을 edge token과 같게 맞춘다. 3. edge 호스트의 `9090/tcp` 포트를 node 호스트에서 접근 가능하게 연다. 4. edge 호스트에서 `./bin/edge.sh` 5. node 호스트에서 `./bin/node.sh` — node는 edge에서 받은 입력을 `claude -p --dangerously-skip-permissions --output-format stream-json ... ` one-shot process로 실행한다. 6. edge 콘솔에서 `/nodes`로 node 등록을 확인한다. 7. (선택 사항) node가 여러 대일 경우 `/node `로 대상을 선택한다. 1대일 경우 자동 선택된다. 8. edge 콘솔의 `edge>` 프롬프트에 메시지를 입력한다. 9. `[node-{alias}-event]` 라인으로 실행 상태를, `[node-{alias}-message]` 라인으로 Codex 응답을 확인한다. 10. edge 콘솔에서 `/exit` 또는 `quit`로 종료한다. 예상 출력: ```text edge> hello [edge] sent run_id=manual-... node=local-node adapter=cli agent=claude session=default background=false [node-local-node-event] start run_id=manual-... [node-local-node-event] complete run_id=manual-... detail="cli execution complete" [node-local-node-message] ``` ## Console 명령 | 명령 | 설명 | |---|---| | `/nodes` | 연결된 node 목록 확인. 선택된 node는 `*`로 표시됨. | | `/node ` | 요청을 보낼 명시적 node 선택 | | `/session ` | 현재 console이 사용할 logical session 변경 | | `/background on\|off` | background 실행 모드 토글 (on: 응답 기다리지 않음) | | `/terminate-session` | 현재 `adapter/agent/session_id`의 worker process 종료 | | `/status` | 현재 선택된 agent/profile의 사용량(Usage Status) 조회 | | `/exit` | 콘솔 종료 | ## 멀티포인트 라우팅 (Multi-Point Routing) edge는 여러 대의 node가 동시에 연결된 환경을 지원한다. - **명시적 선택**: `/node ` 또는 `/node ` 명령으로 특정 node를 고정할 수 있다. - **Single-node Fallback**: 연결된 node가 정확히 1개일 때는 선택 없이도 해당 node가 자동 지정된다. - **Ambiguous Error**: node가 2개 이상일 때 node 선택 없이 메시지를 보내면 에러가 발생하며 선택을 요구한다. - **Node-aware Events**: 모든 이벤트와 메시지 출력에 `[node-{alias}-...]` 접두어가 붙어 출처를 식별할 수 있다. ## Transport 1개 · Logical Session 여러 개 edge-node transport 연결은 **node id당 1개** TCP 연결만 유지한다. 그 연결 위에서 edge는 `session_id`를 지정해 node의 CLI adapter가 관리하는 개별 worker process에 접근한다. 같은 `codex` profile이라도 `session_id`가 다르면 독립적인 장수 process다. - **cancel run**: 현재 run 중단, session process 유지 - **terminate session**: session process 명시 종료 (`/terminate-session` 또는 `CancelAction_TERMINATE_SESSION`) 프롬프트 없이 TCP/protobuf edge 서버만 실행하려면 기존처럼 `go run ./apps/edge/cmd/edge serve -c configs/edge.yaml`를 사용한다.