<!-- task=m-node-multi-target-serving-foundation/04+01,02_engine_profiles plan=0 tag=API -->

# Plan - API

## 이 파일을 읽는 구현 에이전트에게

구현 마지막 단계는 `CODE_REVIEW-cloud-G08.md`에 실제 변경 내용과 검증 출력 기록이다. 사용자 전용 결정 없이 막히면 직접 질문하지 말고 `사용자 리뷰 요청`에 증거를 남긴다.

## 배경

Ollama adapter는 하나의 `baseURL`과 `contextSize`만 가진다. 같은 Node 연결에서 여러 Ollama endpoint/model, vLLM/SGLang류 OpenAI-compatible engine profile을 함께 쓰려면 provider/profile 기준을 Node 쪽 실행 단위에 반영해야 한다.

## 사용자 리뷰 요청 흐름

구현 중 blocker는 active review stub에 기록한다. code-review가 user-review stop 여부를 판단한다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/inference-provider-extension/milestones/node-multi-target-serving-foundation.md`
- Task ids:
  - `engine-profiles`: Ollama는 여러 `base_url`/model target과 target별 `context_size`를 지원하고, vLLM/SGLang 같은 OpenAI-compatible inference engine 연결을 같은 Node 통로에서 확장할 수 있는 provider/profile 기준이 정리되어 있다.
- Completion mode: check-on-pass

## 분석 결과

### 읽은 파일

- `agent-test/local/rules.md`
- `agent-test/local/node-smoke.md`
- `packages/go/config/config.go`
- `proto/iop/runtime.proto`
- `apps/node/internal/adapters/ollama/ollama.go`
- `apps/node/internal/adapters/ollama/ollama_test.go`
- `apps/node/internal/adapters/vllm/vllm.go`
- `apps/node/internal/adapters/vllm/vllm_test.go`
- `apps/node/internal/adapters/factory.go`
- `apps/node/internal/runtime/types.go`

### 테스트 환경 규칙

- test_env: `local`
- Node profile 기준 검증은 `go test ./apps/node/...`다. OpenAI-compatible provider 실행은 unit/fake HTTP server로 deterministic하게 검증한다.

### 테스트 커버리지 공백

- Ollama는 adapter instance 하나가 `baseURL` 하나만 가진다 (`apps/node/internal/adapters/ollama/ollama.go:23`).
- `Capabilities`가 endpoint별 target/source를 구분하지 않는다 (`apps/node/internal/adapters/ollama/ollama.go:45`).
- vLLM은 `Execute`가 비활성 에러를 반환한다 (`apps/node/internal/adapters/vllm/vllm.go:47`).
- multiple profile selection과 target별 `context_size` 테스트가 없다.

### 심볼 참조

- rename/remove 예정 심볼: 없음. `ollama.New`, `vllm.New`, `runtime.Capabilities`, `ExecutionSpec.Target/Input` 확장 가능성이 있다.

### 분할 판단

- predecessor `01`: config/proto topology 완료 필요. 현재 active plan, complete 없음.
- predecessor `02`: registry namespace 완료 필요. 현재 active plan, complete 없음.
- provider 실행은 route catalog와 독립적이지만 registry namespace가 있어야 같은 type 여러 instance를 안전하게 검증할 수 있다.

### 범위 결정 근거

- SGLang 전용 production hardening은 후속 SGLang milestone로 넘긴다.
- Edge route catalog와 OpenAI request option ownership은 별도 sibling task에서 다룬다.

### 빌드 등급

- build: `cloud-G07`, review: `cloud-G08`. provider 실행, fake HTTP server, config/proto 결과가 함께 얽혀 있어 cloud lane으로 둔다.

## 의존 관계 및 구현 순서

- `04+01,02_engine_profiles`는 `01_config_topology`와 `02+01_adapter_registry` 완료 후 구현한다. 디렉터리 이름의 `+01,02` 외 추가 dependency를 만들지 않는다.

## 구현 체크리스트

- [ ] Ollama multi profile이 endpoint/model/context를 target별로 선택한다.
- [ ] vLLM 또는 공통 OpenAI-compatible provider/profile baseline이 registry namespace 위에서 확장 가능하게 정리된다.
- [ ] provider capabilities가 profile/target 식별자를 모호하지 않게 반환한다.
- [ ] Ollama/vLLM/factory 테스트가 multi endpoint/profile 선택을 검증한다.
- [ ] 최종 검증 명령을 실행한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [API-1] Provider Profile Execution

- 문제: `Ollama`는 `baseURL`과 `contextSize`를 adapter instance 필드 하나로 보관한다 (`apps/node/internal/adapters/ollama/ollama.go:23`). `Execute`는 `spec.Target`을 model로만 해석한다 (`apps/node/internal/adapters/ollama/ollama.go:54`). vLLM은 target 조회만 일부 있고 실행은 disabled다 (`apps/node/internal/adapters/vllm/vllm.go:47`).
- 해결 방법: registry instance 또는 provider profile이 endpoint/context/model mapping을 가진다. `ExecutionSpec`가 route/profile metadata를 받거나 target namespace를 parsing 없이 안정적으로 해석한다. vLLM/SGLang류는 공통 OpenAI-compatible provider interface를 두되 완성 범위는 baseline과 fake-server 테스트로 제한한다.
- 수정 파일 및 체크리스트:
  - [ ] `apps/node/internal/adapters/ollama/ollama.go`: profile-aware endpoint/model/context selection.
  - [ ] `apps/node/internal/adapters/vllm/vllm.go`: OpenAI-compatible provider baseline 또는 명확한 extension point.
  - [ ] `apps/node/internal/adapters/factory.go`: profile config를 provider instance로 생성.
  - [ ] `apps/node/internal/runtime/types.go`: 필요한 profile route metadata 최소 추가.
- 테스트 작성: 추가한다. `ollama_test.go`에 두 fake server가 서로 다른 model/context를 받는 테스트를 두고, `vllm_test.go`에는 `/v1/models` 및 실행 baseline contract를 고정한다.
- 중간 검증:
  - `go test -count=1 ./apps/node/internal/adapters/ollama/... ./apps/node/internal/adapters/vllm/... ./apps/node/internal/adapters/...`

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `apps/node/internal/adapters/ollama/ollama.go` | API-1 |
| `apps/node/internal/adapters/ollama/ollama_test.go` | API-1 |
| `apps/node/internal/adapters/vllm/vllm.go` | API-1 |
| `apps/node/internal/adapters/vllm/vllm_test.go` | API-1 |
| `apps/node/internal/adapters/factory.go` | API-1 |
| `apps/node/internal/runtime/types.go` | API-1 |

## 최종 검증

```bash
go test -count=1 ./apps/node/...
```

모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.
