@sideboard-ai/core 0.1.244 → 0.1.245
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-BOIIFMNG.js} +1 -1
- package/dist/{agents-BQZ2CHXK.js → agents-FTQZFMDS.js} +1 -1
- package/dist/{chunk-2QRU4IFI.js → chunk-3ZEBUVUI.js} +110 -26
- package/dist/{chunk-4HMV53AB.js → chunk-J5IZXFLD.js} +5 -3
- package/dist/{chunk-YJJ2A5CI.js → chunk-NT6MCFSB.js} +6 -4
- package/dist/{chunk-CYYQ6577.js → chunk-QRWVKBGP.js} +119 -27
- package/dist/index.cjs +124 -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 +114 -28
- package/dist/mcp/run-stdio.js +3 -3
- package/dist/{orchestrator-ZJ6SYGW7.js → orchestrator-5ROSTGGH.js} +2 -2
- package/dist/{orchestrator-ABF6QFE6.js → orchestrator-7YCQ7V5S.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,70 @@ 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 promoteOrFoldSkillText(parts, textIdx) {
|
|
2085
|
+
const acc = parts[textIdx];
|
|
2086
|
+
if (acc?.type !== "text") return parts;
|
|
2087
|
+
const complete = looksLikeSkillBody(acc.text);
|
|
2088
|
+
const incomplete = looksLikeIncompleteSkillDump(acc.text);
|
|
2089
|
+
if (!complete && !incomplete) return parts;
|
|
2090
|
+
const existing = lastSkillToolIndex(parts, acc.parentId);
|
|
2091
|
+
if (existing >= 0 && existing !== textIdx) {
|
|
2092
|
+
const prev = parts[existing];
|
|
2093
|
+
const next2 = parts.filter((_, i) => i !== textIdx);
|
|
2094
|
+
const existingIdx = lastSkillToolIndex(next2, acc.parentId);
|
|
2095
|
+
if (existingIdx < 0) return parts;
|
|
2096
|
+
next2[existingIdx] = withPartTimes(
|
|
2097
|
+
{
|
|
2098
|
+
...prev,
|
|
2099
|
+
status: complete ? "done" : prev.status,
|
|
2100
|
+
result: clipToolResultForStore(acc.text) ?? prev.result
|
|
2101
|
+
},
|
|
2102
|
+
prev
|
|
2103
|
+
);
|
|
2104
|
+
return next2;
|
|
2105
|
+
}
|
|
2106
|
+
const next = [...parts];
|
|
2107
|
+
next[textIdx] = skillToolFromTextPart(
|
|
2108
|
+
acc,
|
|
2109
|
+
`skill-${next.length}`,
|
|
2110
|
+
complete ? "done" : "running"
|
|
2111
|
+
);
|
|
2112
|
+
return next;
|
|
2113
|
+
}
|
|
2051
2114
|
function compactSummaryPart(text, id = "compact-summary") {
|
|
2052
2115
|
return compactToolPart(text, id, { status: "done" });
|
|
2053
2116
|
}
|
|
@@ -2136,6 +2199,21 @@ function applyAgentEvent(parts, event) {
|
|
|
2136
2199
|
})
|
|
2137
2200
|
];
|
|
2138
2201
|
}
|
|
2202
|
+
const runningSkillIdx = lastRunningSkillIndex(parts, event.parentId);
|
|
2203
|
+
if (runningSkillIdx >= 0) {
|
|
2204
|
+
const prev = parts[runningSkillIdx];
|
|
2205
|
+
const result = `${prev.result ?? ""}${data}`;
|
|
2206
|
+
const next2 = [...parts];
|
|
2207
|
+
next2[runningSkillIdx] = withPartTimes(
|
|
2208
|
+
{
|
|
2209
|
+
...prev,
|
|
2210
|
+
result: clipToolResultForStore(result),
|
|
2211
|
+
status: looksLikeSkillBody(result) ? "done" : prev.status
|
|
2212
|
+
},
|
|
2213
|
+
prev
|
|
2214
|
+
);
|
|
2215
|
+
return next2;
|
|
2216
|
+
}
|
|
2139
2217
|
const next = [...parts];
|
|
2140
2218
|
const last = next[next.length - 1];
|
|
2141
2219
|
if (last?.type === "text" && sameParentId(last.parentId, event.parentId)) {
|
|
@@ -2157,9 +2235,10 @@ function applyAgentEvent(parts, event) {
|
|
|
2157
2235
|
);
|
|
2158
2236
|
}
|
|
2159
2237
|
const acc = next[next.length - 1];
|
|
2160
|
-
if (acc?.type === "text" &&
|
|
2161
|
-
next
|
|
2162
|
-
}
|
|
2238
|
+
if (acc?.type === "text" && (looksLikeSkillBody(acc.text) || looksLikeIncompleteSkillDump(acc.text))) {
|
|
2239
|
+
return promoteOrFoldSkillText(next, next.length - 1);
|
|
2240
|
+
}
|
|
2241
|
+
if (acc?.type === "text" && looksLikeConversationSummary(acc.text)) {
|
|
2163
2242
|
next[next.length - 1] = compactToolPart(acc.text, `compact-${next.length}`, {
|
|
2164
2243
|
parentId: acc.parentId,
|
|
2165
2244
|
status: "done",
|
|
@@ -2534,13 +2613,17 @@ function eventsFromInjectedUserText(text, parentId) {
|
|
|
2534
2613
|
if (looksLikeConversationSummary(text)) return compactToolEventsFromBody(text, parentId);
|
|
2535
2614
|
return [];
|
|
2536
2615
|
}
|
|
2616
|
+
function eventsFromAssistantText(text, parentId) {
|
|
2617
|
+
if (looksLikeSkillBody(text)) return skillToolEventsFromBody(text, parentId);
|
|
2618
|
+
return [withEventParentId({ type: "stdout", data: text }, parentId)];
|
|
2619
|
+
}
|
|
2537
2620
|
function eventsFromUserContent(content, parentId) {
|
|
2538
2621
|
if (typeof content === "string" && content.trim()) {
|
|
2539
2622
|
return eventsFromInjectedUserText(content, parentId);
|
|
2540
2623
|
}
|
|
2541
2624
|
if (!Array.isArray(content) || content.length === 0) return [];
|
|
2542
2625
|
const out = [];
|
|
2543
|
-
const
|
|
2626
|
+
const injected = [];
|
|
2544
2627
|
for (const block of content) {
|
|
2545
2628
|
if (!block?.type) continue;
|
|
2546
2629
|
if (block.type === "tool_use" && block.id && block.name) {
|
|
@@ -2571,13 +2654,12 @@ function eventsFromUserContent(content, parentId) {
|
|
|
2571
2654
|
);
|
|
2572
2655
|
continue;
|
|
2573
2656
|
}
|
|
2574
|
-
if (block.type === "text" && block.text)
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
for (const text of textBlocks) {
|
|
2578
|
-
out.push(...eventsFromInjectedUserText(text, parentId));
|
|
2657
|
+
if (block.type === "text" && block.text) {
|
|
2658
|
+
injected.push(...eventsFromInjectedUserText(block.text, parentId));
|
|
2659
|
+
}
|
|
2579
2660
|
}
|
|
2580
|
-
return
|
|
2661
|
+
if (out.length === 0 && injected.length === 0) return [];
|
|
2662
|
+
return [...out, ...injected];
|
|
2581
2663
|
}
|
|
2582
2664
|
function eventsFromContentBlocks(blocks, parentId) {
|
|
2583
2665
|
if (!blocks?.length) return [];
|
|
@@ -2585,7 +2667,7 @@ function eventsFromContentBlocks(blocks, parentId) {
|
|
|
2585
2667
|
for (const block of blocks) {
|
|
2586
2668
|
if (!block?.type) continue;
|
|
2587
2669
|
if (block.type === "text" && block.text) {
|
|
2588
|
-
out.push(
|
|
2670
|
+
out.push(...eventsFromAssistantText(block.text, parentId));
|
|
2589
2671
|
continue;
|
|
2590
2672
|
}
|
|
2591
2673
|
if ((block.type === "thinking" || block.type === "redacted_thinking") && block.thinking) {
|
|
@@ -3014,7 +3096,9 @@ var claudeAdapter = {
|
|
|
3014
3096
|
events.push({ type: "stderr", data: errorDetail });
|
|
3015
3097
|
} else {
|
|
3016
3098
|
const text = obj.result;
|
|
3017
|
-
if (typeof text === "string" && text)
|
|
3099
|
+
if (typeof text === "string" && text) {
|
|
3100
|
+
events.push(...eventsFromAssistantText(text));
|
|
3101
|
+
}
|
|
3018
3102
|
}
|
|
3019
3103
|
const usage = usageFromClaude(obj.usage);
|
|
3020
3104
|
if (usage) {
|
|
@@ -44,7 +44,7 @@ import {
|
|
|
44
44
|
summarizeTurnStderr,
|
|
45
45
|
toolDescription,
|
|
46
46
|
turnFailChatText
|
|
47
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-3ZEBUVUI.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-5ROSTGGH.js");
|
|
7062
7064
|
const orch = getOrchestrator2();
|
|
7063
7065
|
return {
|
|
7064
7066
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
resolveQuotaFallbackAgent,
|
|
26
26
|
stripBrightsyNdjsonNoise,
|
|
27
27
|
toolDescription
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-QRWVKBGP.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-BOIIFMNG.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-7YCQ7V5S.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,70 @@ 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 promoteOrFoldSkillText(parts, textIdx) {
|
|
1658
|
+
const acc = parts[textIdx];
|
|
1659
|
+
if (acc?.type !== "text") return parts;
|
|
1660
|
+
const complete = looksLikeSkillBody(acc.text);
|
|
1661
|
+
const incomplete = looksLikeIncompleteSkillDump(acc.text);
|
|
1662
|
+
if (!complete && !incomplete) return parts;
|
|
1663
|
+
const existing = lastSkillToolIndex(parts, acc.parentId);
|
|
1664
|
+
if (existing >= 0 && existing !== textIdx) {
|
|
1665
|
+
const prev = parts[existing];
|
|
1666
|
+
const next2 = parts.filter((_, i) => i !== textIdx);
|
|
1667
|
+
const existingIdx = lastSkillToolIndex(next2, acc.parentId);
|
|
1668
|
+
if (existingIdx < 0) return parts;
|
|
1669
|
+
next2[existingIdx] = withPartTimes(
|
|
1670
|
+
{
|
|
1671
|
+
...prev,
|
|
1672
|
+
status: complete ? "done" : prev.status,
|
|
1673
|
+
result: clipToolResultForStore(acc.text) ?? prev.result
|
|
1674
|
+
},
|
|
1675
|
+
prev
|
|
1676
|
+
);
|
|
1677
|
+
return next2;
|
|
1678
|
+
}
|
|
1679
|
+
const next = [...parts];
|
|
1680
|
+
next[textIdx] = skillToolFromTextPart(
|
|
1681
|
+
acc,
|
|
1682
|
+
`skill-${next.length}`,
|
|
1683
|
+
complete ? "done" : "running"
|
|
1684
|
+
);
|
|
1685
|
+
return next;
|
|
1686
|
+
}
|
|
1624
1687
|
function compactSummaryPart(text, id = "compact-summary") {
|
|
1625
1688
|
return compactToolPart(text, id, { status: "done" });
|
|
1626
1689
|
}
|
|
@@ -1716,6 +1779,21 @@ function applyAgentEvent(parts, event) {
|
|
|
1716
1779
|
})
|
|
1717
1780
|
];
|
|
1718
1781
|
}
|
|
1782
|
+
const runningSkillIdx = lastRunningSkillIndex(parts, event.parentId);
|
|
1783
|
+
if (runningSkillIdx >= 0) {
|
|
1784
|
+
const prev = parts[runningSkillIdx];
|
|
1785
|
+
const result = `${prev.result ?? ""}${data}`;
|
|
1786
|
+
const next2 = [...parts];
|
|
1787
|
+
next2[runningSkillIdx] = withPartTimes(
|
|
1788
|
+
{
|
|
1789
|
+
...prev,
|
|
1790
|
+
result: clipToolResultForStore(result),
|
|
1791
|
+
status: looksLikeSkillBody(result) ? "done" : prev.status
|
|
1792
|
+
},
|
|
1793
|
+
prev
|
|
1794
|
+
);
|
|
1795
|
+
return next2;
|
|
1796
|
+
}
|
|
1719
1797
|
const next = [...parts];
|
|
1720
1798
|
const last = next[next.length - 1];
|
|
1721
1799
|
if (last?.type === "text" && sameParentId(last.parentId, event.parentId)) {
|
|
@@ -1737,9 +1815,10 @@ function applyAgentEvent(parts, event) {
|
|
|
1737
1815
|
);
|
|
1738
1816
|
}
|
|
1739
1817
|
const acc = next[next.length - 1];
|
|
1740
|
-
if (acc?.type === "text" &&
|
|
1741
|
-
next
|
|
1742
|
-
}
|
|
1818
|
+
if (acc?.type === "text" && (looksLikeSkillBody(acc.text) || looksLikeIncompleteSkillDump(acc.text))) {
|
|
1819
|
+
return promoteOrFoldSkillText(next, next.length - 1);
|
|
1820
|
+
}
|
|
1821
|
+
if (acc?.type === "text" && looksLikeConversationSummary(acc.text)) {
|
|
1743
1822
|
next[next.length - 1] = compactToolPart(acc.text, `compact-${next.length}`, {
|
|
1744
1823
|
parentId: acc.parentId,
|
|
1745
1824
|
status: "done",
|
|
@@ -1908,6 +1987,12 @@ function partsToAssistantText(parts) {
|
|
|
1908
1987
|
(p) => p.type === "text" && !messagePartParentId(p)
|
|
1909
1988
|
).map((p) => p.text).join("").trim();
|
|
1910
1989
|
}
|
|
1990
|
+
function visibleAssistantText(text, parts) {
|
|
1991
|
+
const fromParts = partsToAssistantText(parts ?? []);
|
|
1992
|
+
if (fromParts) return fromParts;
|
|
1993
|
+
if (parts?.some((p) => p.type === "tool" || p.type === "thinking")) return "";
|
|
1994
|
+
return (text ?? "").trim();
|
|
1995
|
+
}
|
|
1911
1996
|
function lastAssistantMessageText(parts) {
|
|
1912
1997
|
if (!parts?.length) return "";
|
|
1913
1998
|
for (let i = parts.length - 1; i >= 0; i--) {
|
|
@@ -2114,13 +2199,17 @@ function eventsFromInjectedUserText(text, parentId) {
|
|
|
2114
2199
|
if (looksLikeConversationSummary(text)) return compactToolEventsFromBody(text, parentId);
|
|
2115
2200
|
return [];
|
|
2116
2201
|
}
|
|
2202
|
+
function eventsFromAssistantText(text, parentId) {
|
|
2203
|
+
if (looksLikeSkillBody(text)) return skillToolEventsFromBody(text, parentId);
|
|
2204
|
+
return [withEventParentId({ type: "stdout", data: text }, parentId)];
|
|
2205
|
+
}
|
|
2117
2206
|
function eventsFromUserContent(content, parentId) {
|
|
2118
2207
|
if (typeof content === "string" && content.trim()) {
|
|
2119
2208
|
return eventsFromInjectedUserText(content, parentId);
|
|
2120
2209
|
}
|
|
2121
2210
|
if (!Array.isArray(content) || content.length === 0) return [];
|
|
2122
2211
|
const out = [];
|
|
2123
|
-
const
|
|
2212
|
+
const injected = [];
|
|
2124
2213
|
for (const block of content) {
|
|
2125
2214
|
if (!block?.type) continue;
|
|
2126
2215
|
if (block.type === "tool_use" && block.id && block.name) {
|
|
@@ -2151,13 +2240,12 @@ function eventsFromUserContent(content, parentId) {
|
|
|
2151
2240
|
);
|
|
2152
2241
|
continue;
|
|
2153
2242
|
}
|
|
2154
|
-
if (block.type === "text" && block.text)
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
for (const text of textBlocks) {
|
|
2158
|
-
out.push(...eventsFromInjectedUserText(text, parentId));
|
|
2243
|
+
if (block.type === "text" && block.text) {
|
|
2244
|
+
injected.push(...eventsFromInjectedUserText(block.text, parentId));
|
|
2245
|
+
}
|
|
2159
2246
|
}
|
|
2160
|
-
return
|
|
2247
|
+
if (out.length === 0 && injected.length === 0) return [];
|
|
2248
|
+
return [...out, ...injected];
|
|
2161
2249
|
}
|
|
2162
2250
|
function eventsFromContentBlocks(blocks, parentId) {
|
|
2163
2251
|
if (!blocks?.length) return [];
|
|
@@ -2165,7 +2253,7 @@ function eventsFromContentBlocks(blocks, parentId) {
|
|
|
2165
2253
|
for (const block of blocks) {
|
|
2166
2254
|
if (!block?.type) continue;
|
|
2167
2255
|
if (block.type === "text" && block.text) {
|
|
2168
|
-
out.push(
|
|
2256
|
+
out.push(...eventsFromAssistantText(block.text, parentId));
|
|
2169
2257
|
continue;
|
|
2170
2258
|
}
|
|
2171
2259
|
if ((block.type === "thinking" || block.type === "redacted_thinking") && block.thinking) {
|
|
@@ -2594,7 +2682,9 @@ var claudeAdapter = {
|
|
|
2594
2682
|
events.push({ type: "stderr", data: errorDetail });
|
|
2595
2683
|
} else {
|
|
2596
2684
|
const text = obj.result;
|
|
2597
|
-
if (typeof text === "string" && text)
|
|
2685
|
+
if (typeof text === "string" && text) {
|
|
2686
|
+
events.push(...eventsFromAssistantText(text));
|
|
2687
|
+
}
|
|
2598
2688
|
}
|
|
2599
2689
|
const usage = usageFromClaude(obj.usage);
|
|
2600
2690
|
if (usage) {
|
|
@@ -4419,9 +4509,10 @@ export {
|
|
|
4419
4509
|
isSkillToolName,
|
|
4420
4510
|
skillCommandFromInput,
|
|
4421
4511
|
looksLikeComposerSkillExpansion,
|
|
4422
|
-
looksLikeSkillBody,
|
|
4423
4512
|
skillNameFromFrontmatter,
|
|
4424
4513
|
skillCommandFromBody,
|
|
4514
|
+
looksLikeSkillBody,
|
|
4515
|
+
looksLikeIncompleteSkillDump,
|
|
4425
4516
|
isCompactToolName,
|
|
4426
4517
|
isContextCompactDone,
|
|
4427
4518
|
isContextCompactInProgress,
|
|
@@ -4447,6 +4538,7 @@ export {
|
|
|
4447
4538
|
compactPartsForSummaryMessage,
|
|
4448
4539
|
applyAgentEvent,
|
|
4449
4540
|
partsToAssistantText,
|
|
4541
|
+
visibleAssistantText,
|
|
4450
4542
|
lastAssistantMessageText,
|
|
4451
4543
|
stripBrightsyNdjsonNoise,
|
|
4452
4544
|
isBrightsyNdjsonLine,
|