docs(27): research phase hermes-adapter domain
This commit is contained in:
parent
2a5abc2e54
commit
6328c4a5f9
1 changed files with 406 additions and 0 deletions
406
.planning/phases/27-hermes-adapter/27-RESEARCH.md
Normal file
406
.planning/phases/27-hermes-adapter/27-RESEARCH.md
Normal file
|
|
@ -0,0 +1,406 @@
|
|||
# Phase 27: Hermes Adapter - Research
|
||||
|
||||
**Researched:** 2026-04-01
|
||||
**Domain:** Hermes Agent adapter integration into Nexus (hermes-paperclip-adapter v0.2.1)
|
||||
**Confidence:** HIGH
|
||||
|
||||
## Summary
|
||||
|
||||
The `hermes-paperclip-adapter` package is already installed at v0.2.1 in both `server/` and `ui/` (at `server/node_modules/hermes-paperclip-adapter` and `ui/node_modules/hermes-paperclip-adapter`). It is fully implemented and already wired into both the server-side `adapters/registry.ts` and the UI-side `adapters/registry.ts`. The adapter type `hermes_local` is registered in `packages/shared/src/constants.ts`, appears in `NewAgentDialog.tsx`, `NewAgent.tsx`, `AgentDetail.tsx`, and has a `HermesIcon` component and `HermesLocalConfigFields` form.
|
||||
|
||||
However, research reveals that Phase 27 has **specific gaps** preventing full HERM-01 through HERM-04 compliance. These are mostly small integration bugs and missing wiring rather than large new features:
|
||||
|
||||
1. `hermes_local` is absent from `SESSIONED_LOCAL_ADAPTERS` in `heartbeat.ts` — the stale-run reaping logic will incorrectly treat a detached Hermes process as dead.
|
||||
2. `config-fields.tsx` has a bug in create-mode: the Toolsets field reads/writes `extraArgs` (the wrong `CreateConfigValues` field) instead of properly passing toolsets through `buildHermesConfig`.
|
||||
3. `AGENT_ADAPTER_TYPES` in `packages/shared/src/constants.ts` has a duplicate `gemini_local` entry — low-severity lint issue.
|
||||
4. The `hermes-dual-source.test.ts` test file already exists and all 7 tests pass. A `hermes-session-codec.test.ts` is absent from `adapter-session-codecs.test.ts` — there is no test for the hermes session codec round-trip.
|
||||
|
||||
**Primary recommendation:** Fix the four gaps above. The core adapter wiring is complete — this phase is about verification, small bug fixes, and ensuring the full HERM-01 through HERM-04 user flow works end to end.
|
||||
|
||||
---
|
||||
|
||||
<user_constraints>
|
||||
## User Constraints (from CONTEXT.md)
|
||||
|
||||
### Locked Decisions
|
||||
All implementation choices are at Claude's discretion — discuss phase was skipped per user setting. Use ROADMAP phase goal, success criteria, and codebase conventions to guide decisions.
|
||||
|
||||
### Claude's Discretion
|
||||
All implementation choices are at Claude's discretion.
|
||||
|
||||
### Deferred Ideas (OUT OF SCOPE)
|
||||
None — discuss phase skipped.
|
||||
</user_constraints>
|
||||
|
||||
---
|
||||
|
||||
<phase_requirements>
|
||||
## Phase Requirements
|
||||
|
||||
| ID | Description | Research Support |
|
||||
|----|-------------|------------------|
|
||||
| HERM-01 | Hermes adapter is installed, enabled, and appears in the "Add Agent" dropdown | Package installed. `hermesLocalAdapter` registered in server registry. `hermes_local` in `ADVANCED_ADAPTER_OPTIONS` array in `NewAgentDialog.tsx`. `HermesIcon` exists. Already complete — confirm with smoke test. |
|
||||
| HERM-02 | User can create a Hermes agent with config options (model selection, tool permissions) | `HermesLocalConfigFields` exists in `ui/src/adapters/hermes-local/config-fields.tsx` with model + toolsets + persistSession + timeoutSec fields. Bug in create-mode toolsets binding needs fix. |
|
||||
| HERM-03 | Heartbeat execution spawns `hermes chat -q`, processes task, returns result | `execute()` in `hermes-paperclip-adapter/dist/server/execute.js` is fully implemented. `hermesLocalAdapter` wired in server registry. Needs `hermes_local` added to `SESSIONED_LOCAL_ADAPTERS`. |
|
||||
| HERM-04 | Session persistence works across heartbeats via `--resume` flag | `sessionCodec` in adapter handles `sessionId` serialize/deserialize. `execute()` reads `ctx.runtime?.sessionParams?.sessionId` and passes `--resume`. Session saved in `executionResult.sessionParams`. No codec test exists yet. |
|
||||
</phase_requirements>
|
||||
|
||||
---
|
||||
|
||||
## Standard Stack
|
||||
|
||||
### Core
|
||||
| Library | Version | Purpose | Why Standard |
|
||||
|---------|---------|---------|--------------|
|
||||
| hermes-paperclip-adapter | 0.2.1 | Bridges Nexus heartbeat system to `hermes chat -q` CLI | Already installed in both server and UI; fully functional |
|
||||
| @paperclipai/adapter-utils | 2026.325.0 | Shared types/utilities for all adapters | Monorepo standard; defines `AdapterExecutionContext`, `AdapterSessionCodec`, etc. |
|
||||
|
||||
### Supporting
|
||||
| Library | Version | Purpose | When to Use |
|
||||
|---------|---------|---------|-------------|
|
||||
| vitest | 3.2.4 | Test framework | All new unit tests follow server test pattern |
|
||||
|
||||
**Version verification:** `hermes-paperclip-adapter@0.2.1` confirmed via `node_modules/.pnpm/hermes-paperclip-adapter@0.2.1/` directory and `package.json`. `^0.2.0` is in both `server/package.json` and `ui/package.json`.
|
||||
|
||||
**No installation needed** — package is already installed. Run `pnpm install` only if lock file needs updating.
|
||||
|
||||
---
|
||||
|
||||
## Architecture Patterns
|
||||
|
||||
### Existing Adapter Registration Pattern
|
||||
|
||||
Every adapter is registered in two registries:
|
||||
|
||||
**Server registry** (`server/src/adapters/registry.ts`):
|
||||
```typescript
|
||||
// Source: server/src/adapters/registry.ts lines 71–189
|
||||
const hermesLocalAdapter: ServerAdapterModule = {
|
||||
type: "hermes_local",
|
||||
execute: hermesExecute,
|
||||
testEnvironment: hermesTestEnvironment,
|
||||
sessionCodec: hermesSessionCodec,
|
||||
listSkills: hermesListSkills,
|
||||
syncSkills: hermesSyncSkills,
|
||||
models: hermesModels,
|
||||
supportsLocalAgentJwt: true,
|
||||
agentConfigurationDoc: hermesAgentConfigurationDoc,
|
||||
detectModel: () => detectModelFromHermes(),
|
||||
};
|
||||
// — Already complete. No changes needed.
|
||||
```
|
||||
|
||||
**UI registry** (`ui/src/adapters/registry.ts`):
|
||||
```typescript
|
||||
// Source: ui/src/adapters/registry.ts
|
||||
import { hermesLocalUIAdapter } from "./hermes-local";
|
||||
// Already included in uiAdapters array. No changes needed.
|
||||
```
|
||||
|
||||
**UI adapter module** (`ui/src/adapters/hermes-local/index.ts`):
|
||||
```typescript
|
||||
export const hermesLocalUIAdapter: UIAdapterModule = {
|
||||
type: "hermes_local",
|
||||
label: "Hermes Agent",
|
||||
parseStdoutLine: parseHermesStdoutLine, // from hermes-paperclip-adapter/ui
|
||||
ConfigFields: HermesLocalConfigFields, // local component
|
||||
buildAdapterConfig: buildHermesConfig, // from hermes-paperclip-adapter/ui
|
||||
};
|
||||
```
|
||||
|
||||
### Heartbeat Execution Flow
|
||||
|
||||
```
|
||||
Nexus heartbeat scheduler
|
||||
→ heartbeat.ts: getServerAdapter("hermes_local")
|
||||
→ registry.ts: hermesLocalAdapter.execute(ctx)
|
||||
→ hermes-paperclip-adapter/server/execute.js
|
||||
→ buildPrompt(ctx, config) → {{variable}} template rendering
|
||||
→ args = ["chat", "-q", prompt, "-Q"] → hermes chat -q "..." -Q
|
||||
→ if (prevSessionId) args.push("--resume", prevSessionId)
|
||||
→ runChildProcess(runId, "hermes", args, ...)
|
||||
→ parseHermesOutput(stdout, stderr) → extract sessionId, response, usage, cost
|
||||
→ return AdapterExecutionResult with sessionParams: { sessionId }
|
||||
→ heartbeat.ts: saves sessionParams to agentTaskSessions
|
||||
→ next run: ctx.runtime.sessionParams.sessionId = last sessionId
|
||||
```
|
||||
|
||||
### Session Persistence Flow (HERM-04)
|
||||
```
|
||||
Run N:
|
||||
ctx.runtime.sessionParams = null (first run)
|
||||
args = ["chat", "-q", prompt, "-Q"]
|
||||
stdout contains: "session_id: hermes-abc123"
|
||||
result.sessionParams = { sessionId: "hermes-abc123" }
|
||||
→ saved to DB via agentTaskSessions
|
||||
|
||||
Run N+1:
|
||||
ctx.runtime.sessionParams = { sessionId: "hermes-abc123" }
|
||||
args = ["chat", "-q", prompt, "-Q", "--resume", "hermes-abc123"]
|
||||
Hermes resumes the saved conversation context
|
||||
```
|
||||
|
||||
### SESSIONED_LOCAL_ADAPTERS Pattern
|
||||
|
||||
Location: `server/src/services/heartbeat.ts` lines 72–79.
|
||||
|
||||
This set controls whether a run's orphaned PID is checked for liveness. All child-process adapters should be in this set. `hermes_local` is currently missing:
|
||||
|
||||
```typescript
|
||||
// Current (MISSING hermes_local):
|
||||
const SESSIONED_LOCAL_ADAPTERS = new Set([
|
||||
"claude_local", "codex_local", "cursor",
|
||||
"gemini_local", "opencode_local", "pi_local",
|
||||
]);
|
||||
|
||||
// Fix (ADD hermes_local):
|
||||
const SESSIONED_LOCAL_ADAPTERS = new Set([
|
||||
"claude_local", "codex_local", "cursor",
|
||||
"gemini_local", "opencode_local", "pi_local",
|
||||
"hermes_local", // ← add this
|
||||
]);
|
||||
```
|
||||
|
||||
### Config-Fields Create-Mode Bug
|
||||
|
||||
Location: `ui/src/adapters/hermes-local/config-fields.tsx` lines 75–88.
|
||||
|
||||
In create mode (`isCreate === true`), the Toolsets field reads/writes `values!.extraArgs` and `set!({ extraArgs: v })`. This incorrectly stores toolsets as CLI extra-args. The `buildHermesConfig` function (called on form submit) reads `v.extraArgs` and splits it into an array of additional CLI flags — not `-t toolsets`.
|
||||
|
||||
The fix in create mode should set `values!.model` (or a custom field in `extraArgs`) or we need to recognize `CreateConfigValues` has no `toolsets` field. Looking at `buildHermesConfig` in the adapter, toolsets are **not read from any `CreateConfigValues` field** — they are only set when editing via `adapterConfig.toolsets` directly. The field binding in create mode is therefore best left mapping to `extraArgs` for now (it is the closest available field), or we can simply note this field only takes effect on edit, not create. The planner should evaluate whether the toolsets create-mode path matters for HERM-02, or whether we can ship without it (toolsets default to "all" if unset, which is fine).
|
||||
|
||||
### Anti-Patterns to Avoid
|
||||
- **Don't import from `hermes-paperclip-adapter/server` in UI code** — server-only exports use Node APIs that don't work in the browser. The UI only imports from `hermes-paperclip-adapter/ui`.
|
||||
- **Don't add toolset UI to `CreateConfigValues`** — the shared type from `@paperclipai/adapter-utils` is upstream; use `extraArgs` or defer toolset selection to the edit screen.
|
||||
- **Don't bypass the session codec** — always read/write session state through `sessionCodec.serialize/deserialize`; never store raw strings.
|
||||
|
||||
---
|
||||
|
||||
## Don't Hand-Roll
|
||||
|
||||
| Problem | Don't Build | Use Instead | Why |
|
||||
|---------|-------------|-------------|-----|
|
||||
| CLI spawning | Custom child_process wrapper | `runChildProcess` from `@paperclipai/adapter-utils/server-utils` | Handles PID tracking, timeout, SIGTERM/SIGKILL, log streaming |
|
||||
| Hermes stdout parsing | Custom line-by-line parser | `parseHermesStdoutLine` from `hermes-paperclip-adapter/ui` | Already handles all Hermes output patterns (tool cards, quiet-mode, session_id, etc.) |
|
||||
| Config building | Custom `adapterConfig` builder | `buildHermesConfig` from `hermes-paperclip-adapter/ui` | Handles model, extraArgs, timeout, persistSession defaults |
|
||||
| Environment testing | Custom `hermes --version` check | `testEnvironment` from `hermes-paperclip-adapter/server` | Checks CLI, Python version, API keys, provider consistency |
|
||||
| Model detection | Read `~/.hermes/config.yaml` manually | `detectModel` from `hermes-paperclip-adapter/server` | Already handles YAML parsing and fallbacks |
|
||||
|
||||
**Key insight:** `hermes-paperclip-adapter` is a complete, published package implementing every adapter interface. The plan should fix wiring gaps, not reimplement adapter logic.
|
||||
|
||||
---
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
### Pitfall 1: hermes_local Missing from SESSIONED_LOCAL_ADAPTERS
|
||||
**What goes wrong:** When a Nexus server restarts mid-heartbeat, the orphaned Hermes child process is incorrectly reaped (marked as failed) because `isTrackedLocalChildProcessAdapter("hermes_local")` returns `false`. The liveness check never fires.
|
||||
**Why it happens:** `SESSIONED_LOCAL_ADAPTERS` was not updated when `hermes_local` was added to the registry.
|
||||
**How to avoid:** Add `"hermes_local"` to the set in `heartbeat.ts`.
|
||||
**Warning signs:** Runs showing as "failed" immediately after server restart even though `hermes` process is still running.
|
||||
|
||||
### Pitfall 2: Create-Mode Toolsets Binding Uses Wrong Field
|
||||
**What goes wrong:** In `HermesLocalConfigFields` on the create form, the Toolsets field maps to `values!.extraArgs`, not a dedicated toolsets key. `buildHermesConfig` processes `extraArgs` as a space-separated list of raw CLI flags. Entering "terminal,file,web" in create mode would pass `terminal,file,web` as a CLI arg, not as `-t terminal,file,web`.
|
||||
**Why it happens:** `CreateConfigValues` has no `toolsets` field — it's an upstream type.
|
||||
**How to avoid:** Either (a) hide toolsets from create mode (toolsets default to "all" which is fine), or (b) document that toolsets are only configurable post-creation. Do not add a `toolsets` field to `CreateConfigValues`.
|
||||
**Warning signs:** Agent created with toolsets specified but running with all toolsets enabled.
|
||||
|
||||
### Pitfall 3: hermes_local Has a Duplicate in AGENT_ADAPTER_TYPES
|
||||
**What goes wrong:** `packages/shared/src/constants.ts` has `"gemini_local"` twice in `AGENT_ADAPTER_TYPES`. TypeScript's `as const` union deduplicates, so this is silent — but it's a maintenance hazard.
|
||||
**Why it happens:** Stale edit from when `hermes_local` was added.
|
||||
**How to avoid:** Remove the duplicate `"gemini_local"` entry.
|
||||
**Warning signs:** ESLint or tsc --noEmit showing warnings about duplicate array values.
|
||||
|
||||
### Pitfall 4: Session Codec Not Tested
|
||||
**What goes wrong:** The hermes `sessionCodec` handles both `sessionId` and `session_id` key variants (for legacy output). Without a test, a future refactor could silently break session persistence.
|
||||
**Why it happens:** `adapter-session-codecs.test.ts` tests all other adapters but not hermes.
|
||||
**How to avoid:** Add a hermes session codec test to `adapter-session-codecs.test.ts`.
|
||||
**Warning signs:** Session ID not persisting across heartbeats; run N+1 starts fresh instead of resuming.
|
||||
|
||||
### Pitfall 5: --yolo Flag Required for Non-TTY Execution
|
||||
**What goes wrong:** Without `--yolo`, Hermes prompts for confirmation before running "dangerous" commands (curl, python3, etc.). Since Nexus runs Hermes as a non-interactive subprocess, these prompts hang indefinitely.
|
||||
**Why it happens:** Hermes's safety system is designed for attended interactive use.
|
||||
**How to avoid:** The adapter already appends `--yolo` unconditionally. Do not remove this flag.
|
||||
**Warning signs:** Heartbeat run never completes; stdout contains "Awaiting confirmation" text.
|
||||
|
||||
---
|
||||
|
||||
## Code Examples
|
||||
|
||||
### Session Codec Round-Trip (for test)
|
||||
```typescript
|
||||
// Source: hermes-paperclip-adapter/dist/server/index.js
|
||||
import { sessionCodec } from "hermes-paperclip-adapter/server";
|
||||
|
||||
// Hermes -Q mode outputs: "session_id: hermes-abc123\n"
|
||||
// execute() stores resultJson.session_id → executionResult.sessionParams = { sessionId: "hermes-abc123" }
|
||||
const params = sessionCodec.deserialize({ sessionId: "hermes-abc123" });
|
||||
// params = { sessionId: "hermes-abc123" }
|
||||
|
||||
const serialized = sessionCodec.serialize(params);
|
||||
// serialized = { sessionId: "hermes-abc123" }
|
||||
|
||||
sessionCodec.getDisplayId(serialized);
|
||||
// "hermes-abc123"
|
||||
|
||||
// Also handles legacy snake_case output:
|
||||
const legacy = sessionCodec.deserialize({ session_id: "hermes-legacy-456" });
|
||||
// legacy = { sessionId: "hermes-legacy-456" }
|
||||
```
|
||||
|
||||
### Execute Context Shape
|
||||
```typescript
|
||||
// Source: hermes-paperclip-adapter/dist/server/execute.js
|
||||
const ctx: AdapterExecutionContext = {
|
||||
runId: "run-uuid",
|
||||
agent: {
|
||||
id: "agent-uuid",
|
||||
name: "Hermes Engineer",
|
||||
companyId: "company-uuid",
|
||||
adapterConfig: {
|
||||
model: "anthropic/claude-sonnet-4", // optional
|
||||
toolsets: "terminal,file,web", // optional
|
||||
persistSession: true, // default: true
|
||||
timeoutSec: 300, // default: 300
|
||||
},
|
||||
},
|
||||
runtime: {
|
||||
sessionParams: { sessionId: "hermes-abc123" }, // null on first run
|
||||
},
|
||||
config: {
|
||||
taskId: "TRA-42",
|
||||
taskTitle: "Implement feature X",
|
||||
taskBody: "...",
|
||||
},
|
||||
onLog: async (stream, chunk) => { /* stream stdout/stderr to UI */ },
|
||||
};
|
||||
```
|
||||
|
||||
### SESSIONED_LOCAL_ADAPTERS Fix
|
||||
```typescript
|
||||
// Source: server/src/services/heartbeat.ts line 72
|
||||
const SESSIONED_LOCAL_ADAPTERS = new Set([
|
||||
"claude_local",
|
||||
"codex_local",
|
||||
"cursor",
|
||||
"gemini_local",
|
||||
"opencode_local",
|
||||
"pi_local",
|
||||
"hermes_local", // ← add
|
||||
]);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Runtime State Inventory
|
||||
|
||||
> This phase does not involve rename/refactor — no runtime state migration required.
|
||||
|
||||
**Stored data:** None — no Hermes-specific records to migrate.
|
||||
**Live service config:** None — Hermes config lives in `~/.hermes/config.yaml` on the user's machine, not in Nexus state.
|
||||
**OS-registered state:** None.
|
||||
**Secrets/env vars:** None — API keys are in `~/.hermes/.env`, not Nexus-managed.
|
||||
**Build artifacts:** None.
|
||||
|
||||
---
|
||||
|
||||
## Environment Availability
|
||||
|
||||
| Dependency | Required By | Available | Version | Fallback |
|
||||
|------------|------------|-----------|---------|----------|
|
||||
| hermes-paperclip-adapter npm pkg | HERM-01 through HERM-04 | Yes | 0.2.1 (server + UI node_modules) | — |
|
||||
| hermes CLI binary | HERM-03 (runtime execution) | Unknown — user machine | — | testEnvironment returns "fail" gracefully; agent shows setup error in UI |
|
||||
| Python 3.10+ | HERM-03 (Hermes runtime) | Unknown — user machine | — | Same as above |
|
||||
|
||||
**Missing dependencies with no fallback:** None from Nexus's perspective. The `testEnvironment` function handles missing Hermes CLI gracefully with a `status: "fail"` result and a human-readable hint.
|
||||
|
||||
**Missing dependencies with fallback:** Hermes CLI not installed — user sees "fail" status in agent config panel with install instructions. This is expected behavior, not a blocking issue for the phase.
|
||||
|
||||
---
|
||||
|
||||
## Validation Architecture
|
||||
|
||||
### Test Framework
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| Framework | vitest 3.2.4 |
|
||||
| Config file | `server/vitest.config.ts` |
|
||||
| Quick run command | `pnpm --filter server exec vitest run src/__tests__/hermes-dual-source.test.ts` |
|
||||
| Full suite command | `pnpm test:run` |
|
||||
|
||||
### Phase Requirements → Test Map
|
||||
| Req ID | Behavior | Test Type | Automated Command | File Exists? |
|
||||
|--------|----------|-----------|-------------------|-------------|
|
||||
| HERM-01 | `hermes_local` appears in UI adapter registry and NewAgentDialog | unit (registry check) | `pnpm --filter server exec vitest run src/__tests__/adapter-skill-config.test.ts` | Yes |
|
||||
| HERM-02 | `HermesLocalConfigFields` renders model + toolsets fields | unit/smoke | `pnpm --filter server exec vitest run src/__tests__/hermes-dual-source.test.ts` | Yes (skill tests) |
|
||||
| HERM-03 | Heartbeat execution spawns `hermes chat -q` and returns result | integration | `pnpm --filter server exec vitest run src/__tests__/hermes-dual-source.test.ts` | Partial |
|
||||
| HERM-04 | Session persistence via `--resume` across heartbeats | unit (session codec) | `pnpm --filter server exec vitest run src/__tests__/adapter-session-codecs.test.ts` | Needs hermes case added |
|
||||
|
||||
### Sampling Rate
|
||||
- **Per task commit:** `pnpm --filter server exec vitest run src/__tests__/hermes-dual-source.test.ts src/__tests__/adapter-session-codecs.test.ts`
|
||||
- **Per wave merge:** `pnpm test:run`
|
||||
- **Phase gate:** Full suite green before `/gsd:verify-work`
|
||||
|
||||
### Wave 0 Gaps
|
||||
- [ ] `server/src/__tests__/adapter-session-codecs.test.ts` — add `hermes sessionCodec` describe block covering serialize, deserialize, getDisplayId, and legacy `session_id` key variant
|
||||
|
||||
*(All other test infrastructure is already present)*
|
||||
|
||||
---
|
||||
|
||||
## State of the Art
|
||||
|
||||
| Old Approach | Current Approach | When Changed | Impact |
|
||||
|--------------|------------------|--------------|--------|
|
||||
| Custom execute function per adapter | Use `runChildProcess` from `@paperclipai/adapter-utils/server-utils` | adapter-utils 2026.x | Standardized PID tracking, timeout, log streaming across all adapters |
|
||||
| Adapter inline in server code | Published external package (`hermes-paperclip-adapter`) | hermes-paperclip-adapter 0.2.x | Decoupled from Nexus upstream; versioned independently |
|
||||
|
||||
**Deprecated/outdated:**
|
||||
- `addListener` for media queries: not applicable here.
|
||||
|
||||
---
|
||||
|
||||
## Open Questions
|
||||
|
||||
1. **Create-mode toolsets field**
|
||||
- What we know: `CreateConfigValues` has no `toolsets` field; the current create-form code incorrectly uses `extraArgs`.
|
||||
- What's unclear: Whether HERM-02's "tool permissions" requirement specifically calls for toolsets to be configurable at agent creation time (vs. post-creation in the edit form).
|
||||
- Recommendation: Ship with toolsets available only in edit mode (post-creation). Default is "all toolsets" which is sensible. Document in agent config panel.
|
||||
|
||||
2. **`detectModel` capability in `hermesLocalAdapter`**
|
||||
- What we know: `hermesLocalAdapter` has a `detectModel` property calling `detectModelFromHermes()`, which reads `~/.hermes/config.yaml`. No other adapter currently uses `detectModel`.
|
||||
- What's unclear: Whether the UI currently calls `detectModel` to pre-populate the model field during agent creation.
|
||||
- Recommendation: Check if `agentsApi` exposes a `detectModel` endpoint; if not, this feature silently does nothing in the UI and can be left as-is.
|
||||
|
||||
---
|
||||
|
||||
## Sources
|
||||
|
||||
### Primary (HIGH confidence)
|
||||
- `server/src/adapters/registry.ts` — `hermesLocalAdapter` definition, verified complete
|
||||
- `ui/src/adapters/hermes-local/index.ts` and `config-fields.tsx` — UI adapter wiring, verified
|
||||
- `hermes-paperclip-adapter/dist/server/execute.js` — full execute() implementation, read in full
|
||||
- `hermes-paperclip-adapter/dist/server/index.js` — sessionCodec, read in full
|
||||
- `hermes-paperclip-adapter/README.md` — canonical usage docs, read in full
|
||||
- `server/src/services/heartbeat.ts` (SESSIONED_LOCAL_ADAPTERS, lines 72–79) — gap confirmed
|
||||
- `packages/shared/src/constants.ts` — duplicate gemini_local confirmed
|
||||
- `server/src/__tests__/hermes-dual-source.test.ts` — 7/7 tests passing, verified by run
|
||||
|
||||
### Secondary (MEDIUM confidence)
|
||||
- `hermes-paperclip-adapter/dist/ui/build-config.js` — `buildHermesConfig` implementation confirming extraArgs handling
|
||||
- `hermes-paperclip-adapter/dist/ui/parse-stdout.js` — full stdout parser implementation
|
||||
|
||||
### Tertiary (LOW confidence)
|
||||
- None.
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
**Confidence breakdown:**
|
||||
- Standard stack: HIGH — packages installed, imports verified, tests passing
|
||||
- Architecture: HIGH — full implementation read from source
|
||||
- Pitfalls: HIGH — gaps confirmed by reading actual source files
|
||||
- Session persistence: HIGH — codec and execute() both read in full
|
||||
|
||||
**Research date:** 2026-04-01
|
||||
**Valid until:** 2026-05-01 (30 days — adapter package is stable)
|
||||
Loading…
Add table
Reference in a new issue