iop/agent-spec/runtime/provider-pool-config-refresh.md
toki 51de0e259e docs(spec,contract,roadmap,scripts): 계약·스펙·로드맵 문서 갱신 및 e2e 테스트 보완
- edge-node-runtime-wire 계약 스키마 동기화
- edge-node-execution, provider-pool-config-refresh 스펙 갱신
- provider-resource-admission-ownership-alignment 마일스톤 상태 동기화
- control-plane-portal-ops phase 신규 추가 (multi-edge-operations)
- e2e-smoke: 재연결 테스트 플로우, bind timeout, reconnect 설정 반영
2026-07-22 18:11:24 +09:00

11 KiB

spec_doc_type spec_id status source_evidence
spec runtime/provider-pool-config-refresh 부분
type path notes
contract agent-contract/inner/edge-config-runtime-refresh.md Edge config, provider pool, config refresh, Node payload 연결 계약
type path notes
code packages/go/config/provider_types.go provider/model catalog 설정 타입
type path notes
code packages/go/config/load.go Edge config load와 default 적용
type path notes
code packages/go/config/validate.go provider/model 참조와 numeric bound 검증
type path notes
code configs/edge.yaml provider-pool 권장 설정 예시와 live refresh 설정 예시
type path notes
code apps/edge/internal/service/provider_resolution.go provider 후보 해석과 capacity/priority policy 구성
type path notes
code apps/edge/internal/service/model_queue_admission.go provider queue와 long-context slot admission
type path notes
code apps/edge/internal/configrefresh/classify.go dry-run/apply classification과 changed path report 생성
type path notes
code apps/edge/internal/bootstrap/runtime.go mutable config apply, runtime snapshot 교체, Node refresh push
type path notes
code apps/edge/internal/node/mapper.go provider-first NodeConfigPayload compile과 OpenAI-compatible provider label 보존
type path notes
test packages/go/config/provider_catalog_config_test.go provider/model catalog load와 queue 설정 검증
type path notes
test packages/go/config/provider_catalog_validation_config_test.go provider/model 참조와 validation 검증
type path notes
test apps/edge/internal/node/mapper_test.go provider-first adapter payload, Seulgivibe alias/provider label 검증
type path notes
test apps/edge/internal/configrefresh/node_runtime_classify_test.go node runtime과 model catalog refresh classification 검증
type path notes
test apps/edge/internal/configrefresh/provider_classify_test.go provider field refresh classification 검증
type path notes
test apps/edge/internal/bootstrap/reconnect_readiness_integration_test.go dispatch-ready reconnect가 기존 queued waiter를 실제 Node terminal까지 수렴시키는 검증

스펙: Provider Pool과 Config Refresh

목적

Edge 설정에서 provider-pool이 어떻게 모델 실행 후보를 고르고, 어떤 설정 변경이 재시작 없이 반영되는지 설명한다.

기능 목록

기능 설명
model catalog models[].id는 외부 OpenAI-compatible model key이자 provider-pool ModelGroupKey다.
provider mapping models[].providers는 provider id를 실제 served model name으로 매핑한다.
node provider catalog nodes[].providers[]는 Node 아래 resource/provider catalog이며 provider id는 Edge config에서 전역 유일해야 한다.
config validation config load가 provider id 참조, served model membership, numeric bounds, long-context budget을 검증한다.
provider 후보 필터링 dispatch는 dispatch-ready connection을 가진 Node의 provider 후보 중 catalog match, enabled, healthy/available, capacity 조건을 만족하는 후보만 사용한다.
capacity/priority dispatch in-flight가 capacity 미만인 후보를 고르고, 동률이면 낮은 priority와 round-robin을 적용한다.
mixed provider execution path 같은 model group의 OpenAI-compatible provider와 Ollama/CLI/native provider를 같은 후보군으로 두며, 선택된 provider capability로 passthrough 또는 normalized 실행 경로를 결정한다.
long-context admission estimated input token이 threshold 이상이면 context_class=long으로 분류하고, provider long slot이 있으면 일반 capacity slot과 함께 점유한다.
config refresh dry-run/apply loopback admin HTTP POST /refresh가 candidate config를 dry-run 또는 apply한다.
refresh classification listener, Edge identity, bootstrap path, adapter structural 변경 등은 restart-required로 분류한다.
mutable apply 적용 가능한 변경은 Edge Cfg, NodeStore, service/input model catalog, OpenAI long-context threshold를 copy-on-write로 교체한다.
Node config refresh push 변경이 있으면 Edge가 dispatch-ready Node에 node-specific NodeConfigRefreshRequest를 push한다. accepted지만 pending인 Node는 register response config를 적용한 뒤 ready가 될 때까지 push 대상이 아니다.
Node registry swap Node는 refresh payload로 새 adapter registry를 만들고 router registry를 swap한다. old registry stop은 active run이 있으면 drain 이후로 지연한다.
principal token mapping config openai.principal_tokens[]는 raw token 없이 token_ref, token_hash_sha256, principal_ref, optional alias를 관리하고 OpenAI usage metering의 principal/token label 후보를 제공한다. 같은 principal에 여러 token entry를 둘 수 있다.
provider auth forwarding config openai.provider_auth는 caller가 요청 header로 제공한 raw provider token을 selected OpenAI-compatible provider tunnel header로 전달하는 규칙만 저장한다.
Seulgivibe provider aliases seulgivibe_claude, seulgivibe_openai provider type은 runtime adapter type을 openai_compat로 정규화하고, 명시 provider label이 없으면 canonical Seulgivibe alias를 Node payload provider label로 보존한다.

범위

  • 포함: Edge config load/default/validation, provider-pool dispatch, queue admission, long-context admission, config refresh classification/apply, Node config refresh payload.
  • 제외: 개별 adapter의 provider API 호출 세부, OpenAI HTTP request/response shape, Control Plane 원격 config 변경 UX, private credential 관리.

주요 흐름

sequenceDiagram
  participant Caller
  participant Service as Edge service
  participant Queue as Provider queue
  participant Node

  Caller->>Service: SubmitRun(model)
  Service->>Queue: dispatch-ready provider 후보 선택(capacity + priority)
  Queue-->>Service: selected provider + served target
  alt selected provider supports OpenAI-compatible call
    Service->>Node: ProviderTunnelRequest(adapter, served target)
  else selected provider is Ollama/CLI/native
    Service->>Node: RunRequest(adapter, served target)
  end

  participant Operator
  participant Refresh as Config refresh
  Operator->>Refresh: POST /refresh(apply)
  Refresh->>Refresh: load, validate, classify
  Refresh->>Node: NodeConfigRefreshRequest

계약

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

설정/데이터/이벤트

  • long_context_threshold_tokens 기본 예시는 100000이고 0 이하 값은 config load에서 거부된다.
  • provider enabled=false는 dispatch pool에서 제외하지만 adapter process lifecycle 변경을 의미하지 않는다.
  • accepted registration은 provider candidate를 바로 복구하지 않는다. Node가 config 적용과 handler 설치 뒤 ready ack를 받아야 해당 generation이 candidate, connected snapshot, refresh push 대상이 되며 이 transition이 stranded provider-pool waiter를 재평가한다.
  • provider capacity, priority, max queue, queue timeout, enabled toggle, model generation policy는 live apply 대상으로 분류된다.
  • Edge listener, control plane, openai/a2a listener, bootstrap artifact path, node 추가/삭제, node token/alias, adapter 설정 변경은 restart-required 대상이다.
  • openai.principal_tokens[]token_reftoken_hash_sha256 중복을 거부하고, raw token 원문은 tracked config에 저장하지 않는다.
  • 여러 openai.principal_tokens[] entry가 같은 principal_ref를 공유할 수 있으며, 이때 token_ref가 앱/통합/용도별 사용량 분해 기준이다.
  • openai.principal_tokens[] 변경은 credential/hash 변경으로 보고 restart-required로 분류된다.
  • openai.provider_auth.enabled=true이면 생략된 header fields는 from_header=X-IOP-Provider-Authorization, target_header=Authorization, scheme=Bearer, required=true로 해석된다. raw provider token 값은 config/spec/docs에 저장하지 않는다.
  • Seulgivibe provider catalog는 top-level models[]의 정적 provider mapping을 source of truth로 사용한다. provider /models endpoint는 IOP catalog source가 아니다.
  • models[]는 mixed provider group과 Ollama-only group을 모두 표현할 수 있다. Ollama는 후보에서 제외하지 않고 capacity/priority로 운영자가 낮은 동시성과 낮은 선호도를 표현한다.
  • refresh result는 changed nodes/providers/models와 restart-required paths를 stable non-nil slice로 보고한다.

검증

  • go test ./packages/go/config
  • go test ./apps/edge/internal/configrefresh
  • go test ./apps/edge/internal/service
  • go test ./apps/edge/internal/node
  • go test ./apps/node/internal/adapters ./apps/node/internal/node
  • go test ./apps/edge/internal/bootstrap -run '^TestActualNodeReconnectReadyPumpsQueuedWaiterExactlyOnce$'

한계와 주의사항

  • provider health는 현재 config/provider snapshot 기반이다. 모든 runtime에 대한 active health probe가 완성된 것은 아니다.
  • refresh admin API는 operator-local 표면이다. 접근 제어 없이 public interface에 노출하지 않는다.
  • adapter structural 변경은 contract상 restart-required로 분류된다. Node handler가 registry swap을 지원하더라도 Edge refresh classifier가 허용한 변경만 apply해야 한다.
  • no-change apply는 runtime snapshot을 교체하지만 Node push는 생략한다.
  • NodeRuntimeConfig.concurrency는 legacy metadata이며 provider-pool admission의 node-wide capacity로 쓰지 않는다.
  • credential, private endpoint, bearer token 원문은 tracked config/docs/spec에 남기지 않는다.
  • principal token mapping은 완성된 사용자/테넌트 source of truth가 아니라 외부 principal_ref 또는 내부 alias에 대한 얇은 운영 매핑이다.
  • Seulgivibe provider endpoint와 raw user token은 환경별 private config 또는 request-time header로 주입해야 하며 tracked 예시에 실제 값을 남기지 않는다.

변경 기록

  • 2026-07-07: 현재 코드, 계약, config 예시 기준으로 bootstrap spec 작성.
  • 2026-07-07: 기능 목록 중심으로 축소하고 주요 흐름을 Mermaid sequence diagram으로 정리.
  • 2026-07-10: OpenAI usage metering용 principal token hash mapping config와 restart-required 기준을 반영.
  • 2026-07-11: Seulgivibe OpenAI-compatible provider aliases, provider auth forwarding config, static catalog 기준을 현재 코드/계약/테스트 기준으로 반영.
  • 2026-07-12: Model Group Mixed Provider Dispatch 종료 검토 기준으로 mixed provider group과 Ollama-only group, capacity/priority 가중 예시를 반영.
  • 2026-07-18: 저장소 구조 분해 뒤 config, provider resolution/admission, split test의 source_evidence를 현재 경로로 동기화.
  • 2026-07-22: pending accepted connection과 dispatch-ready connection을 구분하고, ready ack 뒤에만 provider candidate 복구·refresh push·queued waiter pump가 일어나는 현재 동작을 반영.