@hermespilot/link 0.8.1-beta.4 → 0.8.2-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-KV3YWRM5.js → chunk-JOFONSVB.js} +1036 -410
- 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.2-beta.0";
|
|
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) {
|
|
@@ -29186,7 +29698,13 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
29186
29698
|
});
|
|
29187
29699
|
if (messageId) {
|
|
29188
29700
|
if (isReasoningEvent) {
|
|
29189
|
-
await this.appendThinkingDelta(
|
|
29701
|
+
await this.appendThinkingDelta(
|
|
29702
|
+
conversationId,
|
|
29703
|
+
runId,
|
|
29704
|
+
messageId,
|
|
29705
|
+
event,
|
|
29706
|
+
conversationEvent.created_at
|
|
29707
|
+
);
|
|
29190
29708
|
} else {
|
|
29191
29709
|
await this.persistAgentEventProjection(
|
|
29192
29710
|
conversationId,
|
|
@@ -29211,10 +29729,10 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
29211
29729
|
return goalStatus;
|
|
29212
29730
|
}
|
|
29213
29731
|
async persistGoalStatusUpdate(conversationId, runId, event) {
|
|
29214
|
-
if (
|
|
29732
|
+
if (readString21(event.payload, "kind") !== "goal") {
|
|
29215
29733
|
return null;
|
|
29216
29734
|
}
|
|
29217
|
-
const text =
|
|
29735
|
+
const text = readString21(event.payload, "text") ?? readString21(event.payload, "message") ?? readString21(event.payload, "status") ?? "";
|
|
29218
29736
|
const manifest = await this.deps.readRunnableManifest(conversationId);
|
|
29219
29737
|
const snapshot = await this.deps.readSnapshot(conversationId);
|
|
29220
29738
|
const run = snapshot.runs.find((item) => item.id === runId);
|
|
@@ -29401,7 +29919,7 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
29401
29919
|
}
|
|
29402
29920
|
const textPart = assistant.parts.find((part) => part.type === "text");
|
|
29403
29921
|
const currentText = textPart?.text ?? "";
|
|
29404
|
-
const pendingDeliveryText =
|
|
29922
|
+
const pendingDeliveryText = readString21(
|
|
29405
29923
|
toRecord19(assistant.hermes),
|
|
29406
29924
|
"pending_media_delivery_text"
|
|
29407
29925
|
);
|
|
@@ -29452,7 +29970,7 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
29452
29970
|
extracted.references
|
|
29453
29971
|
);
|
|
29454
29972
|
}
|
|
29455
|
-
async appendThinkingDelta(conversationId, runId, messageId, event) {
|
|
29973
|
+
async appendThinkingDelta(conversationId, runId, messageId, event, updatedAt) {
|
|
29456
29974
|
const delta = readDelta(event.payload);
|
|
29457
29975
|
if (!delta) {
|
|
29458
29976
|
return;
|
|
@@ -29463,7 +29981,27 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
29463
29981
|
);
|
|
29464
29982
|
const hasAssistantText = assistant != null && messageText2(assistant).trim().length > 0;
|
|
29465
29983
|
const run = snapshot.runs.find((item) => item.id === runId);
|
|
29466
|
-
if (!assistant ||
|
|
29984
|
+
if (!assistant || run?.status !== "running") {
|
|
29985
|
+
return;
|
|
29986
|
+
}
|
|
29987
|
+
const occurredAt = updatedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
29988
|
+
if (isInlineReasoningDeltaEvent(event.payloadType)) {
|
|
29989
|
+
appendThinkingEventBlock(
|
|
29990
|
+
assistant,
|
|
29991
|
+
{
|
|
29992
|
+
id: `reasoning_${this.reasoningDeltaSegmentId(event) ?? "delta"}`,
|
|
29993
|
+
kind: "thinking_delta",
|
|
29994
|
+
title: "Thinking",
|
|
29995
|
+
status: "running",
|
|
29996
|
+
created_at: occurredAt,
|
|
29997
|
+
text: delta
|
|
29998
|
+
},
|
|
29999
|
+
occurredAt
|
|
30000
|
+
);
|
|
30001
|
+
assistant.updated_at = occurredAt;
|
|
30002
|
+
await this.deps.writeSnapshot(conversationId, snapshot);
|
|
30003
|
+
}
|
|
30004
|
+
if (hasAssistantText) {
|
|
29467
30005
|
return;
|
|
29468
30006
|
}
|
|
29469
30007
|
await this.deps.appendEvent(conversationId, {
|
|
@@ -29483,8 +30021,11 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
29483
30021
|
});
|
|
29484
30022
|
}
|
|
29485
30023
|
thinkingSegmentId(runId, event) {
|
|
30024
|
+
return this.reasoningDeltaSegmentId(event) ?? `${event.payloadType}:${runId}`;
|
|
30025
|
+
}
|
|
30026
|
+
reasoningDeltaSegmentId(event) {
|
|
29486
30027
|
const payload = event.payload;
|
|
29487
|
-
return
|
|
30028
|
+
return readString21(payload, "segment_id") ?? readString21(payload, "segmentId") ?? readString21(payload, "id") ?? readString21(payload, "tool_call_id") ?? readString21(payload, "tool_id") ?? null;
|
|
29488
30029
|
}
|
|
29489
30030
|
async runRequestsAppDelivery(conversationId, runId) {
|
|
29490
30031
|
const snapshot = await this.deps.readSnapshot(conversationId).catch(() => null);
|
|
@@ -29496,9 +30037,14 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
29496
30037
|
}
|
|
29497
30038
|
async completeRun(conversationId, runId, source) {
|
|
29498
30039
|
await this.refreshRunHermesCompressionTip(conversationId, runId);
|
|
30040
|
+
const afterWatermark = await this.readRunHermesMessageWatermark(
|
|
30041
|
+
conversationId,
|
|
30042
|
+
runId,
|
|
30043
|
+
"after"
|
|
30044
|
+
);
|
|
29499
30045
|
return this.deps.withConversationLock(
|
|
29500
30046
|
conversationId,
|
|
29501
|
-
() => this.completeRunLocked(conversationId, runId, source)
|
|
30047
|
+
() => this.completeRunLocked(conversationId, runId, source, afterWatermark)
|
|
29502
30048
|
);
|
|
29503
30049
|
}
|
|
29504
30050
|
async refreshRunHermesCompressionTip(conversationId, runId) {
|
|
@@ -29535,7 +30081,7 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
29535
30081
|
await this.rememberRunHermesSessionId(conversationId, runId, compressionTip);
|
|
29536
30082
|
return { previousSessionId, nextSessionId: compressionTip };
|
|
29537
30083
|
}
|
|
29538
|
-
async completeRunLocked(conversationId, runId, source) {
|
|
30084
|
+
async completeRunLocked(conversationId, runId, source, afterWatermark) {
|
|
29539
30085
|
let snapshot = await this.deps.readSnapshot(conversationId);
|
|
29540
30086
|
let run = snapshot.runs.find((item) => item.id === runId);
|
|
29541
30087
|
if (!run || run.status !== "running") {
|
|
@@ -29577,6 +30123,9 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
29577
30123
|
if (usage) {
|
|
29578
30124
|
run.usage = mergeRunUsage(run.usage, usage);
|
|
29579
30125
|
}
|
|
30126
|
+
if (afterWatermark) {
|
|
30127
|
+
applyRunHermesMessageWatermark(run, "after", afterWatermark);
|
|
30128
|
+
}
|
|
29580
30129
|
const probeEvent = shouldUseHermesUsageProbe(run.hermes_backend) ? await findHermesUsageProbeEventForRun({
|
|
29581
30130
|
paths: this.deps.paths,
|
|
29582
30131
|
profileName: run.profile,
|
|
@@ -29725,7 +30274,7 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
29725
30274
|
await this.deps.writeManifest(nextManifest);
|
|
29726
30275
|
return goal;
|
|
29727
30276
|
}
|
|
29728
|
-
async failRunLocked(conversationId, runId, message, source) {
|
|
30277
|
+
async failRunLocked(conversationId, runId, message, source, afterWatermark) {
|
|
29729
30278
|
const snapshot = await this.deps.readSnapshot(conversationId).catch(() => null);
|
|
29730
30279
|
if (!snapshot) {
|
|
29731
30280
|
return;
|
|
@@ -29748,6 +30297,9 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
29748
30297
|
if (usage) {
|
|
29749
30298
|
run.usage = mergeRunUsage(run.usage, usage);
|
|
29750
30299
|
}
|
|
30300
|
+
if (afterWatermark) {
|
|
30301
|
+
applyRunHermesMessageWatermark(run, "after", afterWatermark);
|
|
30302
|
+
}
|
|
29751
30303
|
const assistant = snapshot.messages.find(
|
|
29752
30304
|
(item) => item.id === run.assistant_message_id
|
|
29753
30305
|
);
|
|
@@ -30111,7 +30663,7 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
|
|
|
30111
30663
|
includeDisabled: true
|
|
30112
30664
|
});
|
|
30113
30665
|
return new Set(
|
|
30114
|
-
jobs.map((job) =>
|
|
30666
|
+
jobs.map((job) => readString21(job, "id") ?? readString21(job, "job_id")).filter((id) => Boolean(id))
|
|
30115
30667
|
);
|
|
30116
30668
|
}
|
|
30117
30669
|
async bindNewCronJobsCreatedByRun(input) {
|
|
@@ -30211,7 +30763,7 @@ async function readdirWithDirs(directory) {
|
|
|
30211
30763
|
throw error;
|
|
30212
30764
|
});
|
|
30213
30765
|
}
|
|
30214
|
-
function
|
|
30766
|
+
function readString21(payload, key) {
|
|
30215
30767
|
const value = payload[key];
|
|
30216
30768
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
30217
30769
|
}
|
|
@@ -30302,11 +30854,11 @@ function contextCompressionGeneration(message) {
|
|
|
30302
30854
|
return typeof generation === "number" && Number.isFinite(generation) ? Math.max(0, Math.floor(generation)) : null;
|
|
30303
30855
|
}
|
|
30304
30856
|
function readPreviousSessionId(payload) {
|
|
30305
|
-
return
|
|
30857
|
+
return readString21(payload, "old_session_id") ?? readString21(payload, "oldSessionId") ?? readString21(payload, "previous_session_id") ?? readString21(payload, "previousSessionId");
|
|
30306
30858
|
}
|
|
30307
30859
|
function readNextSessionId(payload) {
|
|
30308
30860
|
const info = toRecord19(payload.info);
|
|
30309
|
-
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");
|
|
30310
30862
|
}
|
|
30311
30863
|
function eventPayloadWithLanguage(payload, language) {
|
|
30312
30864
|
return { ...payload, language };
|
|
@@ -30398,13 +30950,13 @@ function isFileSearchCompletion(payloadType, payload) {
|
|
|
30398
30950
|
const toolCall = toRecord19(payload.tool_call ?? payload.toolCall);
|
|
30399
30951
|
const fn = toRecord19(toolCall.function ?? payload.function);
|
|
30400
30952
|
const candidates = [
|
|
30401
|
-
|
|
30402
|
-
|
|
30403
|
-
|
|
30404
|
-
|
|
30405
|
-
|
|
30406
|
-
|
|
30407
|
-
|
|
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")
|
|
30408
30960
|
].filter((value) => Boolean(value)).map(normalizeToolName);
|
|
30409
30961
|
return candidates.some(
|
|
30410
30962
|
(name) => [
|
|
@@ -30441,7 +30993,7 @@ function messageRequestsAppDelivery(text) {
|
|
|
30441
30993
|
const hasEnglishDeliveryAction = /\b(send|share|attach|deliver|display)\b/u.test(lower) || /\bshow\s+me\b/u.test(lower);
|
|
30442
30994
|
return hasEnglishDeliverable && hasEnglishDeliveryAction;
|
|
30443
30995
|
}
|
|
30444
|
-
function
|
|
30996
|
+
function isVoicePart2(part) {
|
|
30445
30997
|
return part.kind === "voice" || part.is_voice_note === true;
|
|
30446
30998
|
}
|
|
30447
30999
|
function normalizeToolName(value) {
|
|
@@ -30499,9 +31051,12 @@ function appendAgentEventBlock2(message, event, updatedAt) {
|
|
|
30499
31051
|
if (block.type !== "agent_events") {
|
|
30500
31052
|
return false;
|
|
30501
31053
|
}
|
|
31054
|
+
if (!agentEventBlockAcceptsEvent(block, event)) {
|
|
31055
|
+
return false;
|
|
31056
|
+
}
|
|
30502
31057
|
return upsertAgentEventProjection(block.events, event).length === block.events.length;
|
|
30503
31058
|
});
|
|
30504
|
-
const targetIndex = matchingIndex >= 0 ? matchingIndex : blocks.at(-1)?.type === "agent_events" ? blocks.length - 1 : -1;
|
|
31059
|
+
const targetIndex = matchingIndex >= 0 ? matchingIndex : blocks.at(-1)?.type === "agent_events" && agentEventBlockAcceptsEvent(blocks.at(-1), event) ? blocks.length - 1 : -1;
|
|
30505
31060
|
if (targetIndex >= 0) {
|
|
30506
31061
|
const block = blocks[targetIndex];
|
|
30507
31062
|
if (block.type === "agent_events") {
|
|
@@ -30522,6 +31077,68 @@ function appendAgentEventBlock2(message, event, updatedAt) {
|
|
|
30522
31077
|
}
|
|
30523
31078
|
message.blocks = blocks;
|
|
30524
31079
|
}
|
|
31080
|
+
function appendThinkingEventBlock(message, event, updatedAt) {
|
|
31081
|
+
const blocks = [...message.blocks ?? []];
|
|
31082
|
+
const lastBlock = blocks.at(-1);
|
|
31083
|
+
const targetIndex = lastBlock?.type === "agent_events" && agentEventBlockAcceptsEvent(lastBlock, event) ? blocks.length - 1 : -1;
|
|
31084
|
+
if (targetIndex >= 0) {
|
|
31085
|
+
const block = blocks[targetIndex];
|
|
31086
|
+
if (block.type === "agent_events") {
|
|
31087
|
+
blocks[targetIndex] = {
|
|
31088
|
+
...block,
|
|
31089
|
+
events: upsertThinkingDeltaEvent(block.events, event),
|
|
31090
|
+
updated_at: updatedAt
|
|
31091
|
+
};
|
|
31092
|
+
}
|
|
31093
|
+
} else {
|
|
31094
|
+
blocks.push({
|
|
31095
|
+
id: `thinking_${blocks.length + 1}`,
|
|
31096
|
+
type: "agent_events",
|
|
31097
|
+
events: [event],
|
|
31098
|
+
created_at: updatedAt,
|
|
31099
|
+
updated_at: updatedAt
|
|
31100
|
+
});
|
|
31101
|
+
}
|
|
31102
|
+
message.blocks = blocks;
|
|
31103
|
+
}
|
|
31104
|
+
function agentEventBlockAcceptsEvent(block, event) {
|
|
31105
|
+
if (block.type !== "agent_events" || block.events.length === 0) {
|
|
31106
|
+
return true;
|
|
31107
|
+
}
|
|
31108
|
+
return block.events.every(
|
|
31109
|
+
(item) => isThinkingAgentEvent(item) === isThinkingAgentEvent(event)
|
|
31110
|
+
);
|
|
31111
|
+
}
|
|
31112
|
+
function upsertThinkingDeltaEvent(events, event) {
|
|
31113
|
+
const index = events.findIndex((item) => item.id === event.id);
|
|
31114
|
+
if (index < 0) {
|
|
31115
|
+
return [...events, event];
|
|
31116
|
+
}
|
|
31117
|
+
const previous = events[index];
|
|
31118
|
+
const copy = [...events];
|
|
31119
|
+
copy[index] = {
|
|
31120
|
+
...previous,
|
|
31121
|
+
...event,
|
|
31122
|
+
text: mergeThinkingText(previous.text ?? "", event.text ?? ""),
|
|
31123
|
+
created_at: previous.created_at
|
|
31124
|
+
};
|
|
31125
|
+
return copy;
|
|
31126
|
+
}
|
|
31127
|
+
function mergeThinkingText(previous, delta) {
|
|
31128
|
+
if (!delta) {
|
|
31129
|
+
return previous;
|
|
31130
|
+
}
|
|
31131
|
+
if (!previous || delta === previous) {
|
|
31132
|
+
return delta;
|
|
31133
|
+
}
|
|
31134
|
+
if (delta.startsWith(previous)) {
|
|
31135
|
+
return delta;
|
|
31136
|
+
}
|
|
31137
|
+
return `${previous}${delta}`;
|
|
31138
|
+
}
|
|
31139
|
+
function isThinkingAgentEvent(event) {
|
|
31140
|
+
return event.kind === "thinking_delta";
|
|
31141
|
+
}
|
|
30525
31142
|
function contextUsagePayloadForSnapshot(snapshot) {
|
|
30526
31143
|
const run = latestContextUsageRun(snapshot);
|
|
30527
31144
|
return run ? contextUsagePayload2(run) : null;
|
|
@@ -30577,7 +31194,10 @@ function reasoningEffortForRun(run) {
|
|
|
30577
31194
|
return effort;
|
|
30578
31195
|
}
|
|
30579
31196
|
function isReasoningStreamEvent(payloadType) {
|
|
30580
|
-
return payloadType === "reasoning.
|
|
31197
|
+
return payloadType === "reasoning.delta" || payloadType === "thinking.delta";
|
|
31198
|
+
}
|
|
31199
|
+
function isInlineReasoningDeltaEvent(payloadType) {
|
|
31200
|
+
return payloadType === "reasoning.delta";
|
|
30581
31201
|
}
|
|
30582
31202
|
function mergeRunUsage(previous, next) {
|
|
30583
31203
|
const nextContextWindow = next.context_window ?? previous?.context_window;
|
|
@@ -30676,13 +31296,13 @@ function readResponseId(payload) {
|
|
|
30676
31296
|
return null;
|
|
30677
31297
|
}
|
|
30678
31298
|
const response = toRecord19(payload.response);
|
|
30679
|
-
return
|
|
31299
|
+
return readString21(payload, "response_id") ?? readString21(response, "id");
|
|
30680
31300
|
}
|
|
30681
31301
|
function readRunId(payload) {
|
|
30682
31302
|
if (!payload) {
|
|
30683
31303
|
return null;
|
|
30684
31304
|
}
|
|
30685
|
-
return
|
|
31305
|
+
return readString21(payload, "run_id") ?? readString21(payload, "runId");
|
|
30686
31306
|
}
|
|
30687
31307
|
function isCompletedRunStatus(status) {
|
|
30688
31308
|
return status === "completed" || status === "complete" || status === "succeeded" || status === "success" || status === "done";
|
|
@@ -30701,7 +31321,7 @@ function readStatusErrorMessage(value) {
|
|
|
30701
31321
|
return value.trim();
|
|
30702
31322
|
}
|
|
30703
31323
|
const record = toRecord19(value);
|
|
30704
|
-
return
|
|
31324
|
+
return readString21(record, "message") ?? readString21(record, "error");
|
|
30705
31325
|
}
|
|
30706
31326
|
function formatUnknownErrorMessage(error) {
|
|
30707
31327
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -30740,6 +31360,12 @@ function sanitizeLiveSessionForEvent(liveSession) {
|
|
|
30740
31360
|
...liveSession.inflight ? { inflight: liveSession.inflight } : {}
|
|
30741
31361
|
};
|
|
30742
31362
|
}
|
|
31363
|
+
function applyRunHermesMessageWatermark(run, phase, point) {
|
|
31364
|
+
run.hermes_message_watermark = {
|
|
31365
|
+
...run.hermes_message_watermark ?? {},
|
|
31366
|
+
[phase]: point
|
|
31367
|
+
};
|
|
31368
|
+
}
|
|
30743
31369
|
function previewText2(message) {
|
|
30744
31370
|
if (!message) {
|
|
30745
31371
|
return null;
|
|
@@ -32464,7 +33090,7 @@ var ConversationService = class {
|
|
|
32464
33090
|
}
|
|
32465
33091
|
}
|
|
32466
33092
|
hermesArchiveStateSyncMarkerPath() {
|
|
32467
|
-
return
|
|
33093
|
+
return path28.join(this.paths.indexesDir, "hermes-archive-state-sync.json");
|
|
32468
33094
|
}
|
|
32469
33095
|
prepareClearAllConversationPlan(targetStatus) {
|
|
32470
33096
|
return this.maintenance.prepareClearAllConversationPlan(targetStatus);
|
|
@@ -32746,7 +33372,7 @@ function liveActivityTodoProgressForEvent(event) {
|
|
|
32746
33372
|
if (todos) {
|
|
32747
33373
|
const totalCount2 = todos.length;
|
|
32748
33374
|
const doneCount2 = todos.filter((item) => {
|
|
32749
|
-
const status =
|
|
33375
|
+
const status = readString22(item, "status")?.toLowerCase();
|
|
32750
33376
|
return status === "completed" || status === "cancelled" || status === "canceled";
|
|
32751
33377
|
}).length;
|
|
32752
33378
|
return {
|
|
@@ -32795,11 +33421,11 @@ function liveActivityTitleFromConversationUpdate(event) {
|
|
|
32795
33421
|
if (event.type.toLowerCase() !== "conversation.updated") {
|
|
32796
33422
|
return void 0;
|
|
32797
33423
|
}
|
|
32798
|
-
const titleSource =
|
|
33424
|
+
const titleSource = readString22(event.payload, "title_source");
|
|
32799
33425
|
if (titleSource === "default" || titleSource === "temporary_fallback") {
|
|
32800
33426
|
return null;
|
|
32801
33427
|
}
|
|
32802
|
-
const title =
|
|
33428
|
+
const title = readString22(event.payload, "title");
|
|
32803
33429
|
return title ? truncateLiveActivityTitle(title, 24) : null;
|
|
32804
33430
|
}
|
|
32805
33431
|
function liveActivityTitleFromManifest(manifest) {
|
|
@@ -32839,7 +33465,7 @@ function isConversationTitleUpdateEvent(event) {
|
|
|
32839
33465
|
if (event.type.toLowerCase() !== "conversation.updated") {
|
|
32840
33466
|
return false;
|
|
32841
33467
|
}
|
|
32842
|
-
return Boolean(
|
|
33468
|
+
return Boolean(readString22(event.payload, "title")?.trim());
|
|
32843
33469
|
}
|
|
32844
33470
|
function resolveLiveActivityTarget(input) {
|
|
32845
33471
|
if (input.run?.kind === "compression") {
|
|
@@ -32861,7 +33487,7 @@ function liveActivityPhaseForEvent(event, run, contextOperation) {
|
|
|
32861
33487
|
}
|
|
32862
33488
|
if (type === "conversation.goal.updated") {
|
|
32863
33489
|
const goal = readRecord2(event.payload).goal;
|
|
32864
|
-
const status =
|
|
33490
|
+
const status = readString22(goal, "status");
|
|
32865
33491
|
return status === "paused" ? "goal_paused" : "goal_running";
|
|
32866
33492
|
}
|
|
32867
33493
|
if (isConversationTitleUpdateEvent(event)) {
|
|
@@ -32994,7 +33620,7 @@ function readContextCompressionOperation(payload) {
|
|
|
32994
33620
|
if (!operation || typeof operation !== "object") {
|
|
32995
33621
|
return null;
|
|
32996
33622
|
}
|
|
32997
|
-
const operationId =
|
|
33623
|
+
const operationId = readString22(operation, "operation_id");
|
|
32998
33624
|
if (!operationId) {
|
|
32999
33625
|
return null;
|
|
33000
33626
|
}
|
|
@@ -33002,19 +33628,19 @@ function readContextCompressionOperation(payload) {
|
|
|
33002
33628
|
return {
|
|
33003
33629
|
operation_id: operationId,
|
|
33004
33630
|
generation: typeof record.generation === "number" ? record.generation : 0,
|
|
33005
|
-
status:
|
|
33006
|
-
started_at:
|
|
33007
|
-
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"
|
|
33008
33634
|
};
|
|
33009
33635
|
}
|
|
33010
33636
|
function readToolName3(payload) {
|
|
33011
33637
|
const record = readRecord2(payload);
|
|
33012
|
-
return
|
|
33638
|
+
return readString22(record, "tool_name") ?? readString22(record, "tool") ?? readString22(record, "name") ?? readString22(readRecord2(record.tool), "name");
|
|
33013
33639
|
}
|
|
33014
33640
|
function readRecord2(value) {
|
|
33015
33641
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
|
|
33016
33642
|
}
|
|
33017
|
-
function
|
|
33643
|
+
function readString22(value, key) {
|
|
33018
33644
|
const raw = readRecord2(value)[key];
|
|
33019
33645
|
return typeof raw === "string" && raw.trim() ? raw.trim() : null;
|
|
33020
33646
|
}
|
|
@@ -33534,7 +34160,7 @@ async function readRawBody(request, maxBytes) {
|
|
|
33534
34160
|
}
|
|
33535
34161
|
return Buffer.concat(chunks);
|
|
33536
34162
|
}
|
|
33537
|
-
function
|
|
34163
|
+
function readString23(body, key) {
|
|
33538
34164
|
const value = body[key];
|
|
33539
34165
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
33540
34166
|
}
|
|
@@ -33569,7 +34195,7 @@ function readSupportedLanguage(value) {
|
|
|
33569
34195
|
return null;
|
|
33570
34196
|
}
|
|
33571
34197
|
function readOptionalProfileName(body) {
|
|
33572
|
-
return
|
|
34198
|
+
return readString23(body, "profile") ?? readString23(body, "profile_name") ?? readString23(body, "profileName") ?? void 0;
|
|
33573
34199
|
}
|
|
33574
34200
|
function readStringArray(body, ...keys) {
|
|
33575
34201
|
for (const key of keys) {
|
|
@@ -33989,7 +34615,7 @@ function registerConversationRoutes(router, options) {
|
|
|
33989
34615
|
const language = readPreferredLanguage(ctx);
|
|
33990
34616
|
const body = await readJsonBody(ctx.req);
|
|
33991
34617
|
ctx.status = 201;
|
|
33992
|
-
const rawReasoningEffort =
|
|
34618
|
+
const rawReasoningEffort = readString23(body, "reasoning_effort") ?? readString23(body, "reasoningEffort") ?? readString23(body, "default_reasoning_effort") ?? readString23(body, "defaultReasoningEffort");
|
|
33993
34619
|
const reasoningEffort = normalizeReasoningEffort(rawReasoningEffort);
|
|
33994
34620
|
if (rawReasoningEffort && !reasoningEffort) {
|
|
33995
34621
|
throw new LinkHttpError(
|
|
@@ -34002,15 +34628,15 @@ function registerConversationRoutes(router, options) {
|
|
|
34002
34628
|
ok: true,
|
|
34003
34629
|
conversation: localizeConversationSummary(
|
|
34004
34630
|
await conversations.createConversation({
|
|
34005
|
-
title:
|
|
34631
|
+
title: readString23(body, "title") ?? void 0,
|
|
34006
34632
|
profileName: readOptionalProfileName(body),
|
|
34007
34633
|
accountId: auth.accountId,
|
|
34008
34634
|
appInstanceId: auth.appInstanceId,
|
|
34009
34635
|
workspaceId: readConversationWorkspaceId(body),
|
|
34010
|
-
modelId:
|
|
34011
|
-
modelProvider:
|
|
34012
|
-
modelBaseUrl:
|
|
34013
|
-
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,
|
|
34014
34640
|
reasoningEffort
|
|
34015
34641
|
}),
|
|
34016
34642
|
language
|
|
@@ -34088,9 +34714,9 @@ function registerConversationRoutes(router, options) {
|
|
|
34088
34714
|
const auth = await authenticateRequest(ctx, paths);
|
|
34089
34715
|
const language = readPreferredLanguage(ctx);
|
|
34090
34716
|
const body = await readJsonBody(ctx.req);
|
|
34091
|
-
const content =
|
|
34717
|
+
const content = readString23(body, "content") ?? readString23(body, "text") ?? readString23(body, "input") ?? "";
|
|
34092
34718
|
const attachments = readMessageAttachments(body.attachments ?? body.blobs);
|
|
34093
|
-
const mode =
|
|
34719
|
+
const mode = readString23(body, "mode") ?? readString23(body, "send_mode");
|
|
34094
34720
|
if (mode && mode !== "message" && mode !== "goal") {
|
|
34095
34721
|
throw new LinkHttpError(
|
|
34096
34722
|
400,
|
|
@@ -34113,7 +34739,7 @@ function registerConversationRoutes(router, options) {
|
|
|
34113
34739
|
conversationId: ctx.params.conversationId,
|
|
34114
34740
|
content,
|
|
34115
34741
|
attachments,
|
|
34116
|
-
clientMessageId:
|
|
34742
|
+
clientMessageId: readString23(body, "client_message_id") ?? readString23(body, "clientMessageId") ?? void 0,
|
|
34117
34743
|
idempotencyKey: readHeader(ctx, "idempotency-key") ?? void 0,
|
|
34118
34744
|
profileName: readOptionalProfileName(body),
|
|
34119
34745
|
mode: mode === "goal" ? "goal" : "message",
|
|
@@ -34180,8 +34806,8 @@ function registerConversationRoutes(router, options) {
|
|
|
34180
34806
|
...localizeConversationResult(
|
|
34181
34807
|
await conversations.startContextCompression({
|
|
34182
34808
|
conversationId: ctx.params.conversationId,
|
|
34183
|
-
focus:
|
|
34184
|
-
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,
|
|
34185
34811
|
createUserMessage: false,
|
|
34186
34812
|
accountId: auth.accountId,
|
|
34187
34813
|
appInstanceId: auth.appInstanceId,
|
|
@@ -34195,11 +34821,11 @@ function registerConversationRoutes(router, options) {
|
|
|
34195
34821
|
router.patch("/api/v1/conversations/:conversationId/model", async (ctx) => {
|
|
34196
34822
|
await authenticateRequest(ctx, paths);
|
|
34197
34823
|
const body = await readJsonBody(ctx.req);
|
|
34198
|
-
const modelId =
|
|
34199
|
-
const modelProvider =
|
|
34200
|
-
const modelBaseUrl =
|
|
34201
|
-
const modelApiMode =
|
|
34202
|
-
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");
|
|
34203
34829
|
const reasoningEffort = normalizeReasoningEffort(rawReasoningEffort);
|
|
34204
34830
|
if (rawReasoningEffort && !reasoningEffort) {
|
|
34205
34831
|
throw new LinkHttpError(
|
|
@@ -34249,7 +34875,7 @@ function registerConversationRoutes(router, options) {
|
|
|
34249
34875
|
await authenticateRequest(ctx, paths);
|
|
34250
34876
|
const language = readPreferredLanguage(ctx);
|
|
34251
34877
|
const body = await readJsonBody(ctx.req);
|
|
34252
|
-
const title =
|
|
34878
|
+
const title = readString23(body, "title") ?? readString23(body, "name") ?? readString23(body, "display_name");
|
|
34253
34879
|
if (!title) {
|
|
34254
34880
|
throw new LinkHttpError(400, "title_required", "title is required");
|
|
34255
34881
|
}
|
|
@@ -34441,7 +35067,7 @@ function registerConversationRoutes(router, options) {
|
|
|
34441
35067
|
async (ctx) => {
|
|
34442
35068
|
await authenticateRequest(ctx, paths);
|
|
34443
35069
|
const body = await readJsonBody(ctx.req);
|
|
34444
|
-
const scope =
|
|
35070
|
+
const scope = readString23(body, "scope") ?? "always";
|
|
34445
35071
|
ctx.body = {
|
|
34446
35072
|
ok: true,
|
|
34447
35073
|
...await conversations.resolveApproval({
|
|
@@ -34491,7 +35117,7 @@ function registerConversationRoutes(router, options) {
|
|
|
34491
35117
|
conversationId: ctx.params.conversationId,
|
|
34492
35118
|
requestId: ctx.params.requestId,
|
|
34493
35119
|
kind,
|
|
34494
|
-
answer:
|
|
35120
|
+
answer: readString23(body, "answer") ?? void 0,
|
|
34495
35121
|
password: readRawString(body, "password"),
|
|
34496
35122
|
value: readRawString(body, "value")
|
|
34497
35123
|
})
|
|
@@ -34660,10 +35286,10 @@ function readConversationWorkspaceFilter(query) {
|
|
|
34660
35286
|
}
|
|
34661
35287
|
function readConversationWorkspaceId(body) {
|
|
34662
35288
|
if (Object.prototype.hasOwnProperty.call(body, "workspace_id") || Object.prototype.hasOwnProperty.call(body, "workspaceId")) {
|
|
34663
|
-
return
|
|
35289
|
+
return readString23(body, "workspace_id") ?? readString23(body, "workspaceId");
|
|
34664
35290
|
}
|
|
34665
35291
|
if (Object.prototype.hasOwnProperty.call(body, "workspace")) {
|
|
34666
|
-
return
|
|
35292
|
+
return readString23(body, "workspace");
|
|
34667
35293
|
}
|
|
34668
35294
|
return void 0;
|
|
34669
35295
|
}
|
|
@@ -34757,7 +35383,7 @@ function resolveConversationEventCursor(input) {
|
|
|
34757
35383
|
return Math.max(queryAfter, headerAfter);
|
|
34758
35384
|
}
|
|
34759
35385
|
function readConversationClearPlanTargetStatus(body) {
|
|
34760
|
-
const raw =
|
|
35386
|
+
const raw = readString23(body, "target_status") ?? readString23(body, "targetStatus") ?? "active";
|
|
34761
35387
|
if (raw === "active" || raw === "archived") {
|
|
34762
35388
|
return raw;
|
|
34763
35389
|
}
|
|
@@ -34768,7 +35394,7 @@ function readConversationClearPlanTargetStatus(body) {
|
|
|
34768
35394
|
);
|
|
34769
35395
|
}
|
|
34770
35396
|
function readInputRequestKind2(body) {
|
|
34771
|
-
const kind =
|
|
35397
|
+
const kind = readString23(body, "kind") ?? readString23(body, "type");
|
|
34772
35398
|
if (kind === "clarify" || kind === "sudo" || kind === "secret") {
|
|
34773
35399
|
return kind;
|
|
34774
35400
|
}
|
|
@@ -34898,11 +35524,11 @@ function isSseRequestContext(ctx) {
|
|
|
34898
35524
|
}
|
|
34899
35525
|
return isSseRequestPath(ctx.path) || isActiveSseSocket(ctx.req.socket);
|
|
34900
35526
|
}
|
|
34901
|
-
function isSseRequestPath(
|
|
34902
|
-
if (!
|
|
35527
|
+
function isSseRequestPath(path39) {
|
|
35528
|
+
if (!path39) {
|
|
34903
35529
|
return false;
|
|
34904
35530
|
}
|
|
34905
|
-
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);
|
|
34906
35532
|
}
|
|
34907
35533
|
function isExpectedClientDisconnectError2(error, options = {}) {
|
|
34908
35534
|
if (!(error instanceof Error)) {
|
|
@@ -35166,7 +35792,7 @@ function toHermesCronJobInput(input) {
|
|
|
35166
35792
|
};
|
|
35167
35793
|
}
|
|
35168
35794
|
async function bindAndDecorateCronJobForHermesLink(input) {
|
|
35169
|
-
const jobId =
|
|
35795
|
+
const jobId = readString23(input.job, "id") ?? readString23(input.job, "job_id");
|
|
35170
35796
|
if (!jobId) {
|
|
35171
35797
|
return input.job;
|
|
35172
35798
|
}
|
|
@@ -35185,9 +35811,9 @@ async function bindAndDecorateCronJobForHermesLink(input) {
|
|
|
35185
35811
|
}
|
|
35186
35812
|
function readCronJobCreateInput(body) {
|
|
35187
35813
|
const input = {};
|
|
35188
|
-
const name =
|
|
35189
|
-
const prompt =
|
|
35190
|
-
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");
|
|
35191
35817
|
if (!name) {
|
|
35192
35818
|
throw new LinkHttpError(400, "cron_job_name_required", "name is required");
|
|
35193
35819
|
}
|
|
@@ -35208,7 +35834,7 @@ function readCronJobCreateInput(body) {
|
|
|
35208
35834
|
input.name = name;
|
|
35209
35835
|
input.prompt = prompt;
|
|
35210
35836
|
input.schedule = schedule;
|
|
35211
|
-
input.deliver =
|
|
35837
|
+
input.deliver = readString23(body, "deliver") ?? HERMES_LINK_CRON_DELIVER;
|
|
35212
35838
|
const skills = readOptionalCronSkills(body);
|
|
35213
35839
|
if (skills) {
|
|
35214
35840
|
input.skills = skills;
|
|
@@ -35341,7 +35967,7 @@ import { createHash as createHash11 } from "crypto";
|
|
|
35341
35967
|
// src/model-catalog/catalog.ts
|
|
35342
35968
|
import { randomInt } from "crypto";
|
|
35343
35969
|
import { mkdir as mkdir12 } from "fs/promises";
|
|
35344
|
-
import
|
|
35970
|
+
import path29 from "path";
|
|
35345
35971
|
import { fileURLToPath } from "url";
|
|
35346
35972
|
var MODEL_CATALOG_CACHE_VERSION = 1;
|
|
35347
35973
|
var MODEL_CATALOG_FETCH_TIMEOUT_MS = 1e4;
|
|
@@ -35545,7 +36171,7 @@ async function readCachedCatalogFile(paths) {
|
|
|
35545
36171
|
return cached;
|
|
35546
36172
|
}
|
|
35547
36173
|
async function writeCachedCatalog(paths, value) {
|
|
35548
|
-
await mkdir12(
|
|
36174
|
+
await mkdir12(path29.dirname(modelCatalogCachePath(paths)), {
|
|
35549
36175
|
recursive: true,
|
|
35550
36176
|
mode: 448
|
|
35551
36177
|
});
|
|
@@ -35561,7 +36187,7 @@ async function readFallbackCatalog() {
|
|
|
35561
36187
|
throw new Error("model capability fallback catalog was not found");
|
|
35562
36188
|
}
|
|
35563
36189
|
function modelCatalogCachePath(paths) {
|
|
35564
|
-
return
|
|
36190
|
+
return path29.join(paths.homeDir, "model-capabilities", "catalog-cache.json");
|
|
35565
36191
|
}
|
|
35566
36192
|
function normalizeModelCapabilityCatalog(value) {
|
|
35567
36193
|
if (!value || typeof value !== "object") {
|
|
@@ -35572,7 +36198,7 @@ function normalizeModelCapabilityCatalog(value) {
|
|
|
35572
36198
|
const models = rawModels.map(normalizeModelCapabilityEntry).filter((entry) => entry !== null);
|
|
35573
36199
|
return {
|
|
35574
36200
|
schemaVersion: readPositiveInteger3(record.schemaVersion) ?? 1,
|
|
35575
|
-
updatedAt:
|
|
36201
|
+
updatedAt: readString24(record.updatedAt),
|
|
35576
36202
|
models
|
|
35577
36203
|
};
|
|
35578
36204
|
}
|
|
@@ -35581,7 +36207,7 @@ function normalizeModelCapabilityEntry(value) {
|
|
|
35581
36207
|
return null;
|
|
35582
36208
|
}
|
|
35583
36209
|
const record = value;
|
|
35584
|
-
const canonicalId =
|
|
36210
|
+
const canonicalId = readString24(record.canonicalId) ?? readString24(record.canonical_id) ?? readString24(record.id);
|
|
35585
36211
|
if (!canonicalId) {
|
|
35586
36212
|
return null;
|
|
35587
36213
|
}
|
|
@@ -35609,12 +36235,12 @@ function normalizeModelCapabilityEntry(value) {
|
|
|
35609
36235
|
outputModalities: readStringArray2(
|
|
35610
36236
|
record.outputModalities ?? record.output_modalities
|
|
35611
36237
|
),
|
|
35612
|
-
source:
|
|
35613
|
-
updatedAt:
|
|
35614
|
-
notes:
|
|
36238
|
+
source: readString24(record.source),
|
|
36239
|
+
updatedAt: readString24(record.updatedAt ?? record.updated_at),
|
|
36240
|
+
notes: readString24(record.notes)
|
|
35615
36241
|
};
|
|
35616
36242
|
}
|
|
35617
|
-
function
|
|
36243
|
+
function readString24(value) {
|
|
35618
36244
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
35619
36245
|
}
|
|
35620
36246
|
function readStringArray2(value) {
|
|
@@ -35624,7 +36250,7 @@ function readStringArray2(value) {
|
|
|
35624
36250
|
const seen = /* @__PURE__ */ new Set();
|
|
35625
36251
|
const values = [];
|
|
35626
36252
|
for (const item of value) {
|
|
35627
|
-
const text =
|
|
36253
|
+
const text = readString24(item);
|
|
35628
36254
|
if (!text || seen.has(text)) {
|
|
35629
36255
|
continue;
|
|
35630
36256
|
}
|
|
@@ -35641,7 +36267,7 @@ function readPositiveInteger3(value) {
|
|
|
35641
36267
|
return Math.floor(number);
|
|
35642
36268
|
}
|
|
35643
36269
|
function readReasoningSupportPolicy(value) {
|
|
35644
|
-
const normalized =
|
|
36270
|
+
const normalized = readString24(value)?.toLowerCase();
|
|
35645
36271
|
if (!normalized || normalized === "unknown" || normalized === "auto") {
|
|
35646
36272
|
return null;
|
|
35647
36273
|
}
|
|
@@ -35672,7 +36298,7 @@ function readNullableBoolean(value) {
|
|
|
35672
36298
|
if (typeof value === "boolean") {
|
|
35673
36299
|
return value;
|
|
35674
36300
|
}
|
|
35675
|
-
const normalized =
|
|
36301
|
+
const normalized = readString24(value)?.toLowerCase();
|
|
35676
36302
|
if (!normalized) {
|
|
35677
36303
|
return null;
|
|
35678
36304
|
}
|
|
@@ -36821,8 +37447,8 @@ function normalizeUrlForIdentity(value) {
|
|
|
36821
37447
|
return value.trim().replace(/\/+$/u, "").toLowerCase();
|
|
36822
37448
|
}
|
|
36823
37449
|
function readModelProviderConfigInput(body) {
|
|
36824
|
-
const providerName =
|
|
36825
|
-
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");
|
|
36826
37452
|
if (!providerName || !baseUrl) {
|
|
36827
37453
|
throw new LinkHttpError(
|
|
36828
37454
|
400,
|
|
@@ -36833,15 +37459,15 @@ function readModelProviderConfigInput(body) {
|
|
|
36833
37459
|
return {
|
|
36834
37460
|
providerName,
|
|
36835
37461
|
baseUrl,
|
|
36836
|
-
apiMode:
|
|
36837
|
-
keyEnv:
|
|
36838
|
-
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
|
|
36839
37465
|
};
|
|
36840
37466
|
}
|
|
36841
37467
|
function readModelConfigInput(body) {
|
|
36842
|
-
const id =
|
|
36843
|
-
const provider =
|
|
36844
|
-
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");
|
|
36845
37471
|
if (!id || !provider || !baseUrl) {
|
|
36846
37472
|
throw new LinkHttpError(
|
|
36847
37473
|
400,
|
|
@@ -36851,22 +37477,22 @@ function readModelConfigInput(body) {
|
|
|
36851
37477
|
}
|
|
36852
37478
|
return {
|
|
36853
37479
|
id,
|
|
36854
|
-
originalModelId:
|
|
36855
|
-
originalProvider:
|
|
36856
|
-
originalBaseUrl:
|
|
36857
|
-
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,
|
|
36858
37484
|
provider,
|
|
36859
|
-
providerName:
|
|
37485
|
+
providerName: readString23(body, "provider_name") ?? readString23(body, "providerName") ?? void 0,
|
|
36860
37486
|
baseUrl,
|
|
36861
|
-
apiKey:
|
|
36862
|
-
apiMode:
|
|
37487
|
+
apiKey: readString23(body, "api_key") ?? readString23(body, "apiKey") ?? void 0,
|
|
37488
|
+
apiMode: readString23(body, "api_mode") ?? readString23(body, "apiMode") ?? void 0,
|
|
36863
37489
|
contextLength: readPositiveInteger2(
|
|
36864
37490
|
body.context_length ?? body.contextLength
|
|
36865
37491
|
),
|
|
36866
|
-
keyEnv:
|
|
37492
|
+
keyEnv: readString23(body, "key_env") ?? readString23(body, "keyEnv") ?? void 0,
|
|
36867
37493
|
setDefault: readBoolean4(body.set_default ?? body.setDefault),
|
|
36868
|
-
reasoningEffort:
|
|
36869
|
-
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,
|
|
36870
37496
|
supportsVision: readNullableBoolean2(
|
|
36871
37497
|
body.supports_vision ?? body.supportsVision
|
|
36872
37498
|
)
|
|
@@ -36874,28 +37500,28 @@ function readModelConfigInput(body) {
|
|
|
36874
37500
|
}
|
|
36875
37501
|
function readModelDefaultsInput(body) {
|
|
36876
37502
|
return {
|
|
36877
|
-
taskModelId:
|
|
36878
|
-
taskModelProvider:
|
|
36879
|
-
taskModelBaseUrl:
|
|
36880
|
-
taskModelApiMode:
|
|
36881
|
-
compressionModelId:
|
|
36882
|
-
compressionModelProvider:
|
|
36883
|
-
compressionModelBaseUrl:
|
|
36884
|
-
compressionModelApiMode:
|
|
36885
|
-
reasoningEffort:
|
|
36886
|
-
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
|
|
36887
37513
|
};
|
|
36888
37514
|
}
|
|
36889
37515
|
function readModelDeleteInput(body) {
|
|
36890
|
-
const id =
|
|
37516
|
+
const id = readString23(body, "model_id") ?? readString23(body, "modelId");
|
|
36891
37517
|
if (!id) {
|
|
36892
37518
|
throw new LinkHttpError(400, "model_id_required", "model_id is required");
|
|
36893
37519
|
}
|
|
36894
37520
|
return {
|
|
36895
37521
|
id,
|
|
36896
|
-
provider:
|
|
36897
|
-
baseUrl:
|
|
36898
|
-
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
|
|
36899
37525
|
};
|
|
36900
37526
|
}
|
|
36901
37527
|
function readNullableBoolean2(value) {
|
|
@@ -36918,8 +37544,8 @@ function readNullableBoolean2(value) {
|
|
|
36918
37544
|
return void 0;
|
|
36919
37545
|
}
|
|
36920
37546
|
function readModelConfigImportInput(body) {
|
|
36921
|
-
const sourceProfileName =
|
|
36922
|
-
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");
|
|
36923
37549
|
if (!sourceProfileName || !modelId) {
|
|
36924
37550
|
throw new LinkHttpError(
|
|
36925
37551
|
400,
|
|
@@ -36930,9 +37556,9 @@ function readModelConfigImportInput(body) {
|
|
|
36930
37556
|
return {
|
|
36931
37557
|
sourceProfileName,
|
|
36932
37558
|
modelId,
|
|
36933
|
-
provider:
|
|
36934
|
-
baseUrl:
|
|
36935
|
-
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,
|
|
36936
37562
|
setDefault: readBoolean4(body.set_default ?? body.setDefault)
|
|
36937
37563
|
};
|
|
36938
37564
|
}
|
|
@@ -37039,19 +37665,19 @@ function errorMessage3(error) {
|
|
|
37039
37665
|
}
|
|
37040
37666
|
|
|
37041
37667
|
// src/hermes/profile-identity.ts
|
|
37042
|
-
import { readFile as
|
|
37043
|
-
import
|
|
37668
|
+
import { readFile as readFile17, stat as stat19 } from "fs/promises";
|
|
37669
|
+
import path30 from "path";
|
|
37044
37670
|
var MAX_SOUL_MD_LENGTH = 2e4;
|
|
37045
37671
|
async function readHermesProfileIdentity(profileName, paths) {
|
|
37046
37672
|
await assertProfileExists3(profileName, paths);
|
|
37047
37673
|
const soulPath = resolveSoulPath(profileName);
|
|
37048
|
-
const content = await
|
|
37674
|
+
const content = await readFile17(soulPath, "utf8").catch((error) => {
|
|
37049
37675
|
if (isNodeError19(error, "ENOENT")) {
|
|
37050
37676
|
return null;
|
|
37051
37677
|
}
|
|
37052
37678
|
throw error;
|
|
37053
37679
|
});
|
|
37054
|
-
const fileStat = content === null ? null : await
|
|
37680
|
+
const fileStat = content === null ? null : await stat19(soulPath).catch((error) => {
|
|
37055
37681
|
if (isNodeError19(error, "ENOENT")) {
|
|
37056
37682
|
return null;
|
|
37057
37683
|
}
|
|
@@ -37097,7 +37723,7 @@ async function assertProfileExists3(profileName, paths) {
|
|
|
37097
37723
|
}
|
|
37098
37724
|
}
|
|
37099
37725
|
function resolveSoulPath(profileName) {
|
|
37100
|
-
return
|
|
37726
|
+
return path30.join(resolveHermesProfileDir(profileName), "SOUL.md");
|
|
37101
37727
|
}
|
|
37102
37728
|
function isNodeError19(error, code) {
|
|
37103
37729
|
return error instanceof Error && "code" in error && error.code === code;
|
|
@@ -37109,17 +37735,17 @@ import { EventEmitter as EventEmitter2 } from "events";
|
|
|
37109
37735
|
import {
|
|
37110
37736
|
cp,
|
|
37111
37737
|
mkdir as mkdir13,
|
|
37112
|
-
readFile as
|
|
37738
|
+
readFile as readFile19,
|
|
37113
37739
|
rm as rm7,
|
|
37114
|
-
stat as
|
|
37740
|
+
stat as stat21
|
|
37115
37741
|
} from "fs/promises";
|
|
37116
|
-
import
|
|
37742
|
+
import path32 from "path";
|
|
37117
37743
|
import YAML5 from "yaml";
|
|
37118
37744
|
|
|
37119
37745
|
// src/hermes/link-skill.ts
|
|
37120
|
-
import { readFile as
|
|
37746
|
+
import { readFile as readFile18, stat as stat20 } from "fs/promises";
|
|
37121
37747
|
import os7 from "os";
|
|
37122
|
-
import
|
|
37748
|
+
import path31 from "path";
|
|
37123
37749
|
import YAML4 from "yaml";
|
|
37124
37750
|
var HERMES_LINK_SKILL_ROOT_DIR = "hermes-skills";
|
|
37125
37751
|
var HERMES_LINK_SKILL_DIR = "hermes-link";
|
|
@@ -37216,7 +37842,7 @@ Do not modify Hermes profiles, delete user data, edit config files, or kill proc
|
|
|
37216
37842
|
async function ensureHermesLinkSkillInstalledForProfiles(options = {}) {
|
|
37217
37843
|
const paths = options.paths ?? resolveRuntimePaths();
|
|
37218
37844
|
const externalDir = resolveHermesLinkSkillExternalDir(paths);
|
|
37219
|
-
const skillPath =
|
|
37845
|
+
const skillPath = path31.join(
|
|
37220
37846
|
externalDir,
|
|
37221
37847
|
HERMES_LINK_SKILL_DIR,
|
|
37222
37848
|
HERMES_LINK_SKILL_FILE
|
|
@@ -37298,10 +37924,10 @@ function withDefaultProfilePlaceholder2(profiles) {
|
|
|
37298
37924
|
];
|
|
37299
37925
|
}
|
|
37300
37926
|
function resolveHermesLinkSkillExternalDir(paths = resolveRuntimePaths()) {
|
|
37301
|
-
return
|
|
37927
|
+
return path31.join(paths.homeDir, HERMES_LINK_SKILL_ROOT_DIR);
|
|
37302
37928
|
}
|
|
37303
37929
|
async function writeHermesLinkSkill(skillPath) {
|
|
37304
|
-
const existing = await
|
|
37930
|
+
const existing = await readFile18(skillPath, "utf8").catch((error) => {
|
|
37305
37931
|
if (isNodeError20(error, "ENOENT")) {
|
|
37306
37932
|
return null;
|
|
37307
37933
|
}
|
|
@@ -37359,7 +37985,7 @@ async function ensureProfileUsesExternalSkillDir(profile, externalDir) {
|
|
|
37359
37985
|
};
|
|
37360
37986
|
}
|
|
37361
37987
|
async function readHermesConfigDocument3(configPath) {
|
|
37362
|
-
const existingRaw = await
|
|
37988
|
+
const existingRaw = await readFile18(configPath, "utf8").catch(
|
|
37363
37989
|
(error) => {
|
|
37364
37990
|
if (isNodeError20(error, "ENOENT")) {
|
|
37365
37991
|
return null;
|
|
@@ -37393,11 +38019,11 @@ function appendExternalDir(current, externalDir, hermesHome) {
|
|
|
37393
38019
|
const seen = new Set(
|
|
37394
38020
|
entries.map((entry) => resolveExternalDirEntry(entry, hermesHome))
|
|
37395
38021
|
);
|
|
37396
|
-
const normalizedExternalDir =
|
|
38022
|
+
const normalizedExternalDir = path31.resolve(externalDir);
|
|
37397
38023
|
return seen.has(normalizedExternalDir) ? entries : [...entries, normalizedExternalDir];
|
|
37398
38024
|
}
|
|
37399
38025
|
function externalDirsInclude(current, externalDir, hermesHome) {
|
|
37400
|
-
const normalizedExternalDir =
|
|
38026
|
+
const normalizedExternalDir = path31.resolve(externalDir);
|
|
37401
38027
|
return readExternalDirEntries(current).some(
|
|
37402
38028
|
(entry) => resolveExternalDirEntry(entry, hermesHome) === normalizedExternalDir
|
|
37403
38029
|
);
|
|
@@ -37408,14 +38034,14 @@ function readExternalDirEntries(value) {
|
|
|
37408
38034
|
}
|
|
37409
38035
|
function resolveExternalDirEntry(entry, hermesHome) {
|
|
37410
38036
|
const expanded = expandHome(expandEnvVars(entry));
|
|
37411
|
-
return
|
|
38037
|
+
return path31.resolve(path31.isAbsolute(expanded) ? expanded : path31.join(hermesHome, expanded));
|
|
37412
38038
|
}
|
|
37413
38039
|
function expandHome(value) {
|
|
37414
38040
|
if (value === "~") {
|
|
37415
38041
|
return os7.homedir();
|
|
37416
38042
|
}
|
|
37417
|
-
if (value.startsWith(`~${
|
|
37418
|
-
return
|
|
38043
|
+
if (value.startsWith(`~${path31.sep}`) || value.startsWith("~/")) {
|
|
38044
|
+
return path31.join(os7.homedir(), value.slice(2));
|
|
37419
38045
|
}
|
|
37420
38046
|
return value;
|
|
37421
38047
|
}
|
|
@@ -37426,7 +38052,7 @@ function expandEnvVars(value) {
|
|
|
37426
38052
|
);
|
|
37427
38053
|
}
|
|
37428
38054
|
async function pathIsDirectory2(filePath) {
|
|
37429
|
-
return
|
|
38055
|
+
return stat20(filePath).then((value) => value.isDirectory()).catch((error) => {
|
|
37430
38056
|
if (isNodeError20(error, "ENOENT")) {
|
|
37431
38057
|
return false;
|
|
37432
38058
|
}
|
|
@@ -37967,8 +38593,8 @@ function collectEnvKeys(value, keys = /* @__PURE__ */ new Set()) {
|
|
|
37967
38593
|
return keys;
|
|
37968
38594
|
}
|
|
37969
38595
|
async function writeEnvValues(profileName, values) {
|
|
37970
|
-
const envPath =
|
|
37971
|
-
const existingRaw = await
|
|
38596
|
+
const envPath = path32.join(resolveHermesProfileDir(profileName), ".env");
|
|
38597
|
+
const existingRaw = await readFile19(envPath, "utf8").catch((error) => {
|
|
37972
38598
|
if (isNodeError21(error, "ENOENT")) {
|
|
37973
38599
|
return "";
|
|
37974
38600
|
}
|
|
@@ -38004,8 +38630,8 @@ async function writeEnvValues(profileName, values) {
|
|
|
38004
38630
|
await atomicWriteFilePreservingMetadata(envPath, nextRaw);
|
|
38005
38631
|
}
|
|
38006
38632
|
async function copySkills(sourceProfile, targetProfile) {
|
|
38007
|
-
const sourceSkills =
|
|
38008
|
-
const targetSkills =
|
|
38633
|
+
const sourceSkills = path32.join(resolveHermesProfileDir(sourceProfile), "skills");
|
|
38634
|
+
const targetSkills = path32.join(resolveHermesProfileDir(targetProfile), "skills");
|
|
38009
38635
|
if (!await pathExists2(sourceSkills)) {
|
|
38010
38636
|
return;
|
|
38011
38637
|
}
|
|
@@ -38028,7 +38654,7 @@ function copyProperty(source, target, key) {
|
|
|
38028
38654
|
}
|
|
38029
38655
|
}
|
|
38030
38656
|
async function readYamlConfig(configPath) {
|
|
38031
|
-
const existingRaw = await
|
|
38657
|
+
const existingRaw = await readFile19(configPath, "utf8").catch(
|
|
38032
38658
|
(error) => {
|
|
38033
38659
|
if (isNodeError21(error, "ENOENT")) {
|
|
38034
38660
|
return null;
|
|
@@ -38091,7 +38717,7 @@ async function writeProfileCreationState(paths, state) {
|
|
|
38091
38717
|
await writeJsonFile(profileCreationStatePath(paths), state);
|
|
38092
38718
|
}
|
|
38093
38719
|
async function readProfileCreationLogLines(paths) {
|
|
38094
|
-
const raw = await
|
|
38720
|
+
const raw = await readFile19(profileCreationLogPath(paths), "utf8").catch(() => "");
|
|
38095
38721
|
if (!raw.trim()) {
|
|
38096
38722
|
return [];
|
|
38097
38723
|
}
|
|
@@ -38100,10 +38726,10 @@ async function readProfileCreationLogLines(paths) {
|
|
|
38100
38726
|
);
|
|
38101
38727
|
}
|
|
38102
38728
|
function profileCreationStatePath(paths) {
|
|
38103
|
-
return
|
|
38729
|
+
return path32.join(paths.runDir, "profile-create-state.json");
|
|
38104
38730
|
}
|
|
38105
38731
|
function profileCreationLogPath(paths) {
|
|
38106
|
-
return
|
|
38732
|
+
return path32.join(paths.logsDir, PROFILE_CREATE_LOG_FILE);
|
|
38107
38733
|
}
|
|
38108
38734
|
async function clearProfileCreationLogFiles(paths) {
|
|
38109
38735
|
const primary = profileCreationLogPath(paths);
|
|
@@ -38116,7 +38742,7 @@ async function clearProfileCreationLogFiles(paths) {
|
|
|
38116
38742
|
]);
|
|
38117
38743
|
}
|
|
38118
38744
|
async function pathExists2(targetPath) {
|
|
38119
|
-
return await
|
|
38745
|
+
return await stat21(targetPath).then(() => true).catch((error) => {
|
|
38120
38746
|
if (isNodeError21(error, "ENOENT")) {
|
|
38121
38747
|
return false;
|
|
38122
38748
|
}
|
|
@@ -38249,16 +38875,16 @@ function readProfilePermissionsInput(body) {
|
|
|
38249
38875
|
const approvals = readOptionalObject(body, "approvals");
|
|
38250
38876
|
if (approvals) {
|
|
38251
38877
|
input.approvals = {
|
|
38252
|
-
mode:
|
|
38878
|
+
mode: readString23(approvals, "mode") ?? readString23(approvals, "approval_mode") ?? readString23(approvals, "approvalMode") ?? void 0,
|
|
38253
38879
|
timeout: readPositiveInteger2(approvals.timeout),
|
|
38254
|
-
cronMode:
|
|
38880
|
+
cronMode: readString23(approvals, "cron_mode") ?? readString23(approvals, "cronMode") ?? void 0
|
|
38255
38881
|
};
|
|
38256
38882
|
}
|
|
38257
38883
|
const terminal = readOptionalObject(body, "terminal");
|
|
38258
38884
|
if (terminal) {
|
|
38259
38885
|
input.terminal = {
|
|
38260
|
-
backend:
|
|
38261
|
-
cwd:
|
|
38886
|
+
backend: readString23(terminal, "backend") ?? void 0,
|
|
38887
|
+
cwd: readString23(terminal, "cwd") ?? void 0,
|
|
38262
38888
|
containerCpu: readPositiveInteger2(
|
|
38263
38889
|
terminal.container_cpu ?? terminal.containerCpu
|
|
38264
38890
|
),
|
|
@@ -38389,10 +39015,10 @@ function toProfileToolConfigHttpError(error) {
|
|
|
38389
39015
|
import {
|
|
38390
39016
|
access as access3,
|
|
38391
39017
|
readdir as readdir10,
|
|
38392
|
-
readFile as
|
|
38393
|
-
stat as
|
|
39018
|
+
readFile as readFile20,
|
|
39019
|
+
stat as stat22
|
|
38394
39020
|
} from "fs/promises";
|
|
38395
|
-
import
|
|
39021
|
+
import path33 from "path";
|
|
38396
39022
|
import YAML6 from "yaml";
|
|
38397
39023
|
var ENTRY_DELIMITER = "\n\xA7\n";
|
|
38398
39024
|
var DEFAULT_MEMORY_LIMIT = 2200;
|
|
@@ -38589,9 +39215,9 @@ async function testHindsightProviderSettings(profileName, patch) {
|
|
|
38589
39215
|
const mode = normalizeHindsightMode(
|
|
38590
39216
|
patch.mode ?? config.mode ?? env.HINDSIGHT_MODE
|
|
38591
39217
|
);
|
|
38592
|
-
const apiUrl =
|
|
38593
|
-
const bankId =
|
|
38594
|
-
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);
|
|
38595
39221
|
const baseUrl = normalizeHttpUrl2(apiUrl);
|
|
38596
39222
|
if (!baseUrl) {
|
|
38597
39223
|
return {
|
|
@@ -38723,7 +39349,7 @@ async function saveProviderSettings(profileName, provider, patch) {
|
|
|
38723
39349
|
});
|
|
38724
39350
|
await patchJsonProviderConfig(
|
|
38725
39351
|
profileName,
|
|
38726
|
-
|
|
39352
|
+
path33.join("hindsight", "config.json"),
|
|
38727
39353
|
{
|
|
38728
39354
|
mode: patch.mode,
|
|
38729
39355
|
api_url: patch.apiUrl,
|
|
@@ -38871,7 +39497,7 @@ function normalizeCustomProviderId(provider) {
|
|
|
38871
39497
|
}
|
|
38872
39498
|
async function patchHermesMemoryProvider(profileName, provider) {
|
|
38873
39499
|
const configPath = resolveHermesConfigPath(profileName);
|
|
38874
|
-
const existingRaw = await
|
|
39500
|
+
const existingRaw = await readFile20(configPath, "utf8").catch(
|
|
38875
39501
|
(error) => {
|
|
38876
39502
|
if (isNodeError22(error, "ENOENT")) {
|
|
38877
39503
|
return null;
|
|
@@ -38895,7 +39521,7 @@ async function patchHermesMemoryProvider(profileName, provider) {
|
|
|
38895
39521
|
}
|
|
38896
39522
|
async function patchHermesMemoryLimits(profileName, patch) {
|
|
38897
39523
|
const configPath = resolveHermesConfigPath(profileName);
|
|
38898
|
-
const existingRaw = await
|
|
39524
|
+
const existingRaw = await readFile20(configPath, "utf8").catch(
|
|
38899
39525
|
(error) => {
|
|
38900
39526
|
if (isNodeError22(error, "ENOENT")) {
|
|
38901
39527
|
return null;
|
|
@@ -38926,12 +39552,12 @@ async function patchHermesMemoryLimits(profileName, patch) {
|
|
|
38926
39552
|
await atomicWriteFilePreservingMetadata(configPath, document.toString());
|
|
38927
39553
|
}
|
|
38928
39554
|
function resolveMemoryDir(profileName) {
|
|
38929
|
-
return
|
|
39555
|
+
return path33.join(resolveHermesProfileDir(profileName), "memories");
|
|
38930
39556
|
}
|
|
38931
39557
|
async function readMemoryStore(profileName, target, limits) {
|
|
38932
39558
|
const filePath = memoryFilePath(profileName, target);
|
|
38933
39559
|
const entries = await readMemoryEntries(filePath);
|
|
38934
|
-
const fileStat = await
|
|
39560
|
+
const fileStat = await stat22(filePath).catch((error) => {
|
|
38935
39561
|
if (isNodeError22(error, "ENOENT")) {
|
|
38936
39562
|
return null;
|
|
38937
39563
|
}
|
|
@@ -38960,7 +39586,7 @@ async function readMemoryStore(profileName, target, limits) {
|
|
|
38960
39586
|
};
|
|
38961
39587
|
}
|
|
38962
39588
|
async function readMemoryEntries(filePath) {
|
|
38963
|
-
const raw = await
|
|
39589
|
+
const raw = await readFile20(filePath, "utf8").catch((error) => {
|
|
38964
39590
|
if (isNodeError22(error, "ENOENT")) {
|
|
38965
39591
|
return "";
|
|
38966
39592
|
}
|
|
@@ -38987,7 +39613,7 @@ async function writeMemoryEntries(profileName, target, entries) {
|
|
|
38987
39613
|
);
|
|
38988
39614
|
}
|
|
38989
39615
|
function memoryFilePath(profileName, target) {
|
|
38990
|
-
return
|
|
39616
|
+
return path33.join(
|
|
38991
39617
|
resolveMemoryDir(profileName),
|
|
38992
39618
|
target === "user" ? "USER.md" : "MEMORY.md"
|
|
38993
39619
|
);
|
|
@@ -39047,7 +39673,7 @@ async function readCustomProviderSetupSummary(profileName) {
|
|
|
39047
39673
|
configurable: true,
|
|
39048
39674
|
configured: true,
|
|
39049
39675
|
configurationIssue: null,
|
|
39050
|
-
providerConfigPath:
|
|
39676
|
+
providerConfigPath: path33.join(
|
|
39051
39677
|
resolveHermesProfileDir(profileName),
|
|
39052
39678
|
"<provider>.json"
|
|
39053
39679
|
),
|
|
@@ -39125,7 +39751,7 @@ async function readProviderConfigurationStatus(profileName, provider) {
|
|
|
39125
39751
|
const config2 = await readJsonObject(
|
|
39126
39752
|
memoryProviderConfigPath(profileName, "honcho") ?? ""
|
|
39127
39753
|
);
|
|
39128
|
-
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 } : {
|
|
39129
39755
|
configured: false,
|
|
39130
39756
|
issue: "Honcho \u9700\u8981\u5148\u586B\u5199 API Key\uFF0C\u6216\u5728 honcho.json \u914D\u7F6E self-hosted baseUrl\u3002"
|
|
39131
39757
|
};
|
|
@@ -39134,7 +39760,7 @@ async function readProviderConfigurationStatus(profileName, provider) {
|
|
|
39134
39760
|
const config2 = await readJsonObject(
|
|
39135
39761
|
memoryProviderConfigPath(profileName, "mem0") ?? ""
|
|
39136
39762
|
);
|
|
39137
|
-
return isConfiguredEnvValue(env.MEM0_API_KEY) || isConfiguredEnvValue(
|
|
39763
|
+
return isConfiguredEnvValue(env.MEM0_API_KEY) || isConfiguredEnvValue(readString25(config2.api_key)) ? { configured: true, issue: null } : {
|
|
39138
39764
|
configured: false,
|
|
39139
39765
|
issue: "Mem0 \u9700\u8981\u5148\u5728\u672C\u9875\u586B\u5199 API Key\uFF0CLink \u4F1A\u5199\u5165\u5F53\u524D Profile \u7684 .env\u3002"
|
|
39140
39766
|
};
|
|
@@ -39176,7 +39802,7 @@ async function readProviderConfigurationStatus(profileName, provider) {
|
|
|
39176
39802
|
memoryProviderConfigPath(profileName, provider) ?? ""
|
|
39177
39803
|
);
|
|
39178
39804
|
const mode = normalizeHindsightMode(config.mode ?? env.HINDSIGHT_MODE);
|
|
39179
|
-
const apiKey =
|
|
39805
|
+
const apiKey = readString25(config.apiKey) ?? readString25(config.api_key) ?? env.HINDSIGHT_API_KEY;
|
|
39180
39806
|
if (mode === "cloud") {
|
|
39181
39807
|
return isConfiguredEnvValue(apiKey) ? { configured: true, issue: null } : {
|
|
39182
39808
|
configured: false,
|
|
@@ -39184,15 +39810,15 @@ async function readProviderConfigurationStatus(profileName, provider) {
|
|
|
39184
39810
|
};
|
|
39185
39811
|
}
|
|
39186
39812
|
if (mode === "local_external") {
|
|
39187
|
-
const apiUrl =
|
|
39813
|
+
const apiUrl = readString25(config.api_url) ?? env.HINDSIGHT_API_URL ?? HINDSIGHT_DEFAULT_LOCAL_URL;
|
|
39188
39814
|
return isConfiguredEnvValue(apiUrl) ? { configured: true, issue: null } : {
|
|
39189
39815
|
configured: false,
|
|
39190
39816
|
issue: "Hindsight local_external \u9700\u8981\u914D\u7F6E\u53EF\u8BBF\u95EE\u7684 API URL\u3002"
|
|
39191
39817
|
};
|
|
39192
39818
|
}
|
|
39193
39819
|
if (mode === "local_embedded") {
|
|
39194
|
-
const llmProvider =
|
|
39195
|
-
const llmModel =
|
|
39820
|
+
const llmProvider = readString25(config.llm_provider) ?? "openai";
|
|
39821
|
+
const llmModel = readString25(config.llm_model);
|
|
39196
39822
|
if (!llmModel) {
|
|
39197
39823
|
return {
|
|
39198
39824
|
configured: false,
|
|
@@ -39200,7 +39826,7 @@ async function readProviderConfigurationStatus(profileName, provider) {
|
|
|
39200
39826
|
};
|
|
39201
39827
|
}
|
|
39202
39828
|
if (llmProvider === "openai_compatible" && !isConfiguredEnvValue(
|
|
39203
|
-
|
|
39829
|
+
readString25(config.llm_base_url) ?? env.HINDSIGHT_API_LLM_BASE_URL
|
|
39204
39830
|
)) {
|
|
39205
39831
|
return {
|
|
39206
39832
|
configured: false,
|
|
@@ -39208,7 +39834,7 @@ async function readProviderConfigurationStatus(profileName, provider) {
|
|
|
39208
39834
|
};
|
|
39209
39835
|
}
|
|
39210
39836
|
if (!["ollama", "lmstudio", "openai_compatible"].includes(llmProvider) && !isConfiguredEnvValue(
|
|
39211
|
-
|
|
39837
|
+
readString25(config.llmApiKey) ?? readString25(config.llm_api_key) ?? env.HINDSIGHT_LLM_API_KEY
|
|
39212
39838
|
)) {
|
|
39213
39839
|
return {
|
|
39214
39840
|
configured: false,
|
|
@@ -39264,8 +39890,8 @@ async function readProviderSettings(profileName, provider) {
|
|
|
39264
39890
|
secretSetting(
|
|
39265
39891
|
"apiKey",
|
|
39266
39892
|
"API Key",
|
|
39267
|
-
env.HONCHO_API_KEY ??
|
|
39268
|
-
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))
|
|
39269
39895
|
),
|
|
39270
39896
|
stringSetting("workspace", "Workspace", config.workspace ?? "hermes"),
|
|
39271
39897
|
stringSetting("peerName", "\u7528\u6237 Peer", config.peerName ?? ""),
|
|
@@ -39307,8 +39933,8 @@ async function readProviderSettings(profileName, provider) {
|
|
|
39307
39933
|
secretSetting(
|
|
39308
39934
|
"apiKey",
|
|
39309
39935
|
"API Key",
|
|
39310
|
-
env.MEM0_API_KEY ??
|
|
39311
|
-
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))
|
|
39312
39938
|
),
|
|
39313
39939
|
stringSetting("userId", "User ID", config.user_id ?? "hermes-user"),
|
|
39314
39940
|
stringSetting("agentId", "Agent ID", config.agent_id ?? "hermes"),
|
|
@@ -39393,8 +40019,8 @@ async function readProviderSettings(profileName, provider) {
|
|
|
39393
40019
|
secretSetting(
|
|
39394
40020
|
"apiKey",
|
|
39395
40021
|
"Hindsight API Key",
|
|
39396
|
-
env.HINDSIGHT_API_KEY ??
|
|
39397
|
-
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))
|
|
39398
40024
|
),
|
|
39399
40025
|
stringSetting(
|
|
39400
40026
|
"bankId",
|
|
@@ -39416,8 +40042,8 @@ async function readProviderSettings(profileName, provider) {
|
|
|
39416
40042
|
secretSetting(
|
|
39417
40043
|
"llmApiKey",
|
|
39418
40044
|
"LLM API Key",
|
|
39419
|
-
env.HINDSIGHT_LLM_API_KEY ??
|
|
39420
|
-
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))
|
|
39421
40047
|
),
|
|
39422
40048
|
booleanSetting("autoRecall", "\u81EA\u52A8\u56DE\u5FC6", config.auto_recall ?? true),
|
|
39423
40049
|
booleanSetting("autoRetain", "\u81EA\u52A8\u6C89\u6DC0", config.auto_retain ?? true),
|
|
@@ -39441,7 +40067,7 @@ async function readProviderSettings(profileName, provider) {
|
|
|
39441
40067
|
stringSetting(
|
|
39442
40068
|
"dbPath",
|
|
39443
40069
|
"SQLite \u6570\u636E\u5E93\u8DEF\u5F84",
|
|
39444
|
-
config.db_path ??
|
|
40070
|
+
config.db_path ?? path33.join(resolveHermesProfileDir(profileName), "memory_store.db")
|
|
39445
40071
|
),
|
|
39446
40072
|
booleanSetting("autoExtract", "\u4F1A\u8BDD\u7ED3\u675F\u81EA\u52A8\u62BD\u53D6", config.auto_extract ?? false),
|
|
39447
40073
|
numberSetting("defaultTrust", "\u9ED8\u8BA4\u4FE1\u4EFB\u5206", config.default_trust ?? 0.5),
|
|
@@ -39477,7 +40103,7 @@ async function readProviderSettings(profileName, provider) {
|
|
|
39477
40103
|
stringSetting(
|
|
39478
40104
|
"workingDirectory",
|
|
39479
40105
|
"\u5DE5\u4F5C\u76EE\u5F55",
|
|
39480
|
-
|
|
40106
|
+
path33.join(resolveHermesProfileDir(profileName), "byterover"),
|
|
39481
40107
|
false
|
|
39482
40108
|
)
|
|
39483
40109
|
];
|
|
@@ -39486,16 +40112,16 @@ async function readProviderSettings(profileName, provider) {
|
|
|
39486
40112
|
}
|
|
39487
40113
|
function memoryProviderConfigPath(profileName, provider) {
|
|
39488
40114
|
if (provider === "honcho") {
|
|
39489
|
-
return
|
|
40115
|
+
return path33.join(resolveHermesProfileDir(profileName), "honcho.json");
|
|
39490
40116
|
}
|
|
39491
40117
|
if (provider === "mem0") {
|
|
39492
|
-
return
|
|
40118
|
+
return path33.join(resolveHermesProfileDir(profileName), "mem0.json");
|
|
39493
40119
|
}
|
|
39494
40120
|
if (provider === "supermemory") {
|
|
39495
|
-
return
|
|
40121
|
+
return path33.join(resolveHermesProfileDir(profileName), "supermemory.json");
|
|
39496
40122
|
}
|
|
39497
40123
|
if (provider === "hindsight") {
|
|
39498
|
-
return
|
|
40124
|
+
return path33.join(
|
|
39499
40125
|
resolveHermesProfileDir(profileName),
|
|
39500
40126
|
"hindsight",
|
|
39501
40127
|
"config.json"
|
|
@@ -39504,19 +40130,19 @@ function memoryProviderConfigPath(profileName, provider) {
|
|
|
39504
40130
|
return null;
|
|
39505
40131
|
}
|
|
39506
40132
|
function customProviderConfigPath(profileName, provider) {
|
|
39507
|
-
return
|
|
40133
|
+
return path33.join(
|
|
39508
40134
|
resolveHermesProfileDir(profileName),
|
|
39509
40135
|
`${normalizeCustomProviderId(provider)}.json`
|
|
39510
40136
|
);
|
|
39511
40137
|
}
|
|
39512
40138
|
function customProviderRegistryPath(profileName) {
|
|
39513
|
-
return
|
|
40139
|
+
return path33.join(
|
|
39514
40140
|
resolveHermesProfileDir(profileName),
|
|
39515
40141
|
CUSTOM_PROVIDER_REGISTRY_FILE
|
|
39516
40142
|
);
|
|
39517
40143
|
}
|
|
39518
40144
|
async function readCustomProviderRegistry(profileName) {
|
|
39519
|
-
const raw = await
|
|
40145
|
+
const raw = await readFile20(customProviderRegistryPath(profileName), "utf8").catch(
|
|
39520
40146
|
(error) => {
|
|
39521
40147
|
if (isNodeError22(error, "ENOENT")) {
|
|
39522
40148
|
return "";
|
|
@@ -39536,11 +40162,11 @@ async function readCustomProviderRegistry(profileName) {
|
|
|
39536
40162
|
return { id: id2, label: id2, description: "\u81EA\u5B9A\u4E49 memory provider\u3002" };
|
|
39537
40163
|
}
|
|
39538
40164
|
const record = toRecord22(item);
|
|
39539
|
-
const id = normalizeCustomProviderId(
|
|
40165
|
+
const id = normalizeCustomProviderId(readString25(record.id) ?? "");
|
|
39540
40166
|
return {
|
|
39541
40167
|
id,
|
|
39542
|
-
label:
|
|
39543
|
-
description:
|
|
40168
|
+
label: readString25(record.label) ?? id,
|
|
40169
|
+
description: readString25(record.description) ?? "\u81EA\u5B9A\u4E49 memory provider\u3002"
|
|
39544
40170
|
};
|
|
39545
40171
|
}).filter((item) => item.id);
|
|
39546
40172
|
} catch {
|
|
@@ -39562,7 +40188,7 @@ async function saveCustomProviderRegistryEntry(profileName, provider) {
|
|
|
39562
40188
|
);
|
|
39563
40189
|
}
|
|
39564
40190
|
async function discoverUserMemoryProviderDescriptors(profileName) {
|
|
39565
|
-
const pluginsDir =
|
|
40191
|
+
const pluginsDir = path33.join(resolveHermesProfileDir(profileName), "plugins");
|
|
39566
40192
|
const entries = await readdir10(pluginsDir, { withFileTypes: true }).catch(
|
|
39567
40193
|
(error) => {
|
|
39568
40194
|
if (isNodeError22(error, "ENOENT")) {
|
|
@@ -39582,21 +40208,21 @@ async function discoverUserMemoryProviderDescriptors(profileName) {
|
|
|
39582
40208
|
} catch {
|
|
39583
40209
|
continue;
|
|
39584
40210
|
}
|
|
39585
|
-
const providerDir =
|
|
40211
|
+
const providerDir = path33.join(pluginsDir, entry.name);
|
|
39586
40212
|
if (!await isMemoryProviderPluginDir(providerDir)) {
|
|
39587
40213
|
continue;
|
|
39588
40214
|
}
|
|
39589
40215
|
const meta = await readPluginMetadata(providerDir);
|
|
39590
40216
|
descriptors.push({
|
|
39591
40217
|
id: providerId,
|
|
39592
|
-
label:
|
|
39593
|
-
description:
|
|
40218
|
+
label: readString25(meta.name) ?? providerId,
|
|
40219
|
+
description: readString25(meta.description) ?? "\u81EA\u5B9A\u4E49 memory provider\u3002"
|
|
39594
40220
|
});
|
|
39595
40221
|
}
|
|
39596
40222
|
return descriptors;
|
|
39597
40223
|
}
|
|
39598
40224
|
async function isUserMemoryProviderInstalled(profileName, provider) {
|
|
39599
|
-
const providerDir =
|
|
40225
|
+
const providerDir = path33.join(
|
|
39600
40226
|
resolveHermesProfileDir(profileName),
|
|
39601
40227
|
"plugins",
|
|
39602
40228
|
normalizeCustomProviderId(provider)
|
|
@@ -39604,7 +40230,7 @@ async function isUserMemoryProviderInstalled(profileName, provider) {
|
|
|
39604
40230
|
return isMemoryProviderPluginDir(providerDir);
|
|
39605
40231
|
}
|
|
39606
40232
|
async function isMemoryProviderPluginDir(providerDir) {
|
|
39607
|
-
const source = await
|
|
40233
|
+
const source = await readFile20(path33.join(providerDir, "__init__.py"), "utf8").catch(
|
|
39608
40234
|
(error) => {
|
|
39609
40235
|
if (isNodeError22(error, "ENOENT")) {
|
|
39610
40236
|
return "";
|
|
@@ -39616,7 +40242,7 @@ async function isMemoryProviderPluginDir(providerDir) {
|
|
|
39616
40242
|
return sample.includes("register_memory_provider") || sample.includes("MemoryProvider");
|
|
39617
40243
|
}
|
|
39618
40244
|
async function readPluginMetadata(providerDir) {
|
|
39619
|
-
const raw = await
|
|
40245
|
+
const raw = await readFile20(path33.join(providerDir, "plugin.yaml"), "utf8").catch(
|
|
39620
40246
|
(error) => {
|
|
39621
40247
|
if (isNodeError22(error, "ENOENT")) {
|
|
39622
40248
|
return "";
|
|
@@ -39628,10 +40254,10 @@ async function readPluginMetadata(providerDir) {
|
|
|
39628
40254
|
}
|
|
39629
40255
|
async function resolveByteRoverCli() {
|
|
39630
40256
|
const candidates = [
|
|
39631
|
-
...(process.env.PATH ?? "").split(
|
|
39632
|
-
|
|
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"),
|
|
39633
40259
|
"/usr/local/bin/brv",
|
|
39634
|
-
|
|
40260
|
+
path33.join(process.env.HOME ?? "", ".npm-global", "bin", "brv")
|
|
39635
40261
|
].filter(Boolean);
|
|
39636
40262
|
for (const candidate of candidates) {
|
|
39637
40263
|
const found = await access3(candidate).then(() => true).catch(() => false);
|
|
@@ -39642,7 +40268,7 @@ async function resolveByteRoverCli() {
|
|
|
39642
40268
|
return null;
|
|
39643
40269
|
}
|
|
39644
40270
|
async function readHolographicProviderConfig(profileName) {
|
|
39645
|
-
const raw = await
|
|
40271
|
+
const raw = await readFile20(resolveHermesConfigPath(profileName), "utf8").catch(
|
|
39646
40272
|
(error) => {
|
|
39647
40273
|
if (isNodeError22(error, "ENOENT")) {
|
|
39648
40274
|
return "";
|
|
@@ -39656,7 +40282,7 @@ async function readHolographicProviderConfig(profileName) {
|
|
|
39656
40282
|
}
|
|
39657
40283
|
async function patchHolographicProviderConfig(profileName, patch) {
|
|
39658
40284
|
const configPath = resolveHermesConfigPath(profileName);
|
|
39659
|
-
const existingRaw = await
|
|
40285
|
+
const existingRaw = await readFile20(configPath, "utf8").catch(
|
|
39660
40286
|
(error) => {
|
|
39661
40287
|
if (isNodeError22(error, "ENOENT")) {
|
|
39662
40288
|
return null;
|
|
@@ -39692,8 +40318,8 @@ async function patchHermesMemoryEnv(profileName, patch) {
|
|
|
39692
40318
|
if (entries.length === 0) {
|
|
39693
40319
|
return;
|
|
39694
40320
|
}
|
|
39695
|
-
const envPath =
|
|
39696
|
-
const existingRaw = await
|
|
40321
|
+
const envPath = path33.join(resolveHermesProfileDir(profileName), ".env");
|
|
40322
|
+
const existingRaw = await readFile20(envPath, "utf8").catch((error) => {
|
|
39697
40323
|
if (isNodeError22(error, "ENOENT")) {
|
|
39698
40324
|
return "";
|
|
39699
40325
|
}
|
|
@@ -39752,7 +40378,7 @@ function isMemoryEnvKeyWritable(key) {
|
|
|
39752
40378
|
].includes(key);
|
|
39753
40379
|
}
|
|
39754
40380
|
function normalizeHindsightMode(value) {
|
|
39755
|
-
const mode =
|
|
40381
|
+
const mode = readString25(value) ?? "cloud";
|
|
39756
40382
|
return mode === "local" ? "local_embedded" : mode;
|
|
39757
40383
|
}
|
|
39758
40384
|
function normalizeHttpUrl2(value) {
|
|
@@ -39821,31 +40447,31 @@ function parseJsonObject2(text) {
|
|
|
39821
40447
|
}
|
|
39822
40448
|
}
|
|
39823
40449
|
function readHindsightError(json) {
|
|
39824
|
-
const detail =
|
|
40450
|
+
const detail = readString25(json.detail) ?? readString25(json.error);
|
|
39825
40451
|
return detail ? `\uFF1A${detail}` : "";
|
|
39826
40452
|
}
|
|
39827
40453
|
function hindsightSemanticIssue(pathName, json) {
|
|
39828
40454
|
if (pathName === "/health") {
|
|
39829
|
-
const status =
|
|
40455
|
+
const status = readString25(json.status);
|
|
39830
40456
|
return status && ["healthy", "ok"].includes(status.toLowerCase()) ? null : `\u5065\u5EB7\u72B6\u6001\u5F02\u5E38\uFF1A${status ?? "unknown"}`;
|
|
39831
40457
|
}
|
|
39832
40458
|
return null;
|
|
39833
40459
|
}
|
|
39834
40460
|
function summarizeHindsightProbe(pathName, json) {
|
|
39835
40461
|
if (pathName === "/health") {
|
|
39836
|
-
const status =
|
|
39837
|
-
const database =
|
|
40462
|
+
const status = readString25(json.status) ?? "ok";
|
|
40463
|
+
const database = readString25(json.database);
|
|
39838
40464
|
return database ? `${status}, database ${database}` : status;
|
|
39839
40465
|
}
|
|
39840
40466
|
if (pathName === "/version") {
|
|
39841
|
-
const version =
|
|
40467
|
+
const version = readString25(json.api_version);
|
|
39842
40468
|
return version ? `API ${version}` : "version endpoint reachable";
|
|
39843
40469
|
}
|
|
39844
|
-
const bankId =
|
|
40470
|
+
const bankId = readString25(json.bank_id);
|
|
39845
40471
|
return bankId ? `bank ${bankId} reachable` : "bank config reachable";
|
|
39846
40472
|
}
|
|
39847
40473
|
async function readActiveMemoryProvider(profileName) {
|
|
39848
|
-
const raw = await
|
|
40474
|
+
const raw = await readFile20(
|
|
39849
40475
|
resolveHermesConfigPath(profileName),
|
|
39850
40476
|
"utf8"
|
|
39851
40477
|
).catch((error) => {
|
|
@@ -39856,14 +40482,14 @@ async function readActiveMemoryProvider(profileName) {
|
|
|
39856
40482
|
});
|
|
39857
40483
|
const config = raw ? toRecord22(YAML6.parse(raw)) : {};
|
|
39858
40484
|
const memory = toRecord22(config.memory);
|
|
39859
|
-
const provider =
|
|
40485
|
+
const provider = readString25(memory.provider);
|
|
39860
40486
|
if (!provider || provider === "built-in" || provider === "builtin" || provider === "built_in") {
|
|
39861
40487
|
return null;
|
|
39862
40488
|
}
|
|
39863
40489
|
return provider;
|
|
39864
40490
|
}
|
|
39865
40491
|
async function patchJsonProviderConfig(profileName, relativePath, patch) {
|
|
39866
|
-
const configPath =
|
|
40492
|
+
const configPath = path33.join(
|
|
39867
40493
|
resolveHermesProfileDir(profileName),
|
|
39868
40494
|
relativePath
|
|
39869
40495
|
);
|
|
@@ -39881,7 +40507,7 @@ async function patchJsonProviderConfig(profileName, relativePath, patch) {
|
|
|
39881
40507
|
);
|
|
39882
40508
|
}
|
|
39883
40509
|
async function readJsonObject(filePath) {
|
|
39884
|
-
const raw = await
|
|
40510
|
+
const raw = await readFile20(filePath, "utf8").catch((error) => {
|
|
39885
40511
|
if (isNodeError22(error, "ENOENT")) {
|
|
39886
40512
|
return "{}";
|
|
39887
40513
|
}
|
|
@@ -39892,7 +40518,7 @@ async function readJsonObject(filePath) {
|
|
|
39892
40518
|
} catch {
|
|
39893
40519
|
throw new HermesMemoryError(
|
|
39894
40520
|
"memory_provider_config_invalid",
|
|
39895
|
-
`${
|
|
40521
|
+
`${path33.basename(filePath)} \u4E0D\u662F\u6709\u6548\u7684 JSON \u914D\u7F6E\u6587\u4EF6\u3002`
|
|
39896
40522
|
);
|
|
39897
40523
|
}
|
|
39898
40524
|
}
|
|
@@ -39913,7 +40539,7 @@ function stringSetting(key, label, value, editable = true) {
|
|
|
39913
40539
|
return {
|
|
39914
40540
|
key,
|
|
39915
40541
|
label,
|
|
39916
|
-
value:
|
|
40542
|
+
value: readString25(value) ?? "",
|
|
39917
40543
|
editable,
|
|
39918
40544
|
kind: "string"
|
|
39919
40545
|
};
|
|
@@ -39925,7 +40551,7 @@ function secretSetting(key, label, value, configured) {
|
|
|
39925
40551
|
value: "",
|
|
39926
40552
|
editable: true,
|
|
39927
40553
|
kind: "secret",
|
|
39928
|
-
configured: configured || isConfiguredEnvValue(
|
|
40554
|
+
configured: configured || isConfiguredEnvValue(readString25(value))
|
|
39929
40555
|
};
|
|
39930
40556
|
}
|
|
39931
40557
|
function textSetting(key, label, value, editable = true) {
|
|
@@ -39938,11 +40564,11 @@ function textSetting(key, label, value, editable = true) {
|
|
|
39938
40564
|
};
|
|
39939
40565
|
}
|
|
39940
40566
|
function selectSetting(key, label, value, options, editable = true) {
|
|
39941
|
-
const stringValue =
|
|
40567
|
+
const stringValue = readString25(value) ?? options[0] ?? null;
|
|
39942
40568
|
return { key, label, value: stringValue, editable, kind: "select", options };
|
|
39943
40569
|
}
|
|
39944
40570
|
async function readMemoryLimits(profileName) {
|
|
39945
|
-
const raw = await
|
|
40571
|
+
const raw = await readFile20(
|
|
39946
40572
|
resolveHermesConfigPath(profileName),
|
|
39947
40573
|
"utf8"
|
|
39948
40574
|
).catch((error) => {
|
|
@@ -40011,7 +40637,7 @@ function hashString(value) {
|
|
|
40011
40637
|
function toRecord22(value) {
|
|
40012
40638
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
|
|
40013
40639
|
}
|
|
40014
|
-
function
|
|
40640
|
+
function readString25(value) {
|
|
40015
40641
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
40016
40642
|
}
|
|
40017
40643
|
function readPositiveInteger4(value) {
|
|
@@ -40170,7 +40796,7 @@ function registerProfileMemoryRoutes(router, options) {
|
|
|
40170
40796
|
);
|
|
40171
40797
|
}
|
|
40172
40798
|
function readMemoryTarget(body) {
|
|
40173
|
-
const raw =
|
|
40799
|
+
const raw = readString23(body, "target");
|
|
40174
40800
|
if (raw === "memory" || raw === "user") {
|
|
40175
40801
|
return raw;
|
|
40176
40802
|
}
|
|
@@ -40181,7 +40807,7 @@ function readMemoryTarget(body) {
|
|
|
40181
40807
|
);
|
|
40182
40808
|
}
|
|
40183
40809
|
function readMemoryResetTarget(body) {
|
|
40184
|
-
const raw =
|
|
40810
|
+
const raw = readString23(body, "target") ?? "all";
|
|
40185
40811
|
if (raw === "all" || raw === "memory" || raw === "user") {
|
|
40186
40812
|
return raw;
|
|
40187
40813
|
}
|
|
@@ -40192,7 +40818,7 @@ function readMemoryResetTarget(body) {
|
|
|
40192
40818
|
);
|
|
40193
40819
|
}
|
|
40194
40820
|
function readRequiredMemoryContent(body) {
|
|
40195
|
-
const content =
|
|
40821
|
+
const content = readString23(body, "content") ?? readString23(body, "text");
|
|
40196
40822
|
if (!content) {
|
|
40197
40823
|
throw new LinkHttpError(
|
|
40198
40824
|
400,
|
|
@@ -40203,7 +40829,7 @@ function readRequiredMemoryContent(body) {
|
|
|
40203
40829
|
return content;
|
|
40204
40830
|
}
|
|
40205
40831
|
function readRequiredMemoryMatch(body) {
|
|
40206
|
-
const oldText =
|
|
40832
|
+
const oldText = readString23(body, "old_text") ?? readString23(body, "oldText") ?? readString23(body, "match");
|
|
40207
40833
|
if (!oldText) {
|
|
40208
40834
|
throw new LinkHttpError(
|
|
40209
40835
|
400,
|
|
@@ -40214,7 +40840,7 @@ function readRequiredMemoryMatch(body) {
|
|
|
40214
40840
|
return oldText;
|
|
40215
40841
|
}
|
|
40216
40842
|
function readRequiredMemoryProvider(body) {
|
|
40217
|
-
const provider =
|
|
40843
|
+
const provider = readString23(body, "provider") ?? readString23(body, "provider_id") ?? readString23(body, "providerId");
|
|
40218
40844
|
if (!provider) {
|
|
40219
40845
|
throw new LinkHttpError(
|
|
40220
40846
|
400,
|
|
@@ -40244,7 +40870,7 @@ function readMemorySettingsPatch(body, options = {}) {
|
|
|
40244
40870
|
input.userCharLimit = userCharLimit;
|
|
40245
40871
|
}
|
|
40246
40872
|
}
|
|
40247
|
-
const mode =
|
|
40873
|
+
const mode = readString23(body, "mode");
|
|
40248
40874
|
if (mode) {
|
|
40249
40875
|
input.mode = mode;
|
|
40250
40876
|
}
|
|
@@ -40260,7 +40886,7 @@ function readMemorySettingsPatch(body, options = {}) {
|
|
|
40260
40886
|
if (bankId !== void 0) {
|
|
40261
40887
|
input.bankId = bankId;
|
|
40262
40888
|
}
|
|
40263
|
-
const llmProvider =
|
|
40889
|
+
const llmProvider = readString23(body, "llm_provider") ?? readString23(body, "llmProvider");
|
|
40264
40890
|
if (llmProvider) {
|
|
40265
40891
|
input.llmProvider = llmProvider;
|
|
40266
40892
|
}
|
|
@@ -40296,11 +40922,11 @@ function readMemorySettingsPatch(body, options = {}) {
|
|
|
40296
40922
|
if (autoRetain !== void 0) {
|
|
40297
40923
|
input.autoRetain = autoRetain;
|
|
40298
40924
|
}
|
|
40299
|
-
const memoryMode =
|
|
40925
|
+
const memoryMode = readString23(body, "memory_mode") ?? readString23(body, "memoryMode");
|
|
40300
40926
|
if (memoryMode) {
|
|
40301
40927
|
input.memoryMode = memoryMode;
|
|
40302
40928
|
}
|
|
40303
|
-
const recallBudget =
|
|
40929
|
+
const recallBudget = readString23(body, "recall_budget") ?? readString23(body, "recallBudget");
|
|
40304
40930
|
if (recallBudget) {
|
|
40305
40931
|
input.recallBudget = recallBudget;
|
|
40306
40932
|
}
|
|
@@ -40316,11 +40942,11 @@ function readMemorySettingsPatch(body, options = {}) {
|
|
|
40316
40942
|
if (profileFrequency !== void 0) {
|
|
40317
40943
|
input.profileFrequency = profileFrequency;
|
|
40318
40944
|
}
|
|
40319
|
-
const captureMode =
|
|
40945
|
+
const captureMode = readString23(body, "capture_mode") ?? readString23(body, "captureMode");
|
|
40320
40946
|
if (captureMode) {
|
|
40321
40947
|
input.captureMode = captureMode;
|
|
40322
40948
|
}
|
|
40323
|
-
const searchMode =
|
|
40949
|
+
const searchMode = readString23(body, "search_mode") ?? readString23(body, "searchMode");
|
|
40324
40950
|
if (searchMode) {
|
|
40325
40951
|
input.searchMode = searchMode;
|
|
40326
40952
|
}
|
|
@@ -40354,11 +40980,11 @@ function readMemorySettingsPatch(body, options = {}) {
|
|
|
40354
40980
|
if (aiPeer !== void 0) {
|
|
40355
40981
|
input.aiPeer = aiPeer;
|
|
40356
40982
|
}
|
|
40357
|
-
const recallMode =
|
|
40983
|
+
const recallMode = readString23(body, "recall_mode") ?? readString23(body, "recallMode");
|
|
40358
40984
|
if (recallMode) {
|
|
40359
40985
|
input.recallMode = recallMode;
|
|
40360
40986
|
}
|
|
40361
|
-
const writeFrequency =
|
|
40987
|
+
const writeFrequency = readString23(body, "write_frequency") ?? readString23(body, "writeFrequency");
|
|
40362
40988
|
if (writeFrequency) {
|
|
40363
40989
|
input.writeFrequency = writeFrequency;
|
|
40364
40990
|
}
|
|
@@ -40366,7 +40992,7 @@ function readMemorySettingsPatch(body, options = {}) {
|
|
|
40366
40992
|
if (saveMessages !== void 0) {
|
|
40367
40993
|
input.saveMessages = saveMessages;
|
|
40368
40994
|
}
|
|
40369
|
-
const sessionStrategy =
|
|
40995
|
+
const sessionStrategy = readString23(body, "session_strategy") ?? readString23(body, "sessionStrategy");
|
|
40370
40996
|
if (sessionStrategy) {
|
|
40371
40997
|
input.sessionStrategy = sessionStrategy;
|
|
40372
40998
|
}
|
|
@@ -40515,8 +41141,8 @@ function toMemoryHttpError(error) {
|
|
|
40515
41141
|
}
|
|
40516
41142
|
|
|
40517
41143
|
// src/hermes/skills.ts
|
|
40518
|
-
import { readFile as
|
|
40519
|
-
import
|
|
41144
|
+
import { readFile as readFile21, readdir as readdir11 } from "fs/promises";
|
|
41145
|
+
import path34 from "path";
|
|
40520
41146
|
import YAML7 from "yaml";
|
|
40521
41147
|
var HermesSkillNotFoundError = class extends Error {
|
|
40522
41148
|
constructor(skillName) {
|
|
@@ -40530,7 +41156,7 @@ var EXCLUDED_SKILL_DIRS = /* @__PURE__ */ new Set([".git", ".github", ".hub"]);
|
|
|
40530
41156
|
async function listHermesProfileSkills(profileName, paths = resolveRuntimePaths()) {
|
|
40531
41157
|
const profile = await readExistingProfile(profileName, paths);
|
|
40532
41158
|
const profileDir = resolveHermesProfileDir(profile.name);
|
|
40533
|
-
const skillsRoot =
|
|
41159
|
+
const skillsRoot = path34.join(profileDir, "skills");
|
|
40534
41160
|
const [skillFiles, disabled, provenance] = await Promise.all([
|
|
40535
41161
|
findSkillFiles(skillsRoot),
|
|
40536
41162
|
readDisabledSkillNames(resolveHermesConfigPath(profile.name)),
|
|
@@ -40621,7 +41247,7 @@ async function collectSkillFiles(directory, results) {
|
|
|
40621
41247
|
if (EXCLUDED_SKILL_DIRS.has(entry.name)) {
|
|
40622
41248
|
continue;
|
|
40623
41249
|
}
|
|
40624
|
-
const entryPath =
|
|
41250
|
+
const entryPath = path34.join(directory, entry.name);
|
|
40625
41251
|
if (entry.isDirectory()) {
|
|
40626
41252
|
await collectSkillFiles(entryPath, results);
|
|
40627
41253
|
continue;
|
|
@@ -40632,7 +41258,7 @@ async function collectSkillFiles(directory, results) {
|
|
|
40632
41258
|
}
|
|
40633
41259
|
}
|
|
40634
41260
|
async function readSkillMetadata(input) {
|
|
40635
|
-
const raw = await
|
|
41261
|
+
const raw = await readFile21(input.skillFile, "utf8").catch(
|
|
40636
41262
|
(error) => {
|
|
40637
41263
|
if (isNodeError23(error, "ENOENT") || isNodeError23(error, "EACCES")) {
|
|
40638
41264
|
return null;
|
|
@@ -40643,16 +41269,16 @@ async function readSkillMetadata(input) {
|
|
|
40643
41269
|
if (raw === null) {
|
|
40644
41270
|
return null;
|
|
40645
41271
|
}
|
|
40646
|
-
const skillDir =
|
|
41272
|
+
const skillDir = path34.dirname(input.skillFile);
|
|
40647
41273
|
const { frontmatter, body } = parseSkillDocument(raw.slice(0, 4e3));
|
|
40648
41274
|
const name = normalizeSkillName(
|
|
40649
|
-
|
|
41275
|
+
readString26(frontmatter.name) ?? path34.basename(skillDir)
|
|
40650
41276
|
);
|
|
40651
41277
|
if (!name) {
|
|
40652
41278
|
return null;
|
|
40653
41279
|
}
|
|
40654
41280
|
const description = normalizeDescription(
|
|
40655
|
-
|
|
41281
|
+
readString26(frontmatter.description) ?? firstBodyDescription(body)
|
|
40656
41282
|
);
|
|
40657
41283
|
const provenance = input.provenance.get(name) ?? {
|
|
40658
41284
|
source: "local",
|
|
@@ -40665,7 +41291,7 @@ async function readSkillMetadata(input) {
|
|
|
40665
41291
|
enabled: !input.disabled.has(name),
|
|
40666
41292
|
source: provenance.source,
|
|
40667
41293
|
trust: provenance.trust,
|
|
40668
|
-
relativePath:
|
|
41294
|
+
relativePath: path34.relative(input.skillsRoot, skillDir)
|
|
40669
41295
|
};
|
|
40670
41296
|
}
|
|
40671
41297
|
function parseSkillDocument(raw) {
|
|
@@ -40686,8 +41312,8 @@ function parseSkillDocument(raw) {
|
|
|
40686
41312
|
}
|
|
40687
41313
|
}
|
|
40688
41314
|
function categoryFromPath(skillsRoot, skillFile) {
|
|
40689
|
-
const relative =
|
|
40690
|
-
const parts = relative.split(
|
|
41315
|
+
const relative = path34.relative(skillsRoot, skillFile);
|
|
41316
|
+
const parts = relative.split(path34.sep).filter(Boolean);
|
|
40691
41317
|
return parts.length >= 3 ? parts[0] : null;
|
|
40692
41318
|
}
|
|
40693
41319
|
function firstBodyDescription(body) {
|
|
@@ -40710,7 +41336,7 @@ function normalizeDescription(value) {
|
|
|
40710
41336
|
return `${description.slice(0, MAX_DESCRIPTION_LENGTH - 3)}...`;
|
|
40711
41337
|
}
|
|
40712
41338
|
async function readDisabledSkillNames(configPath) {
|
|
40713
|
-
const raw = await
|
|
41339
|
+
const raw = await readFile21(configPath, "utf8").catch((error) => {
|
|
40714
41340
|
if (isNodeError23(error, "ENOENT")) {
|
|
40715
41341
|
return "";
|
|
40716
41342
|
}
|
|
@@ -40734,7 +41360,7 @@ async function readSkillProvenance(root) {
|
|
|
40734
41360
|
return provenance;
|
|
40735
41361
|
}
|
|
40736
41362
|
async function readBundledSkillNames(root) {
|
|
40737
|
-
const raw = await
|
|
41363
|
+
const raw = await readFile21(path34.join(root, ".bundled_manifest"), "utf8").catch(
|
|
40738
41364
|
(error) => {
|
|
40739
41365
|
if (isNodeError23(error, "ENOENT")) {
|
|
40740
41366
|
return "";
|
|
@@ -40757,7 +41383,7 @@ async function readBundledSkillNames(root) {
|
|
|
40757
41383
|
return names;
|
|
40758
41384
|
}
|
|
40759
41385
|
async function readHubInstalledSkills(root) {
|
|
40760
|
-
const raw = await
|
|
41386
|
+
const raw = await readFile21(path34.join(root, ".hub", "lock.json"), "utf8").catch(
|
|
40761
41387
|
(error) => {
|
|
40762
41388
|
if (isNodeError23(error, "ENOENT")) {
|
|
40763
41389
|
return "";
|
|
@@ -40779,8 +41405,8 @@ async function readHubInstalledSkills(root) {
|
|
|
40779
41405
|
for (const [name, rawEntry] of Object.entries(installed2)) {
|
|
40780
41406
|
const entry = toRecord23(rawEntry);
|
|
40781
41407
|
result.set(normalizeSkillName(name), {
|
|
40782
|
-
source:
|
|
40783
|
-
trust:
|
|
41408
|
+
source: readString26(entry.source) ?? "hub",
|
|
41409
|
+
trust: readString26(entry.trust_level) ?? null
|
|
40784
41410
|
});
|
|
40785
41411
|
}
|
|
40786
41412
|
return result;
|
|
@@ -40829,7 +41455,7 @@ function compareCategoryNames(left, right) {
|
|
|
40829
41455
|
return left.localeCompare(right);
|
|
40830
41456
|
}
|
|
40831
41457
|
async function readHermesConfigDocument4(configPath) {
|
|
40832
|
-
const existingRaw = await
|
|
41458
|
+
const existingRaw = await readFile21(configPath, "utf8").catch(
|
|
40833
41459
|
(error) => {
|
|
40834
41460
|
if (isNodeError23(error, "ENOENT")) {
|
|
40835
41461
|
return null;
|
|
@@ -40864,7 +41490,7 @@ function readStringList6(value) {
|
|
|
40864
41490
|
}
|
|
40865
41491
|
return value.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean);
|
|
40866
41492
|
}
|
|
40867
|
-
function
|
|
41493
|
+
function readString26(value) {
|
|
40868
41494
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
40869
41495
|
}
|
|
40870
41496
|
function toRecord23(value) {
|
|
@@ -41236,7 +41862,7 @@ function registerRunRoutes(router, options) {
|
|
|
41236
41862
|
await authenticateRequest(ctx, paths);
|
|
41237
41863
|
const language = readPreferredLanguage(ctx);
|
|
41238
41864
|
const body = await readJsonBody(ctx.req);
|
|
41239
|
-
const input =
|
|
41865
|
+
const input = readString23(body, "input");
|
|
41240
41866
|
if (!input) {
|
|
41241
41867
|
throw new LinkHttpError(400, "run_input_required", "input is required");
|
|
41242
41868
|
}
|
|
@@ -41244,12 +41870,12 @@ function registerRunRoutes(router, options) {
|
|
|
41244
41870
|
ctx.body = await createHermesRun(
|
|
41245
41871
|
{
|
|
41246
41872
|
input,
|
|
41247
|
-
instructions:
|
|
41873
|
+
instructions: readString23(body, "instructions") ?? void 0,
|
|
41248
41874
|
conversation_history: readConversationHistory(
|
|
41249
41875
|
body.conversation_history ?? body.conversationHistory
|
|
41250
41876
|
),
|
|
41251
|
-
session_id:
|
|
41252
|
-
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
|
|
41253
41879
|
},
|
|
41254
41880
|
{ logger, profileName: readOptionalProfileName(body), language }
|
|
41255
41881
|
);
|
|
@@ -41424,8 +42050,8 @@ function readModelList(payload) {
|
|
|
41424
42050
|
// src/hermes/updates.ts
|
|
41425
42051
|
import { EventEmitter as EventEmitter3 } from "events";
|
|
41426
42052
|
import { spawn as spawn4 } from "child_process";
|
|
41427
|
-
import { mkdir as mkdir14, readFile as
|
|
41428
|
-
import
|
|
42053
|
+
import { mkdir as mkdir14, readFile as readFile22, rm as rm8 } from "fs/promises";
|
|
42054
|
+
import path35 from "path";
|
|
41429
42055
|
var SERVER_HERMES_RELEASES_LATEST_PATH = "/api/v1/hermes-agent/releases/latest";
|
|
41430
42056
|
var RELEASE_CACHE_TTL_MS = 6 * 60 * 60 * 1e3;
|
|
41431
42057
|
var RELEASE_FETCH_TIMEOUT_MS = 5e3;
|
|
@@ -41662,20 +42288,20 @@ function normalizeServerReleaseSnapshot(payload) {
|
|
|
41662
42288
|
const remote = toNullableRecord(snapshot.remote);
|
|
41663
42289
|
return {
|
|
41664
42290
|
remote: remote ? normalizeServerRelease(remote) : null,
|
|
41665
|
-
cacheState:
|
|
41666
|
-
issue:
|
|
42291
|
+
cacheState: readString27(snapshot, "cache_state") ?? readString27(snapshot, "cacheState"),
|
|
42292
|
+
issue: readString27(snapshot, "issue")
|
|
41667
42293
|
};
|
|
41668
42294
|
}
|
|
41669
42295
|
function normalizeServerRelease(payload) {
|
|
41670
|
-
const tag =
|
|
41671
|
-
const name =
|
|
42296
|
+
const tag = readString27(payload, "tag");
|
|
42297
|
+
const name = readString27(payload, "name");
|
|
41672
42298
|
return {
|
|
41673
|
-
version:
|
|
42299
|
+
version: readString27(payload, "version") ?? extractSemver(name) ?? extractTagSemver(tag),
|
|
41674
42300
|
tag,
|
|
41675
42301
|
name,
|
|
41676
|
-
releaseUrl:
|
|
41677
|
-
publishedAt:
|
|
41678
|
-
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()
|
|
41679
42305
|
};
|
|
41680
42306
|
}
|
|
41681
42307
|
async function readReleaseCache(paths) {
|
|
@@ -41694,7 +42320,7 @@ async function writeUpdateState(paths, state) {
|
|
|
41694
42320
|
await writeJsonFile(updateStatePath(paths), state);
|
|
41695
42321
|
}
|
|
41696
42322
|
async function readUpdateLogLines(paths) {
|
|
41697
|
-
const raw = await
|
|
42323
|
+
const raw = await readFile22(updateLogPath(paths), "utf8").catch(() => "");
|
|
41698
42324
|
if (!raw.trim()) {
|
|
41699
42325
|
return [];
|
|
41700
42326
|
}
|
|
@@ -41703,13 +42329,13 @@ async function readUpdateLogLines(paths) {
|
|
|
41703
42329
|
);
|
|
41704
42330
|
}
|
|
41705
42331
|
function releaseCachePath(paths) {
|
|
41706
|
-
return
|
|
42332
|
+
return path35.join(paths.indexesDir, "hermes-release-check.json");
|
|
41707
42333
|
}
|
|
41708
42334
|
function updateStatePath(paths) {
|
|
41709
|
-
return
|
|
42335
|
+
return path35.join(paths.runDir, "hermes-update-state.json");
|
|
41710
42336
|
}
|
|
41711
42337
|
function updateLogPath(paths) {
|
|
41712
|
-
return
|
|
42338
|
+
return path35.join(paths.logsDir, UPDATE_LOG_FILE);
|
|
41713
42339
|
}
|
|
41714
42340
|
async function clearUpdateLogFiles(paths) {
|
|
41715
42341
|
const primary = updateLogPath(paths);
|
|
@@ -41801,7 +42427,7 @@ function isRecentRunningState2(state) {
|
|
|
41801
42427
|
const startedAt = Date.parse(state.started_at);
|
|
41802
42428
|
return Number.isFinite(startedAt) && Date.now() - startedAt < 3e4;
|
|
41803
42429
|
}
|
|
41804
|
-
function
|
|
42430
|
+
function readString27(payload, key) {
|
|
41805
42431
|
const value = payload[key];
|
|
41806
42432
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
41807
42433
|
}
|
|
@@ -41809,13 +42435,13 @@ function readString26(payload, key) {
|
|
|
41809
42435
|
// src/link/updates.ts
|
|
41810
42436
|
import { spawn as spawn6 } from "child_process";
|
|
41811
42437
|
import { EventEmitter as EventEmitter4 } from "events";
|
|
41812
|
-
import { mkdir as mkdir17, readFile as
|
|
41813
|
-
import
|
|
42438
|
+
import { mkdir as mkdir17, readFile as readFile24, rm as rm11 } from "fs/promises";
|
|
42439
|
+
import path37 from "path";
|
|
41814
42440
|
|
|
41815
42441
|
// src/daemon/process.ts
|
|
41816
42442
|
import { spawn as spawn5 } from "child_process";
|
|
41817
|
-
import { mkdir as mkdir16, readFile as
|
|
41818
|
-
import
|
|
42443
|
+
import { mkdir as mkdir16, readFile as readFile23, rm as rm10, writeFile as writeFile4 } from "fs/promises";
|
|
42444
|
+
import path36 from "path";
|
|
41819
42445
|
|
|
41820
42446
|
// src/daemon/service.ts
|
|
41821
42447
|
import { createServer } from "http";
|
|
@@ -43843,7 +44469,7 @@ async function runDaemonSupervisor(paths = resolveRuntimePaths()) {
|
|
|
43843
44469
|
await mkdir16(paths.logsDir, { recursive: true, mode: 448 });
|
|
43844
44470
|
const log = createRotatingTextLogWriter({
|
|
43845
44471
|
paths,
|
|
43846
|
-
fileName:
|
|
44472
|
+
fileName: path36.basename(daemonLogFile(paths))
|
|
43847
44473
|
});
|
|
43848
44474
|
const scriptPath = currentCliScriptPath();
|
|
43849
44475
|
const write = (chunk) => {
|
|
@@ -44023,7 +44649,7 @@ function currentCliScriptPath() {
|
|
|
44023
44649
|
return process.argv[1];
|
|
44024
44650
|
}
|
|
44025
44651
|
async function readPid(filePath) {
|
|
44026
|
-
const raw = await
|
|
44652
|
+
const raw = await readFile23(filePath, "utf8").catch(() => null);
|
|
44027
44653
|
if (!raw) {
|
|
44028
44654
|
return null;
|
|
44029
44655
|
}
|
|
@@ -44142,7 +44768,7 @@ function terminateChild(child, previousForceKillTimer) {
|
|
|
44142
44768
|
}
|
|
44143
44769
|
}
|
|
44144
44770
|
function supervisorStopIntentPath(paths) {
|
|
44145
|
-
return
|
|
44771
|
+
return path36.join(paths.runDir, "supervisor-stop-intent.json");
|
|
44146
44772
|
}
|
|
44147
44773
|
async function writeSupervisorStopIntent(paths, pid) {
|
|
44148
44774
|
await mkdir16(paths.runDir, { recursive: true, mode: 448 });
|
|
@@ -44155,7 +44781,7 @@ async function writeSupervisorStopIntent(paths, pid) {
|
|
|
44155
44781
|
}
|
|
44156
44782
|
async function consumeSupervisorStopIntent(paths, pid) {
|
|
44157
44783
|
const filePath = supervisorStopIntentPath(paths);
|
|
44158
|
-
const raw = await
|
|
44784
|
+
const raw = await readFile23(filePath, "utf8").catch(() => null);
|
|
44159
44785
|
if (!raw) {
|
|
44160
44786
|
return false;
|
|
44161
44787
|
}
|
|
@@ -44173,7 +44799,7 @@ async function consumeSupervisorStopIntent(paths, pid) {
|
|
|
44173
44799
|
}
|
|
44174
44800
|
async function clearExpiredSupervisorStopIntent(paths) {
|
|
44175
44801
|
const filePath = supervisorStopIntentPath(paths);
|
|
44176
|
-
const raw = await
|
|
44802
|
+
const raw = await readFile23(filePath, "utf8").catch(() => null);
|
|
44177
44803
|
if (!raw) {
|
|
44178
44804
|
return;
|
|
44179
44805
|
}
|
|
@@ -44622,16 +45248,16 @@ function normalizeServerSnapshot(payload) {
|
|
|
44622
45248
|
if (!policy) {
|
|
44623
45249
|
return {
|
|
44624
45250
|
remote: null,
|
|
44625
|
-
issue:
|
|
45251
|
+
issue: readString28(snapshot, "issue")
|
|
44626
45252
|
};
|
|
44627
45253
|
}
|
|
44628
45254
|
const release = toNullableRecord2(snapshot.release);
|
|
44629
|
-
const currentVersion =
|
|
44630
|
-
const minSafeVersion =
|
|
45255
|
+
const currentVersion = readString28(policy, "current_version") ?? readString28(policy, "currentVersion");
|
|
45256
|
+
const minSafeVersion = readString28(policy, "min_safe_version") ?? readString28(policy, "minSafeVersion");
|
|
44631
45257
|
if (!currentVersion) {
|
|
44632
45258
|
return {
|
|
44633
45259
|
remote: null,
|
|
44634
|
-
issue:
|
|
45260
|
+
issue: readString28(snapshot, "issue")
|
|
44635
45261
|
};
|
|
44636
45262
|
}
|
|
44637
45263
|
return {
|
|
@@ -44639,10 +45265,10 @@ function normalizeServerSnapshot(payload) {
|
|
|
44639
45265
|
current_version: currentVersion,
|
|
44640
45266
|
min_safe_version: minSafeVersion,
|
|
44641
45267
|
target_version: currentVersion,
|
|
44642
|
-
release_url: release ?
|
|
44643
|
-
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
|
|
44644
45270
|
},
|
|
44645
|
-
issue:
|
|
45271
|
+
issue: readString28(snapshot, "issue")
|
|
44646
45272
|
};
|
|
44647
45273
|
}
|
|
44648
45274
|
async function fetchCurrentLinkReleaseFromServer(options, fetcher, channel) {
|
|
@@ -44705,7 +45331,7 @@ async function buildOfficialInstallCommand(options, targetVersion) {
|
|
|
44705
45331
|
};
|
|
44706
45332
|
}
|
|
44707
45333
|
function buildUnixInstallCommand(installerUrl) {
|
|
44708
|
-
const nodeBinDir =
|
|
45334
|
+
const nodeBinDir = path37.dirname(process.execPath);
|
|
44709
45335
|
const fetchScript = [
|
|
44710
45336
|
quoteShellToken(process.execPath),
|
|
44711
45337
|
"--input-type=module",
|
|
@@ -44966,7 +45592,7 @@ async function writeUpdateState2(paths, state) {
|
|
|
44966
45592
|
await writeJsonFile(updateStatePath2(paths), state);
|
|
44967
45593
|
}
|
|
44968
45594
|
async function readUpdateLogLines2(paths) {
|
|
44969
|
-
const raw = await
|
|
45595
|
+
const raw = await readFile24(updateLogPath2(paths), "utf8").catch(() => "");
|
|
44970
45596
|
if (!raw.trim()) {
|
|
44971
45597
|
return [];
|
|
44972
45598
|
}
|
|
@@ -44975,10 +45601,10 @@ async function readUpdateLogLines2(paths) {
|
|
|
44975
45601
|
);
|
|
44976
45602
|
}
|
|
44977
45603
|
function updateStatePath2(paths) {
|
|
44978
|
-
return
|
|
45604
|
+
return path37.join(paths.runDir, "link-update-state.json");
|
|
44979
45605
|
}
|
|
44980
45606
|
function updateLogPath2(paths) {
|
|
44981
|
-
return
|
|
45607
|
+
return path37.join(paths.logsDir, UPDATE_LOG_FILE2);
|
|
44982
45608
|
}
|
|
44983
45609
|
async function clearUpdateLogFiles2(paths) {
|
|
44984
45610
|
const primary = updateLogPath2(paths);
|
|
@@ -45056,13 +45682,13 @@ function toRecord26(value) {
|
|
|
45056
45682
|
function toNullableRecord2(value) {
|
|
45057
45683
|
return typeof value === "object" && value !== null ? value : null;
|
|
45058
45684
|
}
|
|
45059
|
-
function
|
|
45685
|
+
function readString28(payload, key) {
|
|
45060
45686
|
const value = payload[key];
|
|
45061
45687
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
45062
45688
|
}
|
|
45063
45689
|
|
|
45064
45690
|
// src/pairing/pairing.ts
|
|
45065
|
-
import
|
|
45691
|
+
import path38 from "path";
|
|
45066
45692
|
import { rm as rm12 } from "fs/promises";
|
|
45067
45693
|
|
|
45068
45694
|
// src/relay/bootstrap.ts
|
|
@@ -45402,10 +46028,10 @@ async function loadRequiredIdentity2(paths) {
|
|
|
45402
46028
|
}
|
|
45403
46029
|
return identity;
|
|
45404
46030
|
}
|
|
45405
|
-
async function postServerJson(serverBaseUrl,
|
|
46031
|
+
async function postServerJson(serverBaseUrl, path39, body, options) {
|
|
45406
46032
|
let response;
|
|
45407
46033
|
try {
|
|
45408
|
-
response = await fetch(`${serverBaseUrl.replace(/\/+$/u, "")}${
|
|
46034
|
+
response = await fetch(`${serverBaseUrl.replace(/\/+$/u, "")}${path39}`, {
|
|
45409
46035
|
method: "POST",
|
|
45410
46036
|
headers: {
|
|
45411
46037
|
accept: "application/json",
|
|
@@ -45453,10 +46079,10 @@ function pairingErrorSnapshot(stage, error) {
|
|
|
45453
46079
|
occurred_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
45454
46080
|
};
|
|
45455
46081
|
}
|
|
45456
|
-
async function patchServerJson(serverBaseUrl,
|
|
46082
|
+
async function patchServerJson(serverBaseUrl, path39, token, body, options) {
|
|
45457
46083
|
let response;
|
|
45458
46084
|
try {
|
|
45459
|
-
response = await fetch(`${serverBaseUrl.replace(/\/+$/u, "")}${
|
|
46085
|
+
response = await fetch(`${serverBaseUrl.replace(/\/+$/u, "")}${path39}`, {
|
|
45460
46086
|
method: "PATCH",
|
|
45461
46087
|
headers: {
|
|
45462
46088
|
accept: "application/json",
|
|
@@ -45504,10 +46130,10 @@ function createPairingNetworkError(input) {
|
|
|
45504
46130
|
);
|
|
45505
46131
|
}
|
|
45506
46132
|
function pairingClaimPath(sessionId, paths) {
|
|
45507
|
-
return
|
|
46133
|
+
return path38.join(paths.pairingDir, `${Buffer.from(sessionId).toString("base64url")}.claimed.json`);
|
|
45508
46134
|
}
|
|
45509
46135
|
function pairingSessionPath(sessionId, paths) {
|
|
45510
|
-
return
|
|
46136
|
+
return path38.join(paths.pairingDir, `${Buffer.from(sessionId).toString("base64url")}.json`);
|
|
45511
46137
|
}
|
|
45512
46138
|
function qrPreferredUrls(routes) {
|
|
45513
46139
|
return routes.preferredUrls.filter((url) => !url.includes("/api/v1/relay/links/")).slice(0, 1);
|
|
@@ -45610,8 +46236,8 @@ function registerSystemRoutes(router, options) {
|
|
|
45610
46236
|
});
|
|
45611
46237
|
router.post("/api/v1/pairing/claim", async (ctx) => {
|
|
45612
46238
|
const body = await readJsonBody(ctx.req);
|
|
45613
|
-
const sessionId =
|
|
45614
|
-
const claimToken =
|
|
46239
|
+
const sessionId = readString23(body, "session_id") ?? readString23(body, "sessionId");
|
|
46240
|
+
const claimToken = readString23(body, "claim_token") ?? readString23(body, "claimToken");
|
|
45615
46241
|
if (!sessionId || !claimToken) {
|
|
45616
46242
|
throw new LinkHttpError(
|
|
45617
46243
|
400,
|
|
@@ -45622,10 +46248,10 @@ function registerSystemRoutes(router, options) {
|
|
|
45622
46248
|
const claimed = await claimPairing({
|
|
45623
46249
|
sessionId,
|
|
45624
46250
|
claimToken,
|
|
45625
|
-
deviceLabel:
|
|
45626
|
-
devicePlatform:
|
|
45627
|
-
deviceModel:
|
|
45628
|
-
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"),
|
|
45629
46255
|
paths
|
|
45630
46256
|
});
|
|
45631
46257
|
ctx.body = claimed;
|
|
@@ -45705,9 +46331,9 @@ function registerSystemRoutes(router, options) {
|
|
|
45705
46331
|
const body = await readJsonBody(ctx.req);
|
|
45706
46332
|
const session = await createDeviceSession(
|
|
45707
46333
|
{
|
|
45708
|
-
label:
|
|
45709
|
-
platform:
|
|
45710
|
-
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"),
|
|
45711
46337
|
appInstanceId: auth.appInstanceId
|
|
45712
46338
|
},
|
|
45713
46339
|
paths
|
|
@@ -45736,7 +46362,7 @@ function registerSystemRoutes(router, options) {
|
|
|
45736
46362
|
});
|
|
45737
46363
|
router.post("/api/v1/auth/refresh", async (ctx) => {
|
|
45738
46364
|
const body = await readJsonBody(ctx.req);
|
|
45739
|
-
const refreshToken =
|
|
46365
|
+
const refreshToken = readString23(body, "refresh_token") ?? readString23(body, "refreshToken");
|
|
45740
46366
|
if (!refreshToken) {
|
|
45741
46367
|
throw new LinkHttpError(
|
|
45742
46368
|
400,
|
|
@@ -45747,10 +46373,10 @@ function registerSystemRoutes(router, options) {
|
|
|
45747
46373
|
const session = await refreshDeviceSession(
|
|
45748
46374
|
refreshToken,
|
|
45749
46375
|
{
|
|
45750
|
-
appInstanceId:
|
|
45751
|
-
label:
|
|
45752
|
-
platform:
|
|
45753
|
-
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")
|
|
45754
46380
|
},
|
|
45755
46381
|
paths
|
|
45756
46382
|
);
|
|
@@ -45769,7 +46395,7 @@ function registerSystemRoutes(router, options) {
|
|
|
45769
46395
|
});
|
|
45770
46396
|
router.post("/api/v1/auth/logout", async (ctx) => {
|
|
45771
46397
|
const body = await readJsonBody(ctx.req);
|
|
45772
|
-
const refreshToken =
|
|
46398
|
+
const refreshToken = readString23(body, "refresh_token") ?? readString23(body, "refreshToken");
|
|
45773
46399
|
if (refreshToken) {
|
|
45774
46400
|
await revokeDeviceRefreshToken(refreshToken, paths);
|
|
45775
46401
|
}
|
|
@@ -46010,7 +46636,7 @@ function registerSystemRoutes(router, options) {
|
|
|
46010
46636
|
router.patch("/api/v1/devices/:deviceId", async (ctx) => {
|
|
46011
46637
|
const auth = await authenticateRequest(ctx, paths);
|
|
46012
46638
|
const body = await readJsonBody(ctx.req);
|
|
46013
|
-
const label =
|
|
46639
|
+
const label = readString23(body, "label") ?? readString23(body, "device_label");
|
|
46014
46640
|
if (!label) {
|
|
46015
46641
|
throw new LinkHttpError(
|
|
46016
46642
|
400,
|
|
@@ -46054,7 +46680,7 @@ function isActiveCronJob(job) {
|
|
|
46054
46680
|
if (!enabled) {
|
|
46055
46681
|
return false;
|
|
46056
46682
|
}
|
|
46057
|
-
const state =
|
|
46683
|
+
const state = readString23(job, "state")?.toLowerCase();
|
|
46058
46684
|
return !["paused", "disabled", "completed", "deleted"].includes(state ?? "");
|
|
46059
46685
|
}
|
|
46060
46686
|
function filterLogsWithinHours(logs, hours, now = Date.now()) {
|
|
@@ -46098,8 +46724,8 @@ function registerWorkspaceRoutes(router, options) {
|
|
|
46098
46724
|
ctx.body = {
|
|
46099
46725
|
ok: true,
|
|
46100
46726
|
workspace: await conversations.createWorkspace({
|
|
46101
|
-
name:
|
|
46102
|
-
icon:
|
|
46727
|
+
name: readString23(body, "name") ?? "",
|
|
46728
|
+
icon: readString23(body, "icon") ?? void 0
|
|
46103
46729
|
})
|
|
46104
46730
|
};
|
|
46105
46731
|
});
|
|
@@ -46109,8 +46735,8 @@ function registerWorkspaceRoutes(router, options) {
|
|
|
46109
46735
|
ctx.body = {
|
|
46110
46736
|
ok: true,
|
|
46111
46737
|
workspace: await conversations.renameWorkspace(ctx.params.workspaceId, {
|
|
46112
|
-
name:
|
|
46113
|
-
icon:
|
|
46738
|
+
name: readString23(body, "name") ?? "",
|
|
46739
|
+
icon: readString23(body, "icon") ?? void 0
|
|
46114
46740
|
})
|
|
46115
46741
|
};
|
|
46116
46742
|
});
|
|
@@ -46193,8 +46819,8 @@ function registerLinkUpdateRoutes(router, options) {
|
|
|
46193
46819
|
ctx.body = await startLinkUpdate({
|
|
46194
46820
|
paths,
|
|
46195
46821
|
logger,
|
|
46196
|
-
channel:
|
|
46197
|
-
targetVersion:
|
|
46822
|
+
channel: readString23(body, "channel"),
|
|
46823
|
+
targetVersion: readString23(body, "target_version") ?? readString23(body, "targetVersion")
|
|
46198
46824
|
});
|
|
46199
46825
|
});
|
|
46200
46826
|
router.get("/api/v1/link/update/events", async (ctx) => {
|
|
@@ -46224,7 +46850,7 @@ import QRCode from "qrcode";
|
|
|
46224
46850
|
function registerPairingRoutes(router, options) {
|
|
46225
46851
|
const { paths } = options;
|
|
46226
46852
|
router.get("/pair", async (ctx) => {
|
|
46227
|
-
const sessionId =
|
|
46853
|
+
const sessionId = readString23(ctx.query, "session_id");
|
|
46228
46854
|
if (!sessionId) {
|
|
46229
46855
|
throw new LinkHttpError(400, "pairing_session_required", "session_id is required");
|
|
46230
46856
|
}
|
|
@@ -46249,7 +46875,7 @@ function registerPairingRoutes(router, options) {
|
|
|
46249
46875
|
ctx.body = page;
|
|
46250
46876
|
});
|
|
46251
46877
|
router.get("/api/v1/pairing/session", async (ctx) => {
|
|
46252
|
-
const sessionId =
|
|
46878
|
+
const sessionId = readString23(ctx.query, "session_id");
|
|
46253
46879
|
if (!sessionId) {
|
|
46254
46880
|
throw new LinkHttpError(400, "pairing_session_required", "session_id is required");
|
|
46255
46881
|
}
|
|
@@ -46719,7 +47345,7 @@ function registerInternalRoutes(router, options) {
|
|
|
46719
47345
|
router.post("/internal/deliver", async (ctx) => {
|
|
46720
47346
|
assertLoopbackRequest(ctx.req);
|
|
46721
47347
|
const body = await readJsonBody(ctx.req);
|
|
46722
|
-
const stagingDir =
|
|
47348
|
+
const stagingDir = readString23(body, "staging_dir") ?? readString23(body, "stagingDir");
|
|
46723
47349
|
if (!stagingDir) {
|
|
46724
47350
|
throw new LinkHttpError(
|
|
46725
47351
|
400,
|
|
@@ -46738,9 +47364,9 @@ function registerInternalRoutes(router, options) {
|
|
|
46738
47364
|
ctx.body = {
|
|
46739
47365
|
ok: true,
|
|
46740
47366
|
...await options.conversations.deliverFilesFromTool({
|
|
46741
|
-
profile:
|
|
46742
|
-
taskId:
|
|
46743
|
-
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,
|
|
46744
47370
|
files: body.files ?? body.file ?? body.path
|
|
46745
47371
|
})
|
|
46746
47372
|
};
|
|
@@ -46801,9 +47427,9 @@ function registerLiveActivityRoutes(router, options) {
|
|
|
46801
47427
|
const auth = await authenticateRequest(ctx, paths);
|
|
46802
47428
|
const body = await readJsonBody(ctx.req);
|
|
46803
47429
|
const targetKind = readTargetKind(body);
|
|
46804
|
-
const runId = normalizePattern(
|
|
47430
|
+
const runId = normalizePattern(readString23(body, "run_id") ?? readString23(body, "runId"), RUN_ID_PATTERN);
|
|
46805
47431
|
const operationId = normalizePattern(
|
|
46806
|
-
|
|
47432
|
+
readString23(body, "operation_id") ?? readString23(body, "operationId"),
|
|
46807
47433
|
OPERATION_ID_PATTERN
|
|
46808
47434
|
);
|
|
46809
47435
|
if (targetKind === "run" && !runId) {
|
|
@@ -46849,7 +47475,7 @@ function registerLiveActivityRoutes(router, options) {
|
|
|
46849
47475
|
});
|
|
46850
47476
|
}
|
|
46851
47477
|
function readTargetKind(body) {
|
|
46852
|
-
const value =
|
|
47478
|
+
const value = readString23(body, "target_kind") ?? readString23(body, "targetKind");
|
|
46853
47479
|
return readTargetKindValue(value);
|
|
46854
47480
|
}
|
|
46855
47481
|
function readTargetKindValue(value) {
|
|
@@ -46871,21 +47497,21 @@ function readQueryValue(query, key) {
|
|
|
46871
47497
|
return readQueryString(query[key]) ?? null;
|
|
46872
47498
|
}
|
|
46873
47499
|
function readApnsEnvironment(body) {
|
|
46874
|
-
const value =
|
|
47500
|
+
const value = readString23(body, "apns_environment") ?? readString23(body, "apnsEnvironment");
|
|
46875
47501
|
if (value === "sandbox" || value === "production") {
|
|
46876
47502
|
return value;
|
|
46877
47503
|
}
|
|
46878
47504
|
throw new LinkHttpError(400, "apns_environment_invalid", "apns_environment must be sandbox or production");
|
|
46879
47505
|
}
|
|
46880
47506
|
function readLanguage2(body) {
|
|
46881
|
-
const value =
|
|
47507
|
+
const value = readString23(body, "language") ?? readString23(body, "preferred_language") ?? readString23(body, "preferredLanguage");
|
|
46882
47508
|
if (!value) {
|
|
46883
47509
|
return null;
|
|
46884
47510
|
}
|
|
46885
47511
|
return value.toLowerCase().startsWith("zh") ? "zh" : "en";
|
|
46886
47512
|
}
|
|
46887
47513
|
function readPrivacyLevel(body) {
|
|
46888
|
-
const value =
|
|
47514
|
+
const value = readString23(body, "privacy_level") ?? readString23(body, "privacyLevel");
|
|
46889
47515
|
if (value === "minimal" || value === "detailed") {
|
|
46890
47516
|
return value;
|
|
46891
47517
|
}
|
|
@@ -46893,7 +47519,7 @@ function readPrivacyLevel(body) {
|
|
|
46893
47519
|
}
|
|
46894
47520
|
function readRequiredString(body, keys, code) {
|
|
46895
47521
|
for (const key of keys) {
|
|
46896
|
-
const value =
|
|
47522
|
+
const value = readString23(body, key);
|
|
46897
47523
|
if (value) {
|
|
46898
47524
|
return value;
|
|
46899
47525
|
}
|
|
@@ -46909,7 +47535,7 @@ function readRequiredPattern(body, keys, pattern, code) {
|
|
|
46909
47535
|
}
|
|
46910
47536
|
function readOptionalString2(body, keys, maxLength) {
|
|
46911
47537
|
for (const key of keys) {
|
|
46912
|
-
const value =
|
|
47538
|
+
const value = readString23(body, key);
|
|
46913
47539
|
if (value) {
|
|
46914
47540
|
return value.slice(0, maxLength);
|
|
46915
47541
|
}
|
|
@@ -46921,7 +47547,7 @@ function normalizePattern(value, pattern) {
|
|
|
46921
47547
|
}
|
|
46922
47548
|
function readIso(body, keys) {
|
|
46923
47549
|
for (const key of keys) {
|
|
46924
|
-
const value =
|
|
47550
|
+
const value = readString23(body, key);
|
|
46925
47551
|
if (!value) {
|
|
46926
47552
|
continue;
|
|
46927
47553
|
}
|