@hermespilot/link 0.8.2 → 0.8.4
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-SQ2VMFNE.js → chunk-VVHNBT4E.js} +1086 -421
- package/dist/cli/index.js +1 -1
- package/dist/http/app.d.ts +27 -5
- package/dist/http/app.js +1 -1
- package/package.json +1 -1
|
@@ -5,7 +5,7 @@ import Router from "@koa/router";
|
|
|
5
5
|
// src/conversations/conversation-service.ts
|
|
6
6
|
import { EventEmitter } from "events";
|
|
7
7
|
import { createHash as createHash9, randomUUID as randomUUID13 } from "crypto";
|
|
8
|
-
import
|
|
8
|
+
import path28 from "path";
|
|
9
9
|
|
|
10
10
|
// src/database/link-database.ts
|
|
11
11
|
import { mkdir } from "fs/promises";
|
|
@@ -7632,7 +7632,7 @@ async function listCronOutputFiles(profileName, jobId) {
|
|
|
7632
7632
|
orderTimeMs: fileStat.mtimeMs
|
|
7633
7633
|
});
|
|
7634
7634
|
}
|
|
7635
|
-
return files.sort((left, right) => left.orderTimeMs - right.orderTimeMs).map(({ path:
|
|
7635
|
+
return files.sort((left, right) => left.orderTimeMs - right.orderTimeMs).map(({ path: path39, mtime }) => ({ path: path39, mtime }));
|
|
7636
7636
|
}
|
|
7637
7637
|
function readCronOutputTimestamp(fileName) {
|
|
7638
7638
|
const match = fileName.match(
|
|
@@ -7721,7 +7721,7 @@ function isConversationMissingError(error) {
|
|
|
7721
7721
|
}
|
|
7722
7722
|
|
|
7723
7723
|
// src/constants.ts
|
|
7724
|
-
var LINK_VERSION = "0.8.
|
|
7724
|
+
var LINK_VERSION = "0.8.4";
|
|
7725
7725
|
var LINK_COMMAND = "hermeslink";
|
|
7726
7726
|
var LINK_DEFAULT_PORT = 52379;
|
|
7727
7727
|
var LINK_RUNTIME_DIR_NAME = ".hermeslink";
|
|
@@ -14803,6 +14803,8 @@ function toSummary(manifest, snapshot, profile) {
|
|
|
14803
14803
|
id: manifest.id,
|
|
14804
14804
|
title: manifest.title,
|
|
14805
14805
|
title_source: manifest.title_source,
|
|
14806
|
+
category: manifestHasCronSignal(manifest, snapshot) ? "cron" : "chat",
|
|
14807
|
+
is_cron: manifestHasCronSignal(manifest, snapshot),
|
|
14806
14808
|
workspace_id: manifest.workspace_id ?? null,
|
|
14807
14809
|
created_at: manifest.created_at,
|
|
14808
14810
|
updated_at: manifest.updated_at,
|
|
@@ -14823,6 +14825,34 @@ function toSummary(manifest, snapshot, profile) {
|
|
|
14823
14825
|
} : null
|
|
14824
14826
|
};
|
|
14825
14827
|
}
|
|
14828
|
+
function manifestHasCronSignal(manifest, snapshot) {
|
|
14829
|
+
const sessionIds = [
|
|
14830
|
+
manifest.hermes_session_id,
|
|
14831
|
+
...manifest.hermes_session_ids ?? [],
|
|
14832
|
+
manifest.hermes_lineage?.root_session_id,
|
|
14833
|
+
manifest.hermes_lineage?.current_session_id,
|
|
14834
|
+
...manifest.hermes_lineage?.session_ids ?? []
|
|
14835
|
+
].map((value) => value?.trim()).filter((value) => Boolean(value));
|
|
14836
|
+
if (sessionIds.some((sessionId) => sessionId.startsWith("cron_"))) {
|
|
14837
|
+
return true;
|
|
14838
|
+
}
|
|
14839
|
+
if (snapshot?.messages.some((message) => {
|
|
14840
|
+
const raw = message.raw;
|
|
14841
|
+
if (raw && typeof raw === "object" && !Array.isArray(raw)) {
|
|
14842
|
+
const format = raw.format;
|
|
14843
|
+
if (format === "hermes-link-cron-delivery") {
|
|
14844
|
+
return true;
|
|
14845
|
+
}
|
|
14846
|
+
}
|
|
14847
|
+
return Boolean(message.hermes?.cron_job_id || message.hermes?.cron_output_path);
|
|
14848
|
+
})) {
|
|
14849
|
+
return true;
|
|
14850
|
+
}
|
|
14851
|
+
return normalizeTitle(manifest.title) === "HermesLink \u5B9A\u65F6\u4EFB\u52A1";
|
|
14852
|
+
}
|
|
14853
|
+
function normalizeTitle(value) {
|
|
14854
|
+
return value.trim();
|
|
14855
|
+
}
|
|
14826
14856
|
function isDefaultConversationTitle(title) {
|
|
14827
14857
|
const normalized = title.trim().toLowerCase();
|
|
14828
14858
|
return !normalized || normalized === "untitled" || normalized === "new chat" || normalized === DEFAULT_CONVERSATION_TITLE.toLowerCase();
|
|
@@ -19735,14 +19765,16 @@ var ConversationQueryCoordinator = class {
|
|
|
19735
19765
|
status,
|
|
19736
19766
|
limit,
|
|
19737
19767
|
cursor,
|
|
19738
|
-
workspace: options.workspace
|
|
19768
|
+
workspace: options.workspace,
|
|
19769
|
+
category: options.category
|
|
19739
19770
|
}),
|
|
19740
19771
|
listPage: (pageCursor) => listConversationStatsPage(this.deps.paths, {
|
|
19741
19772
|
status,
|
|
19742
19773
|
limit,
|
|
19743
19774
|
cursor: pageCursor,
|
|
19744
19775
|
workspace: options.workspace
|
|
19745
|
-
})
|
|
19776
|
+
}),
|
|
19777
|
+
category: options.category
|
|
19746
19778
|
});
|
|
19747
19779
|
}
|
|
19748
19780
|
async searchConversationPage(options = {}) {
|
|
@@ -19790,7 +19822,8 @@ var ConversationQueryCoordinator = class {
|
|
|
19790
19822
|
usedIndex = true;
|
|
19791
19823
|
const summaries = await this.summarizeIndexedConversations(
|
|
19792
19824
|
input.status,
|
|
19793
|
-
indexedPage.records
|
|
19825
|
+
indexedPage.records,
|
|
19826
|
+
input.category
|
|
19794
19827
|
);
|
|
19795
19828
|
for (const summary of summaries) {
|
|
19796
19829
|
if (!seenConversationIds.add(summary.id)) {
|
|
@@ -19830,15 +19863,18 @@ var ConversationQueryCoordinator = class {
|
|
|
19830
19863
|
}
|
|
19831
19864
|
};
|
|
19832
19865
|
}
|
|
19833
|
-
async listConversationsFromStore(status = "active",
|
|
19866
|
+
async listConversationsFromStore(status = "active", options = {}) {
|
|
19834
19867
|
const summaries = [];
|
|
19835
19868
|
for (const conversationId of await this.deps.store.listConversationIds()) {
|
|
19836
19869
|
const manifest = await this.deps.store.readManifest(conversationId).catch(() => null);
|
|
19837
|
-
if (!manifest || manifest.status !== status || !matchesWorkspaceFilter(manifest, workspace)) {
|
|
19870
|
+
if (!manifest || manifest.status !== status || !matchesWorkspaceFilter(manifest, options.workspace)) {
|
|
19838
19871
|
continue;
|
|
19839
19872
|
}
|
|
19840
19873
|
const snapshot = await this.deps.store.readSnapshot(conversationId).catch(() => emptySnapshot2());
|
|
19841
19874
|
const refreshed = await this.deps.metadata.refreshTitleFromHermes(manifest, { snapshot }).catch(() => manifest);
|
|
19875
|
+
if (!matchesConversationCategory(refreshed, snapshot, options.category)) {
|
|
19876
|
+
continue;
|
|
19877
|
+
}
|
|
19842
19878
|
summaries.push(await this.summarizeConversation(refreshed, snapshot));
|
|
19843
19879
|
}
|
|
19844
19880
|
return summaries.sort(
|
|
@@ -19846,10 +19882,10 @@ var ConversationQueryCoordinator = class {
|
|
|
19846
19882
|
);
|
|
19847
19883
|
}
|
|
19848
19884
|
async listConversationPageFromStore(input) {
|
|
19849
|
-
const all = await this.listConversationsFromStore(
|
|
19850
|
-
input.
|
|
19851
|
-
input.
|
|
19852
|
-
);
|
|
19885
|
+
const all = await this.listConversationsFromStore(input.status, {
|
|
19886
|
+
workspace: input.workspace,
|
|
19887
|
+
category: input.category
|
|
19888
|
+
});
|
|
19853
19889
|
const startIndex = input.cursor ? all.findIndex(
|
|
19854
19890
|
(summary) => isAfterConversationListCursor(summary, input.cursor)
|
|
19855
19891
|
) : 0;
|
|
@@ -19868,7 +19904,7 @@ var ConversationQueryCoordinator = class {
|
|
|
19868
19904
|
}
|
|
19869
19905
|
};
|
|
19870
19906
|
}
|
|
19871
|
-
async summarizeIndexedConversations(status, records) {
|
|
19907
|
+
async summarizeIndexedConversations(status, records, category = "all") {
|
|
19872
19908
|
const summaries = [];
|
|
19873
19909
|
for (const record of records) {
|
|
19874
19910
|
const manifest = await this.deps.store.readManifest(record.conversationId).catch(() => null);
|
|
@@ -19877,6 +19913,9 @@ var ConversationQueryCoordinator = class {
|
|
|
19877
19913
|
}
|
|
19878
19914
|
const snapshot = await this.deps.store.readSnapshot(record.conversationId).catch(() => emptySnapshot2());
|
|
19879
19915
|
const refreshed = await this.deps.metadata.refreshTitleFromHermes(manifest, { snapshot }).catch(() => manifest);
|
|
19916
|
+
if (!matchesConversationCategory(refreshed, snapshot, category)) {
|
|
19917
|
+
continue;
|
|
19918
|
+
}
|
|
19880
19919
|
summaries.push(await this.summarizeConversation(refreshed, snapshot));
|
|
19881
19920
|
}
|
|
19882
19921
|
return summaries;
|
|
@@ -20145,6 +20184,13 @@ function matchesWorkspaceFilter(manifest, filter) {
|
|
|
20145
20184
|
}
|
|
20146
20185
|
return workspaceId === filter.workspaceId;
|
|
20147
20186
|
}
|
|
20187
|
+
function matchesConversationCategory(manifest, snapshot, category = "all") {
|
|
20188
|
+
if (category === "all") {
|
|
20189
|
+
return true;
|
|
20190
|
+
}
|
|
20191
|
+
const isCron = manifestHasCronSignal(manifest, snapshot);
|
|
20192
|
+
return category === "cron" ? isCron : !isCron;
|
|
20193
|
+
}
|
|
20148
20194
|
function isAfterConversationListCursor(summary, cursor) {
|
|
20149
20195
|
return summary.updated_at < cursor.updatedAt || summary.updated_at === cursor.updatedAt && summary.id < cursor.conversationId;
|
|
20150
20196
|
}
|
|
@@ -21380,6 +21426,7 @@ var MESSAGE_COLUMNS = [
|
|
|
21380
21426
|
"reasoning_details",
|
|
21381
21427
|
"codex_reasoning_items"
|
|
21382
21428
|
];
|
|
21429
|
+
var HERMES_ROW_SESSION_POSITION = /* @__PURE__ */ Symbol("hermesRowSessionPosition");
|
|
21383
21430
|
async function syncHermesSessionsIntoConversations(paths, logger, options = {}) {
|
|
21384
21431
|
const maxImports = options.maxImports ?? MAX_IMPORTABLE_SESSIONS;
|
|
21385
21432
|
const store = new ConversationStore(paths);
|
|
@@ -21391,6 +21438,7 @@ async function syncHermesSessionsIntoConversations(paths, logger, options = {})
|
|
|
21391
21438
|
eligible_sessions: 0,
|
|
21392
21439
|
imported_count: 0,
|
|
21393
21440
|
reprojected_count: 0,
|
|
21441
|
+
hermes_archived_count: 0,
|
|
21394
21442
|
skipped_existing: 0,
|
|
21395
21443
|
skipped_hidden: 0,
|
|
21396
21444
|
skipped_empty_transcript: 0,
|
|
@@ -21416,6 +21464,21 @@ async function syncHermesSessionsIntoConversations(paths, logger, options = {})
|
|
|
21416
21464
|
continue;
|
|
21417
21465
|
}
|
|
21418
21466
|
if (isHiddenSession(session)) {
|
|
21467
|
+
if (isArchivedSession(session)) {
|
|
21468
|
+
const candidate = { profileName, profileDir, dbPath, session };
|
|
21469
|
+
result.hermes_archived_count += await archiveKnownHermesConversation({
|
|
21470
|
+
paths,
|
|
21471
|
+
store,
|
|
21472
|
+
knownHermesSessions,
|
|
21473
|
+
candidate
|
|
21474
|
+
}).catch((error) => {
|
|
21475
|
+
result.errors.push({
|
|
21476
|
+
profile: profileName,
|
|
21477
|
+
message: error instanceof Error ? error.message : String(error)
|
|
21478
|
+
});
|
|
21479
|
+
return 0;
|
|
21480
|
+
});
|
|
21481
|
+
}
|
|
21419
21482
|
result.skipped_hidden += 1;
|
|
21420
21483
|
continue;
|
|
21421
21484
|
}
|
|
@@ -21501,7 +21564,7 @@ async function syncHermesSessionsIntoConversations(paths, logger, options = {})
|
|
|
21501
21564
|
}
|
|
21502
21565
|
}
|
|
21503
21566
|
}
|
|
21504
|
-
if (result.imported_count > 0 || result.reprojected_count > 0 || result.errors.length > 0) {
|
|
21567
|
+
if (result.imported_count > 0 || result.reprojected_count > 0 || result.hermes_archived_count > 0 || result.errors.length > 0) {
|
|
21505
21568
|
void logger.info("hermes_session_sync_completed", { ...result });
|
|
21506
21569
|
} else {
|
|
21507
21570
|
void logger.debug("hermes_session_sync_completed", { ...result });
|
|
@@ -21585,7 +21648,7 @@ async function syncHermesCronSessionIntoConversations(paths, logger, input) {
|
|
|
21585
21648
|
async function syncHermesConversationMessages(paths, logger, input) {
|
|
21586
21649
|
const store = input.store ?? new ConversationStore(paths);
|
|
21587
21650
|
const manifest = await store.readActiveManifest(input.conversationId);
|
|
21588
|
-
|
|
21651
|
+
let snapshot = await store.readSnapshot(input.conversationId);
|
|
21589
21652
|
const targets = collectHermesSessionDeleteTargets(manifest, snapshot);
|
|
21590
21653
|
const result = {
|
|
21591
21654
|
conversation_id: input.conversationId,
|
|
@@ -21597,8 +21660,15 @@ async function syncHermesConversationMessages(paths, logger, input) {
|
|
|
21597
21660
|
if (targets.length === 0) {
|
|
21598
21661
|
return result;
|
|
21599
21662
|
}
|
|
21663
|
+
const duplicateCleanup = pruneStrictImportedDuplicateMessages(paths, snapshot);
|
|
21664
|
+
if (duplicateCleanup.removedCount > 0) {
|
|
21665
|
+
snapshot = duplicateCleanup.snapshot;
|
|
21666
|
+
result.removed_duplicate_count = duplicateCleanup.removedCount;
|
|
21667
|
+
result.changed = true;
|
|
21668
|
+
}
|
|
21600
21669
|
const candidates = await collectConversationSyncCandidates(targets);
|
|
21601
21670
|
const knownExactKeys = collectKnownHermesRowKeys(snapshot);
|
|
21671
|
+
const representedRows = collectRepresentedHermesRows(paths, snapshot);
|
|
21602
21672
|
const representedMessages = collectRepresentedMessageSignatures(snapshot);
|
|
21603
21673
|
const projectedMessages = [];
|
|
21604
21674
|
const candidateProfiles = /* @__PURE__ */ new Map();
|
|
@@ -21608,6 +21678,12 @@ async function syncHermesConversationMessages(paths, logger, input) {
|
|
|
21608
21678
|
if (candidateMessages.length === 0) {
|
|
21609
21679
|
continue;
|
|
21610
21680
|
}
|
|
21681
|
+
const missingCandidateMessages = candidateMessages.filter(
|
|
21682
|
+
(message, index) => !isRepresentedHermesRow(representedRows, message, index)
|
|
21683
|
+
);
|
|
21684
|
+
if (missingCandidateMessages.length === 0) {
|
|
21685
|
+
continue;
|
|
21686
|
+
}
|
|
21611
21687
|
const profile = await resolveConversationProfileTarget(
|
|
21612
21688
|
paths,
|
|
21613
21689
|
candidate.profileName
|
|
@@ -21624,7 +21700,7 @@ async function syncHermesConversationMessages(paths, logger, input) {
|
|
|
21624
21700
|
profileUid: profile.profileUid,
|
|
21625
21701
|
profileDisplayName: profile.profileDisplayName,
|
|
21626
21702
|
sessionId: candidate.session.id,
|
|
21627
|
-
messages:
|
|
21703
|
+
messages: missingCandidateMessages
|
|
21628
21704
|
})
|
|
21629
21705
|
);
|
|
21630
21706
|
} catch (error) {
|
|
@@ -21650,6 +21726,14 @@ async function syncHermesConversationMessages(paths, logger, input) {
|
|
|
21650
21726
|
exactKeys.forEach((key) => knownExactKeys.add(key));
|
|
21651
21727
|
}
|
|
21652
21728
|
if (appendedMessages.length === 0) {
|
|
21729
|
+
if (duplicateCleanup.removedCount > 0) {
|
|
21730
|
+
await store.writeSnapshot(input.conversationId, snapshot);
|
|
21731
|
+
const currentManifest = await store.readManifest(input.conversationId);
|
|
21732
|
+
const stats2 = buildConversationStats(currentManifest, snapshot);
|
|
21733
|
+
const nextManifest2 = { ...currentManifest, stats: stats2 };
|
|
21734
|
+
await store.writeManifest(nextManifest2);
|
|
21735
|
+
await upsertConversationStats(paths, toStatsIndexRecord(nextManifest2, stats2));
|
|
21736
|
+
}
|
|
21653
21737
|
return result;
|
|
21654
21738
|
}
|
|
21655
21739
|
await store.writeSnapshot(input.conversationId, {
|
|
@@ -21747,7 +21831,7 @@ async function importHermesSession(input) {
|
|
|
21747
21831
|
id: conversationId,
|
|
21748
21832
|
schema_version: 1,
|
|
21749
21833
|
kind: "direct",
|
|
21750
|
-
title:
|
|
21834
|
+
title: normalizeTitle2(title),
|
|
21751
21835
|
title_source: title ? "hermes" : "default",
|
|
21752
21836
|
status: "active",
|
|
21753
21837
|
hermes_session_id: sessionId,
|
|
@@ -22019,6 +22103,293 @@ function collectKnownHermesRowKeys(snapshot) {
|
|
|
22019
22103
|
}
|
|
22020
22104
|
return keys;
|
|
22021
22105
|
}
|
|
22106
|
+
function collectRepresentedHermesRows(paths, snapshot) {
|
|
22107
|
+
const rows = {
|
|
22108
|
+
syntheticUserTexts: /* @__PURE__ */ new Set(),
|
|
22109
|
+
toolCallIds: /* @__PURE__ */ new Set(),
|
|
22110
|
+
runWindows: []
|
|
22111
|
+
};
|
|
22112
|
+
for (const run of snapshot.runs) {
|
|
22113
|
+
collectRunHermesMessageWindows(run).forEach(
|
|
22114
|
+
(window) => rows.runWindows.push(window)
|
|
22115
|
+
);
|
|
22116
|
+
const userMessage = snapshot.messages.find(
|
|
22117
|
+
(message) => message.id === run.trigger_message_id
|
|
22118
|
+
);
|
|
22119
|
+
if (userMessage) {
|
|
22120
|
+
collectSyntheticRunInputTexts(paths, userMessage).forEach(
|
|
22121
|
+
(text) => rows.syntheticUserTexts.add(hashText(text))
|
|
22122
|
+
);
|
|
22123
|
+
}
|
|
22124
|
+
const assistantMessage = snapshot.messages.find(
|
|
22125
|
+
(message) => message.id === run.assistant_message_id
|
|
22126
|
+
);
|
|
22127
|
+
if (assistantMessage) {
|
|
22128
|
+
collectAgentEventIds(assistantMessage).forEach(
|
|
22129
|
+
(id) => rows.toolCallIds.add(id)
|
|
22130
|
+
);
|
|
22131
|
+
}
|
|
22132
|
+
}
|
|
22133
|
+
return rows;
|
|
22134
|
+
}
|
|
22135
|
+
function pruneStrictImportedDuplicateMessages(paths, snapshot) {
|
|
22136
|
+
if (snapshot.runs.length === 0) {
|
|
22137
|
+
return { snapshot, removedCount: 0 };
|
|
22138
|
+
}
|
|
22139
|
+
const messages2 = snapshot.messages.filter(
|
|
22140
|
+
(message) => !isStrictImportedDuplicateRunMessage(paths, snapshot, message)
|
|
22141
|
+
);
|
|
22142
|
+
const removedCount = snapshot.messages.length - messages2.length;
|
|
22143
|
+
return removedCount > 0 ? { snapshot: { ...snapshot, messages: messages2 }, removedCount } : { snapshot, removedCount: 0 };
|
|
22144
|
+
}
|
|
22145
|
+
function isStrictImportedDuplicateRunMessage(paths, snapshot, message) {
|
|
22146
|
+
if (!isHermesImportedMessage2(message)) {
|
|
22147
|
+
return false;
|
|
22148
|
+
}
|
|
22149
|
+
if (snapshot.runs.some(
|
|
22150
|
+
(run) => run.trigger_message_id === message.id || run.assistant_message_id === message.id
|
|
22151
|
+
)) {
|
|
22152
|
+
return false;
|
|
22153
|
+
}
|
|
22154
|
+
const messageSessionIds = collectMessageHermesSessionIds(message);
|
|
22155
|
+
if (messageSessionIds.size === 0) {
|
|
22156
|
+
return false;
|
|
22157
|
+
}
|
|
22158
|
+
return snapshot.runs.some((run) => {
|
|
22159
|
+
if (!runSessionMatchesMessage(run, messageSessionIds)) {
|
|
22160
|
+
return false;
|
|
22161
|
+
}
|
|
22162
|
+
if (!isMessageInsideRunCleanupWindow(message, run)) {
|
|
22163
|
+
return false;
|
|
22164
|
+
}
|
|
22165
|
+
if (message.role === "user") {
|
|
22166
|
+
const user = snapshot.messages.find(
|
|
22167
|
+
(item) => item.id === run.trigger_message_id
|
|
22168
|
+
);
|
|
22169
|
+
return user ? isDuplicateImportedRunUser(paths, user, message) : false;
|
|
22170
|
+
}
|
|
22171
|
+
if (message.role === "assistant" || message.role === "tool") {
|
|
22172
|
+
const assistant = snapshot.messages.find(
|
|
22173
|
+
(item) => item.id === run.assistant_message_id
|
|
22174
|
+
);
|
|
22175
|
+
return assistant ? isDuplicateImportedRunAssistant(assistant, message) : false;
|
|
22176
|
+
}
|
|
22177
|
+
return false;
|
|
22178
|
+
});
|
|
22179
|
+
}
|
|
22180
|
+
function isDuplicateImportedRunUser(paths, user, imported) {
|
|
22181
|
+
const importedText = normalizedDuplicateText(imported);
|
|
22182
|
+
if (!importedText) {
|
|
22183
|
+
return false;
|
|
22184
|
+
}
|
|
22185
|
+
if (importedText === normalizedDuplicateText(user)) {
|
|
22186
|
+
return true;
|
|
22187
|
+
}
|
|
22188
|
+
return collectSyntheticRunInputTexts(paths, user).some(
|
|
22189
|
+
(text) => normalizedDuplicateTextValue(text) === importedText
|
|
22190
|
+
);
|
|
22191
|
+
}
|
|
22192
|
+
function isDuplicateImportedRunAssistant(assistant, imported) {
|
|
22193
|
+
const importedText = normalizedDuplicateText(imported);
|
|
22194
|
+
if (importedText && importedText === normalizedDuplicateText(assistant)) {
|
|
22195
|
+
return true;
|
|
22196
|
+
}
|
|
22197
|
+
const importedToolIds = collectAgentEventIds(imported);
|
|
22198
|
+
if (importedToolIds.size === 0) {
|
|
22199
|
+
return false;
|
|
22200
|
+
}
|
|
22201
|
+
const assistantToolIds = collectAgentEventIds(assistant);
|
|
22202
|
+
return [...importedToolIds].every((id) => assistantToolIds.has(id));
|
|
22203
|
+
}
|
|
22204
|
+
function collectMessageHermesSessionIds(message) {
|
|
22205
|
+
const sessionIds = /* @__PURE__ */ new Set();
|
|
22206
|
+
const hermes = toRecord12(message.hermes);
|
|
22207
|
+
const sessionId = readString12(hermes, "session_id");
|
|
22208
|
+
if (sessionId) {
|
|
22209
|
+
sessionIds.add(sessionId);
|
|
22210
|
+
}
|
|
22211
|
+
for (const row of readHermesRawMessageRows(message.raw)) {
|
|
22212
|
+
const rowSessionId = readString12(row, "session_id");
|
|
22213
|
+
if (rowSessionId) {
|
|
22214
|
+
sessionIds.add(rowSessionId);
|
|
22215
|
+
}
|
|
22216
|
+
}
|
|
22217
|
+
return sessionIds;
|
|
22218
|
+
}
|
|
22219
|
+
function runSessionMatchesMessage(run, messageSessionIds) {
|
|
22220
|
+
return collectRunHermesSessionIds(run).some(
|
|
22221
|
+
(sessionId) => messageSessionIds.has(sessionId)
|
|
22222
|
+
);
|
|
22223
|
+
}
|
|
22224
|
+
function collectRunHermesSessionIds(run) {
|
|
22225
|
+
return normalizeSessionIds([
|
|
22226
|
+
run.hermes_session_id,
|
|
22227
|
+
run.hermes_message_watermark?.before?.session_id,
|
|
22228
|
+
run.hermes_message_watermark?.after?.session_id
|
|
22229
|
+
]);
|
|
22230
|
+
}
|
|
22231
|
+
function isMessageInsideRunCleanupWindow(message, run) {
|
|
22232
|
+
if (run.status === "queued" || run.status === "running" || run.status === "unknown") {
|
|
22233
|
+
return false;
|
|
22234
|
+
}
|
|
22235
|
+
const messageAt = parseIsoMillis(message.created_at);
|
|
22236
|
+
const startedAt = parseIsoMillis(run.started_at);
|
|
22237
|
+
const completedAt = run.completed_at ? parseIsoMillis(run.completed_at) : void 0;
|
|
22238
|
+
if (messageAt === void 0 || startedAt === void 0) {
|
|
22239
|
+
return false;
|
|
22240
|
+
}
|
|
22241
|
+
const lowerBound = startedAt - 10 * 60 * 1e3;
|
|
22242
|
+
const upperBound = (completedAt ?? startedAt) + 10 * 60 * 1e3;
|
|
22243
|
+
return messageAt >= lowerBound && messageAt <= upperBound;
|
|
22244
|
+
}
|
|
22245
|
+
function normalizedDuplicateText(message) {
|
|
22246
|
+
return normalizedDuplicateTextValue(messageText2(message));
|
|
22247
|
+
}
|
|
22248
|
+
function normalizedDuplicateTextValue(value) {
|
|
22249
|
+
return value.replace(/\r\n/gu, "\n").trim();
|
|
22250
|
+
}
|
|
22251
|
+
function collectRunHermesMessageWindows(run) {
|
|
22252
|
+
const before = normalizeWatermarkPoint(
|
|
22253
|
+
run.hermes_message_watermark?.before,
|
|
22254
|
+
run.hermes_session_id
|
|
22255
|
+
);
|
|
22256
|
+
if (!before) {
|
|
22257
|
+
return [];
|
|
22258
|
+
}
|
|
22259
|
+
const after = normalizeWatermarkPoint(
|
|
22260
|
+
run.hermes_message_watermark?.after,
|
|
22261
|
+
run.hermes_session_id
|
|
22262
|
+
);
|
|
22263
|
+
const sessionId = before.session_id?.trim() || run.hermes_session_id?.trim();
|
|
22264
|
+
if (!sessionId) {
|
|
22265
|
+
return [];
|
|
22266
|
+
}
|
|
22267
|
+
return [
|
|
22268
|
+
{
|
|
22269
|
+
runId: run.id,
|
|
22270
|
+
sessionId,
|
|
22271
|
+
status: run.status,
|
|
22272
|
+
before,
|
|
22273
|
+
...after && (after.session_id ?? sessionId) === sessionId ? { after } : {},
|
|
22274
|
+
startedAtMs: parseIsoMillis(run.started_at),
|
|
22275
|
+
completedAtMs: run.completed_at ? parseIsoMillis(run.completed_at) : void 0
|
|
22276
|
+
}
|
|
22277
|
+
];
|
|
22278
|
+
}
|
|
22279
|
+
function normalizeWatermarkPoint(point, fallbackSessionId) {
|
|
22280
|
+
if (!point || typeof point.message_count !== "number" || !Number.isFinite(point.message_count)) {
|
|
22281
|
+
return null;
|
|
22282
|
+
}
|
|
22283
|
+
const sessionId = point.session_id?.trim() || fallbackSessionId?.trim();
|
|
22284
|
+
return {
|
|
22285
|
+
source: point.source,
|
|
22286
|
+
...sessionId ? { session_id: sessionId } : {},
|
|
22287
|
+
message_count: Math.max(0, Math.trunc(point.message_count)),
|
|
22288
|
+
...typeof point.max_message_id === "number" && Number.isFinite(point.max_message_id) ? { max_message_id: point.max_message_id } : {},
|
|
22289
|
+
...typeof point.max_timestamp === "number" && Number.isFinite(point.max_timestamp) ? { max_timestamp: point.max_timestamp } : {},
|
|
22290
|
+
captured_at: point.captured_at
|
|
22291
|
+
};
|
|
22292
|
+
}
|
|
22293
|
+
function collectSyntheticRunInputTexts(paths, message) {
|
|
22294
|
+
if (message.role !== "user") {
|
|
22295
|
+
return [];
|
|
22296
|
+
}
|
|
22297
|
+
const attachmentLines = message.parts.filter((part) => Boolean(part.blob)).filter((part) => !isVoicePart(part)).map((part) => {
|
|
22298
|
+
const label = part.filename ?? part.blob;
|
|
22299
|
+
const mime = part.mime ? `, ${part.mime}` : "";
|
|
22300
|
+
const size = part.size ? `, ${part.size} bytes` : "";
|
|
22301
|
+
return `- ${label}${mime}${size}: ${part.local_path ?? blobPath(paths, part.blob)}`;
|
|
22302
|
+
});
|
|
22303
|
+
if (attachmentLines.length === 0) {
|
|
22304
|
+
return [];
|
|
22305
|
+
}
|
|
22306
|
+
const content = messageText2(message);
|
|
22307
|
+
const prefix = content ? `${content}
|
|
22308
|
+
|
|
22309
|
+
` : "";
|
|
22310
|
+
return [
|
|
22311
|
+
`${prefix}Attachments available on this computer:
|
|
22312
|
+
${attachmentLines.join("\n")}`
|
|
22313
|
+
];
|
|
22314
|
+
}
|
|
22315
|
+
function collectAgentEventIds(message) {
|
|
22316
|
+
const ids = /* @__PURE__ */ new Set();
|
|
22317
|
+
for (const event of message.agent_events ?? []) {
|
|
22318
|
+
if (event.id) {
|
|
22319
|
+
ids.add(event.id);
|
|
22320
|
+
}
|
|
22321
|
+
}
|
|
22322
|
+
for (const block of message.blocks ?? []) {
|
|
22323
|
+
if (block.type !== "agent_events") {
|
|
22324
|
+
continue;
|
|
22325
|
+
}
|
|
22326
|
+
for (const event of block.events) {
|
|
22327
|
+
if (event.id) {
|
|
22328
|
+
ids.add(event.id);
|
|
22329
|
+
}
|
|
22330
|
+
}
|
|
22331
|
+
}
|
|
22332
|
+
return ids;
|
|
22333
|
+
}
|
|
22334
|
+
function isRepresentedHermesRow(represented, row, index) {
|
|
22335
|
+
const role = normalizeMessageRole(row.role);
|
|
22336
|
+
if (represented.runWindows.some(
|
|
22337
|
+
(window) => isRowInsideRunWindow(window, row, role)
|
|
22338
|
+
)) {
|
|
22339
|
+
return true;
|
|
22340
|
+
}
|
|
22341
|
+
if (role === "user" && represented.syntheticUserTexts.has(hashText(normalizeContent2(row.content)))) {
|
|
22342
|
+
return true;
|
|
22343
|
+
}
|
|
22344
|
+
if (role === "assistant") {
|
|
22345
|
+
const toolCalls = readHermesToolCalls(row);
|
|
22346
|
+
return toolCalls.length > 0 && toolCalls.every(
|
|
22347
|
+
(toolCall) => toolCall.id && represented.toolCallIds.has(toolCall.id)
|
|
22348
|
+
);
|
|
22349
|
+
}
|
|
22350
|
+
if (role === "tool") {
|
|
22351
|
+
const id = readString12(row, "tool_call_id") ?? readString12(row, "tool_id") ?? readString12(row, "call_id");
|
|
22352
|
+
if (id) {
|
|
22353
|
+
return represented.toolCallIds.has(id);
|
|
22354
|
+
}
|
|
22355
|
+
const key = hermesRowKey(row, index);
|
|
22356
|
+
return represented.toolCallIds.has(key);
|
|
22357
|
+
}
|
|
22358
|
+
return false;
|
|
22359
|
+
}
|
|
22360
|
+
function isRowInsideRunWindow(window, row, role) {
|
|
22361
|
+
if (role === "system") {
|
|
22362
|
+
return false;
|
|
22363
|
+
}
|
|
22364
|
+
if ((readString12(row, "session_id") ?? "") !== window.sessionId) {
|
|
22365
|
+
return false;
|
|
22366
|
+
}
|
|
22367
|
+
const hasClosedAfter = Boolean(window.after);
|
|
22368
|
+
const allowOpenEnded = window.status === "running";
|
|
22369
|
+
const allowTerminalGrace = !hasClosedAfter && (window.status === "cancelled" || window.status === "failed") && window.completedAtMs !== void 0;
|
|
22370
|
+
if (!hasClosedAfter && !allowOpenEnded && !allowTerminalGrace) {
|
|
22371
|
+
return false;
|
|
22372
|
+
}
|
|
22373
|
+
const position = rowSessionPosition(row);
|
|
22374
|
+
if (window.before.source !== "none" && position !== void 0 && position > window.before.message_count && (window.after ? position <= window.after.message_count : allowOpenEnded)) {
|
|
22375
|
+
return true;
|
|
22376
|
+
}
|
|
22377
|
+
const rowId = readNumber3(row.id);
|
|
22378
|
+
if (rowId !== null && window.before.max_message_id !== void 0 && rowId > window.before.max_message_id && (window.after?.max_message_id !== void 0 ? rowId <= window.after.max_message_id : allowOpenEnded)) {
|
|
22379
|
+
return true;
|
|
22380
|
+
}
|
|
22381
|
+
const rowTimeMs = hermesTimestampMillis(row.timestamp);
|
|
22382
|
+
if (rowTimeMs === void 0) {
|
|
22383
|
+
return false;
|
|
22384
|
+
}
|
|
22385
|
+
const beforeTimeMs = hermesTimestampMillis(window.before.max_timestamp);
|
|
22386
|
+
const lowerTimeMs = beforeTimeMs ?? (window.startedAtMs ?? 0) - 5e3;
|
|
22387
|
+
const upperTimeMs = hermesTimestampMillis(window.after?.max_timestamp) ?? (allowTerminalGrace && window.completedAtMs !== void 0 ? window.completedAtMs + 2 * 60 * 1e3 : allowOpenEnded ? Number.POSITIVE_INFINITY : void 0);
|
|
22388
|
+
return upperTimeMs !== void 0 && (beforeTimeMs !== void 0 ? rowTimeMs > lowerTimeMs : rowTimeMs >= lowerTimeMs) && rowTimeMs <= upperTimeMs;
|
|
22389
|
+
}
|
|
22390
|
+
function isVoicePart(part) {
|
|
22391
|
+
return part.kind === "voice" || part.is_voice_note === true;
|
|
22392
|
+
}
|
|
22022
22393
|
function collectMessageHermesRowKeys(message) {
|
|
22023
22394
|
const keys = [];
|
|
22024
22395
|
readHermesRawMessageRows(message.raw).forEach((row, index) => {
|
|
@@ -22072,6 +22443,21 @@ function representedMessageSignature(message) {
|
|
|
22072
22443
|
function hashText(value) {
|
|
22073
22444
|
return createHash6("sha256").update(value).digest("hex");
|
|
22074
22445
|
}
|
|
22446
|
+
function rowSessionPosition(row) {
|
|
22447
|
+
const position = row[HERMES_ROW_SESSION_POSITION];
|
|
22448
|
+
return typeof position === "number" && Number.isFinite(position) ? position : void 0;
|
|
22449
|
+
}
|
|
22450
|
+
function hermesTimestampMillis(value) {
|
|
22451
|
+
const numeric = readNumber3(value);
|
|
22452
|
+
if (numeric === null || numeric <= 0) {
|
|
22453
|
+
return void 0;
|
|
22454
|
+
}
|
|
22455
|
+
return numeric > 1e10 ? numeric : numeric * 1e3;
|
|
22456
|
+
}
|
|
22457
|
+
function parseIsoMillis(value) {
|
|
22458
|
+
const parsed = Date.parse(value);
|
|
22459
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
22460
|
+
}
|
|
22075
22461
|
function compareLinkMessagesByCreatedAt(left, right) {
|
|
22076
22462
|
return Date.parse(left.created_at) - Date.parse(right.created_at) || left.id.localeCompare(right.id);
|
|
22077
22463
|
}
|
|
@@ -22165,6 +22551,59 @@ async function readExistingHermesConversations(store, conversationIds) {
|
|
|
22165
22551
|
}
|
|
22166
22552
|
return conversations;
|
|
22167
22553
|
}
|
|
22554
|
+
async function archiveKnownHermesConversation(input) {
|
|
22555
|
+
const conversationIds = findKnownConversationIdsForCandidate(
|
|
22556
|
+
input.knownHermesSessions,
|
|
22557
|
+
input.candidate
|
|
22558
|
+
);
|
|
22559
|
+
if (conversationIds.length === 0) {
|
|
22560
|
+
return 0;
|
|
22561
|
+
}
|
|
22562
|
+
const archivedAt = readString12(input.candidate.session, "archived_at") ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
22563
|
+
let archivedCount = 0;
|
|
22564
|
+
for (const conversation of await readExistingHermesConversations(
|
|
22565
|
+
input.store,
|
|
22566
|
+
conversationIds
|
|
22567
|
+
)) {
|
|
22568
|
+
if (conversation.manifest.status !== "active") {
|
|
22569
|
+
continue;
|
|
22570
|
+
}
|
|
22571
|
+
const nextManifest = {
|
|
22572
|
+
...conversation.manifest,
|
|
22573
|
+
status: "archived",
|
|
22574
|
+
updated_at: archivedAt,
|
|
22575
|
+
archived_at: archivedAt,
|
|
22576
|
+
hermes_session_ids: normalizeSessionIds([
|
|
22577
|
+
conversation.manifest.hermes_session_id,
|
|
22578
|
+
...conversation.manifest.hermes_session_ids ?? [],
|
|
22579
|
+
...conversation.manifest.hermes_lineage?.session_ids ?? [],
|
|
22580
|
+
...lineageSessionIds(input.candidate)
|
|
22581
|
+
]),
|
|
22582
|
+
...lineageManifestPatch(input.candidate)
|
|
22583
|
+
};
|
|
22584
|
+
const stats = buildConversationStats(nextManifest, conversation.snapshot);
|
|
22585
|
+
const archivedManifest = { ...nextManifest, stats };
|
|
22586
|
+
await input.store.writeManifest(archivedManifest);
|
|
22587
|
+
await input.store.appendEvent(conversation.conversationId, {
|
|
22588
|
+
type: "conversation.archived",
|
|
22589
|
+
payload: {
|
|
22590
|
+
archived_at: archivedAt,
|
|
22591
|
+
source: "hermes",
|
|
22592
|
+
hermes_session_id: input.candidate.session.id
|
|
22593
|
+
}
|
|
22594
|
+
});
|
|
22595
|
+
const eventManifest = await input.store.readManifest(conversation.conversationId);
|
|
22596
|
+
const eventStats = buildConversationStats(eventManifest, conversation.snapshot);
|
|
22597
|
+
const indexedManifest = { ...eventManifest, stats: eventStats };
|
|
22598
|
+
await input.store.writeManifest(indexedManifest);
|
|
22599
|
+
await upsertConversationStats(
|
|
22600
|
+
input.paths,
|
|
22601
|
+
toStatsIndexRecord(indexedManifest, eventStats)
|
|
22602
|
+
);
|
|
22603
|
+
archivedCount += 1;
|
|
22604
|
+
}
|
|
22605
|
+
return archivedCount;
|
|
22606
|
+
}
|
|
22168
22607
|
function selectCanonicalHermesConversation(conversations) {
|
|
22169
22608
|
const ranked = [...conversations].sort((left, right) => {
|
|
22170
22609
|
const rightScore = canonicalConversationScore(right);
|
|
@@ -22277,7 +22716,7 @@ function mergeHermesLineageIntoManifest(input) {
|
|
|
22277
22716
|
};
|
|
22278
22717
|
const title = deriveHermesConversationTitle(input.candidate, input.snapshot);
|
|
22279
22718
|
if (title && canSyncHermesTitle(input.manifest)) {
|
|
22280
|
-
nextBase.title =
|
|
22719
|
+
nextBase.title = normalizeTitle2(title);
|
|
22281
22720
|
nextBase.title_source = "hermes";
|
|
22282
22721
|
}
|
|
22283
22722
|
const baseStats = buildConversationStats(nextBase, input.snapshot);
|
|
@@ -23066,9 +23505,15 @@ async function readHermesSessionMessages(candidate) {
|
|
|
23066
23505
|
readJsonlMessages(candidate.profileName, candidate.session.id)
|
|
23067
23506
|
]);
|
|
23068
23507
|
const selected = jsonlMessages.length > dbMessages.length ? jsonlMessages : dbMessages;
|
|
23069
|
-
return selected.map(
|
|
23070
|
-
|
|
23071
|
-
|
|
23508
|
+
return selected.map((message, index) => {
|
|
23509
|
+
const normalized = readString12(message, "session_id") ? message : { ...message, session_id: candidate.session.id };
|
|
23510
|
+
Object.defineProperty(normalized, HERMES_ROW_SESSION_POSITION, {
|
|
23511
|
+
value: index + 1,
|
|
23512
|
+
enumerable: false,
|
|
23513
|
+
configurable: true
|
|
23514
|
+
});
|
|
23515
|
+
return normalized;
|
|
23516
|
+
});
|
|
23072
23517
|
}
|
|
23073
23518
|
async function readStateDbMessages(dbPath, sessionId) {
|
|
23074
23519
|
if (!await isFile(dbPath)) {
|
|
@@ -23310,7 +23755,7 @@ function senderForRole(input) {
|
|
|
23310
23755
|
function firstUserText(snapshot) {
|
|
23311
23756
|
return snapshot.messages.find((message) => message.role === "user")?.parts.find((part) => part.type === "text")?.text?.slice(0, 80);
|
|
23312
23757
|
}
|
|
23313
|
-
function
|
|
23758
|
+
function normalizeTitle2(value) {
|
|
23314
23759
|
const normalized = value?.replace(/\s+/gu, " ").trim();
|
|
23315
23760
|
return normalized || DEFAULT_CONVERSATION_TITLE;
|
|
23316
23761
|
}
|
|
@@ -23423,6 +23868,10 @@ function isHiddenSession(session) {
|
|
|
23423
23868
|
const visibility = readString12(session, "visibility")?.toLowerCase();
|
|
23424
23869
|
return Boolean(source && HIDDEN_SESSION_SOURCES.has(source)) || readBoolean2(session.hidden) || readBoolean2(session.archived) || Boolean(readString12(session, "archived_at")) || status === "hidden" || status === "archived" || visibility === "hidden" || visibility === "hide";
|
|
23425
23870
|
}
|
|
23871
|
+
function isArchivedSession(session) {
|
|
23872
|
+
const status = readString12(session, "status")?.toLowerCase();
|
|
23873
|
+
return readBoolean2(session.archived) || Boolean(readString12(session, "archived_at")) || status === "archived";
|
|
23874
|
+
}
|
|
23426
23875
|
function readTableColumns2(db, tableName) {
|
|
23427
23876
|
try {
|
|
23428
23877
|
const rows = db.prepare(`PRAGMA table_info(${quoteIdentifier(tableName)})`).all();
|
|
@@ -24181,10 +24630,10 @@ function parseHermesApiCapabilities(payload) {
|
|
|
24181
24630
|
sessionKeyHeader: readString14(features, "session_key_header")
|
|
24182
24631
|
};
|
|
24183
24632
|
}
|
|
24184
|
-
async function callHermesApi(
|
|
24633
|
+
async function callHermesApi(path39, init, options) {
|
|
24185
24634
|
const method = init.method ?? "GET";
|
|
24186
24635
|
const startedAt = Date.now();
|
|
24187
|
-
void options.logger?.debug("hermes_api_request_started", { method, path:
|
|
24636
|
+
void options.logger?.debug("hermes_api_request_started", { method, path: path39 });
|
|
24188
24637
|
const availability = await ensureHermesApiServerAvailable({
|
|
24189
24638
|
fetchImpl: options.fetchImpl,
|
|
24190
24639
|
logger: options.logger,
|
|
@@ -24193,7 +24642,7 @@ async function callHermesApi(path38, init, options) {
|
|
|
24193
24642
|
});
|
|
24194
24643
|
let config = availability.configResult.apiServer;
|
|
24195
24644
|
const fetcher = options.fetchImpl ?? fetch;
|
|
24196
|
-
const request = () => fetchHermesApi(fetcher, config,
|
|
24645
|
+
const request = () => fetchHermesApi(fetcher, config, path39, init, options);
|
|
24197
24646
|
let response;
|
|
24198
24647
|
try {
|
|
24199
24648
|
response = await request();
|
|
@@ -24201,7 +24650,7 @@ async function callHermesApi(path38, init, options) {
|
|
|
24201
24650
|
logHermesApiError(
|
|
24202
24651
|
options.logger,
|
|
24203
24652
|
method,
|
|
24204
|
-
|
|
24653
|
+
path39,
|
|
24205
24654
|
options.profileName,
|
|
24206
24655
|
startedAt,
|
|
24207
24656
|
error
|
|
@@ -24212,7 +24661,7 @@ async function callHermesApi(path38, init, options) {
|
|
|
24212
24661
|
logHermesApiResponse(
|
|
24213
24662
|
options.logger,
|
|
24214
24663
|
method,
|
|
24215
|
-
|
|
24664
|
+
path39,
|
|
24216
24665
|
options.profileName,
|
|
24217
24666
|
startedAt,
|
|
24218
24667
|
response
|
|
@@ -24221,7 +24670,7 @@ async function callHermesApi(path38, init, options) {
|
|
|
24221
24670
|
}
|
|
24222
24671
|
void options.logger?.warn("hermes_api_request_retrying_after_401", {
|
|
24223
24672
|
method,
|
|
24224
|
-
path:
|
|
24673
|
+
path: path39,
|
|
24225
24674
|
profile: options.profileName ?? "default",
|
|
24226
24675
|
port: config.port ?? null,
|
|
24227
24676
|
duration_ms: Date.now() - startedAt
|
|
@@ -24240,7 +24689,7 @@ async function callHermesApi(path38, init, options) {
|
|
|
24240
24689
|
logHermesApiError(
|
|
24241
24690
|
options.logger,
|
|
24242
24691
|
method,
|
|
24243
|
-
|
|
24692
|
+
path39,
|
|
24244
24693
|
options.profileName,
|
|
24245
24694
|
startedAt,
|
|
24246
24695
|
error
|
|
@@ -24250,7 +24699,7 @@ async function callHermesApi(path38, init, options) {
|
|
|
24250
24699
|
logHermesApiResponse(
|
|
24251
24700
|
options.logger,
|
|
24252
24701
|
method,
|
|
24253
|
-
|
|
24702
|
+
path39,
|
|
24254
24703
|
options.profileName,
|
|
24255
24704
|
startedAt,
|
|
24256
24705
|
response
|
|
@@ -24260,7 +24709,7 @@ async function callHermesApi(path38, init, options) {
|
|
|
24260
24709
|
}
|
|
24261
24710
|
void options.logger?.warn("hermes_api_request_repairing_after_401", {
|
|
24262
24711
|
method,
|
|
24263
|
-
path:
|
|
24712
|
+
path: path39,
|
|
24264
24713
|
profile: options.profileName ?? "default",
|
|
24265
24714
|
port: config.port ?? null,
|
|
24266
24715
|
duration_ms: Date.now() - startedAt
|
|
@@ -24281,7 +24730,7 @@ async function callHermesApi(path38, init, options) {
|
|
|
24281
24730
|
logHermesApiError(
|
|
24282
24731
|
options.logger,
|
|
24283
24732
|
method,
|
|
24284
|
-
|
|
24733
|
+
path39,
|
|
24285
24734
|
options.profileName,
|
|
24286
24735
|
startedAt,
|
|
24287
24736
|
error
|
|
@@ -24291,21 +24740,21 @@ async function callHermesApi(path38, init, options) {
|
|
|
24291
24740
|
logHermesApiResponse(
|
|
24292
24741
|
options.logger,
|
|
24293
24742
|
method,
|
|
24294
|
-
|
|
24743
|
+
path39,
|
|
24295
24744
|
options.profileName,
|
|
24296
24745
|
startedAt,
|
|
24297
24746
|
response
|
|
24298
24747
|
);
|
|
24299
24748
|
return response;
|
|
24300
24749
|
}
|
|
24301
|
-
async function fetchHermesApi(fetcher, config,
|
|
24750
|
+
async function fetchHermesApi(fetcher, config, path39, init, options) {
|
|
24302
24751
|
const headers = new Headers(init.headers);
|
|
24303
24752
|
headers.set("accept", headers.get("accept") ?? "application/json");
|
|
24304
24753
|
if (config.key) {
|
|
24305
24754
|
headers.set("x-api-key", config.key);
|
|
24306
24755
|
headers.set("authorization", `Bearer ${config.key}`);
|
|
24307
24756
|
}
|
|
24308
|
-
return await fetcher(`http://127.0.0.1:${config.port}${
|
|
24757
|
+
return await fetcher(`http://127.0.0.1:${config.port}${path39}`, {
|
|
24309
24758
|
...init,
|
|
24310
24759
|
headers
|
|
24311
24760
|
}).catch((error) => {
|
|
@@ -24314,10 +24763,10 @@ async function fetchHermesApi(fetcher, config, path38, init, options) {
|
|
|
24314
24763
|
}
|
|
24315
24764
|
void options.logger?.warn("hermes_api_server_connect_failed", {
|
|
24316
24765
|
method: String(init.method ?? "GET").toUpperCase(),
|
|
24317
|
-
path:
|
|
24766
|
+
path: path39,
|
|
24318
24767
|
profile: options.profileName ?? "default",
|
|
24319
24768
|
port: config.port ?? null,
|
|
24320
|
-
url: `http://127.0.0.1:${config.port}${
|
|
24769
|
+
url: `http://127.0.0.1:${config.port}${path39}`,
|
|
24321
24770
|
error: error instanceof Error ? error.message : String(error)
|
|
24322
24771
|
});
|
|
24323
24772
|
throw new LinkHttpError(
|
|
@@ -24327,10 +24776,10 @@ async function fetchHermesApi(fetcher, config, path38, init, options) {
|
|
|
24327
24776
|
);
|
|
24328
24777
|
});
|
|
24329
24778
|
}
|
|
24330
|
-
function logHermesApiResponse(logger, method,
|
|
24779
|
+
function logHermesApiResponse(logger, method, path39, profileName, startedAt, response) {
|
|
24331
24780
|
const fields = {
|
|
24332
24781
|
method,
|
|
24333
|
-
path:
|
|
24782
|
+
path: path39,
|
|
24334
24783
|
profile: profileName ?? "default",
|
|
24335
24784
|
status: response.status,
|
|
24336
24785
|
duration_ms: Date.now() - startedAt
|
|
@@ -24351,10 +24800,10 @@ async function logHermesApiFailureResponse(logger, fields, response) {
|
|
|
24351
24800
|
...upstreamError ? { upstream_error: upstreamError } : {}
|
|
24352
24801
|
});
|
|
24353
24802
|
}
|
|
24354
|
-
function logHermesApiError(logger, method,
|
|
24803
|
+
function logHermesApiError(logger, method, path39, profileName, startedAt, error) {
|
|
24355
24804
|
void logger?.warn("hermes_api_request_failed", {
|
|
24356
24805
|
method,
|
|
24357
|
-
path:
|
|
24806
|
+
path: path39,
|
|
24358
24807
|
profile: profileName ?? "default",
|
|
24359
24808
|
duration_ms: Date.now() - startedAt,
|
|
24360
24809
|
...error instanceof LinkHttpError ? { status: error.status, code: error.code } : {},
|
|
@@ -26790,6 +27239,127 @@ function isNodeError17(error, code) {
|
|
|
26790
27239
|
return typeof error === "object" && error !== null && "code" in error && error.code === code;
|
|
26791
27240
|
}
|
|
26792
27241
|
|
|
27242
|
+
// src/conversations/hermes-message-watermark.ts
|
|
27243
|
+
import { stat as stat18, readFile as readFile16 } from "fs/promises";
|
|
27244
|
+
import path27 from "path";
|
|
27245
|
+
async function readHermesMessageWatermark(input) {
|
|
27246
|
+
const profileName = input.profileName?.trim() || "default";
|
|
27247
|
+
const sessionId = input.sessionId.trim();
|
|
27248
|
+
const profileDir = resolveHermesProfileDir(profileName);
|
|
27249
|
+
const dbPath = path27.join(profileDir, "state.db");
|
|
27250
|
+
const [dbWatermark, jsonlWatermark] = await Promise.all([
|
|
27251
|
+
readStateDbMessageWatermark(dbPath, sessionId),
|
|
27252
|
+
readJsonlMessageWatermark(profileName, sessionId)
|
|
27253
|
+
]);
|
|
27254
|
+
const selected = (jsonlWatermark.message_count ?? 0) > (dbWatermark.message_count ?? 0) ? jsonlWatermark : dbWatermark;
|
|
27255
|
+
return {
|
|
27256
|
+
...selected,
|
|
27257
|
+
session_id: sessionId,
|
|
27258
|
+
captured_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
27259
|
+
};
|
|
27260
|
+
}
|
|
27261
|
+
async function readStateDbMessageWatermark(dbPath, sessionId) {
|
|
27262
|
+
if (!await isFile3(dbPath)) {
|
|
27263
|
+
return { source: "none", message_count: 0 };
|
|
27264
|
+
}
|
|
27265
|
+
let db = null;
|
|
27266
|
+
try {
|
|
27267
|
+
db = openSqliteDatabase(dbPath, {
|
|
27268
|
+
readonly: true,
|
|
27269
|
+
timeout: 1e3
|
|
27270
|
+
});
|
|
27271
|
+
const columns = readTableColumns4(db, "messages");
|
|
27272
|
+
if (!columns.has("session_id")) {
|
|
27273
|
+
return { source: "none", message_count: 0 };
|
|
27274
|
+
}
|
|
27275
|
+
const idExpression = columns.has("id") ? "MAX(CASE WHEN typeof(id) IN ('integer', 'real') THEN id ELSE NULL END) AS max_message_id" : "NULL AS max_message_id";
|
|
27276
|
+
const timestampExpression = columns.has("timestamp") ? "MAX(timestamp) AS max_timestamp" : "NULL AS max_timestamp";
|
|
27277
|
+
const row = db.prepare(
|
|
27278
|
+
`
|
|
27279
|
+
SELECT COUNT(*) AS message_count, ${idExpression}, ${timestampExpression}
|
|
27280
|
+
FROM messages
|
|
27281
|
+
WHERE session_id = ?
|
|
27282
|
+
`
|
|
27283
|
+
).get(sessionId);
|
|
27284
|
+
return {
|
|
27285
|
+
source: "state_db",
|
|
27286
|
+
message_count: readNumber5(row.message_count) ?? 0,
|
|
27287
|
+
...readNumber5(row.max_message_id) !== null ? { max_message_id: readNumber5(row.max_message_id) } : {},
|
|
27288
|
+
...readNumber5(row.max_timestamp) !== null ? { max_timestamp: readNumber5(row.max_timestamp) } : {}
|
|
27289
|
+
};
|
|
27290
|
+
} catch {
|
|
27291
|
+
return { source: "none", message_count: 0 };
|
|
27292
|
+
} finally {
|
|
27293
|
+
db?.close();
|
|
27294
|
+
}
|
|
27295
|
+
}
|
|
27296
|
+
async function readJsonlMessageWatermark(profileName, sessionId) {
|
|
27297
|
+
if (!/^[A-Za-z0-9._:-]{1,160}$/u.test(sessionId)) {
|
|
27298
|
+
return { source: "none", message_count: 0 };
|
|
27299
|
+
}
|
|
27300
|
+
const profileDir = resolveHermesProfileDir(profileName);
|
|
27301
|
+
const sessionsDir = await readHermesSessionsDir(profileName).then((value) => value.sessionsDir).catch(() => path27.join(profileDir, "sessions"));
|
|
27302
|
+
const transcriptPath = path27.join(sessionsDir, `${sessionId}.jsonl`);
|
|
27303
|
+
const raw = await readFile16(transcriptPath, "utf8").catch(() => "");
|
|
27304
|
+
if (!raw.trim()) {
|
|
27305
|
+
return { source: "none", message_count: 0 };
|
|
27306
|
+
}
|
|
27307
|
+
let messageCount = 0;
|
|
27308
|
+
let maxMessageId;
|
|
27309
|
+
let maxTimestamp;
|
|
27310
|
+
for (const line of raw.split(/\r?\n/u)) {
|
|
27311
|
+
if (!line.trim()) {
|
|
27312
|
+
continue;
|
|
27313
|
+
}
|
|
27314
|
+
try {
|
|
27315
|
+
const parsed = JSON.parse(line);
|
|
27316
|
+
if (!readString18(parsed, "role")) {
|
|
27317
|
+
continue;
|
|
27318
|
+
}
|
|
27319
|
+
messageCount += 1;
|
|
27320
|
+
const id = readNumber5(parsed.id);
|
|
27321
|
+
const timestamp = readNumber5(parsed.timestamp) ?? readNumber5(parsed.created_at) ?? readNumber5(parsed.createdAt);
|
|
27322
|
+
if (id !== null) {
|
|
27323
|
+
maxMessageId = maxMessageId === void 0 ? id : Math.max(maxMessageId, id);
|
|
27324
|
+
}
|
|
27325
|
+
if (timestamp !== null) {
|
|
27326
|
+
maxTimestamp = maxTimestamp === void 0 ? timestamp : Math.max(maxTimestamp, timestamp);
|
|
27327
|
+
}
|
|
27328
|
+
} catch {
|
|
27329
|
+
continue;
|
|
27330
|
+
}
|
|
27331
|
+
}
|
|
27332
|
+
return {
|
|
27333
|
+
source: messageCount > 0 ? "jsonl" : "none",
|
|
27334
|
+
message_count: messageCount,
|
|
27335
|
+
...maxMessageId !== void 0 ? { max_message_id: maxMessageId } : {},
|
|
27336
|
+
...maxTimestamp !== void 0 ? { max_timestamp: maxTimestamp } : {}
|
|
27337
|
+
};
|
|
27338
|
+
}
|
|
27339
|
+
function readTableColumns4(db, tableName) {
|
|
27340
|
+
try {
|
|
27341
|
+
const rows = db.prepare(`PRAGMA table_info(${quoteIdentifier3(tableName)})`).all();
|
|
27342
|
+
return new Set(
|
|
27343
|
+
rows.map((row) => typeof row.name === "string" ? row.name : "").filter(Boolean)
|
|
27344
|
+
);
|
|
27345
|
+
} catch {
|
|
27346
|
+
return /* @__PURE__ */ new Set();
|
|
27347
|
+
}
|
|
27348
|
+
}
|
|
27349
|
+
function quoteIdentifier3(value) {
|
|
27350
|
+
return `"${value.replaceAll('"', '""')}"`;
|
|
27351
|
+
}
|
|
27352
|
+
async function isFile3(filePath) {
|
|
27353
|
+
return stat18(filePath).then((value) => value.isFile()).catch(() => false);
|
|
27354
|
+
}
|
|
27355
|
+
function readString18(payload, key) {
|
|
27356
|
+
const value = payload[key];
|
|
27357
|
+
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
27358
|
+
}
|
|
27359
|
+
function readNumber5(value) {
|
|
27360
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
27361
|
+
}
|
|
27362
|
+
|
|
26793
27363
|
// src/conversations/run-tool-event-ids.ts
|
|
26794
27364
|
import { createHash as createHash7 } from "crypto";
|
|
26795
27365
|
var RunToolEventIdCoalescer = class {
|
|
@@ -26883,7 +27453,7 @@ var RunToolEventIdCoalescer = class {
|
|
|
26883
27453
|
}
|
|
26884
27454
|
};
|
|
26885
27455
|
function readToolEventType(event) {
|
|
26886
|
-
const type =
|
|
27456
|
+
const type = readString19(event.payload, "type") ?? readString19(event.payload, "event") ?? event.payloadType;
|
|
26887
27457
|
return type.startsWith("tool.") ? type : null;
|
|
26888
27458
|
}
|
|
26889
27459
|
function isTerminalToolEvent(type) {
|
|
@@ -26894,14 +27464,14 @@ function hasStableToolEventId(payload) {
|
|
|
26894
27464
|
const call = toRecord17(payload.tool_call ?? payload.toolCall);
|
|
26895
27465
|
const fn = toRecord17(call.function ?? payload.function);
|
|
26896
27466
|
return Boolean(
|
|
26897
|
-
|
|
27467
|
+
readString19(payload, "tool_call_id") ?? readString19(payload, "toolCallId") ?? readString19(payload, "tool_id") ?? readString19(payload, "call_id") ?? readString19(payload, "id") ?? readString19(tool, "id") ?? readString19(call, "id") ?? readString19(fn, "id")
|
|
26898
27468
|
);
|
|
26899
27469
|
}
|
|
26900
27470
|
function readToolName2(payload) {
|
|
26901
27471
|
const tool = toRecord17(payload.tool);
|
|
26902
27472
|
const call = toRecord17(payload.tool_call ?? payload.toolCall);
|
|
26903
27473
|
const fn = toRecord17(call.function ?? payload.function);
|
|
26904
|
-
return
|
|
27474
|
+
return readString19(payload, "tool_name") ?? readString19(payload, "toolName") ?? readString19(payload, "name") ?? readString19(payload, "tool") ?? readString19(tool, "name") ?? readString19(call, "name") ?? readString19(fn, "name") ?? "tool";
|
|
26905
27475
|
}
|
|
26906
27476
|
function withGeneratedToolEventId(event, id) {
|
|
26907
27477
|
return {
|
|
@@ -26958,7 +27528,7 @@ function stableStringify2(value) {
|
|
|
26958
27528
|
function hashStableValue(value) {
|
|
26959
27529
|
return createHash7("sha256").update(value).digest("hex").slice(0, 16);
|
|
26960
27530
|
}
|
|
26961
|
-
function
|
|
27531
|
+
function readString19(payload, key) {
|
|
26962
27532
|
const value = payload[key];
|
|
26963
27533
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
26964
27534
|
}
|
|
@@ -26990,8 +27560,8 @@ function normalizeHermesStreamEvent(event) {
|
|
|
26990
27560
|
};
|
|
26991
27561
|
}
|
|
26992
27562
|
if (event.eventName === "hermes.tool.progress") {
|
|
26993
|
-
const toolName =
|
|
26994
|
-
const preview =
|
|
27563
|
+
const toolName = readString20(event.payload, "tool") ?? readString20(event.payload, "name") ?? "tool";
|
|
27564
|
+
const preview = readString20(event.payload, "label") ?? readString20(event.payload, "preview") ?? toolName;
|
|
26995
27565
|
return {
|
|
26996
27566
|
...event,
|
|
26997
27567
|
payloadType: "tool.started",
|
|
@@ -27043,7 +27613,7 @@ function normalizeReasoningEvent(event) {
|
|
|
27043
27613
|
if (type !== "tool.progress" && event.eventName !== "hermes.tool.progress") {
|
|
27044
27614
|
return null;
|
|
27045
27615
|
}
|
|
27046
|
-
const toolName =
|
|
27616
|
+
const toolName = readString20(event.payload, "tool_name") ?? readString20(event.payload, "tool") ?? readString20(event.payload, "name");
|
|
27047
27617
|
if (toolName !== "_thinking") {
|
|
27048
27618
|
return null;
|
|
27049
27619
|
}
|
|
@@ -27094,7 +27664,7 @@ function normalizeHermesResponseEvent(event) {
|
|
|
27094
27664
|
}
|
|
27095
27665
|
function normalizeResponseCreated(event) {
|
|
27096
27666
|
const response = toRecord18(event.payload.response ?? event.payload);
|
|
27097
|
-
const responseId =
|
|
27667
|
+
const responseId = readString20(response, "id") ?? readString20(event.payload, "id");
|
|
27098
27668
|
return responseId ? {
|
|
27099
27669
|
...event,
|
|
27100
27670
|
payloadType: "response.created",
|
|
@@ -27107,10 +27677,10 @@ function normalizeResponseCreated(event) {
|
|
|
27107
27677
|
}
|
|
27108
27678
|
function normalizeResponseOutputItemAdded(event) {
|
|
27109
27679
|
const item = toRecord18(event.payload.item);
|
|
27110
|
-
if (
|
|
27680
|
+
if (readString20(item, "type") !== "function_call") {
|
|
27111
27681
|
return null;
|
|
27112
27682
|
}
|
|
27113
|
-
const toolName =
|
|
27683
|
+
const toolName = readString20(item, "name") ?? "tool";
|
|
27114
27684
|
const argumentsValue = parseJsonValue3(item.arguments) ?? item.arguments;
|
|
27115
27685
|
return {
|
|
27116
27686
|
...event,
|
|
@@ -27120,16 +27690,16 @@ function normalizeResponseOutputItemAdded(event) {
|
|
|
27120
27690
|
tool: toolName,
|
|
27121
27691
|
tool_name: toolName,
|
|
27122
27692
|
name: toolName,
|
|
27123
|
-
tool_call_id:
|
|
27693
|
+
tool_call_id: readString20(item, "call_id") ?? readString20(item, "id"),
|
|
27124
27694
|
arguments: argumentsValue,
|
|
27125
27695
|
preview: toolName,
|
|
27126
|
-
response_item_id:
|
|
27696
|
+
response_item_id: readString20(item, "id") ?? void 0
|
|
27127
27697
|
}
|
|
27128
27698
|
};
|
|
27129
27699
|
}
|
|
27130
27700
|
function normalizeResponseOutputItemDone(event) {
|
|
27131
27701
|
const item = toRecord18(event.payload.item);
|
|
27132
|
-
if (
|
|
27702
|
+
if (readString20(item, "type") === "message") {
|
|
27133
27703
|
const delta = extractResponseAssistantText({ output: [item] });
|
|
27134
27704
|
return delta ? {
|
|
27135
27705
|
...event,
|
|
@@ -27137,7 +27707,7 @@ function normalizeResponseOutputItemDone(event) {
|
|
|
27137
27707
|
payload: { type: "message.delta", delta }
|
|
27138
27708
|
} : null;
|
|
27139
27709
|
}
|
|
27140
|
-
if (
|
|
27710
|
+
if (readString20(item, "type") !== "function_call_output") {
|
|
27141
27711
|
return null;
|
|
27142
27712
|
}
|
|
27143
27713
|
const output = readResponseItemOutput(item.output);
|
|
@@ -27147,12 +27717,12 @@ function normalizeResponseOutputItemDone(event) {
|
|
|
27147
27717
|
payloadType: "tool.completed",
|
|
27148
27718
|
payload: {
|
|
27149
27719
|
type: "tool.completed",
|
|
27150
|
-
tool_call_id:
|
|
27151
|
-
status:
|
|
27720
|
+
tool_call_id: readString20(item, "call_id") ?? readString20(item, "id"),
|
|
27721
|
+
status: readString20(item, "status") ?? "completed",
|
|
27152
27722
|
output,
|
|
27153
27723
|
content: output,
|
|
27154
27724
|
result: parsedOutput ?? output,
|
|
27155
|
-
response_item_id:
|
|
27725
|
+
response_item_id: readString20(item, "id") ?? void 0
|
|
27156
27726
|
}
|
|
27157
27727
|
};
|
|
27158
27728
|
}
|
|
@@ -27163,7 +27733,7 @@ function normalizeResponseCompleted(event) {
|
|
|
27163
27733
|
payloadType: "run.completed",
|
|
27164
27734
|
payload: {
|
|
27165
27735
|
type: "run.completed",
|
|
27166
|
-
response_id:
|
|
27736
|
+
response_id: readString20(response, "id") ?? readString20(event.payload, "id"),
|
|
27167
27737
|
usage: toRecord18(response.usage),
|
|
27168
27738
|
response
|
|
27169
27739
|
}
|
|
@@ -27177,9 +27747,9 @@ function normalizeResponseFailed(event) {
|
|
|
27177
27747
|
payloadType: "run.failed",
|
|
27178
27748
|
payload: {
|
|
27179
27749
|
type: "run.failed",
|
|
27180
|
-
response_id:
|
|
27750
|
+
response_id: readString20(response, "id") ?? readString20(event.payload, "id"),
|
|
27181
27751
|
error: {
|
|
27182
|
-
message:
|
|
27752
|
+
message: readString20(error, "message") ?? readString20(event.payload, "message") ?? "Hermes run failed"
|
|
27183
27753
|
},
|
|
27184
27754
|
usage: toRecord18(response.usage),
|
|
27185
27755
|
response
|
|
@@ -27206,7 +27776,7 @@ function readErrorMessage4(payload) {
|
|
|
27206
27776
|
return payload.error.trim();
|
|
27207
27777
|
}
|
|
27208
27778
|
const error = toRecord18(payload.error);
|
|
27209
|
-
return
|
|
27779
|
+
return readString20(error, "message") ?? readString20(payload, "message");
|
|
27210
27780
|
}
|
|
27211
27781
|
function readDelta(payload) {
|
|
27212
27782
|
return readText3(payload, "delta") ?? readText3(payload, "text") ?? readText3(payload, "content");
|
|
@@ -27253,7 +27823,7 @@ function readChatCompletionDelta(payload) {
|
|
|
27253
27823
|
}
|
|
27254
27824
|
function readChatCompletionFinishReason(payload) {
|
|
27255
27825
|
const choice = readFirstChoice(payload);
|
|
27256
|
-
return
|
|
27826
|
+
return readString20(choice, "finish_reason") ?? readString20(choice, "finishReason");
|
|
27257
27827
|
}
|
|
27258
27828
|
function readChatCompletionUsage(payload) {
|
|
27259
27829
|
const usage = toRecord18(payload.usage);
|
|
@@ -27293,7 +27863,7 @@ function readAssistantTextFromChoices(payload) {
|
|
|
27293
27863
|
return null;
|
|
27294
27864
|
}
|
|
27295
27865
|
const messages2 = choices.map(toRecord18).map((choice) => toRecord18(choice.message ?? choice.delta)).filter((message) => {
|
|
27296
|
-
const role =
|
|
27866
|
+
const role = readString20(message, "role");
|
|
27297
27867
|
return !role || role === "assistant";
|
|
27298
27868
|
}).map(readResponseMessageText).filter((text) => Boolean(text?.trim()));
|
|
27299
27869
|
return messages2.length > 0 ? messages2.join("\n\n") : null;
|
|
@@ -27309,7 +27879,7 @@ function readInteger3(payload, key) {
|
|
|
27309
27879
|
}
|
|
27310
27880
|
return void 0;
|
|
27311
27881
|
}
|
|
27312
|
-
function
|
|
27882
|
+
function readString20(payload, key) {
|
|
27313
27883
|
const value = payload[key];
|
|
27314
27884
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
27315
27885
|
}
|
|
@@ -27322,8 +27892,8 @@ function readResponseOutputItemText(value) {
|
|
|
27322
27892
|
return value;
|
|
27323
27893
|
}
|
|
27324
27894
|
const item = toRecord18(value);
|
|
27325
|
-
const type =
|
|
27326
|
-
const role =
|
|
27895
|
+
const type = readString20(item, "type");
|
|
27896
|
+
const role = readString20(item, "role");
|
|
27327
27897
|
if (type && type !== "message" && type !== "output_text" && type !== "text") {
|
|
27328
27898
|
return null;
|
|
27329
27899
|
}
|
|
@@ -27349,7 +27919,7 @@ function readResponseContentText(value) {
|
|
|
27349
27919
|
return partValue;
|
|
27350
27920
|
}
|
|
27351
27921
|
const part = toRecord18(partValue);
|
|
27352
|
-
const type =
|
|
27922
|
+
const type = readString20(part, "type");
|
|
27353
27923
|
if (type && !isVisibleResponseTextPart(type)) {
|
|
27354
27924
|
return null;
|
|
27355
27925
|
}
|
|
@@ -27658,6 +28228,11 @@ var ConversationRunLifecycle = class {
|
|
|
27658
28228
|
run.profile ?? "default"
|
|
27659
28229
|
);
|
|
27660
28230
|
const reasoningEffort = reasoningEffortForRun(run);
|
|
28231
|
+
await this.recordRunHermesMessageWatermark({
|
|
28232
|
+
conversationId,
|
|
28233
|
+
runId,
|
|
28234
|
+
phase: "before"
|
|
28235
|
+
});
|
|
27661
28236
|
if (backend === "tui_gateway") {
|
|
27662
28237
|
const rpcRun = await streamTuiGatewayRun({
|
|
27663
28238
|
input: resolvedInput,
|
|
@@ -27873,13 +28448,7 @@ var ConversationRunLifecycle = class {
|
|
|
27873
28448
|
}
|
|
27874
28449
|
} catch (error) {
|
|
27875
28450
|
if (controller.signal.aborted) {
|
|
27876
|
-
await this.
|
|
27877
|
-
conversationId,
|
|
27878
|
-
() => this.cancelRunLocked(conversationId, runId, {
|
|
27879
|
-
abortUpstream: false,
|
|
27880
|
-
reason: "cancelled by app"
|
|
27881
|
-
})
|
|
27882
|
-
);
|
|
28451
|
+
await this.cancelRunAfterAbort(conversationId, runId);
|
|
27883
28452
|
return { shouldDrainQueue: true };
|
|
27884
28453
|
}
|
|
27885
28454
|
if (isTuiGatewaySessionBusyError(error)) {
|
|
@@ -28080,16 +28649,27 @@ var ConversationRunLifecycle = class {
|
|
|
28080
28649
|
}
|
|
28081
28650
|
}
|
|
28082
28651
|
async cancelRun(conversationId, runId, options) {
|
|
28083
|
-
|
|
28652
|
+
const result = await this.deps.withConversationLock(
|
|
28084
28653
|
conversationId,
|
|
28085
28654
|
() => this.cancelRunLocked(conversationId, runId, options)
|
|
28086
28655
|
);
|
|
28656
|
+
await this.recordRunHermesMessageWatermark({
|
|
28657
|
+
conversationId,
|
|
28658
|
+
runId,
|
|
28659
|
+
phase: "after"
|
|
28660
|
+
});
|
|
28661
|
+
return result;
|
|
28087
28662
|
}
|
|
28088
28663
|
async failRun(conversationId, runId, message, source) {
|
|
28089
28664
|
await this.refreshRunHermesCompressionTip(conversationId, runId);
|
|
28665
|
+
const afterWatermark = await this.readRunHermesMessageWatermark(
|
|
28666
|
+
conversationId,
|
|
28667
|
+
runId,
|
|
28668
|
+
"after"
|
|
28669
|
+
);
|
|
28090
28670
|
return this.deps.withConversationLock(
|
|
28091
28671
|
conversationId,
|
|
28092
|
-
() => this.failRunLocked(conversationId, runId, message, source)
|
|
28672
|
+
() => this.failRunLocked(conversationId, runId, message, source, afterWatermark)
|
|
28093
28673
|
);
|
|
28094
28674
|
}
|
|
28095
28675
|
async findConversationIdForRun(runId) {
|
|
@@ -28530,6 +29110,11 @@ var ConversationRunLifecycle = class {
|
|
|
28530
29110
|
reason: "cancelled by app"
|
|
28531
29111
|
})
|
|
28532
29112
|
);
|
|
29113
|
+
await this.recordRunHermesMessageWatermark({
|
|
29114
|
+
conversationId,
|
|
29115
|
+
runId,
|
|
29116
|
+
phase: "after"
|
|
29117
|
+
});
|
|
28533
29118
|
}
|
|
28534
29119
|
async completeCancelledRun(conversationId, runId) {
|
|
28535
29120
|
await this.deps.withConversationLock(
|
|
@@ -28539,6 +29124,11 @@ var ConversationRunLifecycle = class {
|
|
|
28539
29124
|
reason: "cancelled by Hermes"
|
|
28540
29125
|
})
|
|
28541
29126
|
);
|
|
29127
|
+
await this.recordRunHermesMessageWatermark({
|
|
29128
|
+
conversationId,
|
|
29129
|
+
runId,
|
|
29130
|
+
phase: "after"
|
|
29131
|
+
});
|
|
28542
29132
|
}
|
|
28543
29133
|
async recoverRunTerminalEvent(input) {
|
|
28544
29134
|
const deadline = Date.now() + RUN_STATUS_RECOVERY_TIMEOUT_MS;
|
|
@@ -28721,14 +29311,14 @@ var ConversationRunLifecycle = class {
|
|
|
28721
29311
|
(message) => message.id === input.run.trigger_message_id
|
|
28722
29312
|
);
|
|
28723
29313
|
const prefix = guidedInterruptInputPrefix(input.run);
|
|
28724
|
-
if (!userMessage || !userMessage.parts.some(
|
|
29314
|
+
if (!userMessage || !userMessage.parts.some(isVoicePart2)) {
|
|
28725
29315
|
return prefix ? `${prefix}
|
|
28726
29316
|
|
|
28727
29317
|
${input.fallbackInput}` : input.fallbackInput;
|
|
28728
29318
|
}
|
|
28729
29319
|
const content = messageText2(userMessage);
|
|
28730
29320
|
const voiceLines = [];
|
|
28731
|
-
for (const part of userMessage.parts.filter(
|
|
29321
|
+
for (const part of userMessage.parts.filter(isVoicePart2)) {
|
|
28732
29322
|
const audioPath = part.local_path ?? (part.blob ? blobPath(this.deps.paths, part.blob) : "");
|
|
28733
29323
|
const result = await transcribeAudioWithHermesProfile({
|
|
28734
29324
|
audioPath,
|
|
@@ -28738,7 +29328,7 @@ ${input.fallbackInput}` : input.fallbackInput;
|
|
|
28738
29328
|
const label = part.filename ?? part.blob ?? "voice message";
|
|
28739
29329
|
voiceLines.push(`- ${label}: ${result.transcript}`);
|
|
28740
29330
|
}
|
|
28741
|
-
const attachmentLines = userMessage.parts.filter((part) => Boolean(part.blob)).filter((part) => !
|
|
29331
|
+
const attachmentLines = userMessage.parts.filter((part) => Boolean(part.blob)).filter((part) => !isVoicePart2(part)).map((part) => {
|
|
28742
29332
|
const label = part.filename ?? part.blob;
|
|
28743
29333
|
const mime = part.mime ? `, ${part.mime}` : "";
|
|
28744
29334
|
const size = part.size ? `, ${part.size} bytes` : "";
|
|
@@ -28824,6 +29414,47 @@ ${resolved}` : resolved;
|
|
|
28824
29414
|
Object.assign(run, patch);
|
|
28825
29415
|
await this.deps.writeSnapshot(conversationId, snapshot);
|
|
28826
29416
|
}
|
|
29417
|
+
async recordRunHermesMessageWatermark(input) {
|
|
29418
|
+
const point = await this.readRunHermesMessageWatermark(
|
|
29419
|
+
input.conversationId,
|
|
29420
|
+
input.runId,
|
|
29421
|
+
input.phase
|
|
29422
|
+
);
|
|
29423
|
+
if (!point) {
|
|
29424
|
+
return;
|
|
29425
|
+
}
|
|
29426
|
+
await this.deps.withConversationLock(input.conversationId, async () => {
|
|
29427
|
+
const snapshot = await this.deps.readSnapshot(input.conversationId);
|
|
29428
|
+
const run = snapshot.runs.find((item) => item.id === input.runId);
|
|
29429
|
+
if (!run) {
|
|
29430
|
+
return;
|
|
29431
|
+
}
|
|
29432
|
+
applyRunHermesMessageWatermark(run, input.phase, point);
|
|
29433
|
+
await this.deps.writeSnapshot(input.conversationId, snapshot);
|
|
29434
|
+
});
|
|
29435
|
+
}
|
|
29436
|
+
async readRunHermesMessageWatermark(conversationId, runId, phase) {
|
|
29437
|
+
const snapshot = await this.deps.readSnapshot(conversationId).catch(() => null);
|
|
29438
|
+
const run = snapshot?.runs.find((item) => item.id === runId);
|
|
29439
|
+
const sessionId = run?.hermes_session_id?.trim();
|
|
29440
|
+
if (!run || !sessionId) {
|
|
29441
|
+
return null;
|
|
29442
|
+
}
|
|
29443
|
+
return await readHermesMessageWatermark({
|
|
29444
|
+
profileName: run.profile,
|
|
29445
|
+
sessionId
|
|
29446
|
+
}).catch((error) => {
|
|
29447
|
+
void this.deps.logger.debug("hermes_message_watermark_read_failed", {
|
|
29448
|
+
conversation_id: conversationId,
|
|
29449
|
+
run_id: runId,
|
|
29450
|
+
phase,
|
|
29451
|
+
profile: run.profile ?? "default",
|
|
29452
|
+
hermes_session_id: sessionId,
|
|
29453
|
+
error: error instanceof Error ? error.message : String(error)
|
|
29454
|
+
});
|
|
29455
|
+
return null;
|
|
29456
|
+
});
|
|
29457
|
+
}
|
|
28827
29458
|
async updateRunUsageFromEvent(conversationId, runId, event) {
|
|
28828
29459
|
const usage = readUsage(event.payload);
|
|
28829
29460
|
if (!usage) {
|
|
@@ -29217,10 +29848,10 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
29217
29848
|
return goalStatus;
|
|
29218
29849
|
}
|
|
29219
29850
|
async persistGoalStatusUpdate(conversationId, runId, event) {
|
|
29220
|
-
if (
|
|
29851
|
+
if (readString21(event.payload, "kind") !== "goal") {
|
|
29221
29852
|
return null;
|
|
29222
29853
|
}
|
|
29223
|
-
const text =
|
|
29854
|
+
const text = readString21(event.payload, "text") ?? readString21(event.payload, "message") ?? readString21(event.payload, "status") ?? "";
|
|
29224
29855
|
const manifest = await this.deps.readRunnableManifest(conversationId);
|
|
29225
29856
|
const snapshot = await this.deps.readSnapshot(conversationId);
|
|
29226
29857
|
const run = snapshot.runs.find((item) => item.id === runId);
|
|
@@ -29407,7 +30038,7 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
29407
30038
|
}
|
|
29408
30039
|
const textPart = assistant.parts.find((part) => part.type === "text");
|
|
29409
30040
|
const currentText = textPart?.text ?? "";
|
|
29410
|
-
const pendingDeliveryText =
|
|
30041
|
+
const pendingDeliveryText = readString21(
|
|
29411
30042
|
toRecord19(assistant.hermes),
|
|
29412
30043
|
"pending_media_delivery_text"
|
|
29413
30044
|
);
|
|
@@ -29513,7 +30144,7 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
29513
30144
|
}
|
|
29514
30145
|
reasoningDeltaSegmentId(event) {
|
|
29515
30146
|
const payload = event.payload;
|
|
29516
|
-
return
|
|
30147
|
+
return readString21(payload, "segment_id") ?? readString21(payload, "segmentId") ?? readString21(payload, "id") ?? readString21(payload, "tool_call_id") ?? readString21(payload, "tool_id") ?? null;
|
|
29517
30148
|
}
|
|
29518
30149
|
async runRequestsAppDelivery(conversationId, runId) {
|
|
29519
30150
|
const snapshot = await this.deps.readSnapshot(conversationId).catch(() => null);
|
|
@@ -29525,9 +30156,14 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
29525
30156
|
}
|
|
29526
30157
|
async completeRun(conversationId, runId, source) {
|
|
29527
30158
|
await this.refreshRunHermesCompressionTip(conversationId, runId);
|
|
30159
|
+
const afterWatermark = await this.readRunHermesMessageWatermark(
|
|
30160
|
+
conversationId,
|
|
30161
|
+
runId,
|
|
30162
|
+
"after"
|
|
30163
|
+
);
|
|
29528
30164
|
return this.deps.withConversationLock(
|
|
29529
30165
|
conversationId,
|
|
29530
|
-
() => this.completeRunLocked(conversationId, runId, source)
|
|
30166
|
+
() => this.completeRunLocked(conversationId, runId, source, afterWatermark)
|
|
29531
30167
|
);
|
|
29532
30168
|
}
|
|
29533
30169
|
async refreshRunHermesCompressionTip(conversationId, runId) {
|
|
@@ -29564,7 +30200,7 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
29564
30200
|
await this.rememberRunHermesSessionId(conversationId, runId, compressionTip);
|
|
29565
30201
|
return { previousSessionId, nextSessionId: compressionTip };
|
|
29566
30202
|
}
|
|
29567
|
-
async completeRunLocked(conversationId, runId, source) {
|
|
30203
|
+
async completeRunLocked(conversationId, runId, source, afterWatermark) {
|
|
29568
30204
|
let snapshot = await this.deps.readSnapshot(conversationId);
|
|
29569
30205
|
let run = snapshot.runs.find((item) => item.id === runId);
|
|
29570
30206
|
if (!run || run.status !== "running") {
|
|
@@ -29606,6 +30242,9 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
29606
30242
|
if (usage) {
|
|
29607
30243
|
run.usage = mergeRunUsage(run.usage, usage);
|
|
29608
30244
|
}
|
|
30245
|
+
if (afterWatermark) {
|
|
30246
|
+
applyRunHermesMessageWatermark(run, "after", afterWatermark);
|
|
30247
|
+
}
|
|
29609
30248
|
const probeEvent = shouldUseHermesUsageProbe(run.hermes_backend) ? await findHermesUsageProbeEventForRun({
|
|
29610
30249
|
paths: this.deps.paths,
|
|
29611
30250
|
profileName: run.profile,
|
|
@@ -29754,7 +30393,7 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
29754
30393
|
await this.deps.writeManifest(nextManifest);
|
|
29755
30394
|
return goal;
|
|
29756
30395
|
}
|
|
29757
|
-
async failRunLocked(conversationId, runId, message, source) {
|
|
30396
|
+
async failRunLocked(conversationId, runId, message, source, afterWatermark) {
|
|
29758
30397
|
const snapshot = await this.deps.readSnapshot(conversationId).catch(() => null);
|
|
29759
30398
|
if (!snapshot) {
|
|
29760
30399
|
return;
|
|
@@ -29777,6 +30416,9 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
29777
30416
|
if (usage) {
|
|
29778
30417
|
run.usage = mergeRunUsage(run.usage, usage);
|
|
29779
30418
|
}
|
|
30419
|
+
if (afterWatermark) {
|
|
30420
|
+
applyRunHermesMessageWatermark(run, "after", afterWatermark);
|
|
30421
|
+
}
|
|
29780
30422
|
const assistant = snapshot.messages.find(
|
|
29781
30423
|
(item) => item.id === run.assistant_message_id
|
|
29782
30424
|
);
|
|
@@ -30140,7 +30782,7 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
30140
30782
|
includeDisabled: true
|
|
30141
30783
|
});
|
|
30142
30784
|
return new Set(
|
|
30143
|
-
jobs.map((job) =>
|
|
30785
|
+
jobs.map((job) => readString21(job, "id") ?? readString21(job, "job_id")).filter((id) => Boolean(id))
|
|
30144
30786
|
);
|
|
30145
30787
|
}
|
|
30146
30788
|
async bindNewCronJobsCreatedByRun(input) {
|
|
@@ -30240,7 +30882,7 @@ async function readdirWithDirs(directory) {
|
|
|
30240
30882
|
throw error;
|
|
30241
30883
|
});
|
|
30242
30884
|
}
|
|
30243
|
-
function
|
|
30885
|
+
function readString21(payload, key) {
|
|
30244
30886
|
const value = payload[key];
|
|
30245
30887
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
30246
30888
|
}
|
|
@@ -30331,11 +30973,11 @@ function contextCompressionGeneration(message) {
|
|
|
30331
30973
|
return typeof generation === "number" && Number.isFinite(generation) ? Math.max(0, Math.floor(generation)) : null;
|
|
30332
30974
|
}
|
|
30333
30975
|
function readPreviousSessionId(payload) {
|
|
30334
|
-
return
|
|
30976
|
+
return readString21(payload, "old_session_id") ?? readString21(payload, "oldSessionId") ?? readString21(payload, "previous_session_id") ?? readString21(payload, "previousSessionId");
|
|
30335
30977
|
}
|
|
30336
30978
|
function readNextSessionId(payload) {
|
|
30337
30979
|
const info = toRecord19(payload.info);
|
|
30338
|
-
return
|
|
30980
|
+
return readString21(payload, "session_key") ?? readString21(payload, "sessionKey") ?? readString21(payload, "stored_session_id") ?? readString21(payload, "storedSessionId") ?? readString21(payload, "session_id") ?? readString21(payload, "sessionId") ?? readString21(info, "session_key") ?? readString21(info, "sessionKey");
|
|
30339
30981
|
}
|
|
30340
30982
|
function eventPayloadWithLanguage(payload, language) {
|
|
30341
30983
|
return { ...payload, language };
|
|
@@ -30427,13 +31069,13 @@ function isFileSearchCompletion(payloadType, payload) {
|
|
|
30427
31069
|
const toolCall = toRecord19(payload.tool_call ?? payload.toolCall);
|
|
30428
31070
|
const fn = toRecord19(toolCall.function ?? payload.function);
|
|
30429
31071
|
const candidates = [
|
|
30430
|
-
|
|
30431
|
-
|
|
30432
|
-
|
|
30433
|
-
|
|
30434
|
-
|
|
30435
|
-
|
|
30436
|
-
|
|
31072
|
+
readString21(payload, "tool_name"),
|
|
31073
|
+
readString21(payload, "toolName"),
|
|
31074
|
+
readString21(payload, "name"),
|
|
31075
|
+
readString21(payload, "tool"),
|
|
31076
|
+
readString21(tool, "name"),
|
|
31077
|
+
readString21(toolCall, "name"),
|
|
31078
|
+
readString21(fn, "name")
|
|
30437
31079
|
].filter((value) => Boolean(value)).map(normalizeToolName);
|
|
30438
31080
|
return candidates.some(
|
|
30439
31081
|
(name) => [
|
|
@@ -30470,7 +31112,7 @@ function messageRequestsAppDelivery(text) {
|
|
|
30470
31112
|
const hasEnglishDeliveryAction = /\b(send|share|attach|deliver|display)\b/u.test(lower) || /\bshow\s+me\b/u.test(lower);
|
|
30471
31113
|
return hasEnglishDeliverable && hasEnglishDeliveryAction;
|
|
30472
31114
|
}
|
|
30473
|
-
function
|
|
31115
|
+
function isVoicePart2(part) {
|
|
30474
31116
|
return part.kind === "voice" || part.is_voice_note === true;
|
|
30475
31117
|
}
|
|
30476
31118
|
function normalizeToolName(value) {
|
|
@@ -30773,13 +31415,13 @@ function readResponseId(payload) {
|
|
|
30773
31415
|
return null;
|
|
30774
31416
|
}
|
|
30775
31417
|
const response = toRecord19(payload.response);
|
|
30776
|
-
return
|
|
31418
|
+
return readString21(payload, "response_id") ?? readString21(response, "id");
|
|
30777
31419
|
}
|
|
30778
31420
|
function readRunId(payload) {
|
|
30779
31421
|
if (!payload) {
|
|
30780
31422
|
return null;
|
|
30781
31423
|
}
|
|
30782
|
-
return
|
|
31424
|
+
return readString21(payload, "run_id") ?? readString21(payload, "runId");
|
|
30783
31425
|
}
|
|
30784
31426
|
function isCompletedRunStatus(status) {
|
|
30785
31427
|
return status === "completed" || status === "complete" || status === "succeeded" || status === "success" || status === "done";
|
|
@@ -30798,7 +31440,7 @@ function readStatusErrorMessage(value) {
|
|
|
30798
31440
|
return value.trim();
|
|
30799
31441
|
}
|
|
30800
31442
|
const record = toRecord19(value);
|
|
30801
|
-
return
|
|
31443
|
+
return readString21(record, "message") ?? readString21(record, "error");
|
|
30802
31444
|
}
|
|
30803
31445
|
function formatUnknownErrorMessage(error) {
|
|
30804
31446
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -30837,6 +31479,12 @@ function sanitizeLiveSessionForEvent(liveSession) {
|
|
|
30837
31479
|
...liveSession.inflight ? { inflight: liveSession.inflight } : {}
|
|
30838
31480
|
};
|
|
30839
31481
|
}
|
|
31482
|
+
function applyRunHermesMessageWatermark(run, phase, point) {
|
|
31483
|
+
run.hermes_message_watermark = {
|
|
31484
|
+
...run.hermes_message_watermark ?? {},
|
|
31485
|
+
[phase]: point
|
|
31486
|
+
};
|
|
31487
|
+
}
|
|
30840
31488
|
function previewText2(message) {
|
|
30841
31489
|
if (!message) {
|
|
30842
31490
|
return null;
|
|
@@ -31686,7 +32334,7 @@ var ConversationService = class {
|
|
|
31686
32334
|
);
|
|
31687
32335
|
}
|
|
31688
32336
|
const shouldApplyModelConfig = configuredModel != null && !runtimeMatchesConfiguredModel(currentRuntime, configuredModel);
|
|
31689
|
-
const modelConfigToApply =
|
|
32337
|
+
const modelConfigToApply = configuredModel ?? void 0;
|
|
31690
32338
|
const sessionConfig = await setTuiGatewaySessionModelConfig({
|
|
31691
32339
|
hermesSessionId: manifest.hermes_session_id,
|
|
31692
32340
|
profileName: currentRuntime.profile.name,
|
|
@@ -32561,7 +33209,7 @@ var ConversationService = class {
|
|
|
32561
33209
|
}
|
|
32562
33210
|
}
|
|
32563
33211
|
hermesArchiveStateSyncMarkerPath() {
|
|
32564
|
-
return
|
|
33212
|
+
return path28.join(this.paths.indexesDir, "hermes-archive-state-sync.json");
|
|
32565
33213
|
}
|
|
32566
33214
|
prepareClearAllConversationPlan(targetStatus) {
|
|
32567
33215
|
return this.maintenance.prepareClearAllConversationPlan(targetStatus);
|
|
@@ -32843,7 +33491,7 @@ function liveActivityTodoProgressForEvent(event) {
|
|
|
32843
33491
|
if (todos) {
|
|
32844
33492
|
const totalCount2 = todos.length;
|
|
32845
33493
|
const doneCount2 = todos.filter((item) => {
|
|
32846
|
-
const status =
|
|
33494
|
+
const status = readString22(item, "status")?.toLowerCase();
|
|
32847
33495
|
return status === "completed" || status === "cancelled" || status === "canceled";
|
|
32848
33496
|
}).length;
|
|
32849
33497
|
return {
|
|
@@ -32892,11 +33540,11 @@ function liveActivityTitleFromConversationUpdate(event) {
|
|
|
32892
33540
|
if (event.type.toLowerCase() !== "conversation.updated") {
|
|
32893
33541
|
return void 0;
|
|
32894
33542
|
}
|
|
32895
|
-
const titleSource =
|
|
33543
|
+
const titleSource = readString22(event.payload, "title_source");
|
|
32896
33544
|
if (titleSource === "default" || titleSource === "temporary_fallback") {
|
|
32897
33545
|
return null;
|
|
32898
33546
|
}
|
|
32899
|
-
const title =
|
|
33547
|
+
const title = readString22(event.payload, "title");
|
|
32900
33548
|
return title ? truncateLiveActivityTitle(title, 24) : null;
|
|
32901
33549
|
}
|
|
32902
33550
|
function liveActivityTitleFromManifest(manifest) {
|
|
@@ -32936,7 +33584,7 @@ function isConversationTitleUpdateEvent(event) {
|
|
|
32936
33584
|
if (event.type.toLowerCase() !== "conversation.updated") {
|
|
32937
33585
|
return false;
|
|
32938
33586
|
}
|
|
32939
|
-
return Boolean(
|
|
33587
|
+
return Boolean(readString22(event.payload, "title")?.trim());
|
|
32940
33588
|
}
|
|
32941
33589
|
function resolveLiveActivityTarget(input) {
|
|
32942
33590
|
if (input.run?.kind === "compression") {
|
|
@@ -32958,7 +33606,7 @@ function liveActivityPhaseForEvent(event, run, contextOperation) {
|
|
|
32958
33606
|
}
|
|
32959
33607
|
if (type === "conversation.goal.updated") {
|
|
32960
33608
|
const goal = readRecord2(event.payload).goal;
|
|
32961
|
-
const status =
|
|
33609
|
+
const status = readString22(goal, "status");
|
|
32962
33610
|
return status === "paused" ? "goal_paused" : "goal_running";
|
|
32963
33611
|
}
|
|
32964
33612
|
if (isConversationTitleUpdateEvent(event)) {
|
|
@@ -33091,7 +33739,7 @@ function readContextCompressionOperation(payload) {
|
|
|
33091
33739
|
if (!operation || typeof operation !== "object") {
|
|
33092
33740
|
return null;
|
|
33093
33741
|
}
|
|
33094
|
-
const operationId =
|
|
33742
|
+
const operationId = readString22(operation, "operation_id");
|
|
33095
33743
|
if (!operationId) {
|
|
33096
33744
|
return null;
|
|
33097
33745
|
}
|
|
@@ -33099,19 +33747,19 @@ function readContextCompressionOperation(payload) {
|
|
|
33099
33747
|
return {
|
|
33100
33748
|
operation_id: operationId,
|
|
33101
33749
|
generation: typeof record.generation === "number" ? record.generation : 0,
|
|
33102
|
-
status:
|
|
33103
|
-
started_at:
|
|
33104
|
-
source:
|
|
33750
|
+
status: readString22(record, "status") === "completed" ? "completed" : readString22(record, "status") === "failed" ? "failed" : readString22(record, "status") === "timed_out" ? "timed_out" : readString22(record, "status") === "cancelled" ? "cancelled" : "compressing",
|
|
33751
|
+
started_at: readString22(record, "started_at") ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
33752
|
+
source: readString22(record, "source") === "manual" ? "manual" : "auto"
|
|
33105
33753
|
};
|
|
33106
33754
|
}
|
|
33107
33755
|
function readToolName3(payload) {
|
|
33108
33756
|
const record = readRecord2(payload);
|
|
33109
|
-
return
|
|
33757
|
+
return readString22(record, "tool_name") ?? readString22(record, "tool") ?? readString22(record, "name") ?? readString22(readRecord2(record.tool), "name");
|
|
33110
33758
|
}
|
|
33111
33759
|
function readRecord2(value) {
|
|
33112
33760
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
|
|
33113
33761
|
}
|
|
33114
|
-
function
|
|
33762
|
+
function readString22(value, key) {
|
|
33115
33763
|
const raw = readRecord2(value)[key];
|
|
33116
33764
|
return typeof raw === "string" && raw.trim() ? raw.trim() : null;
|
|
33117
33765
|
}
|
|
@@ -33631,7 +34279,7 @@ async function readRawBody(request, maxBytes) {
|
|
|
33631
34279
|
}
|
|
33632
34280
|
return Buffer.concat(chunks);
|
|
33633
34281
|
}
|
|
33634
|
-
function
|
|
34282
|
+
function readString23(body, key) {
|
|
33635
34283
|
const value = body[key];
|
|
33636
34284
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
33637
34285
|
}
|
|
@@ -33666,7 +34314,7 @@ function readSupportedLanguage(value) {
|
|
|
33666
34314
|
return null;
|
|
33667
34315
|
}
|
|
33668
34316
|
function readOptionalProfileName(body) {
|
|
33669
|
-
return
|
|
34317
|
+
return readString23(body, "profile") ?? readString23(body, "profile_name") ?? readString23(body, "profileName") ?? void 0;
|
|
33670
34318
|
}
|
|
33671
34319
|
function readStringArray(body, ...keys) {
|
|
33672
34320
|
for (const key of keys) {
|
|
@@ -34024,7 +34672,8 @@ function registerConversationRoutes(router, options) {
|
|
|
34024
34672
|
const result = await conversations.listConversationPage({
|
|
34025
34673
|
limit: readLimit(ctx.query.limit),
|
|
34026
34674
|
cursor,
|
|
34027
|
-
workspace: readConversationWorkspaceFilter(ctx.query)
|
|
34675
|
+
workspace: readConversationWorkspaceFilter(ctx.query),
|
|
34676
|
+
category: readConversationCategoryFilter(ctx.query)
|
|
34028
34677
|
});
|
|
34029
34678
|
const localized = localizeConversationListPage(result, language);
|
|
34030
34679
|
ctx.body = {
|
|
@@ -34086,7 +34735,7 @@ function registerConversationRoutes(router, options) {
|
|
|
34086
34735
|
const language = readPreferredLanguage(ctx);
|
|
34087
34736
|
const body = await readJsonBody(ctx.req);
|
|
34088
34737
|
ctx.status = 201;
|
|
34089
|
-
const rawReasoningEffort =
|
|
34738
|
+
const rawReasoningEffort = readString23(body, "reasoning_effort") ?? readString23(body, "reasoningEffort") ?? readString23(body, "default_reasoning_effort") ?? readString23(body, "defaultReasoningEffort");
|
|
34090
34739
|
const reasoningEffort = normalizeReasoningEffort(rawReasoningEffort);
|
|
34091
34740
|
if (rawReasoningEffort && !reasoningEffort) {
|
|
34092
34741
|
throw new LinkHttpError(
|
|
@@ -34099,15 +34748,15 @@ function registerConversationRoutes(router, options) {
|
|
|
34099
34748
|
ok: true,
|
|
34100
34749
|
conversation: localizeConversationSummary(
|
|
34101
34750
|
await conversations.createConversation({
|
|
34102
|
-
title:
|
|
34751
|
+
title: readString23(body, "title") ?? void 0,
|
|
34103
34752
|
profileName: readOptionalProfileName(body),
|
|
34104
34753
|
accountId: auth.accountId,
|
|
34105
34754
|
appInstanceId: auth.appInstanceId,
|
|
34106
34755
|
workspaceId: readConversationWorkspaceId(body),
|
|
34107
|
-
modelId:
|
|
34108
|
-
modelProvider:
|
|
34109
|
-
modelBaseUrl:
|
|
34110
|
-
modelApiMode:
|
|
34756
|
+
modelId: readString23(body, "model_id") ?? readString23(body, "modelId") ?? readString23(body, "model") ?? void 0,
|
|
34757
|
+
modelProvider: readString23(body, "model_provider") ?? readString23(body, "modelProvider") ?? readString23(body, "provider") ?? void 0,
|
|
34758
|
+
modelBaseUrl: readString23(body, "model_base_url") ?? readString23(body, "modelBaseUrl") ?? readString23(body, "base_url") ?? readString23(body, "baseUrl") ?? void 0,
|
|
34759
|
+
modelApiMode: readString23(body, "model_api_mode") ?? readString23(body, "modelApiMode") ?? readString23(body, "api_mode") ?? readString23(body, "apiMode") ?? void 0,
|
|
34111
34760
|
reasoningEffort
|
|
34112
34761
|
}),
|
|
34113
34762
|
language
|
|
@@ -34185,9 +34834,9 @@ function registerConversationRoutes(router, options) {
|
|
|
34185
34834
|
const auth = await authenticateRequest(ctx, paths);
|
|
34186
34835
|
const language = readPreferredLanguage(ctx);
|
|
34187
34836
|
const body = await readJsonBody(ctx.req);
|
|
34188
|
-
const content =
|
|
34837
|
+
const content = readString23(body, "content") ?? readString23(body, "text") ?? readString23(body, "input") ?? "";
|
|
34189
34838
|
const attachments = readMessageAttachments(body.attachments ?? body.blobs);
|
|
34190
|
-
const mode =
|
|
34839
|
+
const mode = readString23(body, "mode") ?? readString23(body, "send_mode");
|
|
34191
34840
|
if (mode && mode !== "message" && mode !== "goal") {
|
|
34192
34841
|
throw new LinkHttpError(
|
|
34193
34842
|
400,
|
|
@@ -34210,7 +34859,7 @@ function registerConversationRoutes(router, options) {
|
|
|
34210
34859
|
conversationId: ctx.params.conversationId,
|
|
34211
34860
|
content,
|
|
34212
34861
|
attachments,
|
|
34213
|
-
clientMessageId:
|
|
34862
|
+
clientMessageId: readString23(body, "client_message_id") ?? readString23(body, "clientMessageId") ?? void 0,
|
|
34214
34863
|
idempotencyKey: readHeader(ctx, "idempotency-key") ?? void 0,
|
|
34215
34864
|
profileName: readOptionalProfileName(body),
|
|
34216
34865
|
mode: mode === "goal" ? "goal" : "message",
|
|
@@ -34277,8 +34926,8 @@ function registerConversationRoutes(router, options) {
|
|
|
34277
34926
|
...localizeConversationResult(
|
|
34278
34927
|
await conversations.startContextCompression({
|
|
34279
34928
|
conversationId: ctx.params.conversationId,
|
|
34280
|
-
focus:
|
|
34281
|
-
clientOperationId:
|
|
34929
|
+
focus: readString23(body, "focus") ?? readString23(body, "focus_topic") ?? readString23(body, "focusTopic") ?? void 0,
|
|
34930
|
+
clientOperationId: readString23(body, "client_operation_id") ?? readString23(body, "clientOperationId") ?? readHeader(ctx, "idempotency-key") ?? void 0,
|
|
34282
34931
|
createUserMessage: false,
|
|
34283
34932
|
accountId: auth.accountId,
|
|
34284
34933
|
appInstanceId: auth.appInstanceId,
|
|
@@ -34292,11 +34941,11 @@ function registerConversationRoutes(router, options) {
|
|
|
34292
34941
|
router.patch("/api/v1/conversations/:conversationId/model", async (ctx) => {
|
|
34293
34942
|
await authenticateRequest(ctx, paths);
|
|
34294
34943
|
const body = await readJsonBody(ctx.req);
|
|
34295
|
-
const modelId =
|
|
34296
|
-
const modelProvider =
|
|
34297
|
-
const modelBaseUrl =
|
|
34298
|
-
const modelApiMode =
|
|
34299
|
-
const rawReasoningEffort =
|
|
34944
|
+
const modelId = readString23(body, "model_id") ?? readString23(body, "modelId") ?? readString23(body, "model");
|
|
34945
|
+
const modelProvider = readString23(body, "model_provider") ?? readString23(body, "modelProvider") ?? readString23(body, "provider") ?? void 0;
|
|
34946
|
+
const modelBaseUrl = readString23(body, "model_base_url") ?? readString23(body, "modelBaseUrl") ?? readString23(body, "base_url") ?? readString23(body, "baseUrl") ?? void 0;
|
|
34947
|
+
const modelApiMode = readString23(body, "model_api_mode") ?? readString23(body, "modelApiMode") ?? readString23(body, "api_mode") ?? readString23(body, "apiMode") ?? void 0;
|
|
34948
|
+
const rawReasoningEffort = readString23(body, "reasoning_effort") ?? readString23(body, "reasoningEffort") ?? readString23(body, "default_reasoning_effort") ?? readString23(body, "defaultReasoningEffort");
|
|
34300
34949
|
const reasoningEffort = normalizeReasoningEffort(rawReasoningEffort);
|
|
34301
34950
|
if (rawReasoningEffort && !reasoningEffort) {
|
|
34302
34951
|
throw new LinkHttpError(
|
|
@@ -34346,7 +34995,7 @@ function registerConversationRoutes(router, options) {
|
|
|
34346
34995
|
await authenticateRequest(ctx, paths);
|
|
34347
34996
|
const language = readPreferredLanguage(ctx);
|
|
34348
34997
|
const body = await readJsonBody(ctx.req);
|
|
34349
|
-
const title =
|
|
34998
|
+
const title = readString23(body, "title") ?? readString23(body, "name") ?? readString23(body, "display_name");
|
|
34350
34999
|
if (!title) {
|
|
34351
35000
|
throw new LinkHttpError(400, "title_required", "title is required");
|
|
34352
35001
|
}
|
|
@@ -34538,7 +35187,7 @@ function registerConversationRoutes(router, options) {
|
|
|
34538
35187
|
async (ctx) => {
|
|
34539
35188
|
await authenticateRequest(ctx, paths);
|
|
34540
35189
|
const body = await readJsonBody(ctx.req);
|
|
34541
|
-
const scope =
|
|
35190
|
+
const scope = readString23(body, "scope") ?? "always";
|
|
34542
35191
|
ctx.body = {
|
|
34543
35192
|
ok: true,
|
|
34544
35193
|
...await conversations.resolveApproval({
|
|
@@ -34588,7 +35237,7 @@ function registerConversationRoutes(router, options) {
|
|
|
34588
35237
|
conversationId: ctx.params.conversationId,
|
|
34589
35238
|
requestId: ctx.params.requestId,
|
|
34590
35239
|
kind,
|
|
34591
|
-
answer:
|
|
35240
|
+
answer: readString23(body, "answer") ?? void 0,
|
|
34592
35241
|
password: readRawString(body, "password"),
|
|
34593
35242
|
value: readRawString(body, "value")
|
|
34594
35243
|
})
|
|
@@ -34755,12 +35404,27 @@ function readConversationWorkspaceFilter(query) {
|
|
|
34755
35404
|
}
|
|
34756
35405
|
return { kind: "workspace", workspaceId: workspace };
|
|
34757
35406
|
}
|
|
35407
|
+
function readConversationCategoryFilter(query) {
|
|
35408
|
+
const category = readQueryString(query.category) ?? readQueryString(query.conversation_category) ?? readQueryString(query.conversationCategory);
|
|
35409
|
+
const normalized = category?.trim().toLowerCase();
|
|
35410
|
+
if (!normalized || normalized === "all") {
|
|
35411
|
+
return "all";
|
|
35412
|
+
}
|
|
35413
|
+
if (normalized === "chat" || normalized === "cron") {
|
|
35414
|
+
return normalized;
|
|
35415
|
+
}
|
|
35416
|
+
throw new LinkHttpError(
|
|
35417
|
+
400,
|
|
35418
|
+
"conversation_category_invalid",
|
|
35419
|
+
"conversation category must be all, chat or cron"
|
|
35420
|
+
);
|
|
35421
|
+
}
|
|
34758
35422
|
function readConversationWorkspaceId(body) {
|
|
34759
35423
|
if (Object.prototype.hasOwnProperty.call(body, "workspace_id") || Object.prototype.hasOwnProperty.call(body, "workspaceId")) {
|
|
34760
|
-
return
|
|
35424
|
+
return readString23(body, "workspace_id") ?? readString23(body, "workspaceId");
|
|
34761
35425
|
}
|
|
34762
35426
|
if (Object.prototype.hasOwnProperty.call(body, "workspace")) {
|
|
34763
|
-
return
|
|
35427
|
+
return readString23(body, "workspace");
|
|
34764
35428
|
}
|
|
34765
35429
|
return void 0;
|
|
34766
35430
|
}
|
|
@@ -34854,7 +35518,7 @@ function resolveConversationEventCursor(input) {
|
|
|
34854
35518
|
return Math.max(queryAfter, headerAfter);
|
|
34855
35519
|
}
|
|
34856
35520
|
function readConversationClearPlanTargetStatus(body) {
|
|
34857
|
-
const raw =
|
|
35521
|
+
const raw = readString23(body, "target_status") ?? readString23(body, "targetStatus") ?? "active";
|
|
34858
35522
|
if (raw === "active" || raw === "archived") {
|
|
34859
35523
|
return raw;
|
|
34860
35524
|
}
|
|
@@ -34865,7 +35529,7 @@ function readConversationClearPlanTargetStatus(body) {
|
|
|
34865
35529
|
);
|
|
34866
35530
|
}
|
|
34867
35531
|
function readInputRequestKind2(body) {
|
|
34868
|
-
const kind =
|
|
35532
|
+
const kind = readString23(body, "kind") ?? readString23(body, "type");
|
|
34869
35533
|
if (kind === "clarify" || kind === "sudo" || kind === "secret") {
|
|
34870
35534
|
return kind;
|
|
34871
35535
|
}
|
|
@@ -34995,11 +35659,11 @@ function isSseRequestContext(ctx) {
|
|
|
34995
35659
|
}
|
|
34996
35660
|
return isSseRequestPath(ctx.path) || isActiveSseSocket(ctx.req.socket);
|
|
34997
35661
|
}
|
|
34998
|
-
function isSseRequestPath(
|
|
34999
|
-
if (!
|
|
35662
|
+
function isSseRequestPath(path39) {
|
|
35663
|
+
if (!path39) {
|
|
35000
35664
|
return false;
|
|
35001
35665
|
}
|
|
35002
|
-
return
|
|
35666
|
+
return path39 === "/api/v1/conversations/events" || path39 === "/api/v1/profile-creation/events" || path39 === "/api/v1/hermes/update/events" || path39 === "/api/v1/link/update/events" || /^\/api\/v1\/conversations\/[^/]+\/events$/u.test(path39) || /^\/api\/v1\/runs\/[^/]+\/events$/u.test(path39);
|
|
35003
35667
|
}
|
|
35004
35668
|
function isExpectedClientDisconnectError2(error, options = {}) {
|
|
35005
35669
|
if (!(error instanceof Error)) {
|
|
@@ -35263,7 +35927,7 @@ function toHermesCronJobInput(input) {
|
|
|
35263
35927
|
};
|
|
35264
35928
|
}
|
|
35265
35929
|
async function bindAndDecorateCronJobForHermesLink(input) {
|
|
35266
|
-
const jobId =
|
|
35930
|
+
const jobId = readString23(input.job, "id") ?? readString23(input.job, "job_id");
|
|
35267
35931
|
if (!jobId) {
|
|
35268
35932
|
return input.job;
|
|
35269
35933
|
}
|
|
@@ -35282,9 +35946,9 @@ async function bindAndDecorateCronJobForHermesLink(input) {
|
|
|
35282
35946
|
}
|
|
35283
35947
|
function readCronJobCreateInput(body) {
|
|
35284
35948
|
const input = {};
|
|
35285
|
-
const name =
|
|
35286
|
-
const prompt =
|
|
35287
|
-
const schedule =
|
|
35949
|
+
const name = readString23(body, "name") ?? readString23(body, "title");
|
|
35950
|
+
const prompt = readString23(body, "prompt") ?? readString23(body, "description") ?? readString23(body, "task");
|
|
35951
|
+
const schedule = readString23(body, "schedule");
|
|
35288
35952
|
if (!name) {
|
|
35289
35953
|
throw new LinkHttpError(400, "cron_job_name_required", "name is required");
|
|
35290
35954
|
}
|
|
@@ -35305,7 +35969,7 @@ function readCronJobCreateInput(body) {
|
|
|
35305
35969
|
input.name = name;
|
|
35306
35970
|
input.prompt = prompt;
|
|
35307
35971
|
input.schedule = schedule;
|
|
35308
|
-
input.deliver =
|
|
35972
|
+
input.deliver = readString23(body, "deliver") ?? HERMES_LINK_CRON_DELIVER;
|
|
35309
35973
|
const skills = readOptionalCronSkills(body);
|
|
35310
35974
|
if (skills) {
|
|
35311
35975
|
input.skills = skills;
|
|
@@ -35438,7 +36102,7 @@ import { createHash as createHash11 } from "crypto";
|
|
|
35438
36102
|
// src/model-catalog/catalog.ts
|
|
35439
36103
|
import { randomInt } from "crypto";
|
|
35440
36104
|
import { mkdir as mkdir12 } from "fs/promises";
|
|
35441
|
-
import
|
|
36105
|
+
import path29 from "path";
|
|
35442
36106
|
import { fileURLToPath } from "url";
|
|
35443
36107
|
var MODEL_CATALOG_CACHE_VERSION = 1;
|
|
35444
36108
|
var MODEL_CATALOG_FETCH_TIMEOUT_MS = 1e4;
|
|
@@ -35642,7 +36306,7 @@ async function readCachedCatalogFile(paths) {
|
|
|
35642
36306
|
return cached;
|
|
35643
36307
|
}
|
|
35644
36308
|
async function writeCachedCatalog(paths, value) {
|
|
35645
|
-
await mkdir12(
|
|
36309
|
+
await mkdir12(path29.dirname(modelCatalogCachePath(paths)), {
|
|
35646
36310
|
recursive: true,
|
|
35647
36311
|
mode: 448
|
|
35648
36312
|
});
|
|
@@ -35658,7 +36322,7 @@ async function readFallbackCatalog() {
|
|
|
35658
36322
|
throw new Error("model capability fallback catalog was not found");
|
|
35659
36323
|
}
|
|
35660
36324
|
function modelCatalogCachePath(paths) {
|
|
35661
|
-
return
|
|
36325
|
+
return path29.join(paths.homeDir, "model-capabilities", "catalog-cache.json");
|
|
35662
36326
|
}
|
|
35663
36327
|
function normalizeModelCapabilityCatalog(value) {
|
|
35664
36328
|
if (!value || typeof value !== "object") {
|
|
@@ -35669,7 +36333,7 @@ function normalizeModelCapabilityCatalog(value) {
|
|
|
35669
36333
|
const models = rawModels.map(normalizeModelCapabilityEntry).filter((entry) => entry !== null);
|
|
35670
36334
|
return {
|
|
35671
36335
|
schemaVersion: readPositiveInteger3(record.schemaVersion) ?? 1,
|
|
35672
|
-
updatedAt:
|
|
36336
|
+
updatedAt: readString24(record.updatedAt),
|
|
35673
36337
|
models
|
|
35674
36338
|
};
|
|
35675
36339
|
}
|
|
@@ -35678,7 +36342,7 @@ function normalizeModelCapabilityEntry(value) {
|
|
|
35678
36342
|
return null;
|
|
35679
36343
|
}
|
|
35680
36344
|
const record = value;
|
|
35681
|
-
const canonicalId =
|
|
36345
|
+
const canonicalId = readString24(record.canonicalId) ?? readString24(record.canonical_id) ?? readString24(record.id);
|
|
35682
36346
|
if (!canonicalId) {
|
|
35683
36347
|
return null;
|
|
35684
36348
|
}
|
|
@@ -35706,12 +36370,12 @@ function normalizeModelCapabilityEntry(value) {
|
|
|
35706
36370
|
outputModalities: readStringArray2(
|
|
35707
36371
|
record.outputModalities ?? record.output_modalities
|
|
35708
36372
|
),
|
|
35709
|
-
source:
|
|
35710
|
-
updatedAt:
|
|
35711
|
-
notes:
|
|
36373
|
+
source: readString24(record.source),
|
|
36374
|
+
updatedAt: readString24(record.updatedAt ?? record.updated_at),
|
|
36375
|
+
notes: readString24(record.notes)
|
|
35712
36376
|
};
|
|
35713
36377
|
}
|
|
35714
|
-
function
|
|
36378
|
+
function readString24(value) {
|
|
35715
36379
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
35716
36380
|
}
|
|
35717
36381
|
function readStringArray2(value) {
|
|
@@ -35721,7 +36385,7 @@ function readStringArray2(value) {
|
|
|
35721
36385
|
const seen = /* @__PURE__ */ new Set();
|
|
35722
36386
|
const values = [];
|
|
35723
36387
|
for (const item of value) {
|
|
35724
|
-
const text =
|
|
36388
|
+
const text = readString24(item);
|
|
35725
36389
|
if (!text || seen.has(text)) {
|
|
35726
36390
|
continue;
|
|
35727
36391
|
}
|
|
@@ -35738,7 +36402,7 @@ function readPositiveInteger3(value) {
|
|
|
35738
36402
|
return Math.floor(number);
|
|
35739
36403
|
}
|
|
35740
36404
|
function readReasoningSupportPolicy(value) {
|
|
35741
|
-
const normalized =
|
|
36405
|
+
const normalized = readString24(value)?.toLowerCase();
|
|
35742
36406
|
if (!normalized || normalized === "unknown" || normalized === "auto") {
|
|
35743
36407
|
return null;
|
|
35744
36408
|
}
|
|
@@ -35769,7 +36433,7 @@ function readNullableBoolean(value) {
|
|
|
35769
36433
|
if (typeof value === "boolean") {
|
|
35770
36434
|
return value;
|
|
35771
36435
|
}
|
|
35772
|
-
const normalized =
|
|
36436
|
+
const normalized = readString24(value)?.toLowerCase();
|
|
35773
36437
|
if (!normalized) {
|
|
35774
36438
|
return null;
|
|
35775
36439
|
}
|
|
@@ -36918,8 +37582,8 @@ function normalizeUrlForIdentity(value) {
|
|
|
36918
37582
|
return value.trim().replace(/\/+$/u, "").toLowerCase();
|
|
36919
37583
|
}
|
|
36920
37584
|
function readModelProviderConfigInput(body) {
|
|
36921
|
-
const providerName =
|
|
36922
|
-
const baseUrl =
|
|
37585
|
+
const providerName = readString23(body, "display_name") ?? readString23(body, "displayName") ?? readString23(body, "provider_name") ?? readString23(body, "providerName") ?? readString23(body, "name");
|
|
37586
|
+
const baseUrl = readString23(body, "base_url") ?? readString23(body, "baseUrl");
|
|
36923
37587
|
if (!providerName || !baseUrl) {
|
|
36924
37588
|
throw new LinkHttpError(
|
|
36925
37589
|
400,
|
|
@@ -36930,15 +37594,15 @@ function readModelProviderConfigInput(body) {
|
|
|
36930
37594
|
return {
|
|
36931
37595
|
providerName,
|
|
36932
37596
|
baseUrl,
|
|
36933
|
-
apiMode:
|
|
36934
|
-
keyEnv:
|
|
36935
|
-
apiKey:
|
|
37597
|
+
apiMode: readString23(body, "api_mode") ?? readString23(body, "apiMode") ?? readString23(body, "transport") ?? void 0,
|
|
37598
|
+
keyEnv: readString23(body, "key_env") ?? readString23(body, "keyEnv") ?? void 0,
|
|
37599
|
+
apiKey: readString23(body, "api_key") ?? readString23(body, "apiKey") ?? void 0
|
|
36936
37600
|
};
|
|
36937
37601
|
}
|
|
36938
37602
|
function readModelConfigInput(body) {
|
|
36939
|
-
const id =
|
|
36940
|
-
const provider =
|
|
36941
|
-
const baseUrl =
|
|
37603
|
+
const id = readString23(body, "id") ?? readString23(body, "model_id") ?? readString23(body, "modelId");
|
|
37604
|
+
const provider = readString23(body, "provider") ?? readString23(body, "provider_key") ?? readString23(body, "providerKey");
|
|
37605
|
+
const baseUrl = readString23(body, "base_url") ?? readString23(body, "baseUrl");
|
|
36942
37606
|
if (!id || !provider || !baseUrl) {
|
|
36943
37607
|
throw new LinkHttpError(
|
|
36944
37608
|
400,
|
|
@@ -36948,22 +37612,22 @@ function readModelConfigInput(body) {
|
|
|
36948
37612
|
}
|
|
36949
37613
|
return {
|
|
36950
37614
|
id,
|
|
36951
|
-
originalModelId:
|
|
36952
|
-
originalProvider:
|
|
36953
|
-
originalBaseUrl:
|
|
36954
|
-
originalApiMode:
|
|
37615
|
+
originalModelId: readString23(body, "original_model_id") ?? readString23(body, "originalModelId") ?? readString23(body, "original_id") ?? void 0,
|
|
37616
|
+
originalProvider: readString23(body, "original_provider") ?? readString23(body, "originalProvider") ?? readString23(body, "original_provider_key") ?? readString23(body, "originalProviderKey") ?? void 0,
|
|
37617
|
+
originalBaseUrl: readString23(body, "original_base_url") ?? readString23(body, "originalBaseUrl") ?? void 0,
|
|
37618
|
+
originalApiMode: readString23(body, "original_api_mode") ?? readString23(body, "originalApiMode") ?? void 0,
|
|
36955
37619
|
provider,
|
|
36956
|
-
providerName:
|
|
37620
|
+
providerName: readString23(body, "provider_name") ?? readString23(body, "providerName") ?? void 0,
|
|
36957
37621
|
baseUrl,
|
|
36958
|
-
apiKey:
|
|
36959
|
-
apiMode:
|
|
37622
|
+
apiKey: readString23(body, "api_key") ?? readString23(body, "apiKey") ?? void 0,
|
|
37623
|
+
apiMode: readString23(body, "api_mode") ?? readString23(body, "apiMode") ?? void 0,
|
|
36960
37624
|
contextLength: readPositiveInteger2(
|
|
36961
37625
|
body.context_length ?? body.contextLength
|
|
36962
37626
|
),
|
|
36963
|
-
keyEnv:
|
|
37627
|
+
keyEnv: readString23(body, "key_env") ?? readString23(body, "keyEnv") ?? void 0,
|
|
36964
37628
|
setDefault: readBoolean4(body.set_default ?? body.setDefault),
|
|
36965
|
-
reasoningEffort:
|
|
36966
|
-
reasoningSupportPolicy:
|
|
37629
|
+
reasoningEffort: readString23(body, "reasoning_effort") ?? readString23(body, "reasoningEffort") ?? void 0,
|
|
37630
|
+
reasoningSupportPolicy: readString23(body, "reasoning_support_policy") ?? readString23(body, "reasoningSupportPolicy") ?? readString23(body, "reasoning_support") ?? readString23(body, "reasoningSupport") ?? void 0,
|
|
36967
37631
|
supportsVision: readNullableBoolean2(
|
|
36968
37632
|
body.supports_vision ?? body.supportsVision
|
|
36969
37633
|
)
|
|
@@ -36971,28 +37635,28 @@ function readModelConfigInput(body) {
|
|
|
36971
37635
|
}
|
|
36972
37636
|
function readModelDefaultsInput(body) {
|
|
36973
37637
|
return {
|
|
36974
|
-
taskModelId:
|
|
36975
|
-
taskModelProvider:
|
|
36976
|
-
taskModelBaseUrl:
|
|
36977
|
-
taskModelApiMode:
|
|
36978
|
-
compressionModelId:
|
|
36979
|
-
compressionModelProvider:
|
|
36980
|
-
compressionModelBaseUrl:
|
|
36981
|
-
compressionModelApiMode:
|
|
36982
|
-
reasoningEffort:
|
|
36983
|
-
imageInputMode:
|
|
37638
|
+
taskModelId: readString23(body, "task_model_id") ?? readString23(body, "taskModelId") ?? readString23(body, "default_model_id") ?? readString23(body, "defaultModelId") ?? void 0,
|
|
37639
|
+
taskModelProvider: readString23(body, "task_model_provider") ?? readString23(body, "taskModelProvider") ?? readString23(body, "default_model_provider") ?? readString23(body, "defaultModelProvider") ?? void 0,
|
|
37640
|
+
taskModelBaseUrl: readString23(body, "task_model_base_url") ?? readString23(body, "taskModelBaseUrl") ?? readString23(body, "default_model_base_url") ?? readString23(body, "defaultModelBaseUrl") ?? void 0,
|
|
37641
|
+
taskModelApiMode: readString23(body, "task_model_api_mode") ?? readString23(body, "taskModelApiMode") ?? readString23(body, "default_model_api_mode") ?? readString23(body, "defaultModelApiMode") ?? void 0,
|
|
37642
|
+
compressionModelId: readString23(body, "compression_model_id") ?? readString23(body, "compressionModelId") ?? void 0,
|
|
37643
|
+
compressionModelProvider: readString23(body, "compression_model_provider") ?? readString23(body, "compressionModelProvider") ?? void 0,
|
|
37644
|
+
compressionModelBaseUrl: readString23(body, "compression_model_base_url") ?? readString23(body, "compressionModelBaseUrl") ?? void 0,
|
|
37645
|
+
compressionModelApiMode: readString23(body, "compression_model_api_mode") ?? readString23(body, "compressionModelApiMode") ?? void 0,
|
|
37646
|
+
reasoningEffort: readString23(body, "reasoning_effort") ?? readString23(body, "reasoningEffort") ?? readString23(body, "default_reasoning_effort") ?? readString23(body, "defaultReasoningEffort") ?? void 0,
|
|
37647
|
+
imageInputMode: readString23(body, "image_input_mode") ?? readString23(body, "imageInputMode") ?? void 0
|
|
36984
37648
|
};
|
|
36985
37649
|
}
|
|
36986
37650
|
function readModelDeleteInput(body) {
|
|
36987
|
-
const id =
|
|
37651
|
+
const id = readString23(body, "model_id") ?? readString23(body, "modelId");
|
|
36988
37652
|
if (!id) {
|
|
36989
37653
|
throw new LinkHttpError(400, "model_id_required", "model_id is required");
|
|
36990
37654
|
}
|
|
36991
37655
|
return {
|
|
36992
37656
|
id,
|
|
36993
|
-
provider:
|
|
36994
|
-
baseUrl:
|
|
36995
|
-
apiMode:
|
|
37657
|
+
provider: readString23(body, "provider") ?? readString23(body, "provider_key") ?? readString23(body, "providerKey") ?? void 0,
|
|
37658
|
+
baseUrl: readString23(body, "base_url") ?? readString23(body, "baseUrl") ?? void 0,
|
|
37659
|
+
apiMode: readString23(body, "api_mode") ?? readString23(body, "apiMode") ?? void 0
|
|
36996
37660
|
};
|
|
36997
37661
|
}
|
|
36998
37662
|
function readNullableBoolean2(value) {
|
|
@@ -37015,8 +37679,8 @@ function readNullableBoolean2(value) {
|
|
|
37015
37679
|
return void 0;
|
|
37016
37680
|
}
|
|
37017
37681
|
function readModelConfigImportInput(body) {
|
|
37018
|
-
const sourceProfileName =
|
|
37019
|
-
const modelId =
|
|
37682
|
+
const sourceProfileName = readString23(body, "source_profile") ?? readString23(body, "sourceProfile") ?? readString23(body, "source_profile_name") ?? readString23(body, "sourceProfileName");
|
|
37683
|
+
const modelId = readString23(body, "model_id") ?? readString23(body, "modelId") ?? readString23(body, "id");
|
|
37020
37684
|
if (!sourceProfileName || !modelId) {
|
|
37021
37685
|
throw new LinkHttpError(
|
|
37022
37686
|
400,
|
|
@@ -37027,9 +37691,9 @@ function readModelConfigImportInput(body) {
|
|
|
37027
37691
|
return {
|
|
37028
37692
|
sourceProfileName,
|
|
37029
37693
|
modelId,
|
|
37030
|
-
provider:
|
|
37031
|
-
baseUrl:
|
|
37032
|
-
apiMode:
|
|
37694
|
+
provider: readString23(body, "provider") ?? readString23(body, "provider_key") ?? readString23(body, "providerKey") ?? void 0,
|
|
37695
|
+
baseUrl: readString23(body, "base_url") ?? readString23(body, "baseUrl") ?? void 0,
|
|
37696
|
+
apiMode: readString23(body, "api_mode") ?? readString23(body, "apiMode") ?? void 0,
|
|
37033
37697
|
setDefault: readBoolean4(body.set_default ?? body.setDefault)
|
|
37034
37698
|
};
|
|
37035
37699
|
}
|
|
@@ -37136,19 +37800,19 @@ function errorMessage3(error) {
|
|
|
37136
37800
|
}
|
|
37137
37801
|
|
|
37138
37802
|
// src/hermes/profile-identity.ts
|
|
37139
|
-
import { readFile as
|
|
37140
|
-
import
|
|
37803
|
+
import { readFile as readFile17, stat as stat19 } from "fs/promises";
|
|
37804
|
+
import path30 from "path";
|
|
37141
37805
|
var MAX_SOUL_MD_LENGTH = 2e4;
|
|
37142
37806
|
async function readHermesProfileIdentity(profileName, paths) {
|
|
37143
37807
|
await assertProfileExists3(profileName, paths);
|
|
37144
37808
|
const soulPath = resolveSoulPath(profileName);
|
|
37145
|
-
const content = await
|
|
37809
|
+
const content = await readFile17(soulPath, "utf8").catch((error) => {
|
|
37146
37810
|
if (isNodeError19(error, "ENOENT")) {
|
|
37147
37811
|
return null;
|
|
37148
37812
|
}
|
|
37149
37813
|
throw error;
|
|
37150
37814
|
});
|
|
37151
|
-
const fileStat = content === null ? null : await
|
|
37815
|
+
const fileStat = content === null ? null : await stat19(soulPath).catch((error) => {
|
|
37152
37816
|
if (isNodeError19(error, "ENOENT")) {
|
|
37153
37817
|
return null;
|
|
37154
37818
|
}
|
|
@@ -37194,7 +37858,7 @@ async function assertProfileExists3(profileName, paths) {
|
|
|
37194
37858
|
}
|
|
37195
37859
|
}
|
|
37196
37860
|
function resolveSoulPath(profileName) {
|
|
37197
|
-
return
|
|
37861
|
+
return path30.join(resolveHermesProfileDir(profileName), "SOUL.md");
|
|
37198
37862
|
}
|
|
37199
37863
|
function isNodeError19(error, code) {
|
|
37200
37864
|
return error instanceof Error && "code" in error && error.code === code;
|
|
@@ -37206,17 +37870,17 @@ import { EventEmitter as EventEmitter2 } from "events";
|
|
|
37206
37870
|
import {
|
|
37207
37871
|
cp,
|
|
37208
37872
|
mkdir as mkdir13,
|
|
37209
|
-
readFile as
|
|
37873
|
+
readFile as readFile19,
|
|
37210
37874
|
rm as rm7,
|
|
37211
|
-
stat as
|
|
37875
|
+
stat as stat21
|
|
37212
37876
|
} from "fs/promises";
|
|
37213
|
-
import
|
|
37877
|
+
import path32 from "path";
|
|
37214
37878
|
import YAML5 from "yaml";
|
|
37215
37879
|
|
|
37216
37880
|
// src/hermes/link-skill.ts
|
|
37217
|
-
import { readFile as
|
|
37881
|
+
import { readFile as readFile18, stat as stat20 } from "fs/promises";
|
|
37218
37882
|
import os7 from "os";
|
|
37219
|
-
import
|
|
37883
|
+
import path31 from "path";
|
|
37220
37884
|
import YAML4 from "yaml";
|
|
37221
37885
|
var HERMES_LINK_SKILL_ROOT_DIR = "hermes-skills";
|
|
37222
37886
|
var HERMES_LINK_SKILL_DIR = "hermes-link";
|
|
@@ -37313,7 +37977,7 @@ Do not modify Hermes profiles, delete user data, edit config files, or kill proc
|
|
|
37313
37977
|
async function ensureHermesLinkSkillInstalledForProfiles(options = {}) {
|
|
37314
37978
|
const paths = options.paths ?? resolveRuntimePaths();
|
|
37315
37979
|
const externalDir = resolveHermesLinkSkillExternalDir(paths);
|
|
37316
|
-
const skillPath =
|
|
37980
|
+
const skillPath = path31.join(
|
|
37317
37981
|
externalDir,
|
|
37318
37982
|
HERMES_LINK_SKILL_DIR,
|
|
37319
37983
|
HERMES_LINK_SKILL_FILE
|
|
@@ -37395,10 +38059,10 @@ function withDefaultProfilePlaceholder2(profiles) {
|
|
|
37395
38059
|
];
|
|
37396
38060
|
}
|
|
37397
38061
|
function resolveHermesLinkSkillExternalDir(paths = resolveRuntimePaths()) {
|
|
37398
|
-
return
|
|
38062
|
+
return path31.join(paths.homeDir, HERMES_LINK_SKILL_ROOT_DIR);
|
|
37399
38063
|
}
|
|
37400
38064
|
async function writeHermesLinkSkill(skillPath) {
|
|
37401
|
-
const existing = await
|
|
38065
|
+
const existing = await readFile18(skillPath, "utf8").catch((error) => {
|
|
37402
38066
|
if (isNodeError20(error, "ENOENT")) {
|
|
37403
38067
|
return null;
|
|
37404
38068
|
}
|
|
@@ -37456,7 +38120,7 @@ async function ensureProfileUsesExternalSkillDir(profile, externalDir) {
|
|
|
37456
38120
|
};
|
|
37457
38121
|
}
|
|
37458
38122
|
async function readHermesConfigDocument3(configPath) {
|
|
37459
|
-
const existingRaw = await
|
|
38123
|
+
const existingRaw = await readFile18(configPath, "utf8").catch(
|
|
37460
38124
|
(error) => {
|
|
37461
38125
|
if (isNodeError20(error, "ENOENT")) {
|
|
37462
38126
|
return null;
|
|
@@ -37490,11 +38154,11 @@ function appendExternalDir(current, externalDir, hermesHome) {
|
|
|
37490
38154
|
const seen = new Set(
|
|
37491
38155
|
entries.map((entry) => resolveExternalDirEntry(entry, hermesHome))
|
|
37492
38156
|
);
|
|
37493
|
-
const normalizedExternalDir =
|
|
38157
|
+
const normalizedExternalDir = path31.resolve(externalDir);
|
|
37494
38158
|
return seen.has(normalizedExternalDir) ? entries : [...entries, normalizedExternalDir];
|
|
37495
38159
|
}
|
|
37496
38160
|
function externalDirsInclude(current, externalDir, hermesHome) {
|
|
37497
|
-
const normalizedExternalDir =
|
|
38161
|
+
const normalizedExternalDir = path31.resolve(externalDir);
|
|
37498
38162
|
return readExternalDirEntries(current).some(
|
|
37499
38163
|
(entry) => resolveExternalDirEntry(entry, hermesHome) === normalizedExternalDir
|
|
37500
38164
|
);
|
|
@@ -37505,14 +38169,14 @@ function readExternalDirEntries(value) {
|
|
|
37505
38169
|
}
|
|
37506
38170
|
function resolveExternalDirEntry(entry, hermesHome) {
|
|
37507
38171
|
const expanded = expandHome(expandEnvVars(entry));
|
|
37508
|
-
return
|
|
38172
|
+
return path31.resolve(path31.isAbsolute(expanded) ? expanded : path31.join(hermesHome, expanded));
|
|
37509
38173
|
}
|
|
37510
38174
|
function expandHome(value) {
|
|
37511
38175
|
if (value === "~") {
|
|
37512
38176
|
return os7.homedir();
|
|
37513
38177
|
}
|
|
37514
|
-
if (value.startsWith(`~${
|
|
37515
|
-
return
|
|
38178
|
+
if (value.startsWith(`~${path31.sep}`) || value.startsWith("~/")) {
|
|
38179
|
+
return path31.join(os7.homedir(), value.slice(2));
|
|
37516
38180
|
}
|
|
37517
38181
|
return value;
|
|
37518
38182
|
}
|
|
@@ -37523,7 +38187,7 @@ function expandEnvVars(value) {
|
|
|
37523
38187
|
);
|
|
37524
38188
|
}
|
|
37525
38189
|
async function pathIsDirectory2(filePath) {
|
|
37526
|
-
return
|
|
38190
|
+
return stat20(filePath).then((value) => value.isDirectory()).catch((error) => {
|
|
37527
38191
|
if (isNodeError20(error, "ENOENT")) {
|
|
37528
38192
|
return false;
|
|
37529
38193
|
}
|
|
@@ -38064,8 +38728,8 @@ function collectEnvKeys(value, keys = /* @__PURE__ */ new Set()) {
|
|
|
38064
38728
|
return keys;
|
|
38065
38729
|
}
|
|
38066
38730
|
async function writeEnvValues(profileName, values) {
|
|
38067
|
-
const envPath =
|
|
38068
|
-
const existingRaw = await
|
|
38731
|
+
const envPath = path32.join(resolveHermesProfileDir(profileName), ".env");
|
|
38732
|
+
const existingRaw = await readFile19(envPath, "utf8").catch((error) => {
|
|
38069
38733
|
if (isNodeError21(error, "ENOENT")) {
|
|
38070
38734
|
return "";
|
|
38071
38735
|
}
|
|
@@ -38101,8 +38765,8 @@ async function writeEnvValues(profileName, values) {
|
|
|
38101
38765
|
await atomicWriteFilePreservingMetadata(envPath, nextRaw);
|
|
38102
38766
|
}
|
|
38103
38767
|
async function copySkills(sourceProfile, targetProfile) {
|
|
38104
|
-
const sourceSkills =
|
|
38105
|
-
const targetSkills =
|
|
38768
|
+
const sourceSkills = path32.join(resolveHermesProfileDir(sourceProfile), "skills");
|
|
38769
|
+
const targetSkills = path32.join(resolveHermesProfileDir(targetProfile), "skills");
|
|
38106
38770
|
if (!await pathExists2(sourceSkills)) {
|
|
38107
38771
|
return;
|
|
38108
38772
|
}
|
|
@@ -38125,7 +38789,7 @@ function copyProperty(source, target, key) {
|
|
|
38125
38789
|
}
|
|
38126
38790
|
}
|
|
38127
38791
|
async function readYamlConfig(configPath) {
|
|
38128
|
-
const existingRaw = await
|
|
38792
|
+
const existingRaw = await readFile19(configPath, "utf8").catch(
|
|
38129
38793
|
(error) => {
|
|
38130
38794
|
if (isNodeError21(error, "ENOENT")) {
|
|
38131
38795
|
return null;
|
|
@@ -38188,7 +38852,7 @@ async function writeProfileCreationState(paths, state) {
|
|
|
38188
38852
|
await writeJsonFile(profileCreationStatePath(paths), state);
|
|
38189
38853
|
}
|
|
38190
38854
|
async function readProfileCreationLogLines(paths) {
|
|
38191
|
-
const raw = await
|
|
38855
|
+
const raw = await readFile19(profileCreationLogPath(paths), "utf8").catch(() => "");
|
|
38192
38856
|
if (!raw.trim()) {
|
|
38193
38857
|
return [];
|
|
38194
38858
|
}
|
|
@@ -38197,10 +38861,10 @@ async function readProfileCreationLogLines(paths) {
|
|
|
38197
38861
|
);
|
|
38198
38862
|
}
|
|
38199
38863
|
function profileCreationStatePath(paths) {
|
|
38200
|
-
return
|
|
38864
|
+
return path32.join(paths.runDir, "profile-create-state.json");
|
|
38201
38865
|
}
|
|
38202
38866
|
function profileCreationLogPath(paths) {
|
|
38203
|
-
return
|
|
38867
|
+
return path32.join(paths.logsDir, PROFILE_CREATE_LOG_FILE);
|
|
38204
38868
|
}
|
|
38205
38869
|
async function clearProfileCreationLogFiles(paths) {
|
|
38206
38870
|
const primary = profileCreationLogPath(paths);
|
|
@@ -38213,7 +38877,7 @@ async function clearProfileCreationLogFiles(paths) {
|
|
|
38213
38877
|
]);
|
|
38214
38878
|
}
|
|
38215
38879
|
async function pathExists2(targetPath) {
|
|
38216
|
-
return await
|
|
38880
|
+
return await stat21(targetPath).then(() => true).catch((error) => {
|
|
38217
38881
|
if (isNodeError21(error, "ENOENT")) {
|
|
38218
38882
|
return false;
|
|
38219
38883
|
}
|
|
@@ -38346,16 +39010,16 @@ function readProfilePermissionsInput(body) {
|
|
|
38346
39010
|
const approvals = readOptionalObject(body, "approvals");
|
|
38347
39011
|
if (approvals) {
|
|
38348
39012
|
input.approvals = {
|
|
38349
|
-
mode:
|
|
39013
|
+
mode: readString23(approvals, "mode") ?? readString23(approvals, "approval_mode") ?? readString23(approvals, "approvalMode") ?? void 0,
|
|
38350
39014
|
timeout: readPositiveInteger2(approvals.timeout),
|
|
38351
|
-
cronMode:
|
|
39015
|
+
cronMode: readString23(approvals, "cron_mode") ?? readString23(approvals, "cronMode") ?? void 0
|
|
38352
39016
|
};
|
|
38353
39017
|
}
|
|
38354
39018
|
const terminal = readOptionalObject(body, "terminal");
|
|
38355
39019
|
if (terminal) {
|
|
38356
39020
|
input.terminal = {
|
|
38357
|
-
backend:
|
|
38358
|
-
cwd:
|
|
39021
|
+
backend: readString23(terminal, "backend") ?? void 0,
|
|
39022
|
+
cwd: readString23(terminal, "cwd") ?? void 0,
|
|
38359
39023
|
containerCpu: readPositiveInteger2(
|
|
38360
39024
|
terminal.container_cpu ?? terminal.containerCpu
|
|
38361
39025
|
),
|
|
@@ -38486,10 +39150,10 @@ function toProfileToolConfigHttpError(error) {
|
|
|
38486
39150
|
import {
|
|
38487
39151
|
access as access3,
|
|
38488
39152
|
readdir as readdir10,
|
|
38489
|
-
readFile as
|
|
38490
|
-
stat as
|
|
39153
|
+
readFile as readFile20,
|
|
39154
|
+
stat as stat22
|
|
38491
39155
|
} from "fs/promises";
|
|
38492
|
-
import
|
|
39156
|
+
import path33 from "path";
|
|
38493
39157
|
import YAML6 from "yaml";
|
|
38494
39158
|
var ENTRY_DELIMITER = "\n\xA7\n";
|
|
38495
39159
|
var DEFAULT_MEMORY_LIMIT = 2200;
|
|
@@ -38686,9 +39350,9 @@ async function testHindsightProviderSettings(profileName, patch) {
|
|
|
38686
39350
|
const mode = normalizeHindsightMode(
|
|
38687
39351
|
patch.mode ?? config.mode ?? env.HINDSIGHT_MODE
|
|
38688
39352
|
);
|
|
38689
|
-
const apiUrl =
|
|
38690
|
-
const bankId =
|
|
38691
|
-
const apiKey =
|
|
39353
|
+
const apiUrl = readString25(patch.apiUrl) ?? readString25(config.api_url) ?? env.HINDSIGHT_API_URL ?? (mode === "cloud" ? HINDSIGHT_DEFAULT_API_URL : HINDSIGHT_DEFAULT_LOCAL_URL);
|
|
39354
|
+
const bankId = readString25(patch.bankId) ?? readString25(config.bank_id) ?? "hermes";
|
|
39355
|
+
const apiKey = readString25(patch.apiKey) ?? env.HINDSIGHT_API_KEY ?? readString25(config.apiKey) ?? readString25(config.api_key);
|
|
38692
39356
|
const baseUrl = normalizeHttpUrl2(apiUrl);
|
|
38693
39357
|
if (!baseUrl) {
|
|
38694
39358
|
return {
|
|
@@ -38820,7 +39484,7 @@ async function saveProviderSettings(profileName, provider, patch) {
|
|
|
38820
39484
|
});
|
|
38821
39485
|
await patchJsonProviderConfig(
|
|
38822
39486
|
profileName,
|
|
38823
|
-
|
|
39487
|
+
path33.join("hindsight", "config.json"),
|
|
38824
39488
|
{
|
|
38825
39489
|
mode: patch.mode,
|
|
38826
39490
|
api_url: patch.apiUrl,
|
|
@@ -38968,7 +39632,7 @@ function normalizeCustomProviderId(provider) {
|
|
|
38968
39632
|
}
|
|
38969
39633
|
async function patchHermesMemoryProvider(profileName, provider) {
|
|
38970
39634
|
const configPath = resolveHermesConfigPath(profileName);
|
|
38971
|
-
const existingRaw = await
|
|
39635
|
+
const existingRaw = await readFile20(configPath, "utf8").catch(
|
|
38972
39636
|
(error) => {
|
|
38973
39637
|
if (isNodeError22(error, "ENOENT")) {
|
|
38974
39638
|
return null;
|
|
@@ -38992,7 +39656,7 @@ async function patchHermesMemoryProvider(profileName, provider) {
|
|
|
38992
39656
|
}
|
|
38993
39657
|
async function patchHermesMemoryLimits(profileName, patch) {
|
|
38994
39658
|
const configPath = resolveHermesConfigPath(profileName);
|
|
38995
|
-
const existingRaw = await
|
|
39659
|
+
const existingRaw = await readFile20(configPath, "utf8").catch(
|
|
38996
39660
|
(error) => {
|
|
38997
39661
|
if (isNodeError22(error, "ENOENT")) {
|
|
38998
39662
|
return null;
|
|
@@ -39023,12 +39687,12 @@ async function patchHermesMemoryLimits(profileName, patch) {
|
|
|
39023
39687
|
await atomicWriteFilePreservingMetadata(configPath, document.toString());
|
|
39024
39688
|
}
|
|
39025
39689
|
function resolveMemoryDir(profileName) {
|
|
39026
|
-
return
|
|
39690
|
+
return path33.join(resolveHermesProfileDir(profileName), "memories");
|
|
39027
39691
|
}
|
|
39028
39692
|
async function readMemoryStore(profileName, target, limits) {
|
|
39029
39693
|
const filePath = memoryFilePath(profileName, target);
|
|
39030
39694
|
const entries = await readMemoryEntries(filePath);
|
|
39031
|
-
const fileStat = await
|
|
39695
|
+
const fileStat = await stat22(filePath).catch((error) => {
|
|
39032
39696
|
if (isNodeError22(error, "ENOENT")) {
|
|
39033
39697
|
return null;
|
|
39034
39698
|
}
|
|
@@ -39057,7 +39721,7 @@ async function readMemoryStore(profileName, target, limits) {
|
|
|
39057
39721
|
};
|
|
39058
39722
|
}
|
|
39059
39723
|
async function readMemoryEntries(filePath) {
|
|
39060
|
-
const raw = await
|
|
39724
|
+
const raw = await readFile20(filePath, "utf8").catch((error) => {
|
|
39061
39725
|
if (isNodeError22(error, "ENOENT")) {
|
|
39062
39726
|
return "";
|
|
39063
39727
|
}
|
|
@@ -39084,7 +39748,7 @@ async function writeMemoryEntries(profileName, target, entries) {
|
|
|
39084
39748
|
);
|
|
39085
39749
|
}
|
|
39086
39750
|
function memoryFilePath(profileName, target) {
|
|
39087
|
-
return
|
|
39751
|
+
return path33.join(
|
|
39088
39752
|
resolveMemoryDir(profileName),
|
|
39089
39753
|
target === "user" ? "USER.md" : "MEMORY.md"
|
|
39090
39754
|
);
|
|
@@ -39144,7 +39808,7 @@ async function readCustomProviderSetupSummary(profileName) {
|
|
|
39144
39808
|
configurable: true,
|
|
39145
39809
|
configured: true,
|
|
39146
39810
|
configurationIssue: null,
|
|
39147
|
-
providerConfigPath:
|
|
39811
|
+
providerConfigPath: path33.join(
|
|
39148
39812
|
resolveHermesProfileDir(profileName),
|
|
39149
39813
|
"<provider>.json"
|
|
39150
39814
|
),
|
|
@@ -39222,7 +39886,7 @@ async function readProviderConfigurationStatus(profileName, provider) {
|
|
|
39222
39886
|
const config2 = await readJsonObject(
|
|
39223
39887
|
memoryProviderConfigPath(profileName, "honcho") ?? ""
|
|
39224
39888
|
);
|
|
39225
|
-
return isConfiguredEnvValue(env.HONCHO_API_KEY) || isConfiguredEnvValue(
|
|
39889
|
+
return isConfiguredEnvValue(env.HONCHO_API_KEY) || isConfiguredEnvValue(readString25(config2.apiKey)) || isConfiguredEnvValue(readString25(config2.api_key)) || isConfiguredEnvValue(readString25(config2.baseUrl)) ? { configured: true, issue: null } : {
|
|
39226
39890
|
configured: false,
|
|
39227
39891
|
issue: "Honcho \u9700\u8981\u5148\u586B\u5199 API Key\uFF0C\u6216\u5728 honcho.json \u914D\u7F6E self-hosted baseUrl\u3002"
|
|
39228
39892
|
};
|
|
@@ -39231,7 +39895,7 @@ async function readProviderConfigurationStatus(profileName, provider) {
|
|
|
39231
39895
|
const config2 = await readJsonObject(
|
|
39232
39896
|
memoryProviderConfigPath(profileName, "mem0") ?? ""
|
|
39233
39897
|
);
|
|
39234
|
-
return isConfiguredEnvValue(env.MEM0_API_KEY) || isConfiguredEnvValue(
|
|
39898
|
+
return isConfiguredEnvValue(env.MEM0_API_KEY) || isConfiguredEnvValue(readString25(config2.api_key)) ? { configured: true, issue: null } : {
|
|
39235
39899
|
configured: false,
|
|
39236
39900
|
issue: "Mem0 \u9700\u8981\u5148\u5728\u672C\u9875\u586B\u5199 API Key\uFF0CLink \u4F1A\u5199\u5165\u5F53\u524D Profile \u7684 .env\u3002"
|
|
39237
39901
|
};
|
|
@@ -39273,7 +39937,7 @@ async function readProviderConfigurationStatus(profileName, provider) {
|
|
|
39273
39937
|
memoryProviderConfigPath(profileName, provider) ?? ""
|
|
39274
39938
|
);
|
|
39275
39939
|
const mode = normalizeHindsightMode(config.mode ?? env.HINDSIGHT_MODE);
|
|
39276
|
-
const apiKey =
|
|
39940
|
+
const apiKey = readString25(config.apiKey) ?? readString25(config.api_key) ?? env.HINDSIGHT_API_KEY;
|
|
39277
39941
|
if (mode === "cloud") {
|
|
39278
39942
|
return isConfiguredEnvValue(apiKey) ? { configured: true, issue: null } : {
|
|
39279
39943
|
configured: false,
|
|
@@ -39281,15 +39945,15 @@ async function readProviderConfigurationStatus(profileName, provider) {
|
|
|
39281
39945
|
};
|
|
39282
39946
|
}
|
|
39283
39947
|
if (mode === "local_external") {
|
|
39284
|
-
const apiUrl =
|
|
39948
|
+
const apiUrl = readString25(config.api_url) ?? env.HINDSIGHT_API_URL ?? HINDSIGHT_DEFAULT_LOCAL_URL;
|
|
39285
39949
|
return isConfiguredEnvValue(apiUrl) ? { configured: true, issue: null } : {
|
|
39286
39950
|
configured: false,
|
|
39287
39951
|
issue: "Hindsight local_external \u9700\u8981\u914D\u7F6E\u53EF\u8BBF\u95EE\u7684 API URL\u3002"
|
|
39288
39952
|
};
|
|
39289
39953
|
}
|
|
39290
39954
|
if (mode === "local_embedded") {
|
|
39291
|
-
const llmProvider =
|
|
39292
|
-
const llmModel =
|
|
39955
|
+
const llmProvider = readString25(config.llm_provider) ?? "openai";
|
|
39956
|
+
const llmModel = readString25(config.llm_model);
|
|
39293
39957
|
if (!llmModel) {
|
|
39294
39958
|
return {
|
|
39295
39959
|
configured: false,
|
|
@@ -39297,7 +39961,7 @@ async function readProviderConfigurationStatus(profileName, provider) {
|
|
|
39297
39961
|
};
|
|
39298
39962
|
}
|
|
39299
39963
|
if (llmProvider === "openai_compatible" && !isConfiguredEnvValue(
|
|
39300
|
-
|
|
39964
|
+
readString25(config.llm_base_url) ?? env.HINDSIGHT_API_LLM_BASE_URL
|
|
39301
39965
|
)) {
|
|
39302
39966
|
return {
|
|
39303
39967
|
configured: false,
|
|
@@ -39305,7 +39969,7 @@ async function readProviderConfigurationStatus(profileName, provider) {
|
|
|
39305
39969
|
};
|
|
39306
39970
|
}
|
|
39307
39971
|
if (!["ollama", "lmstudio", "openai_compatible"].includes(llmProvider) && !isConfiguredEnvValue(
|
|
39308
|
-
|
|
39972
|
+
readString25(config.llmApiKey) ?? readString25(config.llm_api_key) ?? env.HINDSIGHT_LLM_API_KEY
|
|
39309
39973
|
)) {
|
|
39310
39974
|
return {
|
|
39311
39975
|
configured: false,
|
|
@@ -39361,8 +40025,8 @@ async function readProviderSettings(profileName, provider) {
|
|
|
39361
40025
|
secretSetting(
|
|
39362
40026
|
"apiKey",
|
|
39363
40027
|
"API Key",
|
|
39364
|
-
env.HONCHO_API_KEY ??
|
|
39365
|
-
isConfiguredEnvValue(env.HONCHO_API_KEY) || isConfiguredEnvValue(
|
|
40028
|
+
env.HONCHO_API_KEY ?? readString25(config.apiKey) ?? readString25(config.api_key),
|
|
40029
|
+
isConfiguredEnvValue(env.HONCHO_API_KEY) || isConfiguredEnvValue(readString25(config.apiKey)) || isConfiguredEnvValue(readString25(config.api_key))
|
|
39366
40030
|
),
|
|
39367
40031
|
stringSetting("workspace", "Workspace", config.workspace ?? "hermes"),
|
|
39368
40032
|
stringSetting("peerName", "\u7528\u6237 Peer", config.peerName ?? ""),
|
|
@@ -39404,8 +40068,8 @@ async function readProviderSettings(profileName, provider) {
|
|
|
39404
40068
|
secretSetting(
|
|
39405
40069
|
"apiKey",
|
|
39406
40070
|
"API Key",
|
|
39407
|
-
env.MEM0_API_KEY ??
|
|
39408
|
-
isConfiguredEnvValue(env.MEM0_API_KEY) || isConfiguredEnvValue(
|
|
40071
|
+
env.MEM0_API_KEY ?? readString25(config.apiKey) ?? readString25(config.api_key),
|
|
40072
|
+
isConfiguredEnvValue(env.MEM0_API_KEY) || isConfiguredEnvValue(readString25(config.apiKey)) || isConfiguredEnvValue(readString25(config.api_key))
|
|
39409
40073
|
),
|
|
39410
40074
|
stringSetting("userId", "User ID", config.user_id ?? "hermes-user"),
|
|
39411
40075
|
stringSetting("agentId", "Agent ID", config.agent_id ?? "hermes"),
|
|
@@ -39490,8 +40154,8 @@ async function readProviderSettings(profileName, provider) {
|
|
|
39490
40154
|
secretSetting(
|
|
39491
40155
|
"apiKey",
|
|
39492
40156
|
"Hindsight API Key",
|
|
39493
|
-
env.HINDSIGHT_API_KEY ??
|
|
39494
|
-
isConfiguredEnvValue(env.HINDSIGHT_API_KEY) || isConfiguredEnvValue(
|
|
40157
|
+
env.HINDSIGHT_API_KEY ?? readString25(config.apiKey) ?? readString25(config.api_key),
|
|
40158
|
+
isConfiguredEnvValue(env.HINDSIGHT_API_KEY) || isConfiguredEnvValue(readString25(config.apiKey)) || isConfiguredEnvValue(readString25(config.api_key))
|
|
39495
40159
|
),
|
|
39496
40160
|
stringSetting(
|
|
39497
40161
|
"bankId",
|
|
@@ -39513,8 +40177,8 @@ async function readProviderSettings(profileName, provider) {
|
|
|
39513
40177
|
secretSetting(
|
|
39514
40178
|
"llmApiKey",
|
|
39515
40179
|
"LLM API Key",
|
|
39516
|
-
env.HINDSIGHT_LLM_API_KEY ??
|
|
39517
|
-
isConfiguredEnvValue(env.HINDSIGHT_LLM_API_KEY) || isConfiguredEnvValue(
|
|
40180
|
+
env.HINDSIGHT_LLM_API_KEY ?? readString25(config.llmApiKey) ?? readString25(config.llm_api_key),
|
|
40181
|
+
isConfiguredEnvValue(env.HINDSIGHT_LLM_API_KEY) || isConfiguredEnvValue(readString25(config.llmApiKey)) || isConfiguredEnvValue(readString25(config.llm_api_key))
|
|
39518
40182
|
),
|
|
39519
40183
|
booleanSetting("autoRecall", "\u81EA\u52A8\u56DE\u5FC6", config.auto_recall ?? true),
|
|
39520
40184
|
booleanSetting("autoRetain", "\u81EA\u52A8\u6C89\u6DC0", config.auto_retain ?? true),
|
|
@@ -39538,7 +40202,7 @@ async function readProviderSettings(profileName, provider) {
|
|
|
39538
40202
|
stringSetting(
|
|
39539
40203
|
"dbPath",
|
|
39540
40204
|
"SQLite \u6570\u636E\u5E93\u8DEF\u5F84",
|
|
39541
|
-
config.db_path ??
|
|
40205
|
+
config.db_path ?? path33.join(resolveHermesProfileDir(profileName), "memory_store.db")
|
|
39542
40206
|
),
|
|
39543
40207
|
booleanSetting("autoExtract", "\u4F1A\u8BDD\u7ED3\u675F\u81EA\u52A8\u62BD\u53D6", config.auto_extract ?? false),
|
|
39544
40208
|
numberSetting("defaultTrust", "\u9ED8\u8BA4\u4FE1\u4EFB\u5206", config.default_trust ?? 0.5),
|
|
@@ -39574,7 +40238,7 @@ async function readProviderSettings(profileName, provider) {
|
|
|
39574
40238
|
stringSetting(
|
|
39575
40239
|
"workingDirectory",
|
|
39576
40240
|
"\u5DE5\u4F5C\u76EE\u5F55",
|
|
39577
|
-
|
|
40241
|
+
path33.join(resolveHermesProfileDir(profileName), "byterover"),
|
|
39578
40242
|
false
|
|
39579
40243
|
)
|
|
39580
40244
|
];
|
|
@@ -39583,16 +40247,16 @@ async function readProviderSettings(profileName, provider) {
|
|
|
39583
40247
|
}
|
|
39584
40248
|
function memoryProviderConfigPath(profileName, provider) {
|
|
39585
40249
|
if (provider === "honcho") {
|
|
39586
|
-
return
|
|
40250
|
+
return path33.join(resolveHermesProfileDir(profileName), "honcho.json");
|
|
39587
40251
|
}
|
|
39588
40252
|
if (provider === "mem0") {
|
|
39589
|
-
return
|
|
40253
|
+
return path33.join(resolveHermesProfileDir(profileName), "mem0.json");
|
|
39590
40254
|
}
|
|
39591
40255
|
if (provider === "supermemory") {
|
|
39592
|
-
return
|
|
40256
|
+
return path33.join(resolveHermesProfileDir(profileName), "supermemory.json");
|
|
39593
40257
|
}
|
|
39594
40258
|
if (provider === "hindsight") {
|
|
39595
|
-
return
|
|
40259
|
+
return path33.join(
|
|
39596
40260
|
resolveHermesProfileDir(profileName),
|
|
39597
40261
|
"hindsight",
|
|
39598
40262
|
"config.json"
|
|
@@ -39601,19 +40265,19 @@ function memoryProviderConfigPath(profileName, provider) {
|
|
|
39601
40265
|
return null;
|
|
39602
40266
|
}
|
|
39603
40267
|
function customProviderConfigPath(profileName, provider) {
|
|
39604
|
-
return
|
|
40268
|
+
return path33.join(
|
|
39605
40269
|
resolveHermesProfileDir(profileName),
|
|
39606
40270
|
`${normalizeCustomProviderId(provider)}.json`
|
|
39607
40271
|
);
|
|
39608
40272
|
}
|
|
39609
40273
|
function customProviderRegistryPath(profileName) {
|
|
39610
|
-
return
|
|
40274
|
+
return path33.join(
|
|
39611
40275
|
resolveHermesProfileDir(profileName),
|
|
39612
40276
|
CUSTOM_PROVIDER_REGISTRY_FILE
|
|
39613
40277
|
);
|
|
39614
40278
|
}
|
|
39615
40279
|
async function readCustomProviderRegistry(profileName) {
|
|
39616
|
-
const raw = await
|
|
40280
|
+
const raw = await readFile20(customProviderRegistryPath(profileName), "utf8").catch(
|
|
39617
40281
|
(error) => {
|
|
39618
40282
|
if (isNodeError22(error, "ENOENT")) {
|
|
39619
40283
|
return "";
|
|
@@ -39633,11 +40297,11 @@ async function readCustomProviderRegistry(profileName) {
|
|
|
39633
40297
|
return { id: id2, label: id2, description: "\u81EA\u5B9A\u4E49 memory provider\u3002" };
|
|
39634
40298
|
}
|
|
39635
40299
|
const record = toRecord22(item);
|
|
39636
|
-
const id = normalizeCustomProviderId(
|
|
40300
|
+
const id = normalizeCustomProviderId(readString25(record.id) ?? "");
|
|
39637
40301
|
return {
|
|
39638
40302
|
id,
|
|
39639
|
-
label:
|
|
39640
|
-
description:
|
|
40303
|
+
label: readString25(record.label) ?? id,
|
|
40304
|
+
description: readString25(record.description) ?? "\u81EA\u5B9A\u4E49 memory provider\u3002"
|
|
39641
40305
|
};
|
|
39642
40306
|
}).filter((item) => item.id);
|
|
39643
40307
|
} catch {
|
|
@@ -39659,7 +40323,7 @@ async function saveCustomProviderRegistryEntry(profileName, provider) {
|
|
|
39659
40323
|
);
|
|
39660
40324
|
}
|
|
39661
40325
|
async function discoverUserMemoryProviderDescriptors(profileName) {
|
|
39662
|
-
const pluginsDir =
|
|
40326
|
+
const pluginsDir = path33.join(resolveHermesProfileDir(profileName), "plugins");
|
|
39663
40327
|
const entries = await readdir10(pluginsDir, { withFileTypes: true }).catch(
|
|
39664
40328
|
(error) => {
|
|
39665
40329
|
if (isNodeError22(error, "ENOENT")) {
|
|
@@ -39679,21 +40343,21 @@ async function discoverUserMemoryProviderDescriptors(profileName) {
|
|
|
39679
40343
|
} catch {
|
|
39680
40344
|
continue;
|
|
39681
40345
|
}
|
|
39682
|
-
const providerDir =
|
|
40346
|
+
const providerDir = path33.join(pluginsDir, entry.name);
|
|
39683
40347
|
if (!await isMemoryProviderPluginDir(providerDir)) {
|
|
39684
40348
|
continue;
|
|
39685
40349
|
}
|
|
39686
40350
|
const meta = await readPluginMetadata(providerDir);
|
|
39687
40351
|
descriptors.push({
|
|
39688
40352
|
id: providerId,
|
|
39689
|
-
label:
|
|
39690
|
-
description:
|
|
40353
|
+
label: readString25(meta.name) ?? providerId,
|
|
40354
|
+
description: readString25(meta.description) ?? "\u81EA\u5B9A\u4E49 memory provider\u3002"
|
|
39691
40355
|
});
|
|
39692
40356
|
}
|
|
39693
40357
|
return descriptors;
|
|
39694
40358
|
}
|
|
39695
40359
|
async function isUserMemoryProviderInstalled(profileName, provider) {
|
|
39696
|
-
const providerDir =
|
|
40360
|
+
const providerDir = path33.join(
|
|
39697
40361
|
resolveHermesProfileDir(profileName),
|
|
39698
40362
|
"plugins",
|
|
39699
40363
|
normalizeCustomProviderId(provider)
|
|
@@ -39701,7 +40365,7 @@ async function isUserMemoryProviderInstalled(profileName, provider) {
|
|
|
39701
40365
|
return isMemoryProviderPluginDir(providerDir);
|
|
39702
40366
|
}
|
|
39703
40367
|
async function isMemoryProviderPluginDir(providerDir) {
|
|
39704
|
-
const source = await
|
|
40368
|
+
const source = await readFile20(path33.join(providerDir, "__init__.py"), "utf8").catch(
|
|
39705
40369
|
(error) => {
|
|
39706
40370
|
if (isNodeError22(error, "ENOENT")) {
|
|
39707
40371
|
return "";
|
|
@@ -39713,7 +40377,7 @@ async function isMemoryProviderPluginDir(providerDir) {
|
|
|
39713
40377
|
return sample.includes("register_memory_provider") || sample.includes("MemoryProvider");
|
|
39714
40378
|
}
|
|
39715
40379
|
async function readPluginMetadata(providerDir) {
|
|
39716
|
-
const raw = await
|
|
40380
|
+
const raw = await readFile20(path33.join(providerDir, "plugin.yaml"), "utf8").catch(
|
|
39717
40381
|
(error) => {
|
|
39718
40382
|
if (isNodeError22(error, "ENOENT")) {
|
|
39719
40383
|
return "";
|
|
@@ -39725,10 +40389,10 @@ async function readPluginMetadata(providerDir) {
|
|
|
39725
40389
|
}
|
|
39726
40390
|
async function resolveByteRoverCli() {
|
|
39727
40391
|
const candidates = [
|
|
39728
|
-
...(process.env.PATH ?? "").split(
|
|
39729
|
-
|
|
40392
|
+
...(process.env.PATH ?? "").split(path33.delimiter).filter(Boolean).map((dir) => path33.join(dir, "brv")),
|
|
40393
|
+
path33.join(process.env.HOME ?? "", ".brv-cli", "bin", "brv"),
|
|
39730
40394
|
"/usr/local/bin/brv",
|
|
39731
|
-
|
|
40395
|
+
path33.join(process.env.HOME ?? "", ".npm-global", "bin", "brv")
|
|
39732
40396
|
].filter(Boolean);
|
|
39733
40397
|
for (const candidate of candidates) {
|
|
39734
40398
|
const found = await access3(candidate).then(() => true).catch(() => false);
|
|
@@ -39739,7 +40403,7 @@ async function resolveByteRoverCli() {
|
|
|
39739
40403
|
return null;
|
|
39740
40404
|
}
|
|
39741
40405
|
async function readHolographicProviderConfig(profileName) {
|
|
39742
|
-
const raw = await
|
|
40406
|
+
const raw = await readFile20(resolveHermesConfigPath(profileName), "utf8").catch(
|
|
39743
40407
|
(error) => {
|
|
39744
40408
|
if (isNodeError22(error, "ENOENT")) {
|
|
39745
40409
|
return "";
|
|
@@ -39753,7 +40417,7 @@ async function readHolographicProviderConfig(profileName) {
|
|
|
39753
40417
|
}
|
|
39754
40418
|
async function patchHolographicProviderConfig(profileName, patch) {
|
|
39755
40419
|
const configPath = resolveHermesConfigPath(profileName);
|
|
39756
|
-
const existingRaw = await
|
|
40420
|
+
const existingRaw = await readFile20(configPath, "utf8").catch(
|
|
39757
40421
|
(error) => {
|
|
39758
40422
|
if (isNodeError22(error, "ENOENT")) {
|
|
39759
40423
|
return null;
|
|
@@ -39789,8 +40453,8 @@ async function patchHermesMemoryEnv(profileName, patch) {
|
|
|
39789
40453
|
if (entries.length === 0) {
|
|
39790
40454
|
return;
|
|
39791
40455
|
}
|
|
39792
|
-
const envPath =
|
|
39793
|
-
const existingRaw = await
|
|
40456
|
+
const envPath = path33.join(resolveHermesProfileDir(profileName), ".env");
|
|
40457
|
+
const existingRaw = await readFile20(envPath, "utf8").catch((error) => {
|
|
39794
40458
|
if (isNodeError22(error, "ENOENT")) {
|
|
39795
40459
|
return "";
|
|
39796
40460
|
}
|
|
@@ -39849,7 +40513,7 @@ function isMemoryEnvKeyWritable(key) {
|
|
|
39849
40513
|
].includes(key);
|
|
39850
40514
|
}
|
|
39851
40515
|
function normalizeHindsightMode(value) {
|
|
39852
|
-
const mode =
|
|
40516
|
+
const mode = readString25(value) ?? "cloud";
|
|
39853
40517
|
return mode === "local" ? "local_embedded" : mode;
|
|
39854
40518
|
}
|
|
39855
40519
|
function normalizeHttpUrl2(value) {
|
|
@@ -39918,31 +40582,31 @@ function parseJsonObject2(text) {
|
|
|
39918
40582
|
}
|
|
39919
40583
|
}
|
|
39920
40584
|
function readHindsightError(json) {
|
|
39921
|
-
const detail =
|
|
40585
|
+
const detail = readString25(json.detail) ?? readString25(json.error);
|
|
39922
40586
|
return detail ? `\uFF1A${detail}` : "";
|
|
39923
40587
|
}
|
|
39924
40588
|
function hindsightSemanticIssue(pathName, json) {
|
|
39925
40589
|
if (pathName === "/health") {
|
|
39926
|
-
const status =
|
|
40590
|
+
const status = readString25(json.status);
|
|
39927
40591
|
return status && ["healthy", "ok"].includes(status.toLowerCase()) ? null : `\u5065\u5EB7\u72B6\u6001\u5F02\u5E38\uFF1A${status ?? "unknown"}`;
|
|
39928
40592
|
}
|
|
39929
40593
|
return null;
|
|
39930
40594
|
}
|
|
39931
40595
|
function summarizeHindsightProbe(pathName, json) {
|
|
39932
40596
|
if (pathName === "/health") {
|
|
39933
|
-
const status =
|
|
39934
|
-
const database =
|
|
40597
|
+
const status = readString25(json.status) ?? "ok";
|
|
40598
|
+
const database = readString25(json.database);
|
|
39935
40599
|
return database ? `${status}, database ${database}` : status;
|
|
39936
40600
|
}
|
|
39937
40601
|
if (pathName === "/version") {
|
|
39938
|
-
const version =
|
|
40602
|
+
const version = readString25(json.api_version);
|
|
39939
40603
|
return version ? `API ${version}` : "version endpoint reachable";
|
|
39940
40604
|
}
|
|
39941
|
-
const bankId =
|
|
40605
|
+
const bankId = readString25(json.bank_id);
|
|
39942
40606
|
return bankId ? `bank ${bankId} reachable` : "bank config reachable";
|
|
39943
40607
|
}
|
|
39944
40608
|
async function readActiveMemoryProvider(profileName) {
|
|
39945
|
-
const raw = await
|
|
40609
|
+
const raw = await readFile20(
|
|
39946
40610
|
resolveHermesConfigPath(profileName),
|
|
39947
40611
|
"utf8"
|
|
39948
40612
|
).catch((error) => {
|
|
@@ -39953,14 +40617,14 @@ async function readActiveMemoryProvider(profileName) {
|
|
|
39953
40617
|
});
|
|
39954
40618
|
const config = raw ? toRecord22(YAML6.parse(raw)) : {};
|
|
39955
40619
|
const memory = toRecord22(config.memory);
|
|
39956
|
-
const provider =
|
|
40620
|
+
const provider = readString25(memory.provider);
|
|
39957
40621
|
if (!provider || provider === "built-in" || provider === "builtin" || provider === "built_in") {
|
|
39958
40622
|
return null;
|
|
39959
40623
|
}
|
|
39960
40624
|
return provider;
|
|
39961
40625
|
}
|
|
39962
40626
|
async function patchJsonProviderConfig(profileName, relativePath, patch) {
|
|
39963
|
-
const configPath =
|
|
40627
|
+
const configPath = path33.join(
|
|
39964
40628
|
resolveHermesProfileDir(profileName),
|
|
39965
40629
|
relativePath
|
|
39966
40630
|
);
|
|
@@ -39978,7 +40642,7 @@ async function patchJsonProviderConfig(profileName, relativePath, patch) {
|
|
|
39978
40642
|
);
|
|
39979
40643
|
}
|
|
39980
40644
|
async function readJsonObject(filePath) {
|
|
39981
|
-
const raw = await
|
|
40645
|
+
const raw = await readFile20(filePath, "utf8").catch((error) => {
|
|
39982
40646
|
if (isNodeError22(error, "ENOENT")) {
|
|
39983
40647
|
return "{}";
|
|
39984
40648
|
}
|
|
@@ -39989,7 +40653,7 @@ async function readJsonObject(filePath) {
|
|
|
39989
40653
|
} catch {
|
|
39990
40654
|
throw new HermesMemoryError(
|
|
39991
40655
|
"memory_provider_config_invalid",
|
|
39992
|
-
`${
|
|
40656
|
+
`${path33.basename(filePath)} \u4E0D\u662F\u6709\u6548\u7684 JSON \u914D\u7F6E\u6587\u4EF6\u3002`
|
|
39993
40657
|
);
|
|
39994
40658
|
}
|
|
39995
40659
|
}
|
|
@@ -40010,7 +40674,7 @@ function stringSetting(key, label, value, editable = true) {
|
|
|
40010
40674
|
return {
|
|
40011
40675
|
key,
|
|
40012
40676
|
label,
|
|
40013
|
-
value:
|
|
40677
|
+
value: readString25(value) ?? "",
|
|
40014
40678
|
editable,
|
|
40015
40679
|
kind: "string"
|
|
40016
40680
|
};
|
|
@@ -40022,7 +40686,7 @@ function secretSetting(key, label, value, configured) {
|
|
|
40022
40686
|
value: "",
|
|
40023
40687
|
editable: true,
|
|
40024
40688
|
kind: "secret",
|
|
40025
|
-
configured: configured || isConfiguredEnvValue(
|
|
40689
|
+
configured: configured || isConfiguredEnvValue(readString25(value))
|
|
40026
40690
|
};
|
|
40027
40691
|
}
|
|
40028
40692
|
function textSetting(key, label, value, editable = true) {
|
|
@@ -40035,11 +40699,11 @@ function textSetting(key, label, value, editable = true) {
|
|
|
40035
40699
|
};
|
|
40036
40700
|
}
|
|
40037
40701
|
function selectSetting(key, label, value, options, editable = true) {
|
|
40038
|
-
const stringValue =
|
|
40702
|
+
const stringValue = readString25(value) ?? options[0] ?? null;
|
|
40039
40703
|
return { key, label, value: stringValue, editable, kind: "select", options };
|
|
40040
40704
|
}
|
|
40041
40705
|
async function readMemoryLimits(profileName) {
|
|
40042
|
-
const raw = await
|
|
40706
|
+
const raw = await readFile20(
|
|
40043
40707
|
resolveHermesConfigPath(profileName),
|
|
40044
40708
|
"utf8"
|
|
40045
40709
|
).catch((error) => {
|
|
@@ -40108,7 +40772,7 @@ function hashString(value) {
|
|
|
40108
40772
|
function toRecord22(value) {
|
|
40109
40773
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
|
|
40110
40774
|
}
|
|
40111
|
-
function
|
|
40775
|
+
function readString25(value) {
|
|
40112
40776
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
40113
40777
|
}
|
|
40114
40778
|
function readPositiveInteger4(value) {
|
|
@@ -40267,7 +40931,7 @@ function registerProfileMemoryRoutes(router, options) {
|
|
|
40267
40931
|
);
|
|
40268
40932
|
}
|
|
40269
40933
|
function readMemoryTarget(body) {
|
|
40270
|
-
const raw =
|
|
40934
|
+
const raw = readString23(body, "target");
|
|
40271
40935
|
if (raw === "memory" || raw === "user") {
|
|
40272
40936
|
return raw;
|
|
40273
40937
|
}
|
|
@@ -40278,7 +40942,7 @@ function readMemoryTarget(body) {
|
|
|
40278
40942
|
);
|
|
40279
40943
|
}
|
|
40280
40944
|
function readMemoryResetTarget(body) {
|
|
40281
|
-
const raw =
|
|
40945
|
+
const raw = readString23(body, "target") ?? "all";
|
|
40282
40946
|
if (raw === "all" || raw === "memory" || raw === "user") {
|
|
40283
40947
|
return raw;
|
|
40284
40948
|
}
|
|
@@ -40289,7 +40953,7 @@ function readMemoryResetTarget(body) {
|
|
|
40289
40953
|
);
|
|
40290
40954
|
}
|
|
40291
40955
|
function readRequiredMemoryContent(body) {
|
|
40292
|
-
const content =
|
|
40956
|
+
const content = readString23(body, "content") ?? readString23(body, "text");
|
|
40293
40957
|
if (!content) {
|
|
40294
40958
|
throw new LinkHttpError(
|
|
40295
40959
|
400,
|
|
@@ -40300,7 +40964,7 @@ function readRequiredMemoryContent(body) {
|
|
|
40300
40964
|
return content;
|
|
40301
40965
|
}
|
|
40302
40966
|
function readRequiredMemoryMatch(body) {
|
|
40303
|
-
const oldText =
|
|
40967
|
+
const oldText = readString23(body, "old_text") ?? readString23(body, "oldText") ?? readString23(body, "match");
|
|
40304
40968
|
if (!oldText) {
|
|
40305
40969
|
throw new LinkHttpError(
|
|
40306
40970
|
400,
|
|
@@ -40311,7 +40975,7 @@ function readRequiredMemoryMatch(body) {
|
|
|
40311
40975
|
return oldText;
|
|
40312
40976
|
}
|
|
40313
40977
|
function readRequiredMemoryProvider(body) {
|
|
40314
|
-
const provider =
|
|
40978
|
+
const provider = readString23(body, "provider") ?? readString23(body, "provider_id") ?? readString23(body, "providerId");
|
|
40315
40979
|
if (!provider) {
|
|
40316
40980
|
throw new LinkHttpError(
|
|
40317
40981
|
400,
|
|
@@ -40341,7 +41005,7 @@ function readMemorySettingsPatch(body, options = {}) {
|
|
|
40341
41005
|
input.userCharLimit = userCharLimit;
|
|
40342
41006
|
}
|
|
40343
41007
|
}
|
|
40344
|
-
const mode =
|
|
41008
|
+
const mode = readString23(body, "mode");
|
|
40345
41009
|
if (mode) {
|
|
40346
41010
|
input.mode = mode;
|
|
40347
41011
|
}
|
|
@@ -40357,7 +41021,7 @@ function readMemorySettingsPatch(body, options = {}) {
|
|
|
40357
41021
|
if (bankId !== void 0) {
|
|
40358
41022
|
input.bankId = bankId;
|
|
40359
41023
|
}
|
|
40360
|
-
const llmProvider =
|
|
41024
|
+
const llmProvider = readString23(body, "llm_provider") ?? readString23(body, "llmProvider");
|
|
40361
41025
|
if (llmProvider) {
|
|
40362
41026
|
input.llmProvider = llmProvider;
|
|
40363
41027
|
}
|
|
@@ -40393,11 +41057,11 @@ function readMemorySettingsPatch(body, options = {}) {
|
|
|
40393
41057
|
if (autoRetain !== void 0) {
|
|
40394
41058
|
input.autoRetain = autoRetain;
|
|
40395
41059
|
}
|
|
40396
|
-
const memoryMode =
|
|
41060
|
+
const memoryMode = readString23(body, "memory_mode") ?? readString23(body, "memoryMode");
|
|
40397
41061
|
if (memoryMode) {
|
|
40398
41062
|
input.memoryMode = memoryMode;
|
|
40399
41063
|
}
|
|
40400
|
-
const recallBudget =
|
|
41064
|
+
const recallBudget = readString23(body, "recall_budget") ?? readString23(body, "recallBudget");
|
|
40401
41065
|
if (recallBudget) {
|
|
40402
41066
|
input.recallBudget = recallBudget;
|
|
40403
41067
|
}
|
|
@@ -40413,11 +41077,11 @@ function readMemorySettingsPatch(body, options = {}) {
|
|
|
40413
41077
|
if (profileFrequency !== void 0) {
|
|
40414
41078
|
input.profileFrequency = profileFrequency;
|
|
40415
41079
|
}
|
|
40416
|
-
const captureMode =
|
|
41080
|
+
const captureMode = readString23(body, "capture_mode") ?? readString23(body, "captureMode");
|
|
40417
41081
|
if (captureMode) {
|
|
40418
41082
|
input.captureMode = captureMode;
|
|
40419
41083
|
}
|
|
40420
|
-
const searchMode =
|
|
41084
|
+
const searchMode = readString23(body, "search_mode") ?? readString23(body, "searchMode");
|
|
40421
41085
|
if (searchMode) {
|
|
40422
41086
|
input.searchMode = searchMode;
|
|
40423
41087
|
}
|
|
@@ -40451,11 +41115,11 @@ function readMemorySettingsPatch(body, options = {}) {
|
|
|
40451
41115
|
if (aiPeer !== void 0) {
|
|
40452
41116
|
input.aiPeer = aiPeer;
|
|
40453
41117
|
}
|
|
40454
|
-
const recallMode =
|
|
41118
|
+
const recallMode = readString23(body, "recall_mode") ?? readString23(body, "recallMode");
|
|
40455
41119
|
if (recallMode) {
|
|
40456
41120
|
input.recallMode = recallMode;
|
|
40457
41121
|
}
|
|
40458
|
-
const writeFrequency =
|
|
41122
|
+
const writeFrequency = readString23(body, "write_frequency") ?? readString23(body, "writeFrequency");
|
|
40459
41123
|
if (writeFrequency) {
|
|
40460
41124
|
input.writeFrequency = writeFrequency;
|
|
40461
41125
|
}
|
|
@@ -40463,7 +41127,7 @@ function readMemorySettingsPatch(body, options = {}) {
|
|
|
40463
41127
|
if (saveMessages !== void 0) {
|
|
40464
41128
|
input.saveMessages = saveMessages;
|
|
40465
41129
|
}
|
|
40466
|
-
const sessionStrategy =
|
|
41130
|
+
const sessionStrategy = readString23(body, "session_strategy") ?? readString23(body, "sessionStrategy");
|
|
40467
41131
|
if (sessionStrategy) {
|
|
40468
41132
|
input.sessionStrategy = sessionStrategy;
|
|
40469
41133
|
}
|
|
@@ -40612,8 +41276,8 @@ function toMemoryHttpError(error) {
|
|
|
40612
41276
|
}
|
|
40613
41277
|
|
|
40614
41278
|
// src/hermes/skills.ts
|
|
40615
|
-
import { readFile as
|
|
40616
|
-
import
|
|
41279
|
+
import { readFile as readFile21, readdir as readdir11 } from "fs/promises";
|
|
41280
|
+
import path34 from "path";
|
|
40617
41281
|
import YAML7 from "yaml";
|
|
40618
41282
|
var HermesSkillNotFoundError = class extends Error {
|
|
40619
41283
|
constructor(skillName) {
|
|
@@ -40627,7 +41291,7 @@ var EXCLUDED_SKILL_DIRS = /* @__PURE__ */ new Set([".git", ".github", ".hub"]);
|
|
|
40627
41291
|
async function listHermesProfileSkills(profileName, paths = resolveRuntimePaths()) {
|
|
40628
41292
|
const profile = await readExistingProfile(profileName, paths);
|
|
40629
41293
|
const profileDir = resolveHermesProfileDir(profile.name);
|
|
40630
|
-
const skillsRoot =
|
|
41294
|
+
const skillsRoot = path34.join(profileDir, "skills");
|
|
40631
41295
|
const [skillFiles, disabled, provenance] = await Promise.all([
|
|
40632
41296
|
findSkillFiles(skillsRoot),
|
|
40633
41297
|
readDisabledSkillNames(resolveHermesConfigPath(profile.name)),
|
|
@@ -40718,7 +41382,7 @@ async function collectSkillFiles(directory, results) {
|
|
|
40718
41382
|
if (EXCLUDED_SKILL_DIRS.has(entry.name)) {
|
|
40719
41383
|
continue;
|
|
40720
41384
|
}
|
|
40721
|
-
const entryPath =
|
|
41385
|
+
const entryPath = path34.join(directory, entry.name);
|
|
40722
41386
|
if (entry.isDirectory()) {
|
|
40723
41387
|
await collectSkillFiles(entryPath, results);
|
|
40724
41388
|
continue;
|
|
@@ -40729,7 +41393,7 @@ async function collectSkillFiles(directory, results) {
|
|
|
40729
41393
|
}
|
|
40730
41394
|
}
|
|
40731
41395
|
async function readSkillMetadata(input) {
|
|
40732
|
-
const raw = await
|
|
41396
|
+
const raw = await readFile21(input.skillFile, "utf8").catch(
|
|
40733
41397
|
(error) => {
|
|
40734
41398
|
if (isNodeError23(error, "ENOENT") || isNodeError23(error, "EACCES")) {
|
|
40735
41399
|
return null;
|
|
@@ -40740,16 +41404,16 @@ async function readSkillMetadata(input) {
|
|
|
40740
41404
|
if (raw === null) {
|
|
40741
41405
|
return null;
|
|
40742
41406
|
}
|
|
40743
|
-
const skillDir =
|
|
41407
|
+
const skillDir = path34.dirname(input.skillFile);
|
|
40744
41408
|
const { frontmatter, body } = parseSkillDocument(raw.slice(0, 4e3));
|
|
40745
41409
|
const name = normalizeSkillName(
|
|
40746
|
-
|
|
41410
|
+
readString26(frontmatter.name) ?? path34.basename(skillDir)
|
|
40747
41411
|
);
|
|
40748
41412
|
if (!name) {
|
|
40749
41413
|
return null;
|
|
40750
41414
|
}
|
|
40751
41415
|
const description = normalizeDescription(
|
|
40752
|
-
|
|
41416
|
+
readString26(frontmatter.description) ?? firstBodyDescription(body)
|
|
40753
41417
|
);
|
|
40754
41418
|
const provenance = input.provenance.get(name) ?? {
|
|
40755
41419
|
source: "local",
|
|
@@ -40762,7 +41426,7 @@ async function readSkillMetadata(input) {
|
|
|
40762
41426
|
enabled: !input.disabled.has(name),
|
|
40763
41427
|
source: provenance.source,
|
|
40764
41428
|
trust: provenance.trust,
|
|
40765
|
-
relativePath:
|
|
41429
|
+
relativePath: path34.relative(input.skillsRoot, skillDir)
|
|
40766
41430
|
};
|
|
40767
41431
|
}
|
|
40768
41432
|
function parseSkillDocument(raw) {
|
|
@@ -40783,8 +41447,8 @@ function parseSkillDocument(raw) {
|
|
|
40783
41447
|
}
|
|
40784
41448
|
}
|
|
40785
41449
|
function categoryFromPath(skillsRoot, skillFile) {
|
|
40786
|
-
const relative =
|
|
40787
|
-
const parts = relative.split(
|
|
41450
|
+
const relative = path34.relative(skillsRoot, skillFile);
|
|
41451
|
+
const parts = relative.split(path34.sep).filter(Boolean);
|
|
40788
41452
|
return parts.length >= 3 ? parts[0] : null;
|
|
40789
41453
|
}
|
|
40790
41454
|
function firstBodyDescription(body) {
|
|
@@ -40807,7 +41471,7 @@ function normalizeDescription(value) {
|
|
|
40807
41471
|
return `${description.slice(0, MAX_DESCRIPTION_LENGTH - 3)}...`;
|
|
40808
41472
|
}
|
|
40809
41473
|
async function readDisabledSkillNames(configPath) {
|
|
40810
|
-
const raw = await
|
|
41474
|
+
const raw = await readFile21(configPath, "utf8").catch((error) => {
|
|
40811
41475
|
if (isNodeError23(error, "ENOENT")) {
|
|
40812
41476
|
return "";
|
|
40813
41477
|
}
|
|
@@ -40831,7 +41495,7 @@ async function readSkillProvenance(root) {
|
|
|
40831
41495
|
return provenance;
|
|
40832
41496
|
}
|
|
40833
41497
|
async function readBundledSkillNames(root) {
|
|
40834
|
-
const raw = await
|
|
41498
|
+
const raw = await readFile21(path34.join(root, ".bundled_manifest"), "utf8").catch(
|
|
40835
41499
|
(error) => {
|
|
40836
41500
|
if (isNodeError23(error, "ENOENT")) {
|
|
40837
41501
|
return "";
|
|
@@ -40854,7 +41518,7 @@ async function readBundledSkillNames(root) {
|
|
|
40854
41518
|
return names;
|
|
40855
41519
|
}
|
|
40856
41520
|
async function readHubInstalledSkills(root) {
|
|
40857
|
-
const raw = await
|
|
41521
|
+
const raw = await readFile21(path34.join(root, ".hub", "lock.json"), "utf8").catch(
|
|
40858
41522
|
(error) => {
|
|
40859
41523
|
if (isNodeError23(error, "ENOENT")) {
|
|
40860
41524
|
return "";
|
|
@@ -40876,8 +41540,8 @@ async function readHubInstalledSkills(root) {
|
|
|
40876
41540
|
for (const [name, rawEntry] of Object.entries(installed2)) {
|
|
40877
41541
|
const entry = toRecord23(rawEntry);
|
|
40878
41542
|
result.set(normalizeSkillName(name), {
|
|
40879
|
-
source:
|
|
40880
|
-
trust:
|
|
41543
|
+
source: readString26(entry.source) ?? "hub",
|
|
41544
|
+
trust: readString26(entry.trust_level) ?? null
|
|
40881
41545
|
});
|
|
40882
41546
|
}
|
|
40883
41547
|
return result;
|
|
@@ -40926,7 +41590,7 @@ function compareCategoryNames(left, right) {
|
|
|
40926
41590
|
return left.localeCompare(right);
|
|
40927
41591
|
}
|
|
40928
41592
|
async function readHermesConfigDocument4(configPath) {
|
|
40929
|
-
const existingRaw = await
|
|
41593
|
+
const existingRaw = await readFile21(configPath, "utf8").catch(
|
|
40930
41594
|
(error) => {
|
|
40931
41595
|
if (isNodeError23(error, "ENOENT")) {
|
|
40932
41596
|
return null;
|
|
@@ -40961,7 +41625,7 @@ function readStringList6(value) {
|
|
|
40961
41625
|
}
|
|
40962
41626
|
return value.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean);
|
|
40963
41627
|
}
|
|
40964
|
-
function
|
|
41628
|
+
function readString26(value) {
|
|
40965
41629
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
40966
41630
|
}
|
|
40967
41631
|
function toRecord23(value) {
|
|
@@ -41333,7 +41997,7 @@ function registerRunRoutes(router, options) {
|
|
|
41333
41997
|
await authenticateRequest(ctx, paths);
|
|
41334
41998
|
const language = readPreferredLanguage(ctx);
|
|
41335
41999
|
const body = await readJsonBody(ctx.req);
|
|
41336
|
-
const input =
|
|
42000
|
+
const input = readString23(body, "input");
|
|
41337
42001
|
if (!input) {
|
|
41338
42002
|
throw new LinkHttpError(400, "run_input_required", "input is required");
|
|
41339
42003
|
}
|
|
@@ -41341,12 +42005,12 @@ function registerRunRoutes(router, options) {
|
|
|
41341
42005
|
ctx.body = await createHermesRun(
|
|
41342
42006
|
{
|
|
41343
42007
|
input,
|
|
41344
|
-
instructions:
|
|
42008
|
+
instructions: readString23(body, "instructions") ?? void 0,
|
|
41345
42009
|
conversation_history: readConversationHistory(
|
|
41346
42010
|
body.conversation_history ?? body.conversationHistory
|
|
41347
42011
|
),
|
|
41348
|
-
session_id:
|
|
41349
|
-
session_key:
|
|
42012
|
+
session_id: readString23(body, "session_id") ?? readString23(body, "sessionId") ?? void 0,
|
|
42013
|
+
session_key: readString23(body, "session_key") ?? readString23(body, "sessionKey") ?? void 0
|
|
41350
42014
|
},
|
|
41351
42015
|
{ logger, profileName: readOptionalProfileName(body), language }
|
|
41352
42016
|
);
|
|
@@ -41521,8 +42185,8 @@ function readModelList(payload) {
|
|
|
41521
42185
|
// src/hermes/updates.ts
|
|
41522
42186
|
import { EventEmitter as EventEmitter3 } from "events";
|
|
41523
42187
|
import { spawn as spawn4 } from "child_process";
|
|
41524
|
-
import { mkdir as mkdir14, readFile as
|
|
41525
|
-
import
|
|
42188
|
+
import { mkdir as mkdir14, readFile as readFile22, rm as rm8 } from "fs/promises";
|
|
42189
|
+
import path35 from "path";
|
|
41526
42190
|
var SERVER_HERMES_RELEASES_LATEST_PATH = "/api/v1/hermes-agent/releases/latest";
|
|
41527
42191
|
var RELEASE_CACHE_TTL_MS = 6 * 60 * 60 * 1e3;
|
|
41528
42192
|
var RELEASE_FETCH_TIMEOUT_MS = 5e3;
|
|
@@ -41759,20 +42423,20 @@ function normalizeServerReleaseSnapshot(payload) {
|
|
|
41759
42423
|
const remote = toNullableRecord(snapshot.remote);
|
|
41760
42424
|
return {
|
|
41761
42425
|
remote: remote ? normalizeServerRelease(remote) : null,
|
|
41762
|
-
cacheState:
|
|
41763
|
-
issue:
|
|
42426
|
+
cacheState: readString27(snapshot, "cache_state") ?? readString27(snapshot, "cacheState"),
|
|
42427
|
+
issue: readString27(snapshot, "issue")
|
|
41764
42428
|
};
|
|
41765
42429
|
}
|
|
41766
42430
|
function normalizeServerRelease(payload) {
|
|
41767
|
-
const tag =
|
|
41768
|
-
const name =
|
|
42431
|
+
const tag = readString27(payload, "tag");
|
|
42432
|
+
const name = readString27(payload, "name");
|
|
41769
42433
|
return {
|
|
41770
|
-
version:
|
|
42434
|
+
version: readString27(payload, "version") ?? extractSemver(name) ?? extractTagSemver(tag),
|
|
41771
42435
|
tag,
|
|
41772
42436
|
name,
|
|
41773
|
-
releaseUrl:
|
|
41774
|
-
publishedAt:
|
|
41775
|
-
fetchedAt:
|
|
42437
|
+
releaseUrl: readString27(payload, "releaseUrl") ?? readString27(payload, "release_url"),
|
|
42438
|
+
publishedAt: readString27(payload, "publishedAt") ?? readString27(payload, "published_at"),
|
|
42439
|
+
fetchedAt: readString27(payload, "fetchedAt") ?? readString27(payload, "fetched_at") ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
41776
42440
|
};
|
|
41777
42441
|
}
|
|
41778
42442
|
async function readReleaseCache(paths) {
|
|
@@ -41791,7 +42455,7 @@ async function writeUpdateState(paths, state) {
|
|
|
41791
42455
|
await writeJsonFile(updateStatePath(paths), state);
|
|
41792
42456
|
}
|
|
41793
42457
|
async function readUpdateLogLines(paths) {
|
|
41794
|
-
const raw = await
|
|
42458
|
+
const raw = await readFile22(updateLogPath(paths), "utf8").catch(() => "");
|
|
41795
42459
|
if (!raw.trim()) {
|
|
41796
42460
|
return [];
|
|
41797
42461
|
}
|
|
@@ -41800,13 +42464,13 @@ async function readUpdateLogLines(paths) {
|
|
|
41800
42464
|
);
|
|
41801
42465
|
}
|
|
41802
42466
|
function releaseCachePath(paths) {
|
|
41803
|
-
return
|
|
42467
|
+
return path35.join(paths.indexesDir, "hermes-release-check.json");
|
|
41804
42468
|
}
|
|
41805
42469
|
function updateStatePath(paths) {
|
|
41806
|
-
return
|
|
42470
|
+
return path35.join(paths.runDir, "hermes-update-state.json");
|
|
41807
42471
|
}
|
|
41808
42472
|
function updateLogPath(paths) {
|
|
41809
|
-
return
|
|
42473
|
+
return path35.join(paths.logsDir, UPDATE_LOG_FILE);
|
|
41810
42474
|
}
|
|
41811
42475
|
async function clearUpdateLogFiles(paths) {
|
|
41812
42476
|
const primary = updateLogPath(paths);
|
|
@@ -41898,7 +42562,7 @@ function isRecentRunningState2(state) {
|
|
|
41898
42562
|
const startedAt = Date.parse(state.started_at);
|
|
41899
42563
|
return Number.isFinite(startedAt) && Date.now() - startedAt < 3e4;
|
|
41900
42564
|
}
|
|
41901
|
-
function
|
|
42565
|
+
function readString27(payload, key) {
|
|
41902
42566
|
const value = payload[key];
|
|
41903
42567
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
41904
42568
|
}
|
|
@@ -41906,13 +42570,13 @@ function readString26(payload, key) {
|
|
|
41906
42570
|
// src/link/updates.ts
|
|
41907
42571
|
import { spawn as spawn6 } from "child_process";
|
|
41908
42572
|
import { EventEmitter as EventEmitter4 } from "events";
|
|
41909
|
-
import { mkdir as mkdir17, readFile as
|
|
41910
|
-
import
|
|
42573
|
+
import { mkdir as mkdir17, readFile as readFile24, rm as rm11 } from "fs/promises";
|
|
42574
|
+
import path37 from "path";
|
|
41911
42575
|
|
|
41912
42576
|
// src/daemon/process.ts
|
|
41913
42577
|
import { spawn as spawn5 } from "child_process";
|
|
41914
|
-
import { mkdir as mkdir16, readFile as
|
|
41915
|
-
import
|
|
42578
|
+
import { mkdir as mkdir16, readFile as readFile23, rm as rm10, writeFile as writeFile4 } from "fs/promises";
|
|
42579
|
+
import path36 from "path";
|
|
41916
42580
|
|
|
41917
42581
|
// src/daemon/service.ts
|
|
41918
42582
|
import { createServer } from "http";
|
|
@@ -43940,7 +44604,7 @@ async function runDaemonSupervisor(paths = resolveRuntimePaths()) {
|
|
|
43940
44604
|
await mkdir16(paths.logsDir, { recursive: true, mode: 448 });
|
|
43941
44605
|
const log = createRotatingTextLogWriter({
|
|
43942
44606
|
paths,
|
|
43943
|
-
fileName:
|
|
44607
|
+
fileName: path36.basename(daemonLogFile(paths))
|
|
43944
44608
|
});
|
|
43945
44609
|
const scriptPath = currentCliScriptPath();
|
|
43946
44610
|
const write = (chunk) => {
|
|
@@ -44120,7 +44784,7 @@ function currentCliScriptPath() {
|
|
|
44120
44784
|
return process.argv[1];
|
|
44121
44785
|
}
|
|
44122
44786
|
async function readPid(filePath) {
|
|
44123
|
-
const raw = await
|
|
44787
|
+
const raw = await readFile23(filePath, "utf8").catch(() => null);
|
|
44124
44788
|
if (!raw) {
|
|
44125
44789
|
return null;
|
|
44126
44790
|
}
|
|
@@ -44239,7 +44903,7 @@ function terminateChild(child, previousForceKillTimer) {
|
|
|
44239
44903
|
}
|
|
44240
44904
|
}
|
|
44241
44905
|
function supervisorStopIntentPath(paths) {
|
|
44242
|
-
return
|
|
44906
|
+
return path36.join(paths.runDir, "supervisor-stop-intent.json");
|
|
44243
44907
|
}
|
|
44244
44908
|
async function writeSupervisorStopIntent(paths, pid) {
|
|
44245
44909
|
await mkdir16(paths.runDir, { recursive: true, mode: 448 });
|
|
@@ -44252,7 +44916,7 @@ async function writeSupervisorStopIntent(paths, pid) {
|
|
|
44252
44916
|
}
|
|
44253
44917
|
async function consumeSupervisorStopIntent(paths, pid) {
|
|
44254
44918
|
const filePath = supervisorStopIntentPath(paths);
|
|
44255
|
-
const raw = await
|
|
44919
|
+
const raw = await readFile23(filePath, "utf8").catch(() => null);
|
|
44256
44920
|
if (!raw) {
|
|
44257
44921
|
return false;
|
|
44258
44922
|
}
|
|
@@ -44270,7 +44934,7 @@ async function consumeSupervisorStopIntent(paths, pid) {
|
|
|
44270
44934
|
}
|
|
44271
44935
|
async function clearExpiredSupervisorStopIntent(paths) {
|
|
44272
44936
|
const filePath = supervisorStopIntentPath(paths);
|
|
44273
|
-
const raw = await
|
|
44937
|
+
const raw = await readFile23(filePath, "utf8").catch(() => null);
|
|
44274
44938
|
if (!raw) {
|
|
44275
44939
|
return;
|
|
44276
44940
|
}
|
|
@@ -44719,16 +45383,16 @@ function normalizeServerSnapshot(payload) {
|
|
|
44719
45383
|
if (!policy) {
|
|
44720
45384
|
return {
|
|
44721
45385
|
remote: null,
|
|
44722
|
-
issue:
|
|
45386
|
+
issue: readString28(snapshot, "issue")
|
|
44723
45387
|
};
|
|
44724
45388
|
}
|
|
44725
45389
|
const release = toNullableRecord2(snapshot.release);
|
|
44726
|
-
const currentVersion =
|
|
44727
|
-
const minSafeVersion =
|
|
45390
|
+
const currentVersion = readString28(policy, "current_version") ?? readString28(policy, "currentVersion");
|
|
45391
|
+
const minSafeVersion = readString28(policy, "min_safe_version") ?? readString28(policy, "minSafeVersion");
|
|
44728
45392
|
if (!currentVersion) {
|
|
44729
45393
|
return {
|
|
44730
45394
|
remote: null,
|
|
44731
|
-
issue:
|
|
45395
|
+
issue: readString28(snapshot, "issue")
|
|
44732
45396
|
};
|
|
44733
45397
|
}
|
|
44734
45398
|
return {
|
|
@@ -44736,10 +45400,10 @@ function normalizeServerSnapshot(payload) {
|
|
|
44736
45400
|
current_version: currentVersion,
|
|
44737
45401
|
min_safe_version: minSafeVersion,
|
|
44738
45402
|
target_version: currentVersion,
|
|
44739
|
-
release_url: release ?
|
|
44740
|
-
published_at: release ?
|
|
45403
|
+
release_url: release ? readString28(release, "release_url") ?? readString28(release, "releaseUrl") : null,
|
|
45404
|
+
published_at: release ? readString28(release, "published_at") ?? readString28(release, "publishedAt") : null
|
|
44741
45405
|
},
|
|
44742
|
-
issue:
|
|
45406
|
+
issue: readString28(snapshot, "issue")
|
|
44743
45407
|
};
|
|
44744
45408
|
}
|
|
44745
45409
|
async function fetchCurrentLinkReleaseFromServer(options, fetcher, channel) {
|
|
@@ -44802,7 +45466,7 @@ async function buildOfficialInstallCommand(options, targetVersion) {
|
|
|
44802
45466
|
};
|
|
44803
45467
|
}
|
|
44804
45468
|
function buildUnixInstallCommand(installerUrl) {
|
|
44805
|
-
const nodeBinDir =
|
|
45469
|
+
const nodeBinDir = path37.dirname(process.execPath);
|
|
44806
45470
|
const fetchScript = [
|
|
44807
45471
|
quoteShellToken(process.execPath),
|
|
44808
45472
|
"--input-type=module",
|
|
@@ -45063,7 +45727,7 @@ async function writeUpdateState2(paths, state) {
|
|
|
45063
45727
|
await writeJsonFile(updateStatePath2(paths), state);
|
|
45064
45728
|
}
|
|
45065
45729
|
async function readUpdateLogLines2(paths) {
|
|
45066
|
-
const raw = await
|
|
45730
|
+
const raw = await readFile24(updateLogPath2(paths), "utf8").catch(() => "");
|
|
45067
45731
|
if (!raw.trim()) {
|
|
45068
45732
|
return [];
|
|
45069
45733
|
}
|
|
@@ -45072,10 +45736,10 @@ async function readUpdateLogLines2(paths) {
|
|
|
45072
45736
|
);
|
|
45073
45737
|
}
|
|
45074
45738
|
function updateStatePath2(paths) {
|
|
45075
|
-
return
|
|
45739
|
+
return path37.join(paths.runDir, "link-update-state.json");
|
|
45076
45740
|
}
|
|
45077
45741
|
function updateLogPath2(paths) {
|
|
45078
|
-
return
|
|
45742
|
+
return path37.join(paths.logsDir, UPDATE_LOG_FILE2);
|
|
45079
45743
|
}
|
|
45080
45744
|
async function clearUpdateLogFiles2(paths) {
|
|
45081
45745
|
const primary = updateLogPath2(paths);
|
|
@@ -45153,13 +45817,13 @@ function toRecord26(value) {
|
|
|
45153
45817
|
function toNullableRecord2(value) {
|
|
45154
45818
|
return typeof value === "object" && value !== null ? value : null;
|
|
45155
45819
|
}
|
|
45156
|
-
function
|
|
45820
|
+
function readString28(payload, key) {
|
|
45157
45821
|
const value = payload[key];
|
|
45158
45822
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
45159
45823
|
}
|
|
45160
45824
|
|
|
45161
45825
|
// src/pairing/pairing.ts
|
|
45162
|
-
import
|
|
45826
|
+
import path38 from "path";
|
|
45163
45827
|
import { rm as rm12 } from "fs/promises";
|
|
45164
45828
|
|
|
45165
45829
|
// src/relay/bootstrap.ts
|
|
@@ -45499,10 +46163,10 @@ async function loadRequiredIdentity2(paths) {
|
|
|
45499
46163
|
}
|
|
45500
46164
|
return identity;
|
|
45501
46165
|
}
|
|
45502
|
-
async function postServerJson(serverBaseUrl,
|
|
46166
|
+
async function postServerJson(serverBaseUrl, path39, body, options) {
|
|
45503
46167
|
let response;
|
|
45504
46168
|
try {
|
|
45505
|
-
response = await fetch(`${serverBaseUrl.replace(/\/+$/u, "")}${
|
|
46169
|
+
response = await fetch(`${serverBaseUrl.replace(/\/+$/u, "")}${path39}`, {
|
|
45506
46170
|
method: "POST",
|
|
45507
46171
|
headers: {
|
|
45508
46172
|
accept: "application/json",
|
|
@@ -45550,10 +46214,10 @@ function pairingErrorSnapshot(stage, error) {
|
|
|
45550
46214
|
occurred_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
45551
46215
|
};
|
|
45552
46216
|
}
|
|
45553
|
-
async function patchServerJson(serverBaseUrl,
|
|
46217
|
+
async function patchServerJson(serverBaseUrl, path39, token, body, options) {
|
|
45554
46218
|
let response;
|
|
45555
46219
|
try {
|
|
45556
|
-
response = await fetch(`${serverBaseUrl.replace(/\/+$/u, "")}${
|
|
46220
|
+
response = await fetch(`${serverBaseUrl.replace(/\/+$/u, "")}${path39}`, {
|
|
45557
46221
|
method: "PATCH",
|
|
45558
46222
|
headers: {
|
|
45559
46223
|
accept: "application/json",
|
|
@@ -45601,10 +46265,10 @@ function createPairingNetworkError(input) {
|
|
|
45601
46265
|
);
|
|
45602
46266
|
}
|
|
45603
46267
|
function pairingClaimPath(sessionId, paths) {
|
|
45604
|
-
return
|
|
46268
|
+
return path38.join(paths.pairingDir, `${Buffer.from(sessionId).toString("base64url")}.claimed.json`);
|
|
45605
46269
|
}
|
|
45606
46270
|
function pairingSessionPath(sessionId, paths) {
|
|
45607
|
-
return
|
|
46271
|
+
return path38.join(paths.pairingDir, `${Buffer.from(sessionId).toString("base64url")}.json`);
|
|
45608
46272
|
}
|
|
45609
46273
|
function qrPreferredUrls(routes) {
|
|
45610
46274
|
return routes.preferredUrls.filter((url) => !url.includes("/api/v1/relay/links/")).slice(0, 1);
|
|
@@ -45677,6 +46341,7 @@ function registerSystemRoutes(router, options) {
|
|
|
45677
46341
|
conversation_delete: true,
|
|
45678
46342
|
conversation_bulk_delete: true,
|
|
45679
46343
|
conversation_clear_plan: true,
|
|
46344
|
+
conversation_categories: true,
|
|
45680
46345
|
conversation_cancel: true,
|
|
45681
46346
|
conversation_queue_controls: true,
|
|
45682
46347
|
conversation_queue_limit: MAX_CONVERSATION_QUEUED_RUNS,
|
|
@@ -45707,8 +46372,8 @@ function registerSystemRoutes(router, options) {
|
|
|
45707
46372
|
});
|
|
45708
46373
|
router.post("/api/v1/pairing/claim", async (ctx) => {
|
|
45709
46374
|
const body = await readJsonBody(ctx.req);
|
|
45710
|
-
const sessionId =
|
|
45711
|
-
const claimToken =
|
|
46375
|
+
const sessionId = readString23(body, "session_id") ?? readString23(body, "sessionId");
|
|
46376
|
+
const claimToken = readString23(body, "claim_token") ?? readString23(body, "claimToken");
|
|
45712
46377
|
if (!sessionId || !claimToken) {
|
|
45713
46378
|
throw new LinkHttpError(
|
|
45714
46379
|
400,
|
|
@@ -45719,10 +46384,10 @@ function registerSystemRoutes(router, options) {
|
|
|
45719
46384
|
const claimed = await claimPairing({
|
|
45720
46385
|
sessionId,
|
|
45721
46386
|
claimToken,
|
|
45722
|
-
deviceLabel:
|
|
45723
|
-
devicePlatform:
|
|
45724
|
-
deviceModel:
|
|
45725
|
-
appInstanceId:
|
|
46387
|
+
deviceLabel: readString23(body, "device_label") ?? readString23(body, "deviceLabel") ?? "HermesPilot App",
|
|
46388
|
+
devicePlatform: readString23(body, "device_platform") ?? readString23(body, "devicePlatform") ?? "unknown",
|
|
46389
|
+
deviceModel: readString23(body, "device_model") ?? readString23(body, "deviceModel"),
|
|
46390
|
+
appInstanceId: readString23(body, "app_instance_id") ?? readString23(body, "appInstanceId"),
|
|
45726
46391
|
paths
|
|
45727
46392
|
});
|
|
45728
46393
|
ctx.body = claimed;
|
|
@@ -45802,9 +46467,9 @@ function registerSystemRoutes(router, options) {
|
|
|
45802
46467
|
const body = await readJsonBody(ctx.req);
|
|
45803
46468
|
const session = await createDeviceSession(
|
|
45804
46469
|
{
|
|
45805
|
-
label:
|
|
45806
|
-
platform:
|
|
45807
|
-
model:
|
|
46470
|
+
label: readString23(body, "device_label") ?? readString23(body, "deviceLabel") ?? "HermesPilot App",
|
|
46471
|
+
platform: readString23(body, "device_platform") ?? readString23(body, "devicePlatform") ?? "unknown",
|
|
46472
|
+
model: readString23(body, "device_model") ?? readString23(body, "deviceModel"),
|
|
45808
46473
|
appInstanceId: auth.appInstanceId
|
|
45809
46474
|
},
|
|
45810
46475
|
paths
|
|
@@ -45833,7 +46498,7 @@ function registerSystemRoutes(router, options) {
|
|
|
45833
46498
|
});
|
|
45834
46499
|
router.post("/api/v1/auth/refresh", async (ctx) => {
|
|
45835
46500
|
const body = await readJsonBody(ctx.req);
|
|
45836
|
-
const refreshToken =
|
|
46501
|
+
const refreshToken = readString23(body, "refresh_token") ?? readString23(body, "refreshToken");
|
|
45837
46502
|
if (!refreshToken) {
|
|
45838
46503
|
throw new LinkHttpError(
|
|
45839
46504
|
400,
|
|
@@ -45844,10 +46509,10 @@ function registerSystemRoutes(router, options) {
|
|
|
45844
46509
|
const session = await refreshDeviceSession(
|
|
45845
46510
|
refreshToken,
|
|
45846
46511
|
{
|
|
45847
|
-
appInstanceId:
|
|
45848
|
-
label:
|
|
45849
|
-
platform:
|
|
45850
|
-
model:
|
|
46512
|
+
appInstanceId: readString23(body, "app_instance_id") ?? readString23(body, "appInstanceId"),
|
|
46513
|
+
label: readString23(body, "device_label") ?? readString23(body, "deviceLabel"),
|
|
46514
|
+
platform: readString23(body, "device_platform") ?? readString23(body, "devicePlatform"),
|
|
46515
|
+
model: readString23(body, "device_model") ?? readString23(body, "deviceModel")
|
|
45851
46516
|
},
|
|
45852
46517
|
paths
|
|
45853
46518
|
);
|
|
@@ -45866,7 +46531,7 @@ function registerSystemRoutes(router, options) {
|
|
|
45866
46531
|
});
|
|
45867
46532
|
router.post("/api/v1/auth/logout", async (ctx) => {
|
|
45868
46533
|
const body = await readJsonBody(ctx.req);
|
|
45869
|
-
const refreshToken =
|
|
46534
|
+
const refreshToken = readString23(body, "refresh_token") ?? readString23(body, "refreshToken");
|
|
45870
46535
|
if (refreshToken) {
|
|
45871
46536
|
await revokeDeviceRefreshToken(refreshToken, paths);
|
|
45872
46537
|
}
|
|
@@ -46107,7 +46772,7 @@ function registerSystemRoutes(router, options) {
|
|
|
46107
46772
|
router.patch("/api/v1/devices/:deviceId", async (ctx) => {
|
|
46108
46773
|
const auth = await authenticateRequest(ctx, paths);
|
|
46109
46774
|
const body = await readJsonBody(ctx.req);
|
|
46110
|
-
const label =
|
|
46775
|
+
const label = readString23(body, "label") ?? readString23(body, "device_label");
|
|
46111
46776
|
if (!label) {
|
|
46112
46777
|
throw new LinkHttpError(
|
|
46113
46778
|
400,
|
|
@@ -46151,7 +46816,7 @@ function isActiveCronJob(job) {
|
|
|
46151
46816
|
if (!enabled) {
|
|
46152
46817
|
return false;
|
|
46153
46818
|
}
|
|
46154
|
-
const state =
|
|
46819
|
+
const state = readString23(job, "state")?.toLowerCase();
|
|
46155
46820
|
return !["paused", "disabled", "completed", "deleted"].includes(state ?? "");
|
|
46156
46821
|
}
|
|
46157
46822
|
function filterLogsWithinHours(logs, hours, now = Date.now()) {
|
|
@@ -46195,8 +46860,8 @@ function registerWorkspaceRoutes(router, options) {
|
|
|
46195
46860
|
ctx.body = {
|
|
46196
46861
|
ok: true,
|
|
46197
46862
|
workspace: await conversations.createWorkspace({
|
|
46198
|
-
name:
|
|
46199
|
-
icon:
|
|
46863
|
+
name: readString23(body, "name") ?? "",
|
|
46864
|
+
icon: readString23(body, "icon") ?? void 0
|
|
46200
46865
|
})
|
|
46201
46866
|
};
|
|
46202
46867
|
});
|
|
@@ -46206,8 +46871,8 @@ function registerWorkspaceRoutes(router, options) {
|
|
|
46206
46871
|
ctx.body = {
|
|
46207
46872
|
ok: true,
|
|
46208
46873
|
workspace: await conversations.renameWorkspace(ctx.params.workspaceId, {
|
|
46209
|
-
name:
|
|
46210
|
-
icon:
|
|
46874
|
+
name: readString23(body, "name") ?? "",
|
|
46875
|
+
icon: readString23(body, "icon") ?? void 0
|
|
46211
46876
|
})
|
|
46212
46877
|
};
|
|
46213
46878
|
});
|
|
@@ -46290,8 +46955,8 @@ function registerLinkUpdateRoutes(router, options) {
|
|
|
46290
46955
|
ctx.body = await startLinkUpdate({
|
|
46291
46956
|
paths,
|
|
46292
46957
|
logger,
|
|
46293
|
-
channel:
|
|
46294
|
-
targetVersion:
|
|
46958
|
+
channel: readString23(body, "channel"),
|
|
46959
|
+
targetVersion: readString23(body, "target_version") ?? readString23(body, "targetVersion")
|
|
46295
46960
|
});
|
|
46296
46961
|
});
|
|
46297
46962
|
router.get("/api/v1/link/update/events", async (ctx) => {
|
|
@@ -46321,7 +46986,7 @@ import QRCode from "qrcode";
|
|
|
46321
46986
|
function registerPairingRoutes(router, options) {
|
|
46322
46987
|
const { paths } = options;
|
|
46323
46988
|
router.get("/pair", async (ctx) => {
|
|
46324
|
-
const sessionId =
|
|
46989
|
+
const sessionId = readString23(ctx.query, "session_id");
|
|
46325
46990
|
if (!sessionId) {
|
|
46326
46991
|
throw new LinkHttpError(400, "pairing_session_required", "session_id is required");
|
|
46327
46992
|
}
|
|
@@ -46346,7 +47011,7 @@ function registerPairingRoutes(router, options) {
|
|
|
46346
47011
|
ctx.body = page;
|
|
46347
47012
|
});
|
|
46348
47013
|
router.get("/api/v1/pairing/session", async (ctx) => {
|
|
46349
|
-
const sessionId =
|
|
47014
|
+
const sessionId = readString23(ctx.query, "session_id");
|
|
46350
47015
|
if (!sessionId) {
|
|
46351
47016
|
throw new LinkHttpError(400, "pairing_session_required", "session_id is required");
|
|
46352
47017
|
}
|
|
@@ -46816,7 +47481,7 @@ function registerInternalRoutes(router, options) {
|
|
|
46816
47481
|
router.post("/internal/deliver", async (ctx) => {
|
|
46817
47482
|
assertLoopbackRequest(ctx.req);
|
|
46818
47483
|
const body = await readJsonBody(ctx.req);
|
|
46819
|
-
const stagingDir =
|
|
47484
|
+
const stagingDir = readString23(body, "staging_dir") ?? readString23(body, "stagingDir");
|
|
46820
47485
|
if (!stagingDir) {
|
|
46821
47486
|
throw new LinkHttpError(
|
|
46822
47487
|
400,
|
|
@@ -46835,9 +47500,9 @@ function registerInternalRoutes(router, options) {
|
|
|
46835
47500
|
ctx.body = {
|
|
46836
47501
|
ok: true,
|
|
46837
47502
|
...await options.conversations.deliverFilesFromTool({
|
|
46838
|
-
profile:
|
|
46839
|
-
taskId:
|
|
46840
|
-
sessionId:
|
|
47503
|
+
profile: readString23(body, "profile") ?? readString23(body, "profile_name") ?? readString23(body, "profileName") ?? void 0,
|
|
47504
|
+
taskId: readString23(body, "task_id") ?? readString23(body, "taskId") ?? void 0,
|
|
47505
|
+
sessionId: readString23(body, "session_id") ?? readString23(body, "sessionId") ?? void 0,
|
|
46841
47506
|
files: body.files ?? body.file ?? body.path
|
|
46842
47507
|
})
|
|
46843
47508
|
};
|
|
@@ -46898,9 +47563,9 @@ function registerLiveActivityRoutes(router, options) {
|
|
|
46898
47563
|
const auth = await authenticateRequest(ctx, paths);
|
|
46899
47564
|
const body = await readJsonBody(ctx.req);
|
|
46900
47565
|
const targetKind = readTargetKind(body);
|
|
46901
|
-
const runId = normalizePattern(
|
|
47566
|
+
const runId = normalizePattern(readString23(body, "run_id") ?? readString23(body, "runId"), RUN_ID_PATTERN);
|
|
46902
47567
|
const operationId = normalizePattern(
|
|
46903
|
-
|
|
47568
|
+
readString23(body, "operation_id") ?? readString23(body, "operationId"),
|
|
46904
47569
|
OPERATION_ID_PATTERN
|
|
46905
47570
|
);
|
|
46906
47571
|
if (targetKind === "run" && !runId) {
|
|
@@ -46946,7 +47611,7 @@ function registerLiveActivityRoutes(router, options) {
|
|
|
46946
47611
|
});
|
|
46947
47612
|
}
|
|
46948
47613
|
function readTargetKind(body) {
|
|
46949
|
-
const value =
|
|
47614
|
+
const value = readString23(body, "target_kind") ?? readString23(body, "targetKind");
|
|
46950
47615
|
return readTargetKindValue(value);
|
|
46951
47616
|
}
|
|
46952
47617
|
function readTargetKindValue(value) {
|
|
@@ -46968,21 +47633,21 @@ function readQueryValue(query, key) {
|
|
|
46968
47633
|
return readQueryString(query[key]) ?? null;
|
|
46969
47634
|
}
|
|
46970
47635
|
function readApnsEnvironment(body) {
|
|
46971
|
-
const value =
|
|
47636
|
+
const value = readString23(body, "apns_environment") ?? readString23(body, "apnsEnvironment");
|
|
46972
47637
|
if (value === "sandbox" || value === "production") {
|
|
46973
47638
|
return value;
|
|
46974
47639
|
}
|
|
46975
47640
|
throw new LinkHttpError(400, "apns_environment_invalid", "apns_environment must be sandbox or production");
|
|
46976
47641
|
}
|
|
46977
47642
|
function readLanguage2(body) {
|
|
46978
|
-
const value =
|
|
47643
|
+
const value = readString23(body, "language") ?? readString23(body, "preferred_language") ?? readString23(body, "preferredLanguage");
|
|
46979
47644
|
if (!value) {
|
|
46980
47645
|
return null;
|
|
46981
47646
|
}
|
|
46982
47647
|
return value.toLowerCase().startsWith("zh") ? "zh" : "en";
|
|
46983
47648
|
}
|
|
46984
47649
|
function readPrivacyLevel(body) {
|
|
46985
|
-
const value =
|
|
47650
|
+
const value = readString23(body, "privacy_level") ?? readString23(body, "privacyLevel");
|
|
46986
47651
|
if (value === "minimal" || value === "detailed") {
|
|
46987
47652
|
return value;
|
|
46988
47653
|
}
|
|
@@ -46990,7 +47655,7 @@ function readPrivacyLevel(body) {
|
|
|
46990
47655
|
}
|
|
46991
47656
|
function readRequiredString(body, keys, code) {
|
|
46992
47657
|
for (const key of keys) {
|
|
46993
|
-
const value =
|
|
47658
|
+
const value = readString23(body, key);
|
|
46994
47659
|
if (value) {
|
|
46995
47660
|
return value;
|
|
46996
47661
|
}
|
|
@@ -47006,7 +47671,7 @@ function readRequiredPattern(body, keys, pattern, code) {
|
|
|
47006
47671
|
}
|
|
47007
47672
|
function readOptionalString2(body, keys, maxLength) {
|
|
47008
47673
|
for (const key of keys) {
|
|
47009
|
-
const value =
|
|
47674
|
+
const value = readString23(body, key);
|
|
47010
47675
|
if (value) {
|
|
47011
47676
|
return value.slice(0, maxLength);
|
|
47012
47677
|
}
|
|
@@ -47018,7 +47683,7 @@ function normalizePattern(value, pattern) {
|
|
|
47018
47683
|
}
|
|
47019
47684
|
function readIso(body, keys) {
|
|
47020
47685
|
for (const key of keys) {
|
|
47021
|
-
const value =
|
|
47686
|
+
const value = readString23(body, key);
|
|
47022
47687
|
if (!value) {
|
|
47023
47688
|
continue;
|
|
47024
47689
|
}
|