@abstractframework/monitor-flow 0.1.0
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 +67 -0
- package/dist/AgentCyclesPanel.d.ts +20 -0
- package/dist/AgentCyclesPanel.d.ts.map +1 -0
- package/dist/AgentCyclesPanel.js +548 -0
- package/dist/JsonViewer.d.ts +7 -0
- package/dist/JsonViewer.d.ts.map +1 -0
- package/dist/JsonViewer.js +107 -0
- package/dist/Markdown.d.ts +6 -0
- package/dist/Markdown.d.ts.map +1 -0
- package/dist/Markdown.js +107 -0
- package/dist/agent_cycles_adapter.d.ts +27 -0
- package/dist/agent_cycles_adapter.d.ts.map +1 -0
- package/dist/agent_cycles_adapter.js +107 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/package.json +58 -0
- package/src/agent_cycles.css +576 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo, useState } from "react";
|
|
3
|
+
function is_json_object(value) {
|
|
4
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
5
|
+
}
|
|
6
|
+
function is_json_array(value) {
|
|
7
|
+
return Array.isArray(value);
|
|
8
|
+
}
|
|
9
|
+
function try_parse_json_string(value) {
|
|
10
|
+
const trimmed = value.trim();
|
|
11
|
+
if (!trimmed)
|
|
12
|
+
return value;
|
|
13
|
+
if ((trimmed.startsWith("{") && trimmed.endsWith("}")) || (trimmed.startsWith("[") && trimmed.endsWith("]"))) {
|
|
14
|
+
try {
|
|
15
|
+
return JSON.parse(trimmed);
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
function copy_string_for_json(value) {
|
|
24
|
+
if (value == null)
|
|
25
|
+
return "";
|
|
26
|
+
if (typeof value === "string")
|
|
27
|
+
return value;
|
|
28
|
+
try {
|
|
29
|
+
return JSON.stringify(value, null, 2);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return String(value);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async function copy_text(text) {
|
|
36
|
+
const value = String(text || "");
|
|
37
|
+
if (!value)
|
|
38
|
+
return;
|
|
39
|
+
try {
|
|
40
|
+
await navigator.clipboard.writeText(value);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
const el = document.createElement("textarea");
|
|
44
|
+
el.value = value;
|
|
45
|
+
document.body.appendChild(el);
|
|
46
|
+
el.select();
|
|
47
|
+
document.execCommand("copy");
|
|
48
|
+
document.body.removeChild(el);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function Token({ kind, children, }) {
|
|
52
|
+
return _jsx("span", { className: `json-token ${kind}`, children: children });
|
|
53
|
+
}
|
|
54
|
+
function render_primitive(value) {
|
|
55
|
+
if (value === null)
|
|
56
|
+
return _jsx(Token, { kind: "null", children: "null" });
|
|
57
|
+
if (typeof value === "string")
|
|
58
|
+
return _jsx(Token, { kind: "string", children: JSON.stringify(value) });
|
|
59
|
+
if (typeof value === "number")
|
|
60
|
+
return _jsx(Token, { kind: "number", children: String(value) });
|
|
61
|
+
if (typeof value === "boolean")
|
|
62
|
+
return _jsx(Token, { kind: "boolean", children: value ? "true" : "false" });
|
|
63
|
+
return _jsx(Token, { kind: "string", children: JSON.stringify(String(value)) });
|
|
64
|
+
}
|
|
65
|
+
function count_summary(value) {
|
|
66
|
+
if (is_json_array(value))
|
|
67
|
+
return value.length === 1 ? "1 item" : `${value.length} items`;
|
|
68
|
+
if (is_json_object(value))
|
|
69
|
+
return Object.keys(value).length === 1 ? "1 key" : `${Object.keys(value).length} keys`;
|
|
70
|
+
return "";
|
|
71
|
+
}
|
|
72
|
+
function JsonNode(props) {
|
|
73
|
+
const { label, value, depth, collapse_after_depth, trailing_comma } = props;
|
|
74
|
+
const indent_px = depth * 14;
|
|
75
|
+
const is_object = is_json_object(value);
|
|
76
|
+
const is_array = is_json_array(value);
|
|
77
|
+
const is_container = is_object || is_array;
|
|
78
|
+
const default_open = depth < collapse_after_depth;
|
|
79
|
+
const [open, set_open] = useState(default_open);
|
|
80
|
+
const prefix = label ? (_jsxs(_Fragment, { children: [_jsx(Token, { kind: "key", children: JSON.stringify(label) }), ": "] })) : null;
|
|
81
|
+
if (!is_container) {
|
|
82
|
+
return (_jsxs("div", { className: "json-viewer__line", style: { paddingLeft: indent_px }, children: [prefix, render_primitive(value), trailing_comma ? "," : ""] }));
|
|
83
|
+
}
|
|
84
|
+
const container_open = is_array ? "[" : "{";
|
|
85
|
+
const container_close = is_array ? "]" : "}";
|
|
86
|
+
const summary_text = count_summary(value);
|
|
87
|
+
const summary_value = open ? `${container_open}` : `${container_open}…${container_close}${summary_text ? ` (${summary_text})` : ""}`;
|
|
88
|
+
const entries = is_array
|
|
89
|
+
? value.map((v, i) => ({ key: String(i), label: undefined, value: v }))
|
|
90
|
+
: Object.entries(value).map(([k, v]) => ({ key: k, label: k, value: v }));
|
|
91
|
+
return (_jsxs("details", { className: "json-viewer__details", open: open, onToggle: (e) => set_open(e.currentTarget.open), children: [_jsxs("summary", { className: "json-viewer__summary", style: { paddingLeft: indent_px }, children: [prefix, _jsx("span", { className: "json-viewer__caret", "aria-hidden": "true", children: open ? "▾" : "▸" }), _jsx("span", { className: "json-viewer__punct", children: summary_value }), !open && trailing_comma ? _jsx("span", { className: "json-viewer__punct", children: "," }) : null] }), open ? (_jsx("div", { className: "json-viewer__children", children: entries.length === 0 ? (_jsxs("div", { className: "json-viewer__line", style: { paddingLeft: indent_px }, children: [_jsx("span", { className: "json-viewer__punct", children: container_close }), trailing_comma ? "," : ""] })) : (_jsxs(_Fragment, { children: [entries.map((e, idx) => {
|
|
92
|
+
const is_last = idx === entries.length - 1;
|
|
93
|
+
return (_jsx(JsonNode, { label: e.label, value: e.value, depth: depth + 1, collapse_after_depth: collapse_after_depth, trailing_comma: !is_last }, `${depth}:${label || "root"}:${e.key}`));
|
|
94
|
+
}), _jsxs("div", { className: "json-viewer__line", style: { paddingLeft: indent_px }, children: [_jsx("span", { className: "json-viewer__punct", children: container_close }), trailing_comma ? "," : ""] })] })) })) : null] }));
|
|
95
|
+
}
|
|
96
|
+
export function JsonViewer(props) {
|
|
97
|
+
const { value, className, showCopy = true } = props;
|
|
98
|
+
const collapse_after_depth = Number.isFinite(props.collapseAfterDepth ?? NaN) ? Number(props.collapseAfterDepth) : 3;
|
|
99
|
+
const display_value = useMemo(() => {
|
|
100
|
+
if (typeof value === "string")
|
|
101
|
+
return try_parse_json_string(value);
|
|
102
|
+
return value;
|
|
103
|
+
}, [value]);
|
|
104
|
+
const copy_value = useMemo(() => copy_string_for_json(value), [value]);
|
|
105
|
+
const cls = ["json-viewer", "run-details-output", className].filter(Boolean).join(" ");
|
|
106
|
+
return (_jsxs("div", { className: cls, children: [showCopy ? (_jsx("div", { className: "json-viewer__toolbar", children: _jsx("button", { type: "button", className: "modal-button json-viewer__copy", onClick: () => void copy_text(copy_value), children: "Copy" }) })) : null, _jsx("div", { className: "json-viewer__tree", role: "tree", "aria-label": "JSON viewer", children: _jsx(JsonNode, { value: display_value, depth: 0, collapse_after_depth: collapse_after_depth, trailing_comma: false }) })] }));
|
|
107
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Markdown.d.ts","sourceRoot":"","sources":["../src/Markdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAoD1B,wBAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,KAAK,CAAC,YAAY,CAqFtG"}
|
package/dist/Markdown.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from "react";
|
|
3
|
+
function render_inline(text) {
|
|
4
|
+
const out = [];
|
|
5
|
+
const s = String(text ?? "");
|
|
6
|
+
let i = 0;
|
|
7
|
+
let buf = "";
|
|
8
|
+
const flush = () => {
|
|
9
|
+
if (!buf)
|
|
10
|
+
return;
|
|
11
|
+
out.push(buf);
|
|
12
|
+
buf = "";
|
|
13
|
+
};
|
|
14
|
+
while (i < s.length) {
|
|
15
|
+
const ch = s[i];
|
|
16
|
+
if (ch === "`") {
|
|
17
|
+
const j = s.indexOf("`", i + 1);
|
|
18
|
+
if (j !== -1) {
|
|
19
|
+
flush();
|
|
20
|
+
out.push(_jsx("code", { children: s.slice(i + 1, j) }, `code:${i}`));
|
|
21
|
+
i = j + 1;
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (ch === "*" && s[i + 1] === "*") {
|
|
26
|
+
const j = s.indexOf("**", i + 2);
|
|
27
|
+
if (j !== -1) {
|
|
28
|
+
flush();
|
|
29
|
+
out.push(_jsx("strong", { children: s.slice(i + 2, j) }, `bold:${i}`));
|
|
30
|
+
i = j + 2;
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
buf += ch;
|
|
35
|
+
i += 1;
|
|
36
|
+
}
|
|
37
|
+
flush();
|
|
38
|
+
return out;
|
|
39
|
+
}
|
|
40
|
+
function normalize_lines(text) {
|
|
41
|
+
const s = String(text ?? "").replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
42
|
+
return s.split("\n");
|
|
43
|
+
}
|
|
44
|
+
export function Markdown({ text, className }) {
|
|
45
|
+
const lines = normalize_lines(text);
|
|
46
|
+
const blocks = [];
|
|
47
|
+
let i = 0;
|
|
48
|
+
while (i < lines.length) {
|
|
49
|
+
const raw = lines[i];
|
|
50
|
+
const line = String(raw ?? "");
|
|
51
|
+
if (!line.trim()) {
|
|
52
|
+
i += 1;
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (line.trim().startsWith("```")) {
|
|
56
|
+
const fence = line.trim();
|
|
57
|
+
const lang = fence.replace(/```/g, "").trim();
|
|
58
|
+
const code_lines = [];
|
|
59
|
+
i += 1;
|
|
60
|
+
while (i < lines.length && !String(lines[i] ?? "").trim().startsWith("```")) {
|
|
61
|
+
code_lines.push(String(lines[i] ?? ""));
|
|
62
|
+
i += 1;
|
|
63
|
+
}
|
|
64
|
+
if (i < lines.length)
|
|
65
|
+
i += 1;
|
|
66
|
+
const code = code_lines.join("\n");
|
|
67
|
+
blocks.push(_jsx("pre", { className: "mf-md_pre", children: _jsx("code", { className: lang ? `language-${lang}` : undefined, children: code }) }, `pre:${i}`));
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
const heading_m = line.match(/^(#{1,3})\s+(.*)$/);
|
|
71
|
+
if (heading_m) {
|
|
72
|
+
const level = heading_m[1].length;
|
|
73
|
+
const content = heading_m[2] || "";
|
|
74
|
+
const nodes = render_inline(content);
|
|
75
|
+
if (level === 1)
|
|
76
|
+
blocks.push(_jsx("h1", { children: nodes }, `h1:${i}`));
|
|
77
|
+
else if (level === 2)
|
|
78
|
+
blocks.push(_jsx("h2", { children: nodes }, `h2:${i}`));
|
|
79
|
+
else
|
|
80
|
+
blocks.push(_jsx("h3", { children: nodes }, `h3:${i}`));
|
|
81
|
+
i += 1;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
const is_bullet = (s) => {
|
|
85
|
+
const t = s.trimStart();
|
|
86
|
+
return t.startsWith("- ") || t.startsWith("* ");
|
|
87
|
+
};
|
|
88
|
+
if (is_bullet(line)) {
|
|
89
|
+
const items = [];
|
|
90
|
+
while (i < lines.length && is_bullet(String(lines[i] ?? ""))) {
|
|
91
|
+
const t = String(lines[i] ?? "").trimStart();
|
|
92
|
+
items.push(t.slice(2));
|
|
93
|
+
i += 1;
|
|
94
|
+
}
|
|
95
|
+
blocks.push(_jsx("ul", { className: "mf-md_ul", children: items.map((it, idx) => (_jsx("li", { children: render_inline(it) }, `li:${i}:${idx}`))) }, `ul:${i}`));
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
const para_lines = [];
|
|
99
|
+
while (i < lines.length && String(lines[i] ?? "").trim()) {
|
|
100
|
+
para_lines.push(String(lines[i] ?? ""));
|
|
101
|
+
i += 1;
|
|
102
|
+
}
|
|
103
|
+
blocks.push(_jsx("p", { className: "mf-md_p", children: para_lines.map((pl, idx) => (_jsxs(React.Fragment, { children: [render_inline(pl), idx < para_lines.length - 1 ? _jsx("br", {}) : null] }, `pl:${i}:${idx}`))) }, `p:${i}`));
|
|
104
|
+
}
|
|
105
|
+
const cls = ["mf-md", className].filter(Boolean).join(" ");
|
|
106
|
+
return _jsx("div", { className: cls, children: blocks });
|
|
107
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { TraceItem } from "./AgentCyclesPanel";
|
|
2
|
+
export type StepRecordLike = {
|
|
3
|
+
run_id?: string | null;
|
|
4
|
+
step_id?: string | null;
|
|
5
|
+
node_id?: string | null;
|
|
6
|
+
status?: string | null;
|
|
7
|
+
effect?: {
|
|
8
|
+
type?: string | null;
|
|
9
|
+
} | null;
|
|
10
|
+
started_at?: string | null;
|
|
11
|
+
ended_at?: string | null;
|
|
12
|
+
};
|
|
13
|
+
export type LedgerRecordItem<T extends StepRecordLike = StepRecordLike> = {
|
|
14
|
+
run_id: string;
|
|
15
|
+
cursor: number;
|
|
16
|
+
record: T;
|
|
17
|
+
};
|
|
18
|
+
export type AgentTraceBuildResult = {
|
|
19
|
+
run_id: string;
|
|
20
|
+
node_id: string;
|
|
21
|
+
items: TraceItem[];
|
|
22
|
+
};
|
|
23
|
+
export declare function build_agent_trace(items: LedgerRecordItem[], opts: {
|
|
24
|
+
run_id: string;
|
|
25
|
+
node_id?: string | null;
|
|
26
|
+
}): AgentTraceBuildResult;
|
|
27
|
+
//# sourceMappingURL=agent_cycles_adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent_cycles_adapter.d.ts","sourceRoot":"","sources":["../src/agent_cycles_adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,oBAAoB,CAAC;AAE/D,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IACzC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,cAAc,GAAG,cAAc,IAAI;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,CAAC,CAAC;CACX,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB,CAAC;AAqEF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,gBAAgB,EAAE,EAAE,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,qBAAqB,CAmDrI"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
function as_string(value) {
|
|
2
|
+
return typeof value === "string" ? value.trim() : "";
|
|
3
|
+
}
|
|
4
|
+
function run_id_of(item) {
|
|
5
|
+
return as_string(item.run_id) || as_string(item.record?.run_id);
|
|
6
|
+
}
|
|
7
|
+
function node_id_of(rec) {
|
|
8
|
+
return as_string(rec?.node_id);
|
|
9
|
+
}
|
|
10
|
+
const AGENT_STAGE_SUFFIXES = new Set(["reason", "act", "observe", "thought", "think"]);
|
|
11
|
+
function node_group_id(node_id) {
|
|
12
|
+
const s = as_string(node_id);
|
|
13
|
+
if (!s.includes("::"))
|
|
14
|
+
return s;
|
|
15
|
+
const parts = s.split("::");
|
|
16
|
+
if (parts.length < 2)
|
|
17
|
+
return s;
|
|
18
|
+
const last = String(parts[parts.length - 1] || "").trim().toLowerCase();
|
|
19
|
+
if (!AGENT_STAGE_SUFFIXES.has(last))
|
|
20
|
+
return s;
|
|
21
|
+
return parts.slice(0, -1).join("::");
|
|
22
|
+
}
|
|
23
|
+
function effect_type_of(rec) {
|
|
24
|
+
return as_string(rec?.effect?.type);
|
|
25
|
+
}
|
|
26
|
+
function status_of(rec) {
|
|
27
|
+
return as_string(rec?.status) || "unknown";
|
|
28
|
+
}
|
|
29
|
+
function step_id_of(rec) {
|
|
30
|
+
return as_string(rec?.step_id);
|
|
31
|
+
}
|
|
32
|
+
function ts_of(rec) {
|
|
33
|
+
return as_string(rec?.ended_at) || as_string(rec?.started_at);
|
|
34
|
+
}
|
|
35
|
+
function pick_best_node_group_id(records) {
|
|
36
|
+
const llm = new Map();
|
|
37
|
+
const tools = new Map();
|
|
38
|
+
for (const r of records) {
|
|
39
|
+
const nid = node_group_id(node_id_of(r));
|
|
40
|
+
if (!nid)
|
|
41
|
+
continue;
|
|
42
|
+
const t = effect_type_of(r);
|
|
43
|
+
if (t === "llm_call")
|
|
44
|
+
llm.set(nid, (llm.get(nid) || 0) + 1);
|
|
45
|
+
else if (t === "tool_calls")
|
|
46
|
+
tools.set(nid, (tools.get(nid) || 0) + 1);
|
|
47
|
+
}
|
|
48
|
+
const best_of = (m) => {
|
|
49
|
+
let best = "";
|
|
50
|
+
let best_count = -1;
|
|
51
|
+
for (const [k, v] of m) {
|
|
52
|
+
if (v > best_count) {
|
|
53
|
+
best = k;
|
|
54
|
+
best_count = v;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return best;
|
|
58
|
+
};
|
|
59
|
+
return best_of(llm) || best_of(tools) || "";
|
|
60
|
+
}
|
|
61
|
+
export function build_agent_trace(items, opts) {
|
|
62
|
+
const run_id = as_string(opts.run_id);
|
|
63
|
+
if (!run_id)
|
|
64
|
+
return { run_id: "", node_id: "", items: [] };
|
|
65
|
+
const raw = (Array.isArray(items) ? items : [])
|
|
66
|
+
.filter((x) => x && x.record && run_id_of(x) === run_id)
|
|
67
|
+
.map((x) => ({ cursor: x.cursor, record: x.record }))
|
|
68
|
+
.sort((a, b) => (a.cursor || 0) - (b.cursor || 0));
|
|
69
|
+
const records = raw.map((x) => x.record);
|
|
70
|
+
const requested_node_id = node_group_id(as_string(opts.node_id));
|
|
71
|
+
const node_id = requested_node_id || pick_best_node_group_id(records);
|
|
72
|
+
const INTERESTING = new Set(["llm_call", "tool_calls", "ask_user", "answer_user"]);
|
|
73
|
+
let filtered = raw.filter((x) => INTERESTING.has(effect_type_of(x.record)));
|
|
74
|
+
// Only filter by node_id when explicitly requested by the caller.
|
|
75
|
+
// Auto-picking a dominant node group is useful for labeling, but filtering can
|
|
76
|
+
// accidentally drop tool_calls when workflows split LLM/tool nodes.
|
|
77
|
+
if (requested_node_id)
|
|
78
|
+
filtered = filtered.filter((x) => node_group_id(node_id_of(x.record)) === requested_node_id);
|
|
79
|
+
const by_step_id = new Map();
|
|
80
|
+
const passthrough = [];
|
|
81
|
+
for (const item of filtered) {
|
|
82
|
+
const sid = step_id_of(item.record);
|
|
83
|
+
if (!sid) {
|
|
84
|
+
passthrough.push(item);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const prev = by_step_id.get(sid);
|
|
88
|
+
if (!prev || (item.cursor || 0) > (prev.cursor || 0))
|
|
89
|
+
by_step_id.set(sid, item);
|
|
90
|
+
}
|
|
91
|
+
const deduped = [...passthrough, ...Array.from(by_step_id.values())].sort((a, b) => (a.cursor || 0) - (b.cursor || 0));
|
|
92
|
+
const out = deduped.map((x) => {
|
|
93
|
+
const rec = x.record;
|
|
94
|
+
const nodeId = node_id_of(rec) || "(node?)";
|
|
95
|
+
const ts = ts_of(rec);
|
|
96
|
+
const sid = step_id_of(rec);
|
|
97
|
+
return {
|
|
98
|
+
id: `ledger:${run_id}:${x.cursor}:${sid || ""}`,
|
|
99
|
+
runId: run_id,
|
|
100
|
+
nodeId,
|
|
101
|
+
ts: ts || undefined,
|
|
102
|
+
status: status_of(rec),
|
|
103
|
+
step: rec,
|
|
104
|
+
};
|
|
105
|
+
});
|
|
106
|
+
return { run_id, node_id, items: out };
|
|
107
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { AgentCyclesPanel, type AgentCyclesPanelProps, type TraceItem, type TraceStep } from "./AgentCyclesPanel";
|
|
2
|
+
export { JsonViewer } from "./JsonViewer";
|
|
3
|
+
export { build_agent_trace, type AgentTraceBuildResult, type LedgerRecordItem, type StepRecordLike } from "./agent_cycles_adapter";
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAClH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,KAAK,qBAAqB,EAAE,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC"}
|
package/dist/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@abstractframework/monitor-flow",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Shared flow/agent monitoring UI components for AbstractFramework (used by AbstractFlow and AbstractObserver).",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"author": "Laurent-Philippe Albou",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"abstractframework",
|
|
10
|
+
"flow",
|
|
11
|
+
"agent",
|
|
12
|
+
"observability",
|
|
13
|
+
"ui",
|
|
14
|
+
"react"
|
|
15
|
+
],
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "https://github.com/lpalbou/AbstractUIC.git",
|
|
19
|
+
"directory": "monitor-flow"
|
|
20
|
+
},
|
|
21
|
+
"homepage": "https://github.com/lpalbou/AbstractUIC#readme",
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "public"
|
|
24
|
+
},
|
|
25
|
+
"main": "./dist/index.js",
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"import": "./dist/index.js"
|
|
31
|
+
},
|
|
32
|
+
"./agent_cycles.css": "./src/agent_cycles.css"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist",
|
|
36
|
+
"src/agent_cycles.css",
|
|
37
|
+
"README.md"
|
|
38
|
+
],
|
|
39
|
+
"scripts": {
|
|
40
|
+
"build": "tsc",
|
|
41
|
+
"prepublishOnly": "npm run build"
|
|
42
|
+
},
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"react": "^18.0.0",
|
|
45
|
+
"react-dom": "^18.0.0"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@types/react": "^18.2.48",
|
|
49
|
+
"@types/react-dom": "^18.2.18",
|
|
50
|
+
"typescript": "^5.3.3"
|
|
51
|
+
},
|
|
52
|
+
"sideEffects": [
|
|
53
|
+
"*.css"
|
|
54
|
+
],
|
|
55
|
+
"engines": {
|
|
56
|
+
"node": ">=18.0.0"
|
|
57
|
+
}
|
|
58
|
+
}
|