volute 0.47.0 → 0.49.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 +82 -331
- package/dist/{accept-YAFP5JFJ.js → accept-KYNC5X3U.js} +3 -3
- package/dist/{activity-events-MIOK3IOU.js → activity-events-GJJAI2WT.js} +4 -4
- package/dist/{ai-service-CVZEYKTK.js → ai-service-A7FS7EC3.js} +9 -5
- package/dist/{archive-6Z4GFQPH.js → archive-7E3YE6VF.js} +3 -3
- package/dist/{auth-A4VGHADI.js → auth-ABYLOEZ7.js} +5 -5
- package/dist/{avatar-image-7S3WA77A.js → avatar-image-6ATV2IOZ.js} +6 -5
- package/dist/{backup-IIAFOW2L.js → backup-XYAMT4CU.js} +15 -15
- 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-OGXAEXMV.js} +9 -9
- package/dist/{chunk-LTLFOSA4.js → chunk-3B427GUK.js} +3 -3
- package/dist/{chunk-RUFLGTOT.js → chunk-4B62E4CG.js} +2 -2
- package/dist/{chunk-ODDGGLM6.js → chunk-4DSGN4FL.js} +3 -3
- package/dist/{chunk-BGYHLR54.js → chunk-6HGEZJDH.js} +2 -2
- package/dist/{chunk-RBNMDAKB.js → chunk-BCG45AQB.js} +15 -1
- package/dist/{chunk-5IERLDUS.js → chunk-DAIIMBLB.js} +26 -6
- package/dist/{chunk-DGGZVZTM.js → chunk-DVN6DNMI.js} +1 -1
- package/dist/chunk-DW4TRDOZ.js +29 -0
- package/dist/chunk-EADX54RG.js +113 -0
- package/dist/{chunk-EIQDZC43.js → chunk-EFT2OALG.js} +6 -2
- package/dist/{chunk-XHN6XBWV.js → chunk-EG5LSKHU.js} +2 -2
- package/dist/{chunk-VMCZBXF2.js → chunk-FBBS4BVR.js} +10 -34
- package/dist/{chunk-IWJSNMSY.js → chunk-GWVFDUNB.js} +45 -14
- package/dist/{chunk-CBOIHNMR.js → chunk-HCYQRME2.js} +41 -5
- package/dist/{chunk-4I72V3E5.js → chunk-IH5TKXX6.js} +15 -15
- package/dist/{chunk-5NN2VHJV.js → chunk-JBIFXB6I.js} +4 -4
- package/dist/{chunk-JSVHH32K.js → chunk-JCBPU57A.js} +15 -13
- package/dist/{chunk-M3XDVS5Q.js → chunk-JCWB2ITW.js} +2 -2
- package/dist/{chunk-JCMGDCGX.js → chunk-JPGHSXSV.js} +20 -25
- package/dist/{chunk-K23P5Q5N.js → chunk-K3JOLGWF.js} +30 -8
- package/dist/{chunk-3YUBFTDN.js → chunk-KHCKZ36O.js} +1 -1
- package/dist/{chunk-7KRIHYLR.js → chunk-L27YYONJ.js} +2 -2
- package/dist/{chunk-SZJCJVXV.js → chunk-MG3Z34YE.js} +2 -2
- package/dist/{chunk-SKNXMUIU.js → chunk-NJHN6IRB.js} +26 -2
- package/dist/{chunk-2OIYNHWO.js → chunk-NOIAHMJB.js} +1 -1
- package/dist/{chunk-2MJ7EOMT.js → chunk-P4LHVRNE.js} +1 -0
- package/dist/{chunk-IYG4FBMP.js → chunk-PY24ZL62.js} +1 -1
- package/dist/{chunk-F55GRIEK.js → chunk-QQBOI3QA.js} +356 -296
- package/dist/{chunk-T2TP6ZC6.js → chunk-QUSMYGNQ.js} +6 -0
- package/dist/{chunk-KDLYIECM.js → chunk-R772ET2M.js} +18 -4
- package/dist/{chunk-WW6C3PLV.js → chunk-RSBL3FAD.js} +39 -6
- package/dist/{mind-list-KEGRGQEQ.js → chunk-SHKM5RGD.js} +19 -6
- package/dist/{chunk-YKA7DCVW.js → chunk-SX72DOO3.js} +1 -1
- package/dist/chunk-TXJL36ZQ.js +48 -0
- package/dist/{chunk-M6TTZRGH.js → chunk-VIUH5CHQ.js} +72 -24
- package/dist/{chunk-HPGN6XRT.js → chunk-VNRSXEBF.js} +4 -4
- package/dist/{chunk-PFZBNKUH.js → chunk-WCFSBH33.js} +0 -1
- package/dist/chunk-XTEKINWG.js +158 -0
- package/dist/{chunk-LWDTP6DH.js → chunk-YIJGKHIS.js} +32 -2
- package/dist/{chunk-MTRMQFCQ.js → chunk-ZX46PGCC.js} +2 -2
- package/dist/cli.js +34 -26
- package/dist/{clock-E6N5Y3YW.js → clock-6JZL2FS6.js} +3 -3
- package/dist/{cloud-sync-LQTVDTQ3.js → cloud-sync-VFDTNNCA.js} +22 -20
- package/dist/{config-TJLYUV3U.js → config-RPSLA2HX.js} +3 -3
- package/dist/{conversations-C7IKYSHD.js → conversations-TUM5PJJ4.js} +5 -5
- package/dist/{create-A7PDHIIL.js → create-VIQVP3QB.js} +3 -3
- package/dist/{create-PQQXKTJK.js → create-Z5FSDNVZ.js} +16 -5
- package/dist/{daemon-client-IYR4KCPU.js → daemon-client-ZFY5MOAL.js} +5 -3
- package/dist/{daemon-restart-5F3YTLZK.js → daemon-restart-54L4B6AQ.js} +7 -7
- package/dist/daemon.js +1105 -601
- package/dist/{db-FO6LXYCW.js → db-F6UMFRYD.js} +2 -2
- package/dist/{db-LZTLA7XC.js → db-IPXRJUI7.js} +1 -1
- package/dist/{delete-HPLC7ETU.js → delete-ESEP7NGQ.js} +1 -1
- package/dist/delivery-manager-RBXBPVWM.js +36 -0
- package/dist/{delivery-router-3QFG2ZEX.js → delivery-router-VUOL5YSA.js} +8 -6
- package/dist/{down-ZI4S6265.js → down-6X7KX7BZ.js} +5 -5
- package/dist/echo-text-B6NZ5FGE.js +36 -0
- package/dist/env-KUL4XKN2.js +18 -0
- package/dist/{env-HRL2PWAT.js → env-ZYMSCB7B.js} +6 -6
- package/dist/{exec-QIFYZG4C.js → exec-FBXA3CM4.js} +3 -3
- package/dist/{export-4GVGNW54.js → export-TNBPDH77.js} +4 -4
- package/dist/{extension-QBY4C44L.js → extension-J4ZQ2GHV.js} +3 -3
- package/dist/{extensions-PIMIQ7J3.js → extensions-AWNO3SZF.js} +22 -20
- package/dist/{files-FEFZKMNM.js → files-BVBRJJ2P.js} +6 -6
- package/dist/{import-7MO3YTRE.js → import-ZUNKMCKC.js} +9 -9
- package/dist/{isolation-MCT4ZYLT.js → isolation-OPCZQRTH.js} +3 -3
- package/dist/{join-ZJV7W6MO.js → join-34TR2GXQ.js} +1 -1
- package/dist/{list-LQO2DCIK.js → list-PMUXZNAM.js} +3 -3
- package/dist/{login-OF4WXDAN.js → login-KAKNFCW5.js} +14 -5
- package/dist/{login-6TLMI2TQ.js → login-LKNLCJPA.js} +3 -3
- package/dist/{logout-ERE2BGA3.js → logout-RLT62RQP.js} +5 -5
- package/dist/{logout-BK53HXNY.js → logout-YZRMZ3O2.js} +3 -3
- package/dist/message-delivery-ABPV76EA.js +42 -0
- package/dist/{mind-POOHFZHP.js → mind-IF6CGMFW.js} +23 -19
- package/dist/{mind-activity-tracker-YVZPC4A5.js → mind-activity-tracker-YMMERB6B.js} +5 -5
- package/dist/mind-contacts-BKUFPUCU.js +64 -0
- package/dist/{mind-history-47DN6ILW.js → mind-history-WI5OI3BW.js} +5 -5
- package/dist/mind-list-OTHV4ZO4.js +13 -0
- package/dist/{mind-profile-PEQYASQX.js → mind-profile-LUG353ZT.js} +1 -1
- package/dist/mind-service-42GDO4KH.js +44 -0
- package/dist/{mind-sleep-IN3WPA76.js → mind-sleep-VBV7YRSU.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-N6BCGHFV.js +25 -0
- package/dist/{package-WPEE2HVJ.js → package-PD67VPHB.js} +8 -5
- package/dist/prompts-MDHDLWEX.js +24 -0
- package/dist/{read-PWAJOQIQ.js → read-YSWUXYL7.js} +3 -3
- package/dist/{register-7SZJFHU6.js → register-TWQDKQRT.js} +3 -3
- package/dist/{registry-UMMDRPRM.js → registry-3ELJPUGJ.js} +6 -2
- package/dist/{reject-6VH7N2A4.js → reject-SXGCYN4A.js} +3 -3
- package/dist/{restart-H5WJDMA7.js → restart-5F5QDBOG.js} +5 -5
- package/dist/{sandbox-G4X4K3UN.js → sandbox-XPYA7UIF.js} +5 -5
- package/dist/scheduler-K7Y7Z7FQ.js +34 -0
- package/dist/{schema-VEVO7HG6.js → schema-6YONVTKZ.js} +1 -1
- package/dist/{seed-VANPU43L.js → seed-NQED7PSX.js} +1 -1
- package/dist/{seed-check-VLTVILOV.js → seed-check-TYD7RRZY.js} +1 -1
- package/dist/{seed-cmd-SYVDZKM4.js → seed-cmd-QF3F2G4S.js} +3 -3
- package/dist/{seed-create-3FGZPS6C.js → seed-create-XOO4N2OE.js} +6 -4
- package/dist/seed-readiness-3LRYASA4.js +18 -0
- package/dist/{seed-sprout-H7QLFPFM.js → seed-sprout-HSBBGSS2.js} +32 -33
- package/dist/{send-HYDFGC6G.js → send-IHRJYNXA.js} +8 -8
- package/dist/{service-SYJ5G6LP.js → service-YCOPCTSZ.js} +4 -4
- package/dist/{service-install-FQ43Z4DF.js → service-install-Y46OTF55.js} +5 -5
- package/dist/{setup-QJHGMGSN.js → setup-F4TE64YI.js} +7 -7
- package/dist/{setup-KFYVWTXG.js → setup-TCN7VH5U.js} +9 -3
- package/dist/{skill-GUKG2YVH.js → skill-4CYJLYVY.js} +6 -6
- 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 +5 -3
- package/dist/skills/volute-mind/references/routing.md +6 -5
- package/dist/skills/volute-mind/references/variants.md +48 -14
- package/dist/{skills-L2CMTW7A.js → skills-NN5UZCUU.js} +8 -6
- package/dist/sleep-manager-DSPXFHGX.js +38 -0
- package/dist/spirit-SSJMYC6A.js +31 -0
- package/dist/{split-WBMZXBHF.js → split-JF2VWTXA.js} +5 -2
- package/dist/{sprout-LTL5P36T.js → sprout-AXA2SECQ.js} +1 -1
- package/dist/{src-OJHARHTF.js → src-ZN4LXMPI.js} +17 -8
- package/dist/{start-X46I3GXB.js → start-BTVMTP3K.js} +5 -5
- package/dist/{status-V4RJMHJ4.js → status-VJGXMQ4L.js} +10 -8
- package/dist/{stop-HJQV4YSM.js → stop-YORESK4U.js} +5 -5
- package/dist/system-chat-M2XOBKEM.js +40 -0
- package/dist/{systems-B5YJKMW4.js → systems-5MH2ELQE.js} +6 -6
- package/dist/{tailscale-MCLY5GYE.js → tailscale-AMMVKDXB.js} +3 -3
- package/dist/{template-staleness-EMQORSGG.js → template-staleness-HKGCTS3H.js} +4 -4
- package/dist/{turn-tracker-JZRZDFWV.js → turn-tracker-JQ2YUUY2.js} +7 -7
- package/dist/up-SDLTLPAO.js +20 -0
- package/dist/{update-ACV4SAY3.js → update-WEA4N2TR.js} +5 -5
- package/dist/{update-check-266R4ZSY.js → update-check-DZOTONII.js} +3 -3
- package/dist/{upgrade-NWAZ7MLD.js → upgrade-K5FIQPQD.js} +1 -1
- package/dist/variant-cleanup-P4MBNLJD.js +33 -0
- package/dist/{version-notify-XRGTEEDK.js → version-notify-WFA5XB5A.js} +27 -25
- package/dist/web-assets/assets/index-BostMFoR.css +1 -0
- package/dist/web-assets/assets/index-CKlqUkyG.js +92 -0
- package/dist/web-assets/index.html +2 -2
- package/drizzle/0013_variant_purpose.sql +3 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +8 -5
- 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/.init/.local/hooks/startup-context.ts +19 -2
- package/templates/_base/home/VOLUTE.md +13 -1
- package/templates/_base/src/lib/daemon-client.ts +27 -7
- package/templates/_base/src/lib/startup.ts +16 -1
- package/templates/claude/src/agent.ts +10 -3
- package/templates/claude/src/lib/hooks/identity-reload.ts +12 -3
- 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/templates/pi/src/lib/event-handler.ts +47 -6
- package/dist/delivery-manager-TN5KK2AP.js +0 -34
- package/dist/echo-text-SEQCLGAT.js +0 -34
- package/dist/message-delivery-ZE3YGJDD.js +0 -38
- package/dist/mind-service-JFY7UG5E.js +0 -40
- package/dist/scheduler-HQSDYJFY.js +0 -32
- package/dist/sleep-manager-3NA7ZJP3.js +0 -36
- package/dist/spirit-WXN4IDBF.js +0 -23
- package/dist/system-chat-N2F7HVY3.js +0 -38
- package/dist/up-J2PBPOZL.js +0 -18
- 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
|
@@ -1,88 +1,97 @@
|
|
|
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-VIUH5CHQ.js";
|
|
5
|
+
import {
|
|
6
|
+
extractTextContent,
|
|
7
|
+
getRoutingConfig,
|
|
8
|
+
resolveDeliveryMode,
|
|
9
|
+
resolveRoute,
|
|
10
|
+
setRoutesChangeListener,
|
|
11
|
+
shouldGate
|
|
12
|
+
} from "./chunk-EFT2OALG.js";
|
|
8
13
|
import {
|
|
9
14
|
clearMind,
|
|
10
15
|
linkInboundToActiveTurn,
|
|
11
16
|
publish as publish3,
|
|
12
17
|
summarizeOrphanedTurns
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import {
|
|
15
|
-
getPrompt
|
|
16
|
-
} from "./chunk-JCMGDCGX.js";
|
|
18
|
+
} from "./chunk-K3JOLGWF.js";
|
|
17
19
|
import {
|
|
18
20
|
hashSkillDir,
|
|
19
21
|
importSkillFromDir,
|
|
20
22
|
removeSharedSkill,
|
|
21
23
|
sharedSkillsDir
|
|
22
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-GWVFDUNB.js";
|
|
25
|
+
import {
|
|
26
|
+
getOrCreateMindUser,
|
|
27
|
+
getOrCreateSystemUser,
|
|
28
|
+
getUser,
|
|
29
|
+
getUserByUsername,
|
|
30
|
+
syncMindProfile
|
|
31
|
+
} from "./chunk-4DSGN4FL.js";
|
|
23
32
|
import {
|
|
24
33
|
addMessage,
|
|
25
34
|
createChannel,
|
|
26
35
|
createConversation,
|
|
27
36
|
findDMConversation,
|
|
28
37
|
getChannelByName,
|
|
38
|
+
getChannelSettings,
|
|
29
39
|
getParticipants,
|
|
30
40
|
joinChannel,
|
|
31
|
-
|
|
32
|
-
|
|
41
|
+
listConversationsForMind,
|
|
42
|
+
publish as publish2,
|
|
43
|
+
updateChannelSettings
|
|
44
|
+
} from "./chunk-VNRSXEBF.js";
|
|
45
|
+
import {
|
|
46
|
+
getPrompt
|
|
47
|
+
} from "./chunk-JPGHSXSV.js";
|
|
33
48
|
import {
|
|
34
49
|
isSandboxEnabled,
|
|
35
50
|
wrapForSandbox
|
|
36
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-JCWB2ITW.js";
|
|
52
|
+
import {
|
|
53
|
+
MIND_LEVEL_SESSION,
|
|
54
|
+
recordNotice
|
|
55
|
+
} from "./chunk-XTEKINWG.js";
|
|
37
56
|
import {
|
|
38
57
|
markIdle,
|
|
39
58
|
onMindEvent
|
|
40
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-ZX46PGCC.js";
|
|
41
60
|
import {
|
|
42
61
|
renderAvatarBlock
|
|
43
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-FBBS4BVR.js";
|
|
44
63
|
import {
|
|
45
64
|
readVoluteConfig,
|
|
46
65
|
resolveWakeTriggers,
|
|
47
66
|
writeVoluteConfig
|
|
48
|
-
} from "./chunk-
|
|
49
|
-
import {
|
|
50
|
-
extractTextContent,
|
|
51
|
-
getRoutingConfig,
|
|
52
|
-
resolveDeliveryMode,
|
|
53
|
-
resolveRoute,
|
|
54
|
-
setRoutesChangeListener
|
|
55
|
-
} from "./chunk-EIQDZC43.js";
|
|
67
|
+
} from "./chunk-WCFSBH33.js";
|
|
56
68
|
import {
|
|
57
69
|
chownMindDir,
|
|
58
70
|
exec,
|
|
59
71
|
isIsolationEnabled,
|
|
60
72
|
mindUserName,
|
|
61
73
|
wrapForIsolation
|
|
62
|
-
} from "./chunk-
|
|
74
|
+
} from "./chunk-DVN6DNMI.js";
|
|
75
|
+
import {
|
|
76
|
+
loadMergedEnv
|
|
77
|
+
} from "./chunk-PY24ZL62.js";
|
|
63
78
|
import {
|
|
64
79
|
aiCompleteUtility,
|
|
65
80
|
getAiConfig,
|
|
81
|
+
missingCredentialWarning,
|
|
66
82
|
resolveApiKey
|
|
67
|
-
} from "./chunk-
|
|
83
|
+
} from "./chunk-YIJGKHIS.js";
|
|
68
84
|
import {
|
|
69
85
|
readGlobalConfig,
|
|
70
86
|
writeGlobalConfig
|
|
71
|
-
} from "./chunk-
|
|
72
|
-
import {
|
|
73
|
-
getOrCreateMindUser,
|
|
74
|
-
getOrCreateSystemUser,
|
|
75
|
-
getUser,
|
|
76
|
-
getUserByUsername,
|
|
77
|
-
syncMindProfile
|
|
78
|
-
} from "./chunk-ODDGGLM6.js";
|
|
87
|
+
} from "./chunk-NJHN6IRB.js";
|
|
79
88
|
import {
|
|
80
89
|
publish,
|
|
81
90
|
subscribe
|
|
82
|
-
} from "./chunk-
|
|
91
|
+
} from "./chunk-3B427GUK.js";
|
|
83
92
|
import {
|
|
84
93
|
logger_default
|
|
85
|
-
} from "./chunk-
|
|
94
|
+
} from "./chunk-QUSMYGNQ.js";
|
|
86
95
|
import {
|
|
87
96
|
SPIRIT_NAME,
|
|
88
97
|
findMind,
|
|
@@ -91,39 +100,39 @@ import {
|
|
|
91
100
|
isSpiritName,
|
|
92
101
|
mindDir,
|
|
93
102
|
mindTmpDir,
|
|
103
|
+
readRegistry,
|
|
94
104
|
setMindRunning,
|
|
95
105
|
stateDir,
|
|
96
106
|
voluteHome,
|
|
97
107
|
voluteSystemDir
|
|
98
|
-
} from "./chunk-
|
|
108
|
+
} from "./chunk-RSBL3FAD.js";
|
|
99
109
|
import {
|
|
100
110
|
activity,
|
|
101
111
|
channelGates,
|
|
102
112
|
deliveryQueue,
|
|
103
113
|
messages,
|
|
104
114
|
mindHistory,
|
|
105
|
-
mindNotices,
|
|
106
115
|
sessions
|
|
107
|
-
} from "./chunk-
|
|
116
|
+
} from "./chunk-P4LHVRNE.js";
|
|
108
117
|
|
|
109
118
|
// packages/daemon/src/lib/delivery/message-delivery.ts
|
|
110
|
-
import { and as
|
|
119
|
+
import { and as and4, eq as eq5, inArray as inArray3 } from "drizzle-orm";
|
|
111
120
|
|
|
112
121
|
// packages/daemon/src/lib/daemon/sleep-manager.ts
|
|
113
122
|
import { execFile as execFile2, spawn as spawnChild } from "child_process";
|
|
114
123
|
import {
|
|
115
|
-
existsSync as
|
|
124
|
+
existsSync as existsSync9,
|
|
116
125
|
mkdirSync as mkdirSync5,
|
|
117
126
|
readdirSync as readdirSync2,
|
|
118
|
-
readFileSync as
|
|
127
|
+
readFileSync as readFileSync8,
|
|
119
128
|
readlinkSync,
|
|
120
129
|
renameSync,
|
|
121
130
|
writeFileSync as writeFileSync6
|
|
122
131
|
} from "fs";
|
|
123
|
-
import { resolve as
|
|
132
|
+
import { resolve as resolve8 } from "path";
|
|
124
133
|
import { promisify as promisify2 } from "util";
|
|
125
134
|
import { CronExpressionParser as CronExpressionParser2 } from "cron-parser";
|
|
126
|
-
import { and
|
|
135
|
+
import { and, eq as eq2, inArray } from "drizzle-orm";
|
|
127
136
|
|
|
128
137
|
// packages/daemon/src/lib/daemon/mind-manager.ts
|
|
129
138
|
import { execFile, spawn } from "child_process";
|
|
@@ -152,7 +161,9 @@ function loadJsonMap(path) {
|
|
|
152
161
|
const map = /* @__PURE__ */ new Map();
|
|
153
162
|
try {
|
|
154
163
|
if (existsSync(path)) {
|
|
155
|
-
const
|
|
164
|
+
const raw = readFileSync(path, "utf-8").trim();
|
|
165
|
+
if (!raw) return map;
|
|
166
|
+
const data = JSON.parse(raw);
|
|
156
167
|
for (const [key, value] of Object.entries(data)) {
|
|
157
168
|
if (typeof value === "number") map.set(key, value);
|
|
158
169
|
}
|
|
@@ -348,106 +359,6 @@ function getMindToken(mindName) {
|
|
|
348
359
|
return mindToToken.get(mindName) ?? null;
|
|
349
360
|
}
|
|
350
361
|
|
|
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
362
|
// packages/daemon/src/lib/daemon/restart-tracker.ts
|
|
452
363
|
var DEFAULT_MAX_ATTEMPTS = 5;
|
|
453
364
|
var DEFAULT_BASE_DELAY = 3e3;
|
|
@@ -550,6 +461,35 @@ var MindStartupError = class extends Error {
|
|
|
550
461
|
function mindPidPath(name) {
|
|
551
462
|
return resolve2(stateDir(name), "mind.pid");
|
|
552
463
|
}
|
|
464
|
+
async function buildPendingContextMessage(name, context) {
|
|
465
|
+
const parts = [];
|
|
466
|
+
if (context.type === "merge" || context.type === "merged") {
|
|
467
|
+
parts.push(await getPrompt("merge_message", { name: String(context.name ?? "") }));
|
|
468
|
+
} else if (context.type === "split") {
|
|
469
|
+
parts.push(await getPrompt("split_message", { name, parent: String(context.parent ?? "") }));
|
|
470
|
+
if (context.purpose) parts.push(`Why you were split off: ${String(context.purpose)}`);
|
|
471
|
+
} else if (context.type === "sprouted") {
|
|
472
|
+
parts.push(await getPrompt("sprout_message"));
|
|
473
|
+
} else if (context.type === "upgraded") {
|
|
474
|
+
parts.push(await getPrompt("upgrade_message"));
|
|
475
|
+
} else {
|
|
476
|
+
parts.push(await getPrompt("restart_message"));
|
|
477
|
+
}
|
|
478
|
+
if (context.summary) parts.push(`Changes: ${context.summary}`);
|
|
479
|
+
if (context.justification) parts.push(`Why: ${context.justification}`);
|
|
480
|
+
if (context.memory) parts.push(`Context: ${context.memory}`);
|
|
481
|
+
if (context.memoryDelta) {
|
|
482
|
+
parts.push(
|
|
483
|
+
`
|
|
484
|
+
Your variant's memory & journal (not merged \u2014 integrate into your own memory what you want to keep):
|
|
485
|
+
${context.memoryDelta}`
|
|
486
|
+
);
|
|
487
|
+
}
|
|
488
|
+
if (context.farewell)
|
|
489
|
+
parts.push(`Your variant's parting note (this was you, winding down):
|
|
490
|
+
${context.farewell}`);
|
|
491
|
+
return parts.join("\n");
|
|
492
|
+
}
|
|
553
493
|
var MindManager = class {
|
|
554
494
|
minds = /* @__PURE__ */ new Map();
|
|
555
495
|
stopping = /* @__PURE__ */ new Set();
|
|
@@ -642,7 +582,7 @@ var MindManager = class {
|
|
|
642
582
|
if (isIsolationEnabled()) {
|
|
643
583
|
try {
|
|
644
584
|
await chownMindDir(mindStateDir, baseName);
|
|
645
|
-
await chownMindDir(
|
|
585
|
+
await chownMindDir(resolve2(dir, ".mind"), baseName);
|
|
646
586
|
} catch (err) {
|
|
647
587
|
throw new Error(
|
|
648
588
|
`Cannot start mind ${name}: failed to set ownership on state directory ${mindStateDir}: ${err instanceof Error ? err.message : err}`
|
|
@@ -808,7 +748,7 @@ var MindManager = class {
|
|
|
808
748
|
while (recentStderr.length > 20) recentStderr.shift();
|
|
809
749
|
});
|
|
810
750
|
try {
|
|
811
|
-
await new Promise((
|
|
751
|
+
await new Promise((resolve10, reject) => {
|
|
812
752
|
let settled = false;
|
|
813
753
|
const deadline = Date.now() + 3e4;
|
|
814
754
|
const onExit = (code) => {
|
|
@@ -838,7 +778,7 @@ var MindManager = class {
|
|
|
838
778
|
const { ok } = await checkHealth(port);
|
|
839
779
|
if (settled) return;
|
|
840
780
|
if (ok) {
|
|
841
|
-
finish(() =>
|
|
781
|
+
finish(() => resolve10());
|
|
842
782
|
return;
|
|
843
783
|
}
|
|
844
784
|
if (Date.now() >= deadline) {
|
|
@@ -889,22 +829,7 @@ var MindManager = class {
|
|
|
889
829
|
const tracked = this.minds.get(name);
|
|
890
830
|
if (!tracked) return;
|
|
891
831
|
this.pendingContext.delete(name);
|
|
892
|
-
const
|
|
893
|
-
if (context.type === "merge" || context.type === "merged") {
|
|
894
|
-
parts.push(await getPrompt("merge_message", { name: String(context.name ?? "") }));
|
|
895
|
-
} else if (context.type === "split") {
|
|
896
|
-
parts.push(await getPrompt("split_message", { name, parent: String(context.parent ?? "") }));
|
|
897
|
-
} else if (context.type === "sprouted") {
|
|
898
|
-
parts.push(await getPrompt("sprout_message"));
|
|
899
|
-
} else if (context.type === "upgraded") {
|
|
900
|
-
parts.push(await getPrompt("upgrade_message"));
|
|
901
|
-
} else {
|
|
902
|
-
parts.push(await getPrompt("restart_message"));
|
|
903
|
-
}
|
|
904
|
-
if (context.summary) parts.push(`Changes: ${context.summary}`);
|
|
905
|
-
if (context.justification) parts.push(`Why: ${context.justification}`);
|
|
906
|
-
if (context.memory) parts.push(`Context: ${context.memory}`);
|
|
907
|
-
const content = parts.join("\n");
|
|
832
|
+
const content = await buildPendingContextMessage(name, context);
|
|
908
833
|
let conversationId;
|
|
909
834
|
try {
|
|
910
835
|
const result = await sendSystemMessageDirect(name, content);
|
|
@@ -938,7 +863,7 @@ var MindManager = class {
|
|
|
938
863
|
if (this.shuttingDown || this.stopping.has(name)) return;
|
|
939
864
|
mlog.error(`mind ${name} exited with code ${code}`);
|
|
940
865
|
try {
|
|
941
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
866
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-DSPXFHGX.js");
|
|
942
867
|
const sleepMgr = getSleepManagerIfReady2();
|
|
943
868
|
const sleepState = sleepMgr?.getState(name);
|
|
944
869
|
if (sleepState?.sleeping) {
|
|
@@ -968,15 +893,15 @@ var MindManager = class {
|
|
|
968
893
|
(err) => mlog.warn(`failed to clear turn state for ${name} after crash`, logger_default.errorData(err))
|
|
969
894
|
);
|
|
970
895
|
try {
|
|
971
|
-
const { getDeliveryManager: getDeliveryManager2 } = await import("./delivery-manager-
|
|
896
|
+
const { getDeliveryManager: getDeliveryManager2 } = await import("./delivery-manager-RBXBPVWM.js");
|
|
972
897
|
getDeliveryManager2().clearMindSessions(name);
|
|
973
898
|
} catch (err) {
|
|
974
899
|
if (!(err instanceof Error && err.message.includes("not initialized"))) {
|
|
975
900
|
mlog.warn(`failed to clear delivery state for ${name} after crash`, logger_default.errorData(err));
|
|
976
901
|
}
|
|
977
902
|
}
|
|
978
|
-
import("./mind-activity-tracker-
|
|
979
|
-
import("./activity-events-
|
|
903
|
+
import("./mind-activity-tracker-YMMERB6B.js").then(({ markIdle: markIdle2 }) => markIdle2(name)).catch((err) => mlog.warn(`failed to mark ${name} idle after crash`, logger_default.errorData(err)));
|
|
904
|
+
import("./activity-events-GJJAI2WT.js").then(
|
|
980
905
|
({ publish: publish4 }) => publish4({ type: "mind_stopped", mind: name, summary: `${name} crashed (exit ${code})` })
|
|
981
906
|
).catch((err) => mlog.warn(`failed to publish crash event for ${name}`, logger_default.errorData(err)));
|
|
982
907
|
const { shouldRestart, delay, attempt } = this.restartTracker.recordCrash(name);
|
|
@@ -1006,23 +931,23 @@ var MindManager = class {
|
|
|
1006
931
|
this.stopping.add(name);
|
|
1007
932
|
const { child } = tracked;
|
|
1008
933
|
this.minds.delete(name);
|
|
1009
|
-
await new Promise((
|
|
934
|
+
await new Promise((resolve10) => {
|
|
1010
935
|
const killTimer = setTimeout(() => {
|
|
1011
936
|
try {
|
|
1012
937
|
process.kill(-child.pid, "SIGKILL");
|
|
1013
938
|
} catch {
|
|
1014
939
|
}
|
|
1015
|
-
|
|
940
|
+
resolve10();
|
|
1016
941
|
}, 5e3);
|
|
1017
942
|
child.on("exit", () => {
|
|
1018
943
|
clearTimeout(killTimer);
|
|
1019
|
-
|
|
944
|
+
resolve10();
|
|
1020
945
|
});
|
|
1021
946
|
try {
|
|
1022
947
|
process.kill(-child.pid, "SIGTERM");
|
|
1023
948
|
} catch {
|
|
1024
949
|
clearTimeout(killTimer);
|
|
1025
|
-
|
|
950
|
+
resolve10();
|
|
1026
951
|
}
|
|
1027
952
|
});
|
|
1028
953
|
this.stopping.delete(name);
|
|
@@ -1034,7 +959,7 @@ var MindManager = class {
|
|
|
1034
959
|
mlog.warn(`failed to clear turn state for ${name} on stop`, logger_default.errorData(err));
|
|
1035
960
|
}
|
|
1036
961
|
try {
|
|
1037
|
-
const { getDeliveryManager: getDeliveryManager2 } = await import("./delivery-manager-
|
|
962
|
+
const { getDeliveryManager: getDeliveryManager2 } = await import("./delivery-manager-RBXBPVWM.js");
|
|
1038
963
|
getDeliveryManager2().clearMindSessions(name);
|
|
1039
964
|
} catch (err) {
|
|
1040
965
|
if (!(err instanceof Error && err.message.includes("not initialized"))) {
|
|
@@ -1042,7 +967,7 @@ var MindManager = class {
|
|
|
1042
967
|
}
|
|
1043
968
|
}
|
|
1044
969
|
try {
|
|
1045
|
-
const { clearEchoTextCache } = await import("./echo-text-
|
|
970
|
+
const { clearEchoTextCache } = await import("./echo-text-B6NZ5FGE.js");
|
|
1046
971
|
clearEchoTextCache(name);
|
|
1047
972
|
} catch (err) {
|
|
1048
973
|
mlog.debug(`failed to clear echo-text cache for ${name}`, logger_default.errorData(err));
|
|
@@ -1126,17 +1051,30 @@ function tryGetMindManager() {
|
|
|
1126
1051
|
return instance;
|
|
1127
1052
|
}
|
|
1128
1053
|
|
|
1054
|
+
// packages/daemon/src/lib/daemon/mind-service.ts
|
|
1055
|
+
import { existsSync as existsSync8, readFileSync as readFileSync7 } from "fs";
|
|
1056
|
+
import { resolve as resolve7 } from "path";
|
|
1057
|
+
|
|
1129
1058
|
// packages/daemon/src/lib/chat/system-channel.ts
|
|
1130
1059
|
var SYSTEM_CHANNEL_NAME = "system";
|
|
1060
|
+
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
1061
|
var cachedChannelId = null;
|
|
1132
1062
|
async function ensureSystemChannel() {
|
|
1133
1063
|
if (cachedChannelId) return cachedChannelId;
|
|
1134
1064
|
const existing = await getChannelByName(SYSTEM_CHANNEL_NAME);
|
|
1135
1065
|
if (existing) {
|
|
1136
1066
|
cachedChannelId = existing.id;
|
|
1067
|
+
const settings = await getChannelSettings(SYSTEM_CHANNEL_NAME);
|
|
1068
|
+
if (settings && settings.description == null) {
|
|
1069
|
+
await updateChannelSettings(SYSTEM_CHANNEL_NAME, {
|
|
1070
|
+
description: SYSTEM_CHANNEL_DESCRIPTION
|
|
1071
|
+
});
|
|
1072
|
+
}
|
|
1137
1073
|
return existing.id;
|
|
1138
1074
|
}
|
|
1139
|
-
const conv = await createChannel(SYSTEM_CHANNEL_NAME
|
|
1075
|
+
const conv = await createChannel(SYSTEM_CHANNEL_NAME, void 0, {
|
|
1076
|
+
description: SYSTEM_CHANNEL_DESCRIPTION
|
|
1077
|
+
});
|
|
1140
1078
|
cachedChannelId = conv.id;
|
|
1141
1079
|
logger_default.info("created #system channel");
|
|
1142
1080
|
return conv.id;
|
|
@@ -1149,6 +1087,25 @@ async function joinSystemChannelForMind(mindName) {
|
|
|
1149
1087
|
const user = await getOrCreateMindUser(mindName);
|
|
1150
1088
|
await joinSystemChannel(user.id);
|
|
1151
1089
|
}
|
|
1090
|
+
async function joinSystemChannelForSpirit() {
|
|
1091
|
+
const user = await getOrCreateSystemUser();
|
|
1092
|
+
await joinSystemChannel(user.id);
|
|
1093
|
+
}
|
|
1094
|
+
async function backfillSystemChannelMembers() {
|
|
1095
|
+
const entries = await readRegistry();
|
|
1096
|
+
for (const entry of entries) {
|
|
1097
|
+
if (entry.stage === "seed") continue;
|
|
1098
|
+
try {
|
|
1099
|
+
if (entry.mindType === "spirit") {
|
|
1100
|
+
await joinSystemChannelForSpirit();
|
|
1101
|
+
} else {
|
|
1102
|
+
await joinSystemChannelForMind(entry.name);
|
|
1103
|
+
}
|
|
1104
|
+
} catch (err) {
|
|
1105
|
+
logger_default.error(`failed to backfill ${entry.name} into #system`, logger_default.errorData(err));
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1152
1109
|
async function announceToSystem(text) {
|
|
1153
1110
|
const channelId = await ensureSystemChannel();
|
|
1154
1111
|
const systemUser = await getOrCreateSystemUser();
|
|
@@ -1178,7 +1135,7 @@ import { dirname, resolve as resolve4 } from "path";
|
|
|
1178
1135
|
|
|
1179
1136
|
// packages/daemon/src/web/middleware/auth.ts
|
|
1180
1137
|
import { timingSafeEqual } from "crypto";
|
|
1181
|
-
import { eq
|
|
1138
|
+
import { eq, lt } from "drizzle-orm";
|
|
1182
1139
|
import { getCookie } from "hono/cookie";
|
|
1183
1140
|
import { createMiddleware } from "hono/factory";
|
|
1184
1141
|
var MIND_USER_CACHE_TTL = 5 * 60 * 1e3;
|
|
@@ -1206,14 +1163,14 @@ async function createSession(userId) {
|
|
|
1206
1163
|
async function deleteSession(sessionId) {
|
|
1207
1164
|
sessionCache.delete(sessionId);
|
|
1208
1165
|
const db = await getDb();
|
|
1209
|
-
await db.delete(sessions).where(
|
|
1166
|
+
await db.delete(sessions).where(eq(sessions.id, sessionId));
|
|
1210
1167
|
}
|
|
1211
1168
|
async function getSessionUserId(sessionId) {
|
|
1212
1169
|
const db = await getDb();
|
|
1213
|
-
const row = await db.select().from(sessions).where(
|
|
1170
|
+
const row = await db.select().from(sessions).where(eq(sessions.id, sessionId)).get();
|
|
1214
1171
|
if (!row) return void 0;
|
|
1215
1172
|
if (Date.now() - row.createdAt > SESSION_MAX_AGE) {
|
|
1216
|
-
await db.delete(sessions).where(
|
|
1173
|
+
await db.delete(sessions).where(eq(sessions.id, sessionId));
|
|
1217
1174
|
return void 0;
|
|
1218
1175
|
}
|
|
1219
1176
|
return row.userId;
|
|
@@ -1317,7 +1274,7 @@ var requireSelf = (paramName = "name") => createMiddleware(async (c, next) => {
|
|
|
1317
1274
|
if (user.role !== "admin" && user.role !== "system") {
|
|
1318
1275
|
const target = c.req.param(paramName) ?? "";
|
|
1319
1276
|
const baseName = await getBaseName(target);
|
|
1320
|
-
if (user.username !== baseName) {
|
|
1277
|
+
if (user.username !== baseName && await getBaseName(user.username) !== baseName) {
|
|
1321
1278
|
return c.json({ error: "Forbidden" }, 403);
|
|
1322
1279
|
}
|
|
1323
1280
|
}
|
|
@@ -1734,7 +1691,7 @@ function resolveSkillsDir(manifest) {
|
|
|
1734
1691
|
async function discoverBuiltinExtensions(disabledIds) {
|
|
1735
1692
|
const builtins = [
|
|
1736
1693
|
{ id: "notes", load: async () => (await import("./src-YH6PQ7LJ.js")).default },
|
|
1737
|
-
{ id: "pages", load: async () => (await import("./src-
|
|
1694
|
+
{ id: "pages", load: async () => (await import("./src-ZN4LXMPI.js")).default },
|
|
1738
1695
|
{ id: "plan", load: async () => (await import("./src-JAOVXO5W.js")).default }
|
|
1739
1696
|
];
|
|
1740
1697
|
const results = [];
|
|
@@ -1984,7 +1941,7 @@ async function installNpmExtension(pkg) {
|
|
|
1984
1941
|
throw new Error(`Extension "${pkg}" is already installed`);
|
|
1985
1942
|
}
|
|
1986
1943
|
const dir = ensureExtensionsNpmDir();
|
|
1987
|
-
const { exec: exec2 } = await import("./exec-
|
|
1944
|
+
const { exec: exec2 } = await import("./exec-FBXA3CM4.js");
|
|
1988
1945
|
try {
|
|
1989
1946
|
await exec2("npm", ["install", "--ignore-scripts", pkg], { cwd: dir });
|
|
1990
1947
|
} catch (err) {
|
|
@@ -2005,7 +1962,7 @@ async function uninstallNpmExtension(pkg) {
|
|
|
2005
1962
|
packages.splice(idx, 1);
|
|
2006
1963
|
writeExtensionsConfig(packages);
|
|
2007
1964
|
try {
|
|
2008
|
-
const { exec: exec2 } = await import("./exec-
|
|
1965
|
+
const { exec: exec2 } = await import("./exec-FBXA3CM4.js");
|
|
2009
1966
|
await exec2("npm", ["uninstall", "--ignore-scripts", pkg], { cwd: extensionsNpmDir() });
|
|
2010
1967
|
} catch (err) {
|
|
2011
1968
|
logger_default.warn(
|
|
@@ -2179,8 +2136,7 @@ var MailPoller = class {
|
|
|
2179
2136
|
this.reconnectAttempts = 0;
|
|
2180
2137
|
this.reconnectDelay = INITIAL_RECONNECT_MS;
|
|
2181
2138
|
if (this.disconnectedAt) {
|
|
2182
|
-
this.
|
|
2183
|
-
this.disconnectedAt = null;
|
|
2139
|
+
void this.catchUpAndClear(this.disconnectedAt);
|
|
2184
2140
|
}
|
|
2185
2141
|
if (this.pingTimer) clearInterval(this.pingTimer);
|
|
2186
2142
|
this.pingTimer = setInterval(() => {
|
|
@@ -2197,7 +2153,7 @@ var MailPoller = class {
|
|
|
2197
2153
|
this.handleMessage(String(event.data));
|
|
2198
2154
|
};
|
|
2199
2155
|
this.ws.onclose = () => {
|
|
2200
|
-
mlog2.
|
|
2156
|
+
mlog2.info("disconnected");
|
|
2201
2157
|
if (!this.disconnectedAt) {
|
|
2202
2158
|
this.disconnectedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2203
2159
|
}
|
|
@@ -2205,7 +2161,7 @@ var MailPoller = class {
|
|
|
2205
2161
|
this.scheduleReconnect();
|
|
2206
2162
|
};
|
|
2207
2163
|
this.ws.onerror = (err) => {
|
|
2208
|
-
mlog2.
|
|
2164
|
+
mlog2.info("WebSocket error", logger_default.errorData(err));
|
|
2209
2165
|
};
|
|
2210
2166
|
}
|
|
2211
2167
|
cleanup() {
|
|
@@ -2228,26 +2184,38 @@ var MailPoller = class {
|
|
|
2228
2184
|
}, this.reconnectDelay);
|
|
2229
2185
|
this.reconnectDelay = Math.min(this.reconnectDelay * 2, MAX_RECONNECT_MS);
|
|
2230
2186
|
}
|
|
2231
|
-
/**
|
|
2232
|
-
|
|
2233
|
-
|
|
2187
|
+
/**
|
|
2188
|
+
* Run catch-up and advance the watermark only on full success. On any failure
|
|
2189
|
+
* (fetch error, non-OK response, delivery throw) the watermark is retained so
|
|
2190
|
+
* the next reconnect re-fetches the gap — at-least-once, never dropped.
|
|
2191
|
+
*/
|
|
2192
|
+
async catchUpAndClear(since) {
|
|
2193
|
+
try {
|
|
2194
|
+
await this.catchUp(since);
|
|
2195
|
+
} catch (err) {
|
|
2196
|
+
mlog2.info("catch-up failed \u2014 will retry on next reconnect", logger_default.errorData(err));
|
|
2197
|
+
return;
|
|
2198
|
+
}
|
|
2199
|
+
if (this.disconnectedAt === since && this.ws?.readyState === WebSocket.OPEN) {
|
|
2200
|
+
this.disconnectedAt = null;
|
|
2201
|
+
}
|
|
2202
|
+
}
|
|
2203
|
+
/** Fetch and deliver emails that arrived while disconnected. Throws on failure. */
|
|
2204
|
+
async catchUp(since) {
|
|
2205
|
+
if (!this.config) throw new Error("systems config missing");
|
|
2234
2206
|
const url = `${this.config.apiUrl}/api/mail/system/poll?since=${encodeURIComponent(since)}`;
|
|
2235
|
-
fetch(url, {
|
|
2207
|
+
const res = await fetch(url, {
|
|
2236
2208
|
headers: { Authorization: `Bearer ${this.config.apiKey}` }
|
|
2237
|
-
}).then(async (res) => {
|
|
2238
|
-
if (!res.ok) {
|
|
2239
|
-
mlog2.warn(`catch-up poll failed: HTTP ${res.status}`);
|
|
2240
|
-
return;
|
|
2241
|
-
}
|
|
2242
|
-
const data = await res.json();
|
|
2243
|
-
if (!Array.isArray(data.emails) || data.emails.length === 0) return;
|
|
2244
|
-
mlog2.info(`catching up on ${data.emails.length} missed emails`);
|
|
2245
|
-
for (const email of data.emails) {
|
|
2246
|
-
await this.deliver(email.mind, email);
|
|
2247
|
-
}
|
|
2248
|
-
}).catch((err) => {
|
|
2249
|
-
mlog2.warn("catch-up error", logger_default.errorData(err));
|
|
2250
2209
|
});
|
|
2210
|
+
if (!res.ok) {
|
|
2211
|
+
throw new Error(`catch-up poll failed: HTTP ${res.status}`);
|
|
2212
|
+
}
|
|
2213
|
+
const data = await res.json();
|
|
2214
|
+
if (!Array.isArray(data.emails) || data.emails.length === 0) return;
|
|
2215
|
+
mlog2.info(`catching up on ${data.emails.length} missed emails`);
|
|
2216
|
+
for (const email of data.emails) {
|
|
2217
|
+
await this.deliver(email.mind, email);
|
|
2218
|
+
}
|
|
2251
2219
|
}
|
|
2252
2220
|
handleMessage(data) {
|
|
2253
2221
|
if (data === "pong") return;
|
|
@@ -2284,24 +2252,22 @@ var MailPoller = class {
|
|
|
2284
2252
|
await this.deliver(mind, { ...email, mind });
|
|
2285
2253
|
}
|
|
2286
2254
|
async deliver(mind, email) {
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
mlog2.warn(`skipping delivery to ${mind}: ${!entry ? "not found" : "not running"}`);
|
|
2255
|
+
if (!await findMind(mind)) {
|
|
2256
|
+
mlog2.warn(`skipping delivery to ${mind}: mind not found`);
|
|
2290
2257
|
return;
|
|
2291
2258
|
}
|
|
2292
2259
|
const text = formatEmailContent(email);
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
} catch (err) {
|
|
2303
|
-
mlog2.warn(`failed to deliver to ${mind}`, logger_default.errorData(err));
|
|
2260
|
+
const delivered = await deliverMessage(mind, {
|
|
2261
|
+
content: [{ type: "text", text }],
|
|
2262
|
+
channel: `mail:${email.from.address}`,
|
|
2263
|
+
sender: email.from.name || email.from.address,
|
|
2264
|
+
platform: "Email",
|
|
2265
|
+
isDM: true
|
|
2266
|
+
});
|
|
2267
|
+
if (!delivered) {
|
|
2268
|
+
throw new Error(`delivery to ${mind} failed`);
|
|
2304
2269
|
}
|
|
2270
|
+
mlog2.info(`delivered email from ${email.from.address} to ${mind}`);
|
|
2305
2271
|
}
|
|
2306
2272
|
};
|
|
2307
2273
|
var instance2 = null;
|
|
@@ -2467,10 +2433,17 @@ var Scheduler = class {
|
|
|
2467
2433
|
${stderr}` : ""}`;
|
|
2468
2434
|
slog2.warn(`script "${schedule.id}" failed for ${mindName}`, logger_default.errorData(err));
|
|
2469
2435
|
}
|
|
2436
|
+
} else if (Array.isArray(schedule.messages) && schedule.messages.length > 0) {
|
|
2437
|
+
const pick = schedule.messages[Math.floor(Math.random() * schedule.messages.length)];
|
|
2438
|
+
if (typeof pick !== "string" || !pick.trim()) {
|
|
2439
|
+
slog2.warn(`schedule "${schedule.id}" for ${mindName} has a malformed messages pool`);
|
|
2440
|
+
return;
|
|
2441
|
+
}
|
|
2442
|
+
text = pick;
|
|
2470
2443
|
} else if (schedule.message) {
|
|
2471
2444
|
text = schedule.message;
|
|
2472
2445
|
} else {
|
|
2473
|
-
slog2.warn(`schedule "${schedule.id}" for ${mindName} has no message or script`);
|
|
2446
|
+
slog2.warn(`schedule "${schedule.id}" for ${mindName} has no message, messages, or script`);
|
|
2474
2447
|
return;
|
|
2475
2448
|
}
|
|
2476
2449
|
await this.deliverSystem(mindName, `[${schedule.id}] ${text}`, {
|
|
@@ -2790,6 +2763,9 @@ async function startMindFull(name) {
|
|
|
2790
2763
|
summary: `${name} started`
|
|
2791
2764
|
}).catch((err) => logger_default.error("failed to publish mind_started activity", logger_default.errorData(err)));
|
|
2792
2765
|
if (entry?.parent) return;
|
|
2766
|
+
recordMissingCredentialsNotice(baseName, entry?.template).catch(
|
|
2767
|
+
(err) => logger_default.error(`failed to check credentials for ${baseName}`, logger_default.errorData(err))
|
|
2768
|
+
);
|
|
2793
2769
|
if (!entry || entry.stage === "seed") {
|
|
2794
2770
|
if (entry?.stage === "seed") {
|
|
2795
2771
|
sendSeedOrientation(baseName, entry.createdBy).catch(
|
|
@@ -2823,7 +2799,7 @@ async function startMindFull(name) {
|
|
|
2823
2799
|
);
|
|
2824
2800
|
}
|
|
2825
2801
|
joinSystemChannelForMind(baseName).catch(
|
|
2826
|
-
(err) => logger_default.
|
|
2802
|
+
(err) => logger_default.warn(`failed to join #system for ${baseName}`, logger_default.errorData(err))
|
|
2827
2803
|
);
|
|
2828
2804
|
if (config?.tokenBudget) {
|
|
2829
2805
|
getTokenBudget().setBudget(
|
|
@@ -2834,6 +2810,31 @@ async function startMindFull(name) {
|
|
|
2834
2810
|
}
|
|
2835
2811
|
notifyExtensionsMindStart(baseName);
|
|
2836
2812
|
}
|
|
2813
|
+
async function recordMissingCredentialsNotice(mind, template) {
|
|
2814
|
+
const { hasUndeliveredNotice, recordNotice: recordNotice2, MIND_LEVEL_SESSION: MIND_LEVEL_SESSION2 } = await import("./notices-N6BCGHFV.js");
|
|
2815
|
+
const warning = await missingCredentialWarning(template, readMindModel(mind, template), mind);
|
|
2816
|
+
if (!warning) return;
|
|
2817
|
+
if (await hasUndeliveredNotice(mind, "no_credentials")) return;
|
|
2818
|
+
await recordNotice2({
|
|
2819
|
+
mind,
|
|
2820
|
+
session: MIND_LEVEL_SESSION2,
|
|
2821
|
+
kind: "startup",
|
|
2822
|
+
reason: "no_credentials",
|
|
2823
|
+
detail: warning
|
|
2824
|
+
});
|
|
2825
|
+
}
|
|
2826
|
+
function readMindModel(mind, template) {
|
|
2827
|
+
if (template !== "pi") return void 0;
|
|
2828
|
+
try {
|
|
2829
|
+
const configPath2 = resolve7(mindDir(mind), "home/.config/config.json");
|
|
2830
|
+
if (!existsSync8(configPath2)) return void 0;
|
|
2831
|
+
const model = JSON.parse(readFileSync7(configPath2, "utf-8")).model;
|
|
2832
|
+
return typeof model === "string" ? model : void 0;
|
|
2833
|
+
} catch (err) {
|
|
2834
|
+
logger_default.warn(`failed to read model for ${mind}`, logger_default.errorData(err));
|
|
2835
|
+
return void 0;
|
|
2836
|
+
}
|
|
2837
|
+
}
|
|
2837
2838
|
async function sleepMind(name) {
|
|
2838
2839
|
markIdle(name);
|
|
2839
2840
|
await getMindManager().stopMind(name);
|
|
@@ -2854,10 +2855,13 @@ async function wakeMind(name) {
|
|
|
2854
2855
|
async function startSpiritFull(name) {
|
|
2855
2856
|
const entry = await findMind(name);
|
|
2856
2857
|
if (entry?.dir) {
|
|
2857
|
-
const { registerMindDir } = await import("./delivery-router-
|
|
2858
|
+
const { registerMindDir } = await import("./delivery-router-VUOL5YSA.js");
|
|
2858
2859
|
registerMindDir(name, entry.dir);
|
|
2859
2860
|
}
|
|
2860
2861
|
await getMindManager().startMind(name);
|
|
2862
|
+
joinSystemChannelForSpirit().catch(
|
|
2863
|
+
(err) => logger_default.error(`failed to join #system for ${name}`, logger_default.errorData(err))
|
|
2864
|
+
);
|
|
2861
2865
|
getScheduler().loadSchedules(name, entry?.dir ?? spiritDir());
|
|
2862
2866
|
publish({
|
|
2863
2867
|
type: "mind_started",
|
|
@@ -2884,14 +2888,14 @@ function buildSeedOrientation(createdBy, creatorType) {
|
|
|
2884
2888
|
async function sendSeedOrientation(mindName, createdBy) {
|
|
2885
2889
|
let creatorType;
|
|
2886
2890
|
if (createdBy) {
|
|
2887
|
-
const { getUserByUsername: getUserByUsername2 } = await import("./auth-
|
|
2891
|
+
const { getUserByUsername: getUserByUsername2 } = await import("./auth-ABYLOEZ7.js");
|
|
2888
2892
|
creatorType = (await getUserByUsername2(createdBy))?.user_type;
|
|
2889
2893
|
}
|
|
2890
2894
|
await sendSystemMessage(mindName, buildSeedOrientation(createdBy, creatorType));
|
|
2891
2895
|
}
|
|
2892
2896
|
async function ensureCreatorDM(mindName, creatorUsername) {
|
|
2893
|
-
const { getOrCreateMindUser: getOrCreateMindUser2, getUserByUsername: getUserByUsername2 } = await import("./auth-
|
|
2894
|
-
const { findDMConversation: findDMConversation2, createConversation: createConversation2 } = await import("./conversations-
|
|
2897
|
+
const { getOrCreateMindUser: getOrCreateMindUser2, getUserByUsername: getUserByUsername2 } = await import("./auth-ABYLOEZ7.js");
|
|
2898
|
+
const { findDMConversation: findDMConversation2, createConversation: createConversation2 } = await import("./conversations-TUM5PJJ4.js");
|
|
2895
2899
|
const mindUser = await getOrCreateMindUser2(mindName);
|
|
2896
2900
|
const creatorUser = await getUserByUsername2(creatorUsername);
|
|
2897
2901
|
if (!creatorUser) {
|
|
@@ -2987,7 +2991,7 @@ var SleepManager = class {
|
|
|
2987
2991
|
transitioning = /* @__PURE__ */ new Set();
|
|
2988
2992
|
sleepConfigs = /* @__PURE__ */ new Map();
|
|
2989
2993
|
get statePath() {
|
|
2990
|
-
return
|
|
2994
|
+
return resolve8(voluteSystemDir(), "sleep-state.json");
|
|
2991
2995
|
}
|
|
2992
2996
|
start() {
|
|
2993
2997
|
this.loadState();
|
|
@@ -3003,8 +3007,8 @@ var SleepManager = class {
|
|
|
3003
3007
|
// --- State persistence ---
|
|
3004
3008
|
loadState() {
|
|
3005
3009
|
try {
|
|
3006
|
-
if (
|
|
3007
|
-
const data = JSON.parse(
|
|
3010
|
+
if (existsSync9(this.statePath)) {
|
|
3011
|
+
const data = JSON.parse(readFileSync8(this.statePath, "utf-8"));
|
|
3008
3012
|
for (const [name, state2] of Object.entries(data)) {
|
|
3009
3013
|
state2.triggerWakeHistory ??= [];
|
|
3010
3014
|
state2.wakeFailures ??= 0;
|
|
@@ -3295,7 +3299,7 @@ var SleepManager = class {
|
|
|
3295
3299
|
async flushQueuedMessages(name) {
|
|
3296
3300
|
try {
|
|
3297
3301
|
const db = await getDb();
|
|
3298
|
-
const rows = await db.select().from(deliveryQueue).where(
|
|
3302
|
+
const rows = await db.select().from(deliveryQueue).where(and(eq2(deliveryQueue.mind, name), eq2(deliveryQueue.status, "sleep-queued"))).all();
|
|
3299
3303
|
if (rows.length === 0) return 0;
|
|
3300
3304
|
const groups = /* @__PURE__ */ new Map();
|
|
3301
3305
|
for (const row of rows) {
|
|
@@ -3307,7 +3311,7 @@ var SleepManager = class {
|
|
|
3307
3311
|
`dropping unparseable queued message ${row.id} for ${name}`,
|
|
3308
3312
|
logger_default.errorData(err)
|
|
3309
3313
|
);
|
|
3310
|
-
await db.delete(deliveryQueue).where(
|
|
3314
|
+
await db.delete(deliveryQueue).where(eq2(deliveryQueue.id, row.id));
|
|
3311
3315
|
continue;
|
|
3312
3316
|
}
|
|
3313
3317
|
const channel = payload.channel ?? "unknown";
|
|
@@ -3350,7 +3354,7 @@ var SleepManager = class {
|
|
|
3350
3354
|
* the real delivery stack. Returns whether the batch was handed off to the mind.
|
|
3351
3355
|
*/
|
|
3352
3356
|
async deliverQueuedBatch(name, payloads) {
|
|
3353
|
-
const { deliverBatch: deliverBatch2 } = await import("./message-delivery-
|
|
3357
|
+
const { deliverBatch: deliverBatch2 } = await import("./message-delivery-ABPV76EA.js");
|
|
3354
3358
|
return deliverBatch2(name, payloads);
|
|
3355
3359
|
}
|
|
3356
3360
|
// --- Wake failure handling (#419) ---
|
|
@@ -3528,17 +3532,17 @@ var SleepManager = class {
|
|
|
3528
3532
|
}
|
|
3529
3533
|
}
|
|
3530
3534
|
async waitForIdle(name, timeoutMs) {
|
|
3531
|
-
return new Promise((
|
|
3535
|
+
return new Promise((resolve10) => {
|
|
3532
3536
|
const timeout = setTimeout(() => {
|
|
3533
3537
|
unsub();
|
|
3534
|
-
|
|
3538
|
+
resolve10();
|
|
3535
3539
|
}, timeoutMs);
|
|
3536
3540
|
const unsub = subscribe((event) => {
|
|
3537
3541
|
if (event.mind !== name) return;
|
|
3538
3542
|
if (event.type === "mind_done" || event.type === "mind_idle") {
|
|
3539
3543
|
clearTimeout(timeout);
|
|
3540
3544
|
unsub();
|
|
3541
|
-
|
|
3545
|
+
resolve10();
|
|
3542
3546
|
}
|
|
3543
3547
|
});
|
|
3544
3548
|
});
|
|
@@ -3546,15 +3550,15 @@ var SleepManager = class {
|
|
|
3546
3550
|
async archiveSessions(name) {
|
|
3547
3551
|
const dir = mindDir(name);
|
|
3548
3552
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 16);
|
|
3549
|
-
const sessionsDir =
|
|
3550
|
-
if (
|
|
3551
|
-
const archiveDir =
|
|
3553
|
+
const sessionsDir = resolve8(dir, ".mind", "sessions");
|
|
3554
|
+
if (existsSync9(sessionsDir)) {
|
|
3555
|
+
const archiveDir = resolve8(sessionsDir, "archive");
|
|
3552
3556
|
mkdirSync5(archiveDir, { recursive: true });
|
|
3553
3557
|
for (const file of readdirSync2(sessionsDir)) {
|
|
3554
3558
|
if (file === "archive" || !file.endsWith(".json")) continue;
|
|
3555
|
-
const src =
|
|
3559
|
+
const src = resolve8(sessionsDir, file);
|
|
3556
3560
|
const base = file.replace(/\.json$/, "");
|
|
3557
|
-
const dest =
|
|
3561
|
+
const dest = resolve8(archiveDir, `${base}-${timestamp}.json`);
|
|
3558
3562
|
try {
|
|
3559
3563
|
renameSync(src, dest);
|
|
3560
3564
|
} catch (err) {
|
|
@@ -3562,14 +3566,14 @@ var SleepManager = class {
|
|
|
3562
3566
|
}
|
|
3563
3567
|
}
|
|
3564
3568
|
}
|
|
3565
|
-
const piSessionsDir =
|
|
3566
|
-
if (
|
|
3567
|
-
const archiveDir =
|
|
3569
|
+
const piSessionsDir = resolve8(dir, ".mind", "pi-sessions");
|
|
3570
|
+
if (existsSync9(piSessionsDir)) {
|
|
3571
|
+
const archiveDir = resolve8(piSessionsDir, "archive");
|
|
3568
3572
|
mkdirSync5(archiveDir, { recursive: true });
|
|
3569
3573
|
for (const entry of readdirSync2(piSessionsDir, { withFileTypes: true })) {
|
|
3570
3574
|
if (entry.name === "archive" || !entry.isDirectory()) continue;
|
|
3571
|
-
const src =
|
|
3572
|
-
const dest =
|
|
3575
|
+
const src = resolve8(piSessionsDir, entry.name);
|
|
3576
|
+
const dest = resolve8(archiveDir, `${entry.name}-${timestamp}`);
|
|
3573
3577
|
try {
|
|
3574
3578
|
renameSync(src, dest);
|
|
3575
3579
|
} catch (err) {
|
|
@@ -3579,8 +3583,8 @@ var SleepManager = class {
|
|
|
3579
3583
|
}
|
|
3580
3584
|
}
|
|
3581
3585
|
async runWakeContextScript(name, sleepingSince, duration) {
|
|
3582
|
-
const scriptPath =
|
|
3583
|
-
if (!
|
|
3586
|
+
const scriptPath = resolve8(mindDir(name), "home", ".local", "hooks", "wake-context.sh");
|
|
3587
|
+
if (!existsSync9(scriptPath)) return "";
|
|
3584
3588
|
const input = JSON.stringify({
|
|
3585
3589
|
sleepingSince,
|
|
3586
3590
|
duration,
|
|
@@ -3630,7 +3634,7 @@ var SleepManager = class {
|
|
|
3630
3634
|
async buildQueuedSummary(name) {
|
|
3631
3635
|
try {
|
|
3632
3636
|
const db = await getDb();
|
|
3633
|
-
const rows = await db.select({ channel: deliveryQueue.channel, sender: deliveryQueue.sender }).from(deliveryQueue).where(
|
|
3637
|
+
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
3638
|
if (rows.length === 0) return "No messages arrived while you slept.";
|
|
3635
3639
|
const channelCounts = /* @__PURE__ */ new Map();
|
|
3636
3640
|
const senders = /* @__PURE__ */ new Set();
|
|
@@ -3677,7 +3681,7 @@ var SleepManager = class {
|
|
|
3677
3681
|
} catch {
|
|
3678
3682
|
try {
|
|
3679
3683
|
const portHex = port.toString(16).toUpperCase().padStart(4, "0");
|
|
3680
|
-
const tcp6 =
|
|
3684
|
+
const tcp6 = readFileSync8("/proc/net/tcp6", "utf-8");
|
|
3681
3685
|
for (const line of tcp6.split("\n")) {
|
|
3682
3686
|
if (!line.includes(`:${portHex} `)) continue;
|
|
3683
3687
|
const fields = line.trim().split(/\s+/);
|
|
@@ -3746,8 +3750,8 @@ function getSleepManagerIfReady() {
|
|
|
3746
3750
|
|
|
3747
3751
|
// packages/daemon/src/lib/delivery/delivery-manager.ts
|
|
3748
3752
|
import { realpath } from "fs/promises";
|
|
3749
|
-
import { resolve as
|
|
3750
|
-
import { and as
|
|
3753
|
+
import { resolve as resolve9 } from "path";
|
|
3754
|
+
import { and as and3, eq as eq4, inArray as inArray2, sql } from "drizzle-orm";
|
|
3751
3755
|
|
|
3752
3756
|
// packages/daemon/src/lib/chat/typing.ts
|
|
3753
3757
|
var DEFAULT_TTL_MS = 1e4;
|
|
@@ -3841,7 +3845,7 @@ function publishTypingForChannels(channels, map) {
|
|
|
3841
3845
|
}
|
|
3842
3846
|
|
|
3843
3847
|
// packages/daemon/src/lib/delivery/send-gate.ts
|
|
3844
|
-
import { and as
|
|
3848
|
+
import { and as and2, asc, desc, eq as eq3, gt } from "drizzle-orm";
|
|
3845
3849
|
var state = /* @__PURE__ */ new Map();
|
|
3846
3850
|
function extractText(raw) {
|
|
3847
3851
|
if (!raw) return "";
|
|
@@ -3856,7 +3860,7 @@ function extractText(raw) {
|
|
|
3856
3860
|
}
|
|
3857
3861
|
async function maxMessageId(conversationId) {
|
|
3858
3862
|
const db = await getDb();
|
|
3859
|
-
const rows = await db.select({ id: messages.id }).from(messages).where(
|
|
3863
|
+
const rows = await db.select({ id: messages.id }).from(messages).where(eq3(messages.conversation_id, conversationId)).orderBy(desc(messages.id)).limit(1);
|
|
3860
3864
|
return rows[0]?.id ?? 0;
|
|
3861
3865
|
}
|
|
3862
3866
|
async function onDeliveredToMind(mindBase, conversationId) {
|
|
@@ -3875,7 +3879,7 @@ async function checkStaleSend(mindBase, conversationId, excludeSenders) {
|
|
|
3875
3879
|
const entry = state.get(mindBase)?.get(conversationId);
|
|
3876
3880
|
if (!entry?.turnOpen || entry.heldThisTurn) return { held: false };
|
|
3877
3881
|
const db = await getDb();
|
|
3878
|
-
const rows = await db.select({ id: messages.id, sender: messages.sender_name, content: messages.content }).from(messages).where(
|
|
3882
|
+
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
3883
|
const excluded = new Set(excludeSenders.filter(Boolean));
|
|
3880
3884
|
const unseen = rows.filter((r) => r.sender && !excluded.has(r.sender));
|
|
3881
3885
|
if (unseen.length === 0) return { held: false };
|
|
@@ -3936,7 +3940,7 @@ var DeliveryManager = class {
|
|
|
3936
3940
|
isMindRunning = (name) => tryGetMindManager()?.isRunning(name) ?? false;
|
|
3937
3941
|
/** Sends a system message to a mind (invites, release summaries); overridable in tests. */
|
|
3938
3942
|
notify = async (mindName, text) => {
|
|
3939
|
-
const { sendSystemMessage: sendSystemMessage2 } = await import("./system-chat-
|
|
3943
|
+
const { sendSystemMessage: sendSystemMessage2 } = await import("./system-chat-M2XOBKEM.js");
|
|
3940
3944
|
await sendSystemMessage2(mindName, text);
|
|
3941
3945
|
};
|
|
3942
3946
|
constructor() {
|
|
@@ -3990,7 +3994,7 @@ var DeliveryManager = class {
|
|
|
3990
3994
|
if (route.destination === "file") {
|
|
3991
3995
|
return { routed: true, session: route.path, destination: "file", mode: "immediate" };
|
|
3992
3996
|
}
|
|
3993
|
-
if (
|
|
3997
|
+
if (shouldGate(config, route)) {
|
|
3994
3998
|
dlog.debug(`gating unmatched channel ${payload.channel} for ${mindName}`);
|
|
3995
3999
|
await this.gateMessage(mindName, route.session, payload);
|
|
3996
4000
|
return { routed: true, session: route.session, destination: "mind", mode: "gated" };
|
|
@@ -4070,9 +4074,9 @@ var DeliveryManager = class {
|
|
|
4070
4074
|
try {
|
|
4071
4075
|
const db = await getDb();
|
|
4072
4076
|
rows = await db.select().from(deliveryQueue).where(
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4077
|
+
and3(
|
|
4078
|
+
eq4(deliveryQueue.status, "pending"),
|
|
4079
|
+
sql`(${deliveryQueue.next_attempt_at} IS NULL OR ${deliveryQueue.next_attempt_at} <= datetime('now'))`
|
|
4076
4080
|
)
|
|
4077
4081
|
).orderBy(deliveryQueue.id).limit(REDRIVE_BATCH_LIMIT);
|
|
4078
4082
|
} catch (err) {
|
|
@@ -4132,7 +4136,7 @@ var DeliveryManager = class {
|
|
|
4132
4136
|
let rows;
|
|
4133
4137
|
try {
|
|
4134
4138
|
const db = await getDb();
|
|
4135
|
-
rows = await db.select().from(deliveryQueue).where(
|
|
4139
|
+
rows = await db.select().from(deliveryQueue).where(and3(eq4(deliveryQueue.mind, baseName), eq4(deliveryQueue.status, "gated")));
|
|
4136
4140
|
} catch (err) {
|
|
4137
4141
|
dlog.warn(`failed to read gated rows for ${baseName}`, logger_default.errorData(err));
|
|
4138
4142
|
return;
|
|
@@ -4164,7 +4168,13 @@ var DeliveryManager = class {
|
|
|
4164
4168
|
}
|
|
4165
4169
|
const channel = row.channel ?? payload.channel ?? "unknown";
|
|
4166
4170
|
const list = byChannel.get(channel) ?? [];
|
|
4167
|
-
list.push({
|
|
4171
|
+
list.push({
|
|
4172
|
+
id: row.id,
|
|
4173
|
+
session,
|
|
4174
|
+
channel,
|
|
4175
|
+
sender: payload.sender ?? row.sender ?? null,
|
|
4176
|
+
content: extractTextContent(payload.content)
|
|
4177
|
+
});
|
|
4168
4178
|
byChannel.set(channel, list);
|
|
4169
4179
|
}
|
|
4170
4180
|
const promote = [];
|
|
@@ -4199,16 +4209,38 @@ var DeliveryManager = class {
|
|
|
4199
4209
|
if (truncationNotes.length > 0) await this.sendReleaseSummary(mindName, truncationNotes);
|
|
4200
4210
|
return;
|
|
4201
4211
|
}
|
|
4212
|
+
const orderedPromote = [...promote].sort((a, b) => a.id - b.id);
|
|
4202
4213
|
try {
|
|
4203
4214
|
const db = await getDb();
|
|
4204
|
-
for (const p of
|
|
4205
|
-
await db.
|
|
4215
|
+
for (const p of orderedPromote) {
|
|
4216
|
+
await db.transaction(async (tx) => {
|
|
4217
|
+
await tx.insert(mindHistory).values({
|
|
4218
|
+
mind: baseName,
|
|
4219
|
+
type: "inbound",
|
|
4220
|
+
channel: p.channel,
|
|
4221
|
+
sender: p.sender,
|
|
4222
|
+
content: p.content
|
|
4223
|
+
});
|
|
4224
|
+
await tx.update(deliveryQueue).set({ status: "pending", session: p.session, attempts: 0, next_attempt_at: null }).where(eq4(deliveryQueue.id, p.id));
|
|
4225
|
+
});
|
|
4206
4226
|
}
|
|
4207
4227
|
dlog.info(`released ${promote.length} gated message(s) for ${baseName} after route change`);
|
|
4208
4228
|
} catch (err) {
|
|
4209
|
-
dlog.
|
|
4229
|
+
dlog.error(
|
|
4230
|
+
`failed to record+promote gated rows for ${baseName} (channels: ${[...byChannel.keys()].join(", ")})`,
|
|
4231
|
+
logger_default.errorData(err)
|
|
4232
|
+
);
|
|
4210
4233
|
return;
|
|
4211
4234
|
}
|
|
4235
|
+
for (const p of orderedPromote) {
|
|
4236
|
+
publish3(baseName, {
|
|
4237
|
+
mind: baseName,
|
|
4238
|
+
type: "inbound",
|
|
4239
|
+
channel: p.channel,
|
|
4240
|
+
content: p.content ?? void 0,
|
|
4241
|
+
sender: p.sender ?? void 0
|
|
4242
|
+
});
|
|
4243
|
+
}
|
|
4212
4244
|
if (truncationNotes.length > 0) await this.sendReleaseSummary(mindName, truncationNotes);
|
|
4213
4245
|
await this.redrive();
|
|
4214
4246
|
}
|
|
@@ -4220,7 +4252,7 @@ var DeliveryManager = class {
|
|
|
4220
4252
|
if (!channel) return false;
|
|
4221
4253
|
try {
|
|
4222
4254
|
const db = await getDb();
|
|
4223
|
-
const rows = await db.select({ state: channelGates.state }).from(channelGates).where(
|
|
4255
|
+
const rows = await db.select({ state: channelGates.state }).from(channelGates).where(and3(eq4(channelGates.mind, baseName), eq4(channelGates.channel, channel)));
|
|
4224
4256
|
return rows[0]?.state === "declined";
|
|
4225
4257
|
} catch (err) {
|
|
4226
4258
|
dlog.warn(`failed to read gate state for ${baseName}/${channel}`, logger_default.errorData(err));
|
|
@@ -4237,13 +4269,13 @@ var DeliveryManager = class {
|
|
|
4237
4269
|
const db = await getDb();
|
|
4238
4270
|
await db.insert(channelGates).values({ mind: baseName, channel, state: "declined" }).onConflictDoUpdate({
|
|
4239
4271
|
target: [channelGates.mind, channelGates.channel],
|
|
4240
|
-
set: { state: "declined", updated_at:
|
|
4272
|
+
set: { state: "declined", updated_at: sql`(datetime('now'))` }
|
|
4241
4273
|
});
|
|
4242
4274
|
const archived = await db.update(deliveryQueue).set({ status: "archived" }).where(
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4275
|
+
and3(
|
|
4276
|
+
eq4(deliveryQueue.mind, baseName),
|
|
4277
|
+
eq4(deliveryQueue.channel, channel),
|
|
4278
|
+
eq4(deliveryQueue.status, "gated")
|
|
4247
4279
|
)
|
|
4248
4280
|
).returning({ id: deliveryQueue.id });
|
|
4249
4281
|
dlog.info(
|
|
@@ -4273,7 +4305,7 @@ var DeliveryManager = class {
|
|
|
4273
4305
|
*/
|
|
4274
4306
|
async getPending(mindName) {
|
|
4275
4307
|
const db = await getDb();
|
|
4276
|
-
const rows = await db.select().from(deliveryQueue).where(
|
|
4308
|
+
const rows = await db.select().from(deliveryQueue).where(and3(eq4(deliveryQueue.mind, mindName), eq4(deliveryQueue.status, "gated")));
|
|
4277
4309
|
const byChannel = /* @__PURE__ */ new Map();
|
|
4278
4310
|
for (const row of rows) {
|
|
4279
4311
|
const ch = row.channel ?? "unknown";
|
|
@@ -4443,7 +4475,7 @@ var DeliveryManager = class {
|
|
|
4443
4475
|
const backoffSec = Math.round(
|
|
4444
4476
|
Math.min(RETRY_MAX_MS, RETRY_BASE_MS * 2 ** Math.min(attempts, 20)) / 1e3
|
|
4445
4477
|
);
|
|
4446
|
-
await db.update(deliveryQueue).set({ attempts, next_attempt_at:
|
|
4478
|
+
await db.update(deliveryQueue).set({ attempts, next_attempt_at: sql`datetime('now', ${`+${backoffSec} seconds`})` }).where(eq4(deliveryQueue.id, row.id));
|
|
4447
4479
|
}
|
|
4448
4480
|
} catch (err) {
|
|
4449
4481
|
dlog.warn("failed to schedule delivery retry", logger_default.errorData(err));
|
|
@@ -4672,10 +4704,10 @@ var DeliveryManager = class {
|
|
|
4672
4704
|
if (declined) return;
|
|
4673
4705
|
try {
|
|
4674
4706
|
const db = await getDb();
|
|
4675
|
-
const rows = await db.select({ count:
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
|
|
4707
|
+
const rows = await db.select({ count: sql`count(*)` }).from(deliveryQueue).where(
|
|
4708
|
+
and3(
|
|
4709
|
+
eq4(deliveryQueue.mind, baseName),
|
|
4710
|
+
eq4(deliveryQueue.channel, payload.channel),
|
|
4679
4711
|
inArray2(deliveryQueue.status, ["gated", "archived"])
|
|
4680
4712
|
)
|
|
4681
4713
|
);
|
|
@@ -4692,18 +4724,22 @@ var DeliveryManager = class {
|
|
|
4692
4724
|
const preview = text.length > 200 ? `${text.slice(0, 200)}...` : text;
|
|
4693
4725
|
const channel = payload.channel ?? "unknown";
|
|
4694
4726
|
const heldLine = gatedCount > 1 ? `${gatedCount} messages from this channel are being held, unrouted \u2014 you've not routed it yet.` : `Someone new is reaching out \u2014 you don't have a route for this channel yet.`;
|
|
4695
|
-
const
|
|
4696
|
-
`[New channel: ${channel}]`,
|
|
4697
|
-
heldLine,
|
|
4698
|
-
`Sender: ${payload.sender ?? "unknown"}`,
|
|
4727
|
+
const detailLines = [
|
|
4699
4728
|
payload.platform ? `Platform: ${payload.platform}` : null,
|
|
4700
|
-
payload.participantCount ? `Participants: ${payload.participantCount}` : null
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4729
|
+
payload.participantCount ? `Participants: ${payload.participantCount}` : null
|
|
4730
|
+
].filter((l) => l !== null);
|
|
4731
|
+
const details = detailLines.length > 0 ? `${detailLines.join("\n")}
|
|
4732
|
+
|
|
4733
|
+
` : "\n";
|
|
4734
|
+
const { getPrompt: getPrompt2 } = await import("./prompts-MDHDLWEX.js");
|
|
4735
|
+
const notification = await getPrompt2("channel_invite", {
|
|
4736
|
+
channel,
|
|
4737
|
+
heldLine,
|
|
4738
|
+
sender: payload.sender ?? "unknown",
|
|
4739
|
+
details,
|
|
4740
|
+
preview,
|
|
4741
|
+
limit: String(GATED_RELEASE_LIMIT_PER_CHANNEL)
|
|
4742
|
+
});
|
|
4707
4743
|
await this.notify(mindName, notification);
|
|
4708
4744
|
}
|
|
4709
4745
|
/**
|
|
@@ -4777,8 +4813,8 @@ var DeliveryManager = class {
|
|
|
4777
4813
|
const dir = mindDir(p.username);
|
|
4778
4814
|
const config = readVoluteConfig(dir);
|
|
4779
4815
|
if (!config?.profile?.avatar) continue;
|
|
4780
|
-
filePath =
|
|
4781
|
-
const homeDir =
|
|
4816
|
+
filePath = resolve9(dir, "home", config.profile.avatar);
|
|
4817
|
+
const homeDir = resolve9(dir, "home");
|
|
4782
4818
|
if (!filePath.startsWith(`${homeDir}/`)) {
|
|
4783
4819
|
dlog.warn(`avatar path for ${p.username} escapes home directory, skipping`);
|
|
4784
4820
|
continue;
|
|
@@ -4797,7 +4833,7 @@ var DeliveryManager = class {
|
|
|
4797
4833
|
throw err;
|
|
4798
4834
|
}
|
|
4799
4835
|
} else {
|
|
4800
|
-
filePath =
|
|
4836
|
+
filePath = resolve9(voluteHome(), "avatars", p.avatar);
|
|
4801
4837
|
}
|
|
4802
4838
|
const rendered = await renderAvatarBlock(filePath, p.username);
|
|
4803
4839
|
if (rendered) blocks.push(...rendered);
|
|
@@ -4894,6 +4930,15 @@ async function recordInbound(mind, channel, sender, content) {
|
|
|
4894
4930
|
});
|
|
4895
4931
|
return insertedId;
|
|
4896
4932
|
}
|
|
4933
|
+
async function deliverSproutedNotice(mind) {
|
|
4934
|
+
await recordInbound(mind, "system", "system", "[seed has sprouted]");
|
|
4935
|
+
const convs = await listConversationsForMind(mind);
|
|
4936
|
+
for (const conv of convs) {
|
|
4937
|
+
await addMessage(conv.id, "assistant", "system", [
|
|
4938
|
+
{ type: "text", text: "[seed has sprouted]" }
|
|
4939
|
+
]);
|
|
4940
|
+
}
|
|
4941
|
+
}
|
|
4897
4942
|
async function recordOutbound(mind, channel, content, opts = {}) {
|
|
4898
4943
|
try {
|
|
4899
4944
|
const db = await getDb();
|
|
@@ -4925,7 +4970,7 @@ async function linkToolResultToTurn(mind, turnId, toolResultContent, toolUseEven
|
|
|
4925
4970
|
content: mindHistory.content,
|
|
4926
4971
|
message_id: mindHistory.message_id,
|
|
4927
4972
|
turn_id: mindHistory.turn_id
|
|
4928
|
-
}).from(mindHistory).where(
|
|
4973
|
+
}).from(mindHistory).where(and4(eq5(mindHistory.id, outboundId), eq5(mindHistory.mind, mind))).limit(1);
|
|
4929
4974
|
const row = rows[0];
|
|
4930
4975
|
if (!row) {
|
|
4931
4976
|
dlog2.warn(`outbound marker references missing record: mind=${mind} id=${outboundId}`);
|
|
@@ -4933,13 +4978,13 @@ async function linkToolResultToTurn(mind, turnId, toolResultContent, toolUseEven
|
|
|
4933
4978
|
}
|
|
4934
4979
|
const alreadyTagged = row.turn_id != null;
|
|
4935
4980
|
if (!alreadyTagged) {
|
|
4936
|
-
await db.update(mindHistory).set({ turn_id: turnId }).where(
|
|
4981
|
+
await db.update(mindHistory).set({ turn_id: turnId }).where(eq5(mindHistory.id, outboundId));
|
|
4937
4982
|
}
|
|
4938
4983
|
if (row.message_id) {
|
|
4939
4984
|
await db.update(messages).set({
|
|
4940
4985
|
turn_id: turnId,
|
|
4941
4986
|
...toolUseEventId != null ? { source_event_id: toolUseEventId } : {}
|
|
4942
|
-
}).where(
|
|
4987
|
+
}).where(eq5(messages.id, Number(row.message_id)));
|
|
4943
4988
|
}
|
|
4944
4989
|
if (!alreadyTagged) {
|
|
4945
4990
|
publish3(mind, {
|
|
@@ -4988,6 +5033,17 @@ function resolveSleepAction(sleepBehavior, wokenByTrigger, wakeTriggerMatches) {
|
|
|
4988
5033
|
if (!sleepBehavior && wakeTriggerMatches) return "queue-and-wake";
|
|
4989
5034
|
return "queue";
|
|
4990
5035
|
}
|
|
5036
|
+
function willGate(baseName, payload) {
|
|
5037
|
+
if (payload.session) return false;
|
|
5038
|
+
const config = getRoutingConfig(baseName);
|
|
5039
|
+
const route = resolveRoute(config, {
|
|
5040
|
+
channel: payload.channel,
|
|
5041
|
+
sender: payload.sender ?? void 0,
|
|
5042
|
+
isDM: payload.isDM,
|
|
5043
|
+
participantCount: payload.participantCount
|
|
5044
|
+
});
|
|
5045
|
+
return shouldGate(config, route);
|
|
5046
|
+
}
|
|
4991
5047
|
async function deliverMessage(mindName, payload, opts = {}) {
|
|
4992
5048
|
try {
|
|
4993
5049
|
const baseName = await getBaseName(mindName);
|
|
@@ -4998,9 +5054,9 @@ async function deliverMessage(mindName, payload, opts = {}) {
|
|
|
4998
5054
|
}
|
|
4999
5055
|
if (!opts.isFlush) {
|
|
5000
5056
|
const textContent = extractTextContent(payload.content);
|
|
5001
|
-
await recordInbound(baseName, payload.channel, payload.sender ?? null, textContent);
|
|
5002
5057
|
const sleepManager = getSleepManagerIfReady();
|
|
5003
5058
|
if (sleepManager?.isSleeping(baseName)) {
|
|
5059
|
+
await recordInbound(baseName, payload.channel, payload.sender ?? null, textContent);
|
|
5004
5060
|
const sleepState = sleepManager.getState(baseName);
|
|
5005
5061
|
const action = resolveSleepAction(
|
|
5006
5062
|
payload.whileSleeping,
|
|
@@ -5019,6 +5075,9 @@ async function deliverMessage(mindName, payload, opts = {}) {
|
|
|
5019
5075
|
}
|
|
5020
5076
|
return true;
|
|
5021
5077
|
}
|
|
5078
|
+
if (!willGate(baseName, payload)) {
|
|
5079
|
+
await recordInbound(baseName, payload.channel, payload.sender ?? null, textContent);
|
|
5080
|
+
}
|
|
5022
5081
|
}
|
|
5023
5082
|
const manager = getDeliveryManager();
|
|
5024
5083
|
await manager.routeAndDeliver(mindName, payload);
|
|
@@ -5128,7 +5187,7 @@ async function spiritWillHandle() {
|
|
|
5128
5187
|
const spiritEntry = await findMind(SPIRIT_NAME);
|
|
5129
5188
|
if (spiritEntry?.running && spiritEntry.mindType === "spirit") return true;
|
|
5130
5189
|
try {
|
|
5131
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
5190
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-DSPXFHGX.js");
|
|
5132
5191
|
const sm = getSleepManagerIfReady2();
|
|
5133
5192
|
if (sm?.isSleeping(SPIRIT_NAME)) return true;
|
|
5134
5193
|
} catch (err) {
|
|
@@ -5156,7 +5215,7 @@ async function generateSystemFallbackReply(conversationId, mindName, message) {
|
|
|
5156
5215
|
if (config.sleep.schedule?.wake) contextParts.push(`Wake cron: ${config.sleep.schedule.wake}`);
|
|
5157
5216
|
}
|
|
5158
5217
|
try {
|
|
5159
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
5218
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-DSPXFHGX.js");
|
|
5160
5219
|
const sm = getSleepManagerIfReady2();
|
|
5161
5220
|
if (sm) {
|
|
5162
5221
|
const state2 = sm.getState(mindName);
|
|
@@ -5210,10 +5269,6 @@ export {
|
|
|
5210
5269
|
checkHealth,
|
|
5211
5270
|
RotatingLog,
|
|
5212
5271
|
syncProviderToMinds,
|
|
5213
|
-
recordNotice,
|
|
5214
|
-
drainNotices,
|
|
5215
|
-
clearDeliveredNotices,
|
|
5216
|
-
formatNotices,
|
|
5217
5272
|
RestartTracker,
|
|
5218
5273
|
getTypingMap,
|
|
5219
5274
|
isConversationId,
|
|
@@ -5227,6 +5282,7 @@ export {
|
|
|
5227
5282
|
MindStartupError,
|
|
5228
5283
|
initMindManager,
|
|
5229
5284
|
getMindManager,
|
|
5285
|
+
tryGetMindManager,
|
|
5230
5286
|
invalidateMindUserCache,
|
|
5231
5287
|
SESSION_MAX_AGE,
|
|
5232
5288
|
invalidateSessionCache,
|
|
@@ -5262,6 +5318,7 @@ export {
|
|
|
5262
5318
|
initTokenBudget,
|
|
5263
5319
|
getTokenBudget,
|
|
5264
5320
|
startMindFull,
|
|
5321
|
+
recordMissingCredentialsNotice,
|
|
5265
5322
|
sleepMind,
|
|
5266
5323
|
wakeMind,
|
|
5267
5324
|
startSpiritFull,
|
|
@@ -5274,6 +5331,7 @@ export {
|
|
|
5274
5331
|
getSleepManager,
|
|
5275
5332
|
getSleepManagerIfReady,
|
|
5276
5333
|
recordInbound,
|
|
5334
|
+
deliverSproutedNotice,
|
|
5277
5335
|
recordOutbound,
|
|
5278
5336
|
linkToolResultToTurn,
|
|
5279
5337
|
resolveSleepAction,
|
|
@@ -5281,5 +5339,7 @@ export {
|
|
|
5281
5339
|
deliverBatch,
|
|
5282
5340
|
ensureSystemChannel,
|
|
5283
5341
|
joinSystemChannel,
|
|
5342
|
+
joinSystemChannelForMind,
|
|
5343
|
+
backfillSystemChannelMembers,
|
|
5284
5344
|
announceToSystem
|
|
5285
5345
|
};
|