@saleso.innovations/bridge 0.1.42 → 0.1.43

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.
Files changed (55) hide show
  1. package/dist/client.d.ts +2 -0
  2. package/dist/client.d.ts.map +1 -1
  3. package/dist/client.js +5 -1
  4. package/dist/constants.d.ts +2 -0
  5. package/dist/constants.d.ts.map +1 -1
  6. package/dist/constants.js +3 -0
  7. package/dist/cronList.d.ts +2 -0
  8. package/dist/cronList.d.ts.map +1 -1
  9. package/dist/cronList.js +11 -8
  10. package/dist/cronWatcher.d.ts +1 -1
  11. package/dist/cronWatcher.d.ts.map +1 -1
  12. package/dist/cronWatcher.js +70 -29
  13. package/dist/ensureHermesApi.d.ts +1 -1
  14. package/dist/ensureHermesApi.d.ts.map +1 -1
  15. package/dist/ensureHermesApi.js +14 -10
  16. package/dist/gatewayControl.d.ts +3 -3
  17. package/dist/gatewayControl.d.ts.map +1 -1
  18. package/dist/gatewayControl.js +58 -24
  19. package/dist/hermesCommands.d.ts +1 -1
  20. package/dist/hermesCommands.d.ts.map +1 -1
  21. package/dist/hermesCommands.js +48 -27
  22. package/dist/hermesFileCommands.d.ts +5 -5
  23. package/dist/hermesFileCommands.d.ts.map +1 -1
  24. package/dist/hermesFileCommands.js +10 -10
  25. package/dist/hermesFiles.d.ts +7 -6
  26. package/dist/hermesFiles.d.ts.map +1 -1
  27. package/dist/hermesFiles.js +11 -14
  28. package/dist/hermesForwarder.d.ts +2 -0
  29. package/dist/hermesForwarder.d.ts.map +1 -1
  30. package/dist/hermesForwarder.js +27 -20
  31. package/dist/hermesSessionDb.d.ts +10 -6
  32. package/dist/hermesSessionDb.d.ts.map +1 -1
  33. package/dist/hermesSessionDb.js +44 -24
  34. package/dist/index.d.ts +3 -1
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +2 -1
  37. package/dist/mcpList.d.ts +3 -2
  38. package/dist/mcpList.d.ts.map +1 -1
  39. package/dist/mcpList.js +5 -5
  40. package/dist/profiles.d.ts +66 -0
  41. package/dist/profiles.d.ts.map +1 -0
  42. package/dist/profiles.js +409 -0
  43. package/dist/renameHermesSession.d.ts +1 -1
  44. package/dist/renameHermesSession.d.ts.map +1 -1
  45. package/dist/renameHermesSession.js +2 -2
  46. package/dist/skillLearnedDetector.d.ts +1 -1
  47. package/dist/skillLearnedDetector.d.ts.map +1 -1
  48. package/dist/skillLearnedDetector.js +2 -3
  49. package/dist/skillsList.d.ts +5 -2
  50. package/dist/skillsList.d.ts.map +1 -1
  51. package/dist/skillsList.js +14 -14
  52. package/dist/toolsList.d.ts +2 -2
  53. package/dist/toolsList.d.ts.map +1 -1
  54. package/dist/toolsList.js +4 -4
  55. package/package.json +1 -1
@@ -12,6 +12,7 @@ import { executeShellExec, resetShellSession } from "./shellSession.js";
12
12
  import { fetchHermesRuntimeVersion } from "./runtimeVersion.js";
13
13
  import { fetchBridgeRuntimeVersion, fetchInstalledBridgeVersion } from "./bridgeVersion.js";
14
14
  import { runBridgeUpdate } from "./update.js";
15
+ import { createHermesProfile, deleteHermesProfile, listHermesProfiles, renameHermesProfile, resolveProfileContext, setHermesProfileModel, } from "./profiles.js";
15
16
  import { spawn } from "node:child_process";
16
17
  export const HERMES_COMMAND_NAMES = [
17
18
  "runtime.health",
@@ -34,6 +35,8 @@ export const HERMES_COMMAND_NAMES = [
34
35
  "jobs.delete",
35
36
  "profiles.list",
36
37
  "profiles.create",
38
+ "profiles.rename",
39
+ "profiles.delete",
37
40
  "gateway.start",
38
41
  "gateway.stop",
39
42
  "gateway.restart",
@@ -175,7 +178,11 @@ function scheduleDetachedBridgeRestart() {
175
178
  }
176
179
  }
177
180
  export async function executeHermesCommand(command, args, options = {}) {
178
- const config = resolveHermesApiConfig(options);
181
+ const profileName = optionalString(args, "profile");
182
+ const profileCtx = resolveProfileContext(profileName);
183
+ const config = resolveHermesApiConfig({ ...options, profile: profileCtx.profile });
184
+ const home = profileCtx.home;
185
+ const env = profileCtx.env;
179
186
  const { onDelta } = options;
180
187
  switch (command) {
181
188
  case "runtime.health":
@@ -188,8 +195,10 @@ export async function executeHermesCommand(command, args, options = {}) {
188
195
  return await hermesFetchJson(config, "/v1/capabilities");
189
196
  case "models.list":
190
197
  return await hermesFetchJson(config, "/v1/models");
191
- case "model.set":
192
- throw new HermesCommandError("unsupported_by_http", "Changing the active Hermes model is not exposed over the HTTP API. Update Hermes config on the agent machine.");
198
+ case "model.set": {
199
+ const model = requireString(args, "model");
200
+ return await setHermesProfileModel(profileCtx.profile, model);
201
+ }
193
202
  case "responses.create": {
194
203
  const input = args.input ?? args.prompt;
195
204
  if (typeof input !== "string" || input.trim().length === 0) {
@@ -256,7 +265,7 @@ export async function executeHermesCommand(command, args, options = {}) {
256
265
  case "jobs.list": {
257
266
  const includeAll = args.all === true || args.includeInactive === true;
258
267
  if (includeAll) {
259
- return await listHermesCronJobs({ all: true });
268
+ return await listHermesCronJobs({ all: true, home, env });
260
269
  }
261
270
  return await hermesFetchJson(config, "/api/jobs");
262
271
  }
@@ -318,15 +327,27 @@ export async function executeHermesCommand(command, args, options = {}) {
318
327
  });
319
328
  }
320
329
  case "profiles.list":
321
- throw new HermesCommandError("unsupported_by_http", "Listing Hermes profiles is not exposed over the HTTP API.");
322
- case "profiles.create":
323
- throw new HermesCommandError("unsupported_by_http", "Creating Hermes profiles is not exposed over the HTTP API. Run `hermes profile create` on the agent machine.");
330
+ return await listHermesProfiles();
331
+ case "profiles.create": {
332
+ const name = requireString(args, "name");
333
+ const clone = args.clone === true;
334
+ return await createHermesProfile(name, { clone });
335
+ }
336
+ case "profiles.rename": {
337
+ const oldName = requireString(args, "oldName");
338
+ const newName = requireString(args, "newName");
339
+ return await renameHermesProfile(oldName, newName);
340
+ }
341
+ case "profiles.delete": {
342
+ const name = requireString(args, "name");
343
+ return await deleteHermesProfile(name);
344
+ }
324
345
  case "gateway.start":
325
- return await startHermesGateway();
346
+ return await startHermesGateway(profileCtx.profile);
326
347
  case "gateway.stop":
327
- return await stopHermesGateway();
348
+ return await stopHermesGateway(profileCtx.profile);
328
349
  case "gateway.restart":
329
- return await restartHermesGateway();
350
+ return await restartHermesGateway(profileCtx.profile);
330
351
  case "hermes.update": {
331
352
  const restartGateway = args.restartGateway === true || args.restart_gateway === true;
332
353
  return await runHermesUpdate({ restartGateway });
@@ -349,57 +370,57 @@ export async function executeHermesCommand(command, args, options = {}) {
349
370
  const limit = optionalNumber(args, "limit");
350
371
  const offset = optionalNumber(args, "offset");
351
372
  const offsetFromEnd = optionalNumber(args, "offsetFromEnd");
352
- return listSessionMessages(sessionId, { limit, offset, offsetFromEnd });
373
+ return listSessionMessages(sessionId, { limit, offset, offsetFromEnd, home });
353
374
  }
354
375
  case "sessions.messages.countSent":
355
- return countUserMessagesSent();
376
+ return countUserMessagesSent(home);
356
377
  case "sessions.titles.resolve": {
357
378
  const sessionIds = optionalStringArray(args, "sessionIds") ?? [];
358
- return { titles: resolveSessionTitles(sessionIds) };
379
+ return { titles: resolveSessionTitles(sessionIds, home) };
359
380
  }
360
381
  case "sessions.rename": {
361
382
  const sessionId = requireString(args, "sessionId");
362
383
  const title = requireString(args, "title");
363
- return await renameHermesSession(sessionId, title);
384
+ return await renameHermesSession(sessionId, title, env);
364
385
  }
365
386
  case "sessions.usage.get": {
366
387
  const sessionId = requireString(args, "sessionId");
367
- return getSessionUsage(sessionId);
388
+ return getSessionUsage(sessionId, home);
368
389
  }
369
390
  case "sessions.list": {
370
391
  const limit = optionalNumber(args, "limit");
371
- return { sessions: listHermesSessions({ limit: limit ?? 200 }) };
392
+ return { sessions: listHermesSessions({ limit: limit ?? 200, home }) };
372
393
  }
373
394
  case "skills.list":
374
- return await listHermesSkills();
395
+ return await listHermesSkills({ home, env });
375
396
  case "tools.list": {
376
397
  const platform = optionalString(args, "platform");
377
- return await listHermesTools(platform);
398
+ return await listHermesTools(platform, env);
378
399
  }
379
400
  case "tools.set": {
380
401
  const name = requireString(args, "name");
381
402
  const enabled = args.enabled === true;
382
- return await setHermesToolEnabled(name, enabled);
403
+ return await setHermesToolEnabled(name, enabled, env);
383
404
  }
384
405
  case "mcp.list":
385
- return await listHermesMcpServers();
406
+ return await listHermesMcpServers(env);
386
407
  case "mcp.add": {
387
408
  const name = optionalString(args, "name");
388
409
  const json = requireString(args, "json");
389
- return await addHermesMcpServer({ name, json });
410
+ return await addHermesMcpServer({ name, json, env });
390
411
  }
391
412
  case "mcp.remove": {
392
413
  const name = requireString(args, "name");
393
- return await removeHermesMcpServer(name);
414
+ return await removeHermesMcpServer(name, env);
394
415
  }
395
416
  case "files.list":
396
- return await executeFilesList(args);
417
+ return await executeFilesList(args, home);
397
418
  case "files.read": {
398
419
  const path = optionalString(args, "path");
399
420
  if (!path) {
400
421
  throw new HermesCommandError("invalid_command_args", 'Missing "path"');
401
422
  }
402
- return await executeFilesRead({ ...args, path });
423
+ return await executeFilesRead({ ...args, path }, home);
403
424
  }
404
425
  case "files.write": {
405
426
  const path = optionalString(args, "path");
@@ -410,17 +431,17 @@ export async function executeHermesCommand(command, args, options = {}) {
410
431
  if (typeof content !== "string") {
411
432
  throw new HermesCommandError("invalid_command_args", 'Missing "content"');
412
433
  }
413
- return await executeFilesWrite({ path, content });
434
+ return await executeFilesWrite({ path, content }, home);
414
435
  }
415
436
  case "files.delete": {
416
437
  const path = optionalString(args, "path");
417
438
  if (!path) {
418
439
  throw new HermesCommandError("invalid_command_args", 'Missing "path"');
419
440
  }
420
- return await executeFilesDelete({ path });
441
+ return await executeFilesDelete({ path }, home);
421
442
  }
422
443
  case "memories.list":
423
- return await executeMemoriesList();
444
+ return await executeMemoriesList(home);
424
445
  case "shell.exec": {
425
446
  if (!onDelta) {
426
447
  throw new HermesCommandError("invalid_command_args", "shell.exec requires streaming support");
@@ -1,19 +1,19 @@
1
- export declare function executeFilesList(args: Record<string, unknown>): Promise<{
1
+ export declare function executeFilesList(args: Record<string, unknown>, home?: string): Promise<{
2
2
  files: import("./hermesFiles.js").HermesFileEntry[];
3
3
  }>;
4
- export declare function executeFilesWrite(args: Record<string, unknown>): Promise<{
4
+ export declare function executeFilesWrite(args: Record<string, unknown>, home?: string): Promise<{
5
5
  ok: true;
6
6
  relativePath: string;
7
7
  size: number;
8
8
  }>;
9
- export declare function executeFilesDelete(args: Record<string, unknown>): Promise<{
9
+ export declare function executeFilesDelete(args: Record<string, unknown>, home?: string): Promise<{
10
10
  ok: true;
11
11
  deletedPath: string;
12
12
  }>;
13
- export declare function executeMemoriesList(): Promise<{
13
+ export declare function executeMemoriesList(home?: string): Promise<{
14
14
  files: import("./hermesFiles.js").HermesFileEntry[];
15
15
  }>;
16
- export declare function executeFilesRead(args: Record<string, unknown>): Promise<{
16
+ export declare function executeFilesRead(args: Record<string, unknown>, home?: string): Promise<{
17
17
  fileName: string;
18
18
  mimeType: string;
19
19
  size: number;
@@ -1 +1 @@
1
- {"version":3,"file":"hermesFileCommands.d.ts","sourceRoot":"","sources":["../src/hermesFileCommands.ts"],"names":[],"mappings":"AAgCA,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;GAKnE;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;GAUpE;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;GAMrE;AAED,wBAAsB,mBAAmB;;GAExC;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;;;;GAkCnE"}
1
+ {"version":3,"file":"hermesFileCommands.d.ts","sourceRoot":"","sources":["../src/hermesFileCommands.ts"],"names":[],"mappings":"AAgCA,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM;;GAKlF;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM;;;;GAUnF;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM;;;GAMpF;AAED,wBAAsB,mBAAmB,CAAC,IAAI,CAAC,EAAE,MAAM;;GAEtD;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM;;;;;;;;;;;;;;GAkClF"}
@@ -22,13 +22,13 @@ function optionalCategory(args) {
22
22
  }
23
23
  return "all";
24
24
  }
25
- export async function executeFilesList(args) {
25
+ export async function executeFilesList(args, home) {
26
26
  const limit = optionalNumber(args, "limit");
27
27
  const offset = optionalNumber(args, "offset");
28
28
  const category = optionalCategory(args);
29
- return listHermesFiles({ limit, offset, category });
29
+ return listHermesFiles({ limit, offset, category, home });
30
30
  }
31
- export async function executeFilesWrite(args) {
31
+ export async function executeFilesWrite(args, home) {
32
32
  const path = typeof args.path === "string" ? args.path.trim() : "";
33
33
  if (!path) {
34
34
  throw new Error('Missing "path"');
@@ -37,22 +37,22 @@ export async function executeFilesWrite(args) {
37
37
  if (content === undefined) {
38
38
  throw new Error('Missing "content"');
39
39
  }
40
- return writeHermesFile(path, content);
40
+ return writeHermesFile(path, content, home);
41
41
  }
42
- export async function executeFilesDelete(args) {
42
+ export async function executeFilesDelete(args, home) {
43
43
  const path = typeof args.path === "string" ? args.path.trim() : "";
44
44
  if (!path) {
45
45
  throw new Error('Missing "path"');
46
46
  }
47
- return deleteHermesFile(path);
47
+ return deleteHermesFile(path, home);
48
48
  }
49
- export async function executeMemoriesList() {
50
- return listHermesMemoryFiles();
49
+ export async function executeMemoriesList(home) {
50
+ return listHermesMemoryFiles(home);
51
51
  }
52
- export async function executeFilesRead(args) {
52
+ export async function executeFilesRead(args, home) {
53
53
  const path = typeof args.path === "string" ? args.path.trim() : "";
54
54
  const maxBytes = optionalNumber(args, "maxBytes") ?? DEFAULT_FILES_READ_MAX_BYTES;
55
- const { bytes, mimeType, fileName, size } = readHermesFileBytes(path);
55
+ const { bytes, mimeType, fileName, size } = readHermesFileBytes(path, home);
56
56
  if (size <= maxBytes) {
57
57
  return {
58
58
  fileName,
@@ -43,30 +43,31 @@ export type MediaReference = {
43
43
  export declare function resolveHermesHome(): string;
44
44
  export declare function inferMimeType(fileName: string): string;
45
45
  export declare function inferCategory(fileName: string): HermesFileCategory;
46
- export declare function resolveSandboxedPath(inputPath: string): string;
46
+ export declare function resolveSandboxedPath(inputPath: string, home?: string): string;
47
47
  export declare function listHermesFiles(options?: {
48
48
  limit?: number;
49
49
  offset?: number;
50
50
  category?: HermesFileCategory | "all";
51
+ home?: string;
51
52
  }): {
52
53
  files: HermesFileEntry[];
53
54
  };
54
55
  export declare function normalizeHermesRelativePath(inputPath: string): string;
55
56
  export declare function isWritableSkillPath(relativePath: string): boolean;
56
57
  export declare function assertWritableHermesPath(inputPath: string): string;
57
- export declare function writeHermesFile(inputPath: string, content: string): {
58
+ export declare function writeHermesFile(inputPath: string, content: string, home?: string): {
58
59
  ok: true;
59
60
  relativePath: string;
60
61
  size: number;
61
62
  };
62
- export declare function deleteHermesFile(inputPath: string): {
63
+ export declare function deleteHermesFile(inputPath: string, home?: string): {
63
64
  ok: true;
64
65
  deletedPath: string;
65
66
  };
66
- export declare function listHermesMemoryFiles(): {
67
+ export declare function listHermesMemoryFiles(home?: string): {
67
68
  files: HermesFileEntry[];
68
69
  };
69
- export declare function readHermesFileBytes(inputPath: string): {
70
+ export declare function readHermesFileBytes(inputPath: string, home?: string): {
70
71
  bytes: Buffer;
71
72
  mimeType: string;
72
73
  fileName: string;
@@ -80,7 +81,7 @@ export declare function downloadUrlToBytes(url: string, timeoutMs?: number): Pro
80
81
  fileName: string;
81
82
  size: number;
82
83
  }>;
83
- export declare function resolveMediaReferenceBytes(ref: MediaReference): Promise<{
84
+ export declare function resolveMediaReferenceBytes(ref: MediaReference, home?: string): Promise<{
84
85
  bytes: Buffer;
85
86
  mimeType: string;
86
87
  fileName: string;
@@ -1 +1 @@
1
- {"version":3,"file":"hermesFiles.d.ts","sourceRoot":"","sources":["../src/hermesFiles.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hermesFiles.d.ts","sourceRoot":"","sources":["../src/hermesFiles.ts"],"names":[],"mappings":"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"}
@@ -131,8 +131,7 @@ function isPathInsideRoot(root, candidate) {
131
131
  const { root: normalizedRoot, candidate: normalizedCandidate } = normalizePathForSandbox(root, candidate);
132
132
  return normalizedCandidate === normalizedRoot || normalizedCandidate.startsWith(`${normalizedRoot}${sep}`);
133
133
  }
134
- export function resolveSandboxedPath(inputPath) {
135
- const home = resolveHermesHome();
134
+ export function resolveSandboxedPath(inputPath, home = resolveHermesHome()) {
136
135
  const candidate = inputPath.startsWith("/") ? resolve(inputPath) : resolve(home, inputPath);
137
136
  if (!isPathInsideRoot(home, candidate)) {
138
137
  throw new Error(`Path is outside Hermes home: ${inputPath}`);
@@ -227,7 +226,7 @@ function walkFiles(rootDir, home, files, jobNames) {
227
226
  }
228
227
  }
229
228
  export function listHermesFiles(options = {}) {
230
- const home = resolveHermesHome();
229
+ const home = options.home ?? resolveHermesHome();
231
230
  const limit = options.limit ?? 200;
232
231
  const offset = options.offset ?? 0;
233
232
  const category = options.category ?? "all";
@@ -283,14 +282,13 @@ function memoryCharLimitForPath(relativePath) {
283
282
  return USER_MD_CHAR_LIMIT;
284
283
  return undefined;
285
284
  }
286
- export function writeHermesFile(inputPath, content) {
285
+ export function writeHermesFile(inputPath, content, home = resolveHermesHome()) {
287
286
  const relativePath = assertWritableHermesPath(inputPath);
288
287
  const charLimit = memoryCharLimitForPath(relativePath);
289
288
  if (charLimit !== undefined && content.length > charLimit) {
290
289
  throw new Error(`Content exceeds ${charLimit} character limit for ${relativePath} (${content.length} chars)`);
291
290
  }
292
- const home = resolveHermesHome();
293
- const resolved = resolveSandboxedPath(relativePath);
291
+ const resolved = resolveSandboxedPath(relativePath, home);
294
292
  if (relativePath.startsWith(`${SKILLS_DIR}/`)) {
295
293
  mkdirSync(dirname(resolved), { recursive: true });
296
294
  }
@@ -301,12 +299,12 @@ export function writeHermesFile(inputPath, content) {
301
299
  writeFileSync(resolved, bytes);
302
300
  return { ok: true, relativePath, size: bytes.length };
303
301
  }
304
- export function deleteHermesFile(inputPath) {
302
+ export function deleteHermesFile(inputPath, home = resolveHermesHome()) {
305
303
  const relativePath = normalizeHermesRelativePath(inputPath);
306
304
  if (!isWritableSkillPath(relativePath)) {
307
305
  throw new Error(`Path is not deletable: ${inputPath}`);
308
306
  }
309
- const resolved = resolveSandboxedPath(relativePath);
307
+ const resolved = resolveSandboxedPath(relativePath, home);
310
308
  if (!existsSync(resolved)) {
311
309
  throw new Error(`File not found: ${inputPath}`);
312
310
  }
@@ -342,8 +340,7 @@ function memoryFileEntry(home, fileName) {
342
340
  source: "artifact",
343
341
  };
344
342
  }
345
- export function listHermesMemoryFiles() {
346
- const home = resolveHermesHome();
343
+ export function listHermesMemoryFiles(home = resolveHermesHome()) {
347
344
  const memoriesRoot = join(home, MEMORIES_DIR);
348
345
  const discovered = new Set(KNOWN_MEMORY_FILES);
349
346
  if (existsSync(memoriesRoot)) {
@@ -363,8 +360,8 @@ export function listHermesMemoryFiles() {
363
360
  .map((fileName) => memoryFileEntry(home, fileName));
364
361
  return { files };
365
362
  }
366
- export function readHermesFileBytes(inputPath) {
367
- const resolved = resolveSandboxedPath(inputPath);
363
+ export function readHermesFileBytes(inputPath, home = resolveHermesHome()) {
364
+ const resolved = resolveSandboxedPath(inputPath, home);
368
365
  if (!existsSync(resolved)) {
369
366
  throw new Error(`File not found: ${inputPath}`);
370
367
  }
@@ -441,10 +438,10 @@ export async function downloadUrlToBytes(url, timeoutMs = 30_000) {
441
438
  clearTimeout(timer);
442
439
  }
443
440
  }
444
- export async function resolveMediaReferenceBytes(ref) {
441
+ export async function resolveMediaReferenceBytes(ref, home = resolveHermesHome()) {
445
442
  try {
446
443
  if (ref.kind === "local") {
447
- return readHermesFileBytes(ref.absolutePath);
444
+ return readHermesFileBytes(ref.absolutePath, home);
448
445
  }
449
446
  return await downloadUrlToBytes(ref.url);
450
447
  }
@@ -4,6 +4,7 @@ export type HermesForwarderOptions = {
4
4
  apiKey?: string;
5
5
  model?: string;
6
6
  conversationId?: string;
7
+ profile?: string;
7
8
  };
8
9
  export type HermesForwardResult = {
9
10
  sessionId: string;
@@ -12,6 +13,7 @@ export declare function resolveHermesApiConfig(options?: HermesForwarderOptions)
12
13
  apiUrl: string;
13
14
  apiKey: string | undefined;
14
15
  model: string;
16
+ home: string;
15
17
  };
16
18
  export declare function forwardToHermes(content: string, meta: UserMessageMeta, reply: AgentReply, options?: HermesForwarderOptions): Promise<HermesForwardResult>;
17
19
  export declare function createHermesMessageHandler(options?: HermesForwarderOptions): (content: string, meta: UserMessageMeta, reply: AgentReply) => Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"hermesForwarder.d.ts","sourceRoot":"","sources":["../src/hermesForwarder.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAyB,eAAe,EAAE,MAAM,aAAa,CAAC;AAuBtF,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAkBF,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,sBAA2B,GAAG;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;CACf,CAUA;AAgID,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,UAAU,EACjB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,CA0G9B;AA2BD,wBAAgB,0BAA0B,CAAC,OAAO,GAAE,sBAA2B,IAC/D,SAAS,MAAM,EAAE,MAAM,eAAe,EAAE,OAAO,UAAU,KAAG,OAAO,CAAC,IAAI,CAAC,CAMxF"}
1
+ {"version":3,"file":"hermesForwarder.d.ts","sourceRoot":"","sources":["../src/hermesForwarder.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAyB,eAAe,EAAE,MAAM,aAAa,CAAC;AAuBtF,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAkBF,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,sBAA2B,GAAG;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd,CAaA;AAiID,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,UAAU,EACjB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,CA6G9B;AA4BD,wBAAgB,0BAA0B,CAAC,OAAO,GAAE,sBAA2B,IAC/D,SAAS,MAAM,EAAE,MAAM,eAAe,EAAE,OAAO,UAAU,KAAG,OAAO,CAAC,IAAI,CAAC,CAOxF"}
@@ -2,14 +2,14 @@ import { readFileSync } from "node:fs";
2
2
  import { homedir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  import { linkHermesMessageIds, uploadFileToConvex } from "./convexRelay.js";
5
- import { DEFAULT_HERMES_API_URL } from "./constants.js";
6
5
  import { getLatestTurnMessageIds, getSessionUsage, hermesStateDbExists } from "./hermesSessionDb.js";
7
6
  import { diffSkillsLearned, snapshotSkills } from "./skillLearnedDetector.js";
8
7
  import { buildTurnActivity, createTurnActivityAccumulator, parseSseDataLines, processSseEventBlock, } from "./turnActivity.js";
9
8
  import { parseMediaReferences, resolveMediaReferenceBytes, stripMediaReferences, } from "./hermesFiles.js";
10
9
  import { looksLikeHermesStructuredStream, unwrapHermesStructuredContent, } from "./hermesStructuredContent.js";
11
- function readHermesApiKeyFromEnvFile() {
12
- const envPath = join(homedir(), ".hermes", ".env");
10
+ import { resolveProfileContext } from "./profiles.js";
11
+ function readHermesApiKeyFromEnvFile(home) {
12
+ const envPath = join(home?.trim() || join(homedir(), ".hermes"), ".env");
13
13
  try {
14
14
  const contents = readFileSync(envPath, "utf8");
15
15
  for (const line of contents.split("\n")) {
@@ -27,13 +27,16 @@ function readHermesApiKeyFromEnvFile() {
27
27
  return undefined;
28
28
  }
29
29
  export function resolveHermesApiConfig(options = {}) {
30
+ const ctx = resolveProfileContext(options.profile);
30
31
  return {
31
- apiUrl: options.apiUrl?.trim() || process.env.HERMES_API_URL?.trim() || DEFAULT_HERMES_API_URL,
32
+ apiUrl: options.apiUrl?.trim() || ctx.apiUrl,
32
33
  apiKey: options.apiKey?.trim() ||
34
+ ctx.apiKey ||
33
35
  process.env.HERMES_API_KEY?.trim() ||
34
36
  process.env.API_SERVER_KEY?.trim() ||
35
- readHermesApiKeyFromEnvFile(),
37
+ readHermesApiKeyFromEnvFile(ctx.home),
36
38
  model: options.model?.trim() || process.env.HERMES_MODEL?.trim() || "hermes-agent",
39
+ home: ctx.home,
37
40
  };
38
41
  }
39
42
  async function ensureHermesReachable(apiUrl, apiKey) {
@@ -78,10 +81,10 @@ function buildHermesUserContent(text, attachments) {
78
81
  parts.push(...imageParts);
79
82
  return parts;
80
83
  }
81
- async function uploadMediaAttachments(agentId, refs) {
84
+ async function uploadMediaAttachments(agentId, refs, home) {
82
85
  const attachments = [];
83
86
  for (const ref of refs) {
84
- const resolved = await resolveMediaReferenceBytes(ref);
87
+ const resolved = await resolveMediaReferenceBytes(ref, home);
85
88
  if (!resolved)
86
89
  continue;
87
90
  try {
@@ -106,10 +109,10 @@ async function uploadMediaAttachments(agentId, refs) {
106
109
  }
107
110
  return attachments;
108
111
  }
109
- async function linkTurnToConvex(meta, sessionId) {
110
- if (!hermesStateDbExists())
112
+ async function linkTurnToConvex(meta, sessionId, home) {
113
+ if (!hermesStateDbExists(home))
111
114
  return;
112
- const { userMessageId, assistantMessageId } = getLatestTurnMessageIds(sessionId);
115
+ const { userMessageId, assistantMessageId } = getLatestTurnMessageIds(sessionId, home);
113
116
  const links = [];
114
117
  if (userMessageId !== undefined) {
115
118
  links.push({
@@ -145,7 +148,10 @@ async function linkTurnToConvex(meta, sessionId) {
145
148
  }
146
149
  }
147
150
  export async function forwardToHermes(content, meta, reply, options = {}) {
148
- const { apiUrl, apiKey, model } = resolveHermesApiConfig(options);
151
+ const { apiUrl, apiKey, model, home } = resolveHermesApiConfig({
152
+ ...options,
153
+ profile: options.profile ?? meta.profile,
154
+ });
149
155
  await ensureHermesReachable(apiUrl, apiKey);
150
156
  const sessionId = options.conversationId ?? meta.conversationId;
151
157
  const headers = {
@@ -163,7 +169,7 @@ export async function forwardToHermes(content, meta, reply, options = {}) {
163
169
  user: sessionId,
164
170
  };
165
171
  const turnStartedAt = Date.now();
166
- const skillsBefore = snapshotSkills();
172
+ const skillsBefore = snapshotSkills(home);
167
173
  const response = await fetch(apiUrl, {
168
174
  method: "POST",
169
175
  headers,
@@ -219,18 +225,18 @@ export async function forwardToHermes(content, meta, reply, options = {}) {
219
225
  }
220
226
  }
221
227
  const mediaRefs = parseMediaReferences(fullText);
222
- const attachments = mediaRefs.length > 0 ? await uploadMediaAttachments(meta.agentId, mediaRefs) : [];
228
+ const attachments = mediaRefs.length > 0 ? await uploadMediaAttachments(meta.agentId, mediaRefs, home) : [];
223
229
  const rawDisplayText = attachments.length > 0 ? stripMediaReferences(fullText, mediaRefs) : fullText.trim() || fullText;
224
230
  const displayText = unwrapHermesStructuredContent(rawDisplayText);
225
- const { assistantMessageId } = getLatestTurnMessageIds(resolvedSessionId);
226
- const replyModel = resolveReplyModel(modelFromHeader, resolvedSessionId, model);
231
+ const { assistantMessageId } = getLatestTurnMessageIds(resolvedSessionId, home);
232
+ const replyModel = resolveReplyModel(modelFromHeader, resolvedSessionId, model, home);
227
233
  const turnActivity = buildTurnActivity(accumulator, replyModel);
228
- const skillsLearned = diffSkillsLearned(skillsBefore, snapshotSkills(), { turnStartedAt });
234
+ const skillsLearned = diffSkillsLearned(skillsBefore, snapshotSkills(home), { turnStartedAt });
229
235
  if (skillsLearned.length > 0) {
230
236
  turnActivity.skillsLearned = skillsLearned;
231
237
  }
232
238
  reply.complete(displayText, counters.textSequence, attachments.length > 0 ? attachments : undefined, assistantMessageId !== undefined ? String(assistantMessageId) : undefined, turnActivity);
233
- await linkTurnToConvex(meta, resolvedSessionId);
239
+ await linkTurnToConvex(meta, resolvedSessionId, home);
234
240
  return { sessionId: resolvedSessionId };
235
241
  }
236
242
  /**
@@ -239,12 +245,12 @@ export async function forwardToHermes(content, meta, reply, options = {}) {
239
245
  * 2. The session's recorded model in Hermes `state.db`.
240
246
  * 3. The model from the outbound request (skipping the generic placeholder alias).
241
247
  */
242
- function resolveReplyModel(modelFromHeader, resolvedSessionId, requestModel) {
248
+ function resolveReplyModel(modelFromHeader, resolvedSessionId, requestModel, home) {
243
249
  if (modelFromHeader)
244
250
  return modelFromHeader;
245
- if (hermesStateDbExists()) {
251
+ if (hermesStateDbExists(home)) {
246
252
  try {
247
- const usage = getSessionUsage(resolvedSessionId);
253
+ const usage = getSessionUsage(resolvedSessionId, home);
248
254
  if (usage.model)
249
255
  return usage.model;
250
256
  }
@@ -259,6 +265,7 @@ export function createHermesMessageHandler(options = {}) {
259
265
  await forwardToHermes(content, meta, reply, {
260
266
  ...options,
261
267
  conversationId: meta.conversationId,
268
+ profile: options.profile ?? meta.profile,
262
269
  });
263
270
  };
264
271
  }
@@ -5,14 +5,15 @@ export type HermesSessionMessage = {
5
5
  content: string;
6
6
  timestamp: number;
7
7
  };
8
- export declare function resolveSessionTitle(sessionId: string): string | null;
9
- export declare function resolveSessionTitles(sessionIds: string[]): Record<string, string | null>;
8
+ export declare function resolveSessionTitle(sessionId: string, home?: string): string | null;
9
+ export declare function resolveSessionTitles(sessionIds: string[], home?: string): Record<string, string | null>;
10
10
  export declare function listSessionMessages(sessionId: string, options?: {
11
11
  limit?: number;
12
12
  offset?: number;
13
13
  offsetFromEnd?: number;
14
+ home?: string;
14
15
  }): HermesSessionMessage[];
15
- export declare function getLatestTurnMessageIds(sessionId: string): {
16
+ export declare function getLatestTurnMessageIds(sessionId: string, home?: string): {
16
17
  userMessageId?: number;
17
18
  assistantMessageId?: number;
18
19
  };
@@ -28,6 +29,7 @@ export type HermesSessionListEntry = {
28
29
  export declare function isAutomatedHermesSessionPrompt(content: string): boolean;
29
30
  export declare function listHermesSessions(options?: {
30
31
  limit?: number;
32
+ home?: string;
31
33
  }): HermesSessionListEntry[];
32
34
  export type HermesSessionUsage = {
33
35
  sessionId: string;
@@ -41,9 +43,11 @@ export type HermesSessionUsage = {
41
43
  estimatedCostUsd: number | null;
42
44
  messageCount: number;
43
45
  };
44
- export declare function getSessionUsage(sessionId: string): HermesSessionUsage;
45
- export declare function hermesStateDbExists(): boolean;
46
- export declare function countUserMessagesSent(): {
46
+ export declare function getSessionUsage(sessionId: string, home?: string): HermesSessionUsage;
47
+ export declare function hermesStateDbExists(home?: string): boolean;
48
+ export declare function countUserMessagesSent(home?: string): {
47
49
  count: number;
48
50
  };
51
+ /** Total number of sessions in a profile's state.db (best-effort). */
52
+ export declare function countSessions(home?: string): number;
49
53
  //# sourceMappingURL=hermesSessionDb.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hermesSessionDb.d.ts","sourceRoot":"","sources":["../src/hermesSessionDb.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,oBAAoB,GAAG;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AA4IF,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAapE;AAED,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAuBxF;AAED,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAO,GACxE,oBAAoB,EAAE,CAwCxB;AAED,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,GAChB;IAAE,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAAE,CAmCzD;AAED,MAAM,MAAM,sBAAsB,GAAG;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAMF,mFAAmF;AACnF,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAqBvE;AAcD,wBAAgB,kBAAkB,CAAC,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,sBAAsB,EAAE,CAsE7F;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAiBF,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,kBAAkB,CAkErE;AAED,wBAAgB,mBAAmB,IAAI,OAAO,CAO7C;AAED,wBAAgB,qBAAqB,IAAI;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAgBzD"}
1
+ {"version":3,"file":"hermesSessionDb.d.ts","sourceRoot":"","sources":["../src/hermesSessionDb.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,oBAAoB,GAAG;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAgJF,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAanF;AAED,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAuBvG;AAED,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GACvF,oBAAoB,EAAE,CAwCxB;AAED,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,MAAM,GACZ;IAAE,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAAE,CAmCzD;AAED,MAAM,MAAM,sBAAsB,GAAG;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAMF,mFAAmF;AACnF,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAqBvE;AAcD,wBAAgB,kBAAkB,CAAC,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,sBAAsB,EAAE,CAsE5G;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAiBF,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAkEpF;AAED,wBAAgB,mBAAmB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAO1D;AAED,wBAAgB,qBAAqB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAgBtE;AAED,sEAAsE;AACtE,wBAAgB,aAAa,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAgBnD"}