@mindstudio-ai/remy 0.1.231 → 0.1.233
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 +32 -19
- package/dist/index.js +39 -23
- package/dist/subagents/browserAutomation/prompt.md +11 -0
- package/package.json +1 -1
package/dist/headless.js
CHANGED
|
@@ -478,7 +478,8 @@ var ALLOWED_MODELS_BY_TYPE = {
|
|
|
478
478
|
"glm-5.2",
|
|
479
479
|
"muse-spark-1.1",
|
|
480
480
|
"kimi-k2-7-code",
|
|
481
|
-
"kimi-k3"
|
|
481
|
+
"kimi-k3",
|
|
482
|
+
"deepseek-v4-flash-0731"
|
|
482
483
|
]
|
|
483
484
|
// vision: undefined — unconstrained
|
|
484
485
|
// image_generation: undefined — unconstrained
|
|
@@ -2882,6 +2883,19 @@ ${partial}` : "[INTERRUPTED] Tool execution was stopped.";
|
|
|
2882
2883
|
}
|
|
2883
2884
|
};
|
|
2884
2885
|
|
|
2886
|
+
// src/toolResultCap.ts
|
|
2887
|
+
var MAX_TOOL_RESULT_BYTES = 256 * 1024;
|
|
2888
|
+
function capToolResult(result) {
|
|
2889
|
+
const total = Buffer.byteLength(result, "utf-8");
|
|
2890
|
+
if (total <= MAX_TOOL_RESULT_BYTES) {
|
|
2891
|
+
return result;
|
|
2892
|
+
}
|
|
2893
|
+
const head = Buffer.from(result, "utf-8").subarray(0, MAX_TOOL_RESULT_BYTES).toString("utf-8");
|
|
2894
|
+
return head + `
|
|
2895
|
+
|
|
2896
|
+
(tool result truncated at ${(MAX_TOOL_RESULT_BYTES / 1024).toFixed(0)}KB of ${(total / 1024).toFixed(0)}KB \u2014 too large to keep in context. Narrow the call (select fewer fields, paginate, or query a subset) instead of fetching everything.)`;
|
|
2897
|
+
}
|
|
2898
|
+
|
|
2885
2899
|
// src/statusWatcher.ts
|
|
2886
2900
|
function startStatusWatcher(config) {
|
|
2887
2901
|
const { apiConfig, getContext, onStatus, interval = 5e3, signal } = config;
|
|
@@ -3407,7 +3421,7 @@ ${partial}` : "[INTERRUPTED] Agent was interrupted before producing output.",
|
|
|
3407
3421
|
subAgentMessages
|
|
3408
3422
|
);
|
|
3409
3423
|
}
|
|
3410
|
-
safeSettle(result, result.startsWith("Error"));
|
|
3424
|
+
safeSettle(capToolResult(result), result.startsWith("Error"));
|
|
3411
3425
|
} catch (err) {
|
|
3412
3426
|
safeSettle(`Error: ${err.message}`, true);
|
|
3413
3427
|
}
|
|
@@ -3595,9 +3609,10 @@ var BROWSER_TOOLS = [
|
|
|
3595
3609
|
"evaluate",
|
|
3596
3610
|
"styles",
|
|
3597
3611
|
"screenshotFullPage",
|
|
3598
|
-
"screenshotViewport"
|
|
3612
|
+
"screenshotViewport",
|
|
3613
|
+
"setViewport"
|
|
3599
3614
|
],
|
|
3600
|
-
description:
|
|
3615
|
+
description: 'snapshot: accessibility tree of the page (waits for network to settle). click: click an element (animated cursor, full event sequence). type: type text into input (one char at a time, works with React/Vue/Svelte). select: select a dropdown option by text. wait: wait for an element to appear (polls 100ms, waits for network). navigate: navigate to a URL within the app (waits for load, subsequent steps run on new page). evaluate: run JS in the page. styles: read computed CSS styles from elements (pass properties array with camelCase names, or omit for defaults). screenshotFullPage: full-page viewport-stitched screenshot (returns CDN url with dimensions). screenshotViewport: screenshot of just the visible viewport \u2014 pass `scrollToSelector` (or `scrollY`) on this step to scroll a section into view and capture it in one atomic step (no separate scroll needed). setViewport: switch the browser between desktop and mobile rendering (pass `mode`: "desktop" or "mobile"). Reloads the page so responsive layouts, media queries, and matchMedia re-evaluate \u2014 use it to QA mobile/responsive views.'
|
|
3601
3616
|
},
|
|
3602
3617
|
ref: {
|
|
3603
3618
|
type: "string",
|
|
@@ -3651,6 +3666,11 @@ var BROWSER_TOOLS = [
|
|
|
3651
3666
|
scrollY: {
|
|
3652
3667
|
type: "number",
|
|
3653
3668
|
description: "For screenshotViewport: absolute Y offset to scroll to before the shot, when no selector is available."
|
|
3669
|
+
},
|
|
3670
|
+
mode: {
|
|
3671
|
+
type: "string",
|
|
3672
|
+
enum: ["desktop", "mobile"],
|
|
3673
|
+
description: 'For setViewport: the rendering mode to switch to. "mobile" emulates a phone (narrow width, touch, device pixel ratio); "desktop" is the standard wide viewport.'
|
|
3654
3674
|
}
|
|
3655
3675
|
},
|
|
3656
3676
|
required: ["command"]
|
|
@@ -3700,6 +3720,14 @@ var log7 = createLogger("browser-automation");
|
|
|
3700
3720
|
async function runBrowserAutomation(task, context, opts) {
|
|
3701
3721
|
const release = await acquireBrowserLock();
|
|
3702
3722
|
try {
|
|
3723
|
+
try {
|
|
3724
|
+
await sidecarRequest(
|
|
3725
|
+
"/set-viewport",
|
|
3726
|
+
{ mode: "default" },
|
|
3727
|
+
{ timeout: 2e4 }
|
|
3728
|
+
);
|
|
3729
|
+
} catch {
|
|
3730
|
+
}
|
|
3703
3731
|
let lastBrowserCommandViewport;
|
|
3704
3732
|
const result = await runSubAgent({
|
|
3705
3733
|
system: getBrowserAutomationPrompt(),
|
|
@@ -6401,21 +6429,6 @@ function triggerBrandExtraction(apiConfig, model) {
|
|
|
6401
6429
|
// src/session.ts
|
|
6402
6430
|
import fs22 from "fs";
|
|
6403
6431
|
import path11 from "path";
|
|
6404
|
-
|
|
6405
|
-
// src/toolResultCap.ts
|
|
6406
|
-
var MAX_TOOL_RESULT_BYTES = 256 * 1024;
|
|
6407
|
-
function capToolResult(result) {
|
|
6408
|
-
const total = Buffer.byteLength(result, "utf-8");
|
|
6409
|
-
if (total <= MAX_TOOL_RESULT_BYTES) {
|
|
6410
|
-
return result;
|
|
6411
|
-
}
|
|
6412
|
-
const head = Buffer.from(result, "utf-8").subarray(0, MAX_TOOL_RESULT_BYTES).toString("utf-8");
|
|
6413
|
-
return head + `
|
|
6414
|
-
|
|
6415
|
-
(tool result truncated at ${(MAX_TOOL_RESULT_BYTES / 1024).toFixed(0)}KB of ${(total / 1024).toFixed(0)}KB \u2014 too large to keep in context. Narrow the call (select fewer fields, paginate, or query a subset) instead of fetching everything.)`;
|
|
6416
|
-
}
|
|
6417
|
-
|
|
6418
|
-
// src/session.ts
|
|
6419
6432
|
var log12 = createLogger("session");
|
|
6420
6433
|
var SESSION_FILE = ".remy-session.json";
|
|
6421
6434
|
var ARCHIVE_DIR = ".logs/sessions";
|
package/dist/index.js
CHANGED
|
@@ -2094,7 +2094,8 @@ var init_surfaces = __esm({
|
|
|
2094
2094
|
"glm-5.2",
|
|
2095
2095
|
"muse-spark-1.1",
|
|
2096
2096
|
"kimi-k2-7-code",
|
|
2097
|
-
"kimi-k3"
|
|
2097
|
+
"kimi-k3",
|
|
2098
|
+
"deepseek-v4-flash-0731"
|
|
2098
2099
|
]
|
|
2099
2100
|
// vision: undefined — unconstrained
|
|
2100
2101
|
// image_generation: undefined — unconstrained
|
|
@@ -3513,6 +3514,25 @@ ${partial}` : "[INTERRUPTED] Tool execution was stopped.";
|
|
|
3513
3514
|
}
|
|
3514
3515
|
});
|
|
3515
3516
|
|
|
3517
|
+
// src/toolResultCap.ts
|
|
3518
|
+
function capToolResult(result) {
|
|
3519
|
+
const total = Buffer.byteLength(result, "utf-8");
|
|
3520
|
+
if (total <= MAX_TOOL_RESULT_BYTES) {
|
|
3521
|
+
return result;
|
|
3522
|
+
}
|
|
3523
|
+
const head = Buffer.from(result, "utf-8").subarray(0, MAX_TOOL_RESULT_BYTES).toString("utf-8");
|
|
3524
|
+
return head + `
|
|
3525
|
+
|
|
3526
|
+
(tool result truncated at ${(MAX_TOOL_RESULT_BYTES / 1024).toFixed(0)}KB of ${(total / 1024).toFixed(0)}KB \u2014 too large to keep in context. Narrow the call (select fewer fields, paginate, or query a subset) instead of fetching everything.)`;
|
|
3527
|
+
}
|
|
3528
|
+
var MAX_TOOL_RESULT_BYTES;
|
|
3529
|
+
var init_toolResultCap = __esm({
|
|
3530
|
+
"src/toolResultCap.ts"() {
|
|
3531
|
+
"use strict";
|
|
3532
|
+
MAX_TOOL_RESULT_BYTES = 256 * 1024;
|
|
3533
|
+
}
|
|
3534
|
+
});
|
|
3535
|
+
|
|
3516
3536
|
// src/statusWatcher.ts
|
|
3517
3537
|
function startStatusWatcher(config) {
|
|
3518
3538
|
const { apiConfig, getContext, onStatus, interval = 5e3, signal } = config;
|
|
@@ -4053,7 +4073,7 @@ ${partial}` : "[INTERRUPTED] Agent was interrupted before producing output.",
|
|
|
4053
4073
|
subAgentMessages
|
|
4054
4074
|
);
|
|
4055
4075
|
}
|
|
4056
|
-
safeSettle(result, result.startsWith("Error"));
|
|
4076
|
+
safeSettle(capToolResult(result), result.startsWith("Error"));
|
|
4057
4077
|
} catch (err) {
|
|
4058
4078
|
safeSettle(`Error: ${err.message}`, true);
|
|
4059
4079
|
}
|
|
@@ -4189,6 +4209,7 @@ var init_runner = __esm({
|
|
|
4189
4209
|
init_logger();
|
|
4190
4210
|
init_usageLedger();
|
|
4191
4211
|
init_toolRegistry();
|
|
4212
|
+
init_toolResultCap();
|
|
4192
4213
|
init_statusWatcher();
|
|
4193
4214
|
init_cleanMessages();
|
|
4194
4215
|
log7 = createLogger("sub-agent");
|
|
@@ -4258,9 +4279,10 @@ var init_tools = __esm({
|
|
|
4258
4279
|
"evaluate",
|
|
4259
4280
|
"styles",
|
|
4260
4281
|
"screenshotFullPage",
|
|
4261
|
-
"screenshotViewport"
|
|
4282
|
+
"screenshotViewport",
|
|
4283
|
+
"setViewport"
|
|
4262
4284
|
],
|
|
4263
|
-
description:
|
|
4285
|
+
description: 'snapshot: accessibility tree of the page (waits for network to settle). click: click an element (animated cursor, full event sequence). type: type text into input (one char at a time, works with React/Vue/Svelte). select: select a dropdown option by text. wait: wait for an element to appear (polls 100ms, waits for network). navigate: navigate to a URL within the app (waits for load, subsequent steps run on new page). evaluate: run JS in the page. styles: read computed CSS styles from elements (pass properties array with camelCase names, or omit for defaults). screenshotFullPage: full-page viewport-stitched screenshot (returns CDN url with dimensions). screenshotViewport: screenshot of just the visible viewport \u2014 pass `scrollToSelector` (or `scrollY`) on this step to scroll a section into view and capture it in one atomic step (no separate scroll needed). setViewport: switch the browser between desktop and mobile rendering (pass `mode`: "desktop" or "mobile"). Reloads the page so responsive layouts, media queries, and matchMedia re-evaluate \u2014 use it to QA mobile/responsive views.'
|
|
4264
4286
|
},
|
|
4265
4287
|
ref: {
|
|
4266
4288
|
type: "string",
|
|
@@ -4314,6 +4336,11 @@ var init_tools = __esm({
|
|
|
4314
4336
|
scrollY: {
|
|
4315
4337
|
type: "number",
|
|
4316
4338
|
description: "For screenshotViewport: absolute Y offset to scroll to before the shot, when no selector is available."
|
|
4339
|
+
},
|
|
4340
|
+
mode: {
|
|
4341
|
+
type: "string",
|
|
4342
|
+
enum: ["desktop", "mobile"],
|
|
4343
|
+
description: 'For setViewport: the rendering mode to switch to. "mobile" emulates a phone (narrow width, touch, device pixel ratio); "desktop" is the standard wide viewport.'
|
|
4317
4344
|
}
|
|
4318
4345
|
},
|
|
4319
4346
|
required: ["command"]
|
|
@@ -4371,6 +4398,14 @@ var init_prompt2 = __esm({
|
|
|
4371
4398
|
async function runBrowserAutomation(task, context, opts) {
|
|
4372
4399
|
const release = await acquireBrowserLock();
|
|
4373
4400
|
try {
|
|
4401
|
+
try {
|
|
4402
|
+
await sidecarRequest(
|
|
4403
|
+
"/set-viewport",
|
|
4404
|
+
{ mode: "default" },
|
|
4405
|
+
{ timeout: 2e4 }
|
|
4406
|
+
);
|
|
4407
|
+
} catch {
|
|
4408
|
+
}
|
|
4374
4409
|
let lastBrowserCommandViewport;
|
|
4375
4410
|
const result = await runSubAgent({
|
|
4376
4411
|
system: getBrowserAutomationPrompt(),
|
|
@@ -6755,25 +6790,6 @@ var init_tools7 = __esm({
|
|
|
6755
6790
|
}
|
|
6756
6791
|
});
|
|
6757
6792
|
|
|
6758
|
-
// src/toolResultCap.ts
|
|
6759
|
-
function capToolResult(result) {
|
|
6760
|
-
const total = Buffer.byteLength(result, "utf-8");
|
|
6761
|
-
if (total <= MAX_TOOL_RESULT_BYTES) {
|
|
6762
|
-
return result;
|
|
6763
|
-
}
|
|
6764
|
-
const head = Buffer.from(result, "utf-8").subarray(0, MAX_TOOL_RESULT_BYTES).toString("utf-8");
|
|
6765
|
-
return head + `
|
|
6766
|
-
|
|
6767
|
-
(tool result truncated at ${(MAX_TOOL_RESULT_BYTES / 1024).toFixed(0)}KB of ${(total / 1024).toFixed(0)}KB \u2014 too large to keep in context. Narrow the call (select fewer fields, paginate, or query a subset) instead of fetching everything.)`;
|
|
6768
|
-
}
|
|
6769
|
-
var MAX_TOOL_RESULT_BYTES;
|
|
6770
|
-
var init_toolResultCap = __esm({
|
|
6771
|
-
"src/toolResultCap.ts"() {
|
|
6772
|
-
"use strict";
|
|
6773
|
-
MAX_TOOL_RESULT_BYTES = 256 * 1024;
|
|
6774
|
-
}
|
|
6775
|
-
});
|
|
6776
|
-
|
|
6777
6793
|
// src/session.ts
|
|
6778
6794
|
import fs20 from "fs";
|
|
6779
6795
|
import path9 from "path";
|
|
@@ -44,6 +44,7 @@ Note: the snapshot concatenates inline text and strips whitespace. If you need t
|
|
|
44
44
|
- `evaluate`: Run arbitrary JavaScript in the page and return the result.
|
|
45
45
|
- `styles`: Read computed CSS styles from page elements. Pass a `properties` array with camelCase CSS property names (e.g., `["backgroundColor", "borderRadius", "fontSize"]`). Omit `properties` for a default set covering colors, typography, spacing, borders, shadows, dimensions, and layout. Uses the same targeting as click/type (ref, text, role, label, selector). Omit the target to get styles for all elements from the last snapshot.
|
|
46
46
|
- `screenshotViewport`: Take a screenshot of the visible viewport. Returns CDN url with full text analysis and dimensions. To capture a specific section, set `scrollToSelector` (a CSS selector) — or `scrollY` (an absolute offset) — on this same step; it scrolls the target into view and captures it atomically, so you do NOT need a separate scroll step. Do not use if you can get what you need with other tools - only use when you need to visually see the viewport.
|
|
47
|
+
- `setViewport`: Switch the browser between desktop and mobile rendering. Set `mode` to `"desktop"` or `"mobile"`. Mobile emulates a phone (390-wide, touch, device pixel ratio 2); desktop is the standard wide viewport. This reloads the page so media queries, responsive layouts, and `matchMedia` re-evaluate — the reload clears in-page state, so switch before you set up the state you want to inspect. The mode persists across navigations within a run. Each run starts in the app's default mode, so only use this when you need to check the other one.
|
|
47
48
|
|
|
48
49
|
### Element targeting (tried in order)
|
|
49
50
|
|
|
@@ -118,6 +119,16 @@ Capture a specific below-the-fold section (scroll + capture in one atomic step):
|
|
|
118
119
|
}
|
|
119
120
|
```
|
|
120
121
|
|
|
122
|
+
Check the mobile layout of a page:
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
"steps": [
|
|
126
|
+
{ "command": "setViewport", "mode": "mobile" },
|
|
127
|
+
{ "command": "screenshotViewport" }
|
|
128
|
+
]
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
121
132
|
Navigate to a sub-page and interact with it:
|
|
122
133
|
```json
|
|
123
134
|
{
|