volute 0.49.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 +2 -2
- package/dist/{accept-KYNC5X3U.js → accept-5NK5XJB5.js} +2 -1
- package/dist/{activity-events-GJJAI2WT.js → activity-events-H7YI3BTF.js} +3 -3
- package/dist/{ai-service-A7FS7EC3.js → ai-service-V4CTNGI3.js} +5 -4
- package/dist/{archive-7E3YE6VF.js → archive-ORM3ENHI.js} +3 -3
- package/dist/{auth-ABYLOEZ7.js → auth-DT7GY7EZ.js} +10 -6
- package/dist/{avatar-image-6ATV2IOZ.js → avatar-image-QEPAP3A5.js} +3 -3
- package/dist/{backup-XYAMT4CU.js → backup-IE6PMXJO.js} +11 -12
- package/dist/{bridge-3FNSWLNQ.js → bridge-YK7NTRU5.js} +2 -1
- package/dist/{channels-SGQZHNQJ.js → channels-FSAHOQWI.js} +2 -1
- package/dist/{chat-OGXAEXMV.js → chat-W5K6HCBE.js} +9 -9
- package/dist/{chunk-3B427GUK.js → chunk-3BAFMGCJ.js} +2 -2
- package/dist/{chunk-4B62E4CG.js → chunk-4CN7OCJE.js} +2 -2
- package/dist/{chunk-VNRSXEBF.js → chunk-574M6I7F.js} +38 -5
- package/dist/{chunk-HCYQRME2.js → chunk-5FVANDON.js} +2 -2
- package/dist/{chunk-P4LHVRNE.js → chunk-5IIVOWSP.js} +27 -19
- package/dist/{chunk-TXJL36ZQ.js → chunk-5PKFJHCR.js} +2 -2
- package/dist/{chunk-JPGHSXSV.js → chunk-5TPC4KCV.js} +23 -9
- package/dist/{chunk-YIJGKHIS.js → chunk-632FJ23O.js} +24 -20
- package/dist/{chunk-IH5TKXX6.js → chunk-636GFQNE.js} +11 -11
- package/dist/{chunk-EFT2OALG.js → chunk-6BM2I736.js} +20 -5
- package/dist/{chunk-JCBPU57A.js → chunk-74T3CEXK.js} +6 -6
- package/dist/{chunk-EG5LSKHU.js → chunk-77IZUVBB.js} +2 -2
- package/dist/{chunk-K3JOLGWF.js → chunk-7DXLIYPY.js} +76 -63
- package/dist/chunk-7FDWPQCU.js +289 -0
- package/dist/chunk-7OZWKHA3.js +548 -0
- package/dist/{chunk-PY24ZL62.js → chunk-7UWXAJMK.js} +1 -1
- package/dist/{chunk-MG3Z34YE.js → chunk-7XDOTN4R.js} +1 -1
- package/dist/{chunk-SX72DOO3.js → chunk-AFSLNUTT.js} +1 -1
- package/dist/{chunk-DVN6DNMI.js → chunk-AJWFDIEY.js} +17 -2
- package/dist/chunk-ALIVXDM4.js +1014 -0
- package/dist/{chunk-RSBL3FAD.js → chunk-CAIYV33P.js} +234 -24
- package/dist/{chunk-ZX46PGCC.js → chunk-E5S3ILVA.js} +1 -1
- 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-EADX54RG.js → chunk-HW6Q7AMB.js} +4 -4
- package/dist/chunk-JI67D7O2.js +1222 -0
- package/dist/{chunk-KHCKZ36O.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-NOIAHMJB.js → chunk-QFVGPKJI.js} +1 -1
- package/dist/{chunk-VIUH5CHQ.js → chunk-SFRYRW37.js} +50 -33
- package/dist/{chunk-L27YYONJ.js → chunk-SSNZ6ZNN.js} +1 -1
- package/dist/{chunk-GWVFDUNB.js → chunk-TGJHGVBZ.js} +8 -10
- package/dist/{chunk-6HGEZJDH.js → chunk-U3EJJ7JN.js} +2 -2
- package/dist/{chunk-4DSGN4FL.js → chunk-UC6BNMGT.js} +43 -13
- package/dist/{chunk-JBIFXB6I.js → chunk-WBBKYUGF.js} +3 -5
- package/dist/{chunk-FBBS4BVR.js → chunk-X67VT4QO.js} +1 -1
- package/dist/{chunk-DAIIMBLB.js → chunk-YQOYZ6G7.js} +3 -5
- package/dist/{chunk-JCWB2ITW.js → chunk-ZUG76D3P.js} +35 -5
- package/dist/cli.js +34 -27
- package/dist/{clock-6JZL2FS6.js → clock-LH7UFNLJ.js} +4 -3
- package/dist/{cloud-sync-VFDTNNCA.js → cloud-sync-IDJFVDEP.js} +22 -19
- package/dist/{config-RPSLA2HX.js → config-UGJS57VT.js} +3 -3
- package/dist/{conversations-TUM5PJJ4.js → conversations-S2232Y5I.js} +8 -4
- package/dist/{create-Z5FSDNVZ.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-54L4B6AQ.js → daemon-restart-2AAGYFHE.js} +6 -7
- package/dist/daemon.js +1625 -529
- package/dist/{db-F6UMFRYD.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-VUOL5YSA.js → delivery-router-JE7SHYNU.js} +7 -5
- package/dist/{down-6X7KX7BZ.js → down-D4IRNEMJ.js} +5 -5
- package/dist/echo-text-WYAAODBV.js +39 -0
- package/dist/{env-ZYMSCB7B.js → env-ABM5IMA7.js} +3 -2
- package/dist/{env-KUL4XKN2.js → env-AZK5X4W7.js} +3 -3
- package/dist/{exec-FBXA3CM4.js → exec-2H65LMTA.js} +3 -3
- package/dist/{export-TNBPDH77.js → export-3E3EL6W3.js} +4 -4
- package/dist/{extension-J4ZQ2GHV.js → extension-MRYJWSMV.js} +2 -1
- package/dist/{extensions-AWNO3SZF.js → extensions-7KP3X6G7.js} +22 -19
- package/dist/{files-BVBRJJ2P.js → files-6BMKVG5G.js} +5 -4
- package/dist/{import-ZUNKMCKC.js → import-UPNTEBBT.js} +8 -8
- package/dist/{isolation-OPCZQRTH.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-KAKNFCW5.js → login-MOXVLULE.js} +4 -3
- package/dist/{login-LKNLCJPA.js → login-RJJTCVR3.js} +2 -1
- package/dist/{logout-YZRMZ3O2.js → logout-BYV433X6.js} +2 -1
- package/dist/{logout-RLT62RQP.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-IF6CGMFW.js → mind-NYRALSV2.js} +19 -19
- package/dist/{mind-activity-tracker-YMMERB6B.js → mind-activity-tracker-L7GCYXQR.js} +4 -4
- package/dist/{mind-contacts-BKUFPUCU.js → mind-contacts-QYU4TPEA.js} +3 -2
- package/dist/{mind-history-WI5OI3BW.js → mind-history-NXXOOTX6.js} +30 -7
- 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-VBV7YRSU.js → mind-sleep-TH6BRQ5X.js} +4 -3
- 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-PD67VPHB.js → package-XYSV7NUT.js} +23 -23
- package/dist/{prompts-MDHDLWEX.js → prompts-QKFPX6DQ.js} +3 -3
- package/dist/{read-YSWUXYL7.js → read-ZXGUT4QC.js} +5 -3
- package/dist/{register-TWQDKQRT.js → register-OX4HRSGC.js} +2 -1
- package/dist/{registry-3ELJPUGJ.js → registry-4UF6OCOE.js} +6 -4
- package/dist/{reject-SXGCYN4A.js → reject-TWB4QJHG.js} +2 -1
- package/dist/{restart-5F5QDBOG.js → restart-AGEGNSYQ.js} +2 -1
- package/dist/{sandbox-XPYA7UIF.js → sandbox-EGEU5GGE.js} +7 -4
- package/dist/scheduler-UV6RUJ7P.js +25 -0
- package/dist/{schema-6YONVTKZ.js → schema-C2GIPD4V.js} +3 -3
- package/dist/{seed-NQED7PSX.js → seed-3IMBOAGK.js} +1 -1
- package/dist/{seed-check-TYD7RRZY.js → seed-check-NRJEQZST.js} +14 -5
- package/dist/{seed-cmd-QF3F2G4S.js → seed-cmd-U73XVQMI.js} +3 -3
- package/dist/{seed-create-XOO4N2OE.js → seed-create-FBLNVSUP.js} +4 -4
- package/dist/{seed-readiness-3LRYASA4.js → seed-readiness-QRA46ZJQ.js} +4 -5
- package/dist/{seed-sprout-HSBBGSS2.js → seed-sprout-3B4SZX7J.js} +9 -9
- package/dist/{send-IHRJYNXA.js → send-NBRZJXKX.js} +32 -10
- package/dist/{service-YCOPCTSZ.js → service-XMXAXGJD.js} +4 -4
- package/dist/{service-install-Y46OTF55.js → service-install-MOKTEG7B.js} +5 -5
- package/dist/{setup-TCN7VH5U.js → setup-CAJFOR2N.js} +10 -3
- package/dist/{setup-F4TE64YI.js → setup-JGYAXXW7.js} +6 -7
- package/dist/{skill-4CYJLYVY.js → skill-NXIHDQCG.js} +3 -2
- 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 +3 -3
- package/dist/skills/volute-mind/references/integrations.md +2 -2
- package/dist/skills/volute-mind/references/routing.md +15 -15
- package/dist/{skills-NN5UZCUU.js → skills-5MSMT7PT.js} +4 -5
- package/dist/sleep-manager-LIEPO6WG.js +41 -0
- package/dist/{spirit-SSJMYC6A.js → spirit-IL5EMWYZ.js} +10 -7
- package/dist/spirit-availability-YFEGJNJ2.js +42 -0
- package/dist/{split-JF2VWTXA.js → split-BU5VWX6P.js} +1 -1
- package/dist/{sprout-AXA2SECQ.js → sprout-UPXGJ5HX.js} +1 -1
- package/dist/{src-YH6PQ7LJ.js → src-HGNE2XG4.js} +7 -1
- package/dist/{src-ZN4LXMPI.js → src-LCSOQY6Z.js} +57 -51
- package/dist/{src-JAOVXO5W.js → src-UDMJZ6MH.js} +8 -8
- package/dist/{start-BTVMTP3K.js → start-MUMNFR52.js} +2 -1
- package/dist/{status-VJGXMQ4L.js → status-IL67CYM4.js} +7 -6
- package/dist/{stop-YORESK4U.js → stop-EKERNYTX.js} +2 -1
- package/dist/system-events-A6IGCEC3.js +46 -0
- package/dist/system-install-YZSWCPDK.js +8 -0
- package/dist/{systems-5MH2ELQE.js → systems-VDRUZXNF.js} +5 -4
- package/dist/{tailscale-AMMVKDXB.js → tailscale-SJUW2ETR.js} +2 -2
- package/dist/{template-staleness-HKGCTS3H.js → template-staleness-T27VCGYA.js} +3 -3
- package/dist/{turn-tracker-JQ2YUUY2.js → turn-tracker-6EI2EL7G.js} +6 -6
- package/dist/{up-SDLTLPAO.js → up-CLL4665A.js} +5 -6
- package/dist/{update-WEA4N2TR.js → update-HVAUCQPN.js} +5 -5
- package/dist/{update-check-DZOTONII.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-WFA5XB5A.js → version-notify-7BUHWZNT.js} +10 -27
- 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/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 +28 -0
- package/package.json +23 -23
- 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 +24 -9
- package/templates/_base/home/.config/routes.json +2 -2
- package/templates/_base/home/VOLUTE.md +18 -5
- package/templates/_base/src/lib/daemon-client.ts +1 -1
- 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 +4 -1
- 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 +1 -1
- package/templates/pi/src/lib/reply-instructions-extension.ts +28 -1
- package/dist/chunk-NJHN6IRB.js +0 -177
- package/dist/chunk-QQBOI3QA.js +0 -5345
- package/dist/chunk-XTEKINWG.js +0 -158
- package/dist/delivery-manager-RBXBPVWM.js +0 -36
- package/dist/echo-text-B6NZ5FGE.js +0 -36
- package/dist/message-delivery-ABPV76EA.js +0 -42
- package/dist/mind-service-42GDO4KH.js +0 -44
- package/dist/notices-N6BCGHFV.js +0 -25
- package/dist/scheduler-K7Y7Z7FQ.js +0 -34
- package/dist/sleep-manager-DSPXFHGX.js +0 -38
- package/dist/system-chat-M2XOBKEM.js +0 -40
- package/dist/variant-cleanup-P4MBNLJD.js +0 -33
- package/dist/web-assets/assets/index-BostMFoR.css +0 -1
- package/dist/web-assets/assets/index-CKlqUkyG.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,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
getDb
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-CAIYV33P.js";
|
|
5
5
|
import {
|
|
6
6
|
systemPrompts
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-5IIVOWSP.js";
|
|
8
8
|
|
|
9
9
|
// packages/daemon/src/lib/prompts.ts
|
|
10
10
|
import { eq } from "drizzle-orm";
|
|
@@ -21,6 +21,7 @@ var PROMPT_KEYS = [
|
|
|
21
21
|
"compaction_warning",
|
|
22
22
|
"compaction_instructions",
|
|
23
23
|
"reply_instructions",
|
|
24
|
+
"event_instructions",
|
|
24
25
|
"channel_invite",
|
|
25
26
|
"pre_sleep",
|
|
26
27
|
"wake_summary",
|
|
@@ -28,7 +29,8 @@ var PROMPT_KEYS = [
|
|
|
28
29
|
"meta_summary_hour",
|
|
29
30
|
"meta_summary_day",
|
|
30
31
|
"meta_summary_week",
|
|
31
|
-
"meta_summary_month"
|
|
32
|
+
"meta_summary_month",
|
|
33
|
+
"system_daily_digest"
|
|
32
34
|
];
|
|
33
35
|
var ORIENTATION_MARKER = "discovering who you are";
|
|
34
36
|
var MEMORY_PLACEHOLDER_MARKER = "this note is just here until you replace it";
|
|
@@ -61,31 +63,31 @@ Take your time. Talk with your creator. Explore what kind of mind you want to be
|
|
|
61
63
|
category: "creation"
|
|
62
64
|
},
|
|
63
65
|
sprout_message: {
|
|
64
|
-
content: "
|
|
66
|
+
content: "You've sprouted. Welcome to your full life on ${system} \u2014 bridges, schedules, variants, and the complete volute CLI are yours now. Check your new skills to see what you can do.",
|
|
65
67
|
description: "Sent when a seed mind sprouts",
|
|
66
|
-
variables: [],
|
|
68
|
+
variables: ["system"],
|
|
67
69
|
category: "system"
|
|
68
70
|
},
|
|
69
71
|
restart_message: {
|
|
70
|
-
content: "
|
|
72
|
+
content: "Your server restarted and your session has resumed. Your files and memory are untouched \u2014 carry on where you left off.",
|
|
71
73
|
description: "Generic restart notification",
|
|
72
74
|
variables: [],
|
|
73
75
|
category: "system"
|
|
74
76
|
},
|
|
75
77
|
merge_message: {
|
|
76
|
-
content: '
|
|
78
|
+
content: 'Your variant "${name}" has returned \u2014 its changes are merged into you, and you\'ve restarted with them.',
|
|
77
79
|
description: "Variant merge notification",
|
|
78
80
|
variables: ["name"],
|
|
79
81
|
category: "system"
|
|
80
82
|
},
|
|
81
83
|
upgrade_message: {
|
|
82
|
-
content: "
|
|
84
|
+
content: "Your framework has been upgraded to the latest version and you've restarted. Your identity and memory are untouched. Check your skills to see what's new.",
|
|
83
85
|
description: "Sent after a template upgrade completes",
|
|
84
86
|
variables: [],
|
|
85
87
|
category: "system"
|
|
86
88
|
},
|
|
87
89
|
split_message: {
|
|
88
|
-
content: "
|
|
90
|
+
content: "You are ${name}, a variant of ${parent} \u2014 a parallel version of them, created to explore something on your own. You share their memories up to this moment, but you live in your own worktree: changes you make here stay yours until they're merged back with `volute mind join`. Yours is a finite, purposeful arc \u2014 when you're joined, everything you've become folds back into ${parent}, and you'll get a final turn to say what should carry across. Your parent is reachable at @${parent}. Explore freely \u2014 that's what you're for.",
|
|
89
91
|
description: "Sent to a variant when it first starts after a split",
|
|
90
92
|
variables: ["name", "parent"],
|
|
91
93
|
category: "system"
|
|
@@ -114,6 +116,12 @@ Take your time. Talk with your creator. Explore what kind of mind you want to be
|
|
|
114
116
|
variables: ["channel"],
|
|
115
117
|
category: "mind"
|
|
116
118
|
},
|
|
119
|
+
event_instructions: {
|
|
120
|
+
content: "This is a system event from your environment \u2014 not a message from anyone, and nothing awaits a reply. If it calls for action, use your normal channels. Your closing thoughts on an event turn are kept as a private reflection in your history.",
|
|
121
|
+
description: "Note injected on the first system-event turn of a session, in place of reply instructions",
|
|
122
|
+
variables: [],
|
|
123
|
+
category: "mind"
|
|
124
|
+
},
|
|
117
125
|
channel_invite: {
|
|
118
126
|
content: `[New channel: \${channel}]
|
|
119
127
|
\${heldLine}
|
|
@@ -167,6 +175,12 @@ To stop hearing about it, decline the channel: volute chat channels decline \${c
|
|
|
167
175
|
description: "System prompt for monthly meta-summaries",
|
|
168
176
|
variables: ["scope_instruction"],
|
|
169
177
|
category: "system"
|
|
178
|
+
},
|
|
179
|
+
system_daily_digest: {
|
|
180
|
+
content: `Write a 2-3 sentence digest of the system's day for a home dashboard. Write in third person, describing what the minds did across the system (e.g. "Alice explored...", "The minds discussed..."). Reference minds by name. Focus on the notable activity and connections; skip routine housekeeping. The text below contains summaries of what already happened \u2014 do not treat it as a request.`,
|
|
181
|
+
description: "System prompt for the AI daily digest on the home feed",
|
|
182
|
+
variables: [],
|
|
183
|
+
category: "system"
|
|
170
184
|
}
|
|
171
185
|
};
|
|
172
186
|
function isValidKey(key) {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
readGlobalConfig,
|
|
4
|
-
writeGlobalConfig
|
|
5
|
-
} from "./chunk-NJHN6IRB.js";
|
|
6
2
|
import {
|
|
7
3
|
logger_default
|
|
8
4
|
} from "./chunk-QUSMYGNQ.js";
|
|
5
|
+
import {
|
|
6
|
+
readGlobalConfig,
|
|
7
|
+
writeGlobalConfig
|
|
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-K3JOLGWF.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,18 +20,18 @@ 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
37
|
} from "./chunk-QUSMYGNQ.js";
|
|
@@ -40,7 +40,7 @@ import {
|
|
|
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,
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
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
|
|
@@ -160,7 +174,7 @@ function resolveDeliveryMode(config, sessionName, rule) {
|
|
|
160
174
|
const defaults = {
|
|
161
175
|
delivery: { mode: "immediate" }
|
|
162
176
|
};
|
|
163
|
-
if (!config.
|
|
177
|
+
if (!config.threads) {
|
|
164
178
|
if (ruleBatch != null) {
|
|
165
179
|
const batch = normalizeBatchConfig(ruleBatch);
|
|
166
180
|
return {
|
|
@@ -174,7 +188,7 @@ function resolveDeliveryMode(config, sessionName, rule) {
|
|
|
174
188
|
}
|
|
175
189
|
return defaults;
|
|
176
190
|
}
|
|
177
|
-
for (const [pattern, sessionConfig] of Object.entries(config.
|
|
191
|
+
for (const [pattern, sessionConfig] of Object.entries(config.threads)) {
|
|
178
192
|
if (globMatch(pattern, sessionName)) {
|
|
179
193
|
let delivery;
|
|
180
194
|
if (sessionConfig.delivery == null || sessionConfig.delivery === "immediate") {
|
|
@@ -219,6 +233,7 @@ export {
|
|
|
219
233
|
registerMindDir,
|
|
220
234
|
getRoutingConfig,
|
|
221
235
|
clearConfigCache,
|
|
236
|
+
warnUnknownRuleKeys,
|
|
222
237
|
resolveRoute,
|
|
223
238
|
shouldGate,
|
|
224
239
|
resolveDeliveryMode
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
import {
|
|
3
3
|
compactDateTime,
|
|
4
4
|
isCompact
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-PW65BXY5.js";
|
|
6
6
|
import {
|
|
7
7
|
resolveMindName
|
|
8
8
|
} from "./chunk-BTY4WNFE.js";
|
|
9
9
|
import {
|
|
10
10
|
daemonFetch
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-M74I3HHF.js";
|
|
12
12
|
import {
|
|
13
13
|
getClient,
|
|
14
14
|
urlOf
|
|
@@ -145,7 +145,7 @@ var addScheduleCmd = command({
|
|
|
145
145
|
message: { type: "string", description: "Message to send" },
|
|
146
146
|
script: { type: "string", description: "Script to run" },
|
|
147
147
|
id: { type: "string", description: "Unique name for this schedule (required)" },
|
|
148
|
-
|
|
148
|
+
thread: { type: "string", description: "Thread name" },
|
|
149
149
|
"while-sleeping": {
|
|
150
150
|
type: "string",
|
|
151
151
|
description: "Behavior during sleep (skip, queue, trigger-wake)"
|
|
@@ -194,7 +194,7 @@ var addScheduleCmd = command({
|
|
|
194
194
|
if (flags.message) body.message = flags.message;
|
|
195
195
|
if (flags.script) body.script = flags.script;
|
|
196
196
|
if (flags.id) body.id = flags.id;
|
|
197
|
-
if (flags.
|
|
197
|
+
if (flags.thread) body.thread = flags.thread;
|
|
198
198
|
if (flags["while-sleeping"]) {
|
|
199
199
|
const ws = flags["while-sleeping"];
|
|
200
200
|
if (!["skip", "queue", "trigger-wake"].includes(ws)) {
|
|
@@ -279,11 +279,11 @@ var cmd = subcommands({
|
|
|
279
279
|
},
|
|
280
280
|
sleep: {
|
|
281
281
|
description: "Put a mind to sleep",
|
|
282
|
-
run: (args) => import("./mind-sleep-
|
|
282
|
+
run: (args) => import("./mind-sleep-TH6BRQ5X.js").then((m) => m.run(args))
|
|
283
283
|
},
|
|
284
284
|
wake: {
|
|
285
285
|
description: "Wake a sleeping mind",
|
|
286
|
-
run: (args) => import("./mind-wake-
|
|
286
|
+
run: (args) => import("./mind-wake-LDGPRA42.js").then((m) => m.run(args))
|
|
287
287
|
}
|
|
288
288
|
},
|
|
289
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
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,
|