@tekmidian/pai 0.66.47 → 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
|
@@ -7900,6 +7900,17 @@ var init_workers_config = __esm({
|
|
|
7900
7900
|
import { existsSync as existsSync6, readFileSync as readFileSync5 } from "node:fs";
|
|
7901
7901
|
import { homedir as homedir4 } from "node:os";
|
|
7902
7902
|
import { join as join5 } from "node:path";
|
|
7903
|
+
function nativeAnthropicProvider(models = NATIVE_ANTHROPIC_MODELS) {
|
|
7904
|
+
return {
|
|
7905
|
+
enabled: true,
|
|
7906
|
+
protocol: "anthropic",
|
|
7907
|
+
baseUrl: "",
|
|
7908
|
+
keyFile: null,
|
|
7909
|
+
models: { ...models },
|
|
7910
|
+
env: {},
|
|
7911
|
+
native: true
|
|
7912
|
+
};
|
|
7913
|
+
}
|
|
7903
7914
|
function isModelCapability(v) {
|
|
7904
7915
|
return CAPABILITY_NAME_RE.test(v);
|
|
7905
7916
|
}
|
|
@@ -8245,10 +8256,31 @@ function parseWorkersConfig(raw) {
|
|
|
8245
8256
|
if (r.retryOnQuota !== void 0 && typeof r.retryOnQuota !== "boolean") {
|
|
8246
8257
|
bad(".routing.retryOnQuota", "must be boolean");
|
|
8247
8258
|
}
|
|
8259
|
+
if (r.policy !== void 0 && r.policy !== "budget" && r.policy !== "order") {
|
|
8260
|
+
bad(".routing.policy", 'must be "budget" or "order"');
|
|
8261
|
+
}
|
|
8262
|
+
if (r.priority !== void 0) {
|
|
8263
|
+
if (!Array.isArray(r.priority) || r.priority.some((x) => typeof x !== "string")) {
|
|
8264
|
+
bad(".routing.priority", "must be an array of provider names");
|
|
8265
|
+
}
|
|
8266
|
+
}
|
|
8267
|
+
if (r.budgetWalls !== void 0) {
|
|
8268
|
+
if (typeof r.budgetWalls !== "object" || r.budgetWalls === null || Array.isArray(r.budgetWalls)) {
|
|
8269
|
+
bad(".routing.budgetWalls", "must be an object of provider name \u2192 percent");
|
|
8270
|
+
}
|
|
8271
|
+
for (const [k, v] of Object.entries(r.budgetWalls)) {
|
|
8272
|
+
if (typeof v !== "number" || !Number.isFinite(v) || v < 0 || v > 100) {
|
|
8273
|
+
bad(`.routing.budgetWalls.${k}`, "must be a percent 0\u2013100");
|
|
8274
|
+
}
|
|
8275
|
+
}
|
|
8276
|
+
}
|
|
8248
8277
|
routing = {
|
|
8249
8278
|
order: routing.order,
|
|
8250
8279
|
cooldownMinutes: r.cooldownMinutes === void 0 ? DEFAULT_ROUTING2.cooldownMinutes : r.cooldownMinutes,
|
|
8251
|
-
retryOnQuota: r.retryOnQuota === void 0 ? DEFAULT_ROUTING2.retryOnQuota : r.retryOnQuota === true
|
|
8280
|
+
retryOnQuota: r.retryOnQuota === void 0 ? DEFAULT_ROUTING2.retryOnQuota : r.retryOnQuota === true,
|
|
8281
|
+
policy: r.policy ?? DEFAULT_ROUTING2.policy,
|
|
8282
|
+
priority: r.priority === void 0 ? [] : [...r.priority],
|
|
8283
|
+
budgetWalls: r.budgetWalls === void 0 ? {} : { ...r.budgetWalls }
|
|
8252
8284
|
};
|
|
8253
8285
|
}
|
|
8254
8286
|
let tree = { ...DEFAULT_TREE };
|
|
@@ -8451,7 +8483,10 @@ var init_config2 = __esm({
|
|
|
8451
8483
|
DEFAULT_ROUTING2 = {
|
|
8452
8484
|
order: [],
|
|
8453
8485
|
cooldownMinutes: 30,
|
|
8454
|
-
retryOnQuota: true
|
|
8486
|
+
retryOnQuota: true,
|
|
8487
|
+
policy: "budget",
|
|
8488
|
+
priority: [],
|
|
8489
|
+
budgetWalls: {}
|
|
8455
8490
|
};
|
|
8456
8491
|
DEFAULT_TREE = {
|
|
8457
8492
|
maxDepth: 2,
|
|
@@ -8835,7 +8870,7 @@ var init_router = __esm({
|
|
|
8835
8870
|
// src/workers/run-env.ts
|
|
8836
8871
|
import { existsSync as existsSync9 } from "node:fs";
|
|
8837
8872
|
import { delimiter, join as join10 } from "node:path";
|
|
8838
|
-
function buildRunEnv(provider, headless, proxyUrl, providerName) {
|
|
8873
|
+
function buildRunEnv(provider, headless, proxyUrl, providerName, routerEnabled) {
|
|
8839
8874
|
const env = { ...process.env };
|
|
8840
8875
|
delete env.ANTHROPIC_API_KEY;
|
|
8841
8876
|
if (headless) {
|
|
@@ -8857,6 +8892,8 @@ function buildRunEnv(provider, headless, proxyUrl, providerName) {
|
|
|
8857
8892
|
let token = "local";
|
|
8858
8893
|
if (proxyUrl) {
|
|
8859
8894
|
env.ANTHROPIC_BASE_URL = proxyUrl;
|
|
8895
|
+
} else if (routerEnabled) {
|
|
8896
|
+
env.ANTHROPIC_BASE_URL = routerUrl();
|
|
8860
8897
|
} else {
|
|
8861
8898
|
const resolved = resolveProviderKey(provider);
|
|
8862
8899
|
if (resolved) token = resolved;
|
|
@@ -8878,6 +8915,9 @@ function buildRunEnv(provider, headless, proxyUrl, providerName) {
|
|
|
8878
8915
|
}
|
|
8879
8916
|
return env;
|
|
8880
8917
|
}
|
|
8918
|
+
function routerUrl() {
|
|
8919
|
+
return `http://127.0.0.1:${ROUTER_PORT}`;
|
|
8920
|
+
}
|
|
8881
8921
|
function claudeCommand(env, caveman, routerEnabled) {
|
|
8882
8922
|
const route = env.ANTHROPIC_BASE_URL;
|
|
8883
8923
|
if (!route && caveman) {
|
|
@@ -8888,7 +8928,7 @@ function claudeCommand(env, caveman, routerEnabled) {
|
|
|
8888
8928
|
return ["claude", ...pinnedSettingsArgs(env, routerEnabled, extra)];
|
|
8889
8929
|
}
|
|
8890
8930
|
function pinnedSettingsArgs(env, routerEnabled = loadConfig().router.enabled, extra) {
|
|
8891
|
-
const native = routerEnabled ?
|
|
8931
|
+
const native = routerEnabled ? routerUrl() : ANTHROPIC_FIRST_PARTY_URL;
|
|
8892
8932
|
const pinned = { ANTHROPIC_BASE_URL: env.ANTHROPIC_BASE_URL || native };
|
|
8893
8933
|
if (env.ANTHROPIC_BASE_URL) {
|
|
8894
8934
|
for (const k of PINNED_KEYS) if (env[k]) pinned[k] = env[k];
|
|
@@ -9023,7 +9063,7 @@ function resolveToken() {
|
|
|
9023
9063
|
function forgeClient(cwd, cfg, deps) {
|
|
9024
9064
|
const token = deps.token ?? resolveToken();
|
|
9025
9065
|
if (!token) throw new ForgeError("no forge token");
|
|
9026
|
-
const
|
|
9066
|
+
const http2 = deps.http ?? curlHttp;
|
|
9027
9067
|
let origin = deps.originUrl;
|
|
9028
9068
|
if (!origin) {
|
|
9029
9069
|
try {
|
|
@@ -9045,7 +9085,7 @@ function forgeClient(cwd, cfg, deps) {
|
|
|
9045
9085
|
if (left < 300) throw new ForgeError("time budget exhausted");
|
|
9046
9086
|
let r;
|
|
9047
9087
|
try {
|
|
9048
|
-
r =
|
|
9088
|
+
r = http2(method, `${derived.apiBase}/repos/${repo}/${path}`, token, body, left);
|
|
9049
9089
|
} catch (e) {
|
|
9050
9090
|
throw e instanceof ForgeError ? e : new ForgeError(`request failed (${e.message})`);
|
|
9051
9091
|
}
|
|
@@ -9359,11 +9399,196 @@ var init_controls = __esm({
|
|
|
9359
9399
|
}
|
|
9360
9400
|
});
|
|
9361
9401
|
|
|
9402
|
+
// src/router/limits.ts
|
|
9403
|
+
import { execFile, spawnSync as spawnSync2 } from "node:child_process";
|
|
9404
|
+
import http from "node:http";
|
|
9405
|
+
import https from "node:https";
|
|
9406
|
+
import { homedir as homedir9 } from "node:os";
|
|
9407
|
+
import { dirname as dirname8, join as join14 } from "node:path";
|
|
9408
|
+
function toMs(v, unit) {
|
|
9409
|
+
if (v === null || v === void 0 || v === "") return void 0;
|
|
9410
|
+
if (unit === "iso" || unit === void 0 && typeof v === "string" && !/^\d+(\.\d+)?$/.test(v)) {
|
|
9411
|
+
const t = Date.parse(String(v));
|
|
9412
|
+
return Number.isFinite(t) ? t : void 0;
|
|
9413
|
+
}
|
|
9414
|
+
const n = Number(v);
|
|
9415
|
+
if (!Number.isFinite(n)) return void 0;
|
|
9416
|
+
return unit === "s" ? n * 1e3 : n;
|
|
9417
|
+
}
|
|
9418
|
+
function jq(expr, input) {
|
|
9419
|
+
const r = spawnSync2("jq", ["-r", expr], { input, encoding: "utf8", timeout: 3e3 });
|
|
9420
|
+
if (r.status !== 0) return void 0;
|
|
9421
|
+
const out = r.stdout.trim().split("\n")[0];
|
|
9422
|
+
return out === void 0 || out === "" || out === "null" ? void 0 : out;
|
|
9423
|
+
}
|
|
9424
|
+
function windowsFromJson(body, cfg) {
|
|
9425
|
+
const out = [];
|
|
9426
|
+
for (const w of cfg.windows) {
|
|
9427
|
+
const pct = Number(jq(w.percent, body));
|
|
9428
|
+
if (!Number.isFinite(pct) || jq(w.percent, body) === void 0) continue;
|
|
9429
|
+
const reset = w.resetAt ? toMs(jq(w.resetAt, body), w.resetUnit) : void 0;
|
|
9430
|
+
out.push({ name: w.name, percent: Math.round(pct * 10) / 10, ...reset ? { resetAt: reset } : {} });
|
|
9431
|
+
}
|
|
9432
|
+
return out;
|
|
9433
|
+
}
|
|
9434
|
+
function parseAnthropicUsage(body) {
|
|
9435
|
+
let j;
|
|
9436
|
+
try {
|
|
9437
|
+
j = JSON.parse(body);
|
|
9438
|
+
} catch {
|
|
9439
|
+
return [];
|
|
9440
|
+
}
|
|
9441
|
+
const out = [];
|
|
9442
|
+
for (const [key, name] of [["five_hour", "5h"], ["seven_day", "7d"]]) {
|
|
9443
|
+
const w = j[key];
|
|
9444
|
+
if (!w || typeof w.utilization !== "number") continue;
|
|
9445
|
+
const reset = toMs(w.resets_at, "iso");
|
|
9446
|
+
out.push({ name, percent: w.utilization, ...reset ? { resetAt: reset } : {} });
|
|
9447
|
+
}
|
|
9448
|
+
return out;
|
|
9449
|
+
}
|
|
9450
|
+
function getJson(url, headers) {
|
|
9451
|
+
return new Promise((resolve, reject) => {
|
|
9452
|
+
const mod = url.protocol === "https:" ? https : http;
|
|
9453
|
+
const rq = mod.get(url, { headers, timeout: 5e3 }, (res) => {
|
|
9454
|
+
let t = "";
|
|
9455
|
+
res.on("data", (c) => t += c);
|
|
9456
|
+
res.on("end", () => res.statusCode === 200 ? resolve(t) : reject(new Error(`http ${res.statusCode}`)));
|
|
9457
|
+
});
|
|
9458
|
+
rq.on("timeout", () => rq.destroy(new Error("timeout")));
|
|
9459
|
+
rq.on("error", reject);
|
|
9460
|
+
});
|
|
9461
|
+
}
|
|
9462
|
+
function sh(cmd, args) {
|
|
9463
|
+
return new Promise((resolve) => execFile(cmd, args, { timeout: 4e3 }, (_e, out) => resolve(String(out ?? "").trim())));
|
|
9464
|
+
}
|
|
9465
|
+
async function anthropicToken() {
|
|
9466
|
+
for (const args of [["-a", process.env.USER ?? ""], []]) {
|
|
9467
|
+
const raw = await sh("security", ["find-generic-password", "-s", "Claude Code-credentials", ...args, "-w"]);
|
|
9468
|
+
try {
|
|
9469
|
+
const t = JSON.parse(raw).claudeAiOauth?.accessToken;
|
|
9470
|
+
if (t) return t;
|
|
9471
|
+
} catch {
|
|
9472
|
+
}
|
|
9473
|
+
}
|
|
9474
|
+
return void 0;
|
|
9475
|
+
}
|
|
9476
|
+
var ESTIMATE_FILE, ADVISOR_FILE, LASTGOOD_FILE, PLAN_LASTGOOD_MAX_AGE, BACKOFF_MAX, ANTHROPIC_USAGE_URL;
|
|
9477
|
+
var init_limits = __esm({
|
|
9478
|
+
"src/router/limits.ts"() {
|
|
9479
|
+
"use strict";
|
|
9480
|
+
init_config2();
|
|
9481
|
+
ESTIMATE_FILE = join14(homedir9(), ".claude", "pai", "router-limits.json");
|
|
9482
|
+
ADVISOR_FILE = join14(homedir9(), ".claude", "pai", "advisor-mode.json");
|
|
9483
|
+
LASTGOOD_FILE = join14(homedir9(), ".claude", "pai", "logs", "router-limits-last.json");
|
|
9484
|
+
PLAN_LASTGOOD_MAX_AGE = 2 * 36e5;
|
|
9485
|
+
BACKOFF_MAX = 30 * 6e4;
|
|
9486
|
+
ANTHROPIC_USAGE_URL = "https://api.anthropic.com/api/oauth/usage";
|
|
9487
|
+
}
|
|
9488
|
+
});
|
|
9489
|
+
|
|
9490
|
+
// src/workers/budget.ts
|
|
9491
|
+
function pickBudgetWindow(windows, now) {
|
|
9492
|
+
let best = null;
|
|
9493
|
+
for (const w of windows) if (!best || w.percent > best.percent) best = w;
|
|
9494
|
+
if (!best) return { percent: null, resetAt: null, fetchedAt: now };
|
|
9495
|
+
return { percent: best.percent, resetAt: best.resetAt ?? null, fetchedAt: now };
|
|
9496
|
+
}
|
|
9497
|
+
async function fetchBudgetReading(name, p) {
|
|
9498
|
+
const now = Date.now();
|
|
9499
|
+
try {
|
|
9500
|
+
if (p.native || name === "anthropic") {
|
|
9501
|
+
const token = await anthropicToken();
|
|
9502
|
+
if (!token) throw new Error("no OAuth token in keychain");
|
|
9503
|
+
const body2 = await getJson(new URL(ANTHROPIC_USAGE_URL), {
|
|
9504
|
+
authorization: `Bearer ${token}`,
|
|
9505
|
+
"anthropic-beta": "oauth-2025-04-20"
|
|
9506
|
+
});
|
|
9507
|
+
return pickBudgetWindow(parseAnthropicUsage(body2), now);
|
|
9508
|
+
}
|
|
9509
|
+
if (!p.usage) return { percent: null, resetAt: null, fetchedAt: now };
|
|
9510
|
+
const key = resolveProviderKey(p);
|
|
9511
|
+
const [hn, ...pre] = (p.usage.authHeader ?? "Authorization: Bearer").split(/:\s*/);
|
|
9512
|
+
const prefix = pre.join(": ");
|
|
9513
|
+
const body = await getJson(new URL(p.usage.url), {
|
|
9514
|
+
[hn.toLowerCase()]: prefix ? `${prefix} ${key}` : String(key)
|
|
9515
|
+
});
|
|
9516
|
+
return pickBudgetWindow(windowsFromJson(body, p.usage), now);
|
|
9517
|
+
} catch {
|
|
9518
|
+
return { percent: null, resetAt: null, fetchedAt: now };
|
|
9519
|
+
}
|
|
9520
|
+
}
|
|
9521
|
+
var BUDGET_TTL_MS, BudgetCache, budgetCache;
|
|
9522
|
+
var init_budget = __esm({
|
|
9523
|
+
"src/workers/budget.ts"() {
|
|
9524
|
+
"use strict";
|
|
9525
|
+
init_limits();
|
|
9526
|
+
init_config2();
|
|
9527
|
+
BUDGET_TTL_MS = 5 * 6e4;
|
|
9528
|
+
BudgetCache = class {
|
|
9529
|
+
constructor(ttlMs = BUDGET_TTL_MS, fetch2 = fetchBudgetReading) {
|
|
9530
|
+
this.ttlMs = ttlMs;
|
|
9531
|
+
this.fetch = fetch2;
|
|
9532
|
+
}
|
|
9533
|
+
value = {};
|
|
9534
|
+
at = 0;
|
|
9535
|
+
inflight;
|
|
9536
|
+
/** Refresh every stale provider of `config`; resolves to the full map. */
|
|
9537
|
+
async warm(config, now = Date.now()) {
|
|
9538
|
+
if (this.at && now - this.at < this.ttlMs) return this.value;
|
|
9539
|
+
this.inflight ??= this.poll(config).then((v) => {
|
|
9540
|
+
this.value = v;
|
|
9541
|
+
this.at = now;
|
|
9542
|
+
this.inflight = void 0;
|
|
9543
|
+
return v;
|
|
9544
|
+
});
|
|
9545
|
+
return this.inflight;
|
|
9546
|
+
}
|
|
9547
|
+
async poll(config) {
|
|
9548
|
+
const out = { ...this.value };
|
|
9549
|
+
const jobs = [
|
|
9550
|
+
// native anthropic has no config entry: probe it as the synthetic provider
|
|
9551
|
+
this.fetch("anthropic", nativeAnthropicProvider(config.nativeModels)).then((r) => {
|
|
9552
|
+
out.anthropic = r;
|
|
9553
|
+
})
|
|
9554
|
+
];
|
|
9555
|
+
for (const [name, p] of Object.entries(config.providers)) {
|
|
9556
|
+
jobs.push(
|
|
9557
|
+
this.fetch(name, p).then((r) => {
|
|
9558
|
+
out[name] = r;
|
|
9559
|
+
})
|
|
9560
|
+
);
|
|
9561
|
+
}
|
|
9562
|
+
await Promise.all(jobs);
|
|
9563
|
+
return out;
|
|
9564
|
+
}
|
|
9565
|
+
/** Synchronous read for routing (possibly absent — absence is "unknown"). */
|
|
9566
|
+
get(name) {
|
|
9567
|
+
return this.value[name];
|
|
9568
|
+
}
|
|
9569
|
+
snapshot() {
|
|
9570
|
+
return { ...this.value };
|
|
9571
|
+
}
|
|
9572
|
+
seed(map, at = Date.now()) {
|
|
9573
|
+
this.value = { ...map };
|
|
9574
|
+
this.at = at;
|
|
9575
|
+
}
|
|
9576
|
+
clear() {
|
|
9577
|
+
this.value = {};
|
|
9578
|
+
this.at = 0;
|
|
9579
|
+
this.inflight = void 0;
|
|
9580
|
+
}
|
|
9581
|
+
};
|
|
9582
|
+
budgetCache = new BudgetCache();
|
|
9583
|
+
}
|
|
9584
|
+
});
|
|
9585
|
+
|
|
9362
9586
|
// src/workers/routing.ts
|
|
9363
9587
|
var init_routing = __esm({
|
|
9364
9588
|
"src/workers/routing.ts"() {
|
|
9365
9589
|
"use strict";
|
|
9366
9590
|
init_config2();
|
|
9591
|
+
init_budget();
|
|
9367
9592
|
init_paths();
|
|
9368
9593
|
}
|
|
9369
9594
|
});
|
|
@@ -15426,8 +15651,8 @@ var require_bindings = __commonJS({
|
|
|
15426
15651
|
var fs = __require("fs");
|
|
15427
15652
|
var path = __require("path");
|
|
15428
15653
|
var fileURLToPath = require_file_uri_to_path();
|
|
15429
|
-
var
|
|
15430
|
-
var
|
|
15654
|
+
var join15 = path.join;
|
|
15655
|
+
var dirname9 = path.dirname;
|
|
15431
15656
|
var exists = fs.accessSync && function(path2) {
|
|
15432
15657
|
try {
|
|
15433
15658
|
fs.accessSync(path2);
|
|
@@ -15486,7 +15711,7 @@ var require_bindings = __commonJS({
|
|
|
15486
15711
|
var requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
|
|
15487
15712
|
var tries = [], i = 0, l = opts.try.length, n, b, err;
|
|
15488
15713
|
for (; i < l; i++) {
|
|
15489
|
-
n =
|
|
15714
|
+
n = join15.apply(
|
|
15490
15715
|
null,
|
|
15491
15716
|
opts.try[i].map(function(p) {
|
|
15492
15717
|
return opts[p] || p;
|
|
@@ -15542,12 +15767,12 @@ var require_bindings = __commonJS({
|
|
|
15542
15767
|
return fileName;
|
|
15543
15768
|
};
|
|
15544
15769
|
exports.getRoot = function getRoot(file) {
|
|
15545
|
-
var dir =
|
|
15770
|
+
var dir = dirname9(file), prev;
|
|
15546
15771
|
while (true) {
|
|
15547
15772
|
if (dir === ".") {
|
|
15548
15773
|
dir = process.cwd();
|
|
15549
15774
|
}
|
|
15550
|
-
if (exists(
|
|
15775
|
+
if (exists(join15(dir, "package.json")) || exists(join15(dir, "node_modules"))) {
|
|
15551
15776
|
return dir;
|
|
15552
15777
|
}
|
|
15553
15778
|
if (prev === dir) {
|
|
@@ -15556,7 +15781,7 @@ var require_bindings = __commonJS({
|
|
|
15556
15781
|
);
|
|
15557
15782
|
}
|
|
15558
15783
|
prev = dir;
|
|
15559
|
-
dir =
|
|
15784
|
+
dir = join15(dir, "..");
|
|
15560
15785
|
}
|
|
15561
15786
|
};
|
|
15562
15787
|
}
|
|
@@ -16393,6 +16618,7 @@ var init_run = __esm({
|
|
|
16393
16618
|
init_controls();
|
|
16394
16619
|
init_policy();
|
|
16395
16620
|
init_routing();
|
|
16621
|
+
init_budget();
|
|
16396
16622
|
init_image();
|
|
16397
16623
|
init_pane();
|
|
16398
16624
|
init_tree();
|
|
@@ -16424,6 +16650,7 @@ init_pool();
|
|
|
16424
16650
|
import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync8 } from "node:fs";
|
|
16425
16651
|
|
|
16426
16652
|
// src/workers/pool-host.ts
|
|
16653
|
+
init_config();
|
|
16427
16654
|
init_args();
|
|
16428
16655
|
init_agentish();
|
|
16429
16656
|
init_config2();
|
|
@@ -16618,8 +16845,9 @@ function createPoolHost(opts = {}) {
|
|
|
16618
16845
|
const settings = poolSettings(config);
|
|
16619
16846
|
const port2 = opts.port ?? poolPort(config);
|
|
16620
16847
|
const spawner = opts.spawner ?? realSpawner;
|
|
16621
|
-
const
|
|
16622
|
-
const
|
|
16848
|
+
const routerOn = opts.routerEnabled ?? loadConfig().router.enabled;
|
|
16849
|
+
const envFor = opts.envFor ?? ((name, p) => buildRunEnv(p, true, void 0, name, routerOn));
|
|
16850
|
+
const cmdHead = opts.cmdHead ?? ((env, caveman) => claudeCommand(env, caveman, routerOn));
|
|
16623
16851
|
const now = opts.now ?? (() => /* @__PURE__ */ new Date());
|
|
16624
16852
|
const ledger = ledgerPath(logDir2);
|
|
16625
16853
|
mkdirSync9(logDir2, { recursive: true });
|