@agentproto/adapter-hermes 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +9 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -36,7 +36,15 @@ var hermes = defineAgentCli({
|
|
|
36
36
|
session: {
|
|
37
37
|
mode: "persistent",
|
|
38
38
|
idle_timeout_ms: 18e5,
|
|
39
|
-
context_carryover: true
|
|
39
|
+
context_carryover: true,
|
|
40
|
+
// hermes's own ACP server has been observed to hit its internal
|
|
41
|
+
// max-tool-iterations cap, produce a final answer, and then never
|
|
42
|
+
// send the `prompt` JSON-RPC response — hanging the daemon's turn
|
|
43
|
+
// drain loop forever with no other adapter-side signal available.
|
|
44
|
+
// 5 minutes of true silence (reset on any ACP traffic, so a long
|
|
45
|
+
// legitimate tool-call chain doesn't false-positive) is generous
|
|
46
|
+
// enough to not trip during normal use.
|
|
47
|
+
turn_idle_timeout_ms: 3e5
|
|
40
48
|
},
|
|
41
49
|
models: {
|
|
42
50
|
// Cheap OpenRouter models by default — hermes is the budget delegation
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;AAyBO,IAAM,SAAyB,cAAA,CAAe;AAAA,EACnD,IAAA,EAAM,QAAA;AAAA,EACN,EAAA,EAAI,QAAA;AAAA,EACJ,WAAA,EACE,qLAAA;AAAA,EACF,OAAA,EAAS,OAAA;AAAA,EACT,GAAA,EAAK,QAAA;AAAA,EACL,QAAA,EAAU,CAAC,KAAK,CAAA;AAAA,EAChB,OAAA,EAAS;AAAA,IACP;AAAA,MACE,MAAA,EAAQ,MAAA;AAAA,MACR,GAAA,EAAK;AAAA;AACP,GACF;AAAA,EACA,aAAA,EAAe;AAAA,IACb,GAAA,EAAK,kBAAA;AAAA,IACL,KAAA,EAAO,sBAAA;AAAA,IACP,KAAA,EAAO,iBAAA;AAAA,IACP,UAAA,EAAY;AAAA,GACd;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,GAAA,EAAK,cAAA;AAAA,IACL,OAAO,EAAE,GAAA,EAAK,CAAC,oBAAA,EAAsB,mBAAA,EAAqB,gBAAgB,CAAA;AAAE,GAC9E;AAAA,EACA,OAAA,EAAS,cAAA;AAAA,EACT,QAAA,EAAU,KAAA;AAAA,EACV,GAAA,EAAK,qBAAA;AAAA,EACL,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,YAAA;AAAA,IACN,eAAA,EAAiB,IAAA;AAAA,IACjB,iBAAA,EAAmB;AAAA,
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * @agentproto/adapter-hermes — AIP-45 adapter for Nous Research's Hermes Agent.\n *\n * Re-exports a `defineAgentCli` instance plus the runtime factory so\n * a host can boot Hermes with one import:\n *\n * import { hermes, hermesRuntime } from \"@agentproto/adapter-hermes\"\n * const session = await hermesRuntime().start({ env: { OPENROUTER_API_KEY } })\n * for await (const evt of session.send({ role: \"user\", content: \"...\" })) {\n * console.log(evt)\n * }\n * await session.close()\n *\n * The companion HERMES.md / SECRETS.md / hermes-acp.ACP.md files in\n * this package describe the manifest, secret slots, and ACP wire\n * profile.\n */\n\nimport {\n createAgentCliRuntime,\n defineAgentCli,\n type AgentCliHandle,\n type AgentCliRuntime,\n} from \"@agentproto/driver-agent-cli\"\n\nexport const hermes: AgentCliHandle = defineAgentCli({\n name: \"hermes\",\n id: \"hermes\",\n description:\n \"Nous Research's Hermes Agent — autonomous CLI agent with skills, sandboxes, memory plugins, and a built-in ACP server. Spawned as `hermes acp` and driven over stdio JSON-RPC.\",\n version: \"0.1.0\",\n bin: \"hermes\",\n bin_args: [\"acp\"],\n install: [\n {\n method: \"curl\",\n url: \"https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh\",\n },\n ],\n version_check: {\n cmd: \"hermes --version\",\n parse: \"(\\\\d+\\\\.\\\\d+\\\\.\\\\d+)\",\n range: \">=0.13.0 <1.0.0\",\n timeout_ms: 5000,\n },\n auth: {\n ref: \"./SECRETS.md\",\n state: { env: [\"OPENROUTER_API_KEY\", \"ANTHROPIC_API_KEY\", \"OPENAI_API_KEY\"] },\n },\n sandbox: \"./SANDBOX.md\",\n protocol: \"acp\",\n acp: \"./hermes-acp.ACP.md\",\n session: {\n mode: \"persistent\",\n idle_timeout_ms: 1_800_000,\n context_carryover: true,\n // hermes's own ACP server has been observed to hit its internal\n // max-tool-iterations cap, produce a final answer, and then never\n // send the `prompt` JSON-RPC response — hanging the daemon's turn\n // drain loop forever with no other adapter-side signal available.\n // 5 minutes of true silence (reset on any ACP traffic, so a long\n // legitimate tool-call chain doesn't false-positive) is generous\n // enough to not trip during normal use.\n turn_idle_timeout_ms: 300_000,\n },\n models: {\n // Cheap OpenRouter models by default — hermes is the budget delegation\n // arm (a Sonnet default would defeat the purpose). glm-5.2 + deepseek\n // are the go-to cheap coders; the bigger models stay available.\n default: \"z-ai/glm-5.2\",\n allowed: [\n \"z-ai/glm-5.2\",\n \"deepseek/deepseek-v4-pro\",\n \"meta-llama/llama-3.3-70b\",\n \"anthropic/claude-sonnet-4-6\",\n \"anthropic/claude-opus-4-7\",\n \"openai/gpt-4\",\n ],\n env: {\n anthropic: \"ANTHROPIC_API_KEY\",\n openrouter: \"OPENROUTER_API_KEY\",\n openai: \"OPENAI_API_KEY\",\n },\n // hermes keeps its own configured default when given a model via the\n // ACP session config — selection must go through a `/model <id>`\n // control turn instead. See AgentCliModels.apply.\n apply: \"command\",\n },\n capabilities: {\n streaming: true,\n tool_calls: true,\n sub_agents: true,\n file_io: true,\n multimodal: true,\n resumable: false,\n bidirectional: true,\n },\n options: [\n {\n id: \"model\",\n // string (not enum) so any valid OpenRouter/Anthropic/OpenAI model ID is\n // accepted without requiring a code change to expand the list. Applied via\n // ACP newSession(model:...) — hermes reads the model from the ACP session\n // config, not from its own CLI args.\n type: \"string\" as const,\n description:\n \"Model ID routed through OpenRouter/Anthropic/OpenAI \" +\n \"(e.g. 'anthropic/claude-sonnet-4-6', 'deepseek/deepseek-v4-pro', 'z-ai/glm-5.2'). \" +\n \"Applied via a `/model <id>` control turn after the session is created \" +\n \"(hermes ignores the ACP session model config). \" +\n \"Omit to use the hermes default.\",\n },\n {\n id: \"effort\",\n type: \"enum\" as const,\n enum: [\"low\", \"medium\", \"high\", \"xhigh\", \"max\"],\n description:\n \"Reasoning effort level passed to hermes via ACP newSession. \" +\n \"Omit to use the hermes default.\",\n },\n ],\n tags: [\"hermes\", \"nous\", \"acp\", \"agent-runtime\"],\n})\n\nexport function hermesRuntime(): AgentCliRuntime {\n return createAgentCliRuntime(hermes)\n}\n\nimport { homedir } from \"node:os\"\nimport { join } from \"node:path\"\n\n/** Best-effort read of a hermes session's cost/token usage from its state.db.\n *\n * hermes writes the per-turn cost to state.db slightly AFTER the ACP turn\n * ends, so a single read right at turn-end usually finds the cost column\n * still null. We poll a few times with a short backoff until the cost lands\n * (or give up — best-effort, never throws). Bounded so a missing write can't\n * hang the caller (the turn-end path awaits this). */\nexport async function readHermesUsage(\n sessionId: string,\n): Promise<{ costUsd?: number; tokensIn?: number; tokensOut?: number } | null> {\n try {\n // node:sqlite is a Node 22+ builtin. Build the specifier at runtime so the\n // bundler (esbuild/tsup) can't statically rewrite it — it strips the\n // `node:` prefix off this not-yet-recognised builtin, turning the import\n // into a missing `sqlite` package that throws and silently yields null.\n const sqliteSpecifier = [\"node\", \"sqlite\"].join(\":\")\n const { DatabaseSync } = (await import(sqliteSpecifier)) as unknown as {\n DatabaseSync: new (p: string, o?: { readOnly?: boolean }) => {\n prepare(sql: string): { get(...a: unknown[]): unknown }\n close(): void\n }\n }\n const dbPath = join(homedir(), \".hermes\", \"state.db\")\n const ATTEMPTS = 6\n const DELAY_MS = 130\n let last: { costUsd?: number; tokensIn?: number; tokensOut?: number } | null = null\n for (let i = 0; i < ATTEMPTS; i++) {\n const db = new DatabaseSync(dbPath, { readOnly: true })\n const row = db.prepare(\n \"select estimated_cost_usd as cost, input_tokens as ti, output_tokens as to_ from sessions where id = ?\",\n ).get(sessionId) as { cost?: number; ti?: number; to_?: number } | undefined\n db.close()\n if (row) {\n last = { costUsd: row.cost, tokensIn: row.ti, tokensOut: row.to_ }\n // Cost has landed (non-null) → done. Otherwise keep polling: the row\n // exists but hermes hasn't written the cost for this turn yet.\n if (row.cost !== null && row.cost !== undefined) return last\n }\n if (i < ATTEMPTS - 1) await new Promise(r => setTimeout(r, DELAY_MS))\n }\n return last\n } catch {\n return null\n }\n}\n\nexport type { AgentCliHandle, AgentCliRuntime }\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentproto/adapter-hermes",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "@agentproto/adapter-hermes — AIP-45 AGENT-CLI adapter for Nous Research's Hermes Agent. Spawns `hermes acp` and drives it as an agentproto agent CLI via the ACP protocol arm of @agentproto/driver-agent-cli.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agentproto",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"access": "public"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@agentproto/driver-agent-cli": "0.
|
|
46
|
+
"@agentproto/driver-agent-cli": "0.3.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@types/node": "^25.6.2",
|