arisa 5.1.24 → 5.1.49
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/package.json +2 -3
- package/src/core/agent/agent-manager.js +132 -70
- package/src/core/agent/pi-runtime.js +0 -8
- package/src/core/agent/system-shell-tool.js +13 -2
- package/src/core/artifacts/artifact-store.js +17 -18
- package/src/core/config/config-defaults.js +2 -2
- package/src/core/conversation/session-seed-store.js +85 -0
- package/src/core/tools/ipc-client.js +0 -2
- package/src/core/tools/tool-output-materializer.js +41 -0
- package/src/core/tools/tool-registry.js +96 -23
- package/src/official-tools.lock.json +145 -93
- package/src/runtime/doctor.js +1 -4
- package/src/runtime/headless-tool-executor.js +2 -32
- package/src/runtime/paths.js +7 -1
- package/src/runtime/restart-receipt.js +90 -0
- package/src/transport/telegram/bot.js +390 -1034
- package/src/transport/telegram/chat-queue.js +132 -0
- package/src/transport/telegram/media.js +2 -2
- package/src/transport/telegram/model-callback.js +211 -0
- package/src/transport/telegram/model-controls.js +164 -0
- package/src/transport/telegram/prompt-builders.js +372 -0
- package/src/transport/telegram/task-dispatcher.js +94 -0
- package/src/transport/telegram/update-command.js +1 -1
- package/src/transport/telegram/workspace-group.js +83 -0
- package/test/agent-tool-policy.test.js +7 -1
- package/test/context-and-task-bounds.test.js +9 -7
- package/test/doctor.test.js +2 -4
- package/test/model-selection.test.js +47 -1
- package/test/official-tool-dependencies.test.js +2 -0
- package/test/paths.test.js +4 -4
- package/test/restart-receipt.test.js +39 -0
- package/test/session-start-operational-notes.test.js +47 -0
- package/test/telegram-prompt-builders.test.js +33 -0
- package/test/telegram-task-dispatcher.test.js +102 -0
- package/test/telegram-workspace-group.test.js +76 -0
- package/test/tool-registry-run.test.js +62 -0
- package/test/topic-initialization.test.js +66 -0
- package/src/core/conversation/conversation-history-store.js +0 -142
|
@@ -16,17 +16,53 @@ function toolEnv() {
|
|
|
16
16
|
return { ...process.env, ARISA_PACKAGE_DIR: arisaPackageDir, ARISA_IPC_SOCKET: arisaIpcSocketFile };
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
const defaultToolHelpTimeoutMs = 10_000;
|
|
20
|
+
const defaultToolRunTimeoutMs = 30 * 60_000;
|
|
21
|
+
const defaultToolKillGraceMs = 2_000;
|
|
22
|
+
|
|
23
|
+
function positiveDuration(value, fallback) {
|
|
24
|
+
return Number.isFinite(value) && value > 0 ? value : fallback;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function waitForToolProcess(child, { timeoutMs, killGraceMs, label }) {
|
|
28
|
+
return new Promise((resolve, reject) => {
|
|
29
|
+
let timedOut = false;
|
|
30
|
+
let forceTimer = null;
|
|
31
|
+
const timeout = setTimeout(() => {
|
|
32
|
+
timedOut = true;
|
|
33
|
+
child.kill("SIGTERM");
|
|
34
|
+
forceTimer = setTimeout(() => child.kill("SIGKILL"), killGraceMs);
|
|
35
|
+
}, timeoutMs);
|
|
36
|
+
|
|
37
|
+
const finish = (callback, value) => {
|
|
38
|
+
clearTimeout(timeout);
|
|
39
|
+
clearTimeout(forceTimer);
|
|
40
|
+
callback(value);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
child.once("error", (error) => finish(reject, error));
|
|
44
|
+
child.once("close", (code) => {
|
|
45
|
+
if (!timedOut) {
|
|
46
|
+
finish(resolve, code);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const error = new Error(`${label} timed out after ${timeoutMs}ms`);
|
|
50
|
+
error.code = "TOOL_PROCESS_TIMEOUT";
|
|
51
|
+
finish(reject, error);
|
|
52
|
+
});
|
|
27
53
|
});
|
|
28
54
|
}
|
|
29
55
|
|
|
56
|
+
async function runProcess(command, args, { timeoutMs, killGraceMs, label, ...options } = {}) {
|
|
57
|
+
const child = spawn(command, args, { ...options, stdio: ["ignore", "pipe", "pipe"] });
|
|
58
|
+
let stdout = "";
|
|
59
|
+
let stderr = "";
|
|
60
|
+
child.stdout.on("data", (d) => { stdout += d.toString(); });
|
|
61
|
+
child.stderr.on("data", (d) => { stderr += d.toString(); });
|
|
62
|
+
const code = await waitForToolProcess(child, { timeoutMs, killGraceMs, label });
|
|
63
|
+
return { code, stdout, stderr };
|
|
64
|
+
}
|
|
65
|
+
|
|
30
66
|
function requirementNames(requirements) {
|
|
31
67
|
if (Array.isArray(requirements)) {
|
|
32
68
|
return requirements.map((item) => typeof item === "string" ? item : item?.name).filter(Boolean);
|
|
@@ -121,7 +157,7 @@ export function createToolOutputParser(name, { onEvent, maxFrameBytes = 1_048_57
|
|
|
121
157
|
};
|
|
122
158
|
}
|
|
123
159
|
|
|
124
|
-
async function runToolProcess(command, args, { onEvent, maxFrameBytes, ...options } = {}) {
|
|
160
|
+
async function runToolProcess(command, args, { onEvent, maxFrameBytes, timeoutMs, killGraceMs, label, ...options } = {}) {
|
|
125
161
|
const child = spawn(command, args, { ...options, stdio: ["ignore", "pipe", "pipe"] });
|
|
126
162
|
const parser = createToolOutputParser(path.basename(args[0] || command), { onEvent, maxFrameBytes });
|
|
127
163
|
const stderrChunks = [];
|
|
@@ -139,13 +175,15 @@ async function runToolProcess(command, args, { onEvent, maxFrameBytes, ...option
|
|
|
139
175
|
}
|
|
140
176
|
return Buffer.concat(stderrChunks).toString("utf8");
|
|
141
177
|
})();
|
|
142
|
-
const exitPromise = new Promise((resolve, reject) => {
|
|
143
|
-
child.once("error", reject);
|
|
144
|
-
child.once("close", resolve);
|
|
145
|
-
});
|
|
146
178
|
child.stdout.resume();
|
|
147
179
|
child.stderr.resume();
|
|
148
|
-
|
|
180
|
+
let code;
|
|
181
|
+
try {
|
|
182
|
+
code = await waitForToolProcess(child, { timeoutMs, killGraceMs, label });
|
|
183
|
+
} catch (error) {
|
|
184
|
+
await Promise.allSettled([stdoutTask, stderrTask]);
|
|
185
|
+
throw error;
|
|
186
|
+
}
|
|
149
187
|
const [parsed, stderr] = await Promise.all([stdoutTask, stderrTask]);
|
|
150
188
|
return { code, parsed, stderr };
|
|
151
189
|
}
|
|
@@ -228,17 +266,26 @@ async function readOfficialToolNames() {
|
|
|
228
266
|
}
|
|
229
267
|
|
|
230
268
|
export class ToolRegistry {
|
|
231
|
-
constructor({
|
|
269
|
+
constructor({
|
|
270
|
+
logger,
|
|
271
|
+
usageStore = new ToolUsageStore(),
|
|
272
|
+
resolveOfficialToolNames = readOfficialToolNames,
|
|
273
|
+
helpTimeoutMs = defaultToolHelpTimeoutMs,
|
|
274
|
+
runTimeoutMs = defaultToolRunTimeoutMs,
|
|
275
|
+
killGraceMs = defaultToolKillGraceMs
|
|
276
|
+
} = {}) {
|
|
232
277
|
this.logger = logger;
|
|
278
|
+
this.helpTimeoutMs = positiveDuration(helpTimeoutMs, defaultToolHelpTimeoutMs);
|
|
279
|
+
this.runTimeoutMs = positiveDuration(runTimeoutMs, defaultToolRunTimeoutMs);
|
|
280
|
+
this.killGraceMs = positiveDuration(killGraceMs, defaultToolKillGraceMs);
|
|
233
281
|
this.tools = new Map();
|
|
234
282
|
this.skillRegistry = new SkillRegistry();
|
|
235
283
|
this.usageStore = usageStore;
|
|
236
284
|
this.resolveOfficialToolNames = resolveOfficialToolNames;
|
|
237
285
|
}
|
|
238
286
|
|
|
239
|
-
async
|
|
240
|
-
|
|
241
|
-
|
|
287
|
+
async buildSnapshot() {
|
|
288
|
+
const snapshot = new Map();
|
|
242
289
|
let entries = [];
|
|
243
290
|
try {
|
|
244
291
|
entries = await readdir(userToolsRoot, { withFileTypes: true });
|
|
@@ -253,12 +300,12 @@ export class ToolRegistry {
|
|
|
253
300
|
const configPath = path.join(toolDir, "config.js");
|
|
254
301
|
try {
|
|
255
302
|
const manifest = JSON.parse(await readFile(manifestPath, "utf8"));
|
|
256
|
-
if (
|
|
303
|
+
if (snapshot.has(manifest.name)) continue;
|
|
257
304
|
const configSource = await readFile(configPath, "utf8");
|
|
258
305
|
const defaults = parseConfigModule(configSource);
|
|
259
306
|
const config = await loadToolConfig(manifest.name, defaults);
|
|
260
307
|
const skillHints = this.skillRegistry.normalizeHints(manifest);
|
|
261
|
-
|
|
308
|
+
snapshot.set(manifest.name, {
|
|
262
309
|
...manifest,
|
|
263
310
|
toolDependencies: normalizeToolDependencies(manifest.toolDependencies),
|
|
264
311
|
category: normalizeCategory(manifest.category),
|
|
@@ -275,8 +322,13 @@ export class ToolRegistry {
|
|
|
275
322
|
// ignore invalid tool dirs in v1
|
|
276
323
|
}
|
|
277
324
|
}
|
|
325
|
+
return snapshot;
|
|
326
|
+
}
|
|
278
327
|
|
|
279
|
-
|
|
328
|
+
async load() {
|
|
329
|
+
const snapshot = await this.buildSnapshot();
|
|
330
|
+
this.tools = snapshot;
|
|
331
|
+
this.logger?.log("tools", `loaded ${snapshot.size} tool(s)`);
|
|
280
332
|
}
|
|
281
333
|
|
|
282
334
|
list() {
|
|
@@ -333,7 +385,13 @@ export class ToolRegistry {
|
|
|
333
385
|
async help(name) {
|
|
334
386
|
const tool = this.get(name);
|
|
335
387
|
if (!tool) throw new Error(`Tool not found: ${name}`);
|
|
336
|
-
const result = await runProcess("node", [tool.entry, "--help"], {
|
|
388
|
+
const result = await runProcess("node", [tool.entry, "--help"], {
|
|
389
|
+
cwd: tool.dir,
|
|
390
|
+
env: toolEnv(),
|
|
391
|
+
timeoutMs: this.helpTimeoutMs,
|
|
392
|
+
killGraceMs: this.killGraceMs,
|
|
393
|
+
label: `Tool help for ${name}`
|
|
394
|
+
});
|
|
337
395
|
const help = result.stdout || result.stderr;
|
|
338
396
|
const skills = await this.resolveSkills(name);
|
|
339
397
|
const sections = [
|
|
@@ -443,7 +501,10 @@ export class ToolRegistry {
|
|
|
443
501
|
cwd: tool.dir,
|
|
444
502
|
env: toolEnv(),
|
|
445
503
|
onEvent,
|
|
446
|
-
maxFrameBytes: daemonConfigDefaults.ipcFrameBytes
|
|
504
|
+
maxFrameBytes: daemonConfigDefaults.ipcFrameBytes,
|
|
505
|
+
timeoutMs: this.runTimeoutMs,
|
|
506
|
+
killGraceMs: this.killGraceMs,
|
|
507
|
+
label: `Tool run for ${name}`
|
|
447
508
|
});
|
|
448
509
|
if (processResult.stderr.trim()) {
|
|
449
510
|
this.logger?.log("tools", `${name} stderr: ${processResult.stderr.trim()}`);
|
|
@@ -460,6 +521,18 @@ export class ToolRegistry {
|
|
|
460
521
|
}
|
|
461
522
|
return normalized;
|
|
462
523
|
} catch (error) {
|
|
524
|
+
if (error?.code === "TOOL_PROCESS_TIMEOUT") {
|
|
525
|
+
return normalizeToolResult(name, {
|
|
526
|
+
ok: false,
|
|
527
|
+
status: "outcome_uncertain",
|
|
528
|
+
error: error.message,
|
|
529
|
+
resolution: {
|
|
530
|
+
type: "status_check_required",
|
|
531
|
+
retry: false,
|
|
532
|
+
message: "The tool process was terminated after timing out. Check external state before retrying."
|
|
533
|
+
}
|
|
534
|
+
});
|
|
535
|
+
}
|
|
463
536
|
return normalizeToolResult(name, {
|
|
464
537
|
ok: false,
|
|
465
538
|
error: error?.message || `Invalid tool response for ${name}`
|
|
@@ -1,8 +1,100 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 1,
|
|
3
3
|
"repository": "https://github.com/clasen/Arisa.git",
|
|
4
|
-
"commit": "
|
|
4
|
+
"commit": "aaec12e4f63f4959462b26380e7d4c1a60562586",
|
|
5
5
|
"tools": {
|
|
6
|
+
"browser-session-bridge": {
|
|
7
|
+
"version": "0.1.0",
|
|
8
|
+
"files": {
|
|
9
|
+
"bridge-server.js": "87f5a392bc99fd97899836c0731b4694402b04d5dfbe88e66bb4f496bfef351d",
|
|
10
|
+
"chrome-web-store.js": "a6bd9553f1490d5ccda3fe3044c30ee6fe243f422e69a5000bc844884e6d1e95",
|
|
11
|
+
"config.js": "45c8e9e9a159b9125d6ea3458c616926c2ba2b5327fdfd750aa05316d3ce5af8",
|
|
12
|
+
"extension/icons/icon-128.png": "a55af49bb570bd5471fc0a2e15a6bcaf3f76a2c5e7439f16bb1829682b343380",
|
|
13
|
+
"extension/icons/icon-16.png": "a4aedb49e2227222a68dc56455812a9e17938fd197b1f30268f02d6c9f7bf95e",
|
|
14
|
+
"extension/icons/icon-32.png": "2dfc9e6e7ec6b4e9feb9c1326d65116cda8e53306c65c84074c818c9e7f6a2a2",
|
|
15
|
+
"extension/icons/icon-48.png": "2f316f1f2fbc72227e7e1f14cf1ff1553a12fc9aab139799f1ee2970c0303deb",
|
|
16
|
+
"extension/manifest.json": "3e19d7b1c2a9521745b585fbbb3a6f4639d3056703fdbca17e8cd6dd80fc4c91",
|
|
17
|
+
"extension/popup.css": "138811e3e96e9c7741f064f8cf017be75973cd0942efa9668e96a584b7b52c1c",
|
|
18
|
+
"extension/popup.html": "9d7798efd04c57c534840a7966dd3818f9264022c52390f0fd1d462236a01d60",
|
|
19
|
+
"extension/popup.js": "60ea83f17e5d87f072d27c6540b903361f70e03925c3727983cca6beba9696d3",
|
|
20
|
+
"index.js": "4c92afffaec61910e3522f483535c760e8c660604158a23628d2807daa024934",
|
|
21
|
+
"package-lock.json": "e1081b8b48c2eaaeca73c63e64902519b33e8822ce351a45afe8509224776c12",
|
|
22
|
+
"package.json": "b54fad02442d9d09fb42d6c1fa01bb2e441e946babdf73dbc7e5767002a07b28",
|
|
23
|
+
"README.md": "fc2848472b48627838b757bf1a7be9564f31e483e8b673bd4ae95a11016f3309",
|
|
24
|
+
"session-browser.js": "d5544db5c6712327e76b8436cfabe02e34d8e043ff2d251c2c5ff3f00f1a9dd7",
|
|
25
|
+
"session-store.js": "56b33e1a342ba148cb4443e03435e5c728db60903ecd0ae87c05fbff3ca881ab",
|
|
26
|
+
"test/device-enrollment.test.js": "3dd36d37044eaf1043bd8b2e9f10ead9dc87479152a07237ab87d50146782f4c",
|
|
27
|
+
"test/session-refresh.test.js": "8f5facb81444f0d09928d48f22e82112d47bde21927afcd7fd830ce6832b9f79",
|
|
28
|
+
"tool.manifest.json": "40326de8bc08f2fd51ce51d4a20637b9af37de588d6cb97d27bc0b0d16304095",
|
|
29
|
+
"web-store/listing.md": "914e7c38bc67e19f3afbea86288c0cbc49afcb8941f4734fd3f786c5533861e7",
|
|
30
|
+
"web-store/privacy-policy.md": "c96e84f1a112e5949a3e7bd952fcf5ec794eaa5c4bee14a1dbe0c8e0f5888fb7"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"campaign-draft-runner": {
|
|
34
|
+
"version": "0.3.3",
|
|
35
|
+
"toolDependencies": {
|
|
36
|
+
"pr-campaign": "^0.1.0",
|
|
37
|
+
"gmail-workspace": "^0.1.0"
|
|
38
|
+
},
|
|
39
|
+
"files": {
|
|
40
|
+
"README.md": "fb73d47f6825a1c9b419f6667a319c2cbd959dc7b56c488321db72a6e2210a41",
|
|
41
|
+
"config.js": "23b95ad1851e498310eb400b1d53c648c280ddcc73cf91f6fa0ae5dc470ae6d2",
|
|
42
|
+
"index.js": "28d58096adb76e00d74b23ef10816199a5af57e13866ed6ab829da2535d73890",
|
|
43
|
+
"operation-timeout.js": "9b1ced30ec9ed710bb9118b91f6f3feded5111a08e1e21abf163e4cfb91d7ad2",
|
|
44
|
+
"package.json": "a25b7ed1dd2c30cd68c3c10feb8ee1752cac8cd55cd4344690ffad649e231ec1",
|
|
45
|
+
"product-facts.js": "69339e20e7b70a6b9833878d72b10b70ea4ede4aa448097975d0961b6aaced59",
|
|
46
|
+
"search-quality.js": "ab5412d45d5144e976cccef52992e634c11aca0e21b73fd53f9dc2d489c56dd7",
|
|
47
|
+
"source-exhaustion.js": "407f940f5205eb01715a797672d0dad8bd0b0b897024b5fcb87052a062ecd054",
|
|
48
|
+
"telemetry.js": "bab44341ae2176c8a29eed19b89db4e7e251c9938af163ecd85293917d94bfb5",
|
|
49
|
+
"test/selection-policy.test.js": "27dacdc6ac3b1c570229ef624267c5bf7e4b9606dbb71214c2a451a30ac3762b",
|
|
50
|
+
"test/telemetry.test.js": "e297727e382163f18ab0ec4a21f55bf7e47790939510b615fd8e38c4dfc1998f",
|
|
51
|
+
"tool.manifest.json": "1eacb9ccdf0b37bba9745ba20ce3462548bac28c7abb15214e5502e7e53d3e0d"
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
"creator-scout": {
|
|
55
|
+
"version": "1.0.1",
|
|
56
|
+
"files": {
|
|
57
|
+
"README.md": "4f50850317c0875ad7ddea767c7dda112669112bec107a98e67a31a42787b82c",
|
|
58
|
+
"config.js": "bab728665650b986c0eaef8e1be1c259ec42b1f83df4217c9780f5468d3c7666",
|
|
59
|
+
"index.js": "d1266d622b6abaf77ce1fe93823d4f2faedb8a5991371997c364082a198dc728",
|
|
60
|
+
"package-lock.json": "ed479120b59c2d9b083991dea60eb7750ba36bc7b2c7defb01cfb598889b8d90",
|
|
61
|
+
"package.json": "ad463eeddea6a958ef291d58f216c0b42c5ff3b398b62ed9512b857ea5e4b672",
|
|
62
|
+
"reference-match.js": "762d822ad31f89c06cb5a40f84ba3f864436db486375ed30e48bde94de282c7c",
|
|
63
|
+
"test/reference-match.test.js": "701ce83396126b1e42bd3a54e331ff011a1fc27646a0f3aa99ce1c3e576aff6d",
|
|
64
|
+
"tool.manifest.json": "0617b0488035fd7f8a83a8e5a698558b3d0e956e7ea1e043e2e80bb224d4974f"
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"gmail-workspace": {
|
|
68
|
+
"version": "0.1.1",
|
|
69
|
+
"files": {
|
|
70
|
+
"config.js": "6ad295ec4cedbc936835d8f86c7528e0939ef09d5792c003308d2ee85dc5eea4",
|
|
71
|
+
"index.js": "c4b1c27a3c5d2309501b695058da73f6287e2a6239f6e2384c05daae8ee25d43",
|
|
72
|
+
"package.json": "ba87edd5a148da9e99af6b3ab71a0024b86e1a469d56f548c7eeb253bb431f5d",
|
|
73
|
+
"secretary-state.js": "afc27732670420bccf1ce56ce715676dd2266de9f2d36a92015a93842755094a",
|
|
74
|
+
"test/secretary-state.test.mjs": "3aea05524a4ad5ebcb79c6aa1db94fcd009ac8ae69414c8f950b32a32af94370",
|
|
75
|
+
"tool.manifest.json": "2860c5684b9b9532ab4675f5cc5b96238320209086b132a5eda74ba99b6c294a"
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
"magnific-mcp": {
|
|
79
|
+
"version": "0.1.1",
|
|
80
|
+
"toolDependencies": {
|
|
81
|
+
"mcp-client": "^0.1.0"
|
|
82
|
+
},
|
|
83
|
+
"files": {
|
|
84
|
+
"README.md": "519b68d10c80112f475ab173394e937b0fc5930758415c1fc65ea2f5536b6371",
|
|
85
|
+
"config.js": "98a629781a1b2541806050952aa78a1e6e1b1671a6f1df7ba36c70dd116936a7",
|
|
86
|
+
"delivery-claims.js": "52f05a5bd1ece1ab21f7d9a49f362f9c55f101ef5723efd642dbecf0236921cd",
|
|
87
|
+
"generation-watch-close.js": "0dd780280eef870d2f11cb1800e6e9de19e5ead7b9d02b9983852cc8ddbdc79b",
|
|
88
|
+
"generation-watch-plan.js": "eb60660341f254adc224181ca19dbbb969ef1d676aeaab60b71a8567f52648fe",
|
|
89
|
+
"index.js": "0dcbd84ad03ab59919df57081d34a45c3a8d59b3c37ac31249409210ae7107e6",
|
|
90
|
+
"magnific-api.js": "39fa9a122577029111965c3e8487565c88ce46b61dec5ca685acf1c76cd3b636",
|
|
91
|
+
"network.js": "b45e43b49eea98ca7d80921ebfa6daf8b0a85d2079d4653f9eda682bc82101ae",
|
|
92
|
+
"package.json": "9c44eb43a3555cf79bd327318f9a30d3060f22dd2fd534923e303cca1eed7de9",
|
|
93
|
+
"state-store.js": "c3ee744509f7a6be251cd895406bd1c70827f53cbdc1ac9d1c2a6e48479bfe1e",
|
|
94
|
+
"test/magnific-mcp.test.js": "7a61dd19a2f6f9f48213cabf0de6e87e0b6fb73a94f0ea9dbfe9c8568c2cc32d",
|
|
95
|
+
"tool.manifest.json": "ff886d95250d279eff097430e6f89405a2bdd488d5f0949277cbc3f57f918950"
|
|
96
|
+
}
|
|
97
|
+
},
|
|
6
98
|
"master-slave": {
|
|
7
99
|
"files": {
|
|
8
100
|
"README.md": "84d2841d8df31c07065d4fee6e434dc43cad241f3abf63e95efafad51ed69fcb",
|
|
@@ -53,38 +145,19 @@
|
|
|
53
145
|
"tool.manifest.json": "5659c398922c914c5bf893404519a30071ee685ab49f34a650ecafd585b4d6ec"
|
|
54
146
|
}
|
|
55
147
|
},
|
|
56
|
-
"
|
|
57
|
-
"version": "
|
|
58
|
-
"toolDependencies": {
|
|
59
|
-
"mcp-client": "^0.1.0"
|
|
60
|
-
},
|
|
61
|
-
"files": {
|
|
62
|
-
"README.md": "00342fc9ae98f38716aeb332941524336c0e9ee4a5020104e52e7ed7b61882f9",
|
|
63
|
-
"config.js": "98a629781a1b2541806050952aa78a1e6e1b1671a6f1df7ba36c70dd116936a7",
|
|
64
|
-
"delivery-claims.js": "52f05a5bd1ece1ab21f7d9a49f362f9c55f101ef5723efd642dbecf0236921cd",
|
|
65
|
-
"generation-watch-plan.js": "eb60660341f254adc224181ca19dbbb969ef1d676aeaab60b71a8567f52648fe",
|
|
66
|
-
"index.js": "da7d35f2685fa0d5e716073f20725d7a5a4a0c477a1982b106a314662641b989",
|
|
67
|
-
"magnific-api.js": "39fa9a122577029111965c3e8487565c88ce46b61dec5ca685acf1c76cd3b636",
|
|
68
|
-
"network.js": "b45e43b49eea98ca7d80921ebfa6daf8b0a85d2079d4653f9eda682bc82101ae",
|
|
69
|
-
"package.json": "10ded9e89c13b500208717610984fd837e67e82ac3b31b21fe0058bd53c22a96",
|
|
70
|
-
"state-store.js": "c3ee744509f7a6be251cd895406bd1c70827f53cbdc1ac9d1c2a6e48479bfe1e",
|
|
71
|
-
"test/magnific-mcp.test.js": "c6345e70a7834a22df49abaf648c781f4da2e4d0790cbc13035c8af433c814c5",
|
|
72
|
-
"tool.manifest.json": "bbb24f54814c67f1ca1e119e6767e59d48f8e0cbc7f92444cf8e22fcc2fe06ed"
|
|
73
|
-
}
|
|
74
|
-
},
|
|
75
|
-
"campaign-draft-runner": {
|
|
76
|
-
"version": "0.1.0",
|
|
148
|
+
"official-tool-sync": {
|
|
149
|
+
"version": "1.0.0",
|
|
77
150
|
"toolDependencies": {
|
|
78
|
-
"
|
|
79
|
-
"gmail-workspace": "^0.1.0"
|
|
151
|
+
"trash": "^1.0.0"
|
|
80
152
|
},
|
|
81
153
|
"files": {
|
|
82
|
-
"
|
|
83
|
-
"config.js": "
|
|
84
|
-
"index.js": "
|
|
85
|
-
"package.json": "
|
|
86
|
-
"
|
|
87
|
-
"
|
|
154
|
+
".gitignore": "4d56952b0fb13bf8f9b6c13a6d4c34a075bac3af447636a1df4335d7576e2f97",
|
|
155
|
+
"config.js": "744c445b1d2ff65b77f38a5473c24e50a32f4288c4a08c25a874a478086c08c8",
|
|
156
|
+
"index.js": "fdd4167c63cd33c8e7640cb7ce09fd618dbd416030aa920407392e4591543e94",
|
|
157
|
+
"package.json": "4447cb5d4e0a04526604dfb9820c44af88349c27e208f27baa148686846559da",
|
|
158
|
+
"sync-lib.js": "c9f2cd7e19370088ab5fd10f6b2ada52c07d2e405674a356d0989f9a0f4984f6",
|
|
159
|
+
"sync-lib.test.js": "c97cf850d9f42f6b121a458863b048bdcaa6d7d0475642f20742c5862ebf7cc4",
|
|
160
|
+
"tool.manifest.json": "8e0f94ad786bdaf9edb1a65cd03438e26c1e9927e8db9a5a39e349e7ef3c6cd3"
|
|
88
161
|
}
|
|
89
162
|
},
|
|
90
163
|
"pr-campaign": {
|
|
@@ -99,15 +172,44 @@
|
|
|
99
172
|
"tool.manifest.json": "9c68d89276996039b055c43b4b4f82499ea684edbb36d9bfedcc909a3a23a80f"
|
|
100
173
|
}
|
|
101
174
|
},
|
|
102
|
-
"
|
|
175
|
+
"process-retrospective": {
|
|
176
|
+
"version": "1.1.0",
|
|
177
|
+
"files": {
|
|
178
|
+
"README.md": "798c5c34893dccabe2101be91581b1845359fb57744efcc56a2b5beb83712c15",
|
|
179
|
+
"config.js": "30703e809f0a2c4b85ffb1e1f9cd7ee599224e9bc62c3bc19e71e271cbc72b5d",
|
|
180
|
+
"index.js": "9bd1ae078293211387ee3035b4c4dc7cc5852d08503cd55cf5fb3187cf1ace34",
|
|
181
|
+
"package.json": "491b490a8c7f5db0fef1202f5d3059f1cc2dd75a84c6668f9fd2f5c81c1a4240",
|
|
182
|
+
"reflection-plan.js": "6c7e088385d39d2e3ba4f74c2d6dd94194e6a506f4ac263e552d34d9c2335488",
|
|
183
|
+
"state-store.js": "6d0d39bff7e5e16558123c088eb8946bf3758596ae974598936b94424618c7cf",
|
|
184
|
+
"test/reflection-plan.test.js": "d7c5953b5c5ba6fed4c403d64affce3f2b70b7975c1f28edcd1b902651fbe727",
|
|
185
|
+
"tool.manifest.json": "33440c26660f74dc381c4b4cc5f8487f4764693a352d37ae7ae2ef67e669754f"
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
"telemetry-ledger": {
|
|
103
189
|
"version": "0.1.0",
|
|
104
190
|
"files": {
|
|
105
|
-
"
|
|
106
|
-
"
|
|
107
|
-
"
|
|
108
|
-
"
|
|
109
|
-
"
|
|
110
|
-
"
|
|
191
|
+
"README.md": "4cf1b8c7addaa0f6a2d802a7ae261293822c2662efac9c10afa844f9fbcf4e1d",
|
|
192
|
+
"analysis.js": "c0effbff3af519b018e59c0460d2c277b4f7e1422ca2680de217bcb5e8a13136",
|
|
193
|
+
"config.js": "ddc8543cde5aeda634b8df60628d0024bb03e65b8710cf4878b4c6a7d953a641",
|
|
194
|
+
"index.js": "7df14d142a70b725b32ee40741ce1007fd96a080f96a9b2e3e34d917d88621b5",
|
|
195
|
+
"package.json": "e662652038c1c5a6a2a4502b308ae89e1acbd3cb6d3fc494512a730ebe9ccb8a",
|
|
196
|
+
"stats.js": "fc41b065d1f280dc278c53dc4c4baaa385a5bf25416c3e4ff8a153ea624967fb",
|
|
197
|
+
"storage.js": "099187e270ccc2bd6d7300b78a2ee31a837f98694a23a3b40b20a646cdb1db1e",
|
|
198
|
+
"test/telemetry.test.js": "312eef22ad960b19a6fe777aecd520952ae20ed03168edbbef8a0f747bee01c0",
|
|
199
|
+
"tool.manifest.json": "e4b321a56db9030e5b39b764547769c76bcf282ed019ebba0323bf16a73dbe05",
|
|
200
|
+
"validation.js": "1a50c75a5ca1bb7249bb8bfc3f2927b31ff4accd0efb56a48c36df5adae78f61"
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
"trash": {
|
|
204
|
+
"version": "1.0.0",
|
|
205
|
+
"files": {
|
|
206
|
+
".gitignore": "4d56952b0fb13bf8f9b6c13a6d4c34a075bac3af447636a1df4335d7576e2f97",
|
|
207
|
+
"config.js": "ad76578e9dcc05c2e45854de9fa2cd41285fd8dcdb9a7d9ee2056e0f8b2d68d6",
|
|
208
|
+
"index.js": "d562d2466bddc93dd9a3bc5455962a3457c50368ee5dde0607cae3ff5a88578a",
|
|
209
|
+
"package.json": "18ec594d43b6595c587b16125b9ce0c9426fdf00a28d7e342834e31e360575f8",
|
|
210
|
+
"tool.manifest.json": "4f236d274c891b55e4445d459cff6a3337a5d13adc5e8aca7fb965ff6aba4e4d",
|
|
211
|
+
"trash-store.js": "1318e0f9539292684c0c2ec2f1b7189f066fdba42f78e07821b067792f40e8c9",
|
|
212
|
+
"trash-store.test.js": "5647edba4ab5e5492764ccf8ba3e674e42b63942623d779b0bf69465c5adb53f"
|
|
111
213
|
}
|
|
112
214
|
},
|
|
113
215
|
"x-campaign-runner": {
|
|
@@ -126,66 +228,16 @@
|
|
|
126
228
|
},
|
|
127
229
|
"x-dm": {
|
|
128
230
|
"version": "0.2.0",
|
|
231
|
+
"toolDependencies": {
|
|
232
|
+
"browser-session-bridge": "^0.1.0"
|
|
233
|
+
},
|
|
129
234
|
"files": {
|
|
130
|
-
"README.md": "f02835c10d822ce906df121441761de8c6d61c3a4aac3f9aa9a6d9211b73a6ea",
|
|
131
235
|
"config.js": "69a2dcccd10aa2f1ddcc24d52f4ce8fe4a6f5f5a85be64abbdf9dc9e19de0cd4",
|
|
132
|
-
"index.js": "
|
|
236
|
+
"index.js": "83e3eb7fbeea8a5183303e0e56b1d6854ca7ccb800e4cd2ad689a5f13637380f",
|
|
133
237
|
"package.json": "3a76a921b1e78e91b1d2a5ae1926b298dfd6b4ee3f716d5382159b474ee400f4",
|
|
238
|
+
"README.md": "503b0ed25ef9a8df3079523ea653178e6e029854b4d199cb8d20be82cc837f9e",
|
|
134
239
|
"test/x-dm.test.mjs": "06352996e14777358eb62ad5e5d757b0dab5c0696927ed54ff40a5b7cdefcfd0",
|
|
135
|
-
"tool.manifest.json": "
|
|
136
|
-
}
|
|
137
|
-
},
|
|
138
|
-
"official-tool-sync": {
|
|
139
|
-
"version": "1.0.0",
|
|
140
|
-
"toolDependencies": {
|
|
141
|
-
"trash": "^1.0.0"
|
|
142
|
-
},
|
|
143
|
-
"files": {
|
|
144
|
-
".gitignore": "4d56952b0fb13bf8f9b6c13a6d4c34a075bac3af447636a1df4335d7576e2f97",
|
|
145
|
-
"config.js": "744c445b1d2ff65b77f38a5473c24e50a32f4288c4a08c25a874a478086c08c8",
|
|
146
|
-
"index.js": "fdd4167c63cd33c8e7640cb7ce09fd618dbd416030aa920407392e4591543e94",
|
|
147
|
-
"package.json": "4447cb5d4e0a04526604dfb9820c44af88349c27e208f27baa148686846559da",
|
|
148
|
-
"sync-lib.js": "c9f2cd7e19370088ab5fd10f6b2ada52c07d2e405674a356d0989f9a0f4984f6",
|
|
149
|
-
"sync-lib.test.js": "c97cf850d9f42f6b121a458863b048bdcaa6d7d0475642f20742c5862ebf7cc4",
|
|
150
|
-
"tool.manifest.json": "8e0f94ad786bdaf9edb1a65cd03438e26c1e9927e8db9a5a39e349e7ef3c6cd3"
|
|
151
|
-
}
|
|
152
|
-
},
|
|
153
|
-
"trash": {
|
|
154
|
-
"version": "1.0.0",
|
|
155
|
-
"files": {
|
|
156
|
-
".gitignore": "4d56952b0fb13bf8f9b6c13a6d4c34a075bac3af447636a1df4335d7576e2f97",
|
|
157
|
-
"config.js": "ad76578e9dcc05c2e45854de9fa2cd41285fd8dcdb9a7d9ee2056e0f8b2d68d6",
|
|
158
|
-
"index.js": "d562d2466bddc93dd9a3bc5455962a3457c50368ee5dde0607cae3ff5a88578a",
|
|
159
|
-
"package.json": "18ec594d43b6595c587b16125b9ce0c9426fdf00a28d7e342834e31e360575f8",
|
|
160
|
-
"tool.manifest.json": "4f236d274c891b55e4445d459cff6a3337a5d13adc5e8aca7fb965ff6aba4e4d",
|
|
161
|
-
"trash-store.js": "1318e0f9539292684c0c2ec2f1b7189f066fdba42f78e07821b067792f40e8c9",
|
|
162
|
-
"trash-store.test.js": "5647edba4ab5e5492764ccf8ba3e674e42b63942623d779b0bf69465c5adb53f"
|
|
163
|
-
}
|
|
164
|
-
},
|
|
165
|
-
"process-retrospective": {
|
|
166
|
-
"version": "1.0.0",
|
|
167
|
-
"files": {
|
|
168
|
-
"README.md": "7fa901adf532dbd1bb337a8019b0bd73978eef3b1ded51ffb24a3279d107056d",
|
|
169
|
-
"config.js": "30703e809f0a2c4b85ffb1e1f9cd7ee599224e9bc62c3bc19e71e271cbc72b5d",
|
|
170
|
-
"index.js": "9bd1ae078293211387ee3035b4c4dc7cc5852d08503cd55cf5fb3187cf1ace34",
|
|
171
|
-
"package.json": "e3978089354004e495b7c7f4b4edd9c0984b34f68229d0dfdafbb2e606d48c8d",
|
|
172
|
-
"reflection-plan.js": "ae78b47f5108993395fe9a6f1ff2eea0663a07ae1100780f9a63107fd6402314",
|
|
173
|
-
"state-store.js": "6d0d39bff7e5e16558123c088eb8946bf3758596ae974598936b94424618c7cf",
|
|
174
|
-
"test/reflection-plan.test.js": "d4e960948fc76aaed03651652a592ee4b3109abbb91693d415945cbb79642237",
|
|
175
|
-
"tool.manifest.json": "4304208986be075c95c6d71aa97d301fd266af18fef1b6ddac4cf004e38427e7"
|
|
176
|
-
}
|
|
177
|
-
},
|
|
178
|
-
"creator-scout": {
|
|
179
|
-
"version": "1.0.1",
|
|
180
|
-
"files": {
|
|
181
|
-
"README.md": "4f50850317c0875ad7ddea767c7dda112669112bec107a98e67a31a42787b82c",
|
|
182
|
-
"config.js": "bab728665650b986c0eaef8e1be1c259ec42b1f83df4217c9780f5468d3c7666",
|
|
183
|
-
"index.js": "d1266d622b6abaf77ce1fe93823d4f2faedb8a5991371997c364082a198dc728",
|
|
184
|
-
"package-lock.json": "ed479120b59c2d9b083991dea60eb7750ba36bc7b2c7defb01cfb598889b8d90",
|
|
185
|
-
"package.json": "ad463eeddea6a958ef291d58f216c0b42c5ff3b398b62ed9512b857ea5e4b672",
|
|
186
|
-
"reference-match.js": "762d822ad31f89c06cb5a40f84ba3f864436db486375ed30e48bde94de282c7c",
|
|
187
|
-
"test/reference-match.test.js": "701ce83396126b1e42bd3a54e331ff011a1fc27646a0f3aa99ce1c3e576aff6d",
|
|
188
|
-
"tool.manifest.json": "0617b0488035fd7f8a83a8e5a698558b3d0e956e7ea1e043e2e80bb224d4974f"
|
|
240
|
+
"tool.manifest.json": "177e0abac770f89a0f06aa445363393fa38e7f05ad7cd773ea907fa56faed505"
|
|
189
241
|
}
|
|
190
242
|
}
|
|
191
243
|
}
|
package/src/runtime/doctor.js
CHANGED
|
@@ -193,7 +193,6 @@ export async function inspectSystemResources({ diskPath = arisaHomeDir } = {}) {
|
|
|
193
193
|
|
|
194
194
|
function assertDoctorPolicy(policy) {
|
|
195
195
|
const positiveValues = [
|
|
196
|
-
"contextInspectionTimeoutMs",
|
|
197
196
|
"contextWarningPercent",
|
|
198
197
|
"contextCriticalPercent",
|
|
199
198
|
"contextInefficientMinTokens",
|
|
@@ -318,9 +317,7 @@ export async function runDoctor({
|
|
|
318
317
|
inspectToolDependencies = null
|
|
319
318
|
}) {
|
|
320
319
|
assertDoctorPolicy(doctorPolicy);
|
|
321
|
-
const runtime = await agentManager.getRuntimeDiagnostic(
|
|
322
|
-
contextInspectionTimeoutMs: doctorPolicy.contextInspectionTimeoutMs
|
|
323
|
-
});
|
|
320
|
+
const runtime = await agentManager.getRuntimeDiagnostic();
|
|
324
321
|
const report = {
|
|
325
322
|
runtime,
|
|
326
323
|
contexts: runtime.contexts.map((context) => evaluateContext(context, doctorPolicy)),
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { unlink } from "node:fs/promises";
|
|
1
|
+
import { materializeToolOutput } from "../core/tools/tool-output-materializer.js";
|
|
3
2
|
|
|
4
3
|
export function createHeadlessToolExecutor({ artifactStore, taskStore, toolRegistry } = {}) {
|
|
5
4
|
if (!artifactStore || !taskStore || !toolRegistry) {
|
|
@@ -10,36 +9,7 @@ export function createHeadlessToolExecutor({ artifactStore, taskStore, toolRegis
|
|
|
10
9
|
async runTool({ name, request, chatId }) {
|
|
11
10
|
await toolRegistry.load();
|
|
12
11
|
const result = await toolRegistry.run({ name, request, chatId });
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (result.output?.text) {
|
|
16
|
-
const artifact = await chatArtifacts.createText({
|
|
17
|
-
text: result.output.text,
|
|
18
|
-
source: { type: "tool", toolName: name },
|
|
19
|
-
metadata: { tool: name }
|
|
20
|
-
});
|
|
21
|
-
result.output.artifactId = artifact.id;
|
|
22
|
-
}
|
|
23
|
-
if (result.output?.filePath) {
|
|
24
|
-
const generated = await chatArtifacts.createFromFile({
|
|
25
|
-
originalPath: result.output.filePath,
|
|
26
|
-
fileName: result.output.fileName || path.basename(result.output.filePath),
|
|
27
|
-
kind: result.output.kind || "file",
|
|
28
|
-
mimeType: result.output.mimeType || "application/octet-stream",
|
|
29
|
-
source: { type: "tool", toolName: name },
|
|
30
|
-
metadata: { tool: name, delivery: result.output.delivery }
|
|
31
|
-
});
|
|
32
|
-
result.output.artifactId = generated.id;
|
|
33
|
-
await unlink(result.output.filePath).catch(() => {});
|
|
34
|
-
}
|
|
35
|
-
if (result.asyncTask || result.asyncTasks?.length) {
|
|
36
|
-
result.asyncTasks = await taskStore.addMany(result.asyncTasks || [result.asyncTask], {
|
|
37
|
-
payload: { chatId },
|
|
38
|
-
source: { type: "tool", toolName: name, chatId }
|
|
39
|
-
});
|
|
40
|
-
delete result.asyncTask;
|
|
41
|
-
}
|
|
42
|
-
return result;
|
|
12
|
+
return materializeToolOutput({ result, name, chatId, artifactStore, taskStore });
|
|
43
13
|
}
|
|
44
14
|
};
|
|
45
15
|
}
|
package/src/runtime/paths.js
CHANGED
|
@@ -13,6 +13,8 @@ export const configFile = path.join(stateDir, "config.json");
|
|
|
13
13
|
export const piAuthFile = path.join(stateDir, "pi-auth.json");
|
|
14
14
|
export const servicePidFile = path.join(stateDir, "arisa.pid");
|
|
15
15
|
export const serviceLogFile = path.join(stateDir, "arisa.log");
|
|
16
|
+
export const restartReceiptFile = path.join(stateDir, "restart-receipt.json");
|
|
17
|
+
export const sessionStartOperationalNotesFile = path.join(stateDir, "session-start-operational-notes.json");
|
|
16
18
|
export function createIpcSocketPath({ homeDir = arisaHomeDir, platform = process.platform } = {}) {
|
|
17
19
|
if (platform === "win32") {
|
|
18
20
|
const suffix = crypto.createHash("sha256").update(homeDir).digest("hex").slice(0, 16);
|
|
@@ -47,7 +49,11 @@ export function getChatArtifactsIndexFile(chatId) {
|
|
|
47
49
|
return path.join(getChatDir(chatId), "state", "artifacts.json");
|
|
48
50
|
}
|
|
49
51
|
|
|
50
|
-
export function
|
|
52
|
+
export function getChatSessionSeedFile(chatId) {
|
|
53
|
+
return path.join(getChatDir(chatId), "state", "session-seed.jsonl");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function getChatLegacyConversationHistoryFile(chatId) {
|
|
51
57
|
return path.join(getChatDir(chatId), "state", "conversation.jsonl");
|
|
52
58
|
}
|
|
53
59
|
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import { execFile } from "node:child_process";
|
|
3
|
+
import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { promisify } from "node:util";
|
|
6
|
+
import { arisaPackageDir, restartReceiptFile } from "./paths.js";
|
|
7
|
+
|
|
8
|
+
const execFileAsync = promisify(execFile);
|
|
9
|
+
|
|
10
|
+
function normalizeDestination({ transportChatId, threadId = null }) {
|
|
11
|
+
const chatId = Number(transportChatId);
|
|
12
|
+
if (!Number.isSafeInteger(chatId)) throw new Error("Restart receipt requires a valid Telegram chat id");
|
|
13
|
+
const topic = threadId == null ? null : Number(threadId);
|
|
14
|
+
if (topic != null && (!Number.isSafeInteger(topic) || topic <= 0)) {
|
|
15
|
+
throw new Error("Restart receipt requires a valid Telegram topic id");
|
|
16
|
+
}
|
|
17
|
+
return { transportChatId: chatId, threadId: topic };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function runtimeIdentity() {
|
|
21
|
+
const packageJson = JSON.parse(await readFile(path.join(arisaPackageDir, "package.json"), "utf8"));
|
|
22
|
+
let commit = null;
|
|
23
|
+
try {
|
|
24
|
+
const result = await execFileAsync("git", ["rev-parse", "--short=12", "HEAD"], { cwd: arisaPackageDir });
|
|
25
|
+
commit = String(result.stdout || "").trim() || null;
|
|
26
|
+
} catch {}
|
|
27
|
+
return { version: String(packageJson.version || "unknown"), commit };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export async function prepareRestartReceipt(destination, { reason = "requested restart" } = {}, {
|
|
31
|
+
receiptFile = restartReceiptFile,
|
|
32
|
+
getIdentity = runtimeIdentity
|
|
33
|
+
} = {}) {
|
|
34
|
+
const target = normalizeDestination(destination);
|
|
35
|
+
const identity = await getIdentity();
|
|
36
|
+
const receipt = {
|
|
37
|
+
id: crypto.randomUUID(),
|
|
38
|
+
...target,
|
|
39
|
+
reason: String(reason || "requested restart").slice(0, 500),
|
|
40
|
+
expectedVersion: identity.version,
|
|
41
|
+
expectedCommit: identity.commit,
|
|
42
|
+
requestedAt: new Date().toISOString()
|
|
43
|
+
};
|
|
44
|
+
await mkdir(path.dirname(receiptFile), { recursive: true, mode: 0o700 });
|
|
45
|
+
const temporaryFile = `${receiptFile}.${process.pid}.tmp`;
|
|
46
|
+
await writeFile(temporaryFile, `${JSON.stringify(receipt, null, 2)}\n`, { encoding: "utf8", mode: 0o600 });
|
|
47
|
+
await rename(temporaryFile, receiptFile);
|
|
48
|
+
return receipt;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export async function cancelRestartReceipt(receiptId, { receiptFile = restartReceiptFile } = {}) {
|
|
52
|
+
try {
|
|
53
|
+
const receipt = JSON.parse(await readFile(receiptFile, "utf8"));
|
|
54
|
+
if (receipt.id !== receiptId) return false;
|
|
55
|
+
await rm(receiptFile, { force: true });
|
|
56
|
+
return true;
|
|
57
|
+
} catch (error) {
|
|
58
|
+
if (error?.code === "ENOENT") return false;
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export async function deliverRestartReceipt(sendMessage, {
|
|
64
|
+
receiptFile = restartReceiptFile,
|
|
65
|
+
getIdentity = runtimeIdentity
|
|
66
|
+
} = {}) {
|
|
67
|
+
let receipt;
|
|
68
|
+
try {
|
|
69
|
+
receipt = JSON.parse(await readFile(receiptFile, "utf8"));
|
|
70
|
+
} catch (error) {
|
|
71
|
+
if (error?.code === "ENOENT") return null;
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const actual = await getIdentity();
|
|
76
|
+
const versionMatches = receipt.expectedVersion === actual.version;
|
|
77
|
+
const commitMatches = !receipt.expectedCommit || receipt.expectedCommit === actual.commit;
|
|
78
|
+
const genericReasons = new Set(["requested restart", "Agent-requested restart", "Telegram restart", "Telegram /restart", "Telegram update restart"]);
|
|
79
|
+
const resultSummary = String(receipt.reason || "").trim();
|
|
80
|
+
const lines = [
|
|
81
|
+
versionMatches && commitMatches ? "Restart completed." : "Restart completed with an unexpected runtime identity.",
|
|
82
|
+
resultSummary && !genericReasons.has(resultSummary) ? resultSummary : null,
|
|
83
|
+
`Arisa ${actual.version} is running${actual.commit ? ` at commit ${actual.commit}` : ""}.`,
|
|
84
|
+
versionMatches && commitMatches ? null : `Expected: ${receipt.expectedVersion}${receipt.expectedCommit ? ` at ${receipt.expectedCommit}` : ""}.`
|
|
85
|
+
].filter(Boolean);
|
|
86
|
+
const options = receipt.threadId ? { message_thread_id: receipt.threadId } : {};
|
|
87
|
+
await sendMessage(receipt.transportChatId, lines.join("\n"), options);
|
|
88
|
+
await rm(receiptFile, { force: true });
|
|
89
|
+
return { receipt, actual, verified: versionMatches && commitMatches };
|
|
90
|
+
}
|