@sideboard-ai/core 0.1.244 → 0.1.246
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/{agents-Q23R4WOR.js → agents-47WI5IV2.js} +1 -1
- package/dist/{agents-BQZ2CHXK.js → agents-G7F3BJNB.js} +1 -1
- package/dist/{chunk-2QRU4IFI.js → chunk-HRWCW6LC.js} +123 -26
- package/dist/{chunk-YJJ2A5CI.js → chunk-QFRX5S2E.js} +6 -4
- package/dist/{chunk-CYYQ6577.js → chunk-RLNEKXXT.js} +132 -27
- package/dist/{chunk-4HMV53AB.js → chunk-TLPJ44Y7.js} +5 -3
- package/dist/index.cjs +137 -28
- package/dist/index.d.cts +15 -6
- package/dist/index.d.ts +15 -6
- package/dist/index.js +7 -3
- package/dist/mcp/run-stdio.cjs +127 -28
- package/dist/mcp/run-stdio.js +3 -3
- package/dist/{orchestrator-ABF6QFE6.js → orchestrator-2QGJ7CW2.js} +2 -2
- package/dist/{orchestrator-ZJ6SYGW7.js → orchestrator-DPMS5KMY.js} +2 -2
- package/package.json +1 -1
|
@@ -1697,23 +1697,38 @@ function looksLikeComposerSkillExpansion(text) {
|
|
|
1697
1697
|
const t = text.trim();
|
|
1698
1698
|
return /^## Skill: \//m.test(t) && /Follow this skill for the request above:/i.test(t);
|
|
1699
1699
|
}
|
|
1700
|
+
var SKILL_FRONTMATTER_NAME = /^\s*name\s*:\s*['"]?([A-Za-z0-9][A-Za-z0-9._-]*)['"]?\s*$/m;
|
|
1701
|
+
function skillNameFromFrontmatter(text) {
|
|
1702
|
+
const t = text.trim();
|
|
1703
|
+
if (!t) return void 0;
|
|
1704
|
+
let yaml = t;
|
|
1705
|
+
if (!yaml.startsWith("---")) {
|
|
1706
|
+
const at = t.search(/(?:^|\n)---(?:\r?\n)/);
|
|
1707
|
+
if (at < 0 || at > 800) return void 0;
|
|
1708
|
+
yaml = t.slice(at).replace(/^\n/, "");
|
|
1709
|
+
}
|
|
1710
|
+
if (!yaml.startsWith("---")) return void 0;
|
|
1711
|
+
const close = yaml.indexOf("\n---", 3);
|
|
1712
|
+
if (close < 0) return void 0;
|
|
1713
|
+
return yaml.slice(3, close).match(SKILL_FRONTMATTER_NAME)?.[1];
|
|
1714
|
+
}
|
|
1715
|
+
function skillCommandFromBody(text) {
|
|
1716
|
+
return skillNameFromFrontmatter(text) ?? text.match(/^## Skill: \/([A-Za-z0-9][A-Za-z0-9._-]*)/m)?.[1] ?? text.match(/^Launching skill:\s*\/?([A-Za-z0-9][A-Za-z0-9._-]*)/im)?.[1];
|
|
1717
|
+
}
|
|
1700
1718
|
function looksLikeSkillBody(text) {
|
|
1701
1719
|
const t = text.trim();
|
|
1702
1720
|
if (!t) return false;
|
|
1703
1721
|
if (looksLikeComposerSkillExpansion(t)) return true;
|
|
1704
|
-
|
|
1722
|
+
if (skillNameFromFrontmatter(t) != null) return true;
|
|
1723
|
+
return /^Launching skill:/im.test(t) && /Base directory for this skill:/i.test(t);
|
|
1705
1724
|
}
|
|
1706
|
-
function
|
|
1725
|
+
function looksLikeIncompleteSkillDump(text) {
|
|
1707
1726
|
const t = text.trim();
|
|
1708
|
-
if (!t
|
|
1709
|
-
|
|
1710
|
-
if (
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
return m?.[1];
|
|
1714
|
-
}
|
|
1715
|
-
function skillCommandFromBody(text) {
|
|
1716
|
-
return skillNameFromFrontmatter(text) ?? text.match(/^## Skill: \/([A-Za-z0-9][A-Za-z0-9._-]*)/m)?.[1];
|
|
1727
|
+
if (!t || looksLikeSkillBody(t)) return false;
|
|
1728
|
+
if (/^## Skill: \//m.test(t)) return true;
|
|
1729
|
+
if (/^Launching skill:/im.test(t)) return true;
|
|
1730
|
+
if (/Base directory for this skill:/i.test(t)) return true;
|
|
1731
|
+
return t.startsWith("---") && SKILL_FRONTMATTER_NAME.test(t);
|
|
1717
1732
|
}
|
|
1718
1733
|
function isCompactToolName(name) {
|
|
1719
1734
|
const short = (name ?? "").replace(/^mcp__[^_]+__/, "").trim();
|
|
@@ -2032,22 +2047,78 @@ function withPartTimes(next, prev) {
|
|
|
2032
2047
|
const startedAt = prev && typeof prev.startedAt === "number" ? prev.startedAt : now;
|
|
2033
2048
|
return { ...next, startedAt, updatedAt: now };
|
|
2034
2049
|
}
|
|
2035
|
-
function skillToolFromTextPart(part, id) {
|
|
2050
|
+
function skillToolFromTextPart(part, id, status = "done") {
|
|
2036
2051
|
const command = skillCommandFromBody(part.text);
|
|
2037
2052
|
const input = command ? { skill: command } : void 0;
|
|
2038
2053
|
return {
|
|
2039
2054
|
type: "tool",
|
|
2040
|
-
id,
|
|
2055
|
+
id: command ? `skill-${command}` : id,
|
|
2041
2056
|
name: "Skill",
|
|
2042
2057
|
input,
|
|
2043
2058
|
description: toolDescription("Skill", input),
|
|
2044
|
-
status
|
|
2059
|
+
status,
|
|
2045
2060
|
result: clipToolResultForStore(part.text),
|
|
2046
2061
|
...part.parentId ? { parentId: part.parentId } : {},
|
|
2047
2062
|
startedAt: part.startedAt,
|
|
2048
2063
|
updatedAt: Date.now()
|
|
2049
2064
|
};
|
|
2050
2065
|
}
|
|
2066
|
+
function lastSkillToolIndex(parts, parentId) {
|
|
2067
|
+
for (let i = parts.length - 1; i >= 0; i--) {
|
|
2068
|
+
const p = parts[i];
|
|
2069
|
+
if (p.type === "tool" && isSkillToolName(p.name) && sameParentId(p.parentId, parentId)) {
|
|
2070
|
+
return i;
|
|
2071
|
+
}
|
|
2072
|
+
}
|
|
2073
|
+
return -1;
|
|
2074
|
+
}
|
|
2075
|
+
function lastRunningSkillIndex(parts, parentId) {
|
|
2076
|
+
for (let i = parts.length - 1; i >= 0; i--) {
|
|
2077
|
+
const p = parts[i];
|
|
2078
|
+
if (p.type === "tool" && isSkillToolName(p.name) && p.status === "running" && sameParentId(p.parentId, parentId)) {
|
|
2079
|
+
return i;
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
2082
|
+
return -1;
|
|
2083
|
+
}
|
|
2084
|
+
function markRunningSkillsDone(parts, parentId) {
|
|
2085
|
+
return parts.map((p) => {
|
|
2086
|
+
if (p.type === "tool" && isSkillToolName(p.name) && p.status === "running" && sameParentId(p.parentId, parentId)) {
|
|
2087
|
+
return withPartTimes({ ...p, status: "done" }, p);
|
|
2088
|
+
}
|
|
2089
|
+
return p;
|
|
2090
|
+
});
|
|
2091
|
+
}
|
|
2092
|
+
function promoteOrFoldSkillText(parts, textIdx) {
|
|
2093
|
+
const acc = parts[textIdx];
|
|
2094
|
+
if (acc?.type !== "text") return parts;
|
|
2095
|
+
const complete = looksLikeSkillBody(acc.text);
|
|
2096
|
+
const incomplete = looksLikeIncompleteSkillDump(acc.text);
|
|
2097
|
+
if (!complete && !incomplete) return parts;
|
|
2098
|
+
const existing = lastSkillToolIndex(parts, acc.parentId);
|
|
2099
|
+
if (existing >= 0 && existing !== textIdx) {
|
|
2100
|
+
const prev = parts[existing];
|
|
2101
|
+
const next2 = parts.filter((_, i) => i !== textIdx);
|
|
2102
|
+
const existingIdx = lastSkillToolIndex(next2, acc.parentId);
|
|
2103
|
+
if (existingIdx < 0) return parts;
|
|
2104
|
+
next2[existingIdx] = withPartTimes(
|
|
2105
|
+
{
|
|
2106
|
+
...prev,
|
|
2107
|
+
status: complete ? "done" : prev.status,
|
|
2108
|
+
result: clipToolResultForStore(acc.text) ?? prev.result
|
|
2109
|
+
},
|
|
2110
|
+
prev
|
|
2111
|
+
);
|
|
2112
|
+
return next2;
|
|
2113
|
+
}
|
|
2114
|
+
const next = [...parts];
|
|
2115
|
+
next[textIdx] = skillToolFromTextPart(
|
|
2116
|
+
acc,
|
|
2117
|
+
`skill-${next.length}`,
|
|
2118
|
+
complete ? "done" : "running"
|
|
2119
|
+
);
|
|
2120
|
+
return next;
|
|
2121
|
+
}
|
|
2051
2122
|
function compactSummaryPart(text, id = "compact-summary") {
|
|
2052
2123
|
return compactToolPart(text, id, { status: "done" });
|
|
2053
2124
|
}
|
|
@@ -2136,6 +2207,24 @@ function applyAgentEvent(parts, event) {
|
|
|
2136
2207
|
})
|
|
2137
2208
|
];
|
|
2138
2209
|
}
|
|
2210
|
+
const runningSkillIdx = lastRunningSkillIndex(parts, event.parentId);
|
|
2211
|
+
if (runningSkillIdx >= 0) {
|
|
2212
|
+
const prev = parts[runningSkillIdx];
|
|
2213
|
+
const result = `${prev.result ?? ""}${data}`;
|
|
2214
|
+
const next2 = [...parts];
|
|
2215
|
+
next2[runningSkillIdx] = withPartTimes(
|
|
2216
|
+
{
|
|
2217
|
+
...prev,
|
|
2218
|
+
result: clipToolResultForStore(result),
|
|
2219
|
+
// Stay running after the YAML `name:` fence so later content_block_delta
|
|
2220
|
+
// tokens of SKILL.md stay on this row. thinking / tool_use / finalizeParts
|
|
2221
|
+
// mark the row done so the real reply can be chat.
|
|
2222
|
+
status: "running"
|
|
2223
|
+
},
|
|
2224
|
+
prev
|
|
2225
|
+
);
|
|
2226
|
+
return next2;
|
|
2227
|
+
}
|
|
2139
2228
|
const next = [...parts];
|
|
2140
2229
|
const last = next[next.length - 1];
|
|
2141
2230
|
if (last?.type === "text" && sameParentId(last.parentId, event.parentId)) {
|
|
@@ -2157,9 +2246,10 @@ function applyAgentEvent(parts, event) {
|
|
|
2157
2246
|
);
|
|
2158
2247
|
}
|
|
2159
2248
|
const acc = next[next.length - 1];
|
|
2160
|
-
if (acc?.type === "text" &&
|
|
2161
|
-
next
|
|
2162
|
-
}
|
|
2249
|
+
if (acc?.type === "text" && (looksLikeSkillBody(acc.text) || looksLikeIncompleteSkillDump(acc.text))) {
|
|
2250
|
+
return promoteOrFoldSkillText(next, next.length - 1);
|
|
2251
|
+
}
|
|
2252
|
+
if (acc?.type === "text" && looksLikeConversationSummary(acc.text)) {
|
|
2163
2253
|
next[next.length - 1] = compactToolPart(acc.text, `compact-${next.length}`, {
|
|
2164
2254
|
parentId: acc.parentId,
|
|
2165
2255
|
status: "done",
|
|
@@ -2171,6 +2261,7 @@ function applyAgentEvent(parts, event) {
|
|
|
2171
2261
|
if (event.type === "thinking") {
|
|
2172
2262
|
const data = event.data;
|
|
2173
2263
|
if (!data) return parts;
|
|
2264
|
+
parts = markRunningSkillsDone(parts, event.parentId);
|
|
2174
2265
|
const next = [...parts];
|
|
2175
2266
|
if (event.replace) {
|
|
2176
2267
|
for (let i = next.length - 1; i >= 0; i--) {
|
|
@@ -2218,6 +2309,7 @@ function applyAgentEvent(parts, event) {
|
|
|
2218
2309
|
return withCompactFinish(next, data, event.parentId);
|
|
2219
2310
|
}
|
|
2220
2311
|
if (event.type === "tool_use") {
|
|
2312
|
+
parts = markRunningSkillsDone(parts, event.parentId);
|
|
2221
2313
|
const input = asRecord(event.input);
|
|
2222
2314
|
const diff = diffFromInput(input);
|
|
2223
2315
|
const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
|
|
@@ -2534,13 +2626,17 @@ function eventsFromInjectedUserText(text, parentId) {
|
|
|
2534
2626
|
if (looksLikeConversationSummary(text)) return compactToolEventsFromBody(text, parentId);
|
|
2535
2627
|
return [];
|
|
2536
2628
|
}
|
|
2629
|
+
function eventsFromAssistantText(text, parentId) {
|
|
2630
|
+
if (looksLikeSkillBody(text)) return skillToolEventsFromBody(text, parentId);
|
|
2631
|
+
return [withEventParentId({ type: "stdout", data: text }, parentId)];
|
|
2632
|
+
}
|
|
2537
2633
|
function eventsFromUserContent(content, parentId) {
|
|
2538
2634
|
if (typeof content === "string" && content.trim()) {
|
|
2539
2635
|
return eventsFromInjectedUserText(content, parentId);
|
|
2540
2636
|
}
|
|
2541
2637
|
if (!Array.isArray(content) || content.length === 0) return [];
|
|
2542
2638
|
const out = [];
|
|
2543
|
-
const
|
|
2639
|
+
const injected = [];
|
|
2544
2640
|
for (const block of content) {
|
|
2545
2641
|
if (!block?.type) continue;
|
|
2546
2642
|
if (block.type === "tool_use" && block.id && block.name) {
|
|
@@ -2571,13 +2667,12 @@ function eventsFromUserContent(content, parentId) {
|
|
|
2571
2667
|
);
|
|
2572
2668
|
continue;
|
|
2573
2669
|
}
|
|
2574
|
-
if (block.type === "text" && block.text)
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
for (const text of textBlocks) {
|
|
2578
|
-
out.push(...eventsFromInjectedUserText(text, parentId));
|
|
2670
|
+
if (block.type === "text" && block.text) {
|
|
2671
|
+
injected.push(...eventsFromInjectedUserText(block.text, parentId));
|
|
2672
|
+
}
|
|
2579
2673
|
}
|
|
2580
|
-
return
|
|
2674
|
+
if (out.length === 0 && injected.length === 0) return [];
|
|
2675
|
+
return [...out, ...injected];
|
|
2581
2676
|
}
|
|
2582
2677
|
function eventsFromContentBlocks(blocks, parentId) {
|
|
2583
2678
|
if (!blocks?.length) return [];
|
|
@@ -2585,7 +2680,7 @@ function eventsFromContentBlocks(blocks, parentId) {
|
|
|
2585
2680
|
for (const block of blocks) {
|
|
2586
2681
|
if (!block?.type) continue;
|
|
2587
2682
|
if (block.type === "text" && block.text) {
|
|
2588
|
-
out.push(
|
|
2683
|
+
out.push(...eventsFromAssistantText(block.text, parentId));
|
|
2589
2684
|
continue;
|
|
2590
2685
|
}
|
|
2591
2686
|
if ((block.type === "thinking" || block.type === "redacted_thinking") && block.thinking) {
|
|
@@ -3014,7 +3109,9 @@ var claudeAdapter = {
|
|
|
3014
3109
|
events.push({ type: "stderr", data: errorDetail });
|
|
3015
3110
|
} else {
|
|
3016
3111
|
const text = obj.result;
|
|
3017
|
-
if (typeof text === "string" && text)
|
|
3112
|
+
if (typeof text === "string" && text) {
|
|
3113
|
+
events.push(...eventsFromAssistantText(text));
|
|
3114
|
+
}
|
|
3018
3115
|
}
|
|
3019
3116
|
const usage = usageFromClaude(obj.usage);
|
|
3020
3117
|
if (usage) {
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
resolveQuotaFallbackAgent,
|
|
26
26
|
stripBrightsyNdjsonNoise,
|
|
27
27
|
toolDescription
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-RLNEKXXT.js";
|
|
29
29
|
import {
|
|
30
30
|
SLACK_REPLY_FORMATTING,
|
|
31
31
|
addWorkspace,
|
|
@@ -558,9 +558,11 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
558
558
|
if (assistantText && (parsed.data === assistantText || assistantText.endsWith(parsed.data))) {
|
|
559
559
|
continue;
|
|
560
560
|
}
|
|
561
|
-
assistantText += parsed.data;
|
|
562
561
|
}
|
|
563
562
|
parts = applyAgentEvent(parts, parsed);
|
|
563
|
+
if (parsed.type === "stdout") {
|
|
564
|
+
assistantText = partsToAssistantText(parts);
|
|
565
|
+
}
|
|
564
566
|
outbound.push(parsed);
|
|
565
567
|
}
|
|
566
568
|
});
|
|
@@ -4221,7 +4223,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
4221
4223
|
return readThread(thread.id) ?? thread;
|
|
4222
4224
|
}
|
|
4223
4225
|
async function listLinearIssues(agent, repoPath) {
|
|
4224
|
-
const { getAdapter: getAdapter2 } = await import("./agents-
|
|
4226
|
+
const { getAdapter: getAdapter2 } = await import("./agents-47WI5IV2.js");
|
|
4225
4227
|
await requireAgent(agent, { requireLinear: true });
|
|
4226
4228
|
const adapter = getAdapter2(agent);
|
|
4227
4229
|
if (!adapter.listLinearIssues) {
|
|
@@ -7406,7 +7408,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
7406
7408
|
${prompt}`;
|
|
7407
7409
|
}
|
|
7408
7410
|
async function defaultDeps() {
|
|
7409
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
7411
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-2QGJ7CW2.js");
|
|
7410
7412
|
const orch = getOrchestrator2();
|
|
7411
7413
|
return {
|
|
7412
7414
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -1187,23 +1187,38 @@ function looksLikeComposerSkillExpansion(text) {
|
|
|
1187
1187
|
const t = text.trim();
|
|
1188
1188
|
return /^## Skill: \//m.test(t) && /Follow this skill for the request above:/i.test(t);
|
|
1189
1189
|
}
|
|
1190
|
+
var SKILL_FRONTMATTER_NAME = /^\s*name\s*:\s*['"]?([A-Za-z0-9][A-Za-z0-9._-]*)['"]?\s*$/m;
|
|
1191
|
+
function skillNameFromFrontmatter(text) {
|
|
1192
|
+
const t = text.trim();
|
|
1193
|
+
if (!t) return void 0;
|
|
1194
|
+
let yaml = t;
|
|
1195
|
+
if (!yaml.startsWith("---")) {
|
|
1196
|
+
const at = t.search(/(?:^|\n)---(?:\r?\n)/);
|
|
1197
|
+
if (at < 0 || at > 800) return void 0;
|
|
1198
|
+
yaml = t.slice(at).replace(/^\n/, "");
|
|
1199
|
+
}
|
|
1200
|
+
if (!yaml.startsWith("---")) return void 0;
|
|
1201
|
+
const close = yaml.indexOf("\n---", 3);
|
|
1202
|
+
if (close < 0) return void 0;
|
|
1203
|
+
return yaml.slice(3, close).match(SKILL_FRONTMATTER_NAME)?.[1];
|
|
1204
|
+
}
|
|
1205
|
+
function skillCommandFromBody(text) {
|
|
1206
|
+
return skillNameFromFrontmatter(text) ?? text.match(/^## Skill: \/([A-Za-z0-9][A-Za-z0-9._-]*)/m)?.[1] ?? text.match(/^Launching skill:\s*\/?([A-Za-z0-9][A-Za-z0-9._-]*)/im)?.[1];
|
|
1207
|
+
}
|
|
1190
1208
|
function looksLikeSkillBody(text) {
|
|
1191
1209
|
const t = text.trim();
|
|
1192
1210
|
if (!t) return false;
|
|
1193
1211
|
if (looksLikeComposerSkillExpansion(t)) return true;
|
|
1194
|
-
|
|
1212
|
+
if (skillNameFromFrontmatter(t) != null) return true;
|
|
1213
|
+
return /^Launching skill:/im.test(t) && /Base directory for this skill:/i.test(t);
|
|
1195
1214
|
}
|
|
1196
|
-
function
|
|
1215
|
+
function looksLikeIncompleteSkillDump(text) {
|
|
1197
1216
|
const t = text.trim();
|
|
1198
|
-
if (!t
|
|
1199
|
-
|
|
1200
|
-
if (
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
return m?.[1];
|
|
1204
|
-
}
|
|
1205
|
-
function skillCommandFromBody(text) {
|
|
1206
|
-
return skillNameFromFrontmatter(text) ?? text.match(/^## Skill: \/([A-Za-z0-9][A-Za-z0-9._-]*)/m)?.[1];
|
|
1217
|
+
if (!t || looksLikeSkillBody(t)) return false;
|
|
1218
|
+
if (/^## Skill: \//m.test(t)) return true;
|
|
1219
|
+
if (/^Launching skill:/im.test(t)) return true;
|
|
1220
|
+
if (/Base directory for this skill:/i.test(t)) return true;
|
|
1221
|
+
return t.startsWith("---") && SKILL_FRONTMATTER_NAME.test(t);
|
|
1207
1222
|
}
|
|
1208
1223
|
function isCompactToolName(name) {
|
|
1209
1224
|
const short = (name ?? "").replace(/^mcp__[^_]+__/, "").trim();
|
|
@@ -1605,22 +1620,78 @@ function withPartTimes(next, prev) {
|
|
|
1605
1620
|
const startedAt = prev && typeof prev.startedAt === "number" ? prev.startedAt : now;
|
|
1606
1621
|
return { ...next, startedAt, updatedAt: now };
|
|
1607
1622
|
}
|
|
1608
|
-
function skillToolFromTextPart(part, id) {
|
|
1623
|
+
function skillToolFromTextPart(part, id, status = "done") {
|
|
1609
1624
|
const command = skillCommandFromBody(part.text);
|
|
1610
1625
|
const input = command ? { skill: command } : void 0;
|
|
1611
1626
|
return {
|
|
1612
1627
|
type: "tool",
|
|
1613
|
-
id,
|
|
1628
|
+
id: command ? `skill-${command}` : id,
|
|
1614
1629
|
name: "Skill",
|
|
1615
1630
|
input,
|
|
1616
1631
|
description: toolDescription("Skill", input),
|
|
1617
|
-
status
|
|
1632
|
+
status,
|
|
1618
1633
|
result: clipToolResultForStore(part.text),
|
|
1619
1634
|
...part.parentId ? { parentId: part.parentId } : {},
|
|
1620
1635
|
startedAt: part.startedAt,
|
|
1621
1636
|
updatedAt: Date.now()
|
|
1622
1637
|
};
|
|
1623
1638
|
}
|
|
1639
|
+
function lastSkillToolIndex(parts, parentId) {
|
|
1640
|
+
for (let i = parts.length - 1; i >= 0; i--) {
|
|
1641
|
+
const p = parts[i];
|
|
1642
|
+
if (p.type === "tool" && isSkillToolName(p.name) && sameParentId(p.parentId, parentId)) {
|
|
1643
|
+
return i;
|
|
1644
|
+
}
|
|
1645
|
+
}
|
|
1646
|
+
return -1;
|
|
1647
|
+
}
|
|
1648
|
+
function lastRunningSkillIndex(parts, parentId) {
|
|
1649
|
+
for (let i = parts.length - 1; i >= 0; i--) {
|
|
1650
|
+
const p = parts[i];
|
|
1651
|
+
if (p.type === "tool" && isSkillToolName(p.name) && p.status === "running" && sameParentId(p.parentId, parentId)) {
|
|
1652
|
+
return i;
|
|
1653
|
+
}
|
|
1654
|
+
}
|
|
1655
|
+
return -1;
|
|
1656
|
+
}
|
|
1657
|
+
function markRunningSkillsDone(parts, parentId) {
|
|
1658
|
+
return parts.map((p) => {
|
|
1659
|
+
if (p.type === "tool" && isSkillToolName(p.name) && p.status === "running" && sameParentId(p.parentId, parentId)) {
|
|
1660
|
+
return withPartTimes({ ...p, status: "done" }, p);
|
|
1661
|
+
}
|
|
1662
|
+
return p;
|
|
1663
|
+
});
|
|
1664
|
+
}
|
|
1665
|
+
function promoteOrFoldSkillText(parts, textIdx) {
|
|
1666
|
+
const acc = parts[textIdx];
|
|
1667
|
+
if (acc?.type !== "text") return parts;
|
|
1668
|
+
const complete = looksLikeSkillBody(acc.text);
|
|
1669
|
+
const incomplete = looksLikeIncompleteSkillDump(acc.text);
|
|
1670
|
+
if (!complete && !incomplete) return parts;
|
|
1671
|
+
const existing = lastSkillToolIndex(parts, acc.parentId);
|
|
1672
|
+
if (existing >= 0 && existing !== textIdx) {
|
|
1673
|
+
const prev = parts[existing];
|
|
1674
|
+
const next2 = parts.filter((_, i) => i !== textIdx);
|
|
1675
|
+
const existingIdx = lastSkillToolIndex(next2, acc.parentId);
|
|
1676
|
+
if (existingIdx < 0) return parts;
|
|
1677
|
+
next2[existingIdx] = withPartTimes(
|
|
1678
|
+
{
|
|
1679
|
+
...prev,
|
|
1680
|
+
status: complete ? "done" : prev.status,
|
|
1681
|
+
result: clipToolResultForStore(acc.text) ?? prev.result
|
|
1682
|
+
},
|
|
1683
|
+
prev
|
|
1684
|
+
);
|
|
1685
|
+
return next2;
|
|
1686
|
+
}
|
|
1687
|
+
const next = [...parts];
|
|
1688
|
+
next[textIdx] = skillToolFromTextPart(
|
|
1689
|
+
acc,
|
|
1690
|
+
`skill-${next.length}`,
|
|
1691
|
+
complete ? "done" : "running"
|
|
1692
|
+
);
|
|
1693
|
+
return next;
|
|
1694
|
+
}
|
|
1624
1695
|
function compactSummaryPart(text, id = "compact-summary") {
|
|
1625
1696
|
return compactToolPart(text, id, { status: "done" });
|
|
1626
1697
|
}
|
|
@@ -1716,6 +1787,24 @@ function applyAgentEvent(parts, event) {
|
|
|
1716
1787
|
})
|
|
1717
1788
|
];
|
|
1718
1789
|
}
|
|
1790
|
+
const runningSkillIdx = lastRunningSkillIndex(parts, event.parentId);
|
|
1791
|
+
if (runningSkillIdx >= 0) {
|
|
1792
|
+
const prev = parts[runningSkillIdx];
|
|
1793
|
+
const result = `${prev.result ?? ""}${data}`;
|
|
1794
|
+
const next2 = [...parts];
|
|
1795
|
+
next2[runningSkillIdx] = withPartTimes(
|
|
1796
|
+
{
|
|
1797
|
+
...prev,
|
|
1798
|
+
result: clipToolResultForStore(result),
|
|
1799
|
+
// Stay running after the YAML `name:` fence so later content_block_delta
|
|
1800
|
+
// tokens of SKILL.md stay on this row. thinking / tool_use / finalizeParts
|
|
1801
|
+
// mark the row done so the real reply can be chat.
|
|
1802
|
+
status: "running"
|
|
1803
|
+
},
|
|
1804
|
+
prev
|
|
1805
|
+
);
|
|
1806
|
+
return next2;
|
|
1807
|
+
}
|
|
1719
1808
|
const next = [...parts];
|
|
1720
1809
|
const last = next[next.length - 1];
|
|
1721
1810
|
if (last?.type === "text" && sameParentId(last.parentId, event.parentId)) {
|
|
@@ -1737,9 +1826,10 @@ function applyAgentEvent(parts, event) {
|
|
|
1737
1826
|
);
|
|
1738
1827
|
}
|
|
1739
1828
|
const acc = next[next.length - 1];
|
|
1740
|
-
if (acc?.type === "text" &&
|
|
1741
|
-
next
|
|
1742
|
-
}
|
|
1829
|
+
if (acc?.type === "text" && (looksLikeSkillBody(acc.text) || looksLikeIncompleteSkillDump(acc.text))) {
|
|
1830
|
+
return promoteOrFoldSkillText(next, next.length - 1);
|
|
1831
|
+
}
|
|
1832
|
+
if (acc?.type === "text" && looksLikeConversationSummary(acc.text)) {
|
|
1743
1833
|
next[next.length - 1] = compactToolPart(acc.text, `compact-${next.length}`, {
|
|
1744
1834
|
parentId: acc.parentId,
|
|
1745
1835
|
status: "done",
|
|
@@ -1751,6 +1841,7 @@ function applyAgentEvent(parts, event) {
|
|
|
1751
1841
|
if (event.type === "thinking") {
|
|
1752
1842
|
const data = event.data;
|
|
1753
1843
|
if (!data) return parts;
|
|
1844
|
+
parts = markRunningSkillsDone(parts, event.parentId);
|
|
1754
1845
|
const next = [...parts];
|
|
1755
1846
|
if (event.replace) {
|
|
1756
1847
|
for (let i = next.length - 1; i >= 0; i--) {
|
|
@@ -1798,6 +1889,7 @@ function applyAgentEvent(parts, event) {
|
|
|
1798
1889
|
return withCompactFinish(next, data, event.parentId);
|
|
1799
1890
|
}
|
|
1800
1891
|
if (event.type === "tool_use") {
|
|
1892
|
+
parts = markRunningSkillsDone(parts, event.parentId);
|
|
1801
1893
|
const input = asRecord(event.input);
|
|
1802
1894
|
const diff = diffFromInput(input);
|
|
1803
1895
|
const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
|
|
@@ -1908,6 +2000,12 @@ function partsToAssistantText(parts) {
|
|
|
1908
2000
|
(p) => p.type === "text" && !messagePartParentId(p)
|
|
1909
2001
|
).map((p) => p.text).join("").trim();
|
|
1910
2002
|
}
|
|
2003
|
+
function visibleAssistantText(text, parts) {
|
|
2004
|
+
const fromParts = partsToAssistantText(parts ?? []);
|
|
2005
|
+
if (fromParts) return fromParts;
|
|
2006
|
+
if (parts?.some((p) => p.type === "tool" || p.type === "thinking")) return "";
|
|
2007
|
+
return (text ?? "").trim();
|
|
2008
|
+
}
|
|
1911
2009
|
function lastAssistantMessageText(parts) {
|
|
1912
2010
|
if (!parts?.length) return "";
|
|
1913
2011
|
for (let i = parts.length - 1; i >= 0; i--) {
|
|
@@ -2114,13 +2212,17 @@ function eventsFromInjectedUserText(text, parentId) {
|
|
|
2114
2212
|
if (looksLikeConversationSummary(text)) return compactToolEventsFromBody(text, parentId);
|
|
2115
2213
|
return [];
|
|
2116
2214
|
}
|
|
2215
|
+
function eventsFromAssistantText(text, parentId) {
|
|
2216
|
+
if (looksLikeSkillBody(text)) return skillToolEventsFromBody(text, parentId);
|
|
2217
|
+
return [withEventParentId({ type: "stdout", data: text }, parentId)];
|
|
2218
|
+
}
|
|
2117
2219
|
function eventsFromUserContent(content, parentId) {
|
|
2118
2220
|
if (typeof content === "string" && content.trim()) {
|
|
2119
2221
|
return eventsFromInjectedUserText(content, parentId);
|
|
2120
2222
|
}
|
|
2121
2223
|
if (!Array.isArray(content) || content.length === 0) return [];
|
|
2122
2224
|
const out = [];
|
|
2123
|
-
const
|
|
2225
|
+
const injected = [];
|
|
2124
2226
|
for (const block of content) {
|
|
2125
2227
|
if (!block?.type) continue;
|
|
2126
2228
|
if (block.type === "tool_use" && block.id && block.name) {
|
|
@@ -2151,13 +2253,12 @@ function eventsFromUserContent(content, parentId) {
|
|
|
2151
2253
|
);
|
|
2152
2254
|
continue;
|
|
2153
2255
|
}
|
|
2154
|
-
if (block.type === "text" && block.text)
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
for (const text of textBlocks) {
|
|
2158
|
-
out.push(...eventsFromInjectedUserText(text, parentId));
|
|
2256
|
+
if (block.type === "text" && block.text) {
|
|
2257
|
+
injected.push(...eventsFromInjectedUserText(block.text, parentId));
|
|
2258
|
+
}
|
|
2159
2259
|
}
|
|
2160
|
-
return
|
|
2260
|
+
if (out.length === 0 && injected.length === 0) return [];
|
|
2261
|
+
return [...out, ...injected];
|
|
2161
2262
|
}
|
|
2162
2263
|
function eventsFromContentBlocks(blocks, parentId) {
|
|
2163
2264
|
if (!blocks?.length) return [];
|
|
@@ -2165,7 +2266,7 @@ function eventsFromContentBlocks(blocks, parentId) {
|
|
|
2165
2266
|
for (const block of blocks) {
|
|
2166
2267
|
if (!block?.type) continue;
|
|
2167
2268
|
if (block.type === "text" && block.text) {
|
|
2168
|
-
out.push(
|
|
2269
|
+
out.push(...eventsFromAssistantText(block.text, parentId));
|
|
2169
2270
|
continue;
|
|
2170
2271
|
}
|
|
2171
2272
|
if ((block.type === "thinking" || block.type === "redacted_thinking") && block.thinking) {
|
|
@@ -2594,7 +2695,9 @@ var claudeAdapter = {
|
|
|
2594
2695
|
events.push({ type: "stderr", data: errorDetail });
|
|
2595
2696
|
} else {
|
|
2596
2697
|
const text = obj.result;
|
|
2597
|
-
if (typeof text === "string" && text)
|
|
2698
|
+
if (typeof text === "string" && text) {
|
|
2699
|
+
events.push(...eventsFromAssistantText(text));
|
|
2700
|
+
}
|
|
2598
2701
|
}
|
|
2599
2702
|
const usage = usageFromClaude(obj.usage);
|
|
2600
2703
|
if (usage) {
|
|
@@ -4419,9 +4522,10 @@ export {
|
|
|
4419
4522
|
isSkillToolName,
|
|
4420
4523
|
skillCommandFromInput,
|
|
4421
4524
|
looksLikeComposerSkillExpansion,
|
|
4422
|
-
looksLikeSkillBody,
|
|
4423
4525
|
skillNameFromFrontmatter,
|
|
4424
4526
|
skillCommandFromBody,
|
|
4527
|
+
looksLikeSkillBody,
|
|
4528
|
+
looksLikeIncompleteSkillDump,
|
|
4425
4529
|
isCompactToolName,
|
|
4426
4530
|
isContextCompactDone,
|
|
4427
4531
|
isContextCompactInProgress,
|
|
@@ -4447,6 +4551,7 @@ export {
|
|
|
4447
4551
|
compactPartsForSummaryMessage,
|
|
4448
4552
|
applyAgentEvent,
|
|
4449
4553
|
partsToAssistantText,
|
|
4554
|
+
visibleAssistantText,
|
|
4450
4555
|
lastAssistantMessageText,
|
|
4451
4556
|
stripBrightsyNdjsonNoise,
|
|
4452
4557
|
isBrightsyNdjsonLine,
|
|
@@ -44,7 +44,7 @@ import {
|
|
|
44
44
|
summarizeTurnStderr,
|
|
45
45
|
toolDescription,
|
|
46
46
|
turnFailChatText
|
|
47
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-HRWCW6LC.js";
|
|
48
48
|
import {
|
|
49
49
|
SLACK_REPLY_FORMATTING,
|
|
50
50
|
addWorkspace,
|
|
@@ -606,9 +606,11 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
606
606
|
if (assistantText && (parsed.data === assistantText || assistantText.endsWith(parsed.data))) {
|
|
607
607
|
continue;
|
|
608
608
|
}
|
|
609
|
-
assistantText += parsed.data;
|
|
610
609
|
}
|
|
611
610
|
parts = applyAgentEvent(parts, parsed);
|
|
611
|
+
if (parsed.type === "stdout") {
|
|
612
|
+
assistantText = partsToAssistantText(parts);
|
|
613
|
+
}
|
|
612
614
|
outbound.push(parsed);
|
|
613
615
|
}
|
|
614
616
|
});
|
|
@@ -7058,7 +7060,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
7058
7060
|
${prompt}`;
|
|
7059
7061
|
}
|
|
7060
7062
|
async function defaultDeps() {
|
|
7061
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
7063
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-DPMS5KMY.js");
|
|
7062
7064
|
const orch = getOrchestrator2();
|
|
7063
7065
|
return {
|
|
7064
7066
|
findThread: (id) => findThreadByRef(id),
|