volute 0.48.0 → 0.50.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -328
- package/dist/{accept-KYNC5X3U.js → accept-5NK5XJB5.js} +2 -1
- package/dist/{activity-events-MIOK3IOU.js → activity-events-H7YI3BTF.js} +4 -4
- package/dist/{ai-service-643TNFPH.js → ai-service-V4CTNGI3.js} +6 -5
- package/dist/{archive-6Z4GFQPH.js → archive-ORM3ENHI.js} +3 -3
- package/dist/{auth-A4VGHADI.js → auth-DT7GY7EZ.js} +11 -7
- package/dist/{avatar-image-Y45R7LW5.js → avatar-image-QEPAP3A5.js} +4 -4
- package/dist/{backup-UDH4GMSW.js → backup-IE6PMXJO.js} +17 -18
- package/dist/{bridge-3FNSWLNQ.js → bridge-YK7NTRU5.js} +2 -1
- package/dist/{channels-SGQZHNQJ.js → channels-FSAHOQWI.js} +2 -1
- package/dist/{chat-X43VYHH2.js → chat-W5K6HCBE.js} +9 -9
- package/dist/{chunk-LTLFOSA4.js → chunk-3BAFMGCJ.js} +3 -3
- package/dist/{chunk-XVBSFLM7.js → chunk-4CN7OCJE.js} +2 -2
- package/dist/{chunk-HPGN6XRT.js → chunk-574M6I7F.js} +39 -6
- package/dist/{chunk-FJ2MZ5PH.js → chunk-5FVANDON.js} +2 -2
- package/dist/{chunk-2MJ7EOMT.js → chunk-5IIVOWSP.js} +28 -19
- package/dist/{chunk-4FCL4DVZ.js → chunk-5PKFJHCR.js} +2 -2
- package/dist/{chunk-MOERAQXH.js → chunk-5TPC4KCV.js} +38 -31
- package/dist/{chunk-YNBXEQAP.js → chunk-632FJ23O.js} +24 -20
- package/dist/{chunk-T4VS7UDW.js → chunk-636GFQNE.js} +12 -12
- package/dist/{chunk-EIQDZC43.js → chunk-6BM2I736.js} +25 -6
- package/dist/{chunk-WARH6GIV.js → chunk-74T3CEXK.js} +17 -15
- package/dist/{chunk-OQJMTHEH.js → chunk-77IZUVBB.js} +2 -2
- package/dist/{chunk-USD45JKR.js → chunk-7DXLIYPY.js} +77 -64
- package/dist/chunk-7FDWPQCU.js +289 -0
- package/dist/chunk-7OZWKHA3.js +548 -0
- package/dist/{chunk-IJPMIEVE.js → chunk-7UWXAJMK.js} +1 -1
- package/dist/{chunk-SZJCJVXV.js → chunk-7XDOTN4R.js} +2 -2
- package/dist/{chunk-YKA7DCVW.js → chunk-AFSLNUTT.js} +1 -1
- package/dist/{chunk-DGGZVZTM.js → chunk-AJWFDIEY.js} +17 -2
- package/dist/chunk-ALIVXDM4.js +1014 -0
- package/dist/chunk-CAIYV33P.js +523 -0
- package/dist/{chunk-MTRMQFCQ.js → chunk-E5S3ILVA.js} +2 -2
- package/dist/{chunk-SHKM5RGD.js → chunk-EEOMA4DX.js} +1 -1
- package/dist/chunk-EQKSRVDE.js +2857 -0
- package/dist/chunk-FNJCBRD3.js +31 -0
- package/dist/chunk-HW6Q7AMB.js +113 -0
- package/dist/chunk-JI67D7O2.js +1222 -0
- package/dist/{chunk-3YUBFTDN.js → chunk-KAEZOVP6.js} +1 -1
- package/dist/chunk-LNNI3MS4.js +54 -0
- package/dist/{chunk-BCG45AQB.js → chunk-M74I3HHF.js} +15 -5
- package/dist/chunk-MLZBBLMT.js +109 -0
- package/dist/{chunk-5T5YMX6S.js → chunk-PW65BXY5.js} +5 -0
- package/dist/{chunk-2OIYNHWO.js → chunk-QFVGPKJI.js} +1 -1
- package/dist/{chunk-T2TP6ZC6.js → chunk-QUSMYGNQ.js} +6 -0
- package/dist/{chunk-HNGFKPNS.js → chunk-SFRYRW37.js} +85 -36
- package/dist/{chunk-7KRIHYLR.js → chunk-SSNZ6ZNN.js} +2 -2
- package/dist/{chunk-HUNDXZBZ.js → chunk-TGJHGVBZ.js} +48 -19
- package/dist/{chunk-PJVPDY2Z.js → chunk-U3EJJ7JN.js} +2 -2
- package/dist/{chunk-ODDGGLM6.js → chunk-UC6BNMGT.js} +43 -13
- package/dist/{chunk-Q7HOAVFR.js → chunk-WBBKYUGF.js} +4 -6
- package/dist/{chunk-WQ46E33M.js → chunk-X67VT4QO.js} +2 -2
- package/dist/{chunk-MJRXFUMS.js → chunk-YQOYZ6G7.js} +3 -5
- package/dist/{chunk-VZRA5TYO.js → chunk-ZUG76D3P.js} +36 -6
- package/dist/cli.js +34 -27
- package/dist/{clock-CNRF6F7T.js → clock-LH7UFNLJ.js} +5 -4
- package/dist/{cloud-sync-WHKCB4CD.js → cloud-sync-IDJFVDEP.js} +23 -20
- package/dist/{config-RPSLA2HX.js → config-UGJS57VT.js} +3 -3
- package/dist/{conversations-C7IKYSHD.js → conversations-S2232Y5I.js} +9 -5
- package/dist/{create-GJKHABJB.js → create-2M7DAHQX.js} +2 -2
- package/dist/{create-VIQVP3QB.js → create-M727VUDF.js} +2 -1
- package/dist/{daemon-client-ZFY5MOAL.js → daemon-client-VVYFZI2D.js} +2 -1
- package/dist/{daemon-restart-7KUHVZIN.js → daemon-restart-2AAGYFHE.js} +6 -7
- package/dist/daemon.js +2166 -833
- package/dist/{db-FO6LXYCW.js → db-QAY45Z56.js} +2 -2
- package/dist/{delete-ESEP7NGQ.js → delete-O7PEFQDF.js} +1 -1
- package/dist/delivery-manager-B4OKWD2P.js +33 -0
- package/dist/{delivery-router-3QFG2ZEX.js → delivery-router-JE7SHYNU.js} +10 -6
- package/dist/{down-G6IADJXV.js → down-D4IRNEMJ.js} +5 -5
- package/dist/echo-text-WYAAODBV.js +39 -0
- package/dist/{env-C7Z55QCJ.js → env-ABM5IMA7.js} +8 -7
- package/dist/{env-6TGPO5WG.js → env-AZK5X4W7.js} +3 -3
- package/dist/{exec-QIFYZG4C.js → exec-2H65LMTA.js} +3 -3
- package/dist/{export-C2K3NIRD.js → export-3E3EL6W3.js} +4 -4
- package/dist/{extension-J4ZQ2GHV.js → extension-MRYJWSMV.js} +2 -1
- package/dist/{extensions-GEKF47A4.js → extensions-7KP3X6G7.js} +23 -20
- package/dist/{files-LXQSQOFG.js → files-6BMKVG5G.js} +5 -4
- package/dist/{import-SX3ZXHB4.js → import-UPNTEBBT.js} +9 -9
- package/dist/{isolation-MCT4ZYLT.js → isolation-OKDFM6WA.js} +5 -3
- package/dist/{join-34TR2GXQ.js → join-PYA36HEC.js} +1 -1
- package/dist/{list-PMUXZNAM.js → list-4BVGH7AN.js} +8 -3
- package/dist/{login-CL4IT2ED.js → login-MOXVLULE.js} +7 -6
- package/dist/{login-ARRZ4ORJ.js → login-RJJTCVR3.js} +4 -3
- package/dist/{logout-YZRMZ3O2.js → logout-BYV433X6.js} +2 -1
- package/dist/{logout-HZYJCYCA.js → logout-DWD3OQVT.js} +4 -3
- package/dist/message-delivery-3456PXB7.js +43 -0
- package/dist/migrate-thread-config-4A5LW36Z.js +90 -0
- package/dist/{mind-46AOK373.js → mind-NYRALSV2.js} +19 -19
- package/dist/{mind-activity-tracker-YVZPC4A5.js → mind-activity-tracker-L7GCYXQR.js} +5 -5
- package/dist/{mind-contacts-GV7XYL5D.js → mind-contacts-QYU4TPEA.js} +8 -7
- package/dist/{mind-history-TTGA5BHZ.js → mind-history-NXXOOTX6.js} +34 -11
- package/dist/{mind-list-OTHV4ZO4.js → mind-list-SYRA7CH5.js} +3 -2
- package/dist/{mind-profile-LUG353ZT.js → mind-profile-MRCVZPYT.js} +1 -1
- package/dist/mind-service-5TA7UJAT.js +47 -0
- package/dist/{mind-sleep-DV7KP255.js → mind-sleep-TH6BRQ5X.js} +5 -4
- package/dist/{mind-status-BJNPGXKC.js → mind-status-Z2LQFA6F.js} +3 -2
- package/dist/{mind-wake-LVTZ55EZ.js → mind-wake-LDGPRA42.js} +2 -1
- package/dist/{package-RTN2PS7O.js → package-XYSV7NUT.js} +27 -26
- package/dist/prompts-QKFPX6DQ.js +24 -0
- package/dist/{read-YSWUXYL7.js → read-ZXGUT4QC.js} +5 -3
- package/dist/{register-42VBJKTP.js → register-OX4HRSGC.js} +4 -3
- package/dist/{registry-UMMDRPRM.js → registry-4UF6OCOE.js} +10 -4
- package/dist/{reject-SXGCYN4A.js → reject-TWB4QJHG.js} +2 -1
- package/dist/{restart-YYEGZJDD.js → restart-AGEGNSYQ.js} +6 -5
- package/dist/{sandbox-5VQ454XP.js → sandbox-EGEU5GGE.js} +8 -5
- package/dist/scheduler-UV6RUJ7P.js +25 -0
- package/dist/{schema-VEVO7HG6.js → schema-C2GIPD4V.js} +3 -3
- package/dist/{seed-F2HXZQU4.js → seed-3IMBOAGK.js} +1 -1
- package/dist/{seed-check-TYD7RRZY.js → seed-check-NRJEQZST.js} +14 -5
- package/dist/{seed-cmd-MLCTGSX5.js → seed-cmd-U73XVQMI.js} +3 -3
- package/dist/{seed-create-KQ7OILWB.js → seed-create-FBLNVSUP.js} +4 -4
- package/dist/{seed-readiness-RBPGOLSZ.js → seed-readiness-QRA46ZJQ.js} +4 -5
- package/dist/{seed-sprout-HVYCFJLA.js → seed-sprout-3B4SZX7J.js} +12 -12
- package/dist/{send-TD2X5U3K.js → send-NBRZJXKX.js} +34 -12
- package/dist/{service-CVZMQYK6.js → service-XMXAXGJD.js} +4 -4
- package/dist/{service-install-VCRMFWX5.js → service-install-MOKTEG7B.js} +5 -5
- package/dist/{setup-5ECWTYKG.js → setup-CAJFOR2N.js} +12 -3
- package/dist/{setup-AE4CVUC4.js → setup-JGYAXXW7.js} +6 -7
- package/dist/{skill-UUM4JZRF.js → skill-NXIHDQCG.js} +7 -6
- package/dist/skills/dreaming/references/INSTALL.md +2 -2
- package/dist/skills/imagegen/SKILL.md +21 -4
- package/dist/skills/imagegen/scripts/imagegen.ts +124 -21
- package/dist/skills/tending/SKILL.md +7 -7
- package/dist/skills/volute-mind/SKILL.md +6 -6
- package/dist/skills/volute-mind/references/integrations.md +2 -2
- package/dist/skills/volute-mind/references/routing.md +19 -18
- package/dist/skills/volute-mind/references/variants.md +48 -14
- package/dist/{skills-B3SVDCEB.js → skills-5MSMT7PT.js} +7 -6
- package/dist/sleep-manager-LIEPO6WG.js +41 -0
- package/dist/spirit-IL5EMWYZ.js +34 -0
- package/dist/spirit-availability-YFEGJNJ2.js +42 -0
- package/dist/{split-SKZ4Y2D6.js → split-BU5VWX6P.js} +5 -2
- package/dist/{sprout-KQ43BWZJ.js → sprout-UPXGJ5HX.js} +1 -1
- package/dist/{src-YH6PQ7LJ.js → src-HGNE2XG4.js} +7 -1
- package/dist/{src-WLJE73NP.js → src-LCSOQY6Z.js} +60 -54
- package/dist/{src-JAOVXO5W.js → src-UDMJZ6MH.js} +8 -8
- package/dist/{start-O6UKK7BG.js → start-MUMNFR52.js} +4 -3
- package/dist/{status-F4PGREUU.js → status-IL67CYM4.js} +7 -6
- package/dist/{stop-UBX6X5RA.js → stop-EKERNYTX.js} +6 -5
- package/dist/system-events-A6IGCEC3.js +46 -0
- package/dist/system-install-YZSWCPDK.js +8 -0
- package/dist/{systems-JJNGQHAO.js → systems-VDRUZXNF.js} +5 -4
- package/dist/{tailscale-MCLY5GYE.js → tailscale-SJUW2ETR.js} +3 -3
- package/dist/{template-staleness-EMQORSGG.js → template-staleness-T27VCGYA.js} +4 -4
- package/dist/{turn-tracker-KLPV3PAU.js → turn-tracker-6EI2EL7G.js} +7 -7
- package/dist/{up-RVGDE6CQ.js → up-CLL4665A.js} +5 -6
- package/dist/{update-OXQEGGXD.js → update-HVAUCQPN.js} +5 -5
- package/dist/{update-check-266R4ZSY.js → update-check-2MGBBAFF.js} +3 -3
- package/dist/{upgrade-K5FIQPQD.js → upgrade-LIE46UBB.js} +1 -1
- package/dist/variant-cleanup-HJ7Z75R6.js +22 -0
- package/dist/{version-notify-73YURTFR.js → version-notify-7BUHWZNT.js} +11 -28
- package/dist/web-assets/assets/index-ClsUcXiW.js +95 -0
- package/dist/web-assets/assets/index-Dz3wTbtR.css +1 -0
- package/dist/web-assets/index.html +2 -2
- package/dist/xai-P42CRCZA.js +129 -0
- package/drizzle/0013_variant_purpose.sql +3 -0
- package/drizzle/0014_system_events.sql +26 -0
- package/drizzle/0015_rename_session_to_thread.sql +12 -0
- package/drizzle/0016_brain_to_human.sql +4 -0
- package/drizzle/0017_event_history_rows.sql +9 -0
- package/drizzle/meta/_journal.json +35 -0
- package/package.json +27 -26
- package/packages/extensions/notes/dist/ui/assets/index-BBs8pyel.js +67 -0
- package/packages/extensions/notes/dist/ui/index.html +1 -1
- package/packages/extensions/pages/dist/ui/assets/index-B589e8Xe.js +2 -0
- package/packages/extensions/pages/dist/ui/index.html +1 -1
- package/packages/extensions/plan/dist/ui/assets/index-B8s8wxyt.js +67 -0
- package/packages/extensions/plan/dist/ui/index.html +1 -1
- package/templates/_base/.init/.config/prompts.json +1 -0
- package/templates/_base/.init/.local/hooks/startup-context.ts +34 -2
- package/templates/_base/home/.config/routes.json +2 -2
- package/templates/_base/home/VOLUTE.md +30 -5
- package/templates/_base/src/lib/daemon-client.ts +28 -8
- package/templates/_base/src/lib/event-turn.ts +39 -0
- package/templates/_base/src/lib/format-prefix.ts +21 -2
- package/templates/_base/src/lib/router.ts +6 -2
- package/templates/_base/src/lib/routing.ts +8 -8
- package/templates/_base/src/lib/startup.ts +9 -1
- package/templates/_base/src/lib/types.ts +7 -1
- package/templates/_base/src/lib/volute-server.ts +30 -1
- package/templates/claude/.init/.config/routes.json +3 -3
- package/templates/claude/.init/CLAUDE.md +1 -1
- package/templates/claude/package.json.tmpl +4 -4
- package/templates/claude/src/agent.ts +5 -2
- package/templates/claude/src/lib/hooks/identity-reload.ts +12 -3
- package/templates/claude/src/lib/hooks/reply-instructions.ts +26 -1
- package/templates/codex/.init/.config/routes.json +3 -3
- package/templates/codex/.init/AGENTS.md +1 -1
- package/templates/codex/package.json.tmpl +4 -4
- package/templates/codex/src/agent.ts +11 -11
- package/templates/codex/src/lib/turn-context.ts +51 -0
- package/templates/pi/.init/.config/routes.json +3 -3
- package/templates/pi/.init/MINDS.md +1 -1
- package/templates/pi/package.json.tmpl +6 -6
- package/templates/pi/src/agent.ts +9 -1
- package/templates/pi/src/lib/event-handler.ts +47 -6
- package/templates/pi/src/lib/reply-instructions-extension.ts +28 -1
- package/dist/chunk-5KXCM5AW.js +0 -169
- package/dist/chunk-IYCV34IU.js +0 -158
- package/dist/chunk-VB2QXUJQ.js +0 -5260
- package/dist/chunk-WW6C3PLV.js +0 -280
- package/dist/delivery-manager-HZTT5SJR.js +0 -36
- package/dist/echo-text-H3SH337Q.js +0 -36
- package/dist/message-delivery-GPQ5SE5N.js +0 -40
- package/dist/mind-service-2ARGJNKP.js +0 -44
- package/dist/notices-2KU5NTRY.js +0 -25
- package/dist/scheduler-I7JZCT47.js +0 -34
- package/dist/sleep-manager-Z27R3WTW.js +0 -38
- package/dist/spirit-WXS3HCLN.js +0 -25
- package/dist/system-chat-63ABFF6V.js +0 -40
- package/dist/web-assets/assets/index-WdZ60R6c.css +0 -1
- package/dist/web-assets/assets/index-taX6Ezfa.js +0 -92
- package/packages/extensions/notes/dist/ui/assets/index-D0-DgYyj.js +0 -67
- package/packages/extensions/pages/dist/ui/assets/index-DtzftuPA.js +0 -2
- package/packages/extensions/plan/dist/ui/assets/index-Cfzs-0G9.js +0 -67
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
logger_default
|
|
4
|
+
} from "./chunk-QUSMYGNQ.js";
|
|
2
5
|
import {
|
|
3
6
|
readGlobalConfig,
|
|
4
7
|
writeGlobalConfig
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import {
|
|
7
|
-
logger_default
|
|
8
|
-
} from "./chunk-T2TP6ZC6.js";
|
|
8
|
+
} from "./chunk-CAIYV33P.js";
|
|
9
9
|
|
|
10
10
|
// packages/daemon/src/lib/ai-service.ts
|
|
11
11
|
import { defaultProviderAuthContext } from "@earendil-works/pi-ai";
|
|
@@ -133,7 +133,7 @@ async function missingCredentialWarning(template, model, mindName) {
|
|
|
133
133
|
const envVar = PROVIDER_ENV_VAR[provider] ?? `${provider.toUpperCase().replace(/-/g, "_")}_API_KEY`;
|
|
134
134
|
if (await resolveApiKey(provider)) return null;
|
|
135
135
|
if (provider === "openai-codex" && process.env.OPENAI_API_KEY) return null;
|
|
136
|
-
const { loadMergedEnv } = await import("./env-
|
|
136
|
+
const { loadMergedEnv } = await import("./env-AZK5X4W7.js");
|
|
137
137
|
if (loadMergedEnv(mindName)[envVar]) return null;
|
|
138
138
|
return `No ${provider} credentials are configured, so ${mindName} will start but stay silent until a key is available. Set one with \`volute env set ${envVar} <key> --mind ${mindName}\`, or configure the ${provider} provider in the web dashboard (Settings \u2192 Providers).`;
|
|
139
139
|
}
|
|
@@ -299,25 +299,28 @@ async function getAvailableModels() {
|
|
|
299
299
|
}
|
|
300
300
|
return result;
|
|
301
301
|
}
|
|
302
|
-
async function
|
|
302
|
+
async function resolveOAuthCredentials(providerId) {
|
|
303
303
|
const ai = getAiConfig();
|
|
304
304
|
const providerConfig = ai?.providers[providerId];
|
|
305
|
-
if (providerConfig?.oauth)
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
saveProviderConfig(providerId, { ...providerConfig, oauth: result.newCredentials });
|
|
313
|
-
fireProviderRefreshHook(providerId);
|
|
314
|
-
}
|
|
315
|
-
return result.apiKey;
|
|
316
|
-
}
|
|
317
|
-
} catch (err) {
|
|
318
|
-
aiLog.warn(`OAuth key resolution failed for ${providerId}`, logger_default.errorData(err));
|
|
305
|
+
if (!providerConfig?.oauth) return void 0;
|
|
306
|
+
try {
|
|
307
|
+
const result = await getOAuthApiKey(providerId, { [providerId]: providerConfig.oauth });
|
|
308
|
+
if (!result) return void 0;
|
|
309
|
+
if (result.newCredentials.access !== providerConfig.oauth.access) {
|
|
310
|
+
saveProviderConfig(providerId, { ...providerConfig, oauth: result.newCredentials });
|
|
311
|
+
fireProviderRefreshHook(providerId);
|
|
319
312
|
}
|
|
313
|
+
return result.newCredentials;
|
|
314
|
+
} catch (err) {
|
|
315
|
+
aiLog.warn(`OAuth credential resolution failed for ${providerId}`, logger_default.errorData(err));
|
|
316
|
+
return void 0;
|
|
320
317
|
}
|
|
318
|
+
}
|
|
319
|
+
async function resolveApiKey(providerId) {
|
|
320
|
+
const ai = getAiConfig();
|
|
321
|
+
const providerConfig = ai?.providers[providerId];
|
|
322
|
+
const oauthCreds = await resolveOAuthCredentials(providerId);
|
|
323
|
+
if (oauthCreds) return oauthCreds.access;
|
|
321
324
|
return resolveProviderKey(providerId, providerConfig?.apiKey);
|
|
322
325
|
}
|
|
323
326
|
function qualifyModelId(modelId) {
|
|
@@ -418,6 +421,7 @@ export {
|
|
|
418
421
|
removeCustomModel,
|
|
419
422
|
buildCustomModel,
|
|
420
423
|
getAvailableModels,
|
|
424
|
+
resolveOAuthCredentials,
|
|
421
425
|
resolveApiKey,
|
|
422
426
|
qualifyModelId,
|
|
423
427
|
unqualifyModelId,
|
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
import {
|
|
3
3
|
findBridgeForChannel,
|
|
4
4
|
getBridgeConfig
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-7XDOTN4R.js";
|
|
6
6
|
import {
|
|
7
7
|
recordOutbound
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import {
|
|
10
|
-
publish
|
|
11
|
-
} from "./chunk-USD45JKR.js";
|
|
8
|
+
} from "./chunk-EQKSRVDE.js";
|
|
12
9
|
import {
|
|
13
10
|
getOrCreateMindUser,
|
|
14
11
|
getUserByUsername
|
|
15
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-UC6BNMGT.js";
|
|
13
|
+
import {
|
|
14
|
+
publish
|
|
15
|
+
} from "./chunk-LNNI3MS4.js";
|
|
16
16
|
import {
|
|
17
17
|
addMessage,
|
|
18
18
|
findDMConversation,
|
|
@@ -20,27 +20,27 @@ import {
|
|
|
20
20
|
getChannelName,
|
|
21
21
|
getConversation,
|
|
22
22
|
getParticipants
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-574M6I7F.js";
|
|
24
24
|
import {
|
|
25
25
|
readVoluteConfig
|
|
26
26
|
} from "./chunk-WCFSBH33.js";
|
|
27
27
|
import {
|
|
28
28
|
daemonConfigPath,
|
|
29
29
|
readDaemonToken
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-5FVANDON.js";
|
|
31
31
|
import {
|
|
32
32
|
readEnv,
|
|
33
33
|
sharedEnvPath
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-7UWXAJMK.js";
|
|
35
35
|
import {
|
|
36
36
|
logger_default
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-QUSMYGNQ.js";
|
|
38
38
|
import {
|
|
39
39
|
buildVoluteSlug
|
|
40
40
|
} from "./chunk-LGNUFVMR.js";
|
|
41
41
|
import {
|
|
42
42
|
mindDir
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-CAIYV33P.js";
|
|
44
44
|
import {
|
|
45
45
|
__export
|
|
46
46
|
} from "./chunk-K3NQKI34.js";
|
|
@@ -595,7 +595,7 @@ async function send4(env, channelSlug, message, images) {
|
|
|
595
595
|
};
|
|
596
596
|
if (token) headers.Authorization = `Bearer ${token}`;
|
|
597
597
|
const voluteSession = env.VOLUTE_SESSION || (env.VOLUTE_MIND_DIR ? readSessionFile(env.VOLUTE_MIND_DIR) : void 0);
|
|
598
|
-
if (voluteSession) headers["X-Volute-
|
|
598
|
+
if (voluteSession) headers["X-Volute-Thread"] = voluteSession;
|
|
599
599
|
const res = await fetch(`${url}/api/v1/chat`, {
|
|
600
600
|
method: "POST",
|
|
601
601
|
headers,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
logger_default
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-QUSMYGNQ.js";
|
|
5
5
|
import {
|
|
6
6
|
mindDir
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-CAIYV33P.js";
|
|
8
8
|
|
|
9
9
|
// packages/daemon/src/lib/delivery/delivery-router.ts
|
|
10
10
|
import { readFileSync, statSync } from "fs";
|
|
@@ -63,6 +63,7 @@ function getRoutingConfig(mindName) {
|
|
|
63
63
|
try {
|
|
64
64
|
const config = JSON.parse(readFileSync(path, "utf-8"));
|
|
65
65
|
const changed = cached != null && cached.mtime !== mtime;
|
|
66
|
+
warnUnknownRuleKeys(mindName, config);
|
|
66
67
|
configCache.set(mindName, { config, mtime });
|
|
67
68
|
if (changed) notifyRoutesChanged(mindName);
|
|
68
69
|
return config;
|
|
@@ -94,7 +95,20 @@ function globMatch(pattern, value) {
|
|
|
94
95
|
return regex.test(value);
|
|
95
96
|
}
|
|
96
97
|
var GLOB_MATCH_KEYS = /* @__PURE__ */ new Set(["channel", "sender"]);
|
|
97
|
-
var NON_MATCH_KEYS = /* @__PURE__ */ new Set(["
|
|
98
|
+
var NON_MATCH_KEYS = /* @__PURE__ */ new Set(["thread", "destination", "path", "mode", "batch"]);
|
|
99
|
+
var KNOWN_RULE_KEYS = /* @__PURE__ */ new Set([...GLOB_MATCH_KEYS, ...NON_MATCH_KEYS, "isDM", "participants"]);
|
|
100
|
+
function warnUnknownRuleKeys(mindName, config) {
|
|
101
|
+
if (!Array.isArray(config.rules)) return;
|
|
102
|
+
for (const rule of config.rules) {
|
|
103
|
+
if (rule == null || typeof rule !== "object") continue;
|
|
104
|
+
const unknown = Object.keys(rule).filter((k) => !KNOWN_RULE_KEYS.has(k));
|
|
105
|
+
if (unknown.length > 0) {
|
|
106
|
+
dlog.warn(
|
|
107
|
+
`routes.json for ${mindName} has a rule with unrecognized key(s) ${unknown.map((k) => `"${k}"`).join(", ")} \u2014 the rule will never match (known keys: ${[...KNOWN_RULE_KEYS].join(", ")})`
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
98
112
|
function ruleMatches(rule, meta) {
|
|
99
113
|
for (const [key, pattern] of Object.entries(rule)) {
|
|
100
114
|
if (NON_MATCH_KEYS.has(key)) continue;
|
|
@@ -137,7 +151,7 @@ function resolveRoute(config, meta) {
|
|
|
137
151
|
}
|
|
138
152
|
return {
|
|
139
153
|
destination: "mind",
|
|
140
|
-
session: sanitizeSessionName(expandTemplate(rule.
|
|
154
|
+
session: sanitizeSessionName(expandTemplate(rule.thread ?? fallback, meta)),
|
|
141
155
|
matched: true,
|
|
142
156
|
mode: rule.mode,
|
|
143
157
|
rule
|
|
@@ -146,6 +160,9 @@ function resolveRoute(config, meta) {
|
|
|
146
160
|
}
|
|
147
161
|
return { destination: "mind", session: fallback, matched: false };
|
|
148
162
|
}
|
|
163
|
+
function shouldGate(config, route) {
|
|
164
|
+
return route.destination === "mind" && !route.matched && config.gateUnmatched !== false;
|
|
165
|
+
}
|
|
149
166
|
var DEFAULT_BATCH_DEBOUNCE = 5;
|
|
150
167
|
var DEFAULT_BATCH_MAX_WAIT = 120;
|
|
151
168
|
function normalizeBatchConfig(batch) {
|
|
@@ -157,7 +174,7 @@ function resolveDeliveryMode(config, sessionName, rule) {
|
|
|
157
174
|
const defaults = {
|
|
158
175
|
delivery: { mode: "immediate" }
|
|
159
176
|
};
|
|
160
|
-
if (!config.
|
|
177
|
+
if (!config.threads) {
|
|
161
178
|
if (ruleBatch != null) {
|
|
162
179
|
const batch = normalizeBatchConfig(ruleBatch);
|
|
163
180
|
return {
|
|
@@ -171,7 +188,7 @@ function resolveDeliveryMode(config, sessionName, rule) {
|
|
|
171
188
|
}
|
|
172
189
|
return defaults;
|
|
173
190
|
}
|
|
174
|
-
for (const [pattern, sessionConfig] of Object.entries(config.
|
|
191
|
+
for (const [pattern, sessionConfig] of Object.entries(config.threads)) {
|
|
175
192
|
if (globMatch(pattern, sessionName)) {
|
|
176
193
|
let delivery;
|
|
177
194
|
if (sessionConfig.delivery == null || sessionConfig.delivery === "immediate") {
|
|
@@ -216,6 +233,8 @@ export {
|
|
|
216
233
|
registerMindDir,
|
|
217
234
|
getRoutingConfig,
|
|
218
235
|
clearConfigCache,
|
|
236
|
+
warnUnknownRuleKeys,
|
|
219
237
|
resolveRoute,
|
|
238
|
+
shouldGate,
|
|
220
239
|
resolveDeliveryMode
|
|
221
240
|
};
|
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
import {
|
|
3
3
|
compactDateTime,
|
|
4
4
|
isCompact
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import {
|
|
7
|
-
getClient,
|
|
8
|
-
urlOf
|
|
9
|
-
} from "./chunk-LOPXTW6H.js";
|
|
5
|
+
} from "./chunk-PW65BXY5.js";
|
|
10
6
|
import {
|
|
11
7
|
resolveMindName
|
|
12
8
|
} from "./chunk-BTY4WNFE.js";
|
|
13
9
|
import {
|
|
14
10
|
daemonFetch
|
|
15
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-M74I3HHF.js";
|
|
12
|
+
import {
|
|
13
|
+
getClient,
|
|
14
|
+
urlOf
|
|
15
|
+
} from "./chunk-LOPXTW6H.js";
|
|
16
16
|
import {
|
|
17
17
|
command,
|
|
18
18
|
subcommands
|
|
@@ -114,18 +114,20 @@ var listSchedulesCmd = command({
|
|
|
114
114
|
console.log("No schedules configured.");
|
|
115
115
|
return;
|
|
116
116
|
}
|
|
117
|
+
const compact = isCompact();
|
|
118
|
+
const fmtTime = (s) => compact ? compactDateTime(s) : new Date(s).toLocaleString();
|
|
119
|
+
const scheduleOf = (s) => s.cron ?? (s.fireAt ? `at ${fmtTime(s.fireAt)}` : "");
|
|
117
120
|
const actionLabel = (s) => s.script ? `[script] ${s.script}` : s.messages?.length ? `[rotating x${s.messages.length}] ${s.messages[0]}` : s.message ?? "";
|
|
118
|
-
if (
|
|
121
|
+
if (compact) {
|
|
119
122
|
for (const s of schedules) {
|
|
120
|
-
|
|
121
|
-
console.log(`${s.id} ${sched} ${actionLabel(s)}`);
|
|
123
|
+
console.log(`${s.id} ${scheduleOf(s)} ${actionLabel(s)}`);
|
|
122
124
|
}
|
|
123
125
|
} else {
|
|
124
126
|
const idW = Math.max(2, ...schedules.map((s) => s.id.length));
|
|
125
|
-
const schedW = Math.max(8, ...schedules.map((s) => (s
|
|
127
|
+
const schedW = Math.max(8, ...schedules.map((s) => scheduleOf(s).length));
|
|
126
128
|
console.log(`${"ID".padEnd(idW)} ${"SCHEDULE".padEnd(schedW)} ENABLED ACTION`);
|
|
127
129
|
for (const s of schedules) {
|
|
128
|
-
const sched =
|
|
130
|
+
const sched = scheduleOf(s);
|
|
129
131
|
console.log(
|
|
130
132
|
`${s.id.padEnd(idW)} ${sched.padEnd(schedW)} ${String(s.enabled).padEnd(7)} ${actionLabel(s)}`
|
|
131
133
|
);
|
|
@@ -143,7 +145,7 @@ var addScheduleCmd = command({
|
|
|
143
145
|
message: { type: "string", description: "Message to send" },
|
|
144
146
|
script: { type: "string", description: "Script to run" },
|
|
145
147
|
id: { type: "string", description: "Unique name for this schedule (required)" },
|
|
146
|
-
|
|
148
|
+
thread: { type: "string", description: "Thread name" },
|
|
147
149
|
"while-sleeping": {
|
|
148
150
|
type: "string",
|
|
149
151
|
description: "Behavior during sleep (skip, queue, trigger-wake)"
|
|
@@ -192,7 +194,7 @@ var addScheduleCmd = command({
|
|
|
192
194
|
if (flags.message) body.message = flags.message;
|
|
193
195
|
if (flags.script) body.script = flags.script;
|
|
194
196
|
if (flags.id) body.id = flags.id;
|
|
195
|
-
if (flags.
|
|
197
|
+
if (flags.thread) body.thread = flags.thread;
|
|
196
198
|
if (flags["while-sleeping"]) {
|
|
197
199
|
const ws = flags["while-sleeping"];
|
|
198
200
|
if (!["skip", "queue", "trigger-wake"].includes(ws)) {
|
|
@@ -277,11 +279,11 @@ var cmd = subcommands({
|
|
|
277
279
|
},
|
|
278
280
|
sleep: {
|
|
279
281
|
description: "Put a mind to sleep",
|
|
280
|
-
run: (args) => import("./mind-sleep-
|
|
282
|
+
run: (args) => import("./mind-sleep-TH6BRQ5X.js").then((m) => m.run(args))
|
|
281
283
|
},
|
|
282
284
|
wake: {
|
|
283
285
|
description: "Wake a sleeping mind",
|
|
284
|
-
run: (args) => import("./mind-wake-
|
|
286
|
+
run: (args) => import("./mind-wake-LDGPRA42.js").then((m) => m.run(args))
|
|
285
287
|
}
|
|
286
288
|
},
|
|
287
289
|
footer: "Use --mind <name> or VOLUTE_MIND to identify the mind."
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
setBridgeConfig
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-7XDOTN4R.js";
|
|
5
5
|
import {
|
|
6
6
|
readEnv,
|
|
7
7
|
sharedEnvPath,
|
|
8
8
|
writeEnv
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-7UWXAJMK.js";
|
|
10
10
|
|
|
11
11
|
// packages/daemon/src/lib/template/import-utils.ts
|
|
12
12
|
import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from "fs";
|
|
@@ -1,74 +1,33 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
publish
|
|
4
|
+
} from "./chunk-LNNI3MS4.js";
|
|
2
5
|
import {
|
|
3
6
|
getPrompt
|
|
4
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-5TPC4KCV.js";
|
|
5
8
|
import {
|
|
6
9
|
aiCompleteUtility
|
|
7
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-632FJ23O.js";
|
|
8
11
|
import {
|
|
9
12
|
logger_default
|
|
10
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-QUSMYGNQ.js";
|
|
11
14
|
import {
|
|
12
15
|
getDb
|
|
13
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-CAIYV33P.js";
|
|
14
17
|
import {
|
|
15
18
|
messages,
|
|
16
19
|
mindHistory,
|
|
17
20
|
summaries,
|
|
18
21
|
turns
|
|
19
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-5IIVOWSP.js";
|
|
20
23
|
|
|
21
24
|
// packages/daemon/src/lib/daemon/turn-tracker.ts
|
|
22
25
|
import { randomUUID } from "crypto";
|
|
23
|
-
import { and as and2, eq as eq2, sql as sql2 } from "drizzle-orm";
|
|
26
|
+
import { and as and2, eq as eq2, inArray as inArray2, sql as sql2 } from "drizzle-orm";
|
|
24
27
|
|
|
25
28
|
// packages/daemon/src/lib/daemon/summarizer.ts
|
|
26
29
|
import { and, desc, eq, gte, inArray, like, lt, sql } from "drizzle-orm";
|
|
27
30
|
|
|
28
|
-
// packages/daemon/src/lib/events/mind-events.ts
|
|
29
|
-
var subscribers = /* @__PURE__ */ new Map();
|
|
30
|
-
var globalSubscribers = /* @__PURE__ */ new Set();
|
|
31
|
-
function subscribe(mind, callback) {
|
|
32
|
-
let set = subscribers.get(mind);
|
|
33
|
-
if (!set) {
|
|
34
|
-
set = /* @__PURE__ */ new Set();
|
|
35
|
-
subscribers.set(mind, set);
|
|
36
|
-
}
|
|
37
|
-
set.add(callback);
|
|
38
|
-
return () => {
|
|
39
|
-
set.delete(callback);
|
|
40
|
-
if (set.size === 0) subscribers.delete(mind);
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
function subscribeAll(callback) {
|
|
44
|
-
globalSubscribers.add(callback);
|
|
45
|
-
return () => {
|
|
46
|
-
globalSubscribers.delete(callback);
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
function publish(mind, event) {
|
|
50
|
-
const set = subscribers.get(mind);
|
|
51
|
-
if (set) {
|
|
52
|
-
for (const cb of set) {
|
|
53
|
-
try {
|
|
54
|
-
cb(event);
|
|
55
|
-
} catch (err) {
|
|
56
|
-
logger_default.error(`[mind-events] subscriber threw for ${mind}`, logger_default.errorData(err));
|
|
57
|
-
set.delete(cb);
|
|
58
|
-
if (set.size === 0) subscribers.delete(mind);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
for (const cb of globalSubscribers) {
|
|
63
|
-
try {
|
|
64
|
-
cb(event);
|
|
65
|
-
} catch (err) {
|
|
66
|
-
logger_default.error("[mind-events] global subscriber threw", logger_default.errorData(err));
|
|
67
|
-
globalSubscribers.delete(cb);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
31
|
// packages/daemon/src/lib/util/format-tool.ts
|
|
73
32
|
function summarizeTool(name, input) {
|
|
74
33
|
if (input && typeof input === "object") {
|
|
@@ -166,6 +125,33 @@ function utcDateTimeStr(d) {
|
|
|
166
125
|
function parseUtcDateTime(s) {
|
|
167
126
|
return /* @__PURE__ */ new Date(`${s.replace(" ", "T")}Z`);
|
|
168
127
|
}
|
|
128
|
+
function getUtcTimeRange(periodKey, period) {
|
|
129
|
+
switch (period) {
|
|
130
|
+
case "hour": {
|
|
131
|
+
const d = /* @__PURE__ */ new Date(`${periodKey.slice(0, 10)}T${periodKey.slice(11)}:00:00`);
|
|
132
|
+
return { start: utcDateTimeStr(d), end: utcDateTimeStr(new Date(d.getTime() + 36e5)) };
|
|
133
|
+
}
|
|
134
|
+
case "day": {
|
|
135
|
+
const d = /* @__PURE__ */ new Date(`${periodKey}T00:00:00`);
|
|
136
|
+
const dEnd = new Date(d);
|
|
137
|
+
dEnd.setDate(d.getDate() + 1);
|
|
138
|
+
return { start: utcDateTimeStr(d), end: utcDateTimeStr(dEnd) };
|
|
139
|
+
}
|
|
140
|
+
case "week": {
|
|
141
|
+
const monday = isoWeekToDate(periodKey);
|
|
142
|
+
const nextMonday = new Date(monday);
|
|
143
|
+
nextMonday.setDate(monday.getDate() + 7);
|
|
144
|
+
return { start: utcDateTimeStr(monday), end: utcDateTimeStr(nextMonday) };
|
|
145
|
+
}
|
|
146
|
+
case "month": {
|
|
147
|
+
const [y, m] = periodKey.split("-").map(Number);
|
|
148
|
+
return {
|
|
149
|
+
start: utcDateTimeStr(new Date(y, m - 1, 1)),
|
|
150
|
+
end: utcDateTimeStr(new Date(y, m, 1))
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
169
155
|
function getTimeRange(periodKey, period) {
|
|
170
156
|
switch (period) {
|
|
171
157
|
case "hour": {
|
|
@@ -206,19 +192,19 @@ async function gatherTurnEvents(mind, session, doneId) {
|
|
|
206
192
|
eq(mindHistory.type, "done"),
|
|
207
193
|
lt(mindHistory.id, doneId)
|
|
208
194
|
];
|
|
209
|
-
if (session) subConditions.push(eq(mindHistory.
|
|
195
|
+
if (session) subConditions.push(eq(mindHistory.thread, session));
|
|
210
196
|
const prevDoneSubquery = db.select({ id: mindHistory.id }).from(mindHistory).where(and(...subConditions)).orderBy(desc(mindHistory.id)).limit(1);
|
|
211
197
|
const turnConditions = [
|
|
212
198
|
eq(mindHistory.mind, mind),
|
|
213
199
|
sql`${mindHistory.id} > COALESCE((${prevDoneSubquery}), 0)`,
|
|
214
200
|
sql`${mindHistory.id} <= ${doneId}`
|
|
215
201
|
];
|
|
216
|
-
if (session) turnConditions.push(eq(mindHistory.
|
|
202
|
+
if (session) turnConditions.push(eq(mindHistory.thread, session));
|
|
217
203
|
const events = await db.select({
|
|
218
204
|
id: mindHistory.id,
|
|
219
205
|
type: mindHistory.type,
|
|
220
206
|
channel: mindHistory.channel,
|
|
221
|
-
session: mindHistory.
|
|
207
|
+
session: mindHistory.thread,
|
|
222
208
|
content: mindHistory.content,
|
|
223
209
|
metadata: mindHistory.metadata,
|
|
224
210
|
turn_id: mindHistory.turn_id,
|
|
@@ -236,7 +222,7 @@ async function gatherTurnEventsByTurnId(turnId) {
|
|
|
236
222
|
id: mindHistory.id,
|
|
237
223
|
type: mindHistory.type,
|
|
238
224
|
channel: mindHistory.channel,
|
|
239
|
-
session: mindHistory.
|
|
225
|
+
session: mindHistory.thread,
|
|
240
226
|
content: mindHistory.content,
|
|
241
227
|
metadata: mindHistory.metadata,
|
|
242
228
|
turn_id: mindHistory.turn_id,
|
|
@@ -266,11 +252,16 @@ function buildTurnDeterministicSummary(events, parsedMeta) {
|
|
|
266
252
|
const tools = [];
|
|
267
253
|
let hasInbound = false;
|
|
268
254
|
let hasOutbound = false;
|
|
255
|
+
let eventLabel;
|
|
269
256
|
for (const ev of events) {
|
|
270
257
|
if (ev.type === "inbound") {
|
|
271
258
|
hasInbound = true;
|
|
272
259
|
if (ev.channel) channels.add(ev.channel);
|
|
273
260
|
}
|
|
261
|
+
if (ev.type === "event") {
|
|
262
|
+
const label = parsedMeta.get(ev.id)?.label;
|
|
263
|
+
eventLabel = typeof label === "string" && label ? label : "System event";
|
|
264
|
+
}
|
|
274
265
|
if (ev.type === "outbound" || ev.type === "text") {
|
|
275
266
|
hasOutbound = true;
|
|
276
267
|
}
|
|
@@ -280,6 +271,9 @@ function buildTurnDeterministicSummary(events, parsedMeta) {
|
|
|
280
271
|
}
|
|
281
272
|
}
|
|
282
273
|
const parts = [];
|
|
274
|
+
if (eventLabel) {
|
|
275
|
+
parts.push(`System event: ${eventLabel}`);
|
|
276
|
+
}
|
|
283
277
|
if (hasInbound) {
|
|
284
278
|
const channelList = [...channels];
|
|
285
279
|
parts.push(
|
|
@@ -302,6 +296,16 @@ function buildTranscript(events, parsedMeta) {
|
|
|
302
296
|
case "inbound":
|
|
303
297
|
lines.push(`[inbound${ev.channel ? ` ${ev.channel}` : ""}] ${ev.content ?? ""}`);
|
|
304
298
|
break;
|
|
299
|
+
// A system event is what triggered the turn — the summarizer needs to see it, or a
|
|
300
|
+
// schedule/orientation/wake turn gets summarized from its tool calls alone, with no
|
|
301
|
+
// idea what prompted them. Framed as an event, not an inbound message: it has no
|
|
302
|
+
// sender, and the summary shouldn't imply someone spoke to the mind.
|
|
303
|
+
case "event": {
|
|
304
|
+
const label = parsedMeta.get(ev.id)?.label;
|
|
305
|
+
const named = typeof label === "string" && label ? `: ${label}` : "";
|
|
306
|
+
lines.push(`[system event${named}] ${ev.content ?? ""}`);
|
|
307
|
+
break;
|
|
308
|
+
}
|
|
305
309
|
case "outbound":
|
|
306
310
|
case "text":
|
|
307
311
|
lines.push(`[response] ${(ev.content ?? "").slice(0, 500)}`);
|
|
@@ -345,7 +349,14 @@ async function summarizeTurn(mind, session, channel, doneId, turnId) {
|
|
|
345
349
|
if (effectiveTurnId) {
|
|
346
350
|
try {
|
|
347
351
|
const db2 = await getDb();
|
|
348
|
-
await db2.update(mindHistory).set({ turn_id: null }).where(
|
|
352
|
+
await db2.update(mindHistory).set({ turn_id: null }).where(
|
|
353
|
+
and(
|
|
354
|
+
eq(mindHistory.turn_id, effectiveTurnId),
|
|
355
|
+
// Release system-event rows too, so an interrupted event turn's row can be
|
|
356
|
+
// re-linked to the turn that actually processes it.
|
|
357
|
+
inArray(mindHistory.type, ["inbound", "event"])
|
|
358
|
+
)
|
|
359
|
+
);
|
|
349
360
|
await db2.update(messages).set({ turn_id: null }).where(eq(messages.turn_id, effectiveTurnId));
|
|
350
361
|
await db2.delete(turns).where(eq(turns.id, effectiveTurnId));
|
|
351
362
|
} catch (err) {
|
|
@@ -1049,11 +1060,11 @@ var Summarizer = class {
|
|
|
1049
1060
|
}
|
|
1050
1061
|
};
|
|
1051
1062
|
async function reconcileWedgedTurns(idleMs) {
|
|
1052
|
-
const { sweepWedgedTurns: sweepWedgedTurns2, summarizeOrphanedTurns: summarizeOrphanedTurns2 } = await import("./turn-tracker-
|
|
1063
|
+
const { sweepWedgedTurns: sweepWedgedTurns2, summarizeOrphanedTurns: summarizeOrphanedTurns2 } = await import("./turn-tracker-6EI2EL7G.js");
|
|
1053
1064
|
const wedged = await sweepWedgedTurns2(idleMs);
|
|
1054
1065
|
if (wedged.length === 0) return;
|
|
1055
1066
|
summarizeOrphanedTurns2(wedged);
|
|
1056
|
-
const { tryGetDeliveryManager } = await import("./delivery-manager-
|
|
1067
|
+
const { tryGetDeliveryManager } = await import("./delivery-manager-B4OKWD2P.js");
|
|
1057
1068
|
const dm = tryGetDeliveryManager();
|
|
1058
1069
|
if (!dm) return;
|
|
1059
1070
|
for (const t of wedged) {
|
|
@@ -1112,7 +1123,8 @@ async function linkInboundToActiveTurn(mind, session, channel) {
|
|
|
1112
1123
|
await db.update(mindHistory).set({ turn_id: turnId }).where(
|
|
1113
1124
|
and2(
|
|
1114
1125
|
eq2(mindHistory.mind, mind),
|
|
1115
|
-
|
|
1126
|
+
// System events ("event") arrive mid-turn too and need the same attribution.
|
|
1127
|
+
inArray2(mindHistory.type, ["inbound", "event"]),
|
|
1116
1128
|
sql2`${mindHistory.turn_id} IS NULL`,
|
|
1117
1129
|
eq2(mindHistory.channel, channel)
|
|
1118
1130
|
)
|
|
@@ -1145,7 +1157,7 @@ async function assignSession(mind, turnId, session) {
|
|
|
1145
1157
|
}
|
|
1146
1158
|
try {
|
|
1147
1159
|
const db = await getDb();
|
|
1148
|
-
await db.update(turns).set({ session }).where(eq2(turns.id, turnId));
|
|
1160
|
+
await db.update(turns).set({ thread: session }).where(eq2(turns.id, turnId));
|
|
1149
1161
|
} catch (err) {
|
|
1150
1162
|
tlog.error(`failed to assign session to turn ${turnId}`, logger_default.errorData(err));
|
|
1151
1163
|
return;
|
|
@@ -1171,7 +1183,7 @@ async function completeTurn(mind, session) {
|
|
|
1171
1183
|
}
|
|
1172
1184
|
async function completeOrphanedTurns() {
|
|
1173
1185
|
const db = await getDb();
|
|
1174
|
-
const active = await db.select({ id: turns.id, mind: turns.mind, session: turns.
|
|
1186
|
+
const active = await db.select({ id: turns.id, mind: turns.mind, session: turns.thread }).from(turns).where(eq2(turns.status, "active"));
|
|
1175
1187
|
if (active.length === 0) return [];
|
|
1176
1188
|
try {
|
|
1177
1189
|
await db.update(turns).set({ status: "complete" }).where(eq2(turns.status, "active"));
|
|
@@ -1220,7 +1232,7 @@ async function sweepWedgedTurns(idleMs) {
|
|
|
1220
1232
|
const cutoff = new Date(Date.now() - idleMs).toISOString().slice(0, 19).replace("T", " ");
|
|
1221
1233
|
let rows;
|
|
1222
1234
|
try {
|
|
1223
|
-
rows = await db.select({ id: turns.id, mind: turns.mind, session: turns.
|
|
1235
|
+
rows = await db.select({ id: turns.id, mind: turns.mind, session: turns.thread }).from(turns).innerJoin(mindHistory, eq2(mindHistory.turn_id, turns.id)).where(eq2(turns.status, "active")).groupBy(turns.id).having(
|
|
1224
1236
|
sql2`max(${mindHistory.created_at}) < ${cutoff} and sum(case when ${mindHistory.type} = 'done' then 1 else 0 end) > 0`
|
|
1225
1237
|
);
|
|
1226
1238
|
} catch (err) {
|
|
@@ -1251,11 +1263,12 @@ function summarizeOrphanedTurns(orphanedTurns) {
|
|
|
1251
1263
|
}
|
|
1252
1264
|
|
|
1253
1265
|
export {
|
|
1254
|
-
|
|
1255
|
-
subscribeAll,
|
|
1256
|
-
publish,
|
|
1266
|
+
getPeriodKey,
|
|
1257
1267
|
isoWeekKeyForDateStr,
|
|
1258
1268
|
utcDateTimeStr,
|
|
1269
|
+
parseUtcDateTime,
|
|
1270
|
+
getUtcTimeRange,
|
|
1271
|
+
SYSTEM_MIND,
|
|
1259
1272
|
summarizeTurn,
|
|
1260
1273
|
initSummarizer,
|
|
1261
1274
|
markErrored,
|