@hermespilot/link 0.6.9 → 0.7.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/dist/cli/index.js CHANGED
@@ -17,6 +17,7 @@ import {
17
17
  ensureHermesApiServerAvailable,
18
18
  ensureHermesApiServerConfig,
19
19
  ensureHermesLinkSkillInstalledBestEffort,
20
+ ensureHermesUsageProbeForProfiles,
20
21
  ensureIdentity,
21
22
  fetchRelayStreamBatchPolicy,
22
23
  flushLogFiles,
@@ -50,8 +51,9 @@ import {
50
51
  startDaemonProcess,
51
52
  startLinkService,
52
53
  stopDaemonProcess,
54
+ summarizeUsageProbeEnsure,
53
55
  translate
54
- } from "../chunk-DOSXOXOS.js";
56
+ } from "../chunk-XWQRIQVR.js";
55
57
 
56
58
  // src/cli/index.ts
57
59
  import { Command } from "commander";
@@ -905,6 +907,7 @@ program.command("start").description(helpText("start.description")).action(async
905
907
  paths,
906
908
  source: "cli_start_already_running"
907
909
  });
910
+ await ensureUsageProbeFromCli(paths, t, language, false, "cli_start_already_running");
908
911
  return;
909
912
  }
910
913
  const nextStatus = await startDaemonProcess(paths);
@@ -913,6 +916,7 @@ program.command("start").description(helpText("start.description")).action(async
913
916
  paths,
914
917
  source: "cli_start"
915
918
  });
919
+ await ensureUsageProbeFromCli(paths, t, language, true, "cli_start");
916
920
  });
917
921
  program.command("stop").description(helpText("stop.description")).action(async () => {
918
922
  const config = await loadConfig();
@@ -938,6 +942,7 @@ program.command("restart").description(helpText("restart.description")).action(a
938
942
  paths,
939
943
  source: "cli_restart"
940
944
  });
945
+ await ensureUsageProbeFromCli(paths, t, language, true, "cli_restart");
941
946
  });
942
947
  program.command("deliver").argument("<staging-dir>").description(helpText("deliver.description")).action(async (stagingDir) => {
943
948
  const paths = resolveRuntimePaths();
@@ -1162,6 +1167,7 @@ logsCommand.command("flush").description(helpText("logs.flush.description")).opt
1162
1167
  );
1163
1168
  });
1164
1169
  program.command("doctor").option("--install", helpText("doctor.installOnly")).option("--no-profiles", helpText("doctor.noProfiles")).description(helpText("doctor.description")).action(async (options) => {
1170
+ const paths = resolveRuntimePaths();
1165
1171
  const installInfo = readInstallPathInfo();
1166
1172
  const installLanguage = await loadCliLanguage().catch(() => detectSystemLanguage());
1167
1173
  const installT = translate.bind(null, installLanguage);
@@ -1172,7 +1178,7 @@ program.command("doctor").option("--install", helpText("doctor.installOnly")).op
1172
1178
  if (hasInstallPathIssue(installInfo)) {
1173
1179
  printInstallDiagnostics(installInfo, installT, false);
1174
1180
  }
1175
- const [identity, config] = await Promise.all([ensureIdentity(), loadConfig()]);
1181
+ const [identity, config] = await Promise.all([ensureIdentity(paths), loadConfig(paths)]);
1176
1182
  const language = resolveLanguage(config.language);
1177
1183
  const t = translate.bind(null, language);
1178
1184
  const hermesConfig = await ensureHermesApiServerConfig("default", void 0, language);
@@ -1203,8 +1209,9 @@ program.command("doctor").option("--install", helpText("doctor.installOnly")).op
1203
1209
  } catch (error) {
1204
1210
  console.log(formatHermesApiServerUnavailable(error, language));
1205
1211
  }
1212
+ const usageProbe = await ensureUsageProbeFromCli(paths, t, language, true, "cli_doctor");
1206
1213
  if (options.profiles !== false) {
1207
- await printProfileDiagnostics(t);
1214
+ await printProfileDiagnostics(t, usageProbe.profiles);
1208
1215
  }
1209
1216
  });
1210
1217
  if (isCliEntrypoint()) {
@@ -1218,18 +1225,74 @@ async function loadCliLanguage() {
1218
1225
  const config = await loadConfig();
1219
1226
  return resolveLanguage(config.language);
1220
1227
  }
1221
- async function printProfileDiagnostics(t) {
1228
+ async function ensureUsageProbeFromCli(paths, t, language, activateGateways, source) {
1229
+ console.log(t("usageProbe.ensure.started"));
1230
+ let failedBeforeProfileScan = false;
1231
+ const result = await ensureHermesUsageProbeForProfiles({
1232
+ paths,
1233
+ language,
1234
+ activateGateways,
1235
+ retryLinkDisabled: source === "cli_start" || source === "cli_restart" || source === "cli_doctor",
1236
+ source
1237
+ }).catch((error) => {
1238
+ failedBeforeProfileScan = true;
1239
+ console.log(
1240
+ t("usageProbe.ensure.failedNonBlocking", {
1241
+ failed: 1,
1242
+ ready: 0,
1243
+ total: 1
1244
+ })
1245
+ );
1246
+ console.log(error instanceof Error ? error.message : String(error));
1247
+ return { profiles: [] };
1248
+ });
1249
+ if (failedBeforeProfileScan) {
1250
+ return result;
1251
+ }
1252
+ const summary = summarizeUsageProbeEnsure(result);
1253
+ const attentionCount = summary.failed + summary.needsRestart + summary.disabled;
1254
+ if (attentionCount > 0) {
1255
+ console.log(
1256
+ t(
1257
+ summary.ready > 0 || summary.needsRestart > 0 || summary.disabled > 0 ? "usageProbe.ensure.partial" : "usageProbe.ensure.failedNonBlocking",
1258
+ {
1259
+ ready: summary.ready,
1260
+ total: summary.total,
1261
+ failed: attentionCount
1262
+ }
1263
+ )
1264
+ );
1265
+ } else {
1266
+ console.log(
1267
+ t("usageProbe.ensure.done", {
1268
+ ready: summary.ready,
1269
+ total: summary.total
1270
+ })
1271
+ );
1272
+ }
1273
+ return result;
1274
+ }
1275
+ async function printProfileDiagnostics(t, usageProbeProfiles = []) {
1222
1276
  console.log(t("doctor.profilesHeader"));
1223
1277
  const profiles = await prepareHermesProfilesForUse();
1224
1278
  if (profiles.length === 0) {
1225
1279
  console.log(t("doctor.profilesNone"));
1226
1280
  return;
1227
1281
  }
1282
+ const usageProbeByProfile = new Map(
1283
+ usageProbeProfiles.map((profile) => [profile.profile, profile])
1284
+ );
1228
1285
  for (const profile of profiles) {
1229
- console.log(await formatProfileDiagnosticLine(profile, t));
1286
+ console.log(
1287
+ await formatProfileDiagnosticLine(
1288
+ profile,
1289
+ t,
1290
+ usageProbeByProfile.get(profile.profile.name)
1291
+ )
1292
+ );
1230
1293
  }
1231
1294
  }
1232
- async function formatProfileDiagnosticLine(profile, t) {
1295
+ async function formatProfileDiagnosticLine(profile, t, usageProbe) {
1233
1296
  if (profile.error || !profile.apiServer) {
1234
1297
  return t("doctor.profileLine", {
1235
1298
  profile: profile.profile.name,
@@ -1251,12 +1314,48 @@ async function formatProfileDiagnosticLine(profile, t) {
1251
1314
  message: health.issue ?? t("status.unknown")
1252
1315
  });
1253
1316
  const state = profile.changed ? t("doctor.profilePreparedState", { state: baseState }) : baseState;
1317
+ const usageProbeState = usageProbe ? formatUsageProbeState(usageProbe, t) : null;
1254
1318
  return t("doctor.profileLine", {
1255
1319
  profile: profile.profile.name,
1256
1320
  endpoint: `${host}:${port}`,
1257
- state
1321
+ state: usageProbeState ? `${state}; ${usageProbeState}` : state
1258
1322
  });
1259
1323
  }
1324
+ function formatUsageProbeState(profile, t) {
1325
+ if (profile.disabledByUser) {
1326
+ return t("usageProbe.disabledByUser");
1327
+ }
1328
+ if (profile.error) {
1329
+ if (profile.error.includes("unmanaged Hermes plugin file")) {
1330
+ return t("usageProbe.installConflict", { message: profile.error });
1331
+ }
1332
+ if (profile.error.includes("plugins.enabled")) {
1333
+ return t("usageProbe.configInvalid", { message: profile.error });
1334
+ }
1335
+ if (profile.restart.attempted && profile.restart.error) {
1336
+ return t("usageProbe.gateway.restartFailed", {
1337
+ message: profile.restart.error
1338
+ });
1339
+ }
1340
+ return t("usageProbe.configInvalid", { message: profile.error });
1341
+ }
1342
+ if (profile.restart.succeeded) {
1343
+ return t("usageProbe.gateway.restartDone");
1344
+ }
1345
+ if (profile.needsRestart) {
1346
+ return t("usageProbe.profile.needsRestart");
1347
+ }
1348
+ if (profile.pluginChanged && profile.configChanged) {
1349
+ return t("usageProbe.profile.installed");
1350
+ }
1351
+ if (profile.pluginChanged) {
1352
+ return t("usageProbe.profile.updated");
1353
+ }
1354
+ if (profile.configChanged) {
1355
+ return t("usageProbe.profile.enabled");
1356
+ }
1357
+ return t("usageProbe.profile.ready");
1358
+ }
1260
1359
  function buildRelayStatusPayload(input) {
1261
1360
  if (!input.paired) {
1262
1361
  return emptyRelayStatus(input.relayConfigured, "not_paired");
@@ -10,6 +10,8 @@ interface ConversationProfileSummary {
10
10
  interface ConversationSummary {
11
11
  id: string;
12
12
  title: string;
13
+ display_title?: string;
14
+ title_source?: ConversationTitleSource;
13
15
  created_at: string;
14
16
  updated_at: string;
15
17
  last_event_seq: number;
@@ -51,10 +53,11 @@ interface ConversationRuntimeMetadata {
51
53
  used_tokens?: number;
52
54
  window_tokens?: number;
53
55
  usage_percent?: number;
54
- source: 'explicit' | 'estimated' | 'unknown';
56
+ source: 'explicit' | 'probe' | 'estimated' | 'unknown';
55
57
  updated_at?: string;
56
58
  };
57
59
  }
60
+ type ConversationTitleSource = 'default' | 'temporary_user_message' | 'temporary_fallback' | 'manual' | 'generated' | 'hermes';
58
61
  interface ConversationMessagesPageInfo {
59
62
  limit: number;
60
63
  has_more_before: boolean;
@@ -268,6 +271,7 @@ interface LinkRun {
268
271
  profile?: string;
269
272
  owner_account_id?: string;
270
273
  owner_app_instance_id?: string;
274
+ language?: string;
271
275
  model?: string;
272
276
  provider?: string;
273
277
  context_window?: number;
@@ -278,7 +282,7 @@ interface LinkRun {
278
282
  context_tokens?: number;
279
283
  context_window?: number;
280
284
  usage_percent?: number;
281
- context_source?: 'explicit' | 'estimated';
285
+ context_source?: 'explicit' | 'probe' | 'estimated';
282
286
  };
283
287
  }
284
288
  interface SendMessageInput {
@@ -290,6 +294,7 @@ interface SendMessageInput {
290
294
  profileName?: string;
291
295
  accountId?: string;
292
296
  appInstanceId?: string;
297
+ language?: string;
293
298
  }
294
299
  interface MessageAttachmentInput {
295
300
  blob_id?: string;
@@ -315,6 +320,7 @@ interface SendMessageResult {
315
320
  run: Pick<LinkRun, 'id' | 'status'>;
316
321
  last_event_seq: number;
317
322
  conversation?: ConversationSummary;
323
+ runtime?: ConversationRuntimeMetadata;
318
324
  }
319
325
  interface CancelRunResult {
320
326
  conversation_id: string;
@@ -503,7 +509,7 @@ declare class ConversationService {
503
509
  }>;
504
510
  setConversationModel(conversationId: string, modelId: string): Promise<{
505
511
  conversation_id: string;
506
- model_override: string;
512
+ default_model: string;
507
513
  runtime: ConversationRuntimeMetadata;
508
514
  last_event_seq: number;
509
515
  }>;
package/dist/http/app.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createApp
3
- } from "../chunk-DOSXOXOS.js";
3
+ } from "../chunk-XWQRIQVR.js";
4
4
  export {
5
5
  createApp
6
6
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hermespilot/link",
3
- "version": "0.6.9",
3
+ "version": "0.7.0",
4
4
  "private": false,
5
5
  "description": "Hermes Link companion service and CLI for connecting hermes-agent through HermesPilot",
6
6
  "license": "MIT",