claudish 14.6.0 → 14.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +476 -71
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -114,6 +114,7 @@ var init_launch_env = __esm(() => {
|
|
|
114
114
|
"CLAUDISH_PANE_CWD",
|
|
115
115
|
"CLAUDISH_HOOK_INBOX",
|
|
116
116
|
"CLAUDISH_HOOK_SESSION",
|
|
117
|
+
"CLAUDISH_PARENT_SESSION",
|
|
117
118
|
"CLAUDISH_BIN"
|
|
118
119
|
];
|
|
119
120
|
});
|
|
@@ -166,6 +167,7 @@ var init_config = __esm(() => {
|
|
|
166
167
|
CLAUDISH_PANE_CHILD: "CLAUDISH_PANE_CHILD",
|
|
167
168
|
CLAUDISH_PANE_ENV: "CLAUDISH_PANE_ENV",
|
|
168
169
|
CLAUDISH_PANE_CWD: "CLAUDISH_PANE_CWD",
|
|
170
|
+
CLAUDISH_PARENT_SESSION: "CLAUDISH_PARENT_SESSION",
|
|
169
171
|
CLAUDISH_PANE_ROOT: "CLAUDISH_PANE_ROOT"
|
|
170
172
|
};
|
|
171
173
|
});
|
|
@@ -216,7 +218,8 @@ function applyPaneEnvSnapshot(env) {
|
|
|
216
218
|
ENV.CLAUDISH_PANE_CHILD,
|
|
217
219
|
ENV.CLAUDISH_PANE_CWD,
|
|
218
220
|
HOOK_INBOX_VAR,
|
|
219
|
-
HOOK_SESSION_VAR
|
|
221
|
+
HOOK_SESSION_VAR,
|
|
222
|
+
ENV.CLAUDISH_PARENT_SESSION
|
|
220
223
|
]);
|
|
221
224
|
for (const key of Object.keys(env)) {
|
|
222
225
|
if (Object.hasOwn(snapshot, key) || keep.has(key) || isPaneShellManagedKey(key))
|
|
@@ -298,7 +301,8 @@ var init_child_env = __esm(() => {
|
|
|
298
301
|
ENV.CLAUDISH_PANE_ENV,
|
|
299
302
|
ENV.CLAUDISH_PANE_CWD,
|
|
300
303
|
HOOK_INBOX_VAR,
|
|
301
|
-
HOOK_SESSION_VAR
|
|
304
|
+
HOOK_SESSION_VAR,
|
|
305
|
+
ENV.CLAUDISH_PARENT_SESSION
|
|
302
306
|
];
|
|
303
307
|
PANE_SHELL_MANAGED_KEYS = [
|
|
304
308
|
"COLUMNS",
|
|
@@ -5394,7 +5398,7 @@ var init_onepassword_config = __esm(() => {
|
|
|
5394
5398
|
});
|
|
5395
5399
|
|
|
5396
5400
|
// src/version.ts
|
|
5397
|
-
var VERSION = "14.
|
|
5401
|
+
var VERSION = "14.8.0";
|
|
5398
5402
|
|
|
5399
5403
|
// src/redact.ts
|
|
5400
5404
|
function isPlaceholder(value) {
|
|
@@ -16038,7 +16042,7 @@ var init_minimax_model_dialect = __esm(() => {
|
|
|
16038
16042
|
});
|
|
16039
16043
|
|
|
16040
16044
|
// src/auth/accounts/allowance-report-schema.ts
|
|
16041
|
-
var ALLOWANCE_REPORT_SCHEMA = "claudish.allowance.v1", iso, fraction, finite, nonNegative, quantilesOf = (t) => object({ p10: t, p25: t, p50: t, p75: t, p90: t }), alertLevel, strategyName, evidence, unit, provenance, semantics, gapKind, exactness, accountSchema, remedySchema, alertSchema, trajectorySchema, sessionSchema, allowanceReportSchema, allowanceStatusAnswerSchema;
|
|
16045
|
+
var ALLOWANCE_REPORT_SCHEMA = "claudish.allowance.v1", iso, fraction, finite, nonNegative, quantilesOf = (t) => object({ p10: t, p25: t, p50: t, p75: t, p90: t }), alertLevel, strategyName, evidence, unit, provenance, semantics, gapKind, exactness, accountSchema, remedySchema, alertSchema, historyPoint, trajectorySchema, sessionSchema, allowanceReportSchema, ALLOWANCE_REPORT_SECTIONS, partialReport, allowanceStatusAnswerSchema;
|
|
16042
16046
|
var init_allowance_report_schema = __esm(() => {
|
|
16043
16047
|
init_zod();
|
|
16044
16048
|
iso = exports_iso.datetime({ offset: true });
|
|
@@ -16068,7 +16072,10 @@ var init_allowance_report_schema = __esm(() => {
|
|
|
16068
16072
|
semantics
|
|
16069
16073
|
})),
|
|
16070
16074
|
lambda: union([literal(0), literal(1)]).nullable(),
|
|
16071
|
-
calibration: object({ beta: string2(), kappa: string2().nullable() })
|
|
16075
|
+
calibration: object({ beta: string2(), kappa: string2().nullable() }),
|
|
16076
|
+
active: boolean2().optional(),
|
|
16077
|
+
order: number2().int().min(0).optional(),
|
|
16078
|
+
lostAtReset: object({ at: iso, p10: fraction, p50: fraction, p90: fraction }).nullable().optional()
|
|
16072
16079
|
});
|
|
16073
16080
|
remedySchema = object({
|
|
16074
16081
|
kind: _enum(["cut", "pause", "not-addressable"]),
|
|
@@ -16089,19 +16096,34 @@ var init_allowance_report_schema = __esm(() => {
|
|
|
16089
16096
|
binding: array(object({ account: string2(), window: string2() })),
|
|
16090
16097
|
remedy: remedySchema
|
|
16091
16098
|
});
|
|
16099
|
+
historyPoint = object({
|
|
16100
|
+
at: iso,
|
|
16101
|
+
remaining: finite,
|
|
16102
|
+
provenance: _enum(["observed", "reset-inferred"])
|
|
16103
|
+
});
|
|
16092
16104
|
trajectorySchema = object({
|
|
16093
|
-
history: array(
|
|
16094
|
-
|
|
16095
|
-
remaining: finite,
|
|
16096
|
-
provenance: _enum(["observed", "reset-inferred"])
|
|
16097
|
-
})),
|
|
16105
|
+
history: array(historyPoint),
|
|
16106
|
+
historyByAccount: array(object({ accountId: string2(), history: array(historyPoint) })).optional(),
|
|
16098
16107
|
forecast: array(object({ at: iso, p10: finite, p50: finite, p90: finite, pBlocked: fraction })),
|
|
16099
16108
|
resets: array(object({ at: iso, account: string2(), window: string2(), projected: boolean2() })),
|
|
16100
16109
|
blocked: array(object({ from: iso, to: iso, kind: gapKind, probability: fraction })),
|
|
16110
|
+
switches: array(object({
|
|
16111
|
+
accountId: string2(),
|
|
16112
|
+
soonest: iso,
|
|
16113
|
+
usual: iso,
|
|
16114
|
+
latest: iso,
|
|
16115
|
+
probability: fraction,
|
|
16116
|
+
likelihood: object({
|
|
16117
|
+
start: iso,
|
|
16118
|
+
stepHours: literal(1),
|
|
16119
|
+
p: array(number2().min(0).max(1)).min(1)
|
|
16120
|
+
}).optional()
|
|
16121
|
+
})).optional(),
|
|
16101
16122
|
spark48: string2().regex(/^[\u2581\u2582\u2583\u2584\u2585\u2586\u2587\u2588\u2592\u2593\u250A ]*$/u)
|
|
16102
16123
|
});
|
|
16103
16124
|
sessionSchema = object({
|
|
16104
16125
|
session: union([string2().max(8), literal("unattributed")]),
|
|
16126
|
+
parent: union([string2().max(8), _null3()]).optional(),
|
|
16105
16127
|
account: string2(),
|
|
16106
16128
|
window: string2(),
|
|
16107
16129
|
share: fraction,
|
|
@@ -16143,11 +16165,41 @@ var init_allowance_report_schema = __esm(() => {
|
|
|
16143
16165
|
trajectory: trajectorySchema,
|
|
16144
16166
|
sessions: array(sessionSchema)
|
|
16145
16167
|
});
|
|
16168
|
+
ALLOWANCE_REPORT_SECTIONS = [
|
|
16169
|
+
"accounts",
|
|
16170
|
+
"alerts",
|
|
16171
|
+
"burn",
|
|
16172
|
+
"combined",
|
|
16173
|
+
"sessions",
|
|
16174
|
+
"trajectory"
|
|
16175
|
+
];
|
|
16176
|
+
partialReport = allowanceReportSchema.partial({
|
|
16177
|
+
accounts: true,
|
|
16178
|
+
alerts: true,
|
|
16179
|
+
burn: true,
|
|
16180
|
+
combined: true,
|
|
16181
|
+
sessions: true,
|
|
16182
|
+
trajectory: true
|
|
16183
|
+
});
|
|
16146
16184
|
allowanceStatusAnswerSchema = object({
|
|
16147
16185
|
contract_version: literal(1),
|
|
16148
16186
|
capabilities: array(string2()),
|
|
16149
|
-
|
|
16187
|
+
sections: array(_enum(ALLOWANCE_REPORT_SECTIONS)).min(1).optional(),
|
|
16188
|
+
allowance: partialReport.nullable(),
|
|
16150
16189
|
reason: string2().optional()
|
|
16190
|
+
}).superRefine((answer, ctx) => {
|
|
16191
|
+
if (answer.allowance === null)
|
|
16192
|
+
return;
|
|
16193
|
+
const wanted = answer.sections ?? ALLOWANCE_REPORT_SECTIONS;
|
|
16194
|
+
for (const section of wanted) {
|
|
16195
|
+
if (answer.allowance[section] === undefined) {
|
|
16196
|
+
ctx.addIssue({
|
|
16197
|
+
code: "custom",
|
|
16198
|
+
path: ["allowance", section],
|
|
16199
|
+
message: `section ${section} is missing`
|
|
16200
|
+
});
|
|
16201
|
+
}
|
|
16202
|
+
}
|
|
16151
16203
|
});
|
|
16152
16204
|
});
|
|
16153
16205
|
|
|
@@ -16599,7 +16651,7 @@ function cuOf(tokens, cfg) {
|
|
|
16599
16651
|
const uncached = Math.max(0, tokens.input - tokens.cacheRead - tokens.cacheWrite);
|
|
16600
16652
|
return uncached + w.cacheRead * tokens.cacheRead + w.cacheWrite * tokens.cacheWrite + w.output * tokens.output;
|
|
16601
16653
|
}
|
|
16602
|
-
var PROVIDER_COST_PRIORS, MINUTE_MS2 = 60000, HOUR_MS2, DEFAULT_ALLOWANCE_CONFIG, LOOKAHEAD_TRAJ_PATHS = 40;
|
|
16654
|
+
var PROVIDER_COST_PRIORS, MINUTE_MS2 = 60000, HOUR_MS2, DEFAULT_ALLOWANCE_CONFIG, LOOKAHEAD_TRAJ_PATHS = 40, MIN_PATH_SHARE = 0.1, PACE_MAX_MULT = 64, PACE_BISECT_STEPS = 4;
|
|
16603
16655
|
var init_constants = __esm(() => {
|
|
16604
16656
|
PROVIDER_COST_PRIORS = {
|
|
16605
16657
|
"openai-codex": { cacheRead: 0.1, cacheWrite: 1, output: 4 },
|
|
@@ -17092,7 +17144,7 @@ function fold(s, e, cfg, seen) {
|
|
|
17092
17144
|
insertServed(account, e.at, cu);
|
|
17093
17145
|
addDemand(s, hourOf(e.at), cu, 1);
|
|
17094
17146
|
if (e.session !== null)
|
|
17095
|
-
addSession(s, e.session, e.at, e.account, cu, e.tokens, e.model, 1);
|
|
17147
|
+
addSession(s, e.session, e.at, e.account, cu, e.tokens, e.model, 1, e.parent ?? null);
|
|
17096
17148
|
}
|
|
17097
17149
|
if (e.outcome === "ok")
|
|
17098
17150
|
closeCensor(s, e.at);
|
|
@@ -17141,13 +17193,13 @@ function fold(s, e, cfg, seen) {
|
|
|
17141
17193
|
if (cu > 0) {
|
|
17142
17194
|
insertServed(account, mid, cu);
|
|
17143
17195
|
if (e.session !== null)
|
|
17144
|
-
addSession(s, e.session, mid, e.account, cu, e.tokens, e.model, e.n);
|
|
17196
|
+
addSession(s, e.session, mid, e.account, cu, e.tokens, e.model, e.n, e.parent ?? null);
|
|
17145
17197
|
}
|
|
17146
17198
|
const bucket = addDemand(s, e.hour, cu, e.n);
|
|
17147
17199
|
bucket.censoredMinutes = Math.min(60, Math.max(bucket.censoredMinutes, e.censoredMinutes));
|
|
17148
|
-
if (e.first !== null)
|
|
17200
|
+
if (e.first !== null && e.n > 1)
|
|
17149
17201
|
applySnapshot(account, e.hour, e.first, cfg);
|
|
17150
|
-
if (e.last !== null
|
|
17202
|
+
if (e.last !== null)
|
|
17151
17203
|
applySnapshot(account, e.hour + HOUR_MS4 - 1, e.last, cfg);
|
|
17152
17204
|
touch(s, e.hour + HOUR_MS4 - 1);
|
|
17153
17205
|
return;
|
|
@@ -17225,7 +17277,7 @@ function sealCensor(s, from, to) {
|
|
|
17225
17277
|
bucket.censoredMinutes = Math.min(60, Math.max(bucket.censoredMinutes, overlap / MINUTE_MS4));
|
|
17226
17278
|
}
|
|
17227
17279
|
}
|
|
17228
|
-
function addSession(s, session, at, account, cu, tokens, model, n) {
|
|
17280
|
+
function addSession(s, session, at, account, cu, tokens, model, n, parent) {
|
|
17229
17281
|
let track = s.sessions[session];
|
|
17230
17282
|
if (!track) {
|
|
17231
17283
|
track = {
|
|
@@ -17250,6 +17302,8 @@ function addSession(s, session, at, account, cu, tokens, model, n) {
|
|
|
17250
17302
|
track.tokens.cacheWrite += tokens.cacheWrite;
|
|
17251
17303
|
track.tokens.output += tokens.output;
|
|
17252
17304
|
track.models[model] = (track.models[model] ?? 0) + n;
|
|
17305
|
+
if (parent !== null && (track.parent ?? null) === null)
|
|
17306
|
+
track.parent = parent;
|
|
17253
17307
|
}
|
|
17254
17308
|
function applySnapshot(account, at, readings, cfg) {
|
|
17255
17309
|
const current = account.lastCompleteAt === null || at >= account.lastCompleteAt;
|
|
@@ -19221,18 +19275,88 @@ function pauseGrid(horizonMs) {
|
|
|
19221
19275
|
out.push(hours * HOUR_MS11);
|
|
19222
19276
|
return out.filter((p) => p <= Math.max(horizonMs, HOUR_MS11));
|
|
19223
19277
|
}
|
|
19224
|
-
function*
|
|
19225
|
-
const zero = ctx.factors.map(() => 0);
|
|
19226
|
-
const externalStarts = gapsOn(ctx, zero, cfg).filter((g) => g.kind === "7d" && g.lengthMs >= REMEDY_MIN_GAP_MS).map((g) => g.start);
|
|
19227
|
-
yield;
|
|
19278
|
+
function* cutScan(ctx, rate, cfg) {
|
|
19228
19279
|
let cut = null;
|
|
19229
19280
|
for (const phi of CUT_GRID) {
|
|
19230
|
-
const gs = gapsOn(ctx, ctx.factors.map((f) => phi *
|
|
19281
|
+
const gs = gapsOn(ctx, ctx.factors.map((f) => phi * rate * f), cfg);
|
|
19231
19282
|
yield;
|
|
19232
19283
|
if (hasGap(gs))
|
|
19233
19284
|
break;
|
|
19234
19285
|
cut = phi;
|
|
19235
19286
|
}
|
|
19287
|
+
return cut;
|
|
19288
|
+
}
|
|
19289
|
+
function refillThroughput(ctx) {
|
|
19290
|
+
let total = 0;
|
|
19291
|
+
for (const v of ctx.views.filter(isRead)) {
|
|
19292
|
+
const g = v.windows.find((w) => w.key === v.governing);
|
|
19293
|
+
if (!g || g.lengthMinutes === null || g.lengthMinutes <= 0)
|
|
19294
|
+
continue;
|
|
19295
|
+
const beta = ctx.unit === "cu" ? v.beta[g.key]?.value : undefined;
|
|
19296
|
+
const capacity = beta !== undefined && beta > 0 ? 1 / beta : 1;
|
|
19297
|
+
total += capacity / (g.lengthMinutes / 60);
|
|
19298
|
+
}
|
|
19299
|
+
return total;
|
|
19300
|
+
}
|
|
19301
|
+
function* paceScan(ctx, ev, rates, cfg) {
|
|
19302
|
+
const rhoL = Number.isFinite(rates.long) && rates.long > 0 ? rates.long : 0;
|
|
19303
|
+
if (rhoL > 0 && hasGap(ev.long)) {
|
|
19304
|
+
const cut = yield* cutScan(ctx, rhoL, cfg);
|
|
19305
|
+
return { rate: cut === null ? 0 : cut * rhoL, basis: "cut-scan" };
|
|
19306
|
+
}
|
|
19307
|
+
const anchor = Math.max(rhoL, refillThroughput(ctx));
|
|
19308
|
+
if (!(anchor > 0) || !Number.isFinite(anchor))
|
|
19309
|
+
return null;
|
|
19310
|
+
const clean = (rho) => !hasGap(gapsOn(ctx, ctx.factors.map((f) => rho * f), cfg));
|
|
19311
|
+
if (anchor > rhoL) {
|
|
19312
|
+
const ok = clean(anchor);
|
|
19313
|
+
yield;
|
|
19314
|
+
if (!ok)
|
|
19315
|
+
return { rate: yield* bisect(rhoL, anchor, clean), basis: "bisect" };
|
|
19316
|
+
}
|
|
19317
|
+
const up = yield* bracketUp(anchor, clean);
|
|
19318
|
+
if (up.hi === null)
|
|
19319
|
+
return { rate: up.lo, basis: "capped" };
|
|
19320
|
+
return { rate: yield* bisect(up.lo, up.hi, clean), basis: "bracket" };
|
|
19321
|
+
}
|
|
19322
|
+
function* bracketUp(anchor, clean) {
|
|
19323
|
+
let lo = anchor;
|
|
19324
|
+
for (let mult = 2;mult <= PACE_MAX_MULT; mult *= 2) {
|
|
19325
|
+
const ok = clean(mult * anchor);
|
|
19326
|
+
yield;
|
|
19327
|
+
if (!ok)
|
|
19328
|
+
return { lo, hi: mult * anchor };
|
|
19329
|
+
lo = mult * anchor;
|
|
19330
|
+
}
|
|
19331
|
+
return { lo, hi: null };
|
|
19332
|
+
}
|
|
19333
|
+
function* bisect(lo, hi, clean) {
|
|
19334
|
+
let low = lo;
|
|
19335
|
+
let high = hi;
|
|
19336
|
+
for (let i = 0;i < PACE_BISECT_STEPS; i++) {
|
|
19337
|
+
const mid = (low + high) / 2;
|
|
19338
|
+
const ok = clean(mid);
|
|
19339
|
+
yield;
|
|
19340
|
+
if (ok)
|
|
19341
|
+
low = mid;
|
|
19342
|
+
else
|
|
19343
|
+
high = mid;
|
|
19344
|
+
}
|
|
19345
|
+
return low;
|
|
19346
|
+
}
|
|
19347
|
+
function paceInCuPerHour(pace, burnLong) {
|
|
19348
|
+
if (pace.phi !== null && Number.isFinite(burnLong) && burnLong > 0) {
|
|
19349
|
+
return Math.max(0, pace.phi * burnLong);
|
|
19350
|
+
}
|
|
19351
|
+
if (pace.unit === "cu")
|
|
19352
|
+
return Math.max(0, pace.rate);
|
|
19353
|
+
return null;
|
|
19354
|
+
}
|
|
19355
|
+
function* remedyScan(ctx, rateLong, cfg) {
|
|
19356
|
+
const zero = ctx.factors.map(() => 0);
|
|
19357
|
+
const externalStarts = gapsOn(ctx, zero, cfg).filter((g) => g.kind === "7d" && g.lengthMs >= REMEDY_MIN_GAP_MS).map((g) => g.start);
|
|
19358
|
+
yield;
|
|
19359
|
+
const cut = yield* cutScan(ctx, rateLong, cfg);
|
|
19236
19360
|
let pauseMs = null;
|
|
19237
19361
|
const h0 = hourStart(ctx.now);
|
|
19238
19362
|
for (const p of pauseGrid(ctx.horizonMs)) {
|
|
@@ -19273,6 +19397,25 @@ function remedyText(r, gapStart, formatTime) {
|
|
|
19273
19397
|
function rateBin(n) {
|
|
19274
19398
|
return Number.isFinite(n) && n > 0 ? String(Math.round(8 * Math.log2(n))) : "0";
|
|
19275
19399
|
}
|
|
19400
|
+
function* paceFor(ctx, ev, rates, inputsKey, cfg, opts) {
|
|
19401
|
+
if (!opts.pace || opts.payload === false)
|
|
19402
|
+
return null;
|
|
19403
|
+
const key = fnvHex([inputsKey, "pace"].join("|"));
|
|
19404
|
+
if (opts.paceReuse?.key === key)
|
|
19405
|
+
return opts.paceReuse;
|
|
19406
|
+
const found = yield* paceScan(ctx, ev, rates, cfg);
|
|
19407
|
+
if (found === null)
|
|
19408
|
+
return null;
|
|
19409
|
+
const simLong = rates.long;
|
|
19410
|
+
return {
|
|
19411
|
+
key,
|
|
19412
|
+
rate: found.rate,
|
|
19413
|
+
simLong,
|
|
19414
|
+
phi: Number.isFinite(simLong) && simLong > 0 ? found.rate / simLong : null,
|
|
19415
|
+
unit: ctx.unit,
|
|
19416
|
+
basis: found.basis
|
|
19417
|
+
};
|
|
19418
|
+
}
|
|
19276
19419
|
function* alertsSliced(s, now, prior, cal, cfg, fc, opts = {}) {
|
|
19277
19420
|
const base = prior ?? initialAlertMemory();
|
|
19278
19421
|
if (evidenceOf(s, now) === "none") {
|
|
@@ -19281,7 +19424,8 @@ function* alertsSliced(s, now, prior, cal, cfg, fc, opts = {}) {
|
|
|
19281
19424
|
active: [],
|
|
19282
19425
|
transitions: [],
|
|
19283
19426
|
blockedNow: false,
|
|
19284
|
-
status: "insufficient-evidence"
|
|
19427
|
+
status: "insufficient-evidence",
|
|
19428
|
+
pace: null
|
|
19285
19429
|
};
|
|
19286
19430
|
}
|
|
19287
19431
|
const ctx = gapContext(s, now, cal, cfg);
|
|
@@ -19318,7 +19462,8 @@ function* alertsSliced(s, now, prior, cal, cfg, fc, opts = {}) {
|
|
|
19318
19462
|
const active = [];
|
|
19319
19463
|
const raised = ["critical", "warn"].filter((l) => memory[l].raised);
|
|
19320
19464
|
if (raised.length === 0 || opts.payload === false) {
|
|
19321
|
-
|
|
19465
|
+
const pace = yield* paceFor(ctx, ev, rates, inputsKey, cfg, opts);
|
|
19466
|
+
return { memory, active, transitions, blockedNow, status: "ok", pace };
|
|
19322
19467
|
}
|
|
19323
19468
|
const seed = seedOf(s, now, cfg);
|
|
19324
19469
|
const key = fnvHex([inputsKey, seed, raised.join(","), alertPaths(cfg)].join("|"));
|
|
@@ -19360,9 +19505,10 @@ function* alertsSliced(s, now, prior, cal, cfg, fc, opts = {}) {
|
|
|
19360
19505
|
remedy: r
|
|
19361
19506
|
});
|
|
19362
19507
|
}
|
|
19363
|
-
|
|
19508
|
+
const pace = active.length === 0 ? yield* paceFor(ctx, ev, rates, inputsKey, cfg, opts) : null;
|
|
19509
|
+
return { memory, active, transitions, blockedNow, status: "ok", payload, pace };
|
|
19364
19510
|
}
|
|
19365
|
-
var HOUR_MS11 = 3600000, REMEDY_MIN_GAP_MS, CUT_GRID,
|
|
19511
|
+
var HOUR_MS11 = 3600000, REMEDY_MIN_GAP_MS, CUT_GRID, EPISODE_BUCKET_MS;
|
|
19366
19512
|
var init_alerts = __esm(() => {
|
|
19367
19513
|
init_capacity();
|
|
19368
19514
|
init_constants();
|
|
@@ -19613,6 +19759,7 @@ function contributions(s, q, cfg) {
|
|
|
19613
19759
|
const share = calibrated ? observed > 0 ? r.fraction / observed : 0 : totalCu > 0 ? r.cu / totalCu : 0;
|
|
19614
19760
|
return {
|
|
19615
19761
|
session: r.session,
|
|
19762
|
+
parent: track?.parent ?? null,
|
|
19616
19763
|
account: r.accounts.size === 1 && single ? single.account : account,
|
|
19617
19764
|
window: r.window,
|
|
19618
19765
|
usedFraction: calibrated && single ? r.fraction : null,
|
|
@@ -19631,6 +19778,7 @@ function contributions(s, q, cfg) {
|
|
|
19631
19778
|
const lasts = spent.map((x) => x.lastAt).filter((t) => t !== null);
|
|
19632
19779
|
out.push({
|
|
19633
19780
|
session: "unattributed",
|
|
19781
|
+
parent: null,
|
|
19634
19782
|
account,
|
|
19635
19783
|
window: window2,
|
|
19636
19784
|
usedFraction: calibrated && single ? unattributed : null,
|
|
@@ -19706,7 +19854,7 @@ function deliverableIn(view, unit) {
|
|
|
19706
19854
|
const beta = view.governing === null ? undefined : view.beta[view.governing];
|
|
19707
19855
|
return isStrong(beta) && beta.value > 0 ? d / beta.value : d;
|
|
19708
19856
|
}
|
|
19709
|
-
function
|
|
19857
|
+
function historyFrom(views, now) {
|
|
19710
19858
|
let from = now - WEEK_MS4;
|
|
19711
19859
|
for (const v of views) {
|
|
19712
19860
|
const g = v.windows.find((w) => w.key === v.governing);
|
|
@@ -19714,23 +19862,38 @@ function historyOf(s, views, now, unit) {
|
|
|
19714
19862
|
continue;
|
|
19715
19863
|
from = Math.min(from, g.resetAt - g.lengthMinutes * MINUTE_MS10);
|
|
19716
19864
|
}
|
|
19865
|
+
return from;
|
|
19866
|
+
}
|
|
19867
|
+
function historyAt(s, views, t, unit, byAccount) {
|
|
19868
|
+
let remaining = 0;
|
|
19869
|
+
let any = false;
|
|
19870
|
+
let inferred = false;
|
|
19871
|
+
for (const v of views) {
|
|
19872
|
+
const at = viewAt(s, v, t);
|
|
19873
|
+
if (!at)
|
|
19874
|
+
continue;
|
|
19875
|
+
any = true;
|
|
19876
|
+
inferred ||= at.inferred;
|
|
19877
|
+
const own = deliverableIn(at.view, unit);
|
|
19878
|
+
remaining += own;
|
|
19879
|
+
byAccount[v.account]?.push({ at: t, remaining: own, provenance: provenanceOf(at.inferred) });
|
|
19880
|
+
}
|
|
19881
|
+
return any ? { at: t, remaining, provenance: provenanceOf(inferred) } : null;
|
|
19882
|
+
}
|
|
19883
|
+
function historyOf(s, views, now, unit) {
|
|
19884
|
+
const from = historyFrom(views, now);
|
|
19717
19885
|
const out = [];
|
|
19886
|
+
const byAccount = {};
|
|
19887
|
+
for (const v of views)
|
|
19888
|
+
byAccount[v.account] = [];
|
|
19718
19889
|
for (let t = now;t >= from; t -= HOUR_MS14) {
|
|
19719
|
-
|
|
19720
|
-
|
|
19721
|
-
|
|
19722
|
-
for (const v of views) {
|
|
19723
|
-
const at = viewAt(s, v, t);
|
|
19724
|
-
if (!at)
|
|
19725
|
-
continue;
|
|
19726
|
-
any = true;
|
|
19727
|
-
inferred ||= at.inferred;
|
|
19728
|
-
remaining += deliverableIn(at.view, unit);
|
|
19729
|
-
}
|
|
19730
|
-
if (any)
|
|
19731
|
-
out.push({ at: t, remaining, provenance: inferred ? "reset-inferred" : "observed" });
|
|
19890
|
+
const point = historyAt(s, views, t, unit, byAccount);
|
|
19891
|
+
if (point)
|
|
19892
|
+
out.push(point);
|
|
19732
19893
|
}
|
|
19733
|
-
|
|
19894
|
+
for (const list of Object.values(byAccount))
|
|
19895
|
+
list.reverse();
|
|
19896
|
+
return { history: out.reverse(), byAccount };
|
|
19734
19897
|
}
|
|
19735
19898
|
function resetsOf(views, now, end) {
|
|
19736
19899
|
const out = [];
|
|
@@ -19779,13 +19942,115 @@ function blockedRuns(results, forecast) {
|
|
|
19779
19942
|
}
|
|
19780
19943
|
return out;
|
|
19781
19944
|
}
|
|
19945
|
+
function firstTakeovers(r, from, now, end) {
|
|
19946
|
+
const taken = new Map;
|
|
19947
|
+
let prev = from;
|
|
19948
|
+
for (const d of r.decisions) {
|
|
19949
|
+
if (d.account === null || d.cu <= 0 || d.account === prev)
|
|
19950
|
+
continue;
|
|
19951
|
+
const switched = prev !== null;
|
|
19952
|
+
prev = d.account;
|
|
19953
|
+
if (!switched)
|
|
19954
|
+
continue;
|
|
19955
|
+
const t = Math.max(now, r.start + d.k * HOUR_MS14);
|
|
19956
|
+
if (t > end)
|
|
19957
|
+
break;
|
|
19958
|
+
if (!taken.has(d.account))
|
|
19959
|
+
taken.set(d.account, t);
|
|
19960
|
+
}
|
|
19961
|
+
return taken;
|
|
19962
|
+
}
|
|
19963
|
+
function likelihoodOf(times, q, h0, hours) {
|
|
19964
|
+
const x = times.map((t) => (t - h0) / HOUR_MS14);
|
|
19965
|
+
const n = x.length;
|
|
19966
|
+
const mean = x.reduce((a, b) => a + b, 0) / Math.max(1, n);
|
|
19967
|
+
const sd = Math.sqrt(x.reduce((a, b) => a + (b - mean) ** 2, 0) / Math.max(1, n - 1));
|
|
19968
|
+
const iqr = (q.p75 - q.p25) / HOUR_MS14 / 1.34;
|
|
19969
|
+
const spread = iqr > 0 ? Math.min(sd, iqr) : 0;
|
|
19970
|
+
const bandwidth = 0.9 * spread * n ** -0.2;
|
|
19971
|
+
const p = new Array(Math.max(0, hours)).fill(0);
|
|
19972
|
+
if (bandwidth < MIN_BANDWIDTH_H) {
|
|
19973
|
+
for (const xi of x) {
|
|
19974
|
+
const i = Math.floor(xi);
|
|
19975
|
+
if (i >= 0 && i < p.length)
|
|
19976
|
+
p[i] = (p[i] ?? 0) + 1;
|
|
19977
|
+
}
|
|
19978
|
+
} else {
|
|
19979
|
+
for (let i = 0;i < p.length; i++) {
|
|
19980
|
+
let f = 0;
|
|
19981
|
+
for (const xi of x)
|
|
19982
|
+
f += Math.exp(-0.5 * ((i + 0.5 - xi) / bandwidth) ** 2);
|
|
19983
|
+
p[i] = f;
|
|
19984
|
+
}
|
|
19985
|
+
}
|
|
19986
|
+
const peak = Math.max(0, ...p);
|
|
19987
|
+
return peak > 0 ? p.map((v) => v / peak) : p;
|
|
19988
|
+
}
|
|
19989
|
+
function switchesOf2(results, views, poolActive, now, end) {
|
|
19990
|
+
const order = new Map(views.map((v, i) => [v.account, i]));
|
|
19991
|
+
const from = poolActive !== null && order.has(poolActive) ? poolActive : null;
|
|
19992
|
+
const times = new Map;
|
|
19993
|
+
for (const r of results) {
|
|
19994
|
+
for (const [account, t] of firstTakeovers(r, from, now, end)) {
|
|
19995
|
+
const list = times.get(account) ?? [];
|
|
19996
|
+
list.push(t);
|
|
19997
|
+
times.set(account, list);
|
|
19998
|
+
}
|
|
19999
|
+
}
|
|
20000
|
+
const paths = Math.max(1, results.length);
|
|
20001
|
+
const h0 = hourStart(now);
|
|
20002
|
+
const hours = Math.floor((end - h0) / HOUR_MS14) + 1;
|
|
20003
|
+
const out = [];
|
|
20004
|
+
for (const [account, list] of times) {
|
|
20005
|
+
const probability = list.length / paths;
|
|
20006
|
+
if (probability < MIN_PATH_SHARE)
|
|
20007
|
+
continue;
|
|
20008
|
+
const q = quantilesOf2(list);
|
|
20009
|
+
out.push({
|
|
20010
|
+
account,
|
|
20011
|
+
q,
|
|
20012
|
+
probability: Math.min(1, probability),
|
|
20013
|
+
likelihood: { start: h0, p: likelihoodOf(list, q, h0, hours) }
|
|
20014
|
+
});
|
|
20015
|
+
}
|
|
20016
|
+
return out.sort((a, b) => a.q.p50 - b.q.p50 || (order.get(a.account) ?? 0) - (order.get(b.account) ?? 0));
|
|
20017
|
+
}
|
|
20018
|
+
function lostAtResetOf(results, views) {
|
|
20019
|
+
const out = {};
|
|
20020
|
+
const paths = Math.max(1, results.length);
|
|
20021
|
+
for (const v of views) {
|
|
20022
|
+
const g = v.windows.find((w) => w.key === v.governing);
|
|
20023
|
+
if (!g || g.remaining === null || g.resetAt === null || g.semantics === "sliding")
|
|
20024
|
+
continue;
|
|
20025
|
+
const values = [];
|
|
20026
|
+
for (const r of results) {
|
|
20027
|
+
const left = r.leftoverAtReset[v.account];
|
|
20028
|
+
if (left !== null && left !== undefined && Number.isFinite(left)) {
|
|
20029
|
+
values.push(Math.min(1, Math.max(0, left)));
|
|
20030
|
+
}
|
|
20031
|
+
}
|
|
20032
|
+
if (values.length === 0 || values.length < MIN_PATH_SHARE * paths)
|
|
20033
|
+
continue;
|
|
20034
|
+
out[v.account] = { at: g.resetAt, q: quantilesOf2(values) };
|
|
20035
|
+
}
|
|
20036
|
+
return out;
|
|
20037
|
+
}
|
|
19782
20038
|
function trajectory(s, now, horizonMs, cal, cfg) {
|
|
19783
20039
|
const all = accountViews(s, now, cfg).filter(isRead);
|
|
19784
20040
|
const unit = strongBetas(all) ? "cu" : "account-fraction";
|
|
19785
|
-
const history = historyOf(s, all, now, unit);
|
|
20041
|
+
const { history, byAccount: historyByAccount } = historyOf(s, all, now, unit);
|
|
19786
20042
|
const end = now + Math.max(0, horizonMs);
|
|
19787
20043
|
const resets = resetsOf(all, now, end);
|
|
19788
|
-
const empty = {
|
|
20044
|
+
const empty = {
|
|
20045
|
+
unit,
|
|
20046
|
+
history,
|
|
20047
|
+
forecast: [],
|
|
20048
|
+
resets,
|
|
20049
|
+
blocked: [],
|
|
20050
|
+
switches: [],
|
|
20051
|
+
lostAtReset: {},
|
|
20052
|
+
historyByAccount
|
|
20053
|
+
};
|
|
19789
20054
|
if (evidenceOf(s, now) === "none" || all.length === 0)
|
|
19790
20055
|
return empty;
|
|
19791
20056
|
const views = unit === "cu" ? all : all.map(inFractions);
|
|
@@ -19823,7 +20088,16 @@ function trajectory(s, now, horizonMs, cal, cfg) {
|
|
|
19823
20088
|
}
|
|
19824
20089
|
forecast.push({ at, q: quantilesOf2(values), pBlocked: blocked / paths });
|
|
19825
20090
|
}
|
|
19826
|
-
return {
|
|
20091
|
+
return {
|
|
20092
|
+
unit,
|
|
20093
|
+
history,
|
|
20094
|
+
forecast,
|
|
20095
|
+
resets,
|
|
20096
|
+
blocked: blockedRuns(results, forecast),
|
|
20097
|
+
switches: switchesOf2(results, views, s.poolActive ?? null, now, end),
|
|
20098
|
+
lostAtReset: lostAtResetOf(results, views),
|
|
20099
|
+
historyByAccount
|
|
20100
|
+
};
|
|
19827
20101
|
}
|
|
19828
20102
|
function sparkline(t, cells) {
|
|
19829
20103
|
const n = Math.max(0, Math.floor(cells));
|
|
@@ -19886,7 +20160,7 @@ function sparkline(t, cells) {
|
|
|
19886
20160
|
return LEVELS[Math.max(0, level)] ?? " ";
|
|
19887
20161
|
}).join("");
|
|
19888
20162
|
}
|
|
19889
|
-
var MINUTE_MS10 = 60000, HOUR_MS14 = 3600000, WEEK_MS4, BLOCKED_SHARE = 0.5, WIDE_BAND = 0.15, LEVELS;
|
|
20163
|
+
var MINUTE_MS10 = 60000, HOUR_MS14 = 3600000, WEEK_MS4, BLOCKED_SHARE = 0.5, WIDE_BAND = 0.15, LEVELS, provenanceOf = (inferred) => inferred ? "reset-inferred" : "observed", MIN_BANDWIDTH_H = 0.5;
|
|
19890
20164
|
var init_trajectory = __esm(() => {
|
|
19891
20165
|
init_alerts();
|
|
19892
20166
|
init_calibrate();
|
|
@@ -20032,6 +20306,9 @@ function buildResponseRow(input) {
|
|
|
20032
20306
|
finalInTok: count(input.finalInput),
|
|
20033
20307
|
windows: readingsOf(input.provider, input.usage)
|
|
20034
20308
|
};
|
|
20309
|
+
const parent = input.parent;
|
|
20310
|
+
if (parent && SESSION_PATTERN.test(parent) && parent !== row.session)
|
|
20311
|
+
row.parent = parent;
|
|
20035
20312
|
return responseRowSchema.safeParse(row).success ? row : null;
|
|
20036
20313
|
}
|
|
20037
20314
|
function buildNoEligibleRow(provider, at) {
|
|
@@ -20085,7 +20362,8 @@ function toEvent(row) {
|
|
|
20085
20362
|
tokens: tokensOf(row),
|
|
20086
20363
|
finalInput: row.finalInTok,
|
|
20087
20364
|
windows: row.windows,
|
|
20088
|
-
outcome: row.outcome
|
|
20365
|
+
outcome: row.outcome,
|
|
20366
|
+
parent: row.parent ?? null
|
|
20089
20367
|
};
|
|
20090
20368
|
case "no-eligible":
|
|
20091
20369
|
return row.until === undefined ? { kind: "no-eligible", at: row.at } : {
|
|
@@ -20106,7 +20384,8 @@ function toEvent(row) {
|
|
|
20106
20384
|
tokens: { ...row.tokens },
|
|
20107
20385
|
first: row.first,
|
|
20108
20386
|
last: row.last,
|
|
20109
|
-
censoredMinutes: row.censoredMinutes
|
|
20387
|
+
censoredMinutes: row.censoredMinutes,
|
|
20388
|
+
parent: row.parent ?? null
|
|
20110
20389
|
};
|
|
20111
20390
|
}
|
|
20112
20391
|
}
|
|
@@ -20189,7 +20468,8 @@ var init_ledger_row = __esm(() => {
|
|
|
20189
20468
|
cacheWriteTok: tokenCount,
|
|
20190
20469
|
outTok: tokenCount,
|
|
20191
20470
|
finalInTok: tokenCount,
|
|
20192
|
-
windows: array(windowReadingSchema).max(16).nullable()
|
|
20471
|
+
windows: array(windowReadingSchema).max(16).nullable(),
|
|
20472
|
+
parent: string2().regex(SESSION_PATTERN).nullable().optional()
|
|
20193
20473
|
});
|
|
20194
20474
|
noEligibleRowSchema = object({
|
|
20195
20475
|
v: literal(LEDGER_ROW_VERSION),
|
|
@@ -20218,7 +20498,8 @@ var init_ledger_row = __esm(() => {
|
|
|
20218
20498
|
tokens: tokenCountsSchema,
|
|
20219
20499
|
first: array(windowReadingSchema).max(16).nullable(),
|
|
20220
20500
|
last: array(windowReadingSchema).max(16).nullable(),
|
|
20221
|
-
censoredMinutes: number2().finite().min(0).max(60)
|
|
20501
|
+
censoredMinutes: number2().finite().min(0).max(60),
|
|
20502
|
+
parent: string2().regex(SESSION_PATTERN).nullable().optional()
|
|
20222
20503
|
});
|
|
20223
20504
|
ledgerRowSchema = discriminatedUnion("kind", [
|
|
20224
20505
|
responseRowSchema,
|
|
@@ -20736,6 +21017,7 @@ function* rollupDaySteps(day, rows, openAtStart) {
|
|
|
20736
21017
|
}
|
|
20737
21018
|
}
|
|
20738
21019
|
const hh = String(new Date(hour).getUTCHours()).padStart(2, "0");
|
|
21020
|
+
const parent = group.find((r) => r.parent)?.parent ?? null;
|
|
20739
21021
|
const rollup = {
|
|
20740
21022
|
v: LEDGER_ROW_VERSION,
|
|
20741
21023
|
kind: "rollup",
|
|
@@ -20754,7 +21036,8 @@ function* rollupDaySteps(day, rows, openAtStart) {
|
|
|
20754
21036
|
},
|
|
20755
21037
|
first: first.size > 0 ? [...first.values()] : null,
|
|
20756
21038
|
last: last.size > 0 ? [...last.values()] : null,
|
|
20757
|
-
censoredMinutes: censored.get(head.provider)?.get(hour) ?? 0
|
|
21039
|
+
censoredMinutes: censored.get(head.provider)?.get(hour) ?? 0,
|
|
21040
|
+
...parent ? { parent } : {}
|
|
20758
21041
|
};
|
|
20759
21042
|
lines.push(JSON.stringify(rollup));
|
|
20760
21043
|
}
|
|
@@ -21858,6 +22141,12 @@ function readAlertsFile(env) {
|
|
|
21858
22141
|
return emptyAlertsFile();
|
|
21859
22142
|
}
|
|
21860
22143
|
}
|
|
22144
|
+
function delegatingSession(env) {
|
|
22145
|
+
const value = env[ENV.CLAUDISH_PARENT_SESSION];
|
|
22146
|
+
if (!value || !isPaneChild(env))
|
|
22147
|
+
return null;
|
|
22148
|
+
return SESSION_PATTERN.test(value) ? value : null;
|
|
22149
|
+
}
|
|
21861
22150
|
|
|
21862
22151
|
class AllowanceService {
|
|
21863
22152
|
env;
|
|
@@ -21870,9 +22159,12 @@ class AllowanceService {
|
|
|
21870
22159
|
nextFlight = 0;
|
|
21871
22160
|
threads = new Map;
|
|
21872
22161
|
models = new Map;
|
|
22162
|
+
reportStateStore = null;
|
|
22163
|
+
parentSession;
|
|
21873
22164
|
constructor(env = process.env, clock = Date.now) {
|
|
21874
22165
|
this.env = env;
|
|
21875
22166
|
this.clock = clock;
|
|
22167
|
+
this.parentSession = delegatingSession(env);
|
|
21876
22168
|
}
|
|
21877
22169
|
record(attempt) {
|
|
21878
22170
|
try {
|
|
@@ -21890,7 +22182,8 @@ class AllowanceService {
|
|
|
21890
22182
|
outcome: attempt.outcome,
|
|
21891
22183
|
tokens: attempt.tokens,
|
|
21892
22184
|
finalInput: attempt.finalInput,
|
|
21893
|
-
usage: attempt.usage
|
|
22185
|
+
usage: attempt.usage,
|
|
22186
|
+
parent: this.parentSession
|
|
21894
22187
|
});
|
|
21895
22188
|
if (!row) {
|
|
21896
22189
|
this.warnOnce("a usage row failed its guards and was not written");
|
|
@@ -22070,9 +22363,21 @@ class AllowanceService {
|
|
|
22070
22363
|
cal: m.cal,
|
|
22071
22364
|
fc: m.fc,
|
|
22072
22365
|
alerts: m.lastAlerts,
|
|
22073
|
-
labels
|
|
22366
|
+
labels,
|
|
22367
|
+
poolActive: this.activeNow(provider, s)
|
|
22074
22368
|
});
|
|
22075
22369
|
}
|
|
22370
|
+
activeNow(provider, s) {
|
|
22371
|
+
try {
|
|
22372
|
+
this.reportStateStore ??= new StateStore({ path: statePath(this.env) });
|
|
22373
|
+
const read = this.reportStateStore.read();
|
|
22374
|
+
if (read.kind === "failed")
|
|
22375
|
+
return s.poolActive ?? null;
|
|
22376
|
+
return read.state.providers[provider]?.active ?? null;
|
|
22377
|
+
} catch {
|
|
22378
|
+
return s.poolActive ?? null;
|
|
22379
|
+
}
|
|
22380
|
+
}
|
|
22076
22381
|
modelFor(provider) {
|
|
22077
22382
|
let m = this.models.get(provider);
|
|
22078
22383
|
if (!m) {
|
|
@@ -22103,7 +22408,8 @@ class AllowanceService {
|
|
|
22103
22408
|
sinks: new Set,
|
|
22104
22409
|
label: undefined,
|
|
22105
22410
|
payload: null,
|
|
22106
|
-
|
|
22411
|
+
pace: null,
|
|
22412
|
+
lastAlerts: { active: [], blockedNow: false, status: "insufficient-evidence", pace: null }
|
|
22107
22413
|
};
|
|
22108
22414
|
this.models.set(provider, m);
|
|
22109
22415
|
}
|
|
@@ -22296,14 +22602,21 @@ class AllowanceService {
|
|
|
22296
22602
|
let won = [];
|
|
22297
22603
|
let landed = null;
|
|
22298
22604
|
for (let attempt = 0;attempt < ALERTS_CAS_ATTEMPTS && landed === null; attempt++) {
|
|
22299
|
-
const result = await runSliced(alertsSliced(state, now, peek, m.cal, m.cfg, fc, {
|
|
22605
|
+
const result = await runSliced(alertsSliced(state, now, peek, m.cal, m.cfg, fc, {
|
|
22606
|
+
reuse: m.payload,
|
|
22607
|
+
pace: !announce,
|
|
22608
|
+
paceReuse: m.pace
|
|
22609
|
+
}));
|
|
22300
22610
|
if (result.payload)
|
|
22301
22611
|
m.payload = result.payload;
|
|
22612
|
+
if (result.pace)
|
|
22613
|
+
m.pace = result.pace;
|
|
22302
22614
|
if (!announce) {
|
|
22303
22615
|
m.lastAlerts = {
|
|
22304
22616
|
active: result.active,
|
|
22305
22617
|
blockedNow: result.blockedNow,
|
|
22306
|
-
status: result.status
|
|
22618
|
+
status: result.status,
|
|
22619
|
+
pace: result.pace
|
|
22307
22620
|
};
|
|
22308
22621
|
return [];
|
|
22309
22622
|
}
|
|
@@ -22354,7 +22667,12 @@ class AllowanceService {
|
|
|
22354
22667
|
log(`[allowance] ${provider}: the alert memory kept moving; step skipped`);
|
|
22355
22668
|
return [];
|
|
22356
22669
|
}
|
|
22357
|
-
m.lastAlerts = {
|
|
22670
|
+
m.lastAlerts = {
|
|
22671
|
+
active: landed.active,
|
|
22672
|
+
blockedNow: landed.blockedNow,
|
|
22673
|
+
status: landed.status,
|
|
22674
|
+
pace: null
|
|
22675
|
+
};
|
|
22358
22676
|
const active = landed.active;
|
|
22359
22677
|
const status = landed.status;
|
|
22360
22678
|
const accounts = accountViews(m.state, now, m.cfg).length;
|
|
@@ -22490,19 +22808,37 @@ function poolRemaining(views) {
|
|
|
22490
22808
|
}
|
|
22491
22809
|
return { remainingNow: now.value, capacity, unit: now.unit };
|
|
22492
22810
|
}
|
|
22811
|
+
function likelihoodView(l) {
|
|
22812
|
+
const p = l.p.map((v) => Math.round(Math.min(1, Math.max(0, v)) * 1000) / 1000);
|
|
22813
|
+
const first = p.findIndex((v) => v > 0);
|
|
22814
|
+
if (first < 0)
|
|
22815
|
+
return;
|
|
22816
|
+
let last = p.length - 1;
|
|
22817
|
+
while (last > first && p[last] === 0)
|
|
22818
|
+
last--;
|
|
22819
|
+
return { start: iso2(l.start + first * HOUR_MS16), stepHours: 1, p: p.slice(first, last + 1) };
|
|
22820
|
+
}
|
|
22821
|
+
function sustainableOf(top, pace, burnLong) {
|
|
22822
|
+
const long = Number.isFinite(burnLong) ? Math.max(0, burnLong) : 0;
|
|
22823
|
+
if (top)
|
|
22824
|
+
return top.remedy.kind === "cut" ? top.remedy.cutToFraction * long : 0;
|
|
22825
|
+
return pace ? paceInCuPerHour(pace, long) : null;
|
|
22826
|
+
}
|
|
22493
22827
|
function buildReport(input) {
|
|
22494
22828
|
const { s, now, cfg, cal, fc } = input;
|
|
22495
22829
|
const horizonMs = Math.min(168 * HOUR_MS16, Math.max(HOUR_MS16, input.horizonMs));
|
|
22496
22830
|
const evidence = evidenceOf(s, now);
|
|
22497
22831
|
const none = evidence === "none";
|
|
22498
22832
|
const views = accountViews(s, now, cfg);
|
|
22499
|
-
const
|
|
22833
|
+
const poolActive = input.poolActive !== undefined ? input.poolActive : s.poolActive ?? null;
|
|
22834
|
+
const traj = trajectory({ ...s, poolActive }, now, horizonMs, cal, cfg);
|
|
22500
22835
|
const unit = fc?.unit ?? traj.unit;
|
|
22501
22836
|
const burn = none ? { long: 0, short: 0 } : burnRates(s, now, cal, cfg);
|
|
22502
22837
|
const ledgerHours = ledgerDays(s, now) * 24;
|
|
22503
22838
|
const label = (id) => input.labels.get(id) ?? id;
|
|
22504
22839
|
const pool = poolRemaining(views);
|
|
22505
22840
|
const top = input.alerts.active[0];
|
|
22841
|
+
const status = none ? "insufficient-evidence" : input.alerts.status;
|
|
22506
22842
|
const fmt = (at) => formatLocalTime(at);
|
|
22507
22843
|
const report = {
|
|
22508
22844
|
schema: ALLOWANCE_REPORT_SCHEMA,
|
|
@@ -22518,6 +22854,7 @@ function buildReport(input) {
|
|
|
22518
22854
|
accounts: views.map((v) => {
|
|
22519
22855
|
const g = v.governing === null ? undefined : v.beta[v.governing];
|
|
22520
22856
|
const k = v.binding === null || v.binding === v.governing ? undefined : v.kappa[v.binding];
|
|
22857
|
+
const lost = traj.lostAtReset[v.account];
|
|
22521
22858
|
return {
|
|
22522
22859
|
label: label(v.account),
|
|
22523
22860
|
id: v.account,
|
|
@@ -22533,7 +22870,15 @@ function buildReport(input) {
|
|
|
22533
22870
|
semantics: w.semantics
|
|
22534
22871
|
})),
|
|
22535
22872
|
lambda: null,
|
|
22536
|
-
calibration: { beta: g?.quality ?? "prior", kappa: k?.quality ?? null }
|
|
22873
|
+
calibration: { beta: g?.quality ?? "prior", kappa: k?.quality ?? null },
|
|
22874
|
+
active: poolActive !== null && v.account === poolActive,
|
|
22875
|
+
order: v.order,
|
|
22876
|
+
lostAtReset: lost ? {
|
|
22877
|
+
at: iso2(lost.at),
|
|
22878
|
+
p10: Math.min(1, Math.max(0, lost.q.p10)),
|
|
22879
|
+
p50: Math.min(1, Math.max(0, lost.q.p50)),
|
|
22880
|
+
p90: Math.min(1, Math.max(0, lost.q.p90))
|
|
22881
|
+
} : null
|
|
22537
22882
|
};
|
|
22538
22883
|
}),
|
|
22539
22884
|
combined: {
|
|
@@ -22543,7 +22888,7 @@ function buildReport(input) {
|
|
|
22543
22888
|
burn: {
|
|
22544
22889
|
long: ledgerHours < cfg.BURN_LONG_HL_H ? null : burn.long,
|
|
22545
22890
|
short: ledgerHours < cfg.BURN_SHORT_HL_H ? null : burn.short,
|
|
22546
|
-
sustainable:
|
|
22891
|
+
sustainable: status === "ok" ? sustainableOf(top, input.alerts.pace ?? null, burn.long) : null,
|
|
22547
22892
|
unit: "cu/h"
|
|
22548
22893
|
},
|
|
22549
22894
|
alerts: none ? [] : input.alerts.active.map((a) => {
|
|
@@ -22579,7 +22924,7 @@ function buildReport(input) {
|
|
|
22579
22924
|
};
|
|
22580
22925
|
}),
|
|
22581
22926
|
blockedNow: none ? false : input.alerts.blockedNow,
|
|
22582
|
-
status
|
|
22927
|
+
status,
|
|
22583
22928
|
trajectory: {
|
|
22584
22929
|
history: traj.history.map((h) => ({
|
|
22585
22930
|
at: iso2(h.at),
|
|
@@ -22605,6 +22950,18 @@ function buildReport(input) {
|
|
|
22605
22950
|
kind: b.kind,
|
|
22606
22951
|
probability: b.probability
|
|
22607
22952
|
})),
|
|
22953
|
+
historyByAccount: none ? [] : views.filter((v) => traj.historyByAccount[v.account] !== undefined).map((v) => ({
|
|
22954
|
+
accountId: v.account,
|
|
22955
|
+
history: (traj.historyByAccount[v.account] ?? []).filter((h) => h.at >= now - 24 * HOUR_MS16).map((h) => ({ at: iso2(h.at), remaining: h.remaining, provenance: h.provenance }))
|
|
22956
|
+
})),
|
|
22957
|
+
switches: traj.switches.map((sw) => ({
|
|
22958
|
+
accountId: sw.account,
|
|
22959
|
+
soonest: iso2(sw.q.p10),
|
|
22960
|
+
usual: iso2(sw.q.p50),
|
|
22961
|
+
latest: iso2(sw.q.p90),
|
|
22962
|
+
probability: Math.min(1, Math.max(0, sw.probability)),
|
|
22963
|
+
likelihood: likelihoodView(sw.likelihood)
|
|
22964
|
+
})),
|
|
22608
22965
|
spark48: sparkline({
|
|
22609
22966
|
...traj,
|
|
22610
22967
|
history: traj.history.filter((h) => h.at >= now - 24 * HOUR_MS16),
|
|
@@ -22613,6 +22970,7 @@ function buildReport(input) {
|
|
|
22613
22970
|
},
|
|
22614
22971
|
sessions: none ? [] : contributions(s, { now, window: "binding" }, cfg).map((c) => ({
|
|
22615
22972
|
session: c.session === "unattributed" ? "unattributed" : c.session.slice(0, 8),
|
|
22973
|
+
parent: c.parent === null ? null : c.parent.slice(0, 8),
|
|
22616
22974
|
account: c.account === "all" ? "all" : label(c.account),
|
|
22617
22975
|
window: c.window,
|
|
22618
22976
|
share: Math.min(1, Math.max(0, c.share)),
|
|
@@ -22682,7 +23040,9 @@ function getAllowanceService() {
|
|
|
22682
23040
|
}
|
|
22683
23041
|
var THREAD_MAP_MAX = 512, THREAD_IDLE_MS, HOUR_MS16 = 3600000, DAY_MS6, LOAD_HISTORY_MS, LOAD_RAW_MS, LOAD_DEFER_MS = 1000, REFRESH_MIN_MS = 60000, SERVED_RECENTLY_MS, ALERTS_LOCK_WAIT_MS = 200, ALERTS_LOCK_STALE_MS = 1e4, ALERTS_CAS_ATTEMPTS = 3, IN_FLIGHT_MAX_MS, PENDING_MAX = 4096, LOAD_RETRY_MIN_MS = 60000, LOAD_RETRY_MAX_MS, ANNOUNCED_MAX = 256, CALENDAR_FUTURE_MS, DECLINE = () => null, iso2 = (at) => new Date(at).toISOString(), instance, safeRankerWarned = false;
|
|
22684
23042
|
var init_allowance_service = __esm(() => {
|
|
23043
|
+
init_config();
|
|
22685
23044
|
init_logger();
|
|
23045
|
+
init_child_env();
|
|
22686
23046
|
init_allowance_report_schema();
|
|
22687
23047
|
init_alerts();
|
|
22688
23048
|
init_capacity();
|
|
@@ -90904,6 +91264,7 @@ function buildPaneEnv(input) {
|
|
|
90904
91264
|
env.CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC = "1";
|
|
90905
91265
|
if (input.parentEnv.CLAUDE_CODE_NATIVE_CURSOR === undefined)
|
|
90906
91266
|
env.CLAUDE_CODE_NATIVE_CURSOR = "1";
|
|
91267
|
+
delete env[ENV.CLAUDISH_PARENT_SESSION];
|
|
90907
91268
|
Object.assign(env, input.slotEnv);
|
|
90908
91269
|
if (input.configFile !== null)
|
|
90909
91270
|
env.CLAUDISH_CONFIG = input.configFile;
|
|
@@ -97980,7 +98341,8 @@ async function startModelsIn(flight, sessionPath, opts) {
|
|
|
97980
98341
|
kind: "team",
|
|
97981
98342
|
id: `${runId}:${e.id}`,
|
|
97982
98343
|
role: kind === "judge" ? "judge" : "slot"
|
|
97983
|
-
})
|
|
98344
|
+
}),
|
|
98345
|
+
...opts.parentClaudeSessionId ? { [ENV.CLAUDISH_PARENT_SESSION]: opts.parentClaudeSessionId } : {}
|
|
97984
98346
|
},
|
|
97985
98347
|
shape: "one-shot",
|
|
97986
98348
|
initialPrompt: inputContent,
|
|
@@ -98207,6 +98569,7 @@ async function judgeResponses(sessionPath, opts = {}) {
|
|
|
98207
98569
|
await runModels(judgePath, {
|
|
98208
98570
|
claudeFlags: opts.claudeFlags,
|
|
98209
98571
|
kind: "judge",
|
|
98572
|
+
...opts.parentClaudeSessionId ? { parentClaudeSessionId: opts.parentClaudeSessionId } : {},
|
|
98210
98573
|
...opts.parentEnv ? { parentEnv: opts.parentEnv } : {},
|
|
98211
98574
|
...opts.paneTimings ? { paneTimings: opts.paneTimings } : {}
|
|
98212
98575
|
});
|
|
@@ -99026,7 +99389,8 @@ class SessionManager {
|
|
|
99026
99389
|
[ENV.CLAUDISH_TOKEN_FILE]: entry.tokenFile,
|
|
99027
99390
|
[UPSTREAM_ERROR_LOG_ENV]: entry.upstreamErrorLogPath,
|
|
99028
99391
|
...entry.inboxPath ? { [HOOK_INBOX_ENV]: entry.inboxPath } : {},
|
|
99029
|
-
[HOOK_SESSION_ENV]: JSON.stringify({ kind: "channel", id: info.sessionId, role: null })
|
|
99392
|
+
[HOOK_SESSION_ENV]: JSON.stringify({ kind: "channel", id: info.sessionId, role: null }),
|
|
99393
|
+
...info.parentClaudeSessionId ? { [ENV.CLAUDISH_PARENT_SESSION]: info.parentClaudeSessionId } : {}
|
|
99030
99394
|
},
|
|
99031
99395
|
shape: info.shape,
|
|
99032
99396
|
...opts.prompt ? { initialPrompt: opts.prompt } : {},
|
|
@@ -100854,9 +101218,32 @@ async function allowanceStatus(horizonMs) {
|
|
|
100854
101218
|
return { ...meta, allowance: null, reason: `the allowance report failed: ${message}` };
|
|
100855
101219
|
}
|
|
100856
101220
|
}
|
|
101221
|
+
function allowanceSectionsArg(value) {
|
|
101222
|
+
if (value === undefined)
|
|
101223
|
+
return;
|
|
101224
|
+
const known = ALLOWANCE_REPORT_SECTIONS;
|
|
101225
|
+
if (!Array.isArray(value) || value.length === 0)
|
|
101226
|
+
throw new ContractErrorException("invalid_args", `'sections' must be a non-empty array of ${known.join(", ")}`);
|
|
101227
|
+
for (const name of value) {
|
|
101228
|
+
if (typeof name !== "string" || !known.includes(name))
|
|
101229
|
+
throw new ContractErrorException("invalid_args", `'sections' has an unknown section ${JSON.stringify(name)}; known: ${known.join(", ")}`);
|
|
101230
|
+
}
|
|
101231
|
+
return [...new Set(value)].sort();
|
|
101232
|
+
}
|
|
101233
|
+
function allowanceSections(answer, sections) {
|
|
101234
|
+
if (sections === undefined || answer.allowance === null)
|
|
101235
|
+
return answer;
|
|
101236
|
+
const dropped = new Set(ALLOWANCE_REPORT_SECTIONS.filter((section) => !sections.includes(section)));
|
|
101237
|
+
const allowance = Object.fromEntries(Object.entries(answer.allowance).filter(([key]) => !dropped.has(key)));
|
|
101238
|
+
const { contract_version, capabilities, ...rest } = answer;
|
|
101239
|
+
return { contract_version, capabilities, sections, ...rest, allowance };
|
|
101240
|
+
}
|
|
100857
101241
|
function contractAnswer(value) {
|
|
100858
101242
|
return { content: [{ type: "text", text: JSON.stringify(value, null, 2) }] };
|
|
100859
101243
|
}
|
|
101244
|
+
function compactAnswer(value) {
|
|
101245
|
+
return { content: [{ type: "text", text: JSON.stringify(value) }] };
|
|
101246
|
+
}
|
|
100860
101247
|
function contractErrorAnswer(e) {
|
|
100861
101248
|
const err = e instanceof ContractErrorException ? e : new ContractErrorException("invalid_args", e instanceof Error ? e.message : String(e));
|
|
100862
101249
|
return {
|
|
@@ -101443,11 +101830,15 @@ This searched OpenRouter's listing only. Subscription wire ids and catalog alias
|
|
|
101443
101830
|
models?.[givenModels?.indexOf(m) ?? -1] ?? m,
|
|
101444
101831
|
level
|
|
101445
101832
|
])) : undefined;
|
|
101833
|
+
const runsModels = mode === "run" || mode === "run-and-judge";
|
|
101834
|
+
const runsJudges = mode === "judge" || mode === "run-and-judge";
|
|
101835
|
+
const parentClaudeSessionId = runsModels || runsJudges ? await parentSessionForCall({ hostPid: sessionManager.hostPid }) : undefined;
|
|
101446
101836
|
const runOpts = {
|
|
101447
101837
|
requirePattern,
|
|
101448
101838
|
minOutputBytes,
|
|
101449
101839
|
claudeFlags: childFlags,
|
|
101450
101840
|
efforts,
|
|
101841
|
+
parentClaudeSessionId,
|
|
101451
101842
|
onProgress: (u) => {
|
|
101452
101843
|
ctx.reportProgress(`team: ${u.phase}`);
|
|
101453
101844
|
}
|
|
@@ -101458,8 +101849,6 @@ This searched OpenRouter's listing only. Subscription wire ids and catalog alias
|
|
|
101458
101849
|
const existing = join56(resolved, "input.md");
|
|
101459
101850
|
return existsSync39(existing) ? readFileSync45(existing, "utf-8") : undefined;
|
|
101460
101851
|
};
|
|
101461
|
-
const runsModels = mode === "run" || mode === "run-and-judge";
|
|
101462
|
-
const runsJudges = mode === "judge" || mode === "run-and-judge";
|
|
101463
101852
|
const choice = modelChoiceStop([
|
|
101464
101853
|
...runsModels && givenModels && models ? givenModels.map((given, i) => ({ given, spec: models[i] })) : [],
|
|
101465
101854
|
...runsJudges && givenJudges && judges ? givenJudges.map((given, i) => ({ given, spec: judges[i] })) : []
|
|
@@ -101484,9 +101873,6 @@ This searched OpenRouter's listing only. Subscription wire ids and catalog alias
|
|
|
101484
101873
|
requirePattern
|
|
101485
101874
|
});
|
|
101486
101875
|
setupSession(resolved, models, input);
|
|
101487
|
-
const parentClaudeSessionId = await parentSessionForCall({
|
|
101488
|
-
hostPid: sessionManager.hostPid
|
|
101489
|
-
});
|
|
101490
101876
|
const monitorRecord = sessionManager.recordTeamRun({
|
|
101491
101877
|
teamPath: resolved,
|
|
101492
101878
|
slots: models.length,
|
|
@@ -101539,7 +101925,11 @@ This searched OpenRouter's listing only. Subscription wire ids and catalog alias
|
|
|
101539
101925
|
};
|
|
101540
101926
|
}
|
|
101541
101927
|
case "judge": {
|
|
101542
|
-
const verdict = await judgeResponses(resolved, {
|
|
101928
|
+
const verdict = await judgeResponses(resolved, {
|
|
101929
|
+
judges,
|
|
101930
|
+
claudeFlags: childFlags,
|
|
101931
|
+
parentClaudeSessionId
|
|
101932
|
+
});
|
|
101543
101933
|
const out = providerNote ? { ...verdict, provider_note: providerNote } : verdict;
|
|
101544
101934
|
return { content: [{ type: "text", text: JSON.stringify(out, null, 2) }] };
|
|
101545
101935
|
}
|
|
@@ -101557,7 +101947,11 @@ This searched OpenRouter's listing only. Subscription wire ids and catalog alias
|
|
|
101557
101947
|
const handle = await startModels(resolved, runOpts);
|
|
101558
101948
|
await handle.done;
|
|
101559
101949
|
const run = teamRunRow(resolved, handle.runId);
|
|
101560
|
-
const verdict = await judgeResponses(resolved, {
|
|
101950
|
+
const verdict = await judgeResponses(resolved, {
|
|
101951
|
+
judges,
|
|
101952
|
+
claudeFlags: childFlags,
|
|
101953
|
+
parentClaudeSessionId
|
|
101954
|
+
});
|
|
101561
101955
|
return {
|
|
101562
101956
|
content: [
|
|
101563
101957
|
{
|
|
@@ -101743,7 +102137,7 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
|
|
|
101743
102137
|
});
|
|
101744
102138
|
tools.push({
|
|
101745
102139
|
name: "allowance_status",
|
|
101746
|
-
description:
|
|
102140
|
+
description: 'Report the local Codex account pool\'s allowance: {contract_version, capabilities, allowance, reason?}. `allowance` is the claudish.allowance.v1 report of THIS machine\'s claudish sessions (accounts, remaining capacity, burn rate, projected gaps with remedies, trajectory, per-session shares), or null with a `reason` when there is no account pool. `sections` limits the report to those parts (accounts, combined, burn, alerts, trajectory, sessions) beside its header, and the answer then lists them in `sections`; a frequent poll should pass ["accounts","burn","alerts"]. Read-only; it sends nothing to any vendor.',
|
|
101747
102141
|
inputSchema: {
|
|
101748
102142
|
type: "object",
|
|
101749
102143
|
properties: {
|
|
@@ -101755,6 +102149,15 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
|
|
|
101755
102149
|
horizon_hours: {
|
|
101756
102150
|
type: "number",
|
|
101757
102151
|
description: "Forecast horizon in hours, 1\u2013168 (default: 168)"
|
|
102152
|
+
},
|
|
102153
|
+
sections: {
|
|
102154
|
+
type: "array",
|
|
102155
|
+
items: {
|
|
102156
|
+
type: "string",
|
|
102157
|
+
enum: [...ALLOWANCE_REPORT_SECTIONS]
|
|
102158
|
+
},
|
|
102159
|
+
minItems: 1,
|
|
102160
|
+
description: 'Report only these parts beside the header (default: all). Poll with ["accounts","burn","alerts"]; the trajectory and sessions are most of the bytes.'
|
|
101758
102161
|
}
|
|
101759
102162
|
}
|
|
101760
102163
|
},
|
|
@@ -101767,7 +102170,8 @@ Report manually at https://github.com/anthropics/claudish/issues${autoSendHint}`
|
|
|
101767
102170
|
const hours = args.horizon_hours ?? 168;
|
|
101768
102171
|
if (typeof hours !== "number" || !Number.isFinite(hours) || hours < 1 || hours > 168)
|
|
101769
102172
|
throw new ContractErrorException("invalid_args", "'horizon_hours' must be a number from 1 to 168");
|
|
101770
|
-
|
|
102173
|
+
const sections = allowanceSectionsArg(args.sections);
|
|
102174
|
+
return compactAnswer(allowanceSections(await allowanceStatus(hours * 3600000), sections));
|
|
101771
102175
|
} catch (e) {
|
|
101772
102176
|
return contractErrorAnswer(e);
|
|
101773
102177
|
}
|
|
@@ -102241,6 +102645,7 @@ var init_mcp_server = __esm(() => {
|
|
|
102241
102645
|
init_types3();
|
|
102242
102646
|
init_base_api_format();
|
|
102243
102647
|
init_model_catalog();
|
|
102648
|
+
init_allowance_report_schema();
|
|
102244
102649
|
init_prehydrate();
|
|
102245
102650
|
init_prompt_role();
|
|
102246
102651
|
init_fs_atomic();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claudish",
|
|
3
|
-
"version": "14.
|
|
3
|
+
"version": "14.8.0",
|
|
4
4
|
"description": "Run Claude Code with any model - OpenRouter, Ollama, LM Studio & local models",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -71,10 +71,10 @@
|
|
|
71
71
|
"ai"
|
|
72
72
|
],
|
|
73
73
|
"optionalDependencies": {
|
|
74
|
-
"@claudish/magmux-darwin-arm64": "14.
|
|
75
|
-
"@claudish/magmux-darwin-x64": "14.
|
|
76
|
-
"@claudish/magmux-linux-arm64": "14.
|
|
77
|
-
"@claudish/magmux-linux-x64": "14.
|
|
74
|
+
"@claudish/magmux-darwin-arm64": "14.8.0",
|
|
75
|
+
"@claudish/magmux-darwin-x64": "14.8.0",
|
|
76
|
+
"@claudish/magmux-linux-arm64": "14.8.0",
|
|
77
|
+
"@claudish/magmux-linux-x64": "14.8.0"
|
|
78
78
|
},
|
|
79
79
|
"author": "Jack Rudenko <i@madappgang.com>",
|
|
80
80
|
"license": "MIT",
|