iop/agent-spec/runtime/edge-node-execution.md

9.6 KiB

spec_doc_type spec_id status source_evidence
spec runtime/edge-node-execution 부분
type path notes
contract agent-contract/inner/edge-node-runtime-wire.md Edge-Node register, run stream, cancel, node command, config refresh wire 계약
type path notes
code proto/iop/runtime.proto RunRequest, RunEvent, CancelRequest, NodeCommandRequest, RegisterRequest, NodeConfigPayload 원문
type path notes
code apps/edge/internal/transport/server.go Edge TCP proto-socket server, node register handshake, event relay
type path notes
code apps/edge/internal/service/run_dispatch.go surface-neutral SubmitRun, provider tunnel dispatch, cancel request 생성
type path notes
code apps/node/internal/node/node.go Node transport handler, adapter 실행, cancel, command, config refresh 처리
type path notes
code apps/node/internal/adapters/openai_compat/openai_compat.go OpenAI-compatible provider usage payload를 RuntimeEvent usage로 변환
type path notes
code apps/node/internal/adapters/vllm/vllm.go vLLM usage payload의 reasoning/cached token 변환
type path notes
test apps/edge/internal/transport/server_test.go Edge transport server 단위 검증
type path notes
test apps/node/internal/node/node_test.go Node 실행 처리 단위 검증
type path notes
test apps/node/internal/adapters/openai_compat/openai_compat_test.go OpenAI-compatible provider usage breakdown 검증
type path notes
test apps/node/internal/adapters/vllm/vllm_test.go vLLM usage breakdown 검증

스펙: Edge-Node 실행 경로

목적

Edge와 Node 사이에 현재 구현된 실행 기능을 기능 단위로 정리한다. 코드 배치 규칙이나 도메인별 작업 지침은 domain rule을 따른다.

기능 목록

기능 설명
Node token 등록 Node가 Edge TCP proto-socket endpoint에 연결한 뒤 RegisterRequest.token으로 등록한다.
Node config payload 전달 Edge가 token에 매칭되는 node record를 찾아 NodeConfigPayloadRegisterResponse에 담아 내려준다.
등록 실패 처리 unknown token, duplicate connection, config payload build failure를 register response와 node lifecycle event로 표현한다.
실행 요청 전달 Edge service가 SubmitRun 요청을 RunRequest로 만들어 선택된 Node에 보낸다. 명시 node가 없고 연결 node가 1개면 single-node fallback을 사용한다.
adapter 실행 Node가 RunRequest.adapter로 adapter instance를 찾고 adapter Execute를 호출한다. admission은 adapter Capabilities().MaxConcurrency 기준이다.
실행 이벤트 스트림 Node adapter가 낸 start, delta, reasoning_delta, complete, error, cancelled 이벤트를 RunEvent로 Edge에 relay한다.
provider raw tunnel Edge가 ProviderTunnelRequest를 보내면 Node가 provider HTTP/SSE response를 열고 ordered ProviderTunnelFrame으로 status/header/body/end/error/usage 후보를 relay한다.
mixed provider dispatch wire provider-pool model group은 Edge service에서 provider를 먼저 선택한 뒤 OpenAI-compatible provider에는 ProviderTunnelRequest, Ollama/CLI/native provider에는 normalized RunRequest를 보낸다.
usage breakdown relay RunEvent.usageProviderTunnelFrame.usage는 provider가 보고한 input/output/reasoning/cached input token count를 Edge 관측 계층으로 전달한다.
terminal event 합성 adapter가 terminal event 없이 종료하면 Node가 terminal event를 합성한다.
run cancel Edge가 CancelRequest를 보내면 Node run manager가 active run context를 cancel한다.
logical session 종료 adapter가 SessionTerminator를 구현한 경우 TERMINATE_SESSION으로 session을 종료한다. 모든 adapter 공통 기능은 아니다.
Node command capabilities, transport status, usage status, session list, ollama API 계열 조회/제어성 command를 실행 요청과 분리해 처리한다.
Node local run store Node가 run id, adapter, target, session id, background, status, timestamps, error를 SQLite에 기록한다.
Edge event fanout Edge event bus가 run event와 node lifecycle event를 in-process subscriber에게 fanout한다.

범위

  • 포함: Edge-Node TCP/protobuf transport, register handshake, run/cancel/command, provider raw tunnel, Node adapter execution, Edge event bus fanout, Node local run store.
  • 제외: OpenAI-compatible/A2A HTTP request shape, Control Plane 운영 wire, provider-pool config refresh 상세, durable global history/audit.

주요 흐름

Node 등록

sequenceDiagram
  participant Node
  participant EdgeTransport as Edge transport
  participant NodeStore as Edge NodeStore

  Node->>EdgeTransport: TCP connect
  Node->>EdgeTransport: RegisterRequest(token)
  EdgeTransport->>NodeStore: token으로 NodeRecord 조회
  alt token valid
    EdgeTransport->>EdgeTransport: NodeConfigPayload 생성
    EdgeTransport-->>Node: RegisterResponse(accepted=true, config)
    EdgeTransport->>EdgeTransport: live registry 등록
  else token invalid or duplicate
    EdgeTransport-->>Node: RegisterResponse(accepted=false, reason)
  end

실행 요청과 이벤트

sequenceDiagram
  participant Caller
  participant EdgeService as Edge service
  participant EdgeTransport as Edge transport
  participant Node
  participant Adapter

  Caller->>EdgeService: SubmitRun(adapter, target, input)
  EdgeService->>EdgeService: Node 선택
  EdgeService->>EdgeTransport: RunRequest
  EdgeTransport->>Node: RunRequest
  Node->>Node: adapter instance resolve
  Node->>Adapter: Execute(spec)
  Adapter-->>Node: RuntimeEvent(delta/start/complete)
  Node-->>EdgeTransport: RunEvent
  EdgeTransport-->>Caller: run stream

Provider raw tunnel

sequenceDiagram
  participant OpenAI as Edge OpenAI surface
  participant EdgeService as Edge service
  participant Node
  participant Provider

  OpenAI->>EdgeService: SubmitProviderTunnel
  EdgeService->>Node: ProviderTunnelRequest
  Node->>Provider: HTTP/SSE request
  Provider-->>Node: status/header/body
  Node-->>EdgeService: ProviderTunnelFrame sequence
  EdgeService-->>OpenAI: request-bound frame stream

취소와 session 종료

sequenceDiagram
  participant EdgeService as Edge service
  participant Node
  participant Adapter

  alt cancel run
    EdgeService->>Node: CancelRequest(CANCEL_RUN, run_id)
    Node->>Node: active run context cancel
  else terminate session
    EdgeService->>Node: CancelRequest(TERMINATE_SESSION, adapter, target, session_id)
    Node->>Adapter: TerminateSession(target, session_id)
  end

계약

  • iop.edge-node-runtime-wire: agent-contract/inner/edge-node-runtime-wire.md
  • proto 원문: proto/iop/runtime.proto

설정/데이터/이벤트

  • Edge의 node source of truth는 configs/edge.yamlpackages/go/confignodes[] 구조다.
  • RunEvent는 adapter execution stream이고, EdgeNodeEvent는 node lifecycle/control event다.
  • ProviderTunnelFrame.body는 OpenAI-compatible provider passthrough의 source of truth이며 RunEvent.delta나 Edge event bus payload로 보내지 않는다.
  • ProviderTunnelFrame.usagemetadata는 sideband observation 후보이며 pure passthrough body에 합쳐지지 않는다.
  • provider-pool mixed dispatch에서 ProviderTunnelRequestRunRequest 중 어느 wire를 사용할지는 selected provider capability에서 파생되며, client request metadata selector로 결정하지 않는다.
  • Usage.reasoning_tokensUsage.cached_input_tokens는 provider가 별도 보고한 경우에만 채워지는 optional breakdown이다.
  • Node local DB는 기본 file:iop.db?cache=shared&mode=rwc로 열린다.
  • heartbeat는 Edge와 Node transport 양쪽에서 30초 interval, 45초 wait 기준을 사용한다.

검증

  • go test ./apps/edge/internal/transport ./apps/edge/internal/service ./apps/edge/internal/node
  • go test ./apps/node/internal/transport ./apps/node/internal/node ./apps/node/internal/router ./apps/node/internal/adapters ./apps/node/internal/store
  • go test ./apps/node/internal/adapters/openai_compat ./apps/node/internal/adapters/vllm
  • make test-e2e - Edge-Node와 OpenAI 보조 smoke를 함께 실행한다. runtime path 변경 시 사용자 흐름 검증을 대체하지 않는다.

한계와 주의사항

  • mTLS helper는 존재하지만 현재 Edge-Node transport 설정에는 연결되어 있지 않다.
  • TERMINATE_SESSION은 모든 adapter에 공통으로 보장되는 기능이 아니다.
  • Node store는 전역 query/audit API가 아니다. 상위 운영 이력은 별도 설계가 필요하다.
  • provider raw tunnel은 기존 socket 위 request-bound stream이다. 별도 Node stream server나 Edge의 provider direct access 경로가 아니다.
  • usage breakdown은 provider-reported 값만 전달한다. provider가 보고하지 않은 reasoning token을 Node나 Edge가 추정하지 않는다.

변경 기록

  • 2026-07-07: 현재 코드, 계약, README 기준으로 bootstrap spec 작성.
  • 2026-07-07: 기능 목록 중심으로 축소하고 주요 흐름을 Mermaid sequence diagram으로 정리.
  • 2026-07-08: Provider raw tunnel 실행 흐름과 passthrough event/data 경계를 현재 계약 기준으로 반영.
  • 2026-07-10: RunEvent.usage/ProviderTunnelFrame.usage의 input/output/reasoning/cached input breakdown 전달 기준을 반영.
  • 2026-07-12: Model Group Mixed Provider Dispatch 종료 검토 기준으로 selected provider capability에서 파생되는 ProviderTunnelRequest/RunRequest 분기 경계를 반영.