@tekmidian/pai 0.39.0 → 0.40.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 +41 -0
- package/dist/{auto-route-BlWOWT4z.mjs → auto-route-BwzmlW3W.mjs} +2 -2
- package/dist/{auto-route-BlWOWT4z.mjs.map → auto-route-BwzmlW3W.mjs.map} +1 -1
- package/dist/{chain-CTtHligI.mjs → chain-DhVHVnmT.mjs} +263 -791
- package/dist/chain-DhVHVnmT.mjs.map +1 -0
- package/dist/cli/index.mjs +10 -8
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/program.mjs +10 -8
- package/dist/{clusters-wlK0w41E.mjs → clusters-DRHhfli9.mjs} +1 -1
- package/dist/{clusters-wlK0w41E.mjs.map → clusters-DRHhfli9.mjs.map} +1 -1
- package/dist/{config-B64vFg14.mjs → config-D1G9IFpn.mjs} +50 -3
- package/dist/config-D1G9IFpn.mjs.map +1 -0
- package/dist/{config-C_ErGddD.mjs → config-DD52BPB-.mjs} +1 -1
- package/dist/config-Dl8lT4Lu.mjs +527 -0
- package/dist/config-Dl8lT4Lu.mjs.map +1 -0
- package/dist/{context-handover-cache-BpUojjsi.mjs → context-handover-cache-C6_rs7JT.mjs} +112 -24
- package/dist/context-handover-cache-C6_rs7JT.mjs.map +1 -0
- package/dist/daemon/index.mjs +12 -10
- package/dist/daemon/index.mjs.map +1 -1
- package/dist/daemon-BSL9sXxm.mjs +22 -0
- package/dist/{daemon-CTkN_Vn8.mjs → daemon-CpdVUnl_.mjs} +26 -26
- package/dist/{daemon-CTkN_Vn8.mjs.map → daemon-CpdVUnl_.mjs.map} +1 -1
- package/dist/daemon-mcp/index.mjs +127 -6
- package/dist/daemon-mcp/index.mjs.map +1 -1
- package/dist/detector-BLVOCiJ_.mjs +5 -0
- package/dist/{detector-Bwk_4Pk4.mjs → detector-smpCm7ku.mjs} +1 -1
- package/dist/{detector-Bwk_4Pk4.mjs.map → detector-smpCm7ku.mjs.map} +1 -1
- package/dist/{factory-A9x-T2Kg.mjs → factory-Bc5EyN54.mjs} +7 -7
- package/dist/{factory-A9x-T2Kg.mjs.map → factory-Bc5EyN54.mjs.map} +1 -1
- package/dist/factory-C7ua_3ik.mjs +3 -0
- package/dist/{providers-FYkZjn_C.mjs → fallback-CdXv-Np0.mjs} +411 -51
- package/dist/fallback-CdXv-Np0.mjs.map +1 -0
- package/dist/hooks/context-compression-hook.mjs +136 -22
- package/dist/hooks/context-compression-hook.mjs.map +4 -4
- package/dist/hooks/post-compact-inject.mjs +98 -7
- package/dist/hooks/post-compact-inject.mjs.map +4 -4
- package/dist/hooks/route-agents-to-worker.mjs +75 -6
- package/dist/hooks/route-agents-to-worker.mjs.map +2 -2
- package/dist/hooks/worker-proxy.mjs +75 -6
- package/dist/hooks/worker-proxy.mjs.map +2 -2
- package/dist/hooks/worker-status-line.mjs +149 -90
- package/dist/hooks/worker-status-line.mjs.map +4 -4
- package/dist/{indexer-backend-TG64CCQC.mjs → indexer-backend-rohVVKrA.mjs} +1 -1
- package/dist/{indexer-backend-TG64CCQC.mjs.map → indexer-backend-rohVVKrA.mjs.map} +1 -1
- package/dist/{ipc-client-BmypMNYk.mjs → ipc-client-C7AVpsyv.mjs} +2 -2
- package/dist/{ipc-client-BmypMNYk.mjs.map → ipc-client-C7AVpsyv.mjs.map} +1 -1
- package/dist/{kg-entity-r8duqhi9.mjs → kg-entity-DbOMPdF9.mjs} +1 -1
- package/dist/{kg-entity-r8duqhi9.mjs.map → kg-entity-DbOMPdF9.mjs.map} +1 -1
- package/dist/{latent-ideas-B7wq75Pt.mjs → latent-ideas-iNp5s55R.mjs} +2 -2
- package/dist/{latent-ideas-B7wq75Pt.mjs.map → latent-ideas-iNp5s55R.mjs.map} +1 -1
- package/dist/{link-boost-HkG7JWZR.mjs → link-boost-NNzADHX_.mjs} +1 -1
- package/dist/{link-boost-HkG7JWZR.mjs.map → link-boost-NNzADHX_.mjs.map} +1 -1
- package/dist/{main-resolver-DlaLOFBA.mjs → main-resolver-CM1IHbuu.mjs} +78 -75
- package/dist/main-resolver-CM1IHbuu.mjs.map +1 -0
- package/dist/main-resolver-E5WlilhM.mjs +6 -0
- package/dist/{neighborhood-lThN-MaQ.mjs → neighborhood-AGL7oXQ2.mjs} +1 -1
- package/dist/{neighborhood-lThN-MaQ.mjs.map → neighborhood-AGL7oXQ2.mjs.map} +1 -1
- package/dist/{note-context-b6k0mAKi.mjs → note-context-BHwYpSFf.mjs} +1 -1
- package/dist/{note-context-b6k0mAKi.mjs.map → note-context-BHwYpSFf.mjs.map} +1 -1
- package/dist/{planner-BDI7bE9B.mjs → planner-Cm3g6fWH.mjs} +5 -3
- package/dist/{planner-BDI7bE9B.mjs.map → planner-Cm3g6fWH.mjs.map} +1 -1
- package/dist/{postgres-mW1n7Vi1.mjs → postgres-Dwxe290H.mjs} +1 -1
- package/dist/{postgres-mW1n7Vi1.mjs.map → postgres-Dwxe290H.mjs.map} +1 -1
- package/dist/{program-DXBwJV7h.mjs → program-AR0qlYRg.mjs} +334 -78
- package/dist/program-AR0qlYRg.mjs.map +1 -0
- package/dist/query-feedback-CGcEiGtY.mjs +3 -0
- package/dist/{query-feedback-BV4CcxqS.mjs → query-feedback-DZfjI34w.mjs} +1 -1
- package/dist/{query-feedback-BV4CcxqS.mjs.map → query-feedback-DZfjI34w.mjs.map} +1 -1
- package/dist/router-CAtyVQud.mjs +3 -0
- package/dist/{router-DcHKnEPa.mjs → router-DHracTUC.mjs} +1 -1
- package/dist/{router-DcHKnEPa.mjs.map → router-DHracTUC.mjs.map} +1 -1
- package/dist/server-BOuAOj9b.mjs +386 -0
- package/dist/server-BOuAOj9b.mjs.map +1 -0
- package/dist/skills/Worker/SKILL.md +19 -1
- package/dist/{sources-kLnQsNrW.mjs → sources-ju6AA7lL.mjs} +1 -1
- package/dist/{sources-kLnQsNrW.mjs.map → sources-ju6AA7lL.mjs.map} +1 -1
- package/dist/{sqlite-BenGr3UP.mjs → sqlite-kFZeWCJ2.mjs} +1 -1
- package/dist/{sqlite-BenGr3UP.mjs.map → sqlite-kFZeWCJ2.mjs.map} +1 -1
- package/dist/{state-Ca9F_sZc.mjs → state-DH_mp5Xe.mjs} +1 -1
- package/dist/{state-CAeyOdfq.mjs → state-ahFAbD8b.mjs} +1 -1
- package/dist/{state-CAeyOdfq.mjs.map → state-ahFAbD8b.mjs.map} +1 -1
- package/dist/{themes-BI4GMRP9.mjs → themes-DqhNUUQk.mjs} +1 -1
- package/dist/{themes-BI4GMRP9.mjs.map → themes-DqhNUUQk.mjs.map} +1 -1
- package/dist/{tools-DGcB3o_S.mjs → tools-CMlHa9lZ.mjs} +14 -14
- package/dist/{tools-DGcB3o_S.mjs.map → tools-CMlHa9lZ.mjs.map} +1 -1
- package/dist/{tools-Bp7hj6OW.mjs → tools-COna9vZR.mjs} +1 -1
- package/dist/{trace-bobARFEX.mjs → trace-DTP6k4B_.mjs} +1 -1
- package/dist/{trace-bobARFEX.mjs.map → trace-DTP6k4B_.mjs.map} +1 -1
- package/dist/{vault-indexer-C3OfXTNF.mjs → vault-indexer-YMH22mLU.mjs} +1 -1
- package/dist/{vault-indexer-C3OfXTNF.mjs.map → vault-indexer-YMH22mLU.mjs.map} +1 -1
- package/dist/{work-queue-worker-R7UGIag_.mjs → work-queue-worker-B3nl8yyn.mjs} +23 -26
- package/dist/work-queue-worker-B3nl8yyn.mjs.map +1 -0
- package/dist/work-queue-worker-BM1GcAAq.mjs +14 -0
- package/dist/{zettelkasten-m5QPtb-L.mjs → zettelkasten-DDvKRm2V.mjs} +3 -3
- package/dist/{zettelkasten-m5QPtb-L.mjs.map → zettelkasten-DDvKRm2V.mjs.map} +1 -1
- package/docs/commands/README.md +5 -2
- package/docs/commands/worker.md +66 -5
- package/docs/images/provider-abstraction-live.png +0 -0
- package/docs/images/workers.png +0 -0
- package/docs/launcher-independence.md +70 -0
- package/docs/provider-abstraction.md +87 -0
- package/docs/provider-independence-details.md +330 -0
- package/docs/provider-independence.md +75 -0
- package/docs/worker.md +72 -11
- package/package.json +1 -1
- package/scripts/build-hooks.mjs +6 -1
- package/scripts/build-skill-stubs.mjs +17 -4
- package/src/hooks/ts/lib/context-fill.test.ts +158 -4
- package/src/hooks/ts/lib/context-fill.ts +102 -35
- package/statusline-command.sh +120 -21
- package/dist/chain-CTtHligI.mjs.map +0 -1
- package/dist/config-B64vFg14.mjs.map +0 -1
- package/dist/context-handover-cache-BpUojjsi.mjs.map +0 -1
- package/dist/daemon-CmHHmKpg.mjs +0 -20
- package/dist/detector-DO730Zq0.mjs +0 -5
- package/dist/factory-BD-np0Vd.mjs +0 -3
- package/dist/main-resolver-D6IImXvF.mjs +0 -4
- package/dist/main-resolver-DlaLOFBA.mjs.map +0 -1
- package/dist/program-DXBwJV7h.mjs.map +0 -1
- package/dist/providers-FYkZjn_C.mjs.map +0 -1
- package/dist/query-feedback-DSVyHtrG.mjs +0 -3
- package/dist/router-Bk77E7hj.mjs +0 -3
- package/dist/runtime-paths-rni52zHX.mjs +0 -50
- package/dist/runtime-paths-rni52zHX.mjs.map +0 -1
- package/dist/work-queue-worker-DW8lz-Oo.mjs +0 -11
- package/dist/work-queue-worker-R7UGIag_.mjs.map +0 -1
|
@@ -7,15 +7,16 @@ import { i as indexProject, n as indexAll, t as embedChunks } from "./sync-BWbe8
|
|
|
7
7
|
import { t as STOP_WORDS } from "./stop-words-Hfu8u22w.mjs";
|
|
8
8
|
import { a as searchMemory, i as populateSlugs } from "./search-Rpk1cSBC.mjs";
|
|
9
9
|
import { n as formatDetection, r as formatDetectionJson, t as detectProject } from "./detect-CdaA48EI.mjs";
|
|
10
|
-
import { _ as
|
|
11
|
-
import { a as
|
|
12
|
-
import { t as PaiClient } from "./ipc-client-
|
|
13
|
-
import {
|
|
14
|
-
import { r as
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import { _ as scanSessions, a as renderDedupedSessions, c as probeResume, d as callAiBroker, f as fetchLiveSessions, g as resolveSessionByNameOrId, h as fmtAge, i as normalizeName$2, l as restoreTopLevel, m as sendToSession, o as hasConversation, p as revealItermSession, r as buildDeduped, s as launchInDir, t as cmdMain, u as printExitDir } from "./main-resolver-
|
|
18
|
-
import {
|
|
10
|
+
import { _ as claudeProjectsDir, a as findLatestNote, b as transcriptFiles, c as extractAndStoreTriples, d as loadScanConfig, g as upsertSession, h as upsertProject, i as applyContinue, m as saveScanConfig, o as findNotesDir$1, p as resolveHome, r as appendCheckpointToNote, s as readBodyFile, t as readContextHandoverCache, u as cmdScan, v as findMovedProjects, y as scanTranscriptFolders } from "./context-handover-cache-C6_rs7JT.mjs";
|
|
11
|
+
import { a as expandHome, c as UNROUTED, d as daemonLogPath, f as daemonPidPath, i as ensureConfigDir, m as schedulerLogPath, n as CONFIG_FILE$2, o as loadConfig, p as paiSocketPath, s as OWNER_LABEL_PREFIX, t as CONFIG_DIR } from "./config-D1G9IFpn.mjs";
|
|
12
|
+
import { t as PaiClient } from "./ipc-client-C7AVpsyv.mjs";
|
|
13
|
+
import { r as humanDuration, t as createStorageBackend } from "./factory-Bc5EyN54.mjs";
|
|
14
|
+
import { _ as DEFAULT_CONTEXT_WINDOW, a as WorkersConfigError, b as readJsonStrict, l as isModelCapability, m as readWorkersSection, r as PROVIDER_TAGS, v as contextWindowFromModelId, x as writeJsonAtomic, y as stripModelVariant } from "./config-Dl8lT4Lu.mjs";
|
|
15
|
+
import { s as kgQuery } from "./kg-entity-DbOMPdF9.mjs";
|
|
16
|
+
import { _ as workersLogDir, f as eventsPath, n as ensureProxyRunning, p as ledgerPath, r as stopProxy, t as DEFAULT_PROXY_PORT } from "./server-BOuAOj9b.mjs";
|
|
17
|
+
import { _ as scanSessions, a as renderDedupedSessions, c as probeResume, d as callAiBroker, f as fetchLiveSessions, g as resolveSessionByNameOrId, h as fmtAge, i as normalizeName$2, l as restoreTopLevel, m as sendToSession, o as hasConversation, p as revealItermSession, r as buildDeduped, s as launchInDir, t as cmdMain, u as printExitDir } from "./main-resolver-CM1IHbuu.mjs";
|
|
18
|
+
import { D as loadStatus, M as parseRunnerArgs, S as UNLABELED, _ as openPaneForWorker, a as testProvider, d as handoffFromInside, g as openFollowPane, h as checkPaneForWorker, i as runWorker, l as discardWorker, o as describeMcp, p as sayToWorker, s as parseWorkerReport, t as runChain, u as mergeWorker } from "./chain-DhVHVnmT.mjs";
|
|
19
|
+
import { S as statusLineOutput, _ as updateProvider, a as addProvider, b as psOutput, c as describeProviders, d as resolveProviderName, f as setClass, g as unsetClass, h as setWorkersEnabled, i as fallbackStatusText, l as modelPrefsText, m as setProviderModel, n as fallbackOn, o as classTargetText, p as setProviderEnabled, r as fallbackStatus, s as describeModels, t as fallbackOff, u as removeProvider, v as useProvider, x as replayOutput, y as followWorkers } from "./fallback-CdXv-Np0.mjs";
|
|
19
20
|
import { appendFileSync, chmodSync, copyFileSync, createReadStream, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, readlinkSync, realpathSync, renameSync, statSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
|
|
20
21
|
import { homedir, platform, tmpdir } from "node:os";
|
|
21
22
|
import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
@@ -1890,7 +1891,7 @@ function cmdUnregister(db, slug, opts = {}) {
|
|
|
1890
1891
|
//#region src/cli/commands/project/projects-index.ts
|
|
1891
1892
|
function registerProjectsCommands(projectsCmd, getDb) {
|
|
1892
1893
|
projectsCmd.command("list", { isDefault: true }).description("Show the unified deduped listing (same as `pai`).\nUse --all to include cold / zero-session / archived projects.").option("--all", "Show all entries including cold / zero-session / archived projects").option("-n, --n <count>", "Max rows to show", "20").action(async (opts) => {
|
|
1893
|
-
const { cmdMain } = await import("./main-resolver-
|
|
1894
|
+
const { cmdMain } = await import("./main-resolver-E5WlilhM.mjs");
|
|
1894
1895
|
await cmdMain(getDb(), void 0, void 0, opts);
|
|
1895
1896
|
});
|
|
1896
1897
|
projectsCmd.command("list-raw").description("Raw registry listing with slug, path, status, last_active columns").option("--all", "Include archived projects (default: active only)").option("--status <status>", "Filter by status: active | archived").option("--tag <tag>", "Filter by tag").option("--type <type>", "Filter by type").action((opts) => {
|
|
@@ -2962,9 +2963,9 @@ function registerStatsCommands(memoryCmd, getDb) {
|
|
|
2962
2963
|
//#region src/cli/commands/memory/sources-cmd.ts
|
|
2963
2964
|
function registerSourcesCommand(memoryCmd) {
|
|
2964
2965
|
memoryCmd.command("sources").description("Show what the indexer has taken in: composition by source, which roots\ncontent enters from, the heaviest single files, and how many chunks are\nrewritten per day (which distinguishes a finite backlog from a treadmill).").option("--limit <n>", "Rows per section (default 8)", "8").action(async (opts) => {
|
|
2965
|
-
const { createStorageBackend } = await import("./factory-
|
|
2966
|
-
const { loadConfig } = await import("./config-
|
|
2967
|
-
const { cmdMemorySources } = await import("./sources-
|
|
2966
|
+
const { createStorageBackend } = await import("./factory-C7ua_3ik.mjs");
|
|
2967
|
+
const { loadConfig } = await import("./config-DD52BPB-.mjs");
|
|
2968
|
+
const { cmdMemorySources } = await import("./sources-ju6AA7lL.mjs");
|
|
2968
2969
|
let backend;
|
|
2969
2970
|
try {
|
|
2970
2971
|
backend = await createStorageBackend(loadConfig());
|
|
@@ -3651,8 +3652,8 @@ function cmdLogs(opts) {
|
|
|
3651
3652
|
}
|
|
3652
3653
|
function registerDaemonCommands(daemonCmd) {
|
|
3653
3654
|
daemonCmd.command("serve").description("Start the PAI daemon in the foreground").action(async () => {
|
|
3654
|
-
const { serve } = await import("./daemon-
|
|
3655
|
-
const { loadConfig: lc, ensureConfigDir } = await import("./config-
|
|
3655
|
+
const { serve } = await import("./daemon-BSL9sXxm.mjs");
|
|
3656
|
+
const { loadConfig: lc, ensureConfigDir } = await import("./config-DD52BPB-.mjs");
|
|
3656
3657
|
ensureConfigDir();
|
|
3657
3658
|
await serve(lc());
|
|
3658
3659
|
});
|
|
@@ -7229,7 +7230,7 @@ async function cmdExplore(note, opts) {
|
|
|
7229
7230
|
const depth = parseInt(opts.depth ?? "3", 10);
|
|
7230
7231
|
const direction = opts.direction ?? "both";
|
|
7231
7232
|
const mode = opts.mode ?? "all";
|
|
7232
|
-
const { zettelExplore } = await import("./zettelkasten-
|
|
7233
|
+
const { zettelExplore } = await import("./zettelkasten-DDvKRm2V.mjs");
|
|
7233
7234
|
const result = zettelExplore(getFedDb(), {
|
|
7234
7235
|
startNote: note,
|
|
7235
7236
|
depth,
|
|
@@ -7294,7 +7295,7 @@ async function cmdHealth(opts) {
|
|
|
7294
7295
|
const projectPath = opts.project;
|
|
7295
7296
|
const recentDays = parseInt(opts.days ?? "30", 10);
|
|
7296
7297
|
const includeTypes = opts.include ? opts.include.split(",").map((s) => s.trim()) : void 0;
|
|
7297
|
-
const { zettelHealth } = await import("./zettelkasten-
|
|
7298
|
+
const { zettelHealth } = await import("./zettelkasten-DDvKRm2V.mjs");
|
|
7298
7299
|
const result = zettelHealth(getFedDb(), {
|
|
7299
7300
|
scope,
|
|
7300
7301
|
projectPath,
|
|
@@ -7365,7 +7366,7 @@ async function cmdSurprise(note, opts) {
|
|
|
7365
7366
|
const limit = parseInt(opts.limit ?? "10", 10);
|
|
7366
7367
|
const minSimilarity = parseFloat(opts.minSimilarity ?? "0.3");
|
|
7367
7368
|
const minGraphDistance = parseInt(opts.minDistance ?? "3", 10);
|
|
7368
|
-
const { zettelSurprise } = await import("./zettelkasten-
|
|
7369
|
+
const { zettelSurprise } = await import("./zettelkasten-DDvKRm2V.mjs");
|
|
7369
7370
|
const db = getFedDb();
|
|
7370
7371
|
console.log();
|
|
7371
7372
|
console.log(header(" PAI Zettel Surprise"));
|
|
@@ -7420,7 +7421,7 @@ async function cmdSuggest(note, opts) {
|
|
|
7420
7421
|
const vaultProjectId = parseInt(opts.vaultProjectId, 10);
|
|
7421
7422
|
const limit = parseInt(opts.limit ?? "5", 10);
|
|
7422
7423
|
const excludeLinked = opts.excludeLinked !== false;
|
|
7423
|
-
const { zettelSuggest } = await import("./zettelkasten-
|
|
7424
|
+
const { zettelSuggest } = await import("./zettelkasten-DDvKRm2V.mjs");
|
|
7424
7425
|
const db = getFedDb();
|
|
7425
7426
|
console.log();
|
|
7426
7427
|
console.log(header(" PAI Zettel Suggest"));
|
|
@@ -7473,7 +7474,7 @@ async function cmdConverse(question, opts) {
|
|
|
7473
7474
|
const vaultProjectId = parseInt(opts.vaultProjectId, 10);
|
|
7474
7475
|
const depth = parseInt(opts.depth ?? "2", 10);
|
|
7475
7476
|
const limit = parseInt(opts.limit ?? "15", 10);
|
|
7476
|
-
const { zettelConverse } = await import("./zettelkasten-
|
|
7477
|
+
const { zettelConverse } = await import("./zettelkasten-DDvKRm2V.mjs");
|
|
7477
7478
|
const db = getFedDb();
|
|
7478
7479
|
console.log();
|
|
7479
7480
|
console.log(header(" PAI Zettel Converse"));
|
|
@@ -7536,7 +7537,7 @@ async function cmdThemes(opts) {
|
|
|
7536
7537
|
const minClusterSize = parseInt(opts.minSize ?? "3", 10);
|
|
7537
7538
|
const maxThemes = parseInt(opts.maxThemes ?? "10", 10);
|
|
7538
7539
|
const similarityThreshold = parseFloat(opts.threshold ?? "0.65");
|
|
7539
|
-
const { zettelThemes } = await import("./zettelkasten-
|
|
7540
|
+
const { zettelThemes } = await import("./zettelkasten-DDvKRm2V.mjs");
|
|
7540
7541
|
const db = getFedDb();
|
|
7541
7542
|
console.log();
|
|
7542
7543
|
console.log(header(" PAI Zettel Themes"));
|
|
@@ -9111,8 +9112,8 @@ async function escalate(task, headline, detail, state, now, opts) {
|
|
|
9111
9112
|
state.alarmedAt[task.id] = now;
|
|
9112
9113
|
let delivered = false;
|
|
9113
9114
|
try {
|
|
9114
|
-
const { routeNotification } = await import("./router-
|
|
9115
|
-
const { loadConfig } = await import("./config-
|
|
9115
|
+
const { routeNotification } = await import("./router-CAtyVQud.mjs");
|
|
9116
|
+
const { loadConfig } = await import("./config-DD52BPB-.mjs");
|
|
9116
9117
|
delivered = (await routeNotification({
|
|
9117
9118
|
event: "error",
|
|
9118
9119
|
title: `PAI: ${headline}`,
|
|
@@ -11728,10 +11729,10 @@ function cmdActive(db, opts) {
|
|
|
11728
11729
|
], rows));
|
|
11729
11730
|
}
|
|
11730
11731
|
async function cmdAutoRoute(opts) {
|
|
11731
|
-
const { autoRoute, formatAutoRoute, formatAutoRouteJson } = await import("./auto-route-
|
|
11732
|
+
const { autoRoute, formatAutoRoute, formatAutoRouteJson } = await import("./auto-route-BwzmlW3W.mjs");
|
|
11732
11733
|
const { openRegistry } = await import("./db-XEwJbuGO.mjs");
|
|
11733
|
-
const { createStorageBackend } = await import("./factory-
|
|
11734
|
-
const { loadConfig } = await import("./config-
|
|
11734
|
+
const { createStorageBackend } = await import("./factory-C7ua_3ik.mjs");
|
|
11735
|
+
const { loadConfig } = await import("./config-DD52BPB-.mjs");
|
|
11735
11736
|
const config = loadConfig();
|
|
11736
11737
|
const registryDb = openRegistry();
|
|
11737
11738
|
const federation = await createStorageBackend(config);
|
|
@@ -12393,9 +12394,6 @@ function cmdHandover(db, projectSlug, numberOrLatest, sessionId) {
|
|
|
12393
12394
|
* decision that depends on this number (the compaction handover chief among
|
|
12394
12395
|
* them) for the entire session.
|
|
12395
12396
|
*/
|
|
12396
|
-
/** Fallback window size when nothing on hand reports one. Matches the
|
|
12397
|
-
* default statusline-command.sh already falls back to. */
|
|
12398
|
-
const DEFAULT_CONTEXT_WINDOW = 2e5;
|
|
12399
12397
|
/** How many trailing lines of the transcript to scan for a usage entry.
|
|
12400
12398
|
* A single turn is rarely more than a handful of JSONL lines (assistant
|
|
12401
12399
|
* text + tool_use/tool_result pairs), so 40 comfortably covers one turn
|
|
@@ -12458,16 +12456,22 @@ function usageTotal(usage) {
|
|
|
12458
12456
|
* `message.usage` entry, read from the end backwards so a trailing line with
|
|
12459
12457
|
* no usage field (a plain text turn, a tool_result) doesn't hide one just
|
|
12460
12458
|
* before it.
|
|
12459
|
+
*
|
|
12460
|
+
* The window size, when the caller has none, is derived from the transcript's
|
|
12461
|
+
* own last assistant model id ("glm-5.3[1m]" → 1,000,000) before falling back
|
|
12462
|
+
* to the assumed default — a session whose model declares its window should
|
|
12463
|
+
* not be measured against a guess.
|
|
12461
12464
|
*/
|
|
12462
|
-
function contextFillFromTranscript(transcriptPath, windowSize
|
|
12463
|
-
if (!transcriptPath || !existsSync(transcriptPath)) return unknownReading(windowSize);
|
|
12465
|
+
function contextFillFromTranscript(transcriptPath, windowSize) {
|
|
12466
|
+
if (!transcriptPath || !existsSync(transcriptPath)) return unknownReading(windowSize ?? DEFAULT_CONTEXT_WINDOW);
|
|
12464
12467
|
let raw;
|
|
12465
12468
|
try {
|
|
12466
12469
|
raw = readFileSync(transcriptPath, "utf-8");
|
|
12467
12470
|
} catch {
|
|
12468
|
-
return unknownReading(windowSize);
|
|
12471
|
+
return unknownReading(windowSize ?? DEFAULT_CONTEXT_WINDOW);
|
|
12469
12472
|
}
|
|
12470
12473
|
const tail = raw.trim().split("\n").filter((l) => l.trim()).slice(-TRANSCRIPT_TAIL_LINES);
|
|
12474
|
+
let lastModel = null;
|
|
12471
12475
|
for (let i = tail.length - 1; i >= 0; i--) {
|
|
12472
12476
|
let entry;
|
|
12473
12477
|
try {
|
|
@@ -12475,28 +12479,32 @@ function contextFillFromTranscript(transcriptPath, windowSize = DEFAULT_CONTEXT_
|
|
|
12475
12479
|
} catch {
|
|
12476
12480
|
continue;
|
|
12477
12481
|
}
|
|
12482
|
+
if (entry?.type === "assistant" && lastModel === null) {
|
|
12483
|
+
const model = entry.message?.model;
|
|
12484
|
+
if (typeof model === "string" && model !== "") lastModel = model;
|
|
12485
|
+
}
|
|
12478
12486
|
const usage = entry?.message?.usage;
|
|
12479
12487
|
if (usage && typeof usage === "object") {
|
|
12488
|
+
const window = windowSize ?? contextWindowFromModelId(lastModel) ?? DEFAULT_CONTEXT_WINDOW;
|
|
12480
12489
|
const usedTokens = usageTotal(usage);
|
|
12481
12490
|
return {
|
|
12482
12491
|
status: "ok",
|
|
12483
12492
|
usedTokens,
|
|
12484
|
-
windowSize,
|
|
12485
|
-
fraction: usedTokens /
|
|
12493
|
+
windowSize: window,
|
|
12494
|
+
fraction: usedTokens / window,
|
|
12486
12495
|
source: "transcript"
|
|
12487
12496
|
};
|
|
12488
12497
|
}
|
|
12489
12498
|
}
|
|
12490
|
-
return unknownReading(windowSize);
|
|
12499
|
+
return unknownReading(windowSize ?? contextWindowFromModelId(lastModel) ?? DEFAULT_CONTEXT_WINDOW);
|
|
12491
12500
|
}
|
|
12492
12501
|
function getContextFill(input, now = Date.now()) {
|
|
12493
|
-
const windowSize = input.windowSize ?? DEFAULT_CONTEXT_WINDOW;
|
|
12494
12502
|
if (input.sessionId) {
|
|
12495
12503
|
const fromStatusline = readStatuslineFill(input.sessionId, now);
|
|
12496
12504
|
if (fromStatusline) return fromStatusline;
|
|
12497
12505
|
}
|
|
12498
|
-
if (input.transcriptPath) return contextFillFromTranscript(input.transcriptPath, windowSize);
|
|
12499
|
-
return unknownReading(windowSize);
|
|
12506
|
+
if (input.transcriptPath) return contextFillFromTranscript(input.transcriptPath, input.windowSize);
|
|
12507
|
+
return unknownReading(input.windowSize ?? DEFAULT_CONTEXT_WINDOW);
|
|
12500
12508
|
}
|
|
12501
12509
|
const DEFAULT_AUTOCOMPACT_PCT = 80;
|
|
12502
12510
|
/** How many of the most recent compact_boundary events to consider, and to
|
|
@@ -12543,13 +12551,42 @@ function listProjectTranscripts(cwd, projectsDir) {
|
|
|
12543
12551
|
const SYNTHETIC_MODEL = "<synthetic>";
|
|
12544
12552
|
function modelFamily(model) {
|
|
12545
12553
|
if (typeof model !== "string" || model === "" || model === SYNTHETIC_MODEL) return "unknown";
|
|
12546
|
-
|
|
12554
|
+
const base = stripModelVariant(model);
|
|
12555
|
+
return base.startsWith("claude-") ? "claude" : base;
|
|
12556
|
+
}
|
|
12557
|
+
/**
|
|
12558
|
+
* Is a model id foreign to this machine's sessions? A model is native when it
|
|
12559
|
+
* is a Claude model or one the worker registry configures (any provider's
|
|
12560
|
+
* default or fast alias — the models this stack actually runs on). Anything
|
|
12561
|
+
* else, with a readable model id, is foreign. Doubt (no id, unreadable
|
|
12562
|
+
* registry) reads as native: the callers that skip work on "foreign" must not
|
|
12563
|
+
* skip it on doubt.
|
|
12564
|
+
*/
|
|
12565
|
+
function isForeignModelFamily(family, nativeFamilies) {
|
|
12566
|
+
if (family === "unknown" || family === "claude") return false;
|
|
12567
|
+
return !(nativeFamilies ?? nativeModelFamilies()).has(family);
|
|
12568
|
+
}
|
|
12569
|
+
/** Families of every model id the worker registry configures. Never throws:
|
|
12570
|
+
* an unreadable or missing registry means "nothing configured", which leaves
|
|
12571
|
+
* every non-Claude family foreign — the historical behaviour. */
|
|
12572
|
+
function nativeModelFamilies(configPath) {
|
|
12573
|
+
const families = /* @__PURE__ */ new Set();
|
|
12574
|
+
try {
|
|
12575
|
+
for (const p of Object.values(readWorkersSection(configPath).workers.providers)) {
|
|
12576
|
+
families.add(modelFamily(p.models.default));
|
|
12577
|
+
if (p.models.fast) families.add(modelFamily(p.models.fast));
|
|
12578
|
+
}
|
|
12579
|
+
} catch {
|
|
12580
|
+
return families;
|
|
12581
|
+
}
|
|
12582
|
+
return families;
|
|
12547
12583
|
}
|
|
12548
12584
|
/**
|
|
12549
12585
|
* The family of the LAST assistant model in a transcript — scanned from the
|
|
12550
12586
|
* end so a long transcript costs one read and a few lines of parsing.
|
|
12551
|
-
* Unreadable or model-less transcripts are "unknown", never
|
|
12552
|
-
* the callers that skip work on
|
|
12587
|
+
* Unreadable or model-less transcripts are "unknown", never foreign:
|
|
12588
|
+
* the callers that skip work on foreign models must not skip it on doubt.
|
|
12589
|
+
* Pair with isForeignModelFamily to judge the key.
|
|
12553
12590
|
*/
|
|
12554
12591
|
function transcriptModelFamily(path) {
|
|
12555
12592
|
let raw;
|
|
@@ -12580,7 +12617,7 @@ function transcriptModelFamily(path) {
|
|
|
12580
12617
|
* the event's uuid (falling back to a timestamp+preTokens key for the rare
|
|
12581
12618
|
* line with no uuid) so an event mirrored into `sessions/` is counted once.
|
|
12582
12619
|
*/
|
|
12583
|
-
function readCompactBoundarySamples(cwd, projectsDir) {
|
|
12620
|
+
function readCompactBoundarySamples(cwd, projectsDir, nativeFamilies) {
|
|
12584
12621
|
const byKey = /* @__PURE__ */ new Map();
|
|
12585
12622
|
for (const path of listProjectTranscripts(cwd, projectsDir)) {
|
|
12586
12623
|
let raw;
|
|
@@ -12609,7 +12646,7 @@ function readCompactBoundarySamples(cwd, projectsDir) {
|
|
|
12609
12646
|
if (typeof preTokens !== "number" || !Number.isFinite(preTokens)) continue;
|
|
12610
12647
|
const timestampMs = entry.timestamp ? Date.parse(entry.timestamp) : NaN;
|
|
12611
12648
|
if (!Number.isFinite(timestampMs)) continue;
|
|
12612
|
-
if (modelFamily(lastModel)
|
|
12649
|
+
if (isForeignModelFamily(modelFamily(lastModel), nativeFamilies)) {
|
|
12613
12650
|
foreignDiscards++;
|
|
12614
12651
|
continue;
|
|
12615
12652
|
}
|
|
@@ -12621,7 +12658,7 @@ function readCompactBoundarySamples(cwd, projectsDir) {
|
|
|
12621
12658
|
uuid: entry.uuid
|
|
12622
12659
|
});
|
|
12623
12660
|
}
|
|
12624
|
-
if (foreignDiscards > 0) console.error(`[context-fill] ignored ${foreignDiscards} compaction sample(s) from a
|
|
12661
|
+
if (foreignDiscards > 0) console.error(`[context-fill] ignored ${foreignDiscards} compaction sample(s) from a foreign-model transcript (model=${lastModel}): ${path}`);
|
|
12625
12662
|
}
|
|
12626
12663
|
return [...byKey.values()].sort((a, b) => b.timestampMs - a.timestampMs);
|
|
12627
12664
|
}
|
|
@@ -12632,9 +12669,9 @@ function readCompactBoundarySamples(cwd, projectsDir) {
|
|
|
12632
12669
|
* checkable: print these and the timestamps prove which three events
|
|
12633
12670
|
* produced it, rather than asking for trust.
|
|
12634
12671
|
*/
|
|
12635
|
-
function selectedCompactionSamples(cwd, projectsDir = CLAUDE_PROJECTS_DIR) {
|
|
12672
|
+
function selectedCompactionSamples(cwd, projectsDir = CLAUDE_PROJECTS_DIR, configPath) {
|
|
12636
12673
|
if (!cwd) return [];
|
|
12637
|
-
return readCompactBoundarySamples(cwd, projectsDir).slice(0, MEASURED_TRIGGER_SAMPLE_SIZE);
|
|
12674
|
+
return readCompactBoundarySamples(cwd, projectsDir, nativeModelFamilies(configPath)).slice(0, MEASURED_TRIGGER_SAMPLE_SIZE);
|
|
12638
12675
|
}
|
|
12639
12676
|
/**
|
|
12640
12677
|
* The measured compaction trigger for a project, or null when it has no
|
|
@@ -12647,8 +12684,8 @@ function selectedCompactionSamples(cwd, projectsDir = CLAUDE_PROJECTS_DIR) {
|
|
|
12647
12684
|
* timestamp" both matter (a file-mtime-ordered, non-deduplicated version of
|
|
12648
12685
|
* this returned a stale pre-regime-change trigger on real project data).
|
|
12649
12686
|
*/
|
|
12650
|
-
function measureCompactionTrigger(cwd, projectsDir = CLAUDE_PROJECTS_DIR) {
|
|
12651
|
-
const samples = selectedCompactionSamples(cwd, projectsDir);
|
|
12687
|
+
function measureCompactionTrigger(cwd, projectsDir = CLAUDE_PROJECTS_DIR, configPath) {
|
|
12688
|
+
const samples = selectedCompactionSamples(cwd, projectsDir, configPath);
|
|
12652
12689
|
if (samples.length === 0) return null;
|
|
12653
12690
|
const trigger = Math.min(...samples.map((s) => s.preTokens));
|
|
12654
12691
|
console.error(`[context-fill] measured trigger for ${cwd}: ${trigger} (minimum of ` + samples.map((s) => `${s.preTokens}@${s.timestamp}`).join(", ") + ")");
|
|
@@ -12908,8 +12945,8 @@ async function checkAndEnqueueContextHandover(input, deps = defaultDeps) {
|
|
|
12908
12945
|
console.error(`[context-handover-trigger] session ${input.sessionId}: worker session (PAI_WORKER=1) — no handover.`);
|
|
12909
12946
|
return NOTHING;
|
|
12910
12947
|
}
|
|
12911
|
-
if (input.transcriptPath && transcriptModelFamily(input.transcriptPath)
|
|
12912
|
-
console.error(`[context-handover-trigger] session ${input.sessionId}: transcript written by a
|
|
12948
|
+
if (input.transcriptPath && isForeignModelFamily(transcriptModelFamily(input.transcriptPath))) {
|
|
12949
|
+
console.error(`[context-handover-trigger] session ${input.sessionId}: transcript written by a model this machine does not run — no handover.`);
|
|
12913
12950
|
return NOTHING;
|
|
12914
12951
|
}
|
|
12915
12952
|
let state = deps.loadState(input.sessionId);
|
|
@@ -13591,8 +13628,11 @@ function registerSessionCommands(sessionCmd, getDb) {
|
|
|
13591
13628
|
* - body → --append-system-prompt (prepended, so an explicit caller
|
|
13592
13629
|
* flag still wins);
|
|
13593
13630
|
* - tools → --allowedTools;
|
|
13594
|
-
* - model → a task class (haiku→simple, sonnet→implement,
|
|
13595
|
-
*
|
|
13631
|
+
* - model → a task class via its tier (haiku→simple, sonnet→implement,
|
|
13632
|
+
* opus→complex). Non-Anthropic ids map through the provider
|
|
13633
|
+
* registry (models.fast → haiku tier, models.default → sonnet
|
|
13634
|
+
* tier, a provider's modelTiers override if set), unless
|
|
13635
|
+
* --class is given.
|
|
13596
13636
|
*/
|
|
13597
13637
|
/** Directory the agent library lives in. */
|
|
13598
13638
|
function agentsDir() {
|
|
@@ -13651,13 +13691,43 @@ function loadAgent(name) {
|
|
|
13651
13691
|
}
|
|
13652
13692
|
return parseAgentFile(name, text, path);
|
|
13653
13693
|
}
|
|
13654
|
-
/**
|
|
13655
|
-
|
|
13656
|
-
|
|
13694
|
+
/** Tier → task class: the cheap tier runs as simple, the middle as
|
|
13695
|
+
* implement, the top as complex. */
|
|
13696
|
+
const TIER_CLASS = {
|
|
13697
|
+
haiku: "simple",
|
|
13698
|
+
sonnet: "implement",
|
|
13699
|
+
opus: "complex"
|
|
13700
|
+
};
|
|
13701
|
+
/** Which tier a model id belongs to: one of the CLI's tier aliases, or an
|
|
13702
|
+
* exact match against a configured provider's models (a modelTiers override
|
|
13703
|
+
* first, then fast → haiku tier, default → sonnet tier). null = no match. */
|
|
13704
|
+
function modelTier(model, providers) {
|
|
13657
13705
|
const m = model.toLowerCase();
|
|
13658
|
-
if (m.includes("haiku")) return "
|
|
13659
|
-
if (m.includes("sonnet")) return "
|
|
13660
|
-
if (m.includes("opus")) return "
|
|
13706
|
+
if (m.includes("haiku")) return "haiku";
|
|
13707
|
+
if (m.includes("sonnet")) return "sonnet";
|
|
13708
|
+
if (m.includes("opus")) return "opus";
|
|
13709
|
+
if (providers) for (const p of Object.values(providers)) {
|
|
13710
|
+
const override = p.modelTiers?.[model];
|
|
13711
|
+
if (override) return override;
|
|
13712
|
+
if (p.models.fast === model) return "haiku";
|
|
13713
|
+
if (p.models.default === model) return "sonnet";
|
|
13714
|
+
}
|
|
13715
|
+
return null;
|
|
13716
|
+
}
|
|
13717
|
+
/** Model ids already warned about — one line per id, not one per run. */
|
|
13718
|
+
const unmatchedTierLogged = /* @__PURE__ */ new Set();
|
|
13719
|
+
/** Map an agent's front-matter model to a worker class. An id that matches
|
|
13720
|
+
* no tier is logged once and falls back to the middle tier's class rather
|
|
13721
|
+
* than dropping the hint silently. */
|
|
13722
|
+
function modelToClass(model, providers) {
|
|
13723
|
+
if (!model) return void 0;
|
|
13724
|
+
const tier = modelTier(model, providers);
|
|
13725
|
+
if (tier) return TIER_CLASS[tier];
|
|
13726
|
+
if (!unmatchedTierLogged.has(model)) {
|
|
13727
|
+
unmatchedTierLogged.add(model);
|
|
13728
|
+
console.error(`[agents] model "${model}" matches no known tier — falling back to the ${TIER_CLASS.sonnet} class.`);
|
|
13729
|
+
}
|
|
13730
|
+
return TIER_CLASS.sonnet;
|
|
13661
13731
|
}
|
|
13662
13732
|
/** Extra claude args the definition contributes (before the caller's own). */
|
|
13663
13733
|
function agentClaudeArgs(def) {
|
|
@@ -13668,12 +13738,12 @@ function agentClaudeArgs(def) {
|
|
|
13668
13738
|
}
|
|
13669
13739
|
/** `<agent>: <first 50 chars of prompt>` — the default label for a run. */
|
|
13670
13740
|
function agentLabel(name, prompt) {
|
|
13671
|
-
return `${name}: ${prompt ??
|
|
13741
|
+
return `${name}: ${prompt ?? UNLABELED}`.slice(0, name.length + 2 + 50);
|
|
13672
13742
|
}
|
|
13673
13743
|
|
|
13674
13744
|
//#endregion
|
|
13675
13745
|
//#region src/cli/commands/worker/providers.ts
|
|
13676
|
-
function fail$
|
|
13746
|
+
function fail$2(e) {
|
|
13677
13747
|
const msg = e instanceof Error ? e.message : String(e);
|
|
13678
13748
|
console.error(err("pai worker: ") + msg);
|
|
13679
13749
|
process.exitCode = 1;
|
|
@@ -13763,7 +13833,7 @@ function registerWorkerProviderCommands(providersCmd) {
|
|
|
13763
13833
|
if (workers.active === name) console.log(` active: ${name} — workers ${workers.enabled ? "on" : "off"}`);
|
|
13764
13834
|
for (const line of describeProviders(workers)) console.log(dim$1(` ${line}`));
|
|
13765
13835
|
} catch (e) {
|
|
13766
|
-
fail$
|
|
13836
|
+
fail$2(e);
|
|
13767
13837
|
}
|
|
13768
13838
|
});
|
|
13769
13839
|
providersCmd.command("update <name>").description("Change cost tier and tags of a provider (routing constraints use these)").option("--cost-tier <1-5>", "Cost tier 1 (cheapest) … 5 (most expensive)", parseCostTier).option("--tags <tags>", "Capability tags, comma-separated (from: " + PROVIDER_TAGS.join(", ") + "); --tags '' clears", (v, acc) => [...acc, v], []).action((name, opts) => {
|
|
@@ -13778,7 +13848,7 @@ function registerWorkerProviderCommands(providersCmd) {
|
|
|
13778
13848
|
const { workers } = readWorkersSection();
|
|
13779
13849
|
for (const line of describeProviders(workers)) console.log(dim$1(` ${line}`));
|
|
13780
13850
|
} catch (e) {
|
|
13781
|
-
fail$
|
|
13851
|
+
fail$2(e);
|
|
13782
13852
|
}
|
|
13783
13853
|
});
|
|
13784
13854
|
providersCmd.command("remove <name>").description("Remove a provider and any classes pointing at it").action((name) => {
|
|
@@ -13786,7 +13856,7 @@ function registerWorkerProviderCommands(providersCmd) {
|
|
|
13786
13856
|
removeProvider(name);
|
|
13787
13857
|
console.log(ok$1(`provider ${name} removed`));
|
|
13788
13858
|
} catch (e) {
|
|
13789
|
-
fail$
|
|
13859
|
+
fail$2(e);
|
|
13790
13860
|
}
|
|
13791
13861
|
});
|
|
13792
13862
|
providersCmd.command("use <name>").description("Make this provider the active one for runs without --provider/--class").action((name) => {
|
|
@@ -13794,7 +13864,7 @@ function registerWorkerProviderCommands(providersCmd) {
|
|
|
13794
13864
|
useProvider(name);
|
|
13795
13865
|
console.log(ok$1(`active provider: ${name}`));
|
|
13796
13866
|
} catch (e) {
|
|
13797
|
-
fail$
|
|
13867
|
+
fail$2(e);
|
|
13798
13868
|
}
|
|
13799
13869
|
});
|
|
13800
13870
|
providersCmd.command("enable <name>").description("Enable a provider (also clears its cooldown)").action((name) => {
|
|
@@ -13802,7 +13872,7 @@ function registerWorkerProviderCommands(providersCmd) {
|
|
|
13802
13872
|
setProviderEnabled(name, true);
|
|
13803
13873
|
console.log(ok$1(`provider ${name} enabled`));
|
|
13804
13874
|
} catch (e) {
|
|
13805
|
-
fail$
|
|
13875
|
+
fail$2(e);
|
|
13806
13876
|
}
|
|
13807
13877
|
});
|
|
13808
13878
|
providersCmd.command("disable <name>").description("Disable a provider (auto-routing skips it; --provider still works)").action((name) => {
|
|
@@ -13810,7 +13880,7 @@ function registerWorkerProviderCommands(providersCmd) {
|
|
|
13810
13880
|
setProviderEnabled(name, false);
|
|
13811
13881
|
console.log(ok$1(`provider ${name} disabled`));
|
|
13812
13882
|
} catch (e) {
|
|
13813
|
-
fail$
|
|
13883
|
+
fail$2(e);
|
|
13814
13884
|
}
|
|
13815
13885
|
});
|
|
13816
13886
|
providersCmd.command("test [name]").description("One-word pong probe through a provider (default: the active one)").action(async (name) => {
|
|
@@ -13830,7 +13900,7 @@ function registerWorkerProviderCommands(providersCmd) {
|
|
|
13830
13900
|
console.log(` reply: ${r.result.slice(0, 200)}`);
|
|
13831
13901
|
process.exitCode = r.ok ? 0 : 1;
|
|
13832
13902
|
} catch (e) {
|
|
13833
|
-
fail$
|
|
13903
|
+
fail$2(e);
|
|
13834
13904
|
}
|
|
13835
13905
|
});
|
|
13836
13906
|
}
|
|
@@ -13851,7 +13921,7 @@ function registerClassSubcommands(classesCmd) {
|
|
|
13851
13921
|
setClass(cls, built);
|
|
13852
13922
|
console.log(ok$1(`class ${cls} → ${classTargetText(built)}`));
|
|
13853
13923
|
} catch (e) {
|
|
13854
|
-
fail$
|
|
13924
|
+
fail$2(e);
|
|
13855
13925
|
}
|
|
13856
13926
|
});
|
|
13857
13927
|
classesCmd.command("unset <class>").description("Remove a class (runs then use the active provider)").action((cls) => {
|
|
@@ -13859,7 +13929,7 @@ function registerClassSubcommands(classesCmd) {
|
|
|
13859
13929
|
unsetClass(cls);
|
|
13860
13930
|
console.log(ok$1(`class ${cls} removed`));
|
|
13861
13931
|
} catch (e) {
|
|
13862
|
-
fail$
|
|
13932
|
+
fail$2(e);
|
|
13863
13933
|
}
|
|
13864
13934
|
});
|
|
13865
13935
|
}
|
|
@@ -13869,6 +13939,130 @@ function registerWorkerClassCommands(workerCmd) {
|
|
|
13869
13939
|
registerClassSubcommands(workerCmd.command("roles", { hidden: true }).description("Alias of `classes` (roles was renamed to classes)").action(() => printClasses()));
|
|
13870
13940
|
}
|
|
13871
13941
|
|
|
13942
|
+
//#endregion
|
|
13943
|
+
//#region src/cli/commands/worker/model.ts
|
|
13944
|
+
function fail$1(e) {
|
|
13945
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
13946
|
+
console.error(err("pai worker: ") + msg);
|
|
13947
|
+
process.exitCode = 1;
|
|
13948
|
+
}
|
|
13949
|
+
function registerWorkerModelCommand(workerCmd) {
|
|
13950
|
+
workerCmd.command("model [what] [model]").description("Model ids per provider: no args lists them,\n`model <model-id>` sets the active provider's default model (back-compat),\n`model <capability>` shows one capability, `model <capability> <model-id>` sets it.\nCapabilities: default, fast, image. --provider targets another provider.").option("--provider <name>", "Provider to read or change (default: the active one)").action((what, model, opts) => {
|
|
13951
|
+
try {
|
|
13952
|
+
const { workers } = readWorkersSection();
|
|
13953
|
+
if (what === void 0) {
|
|
13954
|
+
for (const line of describeModels(workers)) console.log(` ${line}`);
|
|
13955
|
+
return;
|
|
13956
|
+
}
|
|
13957
|
+
let capability = "default";
|
|
13958
|
+
let id = what;
|
|
13959
|
+
if (isModelCapability(what)) {
|
|
13960
|
+
capability = what;
|
|
13961
|
+
if (model === void 0) {
|
|
13962
|
+
const name = resolveProviderName(workers, opts.provider);
|
|
13963
|
+
const p = workers.providers[name];
|
|
13964
|
+
if (p) console.log(` ${name} ${capability} ${p.models[capability] ?? "(none)"}`);
|
|
13965
|
+
return;
|
|
13966
|
+
}
|
|
13967
|
+
id = model;
|
|
13968
|
+
} else if (model !== void 0) throw new WorkersConfigError(`unexpected second argument "${model}" — usage: model [<capability>] <model-id>`);
|
|
13969
|
+
const name = resolveProviderName(workers, opts.provider);
|
|
13970
|
+
const p = setProviderModel(name, capability, id).providers[name];
|
|
13971
|
+
if (p) {
|
|
13972
|
+
console.log(ok$1(`${name} ${capability} model: ${p.models[capability]}`));
|
|
13973
|
+
console.log(dim$1(` ${modelPrefsText(p)}`));
|
|
13974
|
+
}
|
|
13975
|
+
} catch (e) {
|
|
13976
|
+
fail$1(e);
|
|
13977
|
+
}
|
|
13978
|
+
});
|
|
13979
|
+
}
|
|
13980
|
+
|
|
13981
|
+
//#endregion
|
|
13982
|
+
//#region src/workers/wait.ts
|
|
13983
|
+
/**
|
|
13984
|
+
* wait.ts — `pai worker wait <id...>`: the deterministic poller.
|
|
13985
|
+
*
|
|
13986
|
+
* A script, not guidance: polls each worker's status file until every one is
|
|
13987
|
+
* terminal (done/failed/killed/lost), then returns their result texts. The
|
|
13988
|
+
* orchestrator's Bash call stays synchronous and gets the JSON on stdout,
|
|
13989
|
+
* with exit 1 naming whoever failed or timed out.
|
|
13990
|
+
*/
|
|
13991
|
+
const TERMINAL = [
|
|
13992
|
+
"done",
|
|
13993
|
+
"failed",
|
|
13994
|
+
"killed",
|
|
13995
|
+
"lost"
|
|
13996
|
+
];
|
|
13997
|
+
function sleep$1(ms) {
|
|
13998
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
13999
|
+
}
|
|
14000
|
+
/**
|
|
14001
|
+
* The `result` text of the last result event in the worker's `<id>.jsonl`,
|
|
14002
|
+
* scanning the file backwards; null when the file or the event is absent.
|
|
14003
|
+
*/
|
|
14004
|
+
function lastResultText(logDir, id) {
|
|
14005
|
+
let raw;
|
|
14006
|
+
try {
|
|
14007
|
+
raw = readFileSync(eventsPath(logDir, id), "utf8");
|
|
14008
|
+
} catch {
|
|
14009
|
+
return null;
|
|
14010
|
+
}
|
|
14011
|
+
const lines = raw.split("\n");
|
|
14012
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
14013
|
+
const line = lines[i].trim();
|
|
14014
|
+
if (!line.startsWith("{")) continue;
|
|
14015
|
+
try {
|
|
14016
|
+
const e = JSON.parse(line);
|
|
14017
|
+
if (e.type === "result" && typeof e.result === "string") return e.result;
|
|
14018
|
+
} catch {}
|
|
14019
|
+
}
|
|
14020
|
+
return null;
|
|
14021
|
+
}
|
|
14022
|
+
function toWaitResult(logDir, st) {
|
|
14023
|
+
const result = lastResultText(logDir, st.id);
|
|
14024
|
+
return {
|
|
14025
|
+
id: st.id,
|
|
14026
|
+
label: st.label,
|
|
14027
|
+
state: st.state,
|
|
14028
|
+
rc: st.rc,
|
|
14029
|
+
secs: st.secs,
|
|
14030
|
+
ok: st.state === "done" && (st.rc ?? 0) === 0,
|
|
14031
|
+
result,
|
|
14032
|
+
report: parseWorkerReport(result ?? "")
|
|
14033
|
+
};
|
|
14034
|
+
}
|
|
14035
|
+
/**
|
|
14036
|
+
* Wait until every named worker reaches a terminal state. Unknown ids throw
|
|
14037
|
+
* immediately. On timeout nothing is thrown: the return carries what is known
|
|
14038
|
+
* and `timedOut` names the still-pending ids.
|
|
14039
|
+
*/
|
|
14040
|
+
async function waitWorkers(logDir, ids, opts = {}) {
|
|
14041
|
+
const timeoutMs = opts.timeoutMs ?? 9e5;
|
|
14042
|
+
const intervalMs = opts.intervalMs ?? 2e3;
|
|
14043
|
+
const known = /* @__PURE__ */ new Map();
|
|
14044
|
+
const pending = /* @__PURE__ */ new Set();
|
|
14045
|
+
for (const id of ids) {
|
|
14046
|
+
const st = loadStatus(logDir, id);
|
|
14047
|
+
if (!st) throw new Error(`no worker named "${id}"`);
|
|
14048
|
+
known.set(id, st);
|
|
14049
|
+
if (!TERMINAL.includes(st.state)) pending.add(id);
|
|
14050
|
+
}
|
|
14051
|
+
const deadline = Date.now() + timeoutMs;
|
|
14052
|
+
while (pending.size > 0 && Date.now() < deadline) {
|
|
14053
|
+
await sleep$1(Math.min(intervalMs, Math.max(1, deadline - Date.now())));
|
|
14054
|
+
for (const id of [...pending]) {
|
|
14055
|
+
const st = loadStatus(logDir, id);
|
|
14056
|
+
if (st) known.set(id, st);
|
|
14057
|
+
if (!st || TERMINAL.includes(known.get(id).state)) pending.delete(id);
|
|
14058
|
+
}
|
|
14059
|
+
}
|
|
14060
|
+
return {
|
|
14061
|
+
results: ids.map((id) => toWaitResult(logDir, known.get(id))),
|
|
14062
|
+
timedOut: [...pending]
|
|
14063
|
+
};
|
|
14064
|
+
}
|
|
14065
|
+
|
|
13872
14066
|
//#endregion
|
|
13873
14067
|
//#region src/cli/commands/worker/index.ts
|
|
13874
14068
|
function currentLogDir() {
|
|
@@ -13890,7 +14084,13 @@ function registerWorkerCommands(workerCmd) {
|
|
|
13890
14084
|
if (opts.agent) {
|
|
13891
14085
|
const def = loadAgent(opts.agent);
|
|
13892
14086
|
claudeArgs = [...agentClaudeArgs(def), ...args];
|
|
13893
|
-
|
|
14087
|
+
let agentProviders;
|
|
14088
|
+
try {
|
|
14089
|
+
agentProviders = readWorkersSection().workers.providers;
|
|
14090
|
+
} catch {
|
|
14091
|
+
agentProviders = void 0;
|
|
14092
|
+
}
|
|
14093
|
+
agentClass = modelToClass(def.model, agentProviders);
|
|
13894
14094
|
if (!label) label = agentLabel(opts.agent, parseRunnerArgs(args).prompt);
|
|
13895
14095
|
}
|
|
13896
14096
|
if (opts.chain) {
|
|
@@ -14035,13 +14235,31 @@ function registerWorkerCommands(workerCmd) {
|
|
|
14035
14235
|
fail(e);
|
|
14036
14236
|
}
|
|
14037
14237
|
});
|
|
14038
|
-
workerCmd.command("merge <id>").description("Merge a worker's worktree branch (worker/<id>) into the original checkout, then remove the worktree").action((id) => {
|
|
14238
|
+
workerCmd.command("merge <id>").description("Merge a worker's worktree branch (worker/<id>) into the original checkout, then remove the worktree and delete the branch").action((id) => {
|
|
14039
14239
|
try {
|
|
14040
14240
|
console.log(mergeWorker(currentLogDir(), id));
|
|
14041
14241
|
} catch (e) {
|
|
14042
14242
|
fail(e);
|
|
14043
14243
|
}
|
|
14044
14244
|
});
|
|
14245
|
+
workerCmd.command("wait <ids...>").description("Poll workers until they finish; prints each result as one JSON line, exit 1 on failure or timeout").option("--timeout <secs>", "Give up after this many seconds (default 900)", parseIntArg).action(async (ids, opts) => {
|
|
14246
|
+
try {
|
|
14247
|
+
const { results, timedOut } = await waitWorkers(currentLogDir(), ids, { timeoutMs: (opts.timeout ?? 900) * 1e3 });
|
|
14248
|
+
for (const r of results) console.log(JSON.stringify(r));
|
|
14249
|
+
if (timedOut.length) {
|
|
14250
|
+
console.error(err(`pai worker wait: timed out waiting for ${timedOut.join(", ")}`));
|
|
14251
|
+
process.exitCode = 1;
|
|
14252
|
+
return;
|
|
14253
|
+
}
|
|
14254
|
+
const failed = results.filter((r) => !r.ok).map((r) => r.id);
|
|
14255
|
+
if (failed.length) {
|
|
14256
|
+
console.error(err(`pai worker wait: failed: ${failed.join(", ")}`));
|
|
14257
|
+
process.exitCode = 1;
|
|
14258
|
+
}
|
|
14259
|
+
} catch (e) {
|
|
14260
|
+
fail(e);
|
|
14261
|
+
}
|
|
14262
|
+
});
|
|
14045
14263
|
workerCmd.command("discard <id>").description("Drop a worker's worktree and branch, keeping nothing").action((id) => {
|
|
14046
14264
|
try {
|
|
14047
14265
|
console.log(discardWorker(currentLogDir(), id));
|
|
@@ -14131,9 +14349,9 @@ function registerWorkerCommands(workerCmd) {
|
|
|
14131
14349
|
fail(e);
|
|
14132
14350
|
}
|
|
14133
14351
|
});
|
|
14134
|
-
workerCmd.command("status-line [term] [cwd]").description("One-line worker summary for a status bar (empty when none in scope).\nCalled by statusline-command.sh with ITERM_SESSION_ID
|
|
14352
|
+
workerCmd.command("status-line [term] [cwd] [session]").description("One-line worker summary for a status bar (empty when none in scope).\nCalled by statusline-command.sh with ITERM_SESSION_ID, the pane cwd and\nthe claude session id (claims workers spawned by that session's Bash).").action((term, cwd, session) => {
|
|
14135
14353
|
try {
|
|
14136
|
-
const out = statusLineOutput(currentLogDir(), term ?? process.env.ITERM_SESSION_ID ?? "", cwd ?? process.cwd());
|
|
14354
|
+
const out = statusLineOutput(currentLogDir(), term ?? process.env.ITERM_SESSION_ID ?? "", cwd ?? process.cwd(), session ?? "");
|
|
14137
14355
|
if (out) console.log(out);
|
|
14138
14356
|
} catch (e) {
|
|
14139
14357
|
fail(e);
|
|
@@ -14155,6 +14373,31 @@ function registerWorkerCommands(workerCmd) {
|
|
|
14155
14373
|
fail(e);
|
|
14156
14374
|
}
|
|
14157
14375
|
});
|
|
14376
|
+
workerCmd.command("fallback [action] [provider]").description("Machine-wide fallback: every NEW Claude Code process runs on a worker\nprovider (settings.json env + model pin) until switched back.\non [provider] switches (default: active), off restores settings.json\nexactly, status shows state and running sessions. CLAUDE_SETTINGS_PATH\npoints at another settings.json for dry runs.").action((action, provider) => {
|
|
14377
|
+
try {
|
|
14378
|
+
if (action === void 0 || action === "status") {
|
|
14379
|
+
console.log(fallbackStatusText(fallbackStatus()).join("\n"));
|
|
14380
|
+
return;
|
|
14381
|
+
}
|
|
14382
|
+
if (action === "on") {
|
|
14383
|
+
const r = fallbackOn(provider);
|
|
14384
|
+
console.log(r.alreadyOn ? `fallback already on — provider ${r.provider}, env re-applied` : `fallback on — provider ${r.provider}; every new Claude Code process uses it`);
|
|
14385
|
+
console.log(` settings.json env: ${r.envKeys.join(", ")}`);
|
|
14386
|
+
console.log(` model pin: ${r.model}`);
|
|
14387
|
+
console.log("running sessions keep their current provider until restarted (see: pai worker fallback status)");
|
|
14388
|
+
return;
|
|
14389
|
+
}
|
|
14390
|
+
if (action === "off") {
|
|
14391
|
+
const r = fallbackOff();
|
|
14392
|
+
console.log(`fallback off — provider ${r.provider} released, settings.json restored`);
|
|
14393
|
+
console.log(` restored keys: ${r.envKeys.join(", ")}`);
|
|
14394
|
+
return;
|
|
14395
|
+
}
|
|
14396
|
+
fail(/* @__PURE__ */ new Error(`unknown fallback action "${action}" (expected: on, off, status)`));
|
|
14397
|
+
} catch (e) {
|
|
14398
|
+
fail(e);
|
|
14399
|
+
}
|
|
14400
|
+
});
|
|
14158
14401
|
workerCmd.command("install").description("Migrate: Agent hook in settings.json, ~/.local/bin glm* shims, old script cleanup").action(() => {
|
|
14159
14402
|
try {
|
|
14160
14403
|
const r = installWorkers();
|
|
@@ -14165,6 +14408,7 @@ function registerWorkerCommands(workerCmd) {
|
|
|
14165
14408
|
});
|
|
14166
14409
|
registerWorkerProviderCommands(workerCmd.command("providers").description("Providers: list, add, remove, use, enable, disable, test"));
|
|
14167
14410
|
registerWorkerClassCommands(workerCmd);
|
|
14411
|
+
registerWorkerModelCommand(workerCmd);
|
|
14168
14412
|
}
|
|
14169
14413
|
function parseIntArg(v) {
|
|
14170
14414
|
const n = parseInt(v, 10);
|
|
@@ -14534,8 +14778,8 @@ function analyzeProject(db, project) {
|
|
|
14534
14778
|
async function countVectorDbPaths(oldPaths) {
|
|
14535
14779
|
if (oldPaths.length === 0) return 0;
|
|
14536
14780
|
try {
|
|
14537
|
-
const { loadConfig } = await import("./config-
|
|
14538
|
-
const { PostgresBackend } = await import("./postgres-
|
|
14781
|
+
const { loadConfig } = await import("./config-DD52BPB-.mjs");
|
|
14782
|
+
const { PostgresBackend } = await import("./postgres-Dwxe290H.mjs");
|
|
14539
14783
|
const config = loadConfig();
|
|
14540
14784
|
if (config.storageBackend !== "postgres") return 0;
|
|
14541
14785
|
const pgBackend = new PostgresBackend(config.postgres ?? {});
|
|
@@ -14555,8 +14799,8 @@ async function countVectorDbPaths(oldPaths) {
|
|
|
14555
14799
|
async function updateVectorDbPaths(moves) {
|
|
14556
14800
|
if (moves.length === 0) return 0;
|
|
14557
14801
|
try {
|
|
14558
|
-
const { loadConfig } = await import("./config-
|
|
14559
|
-
const { PostgresBackend } = await import("./postgres-
|
|
14802
|
+
const { loadConfig } = await import("./config-DD52BPB-.mjs");
|
|
14803
|
+
const { PostgresBackend } = await import("./postgres-Dwxe290H.mjs");
|
|
14560
14804
|
const config = loadConfig();
|
|
14561
14805
|
if (config.storageBackend !== "postgres") return 0;
|
|
14562
14806
|
const pgBackend = new PostgresBackend(config.postgres ?? {});
|
|
@@ -15618,6 +15862,8 @@ async function runSelector(lines, onRemove) {
|
|
|
15618
15862
|
if (cur?.record.live) parts.push(chalk.cyan("g") + dim$1(" go to tab"));
|
|
15619
15863
|
if (cur?.record.dir) parts.push(chalk.cyan("n") + dim$1(" new"));
|
|
15620
15864
|
if (cur?.record.dir) parts.push(chalk.cyan("c") + dim$1(" cd"));
|
|
15865
|
+
if (cur?.record.dir) parts.push(chalk.cyan("w") + dim$1(" worker"));
|
|
15866
|
+
if (cur?.record.dir) parts.push(chalk.cyan("a") + dim$1(" claude"));
|
|
15621
15867
|
if (cur?.record.dir) parts.push(chalk.cyan("f") + dim$1(" finder"));
|
|
15622
15868
|
if (cur?.record.slug) parts.push(chalk.cyan("d") + dim$1(" remove"));
|
|
15623
15869
|
parts.push(chalk.cyan("s") + dim$1(" search"));
|
|
@@ -15714,6 +15960,14 @@ async function runSelector(lines, onRemove) {
|
|
|
15714
15960
|
record: cur.record,
|
|
15715
15961
|
action: "cd"
|
|
15716
15962
|
});
|
|
15963
|
+
if (s === "w" && cur.record.dir) return finish({
|
|
15964
|
+
record: cur.record,
|
|
15965
|
+
action: "worker"
|
|
15966
|
+
});
|
|
15967
|
+
if (s === "a" && cur.record.dir) return finish({
|
|
15968
|
+
record: cur.record,
|
|
15969
|
+
action: "anthropic"
|
|
15970
|
+
});
|
|
15717
15971
|
if (s === "f" && cur.record.dir) {
|
|
15718
15972
|
openInFileManager(cur.record.dir);
|
|
15719
15973
|
return;
|
|
@@ -15832,8 +16086,10 @@ async function cmdPick(db, opts = {}) {
|
|
|
15832
16086
|
printExitDir(record.dir);
|
|
15833
16087
|
return;
|
|
15834
16088
|
}
|
|
16089
|
+
const engine = action === "worker" ? "worker" : action === "anthropic" ? "claude" : void 0;
|
|
15835
16090
|
launchInDir(record.dir, record.name, {
|
|
15836
16091
|
forceFresh: true,
|
|
16092
|
+
engine,
|
|
15837
16093
|
dryRun: opts.dryRun
|
|
15838
16094
|
});
|
|
15839
16095
|
}
|
|
@@ -16081,4 +16337,4 @@ claude() {
|
|
|
16081
16337
|
|
|
16082
16338
|
//#endregion
|
|
16083
16339
|
export { drainStdio as n, buildProgram as t };
|
|
16084
|
-
//# sourceMappingURL=program-
|
|
16340
|
+
//# sourceMappingURL=program-AR0qlYRg.mjs.map
|