--- 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