8.2 KiB
8.2 KiB
| domain | last_rule_review_commit | last_rule_updated_at |
|---|---|---|
| node | aaf35e61a9 |
2026-05-31 |
node
목적 / 책임
Edge에 연결되어 실제 adapter execution을 수행하는 IOP 노드 에이전트 영역이다. edge에서 들어온 실행·취소·조회성 명령을 runtime 요청으로 변환하고, 라우팅된 어댑터를 실행하며, 실행 이벤트와 현재 단계의 로컬 실행 이력을 관리한다.
포함 경로
apps/node/cmd/node/— node CLI 진입점과 서브커맨드apps/node/internal/bootstrap/— fx 의존성 주입과 adapter registry 구성apps/node/internal/node/— transport handler 구현과 실행 오케스트레이션apps/node/internal/runtime/— node 도메인 타입과 핵심 인터페이스apps/node/internal/router/— RunRequest를 ExecutionSpec으로 해석하는 라우팅apps/node/internal/transport/— edge와의 TCP/protobuf 세션 및 메시지 처리apps/node/internal/adapters/— mock/ollama/vllm/cli 실행 어댑터apps/node/internal/store/— SQLite 실행 이력 저장apps/node/README.md— node 실행 흐름과 adapter/session 경계 설명
제외 경로
apps/edge/— Node를 관리하는 실행 그룹 컨트롤러 영역apps/control-plane/— 여러 Edge 연결 관리와 운영 제어 API 제공 영역apps/worker/— 비동기 작업 처리 예정 영역packages/— 여러 앱이 공유하는 공통 패키지proto/— 앱 간 메시지 계약
주요 구성 요소
runtime.Adapter— adapter target 실행 계약runtime.Router— 실행 요청을 구체적인ExecutionSpec으로 변환하는 계약runtime.CommandHandler— adapter별NodeCommandRequest처리 optional 계약runtime.SessionTerminator— logical session 종료를 지원하는 optional 계약node.Node—transport.Handler구현체이자 실행 파이프라인 조정자node.runManager— run ID 기준runHandle(cancel, done) 등록/해제/취소 관리;node.Node내부에서만 사용node.sessionSink— adapterRuntimeEvent를 protoRunEvent로 변환해 edge session으로 보내는 sinktransport.Session— edge와 연결된 node 세션 및 메시지 처리adapters.Registry— 어댑터 등록/조회 및LifecycleAdapterstart/stop lifecycle 관리 (실패 시 역순 롤백)adapters.LifecycleAdapter— start/stop lifecycle이 필요한 어댑터의 optional 인터페이스adapters.BuildFromPayload()— edge에서 받은NodeConfigPayload로Registry를 초기화하는 factoryadapters/cli.CLI— one-shot, persistent TUI, persistent-lazy, codex-exec, antigravity-print, opencode-sse profile을 실행하는 CLI adapteradapters/cli.clineJSONEmitter— Cline JSON output을RuntimeEventdelta/error로 변환하는 emitteradapters/cli.executeAntigravityPrint()— Antigravity print mode conversation id를 IOP logical session별로 보관하고 resume_args로 후속 요청을 재개adapters/cli.executeOpencodeSSE()— opencode serve HTTP/SSE session을 실행하거나--attach로 외부 server에 연결해 delta를 relayadapters/cli.executePersistent()— terminal/persistent profile의 completion marker, idle timeout, output filter를 처리adapters/cli/status— claude/codex/antigravity CLI 상태 파서 (사용량 한도, reset 시각 등)adapters/cli.lineEmitter— stdout 한 줄을 파싱해RuntimeEvent를 반환하는 내부 인터페이스;emitters.go에서 format별로 등록adapters/ollama.Ollama— Ollama/api/chatstreaming,/api/tagscapabilities,/api/*command passthrough를 처리하는 adapterstore.Store— 실행 상태와 결과 저장
유지할 패턴
runtime패키지에는 도메인 타입과 인터페이스를 두고 구체 구현 의존성을 넣지 않는다.- transport/proto 타입은
node.Node경계에서 runtime 타입으로 변환한다. - 내부 실행 식별자는
adapter + target을 사용한다. 외부 OpenAI-compatible API나 legacy placeholder를 제외하고model을 내부 실행 대표 용어로 되돌리지 않는다. - 어댑터 추가 시
runtime.Adapter를 구현하고adapters.BuildFromPayload()또는 bootstrap registry에 등록한다. - 실행 취소는 run ID 기준으로
runManager에 등록하고 실행 종료 시 반드시deregister로 해제한다. CancelAction_CANCEL_RUN은 현재 run 취소,CancelAction_TERMINATE_SESSION은 logical session 종료로 구분한다.NodeCommandRequest는 실행 요청과 분리해USAGE_STATUS,CAPABILITIES,SESSION_LIST,TRANSPORT_STATUS같은 조회/제어성 명령으로 처리한다.OLLAMA_APIcommand는 Ollama adapter 내부의 제한된/api/*passthrough로 처리하고, Edge/OpenAI surface가 node HTTP client를 우회해 직접 Ollama에 붙는 구조로 확장하지 않는다.adapters.Registry의 start/stop은 bootstrap lifecycle에서만 호출하고 개별 adapter에서 직접 호출하지 않는다.- cli adapter의 출력 format별 파싱 로직은
lineEmitter구현체로 분리하고node.Node에 분기문으로 박지 않는다. - CLI profile mode별 세부 실행(
persistent-lazy,codex-exec,antigravity-print,opencode-sse)은adapters/cli내부에 두고,runtime.Adapter계약 밖으로 새 transport를 노출하지 않는다. cline-json,opencode-json,codex-json,claude-json같은 provider별 stdout parser는adapters/cliemitter로 등록하고 runtime 공통 이벤트로만 외부에 노출한다.- CLI logical session은
(target, session_id)로 식별한다. Antigravity conversation id, Codex external id, opencode session/server 상태를 전역 target 단위로 공유하지 않는다. response_idle_timeout_ms,startup_idle_timeout_ms,completion_marker,resume_args,mode같은 CLI profile 설정은 edge config/proto payload를 통해 주입하고 node 코드에 target별 상수를 늘리지 않는다.- Ollama adapter는 내부 target을 model 이름으로 사용하고,
context_size는options.num_ctxdefault로만 주입한다. 요청 input에 명시된options.num_ctx가 있으면 이를 덮어쓰지 않는다. RuntimeEvent는 start/delta/reasoning_delta/complete/error/cancelled 타입을 유지하고, adapter별 streaming 표현을 node 외부로 새 이벤트 체계로 노출하지 않는다.- node 내부 변경은 가능한 대상 패키지 테스트를 먼저 추가하거나 갱신한다.
apps/node/cmd/node/**,apps/node/internal/bootstrap/**,apps/node/internal/transport/**,apps/node/internal/node/**,apps/node/internal/router/**,apps/node/internal/adapters/**,apps/node/internal/store/**의 실행 요청/응답/stream/cancel/status/session 경로를 바꾼 뒤에는testingdomain rule의 작업 후 검증 기준을 따른다.
다른 도메인과의 경계
- edge: edge는 node 연결 등록, adapter/runtime 설정 전달, 라우팅 진입, stream relay를 담당한다. node는 edge가 보낸 실행/취소/명령 요청을 처리하고 이벤트와 명령 응답을 돌려준다.
- platform-common: node는
packages/config,packages/events,packages/observability,proto/gen/iop등을 사용하지만 공통 타입/설정/event helper 자체의 소유자는 platform-common이다. - control-plane: control-plane은 Node가 아니라 Edge를 통해 시스템을 제어한다. node는 control-plane 직접 연결/직접 스케줄링을 전제로 하지 않는다.
금지 사항
- node 도메인 내부에서 gRPC, WebSocket 기본 transport, actor/FSM/plugin framework를 새 기본 구조로 도입하지 않는다.
proto/gen/iop/*.pb.go생성 파일을 직접 수정하지 않는다.- 새 어댑터 구현을
node.Node에 직접 분기문으로 박아 넣지 않는다. - edge-local console, OpenAI-compatible HTTP, A2A 같은 입력 표면 책임을 node로 끌어오지 않는다.
- placeholder 상태인 control-plane/worker 책임을 node에 임시로 흡수하지 않는다.
- CLI provider별 session/conversation 상태를
runtime공통 인터페이스로 성급히 승격하지 않는다. provider 세부 상태는adapters/cli내부에 둔다.