@tekmidian/pai 0.38.0 → 0.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{auto-route-DM7GhJ8y.mjs → auto-route-BlWOWT4z.mjs} +2 -2
- package/dist/{auto-route-DM7GhJ8y.mjs.map → auto-route-BlWOWT4z.mjs.map} +1 -1
- package/dist/{providers-DUshcB-d.mjs → chain-CTtHligI.mjs} +699 -1405
- package/dist/chain-CTtHligI.mjs.map +1 -0
- package/dist/cli/index.mjs +4 -3
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/program.mjs +4 -3
- package/dist/{clusters-Do4tEGyc.mjs → clusters-wlK0w41E.mjs} +1 -1
- package/dist/{clusters-Do4tEGyc.mjs.map → clusters-wlK0w41E.mjs.map} +1 -1
- package/dist/daemon/index.mjs +7 -7
- package/dist/{daemon-CGg1VCbA.mjs → daemon-CTkN_Vn8.mjs} +25 -25
- package/dist/{daemon-CGg1VCbA.mjs.map → daemon-CTkN_Vn8.mjs.map} +1 -1
- package/dist/{daemon-DsGGiIJM.mjs → daemon-CmHHmKpg.mjs} +7 -7
- package/dist/daemon-mcp/index.mjs +55 -3
- package/dist/daemon-mcp/index.mjs.map +1 -1
- package/dist/{detector-CMap-9vw.mjs → detector-Bwk_4Pk4.mjs} +1 -1
- package/dist/{detector-CMap-9vw.mjs.map → detector-Bwk_4Pk4.mjs.map} +1 -1
- package/dist/detector-DO730Zq0.mjs +5 -0
- package/dist/{factory-DD2T33C9.mjs → factory-A9x-T2Kg.mjs} +5 -5
- package/dist/{factory-DD2T33C9.mjs.map → factory-A9x-T2Kg.mjs.map} +1 -1
- package/dist/factory-BD-np0Vd.mjs +3 -0
- package/dist/hooks/route-agents-to-worker.mjs +36 -6
- package/dist/hooks/route-agents-to-worker.mjs.map +2 -2
- package/dist/hooks/worker-proxy.mjs +34 -4
- package/dist/hooks/worker-proxy.mjs.map +2 -2
- package/dist/hooks/worker-status-line.mjs +100 -9
- package/dist/hooks/worker-status-line.mjs.map +4 -4
- package/dist/{indexer-backend-Cox9BCo-.mjs → indexer-backend-TG64CCQC.mjs} +1 -1
- package/dist/{indexer-backend-Cox9BCo-.mjs.map → indexer-backend-TG64CCQC.mjs.map} +1 -1
- package/dist/{latent-ideas-BC1oINZ-.mjs → latent-ideas-B7wq75Pt.mjs} +2 -2
- package/dist/{latent-ideas-BC1oINZ-.mjs.map → latent-ideas-B7wq75Pt.mjs.map} +1 -1
- package/dist/{link-boost-QFLrJwD6.mjs → link-boost-HkG7JWZR.mjs} +1 -1
- package/dist/{link-boost-QFLrJwD6.mjs.map → link-boost-HkG7JWZR.mjs.map} +1 -1
- package/dist/{neighborhood-D9MJ1c8f.mjs → neighborhood-lThN-MaQ.mjs} +1 -1
- package/dist/{neighborhood-D9MJ1c8f.mjs.map → neighborhood-lThN-MaQ.mjs.map} +1 -1
- package/dist/{note-context-d1wT_-GA.mjs → note-context-b6k0mAKi.mjs} +1 -1
- package/dist/{note-context-d1wT_-GA.mjs.map → note-context-b6k0mAKi.mjs.map} +1 -1
- package/dist/planner-BDI7bE9B.mjs +243 -0
- package/dist/planner-BDI7bE9B.mjs.map +1 -0
- package/dist/{postgres--BjPtLa0.mjs → postgres-mW1n7Vi1.mjs} +1 -1
- package/dist/{postgres--BjPtLa0.mjs.map → postgres-mW1n7Vi1.mjs.map} +1 -1
- package/dist/{program-Y0hAiVy8.mjs → program-DXBwJV7h.mjs} +70 -19
- package/dist/{program-Y0hAiVy8.mjs.map → program-DXBwJV7h.mjs.map} +1 -1
- package/dist/providers-FYkZjn_C.mjs +1405 -0
- package/dist/providers-FYkZjn_C.mjs.map +1 -0
- package/dist/{query-feedback-BUJxgw5B.mjs → query-feedback-BV4CcxqS.mjs} +1 -1
- package/dist/{query-feedback-BUJxgw5B.mjs.map → query-feedback-BV4CcxqS.mjs.map} +1 -1
- package/dist/query-feedback-DSVyHtrG.mjs +3 -0
- package/dist/router-Bk77E7hj.mjs +3 -0
- package/dist/{router-DK_sLsUL.mjs → router-DcHKnEPa.mjs} +1 -1
- package/dist/{router-DK_sLsUL.mjs.map → router-DcHKnEPa.mjs.map} +1 -1
- package/dist/{sources-Bi7--33T.mjs → sources-kLnQsNrW.mjs} +1 -1
- package/dist/{sources-Bi7--33T.mjs.map → sources-kLnQsNrW.mjs.map} +1 -1
- package/dist/{sqlite-DtaL1glm.mjs → sqlite-BenGr3UP.mjs} +1 -1
- package/dist/{sqlite-DtaL1glm.mjs.map → sqlite-BenGr3UP.mjs.map} +1 -1
- package/dist/{state-BY2L6-vX.mjs → state-CAeyOdfq.mjs} +1 -1
- package/dist/{state-BY2L6-vX.mjs.map → state-CAeyOdfq.mjs.map} +1 -1
- package/dist/{state-8Hm9E4tW.mjs → state-Ca9F_sZc.mjs} +1 -1
- package/dist/{themes-BN0a2duq.mjs → themes-BI4GMRP9.mjs} +1 -1
- package/dist/{themes-BN0a2duq.mjs.map → themes-BI4GMRP9.mjs.map} +1 -1
- package/dist/{tools-CGPqpU3A.mjs → tools-Bp7hj6OW.mjs} +1 -1
- package/dist/{tools-y2bJpKom.mjs → tools-DGcB3o_S.mjs} +13 -13
- package/dist/{tools-y2bJpKom.mjs.map → tools-DGcB3o_S.mjs.map} +1 -1
- package/dist/{trace-h23JCcFD.mjs → trace-bobARFEX.mjs} +1 -1
- package/dist/{trace-h23JCcFD.mjs.map → trace-bobARFEX.mjs.map} +1 -1
- package/dist/{vault-indexer-DgsPjMgs.mjs → vault-indexer-C3OfXTNF.mjs} +1 -1
- package/dist/{vault-indexer-DgsPjMgs.mjs.map → vault-indexer-C3OfXTNF.mjs.map} +1 -1
- package/dist/{work-queue-worker-gsKd2LJa.mjs → work-queue-worker-DW8lz-Oo.mjs} +3 -3
- package/dist/{work-queue-worker-Dva_v_pI.mjs → work-queue-worker-R7UGIag_.mjs} +3 -3
- package/dist/{work-queue-worker-Dva_v_pI.mjs.map → work-queue-worker-R7UGIag_.mjs.map} +1 -1
- package/dist/{zettelkasten-vo7psPdT.mjs → zettelkasten-m5QPtb-L.mjs} +3 -3
- package/dist/{zettelkasten-vo7psPdT.mjs.map → zettelkasten-m5QPtb-L.mjs.map} +1 -1
- package/docs/commands/README.md +4 -0
- package/docs/commands/worker.md +56 -0
- package/docs/worker.md +89 -1
- package/package.json +1 -1
- package/src/hooks/ts/pre-tool-use/route-agents-to-worker.ts +2 -2
- package/dist/detector-DtLExmHN.mjs +0 -5
- package/dist/factory-BXzqRYVZ.mjs +0 -3
- package/dist/providers-DUshcB-d.mjs.map +0 -1
- package/dist/query-feedback-DhyLOe5S.mjs +0 -3
- package/dist/router-1zi8jiNF.mjs +0 -3
- /package/dist/{main-resolver-IhZo4pI0.mjs → main-resolver-D6IImXvF.mjs} +0 -0
|
@@ -150,16 +150,24 @@ var DEFAULT_ROUTING2 = {
|
|
|
150
150
|
cooldownMinutes: 30,
|
|
151
151
|
retryOnQuota: true
|
|
152
152
|
};
|
|
153
|
+
var DEFAULT_TREE = {
|
|
154
|
+
maxDepth: 2,
|
|
155
|
+
maxChildren: 4
|
|
156
|
+
};
|
|
157
|
+
var DEFAULT_MCP_SETS = {
|
|
158
|
+
desktop: ["clickr"]
|
|
159
|
+
};
|
|
153
160
|
function defaultWorkersConfig() {
|
|
154
161
|
return {
|
|
155
162
|
enabled: false,
|
|
156
163
|
active: null,
|
|
157
164
|
providers: {},
|
|
158
165
|
classes: {},
|
|
159
|
-
mcpSets: {},
|
|
166
|
+
mcpSets: { ...DEFAULT_MCP_SETS },
|
|
160
167
|
pane: { ...DEFAULT_PANE },
|
|
161
168
|
logDir: DEFAULT_LOG_DIR,
|
|
162
|
-
routing: { ...DEFAULT_ROUTING2, order: [] }
|
|
169
|
+
routing: { ...DEFAULT_ROUTING2, order: [] },
|
|
170
|
+
tree: { ...DEFAULT_TREE }
|
|
163
171
|
};
|
|
164
172
|
}
|
|
165
173
|
var WorkersConfigError = class extends Error {
|
|
@@ -330,7 +338,7 @@ function parseWorkersConfig(raw) {
|
|
|
330
338
|
}
|
|
331
339
|
}
|
|
332
340
|
}
|
|
333
|
-
const mcpSets = {};
|
|
341
|
+
const mcpSets = { ...DEFAULT_MCP_SETS };
|
|
334
342
|
if (w.mcpSets !== void 0) {
|
|
335
343
|
if (typeof w.mcpSets !== "object" || w.mcpSets === null || Array.isArray(w.mcpSets)) {
|
|
336
344
|
bad(".mcpSets", "must be an object of set name \u2192 [server names]");
|
|
@@ -381,6 +389,27 @@ function parseWorkersConfig(raw) {
|
|
|
381
389
|
retryOnQuota: r.retryOnQuota === void 0 ? DEFAULT_ROUTING2.retryOnQuota : r.retryOnQuota === true
|
|
382
390
|
};
|
|
383
391
|
}
|
|
392
|
+
let tree = { ...DEFAULT_TREE };
|
|
393
|
+
if (w.tree !== void 0) {
|
|
394
|
+
if (typeof w.tree !== "object" || w.tree === null || Array.isArray(w.tree)) {
|
|
395
|
+
bad(".tree", "must be an object");
|
|
396
|
+
}
|
|
397
|
+
const t = w.tree;
|
|
398
|
+
if (t.maxDepth !== void 0) {
|
|
399
|
+
if (typeof t.maxDepth !== "number" || !Number.isInteger(t.maxDepth) || t.maxDepth < 0) {
|
|
400
|
+
bad(".tree.maxDepth", "must be a non-negative integer");
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
if (t.maxChildren !== void 0) {
|
|
404
|
+
if (typeof t.maxChildren !== "number" || !Number.isInteger(t.maxChildren) || t.maxChildren < 1) {
|
|
405
|
+
bad(".tree.maxChildren", "must be a positive integer");
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
tree = {
|
|
409
|
+
maxDepth: t.maxDepth === void 0 ? DEFAULT_TREE.maxDepth : t.maxDepth,
|
|
410
|
+
maxChildren: t.maxChildren === void 0 ? DEFAULT_TREE.maxChildren : t.maxChildren
|
|
411
|
+
};
|
|
412
|
+
}
|
|
384
413
|
const active = w.active === void 0 || w.active === null ? null : str(w.active);
|
|
385
414
|
if (active !== null && active !== "auto" && !(active in providers)) {
|
|
386
415
|
}
|
|
@@ -392,7 +421,8 @@ function parseWorkersConfig(raw) {
|
|
|
392
421
|
mcpSets,
|
|
393
422
|
pane,
|
|
394
423
|
logDir: str(w.logDir) || d.logDir,
|
|
395
|
-
routing
|
|
424
|
+
routing,
|
|
425
|
+
tree
|
|
396
426
|
};
|
|
397
427
|
}
|
|
398
428
|
function readWorkersSection() {
|
|
@@ -468,7 +498,44 @@ function workerInScope(worker, term2) {
|
|
|
468
498
|
return tabKey(worker.term) === tabKey(term2) && tabKey(term2) !== "";
|
|
469
499
|
}
|
|
470
500
|
|
|
501
|
+
// src/workers/handoff.ts
|
|
502
|
+
import { appendFileSync, existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3 } from "node:fs";
|
|
503
|
+
import { dirname, join as join5 } from "node:path";
|
|
504
|
+
function inboxPath(logDir, id) {
|
|
505
|
+
return join5(logDir, `${id}.inbox.jsonl`);
|
|
506
|
+
}
|
|
507
|
+
function readInbox(logDir, id) {
|
|
508
|
+
const path = inboxPath(logDir, id);
|
|
509
|
+
if (!existsSync3(path)) return [];
|
|
510
|
+
const out = [];
|
|
511
|
+
for (const line of readFileSync3(path, "utf8").split("\n")) {
|
|
512
|
+
if (!line.trim()) continue;
|
|
513
|
+
try {
|
|
514
|
+
out.push(JSON.parse(line));
|
|
515
|
+
} catch {
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
return out;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// src/workers/tree.ts
|
|
522
|
+
function workerDepth(statuses, id) {
|
|
523
|
+
const byId = new Map(statuses.map((s) => [s.id, s]));
|
|
524
|
+
let depth = 0;
|
|
525
|
+
let cur = byId.get(id);
|
|
526
|
+
const seen = /* @__PURE__ */ new Set([id]);
|
|
527
|
+
while (cur?.parent && !seen.has(cur.parent)) {
|
|
528
|
+
seen.add(cur.parent);
|
|
529
|
+
const next = byId.get(cur.parent);
|
|
530
|
+
if (!next) break;
|
|
531
|
+
depth += 1;
|
|
532
|
+
cur = next;
|
|
533
|
+
}
|
|
534
|
+
return depth;
|
|
535
|
+
}
|
|
536
|
+
|
|
471
537
|
// src/workers/report.ts
|
|
538
|
+
var OPERATOR_MARK = "[operator]";
|
|
472
539
|
var WORKER_CONTRACT_PROMPT = [
|
|
473
540
|
"You are a headless implementation worker, run non-interactively by an orchestrating session.",
|
|
474
541
|
"No narration, no timestamps, no greetings, no summaries of what you read; act, verify, then stop.",
|
|
@@ -476,7 +543,20 @@ var WORKER_CONTRACT_PROMPT = [
|
|
|
476
543
|
'{"changed":[{"path":"\u2026","summary":"\u2026"}],"commands":["\u2026"],"checks":[{"name":"\u2026","ok":true,"detail":"\u2026"}],"open":["\u2026"],"notes":"one line"}',
|
|
477
544
|
"changed: files you touched (path + one-line summary). commands: the commands that verify the work.",
|
|
478
545
|
"checks: each with ok true/false and the evidence in detail. open: what you could not finish, if anything.",
|
|
479
|
-
"notes: one line, the headline a reviewer reads first."
|
|
546
|
+
"notes: one line, the headline a reviewer reads first.",
|
|
547
|
+
"",
|
|
548
|
+
`Operator messages: a user turn starting with ${OPERATOR_MARK} was typed by the operator while you`,
|
|
549
|
+
"run (the prompt of a resumed run is the operator's too). Answer it FIRST, in one or two plain lines \u2014",
|
|
550
|
+
"a question gets its answer, an instruction gets one line naming what will change \u2014 then continue the",
|
|
551
|
+
"task you were on.",
|
|
552
|
+
"",
|
|
553
|
+
"Sub-workers: you may start your own workers with `pai worker run --class <class> -p '<prompt>'`",
|
|
554
|
+
"(Bash tool). Your children run on their own provider and report back to you automatically when",
|
|
555
|
+
"they finish. Send a handoff UP instead of doing work yourself when a cheaper provider would",
|
|
556
|
+
"suffice, the task is out of your scope, or a decision is needed:",
|
|
557
|
+
'`pai worker handoff \'{"kind":"proposal","text":"\u2026","data":{\u2026}}\'` (kinds: proposal,',
|
|
558
|
+
"question, blocker; results are sent for you when you finish). Sibling workers are not a",
|
|
559
|
+
"coordination path \u2014 there is no sideways channel; everything goes up to your parent."
|
|
480
560
|
].join("\n");
|
|
481
561
|
|
|
482
562
|
// src/workers/render.ts
|
|
@@ -504,9 +584,9 @@ function contextMeter(c, s, minPct = 0) {
|
|
|
504
584
|
if (pct > 70) return c("yellow", label);
|
|
505
585
|
return label;
|
|
506
586
|
}
|
|
507
|
-
function renderStatusLine(mine, now = /* @__PURE__ */ new Date(), c = makeColor(true)) {
|
|
587
|
+
function renderStatusLine(mine, now = /* @__PURE__ */ new Date(), c = makeColor(true), all = mine, inbox = {}) {
|
|
508
588
|
if (!mine.length) return "";
|
|
509
|
-
const running = mine.filter((s) => s.state === "running" && alive(s.pid));
|
|
589
|
+
const running = mine.filter((s) => s.state === "running" && alive(s.pid)).sort((a, b) => workerDepth(all, a.id) - workerDepth(all, b.id));
|
|
510
590
|
const today = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")}`;
|
|
511
591
|
const doneToday = mine.filter((s) => s.state !== "running" && s.started.startsWith(today));
|
|
512
592
|
const ok = doneToday.filter((s) => s.state === "done").length;
|
|
@@ -516,7 +596,10 @@ function renderStatusLine(mine, now = /* @__PURE__ */ new Date(), c = makeColor(
|
|
|
516
596
|
let head = `${providerTag} \u25B6${running.length}`;
|
|
517
597
|
const parts = running.slice(0, 3).map((s) => {
|
|
518
598
|
const meter = contextMeter(c, s, 60);
|
|
519
|
-
|
|
599
|
+
const depth = workerDepth(all, s.id);
|
|
600
|
+
const lead = depth > 0 ? " ".repeat(depth - 1) + "\u21B3 " : "";
|
|
601
|
+
const box = inbox[s.id] ? ` \u25C6${inbox[s.id]}` : "";
|
|
602
|
+
return `${lead}${s.id.slice(-4)} ${s.label.slice(0, 26)} ${ageOf(s.started, now)} \xB7 ${s.last.slice(0, 30)}${box}` + (meter ? ` ${meter}` : "");
|
|
520
603
|
});
|
|
521
604
|
if (parts.length) head += " " + parts.join(" | ");
|
|
522
605
|
if (doneToday.length) head += ` \u2713${ok} \u2717${bad2} today`;
|
|
@@ -524,6 +607,14 @@ function renderStatusLine(mine, now = /* @__PURE__ */ new Date(), c = makeColor(
|
|
|
524
607
|
}
|
|
525
608
|
|
|
526
609
|
// src/workers/viewer.ts
|
|
610
|
+
function inboxCounts(logDir, statuses) {
|
|
611
|
+
const out = {};
|
|
612
|
+
for (const s of statuses) {
|
|
613
|
+
const n = readInbox(logDir, s.id).length;
|
|
614
|
+
if (n) out[s.id] = n;
|
|
615
|
+
}
|
|
616
|
+
return out;
|
|
617
|
+
}
|
|
527
618
|
function statusLineOutput(logDir, term2, cwd2, now = /* @__PURE__ */ new Date()) {
|
|
528
619
|
const statuses = loadStatuses(logDir);
|
|
529
620
|
const mine = statuses.filter((s) => {
|
|
@@ -531,7 +622,7 @@ function statusLineOutput(logDir, term2, cwd2, now = /* @__PURE__ */ new Date())
|
|
|
531
622
|
const sameDir = cwd2 && s.cwd.startsWith(cwd2);
|
|
532
623
|
return sameScope || !term2 && sameDir;
|
|
533
624
|
});
|
|
534
|
-
return renderStatusLine(mine, now);
|
|
625
|
+
return renderStatusLine(mine, now, makeColor(false), statuses, inboxCounts(logDir, mine));
|
|
535
626
|
}
|
|
536
627
|
|
|
537
628
|
// src/workers/standalone/status-line.ts
|