@mindstudio-ai/remy 0.1.137 → 0.1.138
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/automatedActions/buildFromInitialSpec.md +1 -1
- package/dist/automatedActions/buildFromRoadmap.md +1 -1
- package/dist/headless.js +98 -47
- package/dist/index.js +1980 -1911
- package/package.json +1 -1
|
@@ -29,4 +29,4 @@ The initial build prioritizes getting everything connected and functional, but t
|
|
|
29
29
|
|
|
30
30
|
Then, ask the `visualDesignExpert` to take a screenshot and verity that the visual design looks correct. Fix any issues it flags - we want the user's first time seeing the finished product to truly wow them.
|
|
31
31
|
|
|
32
|
-
When everything is working, use `productVision` to mark the MVP roadmap item as done, then call `setProjectOnboardingState({ state: "onboardingFinished" })`.
|
|
32
|
+
When everything is working, use `productVision` to mark the MVP roadmap item as done, then call `setProjectOnboardingState({ state: "onboardingFinished" })`. Finally, call `compactConversation` to summarize the build session and free up context for the next phase of work.
|
|
@@ -12,4 +12,4 @@ Then, put together a plan to build out the feature. Present the plan to the user
|
|
|
12
12
|
|
|
13
13
|
When they've approved the plan, be sure to update the spec first - remember, the spec is the source of truth about the product. Then, build everything in one turn, using the spec as the master plan.
|
|
14
14
|
|
|
15
|
-
When you're finished, verify your work, then tell`productVision` what was done so it can update the roadmap to reflect the progress. Give the user a summary of what was done.
|
|
15
|
+
When you're finished, verify your work, then tell `productVision` what was done so it can update the roadmap to reflect the progress. Give the user a summary of what was done, then call `compactConversation` to summarize the build session and free up context.
|
package/dist/headless.js
CHANGED
|
@@ -1739,6 +1739,29 @@ var setProjectMetadataTool = {
|
|
|
1739
1739
|
}
|
|
1740
1740
|
};
|
|
1741
1741
|
|
|
1742
|
+
// src/tools/common/compactConversation.ts
|
|
1743
|
+
var compactConversationTool = {
|
|
1744
|
+
clearable: false,
|
|
1745
|
+
definition: {
|
|
1746
|
+
name: "compactConversation",
|
|
1747
|
+
description: "Compact the conversation history by summarizing older messages into a checkpoint. The summary preserves key decisions, what was built, and the current state of the project, but drops the verbose tool results, diffs, and intermediate steps that are no longer useful. Use this when you have just finished a large block of mechanical work (building, refactoring, debugging) and are about to shift back into conversational mode with the user. Runs in the background. Do not use after small changes like fixing a bug or editing copy.",
|
|
1748
|
+
inputSchema: {
|
|
1749
|
+
type: "object",
|
|
1750
|
+
properties: {}
|
|
1751
|
+
}
|
|
1752
|
+
},
|
|
1753
|
+
async execute(_input, context) {
|
|
1754
|
+
if (!context?.conversationMessages || !context.apiConfig) {
|
|
1755
|
+
return "Error: compaction requires execution context.";
|
|
1756
|
+
}
|
|
1757
|
+
triggerCompaction(
|
|
1758
|
+
{ messages: context.conversationMessages },
|
|
1759
|
+
context.apiConfig
|
|
1760
|
+
);
|
|
1761
|
+
return "Compaction started in the background.";
|
|
1762
|
+
}
|
|
1763
|
+
};
|
|
1764
|
+
|
|
1742
1765
|
// src/tools/code/readFile.ts
|
|
1743
1766
|
import fs9 from "fs/promises";
|
|
1744
1767
|
var DEFAULT_MAX_LINES2 = 500;
|
|
@@ -4997,6 +5020,7 @@ var ALL_TOOLS = [
|
|
|
4997
5020
|
designExpertTool,
|
|
4998
5021
|
productVisionTool,
|
|
4999
5022
|
codeSanityCheckTool,
|
|
5023
|
+
compactConversationTool,
|
|
5000
5024
|
// Post-onboarding
|
|
5001
5025
|
clearSyncStatusTool,
|
|
5002
5026
|
presentSyncPlanTool,
|
|
@@ -5115,6 +5139,24 @@ function clearSession(state) {
|
|
|
5115
5139
|
}
|
|
5116
5140
|
}
|
|
5117
5141
|
|
|
5142
|
+
// src/compaction/trigger.ts
|
|
5143
|
+
var log8 = createLogger("compaction:trigger");
|
|
5144
|
+
function triggerCompaction(state, apiConfig, callbacks) {
|
|
5145
|
+
callbacks?.onStart?.();
|
|
5146
|
+
const system = buildSystemPrompt("onboardingFinished");
|
|
5147
|
+
const tools2 = getToolDefinitions("onboardingFinished");
|
|
5148
|
+
compactConversation(state, apiConfig, system, tools2).then(() => {
|
|
5149
|
+
saveSession(state);
|
|
5150
|
+
callbacks?.onComplete?.();
|
|
5151
|
+
log8.info("Compaction complete");
|
|
5152
|
+
}).catch((err) => {
|
|
5153
|
+
callbacks?.onError?.(err.message || "Compaction failed");
|
|
5154
|
+
log8.error("Compaction failed", { error: err.message });
|
|
5155
|
+
}).finally(() => {
|
|
5156
|
+
callbacks?.onFinally?.();
|
|
5157
|
+
});
|
|
5158
|
+
}
|
|
5159
|
+
|
|
5118
5160
|
// src/parsePartialJson.ts
|
|
5119
5161
|
var PartialJSON = class extends Error {
|
|
5120
5162
|
};
|
|
@@ -5305,7 +5347,7 @@ function friendlyError(raw) {
|
|
|
5305
5347
|
}
|
|
5306
5348
|
|
|
5307
5349
|
// src/agent.ts
|
|
5308
|
-
var
|
|
5350
|
+
var log9 = createLogger("agent");
|
|
5309
5351
|
function getTextContent(blocks) {
|
|
5310
5352
|
return blocks.filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
5311
5353
|
}
|
|
@@ -5350,7 +5392,7 @@ async function runTurn(params) {
|
|
|
5350
5392
|
} = params;
|
|
5351
5393
|
const tools2 = getToolDefinitions(onboardingState);
|
|
5352
5394
|
const excludeToolsFromClearing = tools2.filter((t) => !CLEARABLE_TOOLS.has(t.name)).map((t) => t.name);
|
|
5353
|
-
|
|
5395
|
+
log9.info("Turn started", {
|
|
5354
5396
|
requestId,
|
|
5355
5397
|
model,
|
|
5356
5398
|
toolCount: tools2.length,
|
|
@@ -5574,7 +5616,7 @@ async function runTurn(params) {
|
|
|
5574
5616
|
const tool = getToolByName(event.name);
|
|
5575
5617
|
const wasStreamed = acc?.started ?? false;
|
|
5576
5618
|
const isInputStreaming = !!tool?.streaming?.partialInput;
|
|
5577
|
-
|
|
5619
|
+
log9.info("Tool received", {
|
|
5578
5620
|
requestId,
|
|
5579
5621
|
toolCallId: event.id,
|
|
5580
5622
|
name: event.name
|
|
@@ -5621,7 +5663,14 @@ async function runTurn(params) {
|
|
|
5621
5663
|
});
|
|
5622
5664
|
state.messages.push({
|
|
5623
5665
|
role: "assistant",
|
|
5624
|
-
content: [...contentBlocks].sort((a, b) => a.startedAt - b.startedAt)
|
|
5666
|
+
content: [...contentBlocks].sort((a, b) => a.startedAt - b.startedAt),
|
|
5667
|
+
usage: {
|
|
5668
|
+
inputTokens: turnInputTokens,
|
|
5669
|
+
outputTokens: turnOutputTokens,
|
|
5670
|
+
cacheCreationTokens: turnCacheCreation || void 0,
|
|
5671
|
+
cacheReadTokens: turnCacheRead || void 0,
|
|
5672
|
+
llmCalls: turnLlmCalls
|
|
5673
|
+
}
|
|
5625
5674
|
});
|
|
5626
5675
|
}
|
|
5627
5676
|
onEvent({ type: "turn_cancelled" });
|
|
@@ -5631,7 +5680,14 @@ async function runTurn(params) {
|
|
|
5631
5680
|
if (contentBlocks.length > 0) {
|
|
5632
5681
|
state.messages.push({
|
|
5633
5682
|
role: "assistant",
|
|
5634
|
-
content: [...contentBlocks].sort((a, b) => a.startedAt - b.startedAt)
|
|
5683
|
+
content: [...contentBlocks].sort((a, b) => a.startedAt - b.startedAt),
|
|
5684
|
+
usage: {
|
|
5685
|
+
inputTokens: turnInputTokens,
|
|
5686
|
+
outputTokens: turnOutputTokens,
|
|
5687
|
+
cacheCreationTokens: turnCacheCreation || void 0,
|
|
5688
|
+
cacheReadTokens: turnCacheRead || void 0,
|
|
5689
|
+
llmCalls: turnLlmCalls
|
|
5690
|
+
}
|
|
5635
5691
|
});
|
|
5636
5692
|
}
|
|
5637
5693
|
const toolCalls = getToolCalls(contentBlocks);
|
|
@@ -5653,7 +5709,7 @@ async function runTurn(params) {
|
|
|
5653
5709
|
});
|
|
5654
5710
|
return;
|
|
5655
5711
|
}
|
|
5656
|
-
|
|
5712
|
+
log9.info("Tools executing", {
|
|
5657
5713
|
requestId,
|
|
5658
5714
|
count: toolCalls.length,
|
|
5659
5715
|
tools: toolCalls.map((tc) => tc.name)
|
|
@@ -5700,7 +5756,7 @@ async function runTurn(params) {
|
|
|
5700
5756
|
let result;
|
|
5701
5757
|
if (EXTERNAL_TOOLS.has(tc.name) && resolveExternalTool) {
|
|
5702
5758
|
saveSession(state);
|
|
5703
|
-
|
|
5759
|
+
log9.info("Waiting for external tool result", {
|
|
5704
5760
|
requestId,
|
|
5705
5761
|
toolCallId: tc.id,
|
|
5706
5762
|
name: tc.name
|
|
@@ -5757,7 +5813,7 @@ async function runTurn(params) {
|
|
|
5757
5813
|
if (!tc.input.background) {
|
|
5758
5814
|
toolRegistry?.unregister(tc.id);
|
|
5759
5815
|
}
|
|
5760
|
-
|
|
5816
|
+
log9.info("Tool completed", {
|
|
5761
5817
|
requestId,
|
|
5762
5818
|
toolCallId: tc.id,
|
|
5763
5819
|
name: tc.name,
|
|
@@ -5812,7 +5868,7 @@ async function runTurn(params) {
|
|
|
5812
5868
|
}
|
|
5813
5869
|
|
|
5814
5870
|
// src/toolRegistry.ts
|
|
5815
|
-
var
|
|
5871
|
+
var log10 = createLogger("tool-registry");
|
|
5816
5872
|
var ToolRegistry = class {
|
|
5817
5873
|
entries = /* @__PURE__ */ new Map();
|
|
5818
5874
|
onEvent;
|
|
@@ -5838,7 +5894,7 @@ var ToolRegistry = class {
|
|
|
5838
5894
|
if (!entry) {
|
|
5839
5895
|
return false;
|
|
5840
5896
|
}
|
|
5841
|
-
|
|
5897
|
+
log10.info("Tool stopped", { toolCallId: id, name: entry.name, mode });
|
|
5842
5898
|
entry.abortController.abort(mode);
|
|
5843
5899
|
if (mode === "graceful") {
|
|
5844
5900
|
const partial = entry.getPartialResult?.() ?? "";
|
|
@@ -5871,7 +5927,7 @@ ${partial}` : "[INTERRUPTED] Tool execution was stopped.";
|
|
|
5871
5927
|
if (!entry) {
|
|
5872
5928
|
return false;
|
|
5873
5929
|
}
|
|
5874
|
-
|
|
5930
|
+
log10.info("Tool restarted", { toolCallId: id, name: entry.name });
|
|
5875
5931
|
entry.abortController.abort("restart");
|
|
5876
5932
|
const newInput = patchedInput ? { ...entry.input, ...patchedInput } : entry.input;
|
|
5877
5933
|
this.onEvent?.({
|
|
@@ -5916,7 +5972,7 @@ ${body}`;
|
|
|
5916
5972
|
}
|
|
5917
5973
|
|
|
5918
5974
|
// src/headless.ts
|
|
5919
|
-
var
|
|
5975
|
+
var log11 = createLogger("headless");
|
|
5920
5976
|
function emit(event, data, requestId) {
|
|
5921
5977
|
const payload = { event, ...data };
|
|
5922
5978
|
if (requestId) {
|
|
@@ -6032,7 +6088,7 @@ ${xmlParts}
|
|
|
6032
6088
|
}
|
|
6033
6089
|
function onBackgroundComplete(toolCallId, name, result, subAgentMessages) {
|
|
6034
6090
|
pendingBlockUpdates.push({ toolCallId, result, subAgentMessages });
|
|
6035
|
-
|
|
6091
|
+
log11.info("Background complete", {
|
|
6036
6092
|
toolCallId,
|
|
6037
6093
|
name,
|
|
6038
6094
|
requestId: currentRequestId
|
|
@@ -6304,7 +6360,7 @@ ${xmlParts}
|
|
|
6304
6360
|
requestId
|
|
6305
6361
|
);
|
|
6306
6362
|
}
|
|
6307
|
-
|
|
6363
|
+
log11.info("Turn complete", {
|
|
6308
6364
|
requestId,
|
|
6309
6365
|
durationMs: Date.now() - turnStart
|
|
6310
6366
|
});
|
|
@@ -6313,7 +6369,7 @@ ${xmlParts}
|
|
|
6313
6369
|
emit("error", { error: err.message }, requestId);
|
|
6314
6370
|
emit("completed", { success: false, error: err.message }, requestId);
|
|
6315
6371
|
}
|
|
6316
|
-
|
|
6372
|
+
log11.warn("Command failed", {
|
|
6317
6373
|
action: "message",
|
|
6318
6374
|
requestId,
|
|
6319
6375
|
error: err.message
|
|
@@ -6333,7 +6389,7 @@ ${xmlParts}
|
|
|
6333
6389
|
return;
|
|
6334
6390
|
}
|
|
6335
6391
|
const { action, requestId } = parsed;
|
|
6336
|
-
|
|
6392
|
+
log11.info("Command received", { action, requestId });
|
|
6337
6393
|
if (action === "tool_result" && parsed.id) {
|
|
6338
6394
|
const id = parsed.id;
|
|
6339
6395
|
const result = parsed.result ?? "";
|
|
@@ -6342,7 +6398,7 @@ ${xmlParts}
|
|
|
6342
6398
|
pendingTools.delete(id);
|
|
6343
6399
|
pending.resolve(result);
|
|
6344
6400
|
} else if (!running) {
|
|
6345
|
-
|
|
6401
|
+
log11.info("Late tool_result while idle, dismissing", { id });
|
|
6346
6402
|
emit("completed", { success: true }, requestId);
|
|
6347
6403
|
} else {
|
|
6348
6404
|
earlyResults.set(id, result);
|
|
@@ -6398,36 +6454,31 @@ ${xmlParts}
|
|
|
6398
6454
|
return;
|
|
6399
6455
|
}
|
|
6400
6456
|
if (action === "compact") {
|
|
6401
|
-
|
|
6402
|
-
|
|
6403
|
-
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
|
|
6407
|
-
|
|
6408
|
-
|
|
6409
|
-
|
|
6410
|
-
|
|
6411
|
-
|
|
6412
|
-
|
|
6413
|
-
|
|
6414
|
-
|
|
6415
|
-
"compaction_complete",
|
|
6416
|
-
{
|
|
6417
|
-
|
|
6418
|
-
)
|
|
6419
|
-
|
|
6420
|
-
|
|
6421
|
-
|
|
6422
|
-
|
|
6423
|
-
|
|
6424
|
-
|
|
6425
|
-
|
|
6426
|
-
sessionStats.messageCount = state.messages.length;
|
|
6427
|
-
sessionStats.updatedAt = Date.now();
|
|
6428
|
-
try {
|
|
6429
|
-
writeFileSync(".remy-stats.json", JSON.stringify(sessionStats));
|
|
6430
|
-
} catch {
|
|
6457
|
+
triggerCompaction(state, config, {
|
|
6458
|
+
onStart: () => {
|
|
6459
|
+
sessionStats.compactionInProgress = true;
|
|
6460
|
+
sessionStats.updatedAt = Date.now();
|
|
6461
|
+
try {
|
|
6462
|
+
writeFileSync(".remy-stats.json", JSON.stringify(sessionStats));
|
|
6463
|
+
} catch {
|
|
6464
|
+
}
|
|
6465
|
+
},
|
|
6466
|
+
onComplete: () => {
|
|
6467
|
+
emit("compaction_complete", {}, requestId);
|
|
6468
|
+
emit("completed", { success: true }, requestId);
|
|
6469
|
+
},
|
|
6470
|
+
onError: (error) => {
|
|
6471
|
+
emit("compaction_complete", { error }, requestId);
|
|
6472
|
+
emit("completed", { success: false, error }, requestId);
|
|
6473
|
+
},
|
|
6474
|
+
onFinally: () => {
|
|
6475
|
+
sessionStats.compactionInProgress = false;
|
|
6476
|
+
sessionStats.messageCount = state.messages.length;
|
|
6477
|
+
sessionStats.updatedAt = Date.now();
|
|
6478
|
+
try {
|
|
6479
|
+
writeFileSync(".remy-stats.json", JSON.stringify(sessionStats));
|
|
6480
|
+
} catch {
|
|
6481
|
+
}
|
|
6431
6482
|
}
|
|
6432
6483
|
});
|
|
6433
6484
|
return;
|