@coreplane/switchboard 1.262.3 → 1.262.4
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.
|
@@ -73,6 +73,20 @@ providers:
|
|
|
73
73
|
# # object text contract, or both (absent assumes both). The intake gate
|
|
74
74
|
# # refuses at load a card declaring neither under its classify default.
|
|
75
75
|
# answers: ["tool", "text"]
|
|
76
|
+
# # When published prices change above an input-token threshold, give
|
|
77
|
+
# # all four base and tier rates in USD per million tokens. The whole
|
|
78
|
+
# # request uses the tier above the threshold, including cached input.
|
|
79
|
+
# price:
|
|
80
|
+
# input: 2
|
|
81
|
+
# output: 10
|
|
82
|
+
# cacheRead: 0.2
|
|
83
|
+
# cacheWrite: 2.5
|
|
84
|
+
# tiers:
|
|
85
|
+
# - inputTokensAbove: 272000
|
|
86
|
+
# input: 4
|
|
87
|
+
# output: 15
|
|
88
|
+
# cacheRead: 0.4
|
|
89
|
+
# cacheWrite: 5
|
|
76
90
|
# A passthrough is merged into the request body on the wires whose adapter
|
|
77
91
|
# takes one — a vendor-only feature such as OpenRouter's routing, never a
|
|
78
92
|
# control: it is not decided, not noted and not in the matrix, and a wrong
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "switchboard",
|
|
3
|
-
"version": "1.262.
|
|
3
|
+
"version": "1.262.4",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "switchboard",
|
|
9
|
-
"version": "1.262.
|
|
9
|
+
"version": "1.262.4",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"workspaces": [
|
|
12
12
|
"web",
|
|
@@ -21060,7 +21060,7 @@
|
|
|
21060
21060
|
},
|
|
21061
21061
|
"packages/switchboard": {
|
|
21062
21062
|
"name": "@coreplane/switchboard",
|
|
21063
|
-
"version": "1.262.
|
|
21063
|
+
"version": "1.262.4",
|
|
21064
21064
|
"license": "Apache-2.0",
|
|
21065
21065
|
"dependencies": {
|
|
21066
21066
|
"@earendil-works/pi-ai": "0.85.1",
|
package/dist/assets/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "switchboard",
|
|
3
|
-
"version": "1.262.
|
|
3
|
+
"version": "1.262.4",
|
|
4
4
|
"private": true,
|
|
5
5
|
"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.",
|
|
6
6
|
"license": "Apache-2.0",
|
package/dist/assets/source.json
CHANGED
|
@@ -505,8 +505,20 @@ export interface ProviderModelOverride {
|
|
|
505
505
|
inputs?: { image?: boolean; document?: boolean };
|
|
506
506
|
/** The model's cache rule. */
|
|
507
507
|
cache?: "automatic" | "markers" | "none" | "unknown";
|
|
508
|
-
/** USD per million tokens, by kind. */
|
|
509
|
-
price?: {
|
|
508
|
+
/** USD per million tokens, by kind, with whole-request long-context rates. */
|
|
509
|
+
price?: {
|
|
510
|
+
input?: number;
|
|
511
|
+
output?: number;
|
|
512
|
+
cacheRead?: number;
|
|
513
|
+
cacheWrite?: number;
|
|
514
|
+
tiers?: Array<{
|
|
515
|
+
inputTokensAbove: number;
|
|
516
|
+
input: number;
|
|
517
|
+
output: number;
|
|
518
|
+
cacheRead: number;
|
|
519
|
+
cacheWrite: number;
|
|
520
|
+
}>;
|
|
521
|
+
};
|
|
510
522
|
/** The answer shapes the model can produce for a forced one-call turn (the
|
|
511
523
|
* router's, intake's): `tool` — a forced tool call — and `text` — the
|
|
512
524
|
* one-JSON-object text contract. Absent, both are assumed; an empty list
|
package/dist/cli.js
CHANGED
|
@@ -7908,12 +7908,42 @@ function validateModelOverride(path, raw) {
|
|
|
7908
7908
|
if (m.price !== void 0) {
|
|
7909
7909
|
if (typeof m.price !== "object" || m.price === null || Array.isArray(m.price))
|
|
7910
7910
|
throw new Error(`${path}.price must be a mapping of kind \u2192 USD per million tokens`);
|
|
7911
|
-
|
|
7911
|
+
const price = m.price;
|
|
7912
|
+
for (const [kind, v] of Object.entries(price)) {
|
|
7913
|
+
if (kind === "tiers") continue;
|
|
7912
7914
|
if (!Object.hasOwn(PRICE_KINDS2, kind))
|
|
7913
7915
|
throw new Error(`${path}.price.${kind} is not a known kind (input, output, cacheRead, cacheWrite)`);
|
|
7914
7916
|
if (typeof v !== "number" || !Number.isFinite(v) || v < 0)
|
|
7915
7917
|
throw new Error(`${path}.price.${kind} must be a finite number of USD per million tokens, 0 or more`);
|
|
7916
7918
|
}
|
|
7919
|
+
if (price.tiers !== void 0) {
|
|
7920
|
+
if (!Array.isArray(price.tiers) || price.tiers.length === 0)
|
|
7921
|
+
throw new Error(`${path}.price.tiers must be a nonempty list of long-context rates`);
|
|
7922
|
+
for (const kind of Object.keys(PRICE_KINDS2)) {
|
|
7923
|
+
if (price[kind] === void 0) throw new Error(`${path}.price.${kind} is required with tiers`);
|
|
7924
|
+
}
|
|
7925
|
+
const thresholds = /* @__PURE__ */ new Set();
|
|
7926
|
+
for (const [index, rawTier] of price.tiers.entries()) {
|
|
7927
|
+
const tierPath = `${path}.price.tiers[${index}]`;
|
|
7928
|
+
if (typeof rawTier !== "object" || rawTier === null || Array.isArray(rawTier))
|
|
7929
|
+
throw new Error(`${tierPath} must be a mapping of threshold and rates`);
|
|
7930
|
+
const tier = rawTier;
|
|
7931
|
+
for (const key of Object.keys(tier)) {
|
|
7932
|
+
if (key !== "inputTokensAbove" && !Object.hasOwn(PRICE_KINDS2, key))
|
|
7933
|
+
throw new Error(`${tierPath}.${key} is not a known tier field`);
|
|
7934
|
+
}
|
|
7935
|
+
if (!Number.isInteger(tier.inputTokensAbove) || tier.inputTokensAbove <= 0)
|
|
7936
|
+
throw new Error(`${tierPath}.inputTokensAbove must be a positive integer of tokens`);
|
|
7937
|
+
const threshold = tier.inputTokensAbove;
|
|
7938
|
+
if (thresholds.has(threshold)) throw new Error(`${tierPath}.inputTokensAbove duplicates a previous threshold`);
|
|
7939
|
+
thresholds.add(threshold);
|
|
7940
|
+
for (const kind of Object.keys(PRICE_KINDS2)) {
|
|
7941
|
+
const rate = tier[kind];
|
|
7942
|
+
if (typeof rate !== "number" || !Number.isFinite(rate) || rate < 0)
|
|
7943
|
+
throw new Error(`${tierPath}.${kind} must be a finite number of USD per million tokens, 0 or more`);
|
|
7944
|
+
}
|
|
7945
|
+
}
|
|
7946
|
+
}
|
|
7917
7947
|
}
|
|
7918
7948
|
}
|
|
7919
7949
|
function validateProviders(cfg, source2) {
|
|
@@ -40968,6 +40998,8 @@ function ownerNote(owner) {
|
|
|
40968
40998
|
const steer = owner.kind === "live" && owner.runId !== void 0 ? ` bind \`steer run ${owner.runId} <words>\` to deliver it,` : "";
|
|
40969
40999
|
if (owner.kind === "pipeline")
|
|
40970
41000
|
return `This thread is owned by ${who2}: the request below is a continuation of that durable task. Read tools may ground the decision, but every action folds into the owner so the current pull request is re-read and the pipeline resumes; an informational command or question is not fulfillment.`;
|
|
41001
|
+
if (owner.kind === "unit")
|
|
41002
|
+
return `This thread is owned by ${who2}: the request below is a follow-up for that unit. An inferred read command cannot answer it; fold the whole message into the unit unchanged. Ask a question only when a required detail is missing.`;
|
|
40971
41003
|
return `This thread is owned by ${who2}: the request below is a follow-up for that owner. To act on it,${steer} bind a read command, or ask a question. Any other decision \u2014 a refusal, a preset, a write \u2014 folds the whole message into the owner unchanged and posts no answer.`;
|
|
40972
41004
|
}
|
|
40973
41005
|
function operatorProjection(input) {
|
|
@@ -41373,7 +41405,7 @@ function ownedDecisionRuns(event, owner, commands) {
|
|
|
41373
41405
|
const def = commands.list().find((c) => c.id === parsed.id);
|
|
41374
41406
|
if (!def) return false;
|
|
41375
41407
|
if (def.id === "steer.run") return !(owner.kind === "live" && owner.runId === void 0);
|
|
41376
|
-
return boundBlastRadius(def, parsed.input) === "read";
|
|
41408
|
+
return owner.kind !== "unit" && boundBlastRadius(def, parsed.input) === "read";
|
|
41377
41409
|
});
|
|
41378
41410
|
}
|
|
41379
41411
|
function isYesAnswer(text) {
|
|
@@ -50154,10 +50186,12 @@ function judgePush(tail, ctx) {
|
|
|
50154
50186
|
return refused4("repo:use \u2014 existing-PR publication requires the explicit owned destination");
|
|
50155
50187
|
if (additionalRefspecs.length > 0)
|
|
50156
50188
|
return refused4("repo:use \u2014 existing-PR publication allows exactly one owned destination");
|
|
50157
|
-
const destination2 = refspec.replace(/^\+/, "").split(":")
|
|
50158
|
-
const branch3 = destination2
|
|
50189
|
+
const [source3, destination2 = source3] = refspec.replace(/^\+/, "").split(":");
|
|
50190
|
+
const branch3 = destination2.replace(/^refs\/heads\//, "");
|
|
50159
50191
|
if (branch3 !== publication.ref)
|
|
50160
50192
|
return refused4(`repo:use \u2014 push to \`${branch3}\`, not the owned publication ref ${publication.ref}`);
|
|
50193
|
+
if (source3.replace(/^refs\/heads\//, "") !== publication.ref)
|
|
50194
|
+
return refused4(`repo:use \u2014 push from the owned publication ref ${publication.ref}; the checkout may have moved`);
|
|
50161
50195
|
const lease = `--force-with-lease=refs/heads/${publication.ref}:${publication.expectedHeadSha}`;
|
|
50162
50196
|
if (!tail.split(/\s+/).includes(lease))
|
|
50163
50197
|
return refused4(
|
|
@@ -50165,11 +50199,19 @@ function judgePush(tail, ctx) {
|
|
|
50165
50199
|
);
|
|
50166
50200
|
return allowed;
|
|
50167
50201
|
}
|
|
50202
|
+
if (ctx.branch !== void 0 && refspec === void 0)
|
|
50203
|
+
return refused4(
|
|
50204
|
+
`repo:use \u2014 name the run's branch ${ctx.branch} as the push source and destination; the checkout may have moved`
|
|
50205
|
+
);
|
|
50206
|
+
if (ctx.branch !== void 0 && additionalRefspecs.length > 0)
|
|
50207
|
+
return refused4("repo:use \u2014 a bound run may push exactly one branch");
|
|
50168
50208
|
if (refspec === void 0) return allowed;
|
|
50169
|
-
const destination = refspec.replace(/^\+/, "").split(":")
|
|
50209
|
+
const [source2, destination = source2] = refspec.replace(/^\+/, "").split(":");
|
|
50170
50210
|
if (ctx.branch !== void 0) {
|
|
50171
|
-
const branch3 = destination
|
|
50211
|
+
const branch3 = destination.replace(/^refs\/heads\//, "");
|
|
50172
50212
|
if (branch3 !== ctx.branch) return refused4(`repo:use \u2014 push to \`${branch3}\`, not the run's branch ${ctx.branch}`);
|
|
50213
|
+
if (source2.replace(/^refs\/heads\//, "") !== ctx.branch)
|
|
50214
|
+
return refused4(`repo:use \u2014 push from the run's branch ${ctx.branch}; the checkout may have moved`);
|
|
50173
50215
|
return allowed;
|
|
50174
50216
|
}
|
|
50175
50217
|
const branch2 = destination.replace(/^refs\/heads\//, "");
|
|
@@ -52391,7 +52433,7 @@ async function observeCodingWorkspace(executor, opts, span) {
|
|
|
52391
52433
|
}
|
|
52392
52434
|
return {
|
|
52393
52435
|
observation: {
|
|
52394
|
-
head: pushed === void 0 ? headSha : parseRevParseOutput(tipOut),
|
|
52436
|
+
head: pushed === void 0 ? headSha : parseRevParseOutput(tipOut) ?? (checkedOut === pushed ? headSha : void 0),
|
|
52395
52437
|
branch: branch2,
|
|
52396
52438
|
checkedOut,
|
|
52397
52439
|
remoteHead,
|
|
@@ -52408,7 +52450,11 @@ async function observeCodingWorkspace(executor, opts, span) {
|
|
|
52408
52450
|
return (await probesAt(`git -C ${shellQuote(dir)}`)).observation;
|
|
52409
52451
|
}
|
|
52410
52452
|
function salvageTargetOf(opts) {
|
|
52411
|
-
|
|
52453
|
+
if (opts.ownedBranch !== void 0 && opts.checkedOut !== opts.ownedBranch)
|
|
52454
|
+
return {
|
|
52455
|
+
skipped: `the ending checkpoint kept work on \`${opts.checkedOut ?? "an unreadable checkout"}\`: the owned branch is \`${opts.ownedBranch}\``
|
|
52456
|
+
};
|
|
52457
|
+
const branch2 = opts.ownedBranch ?? opts.pushedBranch ?? opts.checkedOut;
|
|
52412
52458
|
if (branch2 === void 0)
|
|
52413
52459
|
return {
|
|
52414
52460
|
skipped: "the budget-end salvage was skipped: the workspace's branch could not be read, so there is nowhere to push"
|
|
@@ -53457,8 +53503,9 @@ async function runLoop(deps, ctx) {
|
|
|
53457
53503
|
let workspaceObserved = false;
|
|
53458
53504
|
let workSalvageAttempted = false;
|
|
53459
53505
|
let endingSalvageAttempted = false;
|
|
53506
|
+
const coordinatorBranch = coordinator?.publication?.publicationRef ?? (coordinator !== void 0 ? binding?.ref ?? repoCtx.ref : void 0);
|
|
53460
53507
|
const observeWorkspaceNow = async () => {
|
|
53461
|
-
const pushedBranch = pushes.branch();
|
|
53508
|
+
const pushedBranch = coordinator !== void 0 ? coordinatorBranch : pushes.branch();
|
|
53462
53509
|
const observed = await root.span(
|
|
53463
53510
|
"run.observe_workspace",
|
|
53464
53511
|
(span) => observeCodingWorkspace(
|
|
@@ -53482,9 +53529,10 @@ async function runLoop(deps, ctx) {
|
|
|
53482
53529
|
const preserveCodingChildWork = async (cue) => {
|
|
53483
53530
|
if (workSalvageAttempted || !isCodingPrRun || coordinator === void 0) return;
|
|
53484
53531
|
if (!workspaceObserved) await observeWorkspaceNow();
|
|
53485
|
-
const target = salvageTargetOf({
|
|
53532
|
+
const target = coordinatorBranch === void 0 ? { skipped: "the ending checkpoint was skipped: the unit's branch is unavailable" } : salvageTargetOf({
|
|
53486
53533
|
pushedBranch: pushes.branch(),
|
|
53487
53534
|
checkedOut: observedCheckedOut,
|
|
53535
|
+
ownedBranch: coordinatorBranch,
|
|
53488
53536
|
base: repoCtx.baseRef ?? await coordinatorBase
|
|
53489
53537
|
});
|
|
53490
53538
|
const salvaged = "skipped" in target ? { pushed: false, summary: target.skipped } : await root.span(
|
|
@@ -53504,7 +53552,7 @@ async function runLoop(deps, ctx) {
|
|
|
53504
53552
|
const cleanCompletion = cue === "completion" && !salvaged.pushed && (/ended with nothing to preserve/i.test(salvaged.summary) || "skipped" in target && (observedUncommitted ?? 0) === 0 && (observedUnpushed ?? 0) === 0);
|
|
53505
53553
|
if (cleanCompletion) return;
|
|
53506
53554
|
workSalvageAttempted = true;
|
|
53507
|
-
if (cue === "ending" || cue === "completion") endingSalvageAttempted = true;
|
|
53555
|
+
if (cue === "ending" || cue === "completion" && !("skipped" in target)) endingSalvageAttempted = true;
|
|
53508
53556
|
onEvent({
|
|
53509
53557
|
type: "run_note",
|
|
53510
53558
|
kind: cue === "budget" ? "budget_salvage" : "work_salvage",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coreplane/switchboard",
|
|
3
|
-
"version": "1.262.
|
|
3
|
+
"version": "1.262.4",
|
|
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",
|