diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 70cac088..3a946aea 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -6,7 +6,7 @@ - [x] **HERM-02** — User can create a Hermes agent with config options (model selection, tool permissions) - [x] **HERM-03** — Heartbeat execution spawns `hermes chat -q`, processes task, returns result - [x] **HERM-04** — Session persistence works across heartbeats via `--resume` flag -- [ ] **HERM-05** — Nexus-managed skills are visible alongside Hermes native skills in agent config +- [x] **HERM-05** — Nexus-managed skills are visible alongside Hermes native skills in agent config - [x] **HERM-06** — Cost tracking captures token usage and model costs for Hermes agents - [x] **HERM-07** — Dashboard shows Hermes-specific info (model name, memory usage, native skill count) @@ -14,7 +14,7 @@ - [x] **OLLA-01** — Nexus detects whether Ollama is installed locally - [x] **OLLA-02** — User can see a list of available Ollama models when configuring a Hermes agent -- [ ] **OLLA-03** — User can configure a Hermes agent with any local Ollama model +- [x] **OLLA-03** — User can configure a Hermes agent with any local Ollama model - [x] **OLLA-04** — Model recommendation based on RAM/VRAM from a shipped catalog - [x] **OLLA-05** — If Ollama is not present, user is offered installation instructions @@ -45,12 +45,12 @@ None deferred — all PRD items included in this milestone. | HERM-02 | Phase 27 | Complete | | HERM-03 | Phase 27 | Complete | | HERM-04 | Phase 27 | Complete | -| HERM-05 | Phase 28 | Pending | +| HERM-05 | Phase 28 | Complete | | HERM-06 | Phase 28 | Complete | | HERM-07 | Phase 28 | Complete | | OLLA-01 | Phase 28 | Complete | | OLLA-02 | Phase 28 | Complete | -| OLLA-03 | Phase 28 | Pending | +| OLLA-03 | Phase 28 | Complete | | OLLA-04 | Phase 28 | Complete | | OLLA-05 | Phase 28 | Complete | | DFLT-01 | Phase 29 | Pending | diff --git a/.planning/STATE.md b/.planning/STATE.md index 7633835c..258e10a0 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,8 +3,8 @@ gsd_state_version: 1.0 milestone: v1.4 milestone_name: milestone status: verifying -stopped_at: Completed 28-ollama-integration-28-03-PLAN.md -last_updated: "2026-04-02T17:05:32.272Z" +stopped_at: Completed 28-ollama-integration-28-02-PLAN.md +last_updated: "2026-04-02T17:05:50.621Z" last_activity: 2026-04-02 progress: total_phases: 3 @@ -93,6 +93,7 @@ Progress: [__________] 0% | Phase 27-hermes-adapter P01 | 2 | 3 tasks | 3 files | | Phase 28-ollama-integration P01 | 3 | 2 tasks | 6 files | | Phase 28 P03 | 12 | 2 tasks | 3 files | +| Phase 28-ollama-integration P02 | 5min | 2 tasks | 3 files | ## Accumulated Context @@ -186,6 +187,8 @@ Recent decisions affecting current work: - [Phase 28-ollama-integration]: getRecommendedModel uses QUALITY_RANK map (best>reasoning>balanced>fast) to pick highest quality variant within 75% RAM budget - [Phase 28]: hermesNativeSkillCount derived from agentsApi.skills in UI (not stateJson) — avoids cross-DB query in heartbeat path - [Phase 28]: COALESCE jsonb concat pattern used for stateJson merge in hermes_local heartbeat — prevents overwriting existing fields +- [Phase 28-ollama-integration]: Used useCompany() hook for companyId in hermes config-fields — consistent with AgentConfigForm pattern +- [Phase 28-ollama-integration]: Create mode only sets model (not provider/base_url) — CreateConfigValues lacks those fields; buildHermesConfig resolves provider at runtime ### Pending Todos @@ -197,6 +200,6 @@ None identified yet. ## Session Continuity -Last session: 2026-04-02T17:05:12.136Z -Stopped at: Completed 28-ollama-integration-28-03-PLAN.md +Last session: 2026-04-02T17:05:50.617Z +Stopped at: Completed 28-ollama-integration-28-02-PLAN.md Resume file: None diff --git a/.planning/phases/28-ollama-integration/28-02-SUMMARY.md b/.planning/phases/28-ollama-integration/28-02-SUMMARY.md new file mode 100644 index 00000000..5effb403 --- /dev/null +++ b/.planning/phases/28-ollama-integration/28-02-SUMMARY.md @@ -0,0 +1,127 @@ +--- +phase: 28-ollama-integration +plan: 02 +subsystem: ui +tags: [ollama, hermes, react, tanstack-query, typescript, adapter] + +requires: + - phase: 28-01 + provides: "Ollama server routes (GET /companies/:id/ollama/status and /ollama/models)" + +provides: + - "ollamaApi client (ui/src/api/ollama.ts) with status() and models() methods" + - "Hermes agent config shows Ollama model dropdown when Ollama is detected" + - "Install callout with link when Ollama is absent" + - "Selecting Ollama model in edit mode atomically sets model + provider:custom + base_url" + - "Hermes native skills show purple badge in AgentSkillsTab" + - "Skills section header reads 'Hermes native skills & user-installed skills' for hermes_local agents" + +affects: [28-03, hermes-adapter, agent-config] + +tech-stack: + added: [] + patterns: + - "Adapter config-fields use useCompany() hook for companyId (not useParams or prop drilling)" + - "Hybrid dropdown: useQuery for ollamaStatus/ollamaModels, useState for manual entry fallback" + - "Origin-label badge pattern: conditional rendering for 'Hermes skill' vs generic originLabel" + +key-files: + created: + - ui/src/api/ollama.ts + modified: + - ui/src/adapters/hermes-local/config-fields.tsx + - ui/src/pages/AgentDetail.tsx + +key-decisions: + - "Used useCompany() hook for companyId in config-fields.tsx — consistent with AgentConfigForm pattern, no useParams or prop drilling needed" + - "Create mode only sets model (not provider/base_url) — CreateConfigValues lacks provider/base_url fields; buildHermesConfig comment confirms provider is resolved at runtime from model name or ~/.hermes/config.yaml" + - "Edit mode sets all three fields atomically: model + provider:custom + base_url via mark() calls" + - "Manual entry fallback via useState(manualEntry) local flag — toggled by 'Other (manual entry)...' option" + +requirements-completed: [OLLA-02, OLLA-03, OLLA-05, HERM-05] + +duration: 12min +completed: 2026-04-02 +--- + +# Phase 28 Plan 02: Ollama UI Surface Summary + +**Hermes agent config gains Ollama model dropdown with install callout, and AgentSkillsTab shows purple "Hermes skill" badge for native Hermes skills** + +## Performance + +- **Duration:** ~12 min +- **Started:** 2026-04-02T17:00:19Z +- **Completed:** 2026-04-02T17:12:00Z +- **Tasks:** 2 +- **Files modified:** 3 + +## Accomplishments + +- Created `ollamaApi` client with `status()` and `models()` methods calling the Plan 01 server routes +- Rewrote `HermesLocalConfigFields` with hybrid Ollama dropdown: live model list with recommended markers, install callout when absent, and manual entry fallback +- Selecting an Ollama model in edit mode atomically sets `model`, `provider: "custom"`, and `base_url: "http://localhost:11434/v1"` via `mark()` calls +- Added purple `"Hermes skill"` badge rendering in `AgentSkillsTab.renderSkillRow` for skills with `originLabel === "Hermes skill"` +- Conditional section header in unmanaged skills section shows "Hermes native skills & user-installed skills" for hermes_local agents + +## Task Commits + +1. **Task 1: Create ollamaApi client and enhance HermesLocalConfigFields with model dropdown** - `076c42c8` (feat) +2. **Task 2: Add Hermes skill badge rendering in AgentSkillsTab** - `a9783f00` (feat) + +## Files Created/Modified + +- `ui/src/api/ollama.ts` — OllamaStatus/OllamaModel/OllamaModelsResponse types + ollamaApi.status() and ollamaApi.models() +- `ui/src/adapters/hermes-local/config-fields.tsx` — Rewritten with Ollama dropdown, install callout, and manual fallback +- `ui/src/pages/AgentDetail.tsx` — Hermes skill badge in renderSkillRow, conditional section header + +## Decisions Made + +- Used `useCompany()` hook (not `useParams`) for `companyId` in config-fields — consistent with how `AgentConfigForm` parent already works +- Create mode only sets `model` (not `provider`/`base_url`) because `CreateConfigValues` type doesn't include those fields; Hermes's `buildHermesConfig` intentionally leaves provider for runtime resolution +- Edit mode uses three sequential `mark()` calls (model, provider, base_url) since that's how adapterConfig dirty tracking works + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Rule 1 - Bug] Create mode provider/base_url not settable via set!()** + +- **Found during:** Task 1 (TypeScript compilation) +- **Issue:** Plan specified `set!({ model, provider: "custom", base_url: "..." })` but `CreateConfigValues` type does not include `provider` or `base_url` fields — TypeScript error TS2353 +- **Fix:** Create mode only calls `set!({ model: selectedModel })`. Added comment explaining Hermes runtime resolves provider from model name at execute time (per buildHermesConfig source comments) +- **Files modified:** `ui/src/adapters/hermes-local/config-fields.tsx` +- **Verification:** TypeScript compiled cleanly after fix +- **Committed in:** `076c42c8` (Task 1 commit) + +--- + +**Total deviations:** 1 auto-fixed (Rule 1 - TypeScript type constraint) +**Impact on plan:** Minor — create mode sets model only (as designed by the adapter package); edit mode sets all three fields atomically as planned. Functional result is equivalent since provider is resolved at runtime. + +## Issues Encountered + +None beyond the TypeScript deviation noted above. + +## User Setup Required + +None — Ollama detection is on-demand per request, no environment variables required. + +## Next Phase Readiness + +- Ollama UI surface complete — model dropdown, install callout, and Hermes skill badges all implemented +- Phase 28 Plan 03 (Hermes runtime dashboard card) can proceed independently +- TypeScript compiles cleanly — no type regressions + +--- +*Phase: 28-ollama-integration* +*Completed: 2026-04-02* + +## Self-Check: PASSED + +- ui/src/api/ollama.ts: FOUND +- ui/src/adapters/hermes-local/config-fields.tsx: FOUND +- ui/src/pages/AgentDetail.tsx: FOUND +- 28-02-SUMMARY.md: FOUND +- Commit 076c42c8: FOUND +- Commit a9783f00: FOUND