@tekmidian/pai 1.0.0 → 1.0.2
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/.claude-plugin/plugin.json +1 -1
- package/README.md +67 -5
- package/dist/aibroker-client-BxzeEHPF.mjs +3 -0
- package/dist/{aibroker-client-CXEYBzbf.mjs → aibroker-client-CQPGqLxL.mjs} +1 -1
- package/dist/atomic-file-BorMa4T3.mjs +21 -0
- package/dist/{auto-route-D5SXrMpB.mjs → auto-route-B4azPk4l.mjs} +3 -3
- package/dist/auto-route-BjoMHKyI.mjs +11 -0
- package/dist/budget-Dod6rnA9.mjs +15 -0
- package/dist/{caller-identity-CVTuiLSs.mjs → caller-identity-yLFb7CKq.mjs} +6 -5
- package/dist/{capacity-DaXrVj3J.mjs → capacity-DEveQdFV.mjs} +3 -3
- package/dist/{chain-BcQlIlEd.mjs → chain-D-yvET_y.mjs} +5 -5
- package/dist/cli/index.mjs +1621 -357
- package/dist/cockpit-actions-BWunx3rY.mjs +20 -0
- package/dist/{cockpit-actions-ODmt8yF9.mjs → cockpit-actions-C8GlTzts.mjs} +84 -42
- package/dist/cockpit-memory-vTlFWV7F.mjs +20 -0
- package/dist/{config-BSXKyeJ1.mjs → config-Bu1_vbY8.mjs} +42 -3
- package/dist/{config-B955yYmo.mjs → config-Cxi-aBf4.mjs} +2 -2
- package/dist/{config-TaWmdTLx.mjs → config-DtENJ6cL.mjs} +1 -1
- package/dist/{config-D5chi2LO.mjs → config-XpZWOYOG.mjs} +2 -2
- package/dist/{controls-BGkK_Bdi.mjs → controls-BcKFHeG1.mjs} +37 -22
- package/dist/daemon/index.mjs +43 -42
- package/dist/{daemon-CorGh6Ub.mjs → daemon-ColVHwGZ.mjs} +103 -55
- package/dist/daemon-N7WhYi6I.mjs +45 -0
- package/dist/daemon-mcp/index.mjs +40 -39
- package/dist/{define-DGFu-sCf.mjs → define-CjJsmq-6.mjs} +1 -1
- package/dist/{detect-C1d5cUkT.mjs → detect-9CZNO0yf.mjs} +2 -2
- package/dist/detect-D1ziFFfA.mjs +10 -0
- package/dist/{embed-pass-CeQD8kRE.mjs → embed-pass-DIWjA68P.mjs} +5 -5
- package/dist/{embedding-gate-BHuBsgHD.mjs → embedding-gate-6rZrWRXa.mjs} +5 -5
- package/dist/{embedding-gate-Z7CJSOJk.mjs → embedding-gate-Cnk4YCyX.mjs} +3 -3
- package/dist/{embeddings-D4t6L-EH.mjs → embeddings-BVq3esBF.mjs} +1 -1
- package/dist/{embeddings-OF9Pt4by.mjs → embeddings-CIkJBKd-.mjs} +1 -1
- package/dist/{endreason-x1KOSrcO.mjs → endreason-C577xIQz.mjs} +7 -6
- package/dist/{env-DArqGq-Z.mjs → env-BE8mrsxr.mjs} +1 -1
- package/dist/factory-Bsib-qDG.mjs +9 -0
- package/dist/{factory-BtjbQ0np.mjs → factory-DjAAsqr_.mjs} +15 -13
- package/dist/{fallback-BIyEpPsQ.mjs → fallback-DFlItw1Z.mjs} +5 -5
- package/dist/{fmt-age-BiSHrTKN.mjs → fmt-age-ByDkvkoU.mjs} +1 -1
- package/dist/{health-C6jZWvRG.mjs → health-Dnym-qcT.mjs} +4 -4
- package/dist/{helpers-DFmYRCOa.mjs → helpers-BD6V-p9w.mjs} +2 -2
- package/dist/helpers-CMGjy_0N.mjs +10 -0
- package/dist/{helpers-CJpb_MNB.mjs → helpers-CRuBUas3.mjs} +87 -38
- package/dist/hooks/capture-all-events.mjs +52 -11
- package/dist/hooks/capture-session-summary.mjs +64 -47
- package/dist/hooks/capture-tool-output.mjs +49 -8
- package/dist/hooks/context-compression-hook.mjs +30 -10
- package/dist/hooks/initialize-session.mjs +1 -0
- package/dist/hooks/load-core-context.mjs +1 -1
- package/dist/hooks/load-project-context.mjs +32 -29
- package/dist/hooks/security-validator.mjs +45 -13
- package/dist/hooks/stop-hook.mjs +54 -16
- package/dist/hooks/supervision-banner.mjs +9 -0
- package/dist/hooks/sync-todo-to-md.mjs +147 -113
- package/dist/hooks/worker-edit-repair.mjs +2 -1
- package/dist/hooks/worker-guard.mjs +40 -16
- package/dist/hooks/worker-note.mjs +12 -5
- package/dist/hooks/worker-path-repair.mjs +1 -1
- package/dist/hooks/worker-pool-host.mjs +214 -116
- package/dist/hooks/worker-status-line.mjs +195 -114
- package/dist/index.d.mts +18 -0
- package/dist/index.mjs +12 -12
- package/dist/{indexer-backend-BM2CUSu8.mjs → indexer-backend-_a6UNhXJ.mjs} +149 -96
- package/dist/{ipc-client-BMqWw_gv.mjs → ipc-client-CaiGJnSM.mjs} +1 -1
- package/dist/{ipc-client-YYDD6zzU.mjs → ipc-client-ZRmDKd5Z.mjs} +1 -1
- package/dist/kill-tree-BG7dRVtp.mjs +10 -0
- package/dist/{kill-tree-BjYz5BxK.mjs → kill-tree-EWYaEk5v.mjs} +8 -8
- package/dist/{launch-CLp0OJxV.mjs → launch-CXVlZjHt.mjs} +8 -8
- package/dist/{launch-DgqQdAjI.mjs → launch-Jh5NVeNe.mjs} +3 -3
- package/dist/local-candidate-DLdwQt0s.mjs +112 -0
- package/dist/local-instances-DOxSgT_L.mjs +210 -0
- package/dist/local-instances-ZeRkkuS5.mjs +6 -0
- package/dist/{local-tiers-DPZYqv9m.mjs → local-tiers-BE4jGaMa.mjs} +2 -2
- package/dist/{local-tiers-DnBIAkbK.mjs → local-tiers-DNMI5W86.mjs} +3 -3
- package/dist/{main-config-ops-C0SflOWk.mjs → main-config-ops-BEMpuhDz.mjs} +3 -3
- package/dist/{main-resolver-DVPpSWVy.mjs → main-resolver-3Ns1HPmS.mjs} +18 -17
- package/dist/{migrate-BUJHadA8.mjs → migrate-DrA_OwlZ.mjs} +45 -14
- package/dist/min-max-DrSRUaWQ.mjs +16 -0
- package/dist/{model-inventory-Dasber3S.mjs → model-inventory-BFVSNFT3.mjs} +13 -12
- package/dist/{models-add-Bt7aUHDs.mjs → models-add-BtB3Se6f.mjs} +39 -38
- package/dist/operator-BTqvTIc8.mjs +7 -0
- package/dist/{operator-DZxcP-g8.mjs → operator-CyuB3aVw.mjs} +3 -3
- package/dist/{pai-marker-kIYuNt3c.mjs → pai-marker-DurzIbw8.mjs} +7 -6
- package/dist/{pane-audit-OGYrOAik.mjs → pane-audit-BQytYa60.mjs} +7 -7
- package/dist/{paths-DoRuFc60.mjs → paths-CFHTloSe.mjs} +3 -3
- package/dist/{paths-DoIyRnhx.mjs → paths-CHifubDh.mjs} +3 -3
- package/dist/{planner-DLGOYlVb.mjs → planner-BM27GBfC.mjs} +31 -30
- package/dist/{pool-CZ5MZaXg.mjs → pool-BRvoOkv6.mjs} +3 -3
- package/dist/{pool-cli-BxNSPzzY.mjs → pool-cli-B_YR8_Gl.mjs} +5 -5
- package/dist/{pool-cli-CbJfl37y.mjs → pool-cli-DkZTAlSW.mjs} +6 -6
- package/dist/postgres-BdBNkL_l.mjs +7 -0
- package/dist/{postgres-CDnd_k5f.mjs → postgres-C6ti4haA.mjs} +55 -34
- package/dist/{project-setup-DM4npnL3.mjs → project-setup-CfpApz5o.mjs} +131 -74
- package/dist/providers-BeDiVEb-.mjs +16 -0
- package/dist/{providers-UsKtLcUR.mjs → providers-CblTFrhz.mjs} +6 -6
- package/dist/{query-feedback-I-txSnld.mjs → query-feedback-BRfPtqki.mjs} +2 -2
- package/dist/registrable-C7b6givx.mjs +9 -0
- package/dist/{registrable-LrRIVYQc.mjs → registrable-Uzgmfyhz.mjs} +4 -4
- package/dist/render-Cc2j5QG9.mjs +13 -0
- package/dist/{render-BDbb4CF-.mjs → render-CwIrgxLi.mjs} +8 -8
- package/dist/{reranker-B4r4vykM.mjs → reranker-8g6xMwP7.mjs} +1 -1
- package/dist/{reranker-DxxMCtA0.mjs → reranker-CqCbpGnX.mjs} +1 -1
- package/dist/{root-BMeJuHOb.mjs → root-BWy0c2Lq.mjs} +11 -11
- package/dist/root-wC_6Fx0B.mjs +36 -0
- package/dist/route-table-B7zpoypi.mjs +15 -0
- package/dist/{router-L8Nu-OHF.mjs → router-CQSc3lk3.mjs} +17 -7
- package/dist/{router-D6Ec6Fid.mjs → router-DwHJRgG9.mjs} +1 -1
- package/dist/{routing-CUyiglfu.mjs → routing-BAAST9vT.mjs} +27 -308
- package/dist/{routing-ZuGlc0ge.mjs → routing-CENt4HH1.mjs} +13 -12
- package/dist/{run-ulAi5dFD.mjs → run-6Q9kCPem.mjs} +35 -33
- package/dist/{scan-B7I0gPe-.mjs → scan-ZQWm-_se.mjs} +6 -6
- package/dist/{local-candidate-jOjTNlOL.mjs → scheduler-CtUyWJ3O.mjs} +7 -109
- package/dist/scheduler-dmHXoRvm.mjs +3 -0
- package/dist/{scope-D5VSQxe4.mjs → scope-D-h6F6DN.mjs} +4 -4
- package/dist/{search-CPoE0830.mjs → search-RSyeQqj1.mjs} +18 -18
- package/dist/session-Bok2PqRS.mjs +35 -0
- package/dist/{session-CNXF6DLP.mjs → session-DVUExUnX.mjs} +55 -31
- package/dist/session-scan-BJI_ZO8M.mjs +9 -0
- package/dist/{session-scan-BDLEc4w1.mjs → session-scan-W-gbwJHM.mjs} +6 -6
- package/dist/{sources-CjhUKKtO.mjs → sources-ESUkZaWv.mjs} +1 -1
- package/dist/{status-DYydKQUI.mjs → status-Dm4dYciN.mjs} +4 -4
- package/dist/{status-CvVi9cDf.mjs → status-ggJ7lgVg.mjs} +17 -9
- package/dist/{stop-words-SdSL1WKH.mjs → stop-words-DSEYQdNe.mjs} +1 -1
- package/dist/{test-isolation-CoDeOVXb.mjs → test-isolation-lqSmYxr0.mjs} +1 -1
- package/dist/{timeouts-OwEONmc8.mjs → timeouts-1MLooEBB.mjs} +1 -1
- package/dist/{tool-errors-AeRQuG3Y.mjs → tool-errors-7E13StWd.mjs} +4 -3
- package/dist/{tool-errors-R5E0fCgf.mjs → tool-errors-CJWODvlo.mjs} +6 -6
- package/dist/{viewer-DtWj5Vti.mjs → viewer-DcpJwGKE.mjs} +15 -15
- package/dist/viewer-MWBVJP3u.mjs +22 -0
- package/dist/{wait-BMUR-U-U.mjs → wait-ByV0OyMZ.mjs} +3 -3
- package/dist/{worker-config-BLqa1yiD.mjs → worker-config-BDYNxbYz.mjs} +294 -92
- package/dist/worker-config-gmAq_-rI.mjs +41 -0
- package/dist/{workers-config-DEI9lrV4.mjs → workers-config-f8KrkY4L.mjs} +2 -2
- package/dist/{worktree-zmRf556h.mjs → worktree-CrnOqTBW.mjs} +37 -7
- package/dist/{zettelkasten-nigq7fqs.mjs → zettelkasten-B_rRRRvD.mjs} +5 -5
- package/dist/{zettelkasten-Cr_Xj0mG.mjs → zettelkasten-BzMm8REH.mjs} +29 -19
- package/docs/README.md +2 -0
- package/docs/cockpit.md +10 -4
- package/docs/commands/README.md +4 -4
- package/docs/commands/backup.md +2 -0
- package/docs/commands/install.md +29 -4
- package/docs/commands/providers.md +1 -1
- package/docs/commands/restore.md +4 -0
- package/docs/commands/setup.md +29 -4
- package/docs/commands/worker.md +1 -1
- package/docs/config.md +2 -0
- package/docs/features.md +299 -0
- package/docs/images/architecture.drawio +51 -0
- package/docs/images/architecture.svg +3 -0
- package/docs/images/cockpit-01-system-tokens.jpg +0 -0
- package/docs/images/cockpit-02-totals-cache.jpg +0 -0
- package/docs/images/cockpit-03-local-servers-models-pool.jpg +0 -0
- package/docs/images/cockpit-04-workers-memory.jpg +0 -0
- package/docs/images/cockpit-05-performance.jpg +0 -0
- package/docs/images/cockpit-06-runs-speed-routing.jpg +0 -0
- package/docs/images/cockpit-07-settings-registry.jpg +0 -0
- package/docs/install/index.md +29 -0
- package/docs/three-tier-coding.md +1 -1
- package/gemini-extension.json +1 -1
- package/package.json +1 -5
- package/pai-plugin.json +1 -1
- package/plugins/context-preservation/plugin.json +1 -1
- package/plugins/core/plugin.json +1 -1
- package/plugins/core/skills/setup/SKILL.md +41 -9
- package/plugins/creative/plugin.json +1 -1
- package/plugins/observability/plugin.json +1 -1
- package/plugins/productivity/plugin.json +1 -1
- package/plugins/semantic-search/plugin.json +1 -1
- package/plugins/ui/plugin.json +1 -1
- package/plugins/zettelkasten/plugin.json +1 -1
- package/src/hooks/session-autosave.sh +8 -1
- package/src/hooks/session-stop.sh +8 -1
- package/src/hooks/ts/capture-all-events.ts +7 -12
- package/src/hooks/ts/lib/context-fill.ts +2 -1
- package/src/hooks/ts/lib/path-repair.ts +1 -1
- package/src/hooks/ts/lib/project-utils/notify.ts +1 -0
- package/src/hooks/ts/lib/project-utils/session-notes.ts +23 -6
- package/src/hooks/ts/lib/raw-capture.ts +36 -0
- package/src/hooks/ts/lib/session-summary.ts +129 -0
- package/src/hooks/ts/lib/todo-sync.ts +120 -0
- package/src/hooks/ts/lib/worker-git-guard.ts +1 -1
- package/src/hooks/ts/post-tool-use/capture-tool-output.ts +6 -10
- package/src/hooks/ts/post-tool-use/sync-todo-to-md.ts +5 -105
- package/src/hooks/ts/pre-compact/context-compression-hook.ts +1 -1
- package/src/hooks/ts/pre-tool-use/security-validator.ts +35 -14
- package/src/hooks/ts/session-end/capture-session-summary.ts +20 -128
- package/src/hooks/ts/session-start/load-core-context.ts +3 -3
- package/src/hooks/ts/session-start/load-project-context.ts +18 -22
- package/src/hooks/ts/stop/stop-hook.ts +13 -5
- package/src/hooks/ztk-auto.sh +7 -2
- package/dist/aibroker-client-JjE74jo0.mjs +0 -3
- package/dist/auto-route-BRk8NEFv.mjs +0 -11
- package/dist/budget-DuhQ2zzG.mjs +0 -14
- package/dist/cockpit-actions-DcQ-ucU8.mjs +0 -19
- package/dist/cockpit-memory-KV45PPO2.mjs +0 -19
- package/dist/daemon-C7yt_ptC.mjs +0 -44
- package/dist/detect-DRUkmHnb.mjs +0 -10
- package/dist/factory-DAGG9_n8.mjs +0 -9
- package/dist/helpers-DPJEHPq6.mjs +0 -10
- package/dist/kill-tree-LV0Q7Mte.mjs +0 -10
- package/dist/operator-CfL0HiBK.mjs +0 -7
- package/dist/postgres-DgqWyqhN.mjs +0 -7
- package/dist/providers-CTu2s1z2.mjs +0 -15
- package/dist/registrable-D9aNZOTh.mjs +0 -9
- package/dist/render-BSfVlYHj.mjs +0 -13
- package/dist/root-xI9DqVIe.mjs +0 -35
- package/dist/route-table-HjvnLVEU.mjs +0 -14
- package/dist/session-BJHzmUg2.mjs +0 -34
- package/dist/session-scan-YORKE1NO.mjs +0 -9
- package/dist/viewer-B8709jDN.mjs +0 -22
- package/dist/worker-config-D8tRuvo7.mjs +0 -40
- package/docs/images/cockpit-limits-routing.jpg +0 -0
- package/docs/images/cockpit-models.jpg +0 -0
- package/docs/images/cockpit-usage.jpg +0 -0
- package/docs/images/cockpit-workers-system.jpg +0 -0
- package/scripts/build-docs.mjs +0 -41
- package/scripts/build-hooks.mjs +0 -311
- package/scripts/build-skill-stubs.mjs +0 -216
- package/scripts/copy-defaults.mjs +0 -46
|
@@ -1,37 +1,39 @@
|
|
|
1
1
|
import { _ as warn, c as ok, i as err, n as dim } from "./utils-J2b9y8PC.mjs";
|
|
2
2
|
import { g as paiHomePath, h as paiHomeDir, l as claudeHomeDir, t as aibrokerHomeDir, u as claudeProjectsDir } from "./runtime-paths-WsO9sJFc.mjs";
|
|
3
|
-
import { Et as parseLedger, G as inlineWorkersYamlKeys, J as parseBuiltinAnthropic, K as migrateWorkersToYaml, Q as relocateWorkersYaml, R as isLoopbackUrl, T as parseProvider, W as initWorkersYaml, Y as parseWorkersYamlDocument, c as WorkersConfigError, et as workersYamlLegacyNotice, ft as parseEntry, it as yamlProviderToRaw, j as readWorkersSection, lt as findTier, m as isLocalProvider, o as PROVIDER_TAGS, p as getProviderOrNative, q as needsWorkersYamlRelocation, t as ANTHROPIC_NATIVE, tt as workersYamlPath, wt as appendLedger, y as nativeAnthropicProvider, z as loopbackUrl } from "./config-
|
|
4
|
-
import { D as readJsonStrict, O as writeJsonAtomic, f as readMainConfigRaw, m as deepMergeConfig, n as CONFIG_FILE, o as expandHome, u as paiConfigFilePath, v as shippedDefaultsDir, y as shippedMainDefaults } from "./config-
|
|
5
|
-
import { i as ledgerPath, t as WORKER_ID_RE, u as workersLogDir } from "./paths-
|
|
6
|
-
import { E as worktreesStatsCached, l as formatWorktreesStats } from "./worktree-
|
|
7
|
-
import { T as ownsPidCached, b as loadStatusesCached, g as isLive, v as loadStatus } from "./status-
|
|
8
|
-
import { C as describeMcp, _ as readPoolMetrics, f as poolMetricsPath, h as poolSettings, i as bundleBuildStamp, l as poolHostProbe, o as poolCarry, u as poolHostStale, v as readPoolState, x as warmOrCold } from "./pool-
|
|
9
|
-
import { a as ownerSessionName } from "./scope-
|
|
10
|
-
import { $t as
|
|
11
|
-
import { C as stopLines, T as tierButtons, _ as readLocalConfig, a as LocalTierError, c as fetchServedModels, f as listensOnPort, g as planStart, h as parseServers, l as fmtRss, m as parseLocalConfig, u as healthUrl, v as resolveModelPath, x as stopCommandFor } from "./local-tiers-
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import { l as reorderQueue, o as providerCap, s as queueRows, u as reorderQueueTo } from "./capacity-
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
3
|
+
import { Et as parseLedger, G as inlineWorkersYamlKeys, J as parseBuiltinAnthropic, K as migrateWorkersToYaml, Q as relocateWorkersYaml, R as isLoopbackUrl, T as parseProvider, W as initWorkersYaml, Y as parseWorkersYamlDocument, c as WorkersConfigError, et as workersYamlLegacyNotice, ft as parseEntry, it as yamlProviderToRaw, j as readWorkersSection, lt as findTier, m as isLocalProvider, o as PROVIDER_TAGS, p as getProviderOrNative, q as needsWorkersYamlRelocation, t as ANTHROPIC_NATIVE, tt as workersYamlPath, wt as appendLedger, y as nativeAnthropicProvider, z as loopbackUrl } from "./config-XpZWOYOG.mjs";
|
|
4
|
+
import { D as readJsonStrict, O as writeJsonAtomic, f as readMainConfigRaw, m as deepMergeConfig, n as CONFIG_FILE, o as expandHome, u as paiConfigFilePath, v as shippedDefaultsDir, y as shippedMainDefaults } from "./config-Bu1_vbY8.mjs";
|
|
5
|
+
import { i as ledgerPath, t as WORKER_ID_RE, u as workersLogDir } from "./paths-CHifubDh.mjs";
|
|
6
|
+
import { E as worktreesStatsCached, l as formatWorktreesStats } from "./worktree-CrnOqTBW.mjs";
|
|
7
|
+
import { T as ownsPidCached, b as loadStatusesCached, g as isLive, v as loadStatus } from "./status-ggJ7lgVg.mjs";
|
|
8
|
+
import { C as describeMcp, _ as readPoolMetrics, f as poolMetricsPath, h as poolSettings, i as bundleBuildStamp, l as poolHostProbe, o as poolCarry, u as poolHostStale, v as readPoolState, x as warmOrCold } from "./pool-BRvoOkv6.mjs";
|
|
9
|
+
import { a as ownerSessionName } from "./scope-D-h6F6DN.mjs";
|
|
10
|
+
import { $t as findLocal, Bt as routeRows, E as budgetCache, Ft as flowText, Gn as isTimeOrdered, Gt as setRoute, Ht as servingChip, I as buildSpeed, Kn as markTimeOrdered, Kt as setSessionRoute, L as percentile, Mt as clearSessionRoute, Ot as isTailnetOrLocalName, Rt as resolveSessionArg, Tt as duplicateModelIds, Vt as routeText, W as currentInventory, Xn as usageLogFile, Xt as clearPolicy, Yn as splitBySessionKind, Yt as POLICY_MODES, _n as pickLocal, at as readInventoryInput, cn as getProfile, en as onBattery, gn as localTierOrder, in as writePolicy, it as readInventory, jt as applyPolicyToRoutes, kt as loopbackRefusal, mn as currentLocalStatus, nn as readPolicy, rn as routeRun, rt as processTreeRssMb, tn as parseDuration, un as readProfiles, vn as probeLoopback, zt as routeChoices } from "./routing-BAAST9vT.mjs";
|
|
11
|
+
import { C as stopLines, T as tierButtons, _ as readLocalConfig, a as LocalTierError, c as fetchServedModels, f as listensOnPort, g as planStart, h as parseServers, l as fmtRss, m as parseLocalConfig, u as healthUrl, v as resolveModelPath, x as stopCommandFor } from "./local-tiers-BE4jGaMa.mjs";
|
|
12
|
+
import { _ as buildSlots, a as buildsDir, g as waitReason, l as listBuildsSync, m as ticketKind, n as breakStaleMutex, x as testSlots } from "./caller-identity-yLFb7CKq.mjs";
|
|
13
|
+
import { f as sharedScheduler, o as readSchedFile, u as schedPlain } from "./scheduler-CtUyWJ3O.mjs";
|
|
14
|
+
import { l as reorderQueue, o as providerCap, s as queueRows, u as reorderQueueTo } from "./capacity-DEveQdFV.mjs";
|
|
15
|
+
import { a as instancesFromProcesses, d as reconcileInstances, i as instanceNumber, l as readInstances, p as writeInstances, r as instanceEngineKey, u as readLiveInstances } from "./local-instances-DOxSgT_L.mjs";
|
|
16
|
+
import { i as localStatusLine, s as readLocalStatus } from "./local-candidate-DLdwQt0s.mjs";
|
|
17
|
+
import { t as LOCAL_PROBE_TIMEOUT_MS } from "./timeouts-1MLooEBB.mjs";
|
|
18
|
+
import { n as OPT, t as CliError } from "./define-CjJsmq-6.mjs";
|
|
19
|
+
import { c as resolveFromModule } from "./postgres-C6ti4haA.mjs";
|
|
20
|
+
import { c as ensureProxyRunning, l as proxyPort, u as stopProxy } from "./launch-Jh5NVeNe.mjs";
|
|
21
|
+
import { a as colorEnabled, f as renderTable, n as readBudget, o as makeStyle } from "./health-Dnym-qcT.mjs";
|
|
22
|
+
import { H as testProvider, o as sessionWorkersLine } from "./run-6Q9kCPem.mjs";
|
|
23
|
+
import { U as planRows, V as loadPlanStatuses, i as localIdleLine, n as markControlsHeld, s as readLocalIdle, t as clickrControlsArgv, yt as psTable } from "./controls-BcKFHeG1.mjs";
|
|
24
|
+
import { n as diskBundleMtime, r as ensurePoolHost } from "./pool-cli-B_YR8_Gl.mjs";
|
|
25
|
+
import { a as readAudit, d as loadPaneRunStatuses, f as paneRunRows } from "./pane-audit-BQytYa60.mjs";
|
|
26
|
+
import { b as useProvider, f as setClass, g as setWorkersEnabled, l as removeProvider, m as setProviderEnabled, p as setProviderCap, r as classTargetText, s as describeProviders, t as addProvider, v as unsetClass, y as updateProvider } from "./providers-CblTFrhz.mjs";
|
|
27
|
+
import { A as cockpitMemoryPayload, B as cockpitLayout, N as liveMemoryDeps, O as embeddingRuntimeName, P as memoryJobProgress, S as runtimeJobProgress, V as cockpitProbeSettings, c as defaultDeps, g as readLabels, h as readCockpitJob, k as readRuntimeCommands, t as COCKPIT_ACTION_EVENT, v as runCockpitAction, x as runningRuntimeJobs } from "./cockpit-actions-C8GlTzts.mjs";
|
|
28
|
+
import { i as fallbackStatusText, n as fallbackOn, r as fallbackStatus, t as fallbackOff } from "./fallback-DFlItw1Z.mjs";
|
|
29
|
+
import { appendFileSync, chmodSync, closeSync, copyFileSync, existsSync, fstatSync, mkdirSync, openSync, readFileSync, readSync, readdirSync, renameSync, rmSync, rmdirSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
30
|
+
import { createHash } from "node:crypto";
|
|
28
31
|
import { basename, dirname, join, resolve } from "node:path";
|
|
29
32
|
import chalk from "chalk";
|
|
30
33
|
import { homedir, loadavg } from "node:os";
|
|
31
34
|
import { execFile, execFileSync, spawn } from "node:child_process";
|
|
32
35
|
import { fileURLToPath } from "node:url";
|
|
33
36
|
import { LineCounter, isMap, isScalar, parse, parseDocument } from "yaml";
|
|
34
|
-
import { createHash } from "node:crypto";
|
|
35
37
|
import { connect, createServer } from "node:net";
|
|
36
38
|
|
|
37
39
|
//#region src/cli/commands/providers.ts
|
|
@@ -5871,7 +5873,6 @@ function cockpitHtml() {
|
|
|
5871
5873
|
* UI that shows the project separately. Unknown ids map to null.
|
|
5872
5874
|
*/
|
|
5873
5875
|
function defaultSources() {
|
|
5874
|
-
homedir();
|
|
5875
5876
|
return {
|
|
5876
5877
|
workerDirs: [paiHomePath("logs", "workers"), join(claudeHomeDir(), "logs", "workers")],
|
|
5877
5878
|
agentSessionsFile: paiHomePath("agent-sessions.json"),
|
|
@@ -5897,6 +5898,11 @@ function jobSessionName(id, jobsDir = defaultSources().jobsDir, now = Date.now()
|
|
|
5897
5898
|
if (hit && now - hit.at < JOB_TTL_MS) return hit.name;
|
|
5898
5899
|
const raw = readJson(join(jobsDir, id8, "state.json"))?.name;
|
|
5899
5900
|
const name = typeof raw === "string" && raw ? raw : null;
|
|
5901
|
+
jobCache.delete(key);
|
|
5902
|
+
for (const [k, v] of jobCache) {
|
|
5903
|
+
if (now - v.at < JOB_TTL_MS) break;
|
|
5904
|
+
jobCache.delete(k);
|
|
5905
|
+
}
|
|
5900
5906
|
jobCache.set(key, {
|
|
5901
5907
|
at: now,
|
|
5902
5908
|
name
|
|
@@ -6035,20 +6041,26 @@ function loadSessionMap(src = defaultSources()) {
|
|
|
6035
6041
|
/** The loader below as steps: a `yield` after each directory or file, so a driver can hand the event loop back between them. */
|
|
6036
6042
|
function* loadSessionMapSteps(src = defaultSources()) {
|
|
6037
6043
|
const map = /* @__PURE__ */ new Map();
|
|
6038
|
-
if (src.projectsDir && existsSync(src.projectsDir))
|
|
6039
|
-
|
|
6040
|
-
if (!name) continue;
|
|
6041
|
-
let files = [];
|
|
6044
|
+
if (src.projectsDir && existsSync(src.projectsDir)) {
|
|
6045
|
+
let projectDirs = [];
|
|
6042
6046
|
try {
|
|
6043
|
-
|
|
6044
|
-
} catch {
|
|
6045
|
-
|
|
6046
|
-
|
|
6047
|
-
|
|
6048
|
-
|
|
6049
|
-
|
|
6047
|
+
projectDirs = readdirSync(src.projectsDir);
|
|
6048
|
+
} catch {}
|
|
6049
|
+
for (const d of projectDirs) {
|
|
6050
|
+
const name = d.split("-").filter(Boolean).pop();
|
|
6051
|
+
if (!name) continue;
|
|
6052
|
+
let files = [];
|
|
6053
|
+
try {
|
|
6054
|
+
files = readdirSync(join(src.projectsDir, d));
|
|
6055
|
+
} catch {
|
|
6056
|
+
continue;
|
|
6057
|
+
}
|
|
6058
|
+
for (const f of files) {
|
|
6059
|
+
const id = f.endsWith(".jsonl") ? f.slice(0, -6) : "";
|
|
6060
|
+
if (id) map.set(id, { name });
|
|
6061
|
+
}
|
|
6062
|
+
yield;
|
|
6050
6063
|
}
|
|
6051
|
-
yield;
|
|
6052
6064
|
}
|
|
6053
6065
|
const agents = existsSync(src.agentSessionsFile) ? readJson(src.agentSessionsFile) : void 0;
|
|
6054
6066
|
if (agents) for (const [id, project] of Object.entries(agents)) {
|
|
@@ -6087,7 +6099,13 @@ function* loadSessionMapSteps(src = defaultSources()) {
|
|
|
6087
6099
|
}
|
|
6088
6100
|
for (const dir of src.workerDirs) {
|
|
6089
6101
|
if (!existsSync(dir)) continue;
|
|
6090
|
-
|
|
6102
|
+
let dirFiles = [];
|
|
6103
|
+
try {
|
|
6104
|
+
dirFiles = readdirSync(dir);
|
|
6105
|
+
} catch {
|
|
6106
|
+
continue;
|
|
6107
|
+
}
|
|
6108
|
+
for (const f of dirFiles) {
|
|
6091
6109
|
if (!f.endsWith(".status")) continue;
|
|
6092
6110
|
yield;
|
|
6093
6111
|
const s = readJson(join(dir, f));
|
|
@@ -6202,7 +6220,7 @@ function* withWorkerAttributionSteps(map, rows, windows, now = Date.now()) {
|
|
|
6202
6220
|
hits.set(w.worker, w);
|
|
6203
6221
|
}
|
|
6204
6222
|
if (!hits.size) continue;
|
|
6205
|
-
const first =
|
|
6223
|
+
const first = reqs.reduce((m, r) => Math.min(m, r.t), Infinity);
|
|
6206
6224
|
const best = [...hits.values()].sort((a, b) => b.startMs - a.startMs)[0];
|
|
6207
6225
|
if (best.startMs > first) continue;
|
|
6208
6226
|
out.set(id, {
|
|
@@ -6725,26 +6743,86 @@ function tierProviderList() {
|
|
|
6725
6743
|
}
|
|
6726
6744
|
const WHOLE_LOG_TTL_MS = 3e4;
|
|
6727
6745
|
const wholeLogMemo = /* @__PURE__ */ new WeakMap();
|
|
6746
|
+
/** Whole-log figures, folded row by row as the log is read so the rows themselves can be dropped once they are older than any window. */
|
|
6747
|
+
var LogAgg = class {
|
|
6748
|
+
/** per provider+model: requests, prompt tokens, first ts (a fold by model owner is applied on top at read time) */
|
|
6749
|
+
pairs = /* @__PURE__ */ new Map();
|
|
6750
|
+
/** tokens per UTC day per model, with the sequence number of the model's first row that day (keeps the model order of a row scan) */
|
|
6751
|
+
daily = /* @__PURE__ */ new Map();
|
|
6752
|
+
seq = 0;
|
|
6753
|
+
add(r) {
|
|
6754
|
+
const model = typeof r.model === "string" ? canonicalModel(r.model) : "";
|
|
6755
|
+
const k = `${r.provider}\u0000${model}`;
|
|
6756
|
+
const p = this.pairs.get(k) ?? {
|
|
6757
|
+
provider: r.provider,
|
|
6758
|
+
model,
|
|
6759
|
+
n: 0,
|
|
6760
|
+
prompt: 0,
|
|
6761
|
+
since: r.ts
|
|
6762
|
+
};
|
|
6763
|
+
p.n++;
|
|
6764
|
+
p.prompt += (r.input_tokens ?? 0) + (r.cache_read_input_tokens ?? 0) + (r.cache_creation_input_tokens ?? 0);
|
|
6765
|
+
if (r.ts < p.since) p.since = r.ts;
|
|
6766
|
+
this.pairs.set(k, p);
|
|
6767
|
+
const day = bucketStart(Date.parse(r.ts), DAY$1);
|
|
6768
|
+
const d = this.daily.get(day) ?? /* @__PURE__ */ new Map();
|
|
6769
|
+
const e = d.get(model) ?? {
|
|
6770
|
+
sum: 0,
|
|
6771
|
+
seq: this.seq
|
|
6772
|
+
};
|
|
6773
|
+
e.sum += (r.input_tokens ?? 0) + (r.output_tokens ?? 0) + (r.cache_creation_input_tokens ?? 0) + (r.cache_read_input_tokens ?? 0);
|
|
6774
|
+
d.set(model, e);
|
|
6775
|
+
this.daily.set(day, d);
|
|
6776
|
+
this.seq++;
|
|
6777
|
+
}
|
|
6778
|
+
/** Forget the day buckets before `cut`: no window looks back further than the 14 days the daily chart shows. */
|
|
6779
|
+
pruneDaily(cut) {
|
|
6780
|
+
for (const day of this.daily.keys()) if (day < cut) this.daily.delete(day);
|
|
6781
|
+
}
|
|
6782
|
+
/** The pairs as the fold of the providers would have rewritten their rows. */
|
|
6783
|
+
folded(providers) {
|
|
6784
|
+
const owners = modelOwners(providers);
|
|
6785
|
+
const all = [...this.pairs.values()];
|
|
6786
|
+
return owners.size ? foldProviders(all, providers, owners) : all;
|
|
6787
|
+
}
|
|
6788
|
+
};
|
|
6789
|
+
const aggs = /* @__PURE__ */ new WeakMap();
|
|
6790
|
+
/** The aggregates a cached log carries; a plain array (tests, callers that bring their own rows) is scanned. */
|
|
6791
|
+
function aggOf(rows) {
|
|
6792
|
+
const have = aggs.get(rows);
|
|
6793
|
+
if (have) return have;
|
|
6794
|
+
const a = new LogAgg();
|
|
6795
|
+
for (const r of rows) a.add(r);
|
|
6796
|
+
return a;
|
|
6797
|
+
}
|
|
6728
6798
|
/** The parts of the cockpit payload that read the whole log whatever the window is. Costly on a big log, so they are kept per log array until it grows or 30 s pass (the speed table moves with the clock). */
|
|
6729
|
-
function wholeLog(allRows, now, providers) {
|
|
6799
|
+
function wholeLog(allRows, agg, now, providers) {
|
|
6730
6800
|
const sig = JSON.stringify(Object.entries(providers).map(([k, v]) => [k, v.baseUrl]));
|
|
6731
6801
|
const m = wholeLogMemo.get(allRows);
|
|
6732
6802
|
if (m && m.n === allRows.length && m.sig === sig && Math.abs(now - m.at) < WHOLE_LOG_TTL_MS) return m.out;
|
|
6733
6803
|
const dayFrom = bucketStart(now, DAY$1) - 13 * DAY$1;
|
|
6734
6804
|
const days = [];
|
|
6735
6805
|
for (let t = dayFrom; t <= now; t += DAY$1) days.push(t);
|
|
6736
|
-
const daily =
|
|
6737
|
-
|
|
6738
|
-
|
|
6739
|
-
if (
|
|
6740
|
-
const
|
|
6741
|
-
|
|
6806
|
+
const daily = dict();
|
|
6807
|
+
const inRange = [];
|
|
6808
|
+
for (const [day, ms] of agg.daily) {
|
|
6809
|
+
if (day < dayFrom) continue;
|
|
6810
|
+
for (const [model, e] of ms) inRange.push({
|
|
6811
|
+
day,
|
|
6812
|
+
model,
|
|
6813
|
+
...e
|
|
6814
|
+
});
|
|
6815
|
+
}
|
|
6816
|
+
inRange.sort((a, b) => a.seq - b.seq);
|
|
6817
|
+
for (const e of inRange) {
|
|
6818
|
+
const arr = daily[e.model] ??= days.map(() => 0);
|
|
6819
|
+
arr[Math.floor((e.day - dayFrom) / DAY$1)] += e.sum;
|
|
6742
6820
|
}
|
|
6743
|
-
const promptByProvider =
|
|
6744
|
-
const promptSince =
|
|
6745
|
-
for (const
|
|
6746
|
-
if (!promptSince[
|
|
6747
|
-
promptByProvider[
|
|
6821
|
+
const promptByProvider = dict();
|
|
6822
|
+
const promptSince = dict();
|
|
6823
|
+
for (const p of agg.folded(providers)) {
|
|
6824
|
+
if (!promptSince[p.provider] || p.since < promptSince[p.provider]) promptSince[p.provider] = p.since;
|
|
6825
|
+
promptByProvider[p.provider] = (promptByProvider[p.provider] ?? 0) + p.prompt;
|
|
6748
6826
|
}
|
|
6749
6827
|
const out = {
|
|
6750
6828
|
days,
|
|
@@ -6794,23 +6872,23 @@ function windowRows(allRows, from) {
|
|
|
6794
6872
|
function buildCockpitData(allRows, win, now = Date.now(), sessions = /* @__PURE__ */ new Map(), pool = null, providers = {}) {
|
|
6795
6873
|
const { span, bucket } = WINDOWS[win];
|
|
6796
6874
|
const from = bucketStart(now - span, bucket);
|
|
6875
|
+
const agg = aggOf(allRows);
|
|
6797
6876
|
allRows = foldedRows(allRows, providers);
|
|
6798
6877
|
const rows = windowRows(allRows, from);
|
|
6799
6878
|
const retries = retryRows(rows);
|
|
6800
6879
|
const ecoCount = /* @__PURE__ */ new Map();
|
|
6801
|
-
for (const r of
|
|
6802
|
-
const
|
|
6803
|
-
const c = ecoCount.get(m) ?? /* @__PURE__ */ new Map();
|
|
6880
|
+
for (const r of agg.folded(providers)) {
|
|
6881
|
+
const c = ecoCount.get(r.model) ?? /* @__PURE__ */ new Map();
|
|
6804
6882
|
const e = providerEcosystem(r.provider, providers);
|
|
6805
|
-
c.set(e, (c.get(e) ?? 0) +
|
|
6806
|
-
ecoCount.set(
|
|
6883
|
+
c.set(e, (c.get(e) ?? 0) + r.n);
|
|
6884
|
+
ecoCount.set(r.model, c);
|
|
6807
6885
|
}
|
|
6808
|
-
const ecosystems =
|
|
6886
|
+
const ecosystems = dict();
|
|
6809
6887
|
for (const [m, c] of ecoCount) ecosystems[m] = [...c.entries()].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))[0][0];
|
|
6810
6888
|
const series = [];
|
|
6811
6889
|
for (let t = from; t <= now; t += bucket) series.push({
|
|
6812
6890
|
t,
|
|
6813
|
-
models:
|
|
6891
|
+
models: dict()
|
|
6814
6892
|
});
|
|
6815
6893
|
const total = tok();
|
|
6816
6894
|
let errors = 0;
|
|
@@ -6821,7 +6899,7 @@ function buildCockpitData(allRows, win, now = Date.now(), sessions = /* @__PURE_
|
|
|
6821
6899
|
const byInstance = /* @__PURE__ */ new Map();
|
|
6822
6900
|
const bySession = /* @__PURE__ */ new Map();
|
|
6823
6901
|
const pause = /* @__PURE__ */ new Map();
|
|
6824
|
-
const bustParts =
|
|
6902
|
+
const bustParts = dict();
|
|
6825
6903
|
for (const r of rows) {
|
|
6826
6904
|
const model = canonicalModel(r.model);
|
|
6827
6905
|
const t = Date.parse(r.ts);
|
|
@@ -6938,7 +7016,7 @@ function buildCockpitData(allRows, win, now = Date.now(), sessions = /* @__PURE_
|
|
|
6938
7016
|
workerEnd: info?.endMs ?? null
|
|
6939
7017
|
};
|
|
6940
7018
|
}).sort((a, b) => b.input + b.output + b.cacheWrite + b.cacheRead - (a.input + a.output + a.cacheWrite + a.cacheRead));
|
|
6941
|
-
const { daily, days, promptByProvider, promptSince, speed } = wholeLog(allRows, now, providers);
|
|
7019
|
+
const { daily, days, promptByProvider, promptSince, speed } = wholeLog(allRows, agg, now, providers);
|
|
6942
7020
|
const withRatio = (x) => ({
|
|
6943
7021
|
...x,
|
|
6944
7022
|
hitRatio: hitRatio(x)
|
|
@@ -6995,45 +7073,93 @@ function buildCockpitData(allRows, win, now = Date.now(), sessions = /* @__PURE_
|
|
|
6995
7073
|
pool: pool && pool.tasks > 0 ? pool : null
|
|
6996
7074
|
};
|
|
6997
7075
|
}
|
|
7076
|
+
const USAGE_HEAD_BYTES = 4096;
|
|
7077
|
+
/** A map keyed by logged names (model, provider): no prototype, so a key such as "__proto__" is an ordinary entry. */
|
|
7078
|
+
const dict = () => Object.create(null);
|
|
6998
7079
|
/**
|
|
6999
7080
|
* The usage log as rows, kept in memory: a log that only grew is read from where the last read
|
|
7000
7081
|
* stopped (the router appends a row per request, so a full reread of tens of MB on every append
|
|
7001
7082
|
* would block the event loop); one that shrank or was replaced is read again from the start.
|
|
7083
|
+
* The whole-log figures (prompt tokens and first ts per provider, requests per provider+model,
|
|
7084
|
+
* tokens per day) are folded into running aggregates as rows are read; the rows themselves are
|
|
7085
|
+
* kept for ROWS_KEPT_MS only (the 7 d window reaches back 8 d at most, one day of slack on top)
|
|
7086
|
+
* and dropped once a day, so memory follows the window, not the log.
|
|
7002
7087
|
*/
|
|
7003
|
-
|
|
7088
|
+
const ROWS_KEPT_MS = 9 * DAY$1;
|
|
7089
|
+
const DAILY_KEPT_MS = 15 * DAY$1;
|
|
7090
|
+
function cachedRows(file = usageLogFile(), clock = Date.now) {
|
|
7004
7091
|
let rows = [];
|
|
7092
|
+
let agg = new LogAgg();
|
|
7093
|
+
let lastTrim = 0;
|
|
7094
|
+
let ordered = true;
|
|
7005
7095
|
let offset = 0;
|
|
7006
7096
|
let mtimeMs = 0;
|
|
7097
|
+
let ino = -1;
|
|
7098
|
+
let head = "";
|
|
7099
|
+
let lastMs = 0;
|
|
7100
|
+
const fresh = (kept) => {
|
|
7101
|
+
rows = kept;
|
|
7102
|
+
if (ordered) markTimeOrdered(rows);
|
|
7103
|
+
aggs.set(rows, agg);
|
|
7104
|
+
};
|
|
7105
|
+
const reset = () => {
|
|
7106
|
+
ordered = true;
|
|
7107
|
+
agg = new LogAgg();
|
|
7108
|
+
lastTrim = clock();
|
|
7109
|
+
fresh([]);
|
|
7110
|
+
offset = 0;
|
|
7111
|
+
ino = -1;
|
|
7112
|
+
head = "";
|
|
7113
|
+
lastMs = 0;
|
|
7114
|
+
mtimeMs = 0;
|
|
7115
|
+
};
|
|
7116
|
+
reset();
|
|
7007
7117
|
return () => {
|
|
7008
7118
|
try {
|
|
7009
|
-
const st = statSync(file);
|
|
7010
|
-
if (st.size === offset && st.mtimeMs === mtimeMs) return rows;
|
|
7011
|
-
if (st.size < offset) {
|
|
7012
|
-
rows = [];
|
|
7013
|
-
offset = 0;
|
|
7014
|
-
}
|
|
7015
7119
|
const fd = openSync(file, "r");
|
|
7016
7120
|
try {
|
|
7121
|
+
const st = fstatSync(fd);
|
|
7122
|
+
const headLen = Math.min(USAGE_HEAD_BYTES, st.size);
|
|
7123
|
+
const headBuf = Buffer.alloc(headLen);
|
|
7124
|
+
readSync(fd, headBuf, 0, headLen, 0);
|
|
7125
|
+
const nowHead = headBuf.toString("latin1");
|
|
7126
|
+
if (offset > 0 && (st.ino !== ino || st.size < offset || !nowHead.startsWith(head))) reset();
|
|
7127
|
+
if (st.size === offset && st.mtimeMs === mtimeMs) return rows;
|
|
7017
7128
|
const buf = Buffer.alloc(st.size - offset);
|
|
7018
7129
|
const n = readSync(fd, buf, 0, buf.length, offset);
|
|
7019
|
-
|
|
7020
|
-
const
|
|
7021
|
-
|
|
7022
|
-
|
|
7130
|
+
let chunk = buf.subarray(0, n);
|
|
7131
|
+
const nl = chunk.lastIndexOf(10);
|
|
7132
|
+
chunk = nl < 0 ? chunk.subarray(0, 0) : chunk.subarray(0, nl + 1);
|
|
7133
|
+
const from = rows.length;
|
|
7134
|
+
for (const l of chunk.toString("utf8").split("\n")) {
|
|
7023
7135
|
if (!l) continue;
|
|
7024
7136
|
try {
|
|
7025
|
-
|
|
7137
|
+
const r = JSON.parse(l);
|
|
7138
|
+
agg.add(r);
|
|
7139
|
+
rows.push(r);
|
|
7026
7140
|
} catch {}
|
|
7027
7141
|
}
|
|
7028
|
-
|
|
7029
|
-
|
|
7142
|
+
for (let i = from; i < rows.length; i++) {
|
|
7143
|
+
const t = Date.parse(rows[i].ts);
|
|
7144
|
+
if (t < lastMs) ordered = false;
|
|
7145
|
+
else if (t >= 0) lastMs = t;
|
|
7146
|
+
}
|
|
7147
|
+
if (!ordered) fresh([...rows]);
|
|
7148
|
+
const at = clock();
|
|
7149
|
+
if (at - lastTrim >= DAY$1) {
|
|
7150
|
+
lastTrim = at;
|
|
7151
|
+
agg.pruneDaily(bucketStart(at, DAY$1) - DAILY_KEPT_MS);
|
|
7152
|
+
fresh(rows.filter((r) => !(Date.parse(r.ts) < at - ROWS_KEPT_MS)));
|
|
7153
|
+
}
|
|
7154
|
+
offset += chunk.length;
|
|
7155
|
+
ino = st.ino;
|
|
7156
|
+
if (head.length < USAGE_HEAD_BYTES) head = nowHead.slice(0, Math.min(offset, USAGE_HEAD_BYTES));
|
|
7157
|
+
mtimeMs = st.mtimeMs;
|
|
7030
7158
|
} finally {
|
|
7031
7159
|
closeSync(fd);
|
|
7032
7160
|
}
|
|
7033
|
-
mtimeMs = st.mtimeMs;
|
|
7034
7161
|
} catch {
|
|
7035
|
-
|
|
7036
|
-
offset = 0;
|
|
7162
|
+
reset();
|
|
7037
7163
|
}
|
|
7038
7164
|
return rows;
|
|
7039
7165
|
};
|
|
@@ -7533,15 +7659,18 @@ function cachedPoolCarry() {
|
|
|
7533
7659
|
/** The whole request body as text. */
|
|
7534
7660
|
function readBody(req) {
|
|
7535
7661
|
return new Promise((resolve, reject) => {
|
|
7536
|
-
|
|
7662
|
+
const chunks = [];
|
|
7663
|
+
let size = 0;
|
|
7537
7664
|
req.on("data", (c) => {
|
|
7538
|
-
|
|
7539
|
-
|
|
7665
|
+
const b = typeof c === "string" ? Buffer.from(c) : c;
|
|
7666
|
+
chunks.push(b);
|
|
7667
|
+
size += b.length;
|
|
7668
|
+
if (size > 64e3) {
|
|
7540
7669
|
reject(/* @__PURE__ */ new Error("body too large"));
|
|
7541
7670
|
req.destroy();
|
|
7542
7671
|
}
|
|
7543
7672
|
});
|
|
7544
|
-
req.on("end", () => resolve(
|
|
7673
|
+
req.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
|
|
7545
7674
|
req.on("error", reject);
|
|
7546
7675
|
});
|
|
7547
7676
|
}
|
|
@@ -7724,7 +7853,7 @@ function cockpitBuildId() {
|
|
|
7724
7853
|
* unless router.bind opens a second listener (then every cockpit route,
|
|
7725
7854
|
* writes included, is token-gated — see src/router/cockpit-auth.ts).
|
|
7726
7855
|
*/
|
|
7727
|
-
function handleCockpit(req, res, limits, readRows =
|
|
7856
|
+
function handleCockpit(req, res, limits, readRows = cachedRows(), sessionMap = loadSessionMap, system, workerWindows = loadWorkerWindows, readPool = cachedPoolCarry(), readPoolPanel = sharedPoolPanel, queueLogDir = workersLogDir) {
|
|
7728
7857
|
const url = new URL(req.url ?? "/", "http://localhost");
|
|
7729
7858
|
if (url.pathname !== "/cockpit" && !url.pathname.startsWith("/cockpit/")) return false;
|
|
7730
7859
|
const send = (status, type, body) => {
|
|
@@ -8599,6 +8728,12 @@ function writeResults(suite, rows) {
|
|
|
8599
8728
|
writeFileSync(file, `# A/B results\n\nGenerated by \`pai worker bench\`; void rows excluded from pass/total.\n\n${aggregate(rows)}\n`);
|
|
8600
8729
|
return file;
|
|
8601
8730
|
}
|
|
8731
|
+
/** A throttle setting must be a positive number: NaN would disable the gate, 0 would wait forever. */
|
|
8732
|
+
function positiveNumber(flag, v) {
|
|
8733
|
+
const n = typeof v === "number" ? v : typeof v === "string" && v.trim() !== "" ? Number(v) : NaN;
|
|
8734
|
+
if (!Number.isFinite(n) || n <= 0) throw new Error(`${flag} must be a positive number, got "${String(v)}"`);
|
|
8735
|
+
return n;
|
|
8736
|
+
}
|
|
8602
8737
|
|
|
8603
8738
|
//#endregion
|
|
8604
8739
|
//#region src/cli/lib/settings-manager.ts
|
|
@@ -9040,7 +9175,7 @@ function collectEnv(pairs) {
|
|
|
9040
9175
|
return o;
|
|
9041
9176
|
}
|
|
9042
9177
|
function parseCostTier(v) {
|
|
9043
|
-
const n =
|
|
9178
|
+
const n = /^\s*\d+\s*$/.test(v) ? Number(v) : NaN;
|
|
9044
9179
|
if (!Number.isInteger(n) || n < 1 || n > 5) throw new WorkersConfigError(`cost tier must be an integer 1 (cheapest) … 5 (most expensive), got "${v}"`);
|
|
9045
9180
|
return n;
|
|
9046
9181
|
}
|
|
@@ -9138,7 +9273,7 @@ const providersAddCommand = {
|
|
|
9138
9273
|
name: "key",
|
|
9139
9274
|
type: "string",
|
|
9140
9275
|
value: "TOKEN",
|
|
9141
|
-
summary: "API token, written into workers.yaml;
|
|
9276
|
+
summary: "API token, written into workers.yaml; visible in ps and shell history, prefer --key-file"
|
|
9142
9277
|
},
|
|
9143
9278
|
{
|
|
9144
9279
|
name: "key-file",
|
|
@@ -9218,6 +9353,7 @@ const providersAddCommand = {
|
|
|
9218
9353
|
const baseUrl = o["base-url"] ?? o.url;
|
|
9219
9354
|
if (protocol !== "openai" && !baseUrl) throw new WorkersConfigError("--base-url (or --url) is required (only --protocol openai goes without it)");
|
|
9220
9355
|
if (o.key && o["key-file"]) throw new WorkersConfigError("--key and --key-file are alternatives — pass one, not both");
|
|
9356
|
+
if (o.key) out(warn("--key puts the token in the process list and shell history; prefer --key-file"));
|
|
9221
9357
|
const costTier = o["cost-tier"] !== void 0 ? parseCostTier(String(o["cost-tier"])) : void 0;
|
|
9222
9358
|
const tags = collectTags(ctx.multi?.tags);
|
|
9223
9359
|
addProvider({
|
|
@@ -9859,6 +9995,16 @@ function launchDetached(plan) {
|
|
|
9859
9995
|
closeSync(fd);
|
|
9860
9996
|
return Object.assign(() => child.exitCode, child.pid !== void 0 ? { pid: child.pid } : {});
|
|
9861
9997
|
}
|
|
9998
|
+
/** SIGTERM a launched server's process group (it is a group leader), else the pid. */
|
|
9999
|
+
function killGroup(pid) {
|
|
10000
|
+
try {
|
|
10001
|
+
process.kill(-pid, "SIGTERM");
|
|
10002
|
+
} catch {
|
|
10003
|
+
try {
|
|
10004
|
+
process.kill(pid, "SIGTERM");
|
|
10005
|
+
} catch {}
|
|
10006
|
+
}
|
|
10007
|
+
}
|
|
9862
10008
|
/** Live servers of catalogue models, one per (model, port). */
|
|
9863
10009
|
function liveServers(cfg) {
|
|
9864
10010
|
return instancesFromProcesses(psTable("pid=,rss=,command="), cfg, scriptListeners(cfg));
|
|
@@ -9875,6 +10021,36 @@ function currentInstances(cfg, deps = {}) {
|
|
|
9875
10021
|
* instances keep running; a short memory or a full model (maxInstances) refuses.
|
|
9876
10022
|
*/
|
|
9877
10023
|
async function startInstance(cfg, model, deps = {}) {
|
|
10024
|
+
return withStartLock(deps.startDir ?? logDir(), model, (release) => startInstanceLocked(cfg, model, deps, release));
|
|
10025
|
+
}
|
|
10026
|
+
/** One start per model at a time: the lock covers read-check-allocate-write and is released once the row is written. */
|
|
10027
|
+
async function withStartLock(dir, model, fn) {
|
|
10028
|
+
mkdirSync(dir, { recursive: true });
|
|
10029
|
+
const m = join(dir, `start-${model.replace(/[^\w.-]/g, "_")}.lock`);
|
|
10030
|
+
const t0 = Date.now();
|
|
10031
|
+
for (;;) try {
|
|
10032
|
+
mkdirSync(m);
|
|
10033
|
+
break;
|
|
10034
|
+
} catch {
|
|
10035
|
+
breakStaleMutex(m, 6e4);
|
|
10036
|
+
if (Date.now() - t0 > 12e4) throw new LocalTierError(`${model}: another start is in progress`);
|
|
10037
|
+
await sleep(10 + Math.random() * 20);
|
|
10038
|
+
}
|
|
10039
|
+
let released = false;
|
|
10040
|
+
const release = () => {
|
|
10041
|
+
if (released) return;
|
|
10042
|
+
released = true;
|
|
10043
|
+
try {
|
|
10044
|
+
rmdirSync(m);
|
|
10045
|
+
} catch {}
|
|
10046
|
+
};
|
|
10047
|
+
try {
|
|
10048
|
+
return await fn(release);
|
|
10049
|
+
} finally {
|
|
10050
|
+
release();
|
|
10051
|
+
}
|
|
10052
|
+
}
|
|
10053
|
+
async function startInstanceLocked(cfg, model, deps, release) {
|
|
9878
10054
|
const tier = cfg.tiers[model];
|
|
9879
10055
|
if (!tier) throw new LocalTierError(`no model "${model}" (configured: ${Object.keys(cfg.tiers).join(", ") || "none"})`);
|
|
9880
10056
|
const dir = deps.startDir ?? logDir();
|
|
@@ -9925,10 +10101,12 @@ async function startInstance(cfg, model, deps = {}) {
|
|
|
9925
10101
|
});
|
|
9926
10102
|
writeInstances(dir, [...rows.filter((r) => r.id !== id), instance]);
|
|
9927
10103
|
const exited = (deps.launch ?? launchDetached)(plan);
|
|
10104
|
+
release();
|
|
9928
10105
|
out(dim(`starting ${tier.label} #${n} (${tier.provider}) on :${port}, log ${plan.logPath}`));
|
|
9929
10106
|
const up = deps.up ?? ((p) => healthOk(tier, p));
|
|
9930
10107
|
const deadline = Date.now() + plan.readyMs;
|
|
9931
10108
|
const failWith = (error, msg) => {
|
|
10109
|
+
if (exited.pid !== void 0 && exited() === null) killGroup(exited.pid);
|
|
9932
10110
|
failLocalStart(dir, error, id);
|
|
9933
10111
|
writeInstances(dir, readInstances(dir).map((r) => r.id === id ? {
|
|
9934
10112
|
...r,
|
|
@@ -10086,6 +10264,25 @@ async function stopInstance(cfg, target, opts = {}, deps = {}) {
|
|
|
10086
10264
|
}
|
|
10087
10265
|
return picked;
|
|
10088
10266
|
}
|
|
10267
|
+
/**
|
|
10268
|
+
* Requests in flight per instance id, from the snapshot the router mirrors to its log dir (the scheduler lives in
|
|
10269
|
+
* the router process, not here). A missing or unreadable snapshot cannot be checked: the lookup throws so
|
|
10270
|
+
* the stop is refused unless confirmed.
|
|
10271
|
+
*/
|
|
10272
|
+
async function cliInflight(cfg, deps = {}) {
|
|
10273
|
+
const [{ engineInflight }, { readSchedFile }, { instanceEngineKey }] = await Promise.all([
|
|
10274
|
+
import("./cockpit-actions-BWunx3rY.mjs"),
|
|
10275
|
+
import("./scheduler-dmHXoRvm.mjs"),
|
|
10276
|
+
import("./local-instances-ZeRkkuS5.mjs")
|
|
10277
|
+
]);
|
|
10278
|
+
const now = deps.now ?? Date.now();
|
|
10279
|
+
const snap = readSchedFile(deps.startDir ?? logDir(), now);
|
|
10280
|
+
const keys = new Map(currentInstances(cfg, deps).map((r) => [r.id, instanceEngineKey(r)]));
|
|
10281
|
+
return (id) => {
|
|
10282
|
+
if (!snap) throw new LocalTierError(`${id}: in-flight requests could not be checked (no router snapshot); confirm to stop anyway (--yes)`);
|
|
10283
|
+
return engineInflight(snap, keys.get(id) ?? id);
|
|
10284
|
+
};
|
|
10285
|
+
}
|
|
10089
10286
|
/** Stop every local server PAI knows (the instances, then anything left on a catalogue port), then wait until the ports are free. */
|
|
10090
10287
|
async function stopAll(cfg) {
|
|
10091
10288
|
for (const m of new Set(currentInstances(cfg).map((r) => r.model))) await stopInstance(cfg, m, { all: true }, { confirm: true });
|
|
@@ -10194,7 +10391,10 @@ const workerLocalCommand = {
|
|
|
10194
10391
|
out(ok(`stopped ${(await stopInstance(cfg, name, {
|
|
10195
10392
|
count,
|
|
10196
10393
|
all: !!ctx.opts.all
|
|
10197
|
-
}, {
|
|
10394
|
+
}, {
|
|
10395
|
+
confirm: !!ctx.opts.yes,
|
|
10396
|
+
inflight: await cliInflight(cfg)
|
|
10397
|
+
})).map((d) => d.id).join(", ")}`));
|
|
10198
10398
|
return;
|
|
10199
10399
|
}
|
|
10200
10400
|
const tier = cfg.tiers[name];
|
|
@@ -10293,6 +10493,8 @@ const workerBenchCommand = {
|
|
|
10293
10493
|
const tasks = o.tasks ? String(o.tasks).split(",") : all;
|
|
10294
10494
|
const unknown = tasks.filter((t) => !all.includes(t));
|
|
10295
10495
|
if (unknown.length) throw new Error(`unknown task(s): ${unknown.join(", ")}`);
|
|
10496
|
+
const maxParallel = positiveNumber("--max-parallel", o["max-parallel"]);
|
|
10497
|
+
const maxLoad = positiveNumber("--max-load", o["max-load"]);
|
|
10296
10498
|
const arms = planArms(tasks, String(o.providers).split(","), prompt, Math.max(1, Number(o.repeat) || 1));
|
|
10297
10499
|
out(`${arms.length} arm(s), prompt ${prompt}, max ${o["max-parallel"]} parallel, load gate ${o["max-load"]}`);
|
|
10298
10500
|
if (ctx.dryRun) {
|
|
@@ -10302,8 +10504,8 @@ const workerBenchCommand = {
|
|
|
10302
10504
|
const rows = await runBench({
|
|
10303
10505
|
suite,
|
|
10304
10506
|
arms,
|
|
10305
|
-
maxParallel
|
|
10306
|
-
maxLoad
|
|
10507
|
+
maxParallel,
|
|
10508
|
+
maxLoad,
|
|
10307
10509
|
log: (s) => out(s)
|
|
10308
10510
|
});
|
|
10309
10511
|
out(aggregate(rows));
|
|
@@ -10489,7 +10691,7 @@ const workerPoolCommand = {
|
|
|
10489
10691
|
async run(ctx) {
|
|
10490
10692
|
try {
|
|
10491
10693
|
const action = ctx.args.ACTION;
|
|
10492
|
-
const { poolOn, poolOff, poolStatusText } = await import("./pool-cli-
|
|
10694
|
+
const { poolOn, poolOff, poolStatusText } = await import("./pool-cli-DkZTAlSW.mjs");
|
|
10493
10695
|
if (action === void 0 || action === "status") return void out(await poolStatusText(logDir()));
|
|
10494
10696
|
if (action === "on") return void (await poolOn(logDir())).forEach((l) => out(l));
|
|
10495
10697
|
if (action === "off") return void (await poolOff(logDir())).forEach((l) => out(l));
|
|
@@ -10665,5 +10867,5 @@ const WORKER_CONFIG_COMMANDS = [
|
|
|
10665
10867
|
];
|
|
10666
10868
|
|
|
10667
10869
|
//#endregion
|
|
10668
|
-
export {
|
|
10669
|
-
//# sourceMappingURL=worker-config-
|
|
10870
|
+
export { exportDefaultLayout as $, workerMcpCommand as A, mergeSettings as B, workerBenchCommand as C, workerFallbackCommand as D, workerControlsCommand as E, workerProvidersCommand as F, cachedRows as G, canBind as H, workerProxyCommand as I, handleCockpit as J, cachedSessionMap as K, workerRolesCommand as L, workerOnCommand as M, workerPolicyCommand as N, workerInstallCommand as O, workerPoolCommand as P, warmCockpit as Q, workerRouteCommand as R, stopInstance as S, workerConfigCommand as T, sizeOnDiskGb as U, allocatePort as V, SystemMonitor as W, setEndpointHealth as X, setActionHooks as Y, setRuntimeSampler as Z, portOpen as _, collectEnv as a, defaultRegistryCtx as at, startTier as b, currentInstances as c, providersCommand as ct, isUp as d, createEndpointHealth as et, killInstance as f, portListeners as g, parseCostTier as h, cliInflight as i, withWorkerAttribution as it, workerOffCommand as j, workerLocalCommand as k, fail as l, listServers as m, WORKER_CONFIG_COMMANDS as n, loadWorkerWindows as nt, collectTags as o, hashText as ot, launchDetached as p, cachedWorkerWindows as q, buildClassTarget as r, sessionDisplayName as rt, controlsArgv as s, saveRegistry as st, PROVIDER_EDIT_COMMANDS as t, loadSessionMap as tt, healthOk as u, serverLine as v, workerClassesCommand as w, stopAll as x, startInstance as y, installWorkers as z };
|
|
10871
|
+
//# sourceMappingURL=worker-config-BDYNxbYz.mjs.map
|