@coreplane/switchboard 1.267.3 → 1.268.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/assets/deploy/cloudflare-memory/worker.ts +23 -1
- package/dist/assets/deploy/cloudflare-resident/imageReconcileState.ts +28 -0
- package/dist/assets/deploy/cloudflare-resident/shared.ts +2 -3
- package/dist/assets/deploy/cloudflare-resident/worker.ts +162 -27
- package/dist/assets/package-lock.json +3 -3
- package/dist/assets/package.json +1 -1
- package/dist/assets/source.json +3 -3
- package/dist/assets/src/core/budgets.ts +4 -0
- package/dist/assets/src/core/coordinator/contract.ts +14 -8
- package/dist/assets/src/core/costs.ts +2 -0
- package/dist/assets/src/core/runEvents.ts +1 -0
- package/dist/assets/src/core/runLedger/types.ts +2 -0
- package/dist/assets/src/core/runRecord.ts +10 -0
- package/dist/assets/src/core/runUsage.ts +53 -0
- package/dist/assets/src/core/shipSpend.ts +52 -0
- package/dist/assets/src/execution/residentPoolSpends.ts +9 -0
- package/dist/assets/src/execution/residentRecreateAdmission.ts +28 -0
- package/dist/assets/web/dist/.vite/manifest.json +31 -31
- package/dist/assets/web/dist/assets/CostsPage-6P9rJ7k_.js +1 -0
- package/dist/assets/web/dist/assets/{HomePage-BQmun9kS.js → HomePage-B4LGwXHO.js} +1 -1
- package/dist/assets/web/dist/assets/ResidentDetailPage-jpGfsR5n.js +1 -0
- package/dist/assets/web/dist/assets/ResidentsIndexPage-C4-5nG9M.js +1 -0
- package/dist/assets/web/dist/assets/{RunFoldRow-C1w-mwch.js → RunFoldRow-u4FTh57c.js} +1 -1
- package/dist/assets/web/dist/assets/{RunRoutePage-zWMHTzla.js → RunRoutePage-CxOKb7oC.js} +4 -4
- package/dist/assets/web/dist/assets/{RunsIndexPage-DF16D2Gg.js → RunsIndexPage-CULSlv_d.js} +1 -1
- package/dist/assets/web/dist/assets/{ScheduledPage-CyRs0fXN.js → ScheduledPage-CDjkZuqM.js} +1 -1
- package/dist/assets/web/dist/assets/{SettingsPage-BRuMCHSj.js → SettingsPage-BMSomotV.js} +1 -1
- package/dist/assets/web/dist/assets/{StatusDot-BIAQN7iD.js → StatusDot-XxLkmRaK.js} +1 -1
- package/dist/assets/web/dist/assets/{Tooltip-CxiQ7luL.js → Tooltip-qB73RL4b.js} +1 -1
- package/dist/assets/web/dist/assets/{UnitRoutePage-BQB5mAAl.js → UnitRoutePage-DFRWAdOT.js} +1 -1
- package/dist/assets/web/dist/assets/{dist-I2OEmPqz.js → dist-BsLBAkQJ.js} +1 -1
- package/dist/assets/web/dist/assets/{main-DYwKyLY5.js → main-9ynpo780.js} +10 -10
- package/dist/assets/web/dist/assets/main-DSiJ9sHU.css +1 -0
- package/dist/cli.js +385 -226
- package/package.json +1 -1
- package/dist/assets/web/dist/assets/CostsPage-RRggVvIx.js +0 -1
- package/dist/assets/web/dist/assets/ResidentDetailPage-CT6v9INM.js +0 -1
- package/dist/assets/web/dist/assets/ResidentsIndexPage-CWqPFf40.js +0 -1
- package/dist/assets/web/dist/assets/main-DPB0UO1-.css +0 -1
package/dist/cli.js
CHANGED
|
@@ -653,7 +653,7 @@ function fit(pipeline) {
|
|
|
653
653
|
const need = ALLOWANCES.provision + ASKS.coding + reserveMinutes({ kind: "coding", index: 0 }, pipeline);
|
|
654
654
|
return { ok: pipeline.maxMinutes >= need, need, have: pipeline.maxMinutes };
|
|
655
655
|
}
|
|
656
|
-
var SECOND_MS, secondsToMs, MINUTE_MS, minutesToMs, DAY_MS, WEEK_MS, CONFIRMATION_TTL_MS, QUESTION_TTL_MS, AUTHOR_BINDING_TTL_MS, GIT_RECEIVE_PACK_FORWARD_TIMEOUT_MS, GIT_PUBLICATION_SETTLE_TIMEOUT_MS, FIRST_ATTACH_WAIT_MS, ATTACH_REQUEST_MIN_MS, HARNESS_PROBE_WAIT_MS, DRAIN, INTAKE_WINDOW_MAX_MS, INTAKE_RECOVERY_WINDOW_MS, INTAKE_DELIVERY_CLAIM_MS, LOOP_PRESETS, ASKS, PRESET_FLOORS, FLOORS, PULL_SWEEP, PROVIDER_RETRY_BACKOFFS_MS, MODEL_STREAM_HEARTBEAT_MS, HOSTED_DEADLINE_MARGIN_MINUTES, SHIP_WAIT, SHIP_RECORD_VISIBILITY, RESTART_CLAIM_GRACE_MS, PLANE, PACE_WINDOW_MINUTES, ALLOWANCES, POST_STEP_MINUTES, WRAP_UP_WARNING, SANDBOX_CREDENTIAL_WRITE_TIMEOUT_MS, BASH_COMMAND, RUNAWAY_TURNS_PER_MINUTE, DEFAULT_GRANT, GRANT_RENEWALS_MAX, STRUCTURED_RETRIES_MAX, IDLE_DAYS_DEFAULT, IDLE_DAYS_MAX, IDLE_WAKES_MAX;
|
|
656
|
+
var SECOND_MS, secondsToMs, MINUTE_MS, minutesToMs, DAY_MS, WEEK_MS, CONFIRMATION_TTL_MS, QUESTION_TTL_MS, AUTHOR_BINDING_TTL_MS, GIT_RECEIVE_PACK_FORWARD_TIMEOUT_MS, GIT_PUBLICATION_SETTLE_TIMEOUT_MS, FIRST_ATTACH_WAIT_MS, ATTACH_REQUEST_MIN_MS, HARNESS_PROBE_WAIT_MS, DRAIN, INTAKE_WINDOW_MAX_MS, INTAKE_RECOVERY_WINDOW_MS, INTAKE_DELIVERY_CLAIM_MS, LOOP_PRESETS, ASKS, PRESET_FLOORS, FLOORS, PULL_SWEEP, PROVIDER_RETRY_BACKOFFS_MS, MODEL_STREAM_HEARTBEAT_MS, RESIDENT_LISTING_POLL_MS, HOSTED_DEADLINE_MARGIN_MINUTES, SHIP_WAIT, SHIP_RECORD_VISIBILITY, RESTART_CLAIM_GRACE_MS, PLANE, PACE_WINDOW_MINUTES, ALLOWANCES, POST_STEP_MINUTES, WRAP_UP_WARNING, SANDBOX_CREDENTIAL_WRITE_TIMEOUT_MS, BASH_COMMAND, RUNAWAY_TURNS_PER_MINUTE, DEFAULT_GRANT, GRANT_RENEWALS_MAX, STRUCTURED_RETRIES_MAX, IDLE_DAYS_DEFAULT, IDLE_DAYS_MAX, IDLE_WAKES_MAX;
|
|
657
657
|
var init_budgets = __esm({
|
|
658
658
|
"../../src/core/budgets.ts"() {
|
|
659
659
|
"use strict";
|
|
@@ -732,6 +732,7 @@ var init_budgets = __esm({
|
|
|
732
732
|
PULL_SWEEP = { leaseMinutes: 15, spendCapUsd: 5 };
|
|
733
733
|
PROVIDER_RETRY_BACKOFFS_MS = [5e3, 15e3, 45e3];
|
|
734
734
|
MODEL_STREAM_HEARTBEAT_MS = 15e3;
|
|
735
|
+
RESIDENT_LISTING_POLL_MS = 3e4;
|
|
735
736
|
HOSTED_DEADLINE_MARGIN_MINUTES = 60;
|
|
736
737
|
SHIP_WAIT = { marginMinutes: 5, chunkMinutes: 5, mergeChunkMinutes: 5, busyRetryMinutes: 2 };
|
|
737
738
|
SHIP_RECORD_VISIBILITY = { retries: 3, retryMs: secondsToMs(1) };
|
|
@@ -5388,197 +5389,6 @@ var init_modelPricing = __esm({
|
|
|
5388
5389
|
}
|
|
5389
5390
|
});
|
|
5390
5391
|
|
|
5391
|
-
// ../../src/core/runUsage.ts
|
|
5392
|
-
function usageOfEvents(events) {
|
|
5393
|
-
const usage = emptyUsage();
|
|
5394
|
-
const priced = /* @__PURE__ */ new Map();
|
|
5395
|
-
for (const e of events) {
|
|
5396
|
-
if (e.type !== "span_end" || e.name !== MODEL_TURN) continue;
|
|
5397
|
-
const attrs = e.attrs ?? {};
|
|
5398
|
-
const model = typeof attrs.model === "string" && attrs.model ? attrs.model : UNKNOWN_MODEL;
|
|
5399
|
-
const m = usage.byModel[model] ?? {
|
|
5400
|
-
turns: 0,
|
|
5401
|
-
inputTokens: 0,
|
|
5402
|
-
outputTokens: 0,
|
|
5403
|
-
cacheReadTokens: 0,
|
|
5404
|
-
cacheWriteTokens: 0
|
|
5405
|
-
};
|
|
5406
|
-
const counted2 = num(attrs.inputTokens) + num(attrs.outputTokens) + num(attrs.cacheReadTokens) + num(attrs.cacheWriteTokens);
|
|
5407
|
-
m.turns += 1;
|
|
5408
|
-
m.inputTokens += num(attrs.inputTokens);
|
|
5409
|
-
m.outputTokens += num(attrs.outputTokens);
|
|
5410
|
-
m.cacheReadTokens += num(attrs.cacheReadTokens);
|
|
5411
|
-
m.cacheWriteTokens += num(attrs.cacheWriteTokens);
|
|
5412
|
-
usage.byModel[model] = m;
|
|
5413
|
-
usage.turns += 1;
|
|
5414
|
-
const hasUsd = typeof attrs.usd === "number" && Number.isFinite(attrs.usd);
|
|
5415
|
-
const hasSource = typeof attrs.priceSource === "string" && attrs.priceSource !== "";
|
|
5416
|
-
const p = priced.get(model) ?? {
|
|
5417
|
-
usd: 0,
|
|
5418
|
-
feeUsd: 0,
|
|
5419
|
-
feeTurns: 0,
|
|
5420
|
-
pricedTurns: 0,
|
|
5421
|
-
unpricedTokenTurns: 0,
|
|
5422
|
-
sources: /* @__PURE__ */ new Set()
|
|
5423
|
-
};
|
|
5424
|
-
if (counted2 > 0 && !hasUsd) p.unpricedTokenTurns += 1;
|
|
5425
|
-
if (hasUsd) {
|
|
5426
|
-
p.usd += attrs.usd;
|
|
5427
|
-
p.pricedTurns += 1;
|
|
5428
|
-
}
|
|
5429
|
-
if (typeof attrs.feeUsd === "number" && Number.isFinite(attrs.feeUsd)) {
|
|
5430
|
-
p.feeUsd += attrs.feeUsd;
|
|
5431
|
-
p.feeTurns += 1;
|
|
5432
|
-
}
|
|
5433
|
-
if (hasSource) p.sources.add(attrs.priceSource);
|
|
5434
|
-
priced.set(model, p);
|
|
5435
|
-
}
|
|
5436
|
-
for (const [model, p] of priced) {
|
|
5437
|
-
if (p.pricedTurns === 0 && p.sources.size === 0) continue;
|
|
5438
|
-
const m = usage.byModel[model];
|
|
5439
|
-
m.usd = p.unpricedTokenTurns > 0 ? null : p.usd;
|
|
5440
|
-
if (p.feeTurns > 0) m.feeUsd = p.feeUsd;
|
|
5441
|
-
if (p.sources.size > 0) m.priceSources = [...p.sources].sort();
|
|
5442
|
-
}
|
|
5443
|
-
return usage;
|
|
5444
|
-
}
|
|
5445
|
-
function addUsage(a, b) {
|
|
5446
|
-
const out = { turns: a.turns + b.turns, byModel: {} };
|
|
5447
|
-
for (const src of [a.byModel, b.byModel]) {
|
|
5448
|
-
for (const [model, m] of Object.entries(src)) {
|
|
5449
|
-
const acc = out.byModel[model];
|
|
5450
|
-
if (!acc) {
|
|
5451
|
-
out.byModel[model] = { ...m, ...m.priceSources ? { priceSources: [...m.priceSources] } : {} };
|
|
5452
|
-
continue;
|
|
5453
|
-
}
|
|
5454
|
-
acc.turns += m.turns;
|
|
5455
|
-
acc.inputTokens += m.inputTokens;
|
|
5456
|
-
acc.outputTokens += m.outputTokens;
|
|
5457
|
-
acc.cacheReadTokens += m.cacheReadTokens;
|
|
5458
|
-
acc.cacheWriteTokens += m.cacheWriteTokens;
|
|
5459
|
-
const usd2 = foldUsd(acc.usd, m.usd);
|
|
5460
|
-
if (usd2 === void 0) delete acc.usd;
|
|
5461
|
-
else acc.usd = usd2;
|
|
5462
|
-
if (acc.feeUsd !== void 0 || m.feeUsd !== void 0) acc.feeUsd = (acc.feeUsd ?? 0) + (m.feeUsd ?? 0);
|
|
5463
|
-
const sources = /* @__PURE__ */ new Set([...acc.priceSources ?? [], ...m.priceSources ?? []]);
|
|
5464
|
-
if (sources.size > 0) acc.priceSources = [...sources].sort();
|
|
5465
|
-
}
|
|
5466
|
-
}
|
|
5467
|
-
return out;
|
|
5468
|
-
}
|
|
5469
|
-
function isRunUsage(v) {
|
|
5470
|
-
if (typeof v !== "object" || v === null) return false;
|
|
5471
|
-
const u = v;
|
|
5472
|
-
if (typeof u.turns !== "number") return false;
|
|
5473
|
-
if (typeof u.byModel !== "object" || u.byModel === null || Array.isArray(u.byModel)) return false;
|
|
5474
|
-
return Object.values(u.byModel).every(isModelUsage);
|
|
5475
|
-
}
|
|
5476
|
-
function billedTo(run2, batch, lookupParent) {
|
|
5477
|
-
if (!run2.parentRunId) return identityOf(run2);
|
|
5478
|
-
const parent = batch.get(run2.parentRunId) ?? lookupParent(run2.parentRunId);
|
|
5479
|
-
return identityOf(parent ?? run2);
|
|
5480
|
-
}
|
|
5481
|
-
function aggregateUsage(runs, lookupParent = () => void 0) {
|
|
5482
|
-
const batch = new Map(runs.map((r) => [r.id, r]));
|
|
5483
|
-
const rows = /* @__PURE__ */ new Map();
|
|
5484
|
-
let pending2 = 0;
|
|
5485
|
-
for (const run2 of runs) {
|
|
5486
|
-
const who2 = billedTo(run2, batch, lookupParent);
|
|
5487
|
-
const day2 = dayOf(run2.finishedAt);
|
|
5488
|
-
const agent = run2.agent ?? UNKNOWN_AGENT;
|
|
5489
|
-
const key = JSON.stringify([day2, who2.userId, run2.threadKey, run2.channelId, agent]);
|
|
5490
|
-
const row2 = rows.get(key) ?? {
|
|
5491
|
-
day: day2,
|
|
5492
|
-
userId: who2.userId,
|
|
5493
|
-
threadKey: run2.threadKey,
|
|
5494
|
-
channelId: run2.channelId,
|
|
5495
|
-
agent,
|
|
5496
|
-
runs: 0,
|
|
5497
|
-
wallMs: 0,
|
|
5498
|
-
usage: emptyUsage()
|
|
5499
|
-
};
|
|
5500
|
-
if (who2.userName && !row2.userName) row2.userName = who2.userName;
|
|
5501
|
-
row2.runs += 1;
|
|
5502
|
-
row2.wallMs += Math.max(0, run2.finishedAt - run2.startedAt);
|
|
5503
|
-
if (run2.usage) row2.usage = addUsage(row2.usage, run2.usage);
|
|
5504
|
-
else pending2 += 1;
|
|
5505
|
-
rows.set(key, row2);
|
|
5506
|
-
}
|
|
5507
|
-
const sorted = [...rows.values()].sort((a, b) => {
|
|
5508
|
-
for (const k of CELL_ORDER) {
|
|
5509
|
-
if (a[k] < b[k]) return -1;
|
|
5510
|
-
if (a[k] > b[k]) return 1;
|
|
5511
|
-
}
|
|
5512
|
-
return 0;
|
|
5513
|
-
});
|
|
5514
|
-
return { rows: sorted, pending: pending2 };
|
|
5515
|
-
}
|
|
5516
|
-
function reportOfUsageRows(rows) {
|
|
5517
|
-
const { rows: cells, pending: pending2 } = aggregateUsage(rows.runs, (id) => rows.parents[id]);
|
|
5518
|
-
return {
|
|
5519
|
-
rows: cells,
|
|
5520
|
-
// The store counts what it could not price; the fold sees the same runs without `usage`.
|
|
5521
|
-
pending: Math.max(pending2, rows.pending),
|
|
5522
|
-
...rows.earliestFinishedAt !== void 0 ? { earliestFinishedAt: rows.earliestFinishedAt } : {},
|
|
5523
|
-
retentionDays: rows.retentionDays
|
|
5524
|
-
};
|
|
5525
|
-
}
|
|
5526
|
-
function isUsageRun(v) {
|
|
5527
|
-
if (!isIdentity(v)) return false;
|
|
5528
|
-
const r = v;
|
|
5529
|
-
return typeof r.id === "string" && typeof r.threadKey === "string" && typeof r.channelId === "string" && (r.agent === void 0 || typeof r.agent === "string") && (r.parentRunId === void 0 || typeof r.parentRunId === "string") && typeof r.startedAt === "number" && typeof r.finishedAt === "number" && (r.usage === void 0 || isRunUsage(r.usage));
|
|
5530
|
-
}
|
|
5531
|
-
function hasReportTail(r) {
|
|
5532
|
-
if (typeof r.pending !== "number" || typeof r.retentionDays !== "number") return false;
|
|
5533
|
-
return r.earliestFinishedAt === void 0 || typeof r.earliestFinishedAt === "number";
|
|
5534
|
-
}
|
|
5535
|
-
function isRunUsageRows(v) {
|
|
5536
|
-
if (typeof v !== "object" || v === null) return false;
|
|
5537
|
-
const r = v;
|
|
5538
|
-
if (!Array.isArray(r.runs) || !r.runs.every(isUsageRun)) return false;
|
|
5539
|
-
if (typeof r.parents !== "object" || r.parents === null || Array.isArray(r.parents)) return false;
|
|
5540
|
-
if (!Object.values(r.parents).every(isIdentity)) return false;
|
|
5541
|
-
return hasReportTail(r);
|
|
5542
|
-
}
|
|
5543
|
-
function isRunUsageReport(v) {
|
|
5544
|
-
if (typeof v !== "object" || v === null) return false;
|
|
5545
|
-
const r = v;
|
|
5546
|
-
if (!Array.isArray(r.rows) || !hasReportTail(r)) return false;
|
|
5547
|
-
return r.rows.every(
|
|
5548
|
-
(row2) => isIdentity(row2) && typeof row2.day === "string" && typeof row2.threadKey === "string" && typeof row2.channelId === "string" && typeof row2.agent === "string" && typeof row2.runs === "number" && typeof row2.wallMs === "number" && isRunUsage(row2.usage)
|
|
5549
|
-
);
|
|
5550
|
-
}
|
|
5551
|
-
var UNKNOWN_MODEL, UNKNOWN_AGENT, MODEL_TURN, num, emptyUsage, foldUsd, isModelUsage, dayOf, identityOf, CELL_ORDER, isIdentity;
|
|
5552
|
-
var init_runUsage = __esm({
|
|
5553
|
-
"../../src/core/runUsage.ts"() {
|
|
5554
|
-
"use strict";
|
|
5555
|
-
UNKNOWN_MODEL = "unknown";
|
|
5556
|
-
UNKNOWN_AGENT = "unknown";
|
|
5557
|
-
MODEL_TURN = "model.turn";
|
|
5558
|
-
num = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0 ? v : 0;
|
|
5559
|
-
emptyUsage = () => ({ turns: 0, byModel: {} });
|
|
5560
|
-
foldUsd = (a, b) => a === void 0 || b === void 0 ? void 0 : a === null || b === null ? null : a + b;
|
|
5561
|
-
isModelUsage = (v) => {
|
|
5562
|
-
if (typeof v !== "object" || v === null) return false;
|
|
5563
|
-
const m = v;
|
|
5564
|
-
if (!["turns", "inputTokens", "outputTokens", "cacheReadTokens", "cacheWriteTokens"].every(
|
|
5565
|
-
(k) => typeof m[k] === "number"
|
|
5566
|
-
))
|
|
5567
|
-
return false;
|
|
5568
|
-
if (m.usd !== void 0 && m.usd !== null && typeof m.usd !== "number") return false;
|
|
5569
|
-
if (m.feeUsd !== void 0 && typeof m.feeUsd !== "number") return false;
|
|
5570
|
-
return m.priceSources === void 0 || Array.isArray(m.priceSources) && m.priceSources.every((s) => typeof s === "string");
|
|
5571
|
-
};
|
|
5572
|
-
dayOf = (epochMs) => new Date(epochMs).toISOString().slice(0, 10);
|
|
5573
|
-
identityOf = (who2) => ({
|
|
5574
|
-
userId: who2.userId,
|
|
5575
|
-
...who2.userName ? { userName: who2.userName } : {}
|
|
5576
|
-
});
|
|
5577
|
-
CELL_ORDER = ["day", "userId", "threadKey", "channelId", "agent"];
|
|
5578
|
-
isIdentity = (v) => typeof v === "object" && v !== null && typeof v.userId === "string" && (v.userName === void 0 || typeof v.userName === "string");
|
|
5579
|
-
}
|
|
5580
|
-
});
|
|
5581
|
-
|
|
5582
5392
|
// ../../src/core/ship/handoff.ts
|
|
5583
5393
|
function isEmptyHandoff(h) {
|
|
5584
5394
|
return LISTS.every((k) => listOf(asLists(h), k).length === 0);
|
|
@@ -5803,7 +5613,11 @@ function pullMergedEventType(key) {
|
|
|
5803
5613
|
return `${PULL_MERGED_EVENT_PREFIX}${key.instanceId.slice(0, room)}${suffix}`;
|
|
5804
5614
|
}
|
|
5805
5615
|
function coordinatorFields(tag) {
|
|
5806
|
-
return tag ? {
|
|
5616
|
+
return tag ? {
|
|
5617
|
+
parentInstanceId: tag.parentInstanceId,
|
|
5618
|
+
idempotencyKey: tag.idempotencyKey,
|
|
5619
|
+
...tag.costCapUsd !== void 0 ? { costCapUsd: tag.costCapUsd } : {}
|
|
5620
|
+
} : {};
|
|
5807
5621
|
}
|
|
5808
5622
|
function isCoordinatorInstance(v) {
|
|
5809
5623
|
if (!isObject(v)) return false;
|
|
@@ -5972,6 +5786,221 @@ var init_contract2 = __esm({
|
|
|
5972
5786
|
}
|
|
5973
5787
|
});
|
|
5974
5788
|
|
|
5789
|
+
// ../../src/core/runUsage.ts
|
|
5790
|
+
function usageOfEvents(events) {
|
|
5791
|
+
const usage = emptyUsage();
|
|
5792
|
+
const priced = /* @__PURE__ */ new Map();
|
|
5793
|
+
for (const e of events) {
|
|
5794
|
+
if (e.type !== "span_end" || e.name !== MODEL_TURN) continue;
|
|
5795
|
+
const attrs = e.attrs ?? {};
|
|
5796
|
+
const model = typeof attrs.model === "string" && attrs.model ? attrs.model : UNKNOWN_MODEL;
|
|
5797
|
+
const m = usage.byModel[model] ?? {
|
|
5798
|
+
turns: 0,
|
|
5799
|
+
inputTokens: 0,
|
|
5800
|
+
outputTokens: 0,
|
|
5801
|
+
cacheReadTokens: 0,
|
|
5802
|
+
cacheWriteTokens: 0
|
|
5803
|
+
};
|
|
5804
|
+
const counted2 = num(attrs.inputTokens) + num(attrs.outputTokens) + num(attrs.cacheReadTokens) + num(attrs.cacheWriteTokens);
|
|
5805
|
+
m.turns += 1;
|
|
5806
|
+
m.inputTokens += num(attrs.inputTokens);
|
|
5807
|
+
m.outputTokens += num(attrs.outputTokens);
|
|
5808
|
+
m.cacheReadTokens += num(attrs.cacheReadTokens);
|
|
5809
|
+
m.cacheWriteTokens += num(attrs.cacheWriteTokens);
|
|
5810
|
+
usage.byModel[model] = m;
|
|
5811
|
+
usage.turns += 1;
|
|
5812
|
+
const hasUsd = typeof attrs.usd === "number" && Number.isFinite(attrs.usd);
|
|
5813
|
+
const hasSource = typeof attrs.priceSource === "string" && attrs.priceSource !== "";
|
|
5814
|
+
const p = priced.get(model) ?? {
|
|
5815
|
+
usd: 0,
|
|
5816
|
+
feeUsd: 0,
|
|
5817
|
+
feeTurns: 0,
|
|
5818
|
+
pricedTurns: 0,
|
|
5819
|
+
unpricedTokenTurns: 0,
|
|
5820
|
+
sources: /* @__PURE__ */ new Set()
|
|
5821
|
+
};
|
|
5822
|
+
if (counted2 > 0 && !hasUsd) p.unpricedTokenTurns += 1;
|
|
5823
|
+
if (hasUsd) {
|
|
5824
|
+
p.usd += attrs.usd;
|
|
5825
|
+
p.pricedTurns += 1;
|
|
5826
|
+
}
|
|
5827
|
+
if (typeof attrs.feeUsd === "number" && Number.isFinite(attrs.feeUsd)) {
|
|
5828
|
+
p.feeUsd += attrs.feeUsd;
|
|
5829
|
+
p.feeTurns += 1;
|
|
5830
|
+
}
|
|
5831
|
+
if (hasSource) p.sources.add(attrs.priceSource);
|
|
5832
|
+
priced.set(model, p);
|
|
5833
|
+
}
|
|
5834
|
+
for (const [model, p] of priced) {
|
|
5835
|
+
if (p.pricedTurns === 0 && p.sources.size === 0) continue;
|
|
5836
|
+
const m = usage.byModel[model];
|
|
5837
|
+
m.usd = p.unpricedTokenTurns > 0 ? null : p.usd;
|
|
5838
|
+
if (p.feeTurns > 0) m.feeUsd = p.feeUsd;
|
|
5839
|
+
if (p.sources.size > 0) m.priceSources = [...p.sources].sort();
|
|
5840
|
+
}
|
|
5841
|
+
return usage;
|
|
5842
|
+
}
|
|
5843
|
+
function addUsage(a, b) {
|
|
5844
|
+
const out = { turns: a.turns + b.turns, byModel: {} };
|
|
5845
|
+
for (const src of [a.byModel, b.byModel]) {
|
|
5846
|
+
for (const [model, m] of Object.entries(src)) {
|
|
5847
|
+
const acc = out.byModel[model];
|
|
5848
|
+
if (!acc) {
|
|
5849
|
+
out.byModel[model] = { ...m, ...m.priceSources ? { priceSources: [...m.priceSources] } : {} };
|
|
5850
|
+
continue;
|
|
5851
|
+
}
|
|
5852
|
+
acc.turns += m.turns;
|
|
5853
|
+
acc.inputTokens += m.inputTokens;
|
|
5854
|
+
acc.outputTokens += m.outputTokens;
|
|
5855
|
+
acc.cacheReadTokens += m.cacheReadTokens;
|
|
5856
|
+
acc.cacheWriteTokens += m.cacheWriteTokens;
|
|
5857
|
+
const usd2 = foldUsd(acc.usd, m.usd);
|
|
5858
|
+
if (usd2 === void 0) delete acc.usd;
|
|
5859
|
+
else acc.usd = usd2;
|
|
5860
|
+
if (acc.feeUsd !== void 0 || m.feeUsd !== void 0) acc.feeUsd = (acc.feeUsd ?? 0) + (m.feeUsd ?? 0);
|
|
5861
|
+
const sources = /* @__PURE__ */ new Set([...acc.priceSources ?? [], ...m.priceSources ?? []]);
|
|
5862
|
+
if (sources.size > 0) acc.priceSources = [...sources].sort();
|
|
5863
|
+
}
|
|
5864
|
+
}
|
|
5865
|
+
return out;
|
|
5866
|
+
}
|
|
5867
|
+
function isRunUsage(v) {
|
|
5868
|
+
if (typeof v !== "object" || v === null) return false;
|
|
5869
|
+
const u = v;
|
|
5870
|
+
if (typeof u.turns !== "number") return false;
|
|
5871
|
+
if (typeof u.byModel !== "object" || u.byModel === null || Array.isArray(u.byModel)) return false;
|
|
5872
|
+
return Object.values(u.byModel).every(isModelUsage);
|
|
5873
|
+
}
|
|
5874
|
+
function shipRunsOf(runs) {
|
|
5875
|
+
return runs.flatMap((run2) => {
|
|
5876
|
+
if (!run2.parentInstanceId || !run2.idempotencyKey) return [];
|
|
5877
|
+
const unit = unitOfIdempotencyKey(run2.idempotencyKey);
|
|
5878
|
+
if (!unit) return [];
|
|
5879
|
+
return [
|
|
5880
|
+
{
|
|
5881
|
+
id: run2.id,
|
|
5882
|
+
unitKey: `${run2.parentInstanceId}:${unit}`,
|
|
5883
|
+
finishedAt: run2.finishedAt,
|
|
5884
|
+
...run2.costCapUsd !== void 0 ? { costCapUsd: run2.costCapUsd } : {},
|
|
5885
|
+
...run2.usage !== void 0 ? { usage: run2.usage } : {}
|
|
5886
|
+
}
|
|
5887
|
+
];
|
|
5888
|
+
});
|
|
5889
|
+
}
|
|
5890
|
+
function billedTo(run2, batch, lookupParent) {
|
|
5891
|
+
if (!run2.parentRunId) return identityOf(run2);
|
|
5892
|
+
const parent = batch.get(run2.parentRunId) ?? lookupParent(run2.parentRunId);
|
|
5893
|
+
return identityOf(parent ?? run2);
|
|
5894
|
+
}
|
|
5895
|
+
function aggregateUsage(runs, lookupParent = () => void 0) {
|
|
5896
|
+
const batch = new Map(runs.map((r) => [r.id, r]));
|
|
5897
|
+
const rows = /* @__PURE__ */ new Map();
|
|
5898
|
+
let pending2 = 0;
|
|
5899
|
+
for (const run2 of runs) {
|
|
5900
|
+
const who2 = billedTo(run2, batch, lookupParent);
|
|
5901
|
+
const day2 = dayOf(run2.finishedAt);
|
|
5902
|
+
const agent = run2.agent ?? UNKNOWN_AGENT;
|
|
5903
|
+
const key = JSON.stringify([day2, who2.userId, run2.threadKey, run2.channelId, agent]);
|
|
5904
|
+
const row2 = rows.get(key) ?? {
|
|
5905
|
+
day: day2,
|
|
5906
|
+
userId: who2.userId,
|
|
5907
|
+
threadKey: run2.threadKey,
|
|
5908
|
+
channelId: run2.channelId,
|
|
5909
|
+
agent,
|
|
5910
|
+
runs: 0,
|
|
5911
|
+
wallMs: 0,
|
|
5912
|
+
usage: emptyUsage()
|
|
5913
|
+
};
|
|
5914
|
+
if (who2.userName && !row2.userName) row2.userName = who2.userName;
|
|
5915
|
+
row2.runs += 1;
|
|
5916
|
+
row2.wallMs += Math.max(0, run2.finishedAt - run2.startedAt);
|
|
5917
|
+
if (run2.usage) row2.usage = addUsage(row2.usage, run2.usage);
|
|
5918
|
+
else pending2 += 1;
|
|
5919
|
+
rows.set(key, row2);
|
|
5920
|
+
}
|
|
5921
|
+
const sorted = [...rows.values()].sort((a, b) => {
|
|
5922
|
+
for (const k of CELL_ORDER) {
|
|
5923
|
+
if (a[k] < b[k]) return -1;
|
|
5924
|
+
if (a[k] > b[k]) return 1;
|
|
5925
|
+
}
|
|
5926
|
+
return 0;
|
|
5927
|
+
});
|
|
5928
|
+
return { rows: sorted, pending: pending2 };
|
|
5929
|
+
}
|
|
5930
|
+
function reportOfUsageRows(rows) {
|
|
5931
|
+
const { rows: cells, pending: pending2 } = aggregateUsage(rows.runs, (id) => rows.parents[id]);
|
|
5932
|
+
return {
|
|
5933
|
+
rows: cells,
|
|
5934
|
+
shipRuns: shipRunsOf(rows.runs),
|
|
5935
|
+
// The store counts what it could not price; the fold sees the same runs without `usage`.
|
|
5936
|
+
pending: Math.max(pending2, rows.pending),
|
|
5937
|
+
...rows.earliestFinishedAt !== void 0 ? { earliestFinishedAt: rows.earliestFinishedAt } : {},
|
|
5938
|
+
retentionDays: rows.retentionDays
|
|
5939
|
+
};
|
|
5940
|
+
}
|
|
5941
|
+
function isUsageRun(v) {
|
|
5942
|
+
if (!isIdentity(v)) return false;
|
|
5943
|
+
const r = v;
|
|
5944
|
+
return typeof r.id === "string" && typeof r.threadKey === "string" && typeof r.channelId === "string" && (r.agent === void 0 || typeof r.agent === "string") && (r.parentRunId === void 0 || typeof r.parentRunId === "string") && (r.parentInstanceId === void 0 || typeof r.parentInstanceId === "string") && (r.idempotencyKey === void 0 || typeof r.idempotencyKey === "string") && (r.costCapUsd === void 0 || typeof r.costCapUsd === "number" && Number.isFinite(r.costCapUsd) && r.costCapUsd > 0) && typeof r.startedAt === "number" && typeof r.finishedAt === "number" && (r.usage === void 0 || isRunUsage(r.usage));
|
|
5945
|
+
}
|
|
5946
|
+
function hasReportTail(r) {
|
|
5947
|
+
if (typeof r.pending !== "number" || typeof r.retentionDays !== "number") return false;
|
|
5948
|
+
return r.earliestFinishedAt === void 0 || typeof r.earliestFinishedAt === "number";
|
|
5949
|
+
}
|
|
5950
|
+
function isRunUsageRows(v) {
|
|
5951
|
+
if (typeof v !== "object" || v === null) return false;
|
|
5952
|
+
const r = v;
|
|
5953
|
+
if (!Array.isArray(r.runs) || !r.runs.every(isUsageRun)) return false;
|
|
5954
|
+
if (typeof r.parents !== "object" || r.parents === null || Array.isArray(r.parents)) return false;
|
|
5955
|
+
if (!Object.values(r.parents).every(isIdentity)) return false;
|
|
5956
|
+
return hasReportTail(r);
|
|
5957
|
+
}
|
|
5958
|
+
function isRunUsageReport(v) {
|
|
5959
|
+
if (typeof v !== "object" || v === null) return false;
|
|
5960
|
+
const r = v;
|
|
5961
|
+
if (!Array.isArray(r.rows) || !hasReportTail(r)) return false;
|
|
5962
|
+
if (r.shipRuns !== void 0 && (!Array.isArray(r.shipRuns) || !r.shipRuns.every(isShipRunUsage))) return false;
|
|
5963
|
+
return r.rows.every(
|
|
5964
|
+
(row2) => isIdentity(row2) && typeof row2.day === "string" && typeof row2.threadKey === "string" && typeof row2.channelId === "string" && typeof row2.agent === "string" && typeof row2.runs === "number" && typeof row2.wallMs === "number" && isRunUsage(row2.usage)
|
|
5965
|
+
);
|
|
5966
|
+
}
|
|
5967
|
+
function isShipRunUsage(v) {
|
|
5968
|
+
if (typeof v !== "object" || v === null) return false;
|
|
5969
|
+
const r = v;
|
|
5970
|
+
return typeof r.id === "string" && typeof r.unitKey === "string" && typeof r.finishedAt === "number" && Number.isFinite(r.finishedAt) && (r.costCapUsd === void 0 || typeof r.costCapUsd === "number" && Number.isFinite(r.costCapUsd) && r.costCapUsd > 0) && (r.usage === void 0 || isRunUsage(r.usage));
|
|
5971
|
+
}
|
|
5972
|
+
var UNKNOWN_MODEL, UNKNOWN_AGENT, MODEL_TURN, num, emptyUsage, foldUsd, isModelUsage, dayOf, identityOf, CELL_ORDER, isIdentity;
|
|
5973
|
+
var init_runUsage = __esm({
|
|
5974
|
+
"../../src/core/runUsage.ts"() {
|
|
5975
|
+
"use strict";
|
|
5976
|
+
init_contract2();
|
|
5977
|
+
UNKNOWN_MODEL = "unknown";
|
|
5978
|
+
UNKNOWN_AGENT = "unknown";
|
|
5979
|
+
MODEL_TURN = "model.turn";
|
|
5980
|
+
num = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0 ? v : 0;
|
|
5981
|
+
emptyUsage = () => ({ turns: 0, byModel: {} });
|
|
5982
|
+
foldUsd = (a, b) => a === void 0 || b === void 0 ? void 0 : a === null || b === null ? null : a + b;
|
|
5983
|
+
isModelUsage = (v) => {
|
|
5984
|
+
if (typeof v !== "object" || v === null) return false;
|
|
5985
|
+
const m = v;
|
|
5986
|
+
if (!["turns", "inputTokens", "outputTokens", "cacheReadTokens", "cacheWriteTokens"].every(
|
|
5987
|
+
(k) => typeof m[k] === "number"
|
|
5988
|
+
))
|
|
5989
|
+
return false;
|
|
5990
|
+
if (m.usd !== void 0 && m.usd !== null && typeof m.usd !== "number") return false;
|
|
5991
|
+
if (m.feeUsd !== void 0 && typeof m.feeUsd !== "number") return false;
|
|
5992
|
+
return m.priceSources === void 0 || Array.isArray(m.priceSources) && m.priceSources.every((s) => typeof s === "string");
|
|
5993
|
+
};
|
|
5994
|
+
dayOf = (epochMs) => new Date(epochMs).toISOString().slice(0, 10);
|
|
5995
|
+
identityOf = (who2) => ({
|
|
5996
|
+
userId: who2.userId,
|
|
5997
|
+
...who2.userName ? { userName: who2.userName } : {}
|
|
5998
|
+
});
|
|
5999
|
+
CELL_ORDER = ["day", "userId", "threadKey", "channelId", "agent"];
|
|
6000
|
+
isIdentity = (v) => typeof v === "object" && v !== null && typeof v.userId === "string" && (v.userName === void 0 || typeof v.userName === "string");
|
|
6001
|
+
}
|
|
6002
|
+
});
|
|
6003
|
+
|
|
5975
6004
|
// ../../src/core/pipelineStanding.ts
|
|
5976
6005
|
function hostedStageDetail(stage) {
|
|
5977
6006
|
switch (stage) {
|
|
@@ -6589,6 +6618,8 @@ function isRunRecord(v) {
|
|
|
6589
6618
|
return false;
|
|
6590
6619
|
if (r.idempotencyKey !== void 0 && (typeof r.idempotencyKey !== "string" || !IDEMPOTENCY_KEY_PATTERN.test(r.idempotencyKey)))
|
|
6591
6620
|
return false;
|
|
6621
|
+
if (r.costCapUsd !== void 0 && (r.parentInstanceId === void 0 || typeof r.costCapUsd !== "number" || !Number.isFinite(r.costCapUsd) || r.costCapUsd <= 0))
|
|
6622
|
+
return false;
|
|
6592
6623
|
if (r.instanceId !== void 0 && (typeof r.instanceId !== "string" || !INSTANCE_ID_PATTERN.test(r.instanceId)))
|
|
6593
6624
|
return false;
|
|
6594
6625
|
if (r.pipeline !== void 0 && !isPipelineSummaryShape(r.pipeline)) return false;
|
|
@@ -12975,6 +13006,9 @@ async function waitForResident(step, expectedCommit, deadline, io, deps, resourc
|
|
|
12975
13006
|
const bearer = RESIDENT_BEARER_ENVS.map((name) => deps.env[name]).find((value) => value?.trim());
|
|
12976
13007
|
if (resources && !bearer) return `registry unreadable: no ${RESIDENT_BEARER_ENVS.join(" / ")}`;
|
|
12977
13008
|
let problem = "readiness deadline expired before readback";
|
|
13009
|
+
let lastLoggedProblem = "";
|
|
13010
|
+
let lastLoggedAt = -Infinity;
|
|
13011
|
+
let nextReconcileAt = 0;
|
|
12978
13012
|
while (deps.now() < deadline) {
|
|
12979
13013
|
const timeoutMs = Math.min(LIVE_GATE_POLL_MS, deadline - deps.now());
|
|
12980
13014
|
const [health, registry] = await Promise.all([
|
|
@@ -12987,7 +13021,16 @@ async function waitForResident(step, expectedCommit, deadline, io, deps, resourc
|
|
|
12987
13021
|
].filter(Boolean);
|
|
12988
13022
|
if (problems.length === 0 && deps.now() <= deadline) return void 0;
|
|
12989
13023
|
problem = problems.join("; ") || "readback arrived after the readiness deadline";
|
|
12990
|
-
|
|
13024
|
+
if (problem !== lastLoggedProblem || deps.now() - lastLoggedAt >= MINUTE_MS) {
|
|
13025
|
+
io.log(`[deploy:all] resident: waiting for readiness \u2014 ${problem}`);
|
|
13026
|
+
lastLoggedProblem = problem;
|
|
13027
|
+
lastLoggedAt = deps.now();
|
|
13028
|
+
}
|
|
13029
|
+
if (resources && deps.now() >= nextReconcileAt && deadline - deps.now() > 2 * LIVE_GATE_POLL_MS && !residentWorkerProblem(health, expectedCommit)) {
|
|
13030
|
+
const retry = await reconcileFleet(step, io, deps, false);
|
|
13031
|
+
if (retry && !reconciledResources(retry)) io.log(reconcileLine(step.name, retry));
|
|
13032
|
+
nextReconcileAt = deps.now() + MINUTE_MS;
|
|
13033
|
+
}
|
|
12991
13034
|
const left = deadline - deps.now();
|
|
12992
13035
|
if (left > 0) await deps.sleep(Math.min(LIVE_GATE_POLL_MS, left));
|
|
12993
13036
|
}
|
|
@@ -13008,11 +13051,11 @@ async function beginDrain(step, expectedCommit, io, deps) {
|
|
|
13008
13051
|
io.log(drainBeganLine(step.name, answer2));
|
|
13009
13052
|
return { attempted: true, drained: drainSet(answer2), until: drainUntil(answer2) };
|
|
13010
13053
|
}
|
|
13011
|
-
async function reconcileFleet(step, io, deps) {
|
|
13054
|
+
async function reconcileFleet(step, io, deps, log = true) {
|
|
13012
13055
|
const bearer = step.drain ? deps.env[step.drain.tokenEnv] : void 0;
|
|
13013
13056
|
if (!step.drain || !bearer || !deps.postJson) return;
|
|
13014
13057
|
const answer2 = await deps.postJson(reconcileUrl(step.drain.url), bearer, {});
|
|
13015
|
-
io.log(reconcileLine(step.name, answer2));
|
|
13058
|
+
if (log) io.log(reconcileLine(step.name, answer2));
|
|
13016
13059
|
return answer2;
|
|
13017
13060
|
}
|
|
13018
13061
|
async function endDrain(step, drain, io, deps) {
|
|
@@ -15586,15 +15629,15 @@ function sandboxNoAnswerMessage(route2, budgetMs) {
|
|
|
15586
15629
|
function sandboxEmptyFailureMessage(route2) {
|
|
15587
15630
|
return `sandbox worker ${route2}: failure with an empty message (the Worker's failure shape with its text missing)`;
|
|
15588
15631
|
}
|
|
15589
|
-
function
|
|
15632
|
+
function sandboxStopped(route2) {
|
|
15633
|
+
return new ExecInfraError(`sandbox ${route2}: the run was stopped`, "aborted");
|
|
15634
|
+
}
|
|
15635
|
+
function waitForRetry(ms, route2, signal2) {
|
|
15590
15636
|
return new Promise((resolve13, reject) => {
|
|
15591
|
-
|
|
15592
|
-
`sandbox fleet busy \u2014 stopped waiting for a free per-thread sandbox after ${Math.round(waitedMs / 1e3)}s: the run was stopped`
|
|
15593
|
-
);
|
|
15594
|
-
if (signal2?.aborted) return reject(stopped());
|
|
15637
|
+
if (signal2?.aborted) return reject(sandboxStopped(route2));
|
|
15595
15638
|
const onAbort = () => {
|
|
15596
15639
|
clearTimeout(timer);
|
|
15597
|
-
reject(
|
|
15640
|
+
reject(sandboxStopped(route2));
|
|
15598
15641
|
};
|
|
15599
15642
|
const timer = setTimeout(() => {
|
|
15600
15643
|
signal2?.removeEventListener("abort", onAbort);
|
|
@@ -15629,13 +15672,13 @@ var init_cloudflareSandbox = __esm({
|
|
|
15629
15672
|
scrubbed;
|
|
15630
15673
|
/** The Worker reconnects by thread key, so scrub a reused sandbox before
|
|
15631
15674
|
* seed, checkout, or any model-visible command can touch its old store. */
|
|
15632
|
-
async prepareCredentialBoundary() {
|
|
15675
|
+
async prepareCredentialBoundary(opts) {
|
|
15633
15676
|
const result = await this.call(
|
|
15634
15677
|
"/exec",
|
|
15635
15678
|
{ command: legacySandboxCredentialScrub(SANDBOX_CREDENTIAL_FILE) },
|
|
15679
|
+
opts?.signal,
|
|
15636
15680
|
void 0,
|
|
15637
|
-
|
|
15638
|
-
void 0,
|
|
15681
|
+
opts?.span,
|
|
15639
15682
|
true
|
|
15640
15683
|
);
|
|
15641
15684
|
if (Number(result.exitCode ?? -1) !== 0)
|
|
@@ -15691,8 +15734,9 @@ var init_cloudflareSandbox = __esm({
|
|
|
15691
15734
|
* each send runs under. Time spent waiting for a slot never eats into a
|
|
15692
15735
|
* send's deadline: nothing ran during it. */
|
|
15693
15736
|
async call(route2, body, signal2, budgetMs = BASH_TIMEOUT_MS, span, skipScrub = false) {
|
|
15737
|
+
if (signal2?.aborted) throw sandboxStopped(route2);
|
|
15694
15738
|
if (this.opts.scrubLegacyCredentials && !skipScrub) {
|
|
15695
|
-
this.scrubbed ??= this.prepareCredentialBoundary();
|
|
15739
|
+
this.scrubbed ??= this.prepareCredentialBoundary({ signal: signal2, span });
|
|
15696
15740
|
await this.scrubbed;
|
|
15697
15741
|
}
|
|
15698
15742
|
const envs = await this.opts.resolveEnvs();
|
|
@@ -15726,7 +15770,7 @@ var init_cloudflareSandbox = __esm({
|
|
|
15726
15770
|
}
|
|
15727
15771
|
const delay = Math.min(plan3.backoff[Math.min(attempt, plan3.backoff.length - 1)], plan3.budget - waited);
|
|
15728
15772
|
attempt++;
|
|
15729
|
-
await
|
|
15773
|
+
await waitForRetry(delay, route2, signal2);
|
|
15730
15774
|
waited += delay;
|
|
15731
15775
|
}
|
|
15732
15776
|
}
|
|
@@ -15740,7 +15784,8 @@ var init_cloudflareSandbox = __esm({
|
|
|
15740
15784
|
let lastErr = "";
|
|
15741
15785
|
let lastStatus = 0;
|
|
15742
15786
|
for (const delay of delays) {
|
|
15743
|
-
if (delay > 0) await
|
|
15787
|
+
if (delay > 0) await waitForRetry(delay, route2, signal2);
|
|
15788
|
+
if (signal2?.aborted) throw sandboxStopped(route2);
|
|
15744
15789
|
let res;
|
|
15745
15790
|
let text;
|
|
15746
15791
|
const deadline = execDeadline(sendDeadlineMs(budgetMs), signal2);
|
|
@@ -19077,7 +19122,13 @@ async function makeExecutor(opts, ctx, span) {
|
|
|
19077
19122
|
const executor2 = await makePerThreadExecutor(opts, perThreadCheckout(opts, ctx));
|
|
19078
19123
|
await recheckOwner();
|
|
19079
19124
|
const handle2 = probe.kind === "status" ? probe.seed : void 0;
|
|
19080
|
-
const outcome = handle2 && executor2 instanceof CloudflareSandboxExecutor ? await seedSandbox(
|
|
19125
|
+
const outcome = handle2 && executor2 instanceof CloudflareSandboxExecutor ? await seedSandbox(
|
|
19126
|
+
executor2,
|
|
19127
|
+
handle2,
|
|
19128
|
+
ctx,
|
|
19129
|
+
() => probeResident(resident, token2, resource, span, ctx.stopSignal),
|
|
19130
|
+
span
|
|
19131
|
+
) : void 0;
|
|
19081
19132
|
if (outcome !== void 0) await recheckOwner();
|
|
19082
19133
|
if (outcome && "seeded" in outcome) {
|
|
19083
19134
|
return {
|
|
@@ -19117,8 +19168,9 @@ async function seedSandbox(executor, handle2, ctx, reprobe, span) {
|
|
|
19117
19168
|
for (let retried = false; ; retried = true) {
|
|
19118
19169
|
let answer2;
|
|
19119
19170
|
try {
|
|
19120
|
-
answer2 = await executor.seed(seed, { span });
|
|
19171
|
+
answer2 = await executor.seed(seed, { span, signal: ctx.stopSignal });
|
|
19121
19172
|
} catch (err2) {
|
|
19173
|
+
if (isRunStopError(err2)) throw err2;
|
|
19122
19174
|
return { why: oneLine(`seed failed (${err2 instanceof Error ? err2.message : String(err2)})`) };
|
|
19123
19175
|
}
|
|
19124
19176
|
if (answer2.seeded) {
|
|
@@ -19134,6 +19186,7 @@ async function seedSandbox(executor, handle2, ctx, reprobe, span) {
|
|
|
19134
19186
|
};
|
|
19135
19187
|
}
|
|
19136
19188
|
const fresh = answer2.reason === "seed-missing" && !retried ? await reprobe() : void 0;
|
|
19189
|
+
if (fresh?.kind === "unreachable" && fresh.transport && ctx.stopSignal?.aborted) throw wakeStopped("/status");
|
|
19137
19190
|
const decision = seedRetryDecision({
|
|
19138
19191
|
answer: answer2,
|
|
19139
19192
|
attempted: seed,
|
|
@@ -21682,6 +21735,9 @@ function usageReportOfRecords(records, query, lookupParent, retentionDays) {
|
|
|
21682
21735
|
userId: r.userId,
|
|
21683
21736
|
...r.userName ? { userName: r.userName } : {},
|
|
21684
21737
|
...r.parentRunId ? { parentRunId: r.parentRunId } : {},
|
|
21738
|
+
...r.parentInstanceId ? { parentInstanceId: r.parentInstanceId } : {},
|
|
21739
|
+
...r.idempotencyKey ? { idempotencyKey: r.idempotencyKey } : {},
|
|
21740
|
+
...r.costCapUsd !== void 0 ? { costCapUsd: r.costCapUsd } : {},
|
|
21685
21741
|
threadKey: r.threadKey,
|
|
21686
21742
|
channelId: r.channelId,
|
|
21687
21743
|
...r.agent ? { agent: r.agent } : {},
|
|
@@ -21694,7 +21750,13 @@ function usageReportOfRecords(records, query, lookupParent, retentionDays) {
|
|
|
21694
21750
|
(m, r) => m === void 0 || r.finishedAt < m ? r.finishedAt : m,
|
|
21695
21751
|
void 0
|
|
21696
21752
|
);
|
|
21697
|
-
return {
|
|
21753
|
+
return {
|
|
21754
|
+
rows,
|
|
21755
|
+
shipRuns: shipRunsOf(runs),
|
|
21756
|
+
pending: pending2,
|
|
21757
|
+
...earliest !== void 0 ? { earliestFinishedAt: earliest } : {},
|
|
21758
|
+
retentionDays
|
|
21759
|
+
};
|
|
21698
21760
|
}
|
|
21699
21761
|
function isValidRunId(id) {
|
|
21700
21762
|
return typeof id === "string" && RUN_ID_PATTERN.test(id);
|
|
@@ -22351,6 +22413,43 @@ var init_costsSnapshotStore = __esm({
|
|
|
22351
22413
|
}
|
|
22352
22414
|
});
|
|
22353
22415
|
|
|
22416
|
+
// ../../src/core/shipSpend.ts
|
|
22417
|
+
function recordedUsd(usage) {
|
|
22418
|
+
const models = Object.values(usage?.byModel ?? {});
|
|
22419
|
+
if (!usage || !Number.isSafeInteger(usage.turns) || usage.turns < 0) return null;
|
|
22420
|
+
if (usage.turns === 0 && models.length === 0) return 0;
|
|
22421
|
+
if (models.length === 0 || models.reduce((sum, model) => sum + model.turns, 0) !== usage.turns || models.some((model) => typeof model.usd !== "number" || !Number.isFinite(model.usd) || model.usd < 0))
|
|
22422
|
+
return null;
|
|
22423
|
+
return models.reduce((sum, model) => sum + model.usd, 0);
|
|
22424
|
+
}
|
|
22425
|
+
function buildShipSpendReport(runs, range) {
|
|
22426
|
+
const groups = /* @__PURE__ */ new Map();
|
|
22427
|
+
for (const run2 of runs) {
|
|
22428
|
+
const day2 = new Date(run2.finishedAt).toISOString().slice(0, 10);
|
|
22429
|
+
if (day2 < range.from || day2 > range.to) continue;
|
|
22430
|
+
groups.set(run2.unitKey, [...groups.get(run2.unitKey) ?? [], run2]);
|
|
22431
|
+
}
|
|
22432
|
+
const units = [...groups].map(([key, children]) => {
|
|
22433
|
+
const ordered = children.sort((a, b) => a.finishedAt - b.finishedAt || a.id.localeCompare(b.id));
|
|
22434
|
+
const caps = new Set(ordered.map((r) => r.costCapUsd));
|
|
22435
|
+
const capUsd = caps.size === 1 ? ordered[0]?.costCapUsd ?? null : null;
|
|
22436
|
+
let cumulative = 0;
|
|
22437
|
+
const points = ordered.map((r) => {
|
|
22438
|
+
const usd2 = recordedUsd(r.usage);
|
|
22439
|
+
cumulative = cumulative === null || usd2 === null ? null : cumulative + usd2;
|
|
22440
|
+
return { id: r.id, finishedAt: r.finishedAt, usd: usd2, cumulativeUsd: cumulative };
|
|
22441
|
+
});
|
|
22442
|
+
return { key, capUsd, totalUsd: cumulative, runs: points };
|
|
22443
|
+
});
|
|
22444
|
+
units.sort((a, b) => (b.runs.at(-1)?.finishedAt ?? 0) - (a.runs.at(-1)?.finishedAt ?? 0));
|
|
22445
|
+
return { range, units };
|
|
22446
|
+
}
|
|
22447
|
+
var init_shipSpend = __esm({
|
|
22448
|
+
"../../src/core/shipSpend.ts"() {
|
|
22449
|
+
"use strict";
|
|
22450
|
+
}
|
|
22451
|
+
});
|
|
22452
|
+
|
|
22354
22453
|
// ../../src/core/costsService.ts
|
|
22355
22454
|
async function viewerRunUserIds(userIds, viewer, emailOfSlackUser, cache2) {
|
|
22356
22455
|
const email = viewer?.email?.toLowerCase();
|
|
@@ -22384,7 +22483,12 @@ function createCostsService(cfg, snapshots, deps = {}) {
|
|
|
22384
22483
|
groups: () => Object.keys(cfg.groups),
|
|
22385
22484
|
async report(group, daysParam) {
|
|
22386
22485
|
const g = groupOf(group);
|
|
22387
|
-
|
|
22486
|
+
const snapshot = await snapshotOrThrow();
|
|
22487
|
+
const daily = reportFromSnapshot(snapshot, group, g, daysParam, meta, deps.billers);
|
|
22488
|
+
return {
|
|
22489
|
+
...daily,
|
|
22490
|
+
...snapshot.runUsage?.shipRuns ? { shipSpend: buildShipSpendReport(snapshot.runUsage.shipRuns, daily.range) } : {}
|
|
22491
|
+
};
|
|
22388
22492
|
},
|
|
22389
22493
|
async byReport(group, daysParam, dimension, viewer) {
|
|
22390
22494
|
const g = groupOf(group);
|
|
@@ -22487,6 +22591,7 @@ var init_costsService = __esm({
|
|
|
22487
22591
|
init_costs();
|
|
22488
22592
|
init_costsSnapshot();
|
|
22489
22593
|
init_costsSnapshotStore();
|
|
22594
|
+
init_shipSpend();
|
|
22490
22595
|
COSTS_OFF_MESSAGE = "Cost reporting isn't configured \u2014 set costs.cloudflareAccountId + costs.groups in config and the CF_ANALYTICS_TOKEN secret to enable this view.";
|
|
22491
22596
|
NoCostsSnapshotError = class extends Error {
|
|
22492
22597
|
name = "NoCostsSnapshotError";
|
|
@@ -33009,7 +33114,13 @@ function interruptedRunRecord(summary, snap, finishedAt) {
|
|
|
33009
33114
|
repo: summary.repo,
|
|
33010
33115
|
...summary.parentRunId !== void 0 ? { parentRunId: summary.parentRunId } : {},
|
|
33011
33116
|
...summary.seed !== void 0 ? { seed: summary.seed } : {},
|
|
33012
|
-
...summary.parentInstanceId !== void 0 && summary.idempotencyKey !== void 0 ? {
|
|
33117
|
+
...summary.parentInstanceId !== void 0 && summary.idempotencyKey !== void 0 ? {
|
|
33118
|
+
coordinator: {
|
|
33119
|
+
parentInstanceId: summary.parentInstanceId,
|
|
33120
|
+
idempotencyKey: summary.idempotencyKey,
|
|
33121
|
+
...summary.costCapUsd !== void 0 ? { costCapUsd: summary.costCapUsd } : {}
|
|
33122
|
+
}
|
|
33123
|
+
} : {},
|
|
33013
33124
|
...summary.hosted ? { hosted: true } : {},
|
|
33014
33125
|
finishedAt,
|
|
33015
33126
|
status: "interrupted",
|
|
@@ -33058,7 +33169,13 @@ function reclaimedRunRecord(input) {
|
|
|
33058
33169
|
...row2.meta.session !== void 0 ? { session: row2.meta.session } : {},
|
|
33059
33170
|
// A coordinator's child keeps its instance and key on the close (item 48),
|
|
33060
33171
|
// so the state Worker's finish still sends the parent its event.
|
|
33061
|
-
...row2.meta.parentInstanceId !== void 0 && row2.meta.idempotencyKey !== void 0 ? {
|
|
33172
|
+
...row2.meta.parentInstanceId !== void 0 && row2.meta.idempotencyKey !== void 0 ? {
|
|
33173
|
+
coordinator: {
|
|
33174
|
+
parentInstanceId: row2.meta.parentInstanceId,
|
|
33175
|
+
idempotencyKey: row2.meta.idempotencyKey,
|
|
33176
|
+
...row2.meta.costCapUsd !== void 0 ? { costCapUsd: row2.meta.costCapUsd } : {}
|
|
33177
|
+
}
|
|
33178
|
+
} : {},
|
|
33062
33179
|
...row2.meta.hosted ? { hosted: true } : {},
|
|
33063
33180
|
finishedAt,
|
|
33064
33181
|
status: status3,
|
|
@@ -36745,7 +36862,7 @@ function addressedBarePrOf(s, text) {
|
|
|
36745
36862
|
function contextCueOf(later2) {
|
|
36746
36863
|
const clause = later2.before.split(/[;\n]/).at(-1) ?? later2.before;
|
|
36747
36864
|
const action = [
|
|
36748
|
-
...clause.matchAll(/\b(?:re-?review|review|see|context|example|reference|related|compare|background)\b/gi)
|
|
36865
|
+
...clause.matchAll(/\b(?:re-?review|review|see|context|example|reference|related|compare|background|packages)\b/gi)
|
|
36749
36866
|
].at(-1)?.[0].toLowerCase();
|
|
36750
36867
|
return action !== void 0 && !/^(?:re-?review|review)$/.test(action) || /^[ \t]*(?:[,:][ \t]*)?(?:for|as)[ \t]+(?:context|reference|background)\b/i.test(later2.after);
|
|
36751
36868
|
}
|
|
@@ -39975,6 +40092,7 @@ function summaryOf(run2, now) {
|
|
|
39975
40092
|
...m?.parentRunId !== void 0 ? { parentRunId: m.parentRunId } : {},
|
|
39976
40093
|
...m?.parentInstanceId !== void 0 ? { parentInstanceId: m.parentInstanceId } : {},
|
|
39977
40094
|
...m?.idempotencyKey !== void 0 ? { idempotencyKey: m.idempotencyKey } : {},
|
|
40095
|
+
...m?.costCapUsd !== void 0 ? { costCapUsd: m.costCapUsd } : {},
|
|
39978
40096
|
...m?.seed !== void 0 ? { seed: m.seed } : {},
|
|
39979
40097
|
...m?.hosted ? { hosted: true } : {},
|
|
39980
40098
|
...run2.instanceId !== void 0 ? { instanceId: run2.instanceId } : {},
|
|
@@ -47793,6 +47911,7 @@ async function claimRun(deps, ctx) {
|
|
|
47793
47911
|
registry.publish(run2.id, {
|
|
47794
47912
|
type: "coordinator_tag",
|
|
47795
47913
|
parentInstanceId: coordinator.parentInstanceId,
|
|
47914
|
+
...coordinator.costCapUsd !== void 0 ? { costCapUsd: coordinator.costCapUsd } : {},
|
|
47796
47915
|
...unit !== void 0 ? { unit } : {},
|
|
47797
47916
|
...coordinator.branch !== void 0 ? { branch: coordinator.branch } : {},
|
|
47798
47917
|
...coordinator.transportWorkflowId !== void 0 ? { transportWorkflowId: coordinator.transportWorkflowId } : {},
|
|
@@ -57760,10 +57879,12 @@ function carriedCoordinatorTag(row2, events) {
|
|
|
57760
57879
|
const publication = tag?.type === "coordinator_tag" ? tag.publication : void 0;
|
|
57761
57880
|
const transportWorkflowId = tag?.type === "coordinator_tag" ? tag.transportWorkflowId : void 0;
|
|
57762
57881
|
const recovery = tag?.type === "coordinator_tag" ? tag.recovery : void 0;
|
|
57882
|
+
const costCapUsd = (tag?.type === "coordinator_tag" ? tag.costCapUsd : void 0) ?? row2.meta.costCapUsd;
|
|
57763
57883
|
const branch3 = (tag?.type === "coordinator_tag" ? tag.branch : void 0) ?? row2.meta.ref;
|
|
57764
57884
|
return {
|
|
57765
57885
|
parentInstanceId,
|
|
57766
57886
|
idempotencyKey,
|
|
57887
|
+
...costCapUsd !== void 0 ? { costCapUsd } : {},
|
|
57767
57888
|
...branch3 !== void 0 ? { branch: branch3 } : {},
|
|
57768
57889
|
...transportWorkflowId !== void 0 ? { transportWorkflowId } : {},
|
|
57769
57890
|
...recovery !== void 0 ? { recovery } : {},
|
|
@@ -58196,6 +58317,11 @@ __export(dispatcher_exports, {
|
|
|
58196
58317
|
dispatch: () => dispatch,
|
|
58197
58318
|
dispatchClick: () => dispatchClick
|
|
58198
58319
|
});
|
|
58320
|
+
function stripConnectorFooters(text) {
|
|
58321
|
+
let probe = text.trimEnd();
|
|
58322
|
+
while (CONNECTOR_FOOTER_RE.test(probe)) probe = probe.replace(CONNECTOR_FOOTER_RE, "").trimEnd();
|
|
58323
|
+
return probe;
|
|
58324
|
+
}
|
|
58199
58325
|
async function priorDecisionRecord(store, threadKey, repo, taskKey) {
|
|
58200
58326
|
let before;
|
|
58201
58327
|
let beforeId;
|
|
@@ -58468,11 +58594,19 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
58468
58594
|
let resumeRowClosed = false;
|
|
58469
58595
|
let restartRequest;
|
|
58470
58596
|
let releaseLegacyOwnership;
|
|
58597
|
+
let pendingStop;
|
|
58598
|
+
const relayStop = (mode) => {
|
|
58599
|
+
if (registered) {
|
|
58600
|
+
registered.control.requestStop(mode);
|
|
58601
|
+
return;
|
|
58602
|
+
}
|
|
58603
|
+
if (mode === "hard" || pendingStop === void 0) pendingStop = mode;
|
|
58604
|
+
};
|
|
58471
58605
|
const reservationHooks = {
|
|
58472
|
-
onStop:
|
|
58606
|
+
onStop: relayStop,
|
|
58473
58607
|
onFenced: () => {
|
|
58474
58608
|
fencedWhileAttaching = true;
|
|
58475
|
-
|
|
58609
|
+
relayStop("hard");
|
|
58476
58610
|
}
|
|
58477
58611
|
};
|
|
58478
58612
|
try {
|
|
@@ -58480,7 +58614,7 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
58480
58614
|
const typed = parseDirectives(msg.text);
|
|
58481
58615
|
const typedAgent = typed.agent;
|
|
58482
58616
|
const explicitPr = explicitPrOf(msg.text);
|
|
58483
|
-
const shipTaskProbe = typed.text
|
|
58617
|
+
const shipTaskProbe = stripConnectorFooters(typed.text);
|
|
58484
58618
|
const namedShipTask = typedAgent === "ship" && explicitPr ? shipTaskText(shipTaskProbe, explicitPr.repo) : "";
|
|
58485
58619
|
const freshShipTask = namedShipTask !== "" && !/^(?:please\s+)?(?:continue|resume|retry|keep going|carry on|finish)(?:\s+(?:with|on))?(?:\s+(?:it|this|the task|the plan|(?:the\s+)?work|working|(?:the\s+)?review|reviewing))?(?:\s+(?:of|on|for|with))?[.!]?$/i.test(
|
|
58486
58620
|
namedShipTask
|
|
@@ -59096,8 +59230,8 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
59096
59230
|
hooks: {
|
|
59097
59231
|
reservation: reservationHooks,
|
|
59098
59232
|
adopt: {
|
|
59099
|
-
onStop:
|
|
59100
|
-
onFenced: () =>
|
|
59233
|
+
onStop: relayStop,
|
|
59234
|
+
onFenced: () => relayStop("hard")
|
|
59101
59235
|
}
|
|
59102
59236
|
}
|
|
59103
59237
|
};
|
|
@@ -59434,6 +59568,10 @@ async function dispatch(deps, msg, io, opts = {}) {
|
|
|
59434
59568
|
});
|
|
59435
59569
|
const { run: run2, runId: runId3, channelVisibility, liveUrl, events, publishText, publishMeta } = registration;
|
|
59436
59570
|
registered = run2;
|
|
59571
|
+
if (pendingStop) {
|
|
59572
|
+
run2.control.requestStop(pendingStop);
|
|
59573
|
+
pendingStop = void 0;
|
|
59574
|
+
}
|
|
59437
59575
|
if (coordinator) io.runStarted?.({ id: runId3 });
|
|
59438
59576
|
for (const summary of seedNotes)
|
|
59439
59577
|
events.publish({ type: "run_note", kind: "seed", summary: oneLine(summary), at: clock4() });
|
|
@@ -60313,7 +60451,7 @@ async function dispatchClick(deps, click) {
|
|
|
60313
60451
|
activeRuns--;
|
|
60314
60452
|
}
|
|
60315
60453
|
}
|
|
60316
|
-
var activeRuns, FULL_SHA2;
|
|
60454
|
+
var CONNECTOR_FOOTER_RE, activeRuns, FULL_SHA2;
|
|
60317
60455
|
var init_dispatcher = __esm({
|
|
60318
60456
|
"../../src/core/dispatcher.ts"() {
|
|
60319
60457
|
"use strict";
|
|
@@ -60379,6 +60517,7 @@ var init_dispatcher = __esm({
|
|
|
60379
60517
|
init_preflight();
|
|
60380
60518
|
init_types5();
|
|
60381
60519
|
init_decisionRecordReservation();
|
|
60520
|
+
CONNECTOR_FOOTER_RE = /(?:^|\s)(?:(\*{1,3}|_{1,3})Sent using\1|Sent using) ChatGPT Connector \(Local MCP\)\s*$/i;
|
|
60382
60521
|
activeRuns = 0;
|
|
60383
60522
|
FULL_SHA2 = /^[0-9a-f]{40}$/i;
|
|
60384
60523
|
}
|
|
@@ -72663,7 +72802,12 @@ function residentStateTone(state) {
|
|
|
72663
72802
|
}
|
|
72664
72803
|
function residentsFleetTone(records) {
|
|
72665
72804
|
if (records.length === 0) return "grey";
|
|
72666
|
-
const tones = new Set(
|
|
72805
|
+
const tones = new Set(
|
|
72806
|
+
records.map((record4) => {
|
|
72807
|
+
const state = residentStateTone(residentLive(rec(record4)).state);
|
|
72808
|
+
return state === "green" && residentImageReport(record4) === "pending" ? "amber" : state;
|
|
72809
|
+
})
|
|
72810
|
+
);
|
|
72667
72811
|
if (tones.has("red")) return "red";
|
|
72668
72812
|
if (tones.has("amber")) return "amber";
|
|
72669
72813
|
return tones.size === 1 && tones.has("green") ? "green" : "grey";
|
|
@@ -72676,6 +72820,10 @@ function residentLive(record4) {
|
|
|
72676
72820
|
if (typeof live.error === "string") return { ...live, state: "unreachable", reason: live.error };
|
|
72677
72821
|
return { ...live, state: str8(live.state) || "unknown", reason: str8(live.reason) };
|
|
72678
72822
|
}
|
|
72823
|
+
function residentImageReport(record4) {
|
|
72824
|
+
const report2 = residentLive(record4).imageReport;
|
|
72825
|
+
return report2 === "current" || report2 === "pending" ? report2 : "unknown";
|
|
72826
|
+
}
|
|
72679
72827
|
var RESIDENT_SLUG_RE, str8, rec;
|
|
72680
72828
|
var init_residentsModel = __esm({
|
|
72681
72829
|
"../../src/channels/residentsModel.ts"() {
|
|
@@ -72806,7 +72954,8 @@ function serveResidentsFeed(source2, sink, onLive) {
|
|
|
72806
72954
|
reading = true;
|
|
72807
72955
|
void source2.listing().then((r) => {
|
|
72808
72956
|
reading = false;
|
|
72809
|
-
if (!("error" in r))
|
|
72957
|
+
if (!("error" in r))
|
|
72958
|
+
send(frame({ type: "residents", cap: r.cap, count: r.count, draining: r.draining, residents: r.residents }));
|
|
72810
72959
|
if (queued) {
|
|
72811
72960
|
queued = false;
|
|
72812
72961
|
reread();
|
|
@@ -72856,7 +73005,7 @@ function serveResidentsFeed(source2, sink, onLive) {
|
|
|
72856
73005
|
for (const off of watched2.values()) off();
|
|
72857
73006
|
watched2.clear();
|
|
72858
73007
|
});
|
|
72859
|
-
onLive?.();
|
|
73008
|
+
onLive?.(reread);
|
|
72860
73009
|
}
|
|
72861
73010
|
var ATTACH_SPAN;
|
|
72862
73011
|
var init_residentsFeed = __esm({
|
|
@@ -72904,7 +73053,7 @@ async function readListing(client) {
|
|
|
72904
73053
|
return { status: 502, reason: `resident Worker answered ${r.status} to /residents: ${reason2}` };
|
|
72905
73054
|
}
|
|
72906
73055
|
const residents = Array.isArray(r.data.residents) ? r.data.residents : [];
|
|
72907
|
-
return { listing: { cap: r.data.cap, count: r.data.count, residents } };
|
|
73056
|
+
return { listing: { cap: r.data.cap, count: r.data.count, draining: r.data.draining, residents } };
|
|
72908
73057
|
}
|
|
72909
73058
|
function createResidentsViewHandler(deps) {
|
|
72910
73059
|
const { client, page: page2, runs } = deps;
|
|
@@ -72936,7 +73085,11 @@ function createResidentsViewHandler(deps) {
|
|
|
72936
73085
|
}
|
|
72937
73086
|
},
|
|
72938
73087
|
nodeSseSink(req, res),
|
|
72939
|
-
() =>
|
|
73088
|
+
(reread) => {
|
|
73089
|
+
startSseHeartbeat(req, res);
|
|
73090
|
+
const timer = setInterval(reread, RESIDENT_LISTING_POLL_MS);
|
|
73091
|
+
req.on("close", () => clearInterval(timer));
|
|
73092
|
+
}
|
|
72940
73093
|
);
|
|
72941
73094
|
return true;
|
|
72942
73095
|
}
|
|
@@ -72964,6 +73117,7 @@ function createResidentsViewHandler(deps) {
|
|
|
72964
73117
|
page: "residents",
|
|
72965
73118
|
cap: listing.cap,
|
|
72966
73119
|
count: listing.count,
|
|
73120
|
+
draining: listing.draining,
|
|
72967
73121
|
residents: listing.residents,
|
|
72968
73122
|
now: now(),
|
|
72969
73123
|
runs: live
|
|
@@ -72991,6 +73145,7 @@ var init_residentsView = __esm({
|
|
|
72991
73145
|
"../../src/channels/residentsView.ts"() {
|
|
72992
73146
|
"use strict";
|
|
72993
73147
|
init_authz();
|
|
73148
|
+
init_budgets();
|
|
72994
73149
|
init_requestTrace();
|
|
72995
73150
|
init_sse();
|
|
72996
73151
|
init_viewer();
|
|
@@ -74934,6 +75089,9 @@ async function reclaimRuns(opts) {
|
|
|
74934
75089
|
const recorded = row2.state.finalStatus;
|
|
74935
75090
|
status3 = typeof recorded === "string" && TERMINAL.has(recorded) ? recorded : "completed";
|
|
74936
75091
|
why = "replied before the previous generation died";
|
|
75092
|
+
} else if (row2.stop === "hard" && !row2.meta.hosted && hostingOf(row2.state) === void 0) {
|
|
75093
|
+
status3 = "stopped_hard";
|
|
75094
|
+
why = "hard stop requested before the previous generation ended";
|
|
74937
75095
|
} else if (run2.reclaimedFrom === "attaching") {
|
|
74938
75096
|
if (typeof row2.meta.request === "object" && row2.meta.request !== null) {
|
|
74939
75097
|
outcome.resumable.push({ kind: "restart", row: row2, reclaimedFrom: "attaching", inbox: run2.inbox });
|
|
@@ -76680,6 +76838,7 @@ ${foldThreadEvents(folded)}` };
|
|
|
76680
76838
|
const tag = {
|
|
76681
76839
|
parentInstanceId: instance.id,
|
|
76682
76840
|
idempotencyKey: key,
|
|
76841
|
+
...instance.grant?.costCapUsd !== void 0 ? { costCapUsd: instance.grant.costCapUsd } : {},
|
|
76683
76842
|
...(row2?.branch ?? instance.branch) !== void 0 ? { branch: row2?.branch ?? instance.branch } : {},
|
|
76684
76843
|
...row2?.recovery !== void 0 ? { transportWorkflowId: row2.recovery.workflowId } : {},
|
|
76685
76844
|
...row2?.recovery !== void 0 && row2.publication !== void 0 ? {
|