volute 0.51.0 → 0.53.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/{accept-5NK5XJB5.js → accept-I4GVGWA3.js} +6 -3
- package/dist/{auth-X6EMNEGB.js → auth-KRDSM55Q.js} +3 -1
- package/dist/{chat-VAZ25KVT.js → chat-WK2BLM7B.js} +9 -9
- package/dist/{chunk-VAEZCIJC.js → chunk-23UJGVYP.js} +9 -9
- package/dist/{chunk-VSBMLB2W.js → chunk-5DBGQBQR.js} +138 -13
- package/dist/chunk-5RBEEAKW.js +58 -0
- package/dist/{chunk-BSHZ23MS.js → chunk-7ARONCZW.js} +25 -3
- package/dist/{chunk-HKP6OAJP.js → chunk-7LT3YZUR.js} +12 -0
- package/dist/{chunk-FXWBFDQR.js → chunk-AP2KQMMW.js} +48 -9
- package/dist/{chunk-DMK5ASKV.js → chunk-F6D766VQ.js} +6 -2
- package/dist/{chunk-VP5PFNZO.js → chunk-HASADR3E.js} +73 -20
- package/dist/{chunk-ICL6T4SN.js → chunk-IQ7VNWH6.js} +26 -2
- package/dist/{chunk-G7A5LEVI.js → chunk-LN7XJ56R.js} +6 -6
- package/dist/{chunk-DN3LKLYR.js → chunk-P2TBUKLW.js} +3 -3
- package/dist/{chunk-Q7XQLKZB.js → chunk-PIZDPY4G.js} +20 -3
- package/dist/{chunk-JHKBALS2.js → chunk-RMADJFA7.js} +1 -1
- package/dist/{chunk-7HN63Q7J.js → chunk-RQRO6PC7.js} +40 -6
- package/dist/{chunk-QT4D5XCI.js → chunk-TAWRJ24T.js} +1 -1
- package/dist/{chunk-AI47FDGL.js → chunk-UO4MZQNO.js} +1 -1
- package/dist/chunk-UTKUO2KY.js +102 -0
- package/dist/{chunk-CDKQJWGK.js → chunk-VDZ4I4ZP.js} +160 -18
- package/dist/cli.js +16 -16
- package/dist/{clock-ZT5YT6HA.js → clock-SH4NQC2F.js} +3 -3
- package/dist/{cloud-sync-GPXYPTIC.js → cloud-sync-MJVJ33LD.js} +11 -10
- package/dist/{daemon-restart-2EWBRTN5.js → daemon-restart-BIGU4OKS.js} +1 -1
- package/dist/daemon.js +543 -236
- package/dist/{delete-O7PEFQDF.js → delete-CYVZUAV2.js} +4 -0
- package/dist/{delivery-manager-HGVZSEES.js → delivery-manager-FDHCZ7PU.js} +7 -5
- package/dist/delivery-notices-65TB3CBX.js +18 -0
- package/dist/{echo-text-6ANI5HHN.js → echo-text-KU6G4Z7V.js} +12 -11
- package/dist/{extensions-NY6WST33.js → extensions-VACUKFA5.js} +11 -10
- package/dist/{files-BRY5RRIM.js → files-CHPNEQXN.js} +5 -4
- package/dist/{join-PYA36HEC.js → join-KLRU72JJ.js} +10 -2
- package/dist/{message-delivery-JHMAJ2GU.js → message-delivery-TUXM3AAE.js} +15 -12
- package/dist/{mind-WF6QIXWV.js → mind-IX5AWUST.js} +13 -13
- package/dist/{mind-contacts-QYU4TPEA.js → mind-contacts-BKUOUJPV.js} +5 -5
- package/dist/{mind-history-OGNR4L7W.js → mind-history-RVF6KJ7K.js} +83 -11
- package/dist/{mind-list-SYRA7CH5.js → mind-list-KNU34SUD.js} +2 -2
- package/dist/{mind-service-DZCUUC7J.js → mind-service-WHFBUKZE.js} +11 -10
- package/dist/{mind-sleep-LZAFBDZD.js → mind-sleep-D3DEYAWG.js} +5 -5
- package/dist/{mind-status-Z2LQFA6F.js → mind-status-BPTLQ5Z6.js} +15 -3
- package/dist/{package-B6O5APCZ.js → package-BN5KMU54.js} +2 -2
- package/dist/{prompts-NBO3HRK3.js → prompts-HNKGCAEY.js} +1 -1
- package/dist/{reject-TWB4QJHG.js → reject-K2A4UK2Y.js} +9 -5
- package/dist/{scheduler-TNBN54ZK.js → scheduler-5X5UIQOQ.js} +7 -5
- package/dist/{seed-K2LYODIH.js → seed-LHZ33UB4.js} +1 -1
- package/dist/{seed-cmd-2EWBTR6P.js → seed-cmd-U4RVJ3UA.js} +2 -2
- package/dist/{seed-create-VGTLU5FD.js → seed-create-OQU4KNCB.js} +1 -1
- package/dist/{seed-readiness-DYOVCYHN.js → seed-readiness-WJYYRRCK.js} +2 -2
- package/dist/{seed-sprout-PILHJ3YS.js → seed-sprout-SFUYH2RG.js} +7 -7
- package/dist/{send-2YKOZJJ5.js → send-FWZAMDBN.js} +35 -20
- package/dist/{setup-MDPSK2XG.js → setup-RVSGCIF3.js} +1 -1
- package/dist/skills/memory/SKILL.md +47 -43
- package/dist/skills/volute-mind/references/variants.md +1 -1
- package/dist/{skills-NH2GQKAF.js → skills-QRPU6BWY.js} +1 -1
- package/dist/{sleep-manager-7JXEQQ2P.js → sleep-manager-NWUCRBZB.js} +11 -10
- package/dist/{spirit-25JVAL3M.js → spirit-I5ECLGRI.js} +16 -2
- package/dist/{spirit-availability-PJDWZJ3J.js → spirit-availability-NIUUYKU2.js} +12 -11
- package/dist/{sprout-EXUZMIOR.js → sprout-A2PMEF7Z.js} +1 -1
- package/dist/{system-events-ZPSH63QX.js → system-events-YTOU66QI.js} +7 -1
- package/dist/{systems-VDRUZXNF.js → systems-2DIJY4RF.js} +6 -6
- package/dist/{turn-tracker-TAT2HGK6.js → turn-tracker-NNHS6MAR.js} +4 -2
- package/dist/{up-J7XCAH7P.js → up-UGBHH743.js} +1 -1
- package/dist/{variant-cleanup-YXN25ZVW.js → variant-cleanup-CZDLIY3F.js} +7 -5
- package/dist/{version-notify-EN3KJ7HH.js → version-notify-SJVAQLZI.js} +4 -4
- package/dist/web-assets/assets/index-BHSU9r-4.css +1 -0
- package/dist/web-assets/assets/index-b7G7ZsVk.js +97 -0
- package/dist/web-assets/index.html +2 -2
- package/package.json +2 -2
- package/templates/_base/.init/.config/prompts.json +1 -1
- package/templates/_base/src/lib/auto-commit.ts +49 -11
- package/templates/_base/src/lib/codex-session-seed.ts +463 -0
- package/templates/_base/src/lib/daemon-client.ts +35 -0
- package/templates/_base/src/lib/pi-session-seed.ts +434 -0
- package/templates/_base/src/lib/seed-note.ts +78 -0
- package/templates/_base/src/lib/session-seed.ts +375 -0
- package/templates/_base/src/lib/startup.ts +108 -4
- package/templates/claude/.init/CLAUDE.md +3 -3
- package/templates/claude/src/agent.ts +267 -89
- package/templates/claude/src/lib/hooks/pre-compact.ts +30 -5
- package/templates/claude/src/lib/stream-consumer.ts +13 -0
- package/templates/claude/src/server.ts +2 -1
- package/templates/codex/.init/AGENTS.md +3 -3
- package/templates/codex/src/agent.ts +256 -39
- package/templates/codex/src/server.ts +2 -1
- package/templates/pi/.init/MINDS.md +3 -3
- package/templates/pi/src/agent.ts +269 -43
- package/templates/pi/src/lib/event-handler.ts +11 -0
- package/templates/pi/src/server.ts +3 -1
- package/dist/web-assets/assets/index-BOyJ4Gqs.css +0 -1
- package/dist/web-assets/assets/index-CrxBwnzp.js +0 -95
- package/dist/{backup-YVGV2ZNM.js → backup-WWXVIMYQ.js} +5 -5
- package/dist/{bridge-YK7NTRU5.js → bridge-KU2IKSH3.js} +3 -3
- package/dist/{channels-FSAHOQWI.js → channels-LW5ZLMSQ.js} +3 -3
- package/dist/{chunk-IWAVIJO2.js → chunk-BDHKCLWK.js} +0 -0
- package/dist/{chunk-EEOMA4DX.js → chunk-HTB7KDRU.js} +3 -3
- package/dist/{create-M727VUDF.js → create-C3XZACTV.js} +3 -3
- package/dist/{env-IBW2QI6K.js → env-BJGM6FBA.js} +5 -5
- package/dist/{extension-MRYJWSMV.js → extension-B2W52WZY.js} +3 -3
- package/dist/{list-UQGIW7OF.js → list-R2GDWOEE.js} +3 -3
- package/dist/{login-RJJTCVR3.js → login-EZ4RRDQX.js} +3 -3
- package/dist/{login-SB5OENMV.js → login-JDOAK465.js} +4 -4
- package/dist/{logout-YFZAJRPY.js → logout-K6ZGAJY5.js} +3 -3
- package/dist/{logout-BYV433X6.js → logout-MWSIUOQU.js} +3 -3
- package/dist/{mind-wake-LDGPRA42.js → mind-wake-DCDFFQKX.js} +3 -3
- package/dist/{read-RJ5NAW5J.js → read-J5RM674N.js} +3 -3
- package/dist/{register-OX4HRSGC.js → register-53LBGSDC.js} +3 -3
- package/dist/{restart-AGEGNSYQ.js → restart-R2WFNF5K.js} +4 -4
- package/dist/{skill-B5OJEQUA.js → skill-DXLLSUHB.js} +5 -5
- package/dist/{start-MUMNFR52.js → start-XDOUAWN3.js} +4 -4
- package/dist/{status-MWLE3RVC.js → status-EYG4A3OK.js} +3 -3
- package/dist/{stop-EKERNYTX.js → stop-O62RTEMD.js} +4 -4
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
logger_default
|
|
4
|
+
} from "./chunk-QUSMYGNQ.js";
|
|
2
5
|
import {
|
|
3
6
|
stateDir
|
|
4
7
|
} from "./chunk-H6X6CKDN.js";
|
|
@@ -7,6 +10,7 @@ import {
|
|
|
7
10
|
import { randomBytes } from "crypto";
|
|
8
11
|
import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from "fs";
|
|
9
12
|
import { basename, join, normalize, resolve } from "path";
|
|
13
|
+
var flog = logger_default.child("file-sharing");
|
|
10
14
|
function validateFilePath(filePath) {
|
|
11
15
|
if (!filePath) return "File path is required";
|
|
12
16
|
const normalized = normalize(filePath);
|
|
@@ -65,7 +69,7 @@ function listPending(receiver) {
|
|
|
65
69
|
try {
|
|
66
70
|
result.push(JSON.parse(readFileSync(metaPath, "utf-8")));
|
|
67
71
|
} catch (err) {
|
|
68
|
-
|
|
72
|
+
flog.warn(`skipping malformed pending entry ${entry.name}`, logger_default.errorData(err));
|
|
69
73
|
}
|
|
70
74
|
}
|
|
71
75
|
return result.sort((a, b) => a.createdAt.localeCompare(b.createdAt));
|
|
@@ -77,7 +81,7 @@ function getPending(receiver, id) {
|
|
|
77
81
|
try {
|
|
78
82
|
return JSON.parse(readFileSync(metaPath, "utf-8"));
|
|
79
83
|
} catch (err) {
|
|
80
|
-
|
|
84
|
+
flog.warn(`failed to read pending metadata for ${id}`, logger_default.errorData(err));
|
|
81
85
|
return null;
|
|
82
86
|
}
|
|
83
87
|
}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
spiritDir
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-5DBGQBQR.js";
|
|
5
5
|
import {
|
|
6
6
|
getScheduler
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-PIZDPY4G.js";
|
|
8
8
|
import {
|
|
9
9
|
getDeliveryManager
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-RQRO6PC7.js";
|
|
11
11
|
import {
|
|
12
12
|
getMindManager,
|
|
13
13
|
resolveMindToken
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-23UJGVYP.js";
|
|
15
15
|
import {
|
|
16
16
|
extractTextContent,
|
|
17
17
|
getRoutingConfig,
|
|
@@ -23,14 +23,14 @@ import {
|
|
|
23
23
|
importSkillFromDir,
|
|
24
24
|
removeSharedSkill,
|
|
25
25
|
sharedSkillsDir
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-TAWRJ24T.js";
|
|
27
27
|
import {
|
|
28
28
|
getOrCreateMindUser,
|
|
29
29
|
getOrCreateSystemUser,
|
|
30
30
|
getUser,
|
|
31
31
|
getUserByUsername,
|
|
32
32
|
syncMindProfile
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-7LT3YZUR.js";
|
|
34
34
|
import {
|
|
35
35
|
MIND_LEVEL_THREAD,
|
|
36
36
|
deliverEvent,
|
|
@@ -38,13 +38,13 @@ import {
|
|
|
38
38
|
pendingEventCount,
|
|
39
39
|
pendingEventsLine,
|
|
40
40
|
recordNotice
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-IQ7VNWH6.js";
|
|
42
42
|
import {
|
|
43
43
|
publish as publish2
|
|
44
44
|
} from "./chunk-LNNI3MS4.js";
|
|
45
45
|
import {
|
|
46
46
|
getPrompt
|
|
47
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-AP2KQMMW.js";
|
|
48
48
|
import {
|
|
49
49
|
addMessage,
|
|
50
50
|
createChannel,
|
|
@@ -891,8 +891,16 @@ async function startMindFull(name) {
|
|
|
891
891
|
(err) => logger_default.error(`failed to ensure system DM for ${baseName}`, logger_default.errorData(err))
|
|
892
892
|
);
|
|
893
893
|
const dir = mindDir(baseName);
|
|
894
|
-
|
|
895
|
-
|
|
894
|
+
try {
|
|
895
|
+
getScheduler().loadSchedules(baseName);
|
|
896
|
+
} catch (err) {
|
|
897
|
+
logger_default.error(`failed to load schedules for ${baseName}`, logger_default.errorData(err));
|
|
898
|
+
}
|
|
899
|
+
try {
|
|
900
|
+
getSleepManagerIfReady()?.loadSleepConfig(baseName);
|
|
901
|
+
} catch (err) {
|
|
902
|
+
logger_default.error(`failed to load sleep config for ${baseName}`, logger_default.errorData(err));
|
|
903
|
+
}
|
|
896
904
|
ensureMailAddress(baseName).catch(
|
|
897
905
|
(err) => logger_default.error(`failed to ensure mail address for ${baseName}`, logger_default.errorData(err))
|
|
898
906
|
);
|
|
@@ -906,16 +914,24 @@ async function startMindFull(name) {
|
|
|
906
914
|
(err) => logger_default.warn(`failed to join #system for ${baseName}`, logger_default.errorData(err))
|
|
907
915
|
);
|
|
908
916
|
if (config?.tokenBudget) {
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
917
|
+
try {
|
|
918
|
+
getTokenBudget().setBudget(
|
|
919
|
+
baseName,
|
|
920
|
+
config.tokenBudget,
|
|
921
|
+
config.tokenBudgetPeriodMinutes ?? DEFAULT_BUDGET_PERIOD_MINUTES
|
|
922
|
+
);
|
|
923
|
+
} catch (err) {
|
|
924
|
+
logger_default.error(`failed to set token budget for ${baseName}`, logger_default.errorData(err));
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
try {
|
|
928
|
+
notifyExtensionsMindStart(baseName);
|
|
929
|
+
} catch (err) {
|
|
930
|
+
logger_default.error(`failed to notify extensions of mind start for ${baseName}`, logger_default.errorData(err));
|
|
914
931
|
}
|
|
915
|
-
notifyExtensionsMindStart(baseName);
|
|
916
932
|
}
|
|
917
933
|
async function recordMissingCredentialsNotice(mind, template) {
|
|
918
|
-
const { hasUndeliveredEvent, recordNotice: recordNotice2, MIND_LEVEL_THREAD: MIND_LEVEL_THREAD2 } = await import("./system-events-
|
|
934
|
+
const { hasUndeliveredEvent, recordNotice: recordNotice2, MIND_LEVEL_THREAD: MIND_LEVEL_THREAD2 } = await import("./system-events-YTOU66QI.js");
|
|
919
935
|
const warning = await missingCredentialWarning(template, readMindModel(mind, template), mind);
|
|
920
936
|
if (!warning) return;
|
|
921
937
|
if (await hasUndeliveredEvent(mind, "no_credentials")) return;
|
|
@@ -992,7 +1008,7 @@ function buildSeedOrientation(createdBy, creatorType) {
|
|
|
992
1008
|
async function sendSeedOrientation(mindName, createdBy) {
|
|
993
1009
|
let creatorType;
|
|
994
1010
|
if (createdBy) {
|
|
995
|
-
const { getUserByUsername: getUserByUsername2 } = await import("./auth-
|
|
1011
|
+
const { getUserByUsername: getUserByUsername2 } = await import("./auth-KRDSM55Q.js");
|
|
996
1012
|
creatorType = (await getUserByUsername2(createdBy))?.user_type;
|
|
997
1013
|
}
|
|
998
1014
|
await deliverEvent(mindName, {
|
|
@@ -1001,7 +1017,7 @@ async function sendSeedOrientation(mindName, createdBy) {
|
|
|
1001
1017
|
});
|
|
1002
1018
|
}
|
|
1003
1019
|
async function ensureCreatorDM(mindName, creatorUsername) {
|
|
1004
|
-
const { getOrCreateMindUser: getOrCreateMindUser2, getUserByUsername: getUserByUsername2 } = await import("./auth-
|
|
1020
|
+
const { getOrCreateMindUser: getOrCreateMindUser2, getUserByUsername: getUserByUsername2 } = await import("./auth-KRDSM55Q.js");
|
|
1005
1021
|
const { findDMConversation: findDMConversation2, createConversation: createConversation2 } = await import("./conversations-ZL6PHROD.js");
|
|
1006
1022
|
const mindUser = await getOrCreateMindUser2(mindName);
|
|
1007
1023
|
const creatorUser = await getUserByUsername2(creatorUsername);
|
|
@@ -1174,6 +1190,13 @@ var SleepManager = class {
|
|
|
1174
1190
|
this.transitioning.add(name);
|
|
1175
1191
|
state.wokenByTrigger = false;
|
|
1176
1192
|
try {
|
|
1193
|
+
await recordNotice({
|
|
1194
|
+
mind: name,
|
|
1195
|
+
thread: MIND_LEVEL_THREAD,
|
|
1196
|
+
kind: "crash",
|
|
1197
|
+
reason: "trigger_wake_crash",
|
|
1198
|
+
detail: await getPrompt("trigger_wake_crash_notice")
|
|
1199
|
+
});
|
|
1177
1200
|
try {
|
|
1178
1201
|
await sleepMind(name);
|
|
1179
1202
|
} catch (err) {
|
|
@@ -1230,6 +1253,15 @@ var SleepManager = class {
|
|
|
1230
1253
|
const wakeTime = formatWakeTime(wakeAt);
|
|
1231
1254
|
const preSleepMsg = await getPrompt("pre_sleep", { wakeTime });
|
|
1232
1255
|
const { delivered } = await deliverEvent(name, { type: "sleep", body: preSleepMsg });
|
|
1256
|
+
if (!delivered) {
|
|
1257
|
+
await recordNotice({
|
|
1258
|
+
mind: name,
|
|
1259
|
+
thread: MIND_LEVEL_THREAD,
|
|
1260
|
+
kind: "delivery_failed",
|
|
1261
|
+
reason: "pre_sleep_failed",
|
|
1262
|
+
detail: await getPrompt("pre_sleep_failure_notice")
|
|
1263
|
+
});
|
|
1264
|
+
}
|
|
1233
1265
|
if (delivered) await this.waitForIdle(name, 12e4);
|
|
1234
1266
|
await new Promise((r) => setTimeout(r, 3e3));
|
|
1235
1267
|
await sleepMind(name);
|
|
@@ -1420,7 +1452,7 @@ var SleepManager = class {
|
|
|
1420
1452
|
* the real delivery stack. Returns whether the batch was handed off to the mind.
|
|
1421
1453
|
*/
|
|
1422
1454
|
async deliverQueuedBatch(name, payloads) {
|
|
1423
|
-
const { deliverBatch: deliverBatch2 } = await import("./message-delivery-
|
|
1455
|
+
const { deliverBatch: deliverBatch2 } = await import("./message-delivery-TUXM3AAE.js");
|
|
1424
1456
|
return deliverBatch2(name, payloads);
|
|
1425
1457
|
}
|
|
1426
1458
|
// --- Wake failure handling (#419) ---
|
|
@@ -1647,6 +1679,22 @@ var SleepManager = class {
|
|
|
1647
1679
|
}
|
|
1648
1680
|
}
|
|
1649
1681
|
}
|
|
1682
|
+
const codexSessionsDir = resolve4(dir, ".mind", "codex-sessions");
|
|
1683
|
+
if (existsSync4(codexSessionsDir)) {
|
|
1684
|
+
const archiveDir = resolve4(codexSessionsDir, "archive");
|
|
1685
|
+
mkdirSync2(archiveDir, { recursive: true });
|
|
1686
|
+
for (const file of readdirSync(codexSessionsDir)) {
|
|
1687
|
+
if (file === "archive" || !file.endsWith(".json")) continue;
|
|
1688
|
+
const src = resolve4(codexSessionsDir, file);
|
|
1689
|
+
const base = file.replace(/\.json$/, "");
|
|
1690
|
+
const dest = resolve4(archiveDir, `${base}-${timestamp}.json`);
|
|
1691
|
+
try {
|
|
1692
|
+
renameSync(src, dest);
|
|
1693
|
+
} catch (err) {
|
|
1694
|
+
slog.warn(`failed to archive codex-session ${file} for ${name}`, logger_default.errorData(err));
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1650
1698
|
}
|
|
1651
1699
|
async runWakeContextScript(name, sleepingSince, duration) {
|
|
1652
1700
|
const scriptPath = resolve4(mindDir(name), "home", ".local", "hooks", "wake-context.sh");
|
|
@@ -1945,6 +1993,10 @@ function willGate(baseName, payload) {
|
|
|
1945
1993
|
});
|
|
1946
1994
|
return shouldGate(config, route);
|
|
1947
1995
|
}
|
|
1996
|
+
async function willGateMessage(mindName, payload) {
|
|
1997
|
+
const baseName = await getBaseName(mindName);
|
|
1998
|
+
return willGate(baseName, payload);
|
|
1999
|
+
}
|
|
1948
2000
|
async function deliverMessage(mindName, payload, opts = {}) {
|
|
1949
2001
|
try {
|
|
1950
2002
|
const baseName = await getBaseName(mindName);
|
|
@@ -2894,6 +2946,7 @@ export {
|
|
|
2894
2946
|
recordOutbound,
|
|
2895
2947
|
linkToolResultToTurn,
|
|
2896
2948
|
resolveSleepAction,
|
|
2949
|
+
willGateMessage,
|
|
2897
2950
|
deliverMessage,
|
|
2898
2951
|
deliverBatch,
|
|
2899
2952
|
ensureSystemChannel,
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
} from "./chunk-2RNMBXD2.js";
|
|
18
18
|
|
|
19
19
|
// packages/daemon/src/lib/chat/system-events.ts
|
|
20
|
-
import { and, asc, desc, eq, gt, isNull, lte, or, sql } from "drizzle-orm";
|
|
20
|
+
import { and, asc, desc, eq, gt, isNotNull, isNull, lt, lte, or, sql } from "drizzle-orm";
|
|
21
21
|
|
|
22
22
|
// packages/daemon/src/lib/util/session-name.ts
|
|
23
23
|
function newEphemeralSession() {
|
|
@@ -29,6 +29,7 @@ var elog = logger_default.child("system-events");
|
|
|
29
29
|
var MIND_LEVEL_THREAD = "";
|
|
30
30
|
var MAX_NEXT_TURN_EVENTS = 100;
|
|
31
31
|
var FLUSH_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
32
|
+
var EVENT_RETENTION_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
32
33
|
function parseMeta(meta, context) {
|
|
33
34
|
if (!meta) return {};
|
|
34
35
|
try {
|
|
@@ -93,6 +94,10 @@ function eventLabel(type, meta) {
|
|
|
93
94
|
return s("reason") ? `Notice: ${s("reason")}` : "Notice";
|
|
94
95
|
case "delivery_failed":
|
|
95
96
|
return "Delivery failed";
|
|
97
|
+
case "context_lost":
|
|
98
|
+
return "Context lost";
|
|
99
|
+
case "join_blocked":
|
|
100
|
+
return "Variant join blocked";
|
|
96
101
|
default:
|
|
97
102
|
return "Notice";
|
|
98
103
|
}
|
|
@@ -100,6 +105,16 @@ function eventLabel(type, meta) {
|
|
|
100
105
|
return type.charAt(0).toUpperCase() + type.slice(1);
|
|
101
106
|
}
|
|
102
107
|
}
|
|
108
|
+
var NOTICE_KINDS = [
|
|
109
|
+
"turn_error",
|
|
110
|
+
"crash",
|
|
111
|
+
"budget",
|
|
112
|
+
"startup",
|
|
113
|
+
"extension",
|
|
114
|
+
"delivery_failed",
|
|
115
|
+
"context_lost",
|
|
116
|
+
"join_blocked"
|
|
117
|
+
];
|
|
103
118
|
async function recordNotice(input) {
|
|
104
119
|
const type = input.kind === "budget" ? "budget" : "notice";
|
|
105
120
|
await deliverEvent(input.mind, {
|
|
@@ -108,6 +123,7 @@ async function recordNotice(input) {
|
|
|
108
123
|
thread: input.thread,
|
|
109
124
|
delivery: "next-turn",
|
|
110
125
|
meta: {
|
|
126
|
+
...input.meta ?? {},
|
|
111
127
|
subtype: input.kind,
|
|
112
128
|
reason: input.reason,
|
|
113
129
|
...input.raw ? { raw: input.raw } : {}
|
|
@@ -241,7 +257,7 @@ async function deliverEvent(mind, input) {
|
|
|
241
257
|
return { id: eventId, delivered: false };
|
|
242
258
|
}
|
|
243
259
|
const baseName = await getBaseName(mind);
|
|
244
|
-
const { getSleepManagerIfReady } = await import("./sleep-manager-
|
|
260
|
+
const { getSleepManagerIfReady } = await import("./sleep-manager-NWUCRBZB.js");
|
|
245
261
|
const sleepManager = getSleepManagerIfReady();
|
|
246
262
|
const sleeping = !input.force && sleepManager?.isSleeping(baseName);
|
|
247
263
|
const behavior = input.whileSleeping ?? "queue";
|
|
@@ -325,6 +341,11 @@ async function pendingEventCount(mind) {
|
|
|
325
341
|
return 0;
|
|
326
342
|
}
|
|
327
343
|
}
|
|
344
|
+
async function cleanExpiredEvents() {
|
|
345
|
+
const db = await getDb();
|
|
346
|
+
const cutoff = new Date(Date.now() - EVENT_RETENTION_MS).toISOString().replace("T", " ").slice(0, 19);
|
|
347
|
+
await db.delete(systemEvents).where(and(isNotNull(systemEvents.delivered_at), lt(systemEvents.created_at, cutoff)));
|
|
348
|
+
}
|
|
328
349
|
function pendingEventsLine(count) {
|
|
329
350
|
if (count <= 0) return "";
|
|
330
351
|
return `${count} system event${count === 1 ? "" : "s"} arrived while you slept and will follow shortly.`;
|
|
@@ -544,14 +565,17 @@ export {
|
|
|
544
565
|
MIND_LEVEL_THREAD,
|
|
545
566
|
parseMeta,
|
|
546
567
|
eventLabel,
|
|
568
|
+
NOTICE_KINDS,
|
|
547
569
|
recordNotice,
|
|
548
570
|
eventChannel,
|
|
549
571
|
deliverEvent,
|
|
550
572
|
flushQueuedEvents,
|
|
551
573
|
pendingEventCount,
|
|
574
|
+
cleanExpiredEvents,
|
|
552
575
|
pendingEventsLine,
|
|
553
576
|
drainEvents,
|
|
554
577
|
formatEvents,
|
|
578
|
+
localHM,
|
|
555
579
|
clearDeliveredEvents,
|
|
556
580
|
latestFailureEvent,
|
|
557
581
|
latestEvent,
|
|
@@ -6,6 +6,10 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
resolveMindName
|
|
8
8
|
} from "./chunk-BTY4WNFE.js";
|
|
9
|
+
import {
|
|
10
|
+
command,
|
|
11
|
+
subcommands
|
|
12
|
+
} from "./chunk-TXSA4Q3V.js";
|
|
9
13
|
import {
|
|
10
14
|
daemonFetch
|
|
11
15
|
} from "./chunk-M74I3HHF.js";
|
|
@@ -13,10 +17,6 @@ import {
|
|
|
13
17
|
getClient,
|
|
14
18
|
urlOf
|
|
15
19
|
} from "./chunk-LOPXTW6H.js";
|
|
16
|
-
import {
|
|
17
|
-
command,
|
|
18
|
-
subcommands
|
|
19
|
-
} from "./chunk-TXSA4Q3V.js";
|
|
20
20
|
|
|
21
21
|
// packages/cli/src/commands/clock.ts
|
|
22
22
|
import { CronExpressionParser } from "cron-parser";
|
|
@@ -279,11 +279,11 @@ var cmd = subcommands({
|
|
|
279
279
|
},
|
|
280
280
|
sleep: {
|
|
281
281
|
description: "Put a mind to sleep",
|
|
282
|
-
run: (args) => import("./mind-sleep-
|
|
282
|
+
run: (args) => import("./mind-sleep-D3DEYAWG.js").then((m) => m.run(args))
|
|
283
283
|
},
|
|
284
284
|
wake: {
|
|
285
285
|
description: "Wake a sleeping mind",
|
|
286
|
-
run: (args) => import("./mind-wake-
|
|
286
|
+
run: (args) => import("./mind-wake-DCDFFQKX.js").then((m) => m.run(args))
|
|
287
287
|
}
|
|
288
288
|
},
|
|
289
289
|
footer: "Use --mind <name> or VOLUTE_MIND to identify the mind."
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
import {
|
|
3
3
|
getSleepManagerIfReady,
|
|
4
4
|
startSpiritFull
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-HASADR3E.js";
|
|
6
6
|
import {
|
|
7
7
|
spiritCreationInProgress
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-5DBGQBQR.js";
|
|
9
9
|
import {
|
|
10
10
|
MindStartupError,
|
|
11
11
|
tryGetMindManager
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-23UJGVYP.js";
|
|
13
13
|
import {
|
|
14
14
|
logger_default
|
|
15
15
|
} from "./chunk-QUSMYGNQ.js";
|
|
@@ -6,10 +6,15 @@ import {
|
|
|
6
6
|
getMindToken,
|
|
7
7
|
loadJsonMap,
|
|
8
8
|
saveJsonMapAsync
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-23UJGVYP.js";
|
|
10
10
|
import {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
MIND_LEVEL_THREAD,
|
|
12
|
+
deliverEvent,
|
|
13
|
+
recordNotice
|
|
14
|
+
} from "./chunk-IQ7VNWH6.js";
|
|
15
|
+
import {
|
|
16
|
+
getPrompt
|
|
17
|
+
} from "./chunk-AP2KQMMW.js";
|
|
13
18
|
import {
|
|
14
19
|
isSandboxEnabled,
|
|
15
20
|
wrapForSandbox
|
|
@@ -197,6 +202,18 @@ ${stderr}` : ""}`;
|
|
|
197
202
|
}
|
|
198
203
|
} catch (err) {
|
|
199
204
|
slog.warn(`failed to fire "${schedule.id}" for ${mindName}`, logger_default.errorData(err));
|
|
205
|
+
const detail = await getPrompt("schedule_failure_notice", {
|
|
206
|
+
id: schedule.id,
|
|
207
|
+
reason: err instanceof Error && err.message ? err.message : String(err)
|
|
208
|
+
});
|
|
209
|
+
const thread = schedule.thread && !schedule.thread.startsWith("new-") ? schedule.thread : MIND_LEVEL_THREAD;
|
|
210
|
+
await recordNotice({
|
|
211
|
+
mind: mindName,
|
|
212
|
+
thread,
|
|
213
|
+
kind: "delivery_failed",
|
|
214
|
+
reason: "schedule_failed",
|
|
215
|
+
detail
|
|
216
|
+
});
|
|
200
217
|
}
|
|
201
218
|
}
|
|
202
219
|
removeSchedule(mindName, scheduleId) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
tryGetMindManager
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-23UJGVYP.js";
|
|
5
5
|
import {
|
|
6
6
|
extractTextContent,
|
|
7
7
|
getRoutingConfig,
|
|
@@ -12,11 +12,11 @@ import {
|
|
|
12
12
|
} from "./chunk-UDZLPR34.js";
|
|
13
13
|
import {
|
|
14
14
|
linkInboundToActiveTurn
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-VDZ4I4ZP.js";
|
|
16
16
|
import {
|
|
17
17
|
MIND_LEVEL_THREAD,
|
|
18
18
|
newEphemeralSession
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-IQ7VNWH6.js";
|
|
20
20
|
import {
|
|
21
21
|
publish
|
|
22
22
|
} from "./chunk-LNNI3MS4.js";
|
|
@@ -36,6 +36,9 @@ import {
|
|
|
36
36
|
import {
|
|
37
37
|
logger_default
|
|
38
38
|
} from "./chunk-QUSMYGNQ.js";
|
|
39
|
+
import {
|
|
40
|
+
slugify
|
|
41
|
+
} from "./chunk-LGNUFVMR.js";
|
|
39
42
|
import {
|
|
40
43
|
findMind,
|
|
41
44
|
getBaseName,
|
|
@@ -243,14 +246,22 @@ var DeliveryManager = class {
|
|
|
243
246
|
isMindRunning = (name) => tryGetMindManager()?.isRunning(name) ?? false;
|
|
244
247
|
/** Delivers a channel event to a mind (invites, release summaries); overridable in tests. */
|
|
245
248
|
notify = async (mindName, text) => {
|
|
246
|
-
const { deliverEvent } = await import("./system-events-
|
|
249
|
+
const { deliverEvent } = await import("./system-events-YTOU66QI.js");
|
|
247
250
|
await deliverEvent(mindName, { type: "channel", body: text });
|
|
248
251
|
};
|
|
249
252
|
/** Surfaces a dead-lettered delivery as a next-turn failure notice; overridable in tests. */
|
|
250
253
|
notifyFailure = async (input) => {
|
|
251
|
-
const { recordNotice } = await import("./system-events-
|
|
254
|
+
const { recordNotice } = await import("./system-events-YTOU66QI.js");
|
|
252
255
|
await recordNotice(input);
|
|
253
256
|
};
|
|
257
|
+
/**
|
|
258
|
+
* Tells a mind *sender* its message was dropped (dead-lettered on the recipient's
|
|
259
|
+
* side); no-ops for human senders. Overridable in tests.
|
|
260
|
+
*/
|
|
261
|
+
notifySenderFailure = async (sender, channel, reason) => {
|
|
262
|
+
const { recordSenderDeliveryFailure } = await import("./delivery-notices-65TB3CBX.js");
|
|
263
|
+
await recordSenderDeliveryFailure(sender, channel, reason);
|
|
264
|
+
};
|
|
254
265
|
constructor() {
|
|
255
266
|
setRoutesChangeListener((mind) => {
|
|
256
267
|
this.releaseGated(mind).catch(
|
|
@@ -270,6 +281,10 @@ var DeliveryManager = class {
|
|
|
270
281
|
setFailureNotifier(fn) {
|
|
271
282
|
this.notifyFailure = fn;
|
|
272
283
|
}
|
|
284
|
+
/** Test seam: capture/override sender-side dead-letter notices. */
|
|
285
|
+
setSenderFailureNotifier(fn) {
|
|
286
|
+
this.notifySenderFailure = fn;
|
|
287
|
+
}
|
|
273
288
|
// --- Public API ---
|
|
274
289
|
/**
|
|
275
290
|
* Route and deliver a message to a mind. This is the main entry point.
|
|
@@ -875,6 +890,25 @@ var DeliveryManager = class {
|
|
|
875
890
|
} catch (err) {
|
|
876
891
|
dlog.warn(`failed to send dead-letter notice for ${mind}`, logger_default.errorData(err));
|
|
877
892
|
}
|
|
893
|
+
const senderPairs = /* @__PURE__ */ new Map();
|
|
894
|
+
for (const r of rows) {
|
|
895
|
+
if (!r.sender || r.sender === r.mind) continue;
|
|
896
|
+
const recipient = r.target_mind ?? r.mind;
|
|
897
|
+
const channel = !r.channel || r.channel === `@${slugify(r.sender)}` ? `@${recipient}` : r.channel;
|
|
898
|
+
senderPairs.set(`${r.sender}
|
|
899
|
+
${channel}`, { sender: r.sender, channel });
|
|
900
|
+
}
|
|
901
|
+
for (const { sender, channel } of senderPairs.values()) {
|
|
902
|
+
try {
|
|
903
|
+
await this.notifySenderFailure(
|
|
904
|
+
sender,
|
|
905
|
+
channel,
|
|
906
|
+
`the recipient's process rejected it after ${MAX_DELIVERY_ATTEMPTS} attempts`
|
|
907
|
+
);
|
|
908
|
+
} catch (err) {
|
|
909
|
+
dlog.warn(`failed to send sender dead-letter notice for ${sender}`, logger_default.errorData(err));
|
|
910
|
+
}
|
|
911
|
+
}
|
|
878
912
|
}
|
|
879
913
|
async deliverToMind(mindName, session, payload, sessionConfig, queueId) {
|
|
880
914
|
if (queueId != null) this.inFlight.add(queueId);
|
|
@@ -1130,7 +1164,7 @@ var DeliveryManager = class {
|
|
|
1130
1164
|
const details = detailLines.length > 0 ? `${detailLines.join("\n")}
|
|
1131
1165
|
|
|
1132
1166
|
` : "\n";
|
|
1133
|
-
const { getPrompt } = await import("./prompts-
|
|
1167
|
+
const { getPrompt } = await import("./prompts-HNKGCAEY.js");
|
|
1134
1168
|
const notification = await getPrompt("channel_invite", {
|
|
1135
1169
|
channel,
|
|
1136
1170
|
heldLine,
|
|
@@ -45,7 +45,7 @@ async function initDefaultSkills() {
|
|
|
45
45
|
const config = readGlobalConfig();
|
|
46
46
|
let extensionSkills = [];
|
|
47
47
|
try {
|
|
48
|
-
const { getExtensionStandardSkills } = await import("./extensions-
|
|
48
|
+
const { getExtensionStandardSkills } = await import("./extensions-VACUKFA5.js");
|
|
49
49
|
extensionSkills = getExtensionStandardSkills();
|
|
50
50
|
} catch (err) {
|
|
51
51
|
logger_default.warn("failed to load extension standard skills during init", logger_default.errorData(err));
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
MIND_LEVEL_THREAD,
|
|
4
|
+
localHM,
|
|
5
|
+
parseMeta,
|
|
6
|
+
recordNotice
|
|
7
|
+
} from "./chunk-IQ7VNWH6.js";
|
|
8
|
+
import {
|
|
9
|
+
getPrompt
|
|
10
|
+
} from "./chunk-AP2KQMMW.js";
|
|
11
|
+
import {
|
|
12
|
+
logger_default
|
|
13
|
+
} from "./chunk-QUSMYGNQ.js";
|
|
14
|
+
import {
|
|
15
|
+
findMind,
|
|
16
|
+
getDb
|
|
17
|
+
} from "./chunk-H6X6CKDN.js";
|
|
18
|
+
import {
|
|
19
|
+
systemEvents
|
|
20
|
+
} from "./chunk-2RNMBXD2.js";
|
|
21
|
+
|
|
22
|
+
// packages/daemon/src/lib/chat/delivery-notices.ts
|
|
23
|
+
import { and, desc, eq, isNull, sql } from "drizzle-orm";
|
|
24
|
+
var nlog = logger_default.child("delivery-notices");
|
|
25
|
+
var COALESCE_WINDOW_MINUTES = 15;
|
|
26
|
+
var recordChains = /* @__PURE__ */ new Map();
|
|
27
|
+
async function recordDeliveryFailure(input) {
|
|
28
|
+
const key = `${input.mind}
|
|
29
|
+
${input.channel}`;
|
|
30
|
+
const next = (recordChains.get(key) ?? Promise.resolve()).then(
|
|
31
|
+
() => recordDeliveryFailureUnserialized(input)
|
|
32
|
+
);
|
|
33
|
+
recordChains.set(key, next);
|
|
34
|
+
await next;
|
|
35
|
+
if (recordChains.get(key) === next) recordChains.delete(key);
|
|
36
|
+
}
|
|
37
|
+
async function recordDeliveryFailureUnserialized(input) {
|
|
38
|
+
const thread = input.thread ?? MIND_LEVEL_THREAD;
|
|
39
|
+
try {
|
|
40
|
+
const db = await getDb();
|
|
41
|
+
const existing = await db.select().from(systemEvents).where(
|
|
42
|
+
and(
|
|
43
|
+
eq(systemEvents.mind, input.mind),
|
|
44
|
+
eq(systemEvents.type, "notice"),
|
|
45
|
+
eq(systemEvents.delivery, "next-turn"),
|
|
46
|
+
eq(systemEvents.thread, thread),
|
|
47
|
+
isNull(systemEvents.delivered_at),
|
|
48
|
+
// Literal subtype + bound channel value — not string-built SQL.
|
|
49
|
+
sql`json_extract(${systemEvents.meta}, '$.subtype') = 'delivery_failed'`,
|
|
50
|
+
sql`json_extract(${systemEvents.meta}, '$.channel') = ${input.channel}`,
|
|
51
|
+
sql`${systemEvents.created_at} > datetime('now', ${`-${COALESCE_WINDOW_MINUTES} minutes`})`
|
|
52
|
+
)
|
|
53
|
+
).orderBy(desc(systemEvents.id)).limit(1).get();
|
|
54
|
+
if (existing) {
|
|
55
|
+
const meta = parseMeta(existing.meta, `event ${existing.id}`);
|
|
56
|
+
const count = (typeof meta.count === "number" ? meta.count : 1) + 1;
|
|
57
|
+
const body2 = await getPrompt("delivery_failure_coalesced", {
|
|
58
|
+
count: String(count),
|
|
59
|
+
channel: input.channel,
|
|
60
|
+
since: localHM(existing.created_at),
|
|
61
|
+
reason: input.reason
|
|
62
|
+
});
|
|
63
|
+
await db.update(systemEvents).set({ body: body2, meta: JSON.stringify({ ...meta, count }) }).where(eq(systemEvents.id, existing.id));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const body = await getPrompt("delivery_failure_notice", {
|
|
67
|
+
channel: input.channel,
|
|
68
|
+
reason: input.reason
|
|
69
|
+
});
|
|
70
|
+
await recordNotice({
|
|
71
|
+
mind: input.mind,
|
|
72
|
+
thread,
|
|
73
|
+
kind: "delivery_failed",
|
|
74
|
+
reason: "delivery_failed",
|
|
75
|
+
detail: body,
|
|
76
|
+
meta: { channel: input.channel, count: 1 }
|
|
77
|
+
});
|
|
78
|
+
} catch (err) {
|
|
79
|
+
nlog.warn(
|
|
80
|
+
`failed to record delivery-failure notice for ${input.mind} \u2192 ${input.channel}`,
|
|
81
|
+
logger_default.errorData(err)
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async function recordSenderDeliveryFailure(sender, channel, reason) {
|
|
86
|
+
try {
|
|
87
|
+
const entry = await findMind(sender);
|
|
88
|
+
if (!entry) return;
|
|
89
|
+
await recordDeliveryFailure({ mind: entry.parent ?? entry.name, channel, reason });
|
|
90
|
+
} catch (err) {
|
|
91
|
+
nlog.warn(
|
|
92
|
+
`failed to record sender delivery-failure notice for ${sender} \u2192 ${channel}`,
|
|
93
|
+
logger_default.errorData(err)
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export {
|
|
99
|
+
COALESCE_WINDOW_MINUTES,
|
|
100
|
+
recordDeliveryFailure,
|
|
101
|
+
recordSenderDeliveryFailure
|
|
102
|
+
};
|