@ai-setting/roy-agent-core 1.4.13 → 1.4.15
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/config/index.js +32 -0
- package/dist/env/agent/index.js +24 -0
- package/dist/env/commands/index.js +14 -0
- package/dist/env/debug/formatters/index.js +11 -0
- package/dist/env/debug/index.js +26 -0
- package/dist/env/hook/index.js +29 -0
- package/dist/env/index.js +81 -0
- package/dist/env/llm/index.js +40 -0
- package/dist/env/log-trace/index.js +83 -0
- package/dist/env/mcp/index.js +39 -0
- package/dist/env/mcp/tool/index.js +14 -0
- package/dist/env/memory/built-in/index.js +11 -0
- package/dist/env/memory/index.js +56 -0
- package/dist/env/memory/plugin/index.js +36 -0
- package/dist/env/prompt/index.js +20 -0
- package/dist/env/session/index.js +25 -0
- package/dist/env/session/storage/index.js +18 -0
- package/dist/env/skill/index.js +34 -0
- package/dist/env/skill/tool/index.js +9 -0
- package/dist/env/task/delegate/index.js +18 -0
- package/dist/env/task/hooks/index.js +7 -0
- package/dist/env/task/index.js +30 -0
- package/dist/env/task/plugins/index.js +23 -0
- package/dist/env/task/storage/index.js +14 -0
- package/dist/env/task/tools/index.js +17 -0
- package/dist/env/task/tools/operation/index.js +15 -0
- package/dist/{shared/chunk-1d4rwms4.js → env/tool/built-in/index.js} +4 -4
- package/dist/env/tool/index.js +39 -0
- package/dist/env/workflow/decorators/index.js +27 -0
- package/dist/env/workflow/engine/index.js +28 -0
- package/dist/env/workflow/index.js +132 -0
- package/dist/env/workflow/nodes/index.js +19 -0
- package/dist/env/workflow/service/index.js +13 -0
- package/dist/env/workflow/storage/index.js +27 -0
- package/dist/env/workflow/tools/index.js +159 -0
- package/dist/env/workflow/types/index.js +94 -0
- package/dist/env/workflow/utils/index.js +637 -0
- package/dist/index.js +233 -16386
- package/dist/shared/{chunk-2b5kbhx3.js → @ai-setting/roy-agent-core-0rtxwr28.js} +6 -114
- package/dist/shared/@ai-setting/roy-agent-core-0vbdz0x7.js +36 -0
- package/dist/shared/@ai-setting/roy-agent-core-12zkpda2.js +393 -0
- package/dist/shared/@ai-setting/roy-agent-core-1ce3fqrk.js +117 -0
- package/dist/shared/@ai-setting/roy-agent-core-2dhd60aw.js +11 -0
- package/dist/shared/@ai-setting/roy-agent-core-2kg2wma8.js +620 -0
- package/dist/shared/@ai-setting/roy-agent-core-2x0m2p66.js +851 -0
- package/dist/shared/@ai-setting/roy-agent-core-35x0wrtt.js +172 -0
- package/dist/shared/{chunk-1pf5mfgd.js → @ai-setting/roy-agent-core-37e4tep3.js} +2 -2
- package/dist/shared/@ai-setting/roy-agent-core-3agad0d9.js +603 -0
- package/dist/shared/@ai-setting/roy-agent-core-4arba14a.js +419 -0
- package/dist/shared/@ai-setting/roy-agent-core-4rqmfr7t.js +266 -0
- package/dist/shared/@ai-setting/roy-agent-core-4t40mkpv.js +206 -0
- package/dist/shared/@ai-setting/roy-agent-core-561b1c4p.js +377 -0
- package/dist/shared/@ai-setting/roy-agent-core-5xf65pz6.js +1305 -0
- package/dist/shared/@ai-setting/roy-agent-core-6a72jfdy.js +303 -0
- package/dist/shared/{chunk-1aakcfp1.js → @ai-setting/roy-agent-core-7f303ffd.js} +3 -3
- package/dist/shared/@ai-setting/roy-agent-core-7fgf85wc.js +284 -0
- package/dist/shared/{chunk-t1rh6jtm.js → @ai-setting/roy-agent-core-7n436rb4.js} +7 -12
- package/dist/shared/@ai-setting/roy-agent-core-7r85t0qn.js +492 -0
- package/dist/shared/@ai-setting/roy-agent-core-7rewcey6.js +862 -0
- package/dist/shared/@ai-setting/roy-agent-core-92z6t4he.js +14 -0
- package/dist/shared/@ai-setting/roy-agent-core-9qwp5qkz.js +1387 -0
- package/dist/shared/{chunk-mf5xqbdh.js → @ai-setting/roy-agent-core-9yxb3ty9.js} +3 -2
- package/dist/shared/@ai-setting/roy-agent-core-anwsxdds.js +1205 -0
- package/dist/shared/{chunk-1qwabsm0.js → @ai-setting/roy-agent-core-bncgx3gb.js} +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-cd00w5mb.js +762 -0
- package/dist/shared/@ai-setting/roy-agent-core-cgs0j60t.js +442 -0
- package/dist/shared/@ai-setting/roy-agent-core-ctdhjv68.js +93 -0
- package/dist/shared/@ai-setting/roy-agent-core-dbsk841j.js +286 -0
- package/dist/shared/@ai-setting/roy-agent-core-e25xkv53.js +64 -0
- package/dist/shared/{chunk-yqmx37vm.js → @ai-setting/roy-agent-core-e5jcp24a.js} +2 -2
- package/dist/shared/@ai-setting/roy-agent-core-e62e2a5a.js +204 -0
- package/dist/shared/{chunk-g6j5n3gv.js → @ai-setting/roy-agent-core-ewrj1c4k.js} +2 -2
- package/dist/shared/{chunk-rncy3rtd.js → @ai-setting/roy-agent-core-fdb6m4e4.js} +119 -1113
- package/dist/shared/{chunk-q9j99fsm.js → @ai-setting/roy-agent-core-fv32jaa8.js} +3 -3
- package/dist/shared/@ai-setting/roy-agent-core-g1s2h0e5.js +171 -0
- package/dist/shared/@ai-setting/roy-agent-core-gmnkza34.js +202 -0
- package/dist/shared/@ai-setting/roy-agent-core-hz7rr4yx.js +513 -0
- package/dist/shared/@ai-setting/roy-agent-core-j3bbr2n0.js +378 -0
- package/dist/shared/{chunk-a9qmy3sc.js → @ai-setting/roy-agent-core-j3wc4465.js} +6 -3
- package/dist/shared/@ai-setting/roy-agent-core-jj79gszx.js +1130 -0
- package/dist/shared/@ai-setting/roy-agent-core-mwwk6req.js +913 -0
- package/dist/shared/{chunk-0q6s9wm6.js → @ai-setting/roy-agent-core-pc9g3962.js} +6 -50
- package/dist/shared/@ai-setting/roy-agent-core-psvxt4c9.js +60 -0
- package/dist/shared/@ai-setting/roy-agent-core-pzsg9pvf.js +393 -0
- package/dist/shared/{chunk-91bas8w5.js → @ai-setting/roy-agent-core-q779wnwm.js} +5 -5
- package/dist/shared/{chunk-25x2pdtp.js → @ai-setting/roy-agent-core-qw0ebh1d.js} +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-qxhq8ven.js +57 -0
- package/dist/shared/@ai-setting/roy-agent-core-qxnbvgwe.js +66 -0
- package/dist/shared/@ai-setting/roy-agent-core-qya7seh6.js +408 -0
- package/dist/shared/@ai-setting/roy-agent-core-rbetrphj.js +97 -0
- package/dist/shared/@ai-setting/roy-agent-core-re1wjfw7.js +587 -0
- package/dist/shared/@ai-setting/roy-agent-core-rft3fmp0.js +14 -0
- package/dist/shared/@ai-setting/roy-agent-core-rvv6ydff.js +584 -0
- package/dist/shared/{chunk-ze20rksg.js → @ai-setting/roy-agent-core-rvxg1wps.js} +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-rzp9kxne.js +341 -0
- package/dist/shared/@ai-setting/roy-agent-core-t94ktchq.js +213 -0
- package/dist/shared/@ai-setting/roy-agent-core-w78syn7w.js +788 -0
- package/dist/shared/{chunk-9qzt1v1p.js → @ai-setting/roy-agent-core-z2t8hse8.js} +3 -2
- package/package.json +8 -7
- package/dist/index.d.ts +0 -7825
- package/dist/shared/chunk-hs7tbmje.js +0 -24
- /package/dist/shared/{chunk-wbkh7wat.js → @ai-setting/roy-agent-core-fs0mn2jk.js} +0 -0
|
@@ -0,0 +1,584 @@
|
|
|
1
|
+
// src/env/debug/formatters/trace-formatter.ts
|
|
2
|
+
class TraceFormatter {
|
|
3
|
+
formatEntry(entry, options = {}) {
|
|
4
|
+
const { pretty = false } = options;
|
|
5
|
+
const actionSymbol = entry.action === "enter" ? ">>>" : entry.action === "error" ? "!!!" : "<<<";
|
|
6
|
+
let output = `${actionSymbol} ${entry.function} ${entry.action}`;
|
|
7
|
+
if (entry.action === "enter" && entry.params) {
|
|
8
|
+
output += `
|
|
9
|
+
` + this.formatData(entry.params, options);
|
|
10
|
+
} else if (entry.action === "quit") {
|
|
11
|
+
if (entry.durationMs !== undefined) {
|
|
12
|
+
output += ` (${entry.durationMs}ms)`;
|
|
13
|
+
}
|
|
14
|
+
if (entry.result) {
|
|
15
|
+
output += `
|
|
16
|
+
` + this.formatData(entry.result, options);
|
|
17
|
+
}
|
|
18
|
+
} else if (entry.action === "error" && entry.error) {
|
|
19
|
+
output += `: ${entry.error}`;
|
|
20
|
+
}
|
|
21
|
+
if (pretty) {
|
|
22
|
+
output = this.indentMultilineContent(output);
|
|
23
|
+
}
|
|
24
|
+
return output;
|
|
25
|
+
}
|
|
26
|
+
indentMultilineContent(text, indent = " ") {
|
|
27
|
+
const lines = text.split(`
|
|
28
|
+
`);
|
|
29
|
+
if (lines.length <= 1)
|
|
30
|
+
return text;
|
|
31
|
+
return lines.map((line, i) => i === 0 ? line : `${indent}${line}`).join(`
|
|
32
|
+
`);
|
|
33
|
+
}
|
|
34
|
+
formatEntries(entries, options = {}) {
|
|
35
|
+
if (entries.length === 0) {
|
|
36
|
+
return "No trace entries";
|
|
37
|
+
}
|
|
38
|
+
const formatted = entries.map((entry) => this.formatEntry(entry, options));
|
|
39
|
+
if (options.pretty) {
|
|
40
|
+
return formatted.join(`
|
|
41
|
+
` + "-".repeat(80) + `
|
|
42
|
+
`);
|
|
43
|
+
}
|
|
44
|
+
return formatted.join(`
|
|
45
|
+
`);
|
|
46
|
+
}
|
|
47
|
+
formatData(data, options = {}) {
|
|
48
|
+
const { pretty = false, maxDepth = 10 } = options;
|
|
49
|
+
if (pretty) {
|
|
50
|
+
return this.formatPretty(data, 0, maxDepth);
|
|
51
|
+
}
|
|
52
|
+
return JSON.stringify(data);
|
|
53
|
+
}
|
|
54
|
+
formatPretty(data, indent = 0, maxDepth) {
|
|
55
|
+
const baseIndent = " ".repeat(indent);
|
|
56
|
+
const nextIndent = " ".repeat(indent + 1);
|
|
57
|
+
if (data === null || data === undefined) {
|
|
58
|
+
return String(data);
|
|
59
|
+
}
|
|
60
|
+
if (typeof data === "string") {
|
|
61
|
+
if (data.includes(`
|
|
62
|
+
`)) {
|
|
63
|
+
return data.split(`
|
|
64
|
+
`).map((line, i) => i === 0 ? line : `${nextIndent}${line}`).join(`
|
|
65
|
+
`);
|
|
66
|
+
}
|
|
67
|
+
return data;
|
|
68
|
+
}
|
|
69
|
+
if (typeof data === "number" || typeof data === "boolean") {
|
|
70
|
+
return String(data);
|
|
71
|
+
}
|
|
72
|
+
if (Array.isArray(data)) {
|
|
73
|
+
if (data.length === 0)
|
|
74
|
+
return "[]";
|
|
75
|
+
const items = data.map((item) => {
|
|
76
|
+
const formatted = this.formatPretty(item, indent + 1, maxDepth);
|
|
77
|
+
return formatted.split(`
|
|
78
|
+
`).map((line) => ` ${line}`).join(`
|
|
79
|
+
`);
|
|
80
|
+
});
|
|
81
|
+
return `[
|
|
82
|
+
` + items.join(`,
|
|
83
|
+
`) + `
|
|
84
|
+
` + baseIndent + "]";
|
|
85
|
+
}
|
|
86
|
+
if (typeof data === "object") {
|
|
87
|
+
const obj = data;
|
|
88
|
+
const keys = Object.keys(obj);
|
|
89
|
+
if (keys.length === 0)
|
|
90
|
+
return "{}";
|
|
91
|
+
if (indent >= maxDepth) {
|
|
92
|
+
return "{...}";
|
|
93
|
+
}
|
|
94
|
+
const entries = keys.map((key) => {
|
|
95
|
+
const value = obj[key];
|
|
96
|
+
let formatted;
|
|
97
|
+
if (typeof value === "object" && value !== null) {
|
|
98
|
+
formatted = this.formatPretty(value, indent + 1, maxDepth);
|
|
99
|
+
} else if (typeof value === "string" && value.includes(`
|
|
100
|
+
`)) {
|
|
101
|
+
formatted = value.split(`
|
|
102
|
+
`).map((line, i) => i === 0 ? line : `${nextIndent}${line}`).join(`
|
|
103
|
+
`);
|
|
104
|
+
} else {
|
|
105
|
+
formatted = JSON.stringify(value);
|
|
106
|
+
}
|
|
107
|
+
return ` ${key}: ` + formatted.split(`
|
|
108
|
+
`).map((line, i) => i === 0 ? line : nextIndent + line).join(`
|
|
109
|
+
`);
|
|
110
|
+
});
|
|
111
|
+
return `{
|
|
112
|
+
` + entries.join(`,
|
|
113
|
+
`) + `
|
|
114
|
+
` + baseIndent + "}";
|
|
115
|
+
}
|
|
116
|
+
return JSON.stringify(data);
|
|
117
|
+
}
|
|
118
|
+
toJSON(entries) {
|
|
119
|
+
return JSON.stringify(entries, null, 2);
|
|
120
|
+
}
|
|
121
|
+
toSummary(entries) {
|
|
122
|
+
if (entries.length === 0) {
|
|
123
|
+
return "No trace entries";
|
|
124
|
+
}
|
|
125
|
+
const functions = new Set(entries.map((e) => e.function));
|
|
126
|
+
const actions = entries.reduce((acc, e) => {
|
|
127
|
+
acc[e.action] = (acc[e.action] || 0) + 1;
|
|
128
|
+
return acc;
|
|
129
|
+
}, {});
|
|
130
|
+
let summary = `Trace Summary (${entries.length} entries)
|
|
131
|
+
`;
|
|
132
|
+
summary += `Functions: ${[...functions].join(", ")}
|
|
133
|
+
`;
|
|
134
|
+
summary += `Actions: ${Object.entries(actions).map(([k, v]) => `${k}=${v}`).join(", ")}`;
|
|
135
|
+
return summary;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// src/env/debug/formatters/tree-formatter.ts
|
|
139
|
+
var Colors = {
|
|
140
|
+
reset: "\x1B[0m",
|
|
141
|
+
bold: "\x1B[1m",
|
|
142
|
+
dim: "\x1B[2m",
|
|
143
|
+
red: "\x1B[31m",
|
|
144
|
+
green: "\x1B[32m",
|
|
145
|
+
yellow: "\x1B[33m",
|
|
146
|
+
cyan: "\x1B[36m",
|
|
147
|
+
white: "\x1B[37m"
|
|
148
|
+
};
|
|
149
|
+
function color(text, colorCode) {
|
|
150
|
+
return `${colorCode}${text}${Colors.reset}`;
|
|
151
|
+
}
|
|
152
|
+
var CHARS = {
|
|
153
|
+
VERTICAL: "│",
|
|
154
|
+
VERTICAL_CONNECTOR: "├──",
|
|
155
|
+
LAST_CONNECTOR: "└──",
|
|
156
|
+
SPACE: " ",
|
|
157
|
+
BAR: "█",
|
|
158
|
+
EMPTY: "░",
|
|
159
|
+
DASH: "─"
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
class TreeFormatter {
|
|
163
|
+
options;
|
|
164
|
+
constructor(options = {}) {
|
|
165
|
+
this.options = {
|
|
166
|
+
showPercent: true,
|
|
167
|
+
showTimeBar: false,
|
|
168
|
+
barWidth: 10,
|
|
169
|
+
...options
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
colorByPercent(percent) {
|
|
173
|
+
if (percent >= 80)
|
|
174
|
+
return Colors.red;
|
|
175
|
+
if (percent >= 50)
|
|
176
|
+
return Colors.yellow;
|
|
177
|
+
if (percent >= 20)
|
|
178
|
+
return Colors.cyan;
|
|
179
|
+
return Colors.dim;
|
|
180
|
+
}
|
|
181
|
+
formatTree(node) {
|
|
182
|
+
const lines = [];
|
|
183
|
+
const totalDuration = node.durationMs || 0;
|
|
184
|
+
const percentBase = node.children.reduce((sum, c) => sum + (c.durationMs || 0), 0) || totalDuration;
|
|
185
|
+
lines.push(this.formatNode(node, totalDuration, percentBase, "", true, true));
|
|
186
|
+
this.formatChildren(node.children, "", lines, totalDuration, percentBase);
|
|
187
|
+
return lines.join(`
|
|
188
|
+
`);
|
|
189
|
+
}
|
|
190
|
+
formatNode(node, totalDuration, percentBase, prefix, isLast, isRoot) {
|
|
191
|
+
const connector = isRoot ? "" : isLast ? CHARS.LAST_CONNECTOR : CHARS.VERTICAL_CONNECTOR;
|
|
192
|
+
const prefixStr = isRoot ? "" : prefix;
|
|
193
|
+
let line = `${prefixStr}${connector} ${node.function}`;
|
|
194
|
+
if (node.durationMs !== undefined) {
|
|
195
|
+
line += color(` (${this.formatDuration(node.durationMs)})`, Colors.dim);
|
|
196
|
+
}
|
|
197
|
+
if (this.options.showPercent && percentBase > 0 && node.durationMs !== undefined && node.function !== "(root)" && !isRoot) {
|
|
198
|
+
const percent = Math.round(node.durationMs / percentBase * 100);
|
|
199
|
+
const percentStr = ` [${percent}%]`;
|
|
200
|
+
line += color(percentStr, this.colorByPercent(percent));
|
|
201
|
+
}
|
|
202
|
+
if (this.options.showTimeBar && node.durationMs !== undefined && totalDuration > 0 && !isRoot) {
|
|
203
|
+
line += " " + this.renderTimeBar(node.durationMs, totalDuration);
|
|
204
|
+
}
|
|
205
|
+
return isRoot ? color(line, Colors.bold) : line;
|
|
206
|
+
}
|
|
207
|
+
formatChildren(children, prefix, lines, totalDuration, percentBase) {
|
|
208
|
+
children.forEach((child, index) => {
|
|
209
|
+
const isLast = index === children.length - 1;
|
|
210
|
+
const newPrefix = prefix + (isLast ? " " : `${CHARS.VERTICAL} `);
|
|
211
|
+
lines.push(this.formatNode(child, totalDuration, percentBase, prefix, isLast, false));
|
|
212
|
+
if (child.children.length > 0) {
|
|
213
|
+
this.formatChildren(child.children, newPrefix, lines, totalDuration, percentBase);
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
renderTimeBar(duration, total) {
|
|
218
|
+
const width = this.options.barWidth || 10;
|
|
219
|
+
const filledWidth = Math.round(duration / total * width);
|
|
220
|
+
const emptyWidth = width - filledWidth;
|
|
221
|
+
const bar = CHARS.BAR.repeat(filledWidth) + CHARS.EMPTY.repeat(emptyWidth);
|
|
222
|
+
return color(`[${bar}]`, Colors.dim);
|
|
223
|
+
}
|
|
224
|
+
formatDuration(ms) {
|
|
225
|
+
if (ms < 1000) {
|
|
226
|
+
return `${ms}ms`;
|
|
227
|
+
} else if (ms < 60000) {
|
|
228
|
+
return `${(ms / 1000).toFixed(2)}s`;
|
|
229
|
+
} else if (ms < 3600000) {
|
|
230
|
+
const mins = Math.floor(ms / 60000);
|
|
231
|
+
const secs = Math.round(ms % 60000 / 1000);
|
|
232
|
+
return `${mins}m ${secs}s`;
|
|
233
|
+
} else {
|
|
234
|
+
const hours = Math.floor(ms / 3600000);
|
|
235
|
+
const mins = Math.floor(ms % 3600000 / 60000);
|
|
236
|
+
return `${hours}h ${mins}m`;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
formatTrees(trees) {
|
|
240
|
+
if (trees.length === 0) {
|
|
241
|
+
return "No trace trees";
|
|
242
|
+
}
|
|
243
|
+
return trees.map((tree) => this.formatTree(tree)).join(`
|
|
244
|
+
|
|
245
|
+
`);
|
|
246
|
+
}
|
|
247
|
+
toJSON(trees) {
|
|
248
|
+
return JSON.stringify(trees, null, 2);
|
|
249
|
+
}
|
|
250
|
+
formatSummary(node) {
|
|
251
|
+
const rows = [];
|
|
252
|
+
const total = node.durationMs || 0;
|
|
253
|
+
const childrenTotal = node.children.reduce((sum, c) => sum + (c.durationMs || 0), 0);
|
|
254
|
+
const percentBase = total > 0 ? total : childrenTotal;
|
|
255
|
+
const collect = (n, depth) => {
|
|
256
|
+
if (n.durationMs !== undefined) {
|
|
257
|
+
rows.push({
|
|
258
|
+
func: n.function,
|
|
259
|
+
duration: n.durationMs,
|
|
260
|
+
percent: percentBase > 0 ? Math.round(n.durationMs / percentBase * 100) : 0,
|
|
261
|
+
depth
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
n.children.forEach((child) => collect(child, depth + 1));
|
|
265
|
+
};
|
|
266
|
+
collect(node, 0);
|
|
267
|
+
rows.sort((a, b) => b.duration - a.duration);
|
|
268
|
+
const lines = [];
|
|
269
|
+
lines.push(color(`
|
|
270
|
+
=== Duration Summary ===`, Colors.bold));
|
|
271
|
+
lines.push(color(`(sorted by time consumption)
|
|
272
|
+
`, Colors.dim));
|
|
273
|
+
lines.push(color(` ${"─".repeat(65)}`, Colors.dim));
|
|
274
|
+
lines.push(color(` ${"FUNCTION".padEnd(35)} ${"TIME".padEnd(12)} %`, Colors.dim));
|
|
275
|
+
lines.push(color(` ${"─".repeat(65)}`, Colors.dim));
|
|
276
|
+
for (const row of rows) {
|
|
277
|
+
const indent = " ".repeat(row.depth);
|
|
278
|
+
const funcDisplay = row.depth > 0 ? "└─ ".repeat(row.depth) + row.func : row.func;
|
|
279
|
+
const percentStr = String(row.percent).padStart(3) + "%";
|
|
280
|
+
const percentColor = row.percent >= 50 ? Colors.red : row.percent >= 20 ? Colors.yellow : Colors.dim;
|
|
281
|
+
lines.push(` ${indent}${funcDisplay.substring(0, 35).padEnd(35)}${this.formatDuration(row.duration).padEnd(12)} ${color(percentStr, percentColor)}`);
|
|
282
|
+
}
|
|
283
|
+
return lines.join(`
|
|
284
|
+
`);
|
|
285
|
+
}
|
|
286
|
+
formatTimeline(node) {
|
|
287
|
+
const lines = [];
|
|
288
|
+
const totalDuration = node.durationMs || 0;
|
|
289
|
+
lines.push(color(`
|
|
290
|
+
=== Timeline: ${node.function} ===`, Colors.bold));
|
|
291
|
+
lines.push(color(`Total: ${this.formatDuration(totalDuration)}
|
|
292
|
+
`, Colors.dim));
|
|
293
|
+
const timeline = this.buildTimeline(node, totalDuration, 0, 0);
|
|
294
|
+
lines.push(...timeline);
|
|
295
|
+
return lines.join(`
|
|
296
|
+
`);
|
|
297
|
+
}
|
|
298
|
+
buildTimeline(node, totalDuration, absoluteOffset, depth) {
|
|
299
|
+
const lines = [];
|
|
300
|
+
const width = 40;
|
|
301
|
+
const startPos = Math.round(absoluteOffset / totalDuration * width);
|
|
302
|
+
const durationWidth = node.durationMs !== undefined ? Math.max(2, Math.round(node.durationMs / totalDuration * width)) : 2;
|
|
303
|
+
const bar = " ".repeat(Math.max(0, startPos)) + CHARS.BAR.repeat(durationWidth);
|
|
304
|
+
const indent = " ".repeat(depth);
|
|
305
|
+
const funcName = node.function.length > 25 ? "..." + node.function.slice(-22) : node.function;
|
|
306
|
+
const time = node.durationMs !== undefined ? this.formatDuration(node.durationMs) : "-";
|
|
307
|
+
const percent = node.durationMs !== undefined ? ` [${Math.round(node.durationMs / totalDuration * 100)}%]` : "";
|
|
308
|
+
lines.push(`${indent}${funcName.padEnd(25)} ${bar} ${color(time + percent, Colors.dim)}`);
|
|
309
|
+
let childOffset = absoluteOffset;
|
|
310
|
+
for (const child of node.children) {
|
|
311
|
+
lines.push(...this.buildTimeline(child, totalDuration, childOffset, depth + 1));
|
|
312
|
+
childOffset += child.durationMs || 0;
|
|
313
|
+
}
|
|
314
|
+
return lines;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
// src/env/debug/formatters/repl-formatter.ts
|
|
318
|
+
class ReplFormatter {
|
|
319
|
+
context = {};
|
|
320
|
+
history = [];
|
|
321
|
+
getWelcomeMessage() {
|
|
322
|
+
return `========================================
|
|
323
|
+
Debug REPL - Interactive Debugger
|
|
324
|
+
========================================
|
|
325
|
+
|
|
326
|
+
Commands:
|
|
327
|
+
list [limit] - List trace IDs
|
|
328
|
+
trace [options] - Show trace details
|
|
329
|
+
tree [options] - Show call tree
|
|
330
|
+
help - Show this help
|
|
331
|
+
exit - Exit REPL
|
|
332
|
+
|
|
333
|
+
Examples:
|
|
334
|
+
list 10
|
|
335
|
+
trace --func llm.invoke
|
|
336
|
+
tree --trace trace-001
|
|
337
|
+
|
|
338
|
+
========================================
|
|
339
|
+
`;
|
|
340
|
+
}
|
|
341
|
+
formatPrompt(context) {
|
|
342
|
+
const ctx = { ...this.context, ...context };
|
|
343
|
+
let prompt = "debug";
|
|
344
|
+
if (ctx.traceId) {
|
|
345
|
+
prompt += `:${ctx.traceId}`;
|
|
346
|
+
} else if (ctx.function) {
|
|
347
|
+
prompt += `:${ctx.function}`;
|
|
348
|
+
}
|
|
349
|
+
return `${prompt}> `;
|
|
350
|
+
}
|
|
351
|
+
getHelpText() {
|
|
352
|
+
return `
|
|
353
|
+
Available Commands:
|
|
354
|
+
==================
|
|
355
|
+
list [n] - List recent trace IDs (default: 10)
|
|
356
|
+
trace [options] - Show trace details
|
|
357
|
+
--func <name> - Filter by function name
|
|
358
|
+
--trace <id> - Show specific trace
|
|
359
|
+
--pretty - Pretty print output
|
|
360
|
+
--limit <n> - Limit results
|
|
361
|
+
tree [options] - Show call tree
|
|
362
|
+
--func <name> - Show tree for function
|
|
363
|
+
--trace <id> - Show tree for trace
|
|
364
|
+
clear - Clear screen
|
|
365
|
+
help - Show this help
|
|
366
|
+
exit - Exit REPL
|
|
367
|
+
`;
|
|
368
|
+
}
|
|
369
|
+
formatCommandResult(command, data) {
|
|
370
|
+
switch (command) {
|
|
371
|
+
case "list":
|
|
372
|
+
return this.formatListResult(data);
|
|
373
|
+
case "trace":
|
|
374
|
+
return this.formatTraceResult(data);
|
|
375
|
+
case "tree":
|
|
376
|
+
return this.formatTreeResult(data);
|
|
377
|
+
default:
|
|
378
|
+
return `Unknown command: ${command}`;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
formatListResult(data) {
|
|
382
|
+
const { traceIds, count } = data;
|
|
383
|
+
if (traceIds.length === 0) {
|
|
384
|
+
return "No traces found.";
|
|
385
|
+
}
|
|
386
|
+
let output = `
|
|
387
|
+
`;
|
|
388
|
+
output += ` TraceId First Time Count
|
|
389
|
+
`;
|
|
390
|
+
output += " " + "-".repeat(70) + `
|
|
391
|
+
`;
|
|
392
|
+
for (const trace of traceIds) {
|
|
393
|
+
const time = trace.firstTime.replace("T", " ").substring(0, 19);
|
|
394
|
+
output += ` ${trace.traceId.padEnd(18)} ${time.padEnd(22)} ${trace.count}
|
|
395
|
+
`;
|
|
396
|
+
}
|
|
397
|
+
output += `
|
|
398
|
+
Total: ${count} traces
|
|
399
|
+
`;
|
|
400
|
+
return output;
|
|
401
|
+
}
|
|
402
|
+
formatTraceResult(entries) {
|
|
403
|
+
if (entries.length === 0) {
|
|
404
|
+
return "No traces found.";
|
|
405
|
+
}
|
|
406
|
+
let output = "";
|
|
407
|
+
let currentTraceId = null;
|
|
408
|
+
for (const entry of entries) {
|
|
409
|
+
if (entry.traceId !== currentTraceId) {
|
|
410
|
+
currentTraceId = entry.traceId;
|
|
411
|
+
output += `
|
|
412
|
+
=== Trace: ${entry.traceId} ===
|
|
413
|
+
|
|
414
|
+
`;
|
|
415
|
+
}
|
|
416
|
+
if (entry.action === "enter") {
|
|
417
|
+
output += `>>> ${entry.function} enter:`;
|
|
418
|
+
if (entry.params) {
|
|
419
|
+
output += `
|
|
420
|
+
` + this.formatJsonCompact(entry.params);
|
|
421
|
+
}
|
|
422
|
+
output += `
|
|
423
|
+
`;
|
|
424
|
+
} else if (entry.action === "quit") {
|
|
425
|
+
output += `<<< ${entry.function} quit`;
|
|
426
|
+
if (entry.durationMs !== undefined) {
|
|
427
|
+
output += ` (${entry.durationMs}ms)`;
|
|
428
|
+
}
|
|
429
|
+
if (entry.result) {
|
|
430
|
+
output += `:
|
|
431
|
+
` + this.formatJsonCompact(entry.result);
|
|
432
|
+
}
|
|
433
|
+
output += `
|
|
434
|
+
`;
|
|
435
|
+
} else if (entry.action === "error") {
|
|
436
|
+
output += `!!! ${entry.function} error: ${entry.error}
|
|
437
|
+
`;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
return output;
|
|
441
|
+
}
|
|
442
|
+
formatTreeResult(trees) {
|
|
443
|
+
if (trees.length === 0) {
|
|
444
|
+
return "No trees found.";
|
|
445
|
+
}
|
|
446
|
+
let output = "";
|
|
447
|
+
for (const tree of trees) {
|
|
448
|
+
output += this.formatTreeNode(tree, "");
|
|
449
|
+
}
|
|
450
|
+
return output;
|
|
451
|
+
}
|
|
452
|
+
formatTreeNode(node, prefix) {
|
|
453
|
+
const duration = node.durationMs !== undefined ? ` (${node.durationMs}ms)` : "";
|
|
454
|
+
let output = `${prefix}${node.function}${duration}
|
|
455
|
+
`;
|
|
456
|
+
const childPrefix = prefix + " ";
|
|
457
|
+
for (let i = 0;i < node.children.length; i++) {
|
|
458
|
+
const isLast = i === node.children.length - 1;
|
|
459
|
+
const connector = isLast ? "└── " : "├── ";
|
|
460
|
+
output += this.formatTreeNode(node.children[i], childPrefix + connector);
|
|
461
|
+
}
|
|
462
|
+
return output;
|
|
463
|
+
}
|
|
464
|
+
formatJsonCompact(data, indent = 2) {
|
|
465
|
+
const spaces = " ".repeat(indent);
|
|
466
|
+
if (data === null || data === undefined) {
|
|
467
|
+
return `${spaces}null
|
|
468
|
+
`;
|
|
469
|
+
}
|
|
470
|
+
if (typeof data === "string") {
|
|
471
|
+
if (data.length > 200) {
|
|
472
|
+
return `${spaces}"${data.substring(0, 200)}..."
|
|
473
|
+
`;
|
|
474
|
+
}
|
|
475
|
+
return `${spaces}"${data}"
|
|
476
|
+
`;
|
|
477
|
+
}
|
|
478
|
+
if (typeof data === "number" || typeof data === "boolean") {
|
|
479
|
+
return `${spaces}${data}
|
|
480
|
+
`;
|
|
481
|
+
}
|
|
482
|
+
if (Array.isArray(data)) {
|
|
483
|
+
if (data.length === 0)
|
|
484
|
+
return `${spaces}[]
|
|
485
|
+
`;
|
|
486
|
+
let output = `${spaces}[
|
|
487
|
+
`;
|
|
488
|
+
for (const item of data) {
|
|
489
|
+
output += this.formatJsonCompact(item, indent + 1);
|
|
490
|
+
}
|
|
491
|
+
output += `${spaces}]
|
|
492
|
+
`;
|
|
493
|
+
return output;
|
|
494
|
+
}
|
|
495
|
+
if (typeof data === "object") {
|
|
496
|
+
const entries = Object.entries(data);
|
|
497
|
+
if (entries.length === 0)
|
|
498
|
+
return `${spaces}{}
|
|
499
|
+
`;
|
|
500
|
+
let output = `${spaces}{
|
|
501
|
+
`;
|
|
502
|
+
for (const [key, val] of entries) {
|
|
503
|
+
output += `${spaces} ${key}: ${JSON.stringify(val).substring(0, 50)}`;
|
|
504
|
+
if (JSON.stringify(val).length > 50) {
|
|
505
|
+
output += "...";
|
|
506
|
+
}
|
|
507
|
+
output += `
|
|
508
|
+
`;
|
|
509
|
+
}
|
|
510
|
+
output += `${spaces}}
|
|
511
|
+
`;
|
|
512
|
+
return output;
|
|
513
|
+
}
|
|
514
|
+
return `${spaces}${String(data)}
|
|
515
|
+
`;
|
|
516
|
+
}
|
|
517
|
+
parseCommand(input) {
|
|
518
|
+
const trimmed = input.trim();
|
|
519
|
+
if (!trimmed) {
|
|
520
|
+
return { command: "help", args: {} };
|
|
521
|
+
}
|
|
522
|
+
if (["exit", "quit", "q"].includes(trimmed.toLowerCase())) {
|
|
523
|
+
return { command: "exit", args: {} };
|
|
524
|
+
}
|
|
525
|
+
if (trimmed.toLowerCase() === "clear") {
|
|
526
|
+
return { command: "clear", args: {} };
|
|
527
|
+
}
|
|
528
|
+
if (["help", "?", "h"].includes(trimmed.toLowerCase())) {
|
|
529
|
+
return { command: "help", args: {} };
|
|
530
|
+
}
|
|
531
|
+
const parts = trimmed.match(/(?:[^\s"]+|"[^"]*")+/g) || [];
|
|
532
|
+
if (parts.length === 0) {
|
|
533
|
+
return { command: "help", args: {} };
|
|
534
|
+
}
|
|
535
|
+
const command = parts[0]?.toLowerCase() ?? "";
|
|
536
|
+
const args = {};
|
|
537
|
+
for (let i = 1;i < parts.length; i++) {
|
|
538
|
+
const part = parts[i];
|
|
539
|
+
if (part.startsWith("--")) {
|
|
540
|
+
const key = part.substring(2);
|
|
541
|
+
const next = parts[i + 1];
|
|
542
|
+
if (next && !next.startsWith("--")) {
|
|
543
|
+
args[key] = next;
|
|
544
|
+
i++;
|
|
545
|
+
} else {
|
|
546
|
+
args[key] = "true";
|
|
547
|
+
}
|
|
548
|
+
} else if (part.startsWith("-")) {
|
|
549
|
+
const key = part.substring(1);
|
|
550
|
+
const next = parts[i + 1];
|
|
551
|
+
if (next && !next.startsWith("-")) {
|
|
552
|
+
args[key] = next;
|
|
553
|
+
i++;
|
|
554
|
+
} else {
|
|
555
|
+
args[key] = "true";
|
|
556
|
+
}
|
|
557
|
+
} else {
|
|
558
|
+
if (command === "list" && !args.limit) {
|
|
559
|
+
args.limit = part;
|
|
560
|
+
} else if (command === "trace" && !args.func) {
|
|
561
|
+
args.func = part;
|
|
562
|
+
} else if (command === "tree" && !args.func) {
|
|
563
|
+
args.func = part;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
return { command, args };
|
|
568
|
+
}
|
|
569
|
+
setContext(context) {
|
|
570
|
+
this.context = { ...this.context, ...context };
|
|
571
|
+
}
|
|
572
|
+
getContext() {
|
|
573
|
+
return { ...this.context };
|
|
574
|
+
}
|
|
575
|
+
addToHistory(command) {
|
|
576
|
+
if (command.trim() && this.history[this.history.length - 1] !== command) {
|
|
577
|
+
this.history.push(command);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
getHistory() {
|
|
581
|
+
return [...this.history];
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
export { TraceFormatter, TreeFormatter, ReplFormatter };
|