# Agent harness map Source of truth for Jarvis runtime: `vendor/agent-harness/`, copied from `/home/raven/dev/agent-harness` (`~/dev/agent-harness`). The original extracted tree remains the upstream working source; the vendored directory is the copy that ships with this repository. ## Layout and runtime The harness is a standalone Node.js CommonJS package. Its public entrypoint is `index.js`, with the CLI at `bin/cli.js`. The README says Node 20 is enough for the harness itself, while its QVAC inference dependency requires Node 22.17+; Jarvis therefore requires Node 22.17+. Important modules: - `index.js`: public `Agent.create()` / `Agent.load()`, session wrapper, engine and catalog exports. - `agent/loop.js`: sample → tool call → tool result → repeat loop, permissions, plan mode, compaction, memory, and subagents. - `agent/custom-tools.js`: per-session JSON-schema tool registry and in-process `execute` handlers. - `agent/tools.js`: built-in host workspace, memory, planning, web, task, and MCP tools. - `agent/sessions.js`: persisted session summaries, history, updates, and plan files. - `agent/memory.js`: local short/long-term memory notes. - `lib/qvac.js`: lazy `@qvac/sdk` import, model loading, completion streaming, vision attachments, cancellation, and lifecycle close. - `lib/catalog.js`: friendly model ids mapped to QVAC SDK constants. ## Start and embed CLI: `node vendor/agent-harness/bin/cli.js [options] [prompt]`. Library integration uses CommonJS from the harness root: ```js const Agent = require('./vendor/agent-harness'); await Agent.engine.load({ model: 'qwen3.5-4b', tools: true, device: 'auto' }); const session = await Agent.create({ cwd: process.cwd(), model: 'qwen3.5-4b', permissionMode: 'ask', tools: [{ name, description, parameters, execute }], }); await session.prompt('hello'); await session.dispose(); await Agent.engine.close(); ``` Sessions emit `agent_message_chunk`, `tool_call`, `permission`, `ask_user`, plan, context, and related loop events. Jarvis adapts the message and tool events to its D-Bus contract. `session.permit()`, `session.answer()`, `session.cancel()`, and `session.addTool()` are the control points. ## Tool registry and permissions Jarvis registers tools through `Agent.create({ tools })`. Each custom tool is a JSON-schema object with an optional in-process `execute(args)` handler. The harness caps custom tools at 32 and reserves its built-ins. Permission mode is `ask` by default; write and dangerous desktop/computer-use tools remain behind Jarvis confirmation gates. ## Session, memory, and planner `agent/loop.js` owns the multi-turn agent loop and repeats completion/tool execution until a final response. `sessions.js` persists conversation state. `memory.js` provides local memory tools. `plan-mode.js`, `compaction.js`, `goal.js`, and `tasks.js` provide planning, context management, goals, and subagents. Jarvis does not create a second planner. ## Model connection The harness does not use an OpenAI-compatible HTTP URL internally. Its `lib/qvac.js` imports `@qvac/sdk` in-process and calls `loadModel()` and `completion()`. Jarvis keeps the optional sibling `qvac serve --openai` provider for external clients and diagnostics, while the cognition bridge wraps the harness in-process as required by the extracted package. ## Computer use The inspected harness has no first-class portal, AT-SPI, libei, or desktop computer-use backend. Jarvis therefore supplies those as custom tools from `computer-use/` and `skills/`, while keeping planning in `agent/loop.js`.