@mindstudio-ai/remy 0.1.253 → 0.1.255
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/headless.js +165 -73
- package/dist/index.js +174 -81
- package/package.json +1 -1
package/dist/headless.js
CHANGED
|
@@ -914,6 +914,54 @@ ${loadPlanStatus(onboardingState)}
|
|
|
914
914
|
return resolveIncludes(template);
|
|
915
915
|
}
|
|
916
916
|
|
|
917
|
+
// src/automatedActions/sentinel.ts
|
|
918
|
+
function sentinel(name) {
|
|
919
|
+
return `@@automated::${name}@@`;
|
|
920
|
+
}
|
|
921
|
+
function automatedMessage(name, body) {
|
|
922
|
+
return body ? `${sentinel(name)}
|
|
923
|
+
${body}` : sentinel(name);
|
|
924
|
+
}
|
|
925
|
+
function hasSentinel(text, name) {
|
|
926
|
+
return text.startsWith(sentinel(name));
|
|
927
|
+
}
|
|
928
|
+
function isAutomatedMessage(text) {
|
|
929
|
+
return text.startsWith("@@automated::");
|
|
930
|
+
}
|
|
931
|
+
function parseSentinel(text) {
|
|
932
|
+
const match = text.match(/^@@automated::(\w+)@@(.*)/s);
|
|
933
|
+
if (!match) {
|
|
934
|
+
return null;
|
|
935
|
+
}
|
|
936
|
+
return { name: match[1], remainder: match[2] };
|
|
937
|
+
}
|
|
938
|
+
function stripSentinelLine(text) {
|
|
939
|
+
return text.replace(/^@@automated::[^@]*@@[^\n]*\n?/, "");
|
|
940
|
+
}
|
|
941
|
+
function buildBackgroundResultsMessage(results) {
|
|
942
|
+
const xml = results.map(
|
|
943
|
+
(r) => `<tool_result id="${r.toolCallId}" name="${r.name}">
|
|
944
|
+
${r.result}
|
|
945
|
+
</tool_result>`
|
|
946
|
+
).join("\n\n");
|
|
947
|
+
const plural = results.length > 1 ? "s" : "";
|
|
948
|
+
const body = `This is an automated message containing the result${plural} of ${results.length > 1 ? "tool calls" : "a tool call"} that ${results.length > 1 ? "have" : "has"} been working in the background. This is not a direct message from the user.
|
|
949
|
+
<background_results>
|
|
950
|
+
${xml}
|
|
951
|
+
</background_results>`;
|
|
952
|
+
return automatedMessage("background_results", body);
|
|
953
|
+
}
|
|
954
|
+
function mergeBackgroundResultsMessages(messages) {
|
|
955
|
+
const results = [];
|
|
956
|
+
const toolRe = /<tool_result id="([^"]+)" name="([^"]+)">\n([\s\S]*?)\n<\/tool_result>/g;
|
|
957
|
+
for (const msg of messages) {
|
|
958
|
+
for (const m of msg.matchAll(toolRe)) {
|
|
959
|
+
results.push({ toolCallId: m[1], name: m[2], result: m[3] });
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
return buildBackgroundResultsMessage(results);
|
|
963
|
+
}
|
|
964
|
+
|
|
917
965
|
// src/tools/spec/readSpec.ts
|
|
918
966
|
import fs5 from "fs/promises";
|
|
919
967
|
|
|
@@ -3187,54 +3235,6 @@ function startStatusWatcher(config) {
|
|
|
3187
3235
|
};
|
|
3188
3236
|
}
|
|
3189
3237
|
|
|
3190
|
-
// src/automatedActions/sentinel.ts
|
|
3191
|
-
function sentinel(name) {
|
|
3192
|
-
return `@@automated::${name}@@`;
|
|
3193
|
-
}
|
|
3194
|
-
function automatedMessage(name, body) {
|
|
3195
|
-
return body ? `${sentinel(name)}
|
|
3196
|
-
${body}` : sentinel(name);
|
|
3197
|
-
}
|
|
3198
|
-
function hasSentinel(text, name) {
|
|
3199
|
-
return text.startsWith(sentinel(name));
|
|
3200
|
-
}
|
|
3201
|
-
function isAutomatedMessage(text) {
|
|
3202
|
-
return text.startsWith("@@automated::");
|
|
3203
|
-
}
|
|
3204
|
-
function parseSentinel(text) {
|
|
3205
|
-
const match = text.match(/^@@automated::(\w+)@@(.*)/s);
|
|
3206
|
-
if (!match) {
|
|
3207
|
-
return null;
|
|
3208
|
-
}
|
|
3209
|
-
return { name: match[1], remainder: match[2] };
|
|
3210
|
-
}
|
|
3211
|
-
function stripSentinelLine(text) {
|
|
3212
|
-
return text.replace(/^@@automated::[^@]*@@[^\n]*\n?/, "");
|
|
3213
|
-
}
|
|
3214
|
-
function buildBackgroundResultsMessage(results) {
|
|
3215
|
-
const xml = results.map(
|
|
3216
|
-
(r) => `<tool_result id="${r.toolCallId}" name="${r.name}">
|
|
3217
|
-
${r.result}
|
|
3218
|
-
</tool_result>`
|
|
3219
|
-
).join("\n\n");
|
|
3220
|
-
const plural = results.length > 1 ? "s" : "";
|
|
3221
|
-
const body = `This is an automated message containing the result${plural} of ${results.length > 1 ? "tool calls" : "a tool call"} that ${results.length > 1 ? "have" : "has"} been working in the background. This is not a direct message from the user.
|
|
3222
|
-
<background_results>
|
|
3223
|
-
${xml}
|
|
3224
|
-
</background_results>`;
|
|
3225
|
-
return automatedMessage("background_results", body);
|
|
3226
|
-
}
|
|
3227
|
-
function mergeBackgroundResultsMessages(messages) {
|
|
3228
|
-
const results = [];
|
|
3229
|
-
const toolRe = /<tool_result id="([^"]+)" name="([^"]+)">\n([\s\S]*?)\n<\/tool_result>/g;
|
|
3230
|
-
for (const msg of messages) {
|
|
3231
|
-
for (const m of msg.matchAll(toolRe)) {
|
|
3232
|
-
results.push({ toolCallId: m[1], name: m[2], result: m[3] });
|
|
3233
|
-
}
|
|
3234
|
-
}
|
|
3235
|
-
return buildBackgroundResultsMessage(results);
|
|
3236
|
-
}
|
|
3237
|
-
|
|
3238
3238
|
// src/subagents/common/cleanMessages.ts
|
|
3239
3239
|
function findLastSummaryCheckpoint(messages, name) {
|
|
3240
3240
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
@@ -3290,11 +3290,18 @@ function cleanMessagesForApi(messages) {
|
|
|
3290
3290
|
(b) => b.type === "summary" && b.name === "conversation"
|
|
3291
3291
|
);
|
|
3292
3292
|
if (summaryBlock && summaryBlock.type === "summary") {
|
|
3293
|
+
const recent = summaryBlock.recent ? `
|
|
3294
|
+
|
|
3295
|
+
<recent_messages>
|
|
3296
|
+
The last few turns of the summarized conversation, quoted exactly as they were said.
|
|
3297
|
+
|
|
3298
|
+
${summaryBlock.recent}
|
|
3299
|
+
</recent_messages>` : "";
|
|
3293
3300
|
prefix.push({
|
|
3294
3301
|
role: "user",
|
|
3295
3302
|
content: `<conversation_summary>
|
|
3296
3303
|
${summaryBlock.text}
|
|
3297
|
-
</conversation_summary
|
|
3304
|
+
</conversation_summary>${recent}`,
|
|
3298
3305
|
hidden: true
|
|
3299
3306
|
});
|
|
3300
3307
|
}
|
|
@@ -5242,6 +5249,11 @@ var PROMPT_TEMPLATE = readAsset(SUBAGENT, "prompt.md").replace(/\{\{([^}]+)\}\}/
|
|
|
5242
5249
|
const k = key.trim();
|
|
5243
5250
|
return RUNTIME_PLACEHOLDERS.has(k) ? match : readAsset(SUBAGENT, k);
|
|
5244
5251
|
}).replace(/\n{3,}/g, "\n\n");
|
|
5252
|
+
var RENDER_TASK_BLOCK = `<render_task>
|
|
5253
|
+
This task is a render: you are the author of the artifact, not an advisor on it. Everything above describes your usual work \u2014 proposing a design to a developer who then builds it. Here there is no developer downstream. You write the file the brief names, using writeFile (or editFile when it already exists), and that file is the entire deliverable.
|
|
5254
|
+
|
|
5255
|
+
The guidance about specifying layouts in prose, writing implementation notes, and keeping wireframes small doesn't apply here: it exists to hand a design to someone else to build, and you are the one building it. Your reply is a receipt \u2014 one line naming what you wrote.
|
|
5256
|
+
</render_task>`;
|
|
5245
5257
|
function renderDesignSystemBlock(designSystem) {
|
|
5246
5258
|
if (!designSystem) {
|
|
5247
5259
|
return "";
|
|
@@ -5252,7 +5264,7 @@ function renderDesignSystemBlock(designSystem) {
|
|
|
5252
5264
|
"</design_system>"
|
|
5253
5265
|
].join("\n");
|
|
5254
5266
|
}
|
|
5255
|
-
function getDesignExpertPrompt(onboardingState) {
|
|
5267
|
+
function getDesignExpertPrompt(onboardingState, opts) {
|
|
5256
5268
|
const specContext = loadSpecIndex();
|
|
5257
5269
|
const indices = getSampleIndices(
|
|
5258
5270
|
{
|
|
@@ -5297,6 +5309,11 @@ ${designSystemBlock}`;
|
|
|
5297
5309
|
<project_phase>
|
|
5298
5310
|
This project is in the "${state}" phase. The codebase is a placeholder scaffold or is being generated for the first time.
|
|
5299
5311
|
</project_phase>`;
|
|
5312
|
+
}
|
|
5313
|
+
if (opts?.render) {
|
|
5314
|
+
prompt += `
|
|
5315
|
+
|
|
5316
|
+
${RENDER_TASK_BLOCK}`;
|
|
5300
5317
|
}
|
|
5301
5318
|
return prompt;
|
|
5302
5319
|
}
|
|
@@ -5358,17 +5375,19 @@ var DESIGN_EXPERT_RENDER_TOOLS = [
|
|
|
5358
5375
|
async function runDesignExpert(opts, context) {
|
|
5359
5376
|
const history = context.conversationMessages ? getSubAgentHistory(context.conversationMessages, "visualDesignExpert") : [];
|
|
5360
5377
|
return runSubAgent({
|
|
5361
|
-
system: getDesignExpertPrompt(context.onboardingState
|
|
5378
|
+
system: getDesignExpertPrompt(context.onboardingState, {
|
|
5379
|
+
render: opts.render
|
|
5380
|
+
}),
|
|
5362
5381
|
task: opts.task,
|
|
5363
5382
|
history: history.length > 0 ? history : void 0,
|
|
5364
|
-
tools: opts.
|
|
5383
|
+
tools: opts.render ? DESIGN_EXPERT_RENDER_TOOLS : DESIGN_EXPERT_TOOLS,
|
|
5365
5384
|
externalTools: /* @__PURE__ */ new Set(),
|
|
5366
5385
|
executeTool: (name, input, toolCallId, onLog, sams) => {
|
|
5367
5386
|
const childCtx = toolCallId ? { ...deriveContext(context, toolCallId), subAgentMessages: sams } : { ...context, subAgentMessages: sams };
|
|
5368
5387
|
if (COMMON_READ_TOOL_NAMES.has(name)) {
|
|
5369
5388
|
return executeTool(name, input, childCtx);
|
|
5370
5389
|
}
|
|
5371
|
-
if (opts.
|
|
5390
|
+
if (opts.render && RENDER_WRITE_TOOL_NAMES.has(name)) {
|
|
5372
5391
|
return executeTool(name, input, childCtx);
|
|
5373
5392
|
}
|
|
5374
5393
|
return executeDesignExpertTool(name, input, childCtx, toolCallId, onLog);
|
|
@@ -5429,7 +5448,7 @@ var designExpertTool = {
|
|
|
5429
5448
|
}
|
|
5430
5449
|
};
|
|
5431
5450
|
async function runDesignExpertRender(opts, context) {
|
|
5432
|
-
return runDesignExpert({ ...opts,
|
|
5451
|
+
return runDesignExpert({ ...opts, render: true }, context);
|
|
5433
5452
|
}
|
|
5434
5453
|
|
|
5435
5454
|
// src/subagents/productVision/tools.ts
|
|
@@ -5540,14 +5559,14 @@ ${unifiedDiff(filePath, oldContent, "")}`;
|
|
|
5540
5559
|
const delivery = exists ? `### Your deliverable
|
|
5541
5560
|
The pitch deck already exists at \`${filePath}\`. Read it, then update it for the new <pitch_content>, keeping the presentation scaffolding intact \u2014 change only what needs to change.
|
|
5542
5561
|
|
|
5543
|
-
|
|
5562
|
+
Then reply with a one-line summary of what you changed.` : `### Your deliverable
|
|
5544
5563
|
Write the complete pitch deck to \`${filePath}\`. It does not exist yet \u2014 start from this scaffold, keeping its progress bar, chevron navigation, keyboard navigation, and transition mechanics intact:
|
|
5545
5564
|
|
|
5546
5565
|
<pitch_deck_shell>
|
|
5547
5566
|
${PITCH_DECK_SHELL}
|
|
5548
5567
|
</pitch_deck_shell>
|
|
5549
5568
|
|
|
5550
|
-
|
|
5569
|
+
Then reply with a one-line summary of what you wrote.`;
|
|
5551
5570
|
const task = `
|
|
5552
5571
|
<pitch_content>${input.task}</pitch_content>
|
|
5553
5572
|
|
|
@@ -5952,13 +5971,13 @@ Write the complete Build Overview to \`${OVERVIEW_FILE}\`. The file does not exi
|
|
|
5952
5971
|
${OVERVIEW_SHELL}
|
|
5953
5972
|
</overview_shell>
|
|
5954
5973
|
|
|
5955
|
-
|
|
5974
|
+
Then reply with a one-line summary of what you wrote.`;
|
|
5956
5975
|
}
|
|
5957
5976
|
function refreshDelivery() {
|
|
5958
5977
|
return `### Your deliverable
|
|
5959
5978
|
The Build Overview already exists at \`${OVERVIEW_FILE}\`. Read it, then update it to reflect <overview_copy>, preserving its established skin \u2014 change only what the copy changed.
|
|
5960
5979
|
|
|
5961
|
-
|
|
5980
|
+
Then reply with a one-line summary of what you changed.`;
|
|
5962
5981
|
}
|
|
5963
5982
|
var buildOverviewTool = {
|
|
5964
5983
|
clearable: false,
|
|
@@ -6094,6 +6113,7 @@ var SUBAGENT_SUMMARY_PROMPT = readAsset("compaction", "subagent.md");
|
|
|
6094
6113
|
var SUMMARIZABLE_SUBAGENTS = ["visualDesignExpert", "productVision"];
|
|
6095
6114
|
async function compactConversation(messages, apiConfig, model) {
|
|
6096
6115
|
const endIndex = findSafeInsertionPoint(messages);
|
|
6116
|
+
const boundary = endIndex > 0 ? messages[endIndex - 1] : null;
|
|
6097
6117
|
const summaries = [];
|
|
6098
6118
|
const tasks = [];
|
|
6099
6119
|
const conversationMessages = getConversationMessagesForSummary(
|
|
@@ -6150,6 +6170,7 @@ async function compactConversation(messages, apiConfig, model) {
|
|
|
6150
6170
|
"Could not summarize the conversation \u2014 the model did not return a usable summary. History left intact."
|
|
6151
6171
|
);
|
|
6152
6172
|
}
|
|
6173
|
+
const recent = collectRecentNarrative(conversationMessages);
|
|
6153
6174
|
const checkpointMessages = summaries.map((s) => ({
|
|
6154
6175
|
role: "user",
|
|
6155
6176
|
hidden: true,
|
|
@@ -6158,12 +6179,16 @@ async function compactConversation(messages, apiConfig, model) {
|
|
|
6158
6179
|
type: "summary",
|
|
6159
6180
|
name: s.name,
|
|
6160
6181
|
text: s.text,
|
|
6182
|
+
...s.name === "conversation" && recent ? { recent } : {},
|
|
6161
6183
|
startedAt: Date.now()
|
|
6162
6184
|
}
|
|
6163
6185
|
]
|
|
6164
6186
|
}));
|
|
6165
|
-
log8.info("Compaction complete", {
|
|
6166
|
-
|
|
6187
|
+
log8.info("Compaction complete", {
|
|
6188
|
+
summaries: summaries.length,
|
|
6189
|
+
recentNarrativeChars: recent.length
|
|
6190
|
+
});
|
|
6191
|
+
return { checkpoints: checkpointMessages, boundary };
|
|
6167
6192
|
}
|
|
6168
6193
|
function findSafeInsertionPoint(messages, fromIndex = messages.length) {
|
|
6169
6194
|
let idx = fromIndex;
|
|
@@ -6239,6 +6264,58 @@ function getSubAgentMessagesForSummary(messages, subAgentName, endIndex) {
|
|
|
6239
6264
|
}
|
|
6240
6265
|
return collected;
|
|
6241
6266
|
}
|
|
6267
|
+
var RECENT_NARRATIVE_REPLIES = 3;
|
|
6268
|
+
var RECENT_NARRATIVE_MAX_CHARS = 2e4;
|
|
6269
|
+
function narrativeText(msg) {
|
|
6270
|
+
if (msg.role === "assistant") {
|
|
6271
|
+
if (!Array.isArray(msg.content)) {
|
|
6272
|
+
return null;
|
|
6273
|
+
}
|
|
6274
|
+
const blocks = msg.content;
|
|
6275
|
+
if (blocks.some((b) => b.type === "tool")) {
|
|
6276
|
+
return null;
|
|
6277
|
+
}
|
|
6278
|
+
const text = blocks.filter((b) => b.type === "text").map((b) => b.text).join("").trim();
|
|
6279
|
+
return text || null;
|
|
6280
|
+
}
|
|
6281
|
+
if (msg.role !== "user" || msg.toolCallId || msg.hidden) {
|
|
6282
|
+
return null;
|
|
6283
|
+
}
|
|
6284
|
+
if (typeof msg.content !== "string" || isAutomatedMessage(msg.content)) {
|
|
6285
|
+
return null;
|
|
6286
|
+
}
|
|
6287
|
+
const body = msg.content.trim();
|
|
6288
|
+
if (body) {
|
|
6289
|
+
return body;
|
|
6290
|
+
}
|
|
6291
|
+
return msg.attachments?.find((a) => a.transcript)?.transcript?.trim() || null;
|
|
6292
|
+
}
|
|
6293
|
+
function collectRecentNarrative(messages) {
|
|
6294
|
+
const quoted = [];
|
|
6295
|
+
let replies = 0;
|
|
6296
|
+
let chars = 0;
|
|
6297
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
6298
|
+
const msg = messages[i];
|
|
6299
|
+
const text = narrativeText(msg);
|
|
6300
|
+
if (!text) {
|
|
6301
|
+
continue;
|
|
6302
|
+
}
|
|
6303
|
+
if (quoted.length > 0) {
|
|
6304
|
+
if (replies >= RECENT_NARRATIVE_REPLIES) {
|
|
6305
|
+
break;
|
|
6306
|
+
}
|
|
6307
|
+
if (chars + text.length > RECENT_NARRATIVE_MAX_CHARS) {
|
|
6308
|
+
break;
|
|
6309
|
+
}
|
|
6310
|
+
}
|
|
6311
|
+
quoted.push(`[${msg.role}]: ${text}`);
|
|
6312
|
+
chars += text.length;
|
|
6313
|
+
if (msg.role === "assistant") {
|
|
6314
|
+
replies++;
|
|
6315
|
+
}
|
|
6316
|
+
}
|
|
6317
|
+
return quoted.reverse().join("\n\n");
|
|
6318
|
+
}
|
|
6242
6319
|
function serializeForSummary(messages) {
|
|
6243
6320
|
const toolNameById = /* @__PURE__ */ new Map();
|
|
6244
6321
|
for (const msg of messages) {
|
|
@@ -6763,15 +6840,26 @@ function clearSession(state) {
|
|
|
6763
6840
|
|
|
6764
6841
|
// src/compaction/trigger.ts
|
|
6765
6842
|
var log10 = createLogger("compaction:trigger");
|
|
6766
|
-
var
|
|
6843
|
+
var pending = null;
|
|
6767
6844
|
var inflightCompaction = null;
|
|
6768
6845
|
function applyPendingSummaries(state) {
|
|
6769
|
-
const
|
|
6770
|
-
|
|
6846
|
+
const drained = pending;
|
|
6847
|
+
pending = null;
|
|
6848
|
+
if (!drained || drained.checkpoints.length === 0) {
|
|
6771
6849
|
return;
|
|
6772
6850
|
}
|
|
6773
|
-
|
|
6774
|
-
|
|
6851
|
+
let idx;
|
|
6852
|
+
if (!drained.boundary) {
|
|
6853
|
+
idx = 0;
|
|
6854
|
+
} else {
|
|
6855
|
+
const at = state.messages.indexOf(drained.boundary);
|
|
6856
|
+
idx = at === -1 ? 0 : at + 1;
|
|
6857
|
+
}
|
|
6858
|
+
state.messages.splice(idx, 0, ...drained.checkpoints);
|
|
6859
|
+
log10.info("Checkpoint applied", {
|
|
6860
|
+
index: idx,
|
|
6861
|
+
messageCount: state.messages.length
|
|
6862
|
+
});
|
|
6775
6863
|
saveSession(state);
|
|
6776
6864
|
}
|
|
6777
6865
|
var listener = null;
|
|
@@ -6782,14 +6870,18 @@ function triggerCompaction(state, apiConfig, opts = {}) {
|
|
|
6782
6870
|
if (inflightCompaction) {
|
|
6783
6871
|
return inflightCompaction;
|
|
6784
6872
|
}
|
|
6873
|
+
if (pending) {
|
|
6874
|
+
log10.info("Compaction skipped \u2014 a checkpoint is already waiting to apply");
|
|
6875
|
+
return Promise.resolve();
|
|
6876
|
+
}
|
|
6785
6877
|
const { blocking = false, requestId, model } = opts;
|
|
6786
6878
|
listener?.({ type: "started", blocking, requestId });
|
|
6787
6879
|
inflightCompaction = compactConversation(
|
|
6788
6880
|
state.messages,
|
|
6789
6881
|
apiConfig,
|
|
6790
6882
|
resolveModel("conversationSummarizer", state.models, model)
|
|
6791
|
-
).then((
|
|
6792
|
-
|
|
6883
|
+
).then((result) => {
|
|
6884
|
+
pending = result;
|
|
6793
6885
|
listener?.({ type: "complete", requestId });
|
|
6794
6886
|
log10.info("Compaction complete");
|
|
6795
6887
|
}).catch((err) => {
|
|
@@ -8963,9 +9055,9 @@ var HeadlessSession = class {
|
|
|
8963
9055
|
if (this.currentAbort) {
|
|
8964
9056
|
this.currentAbort.abort();
|
|
8965
9057
|
}
|
|
8966
|
-
for (const [id,
|
|
8967
|
-
clearTimeout(
|
|
8968
|
-
|
|
9058
|
+
for (const [id, pending2] of this.pendingTools) {
|
|
9059
|
+
clearTimeout(pending2.timeout);
|
|
9060
|
+
pending2.resolve(USER_CANCELLED_RESULT);
|
|
8969
9061
|
this.pendingTools.delete(id);
|
|
8970
9062
|
}
|
|
8971
9063
|
return this.queue.removeWhere((item) => item.source !== "user");
|
|
@@ -9002,10 +9094,10 @@ var HeadlessSession = class {
|
|
|
9002
9094
|
if (action === "tool_result" && parsed.id) {
|
|
9003
9095
|
const id = parsed.id;
|
|
9004
9096
|
const result = parsed.result ?? "";
|
|
9005
|
-
const
|
|
9006
|
-
if (
|
|
9097
|
+
const pending2 = this.pendingTools.get(id);
|
|
9098
|
+
if (pending2) {
|
|
9007
9099
|
this.pendingTools.delete(id);
|
|
9008
|
-
|
|
9100
|
+
pending2.resolve(result);
|
|
9009
9101
|
} else if (!this.running) {
|
|
9010
9102
|
log15.info("Late tool_result while idle, dismissing", { id });
|
|
9011
9103
|
this.emit("completed", { success: true }, requestId);
|
package/dist/index.js
CHANGED
|
@@ -1599,9 +1599,63 @@ var init_assets = __esm({
|
|
|
1599
1599
|
}
|
|
1600
1600
|
});
|
|
1601
1601
|
|
|
1602
|
+
// src/automatedActions/sentinel.ts
|
|
1603
|
+
function sentinel(name) {
|
|
1604
|
+
return `@@automated::${name}@@`;
|
|
1605
|
+
}
|
|
1606
|
+
function automatedMessage(name, body) {
|
|
1607
|
+
return body ? `${sentinel(name)}
|
|
1608
|
+
${body}` : sentinel(name);
|
|
1609
|
+
}
|
|
1610
|
+
function hasSentinel(text, name) {
|
|
1611
|
+
return text.startsWith(sentinel(name));
|
|
1612
|
+
}
|
|
1613
|
+
function isAutomatedMessage(text) {
|
|
1614
|
+
return text.startsWith("@@automated::");
|
|
1615
|
+
}
|
|
1616
|
+
function parseSentinel(text) {
|
|
1617
|
+
const match = text.match(/^@@automated::(\w+)@@(.*)/s);
|
|
1618
|
+
if (!match) {
|
|
1619
|
+
return null;
|
|
1620
|
+
}
|
|
1621
|
+
return { name: match[1], remainder: match[2] };
|
|
1622
|
+
}
|
|
1623
|
+
function stripSentinelLine(text) {
|
|
1624
|
+
return text.replace(/^@@automated::[^@]*@@[^\n]*\n?/, "");
|
|
1625
|
+
}
|
|
1626
|
+
function buildBackgroundResultsMessage(results) {
|
|
1627
|
+
const xml = results.map(
|
|
1628
|
+
(r) => `<tool_result id="${r.toolCallId}" name="${r.name}">
|
|
1629
|
+
${r.result}
|
|
1630
|
+
</tool_result>`
|
|
1631
|
+
).join("\n\n");
|
|
1632
|
+
const plural = results.length > 1 ? "s" : "";
|
|
1633
|
+
const body = `This is an automated message containing the result${plural} of ${results.length > 1 ? "tool calls" : "a tool call"} that ${results.length > 1 ? "have" : "has"} been working in the background. This is not a direct message from the user.
|
|
1634
|
+
<background_results>
|
|
1635
|
+
${xml}
|
|
1636
|
+
</background_results>`;
|
|
1637
|
+
return automatedMessage("background_results", body);
|
|
1638
|
+
}
|
|
1639
|
+
function mergeBackgroundResultsMessages(messages) {
|
|
1640
|
+
const results = [];
|
|
1641
|
+
const toolRe = /<tool_result id="([^"]+)" name="([^"]+)">\n([\s\S]*?)\n<\/tool_result>/g;
|
|
1642
|
+
for (const msg of messages) {
|
|
1643
|
+
for (const m of msg.matchAll(toolRe)) {
|
|
1644
|
+
results.push({ toolCallId: m[1], name: m[2], result: m[3] });
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1647
|
+
return buildBackgroundResultsMessage(results);
|
|
1648
|
+
}
|
|
1649
|
+
var init_sentinel = __esm({
|
|
1650
|
+
"src/automatedActions/sentinel.ts"() {
|
|
1651
|
+
"use strict";
|
|
1652
|
+
}
|
|
1653
|
+
});
|
|
1654
|
+
|
|
1602
1655
|
// src/compaction/index.ts
|
|
1603
1656
|
async function compactConversation(messages, apiConfig, model) {
|
|
1604
1657
|
const endIndex = findSafeInsertionPoint(messages);
|
|
1658
|
+
const boundary = endIndex > 0 ? messages[endIndex - 1] : null;
|
|
1605
1659
|
const summaries = [];
|
|
1606
1660
|
const tasks = [];
|
|
1607
1661
|
const conversationMessages = getConversationMessagesForSummary(
|
|
@@ -1658,6 +1712,7 @@ async function compactConversation(messages, apiConfig, model) {
|
|
|
1658
1712
|
"Could not summarize the conversation \u2014 the model did not return a usable summary. History left intact."
|
|
1659
1713
|
);
|
|
1660
1714
|
}
|
|
1715
|
+
const recent = collectRecentNarrative(conversationMessages);
|
|
1661
1716
|
const checkpointMessages = summaries.map((s) => ({
|
|
1662
1717
|
role: "user",
|
|
1663
1718
|
hidden: true,
|
|
@@ -1666,12 +1721,16 @@ async function compactConversation(messages, apiConfig, model) {
|
|
|
1666
1721
|
type: "summary",
|
|
1667
1722
|
name: s.name,
|
|
1668
1723
|
text: s.text,
|
|
1724
|
+
...s.name === "conversation" && recent ? { recent } : {},
|
|
1669
1725
|
startedAt: Date.now()
|
|
1670
1726
|
}
|
|
1671
1727
|
]
|
|
1672
1728
|
}));
|
|
1673
|
-
log2.info("Compaction complete", {
|
|
1674
|
-
|
|
1729
|
+
log2.info("Compaction complete", {
|
|
1730
|
+
summaries: summaries.length,
|
|
1731
|
+
recentNarrativeChars: recent.length
|
|
1732
|
+
});
|
|
1733
|
+
return { checkpoints: checkpointMessages, boundary };
|
|
1675
1734
|
}
|
|
1676
1735
|
function findSafeInsertionPoint(messages, fromIndex = messages.length) {
|
|
1677
1736
|
let idx = fromIndex;
|
|
@@ -1747,6 +1806,56 @@ function getSubAgentMessagesForSummary(messages, subAgentName, endIndex) {
|
|
|
1747
1806
|
}
|
|
1748
1807
|
return collected;
|
|
1749
1808
|
}
|
|
1809
|
+
function narrativeText(msg) {
|
|
1810
|
+
if (msg.role === "assistant") {
|
|
1811
|
+
if (!Array.isArray(msg.content)) {
|
|
1812
|
+
return null;
|
|
1813
|
+
}
|
|
1814
|
+
const blocks = msg.content;
|
|
1815
|
+
if (blocks.some((b) => b.type === "tool")) {
|
|
1816
|
+
return null;
|
|
1817
|
+
}
|
|
1818
|
+
const text = blocks.filter((b) => b.type === "text").map((b) => b.text).join("").trim();
|
|
1819
|
+
return text || null;
|
|
1820
|
+
}
|
|
1821
|
+
if (msg.role !== "user" || msg.toolCallId || msg.hidden) {
|
|
1822
|
+
return null;
|
|
1823
|
+
}
|
|
1824
|
+
if (typeof msg.content !== "string" || isAutomatedMessage(msg.content)) {
|
|
1825
|
+
return null;
|
|
1826
|
+
}
|
|
1827
|
+
const body = msg.content.trim();
|
|
1828
|
+
if (body) {
|
|
1829
|
+
return body;
|
|
1830
|
+
}
|
|
1831
|
+
return msg.attachments?.find((a) => a.transcript)?.transcript?.trim() || null;
|
|
1832
|
+
}
|
|
1833
|
+
function collectRecentNarrative(messages) {
|
|
1834
|
+
const quoted = [];
|
|
1835
|
+
let replies = 0;
|
|
1836
|
+
let chars = 0;
|
|
1837
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
1838
|
+
const msg = messages[i];
|
|
1839
|
+
const text = narrativeText(msg);
|
|
1840
|
+
if (!text) {
|
|
1841
|
+
continue;
|
|
1842
|
+
}
|
|
1843
|
+
if (quoted.length > 0) {
|
|
1844
|
+
if (replies >= RECENT_NARRATIVE_REPLIES) {
|
|
1845
|
+
break;
|
|
1846
|
+
}
|
|
1847
|
+
if (chars + text.length > RECENT_NARRATIVE_MAX_CHARS) {
|
|
1848
|
+
break;
|
|
1849
|
+
}
|
|
1850
|
+
}
|
|
1851
|
+
quoted.push(`[${msg.role}]: ${text}`);
|
|
1852
|
+
chars += text.length;
|
|
1853
|
+
if (msg.role === "assistant") {
|
|
1854
|
+
replies++;
|
|
1855
|
+
}
|
|
1856
|
+
}
|
|
1857
|
+
return quoted.reverse().join("\n\n");
|
|
1858
|
+
}
|
|
1750
1859
|
function serializeForSummary(messages) {
|
|
1751
1860
|
const toolNameById = /* @__PURE__ */ new Map();
|
|
1752
1861
|
for (const msg of messages) {
|
|
@@ -1930,12 +2039,13 @@ Write the summary of the conversation above, following your instructions.`;
|
|
|
1930
2039
|
}
|
|
1931
2040
|
return summaryText.trim();
|
|
1932
2041
|
}
|
|
1933
|
-
var log2, CONVERSATION_SUMMARY_PROMPT, SUBAGENT_SUMMARY_PROMPT, SUMMARIZABLE_SUBAGENTS, CHUNK_CHAR_LIMIT, MIN_SUMMARY_CHARS;
|
|
2042
|
+
var log2, CONVERSATION_SUMMARY_PROMPT, SUBAGENT_SUMMARY_PROMPT, SUMMARIZABLE_SUBAGENTS, RECENT_NARRATIVE_REPLIES, RECENT_NARRATIVE_MAX_CHARS, CHUNK_CHAR_LIMIT, MIN_SUMMARY_CHARS;
|
|
1934
2043
|
var init_compaction = __esm({
|
|
1935
2044
|
"src/compaction/index.ts"() {
|
|
1936
2045
|
"use strict";
|
|
1937
2046
|
init_api();
|
|
1938
2047
|
init_assets();
|
|
2048
|
+
init_sentinel();
|
|
1939
2049
|
init_tools8();
|
|
1940
2050
|
init_logger();
|
|
1941
2051
|
init_usageLedger();
|
|
@@ -1943,6 +2053,8 @@ var init_compaction = __esm({
|
|
|
1943
2053
|
CONVERSATION_SUMMARY_PROMPT = readAsset("compaction", "conversation.md");
|
|
1944
2054
|
SUBAGENT_SUMMARY_PROMPT = readAsset("compaction", "subagent.md");
|
|
1945
2055
|
SUMMARIZABLE_SUBAGENTS = ["visualDesignExpert", "productVision"];
|
|
2056
|
+
RECENT_NARRATIVE_REPLIES = 3;
|
|
2057
|
+
RECENT_NARRATIVE_MAX_CHARS = 2e4;
|
|
1946
2058
|
CHUNK_CHAR_LIMIT = 2e5;
|
|
1947
2059
|
MIN_SUMMARY_CHARS = 400;
|
|
1948
2060
|
}
|
|
@@ -2111,59 +2223,6 @@ var init_surfaces = __esm({
|
|
|
2111
2223
|
}
|
|
2112
2224
|
});
|
|
2113
2225
|
|
|
2114
|
-
// src/automatedActions/sentinel.ts
|
|
2115
|
-
function sentinel(name) {
|
|
2116
|
-
return `@@automated::${name}@@`;
|
|
2117
|
-
}
|
|
2118
|
-
function automatedMessage(name, body) {
|
|
2119
|
-
return body ? `${sentinel(name)}
|
|
2120
|
-
${body}` : sentinel(name);
|
|
2121
|
-
}
|
|
2122
|
-
function hasSentinel(text, name) {
|
|
2123
|
-
return text.startsWith(sentinel(name));
|
|
2124
|
-
}
|
|
2125
|
-
function isAutomatedMessage(text) {
|
|
2126
|
-
return text.startsWith("@@automated::");
|
|
2127
|
-
}
|
|
2128
|
-
function parseSentinel(text) {
|
|
2129
|
-
const match = text.match(/^@@automated::(\w+)@@(.*)/s);
|
|
2130
|
-
if (!match) {
|
|
2131
|
-
return null;
|
|
2132
|
-
}
|
|
2133
|
-
return { name: match[1], remainder: match[2] };
|
|
2134
|
-
}
|
|
2135
|
-
function stripSentinelLine(text) {
|
|
2136
|
-
return text.replace(/^@@automated::[^@]*@@[^\n]*\n?/, "");
|
|
2137
|
-
}
|
|
2138
|
-
function buildBackgroundResultsMessage(results) {
|
|
2139
|
-
const xml = results.map(
|
|
2140
|
-
(r) => `<tool_result id="${r.toolCallId}" name="${r.name}">
|
|
2141
|
-
${r.result}
|
|
2142
|
-
</tool_result>`
|
|
2143
|
-
).join("\n\n");
|
|
2144
|
-
const plural = results.length > 1 ? "s" : "";
|
|
2145
|
-
const body = `This is an automated message containing the result${plural} of ${results.length > 1 ? "tool calls" : "a tool call"} that ${results.length > 1 ? "have" : "has"} been working in the background. This is not a direct message from the user.
|
|
2146
|
-
<background_results>
|
|
2147
|
-
${xml}
|
|
2148
|
-
</background_results>`;
|
|
2149
|
-
return automatedMessage("background_results", body);
|
|
2150
|
-
}
|
|
2151
|
-
function mergeBackgroundResultsMessages(messages) {
|
|
2152
|
-
const results = [];
|
|
2153
|
-
const toolRe = /<tool_result id="([^"]+)" name="([^"]+)">\n([\s\S]*?)\n<\/tool_result>/g;
|
|
2154
|
-
for (const msg of messages) {
|
|
2155
|
-
for (const m of msg.matchAll(toolRe)) {
|
|
2156
|
-
results.push({ toolCallId: m[1], name: m[2], result: m[3] });
|
|
2157
|
-
}
|
|
2158
|
-
}
|
|
2159
|
-
return buildBackgroundResultsMessage(results);
|
|
2160
|
-
}
|
|
2161
|
-
var init_sentinel = __esm({
|
|
2162
|
-
"src/automatedActions/sentinel.ts"() {
|
|
2163
|
-
"use strict";
|
|
2164
|
-
}
|
|
2165
|
-
});
|
|
2166
|
-
|
|
2167
2226
|
// src/subagents/common/cleanMessages.ts
|
|
2168
2227
|
function findLastSummaryCheckpoint(messages, name) {
|
|
2169
2228
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
@@ -2219,11 +2278,18 @@ function cleanMessagesForApi(messages) {
|
|
|
2219
2278
|
(b) => b.type === "summary" && b.name === "conversation"
|
|
2220
2279
|
);
|
|
2221
2280
|
if (summaryBlock && summaryBlock.type === "summary") {
|
|
2281
|
+
const recent = summaryBlock.recent ? `
|
|
2282
|
+
|
|
2283
|
+
<recent_messages>
|
|
2284
|
+
The last few turns of the summarized conversation, quoted exactly as they were said.
|
|
2285
|
+
|
|
2286
|
+
${summaryBlock.recent}
|
|
2287
|
+
</recent_messages>` : "";
|
|
2222
2288
|
prefix.push({
|
|
2223
2289
|
role: "user",
|
|
2224
2290
|
content: `<conversation_summary>
|
|
2225
2291
|
${summaryBlock.text}
|
|
2226
|
-
</conversation_summary
|
|
2292
|
+
</conversation_summary>${recent}`,
|
|
2227
2293
|
hidden: true
|
|
2228
2294
|
});
|
|
2229
2295
|
}
|
|
@@ -2662,12 +2728,23 @@ var init_session = __esm({
|
|
|
2662
2728
|
|
|
2663
2729
|
// src/compaction/trigger.ts
|
|
2664
2730
|
function applyPendingSummaries(state) {
|
|
2665
|
-
const
|
|
2666
|
-
|
|
2731
|
+
const drained = pending;
|
|
2732
|
+
pending = null;
|
|
2733
|
+
if (!drained || drained.checkpoints.length === 0) {
|
|
2667
2734
|
return;
|
|
2668
2735
|
}
|
|
2669
|
-
|
|
2670
|
-
|
|
2736
|
+
let idx;
|
|
2737
|
+
if (!drained.boundary) {
|
|
2738
|
+
idx = 0;
|
|
2739
|
+
} else {
|
|
2740
|
+
const at = state.messages.indexOf(drained.boundary);
|
|
2741
|
+
idx = at === -1 ? 0 : at + 1;
|
|
2742
|
+
}
|
|
2743
|
+
state.messages.splice(idx, 0, ...drained.checkpoints);
|
|
2744
|
+
log4.info("Checkpoint applied", {
|
|
2745
|
+
index: idx,
|
|
2746
|
+
messageCount: state.messages.length
|
|
2747
|
+
});
|
|
2671
2748
|
saveSession(state);
|
|
2672
2749
|
}
|
|
2673
2750
|
function setCompactionListener(l) {
|
|
@@ -2677,14 +2754,18 @@ function triggerCompaction(state, apiConfig, opts = {}) {
|
|
|
2677
2754
|
if (inflightCompaction) {
|
|
2678
2755
|
return inflightCompaction;
|
|
2679
2756
|
}
|
|
2757
|
+
if (pending) {
|
|
2758
|
+
log4.info("Compaction skipped \u2014 a checkpoint is already waiting to apply");
|
|
2759
|
+
return Promise.resolve();
|
|
2760
|
+
}
|
|
2680
2761
|
const { blocking = false, requestId, model } = opts;
|
|
2681
2762
|
listener?.({ type: "started", blocking, requestId });
|
|
2682
2763
|
inflightCompaction = compactConversation(
|
|
2683
2764
|
state.messages,
|
|
2684
2765
|
apiConfig,
|
|
2685
2766
|
resolveModel("conversationSummarizer", state.models, model)
|
|
2686
|
-
).then((
|
|
2687
|
-
|
|
2767
|
+
).then((result) => {
|
|
2768
|
+
pending = result;
|
|
2688
2769
|
listener?.({ type: "complete", requestId });
|
|
2689
2770
|
log4.info("Compaction complete");
|
|
2690
2771
|
}).catch((err) => {
|
|
@@ -2697,7 +2778,7 @@ function triggerCompaction(state, apiConfig, opts = {}) {
|
|
|
2697
2778
|
});
|
|
2698
2779
|
return inflightCompaction;
|
|
2699
2780
|
}
|
|
2700
|
-
var log4,
|
|
2781
|
+
var log4, pending, inflightCompaction, listener;
|
|
2701
2782
|
var init_trigger = __esm({
|
|
2702
2783
|
"src/compaction/trigger.ts"() {
|
|
2703
2784
|
"use strict";
|
|
@@ -2706,7 +2787,7 @@ var init_trigger = __esm({
|
|
|
2706
2787
|
init_surfaces();
|
|
2707
2788
|
init_session();
|
|
2708
2789
|
log4 = createLogger("compaction:trigger");
|
|
2709
|
-
|
|
2790
|
+
pending = null;
|
|
2710
2791
|
inflightCompaction = null;
|
|
2711
2792
|
listener = null;
|
|
2712
2793
|
}
|
|
@@ -6218,7 +6299,7 @@ function renderDesignSystemBlock(designSystem) {
|
|
|
6218
6299
|
"</design_system>"
|
|
6219
6300
|
].join("\n");
|
|
6220
6301
|
}
|
|
6221
|
-
function getDesignExpertPrompt(onboardingState) {
|
|
6302
|
+
function getDesignExpertPrompt(onboardingState, opts) {
|
|
6222
6303
|
const specContext = loadSpecIndex();
|
|
6223
6304
|
const indices = getSampleIndices(
|
|
6224
6305
|
{
|
|
@@ -6263,10 +6344,15 @@ ${designSystemBlock}`;
|
|
|
6263
6344
|
<project_phase>
|
|
6264
6345
|
This project is in the "${state}" phase. The codebase is a placeholder scaffold or is being generated for the first time.
|
|
6265
6346
|
</project_phase>`;
|
|
6347
|
+
}
|
|
6348
|
+
if (opts?.render) {
|
|
6349
|
+
prompt += `
|
|
6350
|
+
|
|
6351
|
+
${RENDER_TASK_BLOCK}`;
|
|
6266
6352
|
}
|
|
6267
6353
|
return prompt;
|
|
6268
6354
|
}
|
|
6269
|
-
var SUBAGENT, RUNTIME_PLACEHOLDERS, PROMPT_TEMPLATE;
|
|
6355
|
+
var SUBAGENT, RUNTIME_PLACEHOLDERS, PROMPT_TEMPLATE, RENDER_TASK_BLOCK;
|
|
6270
6356
|
var init_prompt2 = __esm({
|
|
6271
6357
|
"src/subagents/designExpert/prompt.ts"() {
|
|
6272
6358
|
"use strict";
|
|
@@ -6287,6 +6373,11 @@ var init_prompt2 = __esm({
|
|
|
6287
6373
|
const k = key.trim();
|
|
6288
6374
|
return RUNTIME_PLACEHOLDERS.has(k) ? match : readAsset(SUBAGENT, k);
|
|
6289
6375
|
}).replace(/\n{3,}/g, "\n\n");
|
|
6376
|
+
RENDER_TASK_BLOCK = `<render_task>
|
|
6377
|
+
This task is a render: you are the author of the artifact, not an advisor on it. Everything above describes your usual work \u2014 proposing a design to a developer who then builds it. Here there is no developer downstream. You write the file the brief names, using writeFile (or editFile when it already exists), and that file is the entire deliverable.
|
|
6378
|
+
|
|
6379
|
+
The guidance about specifying layouts in prose, writing implementation notes, and keeping wireframes small doesn't apply here: it exists to hand a design to someone else to build, and you are the one building it. Your reply is a receipt \u2014 one line naming what you wrote.
|
|
6380
|
+
</render_task>`;
|
|
6290
6381
|
}
|
|
6291
6382
|
});
|
|
6292
6383
|
|
|
@@ -6343,17 +6434,19 @@ var init_history = __esm({
|
|
|
6343
6434
|
async function runDesignExpert(opts, context) {
|
|
6344
6435
|
const history = context.conversationMessages ? getSubAgentHistory(context.conversationMessages, "visualDesignExpert") : [];
|
|
6345
6436
|
return runSubAgent({
|
|
6346
|
-
system: getDesignExpertPrompt(context.onboardingState
|
|
6437
|
+
system: getDesignExpertPrompt(context.onboardingState, {
|
|
6438
|
+
render: opts.render
|
|
6439
|
+
}),
|
|
6347
6440
|
task: opts.task,
|
|
6348
6441
|
history: history.length > 0 ? history : void 0,
|
|
6349
|
-
tools: opts.
|
|
6442
|
+
tools: opts.render ? DESIGN_EXPERT_RENDER_TOOLS : DESIGN_EXPERT_TOOLS,
|
|
6350
6443
|
externalTools: /* @__PURE__ */ new Set(),
|
|
6351
6444
|
executeTool: (name, input, toolCallId, onLog, sams) => {
|
|
6352
6445
|
const childCtx = toolCallId ? { ...deriveContext(context, toolCallId), subAgentMessages: sams } : { ...context, subAgentMessages: sams };
|
|
6353
6446
|
if (COMMON_READ_TOOL_NAMES.has(name)) {
|
|
6354
6447
|
return executeTool(name, input, childCtx);
|
|
6355
6448
|
}
|
|
6356
|
-
if (opts.
|
|
6449
|
+
if (opts.render && RENDER_WRITE_TOOL_NAMES.has(name)) {
|
|
6357
6450
|
return executeTool(name, input, childCtx);
|
|
6358
6451
|
}
|
|
6359
6452
|
return executeDesignExpertTool(name, input, childCtx, toolCallId, onLog);
|
|
@@ -6379,7 +6472,7 @@ async function runDesignExpert(opts, context) {
|
|
|
6379
6472
|
});
|
|
6380
6473
|
}
|
|
6381
6474
|
async function runDesignExpertRender(opts, context) {
|
|
6382
|
-
return runDesignExpert({ ...opts,
|
|
6475
|
+
return runDesignExpert({ ...opts, render: true }, context);
|
|
6383
6476
|
}
|
|
6384
6477
|
var DESCRIPTION, RENDER_WRITE_TOOL_NAMES, DESIGN_EXPERT_RENDER_TOOLS, designExpertTool;
|
|
6385
6478
|
var init_designExpert = __esm({
|
|
@@ -6551,14 +6644,14 @@ ${unifiedDiff(filePath, oldContent, "")}`;
|
|
|
6551
6644
|
const delivery = exists ? `### Your deliverable
|
|
6552
6645
|
The pitch deck already exists at \`${filePath}\`. Read it, then update it for the new <pitch_content>, keeping the presentation scaffolding intact \u2014 change only what needs to change.
|
|
6553
6646
|
|
|
6554
|
-
|
|
6647
|
+
Then reply with a one-line summary of what you changed.` : `### Your deliverable
|
|
6555
6648
|
Write the complete pitch deck to \`${filePath}\`. It does not exist yet \u2014 start from this scaffold, keeping its progress bar, chevron navigation, keyboard navigation, and transition mechanics intact:
|
|
6556
6649
|
|
|
6557
6650
|
<pitch_deck_shell>
|
|
6558
6651
|
${PITCH_DECK_SHELL}
|
|
6559
6652
|
</pitch_deck_shell>
|
|
6560
6653
|
|
|
6561
|
-
|
|
6654
|
+
Then reply with a one-line summary of what you wrote.`;
|
|
6562
6655
|
const task = `
|
|
6563
6656
|
<pitch_content>${input.task}</pitch_content>
|
|
6564
6657
|
|
|
@@ -7016,13 +7109,13 @@ Write the complete Build Overview to \`${OVERVIEW_FILE}\`. The file does not exi
|
|
|
7016
7109
|
${OVERVIEW_SHELL}
|
|
7017
7110
|
</overview_shell>
|
|
7018
7111
|
|
|
7019
|
-
|
|
7112
|
+
Then reply with a one-line summary of what you wrote.`;
|
|
7020
7113
|
}
|
|
7021
7114
|
function refreshDelivery() {
|
|
7022
7115
|
return `### Your deliverable
|
|
7023
7116
|
The Build Overview already exists at \`${OVERVIEW_FILE}\`. Read it, then update it to reflect <overview_copy>, preserving its established skin \u2014 change only what the copy changed.
|
|
7024
7117
|
|
|
7025
|
-
|
|
7118
|
+
Then reply with a one-line summary of what you changed.`;
|
|
7026
7119
|
}
|
|
7027
7120
|
var OVERVIEW_FILE, DESIGN_BRIEF, OVERVIEW_SHELL, buildOverviewTool;
|
|
7028
7121
|
var init_writeBuildOverview = __esm({
|
|
@@ -9861,9 +9954,9 @@ var init_headless = __esm({
|
|
|
9861
9954
|
if (this.currentAbort) {
|
|
9862
9955
|
this.currentAbort.abort();
|
|
9863
9956
|
}
|
|
9864
|
-
for (const [id,
|
|
9865
|
-
clearTimeout(
|
|
9866
|
-
|
|
9957
|
+
for (const [id, pending2] of this.pendingTools) {
|
|
9958
|
+
clearTimeout(pending2.timeout);
|
|
9959
|
+
pending2.resolve(USER_CANCELLED_RESULT);
|
|
9867
9960
|
this.pendingTools.delete(id);
|
|
9868
9961
|
}
|
|
9869
9962
|
return this.queue.removeWhere((item) => item.source !== "user");
|
|
@@ -9900,10 +9993,10 @@ var init_headless = __esm({
|
|
|
9900
9993
|
if (action === "tool_result" && parsed.id) {
|
|
9901
9994
|
const id = parsed.id;
|
|
9902
9995
|
const result = parsed.result ?? "";
|
|
9903
|
-
const
|
|
9904
|
-
if (
|
|
9996
|
+
const pending2 = this.pendingTools.get(id);
|
|
9997
|
+
if (pending2) {
|
|
9905
9998
|
this.pendingTools.delete(id);
|
|
9906
|
-
|
|
9999
|
+
pending2.resolve(result);
|
|
9907
10000
|
} else if (!this.running) {
|
|
9908
10001
|
log15.info("Late tool_result while idle, dismissing", { id });
|
|
9909
10002
|
this.emit("completed", { success: true }, requestId);
|