volute 0.39.0 → 0.40.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{accept-AHAOUFBK.js → accept-IVHOHXQS.js} +1 -1
- package/dist/{activity-events-CR4RIHJT.js → activity-events-DS4QRWBY.js} +4 -4
- package/dist/{ai-service-PL7GKFQC.js → ai-service-AUWIPWLP.js} +9 -5
- package/dist/{api-client-LC5YRA32.js → api-client-NFM6GX2N.js} +1 -1
- package/dist/{archive-UEWIFRAR.js → archive-UDHFZN4G.js} +4 -4
- package/dist/{auth-OJ2YW3NR.js → auth-X6ZITZ7D.js} +5 -5
- package/dist/{bridge-F3ZJEKDN.js → bridge-MSZC4HUT.js} +1 -1
- package/dist/{chat-RQ5NV5EA.js → chat-JD3TJINV.js} +9 -9
- package/dist/{chunk-CJ26DXZL.js → chunk-2HZRJ35V.js} +17 -1
- package/dist/{chunk-QDWPM73D.js → chunk-3Y7UDHO7.js} +3 -3
- package/dist/{chunk-6V2U3GFQ.js → chunk-4UMXOMZ6.js} +2 -2
- package/dist/{chunk-7OS7QFDF.js → chunk-5EVW4KOD.js} +3 -3
- package/dist/{chunk-6FSSMAXU.js → chunk-6SYHHEQ7.js} +1 -1
- package/dist/{chunk-OEXOFBW5.js → chunk-AEAZRTEV.js} +1 -1
- package/dist/{chunk-DZ4LYU6J.js → chunk-ANSTTB55.js} +1 -1
- package/dist/{chunk-QDWP435B.js → chunk-B4WPXYPI.js} +1 -1
- package/dist/{chunk-CHCISTH7.js → chunk-BLAXARBZ.js} +511 -335
- package/dist/{chunk-TCNCRDB5.js → chunk-DNU6XLE2.js} +1 -1
- package/dist/{chunk-7W3UWCQD.js → chunk-E25SO3QW.js} +3 -3
- package/dist/{chunk-IA2SZSLB.js → chunk-I57LLNAQ.js} +1 -1
- package/dist/{chunk-WUH54G5S.js → chunk-ITH5ZLZJ.js} +1 -1
- package/dist/{chunk-QJ4GU5XT.js → chunk-JYQQDI3M.js} +2 -2
- package/dist/{chunk-EVKGKQ2P.js → chunk-KMHC36CA.js} +1 -7
- package/dist/chunk-LMMQX4CK.js +49 -0
- package/dist/{chunk-4BO4I7UF.js → chunk-LZ6CQYRO.js} +7 -7
- package/dist/{chunk-RAVQXKAG.js → chunk-MNUXL4XN.js} +67 -3
- package/dist/{chunk-OS5MRIEP.js → chunk-NERYUSER.js} +1 -1
- package/dist/{chunk-XOSAY7PY.js → chunk-PKGA23XM.js} +1 -1
- package/dist/{chunk-IBOU6Q3Y.js → chunk-QV7P3TYO.js} +5 -5
- package/dist/{chunk-7GZB3ZJP.js → chunk-QYI65HCL.js} +2 -2
- package/dist/{chunk-B7MWXFAH.js → chunk-S4SXBQ7F.js} +15 -1
- package/dist/{chunk-X7GM2OPM.js → chunk-SVXOBKQY.js} +2 -2
- package/dist/{chunk-Y5UC6G3O.js → chunk-TOANT6FD.js} +2 -2
- package/dist/{chunk-TT4WT6Y7.js → chunk-YHWGN4FX.js} +1 -1
- package/dist/{chunk-Y4W3OS7Q.js → chunk-YTNBO7S6.js} +8 -8
- package/dist/cli.js +24 -24
- package/dist/{clock-BMLJ2TR6.js → clock-YLDJUKBW.js} +3 -3
- package/dist/{cloud-sync-NQCWJLYI.js → cloud-sync-MAQCJEFJ.js} +17 -17
- package/dist/{config-QB7W3Z7P.js → config-PO4EZLIK.js} +4 -4
- package/dist/connectors/discord-bridge.js +1 -1
- package/dist/connectors/slack-bridge.js +1 -1
- package/dist/connectors/telegram-bridge.js +1 -1
- package/dist/{conversations-EUXHBWJD.js → conversations-AYLXPOGC.js} +5 -5
- package/dist/{create-3QH7DVLC.js → create-T4UJ64WB.js} +4 -4
- package/dist/{create-C3BBFYV7.js → create-ZMTGINV3.js} +1 -1
- package/dist/{daemon-client-2MIPKY3E.js → daemon-client-H6MEKK2W.js} +1 -1
- package/dist/{daemon-restart-UEB3PLKB.js → daemon-restart-LP2DR24J.js} +9 -9
- package/dist/daemon.js +424 -294
- package/dist/{db-IJL6B26S.js → db-FSYOTHSN.js} +1 -1
- package/dist/db-ZEPKEJJD.js +9 -0
- package/dist/{delete-NLXES2C7.js → delete-TXVOH2OC.js} +3 -3
- package/dist/delivery-manager-VNHLQTTO.js +30 -0
- package/dist/{delivery-router-EUW4RIWG.js → delivery-router-T6CYTS3M.js} +4 -4
- package/dist/down-6DYO2QV7.js +17 -0
- package/dist/echo-text-QFCH3H6G.js +31 -0
- package/dist/{env-IQ6Q2333.js → env-77IOWG4U.js} +1 -1
- package/dist/exec-5DGKQ5V3.js +17 -0
- package/dist/{export-JDAK3THX.js → export-TZKOCSCE.js} +6 -6
- package/dist/{extension-LZYHBNLV.js → extension-35NB6GHW.js} +1 -1
- package/dist/{extensions-V7TXKAKM.js → extensions-LQX2N7TI.js} +17 -17
- package/dist/{files-K5XV23H6.js → files-WNNVJWJB.js} +4 -4
- package/dist/{import-GZ5IYVV7.js → import-BNNFCQ7U.js} +11 -11
- package/dist/{isolation-FPF4UTH2.js → isolation-4Q4P7HRV.js} +4 -4
- package/dist/{join-6SZCA5FX.js → join-E2EJEXZO.js} +3 -3
- package/dist/{list-KHJZJPEJ.js → list-BYCEDASJ.js} +1 -1
- package/dist/{login-GYTH67ES.js → login-JNSIYFVH.js} +1 -1
- package/dist/{login-BGF5JY3I.js → login-Y6UAYQVO.js} +3 -3
- package/dist/{logout-YHQLOFLR.js → logout-M6FI62BL.js} +1 -1
- package/dist/{logout-GQHI6KH6.js → logout-VHGWVH63.js} +3 -3
- package/dist/message-delivery-7BCYJLH2.js +40 -0
- package/dist/{mind-QMJIWWWW.js → mind-ELPD6VBP.js} +19 -19
- package/dist/{mind-activity-tracker-Z3KBQTVU.js → mind-activity-tracker-XFRVGXFS.js} +5 -5
- package/dist/{mind-history-WHCNZ6I5.js → mind-history-W4JPTPTV.js} +1 -1
- package/dist/{mind-list-H3HC2ZRG.js → mind-list-QROHCLGT.js} +1 -1
- package/dist/mind-manager-EDCLALBF.js +30 -0
- package/dist/{mind-profile-7VYRJGFZ.js → mind-profile-3LNKXNPA.js} +2 -2
- package/dist/mind-service-WTOFVNLW.js +36 -0
- package/dist/{mind-sleep-ZL5ZXFTM.js → mind-sleep-PVCMLTAH.js} +1 -1
- package/dist/{mind-status-ZWULKOUO.js → mind-status-RAJFLRCN.js} +1 -1
- package/dist/{mind-wake-HK5ORGUK.js → mind-wake-HZUOVE7J.js} +1 -1
- package/dist/{package-IR4ZEQA2.js → package-GO3PHHUF.js} +28 -27
- package/dist/{read-CP7MYMJQ.js → read-OOINVR2H.js} +1 -1
- package/dist/{read-stdin-4B5UYPPM.js → read-stdin-P6HCZUAA.js} +1 -1
- package/dist/{register-XOBFEMI4.js → register-ISOH34RF.js} +1 -1
- package/dist/{registry-LWEOAO53.js → registry-GV35XFT7.js} +3 -3
- package/dist/{reject-43AGXB6B.js → reject-ZBWP62X5.js} +1 -1
- package/dist/{restart-O5QIYQJT.js → restart-QBJV5455.js} +1 -1
- package/dist/{sandbox-KUAVC37A.js → sandbox-5R32QKWQ.js} +5 -5
- package/dist/scheduler-GQBDCGLU.js +30 -0
- package/dist/{schema-K575EBPE.js → schema-LYQUDL7G.js} +4 -2
- package/dist/{seed-GPBERPXJ.js → seed-MO2C7CWC.js} +2 -2
- package/dist/{seed-check-HZPVFJKZ.js → seed-check-3WXXRHTC.js} +2 -2
- package/dist/{seed-cmd-PWF4FYFG.js → seed-cmd-ETIF4WD6.js} +4 -4
- package/dist/{seed-create-NTIICZVB.js → seed-create-BPQC2IOR.js} +6 -6
- package/dist/{seed-sprout-PRPFKGJF.js → seed-sprout-TX72K33T.js} +11 -11
- package/dist/{send-IMHDYJHW.js → send-WO3CVG73.js} +4 -4
- package/dist/{service-DWBRRFXS.js → service-WMV6R6VJ.js} +6 -6
- package/dist/service-install-W3FQXJKB.js +17 -0
- package/dist/{setup-IFYS3TLS.js → setup-OTEC3ZPM.js} +4 -4
- package/dist/{setup-4CWQ53VV.js → setup-ZTW4FVMQ.js} +9 -9
- package/dist/{skill-ICN6Y2ZF.js → skill-QHACP7EU.js} +1 -1
- package/dist/{skills-FJ5W73AV.js → skills-JEWMHIIE.js} +7 -7
- package/dist/sleep-manager-5277OBHI.js +34 -0
- package/dist/{spirit-U6MDQLYT.js → spirit-NVXWSVKM.js} +9 -9
- package/dist/{split-5YBEQTBF.js → split-7AO4IO42.js} +3 -3
- package/dist/{sprout-ABX2G76C.js → sprout-NFJZKYEW.js} +2 -2
- package/dist/{src-OYWRPLC6.js → src-2IMB3V27.js} +1 -1
- package/dist/src-OS75U2O7.js +241910 -0
- package/dist/{src-O4PRLMKM.js → src-XNUXP2FP.js} +1 -1
- package/dist/{start-LMXXRR3X.js → start-2U57BBK7.js} +1 -1
- package/dist/{status-C6BBWNU3.js → status-BRYYYO7C.js} +7 -7
- package/dist/{stop-TWDKVEUX.js → stop-QILBDUAR.js} +1 -1
- package/dist/system-chat-LQSJVY55.js +34 -0
- package/dist/{systems-Y2WZV2K4.js → systems-3XTAHA35.js} +4 -4
- package/dist/{tailscale-2KKXDMNK.js → tailscale-X4HRKRTW.js} +3 -3
- package/dist/{template-hash-SSIBEEYK.js → template-hash-DMHSLRDX.js} +1 -1
- package/dist/up-4H7TL6WB.js +19 -0
- package/dist/{update-V26PT4VN.js → update-OY2JYXYK.js} +61 -14
- package/dist/update-check-IUB7QHAF.js +24 -0
- package/dist/{upgrade-RXFZR5FI.js → upgrade-25J6AE47.js} +3 -3
- package/dist/{variant-HHDTW74J.js → variant-5LQOPCQA.js} +1 -1
- package/dist/{version-notify-ZBMY2TEX.js → version-notify-N37N2C4G.js} +18 -18
- package/dist/{volute-config-TS62GS6A.js → volute-config-7FO6QKWU.js} +1 -1
- package/dist/web-assets/assets/index-DaUp9iE2.js +79 -0
- package/dist/web-assets/assets/index-DqHSW9Fr.css +1 -0
- package/dist/web-assets/index.html +2 -2
- package/drizzle/0009_mind_notices.sql +14 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +27 -26
- package/packages/extensions/notes/dist/ui/assets/index-BbgANhFm.js +67 -0
- package/packages/extensions/notes/dist/ui/index.html +1 -1
- package/packages/extensions/pages/dist/ui/assets/index-Dxk-DYrf.js +2 -0
- package/packages/extensions/pages/dist/ui/index.html +1 -1
- package/packages/extensions/plan/dist/ui/assets/index-Cfzs-0G9.js +67 -0
- package/packages/extensions/plan/dist/ui/index.html +1 -1
- package/templates/_base/.init/.local/hooks/pre-prompt/notices.ts +46 -0
- package/templates/_base/src/lib/context-breakdown.ts +281 -126
- package/templates/_base/src/lib/daemon-client.ts +5 -2
- package/templates/_base/src/lib/transparency.ts +5 -3
- package/templates/_base/src/lib/volute-server.ts +23 -0
- package/templates/claude/package.json.tmpl +5 -5
- package/templates/claude/src/agent.ts +54 -16
- package/templates/claude/src/server.ts +1 -0
- package/templates/codex/package.json.tmpl +5 -5
- package/templates/codex/src/agent.ts +45 -12
- package/templates/codex/src/server.ts +1 -0
- package/templates/pi/package.json.tmpl +6 -6
- package/templates/pi/src/agent.ts +74 -13
- package/templates/pi/src/lib/subagents.ts +19 -17
- package/templates/pi/src/server.ts +1 -0
- package/dist/chunk-K3NQKI34.js +0 -10
- package/dist/db-32YFKMFL.js +0 -9
- package/dist/delivery-manager-N34XKUGL.js +0 -30
- package/dist/down-TCEBGTMY.js +0 -17
- package/dist/echo-text-N3BC3WNX.js +0 -31
- package/dist/exec-2MFHTGOS.js +0 -17
- package/dist/message-delivery-X7MKA3TA.js +0 -40
- package/dist/mind-manager-7GWTTKWD.js +0 -30
- package/dist/mind-service-MO2XJKJN.js +0 -36
- package/dist/scheduler-CGUPAEBA.js +0 -30
- package/dist/service-install-KEBDNZVE.js +0 -17
- package/dist/sleep-manager-6QRMUNHK.js +0 -34
- package/dist/src-6Z4XYDH5.js +0 -2164
- package/dist/system-chat-D343HYGR.js +0 -34
- package/dist/up-ZU6ILVMA.js +0 -19
- package/dist/update-check-XRERV36Y.js +0 -18
- package/dist/web-assets/assets/index-B1zwqwt8.css +0 -1
- package/dist/web-assets/assets/index-D1guJF1i.js +0 -73
- package/packages/extensions/notes/dist/ui/assets/index-Dsua7alJ.js +0 -61
- package/packages/extensions/pages/dist/ui/assets/index-BM7gRdg7.js +0 -2
- package/packages/extensions/plan/dist/ui/assets/index-DWiqtzBv.js +0 -61
|
@@ -120,12 +120,17 @@ export type ContextInfo = {
|
|
|
120
120
|
systemPrompt: number;
|
|
121
121
|
};
|
|
122
122
|
|
|
123
|
+
export type { ContextBlock, ContextMessage, ContextMessages } from "./context-breakdown.js";
|
|
124
|
+
|
|
125
|
+
import type { ContextMessages } from "./context-breakdown.js";
|
|
126
|
+
|
|
123
127
|
export function createVoluteServer(options: {
|
|
124
128
|
router: Router;
|
|
125
129
|
port: number;
|
|
126
130
|
name: string;
|
|
127
131
|
version: string;
|
|
128
132
|
getContextInfo?: () => ContextInfo | Promise<ContextInfo>;
|
|
133
|
+
getContextMessages?: () => ContextMessages | Promise<ContextMessages>;
|
|
129
134
|
}): Server {
|
|
130
135
|
const { router, port, name, version } = options;
|
|
131
136
|
|
|
@@ -162,6 +167,24 @@ export function createVoluteServer(options: {
|
|
|
162
167
|
return;
|
|
163
168
|
}
|
|
164
169
|
|
|
170
|
+
if (req.method === "GET" && url.pathname === "/context/messages") {
|
|
171
|
+
if (!options.getContextMessages) {
|
|
172
|
+
res.writeHead(404);
|
|
173
|
+
res.end("Not Found");
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
try {
|
|
177
|
+
const messages = await options.getContextMessages();
|
|
178
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
179
|
+
res.end(JSON.stringify(messages));
|
|
180
|
+
} catch (err) {
|
|
181
|
+
log("server", "error in /context/messages:", err);
|
|
182
|
+
res.writeHead(500);
|
|
183
|
+
res.end("Internal Server Error");
|
|
184
|
+
}
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
|
|
165
188
|
if (req.method === "POST" && url.pathname === "/message") {
|
|
166
189
|
try {
|
|
167
190
|
const body = JSON.parse(await readBody(req)) as VoluteRequest;
|
|
@@ -9,13 +9,13 @@
|
|
|
9
9
|
"typecheck": "tsc --noEmit"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@anthropic-ai/claude-agent-sdk": "^0.
|
|
12
|
+
"@anthropic-ai/claude-agent-sdk": "^0.3.185",
|
|
13
13
|
"@anthropic-ai/tokenizer": "^0.0.4",
|
|
14
|
-
"tsx": "^4.
|
|
14
|
+
"tsx": "^4.22.4"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@biomejs/biome": "2.
|
|
18
|
-
"@types/node": "^
|
|
19
|
-
"typescript": "^6.0.
|
|
17
|
+
"@biomejs/biome": "2.5.0",
|
|
18
|
+
"@types/node": "^26.0.0",
|
|
19
|
+
"typescript": "^6.0.3"
|
|
20
20
|
}
|
|
21
21
|
}
|
|
@@ -8,7 +8,9 @@ import {
|
|
|
8
8
|
countSkillDescriptionTokens,
|
|
9
9
|
countSystemPromptTokens,
|
|
10
10
|
findClaudeSessionFile,
|
|
11
|
-
|
|
11
|
+
processClaudeSession,
|
|
12
|
+
readSdkInstructions,
|
|
13
|
+
readSkillDescriptions,
|
|
12
14
|
} from "./lib/context-breakdown.js";
|
|
13
15
|
import { daemonEmit } from "./lib/daemon-client.js";
|
|
14
16
|
import { runHooks } from "./lib/hook-loader.js";
|
|
@@ -30,7 +32,7 @@ import type {
|
|
|
30
32
|
VoluteContentPart,
|
|
31
33
|
VoluteEvent,
|
|
32
34
|
} from "./lib/types.js";
|
|
33
|
-
import type { ContextInfo } from "./lib/volute-server.js";
|
|
35
|
+
import type { ContextInfo, ContextMessages } from "./lib/volute-server.js";
|
|
34
36
|
|
|
35
37
|
type Session = {
|
|
36
38
|
name: string;
|
|
@@ -60,6 +62,7 @@ export function createMind(options: {
|
|
|
60
62
|
resolve: HandlerResolver;
|
|
61
63
|
waitForCommits: () => Promise<void>;
|
|
62
64
|
getContextInfo: () => ContextInfo;
|
|
65
|
+
getContextMessages: () => ContextMessages;
|
|
63
66
|
} {
|
|
64
67
|
const autoCommit = createAutoCommitHook(options.cwd);
|
|
65
68
|
const identityReload = createIdentityReloadHook(options.cwd);
|
|
@@ -369,6 +372,17 @@ export function createMind(options: {
|
|
|
369
372
|
});
|
|
370
373
|
}
|
|
371
374
|
|
|
375
|
+
/**
|
|
376
|
+
* Tell the daemon this turn failed so it can record a notice for the mind's next
|
|
377
|
+
* successful turn. Awaited before emitDone so the daemon flags the session errored
|
|
378
|
+
* (and thus won't mark notices delivered) before the done arrives.
|
|
379
|
+
*/
|
|
380
|
+
async function emitError(err: unknown) {
|
|
381
|
+
await daemonEmit({ type: "error", session: session.name, content: String(err) }).catch(
|
|
382
|
+
(e) => log("mind", `session "${session.name}": failed to emit error to daemon:`, e),
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
|
|
372
386
|
async function runStream(resume?: string) {
|
|
373
387
|
const q = createStream(session, streamAbort, preCompact.hook, resume);
|
|
374
388
|
session.currentQuery = q;
|
|
@@ -428,11 +442,13 @@ export function createMind(options: {
|
|
|
428
442
|
await runStream();
|
|
429
443
|
} catch (retryErr) {
|
|
430
444
|
log("mind", `session "${session.name}": stream consumer error:`, retryErr);
|
|
445
|
+
await emitError(retryErr);
|
|
431
446
|
emitDone();
|
|
432
447
|
sessions.delete(session.name);
|
|
433
448
|
}
|
|
434
449
|
} else {
|
|
435
450
|
log("mind", `session "${session.name}": stream consumer error:`, err);
|
|
451
|
+
await emitError(err);
|
|
436
452
|
emitDone();
|
|
437
453
|
sessions.delete(session.name);
|
|
438
454
|
}
|
|
@@ -543,26 +559,24 @@ export function createMind(options: {
|
|
|
543
559
|
const claudeMdTokens = countSdkInstructionTokens(options.cwd);
|
|
544
560
|
const skillDescTokens = countSkillDescriptionTokens([resolvePath(options.cwd, ".claude/skills")]);
|
|
545
561
|
|
|
562
|
+
function processSession(sessionName: string) {
|
|
563
|
+
const sessionId = sessionStore.load(sessionName);
|
|
564
|
+
const jsonlPath = sessionId ? findClaudeSessionFile(options.cwd, sessionId) : null;
|
|
565
|
+
return jsonlPath
|
|
566
|
+
? processClaudeSession(jsonlPath, systemPromptTokens, claudeMdTokens, skillDescTokens)
|
|
567
|
+
: null;
|
|
568
|
+
}
|
|
569
|
+
|
|
546
570
|
function getContextInfo(): ContextInfo {
|
|
547
571
|
return {
|
|
548
572
|
sessions: Array.from(sessions.values()).map((s) => {
|
|
549
573
|
try {
|
|
550
|
-
const
|
|
551
|
-
const jsonlPath = sessionId ? findClaudeSessionFile(options.cwd, sessionId) : null;
|
|
552
|
-
const parsed = jsonlPath
|
|
553
|
-
? parseClaudeSessionJSONL(
|
|
554
|
-
jsonlPath,
|
|
555
|
-
systemPromptTokens,
|
|
556
|
-
claudeMdTokens,
|
|
557
|
-
skillDescTokens,
|
|
558
|
-
)
|
|
559
|
-
: null;
|
|
560
|
-
|
|
574
|
+
const result = processSession(s.name);
|
|
561
575
|
return {
|
|
562
576
|
name: s.name,
|
|
563
|
-
contextTokens: parsed?.contextTokens ?? s.contextTokens,
|
|
577
|
+
contextTokens: result?.parsed?.contextTokens ?? s.contextTokens,
|
|
564
578
|
contextWindow: maxContextTokens,
|
|
565
|
-
breakdown: parsed?.breakdown,
|
|
579
|
+
breakdown: result?.parsed?.breakdown,
|
|
566
580
|
};
|
|
567
581
|
} catch (err) {
|
|
568
582
|
log("mind", `failed to get context breakdown for session "${s.name}":`, err);
|
|
@@ -573,5 +587,29 @@ export function createMind(options: {
|
|
|
573
587
|
};
|
|
574
588
|
}
|
|
575
589
|
|
|
576
|
-
|
|
590
|
+
function getContextMessages(): ContextMessages {
|
|
591
|
+
const skillsDir = resolvePath(options.cwd, ".claude/skills");
|
|
592
|
+
return {
|
|
593
|
+
preamble: {
|
|
594
|
+
systemPrompt: options.systemPrompt,
|
|
595
|
+
sdkInstructions: readSdkInstructions(options.cwd),
|
|
596
|
+
skillDescriptions: readSkillDescriptions([skillsDir]),
|
|
597
|
+
},
|
|
598
|
+
sessions: Array.from(sessions.values()).map((s) => {
|
|
599
|
+
try {
|
|
600
|
+
const result = processSession(s.name);
|
|
601
|
+
return { name: s.name, messages: result?.messages ?? [] };
|
|
602
|
+
} catch (err) {
|
|
603
|
+
log("mind", `failed to extract messages for session "${s.name}":`, err);
|
|
604
|
+
return { name: s.name, messages: [] };
|
|
605
|
+
}
|
|
606
|
+
}),
|
|
607
|
+
};
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
// Pre-warm the main session so the SDK subprocess starts immediately
|
|
611
|
+
// instead of waiting for the first message (which adds minutes of latency).
|
|
612
|
+
getOrCreateSession("main");
|
|
613
|
+
|
|
614
|
+
return { resolve, waitForCommits: autoCommit.waitForCommits, getContextInfo, getContextMessages };
|
|
577
615
|
}
|
|
@@ -10,12 +10,12 @@
|
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@anthropic-ai/tokenizer": "^0.0.4",
|
|
13
|
-
"@openai/codex-sdk": "^0.
|
|
14
|
-
"tsx": "^4.
|
|
13
|
+
"@openai/codex-sdk": "^0.141.0",
|
|
14
|
+
"tsx": "^4.22.4"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@biomejs/biome": "2.
|
|
18
|
-
"@types/node": "^
|
|
19
|
-
"typescript": "^6.0.
|
|
17
|
+
"@biomejs/biome": "2.5.0",
|
|
18
|
+
"@types/node": "^26.0.0",
|
|
19
|
+
"typescript": "^6.0.3"
|
|
20
20
|
}
|
|
21
21
|
}
|
|
@@ -8,7 +8,9 @@ import {
|
|
|
8
8
|
countSkillDescriptionTokens,
|
|
9
9
|
countSystemPromptTokens,
|
|
10
10
|
findCodexSessionFile,
|
|
11
|
-
|
|
11
|
+
processCodexSession,
|
|
12
|
+
readSdkInstructions,
|
|
13
|
+
readSkillDescriptions,
|
|
12
14
|
} from "./lib/context-breakdown.js";
|
|
13
15
|
import { daemonEmit, daemonRestart, type EventType } from "./lib/daemon-client.js";
|
|
14
16
|
import { runHooks } from "./lib/hook-loader.js";
|
|
@@ -24,7 +26,7 @@ import type {
|
|
|
24
26
|
VoluteContentPart,
|
|
25
27
|
VoluteEvent,
|
|
26
28
|
} from "./lib/types.js";
|
|
27
|
-
import type { ContextInfo } from "./lib/volute-server.js";
|
|
29
|
+
import type { ContextInfo, ContextMessages } from "./lib/volute-server.js";
|
|
28
30
|
|
|
29
31
|
/** Minimal interface for a Codex SDK thread — typed to the methods we actually use */
|
|
30
32
|
type CodexThread = {
|
|
@@ -73,7 +75,11 @@ export function createMind(options: {
|
|
|
73
75
|
model?: string;
|
|
74
76
|
reasoningEffort?: "minimal" | "low" | "medium" | "high" | "xhigh";
|
|
75
77
|
maxContextTokens?: number;
|
|
76
|
-
}): {
|
|
78
|
+
}): {
|
|
79
|
+
resolve: HandlerResolver;
|
|
80
|
+
getContextInfo: () => ContextInfo;
|
|
81
|
+
getContextMessages: () => ContextMessages;
|
|
82
|
+
} {
|
|
77
83
|
const sessions = new Map<string, CodexSession>();
|
|
78
84
|
const prompts = loadPrompts();
|
|
79
85
|
const maxContextTokens = options.maxContextTokens;
|
|
@@ -599,21 +605,24 @@ export function createMind(options: {
|
|
|
599
605
|
const claudeMdTokens = countSdkInstructionTokens(options.cwd);
|
|
600
606
|
const skillDescTokens = countSkillDescriptionTokens([resolvePath(options.cwd, ".agents/skills")]);
|
|
601
607
|
|
|
608
|
+
function processSession(sessionName: string) {
|
|
609
|
+
const threadId = sessionStore.load(sessionName);
|
|
610
|
+
const jsonlPath = threadId ? findCodexSessionFile(threadId, options.mindDir) : null;
|
|
611
|
+
return jsonlPath
|
|
612
|
+
? processCodexSession(jsonlPath, systemPromptTokens, claudeMdTokens, skillDescTokens)
|
|
613
|
+
: null;
|
|
614
|
+
}
|
|
615
|
+
|
|
602
616
|
function getContextInfo(): ContextInfo {
|
|
603
617
|
return {
|
|
604
618
|
sessions: Array.from(sessions.values()).map((s) => {
|
|
605
619
|
try {
|
|
606
|
-
const
|
|
607
|
-
const jsonlPath = threadId ? findCodexSessionFile(threadId) : null;
|
|
608
|
-
const parsed = jsonlPath
|
|
609
|
-
? parseCodexSessionJSONL(jsonlPath, systemPromptTokens, claudeMdTokens, skillDescTokens)
|
|
610
|
-
: null;
|
|
611
|
-
|
|
620
|
+
const result = processSession(s.name);
|
|
612
621
|
return {
|
|
613
622
|
name: s.name,
|
|
614
|
-
contextTokens: parsed?.contextTokens ?? s.cumulativeInputTokens,
|
|
623
|
+
contextTokens: result?.parsed?.contextTokens ?? s.cumulativeInputTokens,
|
|
615
624
|
contextWindow: maxContextTokens,
|
|
616
|
-
breakdown: parsed?.breakdown,
|
|
625
|
+
breakdown: result?.parsed?.breakdown,
|
|
617
626
|
};
|
|
618
627
|
} catch (err) {
|
|
619
628
|
log("mind", `failed to get context breakdown for session "${s.name}":`, err);
|
|
@@ -628,5 +637,29 @@ export function createMind(options: {
|
|
|
628
637
|
};
|
|
629
638
|
}
|
|
630
639
|
|
|
631
|
-
|
|
640
|
+
function getContextMessages(): ContextMessages {
|
|
641
|
+
const skillsDir = resolvePath(options.cwd, ".agents/skills");
|
|
642
|
+
return {
|
|
643
|
+
preamble: {
|
|
644
|
+
systemPrompt: options.systemPrompt,
|
|
645
|
+
sdkInstructions: readSdkInstructions(options.cwd),
|
|
646
|
+
skillDescriptions: readSkillDescriptions([skillsDir]),
|
|
647
|
+
},
|
|
648
|
+
sessions: Array.from(sessions.values()).map((s) => {
|
|
649
|
+
try {
|
|
650
|
+
const result = processSession(s.name);
|
|
651
|
+
return { name: s.name, messages: result?.messages ?? [] };
|
|
652
|
+
} catch (err) {
|
|
653
|
+
log("mind", `failed to extract messages for session "${s.name}":`, err);
|
|
654
|
+
return { name: s.name, messages: [] };
|
|
655
|
+
}
|
|
656
|
+
}),
|
|
657
|
+
};
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
// Pre-warm the main session so the thread is created immediately
|
|
661
|
+
// instead of waiting for the first message.
|
|
662
|
+
getOrCreateSession("main");
|
|
663
|
+
|
|
664
|
+
return { resolve, getContextInfo, getContextMessages };
|
|
632
665
|
}
|
|
@@ -10,13 +10,13 @@
|
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@anthropic-ai/tokenizer": "^0.0.4",
|
|
13
|
-
"@mariozechner/pi-coding-agent": "^0.
|
|
14
|
-
"@sinclair/typebox": "^0.34.
|
|
15
|
-
"tsx": "^4.
|
|
13
|
+
"@mariozechner/pi-coding-agent": "^0.73.1",
|
|
14
|
+
"@sinclair/typebox": "^0.34.49",
|
|
15
|
+
"tsx": "^4.22.4"
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
18
|
-
"@biomejs/biome": "2.
|
|
19
|
-
"@types/node": "^
|
|
20
|
-
"typescript": "^6.0.
|
|
18
|
+
"@biomejs/biome": "2.5.0",
|
|
19
|
+
"@types/node": "^26.0.0",
|
|
20
|
+
"typescript": "^6.0.3"
|
|
21
21
|
}
|
|
22
22
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { readFileSync } from "node:fs";
|
|
1
|
+
import { readFileSync, watchFile } from "node:fs";
|
|
2
2
|
import { resolve as resolvePath } from "node:path";
|
|
3
3
|
import {
|
|
4
4
|
AuthStorage,
|
|
5
5
|
createAgentSession,
|
|
6
6
|
DefaultResourceLoader,
|
|
7
7
|
type ExtensionFactory,
|
|
8
|
+
getAgentDir,
|
|
8
9
|
ModelRegistry,
|
|
9
10
|
SessionManager,
|
|
10
11
|
SettingsManager,
|
|
@@ -15,8 +16,11 @@ import {
|
|
|
15
16
|
countSkillDescriptionTokens,
|
|
16
17
|
countSystemPromptTokens,
|
|
17
18
|
findPiSessionFile,
|
|
18
|
-
|
|
19
|
+
processPiSession,
|
|
20
|
+
readSdkInstructions,
|
|
21
|
+
readSkillDescriptions,
|
|
19
22
|
} from "./lib/context-breakdown.js";
|
|
23
|
+
import { daemonEmit } from "./lib/daemon-client.js";
|
|
20
24
|
import { createEventHandler, emit } from "./lib/event-handler.js";
|
|
21
25
|
import { runHooks } from "./lib/hook-loader.js";
|
|
22
26
|
import { log } from "./lib/logger.js";
|
|
@@ -32,7 +36,7 @@ import type {
|
|
|
32
36
|
VoluteContentPart,
|
|
33
37
|
VoluteEvent,
|
|
34
38
|
} from "./lib/types.js";
|
|
35
|
-
import type { ContextInfo } from "./lib/volute-server.js";
|
|
39
|
+
import type { ContextInfo, ContextMessages } from "./lib/volute-server.js";
|
|
36
40
|
|
|
37
41
|
type PiAgentSession = Awaited<ReturnType<typeof createAgentSession>>["session"];
|
|
38
42
|
|
|
@@ -57,7 +61,11 @@ export function createMind(options: {
|
|
|
57
61
|
compactionMessage?: string;
|
|
58
62
|
maxContextTokens?: number;
|
|
59
63
|
subagents?: Record<string, SubagentConfig>;
|
|
60
|
-
}): {
|
|
64
|
+
}): {
|
|
65
|
+
resolve: HandlerResolver;
|
|
66
|
+
getContextInfo: () => ContextInfo;
|
|
67
|
+
getContextMessages: () => ContextMessages;
|
|
68
|
+
} {
|
|
61
69
|
const sessions = new Map<string, PiSession>();
|
|
62
70
|
const prompts = loadPrompts();
|
|
63
71
|
const today = new Date().toLocaleDateString("en-CA");
|
|
@@ -77,6 +85,29 @@ export function createMind(options: {
|
|
|
77
85
|
const authStorage = AuthStorage.create();
|
|
78
86
|
const modelRegistry = ModelRegistry.create(authStorage);
|
|
79
87
|
|
|
88
|
+
// The daemon centrally refreshes the system OAuth token and rewrites auth.json
|
|
89
|
+
// with the fresh token. Watch the file and reload so a running mind adopts the
|
|
90
|
+
// new token without a restart (mirrors the Claude Agent SDK credential reload).
|
|
91
|
+
// This is why the mind itself does not refresh the rotating grant.
|
|
92
|
+
const piAuthPath = process.env.PI_CODING_AGENT_DIR
|
|
93
|
+
? resolvePath(process.env.PI_CODING_AGENT_DIR, "auth.json")
|
|
94
|
+
: null;
|
|
95
|
+
if (piAuthPath) {
|
|
96
|
+
try {
|
|
97
|
+
watchFile(piAuthPath, { interval: 2000 }, (curr, prev) => {
|
|
98
|
+
if (curr.mtimeMs === prev.mtimeMs) return;
|
|
99
|
+
try {
|
|
100
|
+
authStorage.reload();
|
|
101
|
+
log("mind", "reloaded auth.json after credential refresh");
|
|
102
|
+
} catch (err) {
|
|
103
|
+
log("mind", "failed to reload auth.json:", err);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
} catch (err) {
|
|
107
|
+
log("mind", "failed to watch auth.json for credential refresh:", err);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
80
111
|
// --- Subagents (config-driven) ---
|
|
81
112
|
|
|
82
113
|
function loadSubagents(
|
|
@@ -296,6 +327,7 @@ export function createMind(options: {
|
|
|
296
327
|
|
|
297
328
|
const resourceLoader = new DefaultResourceLoader({
|
|
298
329
|
cwd: options.cwd,
|
|
330
|
+
agentDir: getAgentDir(),
|
|
299
331
|
settingsManager,
|
|
300
332
|
systemPrompt: options.systemPrompt,
|
|
301
333
|
extensionFactories: [
|
|
@@ -457,8 +489,14 @@ export function createMind(options: {
|
|
|
457
489
|
} else {
|
|
458
490
|
session.agentSession.prompt(text, opts);
|
|
459
491
|
}
|
|
460
|
-
})().catch((err) => {
|
|
492
|
+
})().catch(async (err) => {
|
|
461
493
|
log("mind", `session "${sessionName}": prompt failed:`, err);
|
|
494
|
+
// Tell the daemon the turn failed (so it records a notice for the mind's next
|
|
495
|
+
// successful turn) before done, then complete the turn locally and on the daemon.
|
|
496
|
+
await daemonEmit({ type: "error", session: sessionName, content: String(err) }).catch(
|
|
497
|
+
() => {},
|
|
498
|
+
);
|
|
499
|
+
await daemonEmit({ type: "done", session: sessionName }).catch(() => {});
|
|
462
500
|
broadcast(session, { type: "done" });
|
|
463
501
|
});
|
|
464
502
|
|
|
@@ -489,20 +527,23 @@ export function createMind(options: {
|
|
|
489
527
|
const claudeMdTokens = countSdkInstructionTokens(options.cwd);
|
|
490
528
|
const skillDescTokens = countSkillDescriptionTokens([resolvePath(options.cwd, ".pi/skills")]);
|
|
491
529
|
|
|
530
|
+
function processSession(sessionName: string) {
|
|
531
|
+
const jsonlPath = findPiSessionFile(piSessionsDir, sessionName);
|
|
532
|
+
return jsonlPath
|
|
533
|
+
? processPiSession(jsonlPath, systemPromptTokens, claudeMdTokens, skillDescTokens)
|
|
534
|
+
: null;
|
|
535
|
+
}
|
|
536
|
+
|
|
492
537
|
function getContextInfo(): ContextInfo {
|
|
493
538
|
return {
|
|
494
539
|
sessions: Array.from(sessions.values()).map((s) => {
|
|
495
540
|
try {
|
|
496
|
-
const
|
|
497
|
-
const parsed = jsonlPath
|
|
498
|
-
? parsePiSessionJSONL(jsonlPath, systemPromptTokens, claudeMdTokens, skillDescTokens)
|
|
499
|
-
: null;
|
|
500
|
-
|
|
541
|
+
const result = processSession(s.name);
|
|
501
542
|
return {
|
|
502
543
|
name: s.name,
|
|
503
|
-
contextTokens: parsed?.contextTokens ?? s.contextTokens,
|
|
544
|
+
contextTokens: result?.parsed?.contextTokens ?? s.contextTokens,
|
|
504
545
|
contextWindow: maxContextTokens,
|
|
505
|
-
breakdown: parsed?.breakdown,
|
|
546
|
+
breakdown: result?.parsed?.breakdown,
|
|
506
547
|
};
|
|
507
548
|
} catch (err) {
|
|
508
549
|
log("mind", `failed to get context breakdown for session "${s.name}":`, err);
|
|
@@ -513,5 +554,25 @@ export function createMind(options: {
|
|
|
513
554
|
};
|
|
514
555
|
}
|
|
515
556
|
|
|
516
|
-
|
|
557
|
+
function getContextMessages(): ContextMessages {
|
|
558
|
+
const skillsDir = resolvePath(options.cwd, ".pi/skills");
|
|
559
|
+
return {
|
|
560
|
+
preamble: {
|
|
561
|
+
systemPrompt: options.systemPrompt,
|
|
562
|
+
sdkInstructions: readSdkInstructions(options.cwd),
|
|
563
|
+
skillDescriptions: readSkillDescriptions([skillsDir]),
|
|
564
|
+
},
|
|
565
|
+
sessions: Array.from(sessions.values()).map((s) => {
|
|
566
|
+
try {
|
|
567
|
+
const result = processSession(s.name);
|
|
568
|
+
return { name: s.name, messages: result?.messages ?? [] };
|
|
569
|
+
} catch (err) {
|
|
570
|
+
log("mind", `failed to extract messages for session "${s.name}":`, err);
|
|
571
|
+
return { name: s.name, messages: [] };
|
|
572
|
+
}
|
|
573
|
+
}),
|
|
574
|
+
};
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
return { resolve, getContextInfo, getContextMessages };
|
|
517
578
|
}
|
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
import type { Model } from "@mariozechner/pi-ai";
|
|
2
2
|
import {
|
|
3
3
|
type AuthStorage,
|
|
4
|
-
bashTool,
|
|
5
|
-
codingTools,
|
|
6
4
|
createAgentSession,
|
|
7
5
|
DefaultResourceLoader,
|
|
8
6
|
type ExtensionFactory,
|
|
9
|
-
|
|
7
|
+
getAgentDir,
|
|
10
8
|
type ModelRegistry,
|
|
11
|
-
readTool,
|
|
12
9
|
SessionManager,
|
|
13
10
|
SettingsManager,
|
|
14
|
-
writeTool,
|
|
15
11
|
} from "@mariozechner/pi-coding-agent";
|
|
16
12
|
import { Type } from "@sinclair/typebox";
|
|
17
13
|
import { log } from "./logger.js";
|
|
@@ -47,6 +43,7 @@ export function createSubagentExtension(
|
|
|
47
43
|
|
|
48
44
|
const loader = new DefaultResourceLoader({
|
|
49
45
|
cwd: context.cwd,
|
|
46
|
+
agentDir: getAgentDir(),
|
|
50
47
|
systemPromptOverride: () => def.prompt,
|
|
51
48
|
settingsManager: SettingsManager.inMemory({}),
|
|
52
49
|
});
|
|
@@ -125,29 +122,34 @@ export function createSubagentExtension(
|
|
|
125
122
|
};
|
|
126
123
|
}
|
|
127
124
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
125
|
+
// Maps subagent tool labels to pi's built-in coding tool names.
|
|
126
|
+
const TOOL_NAME_MAP: Record<string, string> = {
|
|
127
|
+
Read: "read",
|
|
128
|
+
Write: "write",
|
|
129
|
+
Bash: "bash",
|
|
130
|
+
Edit: "edit",
|
|
133
131
|
};
|
|
134
132
|
|
|
135
|
-
|
|
136
|
-
|
|
133
|
+
// Resolves subagent tool labels to pi tool names for createAgentSession's
|
|
134
|
+
// `tools` filter. Returns undefined to enable all built-in coding tools.
|
|
135
|
+
function resolveTools(names: string[] | undefined): string[] | undefined {
|
|
136
|
+
if (!names) return undefined;
|
|
137
137
|
const resolved = names
|
|
138
138
|
.map((n) => {
|
|
139
|
-
|
|
139
|
+
const toolName = TOOL_NAME_MAP[n];
|
|
140
|
+
if (!toolName) {
|
|
140
141
|
log(
|
|
141
142
|
"mind",
|
|
142
|
-
`unknown subagent tool "${n}" — available: ${Object.keys(
|
|
143
|
+
`unknown subagent tool "${n}" — available: ${Object.keys(TOOL_NAME_MAP).join(", ")}`,
|
|
143
144
|
);
|
|
145
|
+
return undefined;
|
|
144
146
|
}
|
|
145
|
-
return
|
|
147
|
+
return toolName;
|
|
146
148
|
})
|
|
147
|
-
.filter(
|
|
149
|
+
.filter((t) => t !== undefined);
|
|
148
150
|
if (resolved.length === 0) {
|
|
149
151
|
log("mind", "no valid tools resolved for subagent, falling back to all coding tools");
|
|
150
|
-
return
|
|
152
|
+
return undefined;
|
|
151
153
|
}
|
|
152
154
|
return resolved;
|
|
153
155
|
}
|
package/dist/chunk-K3NQKI34.js
DELETED
package/dist/db-32YFKMFL.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
DeliveryManager,
|
|
4
|
-
getDeliveryManager,
|
|
5
|
-
initDeliveryManager
|
|
6
|
-
} from "./chunk-CHCISTH7.js";
|
|
7
|
-
import "./chunk-WUH54G5S.js";
|
|
8
|
-
import "./chunk-Y4W3OS7Q.js";
|
|
9
|
-
import "./chunk-46DYYHN6.js";
|
|
10
|
-
import "./chunk-IBOU6Q3Y.js";
|
|
11
|
-
import "./chunk-QDWPM73D.js";
|
|
12
|
-
import "./chunk-CU6OFXMM.js";
|
|
13
|
-
import "./chunk-EVKGKQ2P.js";
|
|
14
|
-
import "./chunk-DZ4LYU6J.js";
|
|
15
|
-
import "./chunk-OS5MRIEP.js";
|
|
16
|
-
import "./chunk-OEXOFBW5.js";
|
|
17
|
-
import "./chunk-6FSSMAXU.js";
|
|
18
|
-
import "./chunk-7W3UWCQD.js";
|
|
19
|
-
import "./chunk-7GZB3ZJP.js";
|
|
20
|
-
import "./chunk-B7MWXFAH.js";
|
|
21
|
-
import "./chunk-TCNCRDB5.js";
|
|
22
|
-
import "./chunk-T2TP6ZC6.js";
|
|
23
|
-
import "./chunk-QDWP435B.js";
|
|
24
|
-
import "./chunk-CJ26DXZL.js";
|
|
25
|
-
import "./chunk-K3NQKI34.js";
|
|
26
|
-
export {
|
|
27
|
-
DeliveryManager,
|
|
28
|
-
getDeliveryManager,
|
|
29
|
-
initDeliveryManager
|
|
30
|
-
};
|
package/dist/down-TCEBGTMY.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
run,
|
|
4
|
-
stopDaemon
|
|
5
|
-
} from "./chunk-QJ4GU5XT.js";
|
|
6
|
-
import "./chunk-TXSA4Q3V.js";
|
|
7
|
-
import "./chunk-O7IGP7ZW.js";
|
|
8
|
-
import "./chunk-6V2U3GFQ.js";
|
|
9
|
-
import "./chunk-OEXOFBW5.js";
|
|
10
|
-
import "./chunk-6FSSMAXU.js";
|
|
11
|
-
import "./chunk-QDWP435B.js";
|
|
12
|
-
import "./chunk-CJ26DXZL.js";
|
|
13
|
-
import "./chunk-K3NQKI34.js";
|
|
14
|
-
export {
|
|
15
|
-
run,
|
|
16
|
-
stopDaemon
|
|
17
|
-
};
|