@coreplane/switchboard 1.216.0 → 1.216.1
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.
|
@@ -439,7 +439,10 @@ export default {
|
|
|
439
439
|
: pathname === COPY_PATH
|
|
440
440
|
? // The artifact copy (artifactsCopy.ts): the R2 binding and the Slack
|
|
441
441
|
// token are this Worker's; the bot only asks, with its copy bearer.
|
|
442
|
-
|
|
442
|
+
// `forwarded`, never `inbound`: `withTraceContext` rebuilt the request
|
|
443
|
+
// with `new Request(inbound, …)`, which takes the body stream with it —
|
|
444
|
+
// `inbound.text()` is empty afterwards and the route read "not JSON" live.
|
|
445
|
+
await handleArtifactsCopy(forwarded, {
|
|
443
446
|
bucket: env.ARTIFACTS,
|
|
444
447
|
bucketName: env.ARTIFACTS_BUCKET_NAME,
|
|
445
448
|
copyToken: env.ARTIFACTS_COPY_TOKEN,
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "switchboard",
|
|
3
|
-
"version": "1.216.
|
|
3
|
+
"version": "1.216.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "switchboard",
|
|
9
|
-
"version": "1.216.
|
|
9
|
+
"version": "1.216.1",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"workspaces": [
|
|
12
12
|
"web",
|
|
@@ -19000,7 +19000,7 @@
|
|
|
19000
19000
|
},
|
|
19001
19001
|
"packages/switchboard": {
|
|
19002
19002
|
"name": "@coreplane/switchboard",
|
|
19003
|
-
"version": "1.216.
|
|
19003
|
+
"version": "1.216.1",
|
|
19004
19004
|
"license": "Apache-2.0",
|
|
19005
19005
|
"dependencies": {
|
|
19006
19006
|
"@anthropic-ai/sdk": "^0.124.0",
|
package/dist/assets/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "switchboard",
|
|
3
|
-
"version": "1.216.
|
|
3
|
+
"version": "1.216.1",
|
|
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
package/dist/cli.js
CHANGED
|
@@ -24312,6 +24312,73 @@ var init_resolve = __esm({
|
|
|
24312
24312
|
}
|
|
24313
24313
|
});
|
|
24314
24314
|
|
|
24315
|
+
// ../../src/core/statusCardFrame.ts
|
|
24316
|
+
function createCardShell(opts) {
|
|
24317
|
+
let label = opts.label;
|
|
24318
|
+
let link = opts.link;
|
|
24319
|
+
let frame = 0;
|
|
24320
|
+
let finishedAt;
|
|
24321
|
+
let setupLabel;
|
|
24322
|
+
const lead = opts.lead ?? [];
|
|
24323
|
+
const elapsed2 = () => formatDuration((finishedAt ?? opts.now()) - opts.startedAt, "clock");
|
|
24324
|
+
const headline = (icon) => `${icon} ${label} \xB7 ${elapsed2()}`;
|
|
24325
|
+
const closeDetail = (close, own) => [close.shape, close.queued, own, opts.footer].filter(Boolean).join("\n") || void 0;
|
|
24326
|
+
return {
|
|
24327
|
+
get label() {
|
|
24328
|
+
return label;
|
|
24329
|
+
},
|
|
24330
|
+
setLabel(next) {
|
|
24331
|
+
label = next;
|
|
24332
|
+
},
|
|
24333
|
+
setLink(next) {
|
|
24334
|
+
link = next;
|
|
24335
|
+
},
|
|
24336
|
+
freeze(at) {
|
|
24337
|
+
finishedAt = at;
|
|
24338
|
+
},
|
|
24339
|
+
setSetupLabel(next) {
|
|
24340
|
+
setupLabel = next;
|
|
24341
|
+
},
|
|
24342
|
+
ack() {
|
|
24343
|
+
const detail = lead.join("\n");
|
|
24344
|
+
return { title: `\u{1F440} ${label} \xB7 preparing workspace\u2026`, ...detail ? { detail } : {} };
|
|
24345
|
+
},
|
|
24346
|
+
live(parts = {}) {
|
|
24347
|
+
const glyph = SPINNER_GLYPHS[frame++ % SPINNER_GLYPHS.length];
|
|
24348
|
+
const detail = [...lead, ...parts.detail ?? []].filter(Boolean).join("\n");
|
|
24349
|
+
return {
|
|
24350
|
+
title: headline(glyph) + (setupLabel ? ` \u2014 ${setupLabel}` : "") + (parts.suffix ?? "") + (parts.notice ? ` \xB7 ${parts.notice}` : ""),
|
|
24351
|
+
detail: detail || void 0,
|
|
24352
|
+
link
|
|
24353
|
+
};
|
|
24354
|
+
},
|
|
24355
|
+
close(close) {
|
|
24356
|
+
const detail = closeDetail(close, close.kind === "done" ? close.detail : void 0);
|
|
24357
|
+
switch (close.kind) {
|
|
24358
|
+
case "done":
|
|
24359
|
+
return { title: headline(close.icon), detail, link };
|
|
24360
|
+
case "not_started":
|
|
24361
|
+
return { title: `${close.icon} ${label} \xB7 not started (${close.reason}) \xB7 ${elapsed2()}`, detail };
|
|
24362
|
+
case "refused":
|
|
24363
|
+
return { title: `${close.icon} ${label} \xB7 ${close.reason} \xB7 ${elapsed2()}`, detail };
|
|
24364
|
+
case "setup_failed":
|
|
24365
|
+
return { title: `\u274C setup failed \xB7 ${close.reason} \xB7 ${elapsed2()}`, detail };
|
|
24366
|
+
}
|
|
24367
|
+
}
|
|
24368
|
+
};
|
|
24369
|
+
}
|
|
24370
|
+
var SPINNER_GLYPHS, LIVE_CARD_PREFIXES, ROUTED_LABEL_PREFIX, ROUTED_CARD_FOOTER;
|
|
24371
|
+
var init_statusCardFrame = __esm({
|
|
24372
|
+
"../../src/core/statusCardFrame.ts"() {
|
|
24373
|
+
"use strict";
|
|
24374
|
+
init_formatDuration();
|
|
24375
|
+
SPINNER_GLYPHS = ["\u25D0", "\u25D3", "\u25D1", "\u25D2"];
|
|
24376
|
+
LIVE_CARD_PREFIXES = [...SPINNER_GLYPHS, "\u{1F440}"];
|
|
24377
|
+
ROUTED_LABEL_PREFIX = "routed:";
|
|
24378
|
+
ROUTED_CARD_FOOTER = "reply agent:<preset> to run it another way";
|
|
24379
|
+
}
|
|
24380
|
+
});
|
|
24381
|
+
|
|
24315
24382
|
// ../../src/core/dispatch/awaitChildren.ts
|
|
24316
24383
|
function decideWait(inputs) {
|
|
24317
24384
|
const { children, now, budgetEndsAt, timeoutAt, stop, followUpPending } = inputs;
|
|
@@ -24918,7 +24985,7 @@ async function routeRequest(deps, ctx) {
|
|
|
24918
24985
|
};
|
|
24919
24986
|
}
|
|
24920
24987
|
function routedLabel(reason, collapsed) {
|
|
24921
|
-
return
|
|
24988
|
+
return `${ROUTED_LABEL_PREFIX} ${reason}${collapsed ? ` (compound collapsed: ${collapsed.presets.join("+")})` : ""}`;
|
|
24922
24989
|
}
|
|
24923
24990
|
function routedPartLines(parts) {
|
|
24924
24991
|
return parts.map((p) => {
|
|
@@ -24934,7 +25001,7 @@ function compoundBrief(text, parts) {
|
|
|
24934
25001
|
...parts.map((p, i) => `${i + 1}. \`${p.preset}\`: ${p.text}`)
|
|
24935
25002
|
].join("\n");
|
|
24936
25003
|
}
|
|
24937
|
-
var ROUTE_TEXT_CAP, ROUTE_REASON_CAP, ROUTE_MIN_OUTPUT_TOKENS, ROUTE_TOOL_NAME, ROUTE_TIMEOUT_MS, ROUTE_PART_TEXT_CAP, ROUTE_PART_LINE_CAP, COMPOUND_BRIEF_HEADING, identityOf
|
|
25004
|
+
var ROUTE_TEXT_CAP, ROUTE_REASON_CAP, ROUTE_MIN_OUTPUT_TOKENS, ROUTE_TOOL_NAME, ROUTE_TIMEOUT_MS, ROUTE_PART_TEXT_CAP, ROUTE_PART_LINE_CAP, COMPOUND_BRIEF_HEADING, identityOf;
|
|
24938
25005
|
var init_route = __esm({
|
|
24939
25006
|
"../../src/core/dispatch/route.ts"() {
|
|
24940
25007
|
"use strict";
|
|
@@ -24942,7 +25009,9 @@ var init_route = __esm({
|
|
|
24942
25009
|
init_config2();
|
|
24943
25010
|
init_types3();
|
|
24944
25011
|
init_redact();
|
|
25012
|
+
init_statusCardFrame();
|
|
24945
25013
|
init_spawn();
|
|
25014
|
+
init_statusCardFrame();
|
|
24946
25015
|
ROUTE_TEXT_CAP = 2e3;
|
|
24947
25016
|
ROUTE_REASON_CAP = 120;
|
|
24948
25017
|
ROUTE_MIN_OUTPUT_TOKENS = 200;
|
|
@@ -24952,7 +25021,6 @@ var init_route = __esm({
|
|
|
24952
25021
|
ROUTE_PART_LINE_CAP = 100;
|
|
24953
25022
|
COMPOUND_BRIEF_HEADING = "Routed as a compound request";
|
|
24954
25023
|
identityOf = (preset) => AGENTS[preset]?.identity;
|
|
24955
|
-
ROUTED_CARD_FOOTER = "reply agent:<preset> to run it another way";
|
|
24956
25024
|
}
|
|
24957
25025
|
});
|
|
24958
25026
|
|
|
@@ -28923,71 +28991,6 @@ var init_customInstructions = __esm({
|
|
|
28923
28991
|
}
|
|
28924
28992
|
});
|
|
28925
28993
|
|
|
28926
|
-
// ../../src/core/statusCardFrame.ts
|
|
28927
|
-
function createCardShell(opts) {
|
|
28928
|
-
let label = opts.label;
|
|
28929
|
-
let link = opts.link;
|
|
28930
|
-
let frame = 0;
|
|
28931
|
-
let finishedAt;
|
|
28932
|
-
let setupLabel;
|
|
28933
|
-
const lead = opts.lead ?? [];
|
|
28934
|
-
const elapsed2 = () => formatDuration((finishedAt ?? opts.now()) - opts.startedAt, "clock");
|
|
28935
|
-
const headline = (icon) => `${icon} ${label} \xB7 ${elapsed2()}`;
|
|
28936
|
-
const closeDetail = (close, own) => [close.shape, close.queued, own, opts.footer].filter(Boolean).join("\n") || void 0;
|
|
28937
|
-
return {
|
|
28938
|
-
get label() {
|
|
28939
|
-
return label;
|
|
28940
|
-
},
|
|
28941
|
-
setLabel(next) {
|
|
28942
|
-
label = next;
|
|
28943
|
-
},
|
|
28944
|
-
setLink(next) {
|
|
28945
|
-
link = next;
|
|
28946
|
-
},
|
|
28947
|
-
freeze(at) {
|
|
28948
|
-
finishedAt = at;
|
|
28949
|
-
},
|
|
28950
|
-
setSetupLabel(next) {
|
|
28951
|
-
setupLabel = next;
|
|
28952
|
-
},
|
|
28953
|
-
ack() {
|
|
28954
|
-
const detail = lead.join("\n");
|
|
28955
|
-
return { title: `\u{1F440} ${label} \xB7 preparing workspace\u2026`, ...detail ? { detail } : {} };
|
|
28956
|
-
},
|
|
28957
|
-
live(parts = {}) {
|
|
28958
|
-
const glyph = SPINNER_GLYPHS[frame++ % SPINNER_GLYPHS.length];
|
|
28959
|
-
const detail = [...lead, ...parts.detail ?? []].filter(Boolean).join("\n");
|
|
28960
|
-
return {
|
|
28961
|
-
title: headline(glyph) + (setupLabel ? ` \u2014 ${setupLabel}` : "") + (parts.suffix ?? "") + (parts.notice ? ` \xB7 ${parts.notice}` : ""),
|
|
28962
|
-
detail: detail || void 0,
|
|
28963
|
-
link
|
|
28964
|
-
};
|
|
28965
|
-
},
|
|
28966
|
-
close(close) {
|
|
28967
|
-
const detail = closeDetail(close, close.kind === "done" ? close.detail : void 0);
|
|
28968
|
-
switch (close.kind) {
|
|
28969
|
-
case "done":
|
|
28970
|
-
return { title: headline(close.icon), detail, link };
|
|
28971
|
-
case "not_started":
|
|
28972
|
-
return { title: `${close.icon} ${label} \xB7 not started (${close.reason}) \xB7 ${elapsed2()}`, detail };
|
|
28973
|
-
case "refused":
|
|
28974
|
-
return { title: `${close.icon} ${label} \xB7 ${close.reason} \xB7 ${elapsed2()}`, detail };
|
|
28975
|
-
case "setup_failed":
|
|
28976
|
-
return { title: `\u274C setup failed \xB7 ${close.reason} \xB7 ${elapsed2()}`, detail };
|
|
28977
|
-
}
|
|
28978
|
-
}
|
|
28979
|
-
};
|
|
28980
|
-
}
|
|
28981
|
-
var SPINNER_GLYPHS, LIVE_CARD_PREFIXES;
|
|
28982
|
-
var init_statusCardFrame = __esm({
|
|
28983
|
-
"../../src/core/statusCardFrame.ts"() {
|
|
28984
|
-
"use strict";
|
|
28985
|
-
init_formatDuration();
|
|
28986
|
-
SPINNER_GLYPHS = ["\u25D0", "\u25D3", "\u25D1", "\u25D2"];
|
|
28987
|
-
LIVE_CARD_PREFIXES = [...SPINNER_GLYPHS, "\u{1F440}"];
|
|
28988
|
-
}
|
|
28989
|
-
});
|
|
28990
|
-
|
|
28991
28994
|
// ../../src/core/statusCoalescer.ts
|
|
28992
28995
|
function coalesceStatus(inner, minIntervalMs, now = Date.now, schedule = setTimeout) {
|
|
28993
28996
|
let lastSentAt = -Infinity;
|
|
@@ -35969,9 +35972,12 @@ function findOrphanedCards(input) {
|
|
|
35969
35972
|
}
|
|
35970
35973
|
function interruptedCardFrame(cardText) {
|
|
35971
35974
|
const label = cardText.replace(LIVE_GLYPH_PREFIX, "").replace(SHUTDOWN_NOTICE_SUFFIX, "").replace(ACTIVITY_SUFFIX, "").replaceAll("<", "<").replaceAll(">", ">").replaceAll("&", "&").trim();
|
|
35975
|
+
const detail = "The bot restarted (a deploy) while this run was in flight, so the run was lost and this card stopped updating. Re-send your request to run it again.";
|
|
35976
|
+
const routed = label.includes(` \xB7 ${ROUTED_LABEL_PREFIX}`);
|
|
35972
35977
|
return {
|
|
35973
35978
|
title: `\u274C interrupted \xB7 ${label}`,
|
|
35974
|
-
detail:
|
|
35979
|
+
detail: routed ? `${detail}
|
|
35980
|
+
${ROUTED_CARD_FOOTER}` : detail
|
|
35975
35981
|
};
|
|
35976
35982
|
}
|
|
35977
35983
|
async function catchUpMissedMentions(opts) {
|
|
@@ -36282,9 +36288,14 @@ async function closeReclaimedCards(client, closures, warn = console.warn) {
|
|
|
36282
36288
|
let closed = 0;
|
|
36283
36289
|
for (const c of closures) {
|
|
36284
36290
|
if (!c.card || !(c.status in glyph)) continue;
|
|
36291
|
+
const detail = c.status === "interrupted" ? c.note ?? "The bot restarted while this run was in flight and it could not be resumed." : "The bot restarted after this run replied; its record is complete.";
|
|
36285
36292
|
const frame = {
|
|
36286
36293
|
title: `${glyph[c.status]} ${c.agent ?? "run"} \xB7 ${c.status.replace("_", " ")}`,
|
|
36287
|
-
|
|
36294
|
+
// A routed run's close ends with the override footer wherever it is
|
|
36295
|
+
// written: this is the close a person most needs it on — the run was
|
|
36296
|
+
// cut by a deploy, and `agent:<preset>` in a reply is how to run it again.
|
|
36297
|
+
detail: c.routed ? `${detail}
|
|
36298
|
+
${ROUTED_CARD_FOOTER}` : detail
|
|
36288
36299
|
};
|
|
36289
36300
|
try {
|
|
36290
36301
|
await client.chat.update({ channel: c.card.channel, ts: c.card.ts, ...render2(frame) });
|
|
@@ -36322,6 +36333,7 @@ var RENDER_DETAIL_RAW_MAX, liveCards, liveCardKey, foreignLiveCards, foreignLive
|
|
|
36322
36333
|
var init_statusCard = __esm({
|
|
36323
36334
|
"../../src/channels/slack/statusCard.ts"() {
|
|
36324
36335
|
"use strict";
|
|
36336
|
+
init_statusCardFrame();
|
|
36325
36337
|
init_slackEscape();
|
|
36326
36338
|
RENDER_DETAIL_RAW_MAX = 900;
|
|
36327
36339
|
liveCards = /* @__PURE__ */ new Set();
|
|
@@ -39712,6 +39724,9 @@ function prUrlOf(events) {
|
|
|
39712
39724
|
for (const e of events) if (e.type === "pr_opened" && typeof e.url === "string") url = e.url;
|
|
39713
39725
|
return url;
|
|
39714
39726
|
}
|
|
39727
|
+
function routedOf(events) {
|
|
39728
|
+
return events.some((e) => e.type === "run_meta" && e.agentSource === "route");
|
|
39729
|
+
}
|
|
39715
39730
|
async function reclaimRuns(opts) {
|
|
39716
39731
|
const { ledger, gen } = opts;
|
|
39717
39732
|
const now = opts.now ?? Date.now;
|
|
@@ -39786,6 +39801,7 @@ async function reclaimRuns(opts) {
|
|
|
39786
39801
|
events: events.length,
|
|
39787
39802
|
...row.meta.agent !== void 0 ? { agent: row.meta.agent } : {},
|
|
39788
39803
|
...prUrl2 !== void 0 ? { prUrl: prUrl2 } : {},
|
|
39804
|
+
...routedOf(events) ? { routed: true } : {},
|
|
39789
39805
|
...status3 === "interrupted" ? { note: closureNote(row.meta.agent, prUrl2) } : {}
|
|
39790
39806
|
});
|
|
39791
39807
|
log(
|
|
@@ -42787,7 +42803,8 @@ async function runBot() {
|
|
|
42787
42803
|
status: c.status,
|
|
42788
42804
|
agent: c.agent,
|
|
42789
42805
|
card: c.card,
|
|
42790
|
-
...c.note ? { note: c.note } : {}
|
|
42806
|
+
...c.note ? { note: c.note } : {},
|
|
42807
|
+
...c.routed ? { routed: true } : {}
|
|
42791
42808
|
})),
|
|
42792
42809
|
(w) => console.warn(w)
|
|
42793
42810
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coreplane/switchboard",
|
|
3
|
-
"version": "1.216.
|
|
3
|
+
"version": "1.216.1",
|
|
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",
|