@tekmidian/pai 0.66.48 → 0.66.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auto-route-CMARQbQ4.mjs +8 -0
- package/dist/{auto-route-DrncbMaz.mjs → auto-route-Dpm6nZ6X.mjs} +2 -2
- package/dist/{auto-route-DrncbMaz.mjs.map → auto-route-Dpm6nZ6X.mjs.map} +1 -1
- package/dist/{chain-Bba4Y8A8.mjs → chain-xSc3-u0X.mjs} +5 -5
- package/dist/{chain-Bba4Y8A8.mjs.map → chain-xSc3-u0X.mjs.map} +1 -1
- package/dist/cli/index.mjs +14 -14
- package/dist/cli/program.mjs +14 -14
- package/dist/{config-2pR0RqHM.mjs → config-CYjjGSWq.mjs} +41 -4
- package/dist/config-CYjjGSWq.mjs.map +1 -0
- package/dist/config-IuOG1W92.mjs +4 -0
- package/dist/daemon/index.mjs +10 -10
- package/dist/{daemon-C25MKGD8.mjs → daemon-BIG7XcqE.mjs} +10 -10
- package/dist/{daemon-C6K3kikA.mjs → daemon-CiSmbylJ.mjs} +7 -7
- package/dist/{daemon-C6K3kikA.mjs.map → daemon-CiSmbylJ.mjs.map} +1 -1
- package/dist/daemon-mcp/index.mjs +8 -8
- package/dist/{fallback-DyhAZAOe.mjs → fallback-BgAukP8r.mjs} +6 -5
- package/dist/fallback-BgAukP8r.mjs.map +1 -0
- package/dist/hooks/block-sleep-poll.mjs.map +2 -2
- package/dist/hooks/load-project-context.mjs +26 -2
- package/dist/hooks/load-project-context.mjs.map +2 -2
- package/dist/hooks/route-agents-to-worker.mjs +26 -2
- package/dist/hooks/route-agents-to-worker.mjs.map +2 -2
- package/dist/hooks/security-validator.mjs +26 -2
- package/dist/hooks/security-validator.mjs.map +2 -2
- package/dist/hooks/worker-guard.mjs +26 -2
- package/dist/hooks/worker-guard.mjs.map +2 -2
- package/dist/hooks/worker-pool-host.mjs +242 -14
- package/dist/hooks/worker-pool-host.mjs.map +4 -4
- package/dist/hooks/worker-proxy.mjs +26 -2
- package/dist/hooks/worker-proxy.mjs.map +2 -2
- package/dist/hooks/worker-status-line.mjs +26 -2
- package/dist/hooks/worker-status-line.mjs.map +2 -2
- package/dist/hooks/worker-supervision.mjs +26 -2
- package/dist/hooks/worker-supervision.mjs.map +2 -2
- package/dist/index.mjs +4 -4
- package/dist/{local-EmOjw5jq.mjs → local-Bt-7L0oB.mjs} +3 -3
- package/dist/{local-EmOjw5jq.mjs.map → local-Bt-7L0oB.mjs.map} +1 -1
- package/dist/local-oqPQEmhb.mjs +7 -0
- package/dist/{local-tiers-BIINbhkY.mjs → local-tiers-C0QSQcP1.mjs} +2 -2
- package/dist/{local-tiers-8fmjiySw.mjs → local-tiers-_ZOTbjeP.mjs} +2 -2
- package/dist/{local-tiers-8fmjiySw.mjs.map → local-tiers-_ZOTbjeP.mjs.map} +1 -1
- package/dist/{main-resolver-DBXvnYKp.mjs → main-resolver-BwjexuSA.mjs} +3 -3
- package/dist/{main-resolver-B10-lsU0.mjs → main-resolver-CVo0ab7j.mjs} +3 -3
- package/dist/{main-resolver-B10-lsU0.mjs.map → main-resolver-CVo0ab7j.mjs.map} +1 -1
- package/dist/{pai-marker-CDwQOpQ8.mjs → pai-marker-CJ6WMt05.mjs} +4 -4
- package/dist/{pai-marker-CDwQOpQ8.mjs.map → pai-marker-CJ6WMt05.mjs.map} +1 -1
- package/dist/{planner-dO-3PLjD.mjs → planner-ZKXZf9JS.mjs} +8 -8
- package/dist/{planner-dO-3PLjD.mjs.map → planner-ZKXZf9JS.mjs.map} +1 -1
- package/dist/{pool-DLhqOY3P.mjs → pool-CgsnP3La.mjs} +3 -3
- package/dist/{pool-DLhqOY3P.mjs.map → pool-CgsnP3La.mjs.map} +1 -1
- package/dist/{pool-cli-DerrWWpP.mjs → pool-cli-kGGuZCzJ.mjs} +4 -4
- package/dist/{pool-cli-DerrWWpP.mjs.map → pool-cli-kGGuZCzJ.mjs.map} +1 -1
- package/dist/{program-B7gVKc-u.mjs → program-DgcwJN6Z.mjs} +25 -463
- package/dist/program-DgcwJN6Z.mjs.map +1 -0
- package/dist/{run-a_JzcVwv.mjs → run-CsrBbtj_.mjs} +686 -21
- package/dist/run-CsrBbtj_.mjs.map +1 -0
- package/dist/{run-env-DyFZ8C1s.mjs → run-env-Cyw2iwBh.mjs} +15 -5
- package/dist/{run-env-DyFZ8C1s.mjs.map → run-env-Cyw2iwBh.mjs.map} +1 -1
- package/dist/{status-C3fBJKU_.mjs → status-B0br9zV0.mjs} +2 -2
- package/dist/status-B0br9zV0.mjs.map +1 -0
- package/dist/{supervisor-B_2JKYxe.mjs → supervisor-BZA0KICt.mjs} +7 -7
- package/dist/{supervisor-B_2JKYxe.mjs.map → supervisor-BZA0KICt.mjs.map} +1 -1
- package/dist/workers-config-BifEz8ns.mjs +4 -0
- package/dist/{worktree-lnmAOFQv.mjs → worktree-B6d-1uIn.mjs} +2 -2
- package/dist/{worktree-lnmAOFQv.mjs.map → worktree-B6d-1uIn.mjs.map} +1 -1
- package/docs/worker.md +22 -0
- package/package.json +1 -1
- package/dist/auto-route-DYuVfXwc.mjs +0 -8
- package/dist/config-2pR0RqHM.mjs.map +0 -1
- package/dist/config-CQWpEdXb.mjs +0 -4
- package/dist/fallback-DyhAZAOe.mjs.map +0 -1
- package/dist/local-B5SekWOC.mjs +0 -7
- package/dist/program-B7gVKc-u.mjs.map +0 -1
- package/dist/run-a_JzcVwv.mjs.map +0 -1
- package/dist/status-C3fBJKU_.mjs.map +0 -1
- package/dist/workers-config-nXSiW07z.mjs +0 -4
|
@@ -2,27 +2,27 @@ import { a as fmtDate, c as ok$1, d as scaffoldProjectDirs, f as shortenPath, g
|
|
|
2
2
|
import { a as slugify$1, i as parseSessionFilename } from "./migrate-CYccXTAA.mjs";
|
|
3
3
|
import { S as UNROUTED, b as writeJsonAtomic, c as loadConfig, d as paiConfigYamlFilePath, f as readMainConfigRaw, g as resolvedMainConfigPath, h as migrateMainConfigToYaml, l as migrateConfigFile, m as MainConfigError, n as CONFIG_FILE$2, p as writeMainConfigRaw, s as expandHome, t as CONFIG_DIR, u as paiConfigFilePath, x as OWNER_LABEL_PREFIX, y as readJsonStrict } from "./config-DSdCEcHS.mjs";
|
|
4
4
|
import { a as schedulerLogPath, c as migratePaiFile, d as resolvePaiFile, i as paiSocketPath, l as paiHomeDir, n as daemonLogPath, o as PaiFileMigrationError, s as migratePaiDir, u as paiHomePath } from "./runtime-paths-DkZoxofH.mjs";
|
|
5
|
-
import {
|
|
6
|
-
import { B as parseRunnerArgs, C as formatStale, E as loadStatusConfig, G as ledgerPath, U as ensureNoMcpConfig, W as eventsPath, Y as workersLogDir, b as waitForTerminalStatus, d as isLive, f as loadStatus, g as ownsPid, j as writeSectionToForge, k as upsertSection, p as loadStatuses, t as UNLABELED, u as isChatPane, v as saveStatus, y as setWorkerLabel, z as longInlinePromptHint } from "./status-
|
|
7
|
-
import { _ as formatPending, b as appendLedger, i as gcWorktrees, l as mergeWorker, p as verifyWorker, r as discardWorker, v as pendingGate, y as pendingResults } from "./worktree-
|
|
8
|
-
import { a as unregistrableReason, n as ensurePaiMarker, o as worktreeReason } from "./pai-marker-
|
|
5
|
+
import { $ as workersYamlLegacyNotice, C as expandHome$1, E as isModelCapability, G as initWorkersYaml, J as needsWorkersYamlRelocation, K as inlineWorkersYamlKeys, R as readWorkersSection, T as hasProviderKey, Y as parseWorkersYamlDocument, Z as relocateWorkersYaml, _ as PROVIDER_TAGS, at as contextWindowFromModelId, et as workersYamlPath, ot as stripModelVariant, q as migrateWorkersToYaml, rt as DEFAULT_CONTEXT_WINDOW, t as ANTHROPIC_NATIVE, w as getProviderOrNative, y as WorkersConfigError } from "./config-CYjjGSWq.mjs";
|
|
6
|
+
import { B as parseRunnerArgs, C as formatStale, E as loadStatusConfig, G as ledgerPath, U as ensureNoMcpConfig, W as eventsPath, Y as workersLogDir, b as waitForTerminalStatus, d as isLive, f as loadStatus, g as ownsPid, j as writeSectionToForge, k as upsertSection, p as loadStatuses, t as UNLABELED, u as isChatPane, v as saveStatus, y as setWorkerLabel, z as longInlinePromptHint } from "./status-B0br9zV0.mjs";
|
|
7
|
+
import { _ as formatPending, b as appendLedger, i as gcWorktrees, l as mergeWorker, p as verifyWorker, r as discardWorker, v as pendingGate, y as pendingResults } from "./worktree-B6d-1uIn.mjs";
|
|
8
|
+
import { a as unregistrableReason, n as ensurePaiMarker, o as worktreeReason } from "./pai-marker-CJ6WMt05.mjs";
|
|
9
9
|
import { t as STOP_WORDS } from "./stop-words-Hfu8u22w.mjs";
|
|
10
10
|
import { t as applyRecencyBoost } from "./search-qLyvfhwY.mjs";
|
|
11
11
|
import { c as resolveFromModule, i as retryTransient, n as embedChunksWithBackend, r as indexProjectWithBackend, s as packageRoot } from "./postgres-P567vfbi.mjs";
|
|
12
12
|
import { a as getStorageBackend, c as MergeError, f as humanDuration, i as getRegistryBackend, l as federationDbPath, o as oldRegistryPath, r as createStorageBackend, s as registryDbPath, u as oldFederationPath } from "./factory-DRAEDNKV.mjs";
|
|
13
13
|
import { c as detectBackends, d as OLLAMA_DEFAULT_MODEL, f as OLLAMA_DEFAULT_URL, i as measureThroughput, o as BACKEND_IDS, p as OLLAMA_ID, s as createBackend, u as provisionOllama } from "./embedding-gate-BwkbwfIL.mjs";
|
|
14
|
-
import { Bt as findMovedProjects, D as migrateWorkQueue, Et as migrateIdentityFile, Ft as resolveHome, Gt as formatDetectionJson, Ht as transcriptFiles, It as saveScanConfig, Lt as upsertProject, M as migrateSummaryCooldowns, Mt as loadScanConfig, Nt as migrateScanConfig, Rt as upsertSession, Ut as detectProject, Vt as scanTranscriptFolders, Wt as formatDetection, _ as resolveDaemonPid, _t as findNotesDir$1, a as routerRunningPid, d as loadSessionKeepaliveState, dt as extractAndStoreTriples, gt as findLatestNote, h as totalUsageTokens, ht as applyContinue, jt as cmdScan, kt as reexecBackground, l as readContextHandoverCache, m as parseSessionUsage, mt as appendCheckpointToNote, n as ROUTER_PID_FILE, p as sessionKeepaliveLedgerSummary, s as spawnRouter, t as ROUTER_LOG_FILE, vt as readBodyFile, zt as claudeProjectsDir } from "./supervisor-
|
|
15
|
-
import { a as poolMetricsPath, d as readPoolMetrics, m as expandMcpNames, p as describeMcp, t as poolCarry } from "./pool-
|
|
16
|
-
import { $ as ensureProxyRunning, A as routeRun, B as detectCurrentProviderName, D as onBattery, E as findLocal, H as maskLaunchEnv, I as requestKill, J as parseSince, K as errorsTable, L as buildLaunchPlan, M as clickrControlsArgv, N as markControlsHeld, O as parseDuration, P as callerDescription, Q as DEFAULT_PROXY_PORT, R as buildLaunchRows, S as sayToWorker, T as clearPolicy, V as launchableProviderNames, Y as readToolErrors, at as
|
|
17
|
-
import { A as useProvider, B as projectChecks, C as setClass, D as unsetCapabilityPreference, E as setWorkersEnabled, F as setConfigValueOp, I as unsetConfigValueOp, L as formatCheck, M as formatConfigGetOutput, N as getConfigValueOp, O as unsetClass, P as listConfigOp, R as initProject, S as setCapabilityPreference, T as setProviderModel, _ as describeModels, a as followWorkers, b as removeProvider, c as statusLineOutput, d as issueClaim, f as issueClaims, g as describeCapabilities, h as classTargetText, i as fallbackStatusText, j as MainConfigOpsError, k as updateProvider, l as readSpecPrompt, m as addProvider, n as fallbackOn, o as psOutput, p as issueStale, r as fallbackStatus, s as replayOutput, t as fallbackOff, u as resolveSpecPath, v as describeProviders, w as setProviderEnabled, x as resolveProviderName, y as modelPrefsText, z as isGitProject } from "./fallback-
|
|
14
|
+
import { Bt as findMovedProjects, D as migrateWorkQueue, Et as migrateIdentityFile, Ft as resolveHome, Gt as formatDetectionJson, Ht as transcriptFiles, It as saveScanConfig, Lt as upsertProject, M as migrateSummaryCooldowns, Mt as loadScanConfig, Nt as migrateScanConfig, Rt as upsertSession, Ut as detectProject, Vt as scanTranscriptFolders, Wt as formatDetection, _ as resolveDaemonPid, _t as findNotesDir$1, a as routerRunningPid, d as loadSessionKeepaliveState, dt as extractAndStoreTriples, gt as findLatestNote, h as totalUsageTokens, ht as applyContinue, jt as cmdScan, kt as reexecBackground, l as readContextHandoverCache, m as parseSessionUsage, mt as appendCheckpointToNote, n as ROUTER_PID_FILE, p as sessionKeepaliveLedgerSummary, s as spawnRouter, t as ROUTER_LOG_FILE, vt as readBodyFile, zt as claudeProjectsDir } from "./supervisor-BZA0KICt.mjs";
|
|
15
|
+
import { a as poolMetricsPath, d as readPoolMetrics, m as expandMcpNames, p as describeMcp, t as poolCarry } from "./pool-CgsnP3La.mjs";
|
|
16
|
+
import { $ as ensureProxyRunning, A as routeRun, B as detectCurrentProviderName, D as onBattery, E as findLocal, H as maskLaunchEnv, I as requestKill, J as parseSince, K as errorsTable, L as buildLaunchPlan, M as clickrControlsArgv, N as markControlsHeld, O as parseDuration, P as callerDescription, Q as DEFAULT_PROXY_PORT, R as buildLaunchRows, S as sayToWorker, T as clearPolicy, V as launchableProviderNames, Y as readToolErrors, at as LimitsCache, b as handoffFromInside, ct as assertPaneNotDisabled, d as realDeps, et as stopProxy, f as statusMarker, gt as resolveHostSession, i as usageContextTokens, j as writePolicy, k as readPolicy, l as parseWorkerReport, lt as checkPaneForWorker, mt as openPaneForWorker, n as runWorker, ot as pinNotices, p as waitOn, pt as openFollowPane, q as groupToolErrors, r as testProvider, st as projectLaunchConfig, ut as closeEndedPanes, w as POLICY_MODES, z as detectCurrentModel } from "./run-CsrBbtj_.mjs";
|
|
17
|
+
import { A as useProvider, B as projectChecks, C as setClass, D as unsetCapabilityPreference, E as setWorkersEnabled, F as setConfigValueOp, I as unsetConfigValueOp, L as formatCheck, M as formatConfigGetOutput, N as getConfigValueOp, O as unsetClass, P as listConfigOp, R as initProject, S as setCapabilityPreference, T as setProviderModel, _ as describeModels, a as followWorkers, b as removeProvider, c as statusLineOutput, d as issueClaim, f as issueClaims, g as describeCapabilities, h as classTargetText, i as fallbackStatusText, j as MainConfigOpsError, k as updateProvider, l as readSpecPrompt, m as addProvider, n as fallbackOn, o as psOutput, p as issueStale, r as fallbackStatus, s as replayOutput, t as fallbackOff, u as resolveSpecPath, v as describeProviders, w as setProviderEnabled, x as resolveProviderName, y as modelPrefsText, z as isGitProject } from "./fallback-BgAukP8r.mjs";
|
|
18
18
|
import { n as PaiClient } from "./ipc-client-vK3fmbwc.mjs";
|
|
19
|
-
import { _ as resolveSessionByNameOrId, a as buildDeduped, c as hasConversation, d as providerResumePlan, f as restoreTopLevel, g as migrateSessionScanCache, h as fmtAge, l as launchInDir, m as printExitDir, o as normalizeName$2, p as resumeArgvText, s as renderDedupedSessions, t as cmdMain, u as launchPrompt, v as scanCacheFilePath, y as scanSessions } from "./main-resolver-
|
|
19
|
+
import { _ as resolveSessionByNameOrId, a as buildDeduped, c as hasConversation, d as providerResumePlan, f as restoreTopLevel, g as migrateSessionScanCache, h as fmtAge, l as launchInDir, m as printExitDir, o as normalizeName$2, p as resumeArgvText, s as renderDedupedSessions, t as cmdMain, u as launchPrompt, v as scanCacheFilePath, y as scanSessions } from "./main-resolver-CVo0ab7j.mjs";
|
|
20
20
|
import { n as queriesDirPath, t as migrateQueriesDir } from "./query-feedback-C_sRUNju.mjs";
|
|
21
|
-
import { a as routerHandler, c as aggregateBySession, d as formatStats, f as parseSince$1, i as ROUTER_PORT, l as appendUsage, m as splitBySessionKind, o as USAGE_LOG_FILE, p as readUsage, s as aggregate$1, u as formatSessionStats } from "./run-env-
|
|
21
|
+
import { a as routerHandler, c as aggregateBySession, d as formatStats, f as parseSince$1, i as ROUTER_PORT, l as appendUsage, m as splitBySessionKind, o as USAGE_LOG_FILE, p as readUsage, s as aggregate$1, u as formatSessionStats } from "./run-env-Cyw2iwBh.mjs";
|
|
22
22
|
import { a as revealItermSession, n as callAiBroker, o as sendToSession, r as fetchLiveSessions } from "./aibroker-client-Dome-XV2.mjs";
|
|
23
|
-
import { t as runChain } from "./chain-
|
|
24
|
-
import { a as fmtRss, f as resolveModelPath } from "./local-tiers-
|
|
25
|
-
import { r as registerWorkerLocalCommand } from "./local-
|
|
23
|
+
import { t as runChain } from "./chain-xSc3-u0X.mjs";
|
|
24
|
+
import { a as fmtRss, f as resolveModelPath } from "./local-tiers-_ZOTbjeP.mjs";
|
|
25
|
+
import { r as registerWorkerLocalCommand } from "./local-Bt-7L0oB.mjs";
|
|
26
26
|
import { appendFileSync, chmodSync, closeSync, copyFileSync, cpSync, createReadStream, existsSync, lstatSync, mkdirSync, openSync, readFileSync, readSync, readdirSync, readlinkSync, realpathSync, renameSync, statSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
|
|
27
27
|
import { homedir, loadavg, networkInterfaces, platform, tmpdir, userInfo } from "node:os";
|
|
28
28
|
import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
@@ -33,10 +33,8 @@ import { createHash, randomUUID } from "node:crypto";
|
|
|
33
33
|
import { Command, InvalidArgumentError } from "commander";
|
|
34
34
|
import { fileURLToPath } from "node:url";
|
|
35
35
|
import pg from "pg";
|
|
36
|
-
import net from "node:net";
|
|
37
36
|
import BetterSqlite3 from "better-sqlite3";
|
|
38
37
|
import http from "node:http";
|
|
39
|
-
import https from "node:https";
|
|
40
38
|
import { createInterface } from "node:readline";
|
|
41
39
|
import { createConnection } from "net";
|
|
42
40
|
import { getEncoding } from "js-tiktoken";
|
|
@@ -2022,7 +2020,7 @@ async function cmdUnregister(slug, opts = {}) {
|
|
|
2022
2020
|
//#region src/cli/commands/project/projects-index.ts
|
|
2023
2021
|
function registerProjectsCommands(projectsCmd) {
|
|
2024
2022
|
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) => {
|
|
2025
|
-
const { cmdMain } = await import("./main-resolver-
|
|
2023
|
+
const { cmdMain } = await import("./main-resolver-BwjexuSA.mjs");
|
|
2026
2024
|
await cmdMain(void 0, void 0, opts);
|
|
2027
2025
|
});
|
|
2028
2026
|
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(async (opts) => {
|
|
@@ -7232,7 +7230,7 @@ function cmdLogs(opts) {
|
|
|
7232
7230
|
}
|
|
7233
7231
|
function registerDaemonCommands(daemonCmd) {
|
|
7234
7232
|
daemonCmd.command("serve").description("Start the PAI daemon in the foreground").action(async () => {
|
|
7235
|
-
const { serve } = await import("./daemon-
|
|
7233
|
+
const { serve } = await import("./daemon-BIG7XcqE.mjs");
|
|
7236
7234
|
const { loadConfig: lc, ensureConfigDir } = await import("./config-DhgOr-uB.mjs");
|
|
7237
7235
|
ensureConfigDir();
|
|
7238
7236
|
await serve(lc());
|
|
@@ -17406,7 +17404,7 @@ async function cmdActive(opts) {
|
|
|
17406
17404
|
], rows));
|
|
17407
17405
|
}
|
|
17408
17406
|
async function cmdAutoRoute(opts) {
|
|
17409
|
-
const { autoRoute, formatAutoRouteJson } = await import("./auto-route-
|
|
17407
|
+
const { autoRoute, formatAutoRouteJson } = await import("./auto-route-CMARQbQ4.mjs");
|
|
17410
17408
|
const { getRegistryBackend, createStorageBackend } = await import("./factory-qDkL0z7K.mjs");
|
|
17411
17409
|
const { loadConfig } = await import("./config-DhgOr-uB.mjs");
|
|
17412
17410
|
const config = loadConfig();
|
|
@@ -19450,7 +19448,7 @@ function readThermal() {
|
|
|
19450
19448
|
return "?";
|
|
19451
19449
|
}
|
|
19452
19450
|
}
|
|
19453
|
-
function sh$
|
|
19451
|
+
function sh$1(script, args, cwd, env) {
|
|
19454
19452
|
return new Promise((resolve) => {
|
|
19455
19453
|
const p = spawn("sh", [script, ...args], {
|
|
19456
19454
|
cwd,
|
|
@@ -19491,11 +19489,11 @@ async function runBench(o) {
|
|
|
19491
19489
|
...process.env,
|
|
19492
19490
|
PROMPT: arm.prompt
|
|
19493
19491
|
};
|
|
19494
|
-
const started = await sh$
|
|
19492
|
+
const started = await sh$1(join(o.suite, "run.sh"), [arm.task, arm.provider], o.suite, env);
|
|
19495
19493
|
const id = /^arm (\S+) ended/m.exec(started)?.[1];
|
|
19496
19494
|
if (!id) return o.log(`${arm.task}/${arm.provider}: no arm id in run.sh output`);
|
|
19497
19495
|
appendFileSync(envFile, `${id}\t${load}\t${thermal}\n`);
|
|
19498
|
-
const row = parseRow((await sh$
|
|
19496
|
+
const row = parseRow((await sh$1(join(o.suite, "grade.sh"), [arm.task, id], o.suite, process.env)).trim().split("\n").pop() ?? "");
|
|
19499
19497
|
if (row) rows.push(row);
|
|
19500
19498
|
o.log(`${id}: ${row?.verdict ?? "ungraded"} (load ${load}, thermal ${thermal})`);
|
|
19501
19499
|
} finally {
|
|
@@ -20254,7 +20252,7 @@ function registerWorkerCommands(workerCmd) {
|
|
|
20254
20252
|
});
|
|
20255
20253
|
workerCmd.command("pool [action]").description("Worker session pool: long-lived headless claude slots that successive small\nruns talk to instead of each spawning a fresh claude, so the provider\nprompt cache carries over (src/workers/pool.ts).\non starts the detached host and enables routing, off stops both, status\nshows slots, tasks served and the cache-carry total. Default off.").action(async (action) => {
|
|
20256
20254
|
try {
|
|
20257
|
-
const { poolOn, poolOff, poolStatusText } = await import("./pool-cli-
|
|
20255
|
+
const { poolOn, poolOff, poolStatusText } = await import("./pool-cli-kGGuZCzJ.mjs");
|
|
20258
20256
|
if (action === void 0 || action === "status") {
|
|
20259
20257
|
console.log(await poolStatusText(currentLogDir()));
|
|
20260
20258
|
return;
|
|
@@ -20942,442 +20940,6 @@ function handleCockpit(req, res, limits, readRows = readUsage, sessionMap = load
|
|
|
20942
20940
|
return true;
|
|
20943
20941
|
}
|
|
20944
20942
|
|
|
20945
|
-
//#endregion
|
|
20946
|
-
//#region src/router/limits.ts
|
|
20947
|
-
/**
|
|
20948
|
-
* limits.ts — per-provider plan limits for the cockpit. Polled at most once a
|
|
20949
|
-
* minute and cached; keys and tokens stay in this process and never reach the
|
|
20950
|
-
* page or the JSON it is served.
|
|
20951
|
-
*
|
|
20952
|
-
* anthropic Max plan 5h/7d via the OAuth usage endpoint (token from the
|
|
20953
|
-
* keychain, as the statusline does); on a failed poll (http 429)
|
|
20954
|
-
* the last good reading is served with its age and the poll backs
|
|
20955
|
-
* off, advisor-mode.json only when no last good reading exists
|
|
20956
|
-
* others the provider's workers.yaml `usage` block (jq expressions)
|
|
20957
|
-
* local up/down (TCP), RSS of the listener, tokens/s from accounting
|
|
20958
|
-
* rest counted requests vs a configured limit, labelled "estimated"
|
|
20959
|
-
*/
|
|
20960
|
-
const ESTIMATE_FILE = join(homedir(), ".claude", "pai", "router-limits.json");
|
|
20961
|
-
const ADVISOR_FILE = join(homedir(), ".claude", "pai", "advisor-mode.json");
|
|
20962
|
-
/** Last good plan reading per provider, so a rate-limited poll shows an age, not "reset unknown". */
|
|
20963
|
-
const LASTGOOD_FILE = join(homedir(), ".claude", "pai", "logs", "router-limits-last.json");
|
|
20964
|
-
/** A last good reading older than this is too stale to serve when the endpoint fails. */
|
|
20965
|
-
const PLAN_LASTGOOD_MAX_AGE = 2 * 36e5;
|
|
20966
|
-
/** Upper bound for the poll delay after repeated 429s. */
|
|
20967
|
-
const BACKOFF_MAX = 30 * 6e4;
|
|
20968
|
-
function readLastGood(file = LASTGOOD_FILE) {
|
|
20969
|
-
try {
|
|
20970
|
-
const j = JSON.parse(readFileSync(file, "utf8"));
|
|
20971
|
-
const out = {};
|
|
20972
|
-
for (const [k, v] of Object.entries(j)) if (v && Array.isArray(v.windows) && typeof v.fetchedAt === "number") out[k] = {
|
|
20973
|
-
windows: v.windows,
|
|
20974
|
-
fetchedAt: v.fetchedAt
|
|
20975
|
-
};
|
|
20976
|
-
return out;
|
|
20977
|
-
} catch {
|
|
20978
|
-
return {};
|
|
20979
|
-
}
|
|
20980
|
-
}
|
|
20981
|
-
function writeLastGood(file, entries) {
|
|
20982
|
-
try {
|
|
20983
|
-
mkdirSync(dirname(file), { recursive: true });
|
|
20984
|
-
writeFileSync(file, JSON.stringify(entries, null, 1));
|
|
20985
|
-
} catch {}
|
|
20986
|
-
}
|
|
20987
|
-
/**
|
|
20988
|
-
* The reading to show when a poll failed: the last good one, with its age in
|
|
20989
|
-
* the error field, while it is fresh enough to trust; undefined otherwise.
|
|
20990
|
-
*/
|
|
20991
|
-
function staleReading(provider, entry, cause, now, maxAge = PLAN_LASTGOOD_MAX_AGE) {
|
|
20992
|
-
if (!entry || !entry.windows.length || now - entry.fetchedAt >= maxAge) return void 0;
|
|
20993
|
-
const min = Math.round((now - entry.fetchedAt) / 6e4);
|
|
20994
|
-
return {
|
|
20995
|
-
provider,
|
|
20996
|
-
kind: "plan",
|
|
20997
|
-
windows: entry.windows,
|
|
20998
|
-
fetchedAt: entry.fetchedAt,
|
|
20999
|
-
error: `stale ${min}min (${cause})`
|
|
21000
|
-
};
|
|
21001
|
-
}
|
|
21002
|
-
/** Per-provider poll backoff after a http 429: the interval doubles per strike, resets on success. */
|
|
21003
|
-
var Backoff = class {
|
|
21004
|
-
mult = /* @__PURE__ */ new Map();
|
|
21005
|
-
until = /* @__PURE__ */ new Map();
|
|
21006
|
-
constructor(baseMs, maxMs = BACKOFF_MAX) {
|
|
21007
|
-
this.baseMs = baseMs;
|
|
21008
|
-
this.maxMs = maxMs;
|
|
21009
|
-
}
|
|
21010
|
-
/** Record a 429 seen for `provider` at `now`; returns the delay before its next poll. */
|
|
21011
|
-
penalize(provider, now) {
|
|
21012
|
-
const m = Math.min((this.mult.get(provider) ?? 1) * 2, this.maxMs / this.baseMs);
|
|
21013
|
-
this.mult.set(provider, m);
|
|
21014
|
-
this.until.set(provider, now + m * this.baseMs);
|
|
21015
|
-
return m * this.baseMs;
|
|
21016
|
-
}
|
|
21017
|
-
/** ms until `provider` is due again; 0 when it may be polled now. */
|
|
21018
|
-
remaining(provider, now) {
|
|
21019
|
-
return Math.max(0, (this.until.get(provider) ?? 0) - now);
|
|
21020
|
-
}
|
|
21021
|
-
/** A poll succeeded: forget the strikes. */
|
|
21022
|
-
reset(provider) {
|
|
21023
|
-
this.mult.delete(provider);
|
|
21024
|
-
this.until.delete(provider);
|
|
21025
|
-
}
|
|
21026
|
-
};
|
|
21027
|
-
function toMs(v, unit) {
|
|
21028
|
-
if (v === null || v === void 0 || v === "") return void 0;
|
|
21029
|
-
if (unit === "iso" || unit === void 0 && typeof v === "string" && !/^\d+(\.\d+)?$/.test(v)) {
|
|
21030
|
-
const t = Date.parse(String(v));
|
|
21031
|
-
return Number.isFinite(t) ? t : void 0;
|
|
21032
|
-
}
|
|
21033
|
-
const n = Number(v);
|
|
21034
|
-
if (!Number.isFinite(n)) return void 0;
|
|
21035
|
-
return unit === "s" ? n * 1e3 : n;
|
|
21036
|
-
}
|
|
21037
|
-
function jq(expr, input) {
|
|
21038
|
-
const r = spawnSync("jq", ["-r", expr], {
|
|
21039
|
-
input,
|
|
21040
|
-
encoding: "utf8",
|
|
21041
|
-
timeout: 3e3
|
|
21042
|
-
});
|
|
21043
|
-
if (r.status !== 0) return void 0;
|
|
21044
|
-
const out = r.stdout.trim().split("\n")[0];
|
|
21045
|
-
return out === void 0 || out === "" || out === "null" ? void 0 : out;
|
|
21046
|
-
}
|
|
21047
|
-
/** Windows of a provider usage response, using its configured jq expressions. */
|
|
21048
|
-
function windowsFromJson(body, cfg) {
|
|
21049
|
-
const out = [];
|
|
21050
|
-
for (const w of cfg.windows) {
|
|
21051
|
-
const pct = Number(jq(w.percent, body));
|
|
21052
|
-
if (!Number.isFinite(pct) || jq(w.percent, body) === void 0) continue;
|
|
21053
|
-
const reset = w.resetAt ? toMs(jq(w.resetAt, body), w.resetUnit) : void 0;
|
|
21054
|
-
out.push({
|
|
21055
|
-
name: w.name,
|
|
21056
|
-
percent: Math.round(pct * 10) / 10,
|
|
21057
|
-
...reset ? { resetAt: reset } : {}
|
|
21058
|
-
});
|
|
21059
|
-
}
|
|
21060
|
-
return out;
|
|
21061
|
-
}
|
|
21062
|
-
/** Anthropic OAuth usage response: five_hour / seven_day {utilization, resets_at ISO}. */
|
|
21063
|
-
function parseAnthropicUsage(body) {
|
|
21064
|
-
let j;
|
|
21065
|
-
try {
|
|
21066
|
-
j = JSON.parse(body);
|
|
21067
|
-
} catch {
|
|
21068
|
-
return [];
|
|
21069
|
-
}
|
|
21070
|
-
const out = [];
|
|
21071
|
-
for (const [key, name] of [["five_hour", "5h"], ["seven_day", "7d"]]) {
|
|
21072
|
-
const w = j[key];
|
|
21073
|
-
if (!w || typeof w.utilization !== "number") continue;
|
|
21074
|
-
const reset = toMs(w.resets_at, "iso");
|
|
21075
|
-
out.push({
|
|
21076
|
-
name,
|
|
21077
|
-
percent: w.utilization,
|
|
21078
|
-
...reset ? { resetAt: reset } : {}
|
|
21079
|
-
});
|
|
21080
|
-
}
|
|
21081
|
-
return out;
|
|
21082
|
-
}
|
|
21083
|
-
/** Counted requests inside each window vs a configured cap: labelled estimated. */
|
|
21084
|
-
function estimateWindows(rows, provider, caps, now) {
|
|
21085
|
-
const spans = {
|
|
21086
|
-
"5h": 5 * 36e5,
|
|
21087
|
-
"7d": 7 * 864e5
|
|
21088
|
-
};
|
|
21089
|
-
const out = [];
|
|
21090
|
-
for (const [name, span] of Object.entries(spans)) {
|
|
21091
|
-
const cap = caps[name];
|
|
21092
|
-
if (!cap) continue;
|
|
21093
|
-
const inWin = rows.filter((r) => r.provider === provider && Date.parse(r.ts) >= now - span);
|
|
21094
|
-
const first = inWin.reduce((m, r) => Math.min(m, Date.parse(r.ts)), Infinity);
|
|
21095
|
-
out.push({
|
|
21096
|
-
name,
|
|
21097
|
-
percent: Math.round(inWin.length / cap * 1e3) / 10,
|
|
21098
|
-
...Number.isFinite(first) ? { resetAt: first + span } : {},
|
|
21099
|
-
estimated: true
|
|
21100
|
-
});
|
|
21101
|
-
}
|
|
21102
|
-
return out;
|
|
21103
|
-
}
|
|
21104
|
-
function readEstimateCaps(file = ESTIMATE_FILE) {
|
|
21105
|
-
try {
|
|
21106
|
-
return existsSync(file) ? JSON.parse(readFileSync(file, "utf8")) : {};
|
|
21107
|
-
} catch {
|
|
21108
|
-
return {};
|
|
21109
|
-
}
|
|
21110
|
-
}
|
|
21111
|
-
function getJson(url, headers) {
|
|
21112
|
-
return new Promise((resolve, reject) => {
|
|
21113
|
-
const rq = (url.protocol === "https:" ? https : http).get(url, {
|
|
21114
|
-
headers,
|
|
21115
|
-
timeout: 5e3
|
|
21116
|
-
}, (res) => {
|
|
21117
|
-
let t = "";
|
|
21118
|
-
res.on("data", (c) => t += c);
|
|
21119
|
-
res.on("end", () => res.statusCode === 200 ? resolve(t) : reject(/* @__PURE__ */ new Error(`http ${res.statusCode}`)));
|
|
21120
|
-
});
|
|
21121
|
-
rq.on("timeout", () => rq.destroy(/* @__PURE__ */ new Error("timeout")));
|
|
21122
|
-
rq.on("error", reject);
|
|
21123
|
-
});
|
|
21124
|
-
}
|
|
21125
|
-
function sh$1(cmd, args) {
|
|
21126
|
-
return new Promise((resolve) => execFile(cmd, args, { timeout: 4e3 }, (_e, out) => resolve(String(out ?? "").trim())));
|
|
21127
|
-
}
|
|
21128
|
-
async function anthropicToken() {
|
|
21129
|
-
for (const args of [["-a", process.env.USER ?? ""], []]) {
|
|
21130
|
-
const raw = await sh$1("security", [
|
|
21131
|
-
"find-generic-password",
|
|
21132
|
-
"-s",
|
|
21133
|
-
"Claude Code-credentials",
|
|
21134
|
-
...args,
|
|
21135
|
-
"-w"
|
|
21136
|
-
]);
|
|
21137
|
-
try {
|
|
21138
|
-
const t = JSON.parse(raw).claudeAiOauth?.accessToken;
|
|
21139
|
-
if (t) return t;
|
|
21140
|
-
} catch {}
|
|
21141
|
-
}
|
|
21142
|
-
}
|
|
21143
|
-
async function anthropicLimits(now, advisorFile, lastGood) {
|
|
21144
|
-
const base = {
|
|
21145
|
-
provider: "anthropic",
|
|
21146
|
-
kind: "plan",
|
|
21147
|
-
fetchedAt: now
|
|
21148
|
-
};
|
|
21149
|
-
try {
|
|
21150
|
-
const token = await anthropicToken();
|
|
21151
|
-
if (!token) throw new Error("no OAuth token in keychain");
|
|
21152
|
-
const windows = parseAnthropicUsage(await getJson(new URL("https://api.anthropic.com/api/oauth/usage"), {
|
|
21153
|
-
authorization: `Bearer ${token}`,
|
|
21154
|
-
"anthropic-beta": "oauth-2025-04-20"
|
|
21155
|
-
}));
|
|
21156
|
-
if (windows.length) return {
|
|
21157
|
-
...base,
|
|
21158
|
-
windows
|
|
21159
|
-
};
|
|
21160
|
-
throw new Error("no usage windows in response");
|
|
21161
|
-
} catch (e) {
|
|
21162
|
-
const stale = staleReading("anthropic", lastGood, e.message, now);
|
|
21163
|
-
if (stale) return stale;
|
|
21164
|
-
try {
|
|
21165
|
-
const a = JSON.parse(readFileSync(advisorFile, "utf8"));
|
|
21166
|
-
if (typeof a.weeklyBudgetPercent === "number" && a.asOf && now / 1e3 - a.asOf < 6 * 3600) return {
|
|
21167
|
-
...base,
|
|
21168
|
-
windows: [{
|
|
21169
|
-
name: "7d",
|
|
21170
|
-
percent: a.weeklyBudgetPercent
|
|
21171
|
-
}],
|
|
21172
|
-
error: `${e.message}; advisor-mode fallback`
|
|
21173
|
-
};
|
|
21174
|
-
} catch {}
|
|
21175
|
-
return {
|
|
21176
|
-
...base,
|
|
21177
|
-
windows: [],
|
|
21178
|
-
error: e.message
|
|
21179
|
-
};
|
|
21180
|
-
}
|
|
21181
|
-
}
|
|
21182
|
-
async function providerPlanLimits(name, p, now, lastGood) {
|
|
21183
|
-
const base = {
|
|
21184
|
-
provider: name,
|
|
21185
|
-
kind: "plan",
|
|
21186
|
-
fetchedAt: now
|
|
21187
|
-
};
|
|
21188
|
-
const u = p.usage;
|
|
21189
|
-
try {
|
|
21190
|
-
const key = resolveProviderKey(p);
|
|
21191
|
-
const [hn, ...pre] = (u.authHeader ?? "Authorization: Bearer").split(/:\s*/);
|
|
21192
|
-
const prefix = pre.join(": ");
|
|
21193
|
-
const headers = { [hn.toLowerCase()]: prefix ? `${prefix} ${key}` : String(key) };
|
|
21194
|
-
const windows = windowsFromJson(await getJson(new URL(u.url), headers), u);
|
|
21195
|
-
return windows.length ? {
|
|
21196
|
-
...base,
|
|
21197
|
-
windows
|
|
21198
|
-
} : {
|
|
21199
|
-
...base,
|
|
21200
|
-
windows,
|
|
21201
|
-
error: "no windows parsed"
|
|
21202
|
-
};
|
|
21203
|
-
} catch (e) {
|
|
21204
|
-
const msg = e.message.replace(/Bearer\s+\S+/g, "Bearer ***");
|
|
21205
|
-
return staleReading(name, lastGood, msg, now) ?? {
|
|
21206
|
-
...base,
|
|
21207
|
-
windows: [],
|
|
21208
|
-
error: msg
|
|
21209
|
-
};
|
|
21210
|
-
}
|
|
21211
|
-
}
|
|
21212
|
-
function probeTcp(port, host) {
|
|
21213
|
-
return new Promise((resolve) => {
|
|
21214
|
-
const s = net.connect({
|
|
21215
|
-
port,
|
|
21216
|
-
host,
|
|
21217
|
-
timeout: 800
|
|
21218
|
-
});
|
|
21219
|
-
s.on("connect", () => (s.destroy(), resolve(true)));
|
|
21220
|
-
s.on("timeout", () => (s.destroy(), resolve(false)));
|
|
21221
|
-
s.on("error", () => resolve(false));
|
|
21222
|
-
});
|
|
21223
|
-
}
|
|
21224
|
-
async function localLimits(name, p, rows, now) {
|
|
21225
|
-
const u = new URL(p.baseUrl);
|
|
21226
|
-
const port = Number(u.port) || 80;
|
|
21227
|
-
const listening = await probeTcp(port, u.hostname);
|
|
21228
|
-
const served = listening ? await servedModels(u) : void 0;
|
|
21229
|
-
const up = listening && modelServed(served, Object.values(p.models).filter((m) => typeof m === "string"));
|
|
21230
|
-
let rssMb;
|
|
21231
|
-
if (up) {
|
|
21232
|
-
const pid = (await sh$1("lsof", [
|
|
21233
|
-
"-ti",
|
|
21234
|
-
`tcp:${port}`,
|
|
21235
|
-
"-sTCP:LISTEN"
|
|
21236
|
-
])).split("\n")[0];
|
|
21237
|
-
const rss = pid ? Number(await sh$1("ps", [
|
|
21238
|
-
"-o",
|
|
21239
|
-
"rss=",
|
|
21240
|
-
"-p",
|
|
21241
|
-
pid
|
|
21242
|
-
])) : NaN;
|
|
21243
|
-
if (Number.isFinite(rss) && rss > 0) rssMb = Math.round(rss / 1024);
|
|
21244
|
-
}
|
|
21245
|
-
return {
|
|
21246
|
-
provider: name,
|
|
21247
|
-
kind: "local",
|
|
21248
|
-
windows: [],
|
|
21249
|
-
up,
|
|
21250
|
-
...rssMb ? { rssMb } : {},
|
|
21251
|
-
...served ? { served } : {},
|
|
21252
|
-
...tokensPerSec(rows, name, now),
|
|
21253
|
-
fetchedAt: now
|
|
21254
|
-
};
|
|
21255
|
-
}
|
|
21256
|
-
/** Model ids the server at this base URL lists on GET /v1/models; undefined when it cannot say. */
|
|
21257
|
-
async function servedModels(base) {
|
|
21258
|
-
try {
|
|
21259
|
-
const ids = (JSON.parse(await getJson(new URL("/v1/models", base), {})).data ?? []).map((m) => m.id).filter((i) => typeof i === "string");
|
|
21260
|
-
return ids.length ? ids : void 0;
|
|
21261
|
-
} catch {
|
|
21262
|
-
return;
|
|
21263
|
-
}
|
|
21264
|
-
}
|
|
21265
|
-
/** Several providers can share one port: the provider is up only if its model is the one served. Unknown list = port decides. */
|
|
21266
|
-
function modelServed(served, wanted) {
|
|
21267
|
-
if (!served) return true;
|
|
21268
|
-
return wanted.some((w) => served.includes(w));
|
|
21269
|
-
}
|
|
21270
|
-
/** output tokens / generation seconds over the last hour (slow-path requests only). */
|
|
21271
|
-
function tokensPerSec(rows, provider, now) {
|
|
21272
|
-
let out = 0;
|
|
21273
|
-
let ms = 0;
|
|
21274
|
-
for (const r of rows) {
|
|
21275
|
-
if (r.provider !== provider || Date.parse(r.ts) < now - 36e5 || r.status !== 200 || !r.output_tokens) continue;
|
|
21276
|
-
out += r.output_tokens;
|
|
21277
|
-
ms += r.ms;
|
|
21278
|
-
}
|
|
21279
|
-
return ms ? { tokensPerSec: Math.round(out / (ms / 1e3) * 10) / 10 } : {};
|
|
21280
|
-
}
|
|
21281
|
-
function isLocalUrl$1(u) {
|
|
21282
|
-
try {
|
|
21283
|
-
const h = new URL(u).hostname;
|
|
21284
|
-
return h === "127.0.0.1" || h === "localhost";
|
|
21285
|
-
} catch {
|
|
21286
|
-
return false;
|
|
21287
|
-
}
|
|
21288
|
-
}
|
|
21289
|
-
/**
|
|
21290
|
-
* Polls all providers at most once per `ttlMs`; concurrent callers share one
|
|
21291
|
-
* poll. A provider whose poll answered http 429 is not fetched again until its
|
|
21292
|
-
* backoff (the interval doubled per strike, capped) has run out — its last
|
|
21293
|
-
* good reading is served with the current age instead.
|
|
21294
|
-
*/
|
|
21295
|
-
var LimitsCache = class {
|
|
21296
|
-
value = [];
|
|
21297
|
-
at = 0;
|
|
21298
|
-
inflight;
|
|
21299
|
-
backoff;
|
|
21300
|
-
constructor(deps, ttlMs = 6e4) {
|
|
21301
|
-
this.deps = deps;
|
|
21302
|
-
this.ttlMs = ttlMs;
|
|
21303
|
-
this.backoff = new Backoff(ttlMs);
|
|
21304
|
-
}
|
|
21305
|
-
get(now = Date.now()) {
|
|
21306
|
-
if (this.value.length && now - this.at < this.ttlMs) return Promise.resolve(this.value);
|
|
21307
|
-
this.inflight ??= this.poll(now).then((v) => {
|
|
21308
|
-
this.value = v;
|
|
21309
|
-
this.at = now;
|
|
21310
|
-
this.inflight = void 0;
|
|
21311
|
-
return v;
|
|
21312
|
-
});
|
|
21313
|
-
return this.inflight;
|
|
21314
|
-
}
|
|
21315
|
-
async poll(now) {
|
|
21316
|
-
const rows = this.deps.rows();
|
|
21317
|
-
let providers = {};
|
|
21318
|
-
try {
|
|
21319
|
-
providers = this.deps.providers();
|
|
21320
|
-
} catch {}
|
|
21321
|
-
const caps = readEstimateCaps(this.deps.estimateFile);
|
|
21322
|
-
const lastGoodFile = this.deps.lastGoodFile ?? LASTGOOD_FILE;
|
|
21323
|
-
const lastGood = readLastGood(lastGoodFile);
|
|
21324
|
-
const previous = new Map(this.value.map((v) => [v.provider, v]));
|
|
21325
|
-
const jobs = [];
|
|
21326
|
-
const skipped = [];
|
|
21327
|
-
/** Queue a plan poll unless the provider is backing off from a 429. */
|
|
21328
|
-
const plan = (name, fn) => {
|
|
21329
|
-
if (this.backoff.remaining(name, now) > 0) {
|
|
21330
|
-
skipped.push(name);
|
|
21331
|
-
return;
|
|
21332
|
-
}
|
|
21333
|
-
jobs.push(fn(lastGood[name]));
|
|
21334
|
-
};
|
|
21335
|
-
plan("anthropic", (lg) => anthropicLimits(now, this.deps.advisorFile ?? ADVISOR_FILE, lg));
|
|
21336
|
-
for (const [name, p] of Object.entries(providers)) {
|
|
21337
|
-
if (p.native || name === "anthropic" || p.enabled === false || !p.baseUrl) continue;
|
|
21338
|
-
if (isLocalUrl$1(p.baseUrl)) jobs.push(localLimits(name, p, rows, now));
|
|
21339
|
-
else if (p.usage) plan(name, (lg) => providerPlanLimits(name, p, now, lg));
|
|
21340
|
-
else if (caps[name]) jobs.push(Promise.resolve({
|
|
21341
|
-
provider: name,
|
|
21342
|
-
kind: "estimated",
|
|
21343
|
-
windows: estimateWindows(rows, name, caps[name], now),
|
|
21344
|
-
fetchedAt: now
|
|
21345
|
-
}));
|
|
21346
|
-
}
|
|
21347
|
-
const results = await Promise.all(jobs);
|
|
21348
|
-
const store = { ...lastGood };
|
|
21349
|
-
let dirty = false;
|
|
21350
|
-
for (const r of results) if (r.error) {
|
|
21351
|
-
if (r.error.includes("http 429")) this.backoff.penalize(r.provider, now);
|
|
21352
|
-
} else {
|
|
21353
|
-
this.backoff.reset(r.provider);
|
|
21354
|
-
if (r.windows.length) {
|
|
21355
|
-
store[r.provider] = {
|
|
21356
|
-
windows: r.windows,
|
|
21357
|
-
fetchedAt: r.fetchedAt
|
|
21358
|
-
};
|
|
21359
|
-
dirty = true;
|
|
21360
|
-
}
|
|
21361
|
-
}
|
|
21362
|
-
if (dirty) writeLastGood(lastGoodFile, store);
|
|
21363
|
-
for (const name of skipped) {
|
|
21364
|
-
const prev = previous.get(name);
|
|
21365
|
-
const cause = prev?.error?.includes("http 429") ? "http 429" : prev?.error ?? "http 429";
|
|
21366
|
-
results.push(prev ? {
|
|
21367
|
-
...prev,
|
|
21368
|
-
error: `stale ${Math.max(0, Math.round((now - prev.fetchedAt) / 6e4))}min (${cause})`
|
|
21369
|
-
} : {
|
|
21370
|
-
provider: name,
|
|
21371
|
-
kind: "plan",
|
|
21372
|
-
windows: [],
|
|
21373
|
-
error: cause,
|
|
21374
|
-
fetchedAt: now
|
|
21375
|
-
});
|
|
21376
|
-
}
|
|
21377
|
-
return results;
|
|
21378
|
-
}
|
|
21379
|
-
};
|
|
21380
|
-
|
|
21381
20943
|
//#endregion
|
|
21382
20944
|
//#region src/router/system.ts
|
|
21383
20945
|
/**
|
|
@@ -23944,13 +23506,13 @@ function recentMarkdown(root, limit) {
|
|
|
23944
23506
|
async function pickModel(name, dryRun) {
|
|
23945
23507
|
let workers;
|
|
23946
23508
|
try {
|
|
23947
|
-
workers = (await import("./config-
|
|
23509
|
+
workers = (await import("./config-IuOG1W92.mjs")).readWorkersSection().workers;
|
|
23948
23510
|
} catch {
|
|
23949
23511
|
return;
|
|
23950
23512
|
}
|
|
23951
|
-
const { readLocalConfig, planStart, findModelPath } = await import("./local-tiers-
|
|
23952
|
-
const { workersYamlPath } = await import("./workers-config-
|
|
23953
|
-
const { listServers, startTier, isUp } = await import("./local-
|
|
23513
|
+
const { readLocalConfig, planStart, findModelPath } = await import("./local-tiers-C0QSQcP1.mjs");
|
|
23514
|
+
const { workersYamlPath } = await import("./workers-config-BifEz8ns.mjs");
|
|
23515
|
+
const { listServers, startTier, isUp } = await import("./local-oqPQEmhb.mjs");
|
|
23954
23516
|
let local = null;
|
|
23955
23517
|
let running = [];
|
|
23956
23518
|
try {
|
|
@@ -24323,4 +23885,4 @@ claude() {
|
|
|
24323
23885
|
|
|
24324
23886
|
//#endregion
|
|
24325
23887
|
export { drainStdio as n, buildProgram as t };
|
|
24326
|
-
//# sourceMappingURL=program-
|
|
23888
|
+
//# sourceMappingURL=program-DgcwJN6Z.mjs.map
|