@riddledc/openclaw-riddledc 0.2.2 → 0.3.1
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/index.cjs +89 -20
- package/dist/index.js +89 -20
- package/openclaw.plugin.json +2 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -24,6 +24,9 @@ __export(index_exports, {
|
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(index_exports);
|
|
26
26
|
var import_typebox = require("@sinclair/typebox");
|
|
27
|
+
var import_promises = require("fs/promises");
|
|
28
|
+
var import_node_path = require("path");
|
|
29
|
+
var INLINE_CAP = 50 * 1024;
|
|
27
30
|
function getCfg(api) {
|
|
28
31
|
const cfg = api?.config ?? {};
|
|
29
32
|
const pluginCfg = cfg?.plugins?.entries?.["openclaw-riddledc"]?.config ?? {};
|
|
@@ -66,6 +69,58 @@ async function postRun(baseUrl, apiKey, payload) {
|
|
|
66
69
|
function abToBase64(ab) {
|
|
67
70
|
return Buffer.from(ab).toString("base64");
|
|
68
71
|
}
|
|
72
|
+
function getWorkspacePath(api) {
|
|
73
|
+
return api?.workspacePath ?? process.cwd();
|
|
74
|
+
}
|
|
75
|
+
async function writeArtifact(workspace, subdir, filename, content) {
|
|
76
|
+
const dir = (0, import_node_path.join)(workspace, "riddle", subdir);
|
|
77
|
+
await (0, import_promises.mkdir)(dir, { recursive: true });
|
|
78
|
+
const filePath = (0, import_node_path.join)(dir, filename);
|
|
79
|
+
const buf = Buffer.from(content, "utf8");
|
|
80
|
+
await (0, import_promises.writeFile)(filePath, buf);
|
|
81
|
+
return { path: `riddle/${subdir}/${filename}`, sizeBytes: buf.byteLength };
|
|
82
|
+
}
|
|
83
|
+
async function writeArtifactBinary(workspace, subdir, filename, base64Content) {
|
|
84
|
+
const dir = (0, import_node_path.join)(workspace, "riddle", subdir);
|
|
85
|
+
await (0, import_promises.mkdir)(dir, { recursive: true });
|
|
86
|
+
const filePath = (0, import_node_path.join)(dir, filename);
|
|
87
|
+
const buf = Buffer.from(base64Content, "base64");
|
|
88
|
+
await (0, import_promises.writeFile)(filePath, buf);
|
|
89
|
+
return { path: `riddle/${subdir}/${filename}`, sizeBytes: buf.byteLength };
|
|
90
|
+
}
|
|
91
|
+
async function applySafetySpec(result, opts) {
|
|
92
|
+
const jobId = result.job_id ?? "unknown";
|
|
93
|
+
if (result.screenshot != null && typeof result.screenshot === "string") {
|
|
94
|
+
const ref = await writeArtifactBinary(opts.workspace, "screenshots", `${jobId}.png`, result.screenshot);
|
|
95
|
+
result.screenshot = { saved: ref.path, sizeBytes: ref.sizeBytes };
|
|
96
|
+
}
|
|
97
|
+
if (result.rawPngBase64 != null) {
|
|
98
|
+
const ref = await writeArtifactBinary(opts.workspace, "screenshots", `${jobId}.png`, result.rawPngBase64);
|
|
99
|
+
result.screenshot = { saved: ref.path, sizeBytes: ref.sizeBytes };
|
|
100
|
+
delete result.rawPngBase64;
|
|
101
|
+
}
|
|
102
|
+
if (result.har != null) {
|
|
103
|
+
const harStr = typeof result.har === "string" ? result.har : JSON.stringify(result.har);
|
|
104
|
+
const harBytes = Buffer.byteLength(harStr, "utf8");
|
|
105
|
+
if (opts.harInline && harBytes <= INLINE_CAP) {
|
|
106
|
+
} else {
|
|
107
|
+
const ref = await writeArtifact(opts.workspace, "har", `${jobId}.har.json`, harStr);
|
|
108
|
+
if (opts.harInline && harBytes > INLINE_CAP) {
|
|
109
|
+
result.har = { saved: ref.path, sizeBytes: ref.sizeBytes, warning: "Exceeded 50KB inline cap; wrote to file" };
|
|
110
|
+
} else {
|
|
111
|
+
result.har = { saved: ref.path, sizeBytes: ref.sizeBytes };
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (result.console != null) {
|
|
116
|
+
const consoleStr = typeof result.console === "string" ? result.console : JSON.stringify(result.console);
|
|
117
|
+
const consoleBytes = Buffer.byteLength(consoleStr, "utf8");
|
|
118
|
+
if (consoleBytes > INLINE_CAP) {
|
|
119
|
+
const ref = await writeArtifact(opts.workspace, "console", `${jobId}.log`, consoleStr);
|
|
120
|
+
result.console = { saved: ref.path, sizeBytes: ref.sizeBytes };
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
69
124
|
async function runWithDefaults(api, payload, defaults) {
|
|
70
125
|
const { apiKey, baseUrl } = getCfg(api);
|
|
71
126
|
if (!apiKey) {
|
|
@@ -76,14 +131,17 @@ async function runWithDefaults(api, payload, defaults) {
|
|
|
76
131
|
}
|
|
77
132
|
assertAllowedBaseUrl(baseUrl);
|
|
78
133
|
const mode = detectMode(payload);
|
|
134
|
+
const userInclude = payload.include ?? [];
|
|
135
|
+
const userRequestedHar = userInclude.includes("har");
|
|
136
|
+
const harInline = !!payload.harInline;
|
|
79
137
|
const merged = { ...payload };
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
merged.
|
|
138
|
+
delete merged.harInline;
|
|
139
|
+
const defaultInc = defaults?.include ?? ["screenshot", "console"];
|
|
140
|
+
merged.include = Array.from(/* @__PURE__ */ new Set([...userInclude, ...defaultInc]));
|
|
141
|
+
merged.inlineConsole = merged.inlineConsole ?? true;
|
|
142
|
+
merged.inlineResult = merged.inlineResult ?? true;
|
|
143
|
+
if (userRequestedHar) {
|
|
144
|
+
merged.inlineHar = true;
|
|
87
145
|
}
|
|
88
146
|
const out = { ok: true, mode };
|
|
89
147
|
const { contentType, body, headers, status } = await postRun(baseUrl, apiKey, merged);
|
|
@@ -106,26 +164,29 @@ async function runWithDefaults(api, payload, defaults) {
|
|
|
106
164
|
const duration = headers.get("x-duration-ms");
|
|
107
165
|
out.duration_ms = duration ? Number(duration) : void 0;
|
|
108
166
|
out.sync = true;
|
|
167
|
+
const workspace2 = getWorkspacePath(api);
|
|
168
|
+
await applySafetySpec(out, { workspace: workspace2, harInline });
|
|
109
169
|
return out;
|
|
110
170
|
}
|
|
111
171
|
const txt = Buffer.from(body).toString("utf8");
|
|
112
172
|
const json = JSON.parse(txt);
|
|
113
173
|
Object.assign(out, json);
|
|
114
174
|
out.job_id = json.job_id ?? json.jobId ?? out.job_id;
|
|
175
|
+
const workspace = getWorkspacePath(api);
|
|
176
|
+
await applySafetySpec(out, { workspace, harInline });
|
|
115
177
|
return out;
|
|
116
178
|
}
|
|
117
179
|
function register(api) {
|
|
118
180
|
api.registerTool(
|
|
119
181
|
{
|
|
120
182
|
name: "riddle_run",
|
|
121
|
-
description:
|
|
183
|
+
description: 'Run a Riddle job (pass-through payload) against https://api.riddledc.com/v1/run. Supports url/urls/steps/script. Returns screenshot + console by default; pass include:["har"] to opt in to HAR capture.',
|
|
122
184
|
parameters: import_typebox.Type.Object({
|
|
123
185
|
payload: import_typebox.Type.Record(import_typebox.Type.String(), import_typebox.Type.Any())
|
|
124
186
|
}),
|
|
125
187
|
async execute(_id, params) {
|
|
126
188
|
const result = await runWithDefaults(api, params.payload, {
|
|
127
|
-
include: ["
|
|
128
|
-
inline: true
|
|
189
|
+
include: ["screenshot", "console", "result"]
|
|
129
190
|
});
|
|
130
191
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
131
192
|
}
|
|
@@ -135,12 +196,13 @@ function register(api) {
|
|
|
135
196
|
api.registerTool(
|
|
136
197
|
{
|
|
137
198
|
name: "riddle_screenshot",
|
|
138
|
-
description:
|
|
199
|
+
description: 'Riddle: take a screenshot of a single URL. Returns screenshot + console by default; pass include:["har"] to opt in to HAR capture.',
|
|
139
200
|
parameters: import_typebox.Type.Object({
|
|
140
201
|
url: import_typebox.Type.String(),
|
|
141
202
|
timeout_sec: import_typebox.Type.Optional(import_typebox.Type.Number()),
|
|
142
203
|
options: import_typebox.Type.Optional(import_typebox.Type.Record(import_typebox.Type.String(), import_typebox.Type.Any())),
|
|
143
|
-
include: import_typebox.Type.Optional(import_typebox.Type.Array(import_typebox.Type.String()))
|
|
204
|
+
include: import_typebox.Type.Optional(import_typebox.Type.Array(import_typebox.Type.String())),
|
|
205
|
+
harInline: import_typebox.Type.Optional(import_typebox.Type.Boolean())
|
|
144
206
|
}),
|
|
145
207
|
async execute(_id, params) {
|
|
146
208
|
if (!params.url || typeof params.url !== "string") throw new Error("url must be a string");
|
|
@@ -148,7 +210,8 @@ function register(api) {
|
|
|
148
210
|
if (params.timeout_sec) payload.timeout_sec = params.timeout_sec;
|
|
149
211
|
if (params.options) payload.options = params.options;
|
|
150
212
|
if (params.include) payload.include = params.include;
|
|
151
|
-
|
|
213
|
+
if (params.harInline) payload.harInline = params.harInline;
|
|
214
|
+
const result = await runWithDefaults(api, payload, { include: ["screenshot", "console"] });
|
|
152
215
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
153
216
|
}
|
|
154
217
|
},
|
|
@@ -157,12 +220,13 @@ function register(api) {
|
|
|
157
220
|
api.registerTool(
|
|
158
221
|
{
|
|
159
222
|
name: "riddle_screenshots",
|
|
160
|
-
description:
|
|
223
|
+
description: 'Riddle: take screenshots for multiple URLs in one job. Returns screenshots + console by default; pass include:["har"] to opt in to HAR capture.',
|
|
161
224
|
parameters: import_typebox.Type.Object({
|
|
162
225
|
urls: import_typebox.Type.Array(import_typebox.Type.String()),
|
|
163
226
|
timeout_sec: import_typebox.Type.Optional(import_typebox.Type.Number()),
|
|
164
227
|
options: import_typebox.Type.Optional(import_typebox.Type.Record(import_typebox.Type.String(), import_typebox.Type.Any())),
|
|
165
|
-
include: import_typebox.Type.Optional(import_typebox.Type.Array(import_typebox.Type.String()))
|
|
228
|
+
include: import_typebox.Type.Optional(import_typebox.Type.Array(import_typebox.Type.String())),
|
|
229
|
+
harInline: import_typebox.Type.Optional(import_typebox.Type.Boolean())
|
|
166
230
|
}),
|
|
167
231
|
async execute(_id, params) {
|
|
168
232
|
if (!Array.isArray(params.urls) || params.urls.some((url) => typeof url !== "string")) {
|
|
@@ -172,7 +236,8 @@ function register(api) {
|
|
|
172
236
|
if (params.timeout_sec) payload.timeout_sec = params.timeout_sec;
|
|
173
237
|
if (params.options) payload.options = params.options;
|
|
174
238
|
if (params.include) payload.include = params.include;
|
|
175
|
-
|
|
239
|
+
if (params.harInline) payload.harInline = params.harInline;
|
|
240
|
+
const result = await runWithDefaults(api, payload, { include: ["screenshot", "console"] });
|
|
176
241
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
177
242
|
}
|
|
178
243
|
},
|
|
@@ -181,12 +246,13 @@ function register(api) {
|
|
|
181
246
|
api.registerTool(
|
|
182
247
|
{
|
|
183
248
|
name: "riddle_steps",
|
|
184
|
-
description:
|
|
249
|
+
description: 'Riddle: run a workflow in steps mode (goto/click/fill/etc.). Returns screenshot + console by default; pass include:["har"] to opt in to HAR capture.',
|
|
185
250
|
parameters: import_typebox.Type.Object({
|
|
186
251
|
steps: import_typebox.Type.Array(import_typebox.Type.Record(import_typebox.Type.String(), import_typebox.Type.Any())),
|
|
187
252
|
timeout_sec: import_typebox.Type.Optional(import_typebox.Type.Number()),
|
|
188
253
|
options: import_typebox.Type.Optional(import_typebox.Type.Record(import_typebox.Type.String(), import_typebox.Type.Any())),
|
|
189
254
|
include: import_typebox.Type.Optional(import_typebox.Type.Array(import_typebox.Type.String())),
|
|
255
|
+
harInline: import_typebox.Type.Optional(import_typebox.Type.Boolean()),
|
|
190
256
|
sync: import_typebox.Type.Optional(import_typebox.Type.Boolean())
|
|
191
257
|
}),
|
|
192
258
|
async execute(_id, params) {
|
|
@@ -196,7 +262,8 @@ function register(api) {
|
|
|
196
262
|
if (params.timeout_sec) payload.timeout_sec = params.timeout_sec;
|
|
197
263
|
if (params.options) payload.options = params.options;
|
|
198
264
|
if (params.include) payload.include = params.include;
|
|
199
|
-
|
|
265
|
+
if (params.harInline) payload.harInline = params.harInline;
|
|
266
|
+
const result = await runWithDefaults(api, payload, { include: ["screenshot", "console", "result"] });
|
|
200
267
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
201
268
|
}
|
|
202
269
|
},
|
|
@@ -205,12 +272,13 @@ function register(api) {
|
|
|
205
272
|
api.registerTool(
|
|
206
273
|
{
|
|
207
274
|
name: "riddle_script",
|
|
208
|
-
description:
|
|
275
|
+
description: 'Riddle: run full Playwright code (script mode). Returns screenshot + console by default; pass include:["har"] to opt in to HAR capture.',
|
|
209
276
|
parameters: import_typebox.Type.Object({
|
|
210
277
|
script: import_typebox.Type.String(),
|
|
211
278
|
timeout_sec: import_typebox.Type.Optional(import_typebox.Type.Number()),
|
|
212
279
|
options: import_typebox.Type.Optional(import_typebox.Type.Record(import_typebox.Type.String(), import_typebox.Type.Any())),
|
|
213
280
|
include: import_typebox.Type.Optional(import_typebox.Type.Array(import_typebox.Type.String())),
|
|
281
|
+
harInline: import_typebox.Type.Optional(import_typebox.Type.Boolean()),
|
|
214
282
|
sync: import_typebox.Type.Optional(import_typebox.Type.Boolean())
|
|
215
283
|
}),
|
|
216
284
|
async execute(_id, params) {
|
|
@@ -220,7 +288,8 @@ function register(api) {
|
|
|
220
288
|
if (params.timeout_sec) payload.timeout_sec = params.timeout_sec;
|
|
221
289
|
if (params.options) payload.options = params.options;
|
|
222
290
|
if (params.include) payload.include = params.include;
|
|
223
|
-
|
|
291
|
+
if (params.harInline) payload.harInline = params.harInline;
|
|
292
|
+
const result = await runWithDefaults(api, payload, { include: ["screenshot", "console", "result"] });
|
|
224
293
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
225
294
|
}
|
|
226
295
|
},
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import { Type } from "@sinclair/typebox";
|
|
3
|
+
import { writeFile, mkdir } from "fs/promises";
|
|
4
|
+
import { join } from "path";
|
|
5
|
+
var INLINE_CAP = 50 * 1024;
|
|
3
6
|
function getCfg(api) {
|
|
4
7
|
const cfg = api?.config ?? {};
|
|
5
8
|
const pluginCfg = cfg?.plugins?.entries?.["openclaw-riddledc"]?.config ?? {};
|
|
@@ -42,6 +45,58 @@ async function postRun(baseUrl, apiKey, payload) {
|
|
|
42
45
|
function abToBase64(ab) {
|
|
43
46
|
return Buffer.from(ab).toString("base64");
|
|
44
47
|
}
|
|
48
|
+
function getWorkspacePath(api) {
|
|
49
|
+
return api?.workspacePath ?? process.cwd();
|
|
50
|
+
}
|
|
51
|
+
async function writeArtifact(workspace, subdir, filename, content) {
|
|
52
|
+
const dir = join(workspace, "riddle", subdir);
|
|
53
|
+
await mkdir(dir, { recursive: true });
|
|
54
|
+
const filePath = join(dir, filename);
|
|
55
|
+
const buf = Buffer.from(content, "utf8");
|
|
56
|
+
await writeFile(filePath, buf);
|
|
57
|
+
return { path: `riddle/${subdir}/${filename}`, sizeBytes: buf.byteLength };
|
|
58
|
+
}
|
|
59
|
+
async function writeArtifactBinary(workspace, subdir, filename, base64Content) {
|
|
60
|
+
const dir = join(workspace, "riddle", subdir);
|
|
61
|
+
await mkdir(dir, { recursive: true });
|
|
62
|
+
const filePath = join(dir, filename);
|
|
63
|
+
const buf = Buffer.from(base64Content, "base64");
|
|
64
|
+
await writeFile(filePath, buf);
|
|
65
|
+
return { path: `riddle/${subdir}/${filename}`, sizeBytes: buf.byteLength };
|
|
66
|
+
}
|
|
67
|
+
async function applySafetySpec(result, opts) {
|
|
68
|
+
const jobId = result.job_id ?? "unknown";
|
|
69
|
+
if (result.screenshot != null && typeof result.screenshot === "string") {
|
|
70
|
+
const ref = await writeArtifactBinary(opts.workspace, "screenshots", `${jobId}.png`, result.screenshot);
|
|
71
|
+
result.screenshot = { saved: ref.path, sizeBytes: ref.sizeBytes };
|
|
72
|
+
}
|
|
73
|
+
if (result.rawPngBase64 != null) {
|
|
74
|
+
const ref = await writeArtifactBinary(opts.workspace, "screenshots", `${jobId}.png`, result.rawPngBase64);
|
|
75
|
+
result.screenshot = { saved: ref.path, sizeBytes: ref.sizeBytes };
|
|
76
|
+
delete result.rawPngBase64;
|
|
77
|
+
}
|
|
78
|
+
if (result.har != null) {
|
|
79
|
+
const harStr = typeof result.har === "string" ? result.har : JSON.stringify(result.har);
|
|
80
|
+
const harBytes = Buffer.byteLength(harStr, "utf8");
|
|
81
|
+
if (opts.harInline && harBytes <= INLINE_CAP) {
|
|
82
|
+
} else {
|
|
83
|
+
const ref = await writeArtifact(opts.workspace, "har", `${jobId}.har.json`, harStr);
|
|
84
|
+
if (opts.harInline && harBytes > INLINE_CAP) {
|
|
85
|
+
result.har = { saved: ref.path, sizeBytes: ref.sizeBytes, warning: "Exceeded 50KB inline cap; wrote to file" };
|
|
86
|
+
} else {
|
|
87
|
+
result.har = { saved: ref.path, sizeBytes: ref.sizeBytes };
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (result.console != null) {
|
|
92
|
+
const consoleStr = typeof result.console === "string" ? result.console : JSON.stringify(result.console);
|
|
93
|
+
const consoleBytes = Buffer.byteLength(consoleStr, "utf8");
|
|
94
|
+
if (consoleBytes > INLINE_CAP) {
|
|
95
|
+
const ref = await writeArtifact(opts.workspace, "console", `${jobId}.log`, consoleStr);
|
|
96
|
+
result.console = { saved: ref.path, sizeBytes: ref.sizeBytes };
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
45
100
|
async function runWithDefaults(api, payload, defaults) {
|
|
46
101
|
const { apiKey, baseUrl } = getCfg(api);
|
|
47
102
|
if (!apiKey) {
|
|
@@ -52,14 +107,17 @@ async function runWithDefaults(api, payload, defaults) {
|
|
|
52
107
|
}
|
|
53
108
|
assertAllowedBaseUrl(baseUrl);
|
|
54
109
|
const mode = detectMode(payload);
|
|
110
|
+
const userInclude = payload.include ?? [];
|
|
111
|
+
const userRequestedHar = userInclude.includes("har");
|
|
112
|
+
const harInline = !!payload.harInline;
|
|
55
113
|
const merged = { ...payload };
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
merged.
|
|
114
|
+
delete merged.harInline;
|
|
115
|
+
const defaultInc = defaults?.include ?? ["screenshot", "console"];
|
|
116
|
+
merged.include = Array.from(/* @__PURE__ */ new Set([...userInclude, ...defaultInc]));
|
|
117
|
+
merged.inlineConsole = merged.inlineConsole ?? true;
|
|
118
|
+
merged.inlineResult = merged.inlineResult ?? true;
|
|
119
|
+
if (userRequestedHar) {
|
|
120
|
+
merged.inlineHar = true;
|
|
63
121
|
}
|
|
64
122
|
const out = { ok: true, mode };
|
|
65
123
|
const { contentType, body, headers, status } = await postRun(baseUrl, apiKey, merged);
|
|
@@ -82,26 +140,29 @@ async function runWithDefaults(api, payload, defaults) {
|
|
|
82
140
|
const duration = headers.get("x-duration-ms");
|
|
83
141
|
out.duration_ms = duration ? Number(duration) : void 0;
|
|
84
142
|
out.sync = true;
|
|
143
|
+
const workspace2 = getWorkspacePath(api);
|
|
144
|
+
await applySafetySpec(out, { workspace: workspace2, harInline });
|
|
85
145
|
return out;
|
|
86
146
|
}
|
|
87
147
|
const txt = Buffer.from(body).toString("utf8");
|
|
88
148
|
const json = JSON.parse(txt);
|
|
89
149
|
Object.assign(out, json);
|
|
90
150
|
out.job_id = json.job_id ?? json.jobId ?? out.job_id;
|
|
151
|
+
const workspace = getWorkspacePath(api);
|
|
152
|
+
await applySafetySpec(out, { workspace, harInline });
|
|
91
153
|
return out;
|
|
92
154
|
}
|
|
93
155
|
function register(api) {
|
|
94
156
|
api.registerTool(
|
|
95
157
|
{
|
|
96
158
|
name: "riddle_run",
|
|
97
|
-
description:
|
|
159
|
+
description: 'Run a Riddle job (pass-through payload) against https://api.riddledc.com/v1/run. Supports url/urls/steps/script. Returns screenshot + console by default; pass include:["har"] to opt in to HAR capture.',
|
|
98
160
|
parameters: Type.Object({
|
|
99
161
|
payload: Type.Record(Type.String(), Type.Any())
|
|
100
162
|
}),
|
|
101
163
|
async execute(_id, params) {
|
|
102
164
|
const result = await runWithDefaults(api, params.payload, {
|
|
103
|
-
include: ["
|
|
104
|
-
inline: true
|
|
165
|
+
include: ["screenshot", "console", "result"]
|
|
105
166
|
});
|
|
106
167
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
107
168
|
}
|
|
@@ -111,12 +172,13 @@ function register(api) {
|
|
|
111
172
|
api.registerTool(
|
|
112
173
|
{
|
|
113
174
|
name: "riddle_screenshot",
|
|
114
|
-
description:
|
|
175
|
+
description: 'Riddle: take a screenshot of a single URL. Returns screenshot + console by default; pass include:["har"] to opt in to HAR capture.',
|
|
115
176
|
parameters: Type.Object({
|
|
116
177
|
url: Type.String(),
|
|
117
178
|
timeout_sec: Type.Optional(Type.Number()),
|
|
118
179
|
options: Type.Optional(Type.Record(Type.String(), Type.Any())),
|
|
119
|
-
include: Type.Optional(Type.Array(Type.String()))
|
|
180
|
+
include: Type.Optional(Type.Array(Type.String())),
|
|
181
|
+
harInline: Type.Optional(Type.Boolean())
|
|
120
182
|
}),
|
|
121
183
|
async execute(_id, params) {
|
|
122
184
|
if (!params.url || typeof params.url !== "string") throw new Error("url must be a string");
|
|
@@ -124,7 +186,8 @@ function register(api) {
|
|
|
124
186
|
if (params.timeout_sec) payload.timeout_sec = params.timeout_sec;
|
|
125
187
|
if (params.options) payload.options = params.options;
|
|
126
188
|
if (params.include) payload.include = params.include;
|
|
127
|
-
|
|
189
|
+
if (params.harInline) payload.harInline = params.harInline;
|
|
190
|
+
const result = await runWithDefaults(api, payload, { include: ["screenshot", "console"] });
|
|
128
191
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
129
192
|
}
|
|
130
193
|
},
|
|
@@ -133,12 +196,13 @@ function register(api) {
|
|
|
133
196
|
api.registerTool(
|
|
134
197
|
{
|
|
135
198
|
name: "riddle_screenshots",
|
|
136
|
-
description:
|
|
199
|
+
description: 'Riddle: take screenshots for multiple URLs in one job. Returns screenshots + console by default; pass include:["har"] to opt in to HAR capture.',
|
|
137
200
|
parameters: Type.Object({
|
|
138
201
|
urls: Type.Array(Type.String()),
|
|
139
202
|
timeout_sec: Type.Optional(Type.Number()),
|
|
140
203
|
options: Type.Optional(Type.Record(Type.String(), Type.Any())),
|
|
141
|
-
include: Type.Optional(Type.Array(Type.String()))
|
|
204
|
+
include: Type.Optional(Type.Array(Type.String())),
|
|
205
|
+
harInline: Type.Optional(Type.Boolean())
|
|
142
206
|
}),
|
|
143
207
|
async execute(_id, params) {
|
|
144
208
|
if (!Array.isArray(params.urls) || params.urls.some((url) => typeof url !== "string")) {
|
|
@@ -148,7 +212,8 @@ function register(api) {
|
|
|
148
212
|
if (params.timeout_sec) payload.timeout_sec = params.timeout_sec;
|
|
149
213
|
if (params.options) payload.options = params.options;
|
|
150
214
|
if (params.include) payload.include = params.include;
|
|
151
|
-
|
|
215
|
+
if (params.harInline) payload.harInline = params.harInline;
|
|
216
|
+
const result = await runWithDefaults(api, payload, { include: ["screenshot", "console"] });
|
|
152
217
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
153
218
|
}
|
|
154
219
|
},
|
|
@@ -157,12 +222,13 @@ function register(api) {
|
|
|
157
222
|
api.registerTool(
|
|
158
223
|
{
|
|
159
224
|
name: "riddle_steps",
|
|
160
|
-
description:
|
|
225
|
+
description: 'Riddle: run a workflow in steps mode (goto/click/fill/etc.). Returns screenshot + console by default; pass include:["har"] to opt in to HAR capture.',
|
|
161
226
|
parameters: Type.Object({
|
|
162
227
|
steps: Type.Array(Type.Record(Type.String(), Type.Any())),
|
|
163
228
|
timeout_sec: Type.Optional(Type.Number()),
|
|
164
229
|
options: Type.Optional(Type.Record(Type.String(), Type.Any())),
|
|
165
230
|
include: Type.Optional(Type.Array(Type.String())),
|
|
231
|
+
harInline: Type.Optional(Type.Boolean()),
|
|
166
232
|
sync: Type.Optional(Type.Boolean())
|
|
167
233
|
}),
|
|
168
234
|
async execute(_id, params) {
|
|
@@ -172,7 +238,8 @@ function register(api) {
|
|
|
172
238
|
if (params.timeout_sec) payload.timeout_sec = params.timeout_sec;
|
|
173
239
|
if (params.options) payload.options = params.options;
|
|
174
240
|
if (params.include) payload.include = params.include;
|
|
175
|
-
|
|
241
|
+
if (params.harInline) payload.harInline = params.harInline;
|
|
242
|
+
const result = await runWithDefaults(api, payload, { include: ["screenshot", "console", "result"] });
|
|
176
243
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
177
244
|
}
|
|
178
245
|
},
|
|
@@ -181,12 +248,13 @@ function register(api) {
|
|
|
181
248
|
api.registerTool(
|
|
182
249
|
{
|
|
183
250
|
name: "riddle_script",
|
|
184
|
-
description:
|
|
251
|
+
description: 'Riddle: run full Playwright code (script mode). Returns screenshot + console by default; pass include:["har"] to opt in to HAR capture.',
|
|
185
252
|
parameters: Type.Object({
|
|
186
253
|
script: Type.String(),
|
|
187
254
|
timeout_sec: Type.Optional(Type.Number()),
|
|
188
255
|
options: Type.Optional(Type.Record(Type.String(), Type.Any())),
|
|
189
256
|
include: Type.Optional(Type.Array(Type.String())),
|
|
257
|
+
harInline: Type.Optional(Type.Boolean()),
|
|
190
258
|
sync: Type.Optional(Type.Boolean())
|
|
191
259
|
}),
|
|
192
260
|
async execute(_id, params) {
|
|
@@ -196,7 +264,8 @@ function register(api) {
|
|
|
196
264
|
if (params.timeout_sec) payload.timeout_sec = params.timeout_sec;
|
|
197
265
|
if (params.options) payload.options = params.options;
|
|
198
266
|
if (params.include) payload.include = params.include;
|
|
199
|
-
|
|
267
|
+
if (params.harInline) payload.harInline = params.harInline;
|
|
268
|
+
const result = await runWithDefaults(api, payload, { include: ["screenshot", "console", "result"] });
|
|
200
269
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
201
270
|
}
|
|
202
271
|
},
|
package/openclaw.plugin.json
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
"id": "openclaw-riddledc",
|
|
3
3
|
"name": "Riddle",
|
|
4
4
|
"description": "Riddle (riddledc.com) hosted browser API tools for OpenClaw agents.",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.3.1",
|
|
6
|
+
"notes": "0.3.1: Screenshots now saved to workspace files instead of inline base64 to prevent context bloat.",
|
|
6
7
|
"configSchema": {
|
|
7
8
|
"type": "object",
|
|
8
9
|
"additionalProperties": false,
|