update project files and proto definitions
This commit is contained in:
parent
d764adb390
commit
150e9fda2f
17 changed files with 383 additions and 160 deletions
0
.codex
Normal file
0
.codex
Normal file
283
README.md
283
README.md
|
|
@ -1,54 +1,257 @@
|
|||
# IOP — Inference Operations Platform
|
||||
# IOP
|
||||
|
||||
IOP는 단일 서비스가 아닌 플랫폼이다. 여러 앱이 협력하여 AI 모델 추론 워크로드를 처리한다.
|
||||
IOP(Inference Operations Platform)는 단순한 모델 라우터나 OpenAI API proxy가 아니다.
|
||||
|
||||
## 앱 구성
|
||||
IOP는 **Control Plane - Edge - Node** 계층 구조를 기반으로, 여러 로컬 모델 런타임과 CLI Agent 실행 환경을 통합 관리하는 실행 오케스트레이션 플랫폼을 지향한다. 모델 서빙, CLI Agent 실행, shell/git/docker/code workspace 작업, node maintenance 작업을 같은 실행 파이프라인에서 다룰 수 있도록 만드는 것이 핵심 방향이다.
|
||||
|
||||
| 앱 | 책임 |
|
||||
현재 프로젝트는 완성된 운영 시스템이 아니라 스켈레톤 단계다. 이 README는 현재 구현의 세부 사용법보다, 프로젝트가 향하는 구조와 경계를 명확히 설명한다.
|
||||
|
||||
## Overview
|
||||
|
||||
IOP의 실행 대상은 크게 두 가지다.
|
||||
|
||||
- **Model Serving**
|
||||
- Ollama
|
||||
- vLLM
|
||||
- MLX
|
||||
- 그 외 로컬/원격 모델 런타임
|
||||
- **Agent / Automation Execution**
|
||||
- CLI Agent
|
||||
- Shell
|
||||
- Git
|
||||
- Docker
|
||||
- Code workspace 작업
|
||||
- NomadCode 계열 자동화 작업
|
||||
|
||||
IOP는 model serving만 담당하는 시스템이 아니다. CLI Agent 실행과 node maintenance도 adapter 기반 실행으로 보고, Edge와 Node를 통해 실행 요청, 스트림, 상태, 결과를 관리하는 방향으로 설계한다.
|
||||
|
||||
## Core Concept
|
||||
|
||||
IOP의 중심 개념은 `adapter + target` 기반 실행이다.
|
||||
|
||||
- `adapter`는 실행 방식을 나타낸다.
|
||||
- `target`은 해당 adapter 안에서 실행할 구체 대상을 나타낸다.
|
||||
- `execution`은 adapter와 target을 해석해 실제 Node에서 수행되는 단위다.
|
||||
|
||||
예시는 다음과 같다.
|
||||
|
||||
```text
|
||||
adapter = ollama
|
||||
target = qwen3.6
|
||||
|
||||
adapter = vllm
|
||||
target = gemma4
|
||||
|
||||
adapter = cli
|
||||
target = cline-dgx
|
||||
|
||||
adapter = cli
|
||||
target = codex-local
|
||||
```
|
||||
|
||||
외부 OpenAI API 호환 계층에서는 호환성을 위해 `model` 필드가 남을 수 있다. 그러나 내부 실행 개념에서는 모델 이름만으로 전체 실행을 설명하지 않고, `adapter`, `target`, `execution`, `node adapter`, `adapter execution` 같은 용어를 우선한다.
|
||||
|
||||
## Architecture
|
||||
|
||||
IOP는 Control Plane이 Edge를 통해 시스템을 제어하고, Edge가 자신의 로컬 실행 그룹을 운영하는 구조를 지향한다.
|
||||
|
||||
```text
|
||||
Control Plane
|
||||
├─ Edge Group A
|
||||
│ ├─ Node 1
|
||||
│ ├─ Node 2
|
||||
│ └─ Node 3
|
||||
└─ Edge Group B
|
||||
├─ Node 4
|
||||
└─ Node 5
|
||||
```
|
||||
|
||||
Control Plane은 Node에 직접 연결하지 않는다. 전체 시스템 제어는 Edge를 통해 이뤄지고, Edge는 자신이 관리하는 Node와 로컬 런타임 상태의 원본을 가진다.
|
||||
|
||||
핵심 문장은 다음과 같다.
|
||||
|
||||
> Control Plane은 Edge를 통해 시스템을 제어하고, Edge는 자신의 로컬 런타임 상태를 소유하고 운영한다.
|
||||
|
||||
### Control Plane
|
||||
|
||||
Control Plane은 자체 서버와 프론트 페이지를 가진 중앙 관리 계층이다.
|
||||
|
||||
주요 책임은 다음과 같다.
|
||||
|
||||
- 여러 Edge 연결 관리
|
||||
- Edge 상태 조회
|
||||
- Edge 설정 변경
|
||||
- Edge에 명령 전달
|
||||
- Edge 이벤트 수신
|
||||
- 전체 시스템 관찰
|
||||
- Runtime 영역과 Automation 영역을 나눠 보여주는 운영 화면 제공
|
||||
|
||||
Control Plane과 Edge는 소켓 기반 연결을 사용하고, 이벤트, 상태, 명령 결과를 실시간으로 주고받는 구조를 지향한다.
|
||||
|
||||
Control Plane은 전통적인 Kubernetes식 중앙 스케줄러가 아니다. 다음 책임은 Control Plane에 두지 않는다.
|
||||
|
||||
- Node 직접 연결
|
||||
- Node 직접 스케줄링
|
||||
- Edge 내부 DB 대체
|
||||
- 모든 런타임 상태의 단일 원본화
|
||||
- 매 요청마다 Node 할당 판단
|
||||
|
||||
### Edge
|
||||
|
||||
Edge는 단순 API gateway가 아니라 백엔드 전용 실행 그룹 컨트롤러다.
|
||||
|
||||
하나의 Edge는 여러 Node를 관리하며, 특정 디바이스 그룹, 로컬 모델 그룹, 자동화 실행 그룹을 하나로 묶는 단위가 된다. Edge는 모델 서빙과 CLI Agent 실행을 모두 처리할 수 있어야 한다.
|
||||
|
||||
Edge의 핵심 역할은 다음과 같다.
|
||||
|
||||
- Node registry
|
||||
- Node configuration
|
||||
- Adapter/Profile configuration
|
||||
- Runtime routing
|
||||
- Job assignment
|
||||
- Stream relay
|
||||
- Session handling
|
||||
- Local runtime state
|
||||
- Execution history aggregation
|
||||
- Event aggregation
|
||||
|
||||
Edge는 자신의 데이터를 자체적으로 가진다. Control Plane은 Edge의 데이터를 조회하고 조정하지만, 런타임 데이터의 원본은 Edge다.
|
||||
|
||||
### Node
|
||||
|
||||
Node는 실제 실행자다.
|
||||
|
||||
Node는 모델 런타임, CLI Agent, 도구 실행을 담당한다. Node는 Control Plane이 아니라 Edge에 연결되며, Edge가 전달한 실행 요청을 adapter execution으로 수행하고 이벤트와 결과를 되돌려준다.
|
||||
|
||||
Node는 가능한 한 단순한 실행 단위로 유지한다. 정책, 전체 시스템 조정, 다중 Edge 운영 판단을 Node에 밀어 넣지 않고, 전달받은 실행을 안정적으로 수행하는 데 집중한다.
|
||||
|
||||
## Execution Model
|
||||
|
||||
### Adapter and Target
|
||||
|
||||
IOP 내부 실행은 model 중심이 아니라 adapter 중심으로 정리한다.
|
||||
|
||||
- `adapter`: `mock`, `ollama`, `vllm`, `cli` 같은 실행 구현
|
||||
- `target`: adapter 안에서 선택되는 모델, profile, agent, toolchain
|
||||
- `execution`: 특정 adapter와 target으로 수행되는 단일 실행
|
||||
- `node adapter`: Node 안에 등록되어 실제 실행을 담당하는 adapter
|
||||
- `adapter execution`: Node adapter가 수행하는 실행 단위
|
||||
|
||||
현재 코드에는 `RunRequest`, `ExecutionSpec`, `RuntimeEvent`, `NodeCommandRequest`처럼 이 방향을 담기 위한 타입들이 있다. 세부 계약과 schema는 작업을 진행하면서 점진적으로 정리한다.
|
||||
|
||||
### Runtime Domain
|
||||
|
||||
Runtime Domain은 모델 서빙 중심 실행 영역이다.
|
||||
|
||||
- OpenAI API 호환 요청
|
||||
- Ollama, vLLM, MLX 같은 모델 런타임
|
||||
- 모델 라우팅
|
||||
- 추론 요청 처리
|
||||
- 모델 런타임 adapter 확장
|
||||
|
||||
이 영역에서도 내부적으로는 `adapter + target` 개념을 사용한다. 예를 들어 OpenAI 호환 요청의 `model` 값은 내부에서 특정 adapter와 target으로 해석될 수 있다.
|
||||
|
||||
### Automation Domain
|
||||
|
||||
Automation Domain은 CLI Agent와 도구 실행 중심 영역이다.
|
||||
|
||||
- CLI Agent 실행
|
||||
- Shell, Git, Docker 작업
|
||||
- code workspace 작업
|
||||
- Plane 작업과 유지보수 작업
|
||||
- Claude CLI, Gemini CLI, Codex CLI, OpenCode, Cline 같은 실행 대상
|
||||
|
||||
NomadCode는 IOP 안에 완전히 흡수된 제품이 아니라, IOP Automation Domain 위에서 동작할 수 있는 대표 사용처로 본다.
|
||||
|
||||
```text
|
||||
IOP Core
|
||||
└─ 공통 실행 오케스트레이션 계층
|
||||
|
||||
NomadCode
|
||||
└─ IOP Automation Domain을 활용하는 개발 업무 자동화 도메인
|
||||
```
|
||||
|
||||
## Current Status
|
||||
|
||||
현재 go-iop는 스켈레톤 단계다.
|
||||
|
||||
- Edge-Node 소켓 기반 구조를 우선 검증 중이다.
|
||||
- Node 등록, 설정 전달, 실행 요청, 스트리밍 이벤트 흐름이 점진적으로 정리되고 있다.
|
||||
- CLI adapter 쪽 구현이 먼저 진행되고 있다.
|
||||
- 현재 실행 이력은 Node local SQLite store에서 검증 중이다. Edge 단위 이력 집계와 로컬 실행 그룹 상태 소유권은 로드맵에 따라 정리한다.
|
||||
- `mock` adapter와 dummy/TODO 구현은 개발 단계에서 정상적인 구성이다.
|
||||
- Ollama/vLLM 등 모델 runtime adapter는 단계적으로 확장한다.
|
||||
- Control Plane은 향후 여러 Edge 관리와 프론트 페이지 제공을 위해 추가된다.
|
||||
|
||||
현재 앱 구성은 다음과 같다.
|
||||
|
||||
| 경로 | 현재 의미 |
|
||||
|---|---|
|
||||
| `apps/node` | 디바이스별 node agent. 런타임 라우팅, 추론 어댑터 실행, edge 연결을 담당한다. |
|
||||
| `apps/edge` | node 등록, 레지스트리, transport, 콘솔 기반 요청 전달을 담당하는 gateway이다. |
|
||||
| `apps/control-plane` | 노드 등록, 정책, 스케줄링 제어 영역이다. |
|
||||
| `apps/worker` | 비동기 작업 처리 영역이다. |
|
||||
| `apps/node` | Edge에 연결되어 adapter execution을 수행하는 Node agent |
|
||||
| `apps/edge` | Node registry, 설정 전달, routing, stream relay를 담당하는 Edge skeleton |
|
||||
| `apps/control-plane` | 향후 여러 Edge를 연결하고 운영 화면을 제공할 중앙 관리 계층 |
|
||||
| `apps/worker` | 향후 비동기 작업 처리 가능성을 위한 placeholder |
|
||||
| `packages` | 설정, 인증, 정책, 작업, 관측성, 버전 등 공통 패키지 |
|
||||
| `proto` | 앱 간 메시지 계약 원본과 생성물 |
|
||||
| `configs` | 현재 개발용 설정 예시 |
|
||||
|
||||
## 내부 통신
|
||||
## Roadmap
|
||||
|
||||
- **프로토콜**: TCP + Protobuf + mTLS
|
||||
- **메시지 계약**: `proto/iop/*.proto`
|
||||
- **생성물**: `proto/gen/iop/*.pb.go`
|
||||
- gRPC **사용 금지**
|
||||
- WebSocket transport 기본화 **금지**
|
||||
### Phase 1. Edge-Node execution skeleton
|
||||
|
||||
## 외부 API
|
||||
- Edge-Node 소켓 연결
|
||||
- Node adapter execution
|
||||
- CLI adapter 검증
|
||||
- `adapter + target` 개념 정리
|
||||
|
||||
외부 OpenAI-compatible API는 `apps/edge`의 책임 영역으로 둔다.
|
||||
### Phase 2. Runtime and Automation unification
|
||||
|
||||
## 기본 명령 예시
|
||||
- 모델 서빙 adapter 확장
|
||||
- CLI Agent 실행 안정화
|
||||
- Runtime / Automation 실행 흐름 공통화
|
||||
- Node local execution history와 Edge event aggregation 경계 정리
|
||||
|
||||
```bash
|
||||
# 의존성 설치
|
||||
go mod tidy
|
||||
### Phase 3. Control Plane
|
||||
|
||||
# node CLI 빌드 예시
|
||||
go build -o bin/node ./apps/node/cmd/node
|
||||
- 자체 서버와 프론트 페이지 제공
|
||||
- 여러 Edge 연결
|
||||
- Edge 상태 조회
|
||||
- Edge 설정 변경
|
||||
- Edge 명령 전달
|
||||
- 이벤트 수신
|
||||
|
||||
# node CLI 실행 예시
|
||||
./bin/node version
|
||||
./bin/node config print
|
||||
./bin/node serve
|
||||
```
|
||||
### Phase 4. Multi-Edge operations
|
||||
|
||||
## 모노레포 구조
|
||||
- 여러 Edge group 관리
|
||||
- Edge별 runtime/automation 상태 표시
|
||||
- Edge 단위 실행 이력과 상태 집계
|
||||
- Edge 단위 작업 실행과 제어
|
||||
|
||||
```
|
||||
iop/
|
||||
apps/
|
||||
node/
|
||||
edge/
|
||||
control-plane/
|
||||
worker/
|
||||
packages/ # 공통 패키지
|
||||
proto/ # Protobuf 스펙과 생성물
|
||||
configs/ # 앱별 설정 파일
|
||||
docs/ # 아키텍처와 운영 문서
|
||||
```
|
||||
### Phase 5. Policy, History, Audit
|
||||
|
||||
- 권한, 정책, 이력, 감사 기능 확장
|
||||
- 상세 설계는 후속 작업에서 결정
|
||||
|
||||
## Development Notes
|
||||
|
||||
- 기존 구조를 우선하며, 세부 구현은 각 작업의 domain rule과 현재 코드 경계를 먼저 확인한 뒤 진행한다.
|
||||
- 내부 통신은 TCP/protobuf 기반 소켓 흐름을 우선한다.
|
||||
- gRPC 도입, WebSocket 기본 transport 전환, actor/FSM/plugin framework 도입은 현재 단계의 기본 방향이 아니다.
|
||||
- OpenAI API 호환 계층은 외부 호환을 위한 표면이며, 내부 실행 모델 전체를 대표하지 않는다.
|
||||
- 앱별 README에는 현재 수동 테스트나 구현 세부가 더 많이 남아 있을 수 있다. 루트 README는 전체 방향과 경계를 설명하는 문서로 유지한다.
|
||||
|
||||
## Non-Goals for Current Stage
|
||||
|
||||
이번 단계에서는 다음 내용을 루트 README에서 상세 설계로 확정하지 않는다.
|
||||
|
||||
- 상세 DB schema
|
||||
- 상세 protobuf 설계
|
||||
- 상세 event schema
|
||||
- 상세 permission model
|
||||
- 상세 policy engine 설계
|
||||
- 상세 audit log 구조
|
||||
- Edge federation 세부 설계
|
||||
- mTLS 세부 구현 계획
|
||||
- Control Plane UI 화면별 상세 기획
|
||||
- Plane 연동 상세 workflow
|
||||
- NomadCode 상세 제품 설계
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
## 목적 / 책임
|
||||
|
||||
외부 API gateway로 발전할 앱 영역이며, 현재는 node 연결을 수락하고 token 기반 등록을 검증한 뒤 중앙 관리 설정을 내려주는 TCP/protobuf 서버 책임을 가진다.
|
||||
여러 Node를 하나의 로컬 실행 그룹으로 묶는 백엔드 실행 그룹 컨트롤러 영역이다. 현재는 node 연결을 수락하고 token 기반 등록을 검증한 뒤 adapter/runtime 설정을 내려주며, console 기반 실행 요청과 run event relay를 검증한다.
|
||||
|
||||
## 포함 경로
|
||||
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
## 제외 경로
|
||||
|
||||
- `apps/node/` — 실제 모델 실행과 adapter 관리
|
||||
- `apps/control-plane/` — 노드 등록/정책/스케줄링 예정 영역
|
||||
- `apps/control-plane/` — 여러 Edge 연결 관리와 운영 화면 제공 예정 영역
|
||||
- `apps/worker/` — 비동기 작업 처리 예정 영역
|
||||
- `packages/` — 공통 설정/관측성/인증 패키지
|
||||
- `proto/` — 메시지 계약 원본과 생성물
|
||||
|
|
@ -34,21 +34,24 @@
|
|||
## 유지할 패턴
|
||||
|
||||
- edge는 사전 등록된 node 정의를 검증하고 연결 상태를 registry에 반영하는 역할을 먼저 안정화한다.
|
||||
- 외부 OpenAI-compatible HTTP API는 node/transport 안정화 이후 확장한다.
|
||||
- edge는 단순 gateway가 아니라 Node registry, adapter/profile configuration, routing, stream relay의 소유자다.
|
||||
- 외부 OpenAI-compatible HTTP API는 node/transport 안정화 이후 확장하며, 내부 실행 모델 전체를 대표하지 않는다.
|
||||
- node가 연결 직후 RegisterRequest를 보내고 edge가 RegisterResponse로 중앙 설정을 응답하는 흐름을 유지한다.
|
||||
- Registry는 동시성 안전성을 유지하고 외부로 내부 map을 노출하지 않는다.
|
||||
- NodeStore는 설정 파일에서 한 번 seed되며 런타임 중 변경하지 않는다; token 중복·빈 token은 LoadFromConfig에서 즉시 거부한다.
|
||||
- adapter config 변환(mapper)은 `node.BuildConfigPayload()`에서만 수행하고 transport 레이어에 변환 로직을 두지 않는다.
|
||||
- 내부 실행 요청은 `adapter + target`으로 표현한다. 외부 API 호환 경계의 `model` 표현을 edge 내부 책임 전체로 확장하지 않는다.
|
||||
|
||||
## 다른 도메인과의 경계
|
||||
|
||||
- **node**: edge는 node를 실행하지 않는다. edge는 사전 등록 정보와 연결 registry를 기반으로 요청을 보낼 대상만 선택한다.
|
||||
- **node**: edge는 node 내부 adapter를 직접 실행하지 않는다. edge는 사전 등록 정보와 연결 registry를 기반으로 요청을 보낼 대상과 실행 설정을 관리한다.
|
||||
- **platform-common**: edge 설정, metrics, protobuf 타입은 platform-common 계약을 따른다.
|
||||
- **control-plane 후보**: 장기적으로 노드 등록/정책/스케줄링이 control-plane으로 분리될 수 있으므로 edge에 해당 책임을 굳히기 전에 경계를 재검토한다.
|
||||
- **control-plane 후보**: control-plane은 Edge를 통해 시스템을 제어한다. Node 직접 연결/직접 스케줄링을 control-plane 책임으로 굳히지 않는다.
|
||||
|
||||
## 금지 사항
|
||||
|
||||
- edge를 구현하면서 node adapter 실행 로직을 복제하지 않는다.
|
||||
- OpenAI-compatible HTTP API를 추가할 때 내부 TCP/protobuf 경계를 우회하지 않는다.
|
||||
- Control Plane 구현 전이라도 Node를 Control Plane에 직접 연결하는 경로를 edge 도메인에 추가하지 않는다.
|
||||
- gRPC 또는 WebSocket을 기본 내부 transport로 바꾸지 않는다.
|
||||
- `proto/gen/iop/*.pb.go` 생성 파일을 직접 수정하지 않는다.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
## 목적 / 책임
|
||||
|
||||
디바이스당 1개 실행되는 IOP 노드 에이전트 영역이다. edge에서 들어온 실행 요청을 runtime 요청으로 변환하고, 라우팅된 어댑터를 실행하며, 실행 이벤트와 이력을 관리한다.
|
||||
Edge에 연결되어 실제 adapter execution을 수행하는 IOP 노드 에이전트 영역이다. edge에서 들어온 실행 요청을 runtime 요청으로 변환하고, 라우팅된 어댑터를 실행하며, 실행 이벤트와 현재 단계의 로컬 실행 이력을 관리한다.
|
||||
|
||||
## 포함 경로
|
||||
|
||||
|
|
@ -17,15 +17,15 @@
|
|||
|
||||
## 제외 경로
|
||||
|
||||
- `apps/edge/` — node를 받아들이는 gateway 서버 영역
|
||||
- `apps/control-plane/` — 노드 등록/정책/스케줄링 예정 영역
|
||||
- `apps/edge/` — Node를 관리하는 실행 그룹 컨트롤러 영역
|
||||
- `apps/control-plane/` — 여러 Edge 연결 관리와 운영 화면 제공 예정 영역
|
||||
- `apps/worker/` — 비동기 작업 처리 예정 영역
|
||||
- `packages/` — 여러 앱이 공유하는 공통 패키지
|
||||
- `proto/` — 앱 간 메시지 계약
|
||||
|
||||
## 주요 구성 요소
|
||||
|
||||
- `runtime.Adapter` — 모델/CLI 실행 어댑터 계약
|
||||
- `runtime.Adapter` — adapter target 실행 계약
|
||||
- `runtime.Router` — 실행 요청을 구체적인 `ExecutionSpec`으로 변환하는 계약
|
||||
- `node.Node` — `transport.Handler` 구현체이자 실행 파이프라인 조정자
|
||||
- `node.runManager` — run ID 기준 `runHandle`(cancel, done) 등록/해제/취소 관리; `node.Node` 내부에서만 사용
|
||||
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
- `runtime` 패키지에는 도메인 타입과 인터페이스를 두고 구체 구현 의존성을 넣지 않는다.
|
||||
- transport/proto 타입은 `node.Node` 경계에서 runtime 타입으로 변환한다.
|
||||
- 내부 실행 식별자는 `adapter + target`을 사용한다. 외부 OpenAI-compatible API나 legacy placeholder를 제외하고 `model`을 내부 실행 대표 용어로 되돌리지 않는다.
|
||||
- 어댑터 추가 시 `runtime.Adapter`를 구현하고 `adapters.BuildFromPayload()` 또는 bootstrap registry에 등록한다.
|
||||
- 실행 취소는 run ID 기준으로 `runManager`에 등록하고 실행 종료 시 반드시 `deregister`로 해제한다.
|
||||
- `adapters.Registry`의 start/stop은 bootstrap lifecycle에서만 호출하고 개별 adapter에서 직접 호출하지 않는다.
|
||||
|
|
@ -49,9 +50,9 @@
|
|||
|
||||
## 다른 도메인과의 경계
|
||||
|
||||
- **edge**: edge는 node 연결 등록과 중앙 설정 전달, 라우팅 진입을 담당한다. node는 edge가 보낸 실행 요청을 처리하고 이벤트를 돌려준다.
|
||||
- **edge**: edge는 node 연결 등록, adapter/runtime 설정 전달, 라우팅 진입, stream relay를 담당한다. node는 edge가 보낸 실행 요청을 처리하고 이벤트를 돌려준다.
|
||||
- **platform-common**: node는 `packages/config`, `packages/observability`, `proto/gen/iop` 등을 사용하지만 공통 타입/설정 자체의 소유자는 platform-common이다.
|
||||
- **control-plane 후보**: 정책/스케줄링의 시스템 단위 결정은 control-plane에서 다루고, node는 전달받은 실행 단위 수행에 집중한다.
|
||||
- **control-plane 후보**: control-plane은 Node가 아니라 Edge를 통해 시스템을 제어한다. node는 control-plane 직접 연결/직접 스케줄링을 전제로 하지 않는다.
|
||||
|
||||
## 금지 사항
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
## 목적 / 책임
|
||||
|
||||
여러 앱이 공유하는 설정, 인증, 정책, 메타데이터, 작업 상태, 관측성, 버전, protobuf 계약을 관리한다. 앱별 구현보다 안정적인 공통 계약과 작은 유틸리티를 제공하는 영역이다.
|
||||
여러 앱이 공유하는 설정, 인증, 정책, 메타데이터, 작업 상태, 관측성, 버전, protobuf 계약을 관리한다. 앱별 구현보다 안정적인 공통 계약과 작은 유틸리티를 제공하며, 내부 실행 계약은 `adapter + target` 방향을 우선한다.
|
||||
|
||||
## 포함 경로
|
||||
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
## 제외 경로
|
||||
|
||||
- `apps/node/` — node 실행 파이프라인과 adapter 관리
|
||||
- `apps/edge/` — gateway 서버와 node registry
|
||||
- `apps/edge/` — 실행 그룹 컨트롤러와 node registry
|
||||
- `apps/control-plane/` — control-plane 앱 구현 예정 영역
|
||||
- `apps/worker/` — worker 앱 구현 예정 영역
|
||||
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
- `auth.LoadServerTLS` / `auth.LoadClientTLS` — mTLS TLS config 생성
|
||||
- `observability.NewLogger` / `observability.ServeMetrics` — 공통 로깅/메트릭
|
||||
- `policy.Engine` — 정책 적용/검증 계약
|
||||
- `jobs.Job` — 비동기 작업 상태 모델
|
||||
- `jobs.Job` — 비동기 작업 상태 placeholder; 내부 실행 대상은 `target`으로 표현
|
||||
- `proto/iop/*.proto` — 앱 간 메시지 원본 계약
|
||||
|
||||
## 유지할 패턴
|
||||
|
|
@ -40,16 +40,18 @@
|
|||
- protobuf 계약 변경은 `proto/iop/*.proto`에서 시작하고 `make proto`로 생성물을 갱신한다.
|
||||
- 생성 파일(`proto/gen/iop/*.pb.go`)은 사람이 직접 편집하지 않는다.
|
||||
- 공통 패키지는 작고 명확한 계약을 유지하고 앱별 정책을 과도하게 끌어올리지 않는다.
|
||||
- `RunRequest`, `ExecutionSpec`, `NodeCommandRequest`, job/history 계열 계약을 변경할 때 내부 실행 용어는 `target`을 우선하고, `model`은 외부 호환 경계인지 확인한다.
|
||||
|
||||
## 다른 도메인과의 경계
|
||||
|
||||
- **node**: node가 필요로 하는 설정/타입/계약을 제공하지만 실행 파이프라인의 소유자는 node이다.
|
||||
- **edge**: edge가 필요로 하는 설정/관측성/protobuf 계약을 제공하지만 gateway 동작의 소유자는 edge이다.
|
||||
- **edge**: edge가 필요로 하는 설정/관측성/protobuf 계약을 제공하지만 실행 그룹 제어와 node registry 동작의 소유자는 edge이다.
|
||||
- **control-plane/worker 후보**: 두 앱이 구현되면 필요한 공통 타입만 이 영역으로 승격하고 앱 내부 책임은 각 도메인에 둔다.
|
||||
|
||||
## 금지 사항
|
||||
|
||||
- `packages`에서 `apps/*/internal` 패키지를 import하지 않는다.
|
||||
- 앱 하나만을 위한 임시 타입을 충분한 근거 없이 공통 패키지로 승격하지 않는다.
|
||||
- 내부 실행 계약을 확장하면서 `model` 중심 명명을 되살리지 않는다. 외부 API 호환이 필요한 경우 경계와 변환 위치를 명시한다.
|
||||
- protobuf 생성물을 직접 수정하지 않는다.
|
||||
- 설정 파일만 바꾸고 `packages/config`의 로딩/default와 불일치하게 두지 않는다.
|
||||
|
|
|
|||
|
|
@ -7,15 +7,16 @@
|
|||
|
||||
## 프로젝트 개요
|
||||
|
||||
- IOP(Inference Operations Platform)는 분산 AI 모델 추론 워크로드를 처리하는 Go 모노레포이다.
|
||||
- 현재 1차 구현 중심은 `apps/node`이며, `apps/edge`는 node 등록/레지스트리/transport가 일부 구현되어 있다.
|
||||
- IOP(Inference Operations Platform)는 Control Plane - Edge - Node 계층 구조를 기반으로 모델 서빙과 CLI Agent/Automation 실행을 함께 다루는 Go 실행 오케스트레이션 모노레포이다.
|
||||
- 내부 실행 개념은 model 중심이 아니라 `adapter + target` 중심으로 정리한다. 외부 OpenAI-compatible 경계나 외부 CLI 인자에서는 호환성을 위해 `model` 표현이 남을 수 있다.
|
||||
- 현재 1차 구현 중심은 `apps/node`와 `apps/edge`의 Edge-Node 실행 스켈레톤이며, CLI adapter와 node 등록/레지스트리/transport가 우선 검증되고 있다.
|
||||
- `apps/control-plane`과 `apps/worker`는 README와 CLI placeholder 수준이므로, 본격 구현 전 별도 domain rule을 만들거나 갱신한다.
|
||||
|
||||
## 주요 구조
|
||||
|
||||
- `apps/node/` — 디바이스별 노드 에이전트. 런타임 라우팅, 어댑터 실행, edge 연결, 실행 이력 저장을 담당한다.
|
||||
- `apps/edge/` — node 연결을 받아 token 기반 등록을 처리하고 중앙 설정을 내려주는 gateway 서버 영역이다.
|
||||
- `apps/control-plane/` — 노드 등록, 정책, 스케줄링 예정 영역이다. 현재 placeholder이다.
|
||||
- `apps/node/` — Edge에 연결되는 실행자. 런타임 라우팅, adapter execution, CLI/model runtime 실행, 현재 단계의 로컬 실행 이력 저장을 담당한다.
|
||||
- `apps/edge/` — 여러 Node를 묶는 백엔드 실행 그룹 컨트롤러. token 기반 등록, node registry, node 설정 전달, routing, stream relay를 담당한다.
|
||||
- `apps/control-plane/` — 향후 여러 Edge를 연결하고 상태 조회/설정 변경/명령 전달/이벤트 수신/프론트 페이지 제공을 담당할 중앙 관리 계층이다. 현재 placeholder이다.
|
||||
- `apps/worker/` — 비동기 작업 처리 예정 영역이다. 현재 placeholder이다.
|
||||
- `packages/` — 설정, 인증, 정책, 메타데이터, 작업, 관측성, 버전 등 공통 패키지이다.
|
||||
- `proto/iop/` — IOP 메시지 계약 원본이다.
|
||||
|
|
@ -39,11 +40,13 @@
|
|||
|
||||
- 기존 hexagonal 구조를 유지한다. 특히 `apps/node/internal/runtime` 인터페이스를 중심에 두고 transport/adapters/store는 바깥쪽 구현으로 둔다.
|
||||
- 새 node 어댑터는 `runtime.Adapter`를 구현하고 `apps/node/internal/bootstrap/module.go`에서 registry에 등록한다.
|
||||
- 내부 실행 요청과 상태 저장에서는 `adapter`, `target`, `execution` 용어를 우선한다. `model`은 외부 API 호환이나 legacy placeholder일 때만 허용한다.
|
||||
- Control Plane은 Node를 직접 연결/스케줄링하지 않고 Edge를 통해 시스템을 제어한다. Edge는 자신의 로컬 런타임 상태와 Node registry를 소유한다.
|
||||
- 내부 통신은 TCP 기반 protobuf 메시지 흐름을 우선한다. gRPC 도입, WebSocket 기본 transport 전환, actor/FSM/plugin framework 도입은 금지한다.
|
||||
- protobuf 계약 변경 시 `proto/iop/*.proto`를 먼저 수정하고 `make proto`로 `proto/gen/iop/*.pb.go`를 갱신한다. 생성 파일은 직접 수정하지 않는다.
|
||||
- 앱 설정 구조 변경 시 `packages/config`의 struct/default와 `configs/*.yaml` 예시를 함께 확인한다.
|
||||
- 테스트는 변경 범위에 맞춰 `go test ./...` 또는 대상 패키지 테스트를 실행한다.
|
||||
- `packages/protocol`은 README에 언급되어 있지만 현재 디렉터리가 없으므로, 생성이 필요하면 실제 책임 경계를 먼저 확정한다.
|
||||
- 상세 DB schema, event schema, permission/policy/audit model, federation, mTLS 구현 세부, Control Plane UI 세부 기획은 각 작업에서 별도로 결정한다.
|
||||
|
||||
## 도메인 매핑
|
||||
|
||||
|
|
@ -57,7 +60,7 @@
|
|||
|
||||
## 도메인 후보
|
||||
|
||||
- `control-plane`: `apps/control-plane/**`가 placeholder를 넘어 노드 등록, 정책, 스케줄링을 구현하기 시작할 때 생성한다.
|
||||
- `control-plane`: `apps/control-plane/**`가 placeholder를 넘어 여러 Edge 연결 관리, Edge 상태 조회, Edge 설정 변경, Edge 명령 전달, 이벤트 수신, 프론트 페이지 제공을 구현하기 시작할 때 생성한다.
|
||||
- `worker`: `apps/worker/**`가 placeholder를 넘어 작업 큐 소비/재시도/결과 저장을 구현하기 시작할 때 생성한다.
|
||||
|
||||
## 스킬 라우팅
|
||||
|
|
|
|||
|
|
@ -1,12 +1,17 @@
|
|||
# control-plane — Control Plane
|
||||
|
||||
노드 등록, 정책 적용, 작업 스케줄링을 담당한다.
|
||||
여러 Edge를 연결하고 관찰하며, Edge 설정 변경과 명령 전달을 담당할 중앙 관리 계층이다.
|
||||
|
||||
**현재 상태: Placeholder**
|
||||
|
||||
현재 Control Plane은 구현 전 단계다. Node를 직접 등록하거나 직접 스케줄링하는 계층으로 확정하지 않는다. Control Plane은 Edge를 통해 시스템을 제어하고, Edge가 자신의 로컬 런타임 상태와 Node registry를 운영하는 방향을 따른다.
|
||||
|
||||
## 계획된 기능
|
||||
|
||||
- 노드 등록 및 헬스체크
|
||||
- 정책 DSL 평가
|
||||
- 작업 스케줄링 (라운드로빈 / 최소 부하)
|
||||
- 노드 드레이닝 / 업그레이드 조율
|
||||
- 자체 서버와 프론트 페이지 제공
|
||||
- 여러 Edge 연결 관리
|
||||
- Edge 상태 조회
|
||||
- Edge 설정 변경
|
||||
- Edge 명령 전달
|
||||
- Edge 이벤트 수신
|
||||
- Runtime / Automation 영역을 나눠 보여주는 운영 화면
|
||||
|
|
|
|||
|
|
@ -17,11 +17,12 @@ func main() {
|
|||
func rootCmd() *cobra.Command {
|
||||
root := &cobra.Command{
|
||||
Use: "control-plane",
|
||||
Short: "IOP Control Plane — node registry, policy, scheduling (placeholder)",
|
||||
Long: `control-plane manages node registration, enforces policy,
|
||||
and schedules jobs to nodes.
|
||||
Short: "IOP Control Plane — multi-edge management placeholder",
|
||||
Long: `control-plane will manage Edge connections, observe Edge state,
|
||||
adjust Edge configuration, deliver commands to Edge, and receive Edge events.
|
||||
|
||||
This component is a placeholder. Implementation is planned after the node is stable.`,
|
||||
This component is a placeholder. It should control the system through Edge,
|
||||
not by connecting to or scheduling Node directly.`,
|
||||
}
|
||||
root.AddCommand(&cobra.Command{
|
||||
Use: "serve",
|
||||
|
|
|
|||
|
|
@ -2,92 +2,81 @@
|
|||
|
||||
## 개요
|
||||
|
||||
IOP(Inference Operations Platform)는 분산 AI 모델 추론을 위한 플랫폼이다.
|
||||
단일 서비스가 아니라 협력하는 여러 앱으로 구성된다.
|
||||
IOP(Inference Operations Platform)는 모델 서빙과 CLI Agent/Automation 실행을 함께 다루는 실행 오케스트레이션 플랫폼을 지향한다. 단순한 OpenAI-compatible proxy나 모델 라우터가 아니라, Control Plane - Edge - Node 계층으로 로컬 실행 그룹을 관리하는 구조를 목표로 한다.
|
||||
|
||||
```
|
||||
Client (OpenAI SDK)
|
||||
│
|
||||
▼
|
||||
┌─────────┐
|
||||
│ edge │ OpenAI-compatible HTTP API
|
||||
└────┬────┘
|
||||
│ IOP TCP + Protobuf + mTLS
|
||||
▼
|
||||
┌──────────────────┐
|
||||
│ control-plane │ 노드 등록 / 정책 / 스케줄링
|
||||
└────────┬─────────┘
|
||||
│
|
||||
┌─────┴──────┐
|
||||
▼ ▼
|
||||
┌──────┐ ┌──────┐ (N개의 node)
|
||||
│ node │ │ node │
|
||||
└──┬───┘ └──┬───┘
|
||||
│ │
|
||||
┌──┴──┐ ┌──┴──┐
|
||||
│mock │ │ollama│ 어댑터
|
||||
│cli │ │vllm │
|
||||
└─────┘ └──────┘
|
||||
현재 구현은 Edge-Node 실행 스켈레톤을 검증하는 단계다. Control Plane과 worker는 placeholder이며, 세부 계약은 후속 작업에서 정리한다.
|
||||
|
||||
┌────────┐
|
||||
│ worker │ 비동기 작업 처리
|
||||
└────────┘
|
||||
## 계층 구조
|
||||
|
||||
```text
|
||||
Control Plane
|
||||
├─ Edge Group A
|
||||
│ ├─ Node 1
|
||||
│ │ ├─ adapter: cli
|
||||
│ │ └─ adapter: ollama
|
||||
│ └─ Node 2
|
||||
│ └─ adapter: vllm
|
||||
└─ Edge Group B
|
||||
└─ Node 3
|
||||
└─ adapter: cli
|
||||
```
|
||||
|
||||
## 내부 통신 프로토콜
|
||||
Control Plane은 Node에 직접 연결하지 않는다. Control Plane은 Edge 연결을 관리하고, Edge 상태를 조회하고, Edge 설정을 조정하고, Edge에 명령을 전달하는 중앙 관리 계층이다.
|
||||
|
||||
### 와이어 포맷
|
||||
Edge는 여러 Node를 묶는 실행 그룹 컨트롤러다. Edge는 Node registry, adapter/profile configuration, routing, stream relay, session handling, event aggregation을 담당한다.
|
||||
|
||||
```
|
||||
Frame: [4 bytes big-endian uint32: length] [payload]
|
||||
Payload: JSON-encoded Envelope
|
||||
Envelope.Payload: JSON-encoded inner message
|
||||
Node는 실제 실행자다. Node는 Edge에 연결되어 adapter execution을 수행하고, RuntimeEvent를 Edge로 돌려준다.
|
||||
|
||||
## 현재 Edge-Node 흐름
|
||||
|
||||
현재 검증 중인 기본 흐름은 다음과 같다.
|
||||
|
||||
```text
|
||||
Edge
|
||||
└─ accepts Node connection
|
||||
└─ validates token
|
||||
└─ sends NodeConfigPayload
|
||||
└─ relays RunRequest / NodeCommandRequest
|
||||
|
||||
Node
|
||||
└─ receives adapter/runtime config
|
||||
└─ builds adapter registry
|
||||
└─ resolves adapter + target
|
||||
└─ executes adapter
|
||||
└─ emits RuntimeEvent
|
||||
```
|
||||
|
||||
**TODO**: Payload 인코딩을 protobuf로 교체 (proto/iop/runtime.proto 참고)
|
||||
현재 실행 이력은 Node의 local SQLite store에서 검증 중이다. Edge 단위 이력 집계와 로컬 실행 그룹 상태 소유권은 로드맵에 따라 정리한다.
|
||||
|
||||
### 메시지 타입
|
||||
## 내부 실행 모델
|
||||
|
||||
| Type | 방향 | 설명 |
|
||||
|------|------|------|
|
||||
| `run.request` | client → node | 추론 실행 요청 |
|
||||
| `run.event` | node → client | 스트리밍 이벤트 (start/delta/complete/error) |
|
||||
| `heartbeat` | 양방향 | 연결 유지 (30초 간격) |
|
||||
| `cancel.request` | client → node | 실행 중단 요청 |
|
||||
| `register.request` | node → edge | 사전 발급 token 기반 등록 요청 |
|
||||
| `register.response` | edge → node | 등록 수락 여부와 중앙 관리 node 설정 응답 |
|
||||
| `error` | node → client | 에러 응답 |
|
||||
내부 실행은 `adapter + target`으로 표현한다.
|
||||
|
||||
### mTLS
|
||||
- `adapter`: 실행 방식. 예: `mock`, `ollama`, `vllm`, `cli`
|
||||
- `target`: adapter 안의 실행 대상. 예: 모델 이름, CLI profile, agent/toolchain
|
||||
- `execution`: 특정 adapter와 target으로 수행되는 단일 실행
|
||||
|
||||
```yaml
|
||||
tls:
|
||||
enabled: true
|
||||
cert: certs/node.crt
|
||||
key: certs/node.key
|
||||
ca: certs/ca.crt
|
||||
```
|
||||
|
||||
`tls.enabled: true`로 설정하면 RequireAndVerifyClientCert (mTLS) 모드로 동작.
|
||||
외부 OpenAI-compatible API에서는 호환성을 위해 `model` 필드가 남을 수 있다. 그러나 내부 실행 계약에서는 `target`을 우선한다.
|
||||
|
||||
## apps/node 내부 구조
|
||||
|
||||
```
|
||||
```text
|
||||
Hexagonal Architecture
|
||||
|
||||
┌───────────────────────────────┐
|
||||
│ node.Node │ (application core)
|
||||
│ node.Node │ application core
|
||||
│ │
|
||||
TCP │ transport.Handler interface │
|
||||
─────────► OnRunRequest() │
|
||||
client │ OnCancel() │
|
||||
edge │ OnCancel() │
|
||||
│ OnCommandRequest() │
|
||||
└───────┬───────────────────────┘
|
||||
│
|
||||
router.Resolve() → ExecutionSpec
|
||||
router.Resolve() -> ExecutionSpec
|
||||
│
|
||||
adapter.Execute() → RuntimeEvent stream
|
||||
adapter.Execute() -> RuntimeEvent stream
|
||||
│
|
||||
store.CompleteRun() → SQLite
|
||||
store.CompleteRun() -> SQLite
|
||||
```
|
||||
|
||||
### 어댑터 패턴
|
||||
|
|
@ -100,10 +89,14 @@ type Adapter interface {
|
|||
}
|
||||
```
|
||||
|
||||
새 어댑터를 추가하려면:
|
||||
1. `apps/node/internal/adapters/<name>/` 패키지 생성
|
||||
2. `runtime.Adapter` 인터페이스 구현
|
||||
3. `bootstrap/module.go`에서 Registry에 등록
|
||||
새 어댑터를 추가할 때는 `runtime.Adapter`를 구현하고 registry에 등록한다. CLI Agent, 모델 런타임, 도구 실행은 모두 같은 adapter execution 경로로 다루는 방향을 유지한다.
|
||||
|
||||
## 통신 방향
|
||||
|
||||
- Edge-Node 내부 통신은 TCP + protobuf 기반 소켓 흐름을 우선한다.
|
||||
- Node는 Edge에 연결한다.
|
||||
- Control Plane은 향후 Edge와 소켓 기반 연결을 맺는다.
|
||||
- Control Plane이 Node에 직접 연결하거나 매 요청마다 Node를 직접 스케줄링하는 구조는 목표가 아니다.
|
||||
|
||||
## 라이브러리 선택
|
||||
|
||||
|
|
@ -113,9 +106,9 @@ type Adapter interface {
|
|||
| `go.uber.org/zap` | 구조화 로깅 |
|
||||
| `github.com/spf13/cobra` | CLI |
|
||||
| `github.com/spf13/viper` | 설정 파일 |
|
||||
| `google.golang.org/protobuf` | Protobuf (spec용) |
|
||||
| `google.golang.org/protobuf` | Protobuf |
|
||||
| `github.com/prometheus/client_golang` | 메트릭 |
|
||||
| `modernc.org/sqlite` | 실행 이력 저장 |
|
||||
| `modernc.org/sqlite` | 현재 Node local 실행 이력 저장 |
|
||||
|
||||
## 금지 사항
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ type Job struct {
|
|||
RunID string `json:"run_id"`
|
||||
NodeID string `json:"node_id"`
|
||||
Adapter string `json:"adapter"`
|
||||
Model string `json:"model"`
|
||||
Target string `json:"target"`
|
||||
Status Status `json:"status"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
StartedAt *time.Time `json:"started_at,omitempty"`
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ type Spec map[string]any
|
|||
// Engine applies and validates policies on execution specs.
|
||||
type Engine interface {
|
||||
// Apply enriches or modifies spec fields based on policy rules.
|
||||
Apply(ctx context.Context, adapter, model string, policy Spec) (Spec, error)
|
||||
Apply(ctx context.Context, adapter, target string, policy Spec) (Spec, error)
|
||||
// Validate returns an error if the policy rejects the request.
|
||||
Validate(ctx context.Context, adapter, model string, policy Spec) error
|
||||
Validate(ctx context.Context, adapter, target string, policy Spec) error
|
||||
}
|
||||
|
||||
// Passthrough is a no-op policy engine used when no policy is configured.
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ const (
|
|||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// PolicyRule defines a routing/resource constraint.
|
||||
// PolicyRule is a placeholder for future edge-level routing/resource constraints.
|
||||
type PolicyRule struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
|
|
@ -82,7 +82,8 @@ func (x *PolicyRule) GetParams() map[string]string {
|
|||
return nil
|
||||
}
|
||||
|
||||
// ScheduleRequest asks the control-plane to route a job to a node.
|
||||
// ScheduleRequest is a legacy placeholder for future Control Plane orchestration.
|
||||
// It must not be treated as an active contract for direct Node scheduling.
|
||||
type ScheduleRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
JobId string `protobuf:"bytes,1,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"`
|
||||
|
|
@ -151,7 +152,8 @@ func (x *ScheduleRequest) GetMetadata() map[string]string {
|
|||
return nil
|
||||
}
|
||||
|
||||
// ScheduleResponse contains the selected node address.
|
||||
// ScheduleResponse is a legacy placeholder. Future scheduling should be
|
||||
// reworked around Edge-owned runtime state instead of bypassing Edge.
|
||||
type ScheduleResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
NodeId string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"`
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ type Job struct {
|
|||
RunId string `protobuf:"bytes,2,opt,name=run_id,json=runId,proto3" json:"run_id,omitempty"`
|
||||
NodeId string `protobuf:"bytes,3,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"`
|
||||
Adapter string `protobuf:"bytes,4,opt,name=adapter,proto3" json:"adapter,omitempty"`
|
||||
Model string `protobuf:"bytes,5,opt,name=model,proto3" json:"model,omitempty"`
|
||||
Target string `protobuf:"bytes,5,opt,name=target,proto3" json:"target,omitempty"`
|
||||
Status JobStatus `protobuf:"varint,6,opt,name=status,proto3,enum=iop.JobStatus" json:"status,omitempty"`
|
||||
CreatedAt int64 `protobuf:"varint,7,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
|
||||
StartedAt int64 `protobuf:"varint,8,opt,name=started_at,json=startedAt,proto3" json:"started_at,omitempty"`
|
||||
|
|
@ -154,9 +154,9 @@ func (x *Job) GetAdapter() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (x *Job) GetModel() string {
|
||||
func (x *Job) GetTarget() string {
|
||||
if x != nil {
|
||||
return x.Model
|
||||
return x.Target
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
|
@ -319,13 +319,13 @@ var File_proto_iop_job_proto protoreflect.FileDescriptor
|
|||
|
||||
const file_proto_iop_job_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x13proto/iop/job.proto\x12\x03iop\"\x8a\x03\n" +
|
||||
"\x13proto/iop/job.proto\x12\x03iop\"\x8c\x03\n" +
|
||||
"\x03Job\x12\x15\n" +
|
||||
"\x06job_id\x18\x01 \x01(\tR\x05jobId\x12\x15\n" +
|
||||
"\x06run_id\x18\x02 \x01(\tR\x05runId\x12\x17\n" +
|
||||
"\anode_id\x18\x03 \x01(\tR\x06nodeId\x12\x18\n" +
|
||||
"\aadapter\x18\x04 \x01(\tR\aadapter\x12\x14\n" +
|
||||
"\x05model\x18\x05 \x01(\tR\x05model\x12&\n" +
|
||||
"\aadapter\x18\x04 \x01(\tR\aadapter\x12\x16\n" +
|
||||
"\x06target\x18\x05 \x01(\tR\x06target\x12&\n" +
|
||||
"\x06status\x18\x06 \x01(\x0e2\x0e.iop.JobStatusR\x06status\x12\x1d\n" +
|
||||
"\n" +
|
||||
"created_at\x18\a \x01(\x03R\tcreatedAt\x12\x1d\n" +
|
||||
|
|
|
|||
|
|
@ -73,7 +73,9 @@ func (NodeStatus) EnumDescriptor() ([]byte, []int) {
|
|||
return file_proto_iop_node_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
// NodeInfo describes a registered node.
|
||||
// NodeInfo is a legacy placeholder for node snapshots.
|
||||
// Current Edge-Node registration uses RegisterRequest/RegisterResponse in
|
||||
// runtime.proto, and Control Plane should observe nodes through Edge.
|
||||
type NodeInfo struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
NodeId string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"`
|
||||
|
|
@ -158,7 +160,8 @@ func (x *NodeInfo) GetLabels() map[string]string {
|
|||
return nil
|
||||
}
|
||||
|
||||
// NodeRegisterRequest is sent to the control-plane on startup.
|
||||
// NodeRegisterRequest is a legacy placeholder and is not the active startup
|
||||
// contract. Nodes connect to Edge, not directly to Control Plane.
|
||||
type NodeRegisterRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Info *NodeInfo `protobuf:"bytes,1,opt,name=info,proto3" json:"info,omitempty"`
|
||||
|
|
@ -203,7 +206,8 @@ func (x *NodeRegisterRequest) GetInfo() *NodeInfo {
|
|||
return nil
|
||||
}
|
||||
|
||||
// NodeRegisterResponse is returned by the control-plane.
|
||||
// NodeRegisterResponse is a legacy placeholder retained until the
|
||||
// Control Plane contracts are redesigned around Edge.
|
||||
type NodeRegisterResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Accepted bool `protobuf:"varint,1,opt,name=accepted,proto3" json:"accepted,omitempty"`
|
||||
|
|
|
|||
|
|
@ -4,14 +4,15 @@ package iop;
|
|||
|
||||
option go_package = "iop/proto/gen/iop";
|
||||
|
||||
// PolicyRule defines a routing/resource constraint.
|
||||
// PolicyRule is a placeholder for future edge-level routing/resource constraints.
|
||||
message PolicyRule {
|
||||
string name = 1;
|
||||
string expression = 2;
|
||||
map<string, string> params = 3;
|
||||
}
|
||||
|
||||
// ScheduleRequest asks the control-plane to route a job to a node.
|
||||
// ScheduleRequest is a legacy placeholder for future Control Plane orchestration.
|
||||
// It must not be treated as an active contract for direct Node scheduling.
|
||||
message ScheduleRequest {
|
||||
string job_id = 1;
|
||||
string target = 2;
|
||||
|
|
@ -19,7 +20,8 @@ message ScheduleRequest {
|
|||
map<string, string> metadata = 4;
|
||||
}
|
||||
|
||||
// ScheduleResponse contains the selected node address.
|
||||
// ScheduleResponse is a legacy placeholder. Future scheduling should be
|
||||
// reworked around Edge-owned runtime state instead of bypassing Edge.
|
||||
message ScheduleResponse {
|
||||
string node_id = 1;
|
||||
string address = 2;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ message Job {
|
|||
string run_id = 2;
|
||||
string node_id = 3;
|
||||
string adapter = 4;
|
||||
string model = 5;
|
||||
string target = 5;
|
||||
JobStatus status = 6;
|
||||
int64 created_at = 7;
|
||||
int64 started_at = 8;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ package iop;
|
|||
|
||||
option go_package = "iop/proto/gen/iop";
|
||||
|
||||
// NodeInfo describes a registered node.
|
||||
// NodeInfo is a legacy placeholder for node snapshots.
|
||||
// Current Edge-Node registration uses RegisterRequest/RegisterResponse in
|
||||
// runtime.proto, and Control Plane should observe nodes through Edge.
|
||||
message NodeInfo {
|
||||
string node_id = 1;
|
||||
string name = 2;
|
||||
|
|
@ -21,12 +23,14 @@ enum NodeStatus {
|
|||
NODE_STATUS_DRAINING = 3;
|
||||
}
|
||||
|
||||
// NodeRegisterRequest is sent to the control-plane on startup.
|
||||
// NodeRegisterRequest is a legacy placeholder and is not the active startup
|
||||
// contract. Nodes connect to Edge, not directly to Control Plane.
|
||||
message NodeRegisterRequest {
|
||||
NodeInfo info = 1;
|
||||
}
|
||||
|
||||
// NodeRegisterResponse is returned by the control-plane.
|
||||
// NodeRegisterResponse is a legacy placeholder retained until the
|
||||
// Control Plane contracts are redesigned around Edge.
|
||||
message NodeRegisterResponse {
|
||||
bool accepted = 1;
|
||||
string token = 2;
|
||||
|
|
|
|||
Loading…
Reference in a new issue