@hermespilot/link 0.6.8 → 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/{chunk-57ZJLOQA.js → chunk-XWQRIQVR.js} +8848 -5971
- package/dist/cli/index.js +106 -7
- package/dist/http/app.d.ts +39 -5
- package/dist/http/app.js +1 -1
- package/package.json +1 -1
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-
|
|
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
|
|
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(
|
|
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");
|
package/dist/http/app.d.ts
CHANGED
|
@@ -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;
|
|
@@ -248,6 +251,9 @@ interface ConversationArchivePlan {
|
|
|
248
251
|
interface LinkRun {
|
|
249
252
|
id: string;
|
|
250
253
|
kind?: 'agent' | 'command';
|
|
254
|
+
queue_mode?: 'guided_interrupt';
|
|
255
|
+
queue_promoted_at?: string;
|
|
256
|
+
guided_after_run_id?: string;
|
|
251
257
|
hermes_run_id?: string;
|
|
252
258
|
hermes_response_id?: string;
|
|
253
259
|
previous_response_id?: string;
|
|
@@ -263,6 +269,9 @@ interface LinkRun {
|
|
|
263
269
|
profile_uid?: string;
|
|
264
270
|
profile_name_snapshot?: string;
|
|
265
271
|
profile?: string;
|
|
272
|
+
owner_account_id?: string;
|
|
273
|
+
owner_app_instance_id?: string;
|
|
274
|
+
language?: string;
|
|
266
275
|
model?: string;
|
|
267
276
|
provider?: string;
|
|
268
277
|
context_window?: number;
|
|
@@ -273,7 +282,7 @@ interface LinkRun {
|
|
|
273
282
|
context_tokens?: number;
|
|
274
283
|
context_window?: number;
|
|
275
284
|
usage_percent?: number;
|
|
276
|
-
context_source?: 'explicit' | 'estimated';
|
|
285
|
+
context_source?: 'explicit' | 'probe' | 'estimated';
|
|
277
286
|
};
|
|
278
287
|
}
|
|
279
288
|
interface SendMessageInput {
|
|
@@ -283,6 +292,9 @@ interface SendMessageInput {
|
|
|
283
292
|
clientMessageId?: string;
|
|
284
293
|
idempotencyKey?: string;
|
|
285
294
|
profileName?: string;
|
|
295
|
+
accountId?: string;
|
|
296
|
+
appInstanceId?: string;
|
|
297
|
+
language?: string;
|
|
286
298
|
}
|
|
287
299
|
interface MessageAttachmentInput {
|
|
288
300
|
blob_id?: string;
|
|
@@ -308,12 +320,18 @@ interface SendMessageResult {
|
|
|
308
320
|
run: Pick<LinkRun, 'id' | 'status'>;
|
|
309
321
|
last_event_seq: number;
|
|
310
322
|
conversation?: ConversationSummary;
|
|
323
|
+
runtime?: ConversationRuntimeMetadata;
|
|
311
324
|
}
|
|
312
325
|
interface CancelRunResult {
|
|
313
326
|
conversation_id: string;
|
|
314
327
|
run: Pick<LinkRun, 'id' | 'status'>;
|
|
315
328
|
last_event_seq: number;
|
|
316
329
|
}
|
|
330
|
+
interface QueuedRunActionResult {
|
|
331
|
+
conversation_id: string;
|
|
332
|
+
queued_run: Pick<LinkRun, 'id' | 'status'>;
|
|
333
|
+
last_event_seq: number;
|
|
334
|
+
}
|
|
317
335
|
type ConversationEventListener = (event: ConversationEvent) => void;
|
|
318
336
|
|
|
319
337
|
interface LinkStatistics {
|
|
@@ -425,6 +443,7 @@ declare class ConversationService {
|
|
|
425
443
|
private readonly queries;
|
|
426
444
|
private readonly runLifecycle;
|
|
427
445
|
private hermesSessionSyncPromise;
|
|
446
|
+
private cronDeliverySyncPromise;
|
|
428
447
|
constructor(paths: RuntimePaths, logger: FileLogger);
|
|
429
448
|
private withConversationLock;
|
|
430
449
|
private restoreArchivedConversationForUserContinuationLocked;
|
|
@@ -452,20 +471,33 @@ declare class ConversationService {
|
|
|
452
471
|
createConversation(input?: {
|
|
453
472
|
title?: string;
|
|
454
473
|
profileName?: string;
|
|
474
|
+
accountId?: string;
|
|
475
|
+
appInstanceId?: string;
|
|
455
476
|
}): Promise<ConversationSummary>;
|
|
456
477
|
ensureCronInboxConversation(input?: {
|
|
457
478
|
profileName?: string;
|
|
458
479
|
}): Promise<string>;
|
|
459
480
|
appendCronDelivery(input: {
|
|
460
|
-
conversationId
|
|
481
|
+
conversationId?: string;
|
|
461
482
|
profileName: string;
|
|
462
483
|
jobId: string;
|
|
484
|
+
source: 'app' | 'natural_language';
|
|
463
485
|
jobName?: string;
|
|
464
486
|
outputPath: string;
|
|
465
487
|
content: string;
|
|
488
|
+
failed?: boolean;
|
|
466
489
|
runAt?: string;
|
|
467
|
-
|
|
490
|
+
accountId?: string;
|
|
491
|
+
appInstanceId?: string;
|
|
492
|
+
}): Promise<boolean>;
|
|
493
|
+
private appendCronDeliveryToBoundConversation;
|
|
494
|
+
private findImportedCronConversation;
|
|
495
|
+
private reportCronNotification;
|
|
468
496
|
syncCronDeliveries(): Promise<void>;
|
|
497
|
+
backfillCronOwnership(input: {
|
|
498
|
+
accountId?: string;
|
|
499
|
+
appInstanceId?: string;
|
|
500
|
+
}): Promise<void>;
|
|
469
501
|
syncHermesSessions(): Promise<HermesSessionSyncResult>;
|
|
470
502
|
deliverStagedFiles(stagingDir: string): Promise<ImportMediaReferencesResult>;
|
|
471
503
|
getMessages(conversationId: string, options?: ConversationMessagesPageOptions): Promise<{
|
|
@@ -477,7 +509,7 @@ declare class ConversationService {
|
|
|
477
509
|
}>;
|
|
478
510
|
setConversationModel(conversationId: string, modelId: string): Promise<{
|
|
479
511
|
conversation_id: string;
|
|
480
|
-
|
|
512
|
+
default_model: string;
|
|
481
513
|
runtime: ConversationRuntimeMetadata;
|
|
482
514
|
last_event_seq: number;
|
|
483
515
|
}>;
|
|
@@ -508,6 +540,8 @@ declare class ConversationService {
|
|
|
508
540
|
sendMessage(input: SendMessageInput): Promise<SendMessageResult>;
|
|
509
541
|
cancelRun(conversationId: string, runId: string): Promise<CancelRunResult>;
|
|
510
542
|
cancelRunById(runId: string): Promise<CancelRunResult>;
|
|
543
|
+
guideQueuedRun(conversationId: string, runId: string): Promise<QueuedRunActionResult>;
|
|
544
|
+
cancelQueuedRun(conversationId: string, runId: string): Promise<QueuedRunActionResult>;
|
|
511
545
|
resolveApproval(input: {
|
|
512
546
|
conversationId: string;
|
|
513
547
|
approvalId: string;
|
package/dist/http/app.js
CHANGED