clawconnect-agent 0.2.13 → 0.2.14
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/commands/send-file.d.ts +2 -0
- package/dist/commands/send-file.js +8 -0
- package/dist/commands/send-file.js.map +1 -1
- package/dist/core/relay/source-commit.d.ts +7 -0
- package/dist/core/relay/source-commit.js +25 -1
- package/dist/core/relay/source-commit.js.map +1 -1
- package/dist/hermes/hermes-relay-manager.d.ts +3 -0
- package/dist/hermes/hermes-relay-manager.js +7 -0
- package/dist/hermes/hermes-relay-manager.js.map +1 -1
- package/dist/hermes/relay/hermes-cron-change-relay.d.ts +28 -0
- package/dist/hermes/relay/hermes-cron-change-relay.js +55 -0
- package/dist/hermes/relay/hermes-cron-change-relay.js.map +1 -0
- package/dist/hermes/runtime/hermes-cron-change-watcher.d.ts +34 -0
- package/dist/hermes/runtime/hermes-cron-change-watcher.js +135 -0
- package/dist/hermes/runtime/hermes-cron-change-watcher.js.map +1 -0
- package/dist/hermes/runtime/hermes-runtime-chat-cli.d.ts +16 -0
- package/dist/hermes/runtime/hermes-runtime-chat-cli.js +359 -0
- package/dist/hermes/runtime/hermes-runtime-chat-cli.js.map +1 -0
- package/dist/hermes/runtime/hermes-runtime-chat-file-transfer.d.ts +29 -0
- package/dist/hermes/runtime/hermes-runtime-chat-file-transfer.js +323 -0
- package/dist/hermes/runtime/hermes-runtime-chat-file-transfer.js.map +1 -0
- package/dist/hermes/runtime/hermes-runtime-chat-message.d.ts +10 -0
- package/dist/hermes/runtime/hermes-runtime-chat-message.js +133 -0
- package/dist/hermes/runtime/hermes-runtime-chat-message.js.map +1 -0
- package/dist/hermes/runtime/hermes-runtime-chat-output.d.ts +17 -0
- package/dist/hermes/runtime/hermes-runtime-chat-output.js +90 -0
- package/dist/hermes/runtime/hermes-runtime-chat-output.js.map +1 -0
- package/dist/hermes/runtime/hermes-runtime-chat-queue.d.ts +1 -0
- package/dist/hermes/runtime/hermes-runtime-chat-queue.js +18 -0
- package/dist/hermes/runtime/hermes-runtime-chat-queue.js.map +1 -0
- package/dist/hermes/runtime/hermes-runtime-chat.d.ts +3 -33
- package/dist/hermes/runtime/hermes-runtime-chat.js +41 -910
- package/dist/hermes/runtime/hermes-runtime-chat.js.map +1 -1
- package/dist/hermes/runtime/hermes-runtime-slash-command.d.ts +14 -1
- package/dist/hermes/runtime/hermes-runtime-slash-command.js +6 -1
- package/dist/hermes/runtime/hermes-runtime-slash-command.js.map +1 -1
- package/dist/openclaw/relay/chat-history.d.ts +5 -1
- package/dist/openclaw/relay/chat-history.js +4 -7
- package/dist/openclaw/relay/chat-history.js.map +1 -1
- package/dist/openclaw/relay/openclaw-source-commit-watcher.d.ts +7 -4
- package/dist/openclaw/relay/openclaw-source-commit-watcher.js +2 -0
- package/dist/openclaw/relay/openclaw-source-commit-watcher.js.map +1 -1
- package/dist/openclaw/relay/openclaw-source-cursor-connections.d.ts +2 -0
- package/dist/openclaw/relay/openclaw-source-cursor-connections.js +12 -0
- package/dist/openclaw/relay/openclaw-source-cursor-connections.js.map +1 -1
- package/dist/openclaw/relay/source-commit-projection.d.ts +28 -6
- package/dist/openclaw/relay/source-commit-projection.js +106 -30
- package/dist/openclaw/relay/source-commit-projection.js.map +1 -1
- package/dist/openclaw/relay/source-row-fingerprints.d.ts +22 -0
- package/dist/openclaw/relay/source-row-fingerprints.js +48 -0
- package/dist/openclaw/relay/source-row-fingerprints.js.map +1 -0
- package/dist/openclaw/relay-manager.js +44 -22
- package/dist/openclaw/relay-manager.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
// Hermes 文件发送校验:按 sourceRunId 精确定位当前轮次,只认第一方 send-file 回执与 terminal 结构化结果。
|
|
2
|
+
import { stringValue } from "./hermes-runtime-values.js";
|
|
3
|
+
import { hermesSourceRunIdFromMessage } from "./hermes-runtime-history-completion.js";
|
|
4
|
+
import { readHermesSessionMessages } from "./hermes-runtime-state-db.js";
|
|
5
|
+
import { clearPendingHermesFileTransfer, getPendingHermesFileTransfer, recordPendingHermesFileTransfer, } from "./hermes-file-transfer-state.js";
|
|
6
|
+
const HERMES_FILE_TRANSFER_NOT_SENT_MESSAGE = "文件尚未发送:没有检测到可验证的 clawconnect send-file 成功结果,请补充或确认要发送的文件后重试。";
|
|
7
|
+
const HERMES_FILE_TRANSFER_CONTENT_MISSING_MESSAGE = "本轮没有可显示的结构化回答。";
|
|
8
|
+
const HERMES_FILE_TRANSFER_CANCELLED_MESSAGE = "文件发送已取消。";
|
|
9
|
+
export async function planHermesChatPreparation(params) {
|
|
10
|
+
// A continuation is enabled only by a durable host-side pending state from
|
|
11
|
+
// the same gateway/mobile/Hermes session. The user's wording is deliberately
|
|
12
|
+
// opaque to this router; Hermes receives the full history and decides what it
|
|
13
|
+
// means (including any language, selection, or clarification).
|
|
14
|
+
const pending = params.sessionId
|
|
15
|
+
? await getPendingHermesFileTransfer({
|
|
16
|
+
gatewayId: params.gatewayId,
|
|
17
|
+
sessionKey: params.sessionKey,
|
|
18
|
+
hermesSessionId: params.sessionId,
|
|
19
|
+
sourceRunId: params.sourceRunId,
|
|
20
|
+
})
|
|
21
|
+
: undefined;
|
|
22
|
+
return {
|
|
23
|
+
// The mobile relay explicitly grants the typed CLI file-transfer
|
|
24
|
+
// capability on every turn. The model/tool protocol, rather than a
|
|
25
|
+
// language-specific intent table, decides whether a send is needed. This
|
|
26
|
+
// deliberately trades the API fast path for a buffered CLI path on mobile
|
|
27
|
+
// turns, where send-file receipts are persisted atomically.
|
|
28
|
+
preloadFileTransferSkill: params.fileTransferCapability === "cli" || pending !== undefined,
|
|
29
|
+
fileTransferMode: pending ? "continuation" : undefined,
|
|
30
|
+
...(pending ? { pendingFileTransfer: pending } : {}),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function normalizeHermesRole(value) {
|
|
34
|
+
return typeof value === "string" ? value.trim().toLowerCase() : "";
|
|
35
|
+
}
|
|
36
|
+
export async function verifyHermesFileTransferIfRequired(params) {
|
|
37
|
+
if (!params.plan.preloadFileTransferSkill) {
|
|
38
|
+
return {};
|
|
39
|
+
}
|
|
40
|
+
const messages = params.sessionId ? await readHermesSessionMessages(params.sessionId) : undefined;
|
|
41
|
+
const evidence = params.sourceRunId
|
|
42
|
+
? collectHermesFileTransferEvidence(messages, params.sourceRunId)
|
|
43
|
+
: [];
|
|
44
|
+
if (evidence.length > 0) {
|
|
45
|
+
await clearPendingHermesFileTransfer(params.gatewayId, params.sessionKey, params.plan.pendingFileTransfer?.sourceRunId);
|
|
46
|
+
return {
|
|
47
|
+
verifiedFileTransferCount: evidence.length,
|
|
48
|
+
output: `已发送 ${evidence.length} 个文件,请查收。`,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const outcome = params.sourceRunId
|
|
52
|
+
? collectHermesFileTransferOutcome(messages, params.sourceRunId)
|
|
53
|
+
: undefined;
|
|
54
|
+
if (outcome?.kind === "clarification") {
|
|
55
|
+
if (params.sessionId && params.sourceRunId) {
|
|
56
|
+
await recordPendingHermesFileTransfer({
|
|
57
|
+
gatewayId: params.gatewayId,
|
|
58
|
+
sessionKey: params.sessionKey,
|
|
59
|
+
hermesSessionId: params.sessionId,
|
|
60
|
+
sourceRunId: params.sourceRunId,
|
|
61
|
+
continuation: false,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
// Only the typed content field is displayable. Raw assistant prose is
|
|
65
|
+
// deliberately discarded, and this outcome is never delivery evidence.
|
|
66
|
+
return {
|
|
67
|
+
output: outcome.assistantText ?? HERMES_FILE_TRANSFER_CONTENT_MISSING_MESSAGE,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
if (outcome?.kind === "cancelled") {
|
|
71
|
+
await clearPendingHermesFileTransfer(params.gatewayId, params.sessionKey, params.plan.pendingFileTransfer?.sourceRunId);
|
|
72
|
+
return {
|
|
73
|
+
output: outcome.assistantText ?? HERMES_FILE_TRANSFER_CANCELLED_MESSAGE,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
if (outcome?.kind === "ordinary") {
|
|
77
|
+
await clearPendingHermesFileTransfer(params.gatewayId, params.sessionKey, params.plan.pendingFileTransfer?.sourceRunId);
|
|
78
|
+
// Ordinary chat is shown only through the typed assistantText field. The
|
|
79
|
+
// model's ordinary label is routing metadata, never proof of delivery.
|
|
80
|
+
return {
|
|
81
|
+
output: outcome.assistantText ?? HERMES_FILE_TRANSFER_CONTENT_MISSING_MESSAGE,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
if (outcome?.kind === "attempted") {
|
|
85
|
+
await clearPendingHermesFileTransfer(params.gatewayId, params.sessionKey, params.plan.pendingFileTransfer?.sourceRunId);
|
|
86
|
+
return {
|
|
87
|
+
verifiedFileTransferCount: 0,
|
|
88
|
+
output: HERMES_FILE_TRANSFER_NOT_SENT_MESSAGE,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
if (params.sourceRunId && hasHermesSendFileAttempt(messages, params.sourceRunId)) {
|
|
92
|
+
return {
|
|
93
|
+
verifiedFileTransferCount: 0,
|
|
94
|
+
output: HERMES_FILE_TRANSFER_NOT_SENT_MESSAGE,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
// File-transfer capability is available on every mobile turn, but capability
|
|
98
|
+
// alone does not turn ordinary chat into a file operation. Preserve the Host
|
|
99
|
+
// answer unless this exact turn emitted a typed outcome or actually invoked
|
|
100
|
+
// the first-party terminal command. This keeps failure closed around a real
|
|
101
|
+
// send attempt without replacing unrelated Hermes replies.
|
|
102
|
+
return {};
|
|
103
|
+
}
|
|
104
|
+
function hasHermesSendFileAttempt(messages, sourceRunId) {
|
|
105
|
+
const currentIndex = currentHermesTurnIndex(messages, sourceRunId);
|
|
106
|
+
if (currentIndex < 0 || !messages)
|
|
107
|
+
return false;
|
|
108
|
+
for (const message of messages.slice(currentIndex + 1)) {
|
|
109
|
+
if (normalizeHermesRole(message.role) === "user")
|
|
110
|
+
break;
|
|
111
|
+
if (normalizeHermesRole(message.role) !== "assistant")
|
|
112
|
+
continue;
|
|
113
|
+
const rawToolCalls = typeof message.tool_calls === "string"
|
|
114
|
+
? parseJsonValue(message.tool_calls)
|
|
115
|
+
: message.tool_calls;
|
|
116
|
+
if (!Array.isArray(rawToolCalls))
|
|
117
|
+
continue;
|
|
118
|
+
for (const rawToolCall of rawToolCalls) {
|
|
119
|
+
const toolCall = rawToolCall && typeof rawToolCall === "object" && !Array.isArray(rawToolCall)
|
|
120
|
+
? rawToolCall
|
|
121
|
+
: undefined;
|
|
122
|
+
const fn = toolCall?.function && typeof toolCall.function === "object" && !Array.isArray(toolCall.function)
|
|
123
|
+
? toolCall.function
|
|
124
|
+
: undefined;
|
|
125
|
+
const functionName = normalizeHermesRole(fn?.name);
|
|
126
|
+
if (functionName === "clawconnect_send_file")
|
|
127
|
+
return true;
|
|
128
|
+
if (functionName !== "terminal")
|
|
129
|
+
continue;
|
|
130
|
+
const rawArguments = typeof fn?.arguments === "string"
|
|
131
|
+
? parseJsonValue(fn.arguments)
|
|
132
|
+
: fn?.arguments;
|
|
133
|
+
const args = rawArguments && typeof rawArguments === "object" && !Array.isArray(rawArguments)
|
|
134
|
+
? rawArguments
|
|
135
|
+
: undefined;
|
|
136
|
+
if (typeof args?.command === "string" && isClawConnectSendFileCommand(args.command)) {
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
function isClawConnectSendFileCommand(command) {
|
|
144
|
+
return /(?:^|[\s;&|])(?:["'][^"']*clawconnect["']|[^\s;&|]*clawconnect)\s+send-file(?:\s|$)/i.test(command);
|
|
145
|
+
}
|
|
146
|
+
function parseJsonValue(value) {
|
|
147
|
+
try {
|
|
148
|
+
return JSON.parse(value);
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
return undefined;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/** Read only first-party terminal outcome records for the exact current turn. */
|
|
155
|
+
export function collectHermesFileTransferOutcome(messages, sourceRunId) {
|
|
156
|
+
const currentIndex = currentHermesTurnIndex(messages, sourceRunId);
|
|
157
|
+
if (currentIndex < 0 || !messages)
|
|
158
|
+
return undefined;
|
|
159
|
+
const outcomes = [];
|
|
160
|
+
for (const message of messages.slice(currentIndex + 1)) {
|
|
161
|
+
if (normalizeHermesRole(message.role) === "user")
|
|
162
|
+
break;
|
|
163
|
+
if (normalizeHermesRole(message.role) !== "tool" || normalizeHermesRole(message.tool_name) !== "terminal")
|
|
164
|
+
continue;
|
|
165
|
+
for (const record of terminalResultRecords(message)) {
|
|
166
|
+
if (record.protocol !== "clawconnect.hermes-file-transfer-outcome.v1"
|
|
167
|
+
|| record.sourceRunId !== sourceRunId
|
|
168
|
+
|| record.sourceRole !== "assistant"
|
|
169
|
+
|| record.status !== "completed"
|
|
170
|
+
|| record.exit_code !== 0
|
|
171
|
+
|| (record.kind !== "ordinary" && record.kind !== "clarification" && record.kind !== "attempted" && record.kind !== "cancelled"))
|
|
172
|
+
continue;
|
|
173
|
+
const assistantText = typeof record.assistantText === "string" ? record.assistantText.trim() : "";
|
|
174
|
+
if (record.kind !== "attempted" && !assistantText)
|
|
175
|
+
continue;
|
|
176
|
+
outcomes.push({
|
|
177
|
+
protocol: "clawconnect.hermes-file-transfer-outcome.v1",
|
|
178
|
+
kind: record.kind,
|
|
179
|
+
sourceRunId,
|
|
180
|
+
sourceRole: "assistant",
|
|
181
|
+
status: "completed",
|
|
182
|
+
...(assistantText ? { assistantText } : {}),
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
if (outcomes.length !== 1)
|
|
187
|
+
return undefined;
|
|
188
|
+
return outcomes[0];
|
|
189
|
+
}
|
|
190
|
+
export function collectHermesFileTransferEvidence(messages, sourceRunId) {
|
|
191
|
+
if (!messages) {
|
|
192
|
+
return [];
|
|
193
|
+
}
|
|
194
|
+
const currentIndex = currentHermesTurnIndex(messages, sourceRunId);
|
|
195
|
+
if (currentIndex < 0) {
|
|
196
|
+
return [];
|
|
197
|
+
}
|
|
198
|
+
const ids = new Set();
|
|
199
|
+
for (const message of messages.slice(currentIndex + 1)) {
|
|
200
|
+
if (normalizeHermesRole(message.role) === "user") {
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
if (normalizeHermesRole(message.role) !== "tool")
|
|
204
|
+
continue;
|
|
205
|
+
const toolName = normalizeHermesRole(message.tool_name);
|
|
206
|
+
if (toolName === "clawconnect_send_file") {
|
|
207
|
+
const receipt = parseJsonRecord(stringValue(message.content) ?? "");
|
|
208
|
+
if (receipt?.ok === true
|
|
209
|
+
&& receipt.sourceRunId === sourceRunId
|
|
210
|
+
&& receipt.status === "completed"
|
|
211
|
+
&& typeof receipt.fileId === "string"
|
|
212
|
+
&& /^file_[a-z0-9]+$/i.test(receipt.fileId)) {
|
|
213
|
+
ids.add(receipt.fileId);
|
|
214
|
+
}
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
// Only the legacy first-party terminal result is additional evidence. A
|
|
218
|
+
// delegate summary, wrapper output, or assistant claim cannot manufacture
|
|
219
|
+
// an attachment by repeating the command name and a success word.
|
|
220
|
+
if (toolName !== "terminal")
|
|
221
|
+
continue;
|
|
222
|
+
for (const record of terminalResultRecords(message)) {
|
|
223
|
+
if (record.sourceRunId !== sourceRunId
|
|
224
|
+
|| record.sourceRole !== "assistant"
|
|
225
|
+
|| record.status !== "completed"
|
|
226
|
+
|| record.exit_code !== 0
|
|
227
|
+
|| typeof record.fileId !== "string"
|
|
228
|
+
|| !/^file_[a-z0-9]+$/i.test(record.fileId)) {
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
ids.add(record.fileId);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return [...ids];
|
|
235
|
+
}
|
|
236
|
+
function currentHermesTurnIndex(messages, sourceRunId) {
|
|
237
|
+
if (!messages || !sourceRunId.trim())
|
|
238
|
+
return -1;
|
|
239
|
+
let currentIndex = -1;
|
|
240
|
+
for (let index = 0; index < messages.length; index += 1) {
|
|
241
|
+
const message = messages[index];
|
|
242
|
+
if (normalizeHermesRole(message?.role) === "user" && hermesSourceRunIdFromMessage(message) === sourceRunId) {
|
|
243
|
+
currentIndex = index;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return currentIndex;
|
|
247
|
+
}
|
|
248
|
+
function terminalResultRecords(message) {
|
|
249
|
+
const content = stringValue(message.content);
|
|
250
|
+
if (!content) {
|
|
251
|
+
return [];
|
|
252
|
+
}
|
|
253
|
+
const outer = parseJsonRecord(content);
|
|
254
|
+
if (!outer) {
|
|
255
|
+
return [];
|
|
256
|
+
}
|
|
257
|
+
const records = [outer];
|
|
258
|
+
const output = stringValue(outer.output);
|
|
259
|
+
if (output) {
|
|
260
|
+
for (const fragment of extractJsonObjects(output)) {
|
|
261
|
+
const record = parseJsonRecord(fragment);
|
|
262
|
+
if (record) {
|
|
263
|
+
// Hermes stores the command envelope's exit_code beside the textual
|
|
264
|
+
// send-file JSON payload; the payload itself carries the Relay fields.
|
|
265
|
+
records.push(record.exit_code === undefined && outer.exit_code !== undefined
|
|
266
|
+
? { ...record, exit_code: outer.exit_code }
|
|
267
|
+
: record);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return records;
|
|
272
|
+
}
|
|
273
|
+
function parseJsonRecord(value) {
|
|
274
|
+
try {
|
|
275
|
+
const parsed = JSON.parse(value);
|
|
276
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
277
|
+
? parsed
|
|
278
|
+
: undefined;
|
|
279
|
+
}
|
|
280
|
+
catch {
|
|
281
|
+
return undefined;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
function extractJsonObjects(value) {
|
|
285
|
+
const fragments = [];
|
|
286
|
+
let start = -1;
|
|
287
|
+
let depth = 0;
|
|
288
|
+
let inString = false;
|
|
289
|
+
let escaped = false;
|
|
290
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
291
|
+
const character = value[index];
|
|
292
|
+
if (inString) {
|
|
293
|
+
if (escaped) {
|
|
294
|
+
escaped = false;
|
|
295
|
+
}
|
|
296
|
+
else if (character === "\\") {
|
|
297
|
+
escaped = true;
|
|
298
|
+
}
|
|
299
|
+
else if (character === '"') {
|
|
300
|
+
inString = false;
|
|
301
|
+
}
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
if (character === '"') {
|
|
305
|
+
inString = true;
|
|
306
|
+
}
|
|
307
|
+
else if (character === "{") {
|
|
308
|
+
if (depth === 0) {
|
|
309
|
+
start = index;
|
|
310
|
+
}
|
|
311
|
+
depth += 1;
|
|
312
|
+
}
|
|
313
|
+
else if (character === "}" && depth > 0) {
|
|
314
|
+
depth -= 1;
|
|
315
|
+
if (depth === 0 && start >= 0) {
|
|
316
|
+
fragments.push(value.slice(start, index + 1));
|
|
317
|
+
start = -1;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return fragments;
|
|
322
|
+
}
|
|
323
|
+
//# sourceMappingURL=hermes-runtime-chat-file-transfer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hermes-runtime-chat-file-transfer.js","sourceRoot":"","sources":["../../../src/hermes/runtime/hermes-runtime-chat-file-transfer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { HermesUsageSnapshot } from "./hermes-runtime-types.js";
|
|
2
|
+
export type PreparedHermesMessage = {
|
|
3
|
+
apiMessage: string;
|
|
4
|
+
apiInstructions?: string;
|
|
5
|
+
cliMessage: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function prepareRequiredHermesMessage(rawMessage: string, attachments: unknown, sessionKey: string, sourceRunId: string | undefined): Promise<PreparedHermesMessage>;
|
|
8
|
+
export declare function sanitizeHermesUserAttachmentMarkers(message: string): string;
|
|
9
|
+
export declare function cleanupExpiredHermesInbox(inboxDir?: string, nowMs?: number, ttlMs?: number): Promise<void>;
|
|
10
|
+
export declare function buildHermesRuntimeContextHint(snapshot: HermesUsageSnapshot): string | undefined;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// Hermes 对话消息准备:附件落盘到 inbox、用户附件标记失活、运行时上下文提示与移动端轮次身份元数据。
|
|
2
|
+
import { randomUUID } from "crypto";
|
|
3
|
+
import { mkdir, readdir, rm, stat, writeFile } from "fs/promises";
|
|
4
|
+
import { join } from "path";
|
|
5
|
+
import { CLAWCONNECT_MOBILE_BRIDGE_HINT, HERMES_INBOX_DIR, } from "./hermes-runtime-process.js";
|
|
6
|
+
import { readCachedHermesStatusSnapshot } from "./hermes-runtime-usage.js";
|
|
7
|
+
import { compactStringArray, sanitizeFileName } from "./hermes-runtime-values.js";
|
|
8
|
+
const HERMES_RUNTIME_CONTEXT_CACHE_MAX_AGE_MS = 5 * 60_000;
|
|
9
|
+
const HERMES_INBOX_TTL_MS = 24 * 60 * 60 * 1000;
|
|
10
|
+
const USER_FILE_MARKER_PREFIX_RE = /\[file attached:/gi;
|
|
11
|
+
export async function prepareRequiredHermesMessage(rawMessage, attachments, sessionKey, sourceRunId) {
|
|
12
|
+
const preparedMessage = await prepareHermesMessage(rawMessage, attachments, sessionKey, sourceRunId);
|
|
13
|
+
if (!preparedMessage.cliMessage.trim()) {
|
|
14
|
+
throw new Error("message_required");
|
|
15
|
+
}
|
|
16
|
+
return preparedMessage;
|
|
17
|
+
}
|
|
18
|
+
const CLAWCONNECT_MOBILE_TURN_INSTRUCTION = "Use [ClawConnect mobile turn] metadata only for ClawConnect file-transfer attribution and message identity. Do not mention it in the answer.";
|
|
19
|
+
function buildClawConnectMobileTurnMetadata(sourceRunId, sessionKey) {
|
|
20
|
+
if (!sourceRunId) {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
// 这个块是 ClawConnect 和 Hermes history 的稳定身份合同;客户端展示时会剥离它。
|
|
24
|
+
return [
|
|
25
|
+
"[ClawConnect mobile turn]",
|
|
26
|
+
`sourceRunId: ${sourceRunId}`,
|
|
27
|
+
`sessionKey: ${sessionKey}`,
|
|
28
|
+
].join("\n");
|
|
29
|
+
}
|
|
30
|
+
async function prepareHermesMessage(message, attachments, sessionKey, sourceRunId) {
|
|
31
|
+
const refs = [];
|
|
32
|
+
if (Array.isArray(attachments)) {
|
|
33
|
+
await cleanupExpiredHermesInbox();
|
|
34
|
+
const safeSession = sessionKey.replace(/[^\w.-]/g, "_") || "main";
|
|
35
|
+
for (const attachment of attachments) {
|
|
36
|
+
if (!attachment || typeof attachment !== "object" || Array.isArray(attachment)) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const record = attachment;
|
|
40
|
+
if (typeof record.content !== "string" || record.content.length === 0) {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
const fileName = sanitizeFileName(typeof record.fileName === "string" ? record.fileName
|
|
44
|
+
: typeof record.name === "string" ? record.name
|
|
45
|
+
: `attachment-${randomUUID()}`);
|
|
46
|
+
const dir = join(HERMES_INBOX_DIR, safeSession, randomUUID());
|
|
47
|
+
await mkdir(dir, { recursive: true });
|
|
48
|
+
const filePath = join(dir, fileName);
|
|
49
|
+
await writeFile(filePath, Buffer.from(record.content, "base64"));
|
|
50
|
+
const mimeType = typeof record.mimeType === "string" ? record.mimeType : "application/octet-stream";
|
|
51
|
+
refs.push(`[file attached: ${filePath} (${mimeType})]`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const userSections = [sanitizeHermesUserAttachmentMarkers(message).trim()];
|
|
55
|
+
if (refs.length > 0) {
|
|
56
|
+
userSections.push(refs.join("\n"));
|
|
57
|
+
}
|
|
58
|
+
const runtimeHint = buildHermesRuntimeContextHint(readCachedHermesStatusSnapshot(HERMES_RUNTIME_CONTEXT_CACHE_MAX_AGE_MS));
|
|
59
|
+
const turnMetadata = buildClawConnectMobileTurnMetadata(sourceRunId, sessionKey);
|
|
60
|
+
const apiMessageSections = [...userSections];
|
|
61
|
+
if (turnMetadata) {
|
|
62
|
+
apiMessageSections.push(turnMetadata);
|
|
63
|
+
}
|
|
64
|
+
const apiInstructionSections = [
|
|
65
|
+
runtimeHint,
|
|
66
|
+
CLAWCONNECT_MOBILE_BRIDGE_HINT,
|
|
67
|
+
turnMetadata ? CLAWCONNECT_MOBILE_TURN_INSTRUCTION : undefined,
|
|
68
|
+
];
|
|
69
|
+
const cliMessageSections = [
|
|
70
|
+
...userSections,
|
|
71
|
+
runtimeHint,
|
|
72
|
+
CLAWCONNECT_MOBILE_BRIDGE_HINT,
|
|
73
|
+
turnMetadata
|
|
74
|
+
? [turnMetadata, CLAWCONNECT_MOBILE_TURN_INSTRUCTION].join("\n")
|
|
75
|
+
: undefined,
|
|
76
|
+
];
|
|
77
|
+
return {
|
|
78
|
+
apiMessage: apiMessageSections.filter(Boolean).join("\n\n").trim(),
|
|
79
|
+
apiInstructions: apiInstructionSections.filter(Boolean).join("\n\n").trim() || undefined,
|
|
80
|
+
cliMessage: cliMessageSections.filter(Boolean).join("\n\n").trim(),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
export function sanitizeHermesUserAttachmentMarkers(message) {
|
|
84
|
+
// Hermes 的本地文件提示只能由桥接层生成;让用户输入的同形标记失活,
|
|
85
|
+
// 避免把任意 Host 路径伪装成移动端附件交给运行时读取。
|
|
86
|
+
return message.replace(USER_FILE_MARKER_PREFIX_RE, "[file attached:");
|
|
87
|
+
}
|
|
88
|
+
export async function cleanupExpiredHermesInbox(inboxDir = HERMES_INBOX_DIR, nowMs = Date.now(), ttlMs = HERMES_INBOX_TTL_MS) {
|
|
89
|
+
let sessions;
|
|
90
|
+
try {
|
|
91
|
+
sessions = await readdir(inboxDir, { withFileTypes: true });
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
await Promise.all(sessions.filter((entry) => entry.isDirectory() && !entry.isSymbolicLink()).map(async (session) => {
|
|
97
|
+
const sessionDir = join(inboxDir, session.name);
|
|
98
|
+
let runs;
|
|
99
|
+
try {
|
|
100
|
+
runs = await readdir(sessionDir, { withFileTypes: true });
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
await Promise.all(runs.filter((entry) => entry.isDirectory() && !entry.isSymbolicLink()).map(async (run) => {
|
|
106
|
+
const runDir = join(sessionDir, run.name);
|
|
107
|
+
try {
|
|
108
|
+
const metadata = await stat(runDir);
|
|
109
|
+
if (nowMs - metadata.mtimeMs >= Math.max(0, ttlMs)) {
|
|
110
|
+
await rm(runDir, { recursive: true, force: true });
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
// 清理失败不能阻断当前聊天;下一轮发送会再次尝试。
|
|
115
|
+
}
|
|
116
|
+
}));
|
|
117
|
+
}));
|
|
118
|
+
}
|
|
119
|
+
export function buildHermesRuntimeContextHint(snapshot) {
|
|
120
|
+
const details = compactStringArray([
|
|
121
|
+
snapshot.currentModel ? `model=${snapshot.currentModel}` : undefined,
|
|
122
|
+
snapshot.provider ? `provider=${snapshot.provider}` : undefined,
|
|
123
|
+
]);
|
|
124
|
+
if (details.length === 0) {
|
|
125
|
+
return undefined;
|
|
126
|
+
}
|
|
127
|
+
return [
|
|
128
|
+
"[Hermes runtime context]",
|
|
129
|
+
`Current runtime: ${details.join(", ")}.`,
|
|
130
|
+
"If the user asks which model or provider is currently being used, answer from this runtime context.",
|
|
131
|
+
].join("\n");
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=hermes-runtime-chat-message.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hermes-runtime-chat-message.js","sourceRoot":"","sources":["../../../src/hermes/runtime/hermes-runtime-chat-message.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare function isHermesChatAbortedError(error: unknown): boolean;
|
|
2
|
+
export declare function recoverHermesCliSessionAfterAbort(params: {
|
|
3
|
+
sessionKey: string;
|
|
4
|
+
resume: string | undefined;
|
|
5
|
+
mappedResume: string | undefined;
|
|
6
|
+
activeHead: number | undefined;
|
|
7
|
+
sourceRunId: string | undefined;
|
|
8
|
+
}): Promise<void>;
|
|
9
|
+
export declare function requireVisibleHermesOutput(output: string): string;
|
|
10
|
+
export declare function recoverEmptyHermesApiOutputFromHistory(params: {
|
|
11
|
+
output: string;
|
|
12
|
+
hermesSessionId?: string;
|
|
13
|
+
sessionKey: string;
|
|
14
|
+
userMessage: string;
|
|
15
|
+
sourceRunId?: string;
|
|
16
|
+
abortSignal?: AbortSignal;
|
|
17
|
+
}): Promise<string | undefined>;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// Hermes 对话输出校验与恢复:可见输出约束、Provider 失败识别、API 空输出的历史回补以及 CLI 中止后的会话回卷。
|
|
2
|
+
import { forgetHermesSession } from "../hermes-session-store.js";
|
|
3
|
+
import { sanitizeHermesChatOutput } from "./hermes-runtime-process.js";
|
|
4
|
+
import { detectHermesHistoryCompletion } from "./hermes-runtime-history-completion.js";
|
|
5
|
+
import { rewindHermesSessionAfterActiveHead } from "./hermes-runtime-state-db.js";
|
|
6
|
+
const HERMES_API_EMPTY_OUTPUT_HISTORY_COMPLETION_TIMEOUT_MS = 12_000;
|
|
7
|
+
const HERMES_API_EMPTY_OUTPUT_HISTORY_COMPLETION_POLL_MS = 500;
|
|
8
|
+
const HERMES_EMPTY_RESPONSE_MESSAGE = "Hermes 未返回可见回复,请检查当前模型额度或 Provider 凭据后重试。";
|
|
9
|
+
export function isHermesChatAbortedError(error) {
|
|
10
|
+
return error instanceof Error && error.message === "hermes_chat_aborted";
|
|
11
|
+
}
|
|
12
|
+
export async function recoverHermesCliSessionAfterAbort(params) {
|
|
13
|
+
if (!params.resume) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
// Hermes CLI writes the new user row before it reacts to SIGTERM. Rewind
|
|
17
|
+
// only rows beyond the stable pre-run head so completed context remains
|
|
18
|
+
// resumable and the canceled row cannot be answered on the next request.
|
|
19
|
+
if (params.activeHead !== undefined && params.sourceRunId) {
|
|
20
|
+
const recovered = await rewindHermesSessionAfterActiveHead(params.resume, params.activeHead, params.sourceRunId);
|
|
21
|
+
if (recovered) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// Old/unavailable state.db schemas cannot provide a safe row boundary. For
|
|
26
|
+
// an implicit alias, fail closed by dropping only that alias instead of
|
|
27
|
+
// risking a replay of the canceled prompt. Explicit Hermes session ids are
|
|
28
|
+
// never silently deleted or remapped.
|
|
29
|
+
if (params.mappedResume !== params.resume) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
await forgetHermesSession(params.sessionKey, params.mappedResume);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// Abort delivery must not be replaced by a best-effort recovery failure.
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export function requireVisibleHermesOutput(output) {
|
|
40
|
+
const visibleOutput = sanitizeHermesChatOutput(output).trim();
|
|
41
|
+
if (!visibleOutput) {
|
|
42
|
+
// 空完成会让移动端永久留下无内容回复;没有可见文本时必须走显式失败事件。
|
|
43
|
+
throw new Error(HERMES_EMPTY_RESPONSE_MESSAGE);
|
|
44
|
+
}
|
|
45
|
+
if (isHermesProviderFailureOutput(visibleOutput)) {
|
|
46
|
+
// Hermes 某些 Provider 会以 exit 0 返回错误文本;这仍是失败,不能渲染成正常 assistant 回复。
|
|
47
|
+
throw new Error(visibleOutput);
|
|
48
|
+
}
|
|
49
|
+
return visibleOutput;
|
|
50
|
+
}
|
|
51
|
+
function isHermesProviderFailureOutput(output) {
|
|
52
|
+
const firstLine = output.split(/\r?\n/, 1)[0]?.trim() || "";
|
|
53
|
+
return /^(?:[❌✕x]\s*)?API call failed(?: after \d+ retries)?\s*:/i.test(firstLine)
|
|
54
|
+
|| /^(?:[❌✕x]\s*)?HTTP\s+(?:401|402|403|429|5\d\d)\b/i.test(firstLine)
|
|
55
|
+
|| /^Error code:\s*(?:401|402|403|429|5\d\d)\b/i.test(firstLine);
|
|
56
|
+
}
|
|
57
|
+
export async function recoverEmptyHermesApiOutputFromHistory(params) {
|
|
58
|
+
if (sanitizeHermesChatOutput(params.output).trim()) {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
if (!params.hermesSessionId?.trim()) {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
const deadline = Date.now() + HERMES_API_EMPTY_OUTPUT_HISTORY_COMPLETION_TIMEOUT_MS;
|
|
65
|
+
while (Date.now() <= deadline) {
|
|
66
|
+
if (params.abortSignal?.aborted) {
|
|
67
|
+
throw new Error("hermes_chat_aborted");
|
|
68
|
+
}
|
|
69
|
+
const detectedOutput = await detectHermesHistoryCompletion({
|
|
70
|
+
beforeSessions: [],
|
|
71
|
+
resume: params.hermesSessionId,
|
|
72
|
+
sessionKey: params.sessionKey,
|
|
73
|
+
userMessage: params.userMessage,
|
|
74
|
+
sourceRunId: params.sourceRunId,
|
|
75
|
+
});
|
|
76
|
+
if (detectedOutput) {
|
|
77
|
+
return detectedOutput;
|
|
78
|
+
}
|
|
79
|
+
const remainingMs = deadline - Date.now();
|
|
80
|
+
if (remainingMs <= 0) {
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
await sleep(Math.min(HERMES_API_EMPTY_OUTPUT_HISTORY_COMPLETION_POLL_MS, remainingMs));
|
|
84
|
+
}
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
async function sleep(ms) {
|
|
88
|
+
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=hermes-runtime-chat-output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hermes-runtime-chat-output.js","sourceRoot":"","sources":["../../../src/hermes/runtime/hermes-runtime-chat-output.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runSerializedHermesChat<T>(sessionKey: string, operation: () => Promise<T>): Promise<T>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Hermes 对话按 sessionKey 串行执行;队列状态只保存在本模块,保证同一会话的轮次严格按提交顺序处理。
|
|
2
|
+
const hermesChatQueues = new Map();
|
|
3
|
+
export async function runSerializedHermesChat(sessionKey, operation) {
|
|
4
|
+
const queueKey = sessionKey.trim() || "main";
|
|
5
|
+
const previous = hermesChatQueues.get(queueKey) ?? Promise.resolve();
|
|
6
|
+
const current = previous.catch(() => undefined).then(operation);
|
|
7
|
+
const stored = current.then(() => undefined, () => undefined);
|
|
8
|
+
hermesChatQueues.set(queueKey, stored);
|
|
9
|
+
try {
|
|
10
|
+
return await current;
|
|
11
|
+
}
|
|
12
|
+
finally {
|
|
13
|
+
if (hermesChatQueues.get(queueKey) === stored) {
|
|
14
|
+
hermesChatQueues.delete(queueKey);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=hermes-runtime-chat-queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hermes-runtime-chat-queue.js","sourceRoot":"","sources":["../../../src/hermes/runtime/hermes-runtime-chat-queue.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAyB,CAAC;AAE1D,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,UAAkB,EAClB,SAA2B;IAE3B,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,EAAE,IAAI,MAAM,CAAC;IAC7C,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IACrE,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAC9D,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACvC,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC;IACvB,CAAC;YAAS,CAAC;QACT,IAAI,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,MAAM,EAAE,CAAC;YAC9C,gBAAgB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;AACH,CAAC"}
|