@pasko70/pibo 3.6.1 → 3.6.3
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/agent-runtime/auth-contract.js +215 -0
- package/dist/agent-runtime/registry.js +1 -214
- package/dist/agent-runtime/routed-session.js +7 -0
- package/dist/agent-runtimes/codex-native/turn.js +2 -2
- package/dist/agent-runtimes/pi/auth.js +1 -0
- package/dist/agent-runtimes/pi/model-catalog.js +2 -0
- package/dist/agent-runtimes/pi/runtime.js +2 -0
- package/dist/apps/chat/trace-v2.js +1 -0
- package/dist/apps/chat/web-app.js +1 -0
- package/dist/apps/chat-ui/assets/{dist-YQ6IdwhV.js → dist-BHiMQOG6.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-CCgwGNBo.js → dist-BfNGI8zD.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-DFtTPSEB.js → dist-Cf5vD7GX.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-XSlRIuRd.js → dist-Ds-8WrKd.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-mpK-CrNR.js → dist-iE0b01WP.js} +1 -1
- package/dist/apps/chat-ui/assets/{index-B0BS_H88.js → index-BWhdVZpM.js} +87 -87
- package/dist/apps/chat-ui/assets/{index-DRaSMxCz.css → index-VZBlQTo5.css} +1 -1
- package/dist/apps/chat-ui/index.html +2 -2
- package/dist/apps/chat-vscode-web/assets/{index-CxKxukk_.js → index-CtaeZkpG.js} +6 -6
- package/dist/apps/chat-vscode-web/index.html +1 -1
- package/dist/apps/cli-ui/inkColors.js +1 -0
- package/dist/core/session-router.js +112 -3
- package/dist/data/chat-read-projections.js +46 -33
- package/dist/mcp/config.js +13 -48
- package/dist/providers/meta-muse.js +40 -0
- package/dist/runs/resource-isolation.js +3 -125
- package/dist/runs/windows-process-tree.js +132 -0
- package/dist/session-ui/terminalRows.js +106 -12
- package/dist/shared/trace-engine.js +2 -1
- package/dist/shared/trace-event-projection.js +80 -0
- package/dist/shared/trace-patch-nodes.js +14 -0
- package/dist/subagents/context.js +9 -3
- package/dist/subagents/observations.js +1 -1
- package/dist/subagents/tool.js +14 -6
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/packages/workflows/dist/runtime/adapter-node.d.ts.map +1 -1
- package/packages/workflows/dist/runtime/adapter-node.js +1 -13
- package/packages/workflows/dist/runtime/adapter-node.js.map +1 -1
- package/packages/workflows/dist/runtime/dispatch-failures.d.ts +1 -0
- package/packages/workflows/dist/runtime/dispatch-failures.d.ts.map +1 -1
- package/packages/workflows/dist/runtime/dispatch-failures.js +12 -0
- package/packages/workflows/dist/runtime/dispatch-failures.js.map +1 -1
- package/packages/workflows/dist/runtime/edge-transfer.d.ts.map +1 -1
- package/packages/workflows/dist/runtime/edge-transfer.js +1 -12
- package/packages/workflows/dist/runtime/edge-transfer.js.map +1 -1
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { existsSync, readFileSync, unlinkSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { promisify } from "node:util";
|
|
5
|
+
const execFileAsync = promisify(execFile);
|
|
6
|
+
export function windowsProcessTreeCommand(command, pidPath) {
|
|
7
|
+
const portablePidPath = pidPath.replaceAll("\\", "/");
|
|
8
|
+
return [
|
|
9
|
+
"__pibo_win_pid=\"$(ps -W | awk -v p=$$ 'NR > 1 && $1 == p { print $4; exit }')\"",
|
|
10
|
+
"if [ -z \"$__pibo_win_pid\" ]; then printf '%s\\n' 'Pibo could not identify the Windows Bash process.' >&2; exit 125; fi",
|
|
11
|
+
`printf '%s %s' "$$" "$__pibo_win_pid" > ${bashSingleQuote(portablePidPath)}`,
|
|
12
|
+
"unset __pibo_win_pid",
|
|
13
|
+
command,
|
|
14
|
+
].join("\n");
|
|
15
|
+
}
|
|
16
|
+
export async function terminateWindowsProcessTree(pidPath) {
|
|
17
|
+
const identity = await waitForWindowsProcessIdentity(pidPath);
|
|
18
|
+
if (!identity)
|
|
19
|
+
return;
|
|
20
|
+
try {
|
|
21
|
+
const rows = await listWindowsProcessTree(identity.msysPid);
|
|
22
|
+
for (const row of rows) {
|
|
23
|
+
try {
|
|
24
|
+
process.kill(row.windowsPid, "SIGKILL");
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// The process may have exited between the snapshot and termination.
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
for (let attempt = 0; attempt < 100 && processIsAlive(identity.windowsPid); attempt += 1) {
|
|
31
|
+
await new Promise((resolveWait) => setTimeout(resolveWait, 25));
|
|
32
|
+
}
|
|
33
|
+
if (processIsAlive(identity.windowsPid)) {
|
|
34
|
+
throw new Error(`Windows yielded-run process tree rooted at PID ${identity.windowsPid} is still active after termination.`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
finally {
|
|
38
|
+
removeWindowsProcessIdentity(pidPath);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async function waitForWindowsProcessIdentity(pidPath) {
|
|
42
|
+
for (let attempt = 0; attempt < 80; attempt += 1) {
|
|
43
|
+
try {
|
|
44
|
+
const match = readFileSync(pidPath, "utf8").trim().match(/^([1-9]\d*)\s+([1-9]\d*)$/);
|
|
45
|
+
if (match)
|
|
46
|
+
return { msysPid: Number(match[1]), windowsPid: Number(match[2]) };
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// The Bash wrapper may still be starting.
|
|
50
|
+
}
|
|
51
|
+
await new Promise((resolveWait) => setTimeout(resolveWait, 25));
|
|
52
|
+
}
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
async function listWindowsProcessTree(rootMsysPid) {
|
|
56
|
+
const { stdout } = await execFileAsync(windowsBashExecutable(), ["-lc", "ps -W"], {
|
|
57
|
+
encoding: "utf8",
|
|
58
|
+
timeout: 5_000,
|
|
59
|
+
windowsHide: true,
|
|
60
|
+
});
|
|
61
|
+
return parseWindowsProcessTreeSnapshot(stdout, rootMsysPid);
|
|
62
|
+
}
|
|
63
|
+
export function parseWindowsProcessTreeSnapshot(stdout, rootMsysPid) {
|
|
64
|
+
const rows = stdout.split(/\r?\n/).flatMap((line) => {
|
|
65
|
+
const fields = line.trim().split(/\s+/);
|
|
66
|
+
if (fields.length < 4 || !fields.slice(0, 4).every((field) => /^\d+$/.test(field)))
|
|
67
|
+
return [];
|
|
68
|
+
return [{
|
|
69
|
+
msysPid: Number(fields[0]),
|
|
70
|
+
parentMsysPid: Number(fields[1]),
|
|
71
|
+
processGroupId: Number(fields[2]),
|
|
72
|
+
windowsPid: Number(fields[3]),
|
|
73
|
+
}];
|
|
74
|
+
});
|
|
75
|
+
const selected = new Set([rootMsysPid]);
|
|
76
|
+
for (let changed = true; changed;) {
|
|
77
|
+
changed = false;
|
|
78
|
+
for (const row of rows) {
|
|
79
|
+
if (selected.has(row.msysPid))
|
|
80
|
+
continue;
|
|
81
|
+
if (row.processGroupId === rootMsysPid || selected.has(row.parentMsysPid)) {
|
|
82
|
+
selected.add(row.msysPid);
|
|
83
|
+
changed = true;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const byPid = new Map(rows.map((row) => [row.msysPid, row]));
|
|
88
|
+
return rows
|
|
89
|
+
.filter((row) => selected.has(row.msysPid) && row.windowsPid > 0)
|
|
90
|
+
.sort((left, right) => processTreeDepth(right, byPid) - processTreeDepth(left, byPid));
|
|
91
|
+
}
|
|
92
|
+
function processTreeDepth(row, byPid) {
|
|
93
|
+
let depth = 0;
|
|
94
|
+
let current = row;
|
|
95
|
+
const seen = new Set();
|
|
96
|
+
while (!seen.has(current.msysPid)) {
|
|
97
|
+
seen.add(current.msysPid);
|
|
98
|
+
const parent = byPid.get(current.parentMsysPid);
|
|
99
|
+
if (!parent)
|
|
100
|
+
break;
|
|
101
|
+
depth += 1;
|
|
102
|
+
current = parent;
|
|
103
|
+
}
|
|
104
|
+
return depth;
|
|
105
|
+
}
|
|
106
|
+
function windowsBashExecutable() {
|
|
107
|
+
const candidates = [
|
|
108
|
+
process.env.ProgramFiles ? join(process.env.ProgramFiles, "Git", "bin", "bash.exe") : undefined,
|
|
109
|
+
process.env["ProgramFiles(x86)"] ? join(process.env["ProgramFiles(x86)"], "Git", "bin", "bash.exe") : undefined,
|
|
110
|
+
].filter((candidate) => Boolean(candidate));
|
|
111
|
+
return candidates.find((candidate) => existsSync(candidate)) ?? "bash.exe";
|
|
112
|
+
}
|
|
113
|
+
function processIsAlive(pid) {
|
|
114
|
+
try {
|
|
115
|
+
process.kill(pid, 0);
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
export function removeWindowsProcessIdentity(path) {
|
|
123
|
+
try {
|
|
124
|
+
unlinkSync(path);
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
// Best-effort transient process metadata cleanup.
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function bashSingleQuote(value) {
|
|
131
|
+
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
132
|
+
}
|
|
@@ -23,14 +23,18 @@ export function buildCompactTerminalRows(traceView, options) {
|
|
|
23
23
|
const candidates = syncThinkingToolRows(flatNodes.map((item) => createRowCandidate(item.node, item.turnId)));
|
|
24
24
|
applyCompletedTurnTiming(candidates, turnById);
|
|
25
25
|
const reconciled = reconcileConceptualRowCandidates(candidates);
|
|
26
|
-
const toolDisplayMode = options.toolDisplayMode ?? "
|
|
27
|
-
const rows = toolDisplayMode === "
|
|
28
|
-
? groupRelatedToolCandidates(reconciled, showToolDebugMetrics
|
|
29
|
-
:
|
|
26
|
+
const toolDisplayMode = options.toolDisplayMode ?? "full";
|
|
27
|
+
const rows = toolDisplayMode === "full"
|
|
28
|
+
? groupRelatedToolCandidates(reconciled, showToolDebugMetrics).map((candidate) => candidate.row)
|
|
29
|
+
: toolDisplayMode === "default"
|
|
30
|
+
? groupConsecutiveToolCandidates(reconciled).map((candidate) => candidate.row)
|
|
31
|
+
: toolDisplayMode === "slim"
|
|
32
|
+
? groupRelatedToolCandidates(reconciled, true).map((candidate) => candidate.row)
|
|
33
|
+
: reconciled.map((candidate) => candidate.row);
|
|
30
34
|
return applyToolDisplayMode(rows, toolDisplayMode);
|
|
31
35
|
}
|
|
32
36
|
function applyToolDisplayMode(rows, mode) {
|
|
33
|
-
if (mode === "default")
|
|
37
|
+
if (mode === "default" || mode === "full")
|
|
34
38
|
return rows;
|
|
35
39
|
if (mode === "hide")
|
|
36
40
|
return rows.filter((row) => !isToolDisplayRow(row));
|
|
@@ -40,11 +44,7 @@ function applyToolDisplayMode(rows, mode) {
|
|
|
40
44
|
const intent = row.intent?.trim();
|
|
41
45
|
if (mode === "intent" && !intent)
|
|
42
46
|
return [];
|
|
43
|
-
const slimRow =
|
|
44
|
-
...row,
|
|
45
|
-
lines: row.lines.slice(0, 1),
|
|
46
|
-
singleLine: true,
|
|
47
|
-
};
|
|
47
|
+
const slimRow = compactToolDisplayRow(row);
|
|
48
48
|
if (mode !== "intent")
|
|
49
49
|
return [slimRow];
|
|
50
50
|
return [{
|
|
@@ -65,11 +65,19 @@ function applyToolDisplayMode(rows, mode) {
|
|
|
65
65
|
}];
|
|
66
66
|
});
|
|
67
67
|
}
|
|
68
|
+
function compactToolDisplayRow(row) {
|
|
69
|
+
return {
|
|
70
|
+
...row,
|
|
71
|
+
lines: row.lines.slice(0, 1),
|
|
72
|
+
singleLine: true,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
68
75
|
function isToolDisplayRow(row) {
|
|
69
76
|
return row.sourceNodeIds.some((nodeId) => parseTraceToolNodeIdentity(nodeId) !== undefined)
|
|
70
77
|
|| row.id.startsWith("terminal:tool:")
|
|
71
78
|
|| row.kind === "tool.call"
|
|
72
79
|
|| row.kind === "tool.image"
|
|
80
|
+
|| row.kind === "tool.group.calls"
|
|
73
81
|
|| row.kind === "tool.group.exploring"
|
|
74
82
|
|| row.kind === "tool.group.images"
|
|
75
83
|
|| row.kind === "agent.delegation";
|
|
@@ -387,6 +395,16 @@ function debugFields(node) {
|
|
|
387
395
|
}
|
|
388
396
|
function createUserMessageRow(node) {
|
|
389
397
|
const text = stringValue(node.output) || stringValue(node.summary) || node.title;
|
|
398
|
+
const imagePreviews = node.fileAttachments?.flatMap((attachment, index) => {
|
|
399
|
+
if (!isImageFileAttachment(attachment.path, attachment.contentType))
|
|
400
|
+
return [];
|
|
401
|
+
return [{
|
|
402
|
+
id: `${node.id}:attachment:${index}`,
|
|
403
|
+
label: attachment.name,
|
|
404
|
+
path: attachment.path,
|
|
405
|
+
mimeType: attachment.contentType,
|
|
406
|
+
}];
|
|
407
|
+
});
|
|
390
408
|
return {
|
|
391
409
|
id: node.id,
|
|
392
410
|
kind: "message.user",
|
|
@@ -399,8 +417,13 @@ function createUserMessageRow(node) {
|
|
|
399
417
|
startedAt: node.startedAt,
|
|
400
418
|
output: text,
|
|
401
419
|
payloadRefs: node.payloadRefs,
|
|
420
|
+
imagePreviews: imagePreviews?.length ? imagePreviews : undefined,
|
|
402
421
|
};
|
|
403
422
|
}
|
|
423
|
+
function isImageFileAttachment(path, contentType) {
|
|
424
|
+
return contentType?.toLowerCase().startsWith("image/") === true
|
|
425
|
+
|| /\.(?:avif|bmp|gif|jpe?g|png|svg|webp)$/i.test(path);
|
|
426
|
+
}
|
|
404
427
|
function createAssistantMessageRow(node) {
|
|
405
428
|
return {
|
|
406
429
|
id: node.id,
|
|
@@ -548,7 +571,7 @@ function createImageToolRow(node, image) {
|
|
|
548
571
|
lines: [
|
|
549
572
|
{
|
|
550
573
|
prefix: "bullet",
|
|
551
|
-
tokens: [token(image.verb, toneForStatus(node.status), "semibold")],
|
|
574
|
+
tokens: [token(image.verb, node.status === "done" ? "purple" : toneForStatus(node.status), "semibold")],
|
|
552
575
|
},
|
|
553
576
|
{
|
|
554
577
|
prefix: "detail",
|
|
@@ -943,6 +966,77 @@ function isThinkingOutput(value) {
|
|
|
943
966
|
function isThinkingLevelSetOutput(value) {
|
|
944
967
|
return isRecord(value) && value.action === "set_thinking_level";
|
|
945
968
|
}
|
|
969
|
+
function groupConsecutiveToolCandidates(candidates) {
|
|
970
|
+
const grouped = [];
|
|
971
|
+
for (let index = 0; index < candidates.length; index += 1) {
|
|
972
|
+
const candidate = candidates[index];
|
|
973
|
+
const groupKind = defaultToolGroupKind(candidate);
|
|
974
|
+
if (!groupKind) {
|
|
975
|
+
grouped.push(candidate);
|
|
976
|
+
continue;
|
|
977
|
+
}
|
|
978
|
+
const run = [candidate];
|
|
979
|
+
let cursor = index + 1;
|
|
980
|
+
while (cursor < candidates.length && defaultToolGroupKind(candidates[cursor]) === groupKind && candidates[cursor].turnId === candidate.turnId) {
|
|
981
|
+
run.push(candidates[cursor]);
|
|
982
|
+
cursor += 1;
|
|
983
|
+
}
|
|
984
|
+
if (groupKind === "images") {
|
|
985
|
+
grouped.push(run.length === 1 ? candidate : { row: createImageGroup(run), turnId: candidate.turnId });
|
|
986
|
+
}
|
|
987
|
+
else if (run.length === 1) {
|
|
988
|
+
grouped.push({ ...candidate, row: compactToolDisplayRow(candidate.row) });
|
|
989
|
+
}
|
|
990
|
+
else {
|
|
991
|
+
grouped.push({ row: createToolCallGroup(run), turnId: candidate.turnId });
|
|
992
|
+
}
|
|
993
|
+
index = cursor - 1;
|
|
994
|
+
}
|
|
995
|
+
return grouped;
|
|
996
|
+
}
|
|
997
|
+
function defaultToolGroupKind(candidate) {
|
|
998
|
+
if (candidate.image)
|
|
999
|
+
return "images";
|
|
1000
|
+
if (candidate.row.kind === "tool.image" || candidate.row.kind === "tool.group.images")
|
|
1001
|
+
return undefined;
|
|
1002
|
+
return isBundledToolDisplayRow(candidate.row) ? "calls" : undefined;
|
|
1003
|
+
}
|
|
1004
|
+
function isBundledToolDisplayRow(row) {
|
|
1005
|
+
return isToolDisplayRow(row) && row.kind !== "agent.delegation";
|
|
1006
|
+
}
|
|
1007
|
+
function createToolCallGroup(candidates) {
|
|
1008
|
+
const groupRows = candidates.map((candidate) => compactToolDisplayRow(candidate.row));
|
|
1009
|
+
const firstRow = groupRows[0];
|
|
1010
|
+
const latestRow = groupRows[groupRows.length - 1];
|
|
1011
|
+
const hasError = groupRows.some((row) => row.status === "error");
|
|
1012
|
+
const status = groupRows.some((row) => row.status === "running")
|
|
1013
|
+
? "running"
|
|
1014
|
+
: hasError
|
|
1015
|
+
? "error"
|
|
1016
|
+
: "done";
|
|
1017
|
+
return {
|
|
1018
|
+
id: `group:tools:${firstRow.id}`,
|
|
1019
|
+
kind: "tool.group.calls",
|
|
1020
|
+
status,
|
|
1021
|
+
errorKind: hasError ? "tool" : undefined,
|
|
1022
|
+
lines: latestRow.lines.slice(0, 1),
|
|
1023
|
+
sourceNodeIds: groupRows.flatMap((row) => row.sourceNodeIds),
|
|
1024
|
+
isToolCall: true,
|
|
1025
|
+
toolMetrics: latestRow.toolMetrics,
|
|
1026
|
+
modelInferences: latestRow.modelInferences,
|
|
1027
|
+
title: latestRow.title,
|
|
1028
|
+
eventId: latestRow.eventId,
|
|
1029
|
+
runId: latestRow.runId,
|
|
1030
|
+
orderSource: firstRow.orderSource,
|
|
1031
|
+
orderStreamId: firstRow.orderStreamId,
|
|
1032
|
+
orderStreamFrameIndex: firstRow.orderStreamFrameIndex,
|
|
1033
|
+
startedAt: firstRow.startedAt,
|
|
1034
|
+
completedAt: latestRow.completedAt,
|
|
1035
|
+
expandable: true,
|
|
1036
|
+
singleLine: true,
|
|
1037
|
+
groupRows,
|
|
1038
|
+
};
|
|
1039
|
+
}
|
|
946
1040
|
function groupRelatedToolCandidates(candidates, imagesOnly = false) {
|
|
947
1041
|
const grouped = [];
|
|
948
1042
|
for (let index = 0; index < candidates.length; index += 1) {
|
|
@@ -1042,7 +1136,7 @@ function createImageGroup(candidates) {
|
|
|
1042
1136
|
lines: [
|
|
1043
1137
|
{
|
|
1044
1138
|
prefix: "bullet",
|
|
1045
|
-
tokens: [token(status === "running" ? `Viewing ${detailItems.length} images` : status === "error" ? `${detailItems.length} image reads · error` : `${detailItems.length} Viewed ${detailItems.length === 1 ? "Image" : "Images"}`, toneForStatus(status), "semibold")],
|
|
1139
|
+
tokens: [token(status === "running" ? `Viewing ${detailItems.length} images` : status === "error" ? `${detailItems.length} image reads · error` : `${detailItems.length} Viewed ${detailItems.length === 1 ? "Image" : "Images"}`, status === "done" ? "purple" : toneForStatus(status), "semibold")],
|
|
1046
1140
|
},
|
|
1047
1141
|
...visibleDetailItems.map((item, index) => ({
|
|
1048
1142
|
prefix: index === 0 ? "detail" : "continuation",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { reconcileAsyncAgentRunStatuses } from "./trace-async-agent-runs.js";
|
|
2
|
-
import { applySingleEventToNodes, dedupeTraceEvents, findOpenTranscriptEventIds, latestTraceStreamId, markIncompletePersistedTurns, mergeMessageTurnTimings, messageTurnTimingsFromEvents, reconcileTranscriptUserMessages, } from "./trace-event-projection.js";
|
|
2
|
+
import { applySingleEventToNodes, dedupeTraceEvents, findOpenTranscriptEventIds, latestTraceStreamId, markIncompletePersistedTurns, mergeMessageTurnTimings, messageTurnTimingsFromEvents, reconcileAcceptedUserMessageMetadata, reconcileTranscriptUserMessages, } from "./trace-event-projection.js";
|
|
3
3
|
import { flattenTraceNodes, mapTraceNodesById, nestTraceNodes } from "./trace-nodes.js";
|
|
4
4
|
import { mapTraceChildSessionsByParent, mapTraceSubagentSessionLinks, } from "./trace-subagent-links.js";
|
|
5
5
|
import { projectHistoryEntries, traceNodesFromHistoryEntries } from "./trace-history.js";
|
|
@@ -43,6 +43,7 @@ export function buildTraceViewFromEvents(input) {
|
|
|
43
43
|
for (const storedEvent of events) {
|
|
44
44
|
applySingleEventToNodes(nodes, byId, input.session.id, storedEvent, childByParent, linkedChildByToolCallId, historyCoverage, openHistoryEventIds, sessionStatus);
|
|
45
45
|
}
|
|
46
|
+
reconcileAcceptedUserMessageMetadata(nodes, events);
|
|
46
47
|
const hasIncompleteTurns = markIncompletePersistedTurns(nodes, byId, input.session.id, events, turnTimings, sessionStatus);
|
|
47
48
|
const nestedNodes = nestTraceNodes(nodes);
|
|
48
49
|
reconcileAsyncAgentRunStatuses(nestedNodes);
|
|
@@ -7,6 +7,8 @@ import { qualifiedToolNodeId } from "./trace-tool-identity.js";
|
|
|
7
7
|
import { observeCacheUsage } from "./cache-observability.js";
|
|
8
8
|
import { compareInferenceCompletion } from "./model-inference-metrics.js";
|
|
9
9
|
export function applySingleEventToNodes(nodes, byId, piboSessionId, storedEvent, childByParent, linkedChildByToolCallId, historyCoverage, openTranscriptEventIds, sessionStatus) {
|
|
10
|
+
if (applyAcceptedUserMessageMetadata(nodes, storedEvent))
|
|
11
|
+
return;
|
|
10
12
|
const payload = storedEvent.payload;
|
|
11
13
|
if (payload.type === "assistant_usage") {
|
|
12
14
|
attachModelInferenceToLatestOutput(nodes, byId, payload, storedEvent);
|
|
@@ -127,6 +129,7 @@ export function applySingleEventToNodes(nodes, byId, piboSessionId, storedEvent,
|
|
|
127
129
|
if (node.type === "user.message") {
|
|
128
130
|
existing.status = node.status;
|
|
129
131
|
existing.parentId = node.parentId ?? existing.parentId;
|
|
132
|
+
existing.fileAttachments = node.fileAttachments ?? existing.fileAttachments;
|
|
130
133
|
existing.summary = node.summary ?? existing.summary;
|
|
131
134
|
existing.output = node.output ?? existing.output;
|
|
132
135
|
}
|
|
@@ -498,6 +501,82 @@ function normalizedUserMessageText(value) {
|
|
|
498
501
|
const normalized = value?.replace(/\s+/g, " ").trim();
|
|
499
502
|
return normalized || undefined;
|
|
500
503
|
}
|
|
504
|
+
export function reconcileAcceptedUserMessageMetadata(nodes, events) {
|
|
505
|
+
for (const event of events)
|
|
506
|
+
applyAcceptedUserMessageMetadata(nodes, event);
|
|
507
|
+
}
|
|
508
|
+
function applyAcceptedUserMessageMetadata(nodes, storedEvent) {
|
|
509
|
+
const payload = storedEvent.payload;
|
|
510
|
+
if (!isRecord(payload) || payload.type !== "user.message.accepted")
|
|
511
|
+
return false;
|
|
512
|
+
const clientTxnId = typeof payload.clientTxnId === "string" ? payload.clientTxnId : undefined;
|
|
513
|
+
if (!clientTxnId)
|
|
514
|
+
return true;
|
|
515
|
+
const attachments = normalizeTraceFileAttachments(payload.fileAttachments, payload.fileAttachmentPaths);
|
|
516
|
+
if (!attachments.length)
|
|
517
|
+
return true;
|
|
518
|
+
const delivery = payload.delivery === "steer" ? "message_steered" : "message_queued";
|
|
519
|
+
const canonicalId = `event:${delivery}:${clientTxnId}`;
|
|
520
|
+
const target = flattenTraceNodes([...nodes]).find((node) => node.type === "user.message"
|
|
521
|
+
&& (node.id === canonicalId || node.stableKey === canonicalId || node.eventId === clientTxnId));
|
|
522
|
+
if (target) {
|
|
523
|
+
target.fileAttachments = attachments;
|
|
524
|
+
const displayText = acceptedUserMessageDisplayText(payload);
|
|
525
|
+
if (displayText) {
|
|
526
|
+
target.summary = displayText;
|
|
527
|
+
target.output = displayText;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
return true;
|
|
531
|
+
}
|
|
532
|
+
function acceptedUserMessageDisplayText(payload) {
|
|
533
|
+
if (typeof payload.userText === "string" && payload.userText.trim())
|
|
534
|
+
return payload.userText;
|
|
535
|
+
if (typeof payload.text !== "string")
|
|
536
|
+
return undefined;
|
|
537
|
+
let text = payload.text;
|
|
538
|
+
for (const key of ["fileAttachmentContext", "webAnnotationContext"]) {
|
|
539
|
+
const context = typeof payload[key] === "string" ? payload[key] : undefined;
|
|
540
|
+
if (!context || !text.trimEnd().endsWith(context))
|
|
541
|
+
continue;
|
|
542
|
+
text = text.trimEnd().slice(0, -context.length).trimEnd();
|
|
543
|
+
}
|
|
544
|
+
return text.trim() || undefined;
|
|
545
|
+
}
|
|
546
|
+
function traceFileAttachmentsFromMessageEvent(event) {
|
|
547
|
+
const record = event;
|
|
548
|
+
const attachments = normalizeTraceFileAttachments(record.fileAttachments, record.fileAttachmentPaths);
|
|
549
|
+
return attachments.length ? attachments : undefined;
|
|
550
|
+
}
|
|
551
|
+
function normalizeTraceFileAttachments(attachmentsValue, pathsValue) {
|
|
552
|
+
const attachments = Array.isArray(attachmentsValue) ? attachmentsValue.flatMap((value) => {
|
|
553
|
+
if (!isRecord(value) || typeof value.path !== "string" || !value.path.trim())
|
|
554
|
+
return [];
|
|
555
|
+
const path = value.path.trim();
|
|
556
|
+
return [{
|
|
557
|
+
path,
|
|
558
|
+
name: typeof value.name === "string" && value.name.trim() ? value.name.trim() : traceAttachmentName(path),
|
|
559
|
+
...(typeof value.bytes === "number" && Number.isFinite(value.bytes) && value.bytes >= 0 ? { bytes: value.bytes } : {}),
|
|
560
|
+
...(typeof value.contentType === "string" && value.contentType.trim() ? { contentType: value.contentType.trim() } : {}),
|
|
561
|
+
}];
|
|
562
|
+
}) : [];
|
|
563
|
+
if (attachments.length)
|
|
564
|
+
return attachments.slice(0, 10);
|
|
565
|
+
if (!Array.isArray(pathsValue))
|
|
566
|
+
return [];
|
|
567
|
+
return pathsValue.flatMap((value) => {
|
|
568
|
+
if (typeof value !== "string" || !value.trim())
|
|
569
|
+
return [];
|
|
570
|
+
const path = value.trim();
|
|
571
|
+
return [{ path, name: traceAttachmentName(path) }];
|
|
572
|
+
}).slice(0, 10);
|
|
573
|
+
}
|
|
574
|
+
function traceAttachmentName(path) {
|
|
575
|
+
return path.split(/[\\/]/).filter(Boolean).at(-1) ?? path;
|
|
576
|
+
}
|
|
577
|
+
function isRecord(value) {
|
|
578
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
579
|
+
}
|
|
501
580
|
function traceNodeText(node) {
|
|
502
581
|
if (typeof node.output === "string")
|
|
503
582
|
return node.output;
|
|
@@ -654,6 +733,7 @@ function traceNodeFromEvent(piboSessionId, event, childByParent, linkedChildByTo
|
|
|
654
733
|
title: "User Message",
|
|
655
734
|
status: isOptimisticUserMessageEvent(event) ? "running" : "done",
|
|
656
735
|
messageDeliveryState: isOptimisticUserMessageEvent(event) ? "sending" : undefined,
|
|
736
|
+
fileAttachments: traceFileAttachmentsFromMessageEvent(event),
|
|
657
737
|
summary: event.text,
|
|
658
738
|
output: event.text,
|
|
659
739
|
};
|
|
@@ -60,6 +60,7 @@ function traceNodeShallowEqual(left, right) {
|
|
|
60
60
|
left.startedAt === right.startedAt &&
|
|
61
61
|
left.completedAt === right.completedAt &&
|
|
62
62
|
left.durationMs === right.durationMs &&
|
|
63
|
+
traceFileAttachmentsEqual(left.fileAttachments, right.fileAttachments) &&
|
|
63
64
|
left.toolMetrics?.durationMs === right.toolMetrics?.durationMs &&
|
|
64
65
|
left.toolMetrics?.inputTokens === right.toolMetrics?.inputTokens &&
|
|
65
66
|
left.toolMetrics?.outputTokens === right.toolMetrics?.outputTokens &&
|
|
@@ -74,6 +75,19 @@ function traceNodeShallowEqual(left, right) {
|
|
|
74
75
|
left.stableKey === right.stableKey &&
|
|
75
76
|
traceOrderKeyEqual(left.orderKey, right.orderKey));
|
|
76
77
|
}
|
|
78
|
+
function traceFileAttachmentsEqual(left, right) {
|
|
79
|
+
if (left === right)
|
|
80
|
+
return true;
|
|
81
|
+
if (!left || !right || left.length !== right.length)
|
|
82
|
+
return false;
|
|
83
|
+
return left.every((attachment, index) => {
|
|
84
|
+
const other = right[index];
|
|
85
|
+
return attachment.name === other?.name
|
|
86
|
+
&& attachment.path === other.path
|
|
87
|
+
&& attachment.bytes === other.bytes
|
|
88
|
+
&& attachment.contentType === other.contentType;
|
|
89
|
+
});
|
|
90
|
+
}
|
|
77
91
|
function modelInferenceRecordsEqual(left, right) {
|
|
78
92
|
if (left === right)
|
|
79
93
|
return true;
|
|
@@ -27,7 +27,7 @@ export function getDelegatedAgentContextFile(subagents) {
|
|
|
27
27
|
"```text",
|
|
28
28
|
"pibo_run_start({",
|
|
29
29
|
" toolName: \"pibo_agents_send_message\",",
|
|
30
|
-
" arguments: { name, sessionName, message, threadKey? },",
|
|
30
|
+
" arguments: { name, sessionName, message, threadKey?, queue? },",
|
|
31
31
|
" completionPolicy?: \"tracked\" | \"detached\"",
|
|
32
32
|
"}) -> { runId }",
|
|
33
33
|
"",
|
|
@@ -40,9 +40,15 @@ export function getDelegatedAgentContextFile(subagents) {
|
|
|
40
40
|
"pibo_agents_kill({ agentId }) # terminate one persistent child session subtree",
|
|
41
41
|
"```",
|
|
42
42
|
"",
|
|
43
|
-
"Set `sessionName` on every send to a nonblank human-readable child title of at most 40 Unicode code points. Pibo trims surrounding whitespace and rejects missing, blank, non-string, or oversized names before creating a yielded run or child session. Reuse a stable `threadKey` to continue the same child Pibo Session; a new `sessionName` updates its title without changing identity.
|
|
43
|
+
"Set `sessionName` on every send to a nonblank human-readable child title of at most 40 Unicode code points. Pibo trims surrounding whitespace and rejects missing, blank, non-string, or oversized names before creating a yielded run or child session. Reuse a stable `threadKey` to continue the same child Pibo Session; a new `sessionName` updates its title without changing identity.",
|
|
44
44
|
"",
|
|
45
|
-
"
|
|
45
|
+
"## Steering and queue delivery",
|
|
46
|
+
"",
|
|
47
|
+
"When the reused child has an active turn that accepts steering, omit `queue` or set `queue: false`: Pibo sends the message into that active turn at the next steering boundary. Use this default for corrections, changed priorities, additional constraints, or information the child should apply before finishing its current work. When the child is idle, the same call automatically queues a normal new turn; steering cannot be forced while idle. Set `queue: true` only when you deliberately want a separate follow-up turn after the active turn finishes. The result reports the actual `delivery` as `steer` or `queue`. Cancelling a run after its steering message was accepted stops waiting for the shared active-turn result but cannot retract the steering message or cancel that active turn.",
|
|
48
|
+
"",
|
|
49
|
+
"A wait timeout only wakes the orchestrator. Observe uses `cursorMode: \"auto\"` by default: the first equivalent query returns the newest completed assistant messages, and later calls return only unread messages. Use `cursorMode: \"history\"` only to reread earlier observations. Streaming deltas, duplicate tool progress events, and tools are hidden by default. Inspect tools only when a child stalls, reports an error, or needs targeted diagnosis; prefer exact `toolCallIds`, then `includeTools: true`, and use `toolDetail: \"full\"` only when summaries are insufficient. Use `textContains` for case-insensitive substring matching or `textRegex` for rg/Rust-regex matching; both must match when supplied together. Text, regex, identity, and event filters create separate automatic query cursors; an explicit `afterSequence` overrides and advances the matching automatic cursor.",
|
|
50
|
+
"",
|
|
51
|
+
"Observe progress and decide whether to continue waiting, send default steering to an active child, set `queue: true` for a separate follow-up turn, cancel the request, or kill the child session.",
|
|
46
52
|
"",
|
|
47
53
|
"For substantial reports, ask the child to persist a Markdown artifact and include its path in the complete final message.",
|
|
48
54
|
].join("\n"),
|
|
@@ -3,7 +3,7 @@ export const PIBO_AGENT_OBSERVATION_TOOL_SUMMARY_MAX_BYTES = 768;
|
|
|
3
3
|
export const PIBO_AGENT_OBSERVATION_DETAILS_MAX_BYTES = 32 * 1024;
|
|
4
4
|
export const PIBO_AGENT_OBSERVATION_DEFAULT_LIMIT = 20;
|
|
5
5
|
export const PIBO_AGENT_OBSERVATION_MAX_LIMIT = 200;
|
|
6
|
-
export const PIBO_AGENT_OBSERVATION_DEFAULT_EVENT_TYPES = ["assistant_message"];
|
|
6
|
+
export const PIBO_AGENT_OBSERVATION_DEFAULT_EVENT_TYPES = ["assistant_message", "session_error"];
|
|
7
7
|
export const PIBO_AGENT_OBSERVATION_DEFAULT_TOOL_EVENT_TYPES = ["tool_call", "tool_execution_finished"];
|
|
8
8
|
export function piboAgentObservationSourceFromEvent(event) {
|
|
9
9
|
const source = {
|
package/dist/subagents/tool.js
CHANGED
|
@@ -93,6 +93,7 @@ function normalizeAgentSendMessageResult(result, fallbackRequestId) {
|
|
|
93
93
|
return {
|
|
94
94
|
...result,
|
|
95
95
|
requestId: result.requestId?.trim() || fallbackRequestId,
|
|
96
|
+
delivery: result.delivery ?? "queue",
|
|
96
97
|
finalMessage: typeof result.finalMessage === "string" ? result.finalMessage : result.reply.text,
|
|
97
98
|
};
|
|
98
99
|
}
|
|
@@ -114,11 +115,11 @@ export function createAgentToolDefinitions(subagents, controller) {
|
|
|
114
115
|
name: "pibo_agents_send_message",
|
|
115
116
|
title: "Pibo Agents Send Message",
|
|
116
117
|
description: [
|
|
117
|
-
"Yielded-only delegated send with a required sessionName. It must be a nonblank string of at most 40 Unicode code points and is trimmed before use. name selects the configured agent, sessionName is the human-readable child-session title, and threadKey controls conversation reuse. Invalid arguments fail before a run or child session is created. Start this tool through pibo_run_start; bounded waits do not limit the child lifetime.",
|
|
118
|
+
"Yielded-only delegated send with a required sessionName. It must be a nonblank string of at most 40 Unicode code points and is trimmed before use. name selects the configured agent, sessionName is the human-readable child-session title, and threadKey controls conversation reuse. By default, a reused child with an active steerable turn receives the message as steering; an idle child receives a queued turn. Set queue=true only when the message must run as a separate next turn even while the child is active. Steering is never attempted for an idle child. Invalid arguments fail before a run or child session is created. Start this tool through pibo_run_start; bounded waits do not limit the child lifetime.",
|
|
118
119
|
"Available agents:",
|
|
119
120
|
catalog,
|
|
120
121
|
].join("\n"),
|
|
121
|
-
promptSnippet: "Start pibo_agents_send_message through pibo_run_start. Provide a nonblank sessionName of at most 40 Unicode code points on every call;
|
|
122
|
+
promptSnippet: "Start pibo_agents_send_message through pibo_run_start. Reuse threadKey to address the same child session. Omit queue to steer its active turn automatically; if the child is idle, Pibo queues a normal turn instead. Set queue=true only when you deliberately want a separate follow-up turn after the active turn. You cannot force steering on an idle child. Provide a nonblank sessionName of at most 40 Unicode code points on every call; follow-up calls update the reused child title without changing identity. Use run wait/status/read/cancel plus agent observe for lifecycle control.",
|
|
122
123
|
executionMode: "parallel",
|
|
123
124
|
inputSchema: Type.Object({
|
|
124
125
|
name: piboStringEnum(names, { description: "Configured delegated-agent selector; not the child title or reuse key" }),
|
|
@@ -133,6 +134,10 @@ export function createAgentToolDefinitions(subagents, controller) {
|
|
|
133
134
|
description: "Stable reuse key for one delegated-agent conversation; independent of sessionName. Omit it to create a new child session.",
|
|
134
135
|
maxLength: 256,
|
|
135
136
|
})),
|
|
137
|
+
queue: Type.Optional(Type.Boolean({
|
|
138
|
+
description: "Force this message into the child's next-turn queue. Omit or set false to steer an active steerable child automatically; idle children are always queued.",
|
|
139
|
+
default: false,
|
|
140
|
+
})),
|
|
136
141
|
}),
|
|
137
142
|
prepareInput: preparePiboAgentToolInput,
|
|
138
143
|
async execute(toolCallId, params, signal, _onUpdate, context) {
|
|
@@ -148,6 +153,7 @@ export function createAgentToolDefinitions(subagents, controller) {
|
|
|
148
153
|
sessionName: preparedParams.sessionName,
|
|
149
154
|
message: preparedParams.message,
|
|
150
155
|
threadKey: preparedParams.threadKey,
|
|
156
|
+
queue: preparedParams.queue,
|
|
151
157
|
toolCallId,
|
|
152
158
|
requestId: context.yieldedRunId,
|
|
153
159
|
parentProvenance: context.getActiveMessage?.()?.provenance,
|
|
@@ -156,7 +162,7 @@ export function createAgentToolDefinitions(subagents, controller) {
|
|
|
156
162
|
return {
|
|
157
163
|
content: [{
|
|
158
164
|
type: "text",
|
|
159
|
-
text: `Agent request ${result.requestId} completed (${result.name}, ${result.agentId}, thread ${result.threadKey}).\n\n${result.finalMessage}`,
|
|
165
|
+
text: `Agent request ${result.requestId} completed via ${result.delivery} (${result.name}, ${result.agentId}, thread ${result.threadKey}).\n\n${result.finalMessage}`,
|
|
160
166
|
}],
|
|
161
167
|
structuredContent: {
|
|
162
168
|
status: "completed",
|
|
@@ -164,6 +170,8 @@ export function createAgentToolDefinitions(subagents, controller) {
|
|
|
164
170
|
agentId: result.agentId,
|
|
165
171
|
threadKey: result.threadKey,
|
|
166
172
|
eventId: result.eventId,
|
|
173
|
+
delivery: result.delivery,
|
|
174
|
+
...(result.activeEventId ? { activeEventId: result.activeEventId } : {}),
|
|
167
175
|
finalMessage: result.finalMessage,
|
|
168
176
|
},
|
|
169
177
|
details: result,
|
|
@@ -190,11 +198,11 @@ export function createAgentToolDefinitions(subagents, controller) {
|
|
|
190
198
|
name: "pibo_agents_observe",
|
|
191
199
|
title: "Pibo Agents Observe",
|
|
192
200
|
description: [
|
|
193
|
-
"Read completed delegated-agent messages with bounded cursor, identity, event, time, substring, regex, order, and limit filters.",
|
|
194
|
-
"Default cursorMode=auto: the first equivalent query returns the newest 20 completed assistant messages; later calls return only unread
|
|
201
|
+
"Read completed delegated-agent messages and session errors with bounded cursor, identity, event, time, substring, regex, order, and limit filters.",
|
|
202
|
+
"Default cursorMode=auto: the first equivalent query returns the newest 20 completed assistant messages and session errors; later calls return only unread observations. Streaming deltas, duplicate tool progress events, and tools stay hidden.",
|
|
195
203
|
"Use cursorMode=history only to reread earlier observations. Inspect tools only when an agent appears stuck, reports a problem, or needs targeted diagnosis; prefer exact toolCallIds, then includeTools=true, and use toolDetail=full only when compact summaries are insufficient.",
|
|
196
204
|
].join("\n"),
|
|
197
|
-
promptSnippet: "Observe child progress through completed assistant messages. cursorMode=auto is the default and remembers each equivalent query, so repeated calls return only unread
|
|
205
|
+
promptSnippet: "Observe child progress through completed assistant messages and session errors. cursorMode=auto is the default and remembers each equivalent query, so repeated calls return only unread observations; use cursorMode=history to reread earlier observations. Streaming deltas, duplicate tool progress events, and tools are hidden by default. Inspect tools only for stalls, errors, or targeted diagnosis: prefer exact toolCallIds, use includeTools=true only when broader context is needed, and use toolDetail=full only when summaries are insufficient. Use textContains or textRegex for focused matching; different filters use separate automatic cursors. An explicit afterSequence overrides the stored cursor and advances that automatic query cursor.",
|
|
198
206
|
executionMode: "parallel",
|
|
199
207
|
annotations: { readOnly: true },
|
|
200
208
|
inputSchema: Type.Object({
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pasko70/pibo",
|
|
3
|
-
"version": "3.6.
|
|
3
|
+
"version": "3.6.3",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@pasko70/pibo",
|
|
9
|
-
"version": "3.6.
|
|
9
|
+
"version": "3.6.3",
|
|
10
10
|
"workspaces": [
|
|
11
11
|
"packages/workflows"
|
|
12
12
|
],
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter-node.d.ts","sourceRoot":"","sources":["../../src/runtime/adapter-node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,aAAa,EACb,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,EAChB,WAAW,EACX,oBAAoB,EACpB,aAAa,EACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"adapter-node.d.ts","sourceRoot":"","sources":["../../src/runtime/adapter-node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,aAAa,EACb,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,EAChB,WAAW,EACX,oBAAoB,EACpB,aAAa,EACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAiB1D,MAAM,MAAM,kCAAkC,GAAG;IAC/C,QAAQ,EAAE,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC;IAC7C,GAAG,CAAC,EAAE,MAAM,IAAI,GAAG,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,MAAM,aAAa,CAAC;IAC1C,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,SAAS,CAAC,EAAE,oBAAoB,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,kCAAkC,GAAG;IAC/C,EAAE,EAAE,IAAI,CAAC;IACT,GAAG,EAAE,WAAW,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;IACzB,MAAM,EAAE,oBAAoB,EAAE,CAAC;IAC/B,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,aAAa,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,kCAAkC,GAAG;IAC/C,EAAE,EAAE,KAAK,CAAC;IACV,GAAG,EAAE,WAAW,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,MAAM,EAAE,oBAAoB,EAAE,CAAC;IAC/B,WAAW,EAAE,kBAAkB,EAAE,CAAC;IAClC,KAAK,EAAE,oBAAoB,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,iCAAiC,GACzC,kCAAkC,GAClC,kCAAkC,CAAC;AAEvC,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,kBAAkB,EAC9B,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE,kCAAkC,GAC1C,OAAO,CAAC,iCAAiC,CAAC,CAsK5C"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { resolveWorkflowAdapter } from "../registry/index.js";
|
|
2
2
|
import { validateNodeOutput, validateWorkflowPortValue } from "../validation/index.js";
|
|
3
|
-
import { adapterNodeDispatchFailure, failAdapterNodeDispatch, } from "./dispatch-failures.js";
|
|
3
|
+
import { adapterErrorSummaryFromCaught, adapterNodeDispatchFailure, failAdapterNodeDispatch, } from "./dispatch-failures.js";
|
|
4
4
|
import { createWorkflowRuntimeId as createId } from "./ids.js";
|
|
5
5
|
import { emitWorkflowRuntimeEvent, persistWorkflowNodeAttempt, persistWorkflowRun, } from "./persistence.js";
|
|
6
6
|
import { createNodeScopedWorkflowRun, localStateSnapshotForNode } from "./state.js";
|
|
@@ -157,16 +157,4 @@ export async function dispatchWorkflowAdapterNode(definition, run, nodeId, input
|
|
|
157
157
|
});
|
|
158
158
|
}
|
|
159
159
|
}
|
|
160
|
-
function adapterErrorSummaryFromCaught(caught) {
|
|
161
|
-
if (caught instanceof Error) {
|
|
162
|
-
return {
|
|
163
|
-
code: "WorkflowRuntimeError.adapterFailed",
|
|
164
|
-
message: caught.message,
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
return {
|
|
168
|
-
code: "WorkflowRuntimeError.adapterFailed",
|
|
169
|
-
message: "Workflow adapter failed with a non-Error value.",
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
160
|
//# sourceMappingURL=adapter-node.js.map
|