@debugg-ai/debugg-ai-mcp 1.0.40 → 1.0.41
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.
|
@@ -168,10 +168,10 @@ export async function testPageChangesHandler(input, context, progressCallback) {
|
|
|
168
168
|
if (stepsTaken > 0) {
|
|
169
169
|
// Extract the latest brain.step to show what the agent is doing
|
|
170
170
|
const latestStep = (exec.nodeExecutions ?? [])
|
|
171
|
-
.filter(n => n.nodeType === 'brain.step' && n.outputData
|
|
171
|
+
.filter(n => n.nodeType === 'brain.step' && n.outputData)
|
|
172
172
|
.sort((a, b) => b.executionOrder - a.executionOrder)[0];
|
|
173
|
-
|
|
174
|
-
|
|
173
|
+
const d = latestStep?.outputData?.decision ?? latestStep?.outputData;
|
|
174
|
+
if (d) {
|
|
175
175
|
const action = d.actionType ?? d.action_type ?? 'working';
|
|
176
176
|
const intent = d.intent;
|
|
177
177
|
message = intent
|
|
@@ -199,12 +199,16 @@ export async function testPageChangesHandler(input, context, progressCallback) {
|
|
|
199
199
|
// --- Format result ---
|
|
200
200
|
const outcome = finalExecution.state?.outcome ?? finalExecution.status;
|
|
201
201
|
const nodes = finalExecution.nodeExecutions ?? [];
|
|
202
|
-
//
|
|
202
|
+
// subworkflow.run is the current graph shape — carries outcome, actionHistory, screenshot
|
|
203
|
+
const subworkflowNode = nodes.find(n => n.nodeType === 'subworkflow.run');
|
|
204
|
+
// surfer.execute_task and brain.step/brain.evaluate are older graph shapes
|
|
205
|
+
const surferNode = nodes.find(n => n.nodeType === 'surfer.execute_task');
|
|
206
|
+
// Action trace: brain.step nodes (old) → subworkflow.run actionHistory (new)
|
|
203
207
|
const brainSteps = nodes
|
|
204
|
-
.filter(n => n.nodeType === 'brain.step' && n.outputData
|
|
208
|
+
.filter(n => n.nodeType === 'brain.step' && n.outputData)
|
|
205
209
|
.sort((a, b) => a.executionOrder - b.executionOrder);
|
|
206
210
|
const actionTrace = brainSteps.map((n, i) => {
|
|
207
|
-
const d = n.outputData.decision;
|
|
211
|
+
const d = n.outputData.decision ?? n.outputData;
|
|
208
212
|
return {
|
|
209
213
|
step: i + 1,
|
|
210
214
|
action: d.actionType ?? d.action_type,
|
|
@@ -215,33 +219,52 @@ export async function testPageChangesHandler(input, context, progressCallback) {
|
|
|
215
219
|
durationMs: n.executionTimeMs,
|
|
216
220
|
};
|
|
217
221
|
});
|
|
218
|
-
|
|
222
|
+
const subworkflowHistory = subworkflowNode?.outputData?.actionHistory;
|
|
223
|
+
if (actionTrace.length === 0 && Array.isArray(subworkflowHistory) && subworkflowHistory.length > 0) {
|
|
224
|
+
subworkflowHistory.forEach((step, i) => {
|
|
225
|
+
actionTrace.push({
|
|
226
|
+
step: i + 1,
|
|
227
|
+
action: step.actionType ?? step.action_type ?? step.action,
|
|
228
|
+
intent: step.intent,
|
|
229
|
+
target: step.target,
|
|
230
|
+
value: step.value ?? undefined,
|
|
231
|
+
success: step.success ?? true,
|
|
232
|
+
durationMs: step.durationMs ?? step.duration_ms ?? undefined,
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
// Evaluation: brain.evaluate (old) → subworkflow.run outcome/success (new)
|
|
219
237
|
const evalNode = nodes.find(n => n.nodeType === 'brain.evaluate');
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
238
|
+
let evaluation;
|
|
239
|
+
if (evalNode?.outputData) {
|
|
240
|
+
evaluation = {
|
|
241
|
+
passed: evalNode.outputData.passed,
|
|
242
|
+
outcome: evalNode.outputData.outcome,
|
|
243
|
+
reason: evalNode.outputData.reason,
|
|
244
|
+
verifications: evalNode.outputData.verifications,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
else if (subworkflowNode?.outputData) {
|
|
248
|
+
const sw = subworkflowNode.outputData;
|
|
249
|
+
evaluation = {
|
|
250
|
+
passed: sw.success,
|
|
251
|
+
outcome: sw.outcome,
|
|
252
|
+
reason: sw.error || undefined,
|
|
253
|
+
};
|
|
254
|
+
}
|
|
228
255
|
const responsePayload = {
|
|
229
256
|
outcome,
|
|
230
|
-
success: finalExecution.state?.success ?? false,
|
|
257
|
+
success: finalExecution.state?.success ?? subworkflowNode?.outputData?.success ?? false,
|
|
231
258
|
status: finalExecution.status,
|
|
232
|
-
stepsTaken: finalExecution.state?.stepsTaken ?? actionTrace.length
|
|
259
|
+
stepsTaken: finalExecution.state?.stepsTaken ?? subworkflowNode?.outputData?.stepsTaken ?? actionTrace.length,
|
|
233
260
|
targetUrl: originalUrl,
|
|
234
261
|
executionId: executionUuid,
|
|
235
262
|
durationMs: finalExecution.durationMs ?? duration,
|
|
236
263
|
};
|
|
237
|
-
|
|
238
|
-
if (actionTrace.length > 0) {
|
|
264
|
+
if (actionTrace.length > 0)
|
|
239
265
|
responsePayload.actionTrace = actionTrace;
|
|
240
|
-
|
|
241
|
-
// The final evaluation — pass/fail with reasoning
|
|
242
|
-
if (evaluation) {
|
|
266
|
+
if (evaluation)
|
|
243
267
|
responsePayload.evaluation = evaluation;
|
|
244
|
-
}
|
|
245
268
|
if (finalExecution.state?.error)
|
|
246
269
|
responsePayload.agentError = finalExecution.state.error;
|
|
247
270
|
if (finalExecution.errorMessage)
|
|
@@ -262,15 +285,23 @@ export async function testPageChangesHandler(input, context, progressCallback) {
|
|
|
262
285
|
const content = [
|
|
263
286
|
{ type: 'text', text: JSON.stringify(responsePayload, null, 2) },
|
|
264
287
|
];
|
|
265
|
-
//
|
|
266
|
-
const
|
|
288
|
+
// Screenshot: check for already-base64 field first (subworkflow.run), then URL-based fields
|
|
289
|
+
const SCREENSHOT_URL_KEYS = ['finalScreenshot', 'screenshot', 'screenshotUrl', 'screenshotUri'];
|
|
267
290
|
const GIF_KEYS = ['runGif', 'gifUrl', 'gif', 'videoUrl', 'recordingUrl'];
|
|
268
|
-
let
|
|
291
|
+
let screenshotEmbedded = false;
|
|
269
292
|
let gifUrl = null;
|
|
270
|
-
|
|
293
|
+
// subworkflow.run carries screenshotB64 directly — no fetch needed
|
|
294
|
+
const screenshotB64 = subworkflowNode?.outputData?.screenshotB64;
|
|
295
|
+
if (typeof screenshotB64 === 'string' && screenshotB64) {
|
|
296
|
+
logger.info('Embedding inline base64 screenshot from subworkflow.run');
|
|
297
|
+
content.push(imageContentBlock(screenshotB64, 'image/png'));
|
|
298
|
+
screenshotEmbedded = true;
|
|
299
|
+
}
|
|
300
|
+
let screenshotUrl = null;
|
|
301
|
+
for (const node of nodes) {
|
|
271
302
|
const data = node.outputData ?? {};
|
|
272
|
-
if (!screenshotUrl) {
|
|
273
|
-
for (const key of
|
|
303
|
+
if (!screenshotEmbedded && !screenshotUrl) {
|
|
304
|
+
for (const key of SCREENSHOT_URL_KEYS) {
|
|
274
305
|
if (typeof data[key] === 'string' && data[key]) {
|
|
275
306
|
screenshotUrl = data[key];
|
|
276
307
|
break;
|
|
@@ -285,10 +316,10 @@ export async function testPageChangesHandler(input, context, progressCallback) {
|
|
|
285
316
|
}
|
|
286
317
|
}
|
|
287
318
|
}
|
|
288
|
-
if (screenshotUrl && gifUrl)
|
|
319
|
+
if ((screenshotEmbedded || screenshotUrl) && gifUrl)
|
|
289
320
|
break;
|
|
290
321
|
}
|
|
291
|
-
if (screenshotUrl) {
|
|
322
|
+
if (!screenshotEmbedded && screenshotUrl) {
|
|
292
323
|
logger.info(`Embedding screenshot: ${screenshotUrl}`);
|
|
293
324
|
const img = await fetchImageAsBase64(screenshotUrl).catch(() => null);
|
|
294
325
|
if (img)
|