@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 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
- if (defaults?.include?.length) {
81
- merged.include = Array.from(/* @__PURE__ */ new Set([...merged.include ?? [], ...defaults.include]));
82
- }
83
- if (defaults?.inline) {
84
- merged.inlineConsole = merged.inlineConsole ?? true;
85
- merged.inlineHar = merged.inlineHar ?? true;
86
- merged.inlineResult = merged.inlineResult ?? true;
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: "Run a Riddle job (pass-through payload) against https://api.riddledc.com/v1/run. Supports url/urls/steps/script. Returns screenshot/console/har/result when requested.",
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: ["console", "har", "result"],
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: "Riddle: take a screenshot of a single URL (url mode).",
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
- const result = await runWithDefaults(api, payload, { include: ["console", "har"], inline: true });
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: "Riddle: take screenshots for multiple URLs in one job (urls mode).",
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
- const result = await runWithDefaults(api, payload, { include: ["console", "har"], inline: true });
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: "Riddle: run a workflow in steps mode (goto/click/fill/etc.).",
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
- const result = await runWithDefaults(api, payload, { include: ["console", "har", "result"], inline: true });
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: "Riddle: run full Playwright code (script mode).",
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
- const result = await runWithDefaults(api, payload, { include: ["console", "har", "result"], inline: true });
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
- if (defaults?.include?.length) {
57
- merged.include = Array.from(/* @__PURE__ */ new Set([...merged.include ?? [], ...defaults.include]));
58
- }
59
- if (defaults?.inline) {
60
- merged.inlineConsole = merged.inlineConsole ?? true;
61
- merged.inlineHar = merged.inlineHar ?? true;
62
- merged.inlineResult = merged.inlineResult ?? true;
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: "Run a Riddle job (pass-through payload) against https://api.riddledc.com/v1/run. Supports url/urls/steps/script. Returns screenshot/console/har/result when requested.",
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: ["console", "har", "result"],
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: "Riddle: take a screenshot of a single URL (url mode).",
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
- const result = await runWithDefaults(api, payload, { include: ["console", "har"], inline: true });
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: "Riddle: take screenshots for multiple URLs in one job (urls mode).",
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
- const result = await runWithDefaults(api, payload, { include: ["console", "har"], inline: true });
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: "Riddle: run a workflow in steps mode (goto/click/fill/etc.).",
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
- const result = await runWithDefaults(api, payload, { include: ["console", "har", "result"], inline: true });
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: "Riddle: run full Playwright code (script mode).",
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
- const result = await runWithDefaults(api, payload, { include: ["console", "har", "result"], inline: true });
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
  },
@@ -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.2.2",
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,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riddledc/openclaw-riddledc",
3
- "version": "0.2.2",
3
+ "version": "0.3.1",
4
4
  "description": "OpenClaw integration package for RiddleDC (no secrets).",
5
5
  "license": "MIT",
6
6
  "author": "RiddleDC",