@fideliosai/adapter-hermes-local 0.0.4-canary.0
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/LICENSE +22 -0
- package/package.json +29 -0
- package/src/cli/format-event.d.ts +14 -0
- package/src/cli/format-event.d.ts.map +1 -0
- package/src/cli/format-event.js +52 -0
- package/src/cli/format-event.js.map +1 -0
- package/src/cli/index.d.ts +5 -0
- package/src/cli/index.d.ts.map +1 -0
- package/src/cli/index.js +5 -0
- package/src/cli/index.js.map +1 -0
- package/src/index.d.ts +28 -0
- package/src/index.d.ts.map +1 -0
- package/src/index.js +81 -0
- package/src/index.js.map +1 -0
- package/src/server/detect-model.d.ts +21 -0
- package/src/server/detect-model.d.ts.map +1 -0
- package/src/server/detect-model.js +63 -0
- package/src/server/detect-model.js.map +1 -0
- package/src/server/execute.d.ts +20 -0
- package/src/server/execute.d.ts.map +1 -0
- package/src/server/execute.js +389 -0
- package/src/server/execute.js.map +1 -0
- package/src/server/index.d.ts +16 -0
- package/src/server/index.d.ts.map +1 -0
- package/src/server/index.js +43 -0
- package/src/server/index.js.map +1 -0
- package/src/server/skills.d.ts +8 -0
- package/src/server/skills.d.ts.map +1 -0
- package/src/server/skills.js +179 -0
- package/src/server/skills.js.map +1 -0
- package/src/server/test.d.ts +9 -0
- package/src/server/test.d.ts.map +1 -0
- package/src/server/test.js +196 -0
- package/src/server/test.js.map +1 -0
- package/src/shared/constants.d.ts +31 -0
- package/src/shared/constants.d.ts.map +1 -0
- package/src/shared/constants.js +40 -0
- package/src/shared/constants.js.map +1 -0
- package/src/ui/build-config.d.ts +12 -0
- package/src/ui/build-config.d.ts.map +1 -0
- package/src/ui/build-config.js +47 -0
- package/src/ui/build-config.js.map +1 -0
- package/src/ui/index.d.ts +7 -0
- package/src/ui/index.d.ts.map +1 -0
- package/src/ui/index.js +7 -0
- package/src/ui/index.js.map +1 -0
- package/src/ui/parse-stdout.d.ts +25 -0
- package/src/ui/parse-stdout.d.ts.map +1 -0
- package/src/ui/parse-stdout.js +237 -0
- package/src/ui/parse-stdout.js.map +1 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { readFideliOSRuntimeSkillEntries, resolveFideliOSDesiredSkillNames, } from "@fideliosai/adapter-utils/server-utils";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
const __moduleDir = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Helpers
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
function asString(value) {
|
|
11
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
12
|
+
}
|
|
13
|
+
function resolveHermesHome(config) {
|
|
14
|
+
const env = typeof config.env === "object" && config.env !== null && !Array.isArray(config.env)
|
|
15
|
+
? config.env
|
|
16
|
+
: {};
|
|
17
|
+
const configuredHome = asString(env.HOME);
|
|
18
|
+
return configuredHome ? path.resolve(configuredHome) : os.homedir();
|
|
19
|
+
}
|
|
20
|
+
function parseSkillFrontmatter(content) {
|
|
21
|
+
const match = content.match(/^---\s*\n([\s\S]*?)\n---/);
|
|
22
|
+
if (!match)
|
|
23
|
+
return {};
|
|
24
|
+
const frontmatter = {};
|
|
25
|
+
for (const line of match[1].split("\n")) {
|
|
26
|
+
const idx = line.indexOf(":");
|
|
27
|
+
if (idx === -1)
|
|
28
|
+
continue;
|
|
29
|
+
const key = line.slice(0, idx).trim();
|
|
30
|
+
let val = line.slice(idx + 1).trim();
|
|
31
|
+
// Strip quotes
|
|
32
|
+
if (typeof val === "string" && ((val.startsWith('"') && val.endsWith('"')) || (val.startsWith("'") && val.endsWith("'")))) {
|
|
33
|
+
val = val.slice(1, -1);
|
|
34
|
+
}
|
|
35
|
+
frontmatter[key] = val;
|
|
36
|
+
}
|
|
37
|
+
return frontmatter;
|
|
38
|
+
}
|
|
39
|
+
async function scanHermesSkills(skillsHome) {
|
|
40
|
+
const entries = [];
|
|
41
|
+
try {
|
|
42
|
+
const categories = await fs.readdir(skillsHome, { withFileTypes: true });
|
|
43
|
+
for (const cat of categories) {
|
|
44
|
+
if (!cat.isDirectory())
|
|
45
|
+
continue;
|
|
46
|
+
const catPath = path.join(skillsHome, cat.name);
|
|
47
|
+
// Check if the category directory itself has a SKILL.md (top-level skill)
|
|
48
|
+
const topLevelSkillMd = path.join(catPath, "SKILL.md");
|
|
49
|
+
if (await fs.stat(topLevelSkillMd).catch(() => null)) {
|
|
50
|
+
entries.push(await buildSkillEntry(cat.name, topLevelSkillMd, cat.name));
|
|
51
|
+
}
|
|
52
|
+
// Scan for sub-skills
|
|
53
|
+
const items = await fs.readdir(catPath, { withFileTypes: true }).catch(() => []);
|
|
54
|
+
for (const item of items) {
|
|
55
|
+
if (!item.isDirectory())
|
|
56
|
+
continue;
|
|
57
|
+
const skillMd = path.join(catPath, item.name, "SKILL.md");
|
|
58
|
+
if (await fs.stat(skillMd).catch(() => null)) {
|
|
59
|
+
const key = item.name;
|
|
60
|
+
entries.push(await buildSkillEntry(key, skillMd, `${cat.name}/${item.name}`));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// ~/.hermes/skills/ doesn't exist — no skills available
|
|
67
|
+
}
|
|
68
|
+
return entries.sort((a, b) => a.key.localeCompare(b.key));
|
|
69
|
+
}
|
|
70
|
+
async function buildSkillEntry(key, skillMdPath, categoryPath) {
|
|
71
|
+
let description = null;
|
|
72
|
+
try {
|
|
73
|
+
const content = await fs.readFile(skillMdPath, "utf8");
|
|
74
|
+
const fm = parseSkillFrontmatter(content);
|
|
75
|
+
description = fm.description ?? null;
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// ignore
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
key,
|
|
82
|
+
runtimeName: key,
|
|
83
|
+
desired: true, // Hermes loads all available skills
|
|
84
|
+
managed: false,
|
|
85
|
+
state: "installed",
|
|
86
|
+
origin: "user_installed",
|
|
87
|
+
originLabel: "Hermes skill",
|
|
88
|
+
locationLabel: `~/.hermes/skills/${categoryPath}`,
|
|
89
|
+
readOnly: true, // Hermes manages its own skills — FideliOS can't toggle them
|
|
90
|
+
sourcePath: skillMdPath,
|
|
91
|
+
targetPath: null,
|
|
92
|
+
detail: description,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
// ---------------------------------------------------------------------------
|
|
96
|
+
// Public API
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
async function buildHermesSkillSnapshot(config) {
|
|
99
|
+
const home = resolveHermesHome(config);
|
|
100
|
+
const hermesSkillsHome = path.join(home, ".hermes", "skills");
|
|
101
|
+
// 1. Scan FideliOS-managed skills (bundled with the adapter)
|
|
102
|
+
const fideliosEntries = await readFideliOSRuntimeSkillEntries(config, __moduleDir);
|
|
103
|
+
const desiredSkills = resolveFideliOSDesiredSkillNames(config, fideliosEntries);
|
|
104
|
+
const desiredSet = new Set(desiredSkills);
|
|
105
|
+
const availableByKey = new Map(fideliosEntries.map((e) => [e.key, e]));
|
|
106
|
+
// 2. Scan Hermes's own skills from ~/.hermes/skills/
|
|
107
|
+
const hermesSkillEntries = await scanHermesSkills(hermesSkillsHome);
|
|
108
|
+
const hermesKeys = new Set(hermesSkillEntries.map((e) => e.key));
|
|
109
|
+
// 3. Merge: FideliOS skills first (ephemeral), then Hermes skills
|
|
110
|
+
const entries = [];
|
|
111
|
+
const warnings = [];
|
|
112
|
+
// FideliOS-managed skills
|
|
113
|
+
for (const entry of fideliosEntries) {
|
|
114
|
+
const desired = desiredSet.has(entry.key);
|
|
115
|
+
entries.push({
|
|
116
|
+
key: entry.key,
|
|
117
|
+
runtimeName: entry.runtimeName,
|
|
118
|
+
desired,
|
|
119
|
+
managed: true,
|
|
120
|
+
state: desired ? "configured" : "available",
|
|
121
|
+
origin: entry.required ? "fidelios_required" : "company_managed",
|
|
122
|
+
originLabel: entry.required ? "Required by FideliOS" : "Managed by FideliOS",
|
|
123
|
+
readOnly: false,
|
|
124
|
+
sourcePath: entry.source,
|
|
125
|
+
targetPath: null,
|
|
126
|
+
detail: desired
|
|
127
|
+
? "Will be available on the next run via Hermes skill loading."
|
|
128
|
+
: null,
|
|
129
|
+
required: Boolean(entry.required),
|
|
130
|
+
requiredReason: entry.requiredReason ?? null,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
// Hermes-installed skills (read-only, always loaded)
|
|
134
|
+
for (const entry of hermesSkillEntries) {
|
|
135
|
+
// Skip if FideliOS already manages a skill with the same key
|
|
136
|
+
if (availableByKey.has(entry.key))
|
|
137
|
+
continue;
|
|
138
|
+
entries.push(entry);
|
|
139
|
+
}
|
|
140
|
+
// Check for desired skills that don't exist
|
|
141
|
+
for (const desiredSkill of desiredSkills) {
|
|
142
|
+
if (availableByKey.has(desiredSkill) || hermesKeys.has(desiredSkill))
|
|
143
|
+
continue;
|
|
144
|
+
warnings.push(`Desired skill "${desiredSkill}" is not available in FideliOS or Hermes skills.`);
|
|
145
|
+
entries.push({
|
|
146
|
+
key: desiredSkill,
|
|
147
|
+
runtimeName: null,
|
|
148
|
+
desired: true,
|
|
149
|
+
managed: true,
|
|
150
|
+
state: "missing",
|
|
151
|
+
origin: "external_unknown",
|
|
152
|
+
originLabel: "External or unavailable",
|
|
153
|
+
readOnly: false,
|
|
154
|
+
sourcePath: null,
|
|
155
|
+
targetPath: null,
|
|
156
|
+
detail: "Cannot find this skill in FideliOS or ~/.hermes/skills/.",
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
adapterType: "hermes_local",
|
|
161
|
+
supported: true,
|
|
162
|
+
mode: "persistent",
|
|
163
|
+
desiredSkills,
|
|
164
|
+
entries,
|
|
165
|
+
warnings,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
export async function listHermesSkills(ctx) {
|
|
169
|
+
return buildHermesSkillSnapshot(ctx.config);
|
|
170
|
+
}
|
|
171
|
+
export async function syncHermesSkills(ctx, _desiredSkills) {
|
|
172
|
+
// Hermes manages its own skill loading — sync is a no-op.
|
|
173
|
+
// Return the current snapshot so the UI stays in sync.
|
|
174
|
+
return buildHermesSkillSnapshot(ctx.config);
|
|
175
|
+
}
|
|
176
|
+
export function resolveHermesDesiredSkillNames(config, availableEntries) {
|
|
177
|
+
return resolveFideliOSDesiredSkillNames(config, availableEntries);
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=skills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/server/skills.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment test for the Hermes Agent adapter.
|
|
3
|
+
*
|
|
4
|
+
* Verifies that Hermes Agent is installed, accessible, and configured
|
|
5
|
+
* before allowing the adapter to be used.
|
|
6
|
+
*/
|
|
7
|
+
import type { AdapterEnvironmentTestContext, AdapterEnvironmentTestResult } from "@fideliosai/adapter-utils";
|
|
8
|
+
export declare function testEnvironment(ctx: AdapterEnvironmentTestContext): Promise<AdapterEnvironmentTestResult>;
|
|
9
|
+
//# sourceMappingURL=test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../src/server/test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,6BAA6B,EAC7B,4BAA4B,EAE7B,MAAM,4BAA4B,CAAC;AAsKpC,wBAAsB,eAAe,CACnC,GAAG,EAAE,6BAA6B,GACjC,OAAO,CAAC,4BAA4B,CAAC,CA6CvC"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment test for the Hermes Agent adapter.
|
|
3
|
+
*
|
|
4
|
+
* Verifies that Hermes Agent is installed, accessible, and configured
|
|
5
|
+
* before allowing the adapter to be used.
|
|
6
|
+
*/
|
|
7
|
+
import { execFile } from "node:child_process";
|
|
8
|
+
import { promisify } from "node:util";
|
|
9
|
+
import { HERMES_CLI, ADAPTER_TYPE } from "../shared/constants.js";
|
|
10
|
+
const execFileAsync = promisify(execFile);
|
|
11
|
+
function asString(v) {
|
|
12
|
+
return typeof v === "string" ? v : undefined;
|
|
13
|
+
}
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Checks
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
async function checkCliInstalled(command) {
|
|
18
|
+
try {
|
|
19
|
+
// Try to run the command to see if it exists
|
|
20
|
+
await execFileAsync(command, ["--version"], { timeout: 10_000 });
|
|
21
|
+
return null; // OK — it ran successfully
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
const e = err;
|
|
25
|
+
if (e.code === "ENOENT") {
|
|
26
|
+
return {
|
|
27
|
+
level: "error",
|
|
28
|
+
message: `Hermes CLI "${command}" not found in PATH`,
|
|
29
|
+
hint: "Install Hermes Agent: pip install hermes-agent",
|
|
30
|
+
code: "hermes_cli_not_found",
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
// Command exists but --version might have failed for some reason
|
|
34
|
+
// Still consider it installed
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async function checkCliVersion(command) {
|
|
39
|
+
try {
|
|
40
|
+
const { stdout } = await execFileAsync(command, ["--version"], {
|
|
41
|
+
timeout: 10_000,
|
|
42
|
+
});
|
|
43
|
+
const version = stdout.trim();
|
|
44
|
+
if (version) {
|
|
45
|
+
return {
|
|
46
|
+
level: "info",
|
|
47
|
+
message: `Hermes Agent version: ${version}`,
|
|
48
|
+
code: "hermes_version",
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
level: "warn",
|
|
53
|
+
message: "Could not determine Hermes Agent version",
|
|
54
|
+
code: "hermes_version_unknown",
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return {
|
|
59
|
+
level: "warn",
|
|
60
|
+
message: "Could not determine Hermes Agent version (hermes --version failed)",
|
|
61
|
+
hint: "Make sure the hermes CLI is properly installed and functional",
|
|
62
|
+
code: "hermes_version_failed",
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async function checkPython() {
|
|
67
|
+
try {
|
|
68
|
+
const { stdout } = await execFileAsync("python3", ["--version"], {
|
|
69
|
+
timeout: 5_000,
|
|
70
|
+
});
|
|
71
|
+
const version = stdout.trim();
|
|
72
|
+
const match = version.match(/(\d+)\.(\d+)/);
|
|
73
|
+
if (match) {
|
|
74
|
+
const major = parseInt(match[1], 10);
|
|
75
|
+
const minor = parseInt(match[2], 10);
|
|
76
|
+
if (major < 3 || (major === 3 && minor < 10)) {
|
|
77
|
+
return {
|
|
78
|
+
level: "error",
|
|
79
|
+
message: `Python ${version} found — Hermes requires Python 3.10+`,
|
|
80
|
+
hint: "Upgrade Python to 3.10 or later",
|
|
81
|
+
code: "hermes_python_old",
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return null; // OK
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return {
|
|
89
|
+
level: "warn",
|
|
90
|
+
message: "python3 not found in PATH",
|
|
91
|
+
hint: "Hermes Agent requires Python 3.10+. Install it from python.org",
|
|
92
|
+
code: "hermes_python_missing",
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function checkModel(config) {
|
|
97
|
+
const model = asString(config.model);
|
|
98
|
+
if (!model) {
|
|
99
|
+
return {
|
|
100
|
+
level: "info",
|
|
101
|
+
message: "No model specified — Hermes will use its configured default model",
|
|
102
|
+
hint: "Set a model explicitly in FideliOS only if you want to override your local Hermes configuration.",
|
|
103
|
+
code: "hermes_configured_default_model",
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
level: "info",
|
|
108
|
+
message: `Model: ${model}`,
|
|
109
|
+
code: "hermes_model_configured",
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function checkApiKeys(config) {
|
|
113
|
+
// The server resolves secret refs into config.env before calling testEnvironment,
|
|
114
|
+
// so we check config.env first (adapter-configured secrets), then fall back to
|
|
115
|
+
// process.env (server/host environment). This mirrors how the Claude adapter does it.
|
|
116
|
+
const envConfig = (config.env ?? {});
|
|
117
|
+
const resolvedEnv = {};
|
|
118
|
+
for (const [key, value] of Object.entries(envConfig)) {
|
|
119
|
+
if (typeof value === "string" && value.length > 0)
|
|
120
|
+
resolvedEnv[key] = value;
|
|
121
|
+
}
|
|
122
|
+
const has = (key) => !!(resolvedEnv[key] ?? process.env[key]);
|
|
123
|
+
const hasAnthropic = has("ANTHROPIC_API_KEY");
|
|
124
|
+
const hasOpenRouter = has("OPENROUTER_API_KEY");
|
|
125
|
+
const hasOpenAI = has("OPENAI_API_KEY");
|
|
126
|
+
const hasZai = has("ZAI_API_KEY");
|
|
127
|
+
if (!hasAnthropic && !hasOpenRouter && !hasOpenAI && !hasZai) {
|
|
128
|
+
return {
|
|
129
|
+
level: "warn",
|
|
130
|
+
message: "No LLM API keys found in environment",
|
|
131
|
+
hint: "Set ANTHROPIC_API_KEY, OPENROUTER_API_KEY, OPENAI_API_KEY, or ZAI_API_KEY in the agent's env secrets. Hermes may also have keys configured in ~/.hermes/.env",
|
|
132
|
+
code: "hermes_no_api_keys",
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
const providers = [];
|
|
136
|
+
if (hasAnthropic)
|
|
137
|
+
providers.push("Anthropic");
|
|
138
|
+
if (hasOpenRouter)
|
|
139
|
+
providers.push("OpenRouter");
|
|
140
|
+
if (hasOpenAI)
|
|
141
|
+
providers.push("OpenAI");
|
|
142
|
+
if (hasZai)
|
|
143
|
+
providers.push("Z.AI");
|
|
144
|
+
return {
|
|
145
|
+
level: "info",
|
|
146
|
+
message: `API keys found: ${providers.join(", ")}`,
|
|
147
|
+
code: "hermes_api_keys_found",
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
// ---------------------------------------------------------------------------
|
|
151
|
+
// Main test
|
|
152
|
+
// ---------------------------------------------------------------------------
|
|
153
|
+
export async function testEnvironment(ctx) {
|
|
154
|
+
const config = (ctx.config ?? {});
|
|
155
|
+
const command = asString(config.hermesCommand) || HERMES_CLI;
|
|
156
|
+
const checks = [];
|
|
157
|
+
// 1. CLI installed?
|
|
158
|
+
const cliCheck = await checkCliInstalled(command);
|
|
159
|
+
if (cliCheck) {
|
|
160
|
+
checks.push(cliCheck);
|
|
161
|
+
if (cliCheck.level === "error") {
|
|
162
|
+
return {
|
|
163
|
+
adapterType: ADAPTER_TYPE,
|
|
164
|
+
status: "fail",
|
|
165
|
+
checks,
|
|
166
|
+
testedAt: new Date().toISOString(),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// 2. CLI version
|
|
171
|
+
const versionCheck = await checkCliVersion(command);
|
|
172
|
+
if (versionCheck)
|
|
173
|
+
checks.push(versionCheck);
|
|
174
|
+
// 3. Python available?
|
|
175
|
+
const pythonCheck = await checkPython();
|
|
176
|
+
if (pythonCheck)
|
|
177
|
+
checks.push(pythonCheck);
|
|
178
|
+
// 4. Model config
|
|
179
|
+
const modelCheck = checkModel(config);
|
|
180
|
+
if (modelCheck)
|
|
181
|
+
checks.push(modelCheck);
|
|
182
|
+
// 5. API keys (check config.env — server resolves secrets before calling us)
|
|
183
|
+
const apiKeyCheck = checkApiKeys(config);
|
|
184
|
+
if (apiKeyCheck)
|
|
185
|
+
checks.push(apiKeyCheck);
|
|
186
|
+
// Determine overall status
|
|
187
|
+
const hasErrors = checks.some((c) => c.level === "error");
|
|
188
|
+
const hasWarnings = checks.some((c) => c.level === "warn");
|
|
189
|
+
return {
|
|
190
|
+
adapterType: ADAPTER_TYPE,
|
|
191
|
+
status: hasErrors ? "fail" : hasWarnings ? "warn" : "pass",
|
|
192
|
+
checks,
|
|
193
|
+
testedAt: new Date().toISOString(),
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/server/test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared constants for the Hermes Agent adapter.
|
|
3
|
+
*/
|
|
4
|
+
/** Adapter type identifier registered with FideliOS. */
|
|
5
|
+
export declare const ADAPTER_TYPE = "hermes_local";
|
|
6
|
+
/** Human-readable label shown in the FideliOS UI. */
|
|
7
|
+
export declare const ADAPTER_LABEL = "Hermes Agent";
|
|
8
|
+
/** Default CLI binary name. */
|
|
9
|
+
export declare const HERMES_CLI = "hermes";
|
|
10
|
+
/** Default timeout for a single execution run (seconds). */
|
|
11
|
+
export declare const DEFAULT_TIMEOUT_SEC = 300;
|
|
12
|
+
/** Grace period after SIGTERM before SIGKILL (seconds). */
|
|
13
|
+
export declare const DEFAULT_GRACE_SEC = 10;
|
|
14
|
+
/** Default model to use if none specified. */
|
|
15
|
+
export declare const DEFAULT_MODEL = "anthropic/claude-sonnet-4";
|
|
16
|
+
/**
|
|
17
|
+
* Valid --provider choices for the hermes CLI.
|
|
18
|
+
* When not specified, Hermes auto-detects from model name.
|
|
19
|
+
*/
|
|
20
|
+
export declare const VALID_PROVIDERS: readonly ["auto", "openrouter", "nous", "openai-codex", "zai", "kimi-coding", "minimax", "minimax-cn"];
|
|
21
|
+
/** Regex to extract session ID from Hermes CLI output. */
|
|
22
|
+
export declare const SESSION_ID_REGEX: RegExp;
|
|
23
|
+
/** Regex to extract token usage from Hermes output. */
|
|
24
|
+
export declare const TOKEN_USAGE_REGEX: RegExp;
|
|
25
|
+
/** Regex to extract cost from Hermes output. */
|
|
26
|
+
export declare const COST_REGEX: RegExp;
|
|
27
|
+
/** Prefix used by Hermes for tool output lines. */
|
|
28
|
+
export declare const TOOL_OUTPUT_PREFIX = "\u250A";
|
|
29
|
+
/** Prefix for Hermes thinking blocks. */
|
|
30
|
+
export declare const THINKING_PREFIX = "\uD83D\uDCAD";
|
|
31
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/shared/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,yDAAyD;AACzD,eAAO,MAAM,YAAY,iBAAiB,CAAC;AAE3C,sDAAsD;AACtD,eAAO,MAAM,aAAa,iBAAiB,CAAC;AAE5C,+BAA+B;AAC/B,eAAO,MAAM,UAAU,WAAW,CAAC;AAEnC,4DAA4D;AAC5D,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC,2DAA2D;AAC3D,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAEpC,8CAA8C;AAC9C,eAAO,MAAM,aAAa,8BAA8B,CAAC;AAEzD;;;GAGG;AACH,eAAO,MAAM,eAAe,wGASlB,CAAC;AAEX,0DAA0D;AAC1D,eAAO,MAAM,gBAAgB,QAAmD,CAAC;AAEjF,uDAAuD;AACvD,eAAO,MAAM,iBAAiB,QACqC,CAAC;AAEpE,gDAAgD;AAChD,eAAO,MAAM,UAAU,QAAqC,CAAC;AAE7D,mDAAmD;AACnD,eAAO,MAAM,kBAAkB,WAAM,CAAC;AAEtC,yCAAyC;AACzC,eAAO,MAAM,eAAe,iBAAO,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared constants for the Hermes Agent adapter.
|
|
3
|
+
*/
|
|
4
|
+
/** Adapter type identifier registered with FideliOS. */
|
|
5
|
+
export const ADAPTER_TYPE = "hermes_local";
|
|
6
|
+
/** Human-readable label shown in the FideliOS UI. */
|
|
7
|
+
export const ADAPTER_LABEL = "Hermes Agent";
|
|
8
|
+
/** Default CLI binary name. */
|
|
9
|
+
export const HERMES_CLI = "hermes";
|
|
10
|
+
/** Default timeout for a single execution run (seconds). */
|
|
11
|
+
export const DEFAULT_TIMEOUT_SEC = 300;
|
|
12
|
+
/** Grace period after SIGTERM before SIGKILL (seconds). */
|
|
13
|
+
export const DEFAULT_GRACE_SEC = 10;
|
|
14
|
+
/** Default model to use if none specified. */
|
|
15
|
+
export const DEFAULT_MODEL = "anthropic/claude-sonnet-4";
|
|
16
|
+
/**
|
|
17
|
+
* Valid --provider choices for the hermes CLI.
|
|
18
|
+
* When not specified, Hermes auto-detects from model name.
|
|
19
|
+
*/
|
|
20
|
+
export const VALID_PROVIDERS = [
|
|
21
|
+
"auto",
|
|
22
|
+
"openrouter",
|
|
23
|
+
"nous",
|
|
24
|
+
"openai-codex",
|
|
25
|
+
"zai",
|
|
26
|
+
"kimi-coding",
|
|
27
|
+
"minimax",
|
|
28
|
+
"minimax-cn",
|
|
29
|
+
];
|
|
30
|
+
/** Regex to extract session ID from Hermes CLI output. */
|
|
31
|
+
export const SESSION_ID_REGEX = /session[_ ](?:id|saved)[:\s]+([a-zA-Z0-9_-]+)/i;
|
|
32
|
+
/** Regex to extract token usage from Hermes output. */
|
|
33
|
+
export const TOKEN_USAGE_REGEX = /tokens?[:\s]+(\d+)\s*(?:input|in)\b.*?(\d+)\s*(?:output|out)\b/i;
|
|
34
|
+
/** Regex to extract cost from Hermes output. */
|
|
35
|
+
export const COST_REGEX = /(?:cost|spent)[:\s]*\$?([\d.]+)/i;
|
|
36
|
+
/** Prefix used by Hermes for tool output lines. */
|
|
37
|
+
export const TOOL_OUTPUT_PREFIX = "┊";
|
|
38
|
+
/** Prefix for Hermes thinking blocks. */
|
|
39
|
+
export const THINKING_PREFIX = "💭";
|
|
40
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/shared/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,yDAAyD;AACzD,MAAM,CAAC,MAAM,YAAY,GAAG,cAAc,CAAC;AAE3C,sDAAsD;AACtD,MAAM,CAAC,MAAM,aAAa,GAAG,cAAc,CAAC;AAE5C,+BAA+B;AAC/B,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC;AAEnC,4DAA4D;AAC5D,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEvC,2DAA2D;AAC3D,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAEpC,8CAA8C;AAC9C,MAAM,CAAC,MAAM,aAAa,GAAG,2BAA2B,CAAC;AAEzD;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,MAAM;IACN,YAAY;IACZ,MAAM;IACN,cAAc;IACd,KAAK;IACL,aAAa;IACb,SAAS;IACT,YAAY;CACJ,CAAC;AAEX,0DAA0D;AAC1D,MAAM,CAAC,MAAM,gBAAgB,GAAG,gDAAgD,CAAC;AAEjF,uDAAuD;AACvD,MAAM,CAAC,MAAM,iBAAiB,GAC5B,iEAAiE,CAAC;AAEpE,gDAAgD;AAChD,MAAM,CAAC,MAAM,UAAU,GAAG,kCAAkC,CAAC;AAE7D,mDAAmD;AACnD,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAEtC,yCAAyC;AACzC,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build adapter configuration from UI form values.
|
|
3
|
+
*
|
|
4
|
+
* Translates FideliOS's CreateConfigValues into the adapterConfig
|
|
5
|
+
* object stored in the agent record.
|
|
6
|
+
*/
|
|
7
|
+
import type { CreateConfigValues } from "@fideliosai/adapter-utils";
|
|
8
|
+
/**
|
|
9
|
+
* Build a Hermes Agent adapter config from the FideliOS UI form values.
|
|
10
|
+
*/
|
|
11
|
+
export declare function buildHermesConfig(v: CreateConfigValues): Record<string, unknown>;
|
|
12
|
+
//# sourceMappingURL=build-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-config.d.ts","sourceRoot":"","sources":["../../src/ui/build-config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAMrE;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,CAAC,EAAE,kBAAkB,GACpB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA6CzB"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build adapter configuration from UI form values.
|
|
3
|
+
*
|
|
4
|
+
* Translates FideliOS's CreateConfigValues into the adapterConfig
|
|
5
|
+
* object stored in the agent record.
|
|
6
|
+
*/
|
|
7
|
+
import { DEFAULT_TIMEOUT_SEC, } from "../shared/constants.js";
|
|
8
|
+
/**
|
|
9
|
+
* Build a Hermes Agent adapter config from the FideliOS UI form values.
|
|
10
|
+
*/
|
|
11
|
+
export function buildHermesConfig(v) {
|
|
12
|
+
const ac = {};
|
|
13
|
+
// Model
|
|
14
|
+
if (v.model.trim()) {
|
|
15
|
+
ac.model = v.model.trim();
|
|
16
|
+
}
|
|
17
|
+
// Execution limits
|
|
18
|
+
ac.timeoutSec = DEFAULT_TIMEOUT_SEC;
|
|
19
|
+
// maxTurnsPerRun maps to Hermes's max_turns (set via config, not CLI flag)
|
|
20
|
+
// Session persistence (default: on)
|
|
21
|
+
ac.persistSession = true;
|
|
22
|
+
// Working directory
|
|
23
|
+
if (v.cwd) {
|
|
24
|
+
ac.cwd = v.cwd;
|
|
25
|
+
}
|
|
26
|
+
// Custom hermes binary path
|
|
27
|
+
if (v.command) {
|
|
28
|
+
ac.hermesCommand = v.command;
|
|
29
|
+
}
|
|
30
|
+
// Extra CLI arguments
|
|
31
|
+
if (v.extraArgs) {
|
|
32
|
+
ac.extraArgs = v.extraArgs.split(/\s+/).filter(Boolean);
|
|
33
|
+
}
|
|
34
|
+
// Thinking/reasoning effort
|
|
35
|
+
if (v.thinkingEffort) {
|
|
36
|
+
const existing = ac.extraArgs || [];
|
|
37
|
+
existing.push("--reasoning-effort", String(v.thinkingEffort));
|
|
38
|
+
ac.extraArgs = existing;
|
|
39
|
+
}
|
|
40
|
+
// Prompt template
|
|
41
|
+
if (v.promptTemplate) {
|
|
42
|
+
ac.promptTemplate = v.promptTemplate;
|
|
43
|
+
}
|
|
44
|
+
// Heartbeat config is handled by FideliOS itself
|
|
45
|
+
return ac;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=build-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-config.js","sourceRoot":"","sources":["../../src/ui/build-config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EACL,mBAAmB,GACpB,MAAM,wBAAwB,CAAC;AAEhC;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,CAAqB;IAErB,MAAM,EAAE,GAA4B,EAAE,CAAC;IAEvC,QAAQ;IACR,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QACnB,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAC5B,CAAC;IAED,mBAAmB;IACnB,EAAE,CAAC,UAAU,GAAG,mBAAmB,CAAC;IACpC,2EAA2E;IAE3E,oCAAoC;IACpC,EAAE,CAAC,cAAc,GAAG,IAAI,CAAC;IAEzB,oBAAoB;IACpB,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;QACV,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC;IACjB,CAAC;IAED,4BAA4B;IAC5B,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;QACd,EAAE,CAAC,aAAa,GAAG,CAAC,CAAC,OAAO,CAAC;IAC/B,CAAC;IAED,sBAAsB;IACtB,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;QAChB,EAAE,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC1D,CAAC;IAED,4BAA4B;IAC5B,IAAI,CAAC,CAAC,cAAc,EAAE,CAAC;QACrB,MAAM,QAAQ,GAAI,EAAE,CAAC,SAAsB,IAAI,EAAE,CAAC;QAClD,QAAQ,CAAC,IAAI,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC;QAC9D,EAAE,CAAC,SAAS,GAAG,QAAQ,CAAC;IAC1B,CAAC;IAED,kBAAkB;IAClB,IAAI,CAAC,CAAC,cAAc,EAAE,CAAC;QACrB,EAAE,CAAC,cAAc,GAAG,CAAC,CAAC,cAAc,CAAC;IACvC,CAAC;IAED,kDAAkD;IAElD,OAAO,EAAE,CAAC;AACZ,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UI module exports — used by FideliOS's dashboard for run viewing
|
|
3
|
+
* and agent configuration forms.
|
|
4
|
+
*/
|
|
5
|
+
export { parseHermesStdoutLine } from "./parse-stdout.js";
|
|
6
|
+
export { buildHermesConfig } from "./build-config.js";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC"}
|
package/src/ui/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse Hermes Agent stdout into TranscriptEntry objects for the FideliOS UI.
|
|
3
|
+
*
|
|
4
|
+
* Hermes CLI quiet-mode output patterns:
|
|
5
|
+
* Assistant: " ┊ 💬 {text}"
|
|
6
|
+
* Tool (TTY): " ┊ {emoji} {verb:9} {detail} {duration}"
|
|
7
|
+
* Tool (pipe): " [done] ┊ {emoji} {verb:9} {detail} {duration} ({total})"
|
|
8
|
+
* System: "[hermes] ..."
|
|
9
|
+
*
|
|
10
|
+
* We emit structured tool_call/tool_result pairs so FideliOS renders proper
|
|
11
|
+
* tool cards (with status icons, expand/collapse) instead of raw stdout blocks.
|
|
12
|
+
*/
|
|
13
|
+
import type { TranscriptEntry } from "@fideliosai/adapter-utils";
|
|
14
|
+
/**
|
|
15
|
+
* Parse a single line of Hermes stdout into transcript entries.
|
|
16
|
+
*
|
|
17
|
+
* Emits structured tool_call/tool_result pairs (with synthetic IDs) so
|
|
18
|
+
* FideliOS renders proper tool cards with status icons and expand/collapse.
|
|
19
|
+
*
|
|
20
|
+
* @param line Raw stdout line from Hermes CLI
|
|
21
|
+
* @param ts ISO timestamp for the entry
|
|
22
|
+
* @returns Array of TranscriptEntry objects (may be empty)
|
|
23
|
+
*/
|
|
24
|
+
export declare function parseHermesStdoutLine(line: string, ts: string): TranscriptEntry[];
|
|
25
|
+
//# sourceMappingURL=parse-stdout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-stdout.d.ts","sourceRoot":"","sources":["../../src/ui/parse-stdout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AA8JlE;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,GACT,eAAe,EAAE,CAiGnB"}
|