@windsland52/maa-log-tools 1.3.0 → 1.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/README.md +7 -1
- package/dist/runtimeInspection.js +125 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -87,7 +87,9 @@ process-start-bounded interval contains the timestamp; otherwise it returns `nul
|
|
|
87
87
|
`mla-runtime-inspection/v1`. It nests task executions under their runtime session and keeps three
|
|
88
88
|
different semantics separate:
|
|
89
89
|
|
|
90
|
-
- `failures`:
|
|
90
|
+
- `failures`: directly observed `next_list_timeout` and `action_failed` facts, including failures
|
|
91
|
+
inside tasks launched by custom actions. Nested failures retain the nested task identity and
|
|
92
|
+
images while sharing the enclosing top-level `executionId`.
|
|
91
93
|
- `outcomes`: failed or still-running pipeline nodes and tasks, with direct-failure references
|
|
92
94
|
when the propagation can be linked deterministically.
|
|
93
95
|
- `signals`: useful non-failure behavior such as recognition succeeding after earlier misses and
|
|
@@ -97,6 +99,10 @@ An unsuccessful recognition attempt is retry telemetry, not a failure. A next-li
|
|
|
97
99
|
reported only when the node finishes without matching a candidate. Repeated recognition attempts
|
|
98
100
|
inside one node are not treated as pipeline loops.
|
|
99
101
|
|
|
102
|
+
`RuntimeTaskExecution.directFailureIds` and its failure statistics remain limited to the
|
|
103
|
+
top-level task's own pipeline nodes. Nested task failures are available through `failures` and
|
|
104
|
+
`outcomes`, so a propagated parent action failure and its underlying nested failure stay distinct.
|
|
105
|
+
|
|
100
106
|
Tasks are assigned to a process-start session by timestamp. A file segment without a
|
|
101
107
|
`MAA Process Start` marker can also contain tasks when it is the only matching partial interval;
|
|
102
108
|
ambiguous tasks remain in `unscopedTasks` and produce a warning.
|
|
@@ -64,6 +64,39 @@ const imagesFor = (node) => {
|
|
|
64
64
|
vision: attempts.map(item => item.vision_image).filter((item) => Boolean(item)),
|
|
65
65
|
};
|
|
66
66
|
};
|
|
67
|
+
const ownedRecognitionItems = (items) => ((items ?? []).flatMap(item => {
|
|
68
|
+
if (item.type === 'task' || item.type === 'pipeline_node')
|
|
69
|
+
return [];
|
|
70
|
+
return [
|
|
71
|
+
...(item.type === 'recognition' || item.type === 'recognition_node' ? [item] : []),
|
|
72
|
+
...ownedRecognitionItems(item.children),
|
|
73
|
+
];
|
|
74
|
+
}));
|
|
75
|
+
const imagesForFlowItem = (item) => {
|
|
76
|
+
const attempts = ownedRecognitionItems(item.children);
|
|
77
|
+
return {
|
|
78
|
+
error: [item.error_image, ...attempts.map(attempt => attempt.error_image)]
|
|
79
|
+
.filter((image) => Boolean(image)),
|
|
80
|
+
vision: [item.vision_image, ...attempts.map(attempt => attempt.vision_image)]
|
|
81
|
+
.filter((image) => Boolean(image)),
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
const hasFailedOwnedAction = (items) => ((items ?? []).some(item => {
|
|
85
|
+
if (item.type === 'task' || item.type === 'pipeline_node')
|
|
86
|
+
return false;
|
|
87
|
+
if ((item.type === 'action' || item.type === 'action_node')
|
|
88
|
+
&& (item.status === 'failed' || item.action_details?.success === false))
|
|
89
|
+
return true;
|
|
90
|
+
return hasFailedOwnedAction(item.children);
|
|
91
|
+
}));
|
|
92
|
+
const hasFailedNestedTask = (items) => ((items ?? []).some(item => (item.type === 'task' ? item.status === 'failed' : hasFailedNestedTask(item.children))));
|
|
93
|
+
const nestedPipelineFailureKind = (item) => {
|
|
94
|
+
if (item.status !== 'failed')
|
|
95
|
+
return null;
|
|
96
|
+
if (item.action_details?.success === false || hasFailedOwnedAction(item.children))
|
|
97
|
+
return 'action_failed';
|
|
98
|
+
return hasFailedNestedTask(item.children) ? null : 'next_list_timeout';
|
|
99
|
+
};
|
|
67
100
|
const scopeFor = (task, sessionId, executionId) => ({
|
|
68
101
|
sessionId,
|
|
69
102
|
executionId,
|
|
@@ -215,7 +248,99 @@ export const buildRuntimeInspection = (output, framework, sourceSegments) => {
|
|
|
215
248
|
const recognitionOccurrences = [];
|
|
216
249
|
const evidenceIndex = buildEvidenceIndex(task);
|
|
217
250
|
const timeline = buildNodeExecutionTimeline(task.nodes, { rootTaskId: task.task_id });
|
|
251
|
+
const seenNestedTasks = new Set();
|
|
252
|
+
const seenNestedPipelines = new Set();
|
|
253
|
+
const inspectNestedTask = (taskItem) => {
|
|
254
|
+
if (seenNestedTasks.has(taskItem.id))
|
|
255
|
+
return;
|
|
256
|
+
seenNestedTasks.add(taskItem.id);
|
|
257
|
+
const taskId = taskItem.task_details?.task_id ?? taskItem.task_id;
|
|
258
|
+
if (taskId == null) {
|
|
259
|
+
inspectNestedTasks(taskItem.children);
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
const nestedScope = {
|
|
263
|
+
sessionId,
|
|
264
|
+
executionId,
|
|
265
|
+
taskId,
|
|
266
|
+
taskName: taskItem.task_details?.entry ?? taskItem.name,
|
|
267
|
+
};
|
|
268
|
+
const nestedDirectFailureIds = [];
|
|
269
|
+
const inspectOwnedItems = (items) => {
|
|
270
|
+
for (const child of items ?? []) {
|
|
271
|
+
if (child.type === 'task') {
|
|
272
|
+
inspectNestedTask(child);
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
if (child.type !== 'pipeline_node') {
|
|
276
|
+
inspectOwnedItems(child.children);
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
if (seenNestedPipelines.has(child.id))
|
|
280
|
+
continue;
|
|
281
|
+
seenNestedPipelines.add(child.id);
|
|
282
|
+
inspectOwnedItems(child.children);
|
|
283
|
+
const failureKind = nestedPipelineFailureKind(child);
|
|
284
|
+
let nodeFailureId = null;
|
|
285
|
+
if (failureKind && child.node_id != null) {
|
|
286
|
+
nodeFailureId = `failure-${failures.length + 1}`;
|
|
287
|
+
const images = imagesForFlowItem(child);
|
|
288
|
+
failures.push({
|
|
289
|
+
...nestedScope,
|
|
290
|
+
failureId: nodeFailureId,
|
|
291
|
+
kind: failureKind,
|
|
292
|
+
nodeId: child.node_id,
|
|
293
|
+
nodeName: child.name,
|
|
294
|
+
startedAt: child.ts,
|
|
295
|
+
endedAt: child.end_ts ?? null,
|
|
296
|
+
errorImages: [...new Set(images.error)],
|
|
297
|
+
visionImages: [...new Set(images.vision)],
|
|
298
|
+
evidence: evidenceAt(evidenceIndex, child.end_ts ?? child.ts),
|
|
299
|
+
});
|
|
300
|
+
nestedDirectFailureIds.push(nodeFailureId);
|
|
301
|
+
}
|
|
302
|
+
if (child.status !== 'success') {
|
|
303
|
+
const outcomeId = `outcome-${outcomes.length + 1}`;
|
|
304
|
+
outcomes.push({
|
|
305
|
+
...nestedScope,
|
|
306
|
+
outcomeId,
|
|
307
|
+
kind: 'pipeline_node',
|
|
308
|
+
status: child.status,
|
|
309
|
+
nodeId: child.node_id ?? null,
|
|
310
|
+
nodeName: child.name,
|
|
311
|
+
directFailureIds: nodeFailureId ? [nodeFailureId] : [],
|
|
312
|
+
evidence: evidenceAt(evidenceIndex, child.end_ts ?? child.ts),
|
|
313
|
+
});
|
|
314
|
+
outcomeIds.push(outcomeId);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
inspectOwnedItems(taskItem.children);
|
|
319
|
+
if (taskItem.status !== 'success') {
|
|
320
|
+
const outcomeId = `outcome-${outcomes.length + 1}`;
|
|
321
|
+
outcomes.push({
|
|
322
|
+
...nestedScope,
|
|
323
|
+
outcomeId,
|
|
324
|
+
kind: 'task',
|
|
325
|
+
status: taskItem.status,
|
|
326
|
+
nodeId: null,
|
|
327
|
+
nodeName: null,
|
|
328
|
+
directFailureIds: nestedDirectFailureIds,
|
|
329
|
+
evidence: evidenceAt(evidenceIndex, taskItem.end_ts ?? taskItem.ts),
|
|
330
|
+
});
|
|
331
|
+
outcomeIds.push(outcomeId);
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
const inspectNestedTasks = (items) => {
|
|
335
|
+
for (const item of items ?? []) {
|
|
336
|
+
if (item.type === 'task')
|
|
337
|
+
inspectNestedTask(item);
|
|
338
|
+
else
|
|
339
|
+
inspectNestedTasks(item.children);
|
|
340
|
+
}
|
|
341
|
+
};
|
|
218
342
|
for (const item of timeline) {
|
|
343
|
+
inspectNestedTasks(item.nodeInfo.node_flow);
|
|
219
344
|
const failureKind = item.navStatus === 'action-failed'
|
|
220
345
|
? 'action_failed'
|
|
221
346
|
: item.navStatus === 'timeout' && item.nodeInfo.next_list.length > 0
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@windsland52/maa-log-tools",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
6
|
"bin": {
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"fflate": "^0.8.2",
|
|
45
|
-
"@windsland52/maa-log-adapter": "1.1.0",
|
|
46
45
|
"@windsland52/maa-log-parser": "1.1.0",
|
|
47
46
|
"@windsland52/maa-log-kernel": "1.0.2",
|
|
47
|
+
"@windsland52/maa-log-adapter": "1.1.0",
|
|
48
48
|
"@windsland52/maa-log-runtime": "1.1.0"
|
|
49
49
|
},
|
|
50
50
|
"engines": {
|