volute 0.42.1 → 0.43.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/{activity-events-KFKVRZE3.js → activity-events-UISXY4Y5.js} +3 -3
- package/dist/{ai-service-3GBOJGUA.js → ai-service-FBCCEYF5.js} +8 -4
- package/dist/{archive-4PPYF7LL.js → archive-I32WHCJB.js} +3 -3
- package/dist/{auth-EAASQPTN.js → auth-3RIG6GKN.js} +4 -4
- package/dist/{chat-LYL5CWJV.js → chat-SDSX5TVV.js} +2 -2
- package/dist/{chunk-M2YMNTHK.js → chunk-2HIVYZDB.js} +1 -1
- package/dist/{chunk-BWZHX46O.js → chunk-3WLWKOGM.js} +21 -6
- package/dist/{chunk-QPTQKGGF.js → chunk-57LBQ7JX.js} +1 -1
- package/dist/{chunk-43K5UWF7.js → chunk-65OLHBCL.js} +13 -12
- package/dist/{chunk-K547QOCM.js → chunk-7G2EEYXX.js} +2 -2
- package/dist/{chunk-E7XWFDZL.js → chunk-AD46AYZQ.js} +1 -1
- package/dist/{chunk-P6DPB33N.js → chunk-ATEX3ZPG.js} +2 -2
- package/dist/{chunk-WR7CSHQ4.js → chunk-C6ESRQZ7.js} +1 -1
- package/dist/{chunk-BR6KFHVT.js → chunk-EE7SZJON.js} +2 -2
- package/dist/{chunk-5QG36RV7.js → chunk-EFL5UOY4.js} +3 -3
- package/dist/{chunk-M3T3Y6FT.js → chunk-FSSUANZJ.js} +5 -5
- package/dist/{chunk-JPDN6ZRJ.js → chunk-FZ5TH5PF.js} +8 -8
- package/dist/{chunk-OEJFZHZZ.js → chunk-GZJFC76M.js} +1 -1
- package/dist/{chunk-KUJVCDWT.js → chunk-JVK6QQIC.js} +2 -2
- package/dist/{chunk-YLTIEEVL.js → chunk-K4EHBHPE.js} +3 -3
- package/dist/{chunk-MHFAWJCC.js → chunk-L3IV23ZG.js} +12 -1
- package/dist/{chunk-VBKRZCR7.js → chunk-M3PGGSBH.js} +1 -1
- package/dist/{chunk-NSGIVS5T.js → chunk-O3DXAR44.js} +2 -2
- package/dist/{chunk-KZAL7HEQ.js → chunk-ONM2AZFL.js} +1 -1
- package/dist/{chunk-6G7R2LPI.js → chunk-PF2AB7VJ.js} +568 -378
- package/dist/chunk-PGPLCJPK.js +272 -0
- package/dist/{chunk-62ICA2FF.js → chunk-SPLPKBES.js} +17 -1
- package/dist/{chunk-BLOAJLGI.js → chunk-XDTKJNW5.js} +1 -1
- package/dist/{chunk-IUZ3EV2D.js → chunk-YAMO2U3N.js} +1 -1
- package/dist/{chunk-4ZSUUBG5.js → chunk-YSV3VJQK.js} +55 -2
- package/dist/{chunk-JU5GWO77.js → chunk-ZO7IQJKO.js} +3 -3
- package/dist/cli.js +15 -15
- package/dist/{cloud-sync-E3ZL5SZ4.js → cloud-sync-FRYNWKCR.js} +16 -17
- package/dist/{conversations-FSZCUUYO.js → conversations-67WWW25C.js} +4 -4
- package/dist/{create-ERNQYOCK.js → create-7W3LV3J7.js} +1 -1
- package/dist/{daemon-restart-QBZOMILO.js → daemon-restart-5GVZ5V3X.js} +7 -8
- package/dist/daemon.js +524 -433
- package/dist/{db-ZJJJYJBU.js → db-CZV62BOQ.js} +2 -2
- package/dist/delivery-manager-5J2BE22P.js +32 -0
- package/dist/{delivery-router-FDBZJQOY.js → delivery-router-HXBHYHJM.js} +7 -5
- package/dist/down-RRNYIGCU.js +16 -0
- package/dist/echo-text-XKBJM6RV.js +32 -0
- package/dist/{exec-ZDD7NEB4.js → exec-SJK7VUTC.js} +3 -4
- package/dist/{export-WYI3E3TB.js → export-7LPCIB5J.js} +3 -3
- package/dist/{extensions-X6MKBJLB.js → extensions-76EGTMFY.js} +16 -17
- package/dist/{files-COTCVBGO.js → files-LV7VAKPC.js} +3 -3
- package/dist/{import-EPK6WCYS.js → import-XPECCRQ7.js} +6 -6
- package/dist/{isolation-F7ABZMDA.js → isolation-5AYEY55P.js} +5 -3
- package/dist/{login-GPBXOU4D.js → login-KJSN4JDA.js} +2 -2
- package/dist/{logout-DNNTIYE2.js → logout-TMJGUQV2.js} +2 -2
- package/dist/message-delivery-WJBZFALY.js +34 -0
- package/dist/{mind-K5PZHPBR.js → mind-QEWCR7FA.js} +5 -5
- package/dist/{mind-activity-tracker-HWVFE533.js → mind-activity-tracker-JHAT6456.js} +4 -4
- package/dist/mind-service-ZBVUMJ5H.js +36 -0
- package/dist/{package-G4AM2IDZ.js → package-ZOI2KAYC.js} +1 -1
- package/dist/{registry-MDLNPTTI.js → registry-7LQHTRUX.js} +2 -2
- package/dist/{sandbox-E7RWZDVG.js → sandbox-SJH3XOPZ.js} +4 -4
- package/dist/scheduler-BR6C6B3E.js +30 -0
- package/dist/{schema-HHYJDG7B.js → schema-LRUTFOER.js} +1 -1
- package/dist/{seed-SKVSWF7S.js → seed-KOG6KJAO.js} +1 -1
- package/dist/{seed-cmd-D2H5VLB4.js → seed-cmd-GJFENEJH.js} +2 -2
- package/dist/{seed-create-BUSKQ5II.js → seed-create-YXO6R4KE.js} +3 -3
- package/dist/{seed-sprout-R2IZPITD.js → seed-sprout-BBU64QXP.js} +7 -8
- package/dist/{send-SLDFRSTL.js → send-ZBZWIH5V.js} +3 -3
- package/dist/{service-ZDOSEQCE.js → service-4EVZKGSA.js} +4 -5
- package/dist/{service-install-2HZPDHEY.js → service-install-SHRM6NHK.js} +5 -6
- package/dist/{setup-IYOUPCIK.js → setup-25MMJ3J4.js} +3 -3
- package/dist/{setup-IU3ID7II.js → setup-354PDHUF.js} +8 -10
- package/dist/{skills-P6RGGASV.js → skills-DPI3WZPQ.js} +5 -6
- package/dist/sleep-manager-BVU5D2AE.js +34 -0
- package/dist/{spirit-XLD6QXSS.js → spirit-JQQHUVWR.js} +7 -8
- package/dist/{sprout-QV2RJM5W.js → sprout-4WAYBUVV.js} +1 -1
- package/dist/{status-QAKAPDYW.js → status-WTU2WHXY.js} +5 -6
- package/dist/system-chat-KMQIP7VH.js +34 -0
- package/dist/{tailscale-TIRTGM6E.js → tailscale-Q7ZJL7S7.js} +2 -2
- package/dist/{turn-tracker-Z5UJC4BY.js → turn-tracker-2GMKJQTN.js} +7 -5
- package/dist/up-7RSBEKW6.js +18 -0
- package/dist/{update-NY3XBVAJ.js → update-EJ7Q77ZX.js} +5 -6
- package/dist/{update-check-OG27AL4Z.js → update-check-ACYYNKTW.js} +3 -3
- package/dist/{version-notify-P7UAR7HZ.js → version-notify-DCAIXXZB.js} +17 -18
- package/dist/web-assets/assets/{index-CrFAsfiE.js → index-DTDmEfPU.js} +2 -2
- package/dist/web-assets/index.html +1 -1
- package/drizzle/0010_delivery_queue_redrive.sql +10 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +1 -1
- package/templates/codex/src/server.ts +2 -8
- package/dist/chunk-GN52E2DP.js +0 -59
- package/dist/chunk-TFBQESH7.js +0 -179
- package/dist/delivery-manager-J3BRHXUF.js +0 -33
- package/dist/down-DSRWSCXY.js +0 -17
- package/dist/echo-text-3HBQUWPX.js +0 -33
- package/dist/message-delivery-4ZWFDBAY.js +0 -41
- package/dist/mind-manager-6DSY5IJW.js +0 -33
- package/dist/mind-service-R2FM53KD.js +0 -37
- package/dist/scheduler-2FKQCRCM.js +0 -31
- package/dist/sleep-manager-F5KWIFOX.js +0 -35
- package/dist/system-chat-EQIH6JVL.js +0 -35
- package/dist/up-ZTPGC7HB.js +0 -19
package/dist/daemon.js
CHANGED
|
@@ -6,21 +6,21 @@ import {
|
|
|
6
6
|
rejectPending,
|
|
7
7
|
stageFile,
|
|
8
8
|
validateFilePath
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-2HIVYZDB.js";
|
|
10
10
|
import {
|
|
11
11
|
findOpenClawSession,
|
|
12
12
|
importOpenClawConnectors,
|
|
13
13
|
importPiSession,
|
|
14
14
|
parseNameFromIdentity
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-JVK6QQIC.js";
|
|
16
16
|
import {
|
|
17
17
|
checkForUpdate,
|
|
18
18
|
checkForUpdateCached,
|
|
19
19
|
getCurrentVersion
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-AD46AYZQ.js";
|
|
21
21
|
import {
|
|
22
22
|
isHomeOnlyArchive
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-GZJFC76M.js";
|
|
24
24
|
import {
|
|
25
25
|
computeTemplateHash
|
|
26
26
|
} from "./chunk-QMJCNZ6C.js";
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
fixModelEscapes,
|
|
31
31
|
getPlatformDriver,
|
|
32
32
|
routeOutboundBridge
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-FZ5TH5PF.js";
|
|
34
34
|
import {
|
|
35
35
|
getBridgeConfig,
|
|
36
36
|
readBridgesConfig,
|
|
@@ -39,13 +39,15 @@ import {
|
|
|
39
39
|
resolveChannelMapping,
|
|
40
40
|
setBridgeConfig,
|
|
41
41
|
setChannelMapping
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-57LBQ7JX.js";
|
|
43
43
|
import {
|
|
44
|
+
MindStartupError,
|
|
44
45
|
RestartTracker,
|
|
45
46
|
RotatingLog,
|
|
46
47
|
SESSION_MAX_AGE,
|
|
47
48
|
announceToSystem,
|
|
48
49
|
authMiddleware,
|
|
50
|
+
checkHealth,
|
|
49
51
|
cleanExpiredSessions,
|
|
50
52
|
clearDeliveredNotices,
|
|
51
53
|
createSession,
|
|
@@ -94,19 +96,17 @@ import {
|
|
|
94
96
|
startMindFull,
|
|
95
97
|
stopMindFull,
|
|
96
98
|
syncProviderToMinds,
|
|
97
|
-
tagUntaggedInbound,
|
|
98
|
-
tagUntaggedOutbound,
|
|
99
99
|
uninstallNpmExtension,
|
|
100
100
|
writeSystemsConfig
|
|
101
|
-
} from "./chunk-
|
|
101
|
+
} from "./chunk-PF2AB7VJ.js";
|
|
102
102
|
import {
|
|
103
103
|
loadMergedEnv,
|
|
104
104
|
mindEnvPath,
|
|
105
105
|
readEnv,
|
|
106
106
|
sharedEnvPath,
|
|
107
107
|
writeEnv
|
|
108
|
-
} from "./chunk-
|
|
109
|
-
import "./chunk-
|
|
108
|
+
} from "./chunk-XDTKJNW5.js";
|
|
109
|
+
import "./chunk-65OLHBCL.js";
|
|
110
110
|
import {
|
|
111
111
|
applyInitFiles,
|
|
112
112
|
applyTemplateHomeFiles,
|
|
@@ -135,7 +135,7 @@ import {
|
|
|
135
135
|
syncBuiltinSkills,
|
|
136
136
|
uninstallSkill,
|
|
137
137
|
updateSkill
|
|
138
|
-
} from "./chunk-
|
|
138
|
+
} from "./chunk-FSSUANZJ.js";
|
|
139
139
|
import {
|
|
140
140
|
addMessage,
|
|
141
141
|
createChannel,
|
|
@@ -167,7 +167,7 @@ import {
|
|
|
167
167
|
setConversationPrivate,
|
|
168
168
|
subscribe as subscribe2,
|
|
169
169
|
updateChannelSettings
|
|
170
|
-
} from "./chunk-
|
|
170
|
+
} from "./chunk-K4EHBHPE.js";
|
|
171
171
|
import {
|
|
172
172
|
readVoluteConfig,
|
|
173
173
|
writeVoluteConfig
|
|
@@ -175,15 +175,15 @@ import {
|
|
|
175
175
|
import {
|
|
176
176
|
isSandboxEnabled,
|
|
177
177
|
wrapForSandbox
|
|
178
|
-
} from "./chunk-
|
|
178
|
+
} from "./chunk-C6ESRQZ7.js";
|
|
179
179
|
import {
|
|
180
180
|
getActiveMinds,
|
|
181
181
|
onMindEvent,
|
|
182
182
|
stopAll
|
|
183
|
-
} from "./chunk-
|
|
183
|
+
} from "./chunk-M3PGGSBH.js";
|
|
184
184
|
import {
|
|
185
185
|
extractTextContent
|
|
186
|
-
} from "./chunk-
|
|
186
|
+
} from "./chunk-SPLPKBES.js";
|
|
187
187
|
import {
|
|
188
188
|
PROMPT_DEFAULTS,
|
|
189
189
|
PROMPT_KEYS,
|
|
@@ -206,21 +206,19 @@ import {
|
|
|
206
206
|
summarizeTurn,
|
|
207
207
|
takeErrored,
|
|
208
208
|
trackToolUse
|
|
209
|
-
} from "./chunk-
|
|
210
|
-
import "./chunk-
|
|
211
|
-
import {
|
|
212
|
-
exec,
|
|
213
|
-
gitExec,
|
|
214
|
-
resolveVoluteBin
|
|
215
|
-
} from "./chunk-GN52E2DP.js";
|
|
209
|
+
} from "./chunk-3WLWKOGM.js";
|
|
210
|
+
import "./chunk-ATEX3ZPG.js";
|
|
216
211
|
import {
|
|
217
212
|
chownMindDir,
|
|
218
213
|
createMindUser,
|
|
219
214
|
deleteMindUser,
|
|
220
215
|
ensureVoluteGroup,
|
|
216
|
+
exec,
|
|
217
|
+
gitExec,
|
|
221
218
|
isIsolationEnabled,
|
|
219
|
+
resolveVoluteBin,
|
|
222
220
|
wrapForIsolation
|
|
223
|
-
} from "./chunk-
|
|
221
|
+
} from "./chunk-PGPLCJPK.js";
|
|
224
222
|
import {
|
|
225
223
|
addCustomModel,
|
|
226
224
|
buildCustomModel,
|
|
@@ -241,12 +239,12 @@ import {
|
|
|
241
239
|
setProviderRefreshHook,
|
|
242
240
|
setUtilityModel,
|
|
243
241
|
unqualifyModelId
|
|
244
|
-
} from "./chunk-
|
|
242
|
+
} from "./chunk-YSV3VJQK.js";
|
|
245
243
|
import {
|
|
246
244
|
isSetupComplete,
|
|
247
245
|
readGlobalConfig,
|
|
248
246
|
writeGlobalConfig
|
|
249
|
-
} from "./chunk-
|
|
247
|
+
} from "./chunk-ONM2AZFL.js";
|
|
250
248
|
import {
|
|
251
249
|
approveUser,
|
|
252
250
|
changePassword,
|
|
@@ -265,11 +263,11 @@ import {
|
|
|
265
263
|
syncMindProfile,
|
|
266
264
|
updateUserProfile,
|
|
267
265
|
verifyUser
|
|
268
|
-
} from "./chunk-
|
|
266
|
+
} from "./chunk-EFL5UOY4.js";
|
|
269
267
|
import {
|
|
270
268
|
broadcast,
|
|
271
269
|
subscribe
|
|
272
|
-
} from "./chunk-
|
|
270
|
+
} from "./chunk-7G2EEYXX.js";
|
|
273
271
|
import {
|
|
274
272
|
logBuffer,
|
|
275
273
|
logger_default
|
|
@@ -301,7 +299,7 @@ import {
|
|
|
301
299
|
validateMindName,
|
|
302
300
|
voluteHome,
|
|
303
301
|
voluteSystemDir
|
|
304
|
-
} from "./chunk-
|
|
302
|
+
} from "./chunk-YAMO2U3N.js";
|
|
305
303
|
import {
|
|
306
304
|
activity,
|
|
307
305
|
channels,
|
|
@@ -312,11 +310,11 @@ import {
|
|
|
312
310
|
systemPrompts,
|
|
313
311
|
turns,
|
|
314
312
|
users
|
|
315
|
-
} from "./chunk-
|
|
313
|
+
} from "./chunk-L3IV23ZG.js";
|
|
316
314
|
import "./chunk-K3NQKI34.js";
|
|
317
315
|
|
|
318
316
|
// packages/daemon/src/daemon.ts
|
|
319
|
-
import { randomBytes } from "crypto";
|
|
317
|
+
import { randomBytes as randomBytes2 } from "crypto";
|
|
320
318
|
import { chmodSync, mkdirSync as mkdirSync10, readFileSync as readFileSync10, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "fs";
|
|
321
319
|
import { homedir as homedir3 } from "os";
|
|
322
320
|
import { resolve as resolve17 } from "path";
|
|
@@ -1105,17 +1103,21 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1105
1103
|
}).get("/ai/models", requireAdmin, async (c) => {
|
|
1106
1104
|
const models = await getAvailableModels();
|
|
1107
1105
|
const enabled = new Set(getEnabledModels());
|
|
1108
|
-
const customIds = new Set(getCustomModels().map((m) => m.id));
|
|
1106
|
+
const customIds = new Set(getCustomModels().map((m) => `${m.provider}:${m.id}`));
|
|
1109
1107
|
return c.json(
|
|
1110
|
-
models.map((m) =>
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1108
|
+
models.map((m) => {
|
|
1109
|
+
const qualifiedId = `${m.provider}:${m.id}`;
|
|
1110
|
+
return {
|
|
1111
|
+
id: m.id,
|
|
1112
|
+
qualifiedId,
|
|
1113
|
+
name: m.name,
|
|
1114
|
+
provider: m.provider,
|
|
1115
|
+
contextWindow: m.contextWindow,
|
|
1116
|
+
maxTokens: m.maxTokens,
|
|
1117
|
+
enabled: enabled.has(qualifiedId),
|
|
1118
|
+
custom: customIds.has(qualifiedId)
|
|
1119
|
+
};
|
|
1120
|
+
})
|
|
1119
1121
|
);
|
|
1120
1122
|
}).put(
|
|
1121
1123
|
"/ai/models",
|
|
@@ -1141,14 +1143,8 @@ var app = new Hono().post("/restart", requireAdmin, (c) => {
|
|
|
1141
1143
|
400
|
|
1142
1144
|
);
|
|
1143
1145
|
}
|
|
1144
|
-
if (getCustomModels().some((m) => m.id === id && m.provider !== provider)) {
|
|
1145
|
-
return c.json(
|
|
1146
|
-
{ error: `A custom model "${id}" is already registered under another provider` },
|
|
1147
|
-
400
|
|
1148
|
-
);
|
|
1149
|
-
}
|
|
1150
1146
|
addCustomModel(provider, id, name);
|
|
1151
|
-
setEnabledModels([.../* @__PURE__ */ new Set([...getEnabledModels(), id])]);
|
|
1147
|
+
setEnabledModels([.../* @__PURE__ */ new Set([...getEnabledModels(), `${provider}:${id}`])]);
|
|
1152
1148
|
return c.json({ ok: true });
|
|
1153
1149
|
}
|
|
1154
1150
|
).delete("/ai/models/custom", requireAdmin, (c) => {
|
|
@@ -1850,6 +1846,76 @@ async function findOrCreatePuppet(platform, platformId, displayName) {
|
|
|
1850
1846
|
}
|
|
1851
1847
|
}
|
|
1852
1848
|
|
|
1849
|
+
// packages/daemon/src/lib/delivery/fan-out.ts
|
|
1850
|
+
var MAX_CONSECUTIVE_MIND_TURNS = 6;
|
|
1851
|
+
var consecutiveMindTurns = /* @__PURE__ */ new Map();
|
|
1852
|
+
async function emitLoopNotice(conversationId) {
|
|
1853
|
+
const systemUser = await getOrCreateSystemUser();
|
|
1854
|
+
await addMessage(conversationId, "user", systemUser.username, [
|
|
1855
|
+
{
|
|
1856
|
+
type: "text",
|
|
1857
|
+
text: `[System] This exchange has continued for ${MAX_CONSECUTIVE_MIND_TURNS} consecutive automated turns without human input, so automatic delivery between minds has been paused. Send a message to resume.`
|
|
1858
|
+
}
|
|
1859
|
+
]);
|
|
1860
|
+
}
|
|
1861
|
+
async function fanOutToMinds(opts) {
|
|
1862
|
+
const participants = opts.participants ?? await getParticipants(opts.conversationId);
|
|
1863
|
+
const mindParticipants = participants.filter(
|
|
1864
|
+
(p) => p.userType === "mind" || p.userType === "system"
|
|
1865
|
+
);
|
|
1866
|
+
const participantNames = participants.map((p) => p.username);
|
|
1867
|
+
const isDM = opts.isDM ?? participants.length === 2;
|
|
1868
|
+
if (mindParticipants.length > 1) {
|
|
1869
|
+
if (opts.senderIsMind) {
|
|
1870
|
+
const count = (consecutiveMindTurns.get(opts.conversationId) ?? 0) + 1;
|
|
1871
|
+
consecutiveMindTurns.set(opts.conversationId, count);
|
|
1872
|
+
if (count > MAX_CONSECUTIVE_MIND_TURNS) {
|
|
1873
|
+
if (count === MAX_CONSECUTIVE_MIND_TURNS + 1) {
|
|
1874
|
+
await emitLoopNotice(opts.conversationId).catch(
|
|
1875
|
+
(err) => logger_default.warn(`failed to emit loop notice for ${opts.conversationId}`, logger_default.errorData(err))
|
|
1876
|
+
);
|
|
1877
|
+
}
|
|
1878
|
+
logger_default.warn(
|
|
1879
|
+
`loop protection: paused mind fan-out for ${opts.conversationId} after ${count} consecutive mind turns`
|
|
1880
|
+
);
|
|
1881
|
+
return;
|
|
1882
|
+
}
|
|
1883
|
+
} else {
|
|
1884
|
+
consecutiveMindTurns.delete(opts.conversationId);
|
|
1885
|
+
}
|
|
1886
|
+
}
|
|
1887
|
+
const manager = getMindManager();
|
|
1888
|
+
const sm = getSleepManagerIfReady();
|
|
1889
|
+
const targetMinds = mindParticipants.map((ap) => {
|
|
1890
|
+
const key = opts.targetName ? opts.targetName(ap.username) : ap.username;
|
|
1891
|
+
if (manager.isRunning(key) || sm?.isSleeping(ap.username)) return ap.username;
|
|
1892
|
+
return null;
|
|
1893
|
+
}).filter((n) => n !== null && n !== opts.senderName);
|
|
1894
|
+
for (const mindName of targetMinds) {
|
|
1895
|
+
const target = opts.targetName ? opts.targetName(mindName) : mindName;
|
|
1896
|
+
const channel = buildVoluteSlug({
|
|
1897
|
+
participants,
|
|
1898
|
+
mindUsername: mindName,
|
|
1899
|
+
conversationId: opts.conversationId,
|
|
1900
|
+
...opts.slugExtra
|
|
1901
|
+
});
|
|
1902
|
+
const typingMap = getTypingMap();
|
|
1903
|
+
const currentlyTyping = typingMap.get(channel).filter((name) => participantNames.includes(name));
|
|
1904
|
+
deliverMessage(target, {
|
|
1905
|
+
content: opts.contentBlocks,
|
|
1906
|
+
channel,
|
|
1907
|
+
conversationId: opts.conversationId,
|
|
1908
|
+
sender: opts.senderName,
|
|
1909
|
+
participants: participantNames,
|
|
1910
|
+
participantCount: participants.length,
|
|
1911
|
+
isDM,
|
|
1912
|
+
...currentlyTyping.length > 0 ? { typing: currentlyTyping } : {}
|
|
1913
|
+
}).catch((err) => {
|
|
1914
|
+
logger_default.warn(`fan-out delivery failed for ${target}`, logger_default.errorData(err));
|
|
1915
|
+
});
|
|
1916
|
+
}
|
|
1917
|
+
}
|
|
1918
|
+
|
|
1853
1919
|
// packages/daemon/src/web/api/bridges.ts
|
|
1854
1920
|
var inboundSchema = z3.object({
|
|
1855
1921
|
content: z3.array(
|
|
@@ -1923,7 +1989,7 @@ var app4 = new Hono4().post("/:platform/inbound", zValidator3("json", inboundSch
|
|
|
1923
1989
|
}
|
|
1924
1990
|
const participants = await getParticipants(channel.id);
|
|
1925
1991
|
if (!participants.some((p) => p.userId === puppet.id)) {
|
|
1926
|
-
const { addParticipant } = await import("./conversations-
|
|
1992
|
+
const { addParticipant } = await import("./conversations-67WWW25C.js");
|
|
1927
1993
|
await addParticipant(channel.id, puppet.id);
|
|
1928
1994
|
}
|
|
1929
1995
|
const contentBlocks = body.content;
|
|
@@ -2013,34 +2079,13 @@ var app4 = new Hono4().post("/:platform/inbound", zValidator3("json", inboundSch
|
|
|
2013
2079
|
return c.json(config2.channelMappings);
|
|
2014
2080
|
});
|
|
2015
2081
|
async function fanOutToBridgedMinds(opts) {
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
const targetMinds = mindParticipants.filter((ap) => {
|
|
2024
|
-
return (manager.isRunning(ap.username) || sm?.isSleeping(ap.username)) && ap.username !== opts.senderName;
|
|
2025
|
-
}).map((ap) => ap.username);
|
|
2026
|
-
for (const mindName of targetMinds) {
|
|
2027
|
-
const channel = buildVoluteSlug({
|
|
2028
|
-
participants,
|
|
2029
|
-
mindUsername: mindName,
|
|
2030
|
-
conversationId: opts.conversationId
|
|
2031
|
-
});
|
|
2032
|
-
deliverMessage(mindName, {
|
|
2033
|
-
content: opts.contentBlocks,
|
|
2034
|
-
channel,
|
|
2035
|
-
conversationId: opts.conversationId,
|
|
2036
|
-
sender: opts.senderName,
|
|
2037
|
-
participants: participantNames,
|
|
2038
|
-
participantCount: participants.length,
|
|
2039
|
-
isDM: opts.isDM
|
|
2040
|
-
}).catch((err) => {
|
|
2041
|
-
logger_default.warn(`bridge fan-out delivery failed for ${mindName}`, logger_default.errorData(err));
|
|
2042
|
-
});
|
|
2043
|
-
}
|
|
2082
|
+
await fanOutToMinds({
|
|
2083
|
+
conversationId: opts.conversationId,
|
|
2084
|
+
contentBlocks: opts.contentBlocks,
|
|
2085
|
+
senderName: opts.senderName,
|
|
2086
|
+
senderIsMind: false,
|
|
2087
|
+
isDM: opts.isDM
|
|
2088
|
+
});
|
|
2044
2089
|
}
|
|
2045
2090
|
var bridges_default = app4;
|
|
2046
2091
|
|
|
@@ -2083,7 +2128,7 @@ config.get("/models", async (c) => {
|
|
|
2083
2128
|
id: m.id,
|
|
2084
2129
|
name: m.name,
|
|
2085
2130
|
provider: m.provider,
|
|
2086
|
-
enabled: enabled.has(m.id)
|
|
2131
|
+
enabled: enabled.has(`${m.provider}:${m.id}`)
|
|
2087
2132
|
}));
|
|
2088
2133
|
return c.json(models);
|
|
2089
2134
|
});
|
|
@@ -2229,7 +2274,7 @@ async function notifyMind(mindName, message) {
|
|
|
2229
2274
|
const entry = await findMind(mindName);
|
|
2230
2275
|
if (!entry) return;
|
|
2231
2276
|
try {
|
|
2232
|
-
const { sendSystemMessage } = await import("./system-chat-
|
|
2277
|
+
const { sendSystemMessage } = await import("./system-chat-KMQIP7VH.js");
|
|
2233
2278
|
await sendSystemMessage(mindName, message);
|
|
2234
2279
|
} catch (err) {
|
|
2235
2280
|
logger_default.warn(`[file-sharing] notify mind ${mindName} failed`, logger_default.errorData(err));
|
|
@@ -3164,10 +3209,13 @@ import {
|
|
|
3164
3209
|
} from "fs";
|
|
3165
3210
|
import { basename, resolve as resolve11 } from "path";
|
|
3166
3211
|
import { zValidator as zValidator5 } from "@hono/zod-validator";
|
|
3167
|
-
import { and as
|
|
3212
|
+
import { and as and5, desc as desc4, eq as eq5, sql as sql3 } from "drizzle-orm";
|
|
3168
3213
|
import { Hono as Hono15 } from "hono";
|
|
3169
3214
|
import { z as z5 } from "zod";
|
|
3170
3215
|
|
|
3216
|
+
// packages/daemon/src/lib/daemon/turn-lifecycle.ts
|
|
3217
|
+
import { and as and4, desc as desc3, eq as eq4, inArray as inArray2, sql as sql2 } from "drizzle-orm";
|
|
3218
|
+
|
|
3171
3219
|
// packages/daemon/src/lib/daemon/error-classify.ts
|
|
3172
3220
|
function classify(raw) {
|
|
3173
3221
|
const s = (raw ?? "").toLowerCase();
|
|
@@ -3205,6 +3253,178 @@ function classify(raw) {
|
|
|
3205
3253
|
};
|
|
3206
3254
|
}
|
|
3207
3255
|
|
|
3256
|
+
// packages/daemon/src/lib/daemon/turn-lifecycle.ts
|
|
3257
|
+
var llog = logger_default.child("turn-lifecycle");
|
|
3258
|
+
var SUBSTANTIVE_TYPES = /* @__PURE__ */ new Set(["thinking", "text", "tool_use", "tool_result", "outbound"]);
|
|
3259
|
+
var MARKER_RE = /\[volute:(?:outbound|activity):\d+\]/g;
|
|
3260
|
+
var noticeDrainWatermarks = /* @__PURE__ */ new Map();
|
|
3261
|
+
function setNoticeDrainWatermark(mind, session, id) {
|
|
3262
|
+
noticeDrainWatermarks.set(`${mind}:${session}`, id);
|
|
3263
|
+
}
|
|
3264
|
+
function markDeliveredOnCleanTurn(mind, session) {
|
|
3265
|
+
if (!session) return;
|
|
3266
|
+
const wmKey = `${mind}:${session}`;
|
|
3267
|
+
const watermark = noticeDrainWatermarks.get(wmKey);
|
|
3268
|
+
noticeDrainWatermarks.delete(wmKey);
|
|
3269
|
+
const errored = takeErrored(mind, session);
|
|
3270
|
+
if (!errored && watermark != null) {
|
|
3271
|
+
clearDeliveredNotices(mind, session, watermark).catch(
|
|
3272
|
+
(err) => llog.warn(`failed to clear delivered notices for ${mind}:${session}`, logger_default.errorData(err))
|
|
3273
|
+
);
|
|
3274
|
+
}
|
|
3275
|
+
}
|
|
3276
|
+
async function linkPendingInbound(mind, turnId, channel) {
|
|
3277
|
+
if (!channel) return;
|
|
3278
|
+
const db = await getDb();
|
|
3279
|
+
const recent = await db.select({ id: mindHistory.id }).from(mindHistory).where(
|
|
3280
|
+
and4(
|
|
3281
|
+
eq4(mindHistory.mind, mind),
|
|
3282
|
+
eq4(mindHistory.type, "inbound"),
|
|
3283
|
+
sql2`${mindHistory.turn_id} IS NULL`,
|
|
3284
|
+
eq4(mindHistory.channel, channel)
|
|
3285
|
+
)
|
|
3286
|
+
).orderBy(desc3(mindHistory.id)).limit(5);
|
|
3287
|
+
if (recent.length === 0) return;
|
|
3288
|
+
const ids = recent.map((r) => r.id);
|
|
3289
|
+
await db.update(mindHistory).set({ turn_id: turnId }).where(inArray2(mindHistory.id, ids));
|
|
3290
|
+
await db.update(turns).set({ trigger_event_id: recent[0].id }).where(eq4(turns.id, turnId));
|
|
3291
|
+
}
|
|
3292
|
+
async function handleMindEvent(mind, event) {
|
|
3293
|
+
if (event.type === "session_start" && event.session) {
|
|
3294
|
+
const activeTurnId = getActiveTurnId(mind);
|
|
3295
|
+
if (activeTurnId) await assignSession(mind, activeTurnId, event.session);
|
|
3296
|
+
}
|
|
3297
|
+
let turnId = getActiveTurnId(mind, event.session);
|
|
3298
|
+
if (!turnId && SUBSTANTIVE_TYPES.has(event.type)) {
|
|
3299
|
+
turnId = await createTurn(mind);
|
|
3300
|
+
if (!turnId) {
|
|
3301
|
+
llog.warn(`skipping turn tracking for ${mind}: createTurn failed`);
|
|
3302
|
+
} else {
|
|
3303
|
+
publish2(mind, { mind, type: "turn_created", turnId });
|
|
3304
|
+
if (event.session) await assignSession(mind, turnId, event.session);
|
|
3305
|
+
try {
|
|
3306
|
+
await linkPendingInbound(mind, turnId, event.channel);
|
|
3307
|
+
} catch (err) {
|
|
3308
|
+
llog.warn(
|
|
3309
|
+
`failed to link trigger inbound for turn ${turnId} (mind: ${mind})`,
|
|
3310
|
+
logger_default.errorData(err)
|
|
3311
|
+
);
|
|
3312
|
+
}
|
|
3313
|
+
}
|
|
3314
|
+
}
|
|
3315
|
+
const cleanContent = event.type === "tool_result" && event.content ? event.content.replace(MARKER_RE, "").trimEnd() : event.content;
|
|
3316
|
+
const db = await getDb();
|
|
3317
|
+
let insertedId;
|
|
3318
|
+
try {
|
|
3319
|
+
const result = await db.insert(mindHistory).values({
|
|
3320
|
+
mind,
|
|
3321
|
+
type: event.type,
|
|
3322
|
+
session: event.session ?? null,
|
|
3323
|
+
channel: event.channel ?? null,
|
|
3324
|
+
message_id: event.messageId ?? null,
|
|
3325
|
+
content: cleanContent ?? null,
|
|
3326
|
+
metadata: event.metadata ? JSON.stringify(event.metadata) : null,
|
|
3327
|
+
turn_id: turnId ?? null
|
|
3328
|
+
}).returning({ id: mindHistory.id });
|
|
3329
|
+
insertedId = result[0]?.id;
|
|
3330
|
+
} catch (err) {
|
|
3331
|
+
llog.error(`failed to persist event for ${mind}`, logger_default.errorData(err));
|
|
3332
|
+
}
|
|
3333
|
+
if (event.type === "tool_use" && insertedId != null) {
|
|
3334
|
+
trackToolUse(mind, event.session, insertedId);
|
|
3335
|
+
}
|
|
3336
|
+
if (event.type === "tool_result" && turnId && event.content) {
|
|
3337
|
+
const toolUseEventId = getLastToolUseEventId(mind, event.session);
|
|
3338
|
+
try {
|
|
3339
|
+
await linkToolResultToTurn(mind, turnId, event.content, toolUseEventId);
|
|
3340
|
+
} catch (err) {
|
|
3341
|
+
llog.error("failed to link tool_result to turn", logger_default.errorData(err));
|
|
3342
|
+
}
|
|
3343
|
+
}
|
|
3344
|
+
publish2(mind, {
|
|
3345
|
+
mind,
|
|
3346
|
+
type: event.type,
|
|
3347
|
+
session: event.session,
|
|
3348
|
+
channel: event.channel,
|
|
3349
|
+
messageId: event.messageId,
|
|
3350
|
+
content: cleanContent,
|
|
3351
|
+
metadata: event.metadata,
|
|
3352
|
+
turnId: turnId ?? void 0
|
|
3353
|
+
});
|
|
3354
|
+
if (event.type === "text" && event.channel && cleanContent) {
|
|
3355
|
+
echoTextToChannel(mind, event.channel, cleanContent, turnId ?? void 0, insertedId).catch(
|
|
3356
|
+
(err) => llog.error(`echo-text failed for ${mind} on ${event.channel}`, logger_default.errorData(err))
|
|
3357
|
+
);
|
|
3358
|
+
}
|
|
3359
|
+
onMindEvent(mind, event.type, event.channel);
|
|
3360
|
+
if ((event.type === "text" || event.type === "outbound") && event.channel) {
|
|
3361
|
+
const map = getTypingMap();
|
|
3362
|
+
publishTypingForChannels(map.deleteSender(mind), map);
|
|
3363
|
+
}
|
|
3364
|
+
if (event.type === "error" && event.session) {
|
|
3365
|
+
markErrored(mind, event.session);
|
|
3366
|
+
const { reason, detail } = classify(event.content ?? "");
|
|
3367
|
+
await recordNotice({
|
|
3368
|
+
mind,
|
|
3369
|
+
session: event.session,
|
|
3370
|
+
kind: "turn_error",
|
|
3371
|
+
reason,
|
|
3372
|
+
detail,
|
|
3373
|
+
raw: event.content ?? null
|
|
3374
|
+
});
|
|
3375
|
+
}
|
|
3376
|
+
if (event.type === "done") {
|
|
3377
|
+
const map = getTypingMap();
|
|
3378
|
+
publishTypingForChannels(map.deleteSender(mind), map);
|
|
3379
|
+
broadcast({ type: "mind_done", mind, summary: "Finished processing" });
|
|
3380
|
+
try {
|
|
3381
|
+
getDeliveryManager().sessionDone(mind, event.session);
|
|
3382
|
+
} catch (err) {
|
|
3383
|
+
if (!(err instanceof Error && err.message.includes("not initialized"))) {
|
|
3384
|
+
llog.error(`delivery manager sessionDone failed for ${mind}`, logger_default.errorData(err));
|
|
3385
|
+
}
|
|
3386
|
+
}
|
|
3387
|
+
await completeTurnAndSummarize(mind, event, insertedId);
|
|
3388
|
+
}
|
|
3389
|
+
if (event.type === "usage" && event.metadata) {
|
|
3390
|
+
const inputTokens = event.metadata.input_tokens ?? 0;
|
|
3391
|
+
const outputTokens = event.metadata.output_tokens ?? 0;
|
|
3392
|
+
const tb = getTokenBudget();
|
|
3393
|
+
tb.recordUsage(mind, inputTokens, outputTokens);
|
|
3394
|
+
if (event.session && tb.noteExceeded(mind)) {
|
|
3395
|
+
void recordNotice({
|
|
3396
|
+
mind,
|
|
3397
|
+
session: event.session,
|
|
3398
|
+
kind: "budget",
|
|
3399
|
+
reason: "token_budget",
|
|
3400
|
+
detail: "You've reached your token budget for this period. Further activity may be paused until the budget resets \u2014 wrap up or prioritize accordingly."
|
|
3401
|
+
});
|
|
3402
|
+
}
|
|
3403
|
+
}
|
|
3404
|
+
return { turnId: turnId ?? void 0, insertedId };
|
|
3405
|
+
}
|
|
3406
|
+
async function completeTurnAndSummarize(mind, event, insertedId) {
|
|
3407
|
+
const finish = async () => {
|
|
3408
|
+
const completedTurnId = await completeTurn(mind, event.session);
|
|
3409
|
+
markDeliveredOnCleanTurn(mind, event.session);
|
|
3410
|
+
if (insertedId != null) {
|
|
3411
|
+
summarizeTurn(mind, event.session, event.channel, insertedId, completedTurnId).catch(
|
|
3412
|
+
(err) => llog.error("turn summarization failed", logger_default.errorData(err))
|
|
3413
|
+
);
|
|
3414
|
+
}
|
|
3415
|
+
};
|
|
3416
|
+
try {
|
|
3417
|
+
const dm = getDeliveryManager();
|
|
3418
|
+
const busy = event.session ? dm.isSessionBusy(mind, event.session) : false;
|
|
3419
|
+
if (!busy) await finish();
|
|
3420
|
+
} catch (err) {
|
|
3421
|
+
if (!(err instanceof Error && err.message.includes("not initialized"))) {
|
|
3422
|
+
llog.error("turn completion check failed", logger_default.errorData(err));
|
|
3423
|
+
}
|
|
3424
|
+
await finish();
|
|
3425
|
+
}
|
|
3426
|
+
}
|
|
3427
|
+
|
|
3208
3428
|
// packages/daemon/src/lib/mind/consolidate.ts
|
|
3209
3429
|
import { readdirSync, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
3210
3430
|
import { resolve as resolve9 } from "path";
|
|
@@ -3276,6 +3496,39 @@ ${content2}`);
|
|
|
3276
3496
|
}
|
|
3277
3497
|
}
|
|
3278
3498
|
|
|
3499
|
+
// packages/daemon/src/lib/mind/last-known-good.ts
|
|
3500
|
+
import { randomBytes } from "crypto";
|
|
3501
|
+
var glog = logger_default.child("last-known-good");
|
|
3502
|
+
async function hasSrcChanges(dir, mindName) {
|
|
3503
|
+
const status = (await gitExec(["status", "--porcelain", "--", "src"], { cwd: dir, mindName })).trim();
|
|
3504
|
+
return status.length > 0;
|
|
3505
|
+
}
|
|
3506
|
+
async function rollbackSrcChanges(dir, mindName) {
|
|
3507
|
+
if (!await hasSrcChanges(dir, mindName)) return { parked: false };
|
|
3508
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
3509
|
+
const branch = `broken/${ts}-${randomBytes(4).toString("hex")}`;
|
|
3510
|
+
const opts = { cwd: dir, mindName };
|
|
3511
|
+
await gitExec(["add", "--", "src"], opts);
|
|
3512
|
+
await gitExec(
|
|
3513
|
+
["commit", "--only", "-m", `Parked broken src changes (${branch})`, "--", "src"],
|
|
3514
|
+
opts
|
|
3515
|
+
);
|
|
3516
|
+
const brokenHash = (await gitExec(["rev-parse", "HEAD"], opts)).trim();
|
|
3517
|
+
await gitExec(["reset", "--mixed", "HEAD~1"], opts);
|
|
3518
|
+
await gitExec(["branch", branch, brokenHash], opts);
|
|
3519
|
+
await gitExec(["checkout", "--", "src"], opts);
|
|
3520
|
+
await gitExec(["clean", "-fdq", "--", "src"], opts);
|
|
3521
|
+
glog.info(`parked broken src changes on ${branch} (${dir})`);
|
|
3522
|
+
return { parked: true, branch };
|
|
3523
|
+
}
|
|
3524
|
+
async function commitSrcChanges(dir, mindName) {
|
|
3525
|
+
if (!await hasSrcChanges(dir, mindName)) return;
|
|
3526
|
+
const opts = { cwd: dir, mindName };
|
|
3527
|
+
await gitExec(["add", "--", "src"], opts);
|
|
3528
|
+
await gitExec(["commit", "--only", "-m", "Update src (self-edit)", "--", "src"], opts);
|
|
3529
|
+
glog.info(`committed known-good src changes (${dir})`);
|
|
3530
|
+
}
|
|
3531
|
+
|
|
3279
3532
|
// packages/daemon/src/lib/mind/variant-cleanup.ts
|
|
3280
3533
|
import { existsSync as existsSync6, rmSync as rmSync3 } from "fs";
|
|
3281
3534
|
async function cleanupVariant(variantName, projectRoot, variantPath, opts) {
|
|
@@ -3286,7 +3539,7 @@ async function cleanupVariant(variantName, projectRoot, variantPath, opts) {
|
|
|
3286
3539
|
logger_default.warn(`failed to stop variant ${variantName}`, logger_default.errorData(err));
|
|
3287
3540
|
}
|
|
3288
3541
|
}
|
|
3289
|
-
const { findMind: findMind2 } = await import("./registry-
|
|
3542
|
+
const { findMind: findMind2 } = await import("./registry-7LQHTRUX.js");
|
|
3290
3543
|
const variantEntry = await findMind2(variantName);
|
|
3291
3544
|
const branchName = variantEntry?.branch ?? variantName;
|
|
3292
3545
|
if (existsSync6(variantPath)) {
|
|
@@ -3313,7 +3566,7 @@ async function cleanupVariant(variantName, projectRoot, variantPath, opts) {
|
|
|
3313
3566
|
logger_default.warn(`failed to remove variant ${variantName} from DB`, logger_default.errorData(err));
|
|
3314
3567
|
}
|
|
3315
3568
|
try {
|
|
3316
|
-
chownMindDir(projectRoot, baseName);
|
|
3569
|
+
await chownMindDir(projectRoot, baseName);
|
|
3317
3570
|
} catch (err) {
|
|
3318
3571
|
logger_default.error(
|
|
3319
3572
|
`failed to fix ownership during variant cleanup for ${variantName}`,
|
|
@@ -3508,42 +3761,14 @@ function convertAssistantContent(content) {
|
|
|
3508
3761
|
return result;
|
|
3509
3762
|
}
|
|
3510
3763
|
|
|
3511
|
-
// packages/daemon/src/lib/util/health.ts
|
|
3512
|
-
async function checkHealth(port) {
|
|
3513
|
-
try {
|
|
3514
|
-
const res = await fetch(`http://127.0.0.1:${port}/health`, {
|
|
3515
|
-
signal: AbortSignal.timeout(2e3)
|
|
3516
|
-
});
|
|
3517
|
-
if (!res.ok) return { ok: false };
|
|
3518
|
-
const data = await res.json();
|
|
3519
|
-
return { ok: true, name: data.name };
|
|
3520
|
-
} catch {
|
|
3521
|
-
return { ok: false };
|
|
3522
|
-
}
|
|
3523
|
-
}
|
|
3524
|
-
|
|
3525
3764
|
// packages/daemon/src/web/api/minds.ts
|
|
3526
|
-
var SUBSTANTIVE_TYPES = /* @__PURE__ */ new Set(["thinking", "text", "tool_use", "tool_result", "outbound"]);
|
|
3527
|
-
var noticeDrainWatermarks = /* @__PURE__ */ new Map();
|
|
3528
|
-
function markDeliveredOnCleanTurn(mind, session) {
|
|
3529
|
-
if (!session) return;
|
|
3530
|
-
const wmKey = `${mind}:${session}`;
|
|
3531
|
-
const watermark = noticeDrainWatermarks.get(wmKey);
|
|
3532
|
-
noticeDrainWatermarks.delete(wmKey);
|
|
3533
|
-
const errored = takeErrored(mind, session);
|
|
3534
|
-
if (!errored && watermark != null) {
|
|
3535
|
-
clearDeliveredNotices(mind, session, watermark).catch(
|
|
3536
|
-
(err) => logger_default.warn(`failed to clear delivered notices for ${mind}:${session}`, logger_default.errorData(err))
|
|
3537
|
-
);
|
|
3538
|
-
}
|
|
3539
|
-
}
|
|
3540
3765
|
var _lastActiveCache = { map: /* @__PURE__ */ new Map(), ts: 0 };
|
|
3541
3766
|
var _LAST_ACTIVE_TTL = 6e4;
|
|
3542
3767
|
async function getMindStatus(name, port, registryRunning) {
|
|
3543
3768
|
const manager = getMindManager();
|
|
3544
3769
|
let status = "stopped";
|
|
3545
3770
|
try {
|
|
3546
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
3771
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-BVU5D2AE.js");
|
|
3547
3772
|
if (getSleepManagerIfReady2()?.isSleeping(name)) {
|
|
3548
3773
|
status = "sleeping";
|
|
3549
3774
|
}
|
|
@@ -3704,7 +3929,7 @@ async function mergeUpgradeAndRestart(mindName, dir, worktreeDir, upgradeVariant
|
|
|
3704
3929
|
cwd: dir
|
|
3705
3930
|
});
|
|
3706
3931
|
}
|
|
3707
|
-
chownMindDir(dir, mindName);
|
|
3932
|
+
await chownMindDir(dir, mindName);
|
|
3708
3933
|
switchWarning = `Switched ${oldTemplate}\u2192${template}: config reset to ${template} defaults, mechanics doc replaced, conversation starts fresh (sessions aren't portable across runtimes).`;
|
|
3709
3934
|
} catch (err) {
|
|
3710
3935
|
logger_default.warn(`failed to swap template home files for ${mindName}`, logger_default.errorData(err));
|
|
@@ -3786,7 +4011,7 @@ async function importFromFullArchive(c, tempDir, extractedMindDir, nameOverride,
|
|
|
3786
4011
|
const homeDir = resolve11(dest, "home");
|
|
3787
4012
|
ensureVoluteGroup();
|
|
3788
4013
|
createMindUser(name, homeDir);
|
|
3789
|
-
chownMindDir(dest, name);
|
|
4014
|
+
await chownMindDir(dest, name);
|
|
3790
4015
|
await npmInstallAsMind(dest, name);
|
|
3791
4016
|
await importHistoryFromArchive(name, tempDir);
|
|
3792
4017
|
importSessionsFromArchive(dest, tempDir);
|
|
@@ -3802,7 +4027,7 @@ async function importFromFullArchive(c, tempDir, extractedMindDir, nameOverride,
|
|
|
3802
4027
|
rmSync4(resolve11(dest, ".git"), { recursive: true, force: true });
|
|
3803
4028
|
}
|
|
3804
4029
|
}
|
|
3805
|
-
chownMindDir(dest, name);
|
|
4030
|
+
await chownMindDir(dest, name);
|
|
3806
4031
|
rmSync4(tempDir, { recursive: true, force: true });
|
|
3807
4032
|
return c.json({ ok: true, name, port, message: `Imported mind: ${name} (port ${port})` });
|
|
3808
4033
|
} catch (err) {
|
|
@@ -3864,7 +4089,7 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
3864
4089
|
const homeDir = resolve11(dest, "home");
|
|
3865
4090
|
ensureVoluteGroup();
|
|
3866
4091
|
createMindUser(name, homeDir);
|
|
3867
|
-
chownMindDir(dest, name);
|
|
4092
|
+
await chownMindDir(dest, name);
|
|
3868
4093
|
await npmInstallAsMind(dest, name);
|
|
3869
4094
|
let gitWarning;
|
|
3870
4095
|
try {
|
|
@@ -3889,7 +4114,7 @@ async function importFromHomeOnlyArchive(c, tempDir, extractedMindDir, nameOverr
|
|
|
3889
4114
|
}
|
|
3890
4115
|
await importHistoryFromArchive(name, tempDir);
|
|
3891
4116
|
importSessionsFromArchive(dest, tempDir);
|
|
3892
|
-
chownMindDir(dest, name);
|
|
4117
|
+
await chownMindDir(dest, name);
|
|
3893
4118
|
publishPublicKey(name, publicKeyPem).catch(
|
|
3894
4119
|
(err) => logger_default.warn(`failed to publish key for ${name}`, { error: err.message })
|
|
3895
4120
|
);
|
|
@@ -4038,7 +4263,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
|
|
|
4038
4263
|
applyInitFiles(dest);
|
|
4039
4264
|
const { publicKeyPem } = generateIdentity(dest);
|
|
4040
4265
|
{
|
|
4041
|
-
const { readGlobalConfig: readGlobal } = await import("./setup-
|
|
4266
|
+
const { readGlobalConfig: readGlobal } = await import("./setup-25MMJ3J4.js");
|
|
4042
4267
|
const mindDefaults = readGlobal().mindDefaults;
|
|
4043
4268
|
const config2 = readVoluteConfig(dest);
|
|
4044
4269
|
if (!config2) throw new Error("Failed to read volute.json after identity generation");
|
|
@@ -4105,7 +4330,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
|
|
|
4105
4330
|
const homeDir = resolve11(dest, "home");
|
|
4106
4331
|
ensureVoluteGroup();
|
|
4107
4332
|
createMindUser(name, homeDir);
|
|
4108
|
-
chownMindDir(dest, name);
|
|
4333
|
+
await chownMindDir(dest, name);
|
|
4109
4334
|
await npmInstallAsMind(dest, name);
|
|
4110
4335
|
let gitWarning;
|
|
4111
4336
|
try {
|
|
@@ -4118,7 +4343,7 @@ var app13 = new Hono15().post("/", requireAdminOrSystem, zValidator5("json", cre
|
|
|
4118
4343
|
rmSync4(resolve11(dest, ".git"), { recursive: true, force: true });
|
|
4119
4344
|
gitWarning = "Git setup failed \u2014 variants and upgrades won't be available until git is initialized.";
|
|
4120
4345
|
}
|
|
4121
|
-
chownMindDir(dest, name);
|
|
4346
|
+
await chownMindDir(dest, name);
|
|
4122
4347
|
if (body.stage === "seed") {
|
|
4123
4348
|
const descLine = body.description ? `
|
|
4124
4349
|
The human who planted you described you as: "${body.description}"
|
|
@@ -4129,7 +4354,7 @@ The human who planted you described you as: "${body.description}"
|
|
|
4129
4354
|
}
|
|
4130
4355
|
let skillSet = body.skills ?? (body.stage === "seed" ? SEED_SKILLS : getStandardSkillsWithExtensions());
|
|
4131
4356
|
if (body.stage === "seed" && !body.skills) {
|
|
4132
|
-
const { isImagegenEnabled } = await import("./setup-
|
|
4357
|
+
const { isImagegenEnabled } = await import("./setup-25MMJ3J4.js");
|
|
4133
4358
|
if (isImagegenEnabled()) {
|
|
4134
4359
|
skillSet = [...skillSet, "imagegen"];
|
|
4135
4360
|
}
|
|
@@ -4147,7 +4372,7 @@ The human who planted you described you as: "${body.description}"
|
|
|
4147
4372
|
try {
|
|
4148
4373
|
const spiritEntry = await findMind("volute");
|
|
4149
4374
|
if (spiritEntry) {
|
|
4150
|
-
const { spiritDir } = await import("./spirit-
|
|
4375
|
+
const { spiritDir } = await import("./spirit-JQQHUVWR.js");
|
|
4151
4376
|
const sDir = spiritEntry.dir ?? spiritDir();
|
|
4152
4377
|
const spiritConfig = readVoluteConfig(sDir) ?? {};
|
|
4153
4378
|
const schedules = spiritConfig.schedules ?? [];
|
|
@@ -4162,7 +4387,7 @@ The human who planted you described you as: "${body.description}"
|
|
|
4162
4387
|
});
|
|
4163
4388
|
spiritConfig.schedules = schedules;
|
|
4164
4389
|
writeVoluteConfig(sDir, spiritConfig);
|
|
4165
|
-
const { getScheduler: getScheduler2 } = await import("./scheduler-
|
|
4390
|
+
const { getScheduler: getScheduler2 } = await import("./scheduler-BR6C6B3E.js");
|
|
4166
4391
|
getScheduler2().loadSchedules("volute", sDir);
|
|
4167
4392
|
}
|
|
4168
4393
|
}
|
|
@@ -4292,7 +4517,7 @@ ${user.trimEnd()}
|
|
|
4292
4517
|
const homeDir = resolve11(dest, "home");
|
|
4293
4518
|
ensureVoluteGroup();
|
|
4294
4519
|
createMindUser(name, homeDir);
|
|
4295
|
-
chownMindDir(dest, name);
|
|
4520
|
+
await chownMindDir(dest, name);
|
|
4296
4521
|
await npmInstallAsMind(dest, name);
|
|
4297
4522
|
if (!hasMemory && dailyLogCount > 0) {
|
|
4298
4523
|
await consolidateMemory(dest);
|
|
@@ -4314,7 +4539,7 @@ ${user.trimEnd()}
|
|
|
4314
4539
|
}
|
|
4315
4540
|
}
|
|
4316
4541
|
importOpenClawConnectors(name, dest);
|
|
4317
|
-
chownMindDir(dest, name);
|
|
4542
|
+
await chownMindDir(dest, name);
|
|
4318
4543
|
publishPublicKey(name, importPublicKey).catch(
|
|
4319
4544
|
(err) => logger_default.warn(`failed to publish key for ${name}`, { error: err.message })
|
|
4320
4545
|
);
|
|
@@ -4340,7 +4565,7 @@ ${user.trimEnd()}
|
|
|
4340
4565
|
const db = await getDb();
|
|
4341
4566
|
const lastActiveRows = await db.select({
|
|
4342
4567
|
mind: mindHistory.mind,
|
|
4343
|
-
lastActiveAt:
|
|
4568
|
+
lastActiveAt: sql3`MAX(${mindHistory.created_at})`
|
|
4344
4569
|
}).from(mindHistory).groupBy(mindHistory.mind);
|
|
4345
4570
|
lastActiveMap = new Map(lastActiveRows.map((r) => [r.mind, r.lastActiveAt]));
|
|
4346
4571
|
_lastActiveCache.map = lastActiveMap;
|
|
@@ -4427,7 +4652,7 @@ ${user.trimEnd()}
|
|
|
4427
4652
|
const manager = getMindManager();
|
|
4428
4653
|
try {
|
|
4429
4654
|
if (context?.type === "reload") {
|
|
4430
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
4655
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-BVU5D2AE.js");
|
|
4431
4656
|
const sleepState = getSleepManagerIfReady2()?.getState(name);
|
|
4432
4657
|
if (sleepState?.sleeping) {
|
|
4433
4658
|
logger_default.info(`skipping reload for ${name} during sleep \u2014 will apply on next wake`);
|
|
@@ -4499,7 +4724,39 @@ ${user.trimEnd()}
|
|
|
4499
4724
|
logger_default.error(`failed to inject sprouted message for ${baseName}`, logger_default.errorData(err));
|
|
4500
4725
|
}
|
|
4501
4726
|
}
|
|
4502
|
-
|
|
4727
|
+
const repoDir = entry.parent ? entry.dir : mindDir(name);
|
|
4728
|
+
try {
|
|
4729
|
+
await startMindFull(name);
|
|
4730
|
+
} catch (startErr) {
|
|
4731
|
+
const stderr = startErr instanceof MindStartupError ? startErr.stderr : void 0;
|
|
4732
|
+
let rollback = { parked: false };
|
|
4733
|
+
try {
|
|
4734
|
+
rollback = await rollbackSrcChanges(repoDir, name);
|
|
4735
|
+
} catch (rbErr) {
|
|
4736
|
+
logger_default.error(`failed to roll back src changes for ${name}`, logger_default.errorData(rbErr));
|
|
4737
|
+
}
|
|
4738
|
+
if (!rollback.parked) throw startErr;
|
|
4739
|
+
await startMindFull(name);
|
|
4740
|
+
const startMsg = startErr instanceof Error ? startErr.message : String(startErr);
|
|
4741
|
+
const errLine = (stderr ?? startMsg).trim().split("\n").filter(Boolean).pop() ?? "";
|
|
4742
|
+
await recordNotice({
|
|
4743
|
+
mind: name,
|
|
4744
|
+
session: "main",
|
|
4745
|
+
kind: "startup",
|
|
4746
|
+
reason: "startup_failed",
|
|
4747
|
+
detail: `Your last change to src/ broke startup, so it was rolled back and your previous working code was restored. The broken change is preserved on branch \`${rollback.branch}\` \u2014 check it out to inspect and fix it. Error: ${errLine}`,
|
|
4748
|
+
raw: stderr ?? null
|
|
4749
|
+
});
|
|
4750
|
+
return c.json({
|
|
4751
|
+
ok: true,
|
|
4752
|
+
recovered: true,
|
|
4753
|
+
brokenBranch: rollback.branch,
|
|
4754
|
+
port: targetPort
|
|
4755
|
+
});
|
|
4756
|
+
}
|
|
4757
|
+
await commitSrcChanges(repoDir, name).catch(
|
|
4758
|
+
(e) => logger_default.error(`failed to commit known-good src for ${name}`, logger_default.errorData(e))
|
|
4759
|
+
);
|
|
4503
4760
|
return c.json({ ok: true, port: targetPort });
|
|
4504
4761
|
} catch (err) {
|
|
4505
4762
|
return c.json({ error: err instanceof Error ? err.message : "Failed to restart mind" }, 500);
|
|
@@ -4522,7 +4779,7 @@ ${user.trimEnd()}
|
|
|
4522
4779
|
const name = c.req.param("name");
|
|
4523
4780
|
const entry = await findMind(name);
|
|
4524
4781
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
4525
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
4782
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-BVU5D2AE.js");
|
|
4526
4783
|
const sm = getSleepManagerIfReady2();
|
|
4527
4784
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
4528
4785
|
return c.json(sm.getState(name));
|
|
@@ -4530,7 +4787,7 @@ ${user.trimEnd()}
|
|
|
4530
4787
|
const name = c.req.param("name");
|
|
4531
4788
|
const entry = await findMind(name);
|
|
4532
4789
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
4533
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
4790
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-BVU5D2AE.js");
|
|
4534
4791
|
const sm = getSleepManagerIfReady2();
|
|
4535
4792
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
4536
4793
|
if (sm.isSleeping(name)) return c.json({ error: "Mind is already sleeping" }, 409);
|
|
@@ -4550,7 +4807,7 @@ ${user.trimEnd()}
|
|
|
4550
4807
|
const name = c.req.param("name");
|
|
4551
4808
|
const entry = await findMind(name);
|
|
4552
4809
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
4553
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
4810
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-BVU5D2AE.js");
|
|
4554
4811
|
const sm = getSleepManagerIfReady2();
|
|
4555
4812
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
4556
4813
|
const sleepState = sm.getState(name);
|
|
@@ -4565,7 +4822,7 @@ ${user.trimEnd()}
|
|
|
4565
4822
|
const name = c.req.param("name");
|
|
4566
4823
|
const entry = await findMind(name);
|
|
4567
4824
|
if (!entry) return c.json({ error: "Mind not found" }, 404);
|
|
4568
|
-
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-
|
|
4825
|
+
const { getSleepManagerIfReady: getSleepManagerIfReady2 } = await import("./sleep-manager-BVU5D2AE.js");
|
|
4569
4826
|
const sm = getSleepManagerIfReady2();
|
|
4570
4827
|
if (!sm) return c.json({ error: "Sleep manager not initialized" }, 503);
|
|
4571
4828
|
const flushed = await sm.flushQueuedMessages(name);
|
|
@@ -4583,7 +4840,7 @@ ${user.trimEnd()}
|
|
|
4583
4840
|
if (body.avatar !== void 0) profile.avatar = basename(body.avatar);
|
|
4584
4841
|
config2.profile = profile;
|
|
4585
4842
|
writeVoluteConfig(dir, config2);
|
|
4586
|
-
const { syncMindProfile: syncMindProfile2 } = await import("./auth-
|
|
4843
|
+
const { syncMindProfile: syncMindProfile2 } = await import("./auth-3RIG6GKN.js");
|
|
4587
4844
|
await syncMindProfile2(name, profile);
|
|
4588
4845
|
broadcast({ type: "profile_updated", mind: name, summary: `${name} profile updated` });
|
|
4589
4846
|
return c.json({ ok: true });
|
|
@@ -4599,21 +4856,21 @@ ${user.trimEnd()}
|
|
|
4599
4856
|
const rawSpirit = Number(process.env.VOLUTE_NURTURE_SPIRIT_MINUTES);
|
|
4600
4857
|
const spiritThreshold = Number.isNaN(rawSpirit) ? 15 : rawSpirit;
|
|
4601
4858
|
const lastCreatorMsg = await db.select({ created_at: mindHistory.created_at }).from(mindHistory).where(
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4859
|
+
and5(
|
|
4860
|
+
eq5(mindHistory.mind, name),
|
|
4861
|
+
eq5(mindHistory.type, "inbound"),
|
|
4862
|
+
sql3`${mindHistory.sender} != 'volute'`,
|
|
4863
|
+
sql3`${mindHistory.sender} != ${name}`,
|
|
4864
|
+
sql3`${mindHistory.sender} IS NOT NULL`
|
|
4608
4865
|
)
|
|
4609
|
-
).orderBy(
|
|
4866
|
+
).orderBy(desc4(mindHistory.created_at)).limit(1);
|
|
4610
4867
|
const lastSpiritMsg = await db.select({ created_at: mindHistory.created_at }).from(mindHistory).where(
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
|
|
4868
|
+
and5(
|
|
4869
|
+
eq5(mindHistory.mind, name),
|
|
4870
|
+
eq5(mindHistory.type, "inbound"),
|
|
4871
|
+
eq5(mindHistory.sender, "volute")
|
|
4615
4872
|
)
|
|
4616
|
-
).orderBy(
|
|
4873
|
+
).orderBy(desc4(mindHistory.created_at)).limit(1);
|
|
4617
4874
|
const now = Date.now();
|
|
4618
4875
|
const creatorTime = lastCreatorMsg[0] ? new Date(lastCreatorMsg[0].created_at).getTime() : 0;
|
|
4619
4876
|
const spiritTime = lastSpiritMsg[0] ? new Date(lastSpiritMsg[0].created_at).getTime() : 0;
|
|
@@ -4630,7 +4887,7 @@ ${user.trimEnd()}
|
|
|
4630
4887
|
const config2 = readVoluteConfig(dir);
|
|
4631
4888
|
const displayNameSet = !!config2?.profile?.displayName;
|
|
4632
4889
|
const avatarSet = !!config2?.profile?.avatar;
|
|
4633
|
-
const { isImagegenEnabled } = await import("./setup-
|
|
4890
|
+
const { isImagegenEnabled } = await import("./setup-25MMJ3J4.js");
|
|
4634
4891
|
const imagegenEnabled = isImagegenEnabled();
|
|
4635
4892
|
const done = [];
|
|
4636
4893
|
const remaining = [];
|
|
@@ -4668,7 +4925,7 @@ ${user.trimEnd()}
|
|
|
4668
4925
|
try {
|
|
4669
4926
|
const spiritEntry = await findMind("volute");
|
|
4670
4927
|
if (spiritEntry) {
|
|
4671
|
-
const { spiritDir } = await import("./spirit-
|
|
4928
|
+
const { spiritDir } = await import("./spirit-JQQHUVWR.js");
|
|
4672
4929
|
const sDir = spiritEntry.dir ?? spiritDir();
|
|
4673
4930
|
const spiritConfig = readVoluteConfig(sDir);
|
|
4674
4931
|
if (spiritConfig?.schedules) {
|
|
@@ -4676,7 +4933,7 @@ ${user.trimEnd()}
|
|
|
4676
4933
|
spiritConfig.schedules = spiritConfig.schedules.filter((s) => s.id !== nurtureId);
|
|
4677
4934
|
if (spiritConfig.schedules.length === 0) spiritConfig.schedules = void 0;
|
|
4678
4935
|
writeVoluteConfig(sDir, spiritConfig);
|
|
4679
|
-
const { getScheduler: getScheduler2 } = await import("./scheduler-
|
|
4936
|
+
const { getScheduler: getScheduler2 } = await import("./scheduler-BR6C6B3E.js");
|
|
4680
4937
|
getScheduler2().loadSchedules("volute", sDir);
|
|
4681
4938
|
}
|
|
4682
4939
|
}
|
|
@@ -4793,7 +5050,7 @@ ${user.trimEnd()}
|
|
|
4793
5050
|
cwd: worktreeDir
|
|
4794
5051
|
});
|
|
4795
5052
|
}
|
|
4796
|
-
chownMindDir(dir, mindName);
|
|
5053
|
+
await chownMindDir(dir, mindName);
|
|
4797
5054
|
try {
|
|
4798
5055
|
const result = await mergeUpgradeAndRestart(
|
|
4799
5056
|
mindName,
|
|
@@ -4859,7 +5116,7 @@ ${user.trimEnd()}
|
|
|
4859
5116
|
await configureGitIdentity(mindName, { cwd: dir, mindName, env });
|
|
4860
5117
|
await gitExec(["add", "-A"], { cwd: dir, mindName, env });
|
|
4861
5118
|
await gitExec(["commit", "-m", "initial commit"], { cwd: dir, mindName, env });
|
|
4862
|
-
chownMindDir(dir, mindName);
|
|
5119
|
+
await chownMindDir(dir, mindName);
|
|
4863
5120
|
} catch (err) {
|
|
4864
5121
|
rmSync4(resolve11(dir, ".git"), { recursive: true, force: true });
|
|
4865
5122
|
return c.json(
|
|
@@ -4918,7 +5175,7 @@ ${user.trimEnd()}
|
|
|
4918
5175
|
});
|
|
4919
5176
|
}
|
|
4920
5177
|
}
|
|
4921
|
-
chownMindDir(dir, mindName);
|
|
5178
|
+
await chownMindDir(dir, mindName);
|
|
4922
5179
|
if (hasConflicts) {
|
|
4923
5180
|
return c.json({
|
|
4924
5181
|
ok: false,
|
|
@@ -5111,7 +5368,7 @@ ${user.trimEnd()}
|
|
|
5111
5368
|
}
|
|
5112
5369
|
writeVoluteConfig(dir, existing);
|
|
5113
5370
|
if (body.unescapeNewlines !== void 0) {
|
|
5114
|
-
const { clearEchoTextCache } = await import("./echo-text-
|
|
5371
|
+
const { clearEchoTextCache } = await import("./echo-text-XKBJM6RV.js");
|
|
5115
5372
|
clearEchoTextCache(name);
|
|
5116
5373
|
}
|
|
5117
5374
|
const needsConfigJson = body.model !== void 0 || body.thinkingLevel !== void 0 || body.maxThinkingTokens !== void 0 || body.compaction !== void 0;
|
|
@@ -5188,7 +5445,7 @@ ${user.trimEnd()}
|
|
|
5188
5445
|
}
|
|
5189
5446
|
if (entry.mindType === "spirit" && body.model !== void 0) {
|
|
5190
5447
|
try {
|
|
5191
|
-
const { readGlobalConfig: readGlobalConfig2, writeGlobalConfig: writeGlobalConfig2 } = await import("./setup-
|
|
5448
|
+
const { readGlobalConfig: readGlobalConfig2, writeGlobalConfig: writeGlobalConfig2 } = await import("./setup-25MMJ3J4.js");
|
|
5192
5449
|
const globalConfig = readGlobalConfig2();
|
|
5193
5450
|
globalConfig.spiritModel = body.model;
|
|
5194
5451
|
writeGlobalConfig2(globalConfig);
|
|
@@ -5216,7 +5473,7 @@ ${user.trimEnd()}
|
|
|
5216
5473
|
if (!body.systemPrompt || !body.message) {
|
|
5217
5474
|
return c.json({ error: "systemPrompt and message required" }, 400);
|
|
5218
5475
|
}
|
|
5219
|
-
const { aiComplete: aiCompleteFn, isAiConfigured } = await import("./ai-service-
|
|
5476
|
+
const { aiComplete: aiCompleteFn, isAiConfigured } = await import("./ai-service-FBCCEYF5.js");
|
|
5220
5477
|
if (!isAiConfigured()) {
|
|
5221
5478
|
return c.json({ error: "AI service not configured" }, 503);
|
|
5222
5479
|
}
|
|
@@ -5237,166 +5494,7 @@ ${user.trimEnd()}
|
|
|
5237
5494
|
if (!body.type) {
|
|
5238
5495
|
return c.json({ error: "type required" }, 400);
|
|
5239
5496
|
}
|
|
5240
|
-
|
|
5241
|
-
const activeTurnId = getActiveTurnId(baseName);
|
|
5242
|
-
if (activeTurnId) {
|
|
5243
|
-
await assignSession(baseName, activeTurnId, body.session);
|
|
5244
|
-
}
|
|
5245
|
-
}
|
|
5246
|
-
let turnId = getActiveTurnId(baseName, body.session);
|
|
5247
|
-
if (!turnId && SUBSTANTIVE_TYPES.has(body.type)) {
|
|
5248
|
-
turnId = await createTurn(baseName);
|
|
5249
|
-
if (!turnId) {
|
|
5250
|
-
logger_default.warn(`skipping turn tracking for ${baseName}: createTurn failed`);
|
|
5251
|
-
} else {
|
|
5252
|
-
publish2(baseName, { mind: baseName, type: "turn_created", turnId });
|
|
5253
|
-
if (body.session) {
|
|
5254
|
-
await assignSession(baseName, turnId, body.session);
|
|
5255
|
-
}
|
|
5256
|
-
try {
|
|
5257
|
-
await tagUntaggedInbound(baseName, turnId, {
|
|
5258
|
-
setTrigger: true,
|
|
5259
|
-
channel: body.channel
|
|
5260
|
-
});
|
|
5261
|
-
} catch (err) {
|
|
5262
|
-
logger_default.warn(
|
|
5263
|
-
`failed to link trigger/tag inbounds for turn ${turnId} (mind: ${baseName})`,
|
|
5264
|
-
logger_default.errorData(err)
|
|
5265
|
-
);
|
|
5266
|
-
}
|
|
5267
|
-
}
|
|
5268
|
-
}
|
|
5269
|
-
const MARKER_RE = /\[volute:(?:outbound|activity):\d+\]/g;
|
|
5270
|
-
const cleanContent = body.type === "tool_result" && body.content ? body.content.replace(MARKER_RE, "").trimEnd() : body.content;
|
|
5271
|
-
const db = await getDb();
|
|
5272
|
-
let insertedId;
|
|
5273
|
-
try {
|
|
5274
|
-
const result = await db.insert(mindHistory).values({
|
|
5275
|
-
mind: baseName,
|
|
5276
|
-
type: body.type,
|
|
5277
|
-
session: body.session ?? null,
|
|
5278
|
-
channel: body.channel ?? null,
|
|
5279
|
-
message_id: body.messageId ?? null,
|
|
5280
|
-
content: cleanContent ?? null,
|
|
5281
|
-
metadata: body.metadata ? JSON.stringify(body.metadata) : null,
|
|
5282
|
-
turn_id: turnId ?? null
|
|
5283
|
-
}).returning({ id: mindHistory.id });
|
|
5284
|
-
insertedId = result[0]?.id;
|
|
5285
|
-
} catch (err) {
|
|
5286
|
-
logger_default.error(`failed to persist event for ${baseName}`, logger_default.errorData(err));
|
|
5287
|
-
}
|
|
5288
|
-
if (body.type === "tool_use" && insertedId != null) {
|
|
5289
|
-
trackToolUse(baseName, body.session, insertedId);
|
|
5290
|
-
}
|
|
5291
|
-
if (body.type === "tool_result" && turnId && body.content) {
|
|
5292
|
-
const toolUseEventId = getLastToolUseEventId(baseName, body.session);
|
|
5293
|
-
try {
|
|
5294
|
-
await linkToolResultToTurn(baseName, turnId, body.content, toolUseEventId);
|
|
5295
|
-
} catch (err) {
|
|
5296
|
-
logger_default.error("failed to link outbound to turn", logger_default.errorData(err));
|
|
5297
|
-
}
|
|
5298
|
-
}
|
|
5299
|
-
publish2(baseName, {
|
|
5300
|
-
mind: baseName,
|
|
5301
|
-
type: body.type,
|
|
5302
|
-
session: body.session,
|
|
5303
|
-
channel: body.channel,
|
|
5304
|
-
messageId: body.messageId,
|
|
5305
|
-
content: cleanContent,
|
|
5306
|
-
metadata: body.metadata,
|
|
5307
|
-
turnId: turnId ?? void 0
|
|
5308
|
-
});
|
|
5309
|
-
if (body.type === "text" && body.channel && cleanContent) {
|
|
5310
|
-
echoTextToChannel(
|
|
5311
|
-
baseName,
|
|
5312
|
-
body.channel,
|
|
5313
|
-
cleanContent,
|
|
5314
|
-
turnId ?? void 0,
|
|
5315
|
-
insertedId
|
|
5316
|
-
).catch(
|
|
5317
|
-
(err) => logger_default.error(`echo-text failed for ${baseName} on ${body.channel}`, logger_default.errorData(err))
|
|
5318
|
-
);
|
|
5319
|
-
}
|
|
5320
|
-
onMindEvent(baseName, body.type, body.channel);
|
|
5321
|
-
if ((body.type === "text" || body.type === "outbound") && body.channel) {
|
|
5322
|
-
const map = getTypingMap();
|
|
5323
|
-
const affected = map.deleteSender(baseName);
|
|
5324
|
-
publishTypingForChannels(affected, map);
|
|
5325
|
-
}
|
|
5326
|
-
if (body.type === "error" && body.session) {
|
|
5327
|
-
markErrored(baseName, body.session);
|
|
5328
|
-
const { reason, detail } = classify(body.content ?? "");
|
|
5329
|
-
await recordNotice({
|
|
5330
|
-
mind: baseName,
|
|
5331
|
-
session: body.session,
|
|
5332
|
-
kind: "turn_error",
|
|
5333
|
-
reason,
|
|
5334
|
-
detail,
|
|
5335
|
-
raw: body.content ?? null
|
|
5336
|
-
});
|
|
5337
|
-
}
|
|
5338
|
-
if (body.type === "done") {
|
|
5339
|
-
const map = getTypingMap();
|
|
5340
|
-
const affected = map.deleteSender(baseName);
|
|
5341
|
-
publishTypingForChannels(affected, map);
|
|
5342
|
-
broadcast({ type: "mind_done", mind: baseName, summary: "Finished processing" });
|
|
5343
|
-
try {
|
|
5344
|
-
getDeliveryManager().sessionDone(baseName, body.session);
|
|
5345
|
-
} catch (err) {
|
|
5346
|
-
if (!(err instanceof Error && err.message.includes("not initialized"))) {
|
|
5347
|
-
logger_default.error(`delivery manager sessionDone failed for ${baseName}`, logger_default.errorData(err));
|
|
5348
|
-
}
|
|
5349
|
-
}
|
|
5350
|
-
try {
|
|
5351
|
-
const dm = getDeliveryManager();
|
|
5352
|
-
const busy = body.session ? dm.isSessionBusy(baseName, body.session) : false;
|
|
5353
|
-
if (!busy) {
|
|
5354
|
-
const completedTurnId = await completeTurn(baseName, body.session);
|
|
5355
|
-
if (completedTurnId) {
|
|
5356
|
-
tagUntaggedOutbound(baseName, completedTurnId).catch(
|
|
5357
|
-
(err) => logger_default.warn("failed to tag orphaned outbound records", logger_default.errorData(err))
|
|
5358
|
-
);
|
|
5359
|
-
}
|
|
5360
|
-
markDeliveredOnCleanTurn(baseName, body.session);
|
|
5361
|
-
if (insertedId != null) {
|
|
5362
|
-
summarizeTurn(baseName, body.session, body.channel, insertedId, completedTurnId).catch(
|
|
5363
|
-
(err) => logger_default.error("turn summarization failed", logger_default.errorData(err))
|
|
5364
|
-
);
|
|
5365
|
-
}
|
|
5366
|
-
}
|
|
5367
|
-
} catch (err) {
|
|
5368
|
-
if (!(err instanceof Error && err.message.includes("not initialized"))) {
|
|
5369
|
-
logger_default.error("turn completion check failed", logger_default.errorData(err));
|
|
5370
|
-
}
|
|
5371
|
-
const completedTurnId = await completeTurn(baseName, body.session);
|
|
5372
|
-
if (completedTurnId) {
|
|
5373
|
-
tagUntaggedOutbound(baseName, completedTurnId).catch(
|
|
5374
|
-
(err2) => logger_default.warn("failed to tag orphaned outbound records", logger_default.errorData(err2))
|
|
5375
|
-
);
|
|
5376
|
-
}
|
|
5377
|
-
markDeliveredOnCleanTurn(baseName, body.session);
|
|
5378
|
-
if (insertedId != null) {
|
|
5379
|
-
summarizeTurn(baseName, body.session, body.channel, insertedId, completedTurnId).catch(
|
|
5380
|
-
(err2) => logger_default.error("turn summarization failed", logger_default.errorData(err2))
|
|
5381
|
-
);
|
|
5382
|
-
}
|
|
5383
|
-
}
|
|
5384
|
-
}
|
|
5385
|
-
if (body.type === "usage" && body.metadata) {
|
|
5386
|
-
const inputTokens = body.metadata.input_tokens ?? 0;
|
|
5387
|
-
const outputTokens = body.metadata.output_tokens ?? 0;
|
|
5388
|
-
const tb = getTokenBudget();
|
|
5389
|
-
tb.recordUsage(baseName, inputTokens, outputTokens);
|
|
5390
|
-
if (body.session && tb.noteExceeded(baseName)) {
|
|
5391
|
-
void recordNotice({
|
|
5392
|
-
mind: baseName,
|
|
5393
|
-
session: body.session,
|
|
5394
|
-
kind: "budget",
|
|
5395
|
-
reason: "token_budget",
|
|
5396
|
-
detail: "You've reached your token budget for this period. Further activity may be paused until the budget resets \u2014 wrap up or prioritize accordingly."
|
|
5397
|
-
});
|
|
5398
|
-
}
|
|
5399
|
-
}
|
|
5497
|
+
await handleMindEvent(baseName, body);
|
|
5400
5498
|
return c.json({ ok: true });
|
|
5401
5499
|
}).get("/:name/events", requireSelf(), async (c) => {
|
|
5402
5500
|
const name = c.req.param("name");
|
|
@@ -5485,32 +5583,32 @@ ${user.trimEnd()}
|
|
|
5485
5583
|
const db = await getDb();
|
|
5486
5584
|
const rows = await db.select({
|
|
5487
5585
|
session: mindHistory.session,
|
|
5488
|
-
started_at:
|
|
5489
|
-
event_count:
|
|
5490
|
-
message_count:
|
|
5491
|
-
tool_count:
|
|
5492
|
-
}).from(mindHistory).where(
|
|
5586
|
+
started_at: sql3`MIN(${mindHistory.created_at})`,
|
|
5587
|
+
event_count: sql3`COUNT(*)`,
|
|
5588
|
+
message_count: sql3`SUM(CASE WHEN ${mindHistory.type} IN ('inbound','outbound') THEN 1 ELSE 0 END)`,
|
|
5589
|
+
tool_count: sql3`SUM(CASE WHEN ${mindHistory.type}='tool_use' THEN 1 ELSE 0 END)`
|
|
5590
|
+
}).from(mindHistory).where(and5(eq5(mindHistory.mind, name), sql3`${mindHistory.session} IS NOT NULL`)).groupBy(mindHistory.session).orderBy(sql3`MIN(${mindHistory.created_at}) DESC`);
|
|
5493
5591
|
return c.json(rows);
|
|
5494
5592
|
}).get("/:name/history/channels", requireSelf(), async (c) => {
|
|
5495
5593
|
const name = c.req.param("name");
|
|
5496
5594
|
const db = await getDb();
|
|
5497
|
-
const rows = await db.selectDistinct({ channel: mindHistory.channel }).from(mindHistory).where(
|
|
5595
|
+
const rows = await db.selectDistinct({ channel: mindHistory.channel }).from(mindHistory).where(eq5(mindHistory.mind, name));
|
|
5498
5596
|
return c.json(rows.map((r) => r.channel));
|
|
5499
5597
|
}).get("/:name/history/export", requireSelf(), async (c) => {
|
|
5500
5598
|
const name = c.req.param("name");
|
|
5501
5599
|
if (!await findMind(name)) return c.json({ error: "Mind not found" }, 404);
|
|
5502
5600
|
const db = await getDb();
|
|
5503
|
-
const rows = await db.select().from(mindHistory).where(
|
|
5601
|
+
const rows = await db.select().from(mindHistory).where(eq5(mindHistory.mind, name));
|
|
5504
5602
|
return c.json(rows);
|
|
5505
5603
|
}).get("/:name/history/turn", requireSelf(), async (c) => {
|
|
5506
5604
|
const name = c.req.param("name");
|
|
5507
5605
|
const turnId = c.req.query("turn_id");
|
|
5508
5606
|
const detail = c.req.query("detail") === "1";
|
|
5509
5607
|
const db = await getDb();
|
|
5510
|
-
const typeFilter = detail ? void 0 :
|
|
5608
|
+
const typeFilter = detail ? void 0 : sql3`${mindHistory.type} IN ('inbound','outbound','tool_use','tool_result','text','thinking','activity')`;
|
|
5511
5609
|
let rows;
|
|
5512
5610
|
if (turnId) {
|
|
5513
|
-
rows = await db.select().from(mindHistory).where(
|
|
5611
|
+
rows = await db.select().from(mindHistory).where(and5(eq5(mindHistory.mind, name), eq5(mindHistory.turn_id, turnId), typeFilter)).orderBy(mindHistory.id);
|
|
5514
5612
|
} else {
|
|
5515
5613
|
const session = c.req.query("session");
|
|
5516
5614
|
const fromId = parseInt(c.req.query("from_id") ?? "", 10);
|
|
@@ -5519,11 +5617,11 @@ ${user.trimEnd()}
|
|
|
5519
5617
|
return c.json({ error: "turn_id, or session with from_id and to_id, required" }, 400);
|
|
5520
5618
|
}
|
|
5521
5619
|
rows = await db.select().from(mindHistory).where(
|
|
5522
|
-
|
|
5523
|
-
|
|
5524
|
-
|
|
5525
|
-
|
|
5526
|
-
|
|
5620
|
+
and5(
|
|
5621
|
+
eq5(mindHistory.mind, name),
|
|
5622
|
+
eq5(mindHistory.session, session),
|
|
5623
|
+
sql3`${mindHistory.id} >= ${fromId}`,
|
|
5624
|
+
sql3`${mindHistory.id} <= ${toId}`,
|
|
5527
5625
|
typeFilter
|
|
5528
5626
|
)
|
|
5529
5627
|
).orderBy(mindHistory.id);
|
|
@@ -5536,14 +5634,14 @@ ${user.trimEnd()}
|
|
|
5536
5634
|
let sinceTimestamp = null;
|
|
5537
5635
|
if (currentSession) {
|
|
5538
5636
|
const lastTurn = await db.select({ turn_id: mindHistory.turn_id }).from(mindHistory).where(
|
|
5539
|
-
|
|
5540
|
-
|
|
5541
|
-
|
|
5542
|
-
|
|
5637
|
+
and5(
|
|
5638
|
+
eq5(mindHistory.mind, name),
|
|
5639
|
+
eq5(mindHistory.session, currentSession),
|
|
5640
|
+
sql3`${mindHistory.turn_id} IS NOT NULL`
|
|
5543
5641
|
)
|
|
5544
|
-
).orderBy(
|
|
5642
|
+
).orderBy(desc4(mindHistory.created_at)).limit(1);
|
|
5545
5643
|
if (lastTurn.length > 0 && lastTurn[0].turn_id) {
|
|
5546
|
-
const firstEvent = await db.select({ created_at: mindHistory.created_at }).from(mindHistory).where(
|
|
5644
|
+
const firstEvent = await db.select({ created_at: mindHistory.created_at }).from(mindHistory).where(eq5(mindHistory.turn_id, lastTurn[0].turn_id)).orderBy(mindHistory.created_at).limit(1);
|
|
5547
5645
|
if (firstEvent.length > 0) {
|
|
5548
5646
|
sinceTimestamp = firstEvent[0].created_at;
|
|
5549
5647
|
}
|
|
@@ -5553,18 +5651,18 @@ ${user.trimEnd()}
|
|
|
5553
5651
|
sinceTimestamp = new Date(Date.now() - 36e5).toISOString().replace("T", " ").slice(0, 19);
|
|
5554
5652
|
}
|
|
5555
5653
|
const conditions = [
|
|
5556
|
-
|
|
5557
|
-
|
|
5558
|
-
|
|
5654
|
+
eq5(summaries.mind, name),
|
|
5655
|
+
eq5(summaries.period, "turn"),
|
|
5656
|
+
sql3`${summaries.created_at} > ${sinceTimestamp}`
|
|
5559
5657
|
];
|
|
5560
5658
|
if (currentSession) {
|
|
5561
|
-
conditions.push(
|
|
5659
|
+
conditions.push(sql3`${turns.session} != ${currentSession}`);
|
|
5562
5660
|
}
|
|
5563
5661
|
const rows = await db.select({
|
|
5564
5662
|
session: turns.session,
|
|
5565
5663
|
content: summaries.content,
|
|
5566
5664
|
created_at: summaries.created_at
|
|
5567
|
-
}).from(summaries).innerJoin(turns,
|
|
5665
|
+
}).from(summaries).innerJoin(turns, eq5(turns.id, summaries.period_key)).where(and5(...conditions)).orderBy(desc4(summaries.created_at)).limit(50);
|
|
5568
5666
|
if (rows.length === 0) {
|
|
5569
5667
|
return c.json({ context: null });
|
|
5570
5668
|
}
|
|
@@ -5583,7 +5681,7 @@ ${lines.join("\n")}` });
|
|
|
5583
5681
|
const notices = await drainNotices(baseName, session);
|
|
5584
5682
|
if (notices.length === 0) return c.json({ context: null, notices: [] });
|
|
5585
5683
|
const maxId = notices.reduce((m, n) => Math.max(m, n.id), 0);
|
|
5586
|
-
|
|
5684
|
+
setNoticeDrainWatermark(baseName, session, maxId);
|
|
5587
5685
|
return c.json({ context: formatNotices(notices), notices });
|
|
5588
5686
|
}).get("/:name/history", requireSelf(), async (c) => {
|
|
5589
5687
|
const name = c.req.param("name");
|
|
@@ -5594,18 +5692,18 @@ ${lines.join("\n")}` });
|
|
|
5594
5692
|
const limit = Math.min(Math.max(parseInt(c.req.query("limit") ?? "50", 10) || 50, 1), 200);
|
|
5595
5693
|
const offset = Math.max(parseInt(c.req.query("offset") ?? "0", 10) || 0, 0);
|
|
5596
5694
|
const db = await getDb();
|
|
5597
|
-
const conditions = [
|
|
5695
|
+
const conditions = [eq5(mindHistory.mind, name)];
|
|
5598
5696
|
if (channel) {
|
|
5599
|
-
conditions.push(
|
|
5697
|
+
conditions.push(eq5(mindHistory.channel, channel));
|
|
5600
5698
|
}
|
|
5601
5699
|
if (session) {
|
|
5602
|
-
conditions.push(
|
|
5700
|
+
conditions.push(eq5(mindHistory.session, session));
|
|
5603
5701
|
}
|
|
5604
5702
|
const effectivePreset = full ? "all" : preset;
|
|
5605
5703
|
if (!effectivePreset || effectivePreset === "summary") {
|
|
5606
|
-
const sumConditions = [
|
|
5704
|
+
const sumConditions = [eq5(summaries.mind, name), eq5(summaries.period, "turn")];
|
|
5607
5705
|
if (session) {
|
|
5608
|
-
sumConditions.push(
|
|
5706
|
+
sumConditions.push(eq5(turns.session, session));
|
|
5609
5707
|
const sumRows2 = await db.select({
|
|
5610
5708
|
id: summaries.id,
|
|
5611
5709
|
mind: summaries.mind,
|
|
@@ -5615,7 +5713,7 @@ ${lines.join("\n")}` });
|
|
|
5615
5713
|
metadata: summaries.metadata,
|
|
5616
5714
|
created_at: summaries.created_at,
|
|
5617
5715
|
session: turns.session
|
|
5618
|
-
}).from(summaries).innerJoin(turns,
|
|
5716
|
+
}).from(summaries).innerJoin(turns, eq5(turns.id, summaries.period_key)).where(and5(...sumConditions)).orderBy(desc4(summaries.created_at)).limit(limit).offset(offset);
|
|
5619
5717
|
return c.json(
|
|
5620
5718
|
sumRows2.map((r) => ({
|
|
5621
5719
|
id: r.id,
|
|
@@ -5632,7 +5730,7 @@ ${lines.join("\n")}` });
|
|
|
5632
5730
|
}))
|
|
5633
5731
|
);
|
|
5634
5732
|
}
|
|
5635
|
-
const sumRows = await db.select().from(summaries).where(
|
|
5733
|
+
const sumRows = await db.select().from(summaries).where(and5(...sumConditions)).orderBy(desc4(summaries.created_at)).limit(limit).offset(offset);
|
|
5636
5734
|
return c.json(
|
|
5637
5735
|
sumRows.map((r) => ({
|
|
5638
5736
|
id: r.id,
|
|
@@ -5653,22 +5751,22 @@ ${lines.join("\n")}` });
|
|
|
5653
5751
|
case "all":
|
|
5654
5752
|
break;
|
|
5655
5753
|
case "conversation":
|
|
5656
|
-
conditions.push(
|
|
5754
|
+
conditions.push(sql3`${mindHistory.type} IN ('inbound','outbound','tool_use')`);
|
|
5657
5755
|
break;
|
|
5658
5756
|
case "detailed":
|
|
5659
5757
|
conditions.push(
|
|
5660
|
-
|
|
5758
|
+
sql3`${mindHistory.type} IN ('inbound','outbound','tool_use','tool_result','text','thinking')`
|
|
5661
5759
|
);
|
|
5662
5760
|
break;
|
|
5663
5761
|
}
|
|
5664
|
-
const rows = await db.select().from(mindHistory).where(
|
|
5762
|
+
const rows = await db.select().from(mindHistory).where(and5(...conditions)).orderBy(desc4(mindHistory.created_at)).limit(limit).offset(offset);
|
|
5665
5763
|
return c.json(rows);
|
|
5666
5764
|
});
|
|
5667
5765
|
var minds_default = app13;
|
|
5668
5766
|
|
|
5669
5767
|
// packages/daemon/src/web/api/prompts.ts
|
|
5670
5768
|
import { zValidator as zValidator6 } from "@hono/zod-validator";
|
|
5671
|
-
import { eq as
|
|
5769
|
+
import { eq as eq6, sql as sql4 } from "drizzle-orm";
|
|
5672
5770
|
import { Hono as Hono16 } from "hono";
|
|
5673
5771
|
import { z as z6 } from "zod";
|
|
5674
5772
|
var app14 = new Hono16().get("/", async (c) => {
|
|
@@ -5701,9 +5799,9 @@ var app14 = new Hono16().get("/", async (c) => {
|
|
|
5701
5799
|
}
|
|
5702
5800
|
const { content } = c.req.valid("json");
|
|
5703
5801
|
const db = await getDb();
|
|
5704
|
-
await db.insert(systemPrompts).values({ key, content, updated_at:
|
|
5802
|
+
await db.insert(systemPrompts).values({ key, content, updated_at: sql4`(datetime('now'))` }).onConflictDoUpdate({
|
|
5705
5803
|
target: systemPrompts.key,
|
|
5706
|
-
set: { content, updated_at:
|
|
5804
|
+
set: { content, updated_at: sql4`(datetime('now'))` }
|
|
5707
5805
|
});
|
|
5708
5806
|
return c.json({ ok: true });
|
|
5709
5807
|
}).delete("/:key", requireAdmin, async (c) => {
|
|
@@ -5712,7 +5810,7 @@ var app14 = new Hono16().get("/", async (c) => {
|
|
|
5712
5810
|
return c.json({ error: "Unknown prompt key" }, 404);
|
|
5713
5811
|
}
|
|
5714
5812
|
const db = await getDb();
|
|
5715
|
-
await db.delete(systemPrompts).where(
|
|
5813
|
+
await db.delete(systemPrompts).where(eq6(systemPrompts.key, key));
|
|
5716
5814
|
return c.json({ ok: true });
|
|
5717
5815
|
});
|
|
5718
5816
|
var prompts_default = app14;
|
|
@@ -5960,7 +6058,7 @@ var app15 = new Hono17().get("/:name/clock/status", requireSelf(), async (c) =>
|
|
|
5960
6058
|
const body = await c.req.text();
|
|
5961
6059
|
const message = `[webhook: ${event}] ${body}`;
|
|
5962
6060
|
try {
|
|
5963
|
-
const { sendSystemMessage } = await import("./system-chat-
|
|
6061
|
+
const { sendSystemMessage } = await import("./system-chat-KMQIP7VH.js");
|
|
5964
6062
|
await sendSystemMessage(name, message);
|
|
5965
6063
|
return c.json({ ok: true });
|
|
5966
6064
|
} catch (err) {
|
|
@@ -6014,7 +6112,7 @@ setup.get("/status", async (c) => {
|
|
|
6014
6112
|
let hasAccount = false;
|
|
6015
6113
|
if (hasSystem) {
|
|
6016
6114
|
try {
|
|
6017
|
-
const { listUsersByType: listUsersByType2 } = await import("./auth-
|
|
6115
|
+
const { listUsersByType: listUsersByType2 } = await import("./auth-3RIG6GKN.js");
|
|
6018
6116
|
const brains = await listUsersByType2("brain");
|
|
6019
6117
|
hasAccount = brains.length > 0;
|
|
6020
6118
|
} catch (err) {
|
|
@@ -6225,7 +6323,7 @@ setup.post("/account", async (c) => {
|
|
|
6225
6323
|
}
|
|
6226
6324
|
}
|
|
6227
6325
|
try {
|
|
6228
|
-
const { createUser: createUser2, updateUserProfile: updateUserProfile2 } = await import("./auth-
|
|
6326
|
+
const { createUser: createUser2, updateUserProfile: updateUserProfile2 } = await import("./auth-3RIG6GKN.js");
|
|
6229
6327
|
const user = await createUser2(body.username.trim(), body.password);
|
|
6230
6328
|
if (body.displayName?.trim()) {
|
|
6231
6329
|
await updateUserProfile2(user.id, { display_name: body.displayName.trim() });
|
|
@@ -6271,7 +6369,7 @@ setup.post("/models", async (c) => {
|
|
|
6271
6369
|
return c.json({ error: "Spirit model is required" }, 400);
|
|
6272
6370
|
}
|
|
6273
6371
|
try {
|
|
6274
|
-
const { setEnabledModels: setEnabledModels3, setUtilityModel: setUtilityModel2 } = await import("./ai-service-
|
|
6372
|
+
const { setEnabledModels: setEnabledModels3, setUtilityModel: setUtilityModel2 } = await import("./ai-service-FBCCEYF5.js");
|
|
6275
6373
|
setEnabledModels3(body.models);
|
|
6276
6374
|
const config2 = readGlobalConfig();
|
|
6277
6375
|
config2.spiritModel = body.spiritModel.trim();
|
|
@@ -6289,15 +6387,15 @@ setup.post("/complete", async (c) => {
|
|
|
6289
6387
|
return c.json({ error: "Setup already complete" }, 400);
|
|
6290
6388
|
}
|
|
6291
6389
|
try {
|
|
6292
|
-
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-
|
|
6293
|
-
const { startSpiritFull } = await import("./mind-service-
|
|
6390
|
+
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-JQQHUVWR.js");
|
|
6391
|
+
const { startSpiritFull } = await import("./mind-service-ZBVUMJ5H.js");
|
|
6294
6392
|
await ensureSpiritProject();
|
|
6295
6393
|
await syncSpiritTemplate();
|
|
6296
6394
|
const warnings = [];
|
|
6297
6395
|
const config2 = readGlobalConfig();
|
|
6298
6396
|
if (config2.setup?.service && config2.setup?.type === "local") {
|
|
6299
6397
|
try {
|
|
6300
|
-
const { installUserService } = await import("./service-install-
|
|
6398
|
+
const { installUserService } = await import("./service-install-SHRM6NHK.js");
|
|
6301
6399
|
const installed = await installUserService(config2.port, config2.hostname);
|
|
6302
6400
|
if (!installed) {
|
|
6303
6401
|
warnings.push("Service installation is not supported on this platform.");
|
|
@@ -6325,8 +6423,8 @@ setup.post("/complete", async (c) => {
|
|
|
6325
6423
|
}
|
|
6326
6424
|
let spiritConversationId;
|
|
6327
6425
|
try {
|
|
6328
|
-
const { getOrCreateMindUser: getOrCreateMindUser2, listUsersByType: listUsersByType2 } = await import("./auth-
|
|
6329
|
-
const { createConversation: createConversation2, findDMConversation: findDMConversation2 } = await import("./conversations-
|
|
6426
|
+
const { getOrCreateMindUser: getOrCreateMindUser2, listUsersByType: listUsersByType2 } = await import("./auth-3RIG6GKN.js");
|
|
6427
|
+
const { createConversation: createConversation2, findDMConversation: findDMConversation2 } = await import("./conversations-67WWW25C.js");
|
|
6330
6428
|
const spiritUser = await getOrCreateMindUser2("volute");
|
|
6331
6429
|
const brains = await listUsersByType2("brain");
|
|
6332
6430
|
const admin2 = brains.find((u) => u.role === "admin");
|
|
@@ -6348,8 +6446,8 @@ setup.post("/complete", async (c) => {
|
|
|
6348
6446
|
logger_default.info("setup complete state", { spiritConversationId, spiritStarted });
|
|
6349
6447
|
if (spiritConversationId && spiritStarted) {
|
|
6350
6448
|
try {
|
|
6351
|
-
const { deliverMessage: deliverMessage2 } = await import("./message-delivery-
|
|
6352
|
-
const { listUsersByType: listUsers2 } = await import("./auth-
|
|
6449
|
+
const { deliverMessage: deliverMessage2 } = await import("./message-delivery-WJBZFALY.js");
|
|
6450
|
+
const { listUsersByType: listUsers2 } = await import("./auth-3RIG6GKN.js");
|
|
6353
6451
|
const admins = await listUsers2("brain");
|
|
6354
6452
|
const admin2 = admins.find((u) => u.role === "admin");
|
|
6355
6453
|
const adminName = admin2?.display_name || admin2?.username || "the admin";
|
|
@@ -6668,7 +6766,7 @@ var app19 = new Hono22().use("*", authMiddleware).get("/", async (c) => {
|
|
|
6668
6766
|
var conversations_default = app19;
|
|
6669
6767
|
|
|
6670
6768
|
// packages/daemon/src/web/api/v1/events.ts
|
|
6671
|
-
import { desc as
|
|
6769
|
+
import { desc as desc5, eq as eq7 } from "drizzle-orm";
|
|
6672
6770
|
import { Hono as Hono23 } from "hono";
|
|
6673
6771
|
import { streamSSE as streamSSE4 } from "hono/streaming";
|
|
6674
6772
|
|
|
@@ -6711,16 +6809,23 @@ function bufferEvent(data) {
|
|
|
6711
6809
|
function nextEventId() {
|
|
6712
6810
|
return nextId++;
|
|
6713
6811
|
}
|
|
6714
|
-
function getEventsSince(sinceId, allowedConversationIds) {
|
|
6812
|
+
function getEventsSince(sinceId, allowedConversationIds, allowedActivityMind) {
|
|
6715
6813
|
const now = Date.now();
|
|
6716
6814
|
const startIdx = buffer.findIndex((e) => e.id > sinceId);
|
|
6717
6815
|
if (startIdx === -1) return [];
|
|
6718
6816
|
return buffer.slice(startIdx).filter((e) => {
|
|
6719
6817
|
if (now - e.timestamp >= MAX_AGE_MS) return false;
|
|
6720
6818
|
const data = e.data;
|
|
6721
|
-
|
|
6722
|
-
|
|
6723
|
-
|
|
6819
|
+
switch (data.event) {
|
|
6820
|
+
case "snapshot":
|
|
6821
|
+
return false;
|
|
6822
|
+
case "conversation":
|
|
6823
|
+
return allowedConversationIds.has(data.conversationId);
|
|
6824
|
+
case "activity":
|
|
6825
|
+
return allowedActivityMind === void 0 || data.mind === allowedActivityMind;
|
|
6826
|
+
default:
|
|
6827
|
+
return false;
|
|
6828
|
+
}
|
|
6724
6829
|
});
|
|
6725
6830
|
}
|
|
6726
6831
|
|
|
@@ -6729,6 +6834,8 @@ var app20 = new Hono23().use("*", authMiddleware).get("/", async (c) => {
|
|
|
6729
6834
|
const user = c.get("user");
|
|
6730
6835
|
const since = c.req.query("since");
|
|
6731
6836
|
const sinceId = since ? Number(since) : 0;
|
|
6837
|
+
const privileged = user.role === "admin" || user.role === "system";
|
|
6838
|
+
const activityMind = privileged ? void 0 : await getBaseName(user.username);
|
|
6732
6839
|
return streamSSE4(c, async (stream) => {
|
|
6733
6840
|
const cleanups = [];
|
|
6734
6841
|
if (user.user_type === "brain") {
|
|
@@ -6751,7 +6858,7 @@ var app20 = new Hono23().use("*", authMiddleware).get("/", async (c) => {
|
|
|
6751
6858
|
}
|
|
6752
6859
|
const allowedConversationIds = new Set(conversations2.map((c2) => c2.id));
|
|
6753
6860
|
if (sinceId > 0) {
|
|
6754
|
-
const missed = getEventsSince(sinceId, allowedConversationIds);
|
|
6861
|
+
const missed = getEventsSince(sinceId, allowedConversationIds, activityMind);
|
|
6755
6862
|
for (const event of missed) {
|
|
6756
6863
|
await stream.writeSSE({
|
|
6757
6864
|
id: String(event.id),
|
|
@@ -6762,7 +6869,7 @@ var app20 = new Hono23().use("*", authMiddleware).get("/", async (c) => {
|
|
|
6762
6869
|
let recentActivity = [];
|
|
6763
6870
|
try {
|
|
6764
6871
|
const db = await getDb();
|
|
6765
|
-
recentActivity = await db.select().from(activity).orderBy(
|
|
6872
|
+
recentActivity = await db.select().from(activity).where(activityMind ? eq7(activity.mind, activityMind) : void 0).orderBy(desc5(activity.created_at)).limit(50);
|
|
6766
6873
|
recentActivity = recentActivity.map((row) => ({
|
|
6767
6874
|
...row,
|
|
6768
6875
|
metadata: row.metadata ? JSON.parse(row.metadata) : null
|
|
@@ -6789,6 +6896,7 @@ var app20 = new Hono23().use("*", authMiddleware).get("/", async (c) => {
|
|
|
6789
6896
|
metadata: event.metadata ?? null
|
|
6790
6897
|
};
|
|
6791
6898
|
const eventId = bufferEvent(data);
|
|
6899
|
+
if (activityMind !== void 0 && event.mind !== activityMind) return;
|
|
6792
6900
|
stream.writeSSE({
|
|
6793
6901
|
id: String(eventId),
|
|
6794
6902
|
data: JSON.stringify(data)
|
|
@@ -7014,7 +7122,7 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
|
|
|
7014
7122
|
const msg = e instanceof Error ? e.message : String(e);
|
|
7015
7123
|
return c.json({ error: `Failed to create worktree: ${msg}` }, 500);
|
|
7016
7124
|
}
|
|
7017
|
-
chownMindDir(projectRoot, mindName);
|
|
7125
|
+
await chownMindDir(projectRoot, mindName);
|
|
7018
7126
|
try {
|
|
7019
7127
|
if (isIsolationEnabled()) {
|
|
7020
7128
|
const [cmd, args] = await wrapForIsolation("npm", ["install"], mindName);
|
|
@@ -7130,7 +7238,7 @@ var app21 = new Hono24().get("/:name/variants", async (c) => {
|
|
|
7130
7238
|
if (variantName.endsWith("-upgrade") || variantName === "upgrade") {
|
|
7131
7239
|
try {
|
|
7132
7240
|
const { computeTemplateHash: computeTemplateHash2 } = await import("./template-hash-446HHH5V.js");
|
|
7133
|
-
const { setMindTemplateHash: setMindTemplateHash2 } = await import("./registry-
|
|
7241
|
+
const { setMindTemplateHash: setMindTemplateHash2 } = await import("./registry-7LQHTRUX.js");
|
|
7134
7242
|
const tmpl = parentEntry.template ?? "claude";
|
|
7135
7243
|
await setMindTemplateHash2(mindName, computeTemplateHash2(tmpl));
|
|
7136
7244
|
} catch (err) {
|
|
@@ -7304,47 +7412,6 @@ import { zValidator as zValidator10 } from "@hono/zod-validator";
|
|
|
7304
7412
|
import { Hono as Hono26 } from "hono";
|
|
7305
7413
|
import { streamSSE as streamSSE5 } from "hono/streaming";
|
|
7306
7414
|
import { z as z10 } from "zod";
|
|
7307
|
-
async function fanOutToMinds(opts) {
|
|
7308
|
-
const participants = opts.participants;
|
|
7309
|
-
const mindParticipants = participants.filter(
|
|
7310
|
-
(p) => p.userType === "mind" || p.userType === "system"
|
|
7311
|
-
);
|
|
7312
|
-
const participantNames = participants.map((p) => p.username);
|
|
7313
|
-
const isDM = opts.isDM ?? participants.length === 2;
|
|
7314
|
-
const manager = getMindManager();
|
|
7315
|
-
const sm = getSleepManagerIfReady();
|
|
7316
|
-
const targetMinds = mindParticipants.map((ap) => {
|
|
7317
|
-
const key = opts.targetName ? opts.targetName(ap.username) : ap.username;
|
|
7318
|
-
if (manager.isRunning(key) || sm?.isSleeping(ap.username)) return ap.username;
|
|
7319
|
-
return null;
|
|
7320
|
-
}).filter((n) => n !== null && n !== opts.senderName);
|
|
7321
|
-
function slugForMind(mindUsername) {
|
|
7322
|
-
return buildVoluteSlug({
|
|
7323
|
-
participants,
|
|
7324
|
-
mindUsername,
|
|
7325
|
-
conversationId: opts.conversationId,
|
|
7326
|
-
...opts.slugExtra
|
|
7327
|
-
});
|
|
7328
|
-
}
|
|
7329
|
-
for (const mindName of targetMinds) {
|
|
7330
|
-
const target = opts.targetName ? opts.targetName(mindName) : mindName;
|
|
7331
|
-
const channel = slugForMind(mindName);
|
|
7332
|
-
const typingMap = getTypingMap();
|
|
7333
|
-
const currentlyTyping = typingMap.get(channel).filter((name) => participantNames.includes(name));
|
|
7334
|
-
deliverMessage(target, {
|
|
7335
|
-
content: opts.contentBlocks,
|
|
7336
|
-
channel,
|
|
7337
|
-
conversationId: opts.conversationId,
|
|
7338
|
-
sender: opts.senderName,
|
|
7339
|
-
participants: participantNames,
|
|
7340
|
-
participantCount: participants.length,
|
|
7341
|
-
isDM,
|
|
7342
|
-
...currentlyTyping.length > 0 ? { typing: currentlyTyping } : {}
|
|
7343
|
-
}).catch((err) => {
|
|
7344
|
-
logger_default.warn(`fan-out delivery failed for ${target}`, logger_default.errorData(err));
|
|
7345
|
-
});
|
|
7346
|
-
}
|
|
7347
|
-
}
|
|
7348
7415
|
var fileSchema = z10.object({
|
|
7349
7416
|
filename: z10.string(),
|
|
7350
7417
|
data: z10.string()
|
|
@@ -7506,7 +7573,15 @@ var unifiedChatApp = new Hono26().post(
|
|
|
7506
7573
|
logger_default.warn("failed to look up channel char_limit, skipping enforcement", logger_default.errorData(err));
|
|
7507
7574
|
}
|
|
7508
7575
|
}
|
|
7509
|
-
|
|
7576
|
+
let outboundTurnId;
|
|
7577
|
+
let senderBase;
|
|
7578
|
+
if (senderIsMind) {
|
|
7579
|
+
senderBase = await getBaseName(senderName);
|
|
7580
|
+
outboundTurnId = getActiveTurnId(senderBase, c.get("mindSession"));
|
|
7581
|
+
}
|
|
7582
|
+
const message = await addMessage(conversationId, "user", senderName, contentBlocks, {
|
|
7583
|
+
turnId: outboundTurnId
|
|
7584
|
+
});
|
|
7510
7585
|
let outboundId;
|
|
7511
7586
|
if (senderIsMind) {
|
|
7512
7587
|
routeOutboundBridge(conversationId, senderName, contentBlocks).catch((err) => {
|
|
@@ -7519,10 +7594,22 @@ var unifiedChatApp = new Hono26().post(
|
|
|
7519
7594
|
convType: conv.type,
|
|
7520
7595
|
convName
|
|
7521
7596
|
});
|
|
7597
|
+
const text = extractTextContent(contentBlocks);
|
|
7522
7598
|
try {
|
|
7523
|
-
outboundId = await recordOutbound(senderName, channel,
|
|
7524
|
-
messageId: message?.id != null ? String(message.id) : void 0
|
|
7599
|
+
outboundId = await recordOutbound(senderName, channel, text, {
|
|
7600
|
+
messageId: message?.id != null ? String(message.id) : void 0,
|
|
7601
|
+
turnId: outboundTurnId
|
|
7525
7602
|
});
|
|
7603
|
+
if (outboundTurnId) {
|
|
7604
|
+
const mindKey = senderBase ?? senderName;
|
|
7605
|
+
publish2(mindKey, {
|
|
7606
|
+
mind: mindKey,
|
|
7607
|
+
type: "outbound",
|
|
7608
|
+
channel,
|
|
7609
|
+
content: text,
|
|
7610
|
+
turnId: outboundTurnId
|
|
7611
|
+
});
|
|
7612
|
+
}
|
|
7526
7613
|
} catch (err) {
|
|
7527
7614
|
logger_default.warn(`recordOutbound failed for ${senderName}`, logger_default.errorData(err));
|
|
7528
7615
|
}
|
|
@@ -7532,6 +7619,7 @@ var unifiedChatApp = new Hono26().post(
|
|
|
7532
7619
|
conversationId,
|
|
7533
7620
|
contentBlocks,
|
|
7534
7621
|
senderName,
|
|
7622
|
+
senderIsMind: !!senderIsMind,
|
|
7535
7623
|
participants,
|
|
7536
7624
|
isDM,
|
|
7537
7625
|
slugExtra: { convType: conv.type, convName },
|
|
@@ -7920,19 +8008,21 @@ async function startDaemon(opts) {
|
|
|
7920
8008
|
const DAEMON_TOKEN_PATH = resolve17(systemDir, "daemon-token");
|
|
7921
8009
|
mkdirSync10(home, { recursive: true });
|
|
7922
8010
|
ensureSystemDir();
|
|
7923
|
-
const { migrateConfigSecrets, migrateSetupCompleted } = await import("./setup-
|
|
8011
|
+
const { migrateConfigSecrets, migrateSetupCompleted } = await import("./setup-25MMJ3J4.js");
|
|
7924
8012
|
migrateConfigSecrets();
|
|
7925
8013
|
migrateSetupCompleted();
|
|
7926
|
-
|
|
8014
|
+
const { migrateAiModelQualification } = await import("./ai-service-FBCCEYF5.js");
|
|
8015
|
+
migrateAiModelQualification();
|
|
8016
|
+
await (await import("./db-CZV62BOQ.js")).getDb();
|
|
7927
8017
|
try {
|
|
7928
|
-
const { eq:
|
|
7929
|
-
const { users: users2 } = await import("./schema-
|
|
7930
|
-
const db = await (await import("./db-
|
|
7931
|
-
await db.update(users2).set({ role: "system" }).where(
|
|
8018
|
+
const { eq: eq8, and: and6 } = await import("drizzle-orm");
|
|
8019
|
+
const { users: users2 } = await import("./schema-LRUTFOER.js");
|
|
8020
|
+
const db = await (await import("./db-CZV62BOQ.js")).getDb();
|
|
8021
|
+
await db.update(users2).set({ role: "system" }).where(and6(eq8(users2.user_type, "system"), eq8(users2.role, "user")));
|
|
7932
8022
|
} catch (err) {
|
|
7933
8023
|
logger_default.warn("failed to migrate system user role", logger_default.errorData(err));
|
|
7934
8024
|
}
|
|
7935
|
-
const { initSandbox } = await import("./sandbox-
|
|
8025
|
+
const { initSandbox } = await import("./sandbox-SJH3XOPZ.js");
|
|
7936
8026
|
await initSandbox();
|
|
7937
8027
|
try {
|
|
7938
8028
|
await syncBuiltinSkills();
|
|
@@ -7959,7 +8049,7 @@ async function startDaemon(opts) {
|
|
|
7959
8049
|
logger_default.warn("failed to ensure #system channel", logger_default.errorData(err));
|
|
7960
8050
|
}
|
|
7961
8051
|
try {
|
|
7962
|
-
const { getOrCreateSystemUser: getOrCreateSystemUser2 } = await import("./auth-
|
|
8052
|
+
const { getOrCreateSystemUser: getOrCreateSystemUser2 } = await import("./auth-3RIG6GKN.js");
|
|
7963
8053
|
await getOrCreateSystemUser2();
|
|
7964
8054
|
} catch (err) {
|
|
7965
8055
|
logger_default.warn(
|
|
@@ -7967,13 +8057,13 @@ async function startDaemon(opts) {
|
|
|
7967
8057
|
logger_default.errorData(err)
|
|
7968
8058
|
);
|
|
7969
8059
|
}
|
|
7970
|
-
const token = process.env.VOLUTE_DAEMON_TOKEN ||
|
|
7971
|
-
const { readGlobalConfig: readGlobalConfig2 } = await import("./setup-
|
|
8060
|
+
const token = process.env.VOLUTE_DAEMON_TOKEN || randomBytes2(32).toString("hex");
|
|
8061
|
+
const { readGlobalConfig: readGlobalConfig2 } = await import("./setup-25MMJ3J4.js");
|
|
7972
8062
|
const globalCfg = readGlobalConfig2();
|
|
7973
8063
|
let tls;
|
|
7974
8064
|
if (opts.tailscale || globalCfg.tailscale) {
|
|
7975
8065
|
try {
|
|
7976
|
-
const { getTailscaleTls } = await import("./tailscale-
|
|
8066
|
+
const { getTailscaleTls } = await import("./tailscale-Q7ZJL7S7.js");
|
|
7977
8067
|
const tlsConfig = await getTailscaleTls();
|
|
7978
8068
|
tls = { key: tlsConfig.key, cert: tlsConfig.cert };
|
|
7979
8069
|
logger_default.info("Tailscale HTTPS enabled", { hostname: tlsConfig.hostname });
|
|
@@ -8051,10 +8141,10 @@ async function startDaemon(opts) {
|
|
|
8051
8141
|
await Promise.all(workers);
|
|
8052
8142
|
}
|
|
8053
8143
|
try {
|
|
8054
|
-
const { isSetupComplete: isSetupComplete2 } = await import("./setup-
|
|
8144
|
+
const { isSetupComplete: isSetupComplete2 } = await import("./setup-25MMJ3J4.js");
|
|
8055
8145
|
if (isSetupComplete2()) {
|
|
8056
|
-
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-
|
|
8057
|
-
const { startSpiritFull } = await import("./mind-service-
|
|
8146
|
+
const { ensureSpiritProject, syncSpiritTemplate } = await import("./spirit-JQQHUVWR.js");
|
|
8147
|
+
const { startSpiritFull } = await import("./mind-service-ZBVUMJ5H.js");
|
|
8058
8148
|
await ensureSpiritProject();
|
|
8059
8149
|
await syncSpiritTemplate();
|
|
8060
8150
|
const spiritEntry = await findMind("volute");
|
|
@@ -8071,7 +8161,7 @@ async function startDaemon(opts) {
|
|
|
8071
8161
|
bridgeManager.startBridges(daemonPort).catch((err) => {
|
|
8072
8162
|
logger_default.warn("failed to start bridges", logger_default.errorData(err));
|
|
8073
8163
|
});
|
|
8074
|
-
import("./cloud-sync-
|
|
8164
|
+
import("./cloud-sync-FRYNWKCR.js").then(
|
|
8075
8165
|
({ consumeQueuedMessages }) => consumeQueuedMessages().catch((err) => {
|
|
8076
8166
|
logger_default.warn("failed to consume queued cloud messages", logger_default.errorData(err));
|
|
8077
8167
|
})
|
|
@@ -8079,7 +8169,7 @@ async function startDaemon(opts) {
|
|
|
8079
8169
|
logger_default.warn("failed to load cloud-sync module", logger_default.errorData(err));
|
|
8080
8170
|
});
|
|
8081
8171
|
try {
|
|
8082
|
-
const { backfillTemplateHashes, notifyVersionUpdate } = await import("./version-notify-
|
|
8172
|
+
const { backfillTemplateHashes, notifyVersionUpdate } = await import("./version-notify-DCAIXXZB.js");
|
|
8083
8173
|
backfillTemplateHashes();
|
|
8084
8174
|
notifyVersionUpdate().catch((err) => {
|
|
8085
8175
|
logger_default.warn("failed to send version update notifications", logger_default.errorData(err));
|
|
@@ -8090,6 +8180,7 @@ async function startDaemon(opts) {
|
|
|
8090
8180
|
delivery.restoreFromDb().catch((err) => {
|
|
8091
8181
|
logger_default.warn("failed to restore delivery queue", logger_default.errorData(err));
|
|
8092
8182
|
});
|
|
8183
|
+
delivery.startRedrive();
|
|
8093
8184
|
cleanExpiredSessions().catch((err) => {
|
|
8094
8185
|
logger_default.warn("failed to clean expired sessions", logger_default.errorData(err));
|
|
8095
8186
|
});
|