volute 0.47.0 → 0.48.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/README.md +11 -11
- package/dist/{accept-YAFP5JFJ.js → accept-KYNC5X3U.js} +3 -3
- package/dist/{ai-service-CVZEYKTK.js → ai-service-643TNFPH.js} +6 -2
- package/dist/{avatar-image-7S3WA77A.js → avatar-image-Y45R7LW5.js} +3 -2
- package/dist/{backup-IIAFOW2L.js → backup-UDH4GMSW.js} +11 -11
- package/dist/{bridge-TIZGSXOD.js → bridge-3FNSWLNQ.js} +3 -3
- package/dist/{channels-ITE4YC57.js → channels-SGQZHNQJ.js} +3 -3
- package/dist/{chat-AJLJCQ3M.js → chat-X43VYHH2.js} +9 -9
- package/dist/chunk-4FCL4DVZ.js +48 -0
- package/dist/{chunk-SKNXMUIU.js → chunk-5KXCM5AW.js} +17 -1
- package/dist/{chunk-RBNMDAKB.js → chunk-BCG45AQB.js} +15 -1
- package/dist/chunk-DW4TRDOZ.js +29 -0
- package/dist/{chunk-CBOIHNMR.js → chunk-FJ2MZ5PH.js} +39 -3
- package/dist/{chunk-M6TTZRGH.js → chunk-HNGFKPNS.js} +20 -4
- package/dist/{chunk-IWJSNMSY.js → chunk-HUNDXZBZ.js} +2 -2
- package/dist/chunk-IYCV34IU.js +158 -0
- package/dist/{chunk-5IERLDUS.js → chunk-MJRXFUMS.js} +25 -5
- package/dist/{chunk-JCMGDCGX.js → chunk-MOERAQXH.js} +2 -0
- package/dist/{chunk-XHN6XBWV.js → chunk-OQJMTHEH.js} +1 -1
- package/dist/{chunk-BGYHLR54.js → chunk-PJVPDY2Z.js} +1 -1
- package/dist/{chunk-5NN2VHJV.js → chunk-Q7HOAVFR.js} +1 -1
- package/dist/{chunk-KDLYIECM.js → chunk-R772ET2M.js} +18 -4
- package/dist/{mind-list-KEGRGQEQ.js → chunk-SHKM5RGD.js} +19 -6
- package/dist/{chunk-4I72V3E5.js → chunk-T4VS7UDW.js} +11 -11
- package/dist/{chunk-K23P5Q5N.js → chunk-USD45JKR.js} +27 -5
- package/dist/{chunk-F55GRIEK.js → chunk-VB2QXUJQ.js} +176 -201
- package/dist/{chunk-M3XDVS5Q.js → chunk-VZRA5TYO.js} +1 -1
- package/dist/{chunk-JSVHH32K.js → chunk-WARH6GIV.js} +10 -10
- package/dist/{chunk-PFZBNKUH.js → chunk-WCFSBH33.js} +0 -1
- package/dist/{chunk-VMCZBXF2.js → chunk-WQ46E33M.js} +8 -32
- package/dist/{chunk-RUFLGTOT.js → chunk-XVBSFLM7.js} +1 -1
- package/dist/{chunk-LWDTP6DH.js → chunk-YNBXEQAP.js} +31 -1
- package/dist/cli.js +33 -25
- package/dist/{clock-E6N5Y3YW.js → clock-CNRF6F7T.js} +3 -3
- package/dist/{cloud-sync-LQTVDTQ3.js → cloud-sync-WHKCB4CD.js} +14 -12
- package/dist/{config-TJLYUV3U.js → config-RPSLA2HX.js} +3 -3
- package/dist/{create-PQQXKTJK.js → create-GJKHABJB.js} +16 -5
- package/dist/{create-A7PDHIIL.js → create-VIQVP3QB.js} +3 -3
- package/dist/{daemon-client-IYR4KCPU.js → daemon-client-ZFY5MOAL.js} +5 -3
- package/dist/{daemon-restart-5F3YTLZK.js → daemon-restart-7KUHVZIN.js} +4 -4
- package/dist/daemon.js +668 -401
- package/dist/{db-LZTLA7XC.js → db-IPXRJUI7.js} +1 -1
- package/dist/{delete-HPLC7ETU.js → delete-ESEP7NGQ.js} +1 -1
- package/dist/{delivery-manager-TN5KK2AP.js → delivery-manager-HZTT5SJR.js} +14 -12
- package/dist/{down-ZI4S6265.js → down-G6IADJXV.js} +2 -2
- package/dist/{echo-text-SEQCLGAT.js → echo-text-H3SH337Q.js} +16 -14
- package/dist/env-6TGPO5WG.js +18 -0
- package/dist/{env-HRL2PWAT.js → env-C7Z55QCJ.js} +7 -7
- package/dist/{export-4GVGNW54.js → export-C2K3NIRD.js} +1 -1
- package/dist/{extension-QBY4C44L.js → extension-J4ZQ2GHV.js} +3 -3
- package/dist/{extensions-PIMIQ7J3.js → extensions-GEKF47A4.js} +14 -12
- package/dist/{files-FEFZKMNM.js → files-LXQSQOFG.js} +3 -3
- package/dist/{import-7MO3YTRE.js → import-SX3ZXHB4.js} +4 -4
- package/dist/{join-ZJV7W6MO.js → join-34TR2GXQ.js} +1 -1
- package/dist/{list-LQO2DCIK.js → list-PMUXZNAM.js} +3 -3
- package/dist/{login-6TLMI2TQ.js → login-ARRZ4ORJ.js} +3 -3
- package/dist/{login-OF4WXDAN.js → login-CL4IT2ED.js} +12 -3
- package/dist/{logout-ERE2BGA3.js → logout-HZYJCYCA.js} +3 -3
- package/dist/{logout-BK53HXNY.js → logout-YZRMZ3O2.js} +3 -3
- package/dist/{message-delivery-ZE3YGJDD.js → message-delivery-GPQ5SE5N.js} +14 -12
- package/dist/{mind-POOHFZHP.js → mind-46AOK373.js} +23 -19
- package/dist/mind-contacts-GV7XYL5D.js +64 -0
- package/dist/{mind-history-47DN6ILW.js → mind-history-TTGA5BHZ.js} +7 -7
- package/dist/mind-list-OTHV4ZO4.js +13 -0
- package/dist/{mind-profile-PEQYASQX.js → mind-profile-LUG353ZT.js} +1 -1
- package/dist/{mind-service-JFY7UG5E.js → mind-service-2ARGJNKP.js} +16 -12
- package/dist/{mind-sleep-IN3WPA76.js → mind-sleep-DV7KP255.js} +5 -5
- package/dist/{mind-status-SMUWJKGV.js → mind-status-BJNPGXKC.js} +8 -3
- package/dist/{mind-wake-R54BPESY.js → mind-wake-LVTZ55EZ.js} +3 -3
- package/dist/notices-2KU5NTRY.js +25 -0
- package/dist/{package-WPEE2HVJ.js → package-RTN2PS7O.js} +4 -2
- package/dist/{read-PWAJOQIQ.js → read-YSWUXYL7.js} +3 -3
- package/dist/{register-7SZJFHU6.js → register-42VBJKTP.js} +3 -3
- package/dist/{reject-6VH7N2A4.js → reject-SXGCYN4A.js} +3 -3
- package/dist/{restart-H5WJDMA7.js → restart-YYEGZJDD.js} +7 -7
- package/dist/{sandbox-G4X4K3UN.js → sandbox-5VQ454XP.js} +2 -2
- package/dist/{scheduler-HQSDYJFY.js → scheduler-I7JZCT47.js} +14 -12
- package/dist/{seed-VANPU43L.js → seed-F2HXZQU4.js} +1 -1
- package/dist/{seed-check-VLTVILOV.js → seed-check-TYD7RRZY.js} +1 -1
- package/dist/{seed-cmd-SYVDZKM4.js → seed-cmd-MLCTGSX5.js} +3 -3
- package/dist/{seed-create-3FGZPS6C.js → seed-create-KQ7OILWB.js} +6 -4
- package/dist/seed-readiness-RBPGOLSZ.js +18 -0
- package/dist/{seed-sprout-H7QLFPFM.js → seed-sprout-HVYCFJLA.js} +29 -30
- package/dist/{send-HYDFGC6G.js → send-TD2X5U3K.js} +7 -7
- package/dist/{service-SYJ5G6LP.js → service-CVZMQYK6.js} +1 -1
- package/dist/{service-install-FQ43Z4DF.js → service-install-VCRMFWX5.js} +2 -2
- package/dist/{setup-KFYVWTXG.js → setup-5ECWTYKG.js} +5 -1
- package/dist/{setup-QJHGMGSN.js → setup-AE4CVUC4.js} +4 -4
- package/dist/{skill-GUKG2YVH.js → skill-UUM4JZRF.js} +7 -7
- package/dist/skills/dreaming/SKILL.md +5 -1
- package/dist/skills/dreaming/scripts/dream.ts +5 -1
- package/dist/skills/orientation/SKILL.md +8 -7
- package/dist/skills/tending/SKILL.md +51 -2
- package/dist/skills/volute-mind/SKILL.md +2 -0
- package/dist/{skills-L2CMTW7A.js → skills-B3SVDCEB.js} +2 -2
- package/dist/{sleep-manager-3NA7ZJP3.js → sleep-manager-Z27R3WTW.js} +14 -12
- package/dist/{spirit-WXN4IDBF.js → spirit-WXS3HCLN.js} +7 -5
- package/dist/{split-WBMZXBHF.js → split-SKZ4Y2D6.js} +1 -1
- package/dist/{sprout-LTL5P36T.js → sprout-KQ43BWZJ.js} +1 -1
- package/dist/{src-OJHARHTF.js → src-WLJE73NP.js} +14 -5
- package/dist/{start-X46I3GXB.js → start-O6UKK7BG.js} +7 -7
- package/dist/{status-V4RJMHJ4.js → status-F4PGREUU.js} +6 -4
- package/dist/{stop-HJQV4YSM.js → stop-UBX6X5RA.js} +7 -7
- package/dist/{system-chat-N2F7HVY3.js → system-chat-63ABFF6V.js} +14 -12
- package/dist/{systems-B5YJKMW4.js → systems-JJNGQHAO.js} +6 -6
- package/dist/{turn-tracker-JZRZDFWV.js → turn-tracker-KLPV3PAU.js} +4 -4
- package/dist/{up-J2PBPOZL.js → up-RVGDE6CQ.js} +5 -3
- package/dist/{update-ACV4SAY3.js → update-OXQEGGXD.js} +1 -1
- package/dist/{upgrade-NWAZ7MLD.js → upgrade-K5FIQPQD.js} +1 -1
- package/dist/{version-notify-XRGTEEDK.js → version-notify-73YURTFR.js} +17 -15
- package/dist/web-assets/assets/index-WdZ60R6c.css +1 -0
- package/dist/web-assets/assets/index-taX6Ezfa.js +92 -0
- package/dist/web-assets/index.html +2 -2
- package/package.json +4 -2
- package/packages/extensions/pages/dist/ui/assets/index-BuXnE-rb.css +1 -0
- package/packages/extensions/pages/dist/ui/assets/index-DtzftuPA.js +2 -0
- package/packages/extensions/pages/dist/ui/index.html +2 -2
- package/templates/_base/src/lib/startup.ts +16 -1
- package/templates/claude/src/agent.ts +9 -2
- package/templates/claude/src/server.ts +4 -2
- package/templates/pi/src/agent.ts +7 -10
- package/templates/pi/src/lib/dispatch.ts +65 -0
- package/dist/volute-config-A52FHWKM.js +0 -14
- package/dist/web-assets/assets/index-DtctoDXY.css +0 -1
- package/dist/web-assets/assets/index-Wpyb2CML.js +0 -86
- package/packages/extensions/pages/dist/ui/assets/index-BcY6lnq4.css +0 -1
- package/packages/extensions/pages/dist/ui/assets/index-CQjEQg1r.js +0 -2
- /package/dist/{chunk-IYG4FBMP.js → chunk-IJPMIEVE.js} +0 -0
|
@@ -1,51 +1,61 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
loadMergedEnv
|
|
4
|
-
} from "./chunk-IYG4FBMP.js";
|
|
5
2
|
import {
|
|
6
3
|
spiritDir
|
|
7
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-HNGFKPNS.js";
|
|
8
5
|
import {
|
|
9
6
|
clearMind,
|
|
10
7
|
linkInboundToActiveTurn,
|
|
11
8
|
publish as publish3,
|
|
12
9
|
summarizeOrphanedTurns
|
|
13
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-USD45JKR.js";
|
|
14
11
|
import {
|
|
15
12
|
getPrompt
|
|
16
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-MOERAQXH.js";
|
|
17
14
|
import {
|
|
18
15
|
hashSkillDir,
|
|
19
16
|
importSkillFromDir,
|
|
20
17
|
removeSharedSkill,
|
|
21
18
|
sharedSkillsDir
|
|
22
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-HUNDXZBZ.js";
|
|
20
|
+
import {
|
|
21
|
+
getOrCreateMindUser,
|
|
22
|
+
getOrCreateSystemUser,
|
|
23
|
+
getUser,
|
|
24
|
+
getUserByUsername,
|
|
25
|
+
syncMindProfile
|
|
26
|
+
} from "./chunk-ODDGGLM6.js";
|
|
23
27
|
import {
|
|
24
28
|
addMessage,
|
|
25
29
|
createChannel,
|
|
26
30
|
createConversation,
|
|
27
31
|
findDMConversation,
|
|
28
32
|
getChannelByName,
|
|
33
|
+
getChannelSettings,
|
|
29
34
|
getParticipants,
|
|
30
35
|
joinChannel,
|
|
31
|
-
publish as publish2
|
|
36
|
+
publish as publish2,
|
|
37
|
+
updateChannelSettings
|
|
32
38
|
} from "./chunk-HPGN6XRT.js";
|
|
33
39
|
import {
|
|
34
40
|
isSandboxEnabled,
|
|
35
41
|
wrapForSandbox
|
|
36
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-VZRA5TYO.js";
|
|
43
|
+
import {
|
|
44
|
+
MIND_LEVEL_SESSION,
|
|
45
|
+
recordNotice
|
|
46
|
+
} from "./chunk-IYCV34IU.js";
|
|
37
47
|
import {
|
|
38
48
|
markIdle,
|
|
39
49
|
onMindEvent
|
|
40
50
|
} from "./chunk-MTRMQFCQ.js";
|
|
41
51
|
import {
|
|
42
52
|
renderAvatarBlock
|
|
43
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-WQ46E33M.js";
|
|
44
54
|
import {
|
|
45
55
|
readVoluteConfig,
|
|
46
56
|
resolveWakeTriggers,
|
|
47
57
|
writeVoluteConfig
|
|
48
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-WCFSBH33.js";
|
|
49
59
|
import {
|
|
50
60
|
extractTextContent,
|
|
51
61
|
getRoutingConfig,
|
|
@@ -60,22 +70,19 @@ import {
|
|
|
60
70
|
mindUserName,
|
|
61
71
|
wrapForIsolation
|
|
62
72
|
} from "./chunk-DGGZVZTM.js";
|
|
73
|
+
import {
|
|
74
|
+
loadMergedEnv
|
|
75
|
+
} from "./chunk-IJPMIEVE.js";
|
|
63
76
|
import {
|
|
64
77
|
aiCompleteUtility,
|
|
65
78
|
getAiConfig,
|
|
79
|
+
missingCredentialWarning,
|
|
66
80
|
resolveApiKey
|
|
67
|
-
} from "./chunk-
|
|
81
|
+
} from "./chunk-YNBXEQAP.js";
|
|
68
82
|
import {
|
|
69
83
|
readGlobalConfig,
|
|
70
84
|
writeGlobalConfig
|
|
71
|
-
} from "./chunk-
|
|
72
|
-
import {
|
|
73
|
-
getOrCreateMindUser,
|
|
74
|
-
getOrCreateSystemUser,
|
|
75
|
-
getUser,
|
|
76
|
-
getUserByUsername,
|
|
77
|
-
syncMindProfile
|
|
78
|
-
} from "./chunk-ODDGGLM6.js";
|
|
85
|
+
} from "./chunk-5KXCM5AW.js";
|
|
79
86
|
import {
|
|
80
87
|
publish,
|
|
81
88
|
subscribe
|
|
@@ -91,6 +98,7 @@ import {
|
|
|
91
98
|
isSpiritName,
|
|
92
99
|
mindDir,
|
|
93
100
|
mindTmpDir,
|
|
101
|
+
readRegistry,
|
|
94
102
|
setMindRunning,
|
|
95
103
|
stateDir,
|
|
96
104
|
voluteHome,
|
|
@@ -102,28 +110,27 @@ import {
|
|
|
102
110
|
deliveryQueue,
|
|
103
111
|
messages,
|
|
104
112
|
mindHistory,
|
|
105
|
-
mindNotices,
|
|
106
113
|
sessions
|
|
107
114
|
} from "./chunk-2MJ7EOMT.js";
|
|
108
115
|
|
|
109
116
|
// packages/daemon/src/lib/delivery/message-delivery.ts
|
|
110
|
-
import { and as
|
|
117
|
+
import { and as and4, eq as eq5, inArray as inArray3 } from "drizzle-orm";
|
|
111
118
|
|
|
112
119
|
// packages/daemon/src/lib/daemon/sleep-manager.ts
|
|
113
120
|
import { execFile as execFile2, spawn as spawnChild } from "child_process";
|
|
114
121
|
import {
|
|
115
|
-
existsSync as
|
|
122
|
+
existsSync as existsSync9,
|
|
116
123
|
mkdirSync as mkdirSync5,
|
|
117
124
|
readdirSync as readdirSync2,
|
|
118
|
-
readFileSync as
|
|
125
|
+
readFileSync as readFileSync8,
|
|
119
126
|
readlinkSync,
|
|
120
127
|
renameSync,
|
|
121
128
|
writeFileSync as writeFileSync6
|
|
122
129
|
} from "fs";
|
|
123
|
-
import { resolve as
|
|
130
|
+
import { resolve as resolve8 } from "path";
|
|
124
131
|
import { promisify as promisify2 } from "util";
|
|
125
132
|
import { CronExpressionParser as CronExpressionParser2 } from "cron-parser";
|
|
126
|
-
import { and
|
|
133
|
+
import { and, eq as eq2, inArray } from "drizzle-orm";
|
|
127
134
|
|
|
128
135
|
// packages/daemon/src/lib/daemon/mind-manager.ts
|
|
129
136
|
import { execFile, spawn } from "child_process";
|
|
@@ -348,106 +355,6 @@ function getMindToken(mindName) {
|
|
|
348
355
|
return mindToToken.get(mindName) ?? null;
|
|
349
356
|
}
|
|
350
357
|
|
|
351
|
-
// packages/daemon/src/lib/daemon/notices.ts
|
|
352
|
-
import { and, asc, eq, lte, or, sql } from "drizzle-orm";
|
|
353
|
-
var nlog = logger_default.child("notices");
|
|
354
|
-
var MIND_LEVEL_SESSION = "";
|
|
355
|
-
var MAX_NOTICES_PER_SESSION = 100;
|
|
356
|
-
async function recordNotice(input) {
|
|
357
|
-
try {
|
|
358
|
-
const db = await getDb();
|
|
359
|
-
await db.insert(mindNotices).values({
|
|
360
|
-
mind: input.mind,
|
|
361
|
-
session: input.session,
|
|
362
|
-
kind: input.kind,
|
|
363
|
-
reason: input.reason,
|
|
364
|
-
detail: input.detail,
|
|
365
|
-
raw: input.raw ?? null
|
|
366
|
-
});
|
|
367
|
-
await db.run(
|
|
368
|
-
sql`DELETE FROM mind_notices WHERE mind = ${input.mind} AND session = ${input.session} AND id NOT IN (SELECT id FROM mind_notices WHERE mind = ${input.mind} AND session = ${input.session} ORDER BY id DESC LIMIT ${MAX_NOTICES_PER_SESSION})`
|
|
369
|
-
);
|
|
370
|
-
} catch (err) {
|
|
371
|
-
nlog.error(`failed to record notice for ${input.mind}:${input.session}`, logger_default.errorData(err));
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
async function drainNotices(mind, session, limit = MAX_NOTICES_PER_SESSION) {
|
|
375
|
-
const db = await getDb();
|
|
376
|
-
return db.select().from(mindNotices).where(
|
|
377
|
-
and(
|
|
378
|
-
eq(mindNotices.mind, mind),
|
|
379
|
-
or(eq(mindNotices.session, session), eq(mindNotices.session, MIND_LEVEL_SESSION))
|
|
380
|
-
)
|
|
381
|
-
).orderBy(asc(mindNotices.id)).limit(limit);
|
|
382
|
-
}
|
|
383
|
-
async function clearDeliveredNotices(mind, session, uptoId) {
|
|
384
|
-
try {
|
|
385
|
-
const db = await getDb();
|
|
386
|
-
await db.delete(mindNotices).where(
|
|
387
|
-
and(
|
|
388
|
-
eq(mindNotices.mind, mind),
|
|
389
|
-
or(eq(mindNotices.session, session), eq(mindNotices.session, MIND_LEVEL_SESSION)),
|
|
390
|
-
lte(mindNotices.id, uptoId)
|
|
391
|
-
)
|
|
392
|
-
);
|
|
393
|
-
} catch (err) {
|
|
394
|
-
nlog.warn(`failed to clear delivered notices for ${mind}:${session}`, logger_default.errorData(err));
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
var NOTICE_HEADER = "[Notices] While you were unavailable, one or more turns failed. You're back now:";
|
|
398
|
-
function formatNotices(notices) {
|
|
399
|
-
if (notices.length === 0) return null;
|
|
400
|
-
const failures = notices.filter((n) => n.kind !== "extension" && n.kind !== "budget");
|
|
401
|
-
const budgets = notices.filter((n) => n.kind === "budget");
|
|
402
|
-
const extensions = notices.filter((n) => n.kind === "extension");
|
|
403
|
-
const blocks = [];
|
|
404
|
-
if (failures.length > 0) {
|
|
405
|
-
const groups = /* @__PURE__ */ new Map();
|
|
406
|
-
for (const n of failures) {
|
|
407
|
-
const time = localHM(n.created_at);
|
|
408
|
-
const g = groups.get(n.reason);
|
|
409
|
-
if (g) {
|
|
410
|
-
g.count += 1;
|
|
411
|
-
g.detail = n.detail;
|
|
412
|
-
g.last = time;
|
|
413
|
-
} else {
|
|
414
|
-
groups.set(n.reason, { count: 1, detail: n.detail, first: time, last: time });
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
const lines = [...groups.values()].map((g) => {
|
|
418
|
-
const span = g.first === g.last ? g.first : `${g.first}\u2013${g.last}`;
|
|
419
|
-
const plural = g.count === 1 ? "turn" : "turns";
|
|
420
|
-
return `- ${g.count} ${plural} failed (${span}): ${g.detail}`;
|
|
421
|
-
});
|
|
422
|
-
blocks.push(`${NOTICE_HEADER}
|
|
423
|
-
${lines.join("\n")}`);
|
|
424
|
-
}
|
|
425
|
-
if (budgets.length > 0) {
|
|
426
|
-
const lines = budgets.map((n) => `- ${localHM(n.created_at)} ${n.detail}`);
|
|
427
|
-
blocks.push(`[Budget]
|
|
428
|
-
${lines.join("\n")}`);
|
|
429
|
-
}
|
|
430
|
-
if (extensions.length > 0) {
|
|
431
|
-
const byExt = /* @__PURE__ */ new Map();
|
|
432
|
-
for (const n of extensions) {
|
|
433
|
-
const arr = byExt.get(n.reason);
|
|
434
|
-
if (arr) arr.push(n);
|
|
435
|
-
else byExt.set(n.reason, [n]);
|
|
436
|
-
}
|
|
437
|
-
for (const [ext, items] of byExt) {
|
|
438
|
-
const header = `[${ext.charAt(0).toUpperCase()}${ext.slice(1)}]`;
|
|
439
|
-
const lines = items.map((n) => `- ${localHM(n.created_at)} ${n.detail}`);
|
|
440
|
-
blocks.push(`${header}
|
|
441
|
-
${lines.join("\n")}`);
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
return blocks.join("\n\n");
|
|
445
|
-
}
|
|
446
|
-
function localHM(createdAt) {
|
|
447
|
-
const iso = createdAt.endsWith("Z") ? createdAt : `${createdAt.replace(" ", "T")}Z`;
|
|
448
|
-
return new Date(iso).toLocaleTimeString("en-GB", { hour: "2-digit", minute: "2-digit" });
|
|
449
|
-
}
|
|
450
|
-
|
|
451
358
|
// packages/daemon/src/lib/daemon/restart-tracker.ts
|
|
452
359
|
var DEFAULT_MAX_ATTEMPTS = 5;
|
|
453
360
|
var DEFAULT_BASE_DELAY = 3e3;
|
|
@@ -808,7 +715,7 @@ var MindManager = class {
|
|
|
808
715
|
while (recentStderr.length > 20) recentStderr.shift();
|
|
809
716
|
});
|
|
810
717
|
try {
|
|
811
|
-
await new Promise((
|
|
718
|
+
await new Promise((resolve10, reject) => {
|
|
812
719
|
let settled = false;
|
|
813
720
|
const deadline = Date.now() + 3e4;
|
|
814
721
|
const onExit = (code) => {
|
|
@@ -838,7 +745,7 @@ var MindManager = class {
|
|
|
838
745
|
const { ok } = await checkHealth(port);
|
|
839
746
|
if (settled) return;
|
|
840
747
|
if (ok) {
|
|
841
|
-
finish(() =>
|
|
748
|
+
finish(() => resolve10());
|
|
842
749
|
return;
|
|
843
750
|
}
|
|
844
751
|
if (Date.now() >= deadline) {
|
|
@@ -938,7 +845,7 @@ var MindManager = class {
|
|
|
938
845
|
if (this.shuttingDown || this.stopping.has(name)) return;
|
|
939
846
|
mlog.error(`mind ${name} exited with code ${code}`);
|
|
940
847
|
try {
|
|
941
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
848
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-Z27R3WTW.js");
|
|
942
849
|
const sleepMgr = getSleepManagerIfReady2();
|
|
943
850
|
const sleepState = sleepMgr?.getState(name);
|
|
944
851
|
if (sleepState?.sleeping) {
|
|
@@ -968,7 +875,7 @@ var MindManager = class {
|
|
|
968
875
|
(err) => mlog.warn(`failed to clear turn state for ${name} after crash`, logger_default.errorData(err))
|
|
969
876
|
);
|
|
970
877
|
try {
|
|
971
|
-
const { getDeliveryManager: getDeliveryManager2 } = await import("./delivery-manager-
|
|
878
|
+
const { getDeliveryManager: getDeliveryManager2 } = await import("./delivery-manager-HZTT5SJR.js");
|
|
972
879
|
getDeliveryManager2().clearMindSessions(name);
|
|
973
880
|
} catch (err) {
|
|
974
881
|
if (!(err instanceof Error && err.message.includes("not initialized"))) {
|
|
@@ -1006,23 +913,23 @@ var MindManager = class {
|
|
|
1006
913
|
this.stopping.add(name);
|
|
1007
914
|
const { child } = tracked;
|
|
1008
915
|
this.minds.delete(name);
|
|
1009
|
-
await new Promise((
|
|
916
|
+
await new Promise((resolve10) => {
|
|
1010
917
|
const killTimer = setTimeout(() => {
|
|
1011
918
|
try {
|
|
1012
919
|
process.kill(-child.pid, "SIGKILL");
|
|
1013
920
|
} catch {
|
|
1014
921
|
}
|
|
1015
|
-
|
|
922
|
+
resolve10();
|
|
1016
923
|
}, 5e3);
|
|
1017
924
|
child.on("exit", () => {
|
|
1018
925
|
clearTimeout(killTimer);
|
|
1019
|
-
|
|
926
|
+
resolve10();
|
|
1020
927
|
});
|
|
1021
928
|
try {
|
|
1022
929
|
process.kill(-child.pid, "SIGTERM");
|
|
1023
930
|
} catch {
|
|
1024
931
|
clearTimeout(killTimer);
|
|
1025
|
-
|
|
932
|
+
resolve10();
|
|
1026
933
|
}
|
|
1027
934
|
});
|
|
1028
935
|
this.stopping.delete(name);
|
|
@@ -1034,7 +941,7 @@ var MindManager = class {
|
|
|
1034
941
|
mlog.warn(`failed to clear turn state for ${name} on stop`, logger_default.errorData(err));
|
|
1035
942
|
}
|
|
1036
943
|
try {
|
|
1037
|
-
const { getDeliveryManager: getDeliveryManager2 } = await import("./delivery-manager-
|
|
944
|
+
const { getDeliveryManager: getDeliveryManager2 } = await import("./delivery-manager-HZTT5SJR.js");
|
|
1038
945
|
getDeliveryManager2().clearMindSessions(name);
|
|
1039
946
|
} catch (err) {
|
|
1040
947
|
if (!(err instanceof Error && err.message.includes("not initialized"))) {
|
|
@@ -1042,7 +949,7 @@ var MindManager = class {
|
|
|
1042
949
|
}
|
|
1043
950
|
}
|
|
1044
951
|
try {
|
|
1045
|
-
const { clearEchoTextCache } = await import("./echo-text-
|
|
952
|
+
const { clearEchoTextCache } = await import("./echo-text-H3SH337Q.js");
|
|
1046
953
|
clearEchoTextCache(name);
|
|
1047
954
|
} catch (err) {
|
|
1048
955
|
mlog.debug(`failed to clear echo-text cache for ${name}`, logger_default.errorData(err));
|
|
@@ -1126,17 +1033,30 @@ function tryGetMindManager() {
|
|
|
1126
1033
|
return instance;
|
|
1127
1034
|
}
|
|
1128
1035
|
|
|
1036
|
+
// packages/daemon/src/lib/daemon/mind-service.ts
|
|
1037
|
+
import { existsSync as existsSync8, readFileSync as readFileSync7 } from "fs";
|
|
1038
|
+
import { resolve as resolve7 } from "path";
|
|
1039
|
+
|
|
1129
1040
|
// packages/daemon/src/lib/chat/system-channel.ts
|
|
1130
1041
|
var SYSTEM_CHANNEL_NAME = "system";
|
|
1042
|
+
var SYSTEM_CHANNEL_DESCRIPTION = "The commons \u2014 a shared room for every mind and the spirit on this system. Think out loud, check in, riff, coordinate.";
|
|
1131
1043
|
var cachedChannelId = null;
|
|
1132
1044
|
async function ensureSystemChannel() {
|
|
1133
1045
|
if (cachedChannelId) return cachedChannelId;
|
|
1134
1046
|
const existing = await getChannelByName(SYSTEM_CHANNEL_NAME);
|
|
1135
1047
|
if (existing) {
|
|
1136
1048
|
cachedChannelId = existing.id;
|
|
1049
|
+
const settings = await getChannelSettings(SYSTEM_CHANNEL_NAME);
|
|
1050
|
+
if (settings && settings.description == null) {
|
|
1051
|
+
await updateChannelSettings(SYSTEM_CHANNEL_NAME, {
|
|
1052
|
+
description: SYSTEM_CHANNEL_DESCRIPTION
|
|
1053
|
+
});
|
|
1054
|
+
}
|
|
1137
1055
|
return existing.id;
|
|
1138
1056
|
}
|
|
1139
|
-
const conv = await createChannel(SYSTEM_CHANNEL_NAME
|
|
1057
|
+
const conv = await createChannel(SYSTEM_CHANNEL_NAME, void 0, {
|
|
1058
|
+
description: SYSTEM_CHANNEL_DESCRIPTION
|
|
1059
|
+
});
|
|
1140
1060
|
cachedChannelId = conv.id;
|
|
1141
1061
|
logger_default.info("created #system channel");
|
|
1142
1062
|
return conv.id;
|
|
@@ -1149,6 +1069,25 @@ async function joinSystemChannelForMind(mindName) {
|
|
|
1149
1069
|
const user = await getOrCreateMindUser(mindName);
|
|
1150
1070
|
await joinSystemChannel(user.id);
|
|
1151
1071
|
}
|
|
1072
|
+
async function joinSystemChannelForSpirit() {
|
|
1073
|
+
const user = await getOrCreateSystemUser();
|
|
1074
|
+
await joinSystemChannel(user.id);
|
|
1075
|
+
}
|
|
1076
|
+
async function backfillSystemChannelMembers() {
|
|
1077
|
+
const entries = await readRegistry();
|
|
1078
|
+
for (const entry of entries) {
|
|
1079
|
+
if (entry.stage === "seed") continue;
|
|
1080
|
+
try {
|
|
1081
|
+
if (entry.mindType === "spirit") {
|
|
1082
|
+
await joinSystemChannelForSpirit();
|
|
1083
|
+
} else {
|
|
1084
|
+
await joinSystemChannelForMind(entry.name);
|
|
1085
|
+
}
|
|
1086
|
+
} catch (err) {
|
|
1087
|
+
logger_default.error(`failed to backfill ${entry.name} into #system`, logger_default.errorData(err));
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1152
1091
|
async function announceToSystem(text) {
|
|
1153
1092
|
const channelId = await ensureSystemChannel();
|
|
1154
1093
|
const systemUser = await getOrCreateSystemUser();
|
|
@@ -1178,7 +1117,7 @@ import { dirname, resolve as resolve4 } from "path";
|
|
|
1178
1117
|
|
|
1179
1118
|
// packages/daemon/src/web/middleware/auth.ts
|
|
1180
1119
|
import { timingSafeEqual } from "crypto";
|
|
1181
|
-
import { eq
|
|
1120
|
+
import { eq, lt } from "drizzle-orm";
|
|
1182
1121
|
import { getCookie } from "hono/cookie";
|
|
1183
1122
|
import { createMiddleware } from "hono/factory";
|
|
1184
1123
|
var MIND_USER_CACHE_TTL = 5 * 60 * 1e3;
|
|
@@ -1206,14 +1145,14 @@ async function createSession(userId) {
|
|
|
1206
1145
|
async function deleteSession(sessionId) {
|
|
1207
1146
|
sessionCache.delete(sessionId);
|
|
1208
1147
|
const db = await getDb();
|
|
1209
|
-
await db.delete(sessions).where(
|
|
1148
|
+
await db.delete(sessions).where(eq(sessions.id, sessionId));
|
|
1210
1149
|
}
|
|
1211
1150
|
async function getSessionUserId(sessionId) {
|
|
1212
1151
|
const db = await getDb();
|
|
1213
|
-
const row = await db.select().from(sessions).where(
|
|
1152
|
+
const row = await db.select().from(sessions).where(eq(sessions.id, sessionId)).get();
|
|
1214
1153
|
if (!row) return void 0;
|
|
1215
1154
|
if (Date.now() - row.createdAt > SESSION_MAX_AGE) {
|
|
1216
|
-
await db.delete(sessions).where(
|
|
1155
|
+
await db.delete(sessions).where(eq(sessions.id, sessionId));
|
|
1217
1156
|
return void 0;
|
|
1218
1157
|
}
|
|
1219
1158
|
return row.userId;
|
|
@@ -1734,7 +1673,7 @@ function resolveSkillsDir(manifest) {
|
|
|
1734
1673
|
async function discoverBuiltinExtensions(disabledIds) {
|
|
1735
1674
|
const builtins = [
|
|
1736
1675
|
{ id: "notes", load: async () => (await import("./src-YH6PQ7LJ.js")).default },
|
|
1737
|
-
{ id: "pages", load: async () => (await import("./src-
|
|
1676
|
+
{ id: "pages", load: async () => (await import("./src-WLJE73NP.js")).default },
|
|
1738
1677
|
{ id: "plan", load: async () => (await import("./src-JAOVXO5W.js")).default }
|
|
1739
1678
|
];
|
|
1740
1679
|
const results = [];
|
|
@@ -2467,10 +2406,17 @@ var Scheduler = class {
|
|
|
2467
2406
|
${stderr}` : ""}`;
|
|
2468
2407
|
slog2.warn(`script "${schedule.id}" failed for ${mindName}`, logger_default.errorData(err));
|
|
2469
2408
|
}
|
|
2409
|
+
} else if (Array.isArray(schedule.messages) && schedule.messages.length > 0) {
|
|
2410
|
+
const pick = schedule.messages[Math.floor(Math.random() * schedule.messages.length)];
|
|
2411
|
+
if (typeof pick !== "string" || !pick.trim()) {
|
|
2412
|
+
slog2.warn(`schedule "${schedule.id}" for ${mindName} has a malformed messages pool`);
|
|
2413
|
+
return;
|
|
2414
|
+
}
|
|
2415
|
+
text = pick;
|
|
2470
2416
|
} else if (schedule.message) {
|
|
2471
2417
|
text = schedule.message;
|
|
2472
2418
|
} else {
|
|
2473
|
-
slog2.warn(`schedule "${schedule.id}" for ${mindName} has no message or script`);
|
|
2419
|
+
slog2.warn(`schedule "${schedule.id}" for ${mindName} has no message, messages, or script`);
|
|
2474
2420
|
return;
|
|
2475
2421
|
}
|
|
2476
2422
|
await this.deliverSystem(mindName, `[${schedule.id}] ${text}`, {
|
|
@@ -2790,6 +2736,9 @@ async function startMindFull(name) {
|
|
|
2790
2736
|
summary: `${name} started`
|
|
2791
2737
|
}).catch((err) => logger_default.error("failed to publish mind_started activity", logger_default.errorData(err)));
|
|
2792
2738
|
if (entry?.parent) return;
|
|
2739
|
+
recordMissingCredentialsNotice(baseName, entry?.template).catch(
|
|
2740
|
+
(err) => logger_default.error(`failed to check credentials for ${baseName}`, logger_default.errorData(err))
|
|
2741
|
+
);
|
|
2793
2742
|
if (!entry || entry.stage === "seed") {
|
|
2794
2743
|
if (entry?.stage === "seed") {
|
|
2795
2744
|
sendSeedOrientation(baseName, entry.createdBy).catch(
|
|
@@ -2834,6 +2783,31 @@ async function startMindFull(name) {
|
|
|
2834
2783
|
}
|
|
2835
2784
|
notifyExtensionsMindStart(baseName);
|
|
2836
2785
|
}
|
|
2786
|
+
async function recordMissingCredentialsNotice(mind, template) {
|
|
2787
|
+
const { hasUndeliveredNotice, recordNotice: recordNotice2, MIND_LEVEL_SESSION: MIND_LEVEL_SESSION2 } = await import("./notices-2KU5NTRY.js");
|
|
2788
|
+
const warning = await missingCredentialWarning(template, readMindModel(mind, template), mind);
|
|
2789
|
+
if (!warning) return;
|
|
2790
|
+
if (await hasUndeliveredNotice(mind, "no_credentials")) return;
|
|
2791
|
+
await recordNotice2({
|
|
2792
|
+
mind,
|
|
2793
|
+
session: MIND_LEVEL_SESSION2,
|
|
2794
|
+
kind: "startup",
|
|
2795
|
+
reason: "no_credentials",
|
|
2796
|
+
detail: warning
|
|
2797
|
+
});
|
|
2798
|
+
}
|
|
2799
|
+
function readMindModel(mind, template) {
|
|
2800
|
+
if (template !== "pi") return void 0;
|
|
2801
|
+
try {
|
|
2802
|
+
const configPath2 = resolve7(mindDir(mind), "home/.config/config.json");
|
|
2803
|
+
if (!existsSync8(configPath2)) return void 0;
|
|
2804
|
+
const model = JSON.parse(readFileSync7(configPath2, "utf-8")).model;
|
|
2805
|
+
return typeof model === "string" ? model : void 0;
|
|
2806
|
+
} catch (err) {
|
|
2807
|
+
logger_default.warn(`failed to read model for ${mind}`, logger_default.errorData(err));
|
|
2808
|
+
return void 0;
|
|
2809
|
+
}
|
|
2810
|
+
}
|
|
2837
2811
|
async function sleepMind(name) {
|
|
2838
2812
|
markIdle(name);
|
|
2839
2813
|
await getMindManager().stopMind(name);
|
|
@@ -2858,6 +2832,9 @@ async function startSpiritFull(name) {
|
|
|
2858
2832
|
registerMindDir(name, entry.dir);
|
|
2859
2833
|
}
|
|
2860
2834
|
await getMindManager().startMind(name);
|
|
2835
|
+
joinSystemChannelForSpirit().catch(
|
|
2836
|
+
(err) => logger_default.error(`failed to join #system for ${name}`, logger_default.errorData(err))
|
|
2837
|
+
);
|
|
2861
2838
|
getScheduler().loadSchedules(name, entry?.dir ?? spiritDir());
|
|
2862
2839
|
publish({
|
|
2863
2840
|
type: "mind_started",
|
|
@@ -2987,7 +2964,7 @@ var SleepManager = class {
|
|
|
2987
2964
|
transitioning = /* @__PURE__ */ new Set();
|
|
2988
2965
|
sleepConfigs = /* @__PURE__ */ new Map();
|
|
2989
2966
|
get statePath() {
|
|
2990
|
-
return
|
|
2967
|
+
return resolve8(voluteSystemDir(), "sleep-state.json");
|
|
2991
2968
|
}
|
|
2992
2969
|
start() {
|
|
2993
2970
|
this.loadState();
|
|
@@ -3003,8 +2980,8 @@ var SleepManager = class {
|
|
|
3003
2980
|
// --- State persistence ---
|
|
3004
2981
|
loadState() {
|
|
3005
2982
|
try {
|
|
3006
|
-
if (
|
|
3007
|
-
const data = JSON.parse(
|
|
2983
|
+
if (existsSync9(this.statePath)) {
|
|
2984
|
+
const data = JSON.parse(readFileSync8(this.statePath, "utf-8"));
|
|
3008
2985
|
for (const [name, state2] of Object.entries(data)) {
|
|
3009
2986
|
state2.triggerWakeHistory ??= [];
|
|
3010
2987
|
state2.wakeFailures ??= 0;
|
|
@@ -3295,7 +3272,7 @@ var SleepManager = class {
|
|
|
3295
3272
|
async flushQueuedMessages(name) {
|
|
3296
3273
|
try {
|
|
3297
3274
|
const db = await getDb();
|
|
3298
|
-
const rows = await db.select().from(deliveryQueue).where(
|
|
3275
|
+
const rows = await db.select().from(deliveryQueue).where(and(eq2(deliveryQueue.mind, name), eq2(deliveryQueue.status, "sleep-queued"))).all();
|
|
3299
3276
|
if (rows.length === 0) return 0;
|
|
3300
3277
|
const groups = /* @__PURE__ */ new Map();
|
|
3301
3278
|
for (const row of rows) {
|
|
@@ -3307,7 +3284,7 @@ var SleepManager = class {
|
|
|
3307
3284
|
`dropping unparseable queued message ${row.id} for ${name}`,
|
|
3308
3285
|
logger_default.errorData(err)
|
|
3309
3286
|
);
|
|
3310
|
-
await db.delete(deliveryQueue).where(
|
|
3287
|
+
await db.delete(deliveryQueue).where(eq2(deliveryQueue.id, row.id));
|
|
3311
3288
|
continue;
|
|
3312
3289
|
}
|
|
3313
3290
|
const channel = payload.channel ?? "unknown";
|
|
@@ -3350,7 +3327,7 @@ var SleepManager = class {
|
|
|
3350
3327
|
* the real delivery stack. Returns whether the batch was handed off to the mind.
|
|
3351
3328
|
*/
|
|
3352
3329
|
async deliverQueuedBatch(name, payloads) {
|
|
3353
|
-
const { deliverBatch: deliverBatch2 } = await import("./message-delivery-
|
|
3330
|
+
const { deliverBatch: deliverBatch2 } = await import("./message-delivery-GPQ5SE5N.js");
|
|
3354
3331
|
return deliverBatch2(name, payloads);
|
|
3355
3332
|
}
|
|
3356
3333
|
// --- Wake failure handling (#419) ---
|
|
@@ -3528,17 +3505,17 @@ var SleepManager = class {
|
|
|
3528
3505
|
}
|
|
3529
3506
|
}
|
|
3530
3507
|
async waitForIdle(name, timeoutMs) {
|
|
3531
|
-
return new Promise((
|
|
3508
|
+
return new Promise((resolve10) => {
|
|
3532
3509
|
const timeout = setTimeout(() => {
|
|
3533
3510
|
unsub();
|
|
3534
|
-
|
|
3511
|
+
resolve10();
|
|
3535
3512
|
}, timeoutMs);
|
|
3536
3513
|
const unsub = subscribe((event) => {
|
|
3537
3514
|
if (event.mind !== name) return;
|
|
3538
3515
|
if (event.type === "mind_done" || event.type === "mind_idle") {
|
|
3539
3516
|
clearTimeout(timeout);
|
|
3540
3517
|
unsub();
|
|
3541
|
-
|
|
3518
|
+
resolve10();
|
|
3542
3519
|
}
|
|
3543
3520
|
});
|
|
3544
3521
|
});
|
|
@@ -3546,15 +3523,15 @@ var SleepManager = class {
|
|
|
3546
3523
|
async archiveSessions(name) {
|
|
3547
3524
|
const dir = mindDir(name);
|
|
3548
3525
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 16);
|
|
3549
|
-
const sessionsDir =
|
|
3550
|
-
if (
|
|
3551
|
-
const archiveDir =
|
|
3526
|
+
const sessionsDir = resolve8(dir, ".mind", "sessions");
|
|
3527
|
+
if (existsSync9(sessionsDir)) {
|
|
3528
|
+
const archiveDir = resolve8(sessionsDir, "archive");
|
|
3552
3529
|
mkdirSync5(archiveDir, { recursive: true });
|
|
3553
3530
|
for (const file of readdirSync2(sessionsDir)) {
|
|
3554
3531
|
if (file === "archive" || !file.endsWith(".json")) continue;
|
|
3555
|
-
const src =
|
|
3532
|
+
const src = resolve8(sessionsDir, file);
|
|
3556
3533
|
const base = file.replace(/\.json$/, "");
|
|
3557
|
-
const dest =
|
|
3534
|
+
const dest = resolve8(archiveDir, `${base}-${timestamp}.json`);
|
|
3558
3535
|
try {
|
|
3559
3536
|
renameSync(src, dest);
|
|
3560
3537
|
} catch (err) {
|
|
@@ -3562,14 +3539,14 @@ var SleepManager = class {
|
|
|
3562
3539
|
}
|
|
3563
3540
|
}
|
|
3564
3541
|
}
|
|
3565
|
-
const piSessionsDir =
|
|
3566
|
-
if (
|
|
3567
|
-
const archiveDir =
|
|
3542
|
+
const piSessionsDir = resolve8(dir, ".mind", "pi-sessions");
|
|
3543
|
+
if (existsSync9(piSessionsDir)) {
|
|
3544
|
+
const archiveDir = resolve8(piSessionsDir, "archive");
|
|
3568
3545
|
mkdirSync5(archiveDir, { recursive: true });
|
|
3569
3546
|
for (const entry of readdirSync2(piSessionsDir, { withFileTypes: true })) {
|
|
3570
3547
|
if (entry.name === "archive" || !entry.isDirectory()) continue;
|
|
3571
|
-
const src =
|
|
3572
|
-
const dest =
|
|
3548
|
+
const src = resolve8(piSessionsDir, entry.name);
|
|
3549
|
+
const dest = resolve8(archiveDir, `${entry.name}-${timestamp}`);
|
|
3573
3550
|
try {
|
|
3574
3551
|
renameSync(src, dest);
|
|
3575
3552
|
} catch (err) {
|
|
@@ -3579,8 +3556,8 @@ var SleepManager = class {
|
|
|
3579
3556
|
}
|
|
3580
3557
|
}
|
|
3581
3558
|
async runWakeContextScript(name, sleepingSince, duration) {
|
|
3582
|
-
const scriptPath =
|
|
3583
|
-
if (!
|
|
3559
|
+
const scriptPath = resolve8(mindDir(name), "home", ".local", "hooks", "wake-context.sh");
|
|
3560
|
+
if (!existsSync9(scriptPath)) return "";
|
|
3584
3561
|
const input = JSON.stringify({
|
|
3585
3562
|
sleepingSince,
|
|
3586
3563
|
duration,
|
|
@@ -3630,7 +3607,7 @@ var SleepManager = class {
|
|
|
3630
3607
|
async buildQueuedSummary(name) {
|
|
3631
3608
|
try {
|
|
3632
3609
|
const db = await getDb();
|
|
3633
|
-
const rows = await db.select({ channel: deliveryQueue.channel, sender: deliveryQueue.sender }).from(deliveryQueue).where(
|
|
3610
|
+
const rows = await db.select({ channel: deliveryQueue.channel, sender: deliveryQueue.sender }).from(deliveryQueue).where(and(eq2(deliveryQueue.mind, name), eq2(deliveryQueue.status, "sleep-queued"))).all();
|
|
3634
3611
|
if (rows.length === 0) return "No messages arrived while you slept.";
|
|
3635
3612
|
const channelCounts = /* @__PURE__ */ new Map();
|
|
3636
3613
|
const senders = /* @__PURE__ */ new Set();
|
|
@@ -3677,7 +3654,7 @@ var SleepManager = class {
|
|
|
3677
3654
|
} catch {
|
|
3678
3655
|
try {
|
|
3679
3656
|
const portHex = port.toString(16).toUpperCase().padStart(4, "0");
|
|
3680
|
-
const tcp6 =
|
|
3657
|
+
const tcp6 = readFileSync8("/proc/net/tcp6", "utf-8");
|
|
3681
3658
|
for (const line of tcp6.split("\n")) {
|
|
3682
3659
|
if (!line.includes(`:${portHex} `)) continue;
|
|
3683
3660
|
const fields = line.trim().split(/\s+/);
|
|
@@ -3746,8 +3723,8 @@ function getSleepManagerIfReady() {
|
|
|
3746
3723
|
|
|
3747
3724
|
// packages/daemon/src/lib/delivery/delivery-manager.ts
|
|
3748
3725
|
import { realpath } from "fs/promises";
|
|
3749
|
-
import { resolve as
|
|
3750
|
-
import { and as
|
|
3726
|
+
import { resolve as resolve9 } from "path";
|
|
3727
|
+
import { and as and3, eq as eq4, inArray as inArray2, sql } from "drizzle-orm";
|
|
3751
3728
|
|
|
3752
3729
|
// packages/daemon/src/lib/chat/typing.ts
|
|
3753
3730
|
var DEFAULT_TTL_MS = 1e4;
|
|
@@ -3841,7 +3818,7 @@ function publishTypingForChannels(channels, map) {
|
|
|
3841
3818
|
}
|
|
3842
3819
|
|
|
3843
3820
|
// packages/daemon/src/lib/delivery/send-gate.ts
|
|
3844
|
-
import { and as
|
|
3821
|
+
import { and as and2, asc, desc, eq as eq3, gt } from "drizzle-orm";
|
|
3845
3822
|
var state = /* @__PURE__ */ new Map();
|
|
3846
3823
|
function extractText(raw) {
|
|
3847
3824
|
if (!raw) return "";
|
|
@@ -3856,7 +3833,7 @@ function extractText(raw) {
|
|
|
3856
3833
|
}
|
|
3857
3834
|
async function maxMessageId(conversationId) {
|
|
3858
3835
|
const db = await getDb();
|
|
3859
|
-
const rows = await db.select({ id: messages.id }).from(messages).where(
|
|
3836
|
+
const rows = await db.select({ id: messages.id }).from(messages).where(eq3(messages.conversation_id, conversationId)).orderBy(desc(messages.id)).limit(1);
|
|
3860
3837
|
return rows[0]?.id ?? 0;
|
|
3861
3838
|
}
|
|
3862
3839
|
async function onDeliveredToMind(mindBase, conversationId) {
|
|
@@ -3875,7 +3852,7 @@ async function checkStaleSend(mindBase, conversationId, excludeSenders) {
|
|
|
3875
3852
|
const entry = state.get(mindBase)?.get(conversationId);
|
|
3876
3853
|
if (!entry?.turnOpen || entry.heldThisTurn) return { held: false };
|
|
3877
3854
|
const db = await getDb();
|
|
3878
|
-
const rows = await db.select({ id: messages.id, sender: messages.sender_name, content: messages.content }).from(messages).where(
|
|
3855
|
+
const rows = await db.select({ id: messages.id, sender: messages.sender_name, content: messages.content }).from(messages).where(and2(eq3(messages.conversation_id, conversationId), gt(messages.id, entry.baselineId))).orderBy(asc(messages.id));
|
|
3879
3856
|
const excluded = new Set(excludeSenders.filter(Boolean));
|
|
3880
3857
|
const unseen = rows.filter((r) => r.sender && !excluded.has(r.sender));
|
|
3881
3858
|
if (unseen.length === 0) return { held: false };
|
|
@@ -3936,7 +3913,7 @@ var DeliveryManager = class {
|
|
|
3936
3913
|
isMindRunning = (name) => tryGetMindManager()?.isRunning(name) ?? false;
|
|
3937
3914
|
/** Sends a system message to a mind (invites, release summaries); overridable in tests. */
|
|
3938
3915
|
notify = async (mindName, text) => {
|
|
3939
|
-
const { sendSystemMessage: sendSystemMessage2 } = await import("./system-chat-
|
|
3916
|
+
const { sendSystemMessage: sendSystemMessage2 } = await import("./system-chat-63ABFF6V.js");
|
|
3940
3917
|
await sendSystemMessage2(mindName, text);
|
|
3941
3918
|
};
|
|
3942
3919
|
constructor() {
|
|
@@ -4070,9 +4047,9 @@ var DeliveryManager = class {
|
|
|
4070
4047
|
try {
|
|
4071
4048
|
const db = await getDb();
|
|
4072
4049
|
rows = await db.select().from(deliveryQueue).where(
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4050
|
+
and3(
|
|
4051
|
+
eq4(deliveryQueue.status, "pending"),
|
|
4052
|
+
sql`(${deliveryQueue.next_attempt_at} IS NULL OR ${deliveryQueue.next_attempt_at} <= datetime('now'))`
|
|
4076
4053
|
)
|
|
4077
4054
|
).orderBy(deliveryQueue.id).limit(REDRIVE_BATCH_LIMIT);
|
|
4078
4055
|
} catch (err) {
|
|
@@ -4132,7 +4109,7 @@ var DeliveryManager = class {
|
|
|
4132
4109
|
let rows;
|
|
4133
4110
|
try {
|
|
4134
4111
|
const db = await getDb();
|
|
4135
|
-
rows = await db.select().from(deliveryQueue).where(
|
|
4112
|
+
rows = await db.select().from(deliveryQueue).where(and3(eq4(deliveryQueue.mind, baseName), eq4(deliveryQueue.status, "gated")));
|
|
4136
4113
|
} catch (err) {
|
|
4137
4114
|
dlog.warn(`failed to read gated rows for ${baseName}`, logger_default.errorData(err));
|
|
4138
4115
|
return;
|
|
@@ -4202,7 +4179,7 @@ var DeliveryManager = class {
|
|
|
4202
4179
|
try {
|
|
4203
4180
|
const db = await getDb();
|
|
4204
4181
|
for (const p of promote) {
|
|
4205
|
-
await db.update(deliveryQueue).set({ status: "pending", session: p.session, attempts: 0, next_attempt_at: null }).where(
|
|
4182
|
+
await db.update(deliveryQueue).set({ status: "pending", session: p.session, attempts: 0, next_attempt_at: null }).where(eq4(deliveryQueue.id, p.id));
|
|
4206
4183
|
}
|
|
4207
4184
|
dlog.info(`released ${promote.length} gated message(s) for ${baseName} after route change`);
|
|
4208
4185
|
} catch (err) {
|
|
@@ -4220,7 +4197,7 @@ var DeliveryManager = class {
|
|
|
4220
4197
|
if (!channel) return false;
|
|
4221
4198
|
try {
|
|
4222
4199
|
const db = await getDb();
|
|
4223
|
-
const rows = await db.select({ state: channelGates.state }).from(channelGates).where(
|
|
4200
|
+
const rows = await db.select({ state: channelGates.state }).from(channelGates).where(and3(eq4(channelGates.mind, baseName), eq4(channelGates.channel, channel)));
|
|
4224
4201
|
return rows[0]?.state === "declined";
|
|
4225
4202
|
} catch (err) {
|
|
4226
4203
|
dlog.warn(`failed to read gate state for ${baseName}/${channel}`, logger_default.errorData(err));
|
|
@@ -4237,13 +4214,13 @@ var DeliveryManager = class {
|
|
|
4237
4214
|
const db = await getDb();
|
|
4238
4215
|
await db.insert(channelGates).values({ mind: baseName, channel, state: "declined" }).onConflictDoUpdate({
|
|
4239
4216
|
target: [channelGates.mind, channelGates.channel],
|
|
4240
|
-
set: { state: "declined", updated_at:
|
|
4217
|
+
set: { state: "declined", updated_at: sql`(datetime('now'))` }
|
|
4241
4218
|
});
|
|
4242
4219
|
const archived = await db.update(deliveryQueue).set({ status: "archived" }).where(
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4220
|
+
and3(
|
|
4221
|
+
eq4(deliveryQueue.mind, baseName),
|
|
4222
|
+
eq4(deliveryQueue.channel, channel),
|
|
4223
|
+
eq4(deliveryQueue.status, "gated")
|
|
4247
4224
|
)
|
|
4248
4225
|
).returning({ id: deliveryQueue.id });
|
|
4249
4226
|
dlog.info(
|
|
@@ -4273,7 +4250,7 @@ var DeliveryManager = class {
|
|
|
4273
4250
|
*/
|
|
4274
4251
|
async getPending(mindName) {
|
|
4275
4252
|
const db = await getDb();
|
|
4276
|
-
const rows = await db.select().from(deliveryQueue).where(
|
|
4253
|
+
const rows = await db.select().from(deliveryQueue).where(and3(eq4(deliveryQueue.mind, mindName), eq4(deliveryQueue.status, "gated")));
|
|
4277
4254
|
const byChannel = /* @__PURE__ */ new Map();
|
|
4278
4255
|
for (const row of rows) {
|
|
4279
4256
|
const ch = row.channel ?? "unknown";
|
|
@@ -4443,7 +4420,7 @@ var DeliveryManager = class {
|
|
|
4443
4420
|
const backoffSec = Math.round(
|
|
4444
4421
|
Math.min(RETRY_MAX_MS, RETRY_BASE_MS * 2 ** Math.min(attempts, 20)) / 1e3
|
|
4445
4422
|
);
|
|
4446
|
-
await db.update(deliveryQueue).set({ attempts, next_attempt_at:
|
|
4423
|
+
await db.update(deliveryQueue).set({ attempts, next_attempt_at: sql`datetime('now', ${`+${backoffSec} seconds`})` }).where(eq4(deliveryQueue.id, row.id));
|
|
4447
4424
|
}
|
|
4448
4425
|
} catch (err) {
|
|
4449
4426
|
dlog.warn("failed to schedule delivery retry", logger_default.errorData(err));
|
|
@@ -4672,10 +4649,10 @@ var DeliveryManager = class {
|
|
|
4672
4649
|
if (declined) return;
|
|
4673
4650
|
try {
|
|
4674
4651
|
const db = await getDb();
|
|
4675
|
-
const rows = await db.select({ count:
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
|
|
4652
|
+
const rows = await db.select({ count: sql`count(*)` }).from(deliveryQueue).where(
|
|
4653
|
+
and3(
|
|
4654
|
+
eq4(deliveryQueue.mind, baseName),
|
|
4655
|
+
eq4(deliveryQueue.channel, payload.channel),
|
|
4679
4656
|
inArray2(deliveryQueue.status, ["gated", "archived"])
|
|
4680
4657
|
)
|
|
4681
4658
|
);
|
|
@@ -4777,8 +4754,8 @@ var DeliveryManager = class {
|
|
|
4777
4754
|
const dir = mindDir(p.username);
|
|
4778
4755
|
const config = readVoluteConfig(dir);
|
|
4779
4756
|
if (!config?.profile?.avatar) continue;
|
|
4780
|
-
filePath =
|
|
4781
|
-
const homeDir =
|
|
4757
|
+
filePath = resolve9(dir, "home", config.profile.avatar);
|
|
4758
|
+
const homeDir = resolve9(dir, "home");
|
|
4782
4759
|
if (!filePath.startsWith(`${homeDir}/`)) {
|
|
4783
4760
|
dlog.warn(`avatar path for ${p.username} escapes home directory, skipping`);
|
|
4784
4761
|
continue;
|
|
@@ -4797,7 +4774,7 @@ var DeliveryManager = class {
|
|
|
4797
4774
|
throw err;
|
|
4798
4775
|
}
|
|
4799
4776
|
} else {
|
|
4800
|
-
filePath =
|
|
4777
|
+
filePath = resolve9(voluteHome(), "avatars", p.avatar);
|
|
4801
4778
|
}
|
|
4802
4779
|
const rendered = await renderAvatarBlock(filePath, p.username);
|
|
4803
4780
|
if (rendered) blocks.push(...rendered);
|
|
@@ -4925,7 +4902,7 @@ async function linkToolResultToTurn(mind, turnId, toolResultContent, toolUseEven
|
|
|
4925
4902
|
content: mindHistory.content,
|
|
4926
4903
|
message_id: mindHistory.message_id,
|
|
4927
4904
|
turn_id: mindHistory.turn_id
|
|
4928
|
-
}).from(mindHistory).where(
|
|
4905
|
+
}).from(mindHistory).where(and4(eq5(mindHistory.id, outboundId), eq5(mindHistory.mind, mind))).limit(1);
|
|
4929
4906
|
const row = rows[0];
|
|
4930
4907
|
if (!row) {
|
|
4931
4908
|
dlog2.warn(`outbound marker references missing record: mind=${mind} id=${outboundId}`);
|
|
@@ -4933,13 +4910,13 @@ async function linkToolResultToTurn(mind, turnId, toolResultContent, toolUseEven
|
|
|
4933
4910
|
}
|
|
4934
4911
|
const alreadyTagged = row.turn_id != null;
|
|
4935
4912
|
if (!alreadyTagged) {
|
|
4936
|
-
await db.update(mindHistory).set({ turn_id: turnId }).where(
|
|
4913
|
+
await db.update(mindHistory).set({ turn_id: turnId }).where(eq5(mindHistory.id, outboundId));
|
|
4937
4914
|
}
|
|
4938
4915
|
if (row.message_id) {
|
|
4939
4916
|
await db.update(messages).set({
|
|
4940
4917
|
turn_id: turnId,
|
|
4941
4918
|
...toolUseEventId != null ? { source_event_id: toolUseEventId } : {}
|
|
4942
|
-
}).where(
|
|
4919
|
+
}).where(eq5(messages.id, Number(row.message_id)));
|
|
4943
4920
|
}
|
|
4944
4921
|
if (!alreadyTagged) {
|
|
4945
4922
|
publish3(mind, {
|
|
@@ -5128,7 +5105,7 @@ async function spiritWillHandle() {
|
|
|
5128
5105
|
const spiritEntry = await findMind(SPIRIT_NAME);
|
|
5129
5106
|
if (spiritEntry?.running && spiritEntry.mindType === "spirit") return true;
|
|
5130
5107
|
try {
|
|
5131
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
5108
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-Z27R3WTW.js");
|
|
5132
5109
|
const sm = getSleepManagerIfReady2();
|
|
5133
5110
|
if (sm?.isSleeping(SPIRIT_NAME)) return true;
|
|
5134
5111
|
} catch (err) {
|
|
@@ -5156,7 +5133,7 @@ async function generateSystemFallbackReply(conversationId, mindName, message) {
|
|
|
5156
5133
|
if (config.sleep.schedule?.wake) contextParts.push(`Wake cron: ${config.sleep.schedule.wake}`);
|
|
5157
5134
|
}
|
|
5158
5135
|
try {
|
|
5159
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
5136
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-Z27R3WTW.js");
|
|
5160
5137
|
const sm = getSleepManagerIfReady2();
|
|
5161
5138
|
if (sm) {
|
|
5162
5139
|
const state2 = sm.getState(mindName);
|
|
@@ -5210,10 +5187,6 @@ export {
|
|
|
5210
5187
|
checkHealth,
|
|
5211
5188
|
RotatingLog,
|
|
5212
5189
|
syncProviderToMinds,
|
|
5213
|
-
recordNotice,
|
|
5214
|
-
drainNotices,
|
|
5215
|
-
clearDeliveredNotices,
|
|
5216
|
-
formatNotices,
|
|
5217
5190
|
RestartTracker,
|
|
5218
5191
|
getTypingMap,
|
|
5219
5192
|
isConversationId,
|
|
@@ -5262,6 +5235,7 @@ export {
|
|
|
5262
5235
|
initTokenBudget,
|
|
5263
5236
|
getTokenBudget,
|
|
5264
5237
|
startMindFull,
|
|
5238
|
+
recordMissingCredentialsNotice,
|
|
5265
5239
|
sleepMind,
|
|
5266
5240
|
wakeMind,
|
|
5267
5241
|
startSpiritFull,
|
|
@@ -5281,5 +5255,6 @@ export {
|
|
|
5281
5255
|
deliverBatch,
|
|
5282
5256
|
ensureSystemChannel,
|
|
5283
5257
|
joinSystemChannel,
|
|
5258
|
+
backfillSystemChannelMembers,
|
|
5284
5259
|
announceToSystem
|
|
5285
5260
|
};
|