@mindstudio-ai/remy 0.1.20 → 0.1.22
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/compiled/design.md +2 -1
- package/dist/compiled/msfm.md +1 -0
- package/dist/headless.js +172 -113
- package/dist/index.js +186 -115
- package/dist/prompt/.notes.md +1 -1
- package/dist/prompt/compiled/design.md +2 -1
- package/dist/prompt/compiled/msfm.md +1 -0
- package/dist/prompt/sources/frontend-design-notes.md +1 -0
- package/dist/prompt/static/authoring.md +4 -4
- package/dist/prompt/static/team.md +7 -3
- package/dist/static/authoring.md +4 -4
- package/dist/static/team.md +7 -3
- package/dist/subagents/codeSanityCheck/prompt.md +12 -0
- package/dist/subagents/designExpert/.notes.md +3 -2
- package/dist/subagents/designExpert/data/compile-inspiration.sh +2 -2
- package/dist/subagents/designExpert/prompts/frontend-design-notes.md +1 -0
- package/dist/subagents/designExpert/prompts/identity.md +3 -3
- package/dist/subagents/designExpert/prompts/images.md +3 -2
- package/dist/subagents/designExpert/prompts/layout.md +1 -1
- package/dist/subagents/productVision/prompt.md +1 -1
- package/package.json +1 -1
package/dist/compiled/design.md
CHANGED
|
@@ -43,7 +43,7 @@ Derive additional implementation colors (borders, focus states, hover states, di
|
|
|
43
43
|
|
|
44
44
|
### Typography block format
|
|
45
45
|
|
|
46
|
-
A `` ```typography `` fenced block in a `type: design/typography` spec file declares fonts (with source URLs) and one or two anchor styles (typically Display and Body). Derive additional styles (labels, buttons, captions, overlines) from these anchors:
|
|
46
|
+
A `` ```typography `` fenced block in a `type: design/typography` spec file declares fonts (with source URLs) and one or two anchor styles (typically Display and Body). Styles can include an optional `case` field (`uppercase`, `lowercase`, `capitalize`) for text-transform. Derive additional styles (labels, buttons, captions, overlines) from these anchors:
|
|
47
47
|
|
|
48
48
|
```typography
|
|
49
49
|
fonts:
|
|
@@ -59,6 +59,7 @@ styles:
|
|
|
59
59
|
weight: 600
|
|
60
60
|
letterSpacing: -0.03em
|
|
61
61
|
lineHeight: 1.1
|
|
62
|
+
case: uppercase
|
|
62
63
|
description: Page titles and hero text
|
|
63
64
|
Body:
|
|
64
65
|
font: Satoshi
|
package/dist/compiled/msfm.md
CHANGED
package/dist/headless.js
CHANGED
|
@@ -1242,8 +1242,32 @@ var confirmDestructiveActionTool = {
|
|
|
1242
1242
|
}
|
|
1243
1243
|
};
|
|
1244
1244
|
|
|
1245
|
-
// src/subagents/
|
|
1245
|
+
// src/subagents/common/runCli.ts
|
|
1246
1246
|
import { exec } from "child_process";
|
|
1247
|
+
function runCli(cmd, options) {
|
|
1248
|
+
return new Promise((resolve) => {
|
|
1249
|
+
exec(
|
|
1250
|
+
cmd,
|
|
1251
|
+
{
|
|
1252
|
+
timeout: options?.timeout ?? 6e4,
|
|
1253
|
+
maxBuffer: options?.maxBuffer ?? 1024 * 1024
|
|
1254
|
+
},
|
|
1255
|
+
(err, stdout, stderr) => {
|
|
1256
|
+
if (stdout.trim()) {
|
|
1257
|
+
resolve(stdout.trim());
|
|
1258
|
+
return;
|
|
1259
|
+
}
|
|
1260
|
+
if (err) {
|
|
1261
|
+
resolve(`Error: ${stderr.trim() || err.message}`);
|
|
1262
|
+
return;
|
|
1263
|
+
}
|
|
1264
|
+
resolve("(no response)");
|
|
1265
|
+
}
|
|
1266
|
+
);
|
|
1267
|
+
});
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
// src/subagents/sdkConsultant/index.ts
|
|
1247
1271
|
var askMindStudioSdkTool = {
|
|
1248
1272
|
definition: {
|
|
1249
1273
|
name: "askMindStudioSdk",
|
|
@@ -1261,28 +1285,13 @@ var askMindStudioSdkTool = {
|
|
|
1261
1285
|
},
|
|
1262
1286
|
async execute(input) {
|
|
1263
1287
|
const query = input.query;
|
|
1264
|
-
return
|
|
1265
|
-
|
|
1266
|
-
`mindstudio ask ${JSON.stringify(query)}`,
|
|
1267
|
-
{ timeout: 6e4, maxBuffer: 512 * 1024 },
|
|
1268
|
-
(err, stdout, stderr) => {
|
|
1269
|
-
if (stdout.trim()) {
|
|
1270
|
-
resolve(stdout.trim());
|
|
1271
|
-
return;
|
|
1272
|
-
}
|
|
1273
|
-
if (err) {
|
|
1274
|
-
resolve(`Error: ${stderr.trim() || err.message}`);
|
|
1275
|
-
return;
|
|
1276
|
-
}
|
|
1277
|
-
resolve("(no response)");
|
|
1278
|
-
}
|
|
1279
|
-
);
|
|
1288
|
+
return runCli(`mindstudio ask ${JSON.stringify(query)}`, {
|
|
1289
|
+
maxBuffer: 512 * 1024
|
|
1280
1290
|
});
|
|
1281
1291
|
}
|
|
1282
1292
|
};
|
|
1283
1293
|
|
|
1284
1294
|
// src/tools/common/fetchUrl.ts
|
|
1285
|
-
import { exec as exec2 } from "child_process";
|
|
1286
1295
|
var fetchUrlTool = {
|
|
1287
1296
|
definition: {
|
|
1288
1297
|
name: "scapeWebUrl",
|
|
@@ -1309,29 +1318,13 @@ var fetchUrlTool = {
|
|
|
1309
1318
|
if (screenshot) {
|
|
1310
1319
|
pageOptions.screenshot = true;
|
|
1311
1320
|
}
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
cmd,
|
|
1316
|
-
{ timeout: 6e4, maxBuffer: 1024 * 1024 },
|
|
1317
|
-
(err, stdout, stderr) => {
|
|
1318
|
-
if (stdout.trim()) {
|
|
1319
|
-
resolve(stdout.trim());
|
|
1320
|
-
return;
|
|
1321
|
-
}
|
|
1322
|
-
if (err) {
|
|
1323
|
-
resolve(`Error: ${stderr.trim() || err.message}`);
|
|
1324
|
-
return;
|
|
1325
|
-
}
|
|
1326
|
-
resolve("(no response)");
|
|
1327
|
-
}
|
|
1328
|
-
);
|
|
1329
|
-
});
|
|
1321
|
+
return runCli(
|
|
1322
|
+
`mindstudio scrape-url --url ${JSON.stringify(url)} --page-options ${JSON.stringify(JSON.stringify(pageOptions))} --no-meta`
|
|
1323
|
+
);
|
|
1330
1324
|
}
|
|
1331
1325
|
};
|
|
1332
1326
|
|
|
1333
1327
|
// src/tools/common/searchGoogle.ts
|
|
1334
|
-
import { exec as exec3 } from "child_process";
|
|
1335
1328
|
var searchGoogleTool = {
|
|
1336
1329
|
definition: {
|
|
1337
1330
|
name: "searchGoogle",
|
|
@@ -1349,24 +1342,10 @@ var searchGoogleTool = {
|
|
|
1349
1342
|
},
|
|
1350
1343
|
async execute(input) {
|
|
1351
1344
|
const query = input.query;
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
{ timeout: 6e4, maxBuffer: 512 * 1024 },
|
|
1357
|
-
(err, stdout, stderr) => {
|
|
1358
|
-
if (stdout.trim()) {
|
|
1359
|
-
resolve(stdout.trim());
|
|
1360
|
-
return;
|
|
1361
|
-
}
|
|
1362
|
-
if (err) {
|
|
1363
|
-
resolve(`Error: ${stderr.trim() || err.message}`);
|
|
1364
|
-
return;
|
|
1365
|
-
}
|
|
1366
|
-
resolve("(no response)");
|
|
1367
|
-
}
|
|
1368
|
-
);
|
|
1369
|
-
});
|
|
1345
|
+
return runCli(
|
|
1346
|
+
`mindstudio search-google --query ${JSON.stringify(query)} --export-type json --output-key results --no-meta`,
|
|
1347
|
+
{ maxBuffer: 512 * 1024 }
|
|
1348
|
+
);
|
|
1370
1349
|
}
|
|
1371
1350
|
};
|
|
1372
1351
|
|
|
@@ -1691,7 +1670,7 @@ ${unifiedDiff(input.path, content, updated)}`;
|
|
|
1691
1670
|
};
|
|
1692
1671
|
|
|
1693
1672
|
// src/tools/code/bash.ts
|
|
1694
|
-
import { exec as
|
|
1673
|
+
import { exec as exec2 } from "child_process";
|
|
1695
1674
|
var DEFAULT_TIMEOUT_MS = 12e4;
|
|
1696
1675
|
var DEFAULT_MAX_LINES3 = 500;
|
|
1697
1676
|
var bashTool = {
|
|
@@ -1725,7 +1704,7 @@ var bashTool = {
|
|
|
1725
1704
|
const maxLines = input.maxLines === 0 ? Infinity : input.maxLines || DEFAULT_MAX_LINES3;
|
|
1726
1705
|
const timeoutMs = input.timeout ? input.timeout * 1e3 : DEFAULT_TIMEOUT_MS;
|
|
1727
1706
|
return new Promise((resolve) => {
|
|
1728
|
-
|
|
1707
|
+
exec2(
|
|
1729
1708
|
input.command,
|
|
1730
1709
|
{
|
|
1731
1710
|
timeout: timeoutMs,
|
|
@@ -1765,7 +1744,7 @@ var bashTool = {
|
|
|
1765
1744
|
};
|
|
1766
1745
|
|
|
1767
1746
|
// src/tools/code/grep.ts
|
|
1768
|
-
import { exec as
|
|
1747
|
+
import { exec as exec3 } from "child_process";
|
|
1769
1748
|
var DEFAULT_MAX = 50;
|
|
1770
1749
|
function formatResults(stdout, max) {
|
|
1771
1750
|
const lines = stdout.trim().split("\n");
|
|
@@ -1812,12 +1791,12 @@ var grepTool = {
|
|
|
1812
1791
|
const rgCmd = `rg -n --no-heading --max-count=${max}${globFlag} '${escaped}' ${searchPath}`;
|
|
1813
1792
|
const grepCmd = `grep -rn --max-count=${max} '${escaped}' ${searchPath} --include='*.ts' --include='*.tsx' --include='*.js' --include='*.json' --include='*.md'`;
|
|
1814
1793
|
return new Promise((resolve) => {
|
|
1815
|
-
|
|
1794
|
+
exec3(rgCmd, { maxBuffer: 512 * 1024 }, (err, stdout) => {
|
|
1816
1795
|
if (stdout?.trim()) {
|
|
1817
1796
|
resolve(formatResults(stdout, max));
|
|
1818
1797
|
return;
|
|
1819
1798
|
}
|
|
1820
|
-
|
|
1799
|
+
exec3(grepCmd, { maxBuffer: 512 * 1024 }, (_err, grepStdout) => {
|
|
1821
1800
|
if (grepStdout?.trim()) {
|
|
1822
1801
|
resolve(formatResults(grepStdout, max));
|
|
1823
1802
|
} else {
|
|
@@ -2049,17 +2028,38 @@ var runMethodTool = {
|
|
|
2049
2028
|
};
|
|
2050
2029
|
|
|
2051
2030
|
// src/tools/code/screenshot.ts
|
|
2031
|
+
var DEFAULT_PROMPT = "Describe this app screenshot for a developer who cannot see it. What is visible on screen: the layout, content, interactive elements, any loading or error states. Be concise and factual.";
|
|
2052
2032
|
var screenshotTool = {
|
|
2053
2033
|
definition: {
|
|
2054
2034
|
name: "screenshot",
|
|
2055
|
-
description: "Capture a screenshot of the app preview
|
|
2035
|
+
description: "Capture a screenshot of the app preview and get a description of what's on screen. Optionally provide a specific question about what you're looking for.",
|
|
2056
2036
|
inputSchema: {
|
|
2057
2037
|
type: "object",
|
|
2058
|
-
properties: {
|
|
2038
|
+
properties: {
|
|
2039
|
+
prompt: {
|
|
2040
|
+
type: "string",
|
|
2041
|
+
description: "Optional question about the screenshot. If omitted, returns a general description of what's visible."
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2059
2044
|
}
|
|
2060
2045
|
},
|
|
2061
|
-
async execute() {
|
|
2062
|
-
|
|
2046
|
+
async execute(input) {
|
|
2047
|
+
try {
|
|
2048
|
+
const { url } = await sidecarRequest(
|
|
2049
|
+
"/screenshot",
|
|
2050
|
+
{},
|
|
2051
|
+
{ timeout: 3e4 }
|
|
2052
|
+
);
|
|
2053
|
+
const analysisPrompt = input.prompt || DEFAULT_PROMPT;
|
|
2054
|
+
const analysis = await runCli(
|
|
2055
|
+
`mindstudio analyze-image --prompt ${JSON.stringify(analysisPrompt)} --image-url ${JSON.stringify(url)} --output-key analysis --no-meta`
|
|
2056
|
+
);
|
|
2057
|
+
return `Screenshot: ${url}
|
|
2058
|
+
|
|
2059
|
+
${analysis}`;
|
|
2060
|
+
} catch (err) {
|
|
2061
|
+
return `Error taking screenshot: ${err.message}`;
|
|
2062
|
+
}
|
|
2063
2063
|
}
|
|
2064
2064
|
};
|
|
2065
2065
|
|
|
@@ -2413,7 +2413,6 @@ var browserAutomationTool = {
|
|
|
2413
2413
|
};
|
|
2414
2414
|
|
|
2415
2415
|
// src/subagents/designExpert/tools.ts
|
|
2416
|
-
import { exec as exec6 } from "child_process";
|
|
2417
2416
|
var DESIGN_REFERENCE_PROMPT = `Analyze this website/app screenshot as a design reference. Assess:
|
|
2418
2417
|
1) Mood/aesthetic
|
|
2419
2418
|
2) Color palette with approximate hex values and palette strategy
|
|
@@ -2421,7 +2420,7 @@ var DESIGN_REFERENCE_PROMPT = `Analyze this website/app screenshot as a design r
|
|
|
2421
2420
|
4) Layout composition (symmetric/asymmetric, grid structure, whitespace usage, content density)
|
|
2422
2421
|
5) What makes it distinctive and interesting vs generic AI-generated interfaces
|
|
2423
2422
|
Be specific and concise.`;
|
|
2424
|
-
var
|
|
2423
|
+
var DESIGN_EXPERT_TOOLS = [
|
|
2425
2424
|
{
|
|
2426
2425
|
name: "searchGoogle",
|
|
2427
2426
|
description: "Search Google for web results. Use for finding design inspiration, font recommendations, UI patterns, real products in a domain, and reference material.",
|
|
@@ -2496,7 +2495,7 @@ var DESIGN_RESEARCH_TOOLS = [
|
|
|
2496
2495
|
},
|
|
2497
2496
|
{
|
|
2498
2497
|
name: "generateImages",
|
|
2499
|
-
description: "Generate images using AI (Seedream). Returns CDN URLs. Produces high-quality results for both photorealistic images and abstract/creative visuals. Pass multiple prompts to generate in parallel.",
|
|
2498
|
+
description: "Generate images using AI (Seedream). Returns CDN URLs with a quality analysis for each image. Produces high-quality results for both photorealistic images and abstract/creative visuals. Pass multiple prompts to generate in parallel. No need to analyze images separately after generating \u2014 the analysis is included.",
|
|
2500
2499
|
inputSchema: {
|
|
2501
2500
|
type: "object",
|
|
2502
2501
|
properties: {
|
|
@@ -2520,27 +2519,26 @@ var DESIGN_RESEARCH_TOOLS = [
|
|
|
2520
2519
|
}
|
|
2521
2520
|
}
|
|
2522
2521
|
];
|
|
2523
|
-
function
|
|
2524
|
-
return new Promise((resolve) => {
|
|
2525
|
-
exec6(
|
|
2526
|
-
cmd,
|
|
2527
|
-
{ timeout: 6e4, maxBuffer: 1024 * 1024 },
|
|
2528
|
-
(err, stdout, stderr) => {
|
|
2529
|
-
if (stdout.trim()) {
|
|
2530
|
-
resolve(stdout.trim());
|
|
2531
|
-
return;
|
|
2532
|
-
}
|
|
2533
|
-
if (err) {
|
|
2534
|
-
resolve(`Error: ${stderr.trim() || err.message}`);
|
|
2535
|
-
return;
|
|
2536
|
-
}
|
|
2537
|
-
resolve("(no response)");
|
|
2538
|
-
}
|
|
2539
|
-
);
|
|
2540
|
-
});
|
|
2541
|
-
}
|
|
2542
|
-
async function executeDesignTool(name, input) {
|
|
2522
|
+
async function executeDesignExpertTool(name, input) {
|
|
2543
2523
|
switch (name) {
|
|
2524
|
+
case "screenshot": {
|
|
2525
|
+
try {
|
|
2526
|
+
const { url } = await sidecarRequest(
|
|
2527
|
+
"/screenshot",
|
|
2528
|
+
{},
|
|
2529
|
+
{ timeout: 3e4 }
|
|
2530
|
+
);
|
|
2531
|
+
const analysisPrompt = input.prompt || "Describe this app screenshot for a visual designer reviewing the current state. What is visible: layout, typography, colors, spacing, imagery. Note anything that looks broken or off. Be concise.";
|
|
2532
|
+
const analysis = await runCli(
|
|
2533
|
+
`mindstudio analyze-image --prompt ${JSON.stringify(analysisPrompt)} --image-url ${JSON.stringify(url)} --output-key analysis --no-meta`
|
|
2534
|
+
);
|
|
2535
|
+
return `Screenshot: ${url}
|
|
2536
|
+
|
|
2537
|
+
${analysis}`;
|
|
2538
|
+
} catch (err) {
|
|
2539
|
+
return `Error taking screenshot: ${err.message}`;
|
|
2540
|
+
}
|
|
2541
|
+
}
|
|
2544
2542
|
case "searchGoogle":
|
|
2545
2543
|
return runCli(
|
|
2546
2544
|
`mindstudio search-google --query ${JSON.stringify(input.query)} --export-type json --output-key results --no-meta`
|
|
@@ -2585,6 +2583,8 @@ ${analysis}`;
|
|
|
2585
2583
|
const prompts = input.prompts;
|
|
2586
2584
|
const width = input.width || 2048;
|
|
2587
2585
|
const height = input.height || 2048;
|
|
2586
|
+
const ANALYZE_PROMPT = "You are reviewing this image for a visual designer sourcing assets for a project. Describe: what the image depicts, the mood and color palette, how the lighting and composition work, whether there are any issues (unwanted text, artifacts, distortions), and how it could be used in a layout (hero background, feature section, card texture, etc). Be concise and practical.";
|
|
2587
|
+
let imageUrls;
|
|
2588
2588
|
if (prompts.length === 1) {
|
|
2589
2589
|
const step = JSON.stringify({
|
|
2590
2590
|
prompt: prompts[0],
|
|
@@ -2593,21 +2593,47 @@ ${analysis}`;
|
|
|
2593
2593
|
config: { width, height }
|
|
2594
2594
|
}
|
|
2595
2595
|
});
|
|
2596
|
-
|
|
2596
|
+
const url = await runCli(
|
|
2597
2597
|
`mindstudio generate-image '${step}' --output-key imageUrl --no-meta`
|
|
2598
2598
|
);
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2599
|
+
imageUrls = [url];
|
|
2600
|
+
} else {
|
|
2601
|
+
const steps = prompts.map((prompt) => ({
|
|
2602
|
+
stepType: "generateImage",
|
|
2603
|
+
step: {
|
|
2604
|
+
prompt,
|
|
2605
|
+
imageModelOverride: {
|
|
2606
|
+
model: "seedream-4.5",
|
|
2607
|
+
config: { width, height }
|
|
2608
|
+
}
|
|
2607
2609
|
}
|
|
2610
|
+
}));
|
|
2611
|
+
const batchResult = await runCli(
|
|
2612
|
+
`mindstudio batch '${JSON.stringify(steps)}' --no-meta`
|
|
2613
|
+
);
|
|
2614
|
+
try {
|
|
2615
|
+
const parsed = JSON.parse(batchResult);
|
|
2616
|
+
imageUrls = parsed.results.map(
|
|
2617
|
+
(r) => r.output?.imageUrl ?? `Error: ${r.error}`
|
|
2618
|
+
);
|
|
2619
|
+
} catch {
|
|
2620
|
+
return batchResult;
|
|
2608
2621
|
}
|
|
2609
|
-
}
|
|
2610
|
-
|
|
2622
|
+
}
|
|
2623
|
+
const analyses = await Promise.all(
|
|
2624
|
+
imageUrls.map(async (url, i) => {
|
|
2625
|
+
if (url.startsWith("Error")) {
|
|
2626
|
+
return `Image ${i + 1}: ${url}`;
|
|
2627
|
+
}
|
|
2628
|
+
const analysis = await runCli(
|
|
2629
|
+
`mindstudio analyze-image --prompt ${JSON.stringify(ANALYZE_PROMPT)} --image-url ${JSON.stringify(url)} --output-key analysis --no-meta`
|
|
2630
|
+
);
|
|
2631
|
+
return `**Image ${i + 1}:** ${url}
|
|
2632
|
+
Prompt: ${prompts[i]}
|
|
2633
|
+
Analysis: ${analysis}`;
|
|
2634
|
+
})
|
|
2635
|
+
);
|
|
2636
|
+
return analyses.join("\n\n");
|
|
2611
2637
|
}
|
|
2612
2638
|
default:
|
|
2613
2639
|
return `Error: unknown tool "${name}"`;
|
|
@@ -2757,7 +2783,7 @@ function sample(arr, n) {
|
|
|
2757
2783
|
}
|
|
2758
2784
|
return copy.slice(0, n);
|
|
2759
2785
|
}
|
|
2760
|
-
function
|
|
2786
|
+
function getDesignExpertPrompt() {
|
|
2761
2787
|
const fonts = sample(fontData.fonts, 30);
|
|
2762
2788
|
const pairings = sample(fontData.pairings, 20);
|
|
2763
2789
|
const images = sample(inspirationImages, 15);
|
|
@@ -2811,7 +2837,7 @@ ${specContext}`;
|
|
|
2811
2837
|
|
|
2812
2838
|
// src/subagents/designExpert/index.ts
|
|
2813
2839
|
var DESCRIPTION = `
|
|
2814
|
-
Visual design expert.
|
|
2840
|
+
Visual design expert. Describe the situation and what you need \u2014 the agent decides what to deliver. It reads the spec files automatically. Include relevant user requirements and context it can't get from the spec, but do not list specific deliverables or tell it how to do its job.
|
|
2815
2841
|
`.trim();
|
|
2816
2842
|
var designExpertTool = {
|
|
2817
2843
|
definition: {
|
|
@@ -2830,17 +2856,17 @@ var designExpertTool = {
|
|
|
2830
2856
|
},
|
|
2831
2857
|
async execute(input, context) {
|
|
2832
2858
|
if (!context) {
|
|
2833
|
-
return "Error: design
|
|
2859
|
+
return "Error: visual design expert requires execution context";
|
|
2834
2860
|
}
|
|
2835
2861
|
const result = await runSubAgent({
|
|
2836
|
-
system:
|
|
2862
|
+
system: getDesignExpertPrompt(),
|
|
2837
2863
|
task: input.task,
|
|
2838
|
-
tools:
|
|
2839
|
-
externalTools: /* @__PURE__ */ new Set(
|
|
2840
|
-
executeTool:
|
|
2864
|
+
tools: DESIGN_EXPERT_TOOLS,
|
|
2865
|
+
externalTools: /* @__PURE__ */ new Set(),
|
|
2866
|
+
executeTool: executeDesignExpertTool,
|
|
2841
2867
|
apiConfig: context.apiConfig,
|
|
2842
2868
|
model: context.model,
|
|
2843
|
-
subAgentId: "
|
|
2869
|
+
subAgentId: "visualDesignExpert",
|
|
2844
2870
|
signal: context.signal,
|
|
2845
2871
|
parentToolId: context.toolCallId,
|
|
2846
2872
|
onEvent: context.onEvent,
|
|
@@ -3709,7 +3735,6 @@ var EXTERNAL_TOOLS = /* @__PURE__ */ new Set([
|
|
|
3709
3735
|
"runScenario",
|
|
3710
3736
|
"runMethod",
|
|
3711
3737
|
"browserCommand",
|
|
3712
|
-
"screenshot",
|
|
3713
3738
|
"setProjectName"
|
|
3714
3739
|
]);
|
|
3715
3740
|
function createAgentState() {
|
|
@@ -3753,6 +3778,12 @@ async function runTurn(params) {
|
|
|
3753
3778
|
});
|
|
3754
3779
|
}
|
|
3755
3780
|
state.messages.push(userMsg);
|
|
3781
|
+
const STATUS_EXCLUDED_TOOLS = /* @__PURE__ */ new Set([
|
|
3782
|
+
"setProjectOnboardingState",
|
|
3783
|
+
"setProjectName",
|
|
3784
|
+
"clearSyncStatus",
|
|
3785
|
+
"editsFinished"
|
|
3786
|
+
]);
|
|
3756
3787
|
let lastCompletedTools = "";
|
|
3757
3788
|
let lastCompletedResult = "";
|
|
3758
3789
|
while (true) {
|
|
@@ -3841,7 +3872,7 @@ async function runTurn(params) {
|
|
|
3841
3872
|
apiConfig,
|
|
3842
3873
|
getContext: () => ({
|
|
3843
3874
|
assistantText: getTextContent(contentBlocks).slice(-500),
|
|
3844
|
-
lastToolName: getToolCalls(contentBlocks).at(-1)?.name || lastCompletedTools || void 0,
|
|
3875
|
+
lastToolName: getToolCalls(contentBlocks).filter((tc) => !STATUS_EXCLUDED_TOOLS.has(tc.name)).at(-1)?.name || lastCompletedTools || void 0,
|
|
3845
3876
|
lastToolResult: lastCompletedResult || void 0
|
|
3846
3877
|
}),
|
|
3847
3878
|
onStatus: (label) => onEvent({ type: "status", message: label }),
|
|
@@ -4000,6 +4031,28 @@ async function runTurn(params) {
|
|
|
4000
4031
|
count: toolCalls.length,
|
|
4001
4032
|
tools: toolCalls.map((tc) => tc.name)
|
|
4002
4033
|
});
|
|
4034
|
+
let subAgentText = "";
|
|
4035
|
+
const origOnEvent = onEvent;
|
|
4036
|
+
const wrappedOnEvent = (e) => {
|
|
4037
|
+
if ("parentToolId" in e && e.parentToolId) {
|
|
4038
|
+
if (e.type === "text") {
|
|
4039
|
+
subAgentText = e.text;
|
|
4040
|
+
} else if (e.type === "tool_start") {
|
|
4041
|
+
subAgentText = `Using ${e.name}`;
|
|
4042
|
+
}
|
|
4043
|
+
}
|
|
4044
|
+
origOnEvent(e);
|
|
4045
|
+
};
|
|
4046
|
+
const toolStatusWatcher = startStatusWatcher({
|
|
4047
|
+
apiConfig,
|
|
4048
|
+
getContext: () => ({
|
|
4049
|
+
assistantText: subAgentText || getTextContent(contentBlocks).slice(-500),
|
|
4050
|
+
lastToolName: toolCalls.filter((tc) => !STATUS_EXCLUDED_TOOLS.has(tc.name)).map((tc) => tc.name).join(", ") || void 0,
|
|
4051
|
+
lastToolResult: lastCompletedResult || void 0
|
|
4052
|
+
}),
|
|
4053
|
+
onStatus: (label) => origOnEvent({ type: "status", message: label }),
|
|
4054
|
+
signal
|
|
4055
|
+
});
|
|
4003
4056
|
const subAgentMessages = /* @__PURE__ */ new Map();
|
|
4004
4057
|
const results = await Promise.all(
|
|
4005
4058
|
toolCalls.map(async (tc) => {
|
|
@@ -4025,7 +4078,7 @@ async function runTurn(params) {
|
|
|
4025
4078
|
apiConfig,
|
|
4026
4079
|
model,
|
|
4027
4080
|
signal,
|
|
4028
|
-
onEvent,
|
|
4081
|
+
onEvent: wrappedOnEvent,
|
|
4029
4082
|
resolveExternalTool,
|
|
4030
4083
|
toolCallId: tc.id,
|
|
4031
4084
|
subAgentMessages
|
|
@@ -4059,15 +4112,21 @@ async function runTurn(params) {
|
|
|
4059
4112
|
}
|
|
4060
4113
|
})
|
|
4061
4114
|
);
|
|
4062
|
-
|
|
4115
|
+
toolStatusWatcher.stop();
|
|
4116
|
+
for (const r of results) {
|
|
4063
4117
|
const block = contentBlocks.find(
|
|
4064
|
-
(b) => b.type === "tool" && b.id ===
|
|
4118
|
+
(b) => b.type === "tool" && b.id === r.id
|
|
4065
4119
|
);
|
|
4066
4120
|
if (block?.type === "tool") {
|
|
4067
|
-
block.
|
|
4121
|
+
block.result = r.result;
|
|
4122
|
+
block.isError = r.isError;
|
|
4123
|
+
const msgs = subAgentMessages.get(r.id);
|
|
4124
|
+
if (msgs) {
|
|
4125
|
+
block.subAgentMessages = msgs;
|
|
4126
|
+
}
|
|
4068
4127
|
}
|
|
4069
4128
|
}
|
|
4070
|
-
lastCompletedTools = toolCalls.map((tc) => tc.name).join(", ");
|
|
4129
|
+
lastCompletedTools = toolCalls.filter((tc) => !STATUS_EXCLUDED_TOOLS.has(tc.name)).map((tc) => tc.name).join(", ");
|
|
4071
4130
|
lastCompletedResult = results.at(-1)?.result ?? "";
|
|
4072
4131
|
for (const r of results) {
|
|
4073
4132
|
state.messages.push({
|