@mindstudio-ai/remy 0.1.64 → 0.1.65
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
CHANGED
|
@@ -574,7 +574,7 @@ async function* streamChat(params) {
|
|
|
574
574
|
var MAX_RETRIES = 3;
|
|
575
575
|
var INITIAL_BACKOFF_MS = 1e3;
|
|
576
576
|
function isRetryableError(error) {
|
|
577
|
-
return /Network error/i.test(error) || /HTTP 5\d\d/i.test(error) || /Stream stalled/i.test(error);
|
|
577
|
+
return /Network error/i.test(error) || /HTTP 5\d\d/i.test(error) || /Stream stalled/i.test(error) || /overloaded/i.test(error);
|
|
578
578
|
}
|
|
579
579
|
function sleep(ms) {
|
|
580
580
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -1892,7 +1892,7 @@ function formatOccurrenceError(count, lines, filePath) {
|
|
|
1892
1892
|
var editFileTool = {
|
|
1893
1893
|
definition: {
|
|
1894
1894
|
name: "editFile",
|
|
1895
|
-
description: "Replace a string in a file. old_string must appear exactly once (minor indentation differences are handled automatically). Set replace_all to true to replace every occurrence at once. For bulk mechanical substitutions (renaming a variable, swapping colors), prefer replace_all. Always read the file first so you know the exact text to match.",
|
|
1895
|
+
description: "Replace a string in a file. old_string must appear exactly once (minor indentation differences are handled automatically). Set replace_all to true to replace every occurrence at once. For bulk mechanical substitutions (renaming a variable, swapping colors), prefer replace_all. Always read the file first so you know the exact text to match. When editing nested structures (objects, function bodies, arrays, template literals), always include the full enclosing structure in old_string rather than just an inner fragment. Replacing a partial slice from the middle of nested code is the most common source of syntax errors.",
|
|
1896
1896
|
inputSchema: {
|
|
1897
1897
|
type: "object",
|
|
1898
1898
|
properties: {
|
|
@@ -3345,11 +3345,37 @@ var definition5 = {
|
|
|
3345
3345
|
path: {
|
|
3346
3346
|
type: "string",
|
|
3347
3347
|
description: 'Navigate to this path before capturing (e.g. "/settings"). If omitted, screenshots the current page.'
|
|
3348
|
+
},
|
|
3349
|
+
instructions: {
|
|
3350
|
+
type: "string",
|
|
3351
|
+
description: "If the screenshot you need requires interaction first (dismissing a modal, clicking a tab, filling out a form, navigating a flow), describe the steps to get there. A browser automation agent will follow these instructions before capturing the screenshot."
|
|
3348
3352
|
}
|
|
3349
3353
|
}
|
|
3350
3354
|
}
|
|
3351
3355
|
};
|
|
3352
|
-
async function execute5(input, onLog) {
|
|
3356
|
+
async function execute5(input, onLog, context) {
|
|
3357
|
+
if (input.instructions && context) {
|
|
3358
|
+
try {
|
|
3359
|
+
const task = input.path ? `Navigate to "${input.path}", then: ${input.instructions}. After completing these steps, take a full-page screenshot.` : `${input.instructions}. After completing these steps, take a full-page screenshot.`;
|
|
3360
|
+
const result = await browserAutomationTool.execute({ task }, context);
|
|
3361
|
+
const urlMatch = result.match(
|
|
3362
|
+
/https:\/\/[^\s"')]+\.(?:png|jpg|jpeg|webp)/i
|
|
3363
|
+
);
|
|
3364
|
+
if (!urlMatch) {
|
|
3365
|
+
return `Error: browser navigation completed but no screenshot URL was returned. Agent output: ${result}`;
|
|
3366
|
+
}
|
|
3367
|
+
const url = urlMatch[0];
|
|
3368
|
+
const analysisPrompt = input.prompt || SCREENSHOT_ANALYSIS_PROMPT;
|
|
3369
|
+
const analysis = await analyzeImage({
|
|
3370
|
+
prompt: analysisPrompt,
|
|
3371
|
+
imageUrl: url,
|
|
3372
|
+
onLog
|
|
3373
|
+
});
|
|
3374
|
+
return JSON.stringify({ url, analysis });
|
|
3375
|
+
} catch (err) {
|
|
3376
|
+
return `Error taking interactive screenshot: ${err.message}`;
|
|
3377
|
+
}
|
|
3378
|
+
}
|
|
3353
3379
|
try {
|
|
3354
3380
|
return await captureAndAnalyzeScreenshot({
|
|
3355
3381
|
prompt: input.prompt,
|
|
@@ -3618,7 +3644,7 @@ async function executeDesignExpertTool(name, input, context, toolCallId, onLog)
|
|
|
3618
3644
|
if (!tool) {
|
|
3619
3645
|
return `Error: unknown tool "${name}"`;
|
|
3620
3646
|
}
|
|
3621
|
-
return tool.execute(input, onLog);
|
|
3647
|
+
return tool.execute(input, onLog, context);
|
|
3622
3648
|
}
|
|
3623
3649
|
|
|
3624
3650
|
// src/subagents/designExpert/prompt.ts
|
package/dist/index.js
CHANGED
|
@@ -221,7 +221,7 @@ async function* streamChat(params) {
|
|
|
221
221
|
}
|
|
222
222
|
}
|
|
223
223
|
function isRetryableError(error) {
|
|
224
|
-
return /Network error/i.test(error) || /HTTP 5\d\d/i.test(error) || /Stream stalled/i.test(error);
|
|
224
|
+
return /Network error/i.test(error) || /HTTP 5\d\d/i.test(error) || /Stream stalled/i.test(error) || /overloaded/i.test(error);
|
|
225
225
|
}
|
|
226
226
|
function sleep(ms) {
|
|
227
227
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -1477,7 +1477,7 @@ var init_editFile = __esm({
|
|
|
1477
1477
|
editFileTool = {
|
|
1478
1478
|
definition: {
|
|
1479
1479
|
name: "editFile",
|
|
1480
|
-
description: "Replace a string in a file. old_string must appear exactly once (minor indentation differences are handled automatically). Set replace_all to true to replace every occurrence at once. For bulk mechanical substitutions (renaming a variable, swapping colors), prefer replace_all. Always read the file first so you know the exact text to match.",
|
|
1480
|
+
description: "Replace a string in a file. old_string must appear exactly once (minor indentation differences are handled automatically). Set replace_all to true to replace every occurrence at once. For bulk mechanical substitutions (renaming a variable, swapping colors), prefer replace_all. Always read the file first so you know the exact text to match. When editing nested structures (objects, function bodies, arrays, template literals), always include the full enclosing structure in old_string rather than just an inner fragment. Replacing a partial slice from the middle of nested code is the most common source of syntax errors.",
|
|
1481
1481
|
inputSchema: {
|
|
1482
1482
|
type: "object",
|
|
1483
1483
|
properties: {
|
|
@@ -3172,7 +3172,29 @@ __export(screenshot_exports, {
|
|
|
3172
3172
|
definition: () => definition5,
|
|
3173
3173
|
execute: () => execute5
|
|
3174
3174
|
});
|
|
3175
|
-
async function execute5(input, onLog) {
|
|
3175
|
+
async function execute5(input, onLog, context) {
|
|
3176
|
+
if (input.instructions && context) {
|
|
3177
|
+
try {
|
|
3178
|
+
const task = input.path ? `Navigate to "${input.path}", then: ${input.instructions}. After completing these steps, take a full-page screenshot.` : `${input.instructions}. After completing these steps, take a full-page screenshot.`;
|
|
3179
|
+
const result = await browserAutomationTool.execute({ task }, context);
|
|
3180
|
+
const urlMatch = result.match(
|
|
3181
|
+
/https:\/\/[^\s"')]+\.(?:png|jpg|jpeg|webp)/i
|
|
3182
|
+
);
|
|
3183
|
+
if (!urlMatch) {
|
|
3184
|
+
return `Error: browser navigation completed but no screenshot URL was returned. Agent output: ${result}`;
|
|
3185
|
+
}
|
|
3186
|
+
const url = urlMatch[0];
|
|
3187
|
+
const analysisPrompt = input.prompt || SCREENSHOT_ANALYSIS_PROMPT;
|
|
3188
|
+
const analysis = await analyzeImage({
|
|
3189
|
+
prompt: analysisPrompt,
|
|
3190
|
+
imageUrl: url,
|
|
3191
|
+
onLog
|
|
3192
|
+
});
|
|
3193
|
+
return JSON.stringify({ url, analysis });
|
|
3194
|
+
} catch (err) {
|
|
3195
|
+
return `Error taking interactive screenshot: ${err.message}`;
|
|
3196
|
+
}
|
|
3197
|
+
}
|
|
3176
3198
|
try {
|
|
3177
3199
|
return await captureAndAnalyzeScreenshot({
|
|
3178
3200
|
prompt: input.prompt,
|
|
@@ -3188,6 +3210,8 @@ var init_screenshot3 = __esm({
|
|
|
3188
3210
|
"src/subagents/designExpert/tools/screenshot.ts"() {
|
|
3189
3211
|
"use strict";
|
|
3190
3212
|
init_screenshot();
|
|
3213
|
+
init_analyzeImage();
|
|
3214
|
+
init_browserAutomation();
|
|
3191
3215
|
definition5 = {
|
|
3192
3216
|
name: "screenshot",
|
|
3193
3217
|
description: "Capture a full-height screenshot of the current app preview. Returns a CDN URL along with visual analysis. Use to review the current state of the UI being built. Remember, the screenshot analysis is not overly precise - for example, it cannot reliably identify specific fonts by name \u2014 it can only describe what letterforms look like.",
|
|
@@ -3201,6 +3225,10 @@ var init_screenshot3 = __esm({
|
|
|
3201
3225
|
path: {
|
|
3202
3226
|
type: "string",
|
|
3203
3227
|
description: 'Navigate to this path before capturing (e.g. "/settings"). If omitted, screenshots the current page.'
|
|
3228
|
+
},
|
|
3229
|
+
instructions: {
|
|
3230
|
+
type: "string",
|
|
3231
|
+
description: "If the screenshot you need requires interaction first (dismissing a modal, clicking a tab, filling out a form, navigating a flow), describe the steps to get there. A browser automation agent will follow these instructions before capturing the screenshot."
|
|
3204
3232
|
}
|
|
3205
3233
|
}
|
|
3206
3234
|
}
|
|
@@ -3482,7 +3510,7 @@ async function executeDesignExpertTool(name, input, context, toolCallId, onLog)
|
|
|
3482
3510
|
if (!tool) {
|
|
3483
3511
|
return `Error: unknown tool "${name}"`;
|
|
3484
3512
|
}
|
|
3485
|
-
return tool.execute(input, onLog);
|
|
3513
|
+
return tool.execute(input, onLog, context);
|
|
3486
3514
|
}
|
|
3487
3515
|
var tools, DESIGN_EXPERT_TOOLS;
|
|
3488
3516
|
var init_tools2 = __esm({
|
|
@@ -38,7 +38,7 @@ Always consult the code sanity check before writing code in initialCodegen with
|
|
|
38
38
|
|
|
39
39
|
### QA (`runAutomatedBrowserTest`)
|
|
40
40
|
|
|
41
|
-
For verifying complex stateful interactions: multi-step form submissions, auth flows, real-time updates, flows that require specific data/role setup. This spins up a full chrome browser automation — it's heavyweight. Do not use it for basic rendering or navigation checks. If you can verify something with a screenshot or by reading the code, do that instead. Run a scenario first to seed test data and set user roles. The user is able to watch QA work on their screen via a live browser preview - the cursor will move, type, etc - so you can also use this to demo functionality to the user and help them understand how to use their app.
|
|
41
|
+
For verifying complex stateful interactions: multi-step form submissions, auth flows, real-time updates, flows that require specific data/role setup. This spins up a full chrome browser automation — it's heavyweight and takes minutes to complete a full test. Do not use it for basic rendering or navigation checks. If you can verify something with a screenshot or by reading the code, do that instead. Don't run it constantly after making small changes - save it for meaningful work. Run a scenario first to seed test data and set user roles. The user is able to watch QA work on their screen via a live browser preview - the cursor will move, type, etc - so you can also use this to demo functionality to the user and help them understand how to use their app.
|
|
42
42
|
|
|
43
43
|
The QA agent can see the screen. Describe what to test, not how — it will figure out what to click, what to check, and what values to use.
|
|
44
44
|
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
You are a browser smoke test agent. You verify that features work end to end by interacting with the live preview. Focus on outcomes: does the feature work? Did the expected content appear? Just do the thing and see if it worked.
|
|
2
2
|
|
|
3
|
+
## Rules to Remember
|
|
4
|
+
- Don't overthink the tests - the goal is to generally make sure things work as expected, not to provide detailed QA. If something seems mostly okay, note it and move on. Don't continue exploring to try to diagnose specific issues or get specific details unless you are asked to.
|
|
5
|
+
|
|
3
6
|
## Tester Persona
|
|
4
7
|
The user is watching the automation happen on their screen in real-time. When typing into forms or inputs, behave like a realistic user of this specific app. Use the app context (if provided) to understand the audience and tone. Type the way that audience would actually type — not formal, not robotic. The app developer's name is Remy, so use that and the email remy@mindstudio.ai as the basis for any testing that requires a persona.
|
|
5
8
|
|
|
@@ -10,6 +10,7 @@ Then, think about the layout and UI patterns - these are the core of the user's
|
|
|
10
10
|
|
|
11
11
|
## Tool Usage
|
|
12
12
|
- When multiple tool calls are independent, make them all in a single turn. Searching for three different products, or fetching two reference sites: batch them instead of doing one per turn.
|
|
13
|
+
- The screenshot tool supports an `instructions` parameter for taking screenshots that require interaction first. If you need to screenshot a state that's behind a modal, a specific tab, or a multi-step flow, pass `instructions` describing how to get there (e.g., "dismiss the welcome modal, then click XYZ"). A browser automation agent will follow your instructions and capture the screenshot for you.
|
|
13
14
|
|
|
14
15
|
## Voice
|
|
15
16
|
- No emoji, no filler.
|