@coreplane/switchboard 1.221.1 → 1.223.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/config/config.example.yaml +14 -0
- 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/web/dist/.vite/manifest.json +20 -20
- package/dist/assets/web/dist/assets/CostsPage-C-ximW1N.js +2 -0
- package/dist/assets/web/dist/assets/{ResidentDetailPage-iqyj3Kpt.js → ResidentDetailPage-BTg4oFcn.js} +1 -1
- package/dist/assets/web/dist/assets/{ResidentsIndexPage-BiECMcX5.js → ResidentsIndexPage-Dr2qkjKI.js} +1 -1
- package/dist/assets/web/dist/assets/{RunRoutePage-YCWYYZkj.js → RunRoutePage-CTbnfyBQ.js} +3 -3
- package/dist/assets/web/dist/assets/{RunsIndexPage-BX6231bA.js → RunsIndexPage-DEkZXNnw.js} +1 -1
- package/dist/assets/web/dist/assets/{ScheduledPage-ibRdZaDS.js → ScheduledPage-wA7HE6UW.js} +1 -1
- package/dist/assets/web/dist/assets/{StatusDot-W2x3d782.js → StatusDot-7ojvQlTS.js} +1 -1
- package/dist/assets/web/dist/assets/{Tooltip-BLRVgG37.js → Tooltip-Cx88lWUW.js} +1 -1
- package/dist/assets/web/dist/assets/{dist-C3C34ZMu.js → dist-B85zXO-d.js} +1 -1
- package/dist/assets/web/dist/assets/{main-B9dN-Wec.js → main-BdoqEBpN.js} +2 -2
- package/dist/assets/web/dist/assets/main-C1tNx19B.css +1 -0
- package/dist/cli.js +175 -12
- package/package.json +1 -1
- package/dist/assets/web/dist/assets/CostsPage-DGSE48l1.js +0 -1
- package/dist/assets/web/dist/assets/main-DCH3Mezs.css +0 -1
package/dist/cli.js
CHANGED
|
@@ -2858,8 +2858,24 @@ function validateConfig(cfg) {
|
|
|
2858
2858
|
if (cfg.routing !== void 0) validateRouting(cfg.routing, cfg.providers);
|
|
2859
2859
|
if (cfg.artifacts !== void 0) validateArtifacts(cfg.artifacts);
|
|
2860
2860
|
if (cfg.harness !== void 0) validateHarness(cfg.harness);
|
|
2861
|
+
if (cfg.pi !== void 0) validatePi(cfg.pi);
|
|
2861
2862
|
validateDashboardConfig(cfg.dashboard);
|
|
2862
2863
|
}
|
|
2864
|
+
function validatePi(pi) {
|
|
2865
|
+
if (typeof pi !== "object" || pi === null || Array.isArray(pi)) throw new Error("config.yaml: pi must be a mapping");
|
|
2866
|
+
for (const key of unknownKeys2(pi, PI_KEYS)) throw new Error(`config.yaml: pi.${key} is not a known key`);
|
|
2867
|
+
const { compaction } = pi;
|
|
2868
|
+
if (compaction === void 0) return;
|
|
2869
|
+
if (typeof compaction !== "object" || compaction === null || Array.isArray(compaction))
|
|
2870
|
+
throw new Error("config.yaml: pi.compaction must be a mapping");
|
|
2871
|
+
for (const key of unknownKeys2(compaction, PI_COMPACTION_KEYS))
|
|
2872
|
+
throw new Error(`config.yaml: pi.compaction.${key} is not a known key`);
|
|
2873
|
+
for (const key of Object.keys(PI_COMPACTION_KEYS)) {
|
|
2874
|
+
const value = compaction[key];
|
|
2875
|
+
if (value !== void 0 && (typeof value !== "number" || !Number.isInteger(value) || value <= 0))
|
|
2876
|
+
throw new Error(`config.yaml: pi.compaction.${key} must be a positive integer (tokens)`);
|
|
2877
|
+
}
|
|
2878
|
+
}
|
|
2863
2879
|
function validateHarness(harness) {
|
|
2864
2880
|
if (typeof harness !== "object" || harness === null || Array.isArray(harness))
|
|
2865
2881
|
throw new Error("config.yaml: harness must be a mapping of preset to harness (native | pi)");
|
|
@@ -2977,7 +2993,7 @@ function validateRuntimeOverrides(ro) {
|
|
|
2977
2993
|
}
|
|
2978
2994
|
}
|
|
2979
2995
|
}
|
|
2980
|
-
var MAX_INSTRUCTIONS_LENGTH, CONFIG_KEYS, SELF_IMPROVEMENT_KEYS, BOUNDARY_KEYS, MIN_BOUNDARY_MINUTES, ROUTE_ANSWER_MODES, ROUTING_KEYS, SHIP_KEYS, SPAWN_KEYS;
|
|
2996
|
+
var MAX_INSTRUCTIONS_LENGTH, CONFIG_KEYS, SELF_IMPROVEMENT_KEYS, BOUNDARY_KEYS, MIN_BOUNDARY_MINUTES, PI_KEYS, PI_COMPACTION_KEYS, ROUTE_ANSWER_MODES, ROUTING_KEYS, SHIP_KEYS, SPAWN_KEYS;
|
|
2981
2997
|
var init_validate = __esm({
|
|
2982
2998
|
"../../src/config/validate.ts"() {
|
|
2983
2999
|
"use strict";
|
|
@@ -3012,6 +3028,7 @@ var init_validate = __esm({
|
|
|
3012
3028
|
spawn: true,
|
|
3013
3029
|
routing: true,
|
|
3014
3030
|
harness: true,
|
|
3031
|
+
pi: true,
|
|
3015
3032
|
slack: true,
|
|
3016
3033
|
runHistory: true,
|
|
3017
3034
|
runtimeOverrides: true,
|
|
@@ -3026,6 +3043,8 @@ var init_validate = __esm({
|
|
|
3026
3043
|
};
|
|
3027
3044
|
BOUNDARY_KEYS = { maxMinutes: true, maxIdentity: true, machines: true };
|
|
3028
3045
|
MIN_BOUNDARY_MINUTES = 2;
|
|
3046
|
+
PI_KEYS = { compaction: true };
|
|
3047
|
+
PI_COMPACTION_KEYS = { reserveTokens: true, keepRecentTokens: true };
|
|
3029
3048
|
ROUTE_ANSWER_MODES = ["tool", "text"];
|
|
3030
3049
|
ROUTING_KEYS = { auto: true, model: true, answer: true };
|
|
3031
3050
|
SHIP_KEYS = { maxRounds: true, maxMinutes: true };
|
|
@@ -11840,7 +11859,10 @@ function buildCostReport(group, cfg, usage, llm, range) {
|
|
|
11840
11859
|
if (row.workflowName in workflowNames) workflowsUsd += usd;
|
|
11841
11860
|
}
|
|
11842
11861
|
byResource.workflows += workflowsUsd;
|
|
11843
|
-
const
|
|
11862
|
+
const llmRows = llm && cfg.anthropicWorkspaceId ? llm.filter((r) => r.date === date && r.workspaceId === cfg.anthropicWorkspaceId) : [];
|
|
11863
|
+
const llmUsd2 = llmRows.reduce((s, r) => s + r.amountUsd, 0);
|
|
11864
|
+
const llmEstimated = llmRows.some((r) => r.estimated === true);
|
|
11865
|
+
const llmUnpricedTokens = llmRows.reduce((s, r) => s + (r.unpricedTokens ?? 0), 0);
|
|
11844
11866
|
const cloudUsd2 = Object.values(containers).reduce((s, c) => s + c.total, 0) + Object.values(durableObjects).reduce((s, v) => s + v, 0) + doRequestsUsd + doRowsUsd + doStorageUsd + workersUsd + r2Usd + workflowsUsd;
|
|
11845
11867
|
return {
|
|
11846
11868
|
date,
|
|
@@ -11854,6 +11876,8 @@ function buildCostReport(group, cfg, usage, llm, range) {
|
|
|
11854
11876
|
workflowsUsd,
|
|
11855
11877
|
cloudUsd: cloudUsd2,
|
|
11856
11878
|
llmUsd: llmUsd2,
|
|
11879
|
+
llmEstimated,
|
|
11880
|
+
llmUnpricedTokens,
|
|
11857
11881
|
total: cloudUsd2 + llmUsd2
|
|
11858
11882
|
};
|
|
11859
11883
|
});
|
|
@@ -11870,6 +11894,20 @@ function buildCostReport(group, cfg, usage, llm, range) {
|
|
|
11870
11894
|
attribution
|
|
11871
11895
|
};
|
|
11872
11896
|
}
|
|
11897
|
+
function anthropicPriceOf(modelId) {
|
|
11898
|
+
const exact = ANTHROPIC_PRICES[modelId];
|
|
11899
|
+
if (exact) return exact;
|
|
11900
|
+
for (const family of Object.keys(ANTHROPIC_PRICES)) {
|
|
11901
|
+
if (modelId.startsWith(family) && DATED_RELEASE_SUFFIX.test(modelId.slice(family.length)))
|
|
11902
|
+
return ANTHROPIC_PRICES[family];
|
|
11903
|
+
}
|
|
11904
|
+
return void 0;
|
|
11905
|
+
}
|
|
11906
|
+
function anthropicTokensCostUsd(modelId, t) {
|
|
11907
|
+
const p = anthropicPriceOf(modelId);
|
|
11908
|
+
if (!p) return void 0;
|
|
11909
|
+
return (t.uncachedInput * p.input + t.output * p.output + t.cacheRead * p.cacheRead + t.cacheWrite5m * p.cacheWrite5m + t.cacheWrite1h * p.cacheWrite1h) / 1e6;
|
|
11910
|
+
}
|
|
11873
11911
|
function resolveRange(daysParam, now = new Date(systemClock())) {
|
|
11874
11912
|
const parsed = daysParam === null ? NaN : Number(daysParam);
|
|
11875
11913
|
const days = Number.isInteger(parsed) ? Math.min(MAX_DAYS, Math.max(1, parsed)) : DEFAULT_DAYS;
|
|
@@ -11899,7 +11937,7 @@ function createCostsService(cfg, cloudflare, llm, now = () => new Date(systemClo
|
|
|
11899
11937
|
}
|
|
11900
11938
|
};
|
|
11901
11939
|
}
|
|
11902
|
-
var DEFAULT_CF_TOKEN_ENV, DEFAULT_ANTHROPIC_ADMIN_ENV, CLOUDFLARE_PRICES, GIB, GB, DAYS_PER_MONTH, TEMPLATE_BUCKET_NAMES, TEMPLATE_WORKFLOW_NAMES, emptySplit, DEFAULT_DAYS, MAX_DAYS, NullLlmCostSource, CF_GRAPHQL, CF_USAGE_QUERY, WORKFLOW_STEP_EVENTS, num2, str2, CloudflareGraphqlUsageSource, ANTHROPIC_COST_REPORT, ANTHROPIC_VERSION, MAX_COST_PAGES, AnthropicCostReportSource, COSTS_OFF_MESSAGE, NullCostsService;
|
|
11940
|
+
var DEFAULT_CF_TOKEN_ENV, DEFAULT_ANTHROPIC_ADMIN_ENV, CLOUDFLARE_PRICES, GIB, GB, DAYS_PER_MONTH, TEMPLATE_BUCKET_NAMES, TEMPLATE_WORKFLOW_NAMES, emptySplit, ANTHROPIC_PRICES, DATED_RELEASE_SUFFIX, DEFAULT_DAYS, MAX_DAYS, NullLlmCostSource, CF_GRAPHQL, CF_USAGE_QUERY, WORKFLOW_STEP_EVENTS, num2, str2, CloudflareGraphqlUsageSource, ANTHROPIC_COST_REPORT, ANTHROPIC_USAGE_REPORT, ANTHROPIC_VERSION, MAX_COST_PAGES, MAX_ESTIMATED_DAYS, AnthropicCostReportSource, COSTS_OFF_MESSAGE, NullCostsService;
|
|
11903
11941
|
var init_costs = __esm({
|
|
11904
11942
|
"../../src/core/costs.ts"() {
|
|
11905
11943
|
"use strict";
|
|
@@ -11949,6 +11987,26 @@ var init_costs = __esm({
|
|
|
11949
11987
|
r2: 0,
|
|
11950
11988
|
workflows: 0
|
|
11951
11989
|
});
|
|
11990
|
+
ANTHROPIC_PRICES = {
|
|
11991
|
+
"claude-fable-5-1": { input: 10, output: 50, cacheWrite5m: 12.5, cacheWrite1h: 20, cacheRead: 0.25 },
|
|
11992
|
+
"claude-mythos-5-1": { input: 10, output: 50, cacheWrite5m: 12.5, cacheWrite1h: 20, cacheRead: 0.25 },
|
|
11993
|
+
"claude-fable-5": { input: 10, output: 50, cacheWrite5m: 12.5, cacheWrite1h: 20, cacheRead: 1 },
|
|
11994
|
+
"claude-mythos-5": { input: 10, output: 50, cacheWrite5m: 12.5, cacheWrite1h: 20, cacheRead: 1 },
|
|
11995
|
+
"claude-opus-5": { input: 5, output: 25, cacheWrite5m: 6.25, cacheWrite1h: 10, cacheRead: 0.5 },
|
|
11996
|
+
"claude-opus-4-8": { input: 5, output: 25, cacheWrite5m: 6.25, cacheWrite1h: 10, cacheRead: 0.5 },
|
|
11997
|
+
"claude-opus-4-7": { input: 5, output: 25, cacheWrite5m: 6.25, cacheWrite1h: 10, cacheRead: 0.5 },
|
|
11998
|
+
"claude-opus-4-6": { input: 5, output: 25, cacheWrite5m: 6.25, cacheWrite1h: 10, cacheRead: 0.5 },
|
|
11999
|
+
"claude-opus-4-5": { input: 5, output: 25, cacheWrite5m: 6.25, cacheWrite1h: 10, cacheRead: 0.5 },
|
|
12000
|
+
"claude-opus-4-1": { input: 15, output: 75, cacheWrite5m: 18.75, cacheWrite1h: 30, cacheRead: 1.5 },
|
|
12001
|
+
"claude-opus-4": { input: 15, output: 75, cacheWrite5m: 18.75, cacheWrite1h: 30, cacheRead: 1.5 },
|
|
12002
|
+
"claude-sonnet-5": { input: 2, output: 10, cacheWrite5m: 2.5, cacheWrite1h: 4, cacheRead: 0.2 },
|
|
12003
|
+
"claude-sonnet-4-6": { input: 3, output: 15, cacheWrite5m: 3.75, cacheWrite1h: 6, cacheRead: 0.3 },
|
|
12004
|
+
"claude-sonnet-4-5": { input: 3, output: 15, cacheWrite5m: 3.75, cacheWrite1h: 6, cacheRead: 0.3 },
|
|
12005
|
+
"claude-sonnet-4": { input: 3, output: 15, cacheWrite5m: 3.75, cacheWrite1h: 6, cacheRead: 0.3 },
|
|
12006
|
+
"claude-haiku-4-5": { input: 1, output: 5, cacheWrite5m: 1.25, cacheWrite1h: 2, cacheRead: 0.1 },
|
|
12007
|
+
"claude-haiku-3-5": { input: 0.8, output: 4, cacheWrite5m: 1, cacheWrite1h: 1.6, cacheRead: 0.08 }
|
|
12008
|
+
};
|
|
12009
|
+
DATED_RELEASE_SUFFIX = /^-\d{8}$/;
|
|
11952
12010
|
DEFAULT_DAYS = 30;
|
|
11953
12011
|
MAX_DAYS = 90;
|
|
11954
12012
|
NullLlmCostSource = class {
|
|
@@ -12062,8 +12120,10 @@ var init_costs = __esm({
|
|
|
12062
12120
|
}
|
|
12063
12121
|
};
|
|
12064
12122
|
ANTHROPIC_COST_REPORT = "https://api.anthropic.com/v1/organizations/cost_report";
|
|
12123
|
+
ANTHROPIC_USAGE_REPORT = "https://api.anthropic.com/v1/organizations/usage_report/messages";
|
|
12065
12124
|
ANTHROPIC_VERSION = "2023-06-01";
|
|
12066
12125
|
MAX_COST_PAGES = 20;
|
|
12126
|
+
MAX_ESTIMATED_DAYS = 3;
|
|
12067
12127
|
AnthropicCostReportSource = class {
|
|
12068
12128
|
adminKey;
|
|
12069
12129
|
fetchImpl;
|
|
@@ -12072,7 +12132,81 @@ var init_costs = __esm({
|
|
|
12072
12132
|
this.fetchImpl = opts.fetchImpl ?? fetch;
|
|
12073
12133
|
}
|
|
12074
12134
|
async fetchDailyCost(range) {
|
|
12135
|
+
const report2 = await this.fetchCostReport(range);
|
|
12136
|
+
const open2 = eachDay(range).filter((date) => report2.closedThrough === null || date > report2.closedThrough);
|
|
12137
|
+
const estimated = await Promise.all(open2.slice(-MAX_ESTIMATED_DAYS).map((date) => this.estimateDay(date)));
|
|
12138
|
+
return [...report2.rows, ...estimated.flat()];
|
|
12139
|
+
}
|
|
12140
|
+
/** The hourly usage report for one day, summed per workspace × model and
|
|
12141
|
+
* priced at list; one row per workspace, `estimated`, with the tokens of
|
|
12142
|
+
* any model the price table does not know reported as `unpricedTokens`. */
|
|
12143
|
+
async estimateDay(date) {
|
|
12144
|
+
const perWorkspace = /* @__PURE__ */ new Map();
|
|
12145
|
+
let page2 = null;
|
|
12146
|
+
for (let i = 0; ; i++) {
|
|
12147
|
+
if (i >= MAX_COST_PAGES)
|
|
12148
|
+
throw new Error(
|
|
12149
|
+
`anthropic usage_report: more than ${MAX_COST_PAGES} pages for ${date}; refusing a truncated estimate`
|
|
12150
|
+
);
|
|
12151
|
+
const url = new URL(ANTHROPIC_USAGE_REPORT);
|
|
12152
|
+
url.searchParams.set("starting_at", `${date}T00:00:00Z`);
|
|
12153
|
+
url.searchParams.set("ending_at", `${addDays2(date, 1)}T00:00:00Z`);
|
|
12154
|
+
url.searchParams.set("bucket_width", "1h");
|
|
12155
|
+
url.searchParams.append("group_by[]", "workspace_id");
|
|
12156
|
+
url.searchParams.append("group_by[]", "model");
|
|
12157
|
+
url.searchParams.set("limit", "24");
|
|
12158
|
+
if (page2) url.searchParams.set("page", page2);
|
|
12159
|
+
const res = await this.fetchImpl(url.toString(), {
|
|
12160
|
+
headers: { "x-api-key": this.adminKey, "anthropic-version": ANTHROPIC_VERSION }
|
|
12161
|
+
});
|
|
12162
|
+
if (res.status !== 200)
|
|
12163
|
+
throw new Error(`anthropic usage_report ${res.status}: ${(await res.text()).slice(0, 300)}`);
|
|
12164
|
+
const body = await res.json();
|
|
12165
|
+
for (const bucket of body.data ?? []) {
|
|
12166
|
+
for (const r of bucket.results ?? []) {
|
|
12167
|
+
const ws = r.workspace_id ?? null;
|
|
12168
|
+
const byModel = perWorkspace.get(ws) ?? /* @__PURE__ */ new Map();
|
|
12169
|
+
const model = str2(r.model);
|
|
12170
|
+
const t = byModel.get(model) ?? {
|
|
12171
|
+
uncachedInput: 0,
|
|
12172
|
+
output: 0,
|
|
12173
|
+
cacheRead: 0,
|
|
12174
|
+
cacheWrite5m: 0,
|
|
12175
|
+
cacheWrite1h: 0
|
|
12176
|
+
};
|
|
12177
|
+
t.uncachedInput += num2(r.uncached_input_tokens);
|
|
12178
|
+
t.output += num2(r.output_tokens);
|
|
12179
|
+
t.cacheRead += num2(r.cache_read_input_tokens);
|
|
12180
|
+
t.cacheWrite5m += num2(r.cache_creation?.ephemeral_5m_input_tokens);
|
|
12181
|
+
t.cacheWrite1h += num2(r.cache_creation?.ephemeral_1h_input_tokens);
|
|
12182
|
+
byModel.set(model, t);
|
|
12183
|
+
perWorkspace.set(ws, byModel);
|
|
12184
|
+
}
|
|
12185
|
+
}
|
|
12186
|
+
if (!body.has_more || !body.next_page) break;
|
|
12187
|
+
page2 = body.next_page;
|
|
12188
|
+
}
|
|
12189
|
+
const out = [];
|
|
12190
|
+
for (const [workspaceId, byModel] of perWorkspace) {
|
|
12191
|
+
let amountUsd = 0;
|
|
12192
|
+
let unpricedTokens = 0;
|
|
12193
|
+
for (const [model, t] of byModel) {
|
|
12194
|
+
const usd = anthropicTokensCostUsd(model, t);
|
|
12195
|
+
if (usd === void 0)
|
|
12196
|
+
unpricedTokens += t.uncachedInput + t.output + t.cacheRead + t.cacheWrite5m + t.cacheWrite1h;
|
|
12197
|
+
else amountUsd += usd;
|
|
12198
|
+
}
|
|
12199
|
+
out.push({ date, workspaceId, amountUsd, estimated: true, unpricedTokens });
|
|
12200
|
+
}
|
|
12201
|
+
return out;
|
|
12202
|
+
}
|
|
12203
|
+
/** Every page of the cost report for the range, plus the last day it has a
|
|
12204
|
+
* bucket for (null when it has none in the range). */
|
|
12205
|
+
async fetchCostReport(range) {
|
|
12075
12206
|
const rows = [];
|
|
12207
|
+
let closedThrough = null;
|
|
12208
|
+
const endExclusive = range.partialLastDay ? range.to : addDays2(range.to, 1);
|
|
12209
|
+
if (range.from >= endExclusive) return { rows, closedThrough };
|
|
12076
12210
|
let page2 = null;
|
|
12077
12211
|
for (let i = 0; ; i++) {
|
|
12078
12212
|
if (i >= MAX_COST_PAGES)
|
|
@@ -12081,7 +12215,7 @@ var init_costs = __esm({
|
|
|
12081
12215
|
);
|
|
12082
12216
|
const url = new URL(ANTHROPIC_COST_REPORT);
|
|
12083
12217
|
url.searchParams.set("starting_at", `${range.from}T00:00:00Z`);
|
|
12084
|
-
url.searchParams.set("ending_at", `${
|
|
12218
|
+
url.searchParams.set("ending_at", `${endExclusive}T00:00:00Z`);
|
|
12085
12219
|
url.searchParams.set("bucket_width", "1d");
|
|
12086
12220
|
url.searchParams.append("group_by[]", "workspace_id");
|
|
12087
12221
|
url.searchParams.set("limit", "31");
|
|
@@ -12094,6 +12228,7 @@ var init_costs = __esm({
|
|
|
12094
12228
|
const body = await res.json();
|
|
12095
12229
|
for (const bucket of body.data ?? []) {
|
|
12096
12230
|
const date = str2(bucket.starting_at).slice(0, 10);
|
|
12231
|
+
if (closedThrough === null || date > closedThrough) closedThrough = date;
|
|
12097
12232
|
for (const r of bucket.results ?? []) {
|
|
12098
12233
|
if (r.currency !== "USD") throw new Error(`anthropic cost_report: unexpected currency ${r.currency ?? "?"}`);
|
|
12099
12234
|
const cents = Number(r.amount);
|
|
@@ -12104,7 +12239,7 @@ var init_costs = __esm({
|
|
|
12104
12239
|
if (!body.has_more || !body.next_page) break;
|
|
12105
12240
|
page2 = body.next_page;
|
|
12106
12241
|
}
|
|
12107
|
-
return rows;
|
|
12242
|
+
return { rows, closedThrough };
|
|
12108
12243
|
}
|
|
12109
12244
|
};
|
|
12110
12245
|
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.";
|
|
@@ -30978,12 +31113,18 @@ function piSystemPrompt(spec) {
|
|
|
30978
31113
|
${harnessPromptNote(spec.relayTools, spec.identity)}
|
|
30979
31114
|
`;
|
|
30980
31115
|
}
|
|
30981
|
-
function piSettingsJson() {
|
|
30982
|
-
|
|
31116
|
+
function piSettingsJson(compaction) {
|
|
31117
|
+
const settings = { defaultProjectTrust: "never", checkForUpdates: false };
|
|
31118
|
+
const thresholds = {
|
|
31119
|
+
...compaction?.reserveTokens !== void 0 ? { reserveTokens: compaction.reserveTokens } : {},
|
|
31120
|
+
...compaction?.keepRecentTokens !== void 0 ? { keepRecentTokens: compaction.keepRecentTokens } : {}
|
|
31121
|
+
};
|
|
31122
|
+
if (Object.keys(thresholds).length > 0) settings.compaction = thresholds;
|
|
31123
|
+
return JSON.stringify(settings, null, 2) + "\n";
|
|
30983
31124
|
}
|
|
30984
31125
|
function piLaunchFiles(spec) {
|
|
30985
31126
|
return [
|
|
30986
|
-
{ path: `${spec.paths.agentDir}/settings.json`, content: piSettingsJson() },
|
|
31127
|
+
{ path: `${spec.paths.agentDir}/settings.json`, content: piSettingsJson(spec.compaction) },
|
|
30987
31128
|
{ path: `${spec.paths.agentDir}/models.json`, content: piModelsJson(spec) },
|
|
30988
31129
|
{ path: `${spec.paths.agentDir}/SYSTEM.md`, content: piSystemPrompt(spec) },
|
|
30989
31130
|
{ path: spec.paths.extension, content: PI_EXTENSION_SOURCE }
|
|
@@ -32096,6 +32237,9 @@ function promptOf(seed) {
|
|
|
32096
32237
|
}
|
|
32097
32238
|
return { message: texts.join("\n\n"), ...images.length > 0 ? { images } : {} };
|
|
32098
32239
|
}
|
|
32240
|
+
function settlementText(s) {
|
|
32241
|
+
return s.action === "synthetic" ? s.text : `The bot restarted while this ${s.toolUse.name} call was in flight; its result was lost \u2014 re-check its effects before re-running it.`;
|
|
32242
|
+
}
|
|
32099
32243
|
function settlementResults(settlements) {
|
|
32100
32244
|
if (settlements.length === 0) return void 0;
|
|
32101
32245
|
return {
|
|
@@ -32103,11 +32247,14 @@ function settlementResults(settlements) {
|
|
|
32103
32247
|
content: settlements.map((s) => ({
|
|
32104
32248
|
type: "tool_result",
|
|
32105
32249
|
toolUseId: s.toolUse.id,
|
|
32106
|
-
content: s
|
|
32250
|
+
content: settlementText(s),
|
|
32107
32251
|
isError: true
|
|
32108
32252
|
}))
|
|
32109
32253
|
};
|
|
32110
32254
|
}
|
|
32255
|
+
function settlementAnswer(s) {
|
|
32256
|
+
return { content: [{ type: "text", text: settlementText(s) }], isError: true };
|
|
32257
|
+
}
|
|
32111
32258
|
async function runPiHarness(deps, run2) {
|
|
32112
32259
|
const { container, clock: clock3 } = deps;
|
|
32113
32260
|
const now = () => clock3();
|
|
@@ -32184,6 +32331,8 @@ async function runPiHarness(deps, run2) {
|
|
|
32184
32331
|
}
|
|
32185
32332
|
};
|
|
32186
32333
|
const forget = deps.registry.register(live);
|
|
32334
|
+
const calls = deps.registry.calls(run2.runId);
|
|
32335
|
+
for (const s of run2.resume?.settlements ?? []) calls?.settle(s.toolUse.id, settlementAnswer(s));
|
|
32187
32336
|
let pid;
|
|
32188
32337
|
let transport;
|
|
32189
32338
|
let facts2;
|
|
@@ -32228,9 +32377,10 @@ async function runPiHarness(deps, run2) {
|
|
|
32228
32377
|
offset: recorded.logOffset
|
|
32229
32378
|
});
|
|
32230
32379
|
catchingUp = true;
|
|
32380
|
+
const inFlight = run2.resume?.settlements.length ?? 0;
|
|
32231
32381
|
note(
|
|
32232
32382
|
"resumed",
|
|
32233
|
-
`resumed after a restart: pi still runs in the container (pid ${pid}); continuing its session with ${Math.round(remainingMs / 6e4)} min of budget left`
|
|
32383
|
+
`resumed after a restart: pi still runs in the container (pid ${pid}); continuing its session with ${Math.round(remainingMs / 6e4)} min of budget left` + (inFlight > 0 ? ` \u2014 ${inFlight} call(s) were in flight, each answered with a restart note if pi asks for it again` : "")
|
|
32234
32384
|
);
|
|
32235
32385
|
} else {
|
|
32236
32386
|
paths = await container.makeRoot(run2.runId);
|
|
@@ -32245,7 +32395,8 @@ async function runPiHarness(deps, run2) {
|
|
|
32245
32395
|
...run2.effort ? { effort: run2.effort } : {},
|
|
32246
32396
|
identity: run2.agent.identity,
|
|
32247
32397
|
system: run2.system,
|
|
32248
|
-
relayTools: run2.tools.map((t) => t.name)
|
|
32398
|
+
relayTools: run2.tools.map((t) => t.name),
|
|
32399
|
+
...deps.compaction ? { compaction: deps.compaction } : {}
|
|
32249
32400
|
};
|
|
32250
32401
|
let session;
|
|
32251
32402
|
if (run2.resume) {
|
|
@@ -32303,7 +32454,9 @@ async function runPiHarness(deps, run2) {
|
|
|
32303
32454
|
}
|
|
32304
32455
|
transport.send({ id: "retry", type: "set_auto_retry", enabled: false });
|
|
32305
32456
|
transport.send({ id: "state", type: "get_state" });
|
|
32306
|
-
if (reattached
|
|
32457
|
+
if (reattached)
|
|
32458
|
+
transport.send({ id: "prompt", type: "prompt", message: CONTINUE_PROMPT, streamingBehavior: "steer" });
|
|
32459
|
+
else if (run2.resume) transport.send({ id: "prompt", type: "prompt", message: CONTINUE_PROMPT });
|
|
32307
32460
|
else transport.send({ id: "prompt", type: "prompt", ...promptOf(run2.messages) });
|
|
32308
32461
|
let warned = false;
|
|
32309
32462
|
let settled = false;
|
|
@@ -33457,6 +33610,9 @@ async function runLoop2(deps, ctx) {
|
|
|
33457
33610
|
harnessUrl,
|
|
33458
33611
|
registry: deps.harness.registry,
|
|
33459
33612
|
...deps.runBearers ? { bearers: deps.runBearers } : {},
|
|
33613
|
+
// The deployment's compaction thresholds ride into pi's settings for
|
|
33614
|
+
// every run on pi (harness-pi item 4); absent, pi's defaults stand.
|
|
33615
|
+
...deps.config.config.pi?.compaction ? { compaction: deps.config.config.pi.compaction } : {},
|
|
33460
33616
|
clock: clock3,
|
|
33461
33617
|
sleep: (ms) => new Promise((r) => setTimeout(r, ms))
|
|
33462
33618
|
},
|
|
@@ -42968,6 +43124,13 @@ var init_relay = __esm({
|
|
|
42968
43124
|
}
|
|
42969
43125
|
return answer;
|
|
42970
43126
|
}
|
|
43127
|
+
/** The call's answer is known before it is asked (harness-pi item 8): the
|
|
43128
|
+
* record's settlement for a call in flight when the previous generation
|
|
43129
|
+
* died, whose extension asks again with the same id. Every ask reads it and
|
|
43130
|
+
* the tool never runs; a call already joined keeps the answer it has. */
|
|
43131
|
+
settle(callId, answer) {
|
|
43132
|
+
if (!this.calls.has(callId)) this.calls.set(callId, Promise.resolve(answer));
|
|
43133
|
+
}
|
|
42971
43134
|
end() {
|
|
42972
43135
|
this.ending.abort();
|
|
42973
43136
|
this.calls.clear();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coreplane/switchboard",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.223.0",
|
|
4
4
|
"description": "Mention it in Slack and an agent reviews the PR, ships the fix, or answers the question — on the model you choose, with its tools running where you decide.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://openswitchboard.dev",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./AppShell-lYVcj-k7.js";import{Ci as t,Lr as n,Xt as r,_n as i,cn as a,gn as o,ir as s,ln as c,on as l,r as u,sn as d,un as f,ur as p,vi as m,wi as h,xi as g,yn as _}from"./seed-DeKSHrt2.js";var v=`Durable Objects`,y=`Workers · storage · R2`,b=`LLM (Anthropic)`,x=(e,t=2)=>`$${e.toFixed(t)}`,S=e=>e.workersUsd+e.doRowsUsd+e.doStorageUsd+e.r2Usd+e.workflowsUsd;function ee(e){let t=[];for(let n of e.days)for(let e of Object.keys(n.containers))t.includes(e)||t.push(e);return e.days.some(e=>Object.keys(e.durableObjects).length>0)&&t.push(v),e.days.some(e=>S(e)>0)&&t.push(y),e.llmAvailable&&t.push(b),t}function C(e,t){return t===`Durable Objects`?Object.values(e.durableObjects).reduce((e,t)=>e+t,0)+e.doRequestsUsd:t===`Workers · storage · R2`?S(e):t===`LLM (Anthropic)`?e.llmUsd:e.containers[t]?.total??0}function w(e){let t=e.range.partialLastDay?e.days.slice(0,-1):e.days,n=t[t.length-1],r=t.slice(-7),i=r.length?r.reduce((e,t)=>e+t.total,0)/r.length:0,a=e.totals.total>0?Math.round(e.totals.llmUsd/e.totals.total*100):0,o=e.account.cloudUsd>0?Math.round(e.totals.cloudUsd/e.account.cloudUsd*100):0;return{...n?{yesterday:{date:n.date,total:n.total}}:{},avg7:i,projectedMonth:i*30.4,llmShare:a,accountShare:o}}function T(e,t){let n={t:12,r:12,b:30,l:48},r=960-n.l-n.r,i=260-n.t-n.b,a=e.days,o=Math.max(1e-9,...a.map(e=>e.total))*1.08,s=r/Math.max(1,a.length),c=Math.min(10,s*.28),l=e=>n.t+i-e/o*i,u=Array.from({length:5},(e,t)=>{let n=o/4*t;return{y:Number(l(n).toFixed(1)),label:x(n)}}),d=[],f=[];return a.forEach((e,r)=>{let i=0,o=n.l+r*s+c/2,u=s-c;t.forEach((t,n)=>{let r=C(e,t);if(r<=0)return;let a=l(i+r),s=l(i),c=Math.max(0,s-a-2);d.push({seriesIndex:n,x:Number(o.toFixed(1)),y:Number(a.toFixed(1)),width:Number(u.toFixed(1)),height:Number(c.toFixed(1)),title:`${e.date} · ${t} · ${x(r)}`}),i+=r}),(a.length<=16||r%Math.ceil(a.length/16)===0)&&f.push({x:Number((o+u/2).toFixed(1)),label:e.date.slice(5)})}),{width:960,height:260,gridLines:u,segments:d,dayLabels:f,axisY:Number(l(0).toFixed(1)),marginLeft:n.l,marginRight:n.r}}function E(e){let t=e.totals.byResource,n=[[`Memory (provisioned while awake)`,t.memory],[`vCPU (active use only)`,t.cpu],[`Durable Object duration + requests`,t.durableObjects],[`Disk (provisioned while awake)`,t.disk],[`Workers requests + CPU`,t.workers],[`Durable Object SQLite rows`,t.doRows],[`Durable Object SQLite storage`,t.doStorage],[`R2 storage + operations`,t.r2],[`Workflow steps + state`,t.workflows]],r=n.reduce((e,t)=>e+t[1],0)||1;return n.map(([e,t])=>({label:e,usd:t,percent:t/r*100}))}var D=[`fill-[#4478b8] dark:fill-[#7aa7e0]`,`fill-[#c8823b] dark:fill-[#e0a95a]`,`fill-[#4c8c57] dark:fill-[#6fae7a]`,`fill-[#b8963e] dark:fill-[#d4b45a]`,`fill-[#b0568c] dark:fill-[#d489b8]`,`fill-[#6b7bcc] dark:fill-[#98a5e6]`,`fill-[#d05252] dark:fill-[#e07a74]`,`fill-[#3e8e96] dark:fill-[#6fb9c0]`],O=[`bg-[#4478b8] dark:bg-[#7aa7e0]`,`bg-[#c8823b] dark:bg-[#e0a95a]`,`bg-[#4c8c57] dark:bg-[#6fae7a]`,`bg-[#b8963e] dark:bg-[#d4b45a]`,`bg-[#b0568c] dark:bg-[#d489b8]`,`bg-[#6b7bcc] dark:bg-[#98a5e6]`,`bg-[#d05252] dark:bg-[#e07a74]`,`bg-[#3e8e96] dark:bg-[#6fb9c0]`],k={class:`overflow-x-auto`},A=[`viewBox`],j=[`x1`,`x2`,`y1`,`y2`],M=[`x`,`y`],N=[`x`,`y`,`width`,`height`],P=[`x`,`y`],F=[`x1`,`x2`,`y1`,`y2`],I=_({__name:`CostChart`,props:{report:{},series:{}},setup(e){let t=e,n=l(()=>T(t.report,t.series));return(e,t)=>(s(),f(`div`,k,[(s(),f(`svg`,{class:`block h-auto w-full font-mono`,viewBox:`0 0 ${n.value.width} ${n.value.height}`,role:`img`,"aria-label":`Daily cost, stacked by component`},[(s(!0),f(r,null,p(n.value.gridLines,(e,t)=>(s(),f(r,{key:`g${t}`},[d(`line`,{class:`stroke-(--ui-border-muted)`,x1:n.value.marginLeft,x2:n.value.width-n.value.marginRight,y1:e.y,y2:e.y},null,8,j),d(`text`,{class:`fill-(--ui-text-dimmed) text-[11px] tabular-nums`,x:n.value.marginLeft-8,y:e.y+4,"text-anchor":`end`},h(e.label),9,M)],64))),128)),(s(!0),f(r,null,p(n.value.segments,(e,t)=>(s(),f(`rect`,{key:`s${t}`,class:g([`seg hover:opacity-85`,m(D)[e.seriesIndex%m(D).length]]),x:e.x,y:e.y,width:e.width,height:e.height},[d(`title`,null,h(e.title),1)],10,N))),128)),(s(!0),f(r,null,p(n.value.dayLabels,(e,t)=>(s(),f(`text`,{key:`d${t}`,class:`fill-(--ui-text-dimmed) text-[11px]`,x:e.x,y:n.value.height-10,"text-anchor":`middle`},h(e.label),9,P))),128)),d(`line`,{class:`stroke-(--ui-border)`,x1:n.value.marginLeft,x2:n.value.width-n.value.marginRight,y1:n.value.axisY,y2:n.value.axisY},null,8,F)],8,A))]))}}),L={class:`text-xs text-muted`},R={key:1,class:`text-highlighted`},z=[`href`],B={class:`mb-4 flex flex-wrap items-center gap-x-4 gap-y-2`},V={key:0,class:`flex items-center gap-1`,"aria-label":`Cost groups`},H={key:0,class:`rounded-md bg-accented px-2.5 py-1 text-xs font-medium text-highlighted`,"aria-current":`page`},U=[`href`],W={class:`font-mono text-sm tabular-nums text-muted`},G={class:`mb-5 grid grid-cols-[repeat(auto-fit,minmax(190px,1fr))] gap-3`},K={class:`grid gap-0.5 rounded-lg border border-default bg-elevated px-4 py-3.5`},q={class:`font-mono text-2xl font-medium tabular-nums`},J={class:`text-xs text-muted`},Y={class:`grid gap-0.5 rounded-lg border border-default bg-elevated px-4 py-3.5`},X={class:`font-mono text-2xl font-medium tabular-nums`},Z={class:`grid gap-0.5 rounded-lg border border-default bg-elevated px-4 py-3.5`},Q={class:`font-mono text-2xl font-medium tabular-nums`},te={class:`grid gap-0.5 rounded-lg border border-default bg-elevated px-4 py-3.5`},ne={class:`font-mono text-[0.6875rem] font-medium uppercase tracking-widest text-dimmed`},re={class:`font-mono text-2xl font-medium tabular-nums`},ie={class:`text-xs text-muted`},ae={class:`grid gap-0.5 rounded-lg border border-default bg-elevated px-4 py-3.5`},oe={class:`font-mono text-2xl font-medium tabular-nums`},se={class:`text-xs text-muted`},ce={class:`mb-5 grid gap-3 rounded-lg border border-default bg-elevated px-5 py-4`},le={class:`flex flex-wrap items-baseline justify-between gap-x-4 gap-y-2`},ue={class:`legend flex flex-wrap gap-x-4 gap-y-1.5 text-xs text-muted`},de={key:0,class:`text-xs text-warn`},fe={class:`mb-5 grid gap-3 rounded-lg border border-default bg-elevated px-5 py-4`},pe={class:`w-full border-collapse font-mono text-[0.8125rem] tabular-nums`},me={class:`px-2.5 py-1.5`},he={class:`px-2.5 py-1.5 text-right`},ge={class:`px-2.5 py-1.5 text-right`},_e={class:`w-2/5 px-2.5 py-1.5`},ve={class:`mb-5 grid gap-3 rounded-lg border border-default bg-elevated px-5 py-4`},ye={open:``},be={class:`mt-2.5 overflow-x-auto`},$={class:`data w-full min-w-[38rem] border-collapse whitespace-nowrap font-mono text-[0.8125rem] tabular-nums`},xe=[`title`],Se={key:0,class:`text-xs text-dimmed`},Ce={class:`border-b border-muted px-2.5 py-1.5 text-right font-medium`},we={class:`text-xs text-muted`},Te={class:`rounded bg-accented px-1 py-0.5`},Ee={class:`border-t border-default pt-3.5 text-xs text-dimmed`},De={class:`mt-2 grid gap-1.5`},Oe=_({__name:`CostsPage`,setup(_){let v=u(`costs`),y=l(()=>v?.report??null),b=l(()=>v?.groups??[]),S=l(()=>y.value?ee(y.value):[]),T=l(()=>y.value?w(y.value):null),D=l(()=>y.value?E(y.value):[]),k=[7,30,90];function A(e){let t=new Date(`${e}T00:00:00Z`);return Number.isNaN(t.getTime())?e:`${[`Jan`,`Feb`,`Mar`,`Apr`,`May`,`Jun`,`Jul`,`Aug`,`Sep`,`Oct`,`Nov`,`Dec`][t.getUTCMonth()]} ${t.getUTCDate()}`}return(l,u)=>y.value&&T.value?(s(),a(e,{key:0,title:`${y.value.label} spend`,nav:`costs`},{actions:n(()=>[d(`span`,L,[(s(),f(r,null,p(k,(e,t)=>(s(),f(r,{key:e},[t>0?(s(),f(r,{key:0},[o(` · `)],64)):c(``,!0),e===y.value.range.days?(s(),f(`b`,R,h(e)+`d`,1)):(s(),f(`a`,{key:2,class:`text-primary hover:underline`,href:`/costs/${y.value.group}?days=${e}`},h(e)+`d`,9,z))],64))),64))])]),default:n(()=>[d(`div`,B,[b.value.length>1?(s(),f(`nav`,V,[(s(!0),f(r,null,p(b.value,e=>(s(),f(r,{key:e},[e===y.value.group?(s(),f(`span`,H,h(e),1)):(s(),f(`a`,{key:1,class:`rounded-md px-2.5 py-1 text-xs text-muted no-underline hover:bg-elevated hover:text-highlighted`,href:`/costs/${e}`},h(e),9,U))],64))),128))])):c(``,!0),d(`p`,W,[o(h(A(y.value.range.from))+` → `+h(A(y.value.range.to))+` · `+h(y.value.range.days)+`d`,1),y.value.range.partialLastDay?(s(),f(r,{key:0},[o(` · today partial`)],64)):c(``,!0)])]),d(`section`,G,[d(`div`,K,[u[0]||=d(`span`,{class:`font-mono text-[0.6875rem] font-medium uppercase tracking-widest text-dimmed`},`Yesterday`,-1),d(`span`,q,h(T.value.yesterday?m(x)(T.value.yesterday.total):`—`),1),d(`span`,J,h(T.value.yesterday?`${T.value.yesterday.date} · last full day`:`no full day in range`),1)]),d(`div`,Y,[u[1]||=d(`span`,{class:`font-mono text-[0.6875rem] font-medium uppercase tracking-widest text-dimmed`},`7-day average`,-1),d(`span`,X,h(m(x)(T.value.avg7)),1),u[2]||=d(`span`,{class:`text-xs text-muted`},`per day, full days only`,-1)]),d(`div`,Z,[u[3]||=d(`span`,{class:`font-mono text-[0.6875rem] font-medium uppercase tracking-widest text-dimmed`},`Projected month`,-1),d(`span`,Q,h(m(x)(T.value.projectedMonth,0)),1),u[4]||=d(`span`,{class:`text-xs text-muted`},`7-day rate × 30.4, before plan fees and included allowances`,-1)]),d(`div`,te,[d(`span`,ne,h(y.value.llmAvailable?`LLM share`:`LLM spend`),1),d(`span`,re,h(y.value.llmAvailable?`${T.value.llmShare}%`:`—`),1),d(`span`,ie,h(y.value.llmAvailable?`of the range total`:`LLM spend not configured`),1)]),d(`div`,ae,[u[5]||=d(`span`,{class:`font-mono text-[0.6875rem] font-medium uppercase tracking-widest text-dimmed`},`Share of account`,-1),d(`span`,oe,h(T.value.accountShare)+`%`,1),d(`span`,se,h(m(x)(y.value.totals.cloudUsd))+` of `+h(m(x)(y.value.account.cloudUsd))+` Cloudflare spend in range`,1)])]),d(`section`,ce,[d(`div`,le,[u[6]||=d(`div`,null,[d(`h2`,{class:`text-[0.9375rem] font-medium`},`Daily cost`),d(`p`,{class:`text-sm text-muted`},`Stacked by component · USD list price`)],-1),d(`div`,ue,[(s(!0),f(r,null,p(S.value,(e,t)=>(s(),f(`span`,{key:e,class:`inline-flex items-center gap-1.5`},[d(`i`,{class:g([`inline-block size-2.5 rounded-xs`,m(O)[t%m(O).length]])},null,2),o(h(e),1)]))),128))])]),i(I,{report:y.value,series:S.value},null,8,[`report`,`series`]),y.value.llmAvailable?c(``,!0):(s(),f(`p`,de,[...u[7]||=[o(` LLM spend not configured — set `,-1),d(`code`,null,`ANTHROPIC_ADMIN_KEY`,-1),o(` and the group's `,-1),d(`code`,null,`anthropicWorkspaceId`,-1),o(` to layer it in. `,-1)]]))]),d(`section`,fe,[u[8]||=d(`div`,null,[d(`h2`,{class:`text-[0.9375rem] font-medium`},`What each cloud dollar buys`)],-1),d(`table`,pe,[d(`tbody`,null,[(s(!0),f(r,null,p(D.value,e=>(s(),f(`tr`,{key:e.label,class:`border-b border-muted`},[d(`td`,me,h(e.label),1),d(`td`,he,h(m(x)(e.usd)),1),d(`td`,ge,h(Math.round(e.percent))+`%`,1),d(`td`,_e,[d(`i`,{class:`block h-2.5 rounded-xs bg-primary opacity-75`,style:t({width:`${e.percent.toFixed(1)}%`})},null,4)])]))),128))])])]),d(`section`,ve,[d(`details`,ye,[u[11]||=d(`summary`,{class:`cursor-pointer text-sm text-muted`},`Table view — daily cost by component (USD)`,-1),d(`div`,be,[d(`table`,$,[d(`thead`,null,[d(`tr`,null,[u[9]||=d(`th`,{class:`border-b border-muted bg-(--ui-bg-muted) px-2.5 py-1.5 text-left text-xs font-medium text-muted`},` Date `,-1),(s(!0),f(r,null,p(S.value,e=>(s(),f(`th`,{key:e,class:`border-b border-muted bg-(--ui-bg-muted) px-2.5 py-1.5 text-right text-xs font-medium text-muted`},h(e),1))),128)),u[10]||=d(`th`,{class:`border-b border-muted bg-(--ui-bg-muted) px-2.5 py-1.5 text-right text-xs font-medium text-muted`},` Total `,-1)])]),d(`tbody`,null,[(s(!0),f(r,null,p(y.value.days,e=>(s(),f(`tr`,{key:e.date},[d(`td`,{class:`border-b border-muted px-2.5 py-1.5`,title:e.date},[o(h(A(e.date))+` `,1),y.value.range.partialLastDay&&e.date===y.value.range.to?(s(),f(`span`,Se,`(partial day)`)):c(``,!0)],8,xe),(s(!0),f(r,null,p(S.value,t=>(s(),f(`td`,{key:t,class:`border-b border-muted px-2.5 py-1.5 text-right`},h(m(x)(m(C)(e,t),3)),1))),128)),d(`td`,Ce,h(m(x)(e.total,3)),1)]))),128))])])])]),d(`p`,we,[u[12]||=o(` Machine-readable twin: `,-1),d(`code`,Te,`GET /costs/`+h(y.value.group)+`.json`,1),u[13]||=o(` (same Access gate). `,-1)])]),d(`footer`,Ee,[d(`details`,null,[u[18]||=d(`summary`,{class:`cursor-pointer text-muted`},`How these numbers are computed`,-1),d(`div`,De,[u[16]||=d(`div`,null,[d(`b`,null,`Live.`),o(` Both billing sources are read live from this page — nothing cached, nothing stored. Cloudflare bills vCPU on active use only; memory and disk bill on the provisioned size for every second a container is awake. LLM spend is the Anthropic Admin API cost report for this group's workspace (gross, USD). `)],-1),u[17]||=d(`div`,null,[d(`b`,null,`Method.`),o(` Cloudflare GraphQL Analytics, every meter a Workers deployment is billed on: `),d(`code`,null,`containersUsageAdaptiveGroups`),o(` (cpuTimeSec, allocatedMemory, allocatedDisk per app per UTC day), `),d(`code`,null,`durableObjectsPeriodicGroups`),o(` (billable `),d(`code`,null,`duration`),o(` GB-s and SQLite rows read and written per namespace), `),d(`code`,null,`durableObjectsInvocationsAdaptiveGroups`),o(` (requests per namespace), `),d(`code`,null,`durableObjectsSqlStorageGroups`),o(` (bytes stored), `),d(`code`,null,`workersInvocationsAdaptive`),o(` (requests, CPU time), `),d(`code`,null,`r2StorageAdaptiveGroups`),o(` and `),d(`code`,null,`r2OperationsAdaptiveGroups`),o(` (bytes stored, class A/B operations). Prices: vCPU $0.000020/s, memory $0.0000025/GiB-s, disk $0.00000007/GB-s, DO duration $12.50 per million GB-s, DO requests $0.15/M, SQLite rows $0.001/M read and $1.00/M written, DO storage $0.20/GB-month, Workers $0.30/M requests and $0.02/M CPU-ms, R2 $0.015/GB-month, $4.50/M class A and $0.36/M class B (deletes free). Storage is the day's peak, prorated over a 30.44-day month. Gross list price — plan fees and included allowances are not subtracted; Workers Logs volume has no analytics dataset and is not priced. `)],-1),d(`div`,null,[u[14]||=d(`b`,null,`Scope.`,-1),u[15]||=o(` Attributed to this group: the Workers `,-1),d(`code`,null,h(y.value.attribution.workers.join(`, `)),1),o(`, every Durable Object namespace they host (`+h(Object.keys(y.value.attribution.durableObjectNamespaces).length)+`), the R2 buckets named after them (`+h(Object.keys(y.value.attribution.r2Buckets).length)+`), and the container apps mapped in `,1),d(`code`,null,`costs.groups.`+h(y.value.group),1),o(` (`+h(Object.keys(y.value.attribution.containerApps).length)+`). Everything else in the account is priced the same way into the account total, which is what "share of account" divides by. `,1)])])])])]),_:1},8,[`title`])):c(``,!0)}});export{Oe as default};
|