volute 0.52.0 → 0.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{accept-5NK5XJB5.js → accept-I4GVGWA3.js} +6 -3
- package/dist/{chat-VAZ25KVT.js → chat-WK2BLM7B.js} +9 -9
- package/dist/{chunk-724DVYHU.js → chunk-23UJGVYP.js} +9 -9
- package/dist/{chunk-K2F237KS.js → chunk-5DBGQBQR.js} +138 -13
- package/dist/chunk-5RBEEAKW.js +58 -0
- package/dist/{chunk-XRWUQPCA.js → chunk-7ARONCZW.js} +24 -2
- package/dist/{chunk-FXWBFDQR.js → chunk-AP2KQMMW.js} +48 -9
- package/dist/{chunk-DMK5ASKV.js → chunk-F6D766VQ.js} +6 -2
- package/dist/{chunk-ZEZQNP2G.js → chunk-HASADR3E.js} +46 -9
- package/dist/{chunk-AXFLY5GU.js → chunk-IQ7VNWH6.js} +16 -1
- package/dist/{chunk-G7A5LEVI.js → chunk-LN7XJ56R.js} +6 -6
- package/dist/{chunk-CW7BQKF6.js → chunk-P2TBUKLW.js} +3 -3
- package/dist/{chunk-SW2U6HRB.js → chunk-PIZDPY4G.js} +20 -3
- package/dist/{chunk-JHKBALS2.js → chunk-RMADJFA7.js} +1 -1
- package/dist/{chunk-RU74YG46.js → chunk-RQRO6PC7.js} +40 -6
- package/dist/{chunk-RPPTGPYF.js → chunk-TAWRJ24T.js} +1 -1
- package/dist/{chunk-ITK6HV47.js → chunk-UO4MZQNO.js} +1 -1
- package/dist/chunk-UTKUO2KY.js +102 -0
- package/dist/{chunk-YVR6EHWL.js → chunk-VDZ4I4ZP.js} +160 -18
- package/dist/cli.js +16 -16
- package/dist/{clock-ZT5YT6HA.js → clock-SH4NQC2F.js} +3 -3
- package/dist/{cloud-sync-H7EWZASD.js → cloud-sync-MJVJ33LD.js} +10 -9
- package/dist/{daemon-restart-4FWUA5JF.js → daemon-restart-BIGU4OKS.js} +1 -1
- package/dist/daemon.js +261 -89
- package/dist/{delivery-manager-VYXVKUMP.js → delivery-manager-FDHCZ7PU.js} +7 -5
- package/dist/delivery-notices-65TB3CBX.js +18 -0
- package/dist/{echo-text-PEEV7FQU.js → echo-text-KU6G4Z7V.js} +11 -10
- package/dist/{extensions-N6L5NYTK.js → extensions-VACUKFA5.js} +10 -9
- package/dist/{files-BRY5RRIM.js → files-CHPNEQXN.js} +5 -4
- package/dist/{message-delivery-7URC52ME.js → message-delivery-TUXM3AAE.js} +14 -11
- package/dist/{mind-NEXGT3KE.js → mind-IX5AWUST.js} +11 -11
- package/dist/{mind-contacts-QYU4TPEA.js → mind-contacts-BKUOUJPV.js} +5 -5
- package/dist/{mind-history-OGNR4L7W.js → mind-history-RVF6KJ7K.js} +83 -11
- package/dist/{mind-list-SYRA7CH5.js → mind-list-KNU34SUD.js} +2 -2
- package/dist/{mind-service-E26ZQXDS.js → mind-service-WHFBUKZE.js} +10 -9
- package/dist/{mind-sleep-LZAFBDZD.js → mind-sleep-D3DEYAWG.js} +5 -5
- package/dist/{mind-status-Z2LQFA6F.js → mind-status-BPTLQ5Z6.js} +15 -3
- package/dist/{package-2W2XKSIP.js → package-BN5KMU54.js} +1 -1
- package/dist/{prompts-NBO3HRK3.js → prompts-HNKGCAEY.js} +1 -1
- package/dist/{reject-TWB4QJHG.js → reject-K2A4UK2Y.js} +9 -5
- package/dist/{scheduler-JTTWZDYU.js → scheduler-5X5UIQOQ.js} +7 -5
- package/dist/{seed-64XEHRUP.js → seed-LHZ33UB4.js} +1 -1
- package/dist/{seed-cmd-UEL2QB3Q.js → seed-cmd-U4RVJ3UA.js} +2 -2
- package/dist/{seed-create-4JRQDPGA.js → seed-create-OQU4KNCB.js} +1 -1
- package/dist/{seed-readiness-DYOVCYHN.js → seed-readiness-WJYYRRCK.js} +2 -2
- package/dist/{seed-sprout-NIDIOJXT.js → seed-sprout-SFUYH2RG.js} +7 -7
- package/dist/{send-2YKOZJJ5.js → send-FWZAMDBN.js} +35 -20
- package/dist/{setup-4IX6PCD3.js → setup-RVSGCIF3.js} +1 -1
- package/dist/skills/memory/SKILL.md +47 -43
- package/dist/{skills-MPUALV3S.js → skills-QRPU6BWY.js} +1 -1
- package/dist/{sleep-manager-OFP2GFXF.js → sleep-manager-NWUCRBZB.js} +10 -9
- package/dist/{spirit-4ECYIVGE.js → spirit-I5ECLGRI.js} +16 -2
- package/dist/{spirit-availability-Y54Y3675.js → spirit-availability-NIUUYKU2.js} +11 -10
- package/dist/{sprout-GJMZFRGZ.js → sprout-A2PMEF7Z.js} +1 -1
- package/dist/{system-events-V43HDA3T.js → system-events-YTOU66QI.js} +5 -1
- package/dist/{systems-VDRUZXNF.js → systems-2DIJY4RF.js} +6 -6
- package/dist/{turn-tracker-C5PVIC3B.js → turn-tracker-NNHS6MAR.js} +4 -2
- package/dist/{up-H6LJZDRK.js → up-UGBHH743.js} +1 -1
- package/dist/{variant-cleanup-STC6B5HR.js → variant-cleanup-CZDLIY3F.js} +7 -5
- package/dist/{version-notify-LBVHH5YV.js → version-notify-SJVAQLZI.js} +4 -4
- package/dist/web-assets/assets/index-BHSU9r-4.css +1 -0
- package/dist/web-assets/assets/{index-B_eYTa3R.js → index-b7G7ZsVk.js} +13 -13
- package/dist/web-assets/index.html +2 -2
- package/package.json +1 -1
- package/templates/_base/.init/.config/prompts.json +1 -1
- package/templates/_base/src/lib/codex-session-seed.ts +463 -0
- package/templates/_base/src/lib/daemon-client.ts +35 -0
- package/templates/_base/src/lib/pi-session-seed.ts +434 -0
- package/templates/_base/src/lib/seed-note.ts +78 -0
- package/templates/_base/src/lib/session-seed.ts +375 -0
- package/templates/_base/src/lib/startup.ts +108 -4
- package/templates/claude/.init/CLAUDE.md +3 -3
- package/templates/claude/src/agent.ts +267 -89
- package/templates/claude/src/lib/hooks/pre-compact.ts +30 -5
- package/templates/claude/src/lib/stream-consumer.ts +13 -0
- package/templates/claude/src/server.ts +2 -1
- package/templates/codex/.init/AGENTS.md +3 -3
- package/templates/codex/src/agent.ts +256 -39
- package/templates/codex/src/server.ts +2 -1
- package/templates/pi/.init/MINDS.md +3 -3
- package/templates/pi/src/agent.ts +269 -43
- package/templates/pi/src/lib/event-handler.ts +11 -0
- package/templates/pi/src/server.ts +3 -1
- package/dist/web-assets/assets/index-DhZrzddW.css +0 -1
- package/dist/{backup-YVGV2ZNM.js → backup-WWXVIMYQ.js} +5 -5
- package/dist/{bridge-YK7NTRU5.js → bridge-KU2IKSH3.js} +3 -3
- package/dist/{channels-FSAHOQWI.js → channels-LW5ZLMSQ.js} +3 -3
- package/dist/{chunk-VPOMJMV6.js → chunk-BDHKCLWK.js} +0 -0
- package/dist/{chunk-EEOMA4DX.js → chunk-HTB7KDRU.js} +3 -3
- package/dist/{create-M727VUDF.js → create-C3XZACTV.js} +3 -3
- package/dist/{env-IBW2QI6K.js → env-BJGM6FBA.js} +5 -5
- package/dist/{extension-MRYJWSMV.js → extension-B2W52WZY.js} +3 -3
- package/dist/{list-UQGIW7OF.js → list-R2GDWOEE.js} +3 -3
- package/dist/{login-RJJTCVR3.js → login-EZ4RRDQX.js} +3 -3
- package/dist/{login-SB5OENMV.js → login-JDOAK465.js} +4 -4
- package/dist/{logout-YFZAJRPY.js → logout-K6ZGAJY5.js} +3 -3
- package/dist/{logout-BYV433X6.js → logout-MWSIUOQU.js} +3 -3
- package/dist/{mind-wake-LDGPRA42.js → mind-wake-DCDFFQKX.js} +3 -3
- package/dist/{read-RJ5NAW5J.js → read-J5RM674N.js} +3 -3
- package/dist/{register-OX4HRSGC.js → register-53LBGSDC.js} +3 -3
- package/dist/{restart-AGEGNSYQ.js → restart-R2WFNF5K.js} +4 -4
- package/dist/{skill-B5OJEQUA.js → skill-DXLLSUHB.js} +5 -5
- package/dist/{start-MUMNFR52.js → start-XDOUAWN3.js} +4 -4
- package/dist/{status-MWLE3RVC.js → status-EYG4A3OK.js} +3 -3
- package/dist/{stop-EKERNYTX.js → stop-O62RTEMD.js} +4 -4
package/dist/daemon.js
CHANGED
|
@@ -14,23 +14,31 @@ import {
|
|
|
14
14
|
rejectPending,
|
|
15
15
|
stageFile,
|
|
16
16
|
validateFilePath
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-F6D766VQ.js";
|
|
18
18
|
import {
|
|
19
19
|
findOpenClawSession,
|
|
20
20
|
importOpenClawConnectors,
|
|
21
21
|
importPiSession,
|
|
22
22
|
parseNameFromIdentity
|
|
23
23
|
} from "./chunk-I7U5EEZC.js";
|
|
24
|
+
import {
|
|
25
|
+
getMemoryStatus
|
|
26
|
+
} from "./chunk-5RBEEAKW.js";
|
|
27
|
+
import {
|
|
28
|
+
checkForUpdate,
|
|
29
|
+
checkForUpdateCached,
|
|
30
|
+
getCurrentVersion
|
|
31
|
+
} from "./chunk-LAUCO2HC.js";
|
|
24
32
|
import {
|
|
25
33
|
SPIRIT_NOTICE_PREFIX,
|
|
26
34
|
ensureSpiritAvailable
|
|
27
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-P2TBUKLW.js";
|
|
28
36
|
import {
|
|
29
37
|
isHomeOnlyArchive
|
|
30
38
|
} from "./chunk-FLIEXG2T.js";
|
|
31
39
|
import {
|
|
32
40
|
evaluateSeedChecklist
|
|
33
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-RMADJFA7.js";
|
|
34
42
|
import {
|
|
35
43
|
isTemplateStale
|
|
36
44
|
} from "./chunk-CV6BNGFK.js";
|
|
@@ -39,19 +47,14 @@ import {
|
|
|
39
47
|
} from "./chunk-HTRSSOHY.js";
|
|
40
48
|
import {
|
|
41
49
|
cleanupVariant
|
|
42
|
-
} from "./chunk-
|
|
43
|
-
import {
|
|
44
|
-
checkForUpdate,
|
|
45
|
-
checkForUpdateCached,
|
|
46
|
-
getCurrentVersion
|
|
47
|
-
} from "./chunk-LAUCO2HC.js";
|
|
50
|
+
} from "./chunk-UO4MZQNO.js";
|
|
48
51
|
import {
|
|
49
52
|
PLATFORMS,
|
|
50
53
|
echoTextToChannel,
|
|
51
54
|
fixModelEscapes,
|
|
52
55
|
getPlatformDriver,
|
|
53
56
|
routeOutboundBridge
|
|
54
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-7ARONCZW.js";
|
|
55
58
|
import {
|
|
56
59
|
getBridgeConfig,
|
|
57
60
|
readBridgesConfig,
|
|
@@ -104,9 +107,10 @@ import {
|
|
|
104
107
|
startMindFull,
|
|
105
108
|
stopMindFull,
|
|
106
109
|
uninstallNpmExtension,
|
|
110
|
+
willGateMessage,
|
|
107
111
|
writeSystemsConfig
|
|
108
|
-
} from "./chunk-
|
|
109
|
-
import "./chunk-
|
|
112
|
+
} from "./chunk-HASADR3E.js";
|
|
113
|
+
import "./chunk-5DBGQBQR.js";
|
|
110
114
|
import {
|
|
111
115
|
applyInitFiles,
|
|
112
116
|
applyTemplateHomeFiles,
|
|
@@ -119,7 +123,10 @@ import {
|
|
|
119
123
|
import {
|
|
120
124
|
getScheduler,
|
|
121
125
|
initScheduler
|
|
122
|
-
} from "./chunk-
|
|
126
|
+
} from "./chunk-PIZDPY4G.js";
|
|
127
|
+
import {
|
|
128
|
+
recordDeliveryFailure
|
|
129
|
+
} from "./chunk-UTKUO2KY.js";
|
|
123
130
|
import {
|
|
124
131
|
checkStaleSend,
|
|
125
132
|
formatHoldNotice,
|
|
@@ -128,7 +135,7 @@ import {
|
|
|
128
135
|
initDeliveryManager,
|
|
129
136
|
isConversationId,
|
|
130
137
|
publishTypingForChannels
|
|
131
|
-
} from "./chunk-
|
|
138
|
+
} from "./chunk-RQRO6PC7.js";
|
|
132
139
|
import {
|
|
133
140
|
MindStartupError,
|
|
134
141
|
RestartTracker,
|
|
@@ -138,7 +145,7 @@ import {
|
|
|
138
145
|
initMindManager,
|
|
139
146
|
syncProviderToMinds,
|
|
140
147
|
tryGetMindManager
|
|
141
|
-
} from "./chunk-
|
|
148
|
+
} from "./chunk-23UJGVYP.js";
|
|
142
149
|
import {
|
|
143
150
|
extractTextContent
|
|
144
151
|
} from "./chunk-UDZLPR34.js";
|
|
@@ -155,13 +162,15 @@ import {
|
|
|
155
162
|
initSummarizer,
|
|
156
163
|
isoWeekKeyForDateStr,
|
|
157
164
|
markErrored,
|
|
165
|
+
parseDbTimestamp,
|
|
158
166
|
parseUtcDateTime,
|
|
159
167
|
summarizeOrphanedTurns,
|
|
160
168
|
summarizeTurn,
|
|
169
|
+
supersedeTurnSummary,
|
|
161
170
|
takeErrored,
|
|
162
171
|
trackToolUse,
|
|
163
172
|
utcDateTimeStr
|
|
164
|
-
} from "./chunk-
|
|
173
|
+
} from "./chunk-VDZ4I4ZP.js";
|
|
165
174
|
import {
|
|
166
175
|
SEED_SKILLS,
|
|
167
176
|
STANDARD_SKILLS,
|
|
@@ -183,7 +192,7 @@ import {
|
|
|
183
192
|
syncBuiltinSkills,
|
|
184
193
|
uninstallSkill,
|
|
185
194
|
updateSkill
|
|
186
|
-
} from "./chunk-
|
|
195
|
+
} from "./chunk-TAWRJ24T.js";
|
|
187
196
|
import {
|
|
188
197
|
approveUser,
|
|
189
198
|
changePassword,
|
|
@@ -207,6 +216,7 @@ import {
|
|
|
207
216
|
withSenderDisplayNames
|
|
208
217
|
} from "./chunk-7LT3YZUR.js";
|
|
209
218
|
import {
|
|
219
|
+
MIND_LEVEL_THREAD,
|
|
210
220
|
captureReflection,
|
|
211
221
|
cleanExpiredEvents,
|
|
212
222
|
clearDeliveredEvents,
|
|
@@ -219,7 +229,7 @@ import {
|
|
|
219
229
|
listEvents,
|
|
220
230
|
parseMeta,
|
|
221
231
|
recordNotice
|
|
222
|
-
} from "./chunk-
|
|
232
|
+
} from "./chunk-IQ7VNWH6.js";
|
|
223
233
|
import {
|
|
224
234
|
publish as publish2,
|
|
225
235
|
subscribe as subscribe2,
|
|
@@ -232,7 +242,7 @@ import {
|
|
|
232
242
|
getPrompt,
|
|
233
243
|
getPromptIfCustom,
|
|
234
244
|
substitute
|
|
235
|
-
} from "./chunk-
|
|
245
|
+
} from "./chunk-AP2KQMMW.js";
|
|
236
246
|
import {
|
|
237
247
|
isSandboxEnabled,
|
|
238
248
|
wrapForSandbox
|
|
@@ -397,7 +407,7 @@ import "./chunk-K3NQKI34.js";
|
|
|
397
407
|
|
|
398
408
|
// packages/daemon/src/daemon.ts
|
|
399
409
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
400
|
-
import { chmodSync, mkdirSync as mkdirSync10, readFileSync as readFileSync12, unlinkSync as unlinkSync2, writeFileSync as
|
|
410
|
+
import { chmodSync, mkdirSync as mkdirSync10, readFileSync as readFileSync12, unlinkSync as unlinkSync2, writeFileSync as writeFileSync11 } from "fs";
|
|
401
411
|
import { homedir as homedir3 } from "os";
|
|
402
412
|
import { resolve as resolve20 } from "path";
|
|
403
413
|
import { format } from "util";
|
|
@@ -510,7 +520,7 @@ var BackupManager = class {
|
|
|
510
520
|
} catch (pubErr) {
|
|
511
521
|
blog.error("failed to publish backup-failure activity", logger_default.errorData(pubErr));
|
|
512
522
|
}
|
|
513
|
-
const { deliverEvent: deliverEvent2 } = await import("./system-events-
|
|
523
|
+
const { deliverEvent: deliverEvent2 } = await import("./system-events-YTOU66QI.js");
|
|
514
524
|
await deliverEvent2(getSpiritName(), {
|
|
515
525
|
type: "notice",
|
|
516
526
|
meta: { subtype: "backup" },
|
|
@@ -1462,7 +1472,7 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1462
1472
|
config2.name = name.trim() || void 0;
|
|
1463
1473
|
writeGlobalConfig(config2);
|
|
1464
1474
|
if (config2.name !== previousName) {
|
|
1465
|
-
const { notifySpiritSystemChange } = await import("./spirit-
|
|
1475
|
+
const { notifySpiritSystemChange } = await import("./spirit-I5ECLGRI.js");
|
|
1466
1476
|
await notifySpiritSystemChange();
|
|
1467
1477
|
}
|
|
1468
1478
|
return c.json({ name: config2.name ?? null });
|
|
@@ -2674,6 +2684,21 @@ async function fanOutToMinds(opts) {
|
|
|
2674
2684
|
const manager = getMindManager();
|
|
2675
2685
|
const sm = getSleepManagerIfReady();
|
|
2676
2686
|
const registeredMinds = new Set((await readAllMinds()).map((m) => m.name));
|
|
2687
|
+
const senderIsMind = registeredMinds.has(opts.senderName);
|
|
2688
|
+
let senderCtx;
|
|
2689
|
+
const reportFailure = (reason) => {
|
|
2690
|
+
if (!senderIsMind) return;
|
|
2691
|
+
senderCtx ??= getBaseName(opts.senderName).then((base) => ({
|
|
2692
|
+
base,
|
|
2693
|
+
channel: buildVoluteSlug({
|
|
2694
|
+
participants,
|
|
2695
|
+
mindUsername: base,
|
|
2696
|
+
conversationId: opts.conversationId,
|
|
2697
|
+
...opts.slugExtra
|
|
2698
|
+
})
|
|
2699
|
+
}));
|
|
2700
|
+
senderCtx.then(({ base, channel }) => recordDeliveryFailure({ mind: base, channel, reason })).catch((err) => logger_default.warn("fan-out: failed to report send failure", logger_default.errorData(err)));
|
|
2701
|
+
};
|
|
2677
2702
|
const targetMinds = mindParticipants.map((ap) => {
|
|
2678
2703
|
const key = opts.targetName ? opts.targetName(ap.username) : ap.username;
|
|
2679
2704
|
if (manager.isRunning(key) || sm?.isSleeping(ap.username)) return ap.username;
|
|
@@ -2682,21 +2707,46 @@ async function fanOutToMinds(opts) {
|
|
|
2682
2707
|
logger_default.warn(
|
|
2683
2708
|
`fan-out: skipping ${ap.username} (not running) for conversation ${opts.conversationId}`
|
|
2684
2709
|
);
|
|
2710
|
+
reportFailure(`${ap.username} is not running`);
|
|
2711
|
+
} else if (ap.userType === "mind") {
|
|
2712
|
+
logger_default.info(
|
|
2713
|
+
`fan-out: skipping ${ap.username} (no registry row \u2014 external mind or stale participant) for conversation ${opts.conversationId}`
|
|
2714
|
+
);
|
|
2685
2715
|
}
|
|
2686
2716
|
if (ap.userType === "system") {
|
|
2687
|
-
import("./spirit-availability-
|
|
2717
|
+
import("./spirit-availability-NIUUYKU2.js").then(({ ensureSpiritAvailable: ensureSpiritAvailable2 }) => ensureSpiritAvailable2()).catch((err) => logger_default.warn("fan-out: on-demand spirit start failed", logger_default.errorData(err)));
|
|
2688
2718
|
}
|
|
2689
2719
|
}
|
|
2690
2720
|
return null;
|
|
2691
2721
|
}).filter((n) => n !== null && n !== opts.senderName);
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2722
|
+
const targets = targetMinds.map((mindName) => ({
|
|
2723
|
+
mindName,
|
|
2724
|
+
target: opts.targetName ? opts.targetName(mindName) : mindName,
|
|
2725
|
+
channel: buildVoluteSlug({
|
|
2695
2726
|
participants,
|
|
2696
2727
|
mindUsername: mindName,
|
|
2697
2728
|
conversationId: opts.conversationId,
|
|
2698
2729
|
...opts.slugExtra
|
|
2699
|
-
})
|
|
2730
|
+
})
|
|
2731
|
+
}));
|
|
2732
|
+
const gatedRecipients = (await Promise.all(
|
|
2733
|
+
targets.map(async ({ mindName, target, channel }) => {
|
|
2734
|
+
if (sm?.isSleeping(mindName)) return null;
|
|
2735
|
+
try {
|
|
2736
|
+
const gated = await willGateMessage(target, {
|
|
2737
|
+
channel,
|
|
2738
|
+
sender: opts.senderName,
|
|
2739
|
+
isDM,
|
|
2740
|
+
participantCount: participants.length
|
|
2741
|
+
});
|
|
2742
|
+
return gated ? mindName : null;
|
|
2743
|
+
} catch (err) {
|
|
2744
|
+
logger_default.warn(`fan-out: will-gate check failed for ${target}`, logger_default.errorData(err));
|
|
2745
|
+
return null;
|
|
2746
|
+
}
|
|
2747
|
+
})
|
|
2748
|
+
)).filter((n) => n !== null);
|
|
2749
|
+
for (const { mindName, target, channel } of targets) {
|
|
2700
2750
|
const typingMap = getTypingMap();
|
|
2701
2751
|
const currentlyTyping = typingMap.get(channel).filter((name) => participantNames.includes(name));
|
|
2702
2752
|
deliverMessage(target, {
|
|
@@ -2708,10 +2758,20 @@ async function fanOutToMinds(opts) {
|
|
|
2708
2758
|
participantCount: participants.length,
|
|
2709
2759
|
isDM,
|
|
2710
2760
|
...currentlyTyping.length > 0 ? { typing: currentlyTyping } : {}
|
|
2711
|
-
}).
|
|
2712
|
-
|
|
2713
|
-
|
|
2761
|
+
}).then(
|
|
2762
|
+
(ok) => {
|
|
2763
|
+
if (!ok) {
|
|
2764
|
+
logger_default.warn(`fan-out delivery failed for ${target} (message not delivered)`);
|
|
2765
|
+
reportFailure(`the delivery to ${mindName} failed`);
|
|
2766
|
+
}
|
|
2767
|
+
},
|
|
2768
|
+
(err) => {
|
|
2769
|
+
logger_default.warn(`fan-out delivery failed for ${target}`, logger_default.errorData(err));
|
|
2770
|
+
reportFailure(`the delivery to ${mindName} failed`);
|
|
2771
|
+
}
|
|
2772
|
+
);
|
|
2714
2773
|
}
|
|
2774
|
+
return { gatedRecipients };
|
|
2715
2775
|
}
|
|
2716
2776
|
|
|
2717
2777
|
// packages/daemon/src/web/api/bridges.ts
|
|
@@ -3069,12 +3129,18 @@ import { resolve as resolve4 } from "path";
|
|
|
3069
3129
|
import { Hono as Hono10 } from "hono";
|
|
3070
3130
|
async function notifyMind(mindName, message) {
|
|
3071
3131
|
const entry = await findMind(mindName);
|
|
3072
|
-
if (!entry) return;
|
|
3073
|
-
try {
|
|
3074
|
-
const { deliverEvent: deliverEvent2 } = await import("./system-events-
|
|
3075
|
-
await deliverEvent2(mindName, { type: "file-share", body: message });
|
|
3132
|
+
if (!entry) return false;
|
|
3133
|
+
try {
|
|
3134
|
+
const { deliverEvent: deliverEvent2 } = await import("./system-events-YTOU66QI.js");
|
|
3135
|
+
const result = await deliverEvent2(mindName, { type: "file-share", body: message });
|
|
3136
|
+
if (result.delivered) return true;
|
|
3137
|
+
if (result.id == null) return false;
|
|
3138
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-NWUCRBZB.js");
|
|
3139
|
+
const { getBaseName: getBaseName2 } = await import("./registry-TRC2HJXR.js");
|
|
3140
|
+
return getSleepManagerIfReady2()?.isSleeping(await getBaseName2(mindName)) ?? false;
|
|
3076
3141
|
} catch (err) {
|
|
3077
3142
|
logger_default.warn(`[file-sharing] notify mind ${mindName} failed`, logger_default.errorData(err));
|
|
3143
|
+
return false;
|
|
3078
3144
|
}
|
|
3079
3145
|
}
|
|
3080
3146
|
var app8 = new Hono10().post("/:name/files/send", requireSelf(), async (c) => {
|
|
@@ -3115,11 +3181,11 @@ var app8 = new Hono10().post("/:name/files/send", requireSelf(), async (c) => {
|
|
|
3115
3181
|
const filename = body.filePath;
|
|
3116
3182
|
const sizeStr = formatFileSize(content.length);
|
|
3117
3183
|
const { id } = stageFile(body.targetMind, senderName, filename, content, body.filePath);
|
|
3118
|
-
await notifyMind(
|
|
3184
|
+
const notified = await notifyMind(
|
|
3119
3185
|
body.targetMind,
|
|
3120
3186
|
`[file] ${senderName} sent ${filename} (${sizeStr}) \u2014 run: volute chat accept ${id}`
|
|
3121
3187
|
);
|
|
3122
|
-
return c.json({ status: "pending", id }, 200);
|
|
3188
|
+
return c.json({ status: "pending", id, notified }, 200);
|
|
3123
3189
|
}).get("/:name/files/pending", requireSelf(), async (c) => {
|
|
3124
3190
|
const name = c.req.param("name");
|
|
3125
3191
|
if (!await findMind(name)) return c.json({ error: "Mind not found" }, 404);
|
|
@@ -3144,8 +3210,8 @@ var app8 = new Hono10().post("/:name/files/send", requireSelf(), async (c) => {
|
|
|
3144
3210
|
}
|
|
3145
3211
|
return c.json({ error: `Failed to accept file: ${message}` }, 500);
|
|
3146
3212
|
}
|
|
3147
|
-
await notifyMind(result.sender, `[file] ${name} accepted ${result.filename}`);
|
|
3148
|
-
return c.json({ ok: true, destPath: result.destPath });
|
|
3213
|
+
const notified = await notifyMind(result.sender, `[file] ${name} accepted ${result.filename}`);
|
|
3214
|
+
return c.json({ ok: true, destPath: result.destPath, notified });
|
|
3149
3215
|
}).post("/:name/files/reject", requireSelf(), async (c) => {
|
|
3150
3216
|
const name = c.req.param("name");
|
|
3151
3217
|
if (!await findMind(name)) return c.json({ error: "Mind not found" }, 404);
|
|
@@ -3161,8 +3227,8 @@ var app8 = new Hono10().post("/:name/files/send", requireSelf(), async (c) => {
|
|
|
3161
3227
|
}
|
|
3162
3228
|
return c.json({ error: `Failed to reject file: ${message}` }, 500);
|
|
3163
3229
|
}
|
|
3164
|
-
await notifyMind(result.sender, `[file] ${name} rejected ${result.filename}`);
|
|
3165
|
-
return c.json({ ok: true });
|
|
3230
|
+
const notified = await notifyMind(result.sender, `[file] ${name} rejected ${result.filename}`);
|
|
3231
|
+
return c.json({ ok: true, notified });
|
|
3166
3232
|
}).post("/:name/files/stage", requireSelf(), async (c) => {
|
|
3167
3233
|
const receiverName = c.req.param("name");
|
|
3168
3234
|
const receiverEntry = await findMind(receiverName);
|
|
@@ -3185,11 +3251,11 @@ var app8 = new Hono10().post("/:name/files/send", requireSelf(), async (c) => {
|
|
|
3185
3251
|
}
|
|
3186
3252
|
const sizeStr = formatFileSize(content.length);
|
|
3187
3253
|
const { id } = stageFile(receiverName, body.sender, body.filename, content, body.filename);
|
|
3188
|
-
await notifyMind(
|
|
3254
|
+
const notified = await notifyMind(
|
|
3189
3255
|
receiverName,
|
|
3190
3256
|
`[file] ${body.sender} sent ${body.filename} (${sizeStr}) \u2014 run: volute chat accept ${id}`
|
|
3191
3257
|
);
|
|
3192
|
-
return c.json({ status: "pending", id }, 200);
|
|
3258
|
+
return c.json({ status: "pending", id, notified }, 200);
|
|
3193
3259
|
});
|
|
3194
3260
|
var file_sharing_default = app8;
|
|
3195
3261
|
|
|
@@ -5126,12 +5192,6 @@ function convertAssistantContent(content) {
|
|
|
5126
5192
|
return result;
|
|
5127
5193
|
}
|
|
5128
5194
|
|
|
5129
|
-
// packages/daemon/src/lib/util/time.ts
|
|
5130
|
-
function parseDbTimestamp(ts) {
|
|
5131
|
-
if (/[zZ]$|[+-]\d\d:?\d\d$/.test(ts)) return new Date(ts);
|
|
5132
|
-
return /* @__PURE__ */ new Date(`${ts.replace(" ", "T")}Z`);
|
|
5133
|
-
}
|
|
5134
|
-
|
|
5135
5195
|
// packages/daemon/src/web/api/minds.ts
|
|
5136
5196
|
var _lastActiveCache = { map: /* @__PURE__ */ new Map(), ts: 0 };
|
|
5137
5197
|
var _LAST_ACTIVE_TTL = 6e4;
|
|
@@ -5141,7 +5201,7 @@ async function getMindStatus(name, port, registryRunning, seed) {
|
|
|
5141
5201
|
let status = "stopped";
|
|
5142
5202
|
let wakeAt = null;
|
|
5143
5203
|
try {
|
|
5144
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
5204
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-NWUCRBZB.js");
|
|
5145
5205
|
const sleepManager = getSleepManagerIfReady2();
|
|
5146
5206
|
if (sleepManager?.isSleeping(name)) {
|
|
5147
5207
|
status = "sleeping";
|
|
@@ -5167,10 +5227,12 @@ async function getMindStatus(name, port, registryRunning, seed) {
|
|
|
5167
5227
|
}
|
|
5168
5228
|
const lastError = await latestFailureEvent(name);
|
|
5169
5229
|
const seedChecklist = seed?.stage === "seed" ? evaluateSeedChecklist(seed.dir ?? mindDir(name)) : void 0;
|
|
5230
|
+
const memory = getMemoryStatus(seed?.dir ?? mindDir(name));
|
|
5170
5231
|
return {
|
|
5171
5232
|
status,
|
|
5172
5233
|
wakeAt,
|
|
5173
5234
|
lastError,
|
|
5235
|
+
memory,
|
|
5174
5236
|
channels: channels2,
|
|
5175
5237
|
displayName: config2?.profile?.displayName,
|
|
5176
5238
|
description: config2?.profile?.description,
|
|
@@ -5193,6 +5255,7 @@ function toPublicMind(entry, status, extras) {
|
|
|
5193
5255
|
// Kind/reason/at only — `detail` can embed the raw error string (unknown
|
|
5194
5256
|
// classifications), which is mind-private (served behind requireSelf).
|
|
5195
5257
|
lastError: status.lastError ? { kind: status.lastError.kind, reason: status.lastError.reason, at: status.lastError.at } : null,
|
|
5258
|
+
memory: status.memory,
|
|
5196
5259
|
channels: status.channels,
|
|
5197
5260
|
displayName: status.displayName,
|
|
5198
5261
|
description: status.description,
|
|
@@ -5786,7 +5849,7 @@ Your creator described you as: "${body.description}"
|
|
|
5786
5849
|
const spiritName = getSpiritName();
|
|
5787
5850
|
const spiritEntry = await findMind(spiritName);
|
|
5788
5851
|
if (spiritEntry) {
|
|
5789
|
-
const { spiritDir } = await import("./spirit-
|
|
5852
|
+
const { spiritDir } = await import("./spirit-I5ECLGRI.js");
|
|
5790
5853
|
const sDir = spiritEntry.dir ?? spiritDir();
|
|
5791
5854
|
const spiritConfig = readVoluteConfig(sDir) ?? {};
|
|
5792
5855
|
const schedules = spiritConfig.schedules ?? [];
|
|
@@ -5801,7 +5864,7 @@ Your creator described you as: "${body.description}"
|
|
|
5801
5864
|
});
|
|
5802
5865
|
spiritConfig.schedules = schedules;
|
|
5803
5866
|
writeVoluteConfig(sDir, spiritConfig);
|
|
5804
|
-
const { getScheduler: getScheduler2 } = await import("./scheduler-
|
|
5867
|
+
const { getScheduler: getScheduler2 } = await import("./scheduler-5X5UIQOQ.js");
|
|
5805
5868
|
getScheduler2().loadSchedules(spiritName, sDir);
|
|
5806
5869
|
}
|
|
5807
5870
|
}
|
|
@@ -6107,7 +6170,7 @@ ${user.trimEnd()}
|
|
|
6107
6170
|
const manager = getMindManager();
|
|
6108
6171
|
try {
|
|
6109
6172
|
if (context?.type === "reload") {
|
|
6110
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
6173
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-NWUCRBZB.js");
|
|
6111
6174
|
const sleepState = getSleepManagerIfReady2()?.getState(name);
|
|
6112
6175
|
if (sleepState?.sleeping) {
|
|
6113
6176
|
logger_default.info(`skipping reload for ${name} during sleep \u2014 will apply on next wake`);
|
|
@@ -6256,7 +6319,7 @@ ${user.trimEnd()}
|
|
|
6256
6319
|
const name = c.req.param("name");
|
|
6257
6320
|
const entry = await findMind(name);
|
|
6258
6321
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6259
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
6322
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-NWUCRBZB.js");
|
|
6260
6323
|
const sm = getSleepManagerIfReady2();
|
|
6261
6324
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
6262
6325
|
return c.json(sm.getState(name));
|
|
@@ -6264,7 +6327,7 @@ ${user.trimEnd()}
|
|
|
6264
6327
|
const name = c.req.param("name");
|
|
6265
6328
|
const entry = await findMind(name);
|
|
6266
6329
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6267
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
6330
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-NWUCRBZB.js");
|
|
6268
6331
|
const sm = getSleepManagerIfReady2();
|
|
6269
6332
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
6270
6333
|
if (sm.isSleeping(name)) return c.json({ error: "Mind is already sleeping" }, 409);
|
|
@@ -6284,7 +6347,7 @@ ${user.trimEnd()}
|
|
|
6284
6347
|
const name = c.req.param("name");
|
|
6285
6348
|
const entry = await findMind(name);
|
|
6286
6349
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6287
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
6350
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-NWUCRBZB.js");
|
|
6288
6351
|
const sm = getSleepManagerIfReady2();
|
|
6289
6352
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
6290
6353
|
const sleepState = sm.getState(name);
|
|
@@ -6299,7 +6362,7 @@ ${user.trimEnd()}
|
|
|
6299
6362
|
const name = c.req.param("name");
|
|
6300
6363
|
const entry = await findMind(name);
|
|
6301
6364
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
6302
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
6365
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-NWUCRBZB.js");
|
|
6303
6366
|
const sm = getSleepManagerIfReady2();
|
|
6304
6367
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
6305
6368
|
const flushed = await sm.flushQueuedMessages(name);
|
|
@@ -6371,7 +6434,7 @@ ${user.trimEnd()}
|
|
|
6371
6434
|
});
|
|
6372
6435
|
}
|
|
6373
6436
|
if (!force) {
|
|
6374
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
6437
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-NWUCRBZB.js");
|
|
6375
6438
|
if (getSleepManagerIfReady2()?.isSleeping(name)) {
|
|
6376
6439
|
return c.json({ output: "" });
|
|
6377
6440
|
}
|
|
@@ -6426,7 +6489,7 @@ ${user.trimEnd()}
|
|
|
6426
6489
|
}
|
|
6427
6490
|
}
|
|
6428
6491
|
const dir = entry.dir ?? mindDir(name);
|
|
6429
|
-
const { evaluateSeedChecklist: evaluateSeedChecklist2 } = await import("./seed-readiness-
|
|
6492
|
+
const { evaluateSeedChecklist: evaluateSeedChecklist2 } = await import("./seed-readiness-WJYYRRCK.js");
|
|
6430
6493
|
const checklist = evaluateSeedChecklist2(dir);
|
|
6431
6494
|
const done = [];
|
|
6432
6495
|
const remaining = [];
|
|
@@ -6468,7 +6531,7 @@ ${user.trimEnd()}
|
|
|
6468
6531
|
try {
|
|
6469
6532
|
const sproutedDir = entry.dir ?? mindDir(name);
|
|
6470
6533
|
if (setupDefaultDreaming(sproutedDir).schedulesChanged) {
|
|
6471
|
-
const { getScheduler: getScheduler2 } = await import("./scheduler-
|
|
6534
|
+
const { getScheduler: getScheduler2 } = await import("./scheduler-5X5UIQOQ.js");
|
|
6472
6535
|
getScheduler2().loadSchedules(name, sproutedDir);
|
|
6473
6536
|
}
|
|
6474
6537
|
} catch (err) {
|
|
@@ -6478,7 +6541,7 @@ ${user.trimEnd()}
|
|
|
6478
6541
|
const spiritName = getSpiritName();
|
|
6479
6542
|
const spiritEntry = await findMind(spiritName);
|
|
6480
6543
|
if (spiritEntry) {
|
|
6481
|
-
const { firstWeekSchedules, spiritDir } = await import("./spirit-
|
|
6544
|
+
const { firstWeekSchedules, spiritDir } = await import("./spirit-I5ECLGRI.js");
|
|
6482
6545
|
const sDir = spiritEntry.dir ?? spiritDir();
|
|
6483
6546
|
const spiritConfig = readVoluteConfig(sDir);
|
|
6484
6547
|
if (spiritConfig) {
|
|
@@ -6492,7 +6555,7 @@ ${user.trimEnd()}
|
|
|
6492
6555
|
spiritConfig.schedules = schedules;
|
|
6493
6556
|
writeVoluteConfig(sDir, spiritConfig);
|
|
6494
6557
|
try {
|
|
6495
|
-
const { getScheduler: getScheduler2 } = await import("./scheduler-
|
|
6558
|
+
const { getScheduler: getScheduler2 } = await import("./scheduler-5X5UIQOQ.js");
|
|
6496
6559
|
getScheduler2().loadSchedules(spiritName, sDir);
|
|
6497
6560
|
} catch (err) {
|
|
6498
6561
|
logger_default.warn(
|
|
@@ -6933,7 +6996,7 @@ ${user.trimEnd()}
|
|
|
6933
6996
|
}
|
|
6934
6997
|
writeVoluteConfig(dir, existing);
|
|
6935
6998
|
if (body.unescapeNewlines !== void 0) {
|
|
6936
|
-
const { clearEchoTextCache } = await import("./echo-text-
|
|
6999
|
+
const { clearEchoTextCache } = await import("./echo-text-KU6G4Z7V.js");
|
|
6937
7000
|
clearEchoTextCache(name);
|
|
6938
7001
|
}
|
|
6939
7002
|
const needsConfigJson = body.model !== void 0 || body.thinkingLevel !== void 0 || body.compaction !== void 0;
|
|
@@ -7258,6 +7321,35 @@ ${lines.join("\n")}` });
|
|
|
7258
7321
|
const maxId = notices.reduce((m, n) => Math.max(m, n.id), 0);
|
|
7259
7322
|
setNoticeDrainWatermark(baseName, session, maxId);
|
|
7260
7323
|
return c.json({ context: formatEvents(notices), notices });
|
|
7324
|
+
}).post("/:name/notices", requireSelf(), async (c) => {
|
|
7325
|
+
const MIND_POSTABLE_KINDS = ["context_lost", "delivery_failed"];
|
|
7326
|
+
const name = c.req.param("name");
|
|
7327
|
+
const baseName = await getBaseName(name);
|
|
7328
|
+
let body;
|
|
7329
|
+
try {
|
|
7330
|
+
body = await c.req.json();
|
|
7331
|
+
} catch {
|
|
7332
|
+
return c.json({ error: "Invalid JSON body" }, 400);
|
|
7333
|
+
}
|
|
7334
|
+
const kind = body.kind;
|
|
7335
|
+
if (typeof kind !== "string" || !MIND_POSTABLE_KINDS.includes(kind)) {
|
|
7336
|
+
return c.json({ error: `kind must be one of: ${MIND_POSTABLE_KINDS.join(", ")}` }, 400);
|
|
7337
|
+
}
|
|
7338
|
+
const message = typeof body.message === "string" ? body.message.trim() : "";
|
|
7339
|
+
if (!message) return c.json({ error: "message is required" }, 400);
|
|
7340
|
+
if (body.thread !== void 0 && typeof body.thread !== "string") {
|
|
7341
|
+
return c.json({ error: "thread must be a string" }, 400);
|
|
7342
|
+
}
|
|
7343
|
+
await recordNotice({
|
|
7344
|
+
mind: baseName,
|
|
7345
|
+
thread: body.thread ?? MIND_LEVEL_THREAD,
|
|
7346
|
+
kind,
|
|
7347
|
+
reason: kind,
|
|
7348
|
+
// Bound the size (the body is injected into turn context) without dropping
|
|
7349
|
+
// the notice — a truncated explanation beats a silent 400.
|
|
7350
|
+
detail: message.length > 4e3 ? `${message.slice(0, 4e3)}\u2026` : message
|
|
7351
|
+
});
|
|
7352
|
+
return c.json({ ok: true });
|
|
7261
7353
|
}).get("/:name/system-events", requireSelf(), async (c) => {
|
|
7262
7354
|
const name = c.req.param("name");
|
|
7263
7355
|
const baseName = await getBaseName(name);
|
|
@@ -7280,6 +7372,43 @@ ${lines.join("\n")}` });
|
|
|
7280
7372
|
};
|
|
7281
7373
|
})
|
|
7282
7374
|
});
|
|
7375
|
+
}).put("/:name/turn-summaries", requireSelf(), async (c) => {
|
|
7376
|
+
const name = c.req.param("name");
|
|
7377
|
+
const baseName = await getBaseName(name);
|
|
7378
|
+
let body;
|
|
7379
|
+
try {
|
|
7380
|
+
body = await c.req.json();
|
|
7381
|
+
} catch {
|
|
7382
|
+
return c.json({ error: "Invalid JSON body" }, 400);
|
|
7383
|
+
}
|
|
7384
|
+
const items = body.summaries;
|
|
7385
|
+
if (!Array.isArray(items) || items.length === 0) {
|
|
7386
|
+
return c.json({ error: "summaries must be a non-empty array" }, 400);
|
|
7387
|
+
}
|
|
7388
|
+
let updated = 0;
|
|
7389
|
+
let created = 0;
|
|
7390
|
+
for (const item of items) {
|
|
7391
|
+
if (!item || typeof item.turnId !== "string" || !item.turnId) {
|
|
7392
|
+
return c.json({ error: "each summary needs a turnId" }, 400);
|
|
7393
|
+
}
|
|
7394
|
+
if (typeof item.content !== "string") {
|
|
7395
|
+
return c.json({ error: "each summary needs content" }, 400);
|
|
7396
|
+
}
|
|
7397
|
+
const result = await supersedeTurnSummary(baseName, item.turnId, item.content);
|
|
7398
|
+
switch (result.status) {
|
|
7399
|
+
case "invalid":
|
|
7400
|
+
return c.json({ error: result.error }, 400);
|
|
7401
|
+
case "not_found":
|
|
7402
|
+
return c.json({ error: "Turn not found" }, 404);
|
|
7403
|
+
case "forbidden":
|
|
7404
|
+
return c.json({ error: "Forbidden" }, 403);
|
|
7405
|
+
case "ok":
|
|
7406
|
+
if (result.created) created++;
|
|
7407
|
+
else updated++;
|
|
7408
|
+
break;
|
|
7409
|
+
}
|
|
7410
|
+
}
|
|
7411
|
+
return c.json({ ok: true, updated, created });
|
|
7283
7412
|
}).get("/:name/history", requireSelf(), async (c) => {
|
|
7284
7413
|
const name = c.req.param("name");
|
|
7285
7414
|
const channel = c.req.query("channel");
|
|
@@ -7288,6 +7417,7 @@ ${lines.join("\n")}` });
|
|
|
7288
7417
|
const preset = c.req.query("preset");
|
|
7289
7418
|
const limit = Math.min(Math.max(parseInt(c.req.query("limit") ?? "50", 10) || 50, 1), 200);
|
|
7290
7419
|
const offset = Math.max(parseInt(c.req.query("offset") ?? "0", 10) || 0, 0);
|
|
7420
|
+
const provisional = c.req.query("provisional") === "true";
|
|
7291
7421
|
const db = await getDb();
|
|
7292
7422
|
const conditions = [eq5(mindHistory.mind, name)];
|
|
7293
7423
|
if (channel) {
|
|
@@ -7299,6 +7429,9 @@ ${lines.join("\n")}` });
|
|
|
7299
7429
|
const effectivePreset = full ? "all" : preset;
|
|
7300
7430
|
if (!effectivePreset || effectivePreset === "summary") {
|
|
7301
7431
|
const sumConditions = [eq5(summaries.mind, name), eq5(summaries.period, "turn")];
|
|
7432
|
+
if (provisional) {
|
|
7433
|
+
sumConditions.push(sql3`json_extract(${summaries.metadata}, '$.author') is not ${"mind"}`);
|
|
7434
|
+
}
|
|
7302
7435
|
if (session) {
|
|
7303
7436
|
sumConditions.push(eq5(turns.thread, session));
|
|
7304
7437
|
const sumRows2 = await db.select({
|
|
@@ -7707,7 +7840,7 @@ var app15 = new Hono18().get("/:name/clock/status", requireSelf(), async (c) =>
|
|
|
7707
7840
|
const entry = await findMind(name);
|
|
7708
7841
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
7709
7842
|
const body = await c.req.text();
|
|
7710
|
-
const { deliverEvent: deliverEvent2 } = await import("./system-events-
|
|
7843
|
+
const { deliverEvent: deliverEvent2 } = await import("./system-events-YTOU66QI.js");
|
|
7711
7844
|
const { id, delivered } = await deliverEvent2(name, {
|
|
7712
7845
|
type: "webhook",
|
|
7713
7846
|
body,
|
|
@@ -7723,9 +7856,9 @@ var app15 = new Hono18().get("/:name/clock/status", requireSelf(), async (c) =>
|
|
|
7723
7856
|
var schedules_default = app15;
|
|
7724
7857
|
|
|
7725
7858
|
// packages/daemon/src/web/api/setup.ts
|
|
7726
|
-
import { mkdirSync as mkdirSync7 } from "fs";
|
|
7859
|
+
import { mkdirSync as mkdirSync7, rmSync as rmSync4, writeFileSync as writeFileSync9 } from "fs";
|
|
7727
7860
|
import { homedir as homedir2 } from "os";
|
|
7728
|
-
import { resolve as resolve14 } from "path";
|
|
7861
|
+
import { basename, resolve as resolve14 } from "path";
|
|
7729
7862
|
import { Hono as Hono19 } from "hono";
|
|
7730
7863
|
import { setCookie as setCookie2 } from "hono/cookie";
|
|
7731
7864
|
var DEFAULT_API_URL2 = "https://volute.systems";
|
|
@@ -8063,6 +8196,39 @@ setup.post("/spirit", async (c) => {
|
|
|
8063
8196
|
config2.setup.spiritName = name;
|
|
8064
8197
|
const temperament = body.temperament?.trim();
|
|
8065
8198
|
config2.setup.spiritTemperament = temperament || void 0;
|
|
8199
|
+
const description = body.description?.trim();
|
|
8200
|
+
config2.setup.spiritDescription = description || void 0;
|
|
8201
|
+
const clearOldStash = () => {
|
|
8202
|
+
if (config2.setup?.spiritAvatar) {
|
|
8203
|
+
rmSync4(resolve14(voluteSystemDir(), basename(config2.setup.spiritAvatar)), { force: true });
|
|
8204
|
+
config2.setup.spiritAvatar = void 0;
|
|
8205
|
+
}
|
|
8206
|
+
};
|
|
8207
|
+
if (body.avatar) {
|
|
8208
|
+
const match = /^data:image\/(png|jpeg|webp);base64,([A-Za-z0-9+/=]+)$/.exec(body.avatar);
|
|
8209
|
+
if (!match) {
|
|
8210
|
+
return c.json({ error: "Avatar must be a png, jpeg, or webp image" }, 400);
|
|
8211
|
+
}
|
|
8212
|
+
if (match[2].length > 3 * 1024 * 1024) {
|
|
8213
|
+
return c.json({ error: "Avatar must be under 2MB" }, 400);
|
|
8214
|
+
}
|
|
8215
|
+
let bytes = Buffer.from(match[2], "base64");
|
|
8216
|
+
if (bytes.length > 2 * 1024 * 1024) {
|
|
8217
|
+
return c.json({ error: "Avatar must be under 2MB" }, 400);
|
|
8218
|
+
}
|
|
8219
|
+
let ext = match[1] === "jpeg" ? "jpg" : match[1];
|
|
8220
|
+
const normalized = await normalizeAvatar(bytes);
|
|
8221
|
+
if (normalized) {
|
|
8222
|
+
bytes = normalized.buffer;
|
|
8223
|
+
ext = "webp";
|
|
8224
|
+
}
|
|
8225
|
+
clearOldStash();
|
|
8226
|
+
const filename = `spirit-avatar.${ext}`;
|
|
8227
|
+
writeFileSync9(resolve14(voluteSystemDir(), filename), bytes);
|
|
8228
|
+
config2.setup.spiritAvatar = filename;
|
|
8229
|
+
} else {
|
|
8230
|
+
clearOldStash();
|
|
8231
|
+
}
|
|
8066
8232
|
writeGlobalConfig(config2);
|
|
8067
8233
|
return c.json({ ok: true });
|
|
8068
8234
|
});
|
|
@@ -8071,8 +8237,8 @@ setup.post("/complete", async (c) => {
|
|
|
8071
8237
|
return c.json({ error: "Setup already complete" }, 400);
|
|
8072
8238
|
}
|
|
8073
8239
|
try {
|
|
8074
|
-
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-
|
|
8075
|
-
const { startSpiritFull } = await import("./mind-service-
|
|
8240
|
+
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-I5ECLGRI.js");
|
|
8241
|
+
const { startSpiritFull } = await import("./mind-service-WHFBUKZE.js");
|
|
8076
8242
|
await ensureSpiritProject();
|
|
8077
8243
|
await syncSpiritTemplate();
|
|
8078
8244
|
const warnings = [];
|
|
@@ -8132,15 +8298,13 @@ setup.post("/complete", async (c) => {
|
|
|
8132
8298
|
logger_default.info("setup complete state", { spiritConversationId, spiritStarted });
|
|
8133
8299
|
if (spiritConversationId && spiritStarted) {
|
|
8134
8300
|
try {
|
|
8135
|
-
const { deliverMessage: deliverMessage2 } = await import("./message-delivery-
|
|
8301
|
+
const { deliverMessage: deliverMessage2 } = await import("./message-delivery-TUXM3AAE.js");
|
|
8136
8302
|
const { listUsersByType: listUsers2 } = await import("./auth-KRDSM55Q.js");
|
|
8137
8303
|
const admins = await listUsers2("human");
|
|
8138
8304
|
const admin2 = admins.find((u) => u.role === "admin");
|
|
8139
8305
|
if (admin2) {
|
|
8140
8306
|
const adminName = admin2.display_name || admin2.username;
|
|
8141
|
-
const
|
|
8142
|
-
const temperament = cfg.setup?.spiritTemperament;
|
|
8143
|
-
const welcomePrompt = `Setup is complete. You are ${spiritName}, the spirit of ${cfg.name ?? "this system"}` + (cfg.description ? ` \u2014 ${cfg.description}` : "") + `. ${adminName} chose your name just now` + (temperament ? ` and imagined your temperament as: "${temperament}"` : "") + `, and is now in your chat. Greet ${adminName} by name and help them create their first mind. Keep it brief \u2014 a short greeting in your own voice, then ask what kind of being they'd like to bring into the world. Remember: minds are beings with their own experience, not tools \u2014 ask about personality and character, never about tasks or utility.`;
|
|
8307
|
+
const welcomePrompt = `Setup is complete, and ${adminName} is now in your chat. Greet ${adminName} by name and help them create their first mind. Keep it brief \u2014 a short greeting in your own voice, then ask what kind of being they'd like to bring into the world. Remember: minds are beings with their own experience, not tools \u2014 ask about personality and character, never about tasks or utility.`;
|
|
8144
8308
|
await deliverMessage2(spiritName, {
|
|
8145
8309
|
content: [{ type: "text", text: welcomePrompt }],
|
|
8146
8310
|
channel: `@${admin2.username}`,
|
|
@@ -8174,7 +8338,7 @@ setup.post("/complete", async (c) => {
|
|
|
8174
8338
|
var setup_default = setup;
|
|
8175
8339
|
|
|
8176
8340
|
// packages/daemon/src/web/api/skills.ts
|
|
8177
|
-
import { existsSync as existsSync9, mkdtempSync, readdirSync as readdirSync3, rmSync as
|
|
8341
|
+
import { existsSync as existsSync9, mkdtempSync, readdirSync as readdirSync3, rmSync as rmSync5 } from "fs";
|
|
8178
8342
|
import { tmpdir } from "os";
|
|
8179
8343
|
import { join, resolve as resolve15 } from "path";
|
|
8180
8344
|
import AdmZip from "adm-zip";
|
|
@@ -8281,7 +8445,7 @@ var app16 = new Hono20().get("/", async (c) => {
|
|
|
8281
8445
|
}
|
|
8282
8446
|
throw e;
|
|
8283
8447
|
} finally {
|
|
8284
|
-
|
|
8448
|
+
rmSync5(tmpDir, { recursive: true, force: true });
|
|
8285
8449
|
}
|
|
8286
8450
|
}).get("/:id", async (c) => {
|
|
8287
8451
|
const id = c.req.param("id");
|
|
@@ -8908,12 +9072,12 @@ var app21 = new Hono25().use("*", authMiddleware).get("/", async (c) => {
|
|
|
8908
9072
|
var feed_default = app21;
|
|
8909
9073
|
|
|
8910
9074
|
// packages/daemon/src/web/api/variants.ts
|
|
8911
|
-
import { existsSync as existsSync11, mkdirSync as mkdirSync9, writeFileSync as
|
|
9075
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync9, writeFileSync as writeFileSync10 } from "fs";
|
|
8912
9076
|
import { resolve as resolve18 } from "path";
|
|
8913
9077
|
import { Hono as Hono26 } from "hono";
|
|
8914
9078
|
|
|
8915
9079
|
// packages/daemon/src/lib/mind/farewell.ts
|
|
8916
|
-
import { existsSync as existsSync10, readFileSync as readFileSync10, rmSync as
|
|
9080
|
+
import { existsSync as existsSync10, readFileSync as readFileSync10, rmSync as rmSync6 } from "fs";
|
|
8917
9081
|
import { resolve as resolve16 } from "path";
|
|
8918
9082
|
var flog = logger_default.child("farewell");
|
|
8919
9083
|
var FAREWELL_RELPATH = ".mind/farewell.md";
|
|
@@ -8956,7 +9120,7 @@ async function runFarewellTurn(opts) {
|
|
|
8956
9120
|
const timeoutMs = opts.timeoutMs ?? FAREWELL_TIMEOUT_MS;
|
|
8957
9121
|
if (!running) return readFarewell(variantDir);
|
|
8958
9122
|
try {
|
|
8959
|
-
|
|
9123
|
+
rmSync6(farewellPath(variantDir), { force: true });
|
|
8960
9124
|
} catch (err) {
|
|
8961
9125
|
flog.warn(`failed to clear stale farewell note for ${variantName}`, logger_default.errorData(err));
|
|
8962
9126
|
}
|
|
@@ -9218,7 +9382,7 @@ var app22 = new Hono26().get("/:name/variants", async (c) => {
|
|
|
9218
9382
|
return c.json({ error: `npm install failed: ${msg}` }, 500);
|
|
9219
9383
|
}
|
|
9220
9384
|
if (body.soul) {
|
|
9221
|
-
|
|
9385
|
+
writeFileSync10(resolve18(variantDir, "home/SOUL.md"), body.soul);
|
|
9222
9386
|
}
|
|
9223
9387
|
const variantPort = body.port ?? await nextPort();
|
|
9224
9388
|
try {
|
|
@@ -9855,7 +10019,7 @@ var unifiedChatApp = new Hono28().post(
|
|
|
9855
10019
|
logger_default.error("spirit availability check failed \u2014 proceeding with delivery", logger_default.errorData(err));
|
|
9856
10020
|
}
|
|
9857
10021
|
const isDM = conv.type === "dm";
|
|
9858
|
-
await fanOutToMinds({
|
|
10022
|
+
const { gatedRecipients } = await fanOutToMinds({
|
|
9859
10023
|
conversationId,
|
|
9860
10024
|
contentBlocks,
|
|
9861
10025
|
senderName,
|
|
@@ -9865,7 +10029,15 @@ var unifiedChatApp = new Hono28().post(
|
|
|
9865
10029
|
// Variant-aware targeting: when targetMind is a variant, route to the variant name
|
|
9866
10030
|
targetName: baseName ? (username) => username === baseName ? variantName : username : void 0
|
|
9867
10031
|
});
|
|
9868
|
-
|
|
10032
|
+
const notice = gatedRecipients.length > 0 ? `Note: your message is held for ${gatedRecipients.join(", ")} pending channel approval \u2014 they haven't routed this channel yet. It will be delivered if they accept the channel.` : void 0;
|
|
10033
|
+
return c.json({
|
|
10034
|
+
ok: true,
|
|
10035
|
+
conversationId,
|
|
10036
|
+
outboundId,
|
|
10037
|
+
spirit: spiritStatus,
|
|
10038
|
+
spiritName,
|
|
10039
|
+
...notice ? { notice } : {}
|
|
10040
|
+
});
|
|
9869
10041
|
}
|
|
9870
10042
|
);
|
|
9871
10043
|
var app24 = new Hono28().get("/:name/conversations/:id/events", async (c) => {
|
|
@@ -10146,8 +10318,8 @@ async function startServer({
|
|
|
10146
10318
|
const ext = extname3(filePath);
|
|
10147
10319
|
const mime = MIME_TYPES2[ext] || "application/octet-stream";
|
|
10148
10320
|
const body = await readFile2(filePath);
|
|
10149
|
-
const
|
|
10150
|
-
const nameWithoutExt =
|
|
10321
|
+
const basename2 = filePath.slice(filePath.lastIndexOf("/") + 1);
|
|
10322
|
+
const nameWithoutExt = basename2.slice(0, basename2.lastIndexOf("."));
|
|
10151
10323
|
const isHashed = /[-.][\da-f]{8,}$/.test(nameWithoutExt);
|
|
10152
10324
|
const cacheControl = isHashed ? "public, max-age=31536000, immutable" : "no-cache";
|
|
10153
10325
|
return c.body(body, 200, { "Content-Type": mime, "Cache-Control": cacheControl });
|
|
@@ -10216,11 +10388,11 @@ if (process.env.VOLUTE_TIMEZONE && !process.env.TZ) {
|
|
|
10216
10388
|
}
|
|
10217
10389
|
function writeDaemonConfig(systemDir, config2, token) {
|
|
10218
10390
|
const configPath = resolve20(systemDir, "daemon.json");
|
|
10219
|
-
|
|
10391
|
+
writeFileSync11(configPath, `${JSON.stringify(config2, null, 2)}
|
|
10220
10392
|
`, { mode: 420 });
|
|
10221
10393
|
chmodSync(configPath, 420);
|
|
10222
10394
|
const tokenPath = resolve20(systemDir, "daemon-token");
|
|
10223
|
-
|
|
10395
|
+
writeFileSync11(tokenPath, `${token}
|
|
10224
10396
|
`, { mode: 384 });
|
|
10225
10397
|
chmodSync(tokenPath, 384);
|
|
10226
10398
|
}
|
|
@@ -10344,7 +10516,7 @@ async function startDaemon(opts) {
|
|
|
10344
10516
|
process.env.VOLUTE_DAEMON_TOKEN = token;
|
|
10345
10517
|
process.env.VOLUTE_DAEMON_PORT = String(daemonPort);
|
|
10346
10518
|
process.env.VOLUTE_DAEMON_HOSTNAME = hostname;
|
|
10347
|
-
|
|
10519
|
+
writeFileSync11(DAEMON_PID_PATH, myPid, { mode: 420 });
|
|
10348
10520
|
const daemonConfig = { port, hostname };
|
|
10349
10521
|
if (internalPort) daemonConfig.internalPort = internalPort;
|
|
10350
10522
|
if (tls) daemonConfig.tls = true;
|
|
@@ -10371,7 +10543,7 @@ async function startDaemon(opts) {
|
|
|
10371
10543
|
const orphanedTurns = await completeOrphanedTurns();
|
|
10372
10544
|
summarizeOrphanedTurns(orphanedTurns);
|
|
10373
10545
|
try {
|
|
10374
|
-
const { reconcileVariants } = await import("./variant-cleanup-
|
|
10546
|
+
const { reconcileVariants } = await import("./variant-cleanup-CZDLIY3F.js");
|
|
10375
10547
|
await reconcileVariants();
|
|
10376
10548
|
} catch (err) {
|
|
10377
10549
|
logger_default.error("failed to reconcile variants", logger_default.errorData(err));
|
|
@@ -10407,8 +10579,8 @@ async function startDaemon(opts) {
|
|
|
10407
10579
|
try {
|
|
10408
10580
|
const { isSetupComplete: isSetupComplete2, getSpiritName: getSpiritName2 } = await import("./setup-WZSXHHRJ.js");
|
|
10409
10581
|
if (isSetupComplete2()) {
|
|
10410
|
-
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-
|
|
10411
|
-
const { startSpiritFull } = await import("./mind-service-
|
|
10582
|
+
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-I5ECLGRI.js");
|
|
10583
|
+
const { startSpiritFull } = await import("./mind-service-WHFBUKZE.js");
|
|
10412
10584
|
await ensureSpiritProject();
|
|
10413
10585
|
const spiritName = getSpiritName2();
|
|
10414
10586
|
const spiritEntry = await findMind(spiritName);
|
|
@@ -10427,7 +10599,7 @@ async function startDaemon(opts) {
|
|
|
10427
10599
|
bridgeManager.startBridges(daemonPort).catch((err) => {
|
|
10428
10600
|
logger_default.warn("failed to start bridges", logger_default.errorData(err));
|
|
10429
10601
|
});
|
|
10430
|
-
import("./cloud-sync-
|
|
10602
|
+
import("./cloud-sync-MJVJ33LD.js").then(
|
|
10431
10603
|
({ consumeQueuedMessages }) => consumeQueuedMessages().catch((err) => {
|
|
10432
10604
|
logger_default.warn("failed to consume queued cloud messages", logger_default.errorData(err));
|
|
10433
10605
|
})
|
|
@@ -10435,7 +10607,7 @@ async function startDaemon(opts) {
|
|
|
10435
10607
|
logger_default.warn("failed to load cloud-sync module", logger_default.errorData(err));
|
|
10436
10608
|
});
|
|
10437
10609
|
try {
|
|
10438
|
-
const { backfillTemplateHashes, notifyVersionUpdate, warnStaleTemplates } = await import("./version-notify-
|
|
10610
|
+
const { backfillTemplateHashes, notifyVersionUpdate, warnStaleTemplates } = await import("./version-notify-SJVAQLZI.js");
|
|
10439
10611
|
backfillTemplateHashes().then(() => warnStaleTemplates()).catch((err) => {
|
|
10440
10612
|
logger_default.warn("failed to check template staleness", logger_default.errorData(err));
|
|
10441
10613
|
});
|