@hermespilot/link 0.8.2 → 0.8.3
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-JWKKE7ZJ.js} +934 -405
- package/dist/cli/index.js +1 -1
- package/dist/http/app.d.ts +14 -0
- 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.3";
|
|
7725
7725
|
var LINK_COMMAND = "hermeslink";
|
|
7726
7726
|
var LINK_DEFAULT_PORT = 52379;
|
|
7727
7727
|
var LINK_RUNTIME_DIR_NAME = ".hermeslink";
|
|
@@ -21380,6 +21380,7 @@ var MESSAGE_COLUMNS = [
|
|
|
21380
21380
|
"reasoning_details",
|
|
21381
21381
|
"codex_reasoning_items"
|
|
21382
21382
|
];
|
|
21383
|
+
var HERMES_ROW_SESSION_POSITION = /* @__PURE__ */ Symbol("hermesRowSessionPosition");
|
|
21383
21384
|
async function syncHermesSessionsIntoConversations(paths, logger, options = {}) {
|
|
21384
21385
|
const maxImports = options.maxImports ?? MAX_IMPORTABLE_SESSIONS;
|
|
21385
21386
|
const store = new ConversationStore(paths);
|
|
@@ -21585,7 +21586,7 @@ async function syncHermesCronSessionIntoConversations(paths, logger, input) {
|
|
|
21585
21586
|
async function syncHermesConversationMessages(paths, logger, input) {
|
|
21586
21587
|
const store = input.store ?? new ConversationStore(paths);
|
|
21587
21588
|
const manifest = await store.readActiveManifest(input.conversationId);
|
|
21588
|
-
|
|
21589
|
+
let snapshot = await store.readSnapshot(input.conversationId);
|
|
21589
21590
|
const targets = collectHermesSessionDeleteTargets(manifest, snapshot);
|
|
21590
21591
|
const result = {
|
|
21591
21592
|
conversation_id: input.conversationId,
|
|
@@ -21597,8 +21598,15 @@ async function syncHermesConversationMessages(paths, logger, input) {
|
|
|
21597
21598
|
if (targets.length === 0) {
|
|
21598
21599
|
return result;
|
|
21599
21600
|
}
|
|
21601
|
+
const duplicateCleanup = pruneStrictImportedDuplicateMessages(paths, snapshot);
|
|
21602
|
+
if (duplicateCleanup.removedCount > 0) {
|
|
21603
|
+
snapshot = duplicateCleanup.snapshot;
|
|
21604
|
+
result.removed_duplicate_count = duplicateCleanup.removedCount;
|
|
21605
|
+
result.changed = true;
|
|
21606
|
+
}
|
|
21600
21607
|
const candidates = await collectConversationSyncCandidates(targets);
|
|
21601
21608
|
const knownExactKeys = collectKnownHermesRowKeys(snapshot);
|
|
21609
|
+
const representedRows = collectRepresentedHermesRows(paths, snapshot);
|
|
21602
21610
|
const representedMessages = collectRepresentedMessageSignatures(snapshot);
|
|
21603
21611
|
const projectedMessages = [];
|
|
21604
21612
|
const candidateProfiles = /* @__PURE__ */ new Map();
|
|
@@ -21608,6 +21616,12 @@ async function syncHermesConversationMessages(paths, logger, input) {
|
|
|
21608
21616
|
if (candidateMessages.length === 0) {
|
|
21609
21617
|
continue;
|
|
21610
21618
|
}
|
|
21619
|
+
const missingCandidateMessages = candidateMessages.filter(
|
|
21620
|
+
(message, index) => !isRepresentedHermesRow(representedRows, message, index)
|
|
21621
|
+
);
|
|
21622
|
+
if (missingCandidateMessages.length === 0) {
|
|
21623
|
+
continue;
|
|
21624
|
+
}
|
|
21611
21625
|
const profile = await resolveConversationProfileTarget(
|
|
21612
21626
|
paths,
|
|
21613
21627
|
candidate.profileName
|
|
@@ -21624,7 +21638,7 @@ async function syncHermesConversationMessages(paths, logger, input) {
|
|
|
21624
21638
|
profileUid: profile.profileUid,
|
|
21625
21639
|
profileDisplayName: profile.profileDisplayName,
|
|
21626
21640
|
sessionId: candidate.session.id,
|
|
21627
|
-
messages:
|
|
21641
|
+
messages: missingCandidateMessages
|
|
21628
21642
|
})
|
|
21629
21643
|
);
|
|
21630
21644
|
} catch (error) {
|
|
@@ -21650,6 +21664,14 @@ async function syncHermesConversationMessages(paths, logger, input) {
|
|
|
21650
21664
|
exactKeys.forEach((key) => knownExactKeys.add(key));
|
|
21651
21665
|
}
|
|
21652
21666
|
if (appendedMessages.length === 0) {
|
|
21667
|
+
if (duplicateCleanup.removedCount > 0) {
|
|
21668
|
+
await store.writeSnapshot(input.conversationId, snapshot);
|
|
21669
|
+
const currentManifest = await store.readManifest(input.conversationId);
|
|
21670
|
+
const stats2 = buildConversationStats(currentManifest, snapshot);
|
|
21671
|
+
const nextManifest2 = { ...currentManifest, stats: stats2 };
|
|
21672
|
+
await store.writeManifest(nextManifest2);
|
|
21673
|
+
await upsertConversationStats(paths, toStatsIndexRecord(nextManifest2, stats2));
|
|
21674
|
+
}
|
|
21653
21675
|
return result;
|
|
21654
21676
|
}
|
|
21655
21677
|
await store.writeSnapshot(input.conversationId, {
|
|
@@ -22019,6 +22041,293 @@ function collectKnownHermesRowKeys(snapshot) {
|
|
|
22019
22041
|
}
|
|
22020
22042
|
return keys;
|
|
22021
22043
|
}
|
|
22044
|
+
function collectRepresentedHermesRows(paths, snapshot) {
|
|
22045
|
+
const rows = {
|
|
22046
|
+
syntheticUserTexts: /* @__PURE__ */ new Set(),
|
|
22047
|
+
toolCallIds: /* @__PURE__ */ new Set(),
|
|
22048
|
+
runWindows: []
|
|
22049
|
+
};
|
|
22050
|
+
for (const run of snapshot.runs) {
|
|
22051
|
+
collectRunHermesMessageWindows(run).forEach(
|
|
22052
|
+
(window) => rows.runWindows.push(window)
|
|
22053
|
+
);
|
|
22054
|
+
const userMessage = snapshot.messages.find(
|
|
22055
|
+
(message) => message.id === run.trigger_message_id
|
|
22056
|
+
);
|
|
22057
|
+
if (userMessage) {
|
|
22058
|
+
collectSyntheticRunInputTexts(paths, userMessage).forEach(
|
|
22059
|
+
(text) => rows.syntheticUserTexts.add(hashText(text))
|
|
22060
|
+
);
|
|
22061
|
+
}
|
|
22062
|
+
const assistantMessage = snapshot.messages.find(
|
|
22063
|
+
(message) => message.id === run.assistant_message_id
|
|
22064
|
+
);
|
|
22065
|
+
if (assistantMessage) {
|
|
22066
|
+
collectAgentEventIds(assistantMessage).forEach(
|
|
22067
|
+
(id) => rows.toolCallIds.add(id)
|
|
22068
|
+
);
|
|
22069
|
+
}
|
|
22070
|
+
}
|
|
22071
|
+
return rows;
|
|
22072
|
+
}
|
|
22073
|
+
function pruneStrictImportedDuplicateMessages(paths, snapshot) {
|
|
22074
|
+
if (snapshot.runs.length === 0) {
|
|
22075
|
+
return { snapshot, removedCount: 0 };
|
|
22076
|
+
}
|
|
22077
|
+
const messages2 = snapshot.messages.filter(
|
|
22078
|
+
(message) => !isStrictImportedDuplicateRunMessage(paths, snapshot, message)
|
|
22079
|
+
);
|
|
22080
|
+
const removedCount = snapshot.messages.length - messages2.length;
|
|
22081
|
+
return removedCount > 0 ? { snapshot: { ...snapshot, messages: messages2 }, removedCount } : { snapshot, removedCount: 0 };
|
|
22082
|
+
}
|
|
22083
|
+
function isStrictImportedDuplicateRunMessage(paths, snapshot, message) {
|
|
22084
|
+
if (!isHermesImportedMessage2(message)) {
|
|
22085
|
+
return false;
|
|
22086
|
+
}
|
|
22087
|
+
if (snapshot.runs.some(
|
|
22088
|
+
(run) => run.trigger_message_id === message.id || run.assistant_message_id === message.id
|
|
22089
|
+
)) {
|
|
22090
|
+
return false;
|
|
22091
|
+
}
|
|
22092
|
+
const messageSessionIds = collectMessageHermesSessionIds(message);
|
|
22093
|
+
if (messageSessionIds.size === 0) {
|
|
22094
|
+
return false;
|
|
22095
|
+
}
|
|
22096
|
+
return snapshot.runs.some((run) => {
|
|
22097
|
+
if (!runSessionMatchesMessage(run, messageSessionIds)) {
|
|
22098
|
+
return false;
|
|
22099
|
+
}
|
|
22100
|
+
if (!isMessageInsideRunCleanupWindow(message, run)) {
|
|
22101
|
+
return false;
|
|
22102
|
+
}
|
|
22103
|
+
if (message.role === "user") {
|
|
22104
|
+
const user = snapshot.messages.find(
|
|
22105
|
+
(item) => item.id === run.trigger_message_id
|
|
22106
|
+
);
|
|
22107
|
+
return user ? isDuplicateImportedRunUser(paths, user, message) : false;
|
|
22108
|
+
}
|
|
22109
|
+
if (message.role === "assistant" || message.role === "tool") {
|
|
22110
|
+
const assistant = snapshot.messages.find(
|
|
22111
|
+
(item) => item.id === run.assistant_message_id
|
|
22112
|
+
);
|
|
22113
|
+
return assistant ? isDuplicateImportedRunAssistant(assistant, message) : false;
|
|
22114
|
+
}
|
|
22115
|
+
return false;
|
|
22116
|
+
});
|
|
22117
|
+
}
|
|
22118
|
+
function isDuplicateImportedRunUser(paths, user, imported) {
|
|
22119
|
+
const importedText = normalizedDuplicateText(imported);
|
|
22120
|
+
if (!importedText) {
|
|
22121
|
+
return false;
|
|
22122
|
+
}
|
|
22123
|
+
if (importedText === normalizedDuplicateText(user)) {
|
|
22124
|
+
return true;
|
|
22125
|
+
}
|
|
22126
|
+
return collectSyntheticRunInputTexts(paths, user).some(
|
|
22127
|
+
(text) => normalizedDuplicateTextValue(text) === importedText
|
|
22128
|
+
);
|
|
22129
|
+
}
|
|
22130
|
+
function isDuplicateImportedRunAssistant(assistant, imported) {
|
|
22131
|
+
const importedText = normalizedDuplicateText(imported);
|
|
22132
|
+
if (importedText && importedText === normalizedDuplicateText(assistant)) {
|
|
22133
|
+
return true;
|
|
22134
|
+
}
|
|
22135
|
+
const importedToolIds = collectAgentEventIds(imported);
|
|
22136
|
+
if (importedToolIds.size === 0) {
|
|
22137
|
+
return false;
|
|
22138
|
+
}
|
|
22139
|
+
const assistantToolIds = collectAgentEventIds(assistant);
|
|
22140
|
+
return [...importedToolIds].every((id) => assistantToolIds.has(id));
|
|
22141
|
+
}
|
|
22142
|
+
function collectMessageHermesSessionIds(message) {
|
|
22143
|
+
const sessionIds = /* @__PURE__ */ new Set();
|
|
22144
|
+
const hermes = toRecord12(message.hermes);
|
|
22145
|
+
const sessionId = readString12(hermes, "session_id");
|
|
22146
|
+
if (sessionId) {
|
|
22147
|
+
sessionIds.add(sessionId);
|
|
22148
|
+
}
|
|
22149
|
+
for (const row of readHermesRawMessageRows(message.raw)) {
|
|
22150
|
+
const rowSessionId = readString12(row, "session_id");
|
|
22151
|
+
if (rowSessionId) {
|
|
22152
|
+
sessionIds.add(rowSessionId);
|
|
22153
|
+
}
|
|
22154
|
+
}
|
|
22155
|
+
return sessionIds;
|
|
22156
|
+
}
|
|
22157
|
+
function runSessionMatchesMessage(run, messageSessionIds) {
|
|
22158
|
+
return collectRunHermesSessionIds(run).some(
|
|
22159
|
+
(sessionId) => messageSessionIds.has(sessionId)
|
|
22160
|
+
);
|
|
22161
|
+
}
|
|
22162
|
+
function collectRunHermesSessionIds(run) {
|
|
22163
|
+
return normalizeSessionIds([
|
|
22164
|
+
run.hermes_session_id,
|
|
22165
|
+
run.hermes_message_watermark?.before?.session_id,
|
|
22166
|
+
run.hermes_message_watermark?.after?.session_id
|
|
22167
|
+
]);
|
|
22168
|
+
}
|
|
22169
|
+
function isMessageInsideRunCleanupWindow(message, run) {
|
|
22170
|
+
if (run.status === "queued" || run.status === "running" || run.status === "unknown") {
|
|
22171
|
+
return false;
|
|
22172
|
+
}
|
|
22173
|
+
const messageAt = parseIsoMillis(message.created_at);
|
|
22174
|
+
const startedAt = parseIsoMillis(run.started_at);
|
|
22175
|
+
const completedAt = run.completed_at ? parseIsoMillis(run.completed_at) : void 0;
|
|
22176
|
+
if (messageAt === void 0 || startedAt === void 0) {
|
|
22177
|
+
return false;
|
|
22178
|
+
}
|
|
22179
|
+
const lowerBound = startedAt - 10 * 60 * 1e3;
|
|
22180
|
+
const upperBound = (completedAt ?? startedAt) + 10 * 60 * 1e3;
|
|
22181
|
+
return messageAt >= lowerBound && messageAt <= upperBound;
|
|
22182
|
+
}
|
|
22183
|
+
function normalizedDuplicateText(message) {
|
|
22184
|
+
return normalizedDuplicateTextValue(messageText2(message));
|
|
22185
|
+
}
|
|
22186
|
+
function normalizedDuplicateTextValue(value) {
|
|
22187
|
+
return value.replace(/\r\n/gu, "\n").trim();
|
|
22188
|
+
}
|
|
22189
|
+
function collectRunHermesMessageWindows(run) {
|
|
22190
|
+
const before = normalizeWatermarkPoint(
|
|
22191
|
+
run.hermes_message_watermark?.before,
|
|
22192
|
+
run.hermes_session_id
|
|
22193
|
+
);
|
|
22194
|
+
if (!before) {
|
|
22195
|
+
return [];
|
|
22196
|
+
}
|
|
22197
|
+
const after = normalizeWatermarkPoint(
|
|
22198
|
+
run.hermes_message_watermark?.after,
|
|
22199
|
+
run.hermes_session_id
|
|
22200
|
+
);
|
|
22201
|
+
const sessionId = before.session_id?.trim() || run.hermes_session_id?.trim();
|
|
22202
|
+
if (!sessionId) {
|
|
22203
|
+
return [];
|
|
22204
|
+
}
|
|
22205
|
+
return [
|
|
22206
|
+
{
|
|
22207
|
+
runId: run.id,
|
|
22208
|
+
sessionId,
|
|
22209
|
+
status: run.status,
|
|
22210
|
+
before,
|
|
22211
|
+
...after && (after.session_id ?? sessionId) === sessionId ? { after } : {},
|
|
22212
|
+
startedAtMs: parseIsoMillis(run.started_at),
|
|
22213
|
+
completedAtMs: run.completed_at ? parseIsoMillis(run.completed_at) : void 0
|
|
22214
|
+
}
|
|
22215
|
+
];
|
|
22216
|
+
}
|
|
22217
|
+
function normalizeWatermarkPoint(point, fallbackSessionId) {
|
|
22218
|
+
if (!point || typeof point.message_count !== "number" || !Number.isFinite(point.message_count)) {
|
|
22219
|
+
return null;
|
|
22220
|
+
}
|
|
22221
|
+
const sessionId = point.session_id?.trim() || fallbackSessionId?.trim();
|
|
22222
|
+
return {
|
|
22223
|
+
source: point.source,
|
|
22224
|
+
...sessionId ? { session_id: sessionId } : {},
|
|
22225
|
+
message_count: Math.max(0, Math.trunc(point.message_count)),
|
|
22226
|
+
...typeof point.max_message_id === "number" && Number.isFinite(point.max_message_id) ? { max_message_id: point.max_message_id } : {},
|
|
22227
|
+
...typeof point.max_timestamp === "number" && Number.isFinite(point.max_timestamp) ? { max_timestamp: point.max_timestamp } : {},
|
|
22228
|
+
captured_at: point.captured_at
|
|
22229
|
+
};
|
|
22230
|
+
}
|
|
22231
|
+
function collectSyntheticRunInputTexts(paths, message) {
|
|
22232
|
+
if (message.role !== "user") {
|
|
22233
|
+
return [];
|
|
22234
|
+
}
|
|
22235
|
+
const attachmentLines = message.parts.filter((part) => Boolean(part.blob)).filter((part) => !isVoicePart(part)).map((part) => {
|
|
22236
|
+
const label = part.filename ?? part.blob;
|
|
22237
|
+
const mime = part.mime ? `, ${part.mime}` : "";
|
|
22238
|
+
const size = part.size ? `, ${part.size} bytes` : "";
|
|
22239
|
+
return `- ${label}${mime}${size}: ${part.local_path ?? blobPath(paths, part.blob)}`;
|
|
22240
|
+
});
|
|
22241
|
+
if (attachmentLines.length === 0) {
|
|
22242
|
+
return [];
|
|
22243
|
+
}
|
|
22244
|
+
const content = messageText2(message);
|
|
22245
|
+
const prefix = content ? `${content}
|
|
22246
|
+
|
|
22247
|
+
` : "";
|
|
22248
|
+
return [
|
|
22249
|
+
`${prefix}Attachments available on this computer:
|
|
22250
|
+
${attachmentLines.join("\n")}`
|
|
22251
|
+
];
|
|
22252
|
+
}
|
|
22253
|
+
function collectAgentEventIds(message) {
|
|
22254
|
+
const ids = /* @__PURE__ */ new Set();
|
|
22255
|
+
for (const event of message.agent_events ?? []) {
|
|
22256
|
+
if (event.id) {
|
|
22257
|
+
ids.add(event.id);
|
|
22258
|
+
}
|
|
22259
|
+
}
|
|
22260
|
+
for (const block of message.blocks ?? []) {
|
|
22261
|
+
if (block.type !== "agent_events") {
|
|
22262
|
+
continue;
|
|
22263
|
+
}
|
|
22264
|
+
for (const event of block.events) {
|
|
22265
|
+
if (event.id) {
|
|
22266
|
+
ids.add(event.id);
|
|
22267
|
+
}
|
|
22268
|
+
}
|
|
22269
|
+
}
|
|
22270
|
+
return ids;
|
|
22271
|
+
}
|
|
22272
|
+
function isRepresentedHermesRow(represented, row, index) {
|
|
22273
|
+
const role = normalizeMessageRole(row.role);
|
|
22274
|
+
if (represented.runWindows.some(
|
|
22275
|
+
(window) => isRowInsideRunWindow(window, row, role)
|
|
22276
|
+
)) {
|
|
22277
|
+
return true;
|
|
22278
|
+
}
|
|
22279
|
+
if (role === "user" && represented.syntheticUserTexts.has(hashText(normalizeContent2(row.content)))) {
|
|
22280
|
+
return true;
|
|
22281
|
+
}
|
|
22282
|
+
if (role === "assistant") {
|
|
22283
|
+
const toolCalls = readHermesToolCalls(row);
|
|
22284
|
+
return toolCalls.length > 0 && toolCalls.every(
|
|
22285
|
+
(toolCall) => toolCall.id && represented.toolCallIds.has(toolCall.id)
|
|
22286
|
+
);
|
|
22287
|
+
}
|
|
22288
|
+
if (role === "tool") {
|
|
22289
|
+
const id = readString12(row, "tool_call_id") ?? readString12(row, "tool_id") ?? readString12(row, "call_id");
|
|
22290
|
+
if (id) {
|
|
22291
|
+
return represented.toolCallIds.has(id);
|
|
22292
|
+
}
|
|
22293
|
+
const key = hermesRowKey(row, index);
|
|
22294
|
+
return represented.toolCallIds.has(key);
|
|
22295
|
+
}
|
|
22296
|
+
return false;
|
|
22297
|
+
}
|
|
22298
|
+
function isRowInsideRunWindow(window, row, role) {
|
|
22299
|
+
if (role === "system") {
|
|
22300
|
+
return false;
|
|
22301
|
+
}
|
|
22302
|
+
if ((readString12(row, "session_id") ?? "") !== window.sessionId) {
|
|
22303
|
+
return false;
|
|
22304
|
+
}
|
|
22305
|
+
const hasClosedAfter = Boolean(window.after);
|
|
22306
|
+
const allowOpenEnded = window.status === "running";
|
|
22307
|
+
const allowTerminalGrace = !hasClosedAfter && (window.status === "cancelled" || window.status === "failed") && window.completedAtMs !== void 0;
|
|
22308
|
+
if (!hasClosedAfter && !allowOpenEnded && !allowTerminalGrace) {
|
|
22309
|
+
return false;
|
|
22310
|
+
}
|
|
22311
|
+
const position = rowSessionPosition(row);
|
|
22312
|
+
if (window.before.source !== "none" && position !== void 0 && position > window.before.message_count && (window.after ? position <= window.after.message_count : allowOpenEnded)) {
|
|
22313
|
+
return true;
|
|
22314
|
+
}
|
|
22315
|
+
const rowId = readNumber3(row.id);
|
|
22316
|
+
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)) {
|
|
22317
|
+
return true;
|
|
22318
|
+
}
|
|
22319
|
+
const rowTimeMs = hermesTimestampMillis(row.timestamp);
|
|
22320
|
+
if (rowTimeMs === void 0) {
|
|
22321
|
+
return false;
|
|
22322
|
+
}
|
|
22323
|
+
const beforeTimeMs = hermesTimestampMillis(window.before.max_timestamp);
|
|
22324
|
+
const lowerTimeMs = beforeTimeMs ?? (window.startedAtMs ?? 0) - 5e3;
|
|
22325
|
+
const upperTimeMs = hermesTimestampMillis(window.after?.max_timestamp) ?? (allowTerminalGrace && window.completedAtMs !== void 0 ? window.completedAtMs + 2 * 60 * 1e3 : allowOpenEnded ? Number.POSITIVE_INFINITY : void 0);
|
|
22326
|
+
return upperTimeMs !== void 0 && (beforeTimeMs !== void 0 ? rowTimeMs > lowerTimeMs : rowTimeMs >= lowerTimeMs) && rowTimeMs <= upperTimeMs;
|
|
22327
|
+
}
|
|
22328
|
+
function isVoicePart(part) {
|
|
22329
|
+
return part.kind === "voice" || part.is_voice_note === true;
|
|
22330
|
+
}
|
|
22022
22331
|
function collectMessageHermesRowKeys(message) {
|
|
22023
22332
|
const keys = [];
|
|
22024
22333
|
readHermesRawMessageRows(message.raw).forEach((row, index) => {
|
|
@@ -22072,6 +22381,21 @@ function representedMessageSignature(message) {
|
|
|
22072
22381
|
function hashText(value) {
|
|
22073
22382
|
return createHash6("sha256").update(value).digest("hex");
|
|
22074
22383
|
}
|
|
22384
|
+
function rowSessionPosition(row) {
|
|
22385
|
+
const position = row[HERMES_ROW_SESSION_POSITION];
|
|
22386
|
+
return typeof position === "number" && Number.isFinite(position) ? position : void 0;
|
|
22387
|
+
}
|
|
22388
|
+
function hermesTimestampMillis(value) {
|
|
22389
|
+
const numeric = readNumber3(value);
|
|
22390
|
+
if (numeric === null || numeric <= 0) {
|
|
22391
|
+
return void 0;
|
|
22392
|
+
}
|
|
22393
|
+
return numeric > 1e10 ? numeric : numeric * 1e3;
|
|
22394
|
+
}
|
|
22395
|
+
function parseIsoMillis(value) {
|
|
22396
|
+
const parsed = Date.parse(value);
|
|
22397
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
22398
|
+
}
|
|
22075
22399
|
function compareLinkMessagesByCreatedAt(left, right) {
|
|
22076
22400
|
return Date.parse(left.created_at) - Date.parse(right.created_at) || left.id.localeCompare(right.id);
|
|
22077
22401
|
}
|
|
@@ -23066,9 +23390,15 @@ async function readHermesSessionMessages(candidate) {
|
|
|
23066
23390
|
readJsonlMessages(candidate.profileName, candidate.session.id)
|
|
23067
23391
|
]);
|
|
23068
23392
|
const selected = jsonlMessages.length > dbMessages.length ? jsonlMessages : dbMessages;
|
|
23069
|
-
return selected.map(
|
|
23070
|
-
|
|
23071
|
-
|
|
23393
|
+
return selected.map((message, index) => {
|
|
23394
|
+
const normalized = readString12(message, "session_id") ? message : { ...message, session_id: candidate.session.id };
|
|
23395
|
+
Object.defineProperty(normalized, HERMES_ROW_SESSION_POSITION, {
|
|
23396
|
+
value: index + 1,
|
|
23397
|
+
enumerable: false,
|
|
23398
|
+
configurable: true
|
|
23399
|
+
});
|
|
23400
|
+
return normalized;
|
|
23401
|
+
});
|
|
23072
23402
|
}
|
|
23073
23403
|
async function readStateDbMessages(dbPath, sessionId) {
|
|
23074
23404
|
if (!await isFile(dbPath)) {
|
|
@@ -24181,10 +24511,10 @@ function parseHermesApiCapabilities(payload) {
|
|
|
24181
24511
|
sessionKeyHeader: readString14(features, "session_key_header")
|
|
24182
24512
|
};
|
|
24183
24513
|
}
|
|
24184
|
-
async function callHermesApi(
|
|
24514
|
+
async function callHermesApi(path39, init, options) {
|
|
24185
24515
|
const method = init.method ?? "GET";
|
|
24186
24516
|
const startedAt = Date.now();
|
|
24187
|
-
void options.logger?.debug("hermes_api_request_started", { method, path:
|
|
24517
|
+
void options.logger?.debug("hermes_api_request_started", { method, path: path39 });
|
|
24188
24518
|
const availability = await ensureHermesApiServerAvailable({
|
|
24189
24519
|
fetchImpl: options.fetchImpl,
|
|
24190
24520
|
logger: options.logger,
|
|
@@ -24193,7 +24523,7 @@ async function callHermesApi(path38, init, options) {
|
|
|
24193
24523
|
});
|
|
24194
24524
|
let config = availability.configResult.apiServer;
|
|
24195
24525
|
const fetcher = options.fetchImpl ?? fetch;
|
|
24196
|
-
const request = () => fetchHermesApi(fetcher, config,
|
|
24526
|
+
const request = () => fetchHermesApi(fetcher, config, path39, init, options);
|
|
24197
24527
|
let response;
|
|
24198
24528
|
try {
|
|
24199
24529
|
response = await request();
|
|
@@ -24201,7 +24531,7 @@ async function callHermesApi(path38, init, options) {
|
|
|
24201
24531
|
logHermesApiError(
|
|
24202
24532
|
options.logger,
|
|
24203
24533
|
method,
|
|
24204
|
-
|
|
24534
|
+
path39,
|
|
24205
24535
|
options.profileName,
|
|
24206
24536
|
startedAt,
|
|
24207
24537
|
error
|
|
@@ -24212,7 +24542,7 @@ async function callHermesApi(path38, init, options) {
|
|
|
24212
24542
|
logHermesApiResponse(
|
|
24213
24543
|
options.logger,
|
|
24214
24544
|
method,
|
|
24215
|
-
|
|
24545
|
+
path39,
|
|
24216
24546
|
options.profileName,
|
|
24217
24547
|
startedAt,
|
|
24218
24548
|
response
|
|
@@ -24221,7 +24551,7 @@ async function callHermesApi(path38, init, options) {
|
|
|
24221
24551
|
}
|
|
24222
24552
|
void options.logger?.warn("hermes_api_request_retrying_after_401", {
|
|
24223
24553
|
method,
|
|
24224
|
-
path:
|
|
24554
|
+
path: path39,
|
|
24225
24555
|
profile: options.profileName ?? "default",
|
|
24226
24556
|
port: config.port ?? null,
|
|
24227
24557
|
duration_ms: Date.now() - startedAt
|
|
@@ -24240,7 +24570,7 @@ async function callHermesApi(path38, init, options) {
|
|
|
24240
24570
|
logHermesApiError(
|
|
24241
24571
|
options.logger,
|
|
24242
24572
|
method,
|
|
24243
|
-
|
|
24573
|
+
path39,
|
|
24244
24574
|
options.profileName,
|
|
24245
24575
|
startedAt,
|
|
24246
24576
|
error
|
|
@@ -24250,7 +24580,7 @@ async function callHermesApi(path38, init, options) {
|
|
|
24250
24580
|
logHermesApiResponse(
|
|
24251
24581
|
options.logger,
|
|
24252
24582
|
method,
|
|
24253
|
-
|
|
24583
|
+
path39,
|
|
24254
24584
|
options.profileName,
|
|
24255
24585
|
startedAt,
|
|
24256
24586
|
response
|
|
@@ -24260,7 +24590,7 @@ async function callHermesApi(path38, init, options) {
|
|
|
24260
24590
|
}
|
|
24261
24591
|
void options.logger?.warn("hermes_api_request_repairing_after_401", {
|
|
24262
24592
|
method,
|
|
24263
|
-
path:
|
|
24593
|
+
path: path39,
|
|
24264
24594
|
profile: options.profileName ?? "default",
|
|
24265
24595
|
port: config.port ?? null,
|
|
24266
24596
|
duration_ms: Date.now() - startedAt
|
|
@@ -24281,7 +24611,7 @@ async function callHermesApi(path38, init, options) {
|
|
|
24281
24611
|
logHermesApiError(
|
|
24282
24612
|
options.logger,
|
|
24283
24613
|
method,
|
|
24284
|
-
|
|
24614
|
+
path39,
|
|
24285
24615
|
options.profileName,
|
|
24286
24616
|
startedAt,
|
|
24287
24617
|
error
|
|
@@ -24291,21 +24621,21 @@ async function callHermesApi(path38, init, options) {
|
|
|
24291
24621
|
logHermesApiResponse(
|
|
24292
24622
|
options.logger,
|
|
24293
24623
|
method,
|
|
24294
|
-
|
|
24624
|
+
path39,
|
|
24295
24625
|
options.profileName,
|
|
24296
24626
|
startedAt,
|
|
24297
24627
|
response
|
|
24298
24628
|
);
|
|
24299
24629
|
return response;
|
|
24300
24630
|
}
|
|
24301
|
-
async function fetchHermesApi(fetcher, config,
|
|
24631
|
+
async function fetchHermesApi(fetcher, config, path39, init, options) {
|
|
24302
24632
|
const headers = new Headers(init.headers);
|
|
24303
24633
|
headers.set("accept", headers.get("accept") ?? "application/json");
|
|
24304
24634
|
if (config.key) {
|
|
24305
24635
|
headers.set("x-api-key", config.key);
|
|
24306
24636
|
headers.set("authorization", `Bearer ${config.key}`);
|
|
24307
24637
|
}
|
|
24308
|
-
return await fetcher(`http://127.0.0.1:${config.port}${
|
|
24638
|
+
return await fetcher(`http://127.0.0.1:${config.port}${path39}`, {
|
|
24309
24639
|
...init,
|
|
24310
24640
|
headers
|
|
24311
24641
|
}).catch((error) => {
|
|
@@ -24314,10 +24644,10 @@ async function fetchHermesApi(fetcher, config, path38, init, options) {
|
|
|
24314
24644
|
}
|
|
24315
24645
|
void options.logger?.warn("hermes_api_server_connect_failed", {
|
|
24316
24646
|
method: String(init.method ?? "GET").toUpperCase(),
|
|
24317
|
-
path:
|
|
24647
|
+
path: path39,
|
|
24318
24648
|
profile: options.profileName ?? "default",
|
|
24319
24649
|
port: config.port ?? null,
|
|
24320
|
-
url: `http://127.0.0.1:${config.port}${
|
|
24650
|
+
url: `http://127.0.0.1:${config.port}${path39}`,
|
|
24321
24651
|
error: error instanceof Error ? error.message : String(error)
|
|
24322
24652
|
});
|
|
24323
24653
|
throw new LinkHttpError(
|
|
@@ -24327,10 +24657,10 @@ async function fetchHermesApi(fetcher, config, path38, init, options) {
|
|
|
24327
24657
|
);
|
|
24328
24658
|
});
|
|
24329
24659
|
}
|
|
24330
|
-
function logHermesApiResponse(logger, method,
|
|
24660
|
+
function logHermesApiResponse(logger, method, path39, profileName, startedAt, response) {
|
|
24331
24661
|
const fields = {
|
|
24332
24662
|
method,
|
|
24333
|
-
path:
|
|
24663
|
+
path: path39,
|
|
24334
24664
|
profile: profileName ?? "default",
|
|
24335
24665
|
status: response.status,
|
|
24336
24666
|
duration_ms: Date.now() - startedAt
|
|
@@ -24351,10 +24681,10 @@ async function logHermesApiFailureResponse(logger, fields, response) {
|
|
|
24351
24681
|
...upstreamError ? { upstream_error: upstreamError } : {}
|
|
24352
24682
|
});
|
|
24353
24683
|
}
|
|
24354
|
-
function logHermesApiError(logger, method,
|
|
24684
|
+
function logHermesApiError(logger, method, path39, profileName, startedAt, error) {
|
|
24355
24685
|
void logger?.warn("hermes_api_request_failed", {
|
|
24356
24686
|
method,
|
|
24357
|
-
path:
|
|
24687
|
+
path: path39,
|
|
24358
24688
|
profile: profileName ?? "default",
|
|
24359
24689
|
duration_ms: Date.now() - startedAt,
|
|
24360
24690
|
...error instanceof LinkHttpError ? { status: error.status, code: error.code } : {},
|
|
@@ -26790,6 +27120,127 @@ function isNodeError17(error, code) {
|
|
|
26790
27120
|
return typeof error === "object" && error !== null && "code" in error && error.code === code;
|
|
26791
27121
|
}
|
|
26792
27122
|
|
|
27123
|
+
// src/conversations/hermes-message-watermark.ts
|
|
27124
|
+
import { stat as stat18, readFile as readFile16 } from "fs/promises";
|
|
27125
|
+
import path27 from "path";
|
|
27126
|
+
async function readHermesMessageWatermark(input) {
|
|
27127
|
+
const profileName = input.profileName?.trim() || "default";
|
|
27128
|
+
const sessionId = input.sessionId.trim();
|
|
27129
|
+
const profileDir = resolveHermesProfileDir(profileName);
|
|
27130
|
+
const dbPath = path27.join(profileDir, "state.db");
|
|
27131
|
+
const [dbWatermark, jsonlWatermark] = await Promise.all([
|
|
27132
|
+
readStateDbMessageWatermark(dbPath, sessionId),
|
|
27133
|
+
readJsonlMessageWatermark(profileName, sessionId)
|
|
27134
|
+
]);
|
|
27135
|
+
const selected = (jsonlWatermark.message_count ?? 0) > (dbWatermark.message_count ?? 0) ? jsonlWatermark : dbWatermark;
|
|
27136
|
+
return {
|
|
27137
|
+
...selected,
|
|
27138
|
+
session_id: sessionId,
|
|
27139
|
+
captured_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
27140
|
+
};
|
|
27141
|
+
}
|
|
27142
|
+
async function readStateDbMessageWatermark(dbPath, sessionId) {
|
|
27143
|
+
if (!await isFile3(dbPath)) {
|
|
27144
|
+
return { source: "none", message_count: 0 };
|
|
27145
|
+
}
|
|
27146
|
+
let db = null;
|
|
27147
|
+
try {
|
|
27148
|
+
db = openSqliteDatabase(dbPath, {
|
|
27149
|
+
readonly: true,
|
|
27150
|
+
timeout: 1e3
|
|
27151
|
+
});
|
|
27152
|
+
const columns = readTableColumns4(db, "messages");
|
|
27153
|
+
if (!columns.has("session_id")) {
|
|
27154
|
+
return { source: "none", message_count: 0 };
|
|
27155
|
+
}
|
|
27156
|
+
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";
|
|
27157
|
+
const timestampExpression = columns.has("timestamp") ? "MAX(timestamp) AS max_timestamp" : "NULL AS max_timestamp";
|
|
27158
|
+
const row = db.prepare(
|
|
27159
|
+
`
|
|
27160
|
+
SELECT COUNT(*) AS message_count, ${idExpression}, ${timestampExpression}
|
|
27161
|
+
FROM messages
|
|
27162
|
+
WHERE session_id = ?
|
|
27163
|
+
`
|
|
27164
|
+
).get(sessionId);
|
|
27165
|
+
return {
|
|
27166
|
+
source: "state_db",
|
|
27167
|
+
message_count: readNumber5(row.message_count) ?? 0,
|
|
27168
|
+
...readNumber5(row.max_message_id) !== null ? { max_message_id: readNumber5(row.max_message_id) } : {},
|
|
27169
|
+
...readNumber5(row.max_timestamp) !== null ? { max_timestamp: readNumber5(row.max_timestamp) } : {}
|
|
27170
|
+
};
|
|
27171
|
+
} catch {
|
|
27172
|
+
return { source: "none", message_count: 0 };
|
|
27173
|
+
} finally {
|
|
27174
|
+
db?.close();
|
|
27175
|
+
}
|
|
27176
|
+
}
|
|
27177
|
+
async function readJsonlMessageWatermark(profileName, sessionId) {
|
|
27178
|
+
if (!/^[A-Za-z0-9._:-]{1,160}$/u.test(sessionId)) {
|
|
27179
|
+
return { source: "none", message_count: 0 };
|
|
27180
|
+
}
|
|
27181
|
+
const profileDir = resolveHermesProfileDir(profileName);
|
|
27182
|
+
const sessionsDir = await readHermesSessionsDir(profileName).then((value) => value.sessionsDir).catch(() => path27.join(profileDir, "sessions"));
|
|
27183
|
+
const transcriptPath = path27.join(sessionsDir, `${sessionId}.jsonl`);
|
|
27184
|
+
const raw = await readFile16(transcriptPath, "utf8").catch(() => "");
|
|
27185
|
+
if (!raw.trim()) {
|
|
27186
|
+
return { source: "none", message_count: 0 };
|
|
27187
|
+
}
|
|
27188
|
+
let messageCount = 0;
|
|
27189
|
+
let maxMessageId;
|
|
27190
|
+
let maxTimestamp;
|
|
27191
|
+
for (const line of raw.split(/\r?\n/u)) {
|
|
27192
|
+
if (!line.trim()) {
|
|
27193
|
+
continue;
|
|
27194
|
+
}
|
|
27195
|
+
try {
|
|
27196
|
+
const parsed = JSON.parse(line);
|
|
27197
|
+
if (!readString18(parsed, "role")) {
|
|
27198
|
+
continue;
|
|
27199
|
+
}
|
|
27200
|
+
messageCount += 1;
|
|
27201
|
+
const id = readNumber5(parsed.id);
|
|
27202
|
+
const timestamp = readNumber5(parsed.timestamp) ?? readNumber5(parsed.created_at) ?? readNumber5(parsed.createdAt);
|
|
27203
|
+
if (id !== null) {
|
|
27204
|
+
maxMessageId = maxMessageId === void 0 ? id : Math.max(maxMessageId, id);
|
|
27205
|
+
}
|
|
27206
|
+
if (timestamp !== null) {
|
|
27207
|
+
maxTimestamp = maxTimestamp === void 0 ? timestamp : Math.max(maxTimestamp, timestamp);
|
|
27208
|
+
}
|
|
27209
|
+
} catch {
|
|
27210
|
+
continue;
|
|
27211
|
+
}
|
|
27212
|
+
}
|
|
27213
|
+
return {
|
|
27214
|
+
source: messageCount > 0 ? "jsonl" : "none",
|
|
27215
|
+
message_count: messageCount,
|
|
27216
|
+
...maxMessageId !== void 0 ? { max_message_id: maxMessageId } : {},
|
|
27217
|
+
...maxTimestamp !== void 0 ? { max_timestamp: maxTimestamp } : {}
|
|
27218
|
+
};
|
|
27219
|
+
}
|
|
27220
|
+
function readTableColumns4(db, tableName) {
|
|
27221
|
+
try {
|
|
27222
|
+
const rows = db.prepare(`PRAGMA table_info(${quoteIdentifier3(tableName)})`).all();
|
|
27223
|
+
return new Set(
|
|
27224
|
+
rows.map((row) => typeof row.name === "string" ? row.name : "").filter(Boolean)
|
|
27225
|
+
);
|
|
27226
|
+
} catch {
|
|
27227
|
+
return /* @__PURE__ */ new Set();
|
|
27228
|
+
}
|
|
27229
|
+
}
|
|
27230
|
+
function quoteIdentifier3(value) {
|
|
27231
|
+
return `"${value.replaceAll('"', '""')}"`;
|
|
27232
|
+
}
|
|
27233
|
+
async function isFile3(filePath) {
|
|
27234
|
+
return stat18(filePath).then((value) => value.isFile()).catch(() => false);
|
|
27235
|
+
}
|
|
27236
|
+
function readString18(payload, key) {
|
|
27237
|
+
const value = payload[key];
|
|
27238
|
+
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
27239
|
+
}
|
|
27240
|
+
function readNumber5(value) {
|
|
27241
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
27242
|
+
}
|
|
27243
|
+
|
|
26793
27244
|
// src/conversations/run-tool-event-ids.ts
|
|
26794
27245
|
import { createHash as createHash7 } from "crypto";
|
|
26795
27246
|
var RunToolEventIdCoalescer = class {
|
|
@@ -26883,7 +27334,7 @@ var RunToolEventIdCoalescer = class {
|
|
|
26883
27334
|
}
|
|
26884
27335
|
};
|
|
26885
27336
|
function readToolEventType(event) {
|
|
26886
|
-
const type =
|
|
27337
|
+
const type = readString19(event.payload, "type") ?? readString19(event.payload, "event") ?? event.payloadType;
|
|
26887
27338
|
return type.startsWith("tool.") ? type : null;
|
|
26888
27339
|
}
|
|
26889
27340
|
function isTerminalToolEvent(type) {
|
|
@@ -26894,14 +27345,14 @@ function hasStableToolEventId(payload) {
|
|
|
26894
27345
|
const call = toRecord17(payload.tool_call ?? payload.toolCall);
|
|
26895
27346
|
const fn = toRecord17(call.function ?? payload.function);
|
|
26896
27347
|
return Boolean(
|
|
26897
|
-
|
|
27348
|
+
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
27349
|
);
|
|
26899
27350
|
}
|
|
26900
27351
|
function readToolName2(payload) {
|
|
26901
27352
|
const tool = toRecord17(payload.tool);
|
|
26902
27353
|
const call = toRecord17(payload.tool_call ?? payload.toolCall);
|
|
26903
27354
|
const fn = toRecord17(call.function ?? payload.function);
|
|
26904
|
-
return
|
|
27355
|
+
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
27356
|
}
|
|
26906
27357
|
function withGeneratedToolEventId(event, id) {
|
|
26907
27358
|
return {
|
|
@@ -26958,7 +27409,7 @@ function stableStringify2(value) {
|
|
|
26958
27409
|
function hashStableValue(value) {
|
|
26959
27410
|
return createHash7("sha256").update(value).digest("hex").slice(0, 16);
|
|
26960
27411
|
}
|
|
26961
|
-
function
|
|
27412
|
+
function readString19(payload, key) {
|
|
26962
27413
|
const value = payload[key];
|
|
26963
27414
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
26964
27415
|
}
|
|
@@ -26990,8 +27441,8 @@ function normalizeHermesStreamEvent(event) {
|
|
|
26990
27441
|
};
|
|
26991
27442
|
}
|
|
26992
27443
|
if (event.eventName === "hermes.tool.progress") {
|
|
26993
|
-
const toolName =
|
|
26994
|
-
const preview =
|
|
27444
|
+
const toolName = readString20(event.payload, "tool") ?? readString20(event.payload, "name") ?? "tool";
|
|
27445
|
+
const preview = readString20(event.payload, "label") ?? readString20(event.payload, "preview") ?? toolName;
|
|
26995
27446
|
return {
|
|
26996
27447
|
...event,
|
|
26997
27448
|
payloadType: "tool.started",
|
|
@@ -27043,7 +27494,7 @@ function normalizeReasoningEvent(event) {
|
|
|
27043
27494
|
if (type !== "tool.progress" && event.eventName !== "hermes.tool.progress") {
|
|
27044
27495
|
return null;
|
|
27045
27496
|
}
|
|
27046
|
-
const toolName =
|
|
27497
|
+
const toolName = readString20(event.payload, "tool_name") ?? readString20(event.payload, "tool") ?? readString20(event.payload, "name");
|
|
27047
27498
|
if (toolName !== "_thinking") {
|
|
27048
27499
|
return null;
|
|
27049
27500
|
}
|
|
@@ -27094,7 +27545,7 @@ function normalizeHermesResponseEvent(event) {
|
|
|
27094
27545
|
}
|
|
27095
27546
|
function normalizeResponseCreated(event) {
|
|
27096
27547
|
const response = toRecord18(event.payload.response ?? event.payload);
|
|
27097
|
-
const responseId =
|
|
27548
|
+
const responseId = readString20(response, "id") ?? readString20(event.payload, "id");
|
|
27098
27549
|
return responseId ? {
|
|
27099
27550
|
...event,
|
|
27100
27551
|
payloadType: "response.created",
|
|
@@ -27107,10 +27558,10 @@ function normalizeResponseCreated(event) {
|
|
|
27107
27558
|
}
|
|
27108
27559
|
function normalizeResponseOutputItemAdded(event) {
|
|
27109
27560
|
const item = toRecord18(event.payload.item);
|
|
27110
|
-
if (
|
|
27561
|
+
if (readString20(item, "type") !== "function_call") {
|
|
27111
27562
|
return null;
|
|
27112
27563
|
}
|
|
27113
|
-
const toolName =
|
|
27564
|
+
const toolName = readString20(item, "name") ?? "tool";
|
|
27114
27565
|
const argumentsValue = parseJsonValue3(item.arguments) ?? item.arguments;
|
|
27115
27566
|
return {
|
|
27116
27567
|
...event,
|
|
@@ -27120,16 +27571,16 @@ function normalizeResponseOutputItemAdded(event) {
|
|
|
27120
27571
|
tool: toolName,
|
|
27121
27572
|
tool_name: toolName,
|
|
27122
27573
|
name: toolName,
|
|
27123
|
-
tool_call_id:
|
|
27574
|
+
tool_call_id: readString20(item, "call_id") ?? readString20(item, "id"),
|
|
27124
27575
|
arguments: argumentsValue,
|
|
27125
27576
|
preview: toolName,
|
|
27126
|
-
response_item_id:
|
|
27577
|
+
response_item_id: readString20(item, "id") ?? void 0
|
|
27127
27578
|
}
|
|
27128
27579
|
};
|
|
27129
27580
|
}
|
|
27130
27581
|
function normalizeResponseOutputItemDone(event) {
|
|
27131
27582
|
const item = toRecord18(event.payload.item);
|
|
27132
|
-
if (
|
|
27583
|
+
if (readString20(item, "type") === "message") {
|
|
27133
27584
|
const delta = extractResponseAssistantText({ output: [item] });
|
|
27134
27585
|
return delta ? {
|
|
27135
27586
|
...event,
|
|
@@ -27137,7 +27588,7 @@ function normalizeResponseOutputItemDone(event) {
|
|
|
27137
27588
|
payload: { type: "message.delta", delta }
|
|
27138
27589
|
} : null;
|
|
27139
27590
|
}
|
|
27140
|
-
if (
|
|
27591
|
+
if (readString20(item, "type") !== "function_call_output") {
|
|
27141
27592
|
return null;
|
|
27142
27593
|
}
|
|
27143
27594
|
const output = readResponseItemOutput(item.output);
|
|
@@ -27147,12 +27598,12 @@ function normalizeResponseOutputItemDone(event) {
|
|
|
27147
27598
|
payloadType: "tool.completed",
|
|
27148
27599
|
payload: {
|
|
27149
27600
|
type: "tool.completed",
|
|
27150
|
-
tool_call_id:
|
|
27151
|
-
status:
|
|
27601
|
+
tool_call_id: readString20(item, "call_id") ?? readString20(item, "id"),
|
|
27602
|
+
status: readString20(item, "status") ?? "completed",
|
|
27152
27603
|
output,
|
|
27153
27604
|
content: output,
|
|
27154
27605
|
result: parsedOutput ?? output,
|
|
27155
|
-
response_item_id:
|
|
27606
|
+
response_item_id: readString20(item, "id") ?? void 0
|
|
27156
27607
|
}
|
|
27157
27608
|
};
|
|
27158
27609
|
}
|
|
@@ -27163,7 +27614,7 @@ function normalizeResponseCompleted(event) {
|
|
|
27163
27614
|
payloadType: "run.completed",
|
|
27164
27615
|
payload: {
|
|
27165
27616
|
type: "run.completed",
|
|
27166
|
-
response_id:
|
|
27617
|
+
response_id: readString20(response, "id") ?? readString20(event.payload, "id"),
|
|
27167
27618
|
usage: toRecord18(response.usage),
|
|
27168
27619
|
response
|
|
27169
27620
|
}
|
|
@@ -27177,9 +27628,9 @@ function normalizeResponseFailed(event) {
|
|
|
27177
27628
|
payloadType: "run.failed",
|
|
27178
27629
|
payload: {
|
|
27179
27630
|
type: "run.failed",
|
|
27180
|
-
response_id:
|
|
27631
|
+
response_id: readString20(response, "id") ?? readString20(event.payload, "id"),
|
|
27181
27632
|
error: {
|
|
27182
|
-
message:
|
|
27633
|
+
message: readString20(error, "message") ?? readString20(event.payload, "message") ?? "Hermes run failed"
|
|
27183
27634
|
},
|
|
27184
27635
|
usage: toRecord18(response.usage),
|
|
27185
27636
|
response
|
|
@@ -27206,7 +27657,7 @@ function readErrorMessage4(payload) {
|
|
|
27206
27657
|
return payload.error.trim();
|
|
27207
27658
|
}
|
|
27208
27659
|
const error = toRecord18(payload.error);
|
|
27209
|
-
return
|
|
27660
|
+
return readString20(error, "message") ?? readString20(payload, "message");
|
|
27210
27661
|
}
|
|
27211
27662
|
function readDelta(payload) {
|
|
27212
27663
|
return readText3(payload, "delta") ?? readText3(payload, "text") ?? readText3(payload, "content");
|
|
@@ -27253,7 +27704,7 @@ function readChatCompletionDelta(payload) {
|
|
|
27253
27704
|
}
|
|
27254
27705
|
function readChatCompletionFinishReason(payload) {
|
|
27255
27706
|
const choice = readFirstChoice(payload);
|
|
27256
|
-
return
|
|
27707
|
+
return readString20(choice, "finish_reason") ?? readString20(choice, "finishReason");
|
|
27257
27708
|
}
|
|
27258
27709
|
function readChatCompletionUsage(payload) {
|
|
27259
27710
|
const usage = toRecord18(payload.usage);
|
|
@@ -27293,7 +27744,7 @@ function readAssistantTextFromChoices(payload) {
|
|
|
27293
27744
|
return null;
|
|
27294
27745
|
}
|
|
27295
27746
|
const messages2 = choices.map(toRecord18).map((choice) => toRecord18(choice.message ?? choice.delta)).filter((message) => {
|
|
27296
|
-
const role =
|
|
27747
|
+
const role = readString20(message, "role");
|
|
27297
27748
|
return !role || role === "assistant";
|
|
27298
27749
|
}).map(readResponseMessageText).filter((text) => Boolean(text?.trim()));
|
|
27299
27750
|
return messages2.length > 0 ? messages2.join("\n\n") : null;
|
|
@@ -27309,7 +27760,7 @@ function readInteger3(payload, key) {
|
|
|
27309
27760
|
}
|
|
27310
27761
|
return void 0;
|
|
27311
27762
|
}
|
|
27312
|
-
function
|
|
27763
|
+
function readString20(payload, key) {
|
|
27313
27764
|
const value = payload[key];
|
|
27314
27765
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
27315
27766
|
}
|
|
@@ -27322,8 +27773,8 @@ function readResponseOutputItemText(value) {
|
|
|
27322
27773
|
return value;
|
|
27323
27774
|
}
|
|
27324
27775
|
const item = toRecord18(value);
|
|
27325
|
-
const type =
|
|
27326
|
-
const role =
|
|
27776
|
+
const type = readString20(item, "type");
|
|
27777
|
+
const role = readString20(item, "role");
|
|
27327
27778
|
if (type && type !== "message" && type !== "output_text" && type !== "text") {
|
|
27328
27779
|
return null;
|
|
27329
27780
|
}
|
|
@@ -27349,7 +27800,7 @@ function readResponseContentText(value) {
|
|
|
27349
27800
|
return partValue;
|
|
27350
27801
|
}
|
|
27351
27802
|
const part = toRecord18(partValue);
|
|
27352
|
-
const type =
|
|
27803
|
+
const type = readString20(part, "type");
|
|
27353
27804
|
if (type && !isVisibleResponseTextPart(type)) {
|
|
27354
27805
|
return null;
|
|
27355
27806
|
}
|
|
@@ -27658,6 +28109,11 @@ var ConversationRunLifecycle = class {
|
|
|
27658
28109
|
run.profile ?? "default"
|
|
27659
28110
|
);
|
|
27660
28111
|
const reasoningEffort = reasoningEffortForRun(run);
|
|
28112
|
+
await this.recordRunHermesMessageWatermark({
|
|
28113
|
+
conversationId,
|
|
28114
|
+
runId,
|
|
28115
|
+
phase: "before"
|
|
28116
|
+
});
|
|
27661
28117
|
if (backend === "tui_gateway") {
|
|
27662
28118
|
const rpcRun = await streamTuiGatewayRun({
|
|
27663
28119
|
input: resolvedInput,
|
|
@@ -27873,13 +28329,7 @@ var ConversationRunLifecycle = class {
|
|
|
27873
28329
|
}
|
|
27874
28330
|
} catch (error) {
|
|
27875
28331
|
if (controller.signal.aborted) {
|
|
27876
|
-
await this.
|
|
27877
|
-
conversationId,
|
|
27878
|
-
() => this.cancelRunLocked(conversationId, runId, {
|
|
27879
|
-
abortUpstream: false,
|
|
27880
|
-
reason: "cancelled by app"
|
|
27881
|
-
})
|
|
27882
|
-
);
|
|
28332
|
+
await this.cancelRunAfterAbort(conversationId, runId);
|
|
27883
28333
|
return { shouldDrainQueue: true };
|
|
27884
28334
|
}
|
|
27885
28335
|
if (isTuiGatewaySessionBusyError(error)) {
|
|
@@ -28080,16 +28530,27 @@ var ConversationRunLifecycle = class {
|
|
|
28080
28530
|
}
|
|
28081
28531
|
}
|
|
28082
28532
|
async cancelRun(conversationId, runId, options) {
|
|
28083
|
-
|
|
28533
|
+
const result = await this.deps.withConversationLock(
|
|
28084
28534
|
conversationId,
|
|
28085
28535
|
() => this.cancelRunLocked(conversationId, runId, options)
|
|
28086
28536
|
);
|
|
28537
|
+
await this.recordRunHermesMessageWatermark({
|
|
28538
|
+
conversationId,
|
|
28539
|
+
runId,
|
|
28540
|
+
phase: "after"
|
|
28541
|
+
});
|
|
28542
|
+
return result;
|
|
28087
28543
|
}
|
|
28088
28544
|
async failRun(conversationId, runId, message, source) {
|
|
28089
28545
|
await this.refreshRunHermesCompressionTip(conversationId, runId);
|
|
28546
|
+
const afterWatermark = await this.readRunHermesMessageWatermark(
|
|
28547
|
+
conversationId,
|
|
28548
|
+
runId,
|
|
28549
|
+
"after"
|
|
28550
|
+
);
|
|
28090
28551
|
return this.deps.withConversationLock(
|
|
28091
28552
|
conversationId,
|
|
28092
|
-
() => this.failRunLocked(conversationId, runId, message, source)
|
|
28553
|
+
() => this.failRunLocked(conversationId, runId, message, source, afterWatermark)
|
|
28093
28554
|
);
|
|
28094
28555
|
}
|
|
28095
28556
|
async findConversationIdForRun(runId) {
|
|
@@ -28530,6 +28991,11 @@ var ConversationRunLifecycle = class {
|
|
|
28530
28991
|
reason: "cancelled by app"
|
|
28531
28992
|
})
|
|
28532
28993
|
);
|
|
28994
|
+
await this.recordRunHermesMessageWatermark({
|
|
28995
|
+
conversationId,
|
|
28996
|
+
runId,
|
|
28997
|
+
phase: "after"
|
|
28998
|
+
});
|
|
28533
28999
|
}
|
|
28534
29000
|
async completeCancelledRun(conversationId, runId) {
|
|
28535
29001
|
await this.deps.withConversationLock(
|
|
@@ -28539,6 +29005,11 @@ var ConversationRunLifecycle = class {
|
|
|
28539
29005
|
reason: "cancelled by Hermes"
|
|
28540
29006
|
})
|
|
28541
29007
|
);
|
|
29008
|
+
await this.recordRunHermesMessageWatermark({
|
|
29009
|
+
conversationId,
|
|
29010
|
+
runId,
|
|
29011
|
+
phase: "after"
|
|
29012
|
+
});
|
|
28542
29013
|
}
|
|
28543
29014
|
async recoverRunTerminalEvent(input) {
|
|
28544
29015
|
const deadline = Date.now() + RUN_STATUS_RECOVERY_TIMEOUT_MS;
|
|
@@ -28721,14 +29192,14 @@ var ConversationRunLifecycle = class {
|
|
|
28721
29192
|
(message) => message.id === input.run.trigger_message_id
|
|
28722
29193
|
);
|
|
28723
29194
|
const prefix = guidedInterruptInputPrefix(input.run);
|
|
28724
|
-
if (!userMessage || !userMessage.parts.some(
|
|
29195
|
+
if (!userMessage || !userMessage.parts.some(isVoicePart2)) {
|
|
28725
29196
|
return prefix ? `${prefix}
|
|
28726
29197
|
|
|
28727
29198
|
${input.fallbackInput}` : input.fallbackInput;
|
|
28728
29199
|
}
|
|
28729
29200
|
const content = messageText2(userMessage);
|
|
28730
29201
|
const voiceLines = [];
|
|
28731
|
-
for (const part of userMessage.parts.filter(
|
|
29202
|
+
for (const part of userMessage.parts.filter(isVoicePart2)) {
|
|
28732
29203
|
const audioPath = part.local_path ?? (part.blob ? blobPath(this.deps.paths, part.blob) : "");
|
|
28733
29204
|
const result = await transcribeAudioWithHermesProfile({
|
|
28734
29205
|
audioPath,
|
|
@@ -28738,7 +29209,7 @@ ${input.fallbackInput}` : input.fallbackInput;
|
|
|
28738
29209
|
const label = part.filename ?? part.blob ?? "voice message";
|
|
28739
29210
|
voiceLines.push(`- ${label}: ${result.transcript}`);
|
|
28740
29211
|
}
|
|
28741
|
-
const attachmentLines = userMessage.parts.filter((part) => Boolean(part.blob)).filter((part) => !
|
|
29212
|
+
const attachmentLines = userMessage.parts.filter((part) => Boolean(part.blob)).filter((part) => !isVoicePart2(part)).map((part) => {
|
|
28742
29213
|
const label = part.filename ?? part.blob;
|
|
28743
29214
|
const mime = part.mime ? `, ${part.mime}` : "";
|
|
28744
29215
|
const size = part.size ? `, ${part.size} bytes` : "";
|
|
@@ -28824,6 +29295,47 @@ ${resolved}` : resolved;
|
|
|
28824
29295
|
Object.assign(run, patch);
|
|
28825
29296
|
await this.deps.writeSnapshot(conversationId, snapshot);
|
|
28826
29297
|
}
|
|
29298
|
+
async recordRunHermesMessageWatermark(input) {
|
|
29299
|
+
const point = await this.readRunHermesMessageWatermark(
|
|
29300
|
+
input.conversationId,
|
|
29301
|
+
input.runId,
|
|
29302
|
+
input.phase
|
|
29303
|
+
);
|
|
29304
|
+
if (!point) {
|
|
29305
|
+
return;
|
|
29306
|
+
}
|
|
29307
|
+
await this.deps.withConversationLock(input.conversationId, async () => {
|
|
29308
|
+
const snapshot = await this.deps.readSnapshot(input.conversationId);
|
|
29309
|
+
const run = snapshot.runs.find((item) => item.id === input.runId);
|
|
29310
|
+
if (!run) {
|
|
29311
|
+
return;
|
|
29312
|
+
}
|
|
29313
|
+
applyRunHermesMessageWatermark(run, input.phase, point);
|
|
29314
|
+
await this.deps.writeSnapshot(input.conversationId, snapshot);
|
|
29315
|
+
});
|
|
29316
|
+
}
|
|
29317
|
+
async readRunHermesMessageWatermark(conversationId, runId, phase) {
|
|
29318
|
+
const snapshot = await this.deps.readSnapshot(conversationId).catch(() => null);
|
|
29319
|
+
const run = snapshot?.runs.find((item) => item.id === runId);
|
|
29320
|
+
const sessionId = run?.hermes_session_id?.trim();
|
|
29321
|
+
if (!run || !sessionId) {
|
|
29322
|
+
return null;
|
|
29323
|
+
}
|
|
29324
|
+
return await readHermesMessageWatermark({
|
|
29325
|
+
profileName: run.profile,
|
|
29326
|
+
sessionId
|
|
29327
|
+
}).catch((error) => {
|
|
29328
|
+
void this.deps.logger.debug("hermes_message_watermark_read_failed", {
|
|
29329
|
+
conversation_id: conversationId,
|
|
29330
|
+
run_id: runId,
|
|
29331
|
+
phase,
|
|
29332
|
+
profile: run.profile ?? "default",
|
|
29333
|
+
hermes_session_id: sessionId,
|
|
29334
|
+
error: error instanceof Error ? error.message : String(error)
|
|
29335
|
+
});
|
|
29336
|
+
return null;
|
|
29337
|
+
});
|
|
29338
|
+
}
|
|
28827
29339
|
async updateRunUsageFromEvent(conversationId, runId, event) {
|
|
28828
29340
|
const usage = readUsage(event.payload);
|
|
28829
29341
|
if (!usage) {
|
|
@@ -29217,10 +29729,10 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
29217
29729
|
return goalStatus;
|
|
29218
29730
|
}
|
|
29219
29731
|
async persistGoalStatusUpdate(conversationId, runId, event) {
|
|
29220
|
-
if (
|
|
29732
|
+
if (readString21(event.payload, "kind") !== "goal") {
|
|
29221
29733
|
return null;
|
|
29222
29734
|
}
|
|
29223
|
-
const text =
|
|
29735
|
+
const text = readString21(event.payload, "text") ?? readString21(event.payload, "message") ?? readString21(event.payload, "status") ?? "";
|
|
29224
29736
|
const manifest = await this.deps.readRunnableManifest(conversationId);
|
|
29225
29737
|
const snapshot = await this.deps.readSnapshot(conversationId);
|
|
29226
29738
|
const run = snapshot.runs.find((item) => item.id === runId);
|
|
@@ -29407,7 +29919,7 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
29407
29919
|
}
|
|
29408
29920
|
const textPart = assistant.parts.find((part) => part.type === "text");
|
|
29409
29921
|
const currentText = textPart?.text ?? "";
|
|
29410
|
-
const pendingDeliveryText =
|
|
29922
|
+
const pendingDeliveryText = readString21(
|
|
29411
29923
|
toRecord19(assistant.hermes),
|
|
29412
29924
|
"pending_media_delivery_text"
|
|
29413
29925
|
);
|
|
@@ -29513,7 +30025,7 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
29513
30025
|
}
|
|
29514
30026
|
reasoningDeltaSegmentId(event) {
|
|
29515
30027
|
const payload = event.payload;
|
|
29516
|
-
return
|
|
30028
|
+
return readString21(payload, "segment_id") ?? readString21(payload, "segmentId") ?? readString21(payload, "id") ?? readString21(payload, "tool_call_id") ?? readString21(payload, "tool_id") ?? null;
|
|
29517
30029
|
}
|
|
29518
30030
|
async runRequestsAppDelivery(conversationId, runId) {
|
|
29519
30031
|
const snapshot = await this.deps.readSnapshot(conversationId).catch(() => null);
|
|
@@ -29525,9 +30037,14 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
29525
30037
|
}
|
|
29526
30038
|
async completeRun(conversationId, runId, source) {
|
|
29527
30039
|
await this.refreshRunHermesCompressionTip(conversationId, runId);
|
|
30040
|
+
const afterWatermark = await this.readRunHermesMessageWatermark(
|
|
30041
|
+
conversationId,
|
|
30042
|
+
runId,
|
|
30043
|
+
"after"
|
|
30044
|
+
);
|
|
29528
30045
|
return this.deps.withConversationLock(
|
|
29529
30046
|
conversationId,
|
|
29530
|
-
() => this.completeRunLocked(conversationId, runId, source)
|
|
30047
|
+
() => this.completeRunLocked(conversationId, runId, source, afterWatermark)
|
|
29531
30048
|
);
|
|
29532
30049
|
}
|
|
29533
30050
|
async refreshRunHermesCompressionTip(conversationId, runId) {
|
|
@@ -29564,7 +30081,7 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
29564
30081
|
await this.rememberRunHermesSessionId(conversationId, runId, compressionTip);
|
|
29565
30082
|
return { previousSessionId, nextSessionId: compressionTip };
|
|
29566
30083
|
}
|
|
29567
|
-
async completeRunLocked(conversationId, runId, source) {
|
|
30084
|
+
async completeRunLocked(conversationId, runId, source, afterWatermark) {
|
|
29568
30085
|
let snapshot = await this.deps.readSnapshot(conversationId);
|
|
29569
30086
|
let run = snapshot.runs.find((item) => item.id === runId);
|
|
29570
30087
|
if (!run || run.status !== "running") {
|
|
@@ -29606,6 +30123,9 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
29606
30123
|
if (usage) {
|
|
29607
30124
|
run.usage = mergeRunUsage(run.usage, usage);
|
|
29608
30125
|
}
|
|
30126
|
+
if (afterWatermark) {
|
|
30127
|
+
applyRunHermesMessageWatermark(run, "after", afterWatermark);
|
|
30128
|
+
}
|
|
29609
30129
|
const probeEvent = shouldUseHermesUsageProbe(run.hermes_backend) ? await findHermesUsageProbeEventForRun({
|
|
29610
30130
|
paths: this.deps.paths,
|
|
29611
30131
|
profileName: run.profile,
|
|
@@ -29754,7 +30274,7 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
29754
30274
|
await this.deps.writeManifest(nextManifest);
|
|
29755
30275
|
return goal;
|
|
29756
30276
|
}
|
|
29757
|
-
async failRunLocked(conversationId, runId, message, source) {
|
|
30277
|
+
async failRunLocked(conversationId, runId, message, source, afterWatermark) {
|
|
29758
30278
|
const snapshot = await this.deps.readSnapshot(conversationId).catch(() => null);
|
|
29759
30279
|
if (!snapshot) {
|
|
29760
30280
|
return;
|
|
@@ -29777,6 +30297,9 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
29777
30297
|
if (usage) {
|
|
29778
30298
|
run.usage = mergeRunUsage(run.usage, usage);
|
|
29779
30299
|
}
|
|
30300
|
+
if (afterWatermark) {
|
|
30301
|
+
applyRunHermesMessageWatermark(run, "after", afterWatermark);
|
|
30302
|
+
}
|
|
29780
30303
|
const assistant = snapshot.messages.find(
|
|
29781
30304
|
(item) => item.id === run.assistant_message_id
|
|
29782
30305
|
);
|
|
@@ -30140,7 +30663,7 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
30140
30663
|
includeDisabled: true
|
|
30141
30664
|
});
|
|
30142
30665
|
return new Set(
|
|
30143
|
-
jobs.map((job) =>
|
|
30666
|
+
jobs.map((job) => readString21(job, "id") ?? readString21(job, "job_id")).filter((id) => Boolean(id))
|
|
30144
30667
|
);
|
|
30145
30668
|
}
|
|
30146
30669
|
async bindNewCronJobsCreatedByRun(input) {
|
|
@@ -30240,7 +30763,7 @@ async function readdirWithDirs(directory) {
|
|
|
30240
30763
|
throw error;
|
|
30241
30764
|
});
|
|
30242
30765
|
}
|
|
30243
|
-
function
|
|
30766
|
+
function readString21(payload, key) {
|
|
30244
30767
|
const value = payload[key];
|
|
30245
30768
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
30246
30769
|
}
|
|
@@ -30331,11 +30854,11 @@ function contextCompressionGeneration(message) {
|
|
|
30331
30854
|
return typeof generation === "number" && Number.isFinite(generation) ? Math.max(0, Math.floor(generation)) : null;
|
|
30332
30855
|
}
|
|
30333
30856
|
function readPreviousSessionId(payload) {
|
|
30334
|
-
return
|
|
30857
|
+
return readString21(payload, "old_session_id") ?? readString21(payload, "oldSessionId") ?? readString21(payload, "previous_session_id") ?? readString21(payload, "previousSessionId");
|
|
30335
30858
|
}
|
|
30336
30859
|
function readNextSessionId(payload) {
|
|
30337
30860
|
const info = toRecord19(payload.info);
|
|
30338
|
-
return
|
|
30861
|
+
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
30862
|
}
|
|
30340
30863
|
function eventPayloadWithLanguage(payload, language) {
|
|
30341
30864
|
return { ...payload, language };
|
|
@@ -30427,13 +30950,13 @@ function isFileSearchCompletion(payloadType, payload) {
|
|
|
30427
30950
|
const toolCall = toRecord19(payload.tool_call ?? payload.toolCall);
|
|
30428
30951
|
const fn = toRecord19(toolCall.function ?? payload.function);
|
|
30429
30952
|
const candidates = [
|
|
30430
|
-
|
|
30431
|
-
|
|
30432
|
-
|
|
30433
|
-
|
|
30434
|
-
|
|
30435
|
-
|
|
30436
|
-
|
|
30953
|
+
readString21(payload, "tool_name"),
|
|
30954
|
+
readString21(payload, "toolName"),
|
|
30955
|
+
readString21(payload, "name"),
|
|
30956
|
+
readString21(payload, "tool"),
|
|
30957
|
+
readString21(tool, "name"),
|
|
30958
|
+
readString21(toolCall, "name"),
|
|
30959
|
+
readString21(fn, "name")
|
|
30437
30960
|
].filter((value) => Boolean(value)).map(normalizeToolName);
|
|
30438
30961
|
return candidates.some(
|
|
30439
30962
|
(name) => [
|
|
@@ -30470,7 +30993,7 @@ function messageRequestsAppDelivery(text) {
|
|
|
30470
30993
|
const hasEnglishDeliveryAction = /\b(send|share|attach|deliver|display)\b/u.test(lower) || /\bshow\s+me\b/u.test(lower);
|
|
30471
30994
|
return hasEnglishDeliverable && hasEnglishDeliveryAction;
|
|
30472
30995
|
}
|
|
30473
|
-
function
|
|
30996
|
+
function isVoicePart2(part) {
|
|
30474
30997
|
return part.kind === "voice" || part.is_voice_note === true;
|
|
30475
30998
|
}
|
|
30476
30999
|
function normalizeToolName(value) {
|
|
@@ -30773,13 +31296,13 @@ function readResponseId(payload) {
|
|
|
30773
31296
|
return null;
|
|
30774
31297
|
}
|
|
30775
31298
|
const response = toRecord19(payload.response);
|
|
30776
|
-
return
|
|
31299
|
+
return readString21(payload, "response_id") ?? readString21(response, "id");
|
|
30777
31300
|
}
|
|
30778
31301
|
function readRunId(payload) {
|
|
30779
31302
|
if (!payload) {
|
|
30780
31303
|
return null;
|
|
30781
31304
|
}
|
|
30782
|
-
return
|
|
31305
|
+
return readString21(payload, "run_id") ?? readString21(payload, "runId");
|
|
30783
31306
|
}
|
|
30784
31307
|
function isCompletedRunStatus(status) {
|
|
30785
31308
|
return status === "completed" || status === "complete" || status === "succeeded" || status === "success" || status === "done";
|
|
@@ -30798,7 +31321,7 @@ function readStatusErrorMessage(value) {
|
|
|
30798
31321
|
return value.trim();
|
|
30799
31322
|
}
|
|
30800
31323
|
const record = toRecord19(value);
|
|
30801
|
-
return
|
|
31324
|
+
return readString21(record, "message") ?? readString21(record, "error");
|
|
30802
31325
|
}
|
|
30803
31326
|
function formatUnknownErrorMessage(error) {
|
|
30804
31327
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -30837,6 +31360,12 @@ function sanitizeLiveSessionForEvent(liveSession) {
|
|
|
30837
31360
|
...liveSession.inflight ? { inflight: liveSession.inflight } : {}
|
|
30838
31361
|
};
|
|
30839
31362
|
}
|
|
31363
|
+
function applyRunHermesMessageWatermark(run, phase, point) {
|
|
31364
|
+
run.hermes_message_watermark = {
|
|
31365
|
+
...run.hermes_message_watermark ?? {},
|
|
31366
|
+
[phase]: point
|
|
31367
|
+
};
|
|
31368
|
+
}
|
|
30840
31369
|
function previewText2(message) {
|
|
30841
31370
|
if (!message) {
|
|
30842
31371
|
return null;
|
|
@@ -32561,7 +33090,7 @@ var ConversationService = class {
|
|
|
32561
33090
|
}
|
|
32562
33091
|
}
|
|
32563
33092
|
hermesArchiveStateSyncMarkerPath() {
|
|
32564
|
-
return
|
|
33093
|
+
return path28.join(this.paths.indexesDir, "hermes-archive-state-sync.json");
|
|
32565
33094
|
}
|
|
32566
33095
|
prepareClearAllConversationPlan(targetStatus) {
|
|
32567
33096
|
return this.maintenance.prepareClearAllConversationPlan(targetStatus);
|
|
@@ -32843,7 +33372,7 @@ function liveActivityTodoProgressForEvent(event) {
|
|
|
32843
33372
|
if (todos) {
|
|
32844
33373
|
const totalCount2 = todos.length;
|
|
32845
33374
|
const doneCount2 = todos.filter((item) => {
|
|
32846
|
-
const status =
|
|
33375
|
+
const status = readString22(item, "status")?.toLowerCase();
|
|
32847
33376
|
return status === "completed" || status === "cancelled" || status === "canceled";
|
|
32848
33377
|
}).length;
|
|
32849
33378
|
return {
|
|
@@ -32892,11 +33421,11 @@ function liveActivityTitleFromConversationUpdate(event) {
|
|
|
32892
33421
|
if (event.type.toLowerCase() !== "conversation.updated") {
|
|
32893
33422
|
return void 0;
|
|
32894
33423
|
}
|
|
32895
|
-
const titleSource =
|
|
33424
|
+
const titleSource = readString22(event.payload, "title_source");
|
|
32896
33425
|
if (titleSource === "default" || titleSource === "temporary_fallback") {
|
|
32897
33426
|
return null;
|
|
32898
33427
|
}
|
|
32899
|
-
const title =
|
|
33428
|
+
const title = readString22(event.payload, "title");
|
|
32900
33429
|
return title ? truncateLiveActivityTitle(title, 24) : null;
|
|
32901
33430
|
}
|
|
32902
33431
|
function liveActivityTitleFromManifest(manifest) {
|
|
@@ -32936,7 +33465,7 @@ function isConversationTitleUpdateEvent(event) {
|
|
|
32936
33465
|
if (event.type.toLowerCase() !== "conversation.updated") {
|
|
32937
33466
|
return false;
|
|
32938
33467
|
}
|
|
32939
|
-
return Boolean(
|
|
33468
|
+
return Boolean(readString22(event.payload, "title")?.trim());
|
|
32940
33469
|
}
|
|
32941
33470
|
function resolveLiveActivityTarget(input) {
|
|
32942
33471
|
if (input.run?.kind === "compression") {
|
|
@@ -32958,7 +33487,7 @@ function liveActivityPhaseForEvent(event, run, contextOperation) {
|
|
|
32958
33487
|
}
|
|
32959
33488
|
if (type === "conversation.goal.updated") {
|
|
32960
33489
|
const goal = readRecord2(event.payload).goal;
|
|
32961
|
-
const status =
|
|
33490
|
+
const status = readString22(goal, "status");
|
|
32962
33491
|
return status === "paused" ? "goal_paused" : "goal_running";
|
|
32963
33492
|
}
|
|
32964
33493
|
if (isConversationTitleUpdateEvent(event)) {
|
|
@@ -33091,7 +33620,7 @@ function readContextCompressionOperation(payload) {
|
|
|
33091
33620
|
if (!operation || typeof operation !== "object") {
|
|
33092
33621
|
return null;
|
|
33093
33622
|
}
|
|
33094
|
-
const operationId =
|
|
33623
|
+
const operationId = readString22(operation, "operation_id");
|
|
33095
33624
|
if (!operationId) {
|
|
33096
33625
|
return null;
|
|
33097
33626
|
}
|
|
@@ -33099,19 +33628,19 @@ function readContextCompressionOperation(payload) {
|
|
|
33099
33628
|
return {
|
|
33100
33629
|
operation_id: operationId,
|
|
33101
33630
|
generation: typeof record.generation === "number" ? record.generation : 0,
|
|
33102
|
-
status:
|
|
33103
|
-
started_at:
|
|
33104
|
-
source:
|
|
33631
|
+
status: readString22(record, "status") === "completed" ? "completed" : readString22(record, "status") === "failed" ? "failed" : readString22(record, "status") === "timed_out" ? "timed_out" : readString22(record, "status") === "cancelled" ? "cancelled" : "compressing",
|
|
33632
|
+
started_at: readString22(record, "started_at") ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
33633
|
+
source: readString22(record, "source") === "manual" ? "manual" : "auto"
|
|
33105
33634
|
};
|
|
33106
33635
|
}
|
|
33107
33636
|
function readToolName3(payload) {
|
|
33108
33637
|
const record = readRecord2(payload);
|
|
33109
|
-
return
|
|
33638
|
+
return readString22(record, "tool_name") ?? readString22(record, "tool") ?? readString22(record, "name") ?? readString22(readRecord2(record.tool), "name");
|
|
33110
33639
|
}
|
|
33111
33640
|
function readRecord2(value) {
|
|
33112
33641
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
|
|
33113
33642
|
}
|
|
33114
|
-
function
|
|
33643
|
+
function readString22(value, key) {
|
|
33115
33644
|
const raw = readRecord2(value)[key];
|
|
33116
33645
|
return typeof raw === "string" && raw.trim() ? raw.trim() : null;
|
|
33117
33646
|
}
|
|
@@ -33631,7 +34160,7 @@ async function readRawBody(request, maxBytes) {
|
|
|
33631
34160
|
}
|
|
33632
34161
|
return Buffer.concat(chunks);
|
|
33633
34162
|
}
|
|
33634
|
-
function
|
|
34163
|
+
function readString23(body, key) {
|
|
33635
34164
|
const value = body[key];
|
|
33636
34165
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
33637
34166
|
}
|
|
@@ -33666,7 +34195,7 @@ function readSupportedLanguage(value) {
|
|
|
33666
34195
|
return null;
|
|
33667
34196
|
}
|
|
33668
34197
|
function readOptionalProfileName(body) {
|
|
33669
|
-
return
|
|
34198
|
+
return readString23(body, "profile") ?? readString23(body, "profile_name") ?? readString23(body, "profileName") ?? void 0;
|
|
33670
34199
|
}
|
|
33671
34200
|
function readStringArray(body, ...keys) {
|
|
33672
34201
|
for (const key of keys) {
|
|
@@ -34086,7 +34615,7 @@ function registerConversationRoutes(router, options) {
|
|
|
34086
34615
|
const language = readPreferredLanguage(ctx);
|
|
34087
34616
|
const body = await readJsonBody(ctx.req);
|
|
34088
34617
|
ctx.status = 201;
|
|
34089
|
-
const rawReasoningEffort =
|
|
34618
|
+
const rawReasoningEffort = readString23(body, "reasoning_effort") ?? readString23(body, "reasoningEffort") ?? readString23(body, "default_reasoning_effort") ?? readString23(body, "defaultReasoningEffort");
|
|
34090
34619
|
const reasoningEffort = normalizeReasoningEffort(rawReasoningEffort);
|
|
34091
34620
|
if (rawReasoningEffort && !reasoningEffort) {
|
|
34092
34621
|
throw new LinkHttpError(
|
|
@@ -34099,15 +34628,15 @@ function registerConversationRoutes(router, options) {
|
|
|
34099
34628
|
ok: true,
|
|
34100
34629
|
conversation: localizeConversationSummary(
|
|
34101
34630
|
await conversations.createConversation({
|
|
34102
|
-
title:
|
|
34631
|
+
title: readString23(body, "title") ?? void 0,
|
|
34103
34632
|
profileName: readOptionalProfileName(body),
|
|
34104
34633
|
accountId: auth.accountId,
|
|
34105
34634
|
appInstanceId: auth.appInstanceId,
|
|
34106
34635
|
workspaceId: readConversationWorkspaceId(body),
|
|
34107
|
-
modelId:
|
|
34108
|
-
modelProvider:
|
|
34109
|
-
modelBaseUrl:
|
|
34110
|
-
modelApiMode:
|
|
34636
|
+
modelId: readString23(body, "model_id") ?? readString23(body, "modelId") ?? readString23(body, "model") ?? void 0,
|
|
34637
|
+
modelProvider: readString23(body, "model_provider") ?? readString23(body, "modelProvider") ?? readString23(body, "provider") ?? void 0,
|
|
34638
|
+
modelBaseUrl: readString23(body, "model_base_url") ?? readString23(body, "modelBaseUrl") ?? readString23(body, "base_url") ?? readString23(body, "baseUrl") ?? void 0,
|
|
34639
|
+
modelApiMode: readString23(body, "model_api_mode") ?? readString23(body, "modelApiMode") ?? readString23(body, "api_mode") ?? readString23(body, "apiMode") ?? void 0,
|
|
34111
34640
|
reasoningEffort
|
|
34112
34641
|
}),
|
|
34113
34642
|
language
|
|
@@ -34185,9 +34714,9 @@ function registerConversationRoutes(router, options) {
|
|
|
34185
34714
|
const auth = await authenticateRequest(ctx, paths);
|
|
34186
34715
|
const language = readPreferredLanguage(ctx);
|
|
34187
34716
|
const body = await readJsonBody(ctx.req);
|
|
34188
|
-
const content =
|
|
34717
|
+
const content = readString23(body, "content") ?? readString23(body, "text") ?? readString23(body, "input") ?? "";
|
|
34189
34718
|
const attachments = readMessageAttachments(body.attachments ?? body.blobs);
|
|
34190
|
-
const mode =
|
|
34719
|
+
const mode = readString23(body, "mode") ?? readString23(body, "send_mode");
|
|
34191
34720
|
if (mode && mode !== "message" && mode !== "goal") {
|
|
34192
34721
|
throw new LinkHttpError(
|
|
34193
34722
|
400,
|
|
@@ -34210,7 +34739,7 @@ function registerConversationRoutes(router, options) {
|
|
|
34210
34739
|
conversationId: ctx.params.conversationId,
|
|
34211
34740
|
content,
|
|
34212
34741
|
attachments,
|
|
34213
|
-
clientMessageId:
|
|
34742
|
+
clientMessageId: readString23(body, "client_message_id") ?? readString23(body, "clientMessageId") ?? void 0,
|
|
34214
34743
|
idempotencyKey: readHeader(ctx, "idempotency-key") ?? void 0,
|
|
34215
34744
|
profileName: readOptionalProfileName(body),
|
|
34216
34745
|
mode: mode === "goal" ? "goal" : "message",
|
|
@@ -34277,8 +34806,8 @@ function registerConversationRoutes(router, options) {
|
|
|
34277
34806
|
...localizeConversationResult(
|
|
34278
34807
|
await conversations.startContextCompression({
|
|
34279
34808
|
conversationId: ctx.params.conversationId,
|
|
34280
|
-
focus:
|
|
34281
|
-
clientOperationId:
|
|
34809
|
+
focus: readString23(body, "focus") ?? readString23(body, "focus_topic") ?? readString23(body, "focusTopic") ?? void 0,
|
|
34810
|
+
clientOperationId: readString23(body, "client_operation_id") ?? readString23(body, "clientOperationId") ?? readHeader(ctx, "idempotency-key") ?? void 0,
|
|
34282
34811
|
createUserMessage: false,
|
|
34283
34812
|
accountId: auth.accountId,
|
|
34284
34813
|
appInstanceId: auth.appInstanceId,
|
|
@@ -34292,11 +34821,11 @@ function registerConversationRoutes(router, options) {
|
|
|
34292
34821
|
router.patch("/api/v1/conversations/:conversationId/model", async (ctx) => {
|
|
34293
34822
|
await authenticateRequest(ctx, paths);
|
|
34294
34823
|
const body = await readJsonBody(ctx.req);
|
|
34295
|
-
const modelId =
|
|
34296
|
-
const modelProvider =
|
|
34297
|
-
const modelBaseUrl =
|
|
34298
|
-
const modelApiMode =
|
|
34299
|
-
const rawReasoningEffort =
|
|
34824
|
+
const modelId = readString23(body, "model_id") ?? readString23(body, "modelId") ?? readString23(body, "model");
|
|
34825
|
+
const modelProvider = readString23(body, "model_provider") ?? readString23(body, "modelProvider") ?? readString23(body, "provider") ?? void 0;
|
|
34826
|
+
const modelBaseUrl = readString23(body, "model_base_url") ?? readString23(body, "modelBaseUrl") ?? readString23(body, "base_url") ?? readString23(body, "baseUrl") ?? void 0;
|
|
34827
|
+
const modelApiMode = readString23(body, "model_api_mode") ?? readString23(body, "modelApiMode") ?? readString23(body, "api_mode") ?? readString23(body, "apiMode") ?? void 0;
|
|
34828
|
+
const rawReasoningEffort = readString23(body, "reasoning_effort") ?? readString23(body, "reasoningEffort") ?? readString23(body, "default_reasoning_effort") ?? readString23(body, "defaultReasoningEffort");
|
|
34300
34829
|
const reasoningEffort = normalizeReasoningEffort(rawReasoningEffort);
|
|
34301
34830
|
if (rawReasoningEffort && !reasoningEffort) {
|
|
34302
34831
|
throw new LinkHttpError(
|
|
@@ -34346,7 +34875,7 @@ function registerConversationRoutes(router, options) {
|
|
|
34346
34875
|
await authenticateRequest(ctx, paths);
|
|
34347
34876
|
const language = readPreferredLanguage(ctx);
|
|
34348
34877
|
const body = await readJsonBody(ctx.req);
|
|
34349
|
-
const title =
|
|
34878
|
+
const title = readString23(body, "title") ?? readString23(body, "name") ?? readString23(body, "display_name");
|
|
34350
34879
|
if (!title) {
|
|
34351
34880
|
throw new LinkHttpError(400, "title_required", "title is required");
|
|
34352
34881
|
}
|
|
@@ -34538,7 +35067,7 @@ function registerConversationRoutes(router, options) {
|
|
|
34538
35067
|
async (ctx) => {
|
|
34539
35068
|
await authenticateRequest(ctx, paths);
|
|
34540
35069
|
const body = await readJsonBody(ctx.req);
|
|
34541
|
-
const scope =
|
|
35070
|
+
const scope = readString23(body, "scope") ?? "always";
|
|
34542
35071
|
ctx.body = {
|
|
34543
35072
|
ok: true,
|
|
34544
35073
|
...await conversations.resolveApproval({
|
|
@@ -34588,7 +35117,7 @@ function registerConversationRoutes(router, options) {
|
|
|
34588
35117
|
conversationId: ctx.params.conversationId,
|
|
34589
35118
|
requestId: ctx.params.requestId,
|
|
34590
35119
|
kind,
|
|
34591
|
-
answer:
|
|
35120
|
+
answer: readString23(body, "answer") ?? void 0,
|
|
34592
35121
|
password: readRawString(body, "password"),
|
|
34593
35122
|
value: readRawString(body, "value")
|
|
34594
35123
|
})
|
|
@@ -34757,10 +35286,10 @@ function readConversationWorkspaceFilter(query) {
|
|
|
34757
35286
|
}
|
|
34758
35287
|
function readConversationWorkspaceId(body) {
|
|
34759
35288
|
if (Object.prototype.hasOwnProperty.call(body, "workspace_id") || Object.prototype.hasOwnProperty.call(body, "workspaceId")) {
|
|
34760
|
-
return
|
|
35289
|
+
return readString23(body, "workspace_id") ?? readString23(body, "workspaceId");
|
|
34761
35290
|
}
|
|
34762
35291
|
if (Object.prototype.hasOwnProperty.call(body, "workspace")) {
|
|
34763
|
-
return
|
|
35292
|
+
return readString23(body, "workspace");
|
|
34764
35293
|
}
|
|
34765
35294
|
return void 0;
|
|
34766
35295
|
}
|
|
@@ -34854,7 +35383,7 @@ function resolveConversationEventCursor(input) {
|
|
|
34854
35383
|
return Math.max(queryAfter, headerAfter);
|
|
34855
35384
|
}
|
|
34856
35385
|
function readConversationClearPlanTargetStatus(body) {
|
|
34857
|
-
const raw =
|
|
35386
|
+
const raw = readString23(body, "target_status") ?? readString23(body, "targetStatus") ?? "active";
|
|
34858
35387
|
if (raw === "active" || raw === "archived") {
|
|
34859
35388
|
return raw;
|
|
34860
35389
|
}
|
|
@@ -34865,7 +35394,7 @@ function readConversationClearPlanTargetStatus(body) {
|
|
|
34865
35394
|
);
|
|
34866
35395
|
}
|
|
34867
35396
|
function readInputRequestKind2(body) {
|
|
34868
|
-
const kind =
|
|
35397
|
+
const kind = readString23(body, "kind") ?? readString23(body, "type");
|
|
34869
35398
|
if (kind === "clarify" || kind === "sudo" || kind === "secret") {
|
|
34870
35399
|
return kind;
|
|
34871
35400
|
}
|
|
@@ -34995,11 +35524,11 @@ function isSseRequestContext(ctx) {
|
|
|
34995
35524
|
}
|
|
34996
35525
|
return isSseRequestPath(ctx.path) || isActiveSseSocket(ctx.req.socket);
|
|
34997
35526
|
}
|
|
34998
|
-
function isSseRequestPath(
|
|
34999
|
-
if (!
|
|
35527
|
+
function isSseRequestPath(path39) {
|
|
35528
|
+
if (!path39) {
|
|
35000
35529
|
return false;
|
|
35001
35530
|
}
|
|
35002
|
-
return
|
|
35531
|
+
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
35532
|
}
|
|
35004
35533
|
function isExpectedClientDisconnectError2(error, options = {}) {
|
|
35005
35534
|
if (!(error instanceof Error)) {
|
|
@@ -35263,7 +35792,7 @@ function toHermesCronJobInput(input) {
|
|
|
35263
35792
|
};
|
|
35264
35793
|
}
|
|
35265
35794
|
async function bindAndDecorateCronJobForHermesLink(input) {
|
|
35266
|
-
const jobId =
|
|
35795
|
+
const jobId = readString23(input.job, "id") ?? readString23(input.job, "job_id");
|
|
35267
35796
|
if (!jobId) {
|
|
35268
35797
|
return input.job;
|
|
35269
35798
|
}
|
|
@@ -35282,9 +35811,9 @@ async function bindAndDecorateCronJobForHermesLink(input) {
|
|
|
35282
35811
|
}
|
|
35283
35812
|
function readCronJobCreateInput(body) {
|
|
35284
35813
|
const input = {};
|
|
35285
|
-
const name =
|
|
35286
|
-
const prompt =
|
|
35287
|
-
const schedule =
|
|
35814
|
+
const name = readString23(body, "name") ?? readString23(body, "title");
|
|
35815
|
+
const prompt = readString23(body, "prompt") ?? readString23(body, "description") ?? readString23(body, "task");
|
|
35816
|
+
const schedule = readString23(body, "schedule");
|
|
35288
35817
|
if (!name) {
|
|
35289
35818
|
throw new LinkHttpError(400, "cron_job_name_required", "name is required");
|
|
35290
35819
|
}
|
|
@@ -35305,7 +35834,7 @@ function readCronJobCreateInput(body) {
|
|
|
35305
35834
|
input.name = name;
|
|
35306
35835
|
input.prompt = prompt;
|
|
35307
35836
|
input.schedule = schedule;
|
|
35308
|
-
input.deliver =
|
|
35837
|
+
input.deliver = readString23(body, "deliver") ?? HERMES_LINK_CRON_DELIVER;
|
|
35309
35838
|
const skills = readOptionalCronSkills(body);
|
|
35310
35839
|
if (skills) {
|
|
35311
35840
|
input.skills = skills;
|
|
@@ -35438,7 +35967,7 @@ import { createHash as createHash11 } from "crypto";
|
|
|
35438
35967
|
// src/model-catalog/catalog.ts
|
|
35439
35968
|
import { randomInt } from "crypto";
|
|
35440
35969
|
import { mkdir as mkdir12 } from "fs/promises";
|
|
35441
|
-
import
|
|
35970
|
+
import path29 from "path";
|
|
35442
35971
|
import { fileURLToPath } from "url";
|
|
35443
35972
|
var MODEL_CATALOG_CACHE_VERSION = 1;
|
|
35444
35973
|
var MODEL_CATALOG_FETCH_TIMEOUT_MS = 1e4;
|
|
@@ -35642,7 +36171,7 @@ async function readCachedCatalogFile(paths) {
|
|
|
35642
36171
|
return cached;
|
|
35643
36172
|
}
|
|
35644
36173
|
async function writeCachedCatalog(paths, value) {
|
|
35645
|
-
await mkdir12(
|
|
36174
|
+
await mkdir12(path29.dirname(modelCatalogCachePath(paths)), {
|
|
35646
36175
|
recursive: true,
|
|
35647
36176
|
mode: 448
|
|
35648
36177
|
});
|
|
@@ -35658,7 +36187,7 @@ async function readFallbackCatalog() {
|
|
|
35658
36187
|
throw new Error("model capability fallback catalog was not found");
|
|
35659
36188
|
}
|
|
35660
36189
|
function modelCatalogCachePath(paths) {
|
|
35661
|
-
return
|
|
36190
|
+
return path29.join(paths.homeDir, "model-capabilities", "catalog-cache.json");
|
|
35662
36191
|
}
|
|
35663
36192
|
function normalizeModelCapabilityCatalog(value) {
|
|
35664
36193
|
if (!value || typeof value !== "object") {
|
|
@@ -35669,7 +36198,7 @@ function normalizeModelCapabilityCatalog(value) {
|
|
|
35669
36198
|
const models = rawModels.map(normalizeModelCapabilityEntry).filter((entry) => entry !== null);
|
|
35670
36199
|
return {
|
|
35671
36200
|
schemaVersion: readPositiveInteger3(record.schemaVersion) ?? 1,
|
|
35672
|
-
updatedAt:
|
|
36201
|
+
updatedAt: readString24(record.updatedAt),
|
|
35673
36202
|
models
|
|
35674
36203
|
};
|
|
35675
36204
|
}
|
|
@@ -35678,7 +36207,7 @@ function normalizeModelCapabilityEntry(value) {
|
|
|
35678
36207
|
return null;
|
|
35679
36208
|
}
|
|
35680
36209
|
const record = value;
|
|
35681
|
-
const canonicalId =
|
|
36210
|
+
const canonicalId = readString24(record.canonicalId) ?? readString24(record.canonical_id) ?? readString24(record.id);
|
|
35682
36211
|
if (!canonicalId) {
|
|
35683
36212
|
return null;
|
|
35684
36213
|
}
|
|
@@ -35706,12 +36235,12 @@ function normalizeModelCapabilityEntry(value) {
|
|
|
35706
36235
|
outputModalities: readStringArray2(
|
|
35707
36236
|
record.outputModalities ?? record.output_modalities
|
|
35708
36237
|
),
|
|
35709
|
-
source:
|
|
35710
|
-
updatedAt:
|
|
35711
|
-
notes:
|
|
36238
|
+
source: readString24(record.source),
|
|
36239
|
+
updatedAt: readString24(record.updatedAt ?? record.updated_at),
|
|
36240
|
+
notes: readString24(record.notes)
|
|
35712
36241
|
};
|
|
35713
36242
|
}
|
|
35714
|
-
function
|
|
36243
|
+
function readString24(value) {
|
|
35715
36244
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
35716
36245
|
}
|
|
35717
36246
|
function readStringArray2(value) {
|
|
@@ -35721,7 +36250,7 @@ function readStringArray2(value) {
|
|
|
35721
36250
|
const seen = /* @__PURE__ */ new Set();
|
|
35722
36251
|
const values = [];
|
|
35723
36252
|
for (const item of value) {
|
|
35724
|
-
const text =
|
|
36253
|
+
const text = readString24(item);
|
|
35725
36254
|
if (!text || seen.has(text)) {
|
|
35726
36255
|
continue;
|
|
35727
36256
|
}
|
|
@@ -35738,7 +36267,7 @@ function readPositiveInteger3(value) {
|
|
|
35738
36267
|
return Math.floor(number);
|
|
35739
36268
|
}
|
|
35740
36269
|
function readReasoningSupportPolicy(value) {
|
|
35741
|
-
const normalized =
|
|
36270
|
+
const normalized = readString24(value)?.toLowerCase();
|
|
35742
36271
|
if (!normalized || normalized === "unknown" || normalized === "auto") {
|
|
35743
36272
|
return null;
|
|
35744
36273
|
}
|
|
@@ -35769,7 +36298,7 @@ function readNullableBoolean(value) {
|
|
|
35769
36298
|
if (typeof value === "boolean") {
|
|
35770
36299
|
return value;
|
|
35771
36300
|
}
|
|
35772
|
-
const normalized =
|
|
36301
|
+
const normalized = readString24(value)?.toLowerCase();
|
|
35773
36302
|
if (!normalized) {
|
|
35774
36303
|
return null;
|
|
35775
36304
|
}
|
|
@@ -36918,8 +37447,8 @@ function normalizeUrlForIdentity(value) {
|
|
|
36918
37447
|
return value.trim().replace(/\/+$/u, "").toLowerCase();
|
|
36919
37448
|
}
|
|
36920
37449
|
function readModelProviderConfigInput(body) {
|
|
36921
|
-
const providerName =
|
|
36922
|
-
const baseUrl =
|
|
37450
|
+
const providerName = readString23(body, "display_name") ?? readString23(body, "displayName") ?? readString23(body, "provider_name") ?? readString23(body, "providerName") ?? readString23(body, "name");
|
|
37451
|
+
const baseUrl = readString23(body, "base_url") ?? readString23(body, "baseUrl");
|
|
36923
37452
|
if (!providerName || !baseUrl) {
|
|
36924
37453
|
throw new LinkHttpError(
|
|
36925
37454
|
400,
|
|
@@ -36930,15 +37459,15 @@ function readModelProviderConfigInput(body) {
|
|
|
36930
37459
|
return {
|
|
36931
37460
|
providerName,
|
|
36932
37461
|
baseUrl,
|
|
36933
|
-
apiMode:
|
|
36934
|
-
keyEnv:
|
|
36935
|
-
apiKey:
|
|
37462
|
+
apiMode: readString23(body, "api_mode") ?? readString23(body, "apiMode") ?? readString23(body, "transport") ?? void 0,
|
|
37463
|
+
keyEnv: readString23(body, "key_env") ?? readString23(body, "keyEnv") ?? void 0,
|
|
37464
|
+
apiKey: readString23(body, "api_key") ?? readString23(body, "apiKey") ?? void 0
|
|
36936
37465
|
};
|
|
36937
37466
|
}
|
|
36938
37467
|
function readModelConfigInput(body) {
|
|
36939
|
-
const id =
|
|
36940
|
-
const provider =
|
|
36941
|
-
const baseUrl =
|
|
37468
|
+
const id = readString23(body, "id") ?? readString23(body, "model_id") ?? readString23(body, "modelId");
|
|
37469
|
+
const provider = readString23(body, "provider") ?? readString23(body, "provider_key") ?? readString23(body, "providerKey");
|
|
37470
|
+
const baseUrl = readString23(body, "base_url") ?? readString23(body, "baseUrl");
|
|
36942
37471
|
if (!id || !provider || !baseUrl) {
|
|
36943
37472
|
throw new LinkHttpError(
|
|
36944
37473
|
400,
|
|
@@ -36948,22 +37477,22 @@ function readModelConfigInput(body) {
|
|
|
36948
37477
|
}
|
|
36949
37478
|
return {
|
|
36950
37479
|
id,
|
|
36951
|
-
originalModelId:
|
|
36952
|
-
originalProvider:
|
|
36953
|
-
originalBaseUrl:
|
|
36954
|
-
originalApiMode:
|
|
37480
|
+
originalModelId: readString23(body, "original_model_id") ?? readString23(body, "originalModelId") ?? readString23(body, "original_id") ?? void 0,
|
|
37481
|
+
originalProvider: readString23(body, "original_provider") ?? readString23(body, "originalProvider") ?? readString23(body, "original_provider_key") ?? readString23(body, "originalProviderKey") ?? void 0,
|
|
37482
|
+
originalBaseUrl: readString23(body, "original_base_url") ?? readString23(body, "originalBaseUrl") ?? void 0,
|
|
37483
|
+
originalApiMode: readString23(body, "original_api_mode") ?? readString23(body, "originalApiMode") ?? void 0,
|
|
36955
37484
|
provider,
|
|
36956
|
-
providerName:
|
|
37485
|
+
providerName: readString23(body, "provider_name") ?? readString23(body, "providerName") ?? void 0,
|
|
36957
37486
|
baseUrl,
|
|
36958
|
-
apiKey:
|
|
36959
|
-
apiMode:
|
|
37487
|
+
apiKey: readString23(body, "api_key") ?? readString23(body, "apiKey") ?? void 0,
|
|
37488
|
+
apiMode: readString23(body, "api_mode") ?? readString23(body, "apiMode") ?? void 0,
|
|
36960
37489
|
contextLength: readPositiveInteger2(
|
|
36961
37490
|
body.context_length ?? body.contextLength
|
|
36962
37491
|
),
|
|
36963
|
-
keyEnv:
|
|
37492
|
+
keyEnv: readString23(body, "key_env") ?? readString23(body, "keyEnv") ?? void 0,
|
|
36964
37493
|
setDefault: readBoolean4(body.set_default ?? body.setDefault),
|
|
36965
|
-
reasoningEffort:
|
|
36966
|
-
reasoningSupportPolicy:
|
|
37494
|
+
reasoningEffort: readString23(body, "reasoning_effort") ?? readString23(body, "reasoningEffort") ?? void 0,
|
|
37495
|
+
reasoningSupportPolicy: readString23(body, "reasoning_support_policy") ?? readString23(body, "reasoningSupportPolicy") ?? readString23(body, "reasoning_support") ?? readString23(body, "reasoningSupport") ?? void 0,
|
|
36967
37496
|
supportsVision: readNullableBoolean2(
|
|
36968
37497
|
body.supports_vision ?? body.supportsVision
|
|
36969
37498
|
)
|
|
@@ -36971,28 +37500,28 @@ function readModelConfigInput(body) {
|
|
|
36971
37500
|
}
|
|
36972
37501
|
function readModelDefaultsInput(body) {
|
|
36973
37502
|
return {
|
|
36974
|
-
taskModelId:
|
|
36975
|
-
taskModelProvider:
|
|
36976
|
-
taskModelBaseUrl:
|
|
36977
|
-
taskModelApiMode:
|
|
36978
|
-
compressionModelId:
|
|
36979
|
-
compressionModelProvider:
|
|
36980
|
-
compressionModelBaseUrl:
|
|
36981
|
-
compressionModelApiMode:
|
|
36982
|
-
reasoningEffort:
|
|
36983
|
-
imageInputMode:
|
|
37503
|
+
taskModelId: readString23(body, "task_model_id") ?? readString23(body, "taskModelId") ?? readString23(body, "default_model_id") ?? readString23(body, "defaultModelId") ?? void 0,
|
|
37504
|
+
taskModelProvider: readString23(body, "task_model_provider") ?? readString23(body, "taskModelProvider") ?? readString23(body, "default_model_provider") ?? readString23(body, "defaultModelProvider") ?? void 0,
|
|
37505
|
+
taskModelBaseUrl: readString23(body, "task_model_base_url") ?? readString23(body, "taskModelBaseUrl") ?? readString23(body, "default_model_base_url") ?? readString23(body, "defaultModelBaseUrl") ?? void 0,
|
|
37506
|
+
taskModelApiMode: readString23(body, "task_model_api_mode") ?? readString23(body, "taskModelApiMode") ?? readString23(body, "default_model_api_mode") ?? readString23(body, "defaultModelApiMode") ?? void 0,
|
|
37507
|
+
compressionModelId: readString23(body, "compression_model_id") ?? readString23(body, "compressionModelId") ?? void 0,
|
|
37508
|
+
compressionModelProvider: readString23(body, "compression_model_provider") ?? readString23(body, "compressionModelProvider") ?? void 0,
|
|
37509
|
+
compressionModelBaseUrl: readString23(body, "compression_model_base_url") ?? readString23(body, "compressionModelBaseUrl") ?? void 0,
|
|
37510
|
+
compressionModelApiMode: readString23(body, "compression_model_api_mode") ?? readString23(body, "compressionModelApiMode") ?? void 0,
|
|
37511
|
+
reasoningEffort: readString23(body, "reasoning_effort") ?? readString23(body, "reasoningEffort") ?? readString23(body, "default_reasoning_effort") ?? readString23(body, "defaultReasoningEffort") ?? void 0,
|
|
37512
|
+
imageInputMode: readString23(body, "image_input_mode") ?? readString23(body, "imageInputMode") ?? void 0
|
|
36984
37513
|
};
|
|
36985
37514
|
}
|
|
36986
37515
|
function readModelDeleteInput(body) {
|
|
36987
|
-
const id =
|
|
37516
|
+
const id = readString23(body, "model_id") ?? readString23(body, "modelId");
|
|
36988
37517
|
if (!id) {
|
|
36989
37518
|
throw new LinkHttpError(400, "model_id_required", "model_id is required");
|
|
36990
37519
|
}
|
|
36991
37520
|
return {
|
|
36992
37521
|
id,
|
|
36993
|
-
provider:
|
|
36994
|
-
baseUrl:
|
|
36995
|
-
apiMode:
|
|
37522
|
+
provider: readString23(body, "provider") ?? readString23(body, "provider_key") ?? readString23(body, "providerKey") ?? void 0,
|
|
37523
|
+
baseUrl: readString23(body, "base_url") ?? readString23(body, "baseUrl") ?? void 0,
|
|
37524
|
+
apiMode: readString23(body, "api_mode") ?? readString23(body, "apiMode") ?? void 0
|
|
36996
37525
|
};
|
|
36997
37526
|
}
|
|
36998
37527
|
function readNullableBoolean2(value) {
|
|
@@ -37015,8 +37544,8 @@ function readNullableBoolean2(value) {
|
|
|
37015
37544
|
return void 0;
|
|
37016
37545
|
}
|
|
37017
37546
|
function readModelConfigImportInput(body) {
|
|
37018
|
-
const sourceProfileName =
|
|
37019
|
-
const modelId =
|
|
37547
|
+
const sourceProfileName = readString23(body, "source_profile") ?? readString23(body, "sourceProfile") ?? readString23(body, "source_profile_name") ?? readString23(body, "sourceProfileName");
|
|
37548
|
+
const modelId = readString23(body, "model_id") ?? readString23(body, "modelId") ?? readString23(body, "id");
|
|
37020
37549
|
if (!sourceProfileName || !modelId) {
|
|
37021
37550
|
throw new LinkHttpError(
|
|
37022
37551
|
400,
|
|
@@ -37027,9 +37556,9 @@ function readModelConfigImportInput(body) {
|
|
|
37027
37556
|
return {
|
|
37028
37557
|
sourceProfileName,
|
|
37029
37558
|
modelId,
|
|
37030
|
-
provider:
|
|
37031
|
-
baseUrl:
|
|
37032
|
-
apiMode:
|
|
37559
|
+
provider: readString23(body, "provider") ?? readString23(body, "provider_key") ?? readString23(body, "providerKey") ?? void 0,
|
|
37560
|
+
baseUrl: readString23(body, "base_url") ?? readString23(body, "baseUrl") ?? void 0,
|
|
37561
|
+
apiMode: readString23(body, "api_mode") ?? readString23(body, "apiMode") ?? void 0,
|
|
37033
37562
|
setDefault: readBoolean4(body.set_default ?? body.setDefault)
|
|
37034
37563
|
};
|
|
37035
37564
|
}
|
|
@@ -37136,19 +37665,19 @@ function errorMessage3(error) {
|
|
|
37136
37665
|
}
|
|
37137
37666
|
|
|
37138
37667
|
// src/hermes/profile-identity.ts
|
|
37139
|
-
import { readFile as
|
|
37140
|
-
import
|
|
37668
|
+
import { readFile as readFile17, stat as stat19 } from "fs/promises";
|
|
37669
|
+
import path30 from "path";
|
|
37141
37670
|
var MAX_SOUL_MD_LENGTH = 2e4;
|
|
37142
37671
|
async function readHermesProfileIdentity(profileName, paths) {
|
|
37143
37672
|
await assertProfileExists3(profileName, paths);
|
|
37144
37673
|
const soulPath = resolveSoulPath(profileName);
|
|
37145
|
-
const content = await
|
|
37674
|
+
const content = await readFile17(soulPath, "utf8").catch((error) => {
|
|
37146
37675
|
if (isNodeError19(error, "ENOENT")) {
|
|
37147
37676
|
return null;
|
|
37148
37677
|
}
|
|
37149
37678
|
throw error;
|
|
37150
37679
|
});
|
|
37151
|
-
const fileStat = content === null ? null : await
|
|
37680
|
+
const fileStat = content === null ? null : await stat19(soulPath).catch((error) => {
|
|
37152
37681
|
if (isNodeError19(error, "ENOENT")) {
|
|
37153
37682
|
return null;
|
|
37154
37683
|
}
|
|
@@ -37194,7 +37723,7 @@ async function assertProfileExists3(profileName, paths) {
|
|
|
37194
37723
|
}
|
|
37195
37724
|
}
|
|
37196
37725
|
function resolveSoulPath(profileName) {
|
|
37197
|
-
return
|
|
37726
|
+
return path30.join(resolveHermesProfileDir(profileName), "SOUL.md");
|
|
37198
37727
|
}
|
|
37199
37728
|
function isNodeError19(error, code) {
|
|
37200
37729
|
return error instanceof Error && "code" in error && error.code === code;
|
|
@@ -37206,17 +37735,17 @@ import { EventEmitter as EventEmitter2 } from "events";
|
|
|
37206
37735
|
import {
|
|
37207
37736
|
cp,
|
|
37208
37737
|
mkdir as mkdir13,
|
|
37209
|
-
readFile as
|
|
37738
|
+
readFile as readFile19,
|
|
37210
37739
|
rm as rm7,
|
|
37211
|
-
stat as
|
|
37740
|
+
stat as stat21
|
|
37212
37741
|
} from "fs/promises";
|
|
37213
|
-
import
|
|
37742
|
+
import path32 from "path";
|
|
37214
37743
|
import YAML5 from "yaml";
|
|
37215
37744
|
|
|
37216
37745
|
// src/hermes/link-skill.ts
|
|
37217
|
-
import { readFile as
|
|
37746
|
+
import { readFile as readFile18, stat as stat20 } from "fs/promises";
|
|
37218
37747
|
import os7 from "os";
|
|
37219
|
-
import
|
|
37748
|
+
import path31 from "path";
|
|
37220
37749
|
import YAML4 from "yaml";
|
|
37221
37750
|
var HERMES_LINK_SKILL_ROOT_DIR = "hermes-skills";
|
|
37222
37751
|
var HERMES_LINK_SKILL_DIR = "hermes-link";
|
|
@@ -37313,7 +37842,7 @@ Do not modify Hermes profiles, delete user data, edit config files, or kill proc
|
|
|
37313
37842
|
async function ensureHermesLinkSkillInstalledForProfiles(options = {}) {
|
|
37314
37843
|
const paths = options.paths ?? resolveRuntimePaths();
|
|
37315
37844
|
const externalDir = resolveHermesLinkSkillExternalDir(paths);
|
|
37316
|
-
const skillPath =
|
|
37845
|
+
const skillPath = path31.join(
|
|
37317
37846
|
externalDir,
|
|
37318
37847
|
HERMES_LINK_SKILL_DIR,
|
|
37319
37848
|
HERMES_LINK_SKILL_FILE
|
|
@@ -37395,10 +37924,10 @@ function withDefaultProfilePlaceholder2(profiles) {
|
|
|
37395
37924
|
];
|
|
37396
37925
|
}
|
|
37397
37926
|
function resolveHermesLinkSkillExternalDir(paths = resolveRuntimePaths()) {
|
|
37398
|
-
return
|
|
37927
|
+
return path31.join(paths.homeDir, HERMES_LINK_SKILL_ROOT_DIR);
|
|
37399
37928
|
}
|
|
37400
37929
|
async function writeHermesLinkSkill(skillPath) {
|
|
37401
|
-
const existing = await
|
|
37930
|
+
const existing = await readFile18(skillPath, "utf8").catch((error) => {
|
|
37402
37931
|
if (isNodeError20(error, "ENOENT")) {
|
|
37403
37932
|
return null;
|
|
37404
37933
|
}
|
|
@@ -37456,7 +37985,7 @@ async function ensureProfileUsesExternalSkillDir(profile, externalDir) {
|
|
|
37456
37985
|
};
|
|
37457
37986
|
}
|
|
37458
37987
|
async function readHermesConfigDocument3(configPath) {
|
|
37459
|
-
const existingRaw = await
|
|
37988
|
+
const existingRaw = await readFile18(configPath, "utf8").catch(
|
|
37460
37989
|
(error) => {
|
|
37461
37990
|
if (isNodeError20(error, "ENOENT")) {
|
|
37462
37991
|
return null;
|
|
@@ -37490,11 +38019,11 @@ function appendExternalDir(current, externalDir, hermesHome) {
|
|
|
37490
38019
|
const seen = new Set(
|
|
37491
38020
|
entries.map((entry) => resolveExternalDirEntry(entry, hermesHome))
|
|
37492
38021
|
);
|
|
37493
|
-
const normalizedExternalDir =
|
|
38022
|
+
const normalizedExternalDir = path31.resolve(externalDir);
|
|
37494
38023
|
return seen.has(normalizedExternalDir) ? entries : [...entries, normalizedExternalDir];
|
|
37495
38024
|
}
|
|
37496
38025
|
function externalDirsInclude(current, externalDir, hermesHome) {
|
|
37497
|
-
const normalizedExternalDir =
|
|
38026
|
+
const normalizedExternalDir = path31.resolve(externalDir);
|
|
37498
38027
|
return readExternalDirEntries(current).some(
|
|
37499
38028
|
(entry) => resolveExternalDirEntry(entry, hermesHome) === normalizedExternalDir
|
|
37500
38029
|
);
|
|
@@ -37505,14 +38034,14 @@ function readExternalDirEntries(value) {
|
|
|
37505
38034
|
}
|
|
37506
38035
|
function resolveExternalDirEntry(entry, hermesHome) {
|
|
37507
38036
|
const expanded = expandHome(expandEnvVars(entry));
|
|
37508
|
-
return
|
|
38037
|
+
return path31.resolve(path31.isAbsolute(expanded) ? expanded : path31.join(hermesHome, expanded));
|
|
37509
38038
|
}
|
|
37510
38039
|
function expandHome(value) {
|
|
37511
38040
|
if (value === "~") {
|
|
37512
38041
|
return os7.homedir();
|
|
37513
38042
|
}
|
|
37514
|
-
if (value.startsWith(`~${
|
|
37515
|
-
return
|
|
38043
|
+
if (value.startsWith(`~${path31.sep}`) || value.startsWith("~/")) {
|
|
38044
|
+
return path31.join(os7.homedir(), value.slice(2));
|
|
37516
38045
|
}
|
|
37517
38046
|
return value;
|
|
37518
38047
|
}
|
|
@@ -37523,7 +38052,7 @@ function expandEnvVars(value) {
|
|
|
37523
38052
|
);
|
|
37524
38053
|
}
|
|
37525
38054
|
async function pathIsDirectory2(filePath) {
|
|
37526
|
-
return
|
|
38055
|
+
return stat20(filePath).then((value) => value.isDirectory()).catch((error) => {
|
|
37527
38056
|
if (isNodeError20(error, "ENOENT")) {
|
|
37528
38057
|
return false;
|
|
37529
38058
|
}
|
|
@@ -38064,8 +38593,8 @@ function collectEnvKeys(value, keys = /* @__PURE__ */ new Set()) {
|
|
|
38064
38593
|
return keys;
|
|
38065
38594
|
}
|
|
38066
38595
|
async function writeEnvValues(profileName, values) {
|
|
38067
|
-
const envPath =
|
|
38068
|
-
const existingRaw = await
|
|
38596
|
+
const envPath = path32.join(resolveHermesProfileDir(profileName), ".env");
|
|
38597
|
+
const existingRaw = await readFile19(envPath, "utf8").catch((error) => {
|
|
38069
38598
|
if (isNodeError21(error, "ENOENT")) {
|
|
38070
38599
|
return "";
|
|
38071
38600
|
}
|
|
@@ -38101,8 +38630,8 @@ async function writeEnvValues(profileName, values) {
|
|
|
38101
38630
|
await atomicWriteFilePreservingMetadata(envPath, nextRaw);
|
|
38102
38631
|
}
|
|
38103
38632
|
async function copySkills(sourceProfile, targetProfile) {
|
|
38104
|
-
const sourceSkills =
|
|
38105
|
-
const targetSkills =
|
|
38633
|
+
const sourceSkills = path32.join(resolveHermesProfileDir(sourceProfile), "skills");
|
|
38634
|
+
const targetSkills = path32.join(resolveHermesProfileDir(targetProfile), "skills");
|
|
38106
38635
|
if (!await pathExists2(sourceSkills)) {
|
|
38107
38636
|
return;
|
|
38108
38637
|
}
|
|
@@ -38125,7 +38654,7 @@ function copyProperty(source, target, key) {
|
|
|
38125
38654
|
}
|
|
38126
38655
|
}
|
|
38127
38656
|
async function readYamlConfig(configPath) {
|
|
38128
|
-
const existingRaw = await
|
|
38657
|
+
const existingRaw = await readFile19(configPath, "utf8").catch(
|
|
38129
38658
|
(error) => {
|
|
38130
38659
|
if (isNodeError21(error, "ENOENT")) {
|
|
38131
38660
|
return null;
|
|
@@ -38188,7 +38717,7 @@ async function writeProfileCreationState(paths, state) {
|
|
|
38188
38717
|
await writeJsonFile(profileCreationStatePath(paths), state);
|
|
38189
38718
|
}
|
|
38190
38719
|
async function readProfileCreationLogLines(paths) {
|
|
38191
|
-
const raw = await
|
|
38720
|
+
const raw = await readFile19(profileCreationLogPath(paths), "utf8").catch(() => "");
|
|
38192
38721
|
if (!raw.trim()) {
|
|
38193
38722
|
return [];
|
|
38194
38723
|
}
|
|
@@ -38197,10 +38726,10 @@ async function readProfileCreationLogLines(paths) {
|
|
|
38197
38726
|
);
|
|
38198
38727
|
}
|
|
38199
38728
|
function profileCreationStatePath(paths) {
|
|
38200
|
-
return
|
|
38729
|
+
return path32.join(paths.runDir, "profile-create-state.json");
|
|
38201
38730
|
}
|
|
38202
38731
|
function profileCreationLogPath(paths) {
|
|
38203
|
-
return
|
|
38732
|
+
return path32.join(paths.logsDir, PROFILE_CREATE_LOG_FILE);
|
|
38204
38733
|
}
|
|
38205
38734
|
async function clearProfileCreationLogFiles(paths) {
|
|
38206
38735
|
const primary = profileCreationLogPath(paths);
|
|
@@ -38213,7 +38742,7 @@ async function clearProfileCreationLogFiles(paths) {
|
|
|
38213
38742
|
]);
|
|
38214
38743
|
}
|
|
38215
38744
|
async function pathExists2(targetPath) {
|
|
38216
|
-
return await
|
|
38745
|
+
return await stat21(targetPath).then(() => true).catch((error) => {
|
|
38217
38746
|
if (isNodeError21(error, "ENOENT")) {
|
|
38218
38747
|
return false;
|
|
38219
38748
|
}
|
|
@@ -38346,16 +38875,16 @@ function readProfilePermissionsInput(body) {
|
|
|
38346
38875
|
const approvals = readOptionalObject(body, "approvals");
|
|
38347
38876
|
if (approvals) {
|
|
38348
38877
|
input.approvals = {
|
|
38349
|
-
mode:
|
|
38878
|
+
mode: readString23(approvals, "mode") ?? readString23(approvals, "approval_mode") ?? readString23(approvals, "approvalMode") ?? void 0,
|
|
38350
38879
|
timeout: readPositiveInteger2(approvals.timeout),
|
|
38351
|
-
cronMode:
|
|
38880
|
+
cronMode: readString23(approvals, "cron_mode") ?? readString23(approvals, "cronMode") ?? void 0
|
|
38352
38881
|
};
|
|
38353
38882
|
}
|
|
38354
38883
|
const terminal = readOptionalObject(body, "terminal");
|
|
38355
38884
|
if (terminal) {
|
|
38356
38885
|
input.terminal = {
|
|
38357
|
-
backend:
|
|
38358
|
-
cwd:
|
|
38886
|
+
backend: readString23(terminal, "backend") ?? void 0,
|
|
38887
|
+
cwd: readString23(terminal, "cwd") ?? void 0,
|
|
38359
38888
|
containerCpu: readPositiveInteger2(
|
|
38360
38889
|
terminal.container_cpu ?? terminal.containerCpu
|
|
38361
38890
|
),
|
|
@@ -38486,10 +39015,10 @@ function toProfileToolConfigHttpError(error) {
|
|
|
38486
39015
|
import {
|
|
38487
39016
|
access as access3,
|
|
38488
39017
|
readdir as readdir10,
|
|
38489
|
-
readFile as
|
|
38490
|
-
stat as
|
|
39018
|
+
readFile as readFile20,
|
|
39019
|
+
stat as stat22
|
|
38491
39020
|
} from "fs/promises";
|
|
38492
|
-
import
|
|
39021
|
+
import path33 from "path";
|
|
38493
39022
|
import YAML6 from "yaml";
|
|
38494
39023
|
var ENTRY_DELIMITER = "\n\xA7\n";
|
|
38495
39024
|
var DEFAULT_MEMORY_LIMIT = 2200;
|
|
@@ -38686,9 +39215,9 @@ async function testHindsightProviderSettings(profileName, patch) {
|
|
|
38686
39215
|
const mode = normalizeHindsightMode(
|
|
38687
39216
|
patch.mode ?? config.mode ?? env.HINDSIGHT_MODE
|
|
38688
39217
|
);
|
|
38689
|
-
const apiUrl =
|
|
38690
|
-
const bankId =
|
|
38691
|
-
const apiKey =
|
|
39218
|
+
const apiUrl = readString25(patch.apiUrl) ?? readString25(config.api_url) ?? env.HINDSIGHT_API_URL ?? (mode === "cloud" ? HINDSIGHT_DEFAULT_API_URL : HINDSIGHT_DEFAULT_LOCAL_URL);
|
|
39219
|
+
const bankId = readString25(patch.bankId) ?? readString25(config.bank_id) ?? "hermes";
|
|
39220
|
+
const apiKey = readString25(patch.apiKey) ?? env.HINDSIGHT_API_KEY ?? readString25(config.apiKey) ?? readString25(config.api_key);
|
|
38692
39221
|
const baseUrl = normalizeHttpUrl2(apiUrl);
|
|
38693
39222
|
if (!baseUrl) {
|
|
38694
39223
|
return {
|
|
@@ -38820,7 +39349,7 @@ async function saveProviderSettings(profileName, provider, patch) {
|
|
|
38820
39349
|
});
|
|
38821
39350
|
await patchJsonProviderConfig(
|
|
38822
39351
|
profileName,
|
|
38823
|
-
|
|
39352
|
+
path33.join("hindsight", "config.json"),
|
|
38824
39353
|
{
|
|
38825
39354
|
mode: patch.mode,
|
|
38826
39355
|
api_url: patch.apiUrl,
|
|
@@ -38968,7 +39497,7 @@ function normalizeCustomProviderId(provider) {
|
|
|
38968
39497
|
}
|
|
38969
39498
|
async function patchHermesMemoryProvider(profileName, provider) {
|
|
38970
39499
|
const configPath = resolveHermesConfigPath(profileName);
|
|
38971
|
-
const existingRaw = await
|
|
39500
|
+
const existingRaw = await readFile20(configPath, "utf8").catch(
|
|
38972
39501
|
(error) => {
|
|
38973
39502
|
if (isNodeError22(error, "ENOENT")) {
|
|
38974
39503
|
return null;
|
|
@@ -38992,7 +39521,7 @@ async function patchHermesMemoryProvider(profileName, provider) {
|
|
|
38992
39521
|
}
|
|
38993
39522
|
async function patchHermesMemoryLimits(profileName, patch) {
|
|
38994
39523
|
const configPath = resolveHermesConfigPath(profileName);
|
|
38995
|
-
const existingRaw = await
|
|
39524
|
+
const existingRaw = await readFile20(configPath, "utf8").catch(
|
|
38996
39525
|
(error) => {
|
|
38997
39526
|
if (isNodeError22(error, "ENOENT")) {
|
|
38998
39527
|
return null;
|
|
@@ -39023,12 +39552,12 @@ async function patchHermesMemoryLimits(profileName, patch) {
|
|
|
39023
39552
|
await atomicWriteFilePreservingMetadata(configPath, document.toString());
|
|
39024
39553
|
}
|
|
39025
39554
|
function resolveMemoryDir(profileName) {
|
|
39026
|
-
return
|
|
39555
|
+
return path33.join(resolveHermesProfileDir(profileName), "memories");
|
|
39027
39556
|
}
|
|
39028
39557
|
async function readMemoryStore(profileName, target, limits) {
|
|
39029
39558
|
const filePath = memoryFilePath(profileName, target);
|
|
39030
39559
|
const entries = await readMemoryEntries(filePath);
|
|
39031
|
-
const fileStat = await
|
|
39560
|
+
const fileStat = await stat22(filePath).catch((error) => {
|
|
39032
39561
|
if (isNodeError22(error, "ENOENT")) {
|
|
39033
39562
|
return null;
|
|
39034
39563
|
}
|
|
@@ -39057,7 +39586,7 @@ async function readMemoryStore(profileName, target, limits) {
|
|
|
39057
39586
|
};
|
|
39058
39587
|
}
|
|
39059
39588
|
async function readMemoryEntries(filePath) {
|
|
39060
|
-
const raw = await
|
|
39589
|
+
const raw = await readFile20(filePath, "utf8").catch((error) => {
|
|
39061
39590
|
if (isNodeError22(error, "ENOENT")) {
|
|
39062
39591
|
return "";
|
|
39063
39592
|
}
|
|
@@ -39084,7 +39613,7 @@ async function writeMemoryEntries(profileName, target, entries) {
|
|
|
39084
39613
|
);
|
|
39085
39614
|
}
|
|
39086
39615
|
function memoryFilePath(profileName, target) {
|
|
39087
|
-
return
|
|
39616
|
+
return path33.join(
|
|
39088
39617
|
resolveMemoryDir(profileName),
|
|
39089
39618
|
target === "user" ? "USER.md" : "MEMORY.md"
|
|
39090
39619
|
);
|
|
@@ -39144,7 +39673,7 @@ async function readCustomProviderSetupSummary(profileName) {
|
|
|
39144
39673
|
configurable: true,
|
|
39145
39674
|
configured: true,
|
|
39146
39675
|
configurationIssue: null,
|
|
39147
|
-
providerConfigPath:
|
|
39676
|
+
providerConfigPath: path33.join(
|
|
39148
39677
|
resolveHermesProfileDir(profileName),
|
|
39149
39678
|
"<provider>.json"
|
|
39150
39679
|
),
|
|
@@ -39222,7 +39751,7 @@ async function readProviderConfigurationStatus(profileName, provider) {
|
|
|
39222
39751
|
const config2 = await readJsonObject(
|
|
39223
39752
|
memoryProviderConfigPath(profileName, "honcho") ?? ""
|
|
39224
39753
|
);
|
|
39225
|
-
return isConfiguredEnvValue(env.HONCHO_API_KEY) || isConfiguredEnvValue(
|
|
39754
|
+
return isConfiguredEnvValue(env.HONCHO_API_KEY) || isConfiguredEnvValue(readString25(config2.apiKey)) || isConfiguredEnvValue(readString25(config2.api_key)) || isConfiguredEnvValue(readString25(config2.baseUrl)) ? { configured: true, issue: null } : {
|
|
39226
39755
|
configured: false,
|
|
39227
39756
|
issue: "Honcho \u9700\u8981\u5148\u586B\u5199 API Key\uFF0C\u6216\u5728 honcho.json \u914D\u7F6E self-hosted baseUrl\u3002"
|
|
39228
39757
|
};
|
|
@@ -39231,7 +39760,7 @@ async function readProviderConfigurationStatus(profileName, provider) {
|
|
|
39231
39760
|
const config2 = await readJsonObject(
|
|
39232
39761
|
memoryProviderConfigPath(profileName, "mem0") ?? ""
|
|
39233
39762
|
);
|
|
39234
|
-
return isConfiguredEnvValue(env.MEM0_API_KEY) || isConfiguredEnvValue(
|
|
39763
|
+
return isConfiguredEnvValue(env.MEM0_API_KEY) || isConfiguredEnvValue(readString25(config2.api_key)) ? { configured: true, issue: null } : {
|
|
39235
39764
|
configured: false,
|
|
39236
39765
|
issue: "Mem0 \u9700\u8981\u5148\u5728\u672C\u9875\u586B\u5199 API Key\uFF0CLink \u4F1A\u5199\u5165\u5F53\u524D Profile \u7684 .env\u3002"
|
|
39237
39766
|
};
|
|
@@ -39273,7 +39802,7 @@ async function readProviderConfigurationStatus(profileName, provider) {
|
|
|
39273
39802
|
memoryProviderConfigPath(profileName, provider) ?? ""
|
|
39274
39803
|
);
|
|
39275
39804
|
const mode = normalizeHindsightMode(config.mode ?? env.HINDSIGHT_MODE);
|
|
39276
|
-
const apiKey =
|
|
39805
|
+
const apiKey = readString25(config.apiKey) ?? readString25(config.api_key) ?? env.HINDSIGHT_API_KEY;
|
|
39277
39806
|
if (mode === "cloud") {
|
|
39278
39807
|
return isConfiguredEnvValue(apiKey) ? { configured: true, issue: null } : {
|
|
39279
39808
|
configured: false,
|
|
@@ -39281,15 +39810,15 @@ async function readProviderConfigurationStatus(profileName, provider) {
|
|
|
39281
39810
|
};
|
|
39282
39811
|
}
|
|
39283
39812
|
if (mode === "local_external") {
|
|
39284
|
-
const apiUrl =
|
|
39813
|
+
const apiUrl = readString25(config.api_url) ?? env.HINDSIGHT_API_URL ?? HINDSIGHT_DEFAULT_LOCAL_URL;
|
|
39285
39814
|
return isConfiguredEnvValue(apiUrl) ? { configured: true, issue: null } : {
|
|
39286
39815
|
configured: false,
|
|
39287
39816
|
issue: "Hindsight local_external \u9700\u8981\u914D\u7F6E\u53EF\u8BBF\u95EE\u7684 API URL\u3002"
|
|
39288
39817
|
};
|
|
39289
39818
|
}
|
|
39290
39819
|
if (mode === "local_embedded") {
|
|
39291
|
-
const llmProvider =
|
|
39292
|
-
const llmModel =
|
|
39820
|
+
const llmProvider = readString25(config.llm_provider) ?? "openai";
|
|
39821
|
+
const llmModel = readString25(config.llm_model);
|
|
39293
39822
|
if (!llmModel) {
|
|
39294
39823
|
return {
|
|
39295
39824
|
configured: false,
|
|
@@ -39297,7 +39826,7 @@ async function readProviderConfigurationStatus(profileName, provider) {
|
|
|
39297
39826
|
};
|
|
39298
39827
|
}
|
|
39299
39828
|
if (llmProvider === "openai_compatible" && !isConfiguredEnvValue(
|
|
39300
|
-
|
|
39829
|
+
readString25(config.llm_base_url) ?? env.HINDSIGHT_API_LLM_BASE_URL
|
|
39301
39830
|
)) {
|
|
39302
39831
|
return {
|
|
39303
39832
|
configured: false,
|
|
@@ -39305,7 +39834,7 @@ async function readProviderConfigurationStatus(profileName, provider) {
|
|
|
39305
39834
|
};
|
|
39306
39835
|
}
|
|
39307
39836
|
if (!["ollama", "lmstudio", "openai_compatible"].includes(llmProvider) && !isConfiguredEnvValue(
|
|
39308
|
-
|
|
39837
|
+
readString25(config.llmApiKey) ?? readString25(config.llm_api_key) ?? env.HINDSIGHT_LLM_API_KEY
|
|
39309
39838
|
)) {
|
|
39310
39839
|
return {
|
|
39311
39840
|
configured: false,
|
|
@@ -39361,8 +39890,8 @@ async function readProviderSettings(profileName, provider) {
|
|
|
39361
39890
|
secretSetting(
|
|
39362
39891
|
"apiKey",
|
|
39363
39892
|
"API Key",
|
|
39364
|
-
env.HONCHO_API_KEY ??
|
|
39365
|
-
isConfiguredEnvValue(env.HONCHO_API_KEY) || isConfiguredEnvValue(
|
|
39893
|
+
env.HONCHO_API_KEY ?? readString25(config.apiKey) ?? readString25(config.api_key),
|
|
39894
|
+
isConfiguredEnvValue(env.HONCHO_API_KEY) || isConfiguredEnvValue(readString25(config.apiKey)) || isConfiguredEnvValue(readString25(config.api_key))
|
|
39366
39895
|
),
|
|
39367
39896
|
stringSetting("workspace", "Workspace", config.workspace ?? "hermes"),
|
|
39368
39897
|
stringSetting("peerName", "\u7528\u6237 Peer", config.peerName ?? ""),
|
|
@@ -39404,8 +39933,8 @@ async function readProviderSettings(profileName, provider) {
|
|
|
39404
39933
|
secretSetting(
|
|
39405
39934
|
"apiKey",
|
|
39406
39935
|
"API Key",
|
|
39407
|
-
env.MEM0_API_KEY ??
|
|
39408
|
-
isConfiguredEnvValue(env.MEM0_API_KEY) || isConfiguredEnvValue(
|
|
39936
|
+
env.MEM0_API_KEY ?? readString25(config.apiKey) ?? readString25(config.api_key),
|
|
39937
|
+
isConfiguredEnvValue(env.MEM0_API_KEY) || isConfiguredEnvValue(readString25(config.apiKey)) || isConfiguredEnvValue(readString25(config.api_key))
|
|
39409
39938
|
),
|
|
39410
39939
|
stringSetting("userId", "User ID", config.user_id ?? "hermes-user"),
|
|
39411
39940
|
stringSetting("agentId", "Agent ID", config.agent_id ?? "hermes"),
|
|
@@ -39490,8 +40019,8 @@ async function readProviderSettings(profileName, provider) {
|
|
|
39490
40019
|
secretSetting(
|
|
39491
40020
|
"apiKey",
|
|
39492
40021
|
"Hindsight API Key",
|
|
39493
|
-
env.HINDSIGHT_API_KEY ??
|
|
39494
|
-
isConfiguredEnvValue(env.HINDSIGHT_API_KEY) || isConfiguredEnvValue(
|
|
40022
|
+
env.HINDSIGHT_API_KEY ?? readString25(config.apiKey) ?? readString25(config.api_key),
|
|
40023
|
+
isConfiguredEnvValue(env.HINDSIGHT_API_KEY) || isConfiguredEnvValue(readString25(config.apiKey)) || isConfiguredEnvValue(readString25(config.api_key))
|
|
39495
40024
|
),
|
|
39496
40025
|
stringSetting(
|
|
39497
40026
|
"bankId",
|
|
@@ -39513,8 +40042,8 @@ async function readProviderSettings(profileName, provider) {
|
|
|
39513
40042
|
secretSetting(
|
|
39514
40043
|
"llmApiKey",
|
|
39515
40044
|
"LLM API Key",
|
|
39516
|
-
env.HINDSIGHT_LLM_API_KEY ??
|
|
39517
|
-
isConfiguredEnvValue(env.HINDSIGHT_LLM_API_KEY) || isConfiguredEnvValue(
|
|
40045
|
+
env.HINDSIGHT_LLM_API_KEY ?? readString25(config.llmApiKey) ?? readString25(config.llm_api_key),
|
|
40046
|
+
isConfiguredEnvValue(env.HINDSIGHT_LLM_API_KEY) || isConfiguredEnvValue(readString25(config.llmApiKey)) || isConfiguredEnvValue(readString25(config.llm_api_key))
|
|
39518
40047
|
),
|
|
39519
40048
|
booleanSetting("autoRecall", "\u81EA\u52A8\u56DE\u5FC6", config.auto_recall ?? true),
|
|
39520
40049
|
booleanSetting("autoRetain", "\u81EA\u52A8\u6C89\u6DC0", config.auto_retain ?? true),
|
|
@@ -39538,7 +40067,7 @@ async function readProviderSettings(profileName, provider) {
|
|
|
39538
40067
|
stringSetting(
|
|
39539
40068
|
"dbPath",
|
|
39540
40069
|
"SQLite \u6570\u636E\u5E93\u8DEF\u5F84",
|
|
39541
|
-
config.db_path ??
|
|
40070
|
+
config.db_path ?? path33.join(resolveHermesProfileDir(profileName), "memory_store.db")
|
|
39542
40071
|
),
|
|
39543
40072
|
booleanSetting("autoExtract", "\u4F1A\u8BDD\u7ED3\u675F\u81EA\u52A8\u62BD\u53D6", config.auto_extract ?? false),
|
|
39544
40073
|
numberSetting("defaultTrust", "\u9ED8\u8BA4\u4FE1\u4EFB\u5206", config.default_trust ?? 0.5),
|
|
@@ -39574,7 +40103,7 @@ async function readProviderSettings(profileName, provider) {
|
|
|
39574
40103
|
stringSetting(
|
|
39575
40104
|
"workingDirectory",
|
|
39576
40105
|
"\u5DE5\u4F5C\u76EE\u5F55",
|
|
39577
|
-
|
|
40106
|
+
path33.join(resolveHermesProfileDir(profileName), "byterover"),
|
|
39578
40107
|
false
|
|
39579
40108
|
)
|
|
39580
40109
|
];
|
|
@@ -39583,16 +40112,16 @@ async function readProviderSettings(profileName, provider) {
|
|
|
39583
40112
|
}
|
|
39584
40113
|
function memoryProviderConfigPath(profileName, provider) {
|
|
39585
40114
|
if (provider === "honcho") {
|
|
39586
|
-
return
|
|
40115
|
+
return path33.join(resolveHermesProfileDir(profileName), "honcho.json");
|
|
39587
40116
|
}
|
|
39588
40117
|
if (provider === "mem0") {
|
|
39589
|
-
return
|
|
40118
|
+
return path33.join(resolveHermesProfileDir(profileName), "mem0.json");
|
|
39590
40119
|
}
|
|
39591
40120
|
if (provider === "supermemory") {
|
|
39592
|
-
return
|
|
40121
|
+
return path33.join(resolveHermesProfileDir(profileName), "supermemory.json");
|
|
39593
40122
|
}
|
|
39594
40123
|
if (provider === "hindsight") {
|
|
39595
|
-
return
|
|
40124
|
+
return path33.join(
|
|
39596
40125
|
resolveHermesProfileDir(profileName),
|
|
39597
40126
|
"hindsight",
|
|
39598
40127
|
"config.json"
|
|
@@ -39601,19 +40130,19 @@ function memoryProviderConfigPath(profileName, provider) {
|
|
|
39601
40130
|
return null;
|
|
39602
40131
|
}
|
|
39603
40132
|
function customProviderConfigPath(profileName, provider) {
|
|
39604
|
-
return
|
|
40133
|
+
return path33.join(
|
|
39605
40134
|
resolveHermesProfileDir(profileName),
|
|
39606
40135
|
`${normalizeCustomProviderId(provider)}.json`
|
|
39607
40136
|
);
|
|
39608
40137
|
}
|
|
39609
40138
|
function customProviderRegistryPath(profileName) {
|
|
39610
|
-
return
|
|
40139
|
+
return path33.join(
|
|
39611
40140
|
resolveHermesProfileDir(profileName),
|
|
39612
40141
|
CUSTOM_PROVIDER_REGISTRY_FILE
|
|
39613
40142
|
);
|
|
39614
40143
|
}
|
|
39615
40144
|
async function readCustomProviderRegistry(profileName) {
|
|
39616
|
-
const raw = await
|
|
40145
|
+
const raw = await readFile20(customProviderRegistryPath(profileName), "utf8").catch(
|
|
39617
40146
|
(error) => {
|
|
39618
40147
|
if (isNodeError22(error, "ENOENT")) {
|
|
39619
40148
|
return "";
|
|
@@ -39633,11 +40162,11 @@ async function readCustomProviderRegistry(profileName) {
|
|
|
39633
40162
|
return { id: id2, label: id2, description: "\u81EA\u5B9A\u4E49 memory provider\u3002" };
|
|
39634
40163
|
}
|
|
39635
40164
|
const record = toRecord22(item);
|
|
39636
|
-
const id = normalizeCustomProviderId(
|
|
40165
|
+
const id = normalizeCustomProviderId(readString25(record.id) ?? "");
|
|
39637
40166
|
return {
|
|
39638
40167
|
id,
|
|
39639
|
-
label:
|
|
39640
|
-
description:
|
|
40168
|
+
label: readString25(record.label) ?? id,
|
|
40169
|
+
description: readString25(record.description) ?? "\u81EA\u5B9A\u4E49 memory provider\u3002"
|
|
39641
40170
|
};
|
|
39642
40171
|
}).filter((item) => item.id);
|
|
39643
40172
|
} catch {
|
|
@@ -39659,7 +40188,7 @@ async function saveCustomProviderRegistryEntry(profileName, provider) {
|
|
|
39659
40188
|
);
|
|
39660
40189
|
}
|
|
39661
40190
|
async function discoverUserMemoryProviderDescriptors(profileName) {
|
|
39662
|
-
const pluginsDir =
|
|
40191
|
+
const pluginsDir = path33.join(resolveHermesProfileDir(profileName), "plugins");
|
|
39663
40192
|
const entries = await readdir10(pluginsDir, { withFileTypes: true }).catch(
|
|
39664
40193
|
(error) => {
|
|
39665
40194
|
if (isNodeError22(error, "ENOENT")) {
|
|
@@ -39679,21 +40208,21 @@ async function discoverUserMemoryProviderDescriptors(profileName) {
|
|
|
39679
40208
|
} catch {
|
|
39680
40209
|
continue;
|
|
39681
40210
|
}
|
|
39682
|
-
const providerDir =
|
|
40211
|
+
const providerDir = path33.join(pluginsDir, entry.name);
|
|
39683
40212
|
if (!await isMemoryProviderPluginDir(providerDir)) {
|
|
39684
40213
|
continue;
|
|
39685
40214
|
}
|
|
39686
40215
|
const meta = await readPluginMetadata(providerDir);
|
|
39687
40216
|
descriptors.push({
|
|
39688
40217
|
id: providerId,
|
|
39689
|
-
label:
|
|
39690
|
-
description:
|
|
40218
|
+
label: readString25(meta.name) ?? providerId,
|
|
40219
|
+
description: readString25(meta.description) ?? "\u81EA\u5B9A\u4E49 memory provider\u3002"
|
|
39691
40220
|
});
|
|
39692
40221
|
}
|
|
39693
40222
|
return descriptors;
|
|
39694
40223
|
}
|
|
39695
40224
|
async function isUserMemoryProviderInstalled(profileName, provider) {
|
|
39696
|
-
const providerDir =
|
|
40225
|
+
const providerDir = path33.join(
|
|
39697
40226
|
resolveHermesProfileDir(profileName),
|
|
39698
40227
|
"plugins",
|
|
39699
40228
|
normalizeCustomProviderId(provider)
|
|
@@ -39701,7 +40230,7 @@ async function isUserMemoryProviderInstalled(profileName, provider) {
|
|
|
39701
40230
|
return isMemoryProviderPluginDir(providerDir);
|
|
39702
40231
|
}
|
|
39703
40232
|
async function isMemoryProviderPluginDir(providerDir) {
|
|
39704
|
-
const source = await
|
|
40233
|
+
const source = await readFile20(path33.join(providerDir, "__init__.py"), "utf8").catch(
|
|
39705
40234
|
(error) => {
|
|
39706
40235
|
if (isNodeError22(error, "ENOENT")) {
|
|
39707
40236
|
return "";
|
|
@@ -39713,7 +40242,7 @@ async function isMemoryProviderPluginDir(providerDir) {
|
|
|
39713
40242
|
return sample.includes("register_memory_provider") || sample.includes("MemoryProvider");
|
|
39714
40243
|
}
|
|
39715
40244
|
async function readPluginMetadata(providerDir) {
|
|
39716
|
-
const raw = await
|
|
40245
|
+
const raw = await readFile20(path33.join(providerDir, "plugin.yaml"), "utf8").catch(
|
|
39717
40246
|
(error) => {
|
|
39718
40247
|
if (isNodeError22(error, "ENOENT")) {
|
|
39719
40248
|
return "";
|
|
@@ -39725,10 +40254,10 @@ async function readPluginMetadata(providerDir) {
|
|
|
39725
40254
|
}
|
|
39726
40255
|
async function resolveByteRoverCli() {
|
|
39727
40256
|
const candidates = [
|
|
39728
|
-
...(process.env.PATH ?? "").split(
|
|
39729
|
-
|
|
40257
|
+
...(process.env.PATH ?? "").split(path33.delimiter).filter(Boolean).map((dir) => path33.join(dir, "brv")),
|
|
40258
|
+
path33.join(process.env.HOME ?? "", ".brv-cli", "bin", "brv"),
|
|
39730
40259
|
"/usr/local/bin/brv",
|
|
39731
|
-
|
|
40260
|
+
path33.join(process.env.HOME ?? "", ".npm-global", "bin", "brv")
|
|
39732
40261
|
].filter(Boolean);
|
|
39733
40262
|
for (const candidate of candidates) {
|
|
39734
40263
|
const found = await access3(candidate).then(() => true).catch(() => false);
|
|
@@ -39739,7 +40268,7 @@ async function resolveByteRoverCli() {
|
|
|
39739
40268
|
return null;
|
|
39740
40269
|
}
|
|
39741
40270
|
async function readHolographicProviderConfig(profileName) {
|
|
39742
|
-
const raw = await
|
|
40271
|
+
const raw = await readFile20(resolveHermesConfigPath(profileName), "utf8").catch(
|
|
39743
40272
|
(error) => {
|
|
39744
40273
|
if (isNodeError22(error, "ENOENT")) {
|
|
39745
40274
|
return "";
|
|
@@ -39753,7 +40282,7 @@ async function readHolographicProviderConfig(profileName) {
|
|
|
39753
40282
|
}
|
|
39754
40283
|
async function patchHolographicProviderConfig(profileName, patch) {
|
|
39755
40284
|
const configPath = resolveHermesConfigPath(profileName);
|
|
39756
|
-
const existingRaw = await
|
|
40285
|
+
const existingRaw = await readFile20(configPath, "utf8").catch(
|
|
39757
40286
|
(error) => {
|
|
39758
40287
|
if (isNodeError22(error, "ENOENT")) {
|
|
39759
40288
|
return null;
|
|
@@ -39789,8 +40318,8 @@ async function patchHermesMemoryEnv(profileName, patch) {
|
|
|
39789
40318
|
if (entries.length === 0) {
|
|
39790
40319
|
return;
|
|
39791
40320
|
}
|
|
39792
|
-
const envPath =
|
|
39793
|
-
const existingRaw = await
|
|
40321
|
+
const envPath = path33.join(resolveHermesProfileDir(profileName), ".env");
|
|
40322
|
+
const existingRaw = await readFile20(envPath, "utf8").catch((error) => {
|
|
39794
40323
|
if (isNodeError22(error, "ENOENT")) {
|
|
39795
40324
|
return "";
|
|
39796
40325
|
}
|
|
@@ -39849,7 +40378,7 @@ function isMemoryEnvKeyWritable(key) {
|
|
|
39849
40378
|
].includes(key);
|
|
39850
40379
|
}
|
|
39851
40380
|
function normalizeHindsightMode(value) {
|
|
39852
|
-
const mode =
|
|
40381
|
+
const mode = readString25(value) ?? "cloud";
|
|
39853
40382
|
return mode === "local" ? "local_embedded" : mode;
|
|
39854
40383
|
}
|
|
39855
40384
|
function normalizeHttpUrl2(value) {
|
|
@@ -39918,31 +40447,31 @@ function parseJsonObject2(text) {
|
|
|
39918
40447
|
}
|
|
39919
40448
|
}
|
|
39920
40449
|
function readHindsightError(json) {
|
|
39921
|
-
const detail =
|
|
40450
|
+
const detail = readString25(json.detail) ?? readString25(json.error);
|
|
39922
40451
|
return detail ? `\uFF1A${detail}` : "";
|
|
39923
40452
|
}
|
|
39924
40453
|
function hindsightSemanticIssue(pathName, json) {
|
|
39925
40454
|
if (pathName === "/health") {
|
|
39926
|
-
const status =
|
|
40455
|
+
const status = readString25(json.status);
|
|
39927
40456
|
return status && ["healthy", "ok"].includes(status.toLowerCase()) ? null : `\u5065\u5EB7\u72B6\u6001\u5F02\u5E38\uFF1A${status ?? "unknown"}`;
|
|
39928
40457
|
}
|
|
39929
40458
|
return null;
|
|
39930
40459
|
}
|
|
39931
40460
|
function summarizeHindsightProbe(pathName, json) {
|
|
39932
40461
|
if (pathName === "/health") {
|
|
39933
|
-
const status =
|
|
39934
|
-
const database =
|
|
40462
|
+
const status = readString25(json.status) ?? "ok";
|
|
40463
|
+
const database = readString25(json.database);
|
|
39935
40464
|
return database ? `${status}, database ${database}` : status;
|
|
39936
40465
|
}
|
|
39937
40466
|
if (pathName === "/version") {
|
|
39938
|
-
const version =
|
|
40467
|
+
const version = readString25(json.api_version);
|
|
39939
40468
|
return version ? `API ${version}` : "version endpoint reachable";
|
|
39940
40469
|
}
|
|
39941
|
-
const bankId =
|
|
40470
|
+
const bankId = readString25(json.bank_id);
|
|
39942
40471
|
return bankId ? `bank ${bankId} reachable` : "bank config reachable";
|
|
39943
40472
|
}
|
|
39944
40473
|
async function readActiveMemoryProvider(profileName) {
|
|
39945
|
-
const raw = await
|
|
40474
|
+
const raw = await readFile20(
|
|
39946
40475
|
resolveHermesConfigPath(profileName),
|
|
39947
40476
|
"utf8"
|
|
39948
40477
|
).catch((error) => {
|
|
@@ -39953,14 +40482,14 @@ async function readActiveMemoryProvider(profileName) {
|
|
|
39953
40482
|
});
|
|
39954
40483
|
const config = raw ? toRecord22(YAML6.parse(raw)) : {};
|
|
39955
40484
|
const memory = toRecord22(config.memory);
|
|
39956
|
-
const provider =
|
|
40485
|
+
const provider = readString25(memory.provider);
|
|
39957
40486
|
if (!provider || provider === "built-in" || provider === "builtin" || provider === "built_in") {
|
|
39958
40487
|
return null;
|
|
39959
40488
|
}
|
|
39960
40489
|
return provider;
|
|
39961
40490
|
}
|
|
39962
40491
|
async function patchJsonProviderConfig(profileName, relativePath, patch) {
|
|
39963
|
-
const configPath =
|
|
40492
|
+
const configPath = path33.join(
|
|
39964
40493
|
resolveHermesProfileDir(profileName),
|
|
39965
40494
|
relativePath
|
|
39966
40495
|
);
|
|
@@ -39978,7 +40507,7 @@ async function patchJsonProviderConfig(profileName, relativePath, patch) {
|
|
|
39978
40507
|
);
|
|
39979
40508
|
}
|
|
39980
40509
|
async function readJsonObject(filePath) {
|
|
39981
|
-
const raw = await
|
|
40510
|
+
const raw = await readFile20(filePath, "utf8").catch((error) => {
|
|
39982
40511
|
if (isNodeError22(error, "ENOENT")) {
|
|
39983
40512
|
return "{}";
|
|
39984
40513
|
}
|
|
@@ -39989,7 +40518,7 @@ async function readJsonObject(filePath) {
|
|
|
39989
40518
|
} catch {
|
|
39990
40519
|
throw new HermesMemoryError(
|
|
39991
40520
|
"memory_provider_config_invalid",
|
|
39992
|
-
`${
|
|
40521
|
+
`${path33.basename(filePath)} \u4E0D\u662F\u6709\u6548\u7684 JSON \u914D\u7F6E\u6587\u4EF6\u3002`
|
|
39993
40522
|
);
|
|
39994
40523
|
}
|
|
39995
40524
|
}
|
|
@@ -40010,7 +40539,7 @@ function stringSetting(key, label, value, editable = true) {
|
|
|
40010
40539
|
return {
|
|
40011
40540
|
key,
|
|
40012
40541
|
label,
|
|
40013
|
-
value:
|
|
40542
|
+
value: readString25(value) ?? "",
|
|
40014
40543
|
editable,
|
|
40015
40544
|
kind: "string"
|
|
40016
40545
|
};
|
|
@@ -40022,7 +40551,7 @@ function secretSetting(key, label, value, configured) {
|
|
|
40022
40551
|
value: "",
|
|
40023
40552
|
editable: true,
|
|
40024
40553
|
kind: "secret",
|
|
40025
|
-
configured: configured || isConfiguredEnvValue(
|
|
40554
|
+
configured: configured || isConfiguredEnvValue(readString25(value))
|
|
40026
40555
|
};
|
|
40027
40556
|
}
|
|
40028
40557
|
function textSetting(key, label, value, editable = true) {
|
|
@@ -40035,11 +40564,11 @@ function textSetting(key, label, value, editable = true) {
|
|
|
40035
40564
|
};
|
|
40036
40565
|
}
|
|
40037
40566
|
function selectSetting(key, label, value, options, editable = true) {
|
|
40038
|
-
const stringValue =
|
|
40567
|
+
const stringValue = readString25(value) ?? options[0] ?? null;
|
|
40039
40568
|
return { key, label, value: stringValue, editable, kind: "select", options };
|
|
40040
40569
|
}
|
|
40041
40570
|
async function readMemoryLimits(profileName) {
|
|
40042
|
-
const raw = await
|
|
40571
|
+
const raw = await readFile20(
|
|
40043
40572
|
resolveHermesConfigPath(profileName),
|
|
40044
40573
|
"utf8"
|
|
40045
40574
|
).catch((error) => {
|
|
@@ -40108,7 +40637,7 @@ function hashString(value) {
|
|
|
40108
40637
|
function toRecord22(value) {
|
|
40109
40638
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
|
|
40110
40639
|
}
|
|
40111
|
-
function
|
|
40640
|
+
function readString25(value) {
|
|
40112
40641
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
40113
40642
|
}
|
|
40114
40643
|
function readPositiveInteger4(value) {
|
|
@@ -40267,7 +40796,7 @@ function registerProfileMemoryRoutes(router, options) {
|
|
|
40267
40796
|
);
|
|
40268
40797
|
}
|
|
40269
40798
|
function readMemoryTarget(body) {
|
|
40270
|
-
const raw =
|
|
40799
|
+
const raw = readString23(body, "target");
|
|
40271
40800
|
if (raw === "memory" || raw === "user") {
|
|
40272
40801
|
return raw;
|
|
40273
40802
|
}
|
|
@@ -40278,7 +40807,7 @@ function readMemoryTarget(body) {
|
|
|
40278
40807
|
);
|
|
40279
40808
|
}
|
|
40280
40809
|
function readMemoryResetTarget(body) {
|
|
40281
|
-
const raw =
|
|
40810
|
+
const raw = readString23(body, "target") ?? "all";
|
|
40282
40811
|
if (raw === "all" || raw === "memory" || raw === "user") {
|
|
40283
40812
|
return raw;
|
|
40284
40813
|
}
|
|
@@ -40289,7 +40818,7 @@ function readMemoryResetTarget(body) {
|
|
|
40289
40818
|
);
|
|
40290
40819
|
}
|
|
40291
40820
|
function readRequiredMemoryContent(body) {
|
|
40292
|
-
const content =
|
|
40821
|
+
const content = readString23(body, "content") ?? readString23(body, "text");
|
|
40293
40822
|
if (!content) {
|
|
40294
40823
|
throw new LinkHttpError(
|
|
40295
40824
|
400,
|
|
@@ -40300,7 +40829,7 @@ function readRequiredMemoryContent(body) {
|
|
|
40300
40829
|
return content;
|
|
40301
40830
|
}
|
|
40302
40831
|
function readRequiredMemoryMatch(body) {
|
|
40303
|
-
const oldText =
|
|
40832
|
+
const oldText = readString23(body, "old_text") ?? readString23(body, "oldText") ?? readString23(body, "match");
|
|
40304
40833
|
if (!oldText) {
|
|
40305
40834
|
throw new LinkHttpError(
|
|
40306
40835
|
400,
|
|
@@ -40311,7 +40840,7 @@ function readRequiredMemoryMatch(body) {
|
|
|
40311
40840
|
return oldText;
|
|
40312
40841
|
}
|
|
40313
40842
|
function readRequiredMemoryProvider(body) {
|
|
40314
|
-
const provider =
|
|
40843
|
+
const provider = readString23(body, "provider") ?? readString23(body, "provider_id") ?? readString23(body, "providerId");
|
|
40315
40844
|
if (!provider) {
|
|
40316
40845
|
throw new LinkHttpError(
|
|
40317
40846
|
400,
|
|
@@ -40341,7 +40870,7 @@ function readMemorySettingsPatch(body, options = {}) {
|
|
|
40341
40870
|
input.userCharLimit = userCharLimit;
|
|
40342
40871
|
}
|
|
40343
40872
|
}
|
|
40344
|
-
const mode =
|
|
40873
|
+
const mode = readString23(body, "mode");
|
|
40345
40874
|
if (mode) {
|
|
40346
40875
|
input.mode = mode;
|
|
40347
40876
|
}
|
|
@@ -40357,7 +40886,7 @@ function readMemorySettingsPatch(body, options = {}) {
|
|
|
40357
40886
|
if (bankId !== void 0) {
|
|
40358
40887
|
input.bankId = bankId;
|
|
40359
40888
|
}
|
|
40360
|
-
const llmProvider =
|
|
40889
|
+
const llmProvider = readString23(body, "llm_provider") ?? readString23(body, "llmProvider");
|
|
40361
40890
|
if (llmProvider) {
|
|
40362
40891
|
input.llmProvider = llmProvider;
|
|
40363
40892
|
}
|
|
@@ -40393,11 +40922,11 @@ function readMemorySettingsPatch(body, options = {}) {
|
|
|
40393
40922
|
if (autoRetain !== void 0) {
|
|
40394
40923
|
input.autoRetain = autoRetain;
|
|
40395
40924
|
}
|
|
40396
|
-
const memoryMode =
|
|
40925
|
+
const memoryMode = readString23(body, "memory_mode") ?? readString23(body, "memoryMode");
|
|
40397
40926
|
if (memoryMode) {
|
|
40398
40927
|
input.memoryMode = memoryMode;
|
|
40399
40928
|
}
|
|
40400
|
-
const recallBudget =
|
|
40929
|
+
const recallBudget = readString23(body, "recall_budget") ?? readString23(body, "recallBudget");
|
|
40401
40930
|
if (recallBudget) {
|
|
40402
40931
|
input.recallBudget = recallBudget;
|
|
40403
40932
|
}
|
|
@@ -40413,11 +40942,11 @@ function readMemorySettingsPatch(body, options = {}) {
|
|
|
40413
40942
|
if (profileFrequency !== void 0) {
|
|
40414
40943
|
input.profileFrequency = profileFrequency;
|
|
40415
40944
|
}
|
|
40416
|
-
const captureMode =
|
|
40945
|
+
const captureMode = readString23(body, "capture_mode") ?? readString23(body, "captureMode");
|
|
40417
40946
|
if (captureMode) {
|
|
40418
40947
|
input.captureMode = captureMode;
|
|
40419
40948
|
}
|
|
40420
|
-
const searchMode =
|
|
40949
|
+
const searchMode = readString23(body, "search_mode") ?? readString23(body, "searchMode");
|
|
40421
40950
|
if (searchMode) {
|
|
40422
40951
|
input.searchMode = searchMode;
|
|
40423
40952
|
}
|
|
@@ -40451,11 +40980,11 @@ function readMemorySettingsPatch(body, options = {}) {
|
|
|
40451
40980
|
if (aiPeer !== void 0) {
|
|
40452
40981
|
input.aiPeer = aiPeer;
|
|
40453
40982
|
}
|
|
40454
|
-
const recallMode =
|
|
40983
|
+
const recallMode = readString23(body, "recall_mode") ?? readString23(body, "recallMode");
|
|
40455
40984
|
if (recallMode) {
|
|
40456
40985
|
input.recallMode = recallMode;
|
|
40457
40986
|
}
|
|
40458
|
-
const writeFrequency =
|
|
40987
|
+
const writeFrequency = readString23(body, "write_frequency") ?? readString23(body, "writeFrequency");
|
|
40459
40988
|
if (writeFrequency) {
|
|
40460
40989
|
input.writeFrequency = writeFrequency;
|
|
40461
40990
|
}
|
|
@@ -40463,7 +40992,7 @@ function readMemorySettingsPatch(body, options = {}) {
|
|
|
40463
40992
|
if (saveMessages !== void 0) {
|
|
40464
40993
|
input.saveMessages = saveMessages;
|
|
40465
40994
|
}
|
|
40466
|
-
const sessionStrategy =
|
|
40995
|
+
const sessionStrategy = readString23(body, "session_strategy") ?? readString23(body, "sessionStrategy");
|
|
40467
40996
|
if (sessionStrategy) {
|
|
40468
40997
|
input.sessionStrategy = sessionStrategy;
|
|
40469
40998
|
}
|
|
@@ -40612,8 +41141,8 @@ function toMemoryHttpError(error) {
|
|
|
40612
41141
|
}
|
|
40613
41142
|
|
|
40614
41143
|
// src/hermes/skills.ts
|
|
40615
|
-
import { readFile as
|
|
40616
|
-
import
|
|
41144
|
+
import { readFile as readFile21, readdir as readdir11 } from "fs/promises";
|
|
41145
|
+
import path34 from "path";
|
|
40617
41146
|
import YAML7 from "yaml";
|
|
40618
41147
|
var HermesSkillNotFoundError = class extends Error {
|
|
40619
41148
|
constructor(skillName) {
|
|
@@ -40627,7 +41156,7 @@ var EXCLUDED_SKILL_DIRS = /* @__PURE__ */ new Set([".git", ".github", ".hub"]);
|
|
|
40627
41156
|
async function listHermesProfileSkills(profileName, paths = resolveRuntimePaths()) {
|
|
40628
41157
|
const profile = await readExistingProfile(profileName, paths);
|
|
40629
41158
|
const profileDir = resolveHermesProfileDir(profile.name);
|
|
40630
|
-
const skillsRoot =
|
|
41159
|
+
const skillsRoot = path34.join(profileDir, "skills");
|
|
40631
41160
|
const [skillFiles, disabled, provenance] = await Promise.all([
|
|
40632
41161
|
findSkillFiles(skillsRoot),
|
|
40633
41162
|
readDisabledSkillNames(resolveHermesConfigPath(profile.name)),
|
|
@@ -40718,7 +41247,7 @@ async function collectSkillFiles(directory, results) {
|
|
|
40718
41247
|
if (EXCLUDED_SKILL_DIRS.has(entry.name)) {
|
|
40719
41248
|
continue;
|
|
40720
41249
|
}
|
|
40721
|
-
const entryPath =
|
|
41250
|
+
const entryPath = path34.join(directory, entry.name);
|
|
40722
41251
|
if (entry.isDirectory()) {
|
|
40723
41252
|
await collectSkillFiles(entryPath, results);
|
|
40724
41253
|
continue;
|
|
@@ -40729,7 +41258,7 @@ async function collectSkillFiles(directory, results) {
|
|
|
40729
41258
|
}
|
|
40730
41259
|
}
|
|
40731
41260
|
async function readSkillMetadata(input) {
|
|
40732
|
-
const raw = await
|
|
41261
|
+
const raw = await readFile21(input.skillFile, "utf8").catch(
|
|
40733
41262
|
(error) => {
|
|
40734
41263
|
if (isNodeError23(error, "ENOENT") || isNodeError23(error, "EACCES")) {
|
|
40735
41264
|
return null;
|
|
@@ -40740,16 +41269,16 @@ async function readSkillMetadata(input) {
|
|
|
40740
41269
|
if (raw === null) {
|
|
40741
41270
|
return null;
|
|
40742
41271
|
}
|
|
40743
|
-
const skillDir =
|
|
41272
|
+
const skillDir = path34.dirname(input.skillFile);
|
|
40744
41273
|
const { frontmatter, body } = parseSkillDocument(raw.slice(0, 4e3));
|
|
40745
41274
|
const name = normalizeSkillName(
|
|
40746
|
-
|
|
41275
|
+
readString26(frontmatter.name) ?? path34.basename(skillDir)
|
|
40747
41276
|
);
|
|
40748
41277
|
if (!name) {
|
|
40749
41278
|
return null;
|
|
40750
41279
|
}
|
|
40751
41280
|
const description = normalizeDescription(
|
|
40752
|
-
|
|
41281
|
+
readString26(frontmatter.description) ?? firstBodyDescription(body)
|
|
40753
41282
|
);
|
|
40754
41283
|
const provenance = input.provenance.get(name) ?? {
|
|
40755
41284
|
source: "local",
|
|
@@ -40762,7 +41291,7 @@ async function readSkillMetadata(input) {
|
|
|
40762
41291
|
enabled: !input.disabled.has(name),
|
|
40763
41292
|
source: provenance.source,
|
|
40764
41293
|
trust: provenance.trust,
|
|
40765
|
-
relativePath:
|
|
41294
|
+
relativePath: path34.relative(input.skillsRoot, skillDir)
|
|
40766
41295
|
};
|
|
40767
41296
|
}
|
|
40768
41297
|
function parseSkillDocument(raw) {
|
|
@@ -40783,8 +41312,8 @@ function parseSkillDocument(raw) {
|
|
|
40783
41312
|
}
|
|
40784
41313
|
}
|
|
40785
41314
|
function categoryFromPath(skillsRoot, skillFile) {
|
|
40786
|
-
const relative =
|
|
40787
|
-
const parts = relative.split(
|
|
41315
|
+
const relative = path34.relative(skillsRoot, skillFile);
|
|
41316
|
+
const parts = relative.split(path34.sep).filter(Boolean);
|
|
40788
41317
|
return parts.length >= 3 ? parts[0] : null;
|
|
40789
41318
|
}
|
|
40790
41319
|
function firstBodyDescription(body) {
|
|
@@ -40807,7 +41336,7 @@ function normalizeDescription(value) {
|
|
|
40807
41336
|
return `${description.slice(0, MAX_DESCRIPTION_LENGTH - 3)}...`;
|
|
40808
41337
|
}
|
|
40809
41338
|
async function readDisabledSkillNames(configPath) {
|
|
40810
|
-
const raw = await
|
|
41339
|
+
const raw = await readFile21(configPath, "utf8").catch((error) => {
|
|
40811
41340
|
if (isNodeError23(error, "ENOENT")) {
|
|
40812
41341
|
return "";
|
|
40813
41342
|
}
|
|
@@ -40831,7 +41360,7 @@ async function readSkillProvenance(root) {
|
|
|
40831
41360
|
return provenance;
|
|
40832
41361
|
}
|
|
40833
41362
|
async function readBundledSkillNames(root) {
|
|
40834
|
-
const raw = await
|
|
41363
|
+
const raw = await readFile21(path34.join(root, ".bundled_manifest"), "utf8").catch(
|
|
40835
41364
|
(error) => {
|
|
40836
41365
|
if (isNodeError23(error, "ENOENT")) {
|
|
40837
41366
|
return "";
|
|
@@ -40854,7 +41383,7 @@ async function readBundledSkillNames(root) {
|
|
|
40854
41383
|
return names;
|
|
40855
41384
|
}
|
|
40856
41385
|
async function readHubInstalledSkills(root) {
|
|
40857
|
-
const raw = await
|
|
41386
|
+
const raw = await readFile21(path34.join(root, ".hub", "lock.json"), "utf8").catch(
|
|
40858
41387
|
(error) => {
|
|
40859
41388
|
if (isNodeError23(error, "ENOENT")) {
|
|
40860
41389
|
return "";
|
|
@@ -40876,8 +41405,8 @@ async function readHubInstalledSkills(root) {
|
|
|
40876
41405
|
for (const [name, rawEntry] of Object.entries(installed2)) {
|
|
40877
41406
|
const entry = toRecord23(rawEntry);
|
|
40878
41407
|
result.set(normalizeSkillName(name), {
|
|
40879
|
-
source:
|
|
40880
|
-
trust:
|
|
41408
|
+
source: readString26(entry.source) ?? "hub",
|
|
41409
|
+
trust: readString26(entry.trust_level) ?? null
|
|
40881
41410
|
});
|
|
40882
41411
|
}
|
|
40883
41412
|
return result;
|
|
@@ -40926,7 +41455,7 @@ function compareCategoryNames(left, right) {
|
|
|
40926
41455
|
return left.localeCompare(right);
|
|
40927
41456
|
}
|
|
40928
41457
|
async function readHermesConfigDocument4(configPath) {
|
|
40929
|
-
const existingRaw = await
|
|
41458
|
+
const existingRaw = await readFile21(configPath, "utf8").catch(
|
|
40930
41459
|
(error) => {
|
|
40931
41460
|
if (isNodeError23(error, "ENOENT")) {
|
|
40932
41461
|
return null;
|
|
@@ -40961,7 +41490,7 @@ function readStringList6(value) {
|
|
|
40961
41490
|
}
|
|
40962
41491
|
return value.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean);
|
|
40963
41492
|
}
|
|
40964
|
-
function
|
|
41493
|
+
function readString26(value) {
|
|
40965
41494
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
40966
41495
|
}
|
|
40967
41496
|
function toRecord23(value) {
|
|
@@ -41333,7 +41862,7 @@ function registerRunRoutes(router, options) {
|
|
|
41333
41862
|
await authenticateRequest(ctx, paths);
|
|
41334
41863
|
const language = readPreferredLanguage(ctx);
|
|
41335
41864
|
const body = await readJsonBody(ctx.req);
|
|
41336
|
-
const input =
|
|
41865
|
+
const input = readString23(body, "input");
|
|
41337
41866
|
if (!input) {
|
|
41338
41867
|
throw new LinkHttpError(400, "run_input_required", "input is required");
|
|
41339
41868
|
}
|
|
@@ -41341,12 +41870,12 @@ function registerRunRoutes(router, options) {
|
|
|
41341
41870
|
ctx.body = await createHermesRun(
|
|
41342
41871
|
{
|
|
41343
41872
|
input,
|
|
41344
|
-
instructions:
|
|
41873
|
+
instructions: readString23(body, "instructions") ?? void 0,
|
|
41345
41874
|
conversation_history: readConversationHistory(
|
|
41346
41875
|
body.conversation_history ?? body.conversationHistory
|
|
41347
41876
|
),
|
|
41348
|
-
session_id:
|
|
41349
|
-
session_key:
|
|
41877
|
+
session_id: readString23(body, "session_id") ?? readString23(body, "sessionId") ?? void 0,
|
|
41878
|
+
session_key: readString23(body, "session_key") ?? readString23(body, "sessionKey") ?? void 0
|
|
41350
41879
|
},
|
|
41351
41880
|
{ logger, profileName: readOptionalProfileName(body), language }
|
|
41352
41881
|
);
|
|
@@ -41521,8 +42050,8 @@ function readModelList(payload) {
|
|
|
41521
42050
|
// src/hermes/updates.ts
|
|
41522
42051
|
import { EventEmitter as EventEmitter3 } from "events";
|
|
41523
42052
|
import { spawn as spawn4 } from "child_process";
|
|
41524
|
-
import { mkdir as mkdir14, readFile as
|
|
41525
|
-
import
|
|
42053
|
+
import { mkdir as mkdir14, readFile as readFile22, rm as rm8 } from "fs/promises";
|
|
42054
|
+
import path35 from "path";
|
|
41526
42055
|
var SERVER_HERMES_RELEASES_LATEST_PATH = "/api/v1/hermes-agent/releases/latest";
|
|
41527
42056
|
var RELEASE_CACHE_TTL_MS = 6 * 60 * 60 * 1e3;
|
|
41528
42057
|
var RELEASE_FETCH_TIMEOUT_MS = 5e3;
|
|
@@ -41759,20 +42288,20 @@ function normalizeServerReleaseSnapshot(payload) {
|
|
|
41759
42288
|
const remote = toNullableRecord(snapshot.remote);
|
|
41760
42289
|
return {
|
|
41761
42290
|
remote: remote ? normalizeServerRelease(remote) : null,
|
|
41762
|
-
cacheState:
|
|
41763
|
-
issue:
|
|
42291
|
+
cacheState: readString27(snapshot, "cache_state") ?? readString27(snapshot, "cacheState"),
|
|
42292
|
+
issue: readString27(snapshot, "issue")
|
|
41764
42293
|
};
|
|
41765
42294
|
}
|
|
41766
42295
|
function normalizeServerRelease(payload) {
|
|
41767
|
-
const tag =
|
|
41768
|
-
const name =
|
|
42296
|
+
const tag = readString27(payload, "tag");
|
|
42297
|
+
const name = readString27(payload, "name");
|
|
41769
42298
|
return {
|
|
41770
|
-
version:
|
|
42299
|
+
version: readString27(payload, "version") ?? extractSemver(name) ?? extractTagSemver(tag),
|
|
41771
42300
|
tag,
|
|
41772
42301
|
name,
|
|
41773
|
-
releaseUrl:
|
|
41774
|
-
publishedAt:
|
|
41775
|
-
fetchedAt:
|
|
42302
|
+
releaseUrl: readString27(payload, "releaseUrl") ?? readString27(payload, "release_url"),
|
|
42303
|
+
publishedAt: readString27(payload, "publishedAt") ?? readString27(payload, "published_at"),
|
|
42304
|
+
fetchedAt: readString27(payload, "fetchedAt") ?? readString27(payload, "fetched_at") ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
41776
42305
|
};
|
|
41777
42306
|
}
|
|
41778
42307
|
async function readReleaseCache(paths) {
|
|
@@ -41791,7 +42320,7 @@ async function writeUpdateState(paths, state) {
|
|
|
41791
42320
|
await writeJsonFile(updateStatePath(paths), state);
|
|
41792
42321
|
}
|
|
41793
42322
|
async function readUpdateLogLines(paths) {
|
|
41794
|
-
const raw = await
|
|
42323
|
+
const raw = await readFile22(updateLogPath(paths), "utf8").catch(() => "");
|
|
41795
42324
|
if (!raw.trim()) {
|
|
41796
42325
|
return [];
|
|
41797
42326
|
}
|
|
@@ -41800,13 +42329,13 @@ async function readUpdateLogLines(paths) {
|
|
|
41800
42329
|
);
|
|
41801
42330
|
}
|
|
41802
42331
|
function releaseCachePath(paths) {
|
|
41803
|
-
return
|
|
42332
|
+
return path35.join(paths.indexesDir, "hermes-release-check.json");
|
|
41804
42333
|
}
|
|
41805
42334
|
function updateStatePath(paths) {
|
|
41806
|
-
return
|
|
42335
|
+
return path35.join(paths.runDir, "hermes-update-state.json");
|
|
41807
42336
|
}
|
|
41808
42337
|
function updateLogPath(paths) {
|
|
41809
|
-
return
|
|
42338
|
+
return path35.join(paths.logsDir, UPDATE_LOG_FILE);
|
|
41810
42339
|
}
|
|
41811
42340
|
async function clearUpdateLogFiles(paths) {
|
|
41812
42341
|
const primary = updateLogPath(paths);
|
|
@@ -41898,7 +42427,7 @@ function isRecentRunningState2(state) {
|
|
|
41898
42427
|
const startedAt = Date.parse(state.started_at);
|
|
41899
42428
|
return Number.isFinite(startedAt) && Date.now() - startedAt < 3e4;
|
|
41900
42429
|
}
|
|
41901
|
-
function
|
|
42430
|
+
function readString27(payload, key) {
|
|
41902
42431
|
const value = payload[key];
|
|
41903
42432
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
41904
42433
|
}
|
|
@@ -41906,13 +42435,13 @@ function readString26(payload, key) {
|
|
|
41906
42435
|
// src/link/updates.ts
|
|
41907
42436
|
import { spawn as spawn6 } from "child_process";
|
|
41908
42437
|
import { EventEmitter as EventEmitter4 } from "events";
|
|
41909
|
-
import { mkdir as mkdir17, readFile as
|
|
41910
|
-
import
|
|
42438
|
+
import { mkdir as mkdir17, readFile as readFile24, rm as rm11 } from "fs/promises";
|
|
42439
|
+
import path37 from "path";
|
|
41911
42440
|
|
|
41912
42441
|
// src/daemon/process.ts
|
|
41913
42442
|
import { spawn as spawn5 } from "child_process";
|
|
41914
|
-
import { mkdir as mkdir16, readFile as
|
|
41915
|
-
import
|
|
42443
|
+
import { mkdir as mkdir16, readFile as readFile23, rm as rm10, writeFile as writeFile4 } from "fs/promises";
|
|
42444
|
+
import path36 from "path";
|
|
41916
42445
|
|
|
41917
42446
|
// src/daemon/service.ts
|
|
41918
42447
|
import { createServer } from "http";
|
|
@@ -43940,7 +44469,7 @@ async function runDaemonSupervisor(paths = resolveRuntimePaths()) {
|
|
|
43940
44469
|
await mkdir16(paths.logsDir, { recursive: true, mode: 448 });
|
|
43941
44470
|
const log = createRotatingTextLogWriter({
|
|
43942
44471
|
paths,
|
|
43943
|
-
fileName:
|
|
44472
|
+
fileName: path36.basename(daemonLogFile(paths))
|
|
43944
44473
|
});
|
|
43945
44474
|
const scriptPath = currentCliScriptPath();
|
|
43946
44475
|
const write = (chunk) => {
|
|
@@ -44120,7 +44649,7 @@ function currentCliScriptPath() {
|
|
|
44120
44649
|
return process.argv[1];
|
|
44121
44650
|
}
|
|
44122
44651
|
async function readPid(filePath) {
|
|
44123
|
-
const raw = await
|
|
44652
|
+
const raw = await readFile23(filePath, "utf8").catch(() => null);
|
|
44124
44653
|
if (!raw) {
|
|
44125
44654
|
return null;
|
|
44126
44655
|
}
|
|
@@ -44239,7 +44768,7 @@ function terminateChild(child, previousForceKillTimer) {
|
|
|
44239
44768
|
}
|
|
44240
44769
|
}
|
|
44241
44770
|
function supervisorStopIntentPath(paths) {
|
|
44242
|
-
return
|
|
44771
|
+
return path36.join(paths.runDir, "supervisor-stop-intent.json");
|
|
44243
44772
|
}
|
|
44244
44773
|
async function writeSupervisorStopIntent(paths, pid) {
|
|
44245
44774
|
await mkdir16(paths.runDir, { recursive: true, mode: 448 });
|
|
@@ -44252,7 +44781,7 @@ async function writeSupervisorStopIntent(paths, pid) {
|
|
|
44252
44781
|
}
|
|
44253
44782
|
async function consumeSupervisorStopIntent(paths, pid) {
|
|
44254
44783
|
const filePath = supervisorStopIntentPath(paths);
|
|
44255
|
-
const raw = await
|
|
44784
|
+
const raw = await readFile23(filePath, "utf8").catch(() => null);
|
|
44256
44785
|
if (!raw) {
|
|
44257
44786
|
return false;
|
|
44258
44787
|
}
|
|
@@ -44270,7 +44799,7 @@ async function consumeSupervisorStopIntent(paths, pid) {
|
|
|
44270
44799
|
}
|
|
44271
44800
|
async function clearExpiredSupervisorStopIntent(paths) {
|
|
44272
44801
|
const filePath = supervisorStopIntentPath(paths);
|
|
44273
|
-
const raw = await
|
|
44802
|
+
const raw = await readFile23(filePath, "utf8").catch(() => null);
|
|
44274
44803
|
if (!raw) {
|
|
44275
44804
|
return;
|
|
44276
44805
|
}
|
|
@@ -44719,16 +45248,16 @@ function normalizeServerSnapshot(payload) {
|
|
|
44719
45248
|
if (!policy) {
|
|
44720
45249
|
return {
|
|
44721
45250
|
remote: null,
|
|
44722
|
-
issue:
|
|
45251
|
+
issue: readString28(snapshot, "issue")
|
|
44723
45252
|
};
|
|
44724
45253
|
}
|
|
44725
45254
|
const release = toNullableRecord2(snapshot.release);
|
|
44726
|
-
const currentVersion =
|
|
44727
|
-
const minSafeVersion =
|
|
45255
|
+
const currentVersion = readString28(policy, "current_version") ?? readString28(policy, "currentVersion");
|
|
45256
|
+
const minSafeVersion = readString28(policy, "min_safe_version") ?? readString28(policy, "minSafeVersion");
|
|
44728
45257
|
if (!currentVersion) {
|
|
44729
45258
|
return {
|
|
44730
45259
|
remote: null,
|
|
44731
|
-
issue:
|
|
45260
|
+
issue: readString28(snapshot, "issue")
|
|
44732
45261
|
};
|
|
44733
45262
|
}
|
|
44734
45263
|
return {
|
|
@@ -44736,10 +45265,10 @@ function normalizeServerSnapshot(payload) {
|
|
|
44736
45265
|
current_version: currentVersion,
|
|
44737
45266
|
min_safe_version: minSafeVersion,
|
|
44738
45267
|
target_version: currentVersion,
|
|
44739
|
-
release_url: release ?
|
|
44740
|
-
published_at: release ?
|
|
45268
|
+
release_url: release ? readString28(release, "release_url") ?? readString28(release, "releaseUrl") : null,
|
|
45269
|
+
published_at: release ? readString28(release, "published_at") ?? readString28(release, "publishedAt") : null
|
|
44741
45270
|
},
|
|
44742
|
-
issue:
|
|
45271
|
+
issue: readString28(snapshot, "issue")
|
|
44743
45272
|
};
|
|
44744
45273
|
}
|
|
44745
45274
|
async function fetchCurrentLinkReleaseFromServer(options, fetcher, channel) {
|
|
@@ -44802,7 +45331,7 @@ async function buildOfficialInstallCommand(options, targetVersion) {
|
|
|
44802
45331
|
};
|
|
44803
45332
|
}
|
|
44804
45333
|
function buildUnixInstallCommand(installerUrl) {
|
|
44805
|
-
const nodeBinDir =
|
|
45334
|
+
const nodeBinDir = path37.dirname(process.execPath);
|
|
44806
45335
|
const fetchScript = [
|
|
44807
45336
|
quoteShellToken(process.execPath),
|
|
44808
45337
|
"--input-type=module",
|
|
@@ -45063,7 +45592,7 @@ async function writeUpdateState2(paths, state) {
|
|
|
45063
45592
|
await writeJsonFile(updateStatePath2(paths), state);
|
|
45064
45593
|
}
|
|
45065
45594
|
async function readUpdateLogLines2(paths) {
|
|
45066
|
-
const raw = await
|
|
45595
|
+
const raw = await readFile24(updateLogPath2(paths), "utf8").catch(() => "");
|
|
45067
45596
|
if (!raw.trim()) {
|
|
45068
45597
|
return [];
|
|
45069
45598
|
}
|
|
@@ -45072,10 +45601,10 @@ async function readUpdateLogLines2(paths) {
|
|
|
45072
45601
|
);
|
|
45073
45602
|
}
|
|
45074
45603
|
function updateStatePath2(paths) {
|
|
45075
|
-
return
|
|
45604
|
+
return path37.join(paths.runDir, "link-update-state.json");
|
|
45076
45605
|
}
|
|
45077
45606
|
function updateLogPath2(paths) {
|
|
45078
|
-
return
|
|
45607
|
+
return path37.join(paths.logsDir, UPDATE_LOG_FILE2);
|
|
45079
45608
|
}
|
|
45080
45609
|
async function clearUpdateLogFiles2(paths) {
|
|
45081
45610
|
const primary = updateLogPath2(paths);
|
|
@@ -45153,13 +45682,13 @@ function toRecord26(value) {
|
|
|
45153
45682
|
function toNullableRecord2(value) {
|
|
45154
45683
|
return typeof value === "object" && value !== null ? value : null;
|
|
45155
45684
|
}
|
|
45156
|
-
function
|
|
45685
|
+
function readString28(payload, key) {
|
|
45157
45686
|
const value = payload[key];
|
|
45158
45687
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
45159
45688
|
}
|
|
45160
45689
|
|
|
45161
45690
|
// src/pairing/pairing.ts
|
|
45162
|
-
import
|
|
45691
|
+
import path38 from "path";
|
|
45163
45692
|
import { rm as rm12 } from "fs/promises";
|
|
45164
45693
|
|
|
45165
45694
|
// src/relay/bootstrap.ts
|
|
@@ -45499,10 +46028,10 @@ async function loadRequiredIdentity2(paths) {
|
|
|
45499
46028
|
}
|
|
45500
46029
|
return identity;
|
|
45501
46030
|
}
|
|
45502
|
-
async function postServerJson(serverBaseUrl,
|
|
46031
|
+
async function postServerJson(serverBaseUrl, path39, body, options) {
|
|
45503
46032
|
let response;
|
|
45504
46033
|
try {
|
|
45505
|
-
response = await fetch(`${serverBaseUrl.replace(/\/+$/u, "")}${
|
|
46034
|
+
response = await fetch(`${serverBaseUrl.replace(/\/+$/u, "")}${path39}`, {
|
|
45506
46035
|
method: "POST",
|
|
45507
46036
|
headers: {
|
|
45508
46037
|
accept: "application/json",
|
|
@@ -45550,10 +46079,10 @@ function pairingErrorSnapshot(stage, error) {
|
|
|
45550
46079
|
occurred_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
45551
46080
|
};
|
|
45552
46081
|
}
|
|
45553
|
-
async function patchServerJson(serverBaseUrl,
|
|
46082
|
+
async function patchServerJson(serverBaseUrl, path39, token, body, options) {
|
|
45554
46083
|
let response;
|
|
45555
46084
|
try {
|
|
45556
|
-
response = await fetch(`${serverBaseUrl.replace(/\/+$/u, "")}${
|
|
46085
|
+
response = await fetch(`${serverBaseUrl.replace(/\/+$/u, "")}${path39}`, {
|
|
45557
46086
|
method: "PATCH",
|
|
45558
46087
|
headers: {
|
|
45559
46088
|
accept: "application/json",
|
|
@@ -45601,10 +46130,10 @@ function createPairingNetworkError(input) {
|
|
|
45601
46130
|
);
|
|
45602
46131
|
}
|
|
45603
46132
|
function pairingClaimPath(sessionId, paths) {
|
|
45604
|
-
return
|
|
46133
|
+
return path38.join(paths.pairingDir, `${Buffer.from(sessionId).toString("base64url")}.claimed.json`);
|
|
45605
46134
|
}
|
|
45606
46135
|
function pairingSessionPath(sessionId, paths) {
|
|
45607
|
-
return
|
|
46136
|
+
return path38.join(paths.pairingDir, `${Buffer.from(sessionId).toString("base64url")}.json`);
|
|
45608
46137
|
}
|
|
45609
46138
|
function qrPreferredUrls(routes) {
|
|
45610
46139
|
return routes.preferredUrls.filter((url) => !url.includes("/api/v1/relay/links/")).slice(0, 1);
|
|
@@ -45707,8 +46236,8 @@ function registerSystemRoutes(router, options) {
|
|
|
45707
46236
|
});
|
|
45708
46237
|
router.post("/api/v1/pairing/claim", async (ctx) => {
|
|
45709
46238
|
const body = await readJsonBody(ctx.req);
|
|
45710
|
-
const sessionId =
|
|
45711
|
-
const claimToken =
|
|
46239
|
+
const sessionId = readString23(body, "session_id") ?? readString23(body, "sessionId");
|
|
46240
|
+
const claimToken = readString23(body, "claim_token") ?? readString23(body, "claimToken");
|
|
45712
46241
|
if (!sessionId || !claimToken) {
|
|
45713
46242
|
throw new LinkHttpError(
|
|
45714
46243
|
400,
|
|
@@ -45719,10 +46248,10 @@ function registerSystemRoutes(router, options) {
|
|
|
45719
46248
|
const claimed = await claimPairing({
|
|
45720
46249
|
sessionId,
|
|
45721
46250
|
claimToken,
|
|
45722
|
-
deviceLabel:
|
|
45723
|
-
devicePlatform:
|
|
45724
|
-
deviceModel:
|
|
45725
|
-
appInstanceId:
|
|
46251
|
+
deviceLabel: readString23(body, "device_label") ?? readString23(body, "deviceLabel") ?? "HermesPilot App",
|
|
46252
|
+
devicePlatform: readString23(body, "device_platform") ?? readString23(body, "devicePlatform") ?? "unknown",
|
|
46253
|
+
deviceModel: readString23(body, "device_model") ?? readString23(body, "deviceModel"),
|
|
46254
|
+
appInstanceId: readString23(body, "app_instance_id") ?? readString23(body, "appInstanceId"),
|
|
45726
46255
|
paths
|
|
45727
46256
|
});
|
|
45728
46257
|
ctx.body = claimed;
|
|
@@ -45802,9 +46331,9 @@ function registerSystemRoutes(router, options) {
|
|
|
45802
46331
|
const body = await readJsonBody(ctx.req);
|
|
45803
46332
|
const session = await createDeviceSession(
|
|
45804
46333
|
{
|
|
45805
|
-
label:
|
|
45806
|
-
platform:
|
|
45807
|
-
model:
|
|
46334
|
+
label: readString23(body, "device_label") ?? readString23(body, "deviceLabel") ?? "HermesPilot App",
|
|
46335
|
+
platform: readString23(body, "device_platform") ?? readString23(body, "devicePlatform") ?? "unknown",
|
|
46336
|
+
model: readString23(body, "device_model") ?? readString23(body, "deviceModel"),
|
|
45808
46337
|
appInstanceId: auth.appInstanceId
|
|
45809
46338
|
},
|
|
45810
46339
|
paths
|
|
@@ -45833,7 +46362,7 @@ function registerSystemRoutes(router, options) {
|
|
|
45833
46362
|
});
|
|
45834
46363
|
router.post("/api/v1/auth/refresh", async (ctx) => {
|
|
45835
46364
|
const body = await readJsonBody(ctx.req);
|
|
45836
|
-
const refreshToken =
|
|
46365
|
+
const refreshToken = readString23(body, "refresh_token") ?? readString23(body, "refreshToken");
|
|
45837
46366
|
if (!refreshToken) {
|
|
45838
46367
|
throw new LinkHttpError(
|
|
45839
46368
|
400,
|
|
@@ -45844,10 +46373,10 @@ function registerSystemRoutes(router, options) {
|
|
|
45844
46373
|
const session = await refreshDeviceSession(
|
|
45845
46374
|
refreshToken,
|
|
45846
46375
|
{
|
|
45847
|
-
appInstanceId:
|
|
45848
|
-
label:
|
|
45849
|
-
platform:
|
|
45850
|
-
model:
|
|
46376
|
+
appInstanceId: readString23(body, "app_instance_id") ?? readString23(body, "appInstanceId"),
|
|
46377
|
+
label: readString23(body, "device_label") ?? readString23(body, "deviceLabel"),
|
|
46378
|
+
platform: readString23(body, "device_platform") ?? readString23(body, "devicePlatform"),
|
|
46379
|
+
model: readString23(body, "device_model") ?? readString23(body, "deviceModel")
|
|
45851
46380
|
},
|
|
45852
46381
|
paths
|
|
45853
46382
|
);
|
|
@@ -45866,7 +46395,7 @@ function registerSystemRoutes(router, options) {
|
|
|
45866
46395
|
});
|
|
45867
46396
|
router.post("/api/v1/auth/logout", async (ctx) => {
|
|
45868
46397
|
const body = await readJsonBody(ctx.req);
|
|
45869
|
-
const refreshToken =
|
|
46398
|
+
const refreshToken = readString23(body, "refresh_token") ?? readString23(body, "refreshToken");
|
|
45870
46399
|
if (refreshToken) {
|
|
45871
46400
|
await revokeDeviceRefreshToken(refreshToken, paths);
|
|
45872
46401
|
}
|
|
@@ -46107,7 +46636,7 @@ function registerSystemRoutes(router, options) {
|
|
|
46107
46636
|
router.patch("/api/v1/devices/:deviceId", async (ctx) => {
|
|
46108
46637
|
const auth = await authenticateRequest(ctx, paths);
|
|
46109
46638
|
const body = await readJsonBody(ctx.req);
|
|
46110
|
-
const label =
|
|
46639
|
+
const label = readString23(body, "label") ?? readString23(body, "device_label");
|
|
46111
46640
|
if (!label) {
|
|
46112
46641
|
throw new LinkHttpError(
|
|
46113
46642
|
400,
|
|
@@ -46151,7 +46680,7 @@ function isActiveCronJob(job) {
|
|
|
46151
46680
|
if (!enabled) {
|
|
46152
46681
|
return false;
|
|
46153
46682
|
}
|
|
46154
|
-
const state =
|
|
46683
|
+
const state = readString23(job, "state")?.toLowerCase();
|
|
46155
46684
|
return !["paused", "disabled", "completed", "deleted"].includes(state ?? "");
|
|
46156
46685
|
}
|
|
46157
46686
|
function filterLogsWithinHours(logs, hours, now = Date.now()) {
|
|
@@ -46195,8 +46724,8 @@ function registerWorkspaceRoutes(router, options) {
|
|
|
46195
46724
|
ctx.body = {
|
|
46196
46725
|
ok: true,
|
|
46197
46726
|
workspace: await conversations.createWorkspace({
|
|
46198
|
-
name:
|
|
46199
|
-
icon:
|
|
46727
|
+
name: readString23(body, "name") ?? "",
|
|
46728
|
+
icon: readString23(body, "icon") ?? void 0
|
|
46200
46729
|
})
|
|
46201
46730
|
};
|
|
46202
46731
|
});
|
|
@@ -46206,8 +46735,8 @@ function registerWorkspaceRoutes(router, options) {
|
|
|
46206
46735
|
ctx.body = {
|
|
46207
46736
|
ok: true,
|
|
46208
46737
|
workspace: await conversations.renameWorkspace(ctx.params.workspaceId, {
|
|
46209
|
-
name:
|
|
46210
|
-
icon:
|
|
46738
|
+
name: readString23(body, "name") ?? "",
|
|
46739
|
+
icon: readString23(body, "icon") ?? void 0
|
|
46211
46740
|
})
|
|
46212
46741
|
};
|
|
46213
46742
|
});
|
|
@@ -46290,8 +46819,8 @@ function registerLinkUpdateRoutes(router, options) {
|
|
|
46290
46819
|
ctx.body = await startLinkUpdate({
|
|
46291
46820
|
paths,
|
|
46292
46821
|
logger,
|
|
46293
|
-
channel:
|
|
46294
|
-
targetVersion:
|
|
46822
|
+
channel: readString23(body, "channel"),
|
|
46823
|
+
targetVersion: readString23(body, "target_version") ?? readString23(body, "targetVersion")
|
|
46295
46824
|
});
|
|
46296
46825
|
});
|
|
46297
46826
|
router.get("/api/v1/link/update/events", async (ctx) => {
|
|
@@ -46321,7 +46850,7 @@ import QRCode from "qrcode";
|
|
|
46321
46850
|
function registerPairingRoutes(router, options) {
|
|
46322
46851
|
const { paths } = options;
|
|
46323
46852
|
router.get("/pair", async (ctx) => {
|
|
46324
|
-
const sessionId =
|
|
46853
|
+
const sessionId = readString23(ctx.query, "session_id");
|
|
46325
46854
|
if (!sessionId) {
|
|
46326
46855
|
throw new LinkHttpError(400, "pairing_session_required", "session_id is required");
|
|
46327
46856
|
}
|
|
@@ -46346,7 +46875,7 @@ function registerPairingRoutes(router, options) {
|
|
|
46346
46875
|
ctx.body = page;
|
|
46347
46876
|
});
|
|
46348
46877
|
router.get("/api/v1/pairing/session", async (ctx) => {
|
|
46349
|
-
const sessionId =
|
|
46878
|
+
const sessionId = readString23(ctx.query, "session_id");
|
|
46350
46879
|
if (!sessionId) {
|
|
46351
46880
|
throw new LinkHttpError(400, "pairing_session_required", "session_id is required");
|
|
46352
46881
|
}
|
|
@@ -46816,7 +47345,7 @@ function registerInternalRoutes(router, options) {
|
|
|
46816
47345
|
router.post("/internal/deliver", async (ctx) => {
|
|
46817
47346
|
assertLoopbackRequest(ctx.req);
|
|
46818
47347
|
const body = await readJsonBody(ctx.req);
|
|
46819
|
-
const stagingDir =
|
|
47348
|
+
const stagingDir = readString23(body, "staging_dir") ?? readString23(body, "stagingDir");
|
|
46820
47349
|
if (!stagingDir) {
|
|
46821
47350
|
throw new LinkHttpError(
|
|
46822
47351
|
400,
|
|
@@ -46835,9 +47364,9 @@ function registerInternalRoutes(router, options) {
|
|
|
46835
47364
|
ctx.body = {
|
|
46836
47365
|
ok: true,
|
|
46837
47366
|
...await options.conversations.deliverFilesFromTool({
|
|
46838
|
-
profile:
|
|
46839
|
-
taskId:
|
|
46840
|
-
sessionId:
|
|
47367
|
+
profile: readString23(body, "profile") ?? readString23(body, "profile_name") ?? readString23(body, "profileName") ?? void 0,
|
|
47368
|
+
taskId: readString23(body, "task_id") ?? readString23(body, "taskId") ?? void 0,
|
|
47369
|
+
sessionId: readString23(body, "session_id") ?? readString23(body, "sessionId") ?? void 0,
|
|
46841
47370
|
files: body.files ?? body.file ?? body.path
|
|
46842
47371
|
})
|
|
46843
47372
|
};
|
|
@@ -46898,9 +47427,9 @@ function registerLiveActivityRoutes(router, options) {
|
|
|
46898
47427
|
const auth = await authenticateRequest(ctx, paths);
|
|
46899
47428
|
const body = await readJsonBody(ctx.req);
|
|
46900
47429
|
const targetKind = readTargetKind(body);
|
|
46901
|
-
const runId = normalizePattern(
|
|
47430
|
+
const runId = normalizePattern(readString23(body, "run_id") ?? readString23(body, "runId"), RUN_ID_PATTERN);
|
|
46902
47431
|
const operationId = normalizePattern(
|
|
46903
|
-
|
|
47432
|
+
readString23(body, "operation_id") ?? readString23(body, "operationId"),
|
|
46904
47433
|
OPERATION_ID_PATTERN
|
|
46905
47434
|
);
|
|
46906
47435
|
if (targetKind === "run" && !runId) {
|
|
@@ -46946,7 +47475,7 @@ function registerLiveActivityRoutes(router, options) {
|
|
|
46946
47475
|
});
|
|
46947
47476
|
}
|
|
46948
47477
|
function readTargetKind(body) {
|
|
46949
|
-
const value =
|
|
47478
|
+
const value = readString23(body, "target_kind") ?? readString23(body, "targetKind");
|
|
46950
47479
|
return readTargetKindValue(value);
|
|
46951
47480
|
}
|
|
46952
47481
|
function readTargetKindValue(value) {
|
|
@@ -46968,21 +47497,21 @@ function readQueryValue(query, key) {
|
|
|
46968
47497
|
return readQueryString(query[key]) ?? null;
|
|
46969
47498
|
}
|
|
46970
47499
|
function readApnsEnvironment(body) {
|
|
46971
|
-
const value =
|
|
47500
|
+
const value = readString23(body, "apns_environment") ?? readString23(body, "apnsEnvironment");
|
|
46972
47501
|
if (value === "sandbox" || value === "production") {
|
|
46973
47502
|
return value;
|
|
46974
47503
|
}
|
|
46975
47504
|
throw new LinkHttpError(400, "apns_environment_invalid", "apns_environment must be sandbox or production");
|
|
46976
47505
|
}
|
|
46977
47506
|
function readLanguage2(body) {
|
|
46978
|
-
const value =
|
|
47507
|
+
const value = readString23(body, "language") ?? readString23(body, "preferred_language") ?? readString23(body, "preferredLanguage");
|
|
46979
47508
|
if (!value) {
|
|
46980
47509
|
return null;
|
|
46981
47510
|
}
|
|
46982
47511
|
return value.toLowerCase().startsWith("zh") ? "zh" : "en";
|
|
46983
47512
|
}
|
|
46984
47513
|
function readPrivacyLevel(body) {
|
|
46985
|
-
const value =
|
|
47514
|
+
const value = readString23(body, "privacy_level") ?? readString23(body, "privacyLevel");
|
|
46986
47515
|
if (value === "minimal" || value === "detailed") {
|
|
46987
47516
|
return value;
|
|
46988
47517
|
}
|
|
@@ -46990,7 +47519,7 @@ function readPrivacyLevel(body) {
|
|
|
46990
47519
|
}
|
|
46991
47520
|
function readRequiredString(body, keys, code) {
|
|
46992
47521
|
for (const key of keys) {
|
|
46993
|
-
const value =
|
|
47522
|
+
const value = readString23(body, key);
|
|
46994
47523
|
if (value) {
|
|
46995
47524
|
return value;
|
|
46996
47525
|
}
|
|
@@ -47006,7 +47535,7 @@ function readRequiredPattern(body, keys, pattern, code) {
|
|
|
47006
47535
|
}
|
|
47007
47536
|
function readOptionalString2(body, keys, maxLength) {
|
|
47008
47537
|
for (const key of keys) {
|
|
47009
|
-
const value =
|
|
47538
|
+
const value = readString23(body, key);
|
|
47010
47539
|
if (value) {
|
|
47011
47540
|
return value.slice(0, maxLength);
|
|
47012
47541
|
}
|
|
@@ -47018,7 +47547,7 @@ function normalizePattern(value, pattern) {
|
|
|
47018
47547
|
}
|
|
47019
47548
|
function readIso(body, keys) {
|
|
47020
47549
|
for (const key of keys) {
|
|
47021
|
-
const value =
|
|
47550
|
+
const value = readString23(body, key);
|
|
47022
47551
|
if (!value) {
|
|
47023
47552
|
continue;
|
|
47024
47553
|
}
|