11 KiB
11 KiB
| domain | last_rule_review_commit | last_rule_updated_at |
|---|---|---|
| node | 4695bcbc60 |
2026-07-30 |
node
목적 / 책임
Edge에 연결되어 실제 adapter execution을 수행하는 IOP 노드 에이전트 영역이다. Edge에서 들어온 실행·취소·조회성 명령을 공통 Agent Runtime 요청으로 변환하고, 공통 registry/provider를 Node transport와 연결하며, 실행 이벤트와 현재 단계의 로컬 실행 이력을 관리한다.
포함 경로
apps/node/cmd/node/— node CLI 진입점과 서브커맨드apps/node/internal/bootstrap/— fx 의존성 주입과 adapter registry 구성apps/node/internal/node/— transport handler 구현과 실행 오케스트레이션apps/node/internal/router/— RunRequest를 ExecutionSpec으로 해석하는 라우팅apps/node/internal/transport/— edge와의 TCP/protobuf 세션 및 메시지 처리apps/node/internal/adapters/— Node-owned mock/ollama/vllm/OpenAI-compatible adapter와 Edge config translationapps/node/internal/store/— SQLite 실행 이력 저장apps/node/README.md— node 실행 흐름과 adapter/session 경계 설명
제외 경로
apps/edge/— Node를 관리하는 실행 그룹 컨트롤러 영역apps/control-plane/— 여러 Edge 연결 관리와 운영 제어 API 제공 영역apps/worker/— 비동기 작업 처리 예정 영역packages/go/agentruntime/,packages/go/agentprovider/cli/— Node가 소비하는 공통 provider/runtime 구현packages/go/의 나머지 영역 — 여러 앱이 공유하는 Go 공통 패키지proto/— 앱 간 메시지 계약
주요 구성 요소
agentruntime.Provider/agentruntime.Router— 공통 provider 실행과 Node routing 계약agentruntime.CommandHandler/agentruntime.SessionTerminator— command와 logical session 종료 optional 계약agentruntime.ProviderProber/agentruntime.ProviderTunnelAdapter— provider availability probe와 raw tunnel optional 계약node.runRequestFromProto()/node.runEventToProto()— Edge-Node protobuf와 공통 runtime request/event translationnode.Node—transport.Handler구현체이자 실행 파이프라인 조정자node.runManager— run ID 기준runHandle(cancel, done) 등록/해제/취소 관리;node.Node내부에서만 사용node.Node.OnConfigRefresh()— Edge가 보낸NodeConfigRefreshRequest를 적용하고 adapter registry를 live swapnode.Node.OnProviderTunnelRequest()— provider tunnel 요청을 지원 adapter에 전달하고 tunnel frame을 edge session으로 반환node.sessionSink— adapterRuntimeEvent를 protoRunEvent로 변환해 edge session으로 보내는 sinktransport.Session— edge와 연결된 node 세션 및 메시지 처리bootstrap.runtimeSupervisor— 초기 연결과 reconnect를 직렬화하고 단일 active Edge session, bounded retry, fatal shutdown을 소유하는 Node lifecycle supervisorquota-probe— 공통 CLI status checker 결과를 content-addressedQuotaSnapshotJSON으로 내보내는 내부 진단 commandagentruntime.Registry/agentruntime.LifecycleProvider— provider 등록/조회와 start/stop lifecycle 관리adapters.ConfigSet/adapters.DiffConfigSets()— Edge config payload에서 adapter registry/runtime snapshot을 만들고 refresh diff를 산출adapters.BuildFromPayload()— edge에서 받은NodeConfigPayload로Registry를 초기화하는 factoryadapters/ollama.Ollama— Ollama/api/chatstreaming,/api/tagscapabilities,/api/*command passthrough를 처리하는 adapteradapters/openai_compat.Adapter— OpenAI-compatible/v1/models, chat completions, provider label/header/options passthrough, provider tunnel을 처리하는 adapteradapters/vllm.Vllm— vLLM/SGLang류 OpenAI-compatible endpoint를 직접 호출하고 provider tunnel을 처리하는 adapterstore.Store— 실행 상태와 결과 저장
유지할 패턴
- transport/proto 타입은
apps/node/internal/node/runtime_bridge.go에서agentruntime타입으로 변환한다. - 내부 실행 식별자는
adapter + target을 사용한다. 외부 OpenAI-compatible API나 legacy placeholder를 제외하고model을 내부 실행 대표 용어로 되돌리지 않는다. - Edge-Node runtime wire와 Edge가 내려주는 config payload 계약 상세는
agent-contract/inner/edge-node-runtime-wire.md와agent-contract/inner/edge-config-runtime-refresh.md를 기준으로 확인한다. - Node-owned 어댑터 추가 시
agentruntime.Provider를 구현하고adapters.BuildFromPayload()에서 공통 registry에 등록한다. 여러 host가 함께 사용할 provider는 platform-common 경계로 둔다. - 여러 adapter instance는
agentruntime.Registry.RegisterKeyed(instanceKey, typeName, provider)로 등록하고, router lookup은 instance key를 우선한다. legacy type-name lookup은 단일 instance일 때만 안전하다. - field Node의 기본 시작 경로는 Edge bootstrap script가 만든 최소 config와 Edge가 RegisterResponse로 내려주는 adapter/runtime payload다. 사용자가 기본 경로에서 node config를 직접 작성하거나 adapter/provider 세부값을 명령줄에 넣는 흐름을 만들지 않는다.
- Node runtime 작업 디렉터리나 store/workspace 경로는 대상 OS에서 쓰기 가능한 기본값이어야 한다. Edge가 특정 node에
workspace_root를 내려줄 때 macOS/dev host 절대 경로(/Users/...) 같은 값을 Linux/Windows node에 재사용하지 않으며, OS별 경로가 필요하면 Edge 설정에 미리 굽는다. - 실행 취소는 run ID 기준으로
runManager에 등록하고 실행 종료 시 반드시deregister로 해제한다. CancelAction_CANCEL_RUN은 현재 run 취소,CancelAction_TERMINATE_SESSION은 logical session 종료로 구분한다.ProviderTunnelRequest는 run ID/tunnel ID 기준으로runManager에 등록하고,ProviderTunnelFrame은 RunEvent stream과 별도 proto message로 edge에 반환한다. tunnel 지원은agentruntime.ProviderTunnelAdapter를 구현한 adapter에만 허용한다.NodeCommandRequest는 실행 요청과 분리해USAGE_STATUS,CAPABILITIES,SESSION_LIST,TRANSPORT_STATUS같은 조회/제어성 명령으로 처리한다.OLLAMA_APIcommand는 Ollama adapter 내부의 제한된/api/*passthrough로 처리하고, Edge/OpenAI surface가 node HTTP client를 우회해 직접 Ollama에 붙는 구조로 확장하지 않는다.agentruntime.Registry의 start/stop은 bootstrap lifecycle에서만 호출하고 개별 provider에서 직접 호출하지 않는다.- Edge 연결 lifecycle은
runtimeSupervisor하나가 초기 dial, active session 종료 대기, reconnect와 shutdown을 직렬화해 동시에 둘 이상의 dial/session이 생기지 않도록 유지한다. quota-probe는 provider 원문이나 credential을 내보내지 않고 공통 status package가 정규화·검증할 수 있는 quota evidence만 출력한다.response_idle_timeout_ms,startup_idle_timeout_ms,completion_marker,resume_args,mode같은 CLI profile 설정은 edge config/proto payload를 통해 주입하고 node 코드에 target별 상수를 늘리지 않는다.- config refresh는
adapters.BuildConfigSet()로 next registry를 만들고 start 성공 후 router registry를 live swap한다. 기존 in-flight run은 old adapter snapshot으로 마무리하고, old registry stop은 active run drain 뒤에 처리한다. - Node-wide runtime concurrency는 admission source로 되살리지 않는다. per-adapter
Capabilities().MaxConcurrency가 adapter gate capacity의 기준이다. - Ollama adapter는 내부 target을 model 이름으로 사용하고,
context_size는options.num_ctx의 강제 소유값으로 주입한다. 요청 input에 명시된options.num_ctx가 있어도 Edge-ownedcontext_size가 항상 우선한다.context_size가 0이면 request 값을 그대로 사용한다. - vLLM/openai_compat adapter는 OpenAI-compatible provider endpoint를 호출하되, Edge가 선택한 served model target과 provider header/auth/passthrough 정책을 보존한다.
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/config-refresh/provider-tunnel 경로를 바꾼 뒤에는testingdomain rule의 작업 후 검증 기준을 따른다.
다른 도메인과의 경계
- edge: edge는 node 연결 등록, adapter/runtime 설정 전달, 라우팅 진입, stream relay를 담당한다. node는 edge가 보낸 실행/취소/명령 요청을 처리하고 이벤트와 명령 응답을 돌려준다.
- platform-common: node는
packages/go/agentruntime,packages/go/agentprovider/cli, config/events/observability와 proto 생성물을 소비한다. 공통 provider/runtime 구현과 설정/event helper는 platform-common이 소유하고 Node는 wire translation과 실행 조정을 소유한다. - control-plane: control-plane은 Node가 아니라 Edge를 통해 시스템을 제어한다. node는 control-plane 직접 연결/직접 스케줄링을 전제로 하지 않는다.
금지 사항
- node 도메인 내부에서 gRPC, WebSocket 기본 transport, actor/FSM/plugin framework를 새 기본 구조로 도입하지 않는다.
proto/gen/iop/*.pb.go생성 파일을 직접 수정하지 않는다.- 새 어댑터 구현을
node.Node에 직접 분기문으로 박아 넣지 않는다. - provider tunnel 지원을 RunEvent delta에 섞거나 OpenAI-compatible raw response를 node stdout parser처럼 취급하지 않는다.
- config refresh 중 old registry를 in-flight run이 끝나기 전에 stop해 기존 실행을 끊지 않는다.
- edge-local console, OpenAI-compatible HTTP, A2A 같은 입력 표면 책임을 node로 끌어오지 않는다.
- placeholder 상태인 control-plane/worker 책임을 node에 임시로 흡수하지 않는다.
- CLI provider별 session/conversation 상태를 Node에 다시 구현하지 않는다. provider 세부 상태는
packages/go/agentprovider/cli내부에 두고 공통agentruntimeinterface에는 host-neutral 의미만 노출한다. - field bootstrap 기본 안내에서 사용자가
IOP_HOME,IOP_NODE_CONFIG,IOP_NODE_METRICS_PORT같은 환경 변수를 먼저 선언해야만 동작하는 형태를 요구하지 않는다. 필요한 값은 bootstrap 기본값 또는 Edge-provided config로 처리하고, 환경 변수는 optional override로만 둔다.