@ai-setting/roy-agent-core 1.4.12 → 1.4.14

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.
Files changed (127) hide show
  1. package/dist/packages/core/src/config/index.js +32 -0
  2. package/dist/packages/core/src/env/agent/index.js +24 -0
  3. package/dist/packages/core/src/env/commands/index.js +14 -0
  4. package/dist/packages/core/src/env/debug/formatters/index.js +11 -0
  5. package/dist/packages/core/src/env/debug/index.js +26 -0
  6. package/dist/packages/core/src/env/hook/index.js +29 -0
  7. package/dist/packages/core/src/env/index.js +81 -0
  8. package/dist/packages/core/src/env/llm/index.js +40 -0
  9. package/dist/packages/core/src/env/log-trace/index.js +83 -0
  10. package/dist/packages/core/src/env/mcp/index.js +39 -0
  11. package/dist/packages/core/src/env/mcp/tool/index.js +14 -0
  12. package/dist/packages/core/src/env/memory/built-in/index.js +11 -0
  13. package/dist/packages/core/src/env/memory/index.js +56 -0
  14. package/dist/packages/core/src/env/memory/plugin/index.js +36 -0
  15. package/dist/packages/core/src/env/prompt/index.js +20 -0
  16. package/dist/packages/core/src/env/session/index.js +25 -0
  17. package/dist/packages/core/src/env/session/storage/index.js +18 -0
  18. package/dist/packages/core/src/env/skill/index.js +34 -0
  19. package/dist/packages/core/src/env/skill/tool/index.js +9 -0
  20. package/dist/packages/core/src/env/task/delegate/index.js +18 -0
  21. package/dist/packages/core/src/env/task/hooks/index.js +7 -0
  22. package/dist/packages/core/src/env/task/index.js +30 -0
  23. package/dist/packages/core/src/env/task/plugins/index.js +23 -0
  24. package/dist/packages/core/src/env/task/storage/index.js +14 -0
  25. package/dist/packages/core/src/env/task/tools/index.js +17 -0
  26. package/dist/packages/core/src/env/task/tools/operation/index.js +15 -0
  27. package/dist/packages/core/src/env/tool/built-in/index.js +25 -0
  28. package/dist/packages/core/src/env/tool/index.js +39 -0
  29. package/dist/packages/core/src/env/workflow/decorators/index.js +27 -0
  30. package/dist/packages/core/src/env/workflow/engine/index.js +28 -0
  31. package/dist/packages/core/src/env/workflow/index.js +132 -0
  32. package/dist/packages/core/src/env/workflow/nodes/index.js +19 -0
  33. package/dist/packages/core/src/env/workflow/service/index.js +13 -0
  34. package/dist/packages/core/src/env/workflow/storage/index.js +27 -0
  35. package/dist/packages/core/src/env/workflow/tools/index.js +159 -0
  36. package/dist/packages/core/src/env/workflow/types/index.js +94 -0
  37. package/dist/packages/core/src/env/workflow/utils/index.js +637 -0
  38. package/dist/packages/core/src/index.js +398 -0
  39. package/dist/shared/@ai-setting/roy-agent-core-04fm8177.js +393 -0
  40. package/dist/shared/@ai-setting/roy-agent-core-04qgbjbe.js +172 -0
  41. package/dist/shared/@ai-setting/roy-agent-core-084qqd7t.js +11 -0
  42. package/dist/shared/@ai-setting/roy-agent-core-0gekht4e.js +1130 -0
  43. package/dist/shared/@ai-setting/roy-agent-core-0hdry23r.js +419 -0
  44. package/dist/shared/@ai-setting/roy-agent-core-0sgn3de4.js +102 -0
  45. package/dist/{env/task/tools/index.js → shared/@ai-setting/roy-agent-core-12x57kf1.js} +1 -59
  46. package/dist/shared/@ai-setting/roy-agent-core-1f3xrrm6.js +393 -0
  47. package/dist/shared/@ai-setting/roy-agent-core-1k28kg7h.js +368 -0
  48. package/dist/shared/@ai-setting/roy-agent-core-1z1zv5g8.js +258 -0
  49. package/dist/shared/@ai-setting/roy-agent-core-2hqxnaf3.js +851 -0
  50. package/dist/shared/@ai-setting/roy-agent-core-3dfq8awb.js +587 -0
  51. package/dist/shared/@ai-setting/roy-agent-core-3takar0s.js +93 -0
  52. package/dist/shared/@ai-setting/roy-agent-core-3tnb2005.js +117 -0
  53. package/dist/shared/@ai-setting/roy-agent-core-4vmcvkav.js +14 -0
  54. package/dist/shared/@ai-setting/roy-agent-core-4ws8atva.js +107 -0
  55. package/dist/{env/workflow/nodes/index.js → shared/@ai-setting/roy-agent-core-5fbp24se.js} +8 -55
  56. package/dist/shared/@ai-setting/roy-agent-core-5my94ywp.js +66 -0
  57. package/dist/shared/@ai-setting/roy-agent-core-6j0zcmwk.js +2146 -0
  58. package/dist/shared/@ai-setting/roy-agent-core-6w4pmxc7.js +266 -0
  59. package/dist/shared/@ai-setting/roy-agent-core-7vrk3add.js +10 -0
  60. package/dist/shared/@ai-setting/roy-agent-core-8dvbn7tw.js +64 -0
  61. package/dist/{env/memory/built-in/index.js → shared/@ai-setting/roy-agent-core-8mbmrwzs.js} +22 -76
  62. package/dist/shared/@ai-setting/roy-agent-core-8wzz66qe.js +620 -0
  63. package/dist/shared/@ai-setting/roy-agent-core-9ykq91jc.js +762 -0
  64. package/dist/shared/@ai-setting/roy-agent-core-dde19zke.js +1305 -0
  65. package/dist/shared/@ai-setting/roy-agent-core-f7g67gce.js +913 -0
  66. package/dist/{env/workflow/types/index.js → shared/@ai-setting/roy-agent-core-fq5mtxsy.js} +16 -154
  67. package/dist/{env/task/hooks/index.js → shared/@ai-setting/roy-agent-core-fs0mn2jk.js} +3 -18
  68. package/dist/{config/index.js → shared/@ai-setting/roy-agent-core-fvd9g6k8.js} +140 -605
  69. package/dist/shared/@ai-setting/roy-agent-core-gv1hrn3x.js +378 -0
  70. package/dist/{env/task/tools/operation/index.js → shared/@ai-setting/roy-agent-core-gy0wp5h7.js} +1 -58
  71. package/dist/shared/@ai-setting/roy-agent-core-hyza1gm7.js +15 -0
  72. package/dist/shared/@ai-setting/roy-agent-core-j8zx62zr.js +154 -0
  73. package/dist/shared/@ai-setting/roy-agent-core-jb2exr0d.js +442 -0
  74. package/dist/shared/@ai-setting/roy-agent-core-jv3b7v9w.js +57 -0
  75. package/dist/shared/@ai-setting/roy-agent-core-k1rxf9ya.js +513 -0
  76. package/dist/shared/@ai-setting/roy-agent-core-kydc9nwb.js +60 -0
  77. package/dist/shared/@ai-setting/roy-agent-core-m2x48hw6.js +97 -0
  78. package/dist/shared/@ai-setting/roy-agent-core-m6y668cc.js +377 -0
  79. package/dist/shared/@ai-setting/roy-agent-core-nczzf0ms.js +15 -0
  80. package/dist/shared/@ai-setting/roy-agent-core-nfj6knp5.js +36 -0
  81. package/dist/shared/@ai-setting/roy-agent-core-ntrp979d.js +204 -0
  82. package/dist/shared/@ai-setting/roy-agent-core-pd7g8z5v.js +1387 -0
  83. package/dist/shared/@ai-setting/roy-agent-core-pzk1syce.js +14 -0
  84. package/dist/shared/@ai-setting/roy-agent-core-q50tg9m2.js +862 -0
  85. package/dist/shared/@ai-setting/roy-agent-core-qg9tcaph.js +11 -0
  86. package/dist/shared/@ai-setting/roy-agent-core-qhyerewk.js +20 -0
  87. package/dist/shared/@ai-setting/roy-agent-core-qxybm159.js +82 -0
  88. package/dist/shared/@ai-setting/roy-agent-core-rh9dpkpw.js +549 -0
  89. package/dist/shared/@ai-setting/roy-agent-core-rr9p1g43.js +205 -0
  90. package/dist/{env/workflow/decorators/index.js → shared/@ai-setting/roy-agent-core-sbzvpfn7.js} +8 -173
  91. package/dist/shared/@ai-setting/roy-agent-core-t22nqt4d.js +788 -0
  92. package/dist/shared/@ai-setting/roy-agent-core-tkr5ynkh.js +200 -0
  93. package/dist/shared/@ai-setting/roy-agent-core-v4aabsf0.js +303 -0
  94. package/dist/{env/hook/index.js → shared/@ai-setting/roy-agent-core-w75rafhy.js} +3 -74
  95. package/dist/{env/debug/formatters/index.js → shared/@ai-setting/roy-agent-core-w76hqkmg.js} +11 -66
  96. package/dist/shared/@ai-setting/roy-agent-core-yfbgwes2.js +408 -0
  97. package/dist/shared/@ai-setting/roy-agent-core-yn761yve.js +299 -0
  98. package/dist/shared/@ai-setting/roy-agent-core-yrzmn4m1.js +492 -0
  99. package/dist/{env/workflow/service/index.js → shared/@ai-setting/roy-agent-core-yt8wdh2w.js} +1 -57
  100. package/package.json +3 -2
  101. package/dist/env/agent/index.js +0 -3035
  102. package/dist/env/commands/index.js +0 -1685
  103. package/dist/env/debug/index.js +0 -2300
  104. package/dist/env/index.js +0 -12591
  105. package/dist/env/llm/index.js +0 -2736
  106. package/dist/env/log-trace/index.js +0 -1779
  107. package/dist/env/mcp/index.js +0 -2173
  108. package/dist/env/mcp/tool/index.js +0 -1149
  109. package/dist/env/memory/index.js +0 -2171
  110. package/dist/env/memory/plugin/index.js +0 -1263
  111. package/dist/env/prompt/index.js +0 -2107
  112. package/dist/env/session/index.js +0 -3594
  113. package/dist/env/session/storage/index.js +0 -2049
  114. package/dist/env/skill/index.js +0 -1635
  115. package/dist/env/skill/tool/index.js +0 -114
  116. package/dist/env/task/delegate/index.js +0 -1844
  117. package/dist/env/task/index.js +0 -3578
  118. package/dist/env/task/plugins/index.js +0 -1626
  119. package/dist/env/task/storage/index.js +0 -1464
  120. package/dist/env/tool/built-in/index.js +0 -1151
  121. package/dist/env/tool/index.js +0 -2284
  122. package/dist/env/workflow/engine/index.js +0 -4391
  123. package/dist/env/workflow/index.js +0 -6214
  124. package/dist/env/workflow/storage/index.js +0 -1236
  125. package/dist/env/workflow/tools/index.js +0 -1081
  126. package/dist/env/workflow/utils/index.js +0 -1631
  127. package/dist/index.js +0 -22778
@@ -1,2300 +0,0 @@
1
- // @bun
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropNames = Object.getOwnPropertyNames;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- function __accessProp(key) {
7
- return this[key];
8
- }
9
- var __toCommonJS = (from) => {
10
- var entry = (__moduleCache ??= new WeakMap).get(from), desc;
11
- if (entry)
12
- return entry;
13
- entry = __defProp({}, "__esModule", { value: true });
14
- if (from && typeof from === "object" || typeof from === "function") {
15
- for (var key of __getOwnPropNames(from))
16
- if (!__hasOwnProp.call(entry, key))
17
- __defProp(entry, key, {
18
- get: __accessProp.bind(from, key),
19
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
20
- });
21
- }
22
- __moduleCache.set(from, entry);
23
- return entry;
24
- };
25
- var __moduleCache;
26
- var __returnValue = (v) => v;
27
- function __exportSetter(name, newValue) {
28
- this[name] = __returnValue.bind(null, newValue);
29
- }
30
- var __export = (target, all) => {
31
- for (var name in all)
32
- __defProp(target, name, {
33
- get: all[name],
34
- enumerable: true,
35
- configurable: true,
36
- set: __exportSetter.bind(all, name)
37
- });
38
- };
39
- var __legacyDecorateClassTS = function(decorators, target, key, desc) {
40
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
41
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
42
- r = Reflect.decorate(decorators, target, key, desc);
43
- else
44
- for (var i = decorators.length - 1;i >= 0; i--)
45
- if (d = decorators[i])
46
- r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
47
- return c > 3 && r && Object.defineProperty(target, key, r), r;
48
- };
49
- var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
50
- var __require = import.meta.require;
51
-
52
- // packages/core/src/env/log-trace/span-storage.ts
53
- var exports_span_storage = {};
54
- __export(exports_span_storage, {
55
- SQLiteSpanStorage: () => SQLiteSpanStorage
56
- });
57
-
58
- class SQLiteSpanStorage {
59
- db = null;
60
- dbPath;
61
- initialized = false;
62
- constructor(dbPath) {
63
- if (!dbPath) {
64
- throw new Error("SQLiteSpanStorage requires a valid dbPath parameter");
65
- }
66
- if (dbPath === ":memory:") {
67
- throw new Error("SQLiteSpanStorage does not support :memory: mode. Use a file path instead.");
68
- }
69
- this.dbPath = dbPath;
70
- }
71
- async initialize() {
72
- if (this.initialized)
73
- return;
74
- const { Database } = __require("bun:sqlite");
75
- const fs2 = __require("fs");
76
- const path2 = __require("path");
77
- const dir = path2.dirname(this.dbPath);
78
- if (!fs2.existsSync(dir)) {
79
- fs2.mkdirSync(dir, { recursive: true });
80
- }
81
- this.db = new Database(this.dbPath);
82
- this.db.run("PRAGMA journal_mode=WAL");
83
- this.db.run("PRAGMA busy_timeout=5000");
84
- this.db.run("PRAGMA synchronous=NORMAL");
85
- this.db.run(`
86
- CREATE TABLE IF NOT EXISTS span (
87
- span_id TEXT PRIMARY KEY,
88
- trace_id TEXT NOT NULL,
89
- parent_span_id TEXT,
90
- name TEXT NOT NULL,
91
- kind TEXT NOT NULL,
92
- status TEXT NOT NULL,
93
- start_time INTEGER NOT NULL,
94
- end_time INTEGER,
95
- attributes TEXT,
96
- result TEXT,
97
- error TEXT,
98
- time_created INTEGER NOT NULL
99
- )
100
- `);
101
- this.db.run("CREATE INDEX IF NOT EXISTS idx_span_trace ON span(trace_id)");
102
- this.db.run("CREATE INDEX IF NOT EXISTS idx_span_parent ON span(parent_span_id)");
103
- this.initialized = true;
104
- }
105
- save(span) {
106
- if (!this.db)
107
- return;
108
- const stmt = this.db.prepare(`
109
- INSERT OR REPLACE INTO span
110
- (span_id, trace_id, parent_span_id, name, kind, status, start_time, end_time, attributes, result, error, time_created)
111
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
112
- `);
113
- const resultValue = span.result !== undefined && span.result !== null ? typeof span.result === "string" ? span.result : JSON.stringify(span.result) : null;
114
- stmt.run(span.spanId, span.traceId, span.parentSpanId || null, span.name, span.kind, span.status, span.startTime, span.endTime || null, JSON.stringify(span.attributes), resultValue, span.error || null, Date.now());
115
- }
116
- saveBatch(spans) {
117
- for (const span of spans) {
118
- this.save(span);
119
- }
120
- }
121
- findByTraceId(traceId) {
122
- if (!this.db)
123
- return [];
124
- const rows = this.db.prepare("SELECT * FROM span WHERE trace_id = ?").all(traceId);
125
- return this.buildTree(rows.map(this.rowToSpan));
126
- }
127
- findBySpanId(spanId) {
128
- if (!this.db)
129
- return;
130
- const row = this.db.prepare("SELECT * FROM span WHERE span_id = ?").get(spanId);
131
- return row ? this.rowToSpan(row) : undefined;
132
- }
133
- listTraces(limit = 10) {
134
- if (!this.db)
135
- return [];
136
- const rows = this.db.prepare(`
137
- SELECT trace_id,
138
- MIN(start_time) as start_time,
139
- MAX(end_time) as end_time,
140
- COUNT(*) as span_count
141
- FROM span
142
- GROUP BY trace_id
143
- ORDER BY start_time DESC
144
- LIMIT ?
145
- `).all(limit);
146
- return rows.map((row) => ({
147
- traceId: row.trace_id,
148
- rootSpanName: "unknown",
149
- startTime: row.start_time,
150
- endTime: row.end_time,
151
- duration: row.end_time - row.start_time,
152
- spanCount: row.span_count,
153
- status: "ok"
154
- }));
155
- }
156
- deleteByTraceId(traceId) {
157
- if (this.db) {
158
- this.db.prepare("DELETE FROM span WHERE trace_id = ?").run(traceId);
159
- }
160
- }
161
- close() {
162
- if (this.db) {
163
- this.db.close();
164
- this.db = null;
165
- }
166
- }
167
- rowToSpan(row) {
168
- return {
169
- traceId: row.trace_id,
170
- spanId: row.span_id,
171
- parentSpanId: row.parent_span_id,
172
- name: row.name,
173
- kind: row.kind,
174
- status: row.status,
175
- startTime: row.start_time,
176
- endTime: row.end_time,
177
- attributes: row.attributes ? JSON.parse(row.attributes) : {},
178
- result: row.result || undefined,
179
- error: row.error || undefined
180
- };
181
- }
182
- buildTree(spans) {
183
- const spanMap = new Map;
184
- const roots = [];
185
- for (const span of spans) {
186
- spanMap.set(span.spanId, { ...span, children: [] });
187
- }
188
- for (const span of spanMap.values()) {
189
- if (span.parentSpanId) {
190
- const parent = spanMap.get(span.parentSpanId);
191
- if (parent) {
192
- parent.children.push(span);
193
- } else {
194
- roots.push(span);
195
- }
196
- } else {
197
- roots.push(span);
198
- }
199
- }
200
- return roots;
201
- }
202
- }
203
-
204
- // packages/core/src/env/log-trace/opentelemetry/propagation.ts
205
- function padLeft(str, length) {
206
- return str.padStart(length, "0");
207
- }
208
- function isValidHex(str) {
209
- return /^[0-9a-f]+$/i.test(str);
210
- }
211
- function serialize(context) {
212
- const traceId = padLeft(context.traceId.toLowerCase(), TRACE_ID_LENGTH);
213
- const spanId = padLeft(context.spanId.toLowerCase(), PARENT_SPAN_ID_LENGTH);
214
- const parts = [
215
- TRACE_CONTEXT_VERSION,
216
- traceId,
217
- spanId,
218
- TRACE_FLAGS_SAMPLED
219
- ];
220
- return parts.join("-");
221
- }
222
- function parse(traceparent) {
223
- if (!traceparent || typeof traceparent !== "string") {
224
- return;
225
- }
226
- const trimmed = traceparent.trim();
227
- const parts = trimmed.split("-");
228
- if (parts.length !== 4) {
229
- return;
230
- }
231
- const [version, traceId, senderSpanId, flags] = parts;
232
- if (version !== TRACE_CONTEXT_VERSION) {
233
- if (version > TRACE_CONTEXT_VERSION) {
234
- return;
235
- }
236
- }
237
- if (traceId.length !== TRACE_ID_LENGTH || !isValidHex(traceId)) {
238
- return;
239
- }
240
- if (senderSpanId.length !== PARENT_SPAN_ID_LENGTH || !isValidHex(senderSpanId)) {
241
- return;
242
- }
243
- if (flags.length !== FLAGS_LENGTH || !isValidHex(flags)) {
244
- return;
245
- }
246
- return {
247
- traceId: traceId.toLowerCase(),
248
- spanId: senderSpanId.toLowerCase()
249
- };
250
- }
251
- var TRACE_CONTEXT_VERSION = "00", TRACE_FLAGS_SAMPLED = "01", TRACEPARENT_HEADER = "TRACEPARENT", TRACE_ID_LENGTH = 32, PARENT_SPAN_ID_LENGTH = 16, FLAGS_LENGTH = 2, propagation;
252
- var init_propagation = __esm(() => {
253
- propagation = {
254
- inject(carrier, context) {
255
- carrier[TRACEPARENT_HEADER] = serialize(context);
256
- },
257
- extract(carrier) {
258
- const traceparent = carrier[TRACEPARENT_HEADER];
259
- if (!traceparent) {
260
- return;
261
- }
262
- return parse(traceparent);
263
- },
264
- getTraceparentHeader() {
265
- return TRACEPARENT_HEADER;
266
- }
267
- };
268
- });
269
-
270
- // packages/core/src/env/log-trace/types.ts
271
- var SpanKind, SpanStatus;
272
- var init_types = __esm(() => {
273
- ((SpanKind2) => {
274
- SpanKind2["CLIENT"] = "client";
275
- SpanKind2["SERVER"] = "server";
276
- SpanKind2["INTERNAL"] = "internal";
277
- })(SpanKind ||= {});
278
- ((SpanStatus2) => {
279
- SpanStatus2["OK"] = "ok";
280
- SpanStatus2["ERROR"] = "error";
281
- })(SpanStatus ||= {});
282
- });
283
-
284
- // packages/core/src/env/log-trace/opentelemetry/tracer-provider.ts
285
- var exports_tracer_provider = {};
286
- __export(exports_tracer_provider, {
287
- resetTracerProvider: () => resetTracerProvider,
288
- getTracerProvider: () => getTracerProvider,
289
- OTelTracerProvider: () => OTelTracerProvider
290
- });
291
-
292
- class OTelSpanImpl {
293
- name;
294
- kind;
295
- spanContext;
296
- attributes = {};
297
- startTime;
298
- endTime;
299
- error;
300
- storage;
301
- parentSpanContext;
302
- onEnd;
303
- constructor(name, spanContext, storage, parentSpanContext, onEnd) {
304
- this.name = name;
305
- this.kind = "internal";
306
- this.spanContext = spanContext;
307
- this.parentSpanContext = parentSpanContext;
308
- this.startTime = Date.now();
309
- this.storage = storage;
310
- this.onEnd = onEnd;
311
- }
312
- setAttribute(key, value) {
313
- this.attributes[key] = value;
314
- }
315
- addEvent(name, attributes) {
316
- const events = this.attributes._events || [];
317
- events.push({ name, attributes });
318
- this.attributes._events = events;
319
- }
320
- end(result, error) {
321
- this.endTime = Date.now();
322
- if (error) {
323
- this.error = error.message;
324
- }
325
- this.storage.save({
326
- traceId: this.spanContext.traceId,
327
- spanId: this.spanContext.spanId,
328
- parentSpanId: this.spanContext.parentSpanId,
329
- name: this.name,
330
- kind: this.kind,
331
- status: error ? "error" /* ERROR */ : "ok" /* OK */,
332
- startTime: this.startTime,
333
- endTime: this.endTime,
334
- attributes: this.attributes,
335
- result,
336
- error: this.error
337
- });
338
- this.onEnd?.();
339
- }
340
- }
341
-
342
- class OTelTracerImpl {
343
- name;
344
- version;
345
- storage;
346
- currentContext;
347
- activeSpans = new Map;
348
- onSpanEndCallback;
349
- provider;
350
- constructor(name, version, storage, provider) {
351
- this.name = name;
352
- this.version = version;
353
- this.storage = storage;
354
- this.provider = provider;
355
- }
356
- setOnSpanEndCallback(callback) {
357
- this.onSpanEndCallback = callback;
358
- }
359
- getActiveSpanCount() {
360
- return this.activeSpans.size;
361
- }
362
- startSpan(name, options) {
363
- const parentFromOptions = options?.parent;
364
- const hasExplicitParent = options && "parent" in options;
365
- const globalContext = this.provider.getGlobalContext();
366
- let effectiveParentContext;
367
- if (hasExplicitParent) {
368
- effectiveParentContext = parentFromOptions;
369
- } else if (this.currentContext) {
370
- effectiveParentContext = this.currentContext;
371
- } else if (globalContext) {
372
- effectiveParentContext = globalContext;
373
- }
374
- const traceId = effectiveParentContext?.traceId || this.generateTraceId();
375
- const spanId = this.generateSpanId();
376
- let parentSpanId;
377
- if (hasExplicitParent && parentFromOptions) {
378
- parentSpanId = parentFromOptions.parentSpanId || parentFromOptions.spanId;
379
- } else if (this.currentContext) {
380
- parentSpanId = this.currentContext.spanId;
381
- } else if (globalContext) {
382
- parentSpanId = globalContext.spanId;
383
- }
384
- const spanContext = {
385
- traceId,
386
- spanId,
387
- parentSpanId
388
- };
389
- this.currentContext = {
390
- traceId,
391
- spanId,
392
- parentSpanId
393
- };
394
- const span = new OTelSpanImpl(name, spanContext, this.storage, effectiveParentContext, () => this.handleSpanEnd(spanContext.spanId, effectiveParentContext?.spanId));
395
- if (options?.attributes) {
396
- for (const [key, value] of Object.entries(options.attributes)) {
397
- span.setAttribute(key, value);
398
- }
399
- }
400
- this.activeSpans.set(spanId, span);
401
- return span;
402
- }
403
- injectToEnv(env) {
404
- if (this.currentContext) {
405
- propagation.inject(env, this.currentContext);
406
- }
407
- }
408
- getCurrentContext() {
409
- return this.currentContext;
410
- }
411
- setCurrentContext(context) {
412
- this.currentContext = context;
413
- }
414
- endSpan(span) {
415
- const spanContext = span.spanContext;
416
- this.activeSpans.delete(spanContext.spanId);
417
- const currentTraceId = this.currentContext?.traceId;
418
- if (spanContext.parentSpanId) {
419
- const parentSpan = this.activeSpans.get(spanContext.parentSpanId);
420
- if (parentSpan) {
421
- const parentContext = {
422
- traceId: spanContext.traceId,
423
- spanId: parentSpan.spanContext.spanId,
424
- parentSpanId: parentSpan.spanContext.parentSpanId
425
- };
426
- this.currentContext = parentContext;
427
- return parentContext;
428
- }
429
- if (currentTraceId) {
430
- const parentContext = {
431
- traceId: currentTraceId,
432
- spanId: spanContext.parentSpanId,
433
- parentSpanId: undefined
434
- };
435
- this.currentContext = parentContext;
436
- return parentContext;
437
- }
438
- }
439
- this.currentContext = undefined;
440
- return;
441
- }
442
- generateTraceId() {
443
- const timestamp = Date.now().toString(16).padStart(12, "0");
444
- const random = Array.from({ length: 5 }, () => Math.floor(Math.random() * 4294967295).toString(16).padStart(8, "0")).join("");
445
- return (timestamp + random).slice(0, 32).padStart(32, "0");
446
- }
447
- generateSpanId() {
448
- return Math.floor(Math.random() * 18446744073709552000).toString(16).padStart(16, "0");
449
- }
450
- handleSpanEnd(spanId, parentSpanId) {
451
- this.activeSpans.delete(spanId);
452
- const currentTraceId = this.currentContext?.traceId;
453
- if (parentSpanId) {
454
- const parentSpan = this.activeSpans.get(parentSpanId);
455
- if (parentSpan) {
456
- this.currentContext = {
457
- traceId: parentSpan.spanContext.traceId,
458
- spanId: parentSpan.spanContext.spanId,
459
- parentSpanId: parentSpan.spanContext.parentSpanId
460
- };
461
- return;
462
- }
463
- if (currentTraceId) {
464
- this.currentContext = {
465
- traceId: currentTraceId,
466
- spanId: parentSpanId,
467
- parentSpanId: undefined
468
- };
469
- return;
470
- }
471
- }
472
- this.currentContext = undefined;
473
- }
474
- }
475
-
476
- class OTelTracerProvider {
477
- tracers = new Map;
478
- storage;
479
- initialized = false;
480
- globalContext;
481
- constructor(storage, dbPath) {
482
- this.storage = storage || new SQLiteSpanStorage(dbPath || getDefaultDbPath());
483
- }
484
- async initialize() {
485
- if (this.initialized)
486
- return;
487
- await this.storage.initialize();
488
- this.initialized = true;
489
- }
490
- isInitialized() {
491
- return this.initialized;
492
- }
493
- getGlobalContext() {
494
- return this.globalContext;
495
- }
496
- setGlobalContext(context) {
497
- this.globalContext = context;
498
- }
499
- getTracer(name, version) {
500
- const key = `${name}@${version || "0.0.0"}`;
501
- let tracer = this.tracers.get(key);
502
- if (!tracer) {
503
- tracer = new OTelTracerImpl(name, version, this.storage, this);
504
- this.tracers.set(key, tracer);
505
- if (this.initialized) {
506
- this.restoreFromEnv(tracer);
507
- }
508
- }
509
- return tracer;
510
- }
511
- restoreFromEnv(tracer) {
512
- const extracted = propagation.extract(process.env);
513
- if (extracted) {
514
- tracer.setCurrentContext({
515
- traceId: extracted.traceId,
516
- spanId: extracted.spanId,
517
- parentSpanId: undefined
518
- });
519
- }
520
- }
521
- shutdown() {
522
- for (const tracer of this.tracers.values()) {}
523
- this.tracers.clear();
524
- this.storage.close();
525
- this.initialized = false;
526
- this.globalContext = undefined;
527
- delete process.env["TRACEPARENT"];
528
- delete process.env["TRACE_ID"];
529
- delete process.env["LOG_TRACE_REQUEST_ID"];
530
- }
531
- getStorage() {
532
- return this.storage;
533
- }
534
- }
535
- function getTracerProvider() {
536
- if (!providerInstance) {
537
- providerInstance = new OTelTracerProvider;
538
- }
539
- return providerInstance;
540
- }
541
- function resetTracerProvider() {
542
- if (providerInstance) {
543
- providerInstance.shutdown();
544
- providerInstance = null;
545
- }
546
- }
547
- function getDefaultDbPath() {
548
- const os = __require("os");
549
- const path2 = __require("path");
550
- const home = os.homedir();
551
- const dataHome = process.env.XDG_DATA_HOME || path2.join(home, ".local", "share");
552
- return path2.join(dataHome, "roy-agent", "traces.db");
553
- }
554
- var providerInstance = null;
555
- var init_tracer_provider = __esm(() => {
556
- init_propagation();
557
- init_types();
558
- });
559
-
560
- // packages/core/src/env/hook/types.ts
561
- function createHook(meta, fn) {
562
- return {
563
- ...meta,
564
- execute: fn
565
- };
566
- }
567
- function createPriorityHook(name, fn, priority) {
568
- return createHook({ name, priority }, fn);
569
- }
570
- // packages/core/src/env/hook/hook-manager.ts
571
- class HookManager {
572
- _hooks = new Map;
573
- componentName;
574
- componentVersion;
575
- defaultPriority;
576
- constructor(options = {}) {
577
- this.componentName = options.componentName ?? "unknown";
578
- this.componentVersion = options.componentVersion ?? "0.0.0";
579
- this.defaultPriority = options.defaultPriority ?? 0;
580
- }
581
- register(hookPoint, hook) {
582
- const hooks = this.getOrCreateHooks(hookPoint);
583
- hooks.push(hook);
584
- }
585
- registerMany(hookPoint, hooks) {
586
- const hookList = this.getOrCreateHooks(hookPoint);
587
- hookList.push(...hooks);
588
- }
589
- unregister(hookPoint, name) {
590
- const hooks = this._hooks.get(hookPoint);
591
- if (!hooks)
592
- return false;
593
- const index = hooks.findIndex((h) => h.name === name);
594
- if (index === -1)
595
- return false;
596
- hooks.splice(index, 1);
597
- return true;
598
- }
599
- unregisterAll(hookPoint) {
600
- this._hooks.delete(hookPoint);
601
- }
602
- async execute(hookPoint, data, metadata = {}) {
603
- const hooks = this._hooks.get(hookPoint);
604
- if (!hooks || hooks.length === 0)
605
- return;
606
- const sortedHooks = this.sortHooks(hooks);
607
- const ctx = this.createContext(hookPoint, data, metadata, "before");
608
- for (const hook of sortedHooks) {
609
- await this.safeExecute(hook, ctx);
610
- }
611
- }
612
- async executeAndCollect(hookPoint, data, metadata = {}) {
613
- const hooks = this._hooks.get(hookPoint);
614
- if (!hooks || hooks.length === 0)
615
- return [];
616
- const sortedHooks = this.sortHooks(hooks);
617
- const ctx = this.createContext(hookPoint, data, metadata, "before");
618
- const results = [];
619
- for (const hook of sortedHooks) {
620
- const result = await this.safeExecuteAndReturn(hook, ctx);
621
- if (result !== undefined) {
622
- results.push(result);
623
- }
624
- }
625
- return results;
626
- }
627
- count(hookPoint) {
628
- return this._hooks.get(hookPoint)?.length ?? 0;
629
- }
630
- clear() {
631
- this._hooks.clear();
632
- }
633
- getHookPoints() {
634
- return Array.from(this._hooks.keys());
635
- }
636
- hasHooks(hookPoint) {
637
- return this.count(hookPoint) > 0;
638
- }
639
- setComponentInfo(name, version) {
640
- this.componentName = name;
641
- this.componentVersion = version;
642
- }
643
- get hooks() {
644
- return this._hooks;
645
- }
646
- async executeWithIntervention(hookPoint, data, metadata = {}) {
647
- const hooks = this._hooks.get(hookPoint);
648
- if (!hooks || hooks.length === 0) {
649
- return { stopped: false, results: [] };
650
- }
651
- const sortedHooks = this.sortHooks(hooks);
652
- const ctx = this.createContext(hookPoint, data, metadata, "before");
653
- const results = [];
654
- let stopped = false;
655
- let action;
656
- for (const hook of sortedHooks) {
657
- if (stopped)
658
- break;
659
- const result = await this.safeExecuteAndReturn(hook, ctx);
660
- results.push(result);
661
- if (result && typeof result === "object" && "stopped" in result) {
662
- const hookResult = result;
663
- if (hookResult.stopped) {
664
- stopped = true;
665
- action = hookResult.action;
666
- }
667
- }
668
- }
669
- return { stopped, action, results };
670
- }
671
- getOrCreateHooks(hookPoint) {
672
- let hooks = this._hooks.get(hookPoint);
673
- if (!hooks) {
674
- hooks = [];
675
- this._hooks.set(hookPoint, hooks);
676
- }
677
- return hooks;
678
- }
679
- sortHooks(hooks) {
680
- return [...hooks].sort((a, b) => {
681
- const priorityA = a.priority ?? this.defaultPriority;
682
- const priorityB = b.priority ?? this.defaultPriority;
683
- return priorityA - priorityB;
684
- });
685
- }
686
- createContext(hookPoint, data, metadata, phase) {
687
- return {
688
- component: {
689
- name: this.componentName,
690
- version: this.componentVersion
691
- },
692
- data,
693
- metadata,
694
- phase,
695
- hookPoint
696
- };
697
- }
698
- async safeExecute(hook, ctx) {
699
- try {
700
- await hook.execute(ctx);
701
- } catch (error) {
702
- console.error(`Hook "${hook.name}" failed:`, error);
703
- }
704
- }
705
- async safeExecuteAndReturn(hook, ctx) {
706
- try {
707
- return await hook.execute(ctx);
708
- } catch (error) {
709
- console.error(`Hook "${hook.name}" failed:`, error);
710
- return;
711
- }
712
- }
713
- }
714
- // packages/core/src/env/hook/global-hook-manager.ts
715
- var globalHookManager = new HookManager;
716
- var AgentHookPoints = {
717
- BEFORE_START: "agent:before.start",
718
- BEFORE_LLM: "agent:before.llm",
719
- AFTER_LLM: "agent:after.llm",
720
- BEFORE_TOOL: "agent:before.tool",
721
- AFTER_TOOL: "agent:after.tool",
722
- ON_ITERATION: "agent:on.iteration",
723
- ON_THRESHOLD: "agent:on.threshold",
724
- AFTER_COMPLETE: "agent:after.complete",
725
- ON_ERROR: "agent:on.error"
726
- };
727
- var LLMHookPoints = {
728
- BEFORE_INVOKE: "llm:before.invoke",
729
- AFTER_INVOKE: "llm:after.invoke",
730
- ON_STREAM: "llm:on.stream"
731
- };
732
- var ToolHookPoints = {
733
- BEFORE_EXECUTE: "tool:before.execute",
734
- AFTER_EXECUTE: "tool:after.execute",
735
- BEFORE_REGISTER: "tool:before.register",
736
- AFTER_REGISTER: "tool:after.register",
737
- ON_ERROR: "tool:on.error"
738
- };
739
- var hookPointAliases = {
740
- "before.tool": "tool:before.execute",
741
- "after.tool": "tool:after.execute",
742
- "llm.before-invoke": "llm:before.invoke",
743
- "llm.after-invoke": "llm:after.invoke",
744
- "llm.stream": "llm:on.stream"
745
- };
746
- function setupAliasHooks() {
747
- const originalRegister = globalHookManager.register.bind(globalHookManager);
748
- globalHookManager.register = function(hookPoint, hook) {
749
- originalRegister(hookPoint, hook);
750
- const alias = hookPointAliases[hookPoint];
751
- if (alias) {
752
- originalRegister(alias, hook);
753
- }
754
- };
755
- }
756
- setupAliasHooks();
757
- async function executeAgentHook(hookPoint, data, metadata = {}) {
758
- await globalHookManager.execute(hookPoint, data, metadata);
759
- }
760
- async function executeAgentHookWithIntervention(hookPoint, data, metadata = {}) {
761
- return globalHookManager.executeWithIntervention(hookPoint, data, metadata);
762
- }
763
- async function executeLLMHook(hookPoint, data, metadata = {}) {
764
- await globalHookManager.execute(hookPoint, data, metadata);
765
- }
766
- async function executeToolHook(hookPoint, data, metadata = {}) {
767
- await globalHookManager.execute(hookPoint, data, metadata);
768
- }
769
- // packages/core/src/env/debug/formatters/trace-formatter.ts
770
- class TraceFormatter {
771
- formatEntry(entry, options = {}) {
772
- const { pretty = false } = options;
773
- const actionSymbol = entry.action === "enter" ? ">>>" : entry.action === "error" ? "!!!" : "<<<";
774
- let output = `${actionSymbol} ${entry.function} ${entry.action}`;
775
- if (entry.action === "enter" && entry.params) {
776
- output += `
777
- ` + this.formatData(entry.params, options);
778
- } else if (entry.action === "quit") {
779
- if (entry.durationMs !== undefined) {
780
- output += ` (${entry.durationMs}ms)`;
781
- }
782
- if (entry.result) {
783
- output += `
784
- ` + this.formatData(entry.result, options);
785
- }
786
- } else if (entry.action === "error" && entry.error) {
787
- output += `: ${entry.error}`;
788
- }
789
- if (pretty) {
790
- output = this.indentMultilineContent(output);
791
- }
792
- return output;
793
- }
794
- indentMultilineContent(text, indent = " ") {
795
- const lines = text.split(`
796
- `);
797
- if (lines.length <= 1)
798
- return text;
799
- return lines.map((line, i) => i === 0 ? line : `${indent}${line}`).join(`
800
- `);
801
- }
802
- formatEntries(entries, options = {}) {
803
- if (entries.length === 0) {
804
- return "No trace entries";
805
- }
806
- const formatted = entries.map((entry) => this.formatEntry(entry, options));
807
- if (options.pretty) {
808
- return formatted.join(`
809
- ` + "-".repeat(80) + `
810
- `);
811
- }
812
- return formatted.join(`
813
- `);
814
- }
815
- formatData(data, options = {}) {
816
- const { pretty = false, maxDepth = 10 } = options;
817
- if (pretty) {
818
- return this.formatPretty(data, 0, maxDepth);
819
- }
820
- return JSON.stringify(data);
821
- }
822
- formatPretty(data, indent = 0, maxDepth) {
823
- const baseIndent = " ".repeat(indent);
824
- const nextIndent = " ".repeat(indent + 1);
825
- if (data === null || data === undefined) {
826
- return String(data);
827
- }
828
- if (typeof data === "string") {
829
- if (data.includes(`
830
- `)) {
831
- return data.split(`
832
- `).map((line, i) => i === 0 ? line : `${nextIndent}${line}`).join(`
833
- `);
834
- }
835
- return data;
836
- }
837
- if (typeof data === "number" || typeof data === "boolean") {
838
- return String(data);
839
- }
840
- if (Array.isArray(data)) {
841
- if (data.length === 0)
842
- return "[]";
843
- const items = data.map((item) => {
844
- const formatted = this.formatPretty(item, indent + 1, maxDepth);
845
- return formatted.split(`
846
- `).map((line) => ` ${line}`).join(`
847
- `);
848
- });
849
- return `[
850
- ` + items.join(`,
851
- `) + `
852
- ` + baseIndent + "]";
853
- }
854
- if (typeof data === "object") {
855
- const obj = data;
856
- const keys = Object.keys(obj);
857
- if (keys.length === 0)
858
- return "{}";
859
- if (indent >= maxDepth) {
860
- return "{...}";
861
- }
862
- const entries = keys.map((key) => {
863
- const value = obj[key];
864
- let formatted;
865
- if (typeof value === "object" && value !== null) {
866
- formatted = this.formatPretty(value, indent + 1, maxDepth);
867
- } else if (typeof value === "string" && value.includes(`
868
- `)) {
869
- formatted = value.split(`
870
- `).map((line, i) => i === 0 ? line : `${nextIndent}${line}`).join(`
871
- `);
872
- } else {
873
- formatted = JSON.stringify(value);
874
- }
875
- return ` ${key}: ` + formatted.split(`
876
- `).map((line, i) => i === 0 ? line : nextIndent + line).join(`
877
- `);
878
- });
879
- return `{
880
- ` + entries.join(`,
881
- `) + `
882
- ` + baseIndent + "}";
883
- }
884
- return JSON.stringify(data);
885
- }
886
- toJSON(entries) {
887
- return JSON.stringify(entries, null, 2);
888
- }
889
- toSummary(entries) {
890
- if (entries.length === 0) {
891
- return "No trace entries";
892
- }
893
- const functions = new Set(entries.map((e) => e.function));
894
- const actions = entries.reduce((acc, e) => {
895
- acc[e.action] = (acc[e.action] || 0) + 1;
896
- return acc;
897
- }, {});
898
- let summary = `Trace Summary (${entries.length} entries)
899
- `;
900
- summary += `Functions: ${[...functions].join(", ")}
901
- `;
902
- summary += `Actions: ${Object.entries(actions).map(([k, v]) => `${k}=${v}`).join(", ")}`;
903
- return summary;
904
- }
905
- }
906
- // packages/core/src/env/debug/formatters/tree-formatter.ts
907
- var Colors = {
908
- reset: "\x1B[0m",
909
- bold: "\x1B[1m",
910
- dim: "\x1B[2m",
911
- red: "\x1B[31m",
912
- green: "\x1B[32m",
913
- yellow: "\x1B[33m",
914
- cyan: "\x1B[36m",
915
- white: "\x1B[37m"
916
- };
917
- function color(text, colorCode) {
918
- return `${colorCode}${text}${Colors.reset}`;
919
- }
920
- var CHARS = {
921
- VERTICAL: "\u2502",
922
- VERTICAL_CONNECTOR: "\u251C\u2500\u2500",
923
- LAST_CONNECTOR: "\u2514\u2500\u2500",
924
- SPACE: " ",
925
- BAR: "\u2588",
926
- EMPTY: "\u2591",
927
- DASH: "\u2500"
928
- };
929
-
930
- class TreeFormatter {
931
- options;
932
- constructor(options = {}) {
933
- this.options = {
934
- showPercent: true,
935
- showTimeBar: false,
936
- barWidth: 10,
937
- ...options
938
- };
939
- }
940
- colorByPercent(percent) {
941
- if (percent >= 80)
942
- return Colors.red;
943
- if (percent >= 50)
944
- return Colors.yellow;
945
- if (percent >= 20)
946
- return Colors.cyan;
947
- return Colors.dim;
948
- }
949
- formatTree(node) {
950
- const lines = [];
951
- const totalDuration = node.durationMs || 0;
952
- const percentBase = node.children.reduce((sum, c) => sum + (c.durationMs || 0), 0) || totalDuration;
953
- lines.push(this.formatNode(node, totalDuration, percentBase, "", true, true));
954
- this.formatChildren(node.children, "", lines, totalDuration, percentBase);
955
- return lines.join(`
956
- `);
957
- }
958
- formatNode(node, totalDuration, percentBase, prefix, isLast, isRoot) {
959
- const connector = isRoot ? "" : isLast ? CHARS.LAST_CONNECTOR : CHARS.VERTICAL_CONNECTOR;
960
- const prefixStr = isRoot ? "" : prefix;
961
- let line = `${prefixStr}${connector} ${node.function}`;
962
- if (node.durationMs !== undefined) {
963
- line += color(` (${this.formatDuration(node.durationMs)})`, Colors.dim);
964
- }
965
- if (this.options.showPercent && percentBase > 0 && node.durationMs !== undefined && node.function !== "(root)" && !isRoot) {
966
- const percent = Math.round(node.durationMs / percentBase * 100);
967
- const percentStr = ` [${percent}%]`;
968
- line += color(percentStr, this.colorByPercent(percent));
969
- }
970
- if (this.options.showTimeBar && node.durationMs !== undefined && totalDuration > 0 && !isRoot) {
971
- line += " " + this.renderTimeBar(node.durationMs, totalDuration);
972
- }
973
- return isRoot ? color(line, Colors.bold) : line;
974
- }
975
- formatChildren(children, prefix, lines, totalDuration, percentBase) {
976
- children.forEach((child, index) => {
977
- const isLast = index === children.length - 1;
978
- const newPrefix = prefix + (isLast ? " " : `${CHARS.VERTICAL} `);
979
- lines.push(this.formatNode(child, totalDuration, percentBase, prefix, isLast, false));
980
- if (child.children.length > 0) {
981
- this.formatChildren(child.children, newPrefix, lines, totalDuration, percentBase);
982
- }
983
- });
984
- }
985
- renderTimeBar(duration, total) {
986
- const width = this.options.barWidth || 10;
987
- const filledWidth = Math.round(duration / total * width);
988
- const emptyWidth = width - filledWidth;
989
- const bar = CHARS.BAR.repeat(filledWidth) + CHARS.EMPTY.repeat(emptyWidth);
990
- return color(`[${bar}]`, Colors.dim);
991
- }
992
- formatDuration(ms) {
993
- if (ms < 1000) {
994
- return `${ms}ms`;
995
- } else if (ms < 60000) {
996
- return `${(ms / 1000).toFixed(2)}s`;
997
- } else if (ms < 3600000) {
998
- const mins = Math.floor(ms / 60000);
999
- const secs = Math.round(ms % 60000 / 1000);
1000
- return `${mins}m ${secs}s`;
1001
- } else {
1002
- const hours = Math.floor(ms / 3600000);
1003
- const mins = Math.floor(ms % 3600000 / 60000);
1004
- return `${hours}h ${mins}m`;
1005
- }
1006
- }
1007
- formatTrees(trees) {
1008
- if (trees.length === 0) {
1009
- return "No trace trees";
1010
- }
1011
- return trees.map((tree) => this.formatTree(tree)).join(`
1012
-
1013
- `);
1014
- }
1015
- toJSON(trees) {
1016
- return JSON.stringify(trees, null, 2);
1017
- }
1018
- formatSummary(node) {
1019
- const rows = [];
1020
- const total = node.durationMs || 0;
1021
- const childrenTotal = node.children.reduce((sum, c) => sum + (c.durationMs || 0), 0);
1022
- const percentBase = total > 0 ? total : childrenTotal;
1023
- const collect = (n, depth) => {
1024
- if (n.durationMs !== undefined) {
1025
- rows.push({
1026
- func: n.function,
1027
- duration: n.durationMs,
1028
- percent: percentBase > 0 ? Math.round(n.durationMs / percentBase * 100) : 0,
1029
- depth
1030
- });
1031
- }
1032
- n.children.forEach((child) => collect(child, depth + 1));
1033
- };
1034
- collect(node, 0);
1035
- rows.sort((a, b) => b.duration - a.duration);
1036
- const lines = [];
1037
- lines.push(color(`
1038
- === Duration Summary ===`, Colors.bold));
1039
- lines.push(color(`(sorted by time consumption)
1040
- `, Colors.dim));
1041
- lines.push(color(` ${"\u2500".repeat(65)}`, Colors.dim));
1042
- lines.push(color(` ${"FUNCTION".padEnd(35)} ${"TIME".padEnd(12)} %`, Colors.dim));
1043
- lines.push(color(` ${"\u2500".repeat(65)}`, Colors.dim));
1044
- for (const row of rows) {
1045
- const indent = " ".repeat(row.depth);
1046
- const funcDisplay = row.depth > 0 ? "\u2514\u2500 ".repeat(row.depth) + row.func : row.func;
1047
- const percentStr = String(row.percent).padStart(3) + "%";
1048
- const percentColor = row.percent >= 50 ? Colors.red : row.percent >= 20 ? Colors.yellow : Colors.dim;
1049
- lines.push(` ${indent}${funcDisplay.substring(0, 35).padEnd(35)}${this.formatDuration(row.duration).padEnd(12)} ${color(percentStr, percentColor)}`);
1050
- }
1051
- return lines.join(`
1052
- `);
1053
- }
1054
- formatTimeline(node) {
1055
- const lines = [];
1056
- const totalDuration = node.durationMs || 0;
1057
- lines.push(color(`
1058
- === Timeline: ${node.function} ===`, Colors.bold));
1059
- lines.push(color(`Total: ${this.formatDuration(totalDuration)}
1060
- `, Colors.dim));
1061
- const timeline = this.buildTimeline(node, totalDuration, 0, 0);
1062
- lines.push(...timeline);
1063
- return lines.join(`
1064
- `);
1065
- }
1066
- buildTimeline(node, totalDuration, absoluteOffset, depth) {
1067
- const lines = [];
1068
- const width = 40;
1069
- const startPos = Math.round(absoluteOffset / totalDuration * width);
1070
- const durationWidth = node.durationMs !== undefined ? Math.max(2, Math.round(node.durationMs / totalDuration * width)) : 2;
1071
- const bar = " ".repeat(Math.max(0, startPos)) + CHARS.BAR.repeat(durationWidth);
1072
- const indent = " ".repeat(depth);
1073
- const funcName = node.function.length > 25 ? "..." + node.function.slice(-22) : node.function;
1074
- const time = node.durationMs !== undefined ? this.formatDuration(node.durationMs) : "-";
1075
- const percent = node.durationMs !== undefined ? ` [${Math.round(node.durationMs / totalDuration * 100)}%]` : "";
1076
- lines.push(`${indent}${funcName.padEnd(25)} ${bar} ${color(time + percent, Colors.dim)}`);
1077
- let childOffset = absoluteOffset;
1078
- for (const child of node.children) {
1079
- lines.push(...this.buildTimeline(child, totalDuration, childOffset, depth + 1));
1080
- childOffset += child.durationMs || 0;
1081
- }
1082
- return lines;
1083
- }
1084
- }
1085
- // packages/core/src/env/debug/formatters/repl-formatter.ts
1086
- class ReplFormatter {
1087
- context = {};
1088
- history = [];
1089
- getWelcomeMessage() {
1090
- return `========================================
1091
- Debug REPL - Interactive Debugger
1092
- ========================================
1093
-
1094
- Commands:
1095
- list [limit] - List trace IDs
1096
- trace [options] - Show trace details
1097
- tree [options] - Show call tree
1098
- help - Show this help
1099
- exit - Exit REPL
1100
-
1101
- Examples:
1102
- list 10
1103
- trace --func llm.invoke
1104
- tree --trace trace-001
1105
-
1106
- ========================================
1107
- `;
1108
- }
1109
- formatPrompt(context) {
1110
- const ctx = { ...this.context, ...context };
1111
- let prompt = "debug";
1112
- if (ctx.traceId) {
1113
- prompt += `:${ctx.traceId}`;
1114
- } else if (ctx.function) {
1115
- prompt += `:${ctx.function}`;
1116
- }
1117
- return `${prompt}> `;
1118
- }
1119
- getHelpText() {
1120
- return `
1121
- Available Commands:
1122
- ==================
1123
- list [n] - List recent trace IDs (default: 10)
1124
- trace [options] - Show trace details
1125
- --func <name> - Filter by function name
1126
- --trace <id> - Show specific trace
1127
- --pretty - Pretty print output
1128
- --limit <n> - Limit results
1129
- tree [options] - Show call tree
1130
- --func <name> - Show tree for function
1131
- --trace <id> - Show tree for trace
1132
- clear - Clear screen
1133
- help - Show this help
1134
- exit - Exit REPL
1135
- `;
1136
- }
1137
- formatCommandResult(command, data) {
1138
- switch (command) {
1139
- case "list":
1140
- return this.formatListResult(data);
1141
- case "trace":
1142
- return this.formatTraceResult(data);
1143
- case "tree":
1144
- return this.formatTreeResult(data);
1145
- default:
1146
- return `Unknown command: ${command}`;
1147
- }
1148
- }
1149
- formatListResult(data) {
1150
- const { traceIds, count } = data;
1151
- if (traceIds.length === 0) {
1152
- return "No traces found.";
1153
- }
1154
- let output = `
1155
- `;
1156
- output += ` TraceId First Time Count
1157
- `;
1158
- output += " " + "-".repeat(70) + `
1159
- `;
1160
- for (const trace of traceIds) {
1161
- const time = trace.firstTime.replace("T", " ").substring(0, 19);
1162
- output += ` ${trace.traceId.padEnd(18)} ${time.padEnd(22)} ${trace.count}
1163
- `;
1164
- }
1165
- output += `
1166
- Total: ${count} traces
1167
- `;
1168
- return output;
1169
- }
1170
- formatTraceResult(entries) {
1171
- if (entries.length === 0) {
1172
- return "No traces found.";
1173
- }
1174
- let output = "";
1175
- let currentTraceId = null;
1176
- for (const entry of entries) {
1177
- if (entry.traceId !== currentTraceId) {
1178
- currentTraceId = entry.traceId;
1179
- output += `
1180
- === Trace: ${entry.traceId} ===
1181
-
1182
- `;
1183
- }
1184
- if (entry.action === "enter") {
1185
- output += `>>> ${entry.function} enter:`;
1186
- if (entry.params) {
1187
- output += `
1188
- ` + this.formatJsonCompact(entry.params);
1189
- }
1190
- output += `
1191
- `;
1192
- } else if (entry.action === "quit") {
1193
- output += `<<< ${entry.function} quit`;
1194
- if (entry.durationMs !== undefined) {
1195
- output += ` (${entry.durationMs}ms)`;
1196
- }
1197
- if (entry.result) {
1198
- output += `:
1199
- ` + this.formatJsonCompact(entry.result);
1200
- }
1201
- output += `
1202
- `;
1203
- } else if (entry.action === "error") {
1204
- output += `!!! ${entry.function} error: ${entry.error}
1205
- `;
1206
- }
1207
- }
1208
- return output;
1209
- }
1210
- formatTreeResult(trees) {
1211
- if (trees.length === 0) {
1212
- return "No trees found.";
1213
- }
1214
- let output = "";
1215
- for (const tree of trees) {
1216
- output += this.formatTreeNode(tree, "");
1217
- }
1218
- return output;
1219
- }
1220
- formatTreeNode(node, prefix) {
1221
- const duration = node.durationMs !== undefined ? ` (${node.durationMs}ms)` : "";
1222
- let output = `${prefix}${node.function}${duration}
1223
- `;
1224
- const childPrefix = prefix + " ";
1225
- for (let i = 0;i < node.children.length; i++) {
1226
- const isLast = i === node.children.length - 1;
1227
- const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
1228
- output += this.formatTreeNode(node.children[i], childPrefix + connector);
1229
- }
1230
- return output;
1231
- }
1232
- formatJsonCompact(data, indent = 2) {
1233
- const spaces = " ".repeat(indent);
1234
- if (data === null || data === undefined) {
1235
- return `${spaces}null
1236
- `;
1237
- }
1238
- if (typeof data === "string") {
1239
- if (data.length > 200) {
1240
- return `${spaces}"${data.substring(0, 200)}..."
1241
- `;
1242
- }
1243
- return `${spaces}"${data}"
1244
- `;
1245
- }
1246
- if (typeof data === "number" || typeof data === "boolean") {
1247
- return `${spaces}${data}
1248
- `;
1249
- }
1250
- if (Array.isArray(data)) {
1251
- if (data.length === 0)
1252
- return `${spaces}[]
1253
- `;
1254
- let output = `${spaces}[
1255
- `;
1256
- for (const item of data) {
1257
- output += this.formatJsonCompact(item, indent + 1);
1258
- }
1259
- output += `${spaces}]
1260
- `;
1261
- return output;
1262
- }
1263
- if (typeof data === "object") {
1264
- const entries = Object.entries(data);
1265
- if (entries.length === 0)
1266
- return `${spaces}{}
1267
- `;
1268
- let output = `${spaces}{
1269
- `;
1270
- for (const [key, val] of entries) {
1271
- output += `${spaces} ${key}: ${JSON.stringify(val).substring(0, 50)}`;
1272
- if (JSON.stringify(val).length > 50) {
1273
- output += "...";
1274
- }
1275
- output += `
1276
- `;
1277
- }
1278
- output += `${spaces}}
1279
- `;
1280
- return output;
1281
- }
1282
- return `${spaces}${String(data)}
1283
- `;
1284
- }
1285
- parseCommand(input) {
1286
- const trimmed = input.trim();
1287
- if (!trimmed) {
1288
- return { command: "help", args: {} };
1289
- }
1290
- if (["exit", "quit", "q"].includes(trimmed.toLowerCase())) {
1291
- return { command: "exit", args: {} };
1292
- }
1293
- if (trimmed.toLowerCase() === "clear") {
1294
- return { command: "clear", args: {} };
1295
- }
1296
- if (["help", "?", "h"].includes(trimmed.toLowerCase())) {
1297
- return { command: "help", args: {} };
1298
- }
1299
- const parts = trimmed.match(/(?:[^\s"]+|"[^"]*")+/g) || [];
1300
- if (parts.length === 0) {
1301
- return { command: "help", args: {} };
1302
- }
1303
- const command = parts[0]?.toLowerCase() ?? "";
1304
- const args = {};
1305
- for (let i = 1;i < parts.length; i++) {
1306
- const part = parts[i];
1307
- if (part.startsWith("--")) {
1308
- const key = part.substring(2);
1309
- const next = parts[i + 1];
1310
- if (next && !next.startsWith("--")) {
1311
- args[key] = next;
1312
- i++;
1313
- } else {
1314
- args[key] = "true";
1315
- }
1316
- } else if (part.startsWith("-")) {
1317
- const key = part.substring(1);
1318
- const next = parts[i + 1];
1319
- if (next && !next.startsWith("-")) {
1320
- args[key] = next;
1321
- i++;
1322
- } else {
1323
- args[key] = "true";
1324
- }
1325
- } else {
1326
- if (command === "list" && !args.limit) {
1327
- args.limit = part;
1328
- } else if (command === "trace" && !args.func) {
1329
- args.func = part;
1330
- } else if (command === "tree" && !args.func) {
1331
- args.func = part;
1332
- }
1333
- }
1334
- }
1335
- return { command, args };
1336
- }
1337
- setContext(context) {
1338
- this.context = { ...this.context, ...context };
1339
- }
1340
- getContext() {
1341
- return { ...this.context };
1342
- }
1343
- addToHistory(command) {
1344
- if (command.trim() && this.history[this.history.length - 1] !== command) {
1345
- this.history.push(command);
1346
- }
1347
- }
1348
- getHistory() {
1349
- return [...this.history];
1350
- }
1351
- }
1352
- // packages/core/src/env/component.ts
1353
- class BaseComponent {
1354
- _status = "created";
1355
- _enabled = true;
1356
- env;
1357
- hookManager;
1358
- constructor() {
1359
- this.hookManager = new HookManager;
1360
- }
1361
- getStatus() {
1362
- return this._status;
1363
- }
1364
- getConfig() {
1365
- return {
1366
- name: this.name,
1367
- version: this.version,
1368
- enabled: this._enabled,
1369
- env: this.env
1370
- };
1371
- }
1372
- isEnvInitialized() {
1373
- return this._status !== "created";
1374
- }
1375
- setStatus(status) {
1376
- this._status = status;
1377
- }
1378
- getEnv() {
1379
- return this.env;
1380
- }
1381
- async init(config) {
1382
- if (config?.env) {
1383
- this.env = config.env;
1384
- }
1385
- this.setStatus("initializing");
1386
- try {
1387
- if (config?.name)
1388
- Object.defineProperty(this, "name", { value: config.name, writable: false });
1389
- if (config?.version)
1390
- Object.defineProperty(this, "version", { value: config.version, writable: false });
1391
- } catch {}
1392
- if (config?.enabled !== undefined)
1393
- this._enabled = config.enabled;
1394
- this.hookManager.setComponentInfo(this.name, this.version);
1395
- await this.onInit();
1396
- this.setStatus("running");
1397
- }
1398
- async start() {
1399
- if (this._started)
1400
- return;
1401
- this._started = true;
1402
- await this.onStart();
1403
- this.setStatus("running");
1404
- }
1405
- async stop() {
1406
- this.setStatus("stopping");
1407
- this.hookManager.clear();
1408
- await this.onStop();
1409
- this.setStatus("stopped");
1410
- }
1411
- async onInit() {}
1412
- async onStart() {}
1413
- async onStop() {}
1414
- registerHook(hookPoint, hook) {
1415
- this.hookManager.register(hookPoint, hook);
1416
- }
1417
- addHook(hookPoint, name, fn, priority) {
1418
- this.hookManager.register(hookPoint, createHook({ name, priority }, fn));
1419
- }
1420
- removeHook(hookPoint, name) {
1421
- return this.hookManager.unregister(hookPoint, name);
1422
- }
1423
- async executeHooks(hookPoint, data, metadata) {
1424
- await this.hookManager.execute(hookPoint, data, metadata);
1425
- }
1426
- getConfigComponent() {
1427
- return this.env?.getComponent("config");
1428
- }
1429
- getRuntimeConfig(key, defaultValue) {
1430
- const configComponent = this.getConfigComponent();
1431
- if (configComponent) {
1432
- const value = configComponent.get(key);
1433
- if (value !== undefined) {
1434
- return value;
1435
- }
1436
- }
1437
- return defaultValue;
1438
- }
1439
- }
1440
-
1441
- // packages/core/src/env/debug/reader/log-reader.ts
1442
- import * as fs from "fs";
1443
- import * as readline from "readline";
1444
- import * as path from "path";
1445
- import { glob } from "glob";
1446
- function getXDGDataHome() {
1447
- return process.env.XDG_DATA_HOME || path.join(process.env.HOME || "/home/" + (process.env.USER || "user"), ".local", "share");
1448
- }
1449
-
1450
- class LogReader {
1451
- logDir;
1452
- constructor(options) {
1453
- this.logDir = options?.logDir || path.join(getXDGDataHome(), "roy-agent", "logs");
1454
- }
1455
- getLogPath(filename) {
1456
- if (!filename) {
1457
- return path.join(this.logDir, "app.log");
1458
- }
1459
- if (path.isAbsolute(filename)) {
1460
- return filename;
1461
- }
1462
- return path.join(this.logDir, filename);
1463
- }
1464
- async findLogFiles(pattern = "*.log") {
1465
- try {
1466
- const normalizedDir = this.logDir.replace(/\\/g, "/");
1467
- const fullPattern = `${normalizedDir}/${pattern}`;
1468
- const files = await glob(fullPattern);
1469
- return files.sort();
1470
- } catch {
1471
- return [];
1472
- }
1473
- }
1474
- getDefaultLogDir() {
1475
- return this.logDir;
1476
- }
1477
- async* readLines(filepath, options) {
1478
- const sinceTime = options?.since ? this.parseTime(options.since) : null;
1479
- const untilTime = options?.until ? this.parseTime(options.until) : null;
1480
- if (!fs.existsSync(filepath)) {
1481
- return;
1482
- }
1483
- const fileStream = fs.createReadStream(filepath, { encoding: "utf-8" });
1484
- const rl = readline.createInterface({
1485
- input: fileStream,
1486
- crlfDelay: Infinity
1487
- });
1488
- try {
1489
- for await (const line of rl) {
1490
- if (!line.trim())
1491
- continue;
1492
- if (sinceTime || untilTime) {
1493
- const lineTime = this.extractTimestamp(line);
1494
- if (lineTime) {
1495
- if (sinceTime && lineTime < sinceTime)
1496
- continue;
1497
- if (untilTime && lineTime > untilTime)
1498
- continue;
1499
- }
1500
- }
1501
- yield line;
1502
- }
1503
- } finally {
1504
- rl.close();
1505
- fileStream.destroy();
1506
- }
1507
- }
1508
- extractTimestamp(line) {
1509
- const match = line.match(/^(\d{4}-\d{2}-\d{2})[T ](\d{2}:\d{2}:\d{2})/);
1510
- if (!match)
1511
- return null;
1512
- const datePart = match[1];
1513
- const timePart = match[2];
1514
- const isoString = `${datePart}T${timePart}`;
1515
- const timestamp = new Date(isoString).getTime();
1516
- return isNaN(timestamp) ? null : timestamp;
1517
- }
1518
- parseTime(timeStr) {
1519
- const now = Date.now();
1520
- const normalizedStr = timeStr.replace("T", " ");
1521
- const absoluteTime = new Date(normalizedStr).getTime();
1522
- if (!isNaN(absoluteTime) && absoluteTime > 0) {
1523
- return absoluteTime;
1524
- }
1525
- const originalTime = new Date(timeStr).getTime();
1526
- if (!isNaN(originalTime) && originalTime > 0) {
1527
- return originalTime;
1528
- }
1529
- const relativeMatch = timeStr.match(/^(\d+)([hms])$/);
1530
- if (relativeMatch) {
1531
- const value = parseInt(relativeMatch[1], 10);
1532
- const unit = relativeMatch[2];
1533
- switch (unit) {
1534
- case "h":
1535
- return now - value * 60 * 60 * 1000;
1536
- case "m":
1537
- return now - value * 60 * 1000;
1538
- case "s":
1539
- return now - value * 1000;
1540
- }
1541
- }
1542
- return now;
1543
- }
1544
- async readFile(filepath) {
1545
- return fs.promises.readFile(filepath, "utf-8");
1546
- }
1547
- exists(filepath) {
1548
- return fs.existsSync(filepath);
1549
- }
1550
- }
1551
-
1552
- // packages/core/src/env/debug/reader/span-db-reader.ts
1553
- class SpanDbReader {
1554
- storage = null;
1555
- dbPath = null;
1556
- sqliteDb = null;
1557
- constructor(options) {
1558
- if (options?.storage) {
1559
- this.storage = options.storage;
1560
- } else if (options?.dbPath) {
1561
- this.dbPath = options.dbPath;
1562
- }
1563
- }
1564
- async initialize() {
1565
- if (this.storage) {
1566
- await this.storage.initialize();
1567
- } else if (this.dbPath) {
1568
- await this.initSqliteStorage();
1569
- }
1570
- }
1571
- async initSqliteStorage() {
1572
- try {
1573
- const { SQLiteSpanStorage: SQLiteSpanStorage2 } = await Promise.resolve().then(() => exports_span_storage);
1574
- this.storage = new SQLiteSpanStorage2(this.dbPath);
1575
- await this.storage.initialize();
1576
- } catch (error) {
1577
- throw new Error(`Failed to initialize SQLite storage: ${error}`);
1578
- }
1579
- }
1580
- async getTraceEntries(traceId) {
1581
- if (!this.storage) {
1582
- throw new Error("Storage not initialized. Call initialize() first.");
1583
- }
1584
- const spans = this.storage.findByTraceId(traceId);
1585
- if (spans.length === 0) {
1586
- return [];
1587
- }
1588
- return this.spansToEntries(spans);
1589
- }
1590
- async listTraceIds(limit = 20) {
1591
- if (!this.storage) {
1592
- throw new Error("Storage not initialized. Call initialize() first.");
1593
- }
1594
- const traceInfos = this.storage.listTraces(limit);
1595
- const traceIds = traceInfos.map((info) => ({
1596
- traceId: info.traceId,
1597
- firstTime: new Date(info.startTime).toISOString(),
1598
- lastTime: info.endTime ? new Date(info.endTime).toISOString() : undefined,
1599
- count: info.spanCount
1600
- }));
1601
- return {
1602
- traceIds,
1603
- count: traceInfos.length
1604
- };
1605
- }
1606
- spansToEntries(spans) {
1607
- const entries = [];
1608
- for (const span of spans) {
1609
- entries.push({
1610
- traceId: span.traceId,
1611
- timestamp: new Date(span.startTime).toISOString(),
1612
- function: span.name,
1613
- action: "enter",
1614
- params: this.attributesToParams(span.attributes),
1615
- spanId: span.spanId,
1616
- parentSpanId: span.parentSpanId
1617
- });
1618
- if (span.endTime) {
1619
- entries.push({
1620
- traceId: span.traceId,
1621
- timestamp: new Date(span.endTime).toISOString(),
1622
- function: span.name,
1623
- action: "quit",
1624
- result: span.result,
1625
- error: span.error,
1626
- durationMs: span.endTime - span.startTime,
1627
- spanId: span.spanId,
1628
- parentSpanId: span.parentSpanId
1629
- });
1630
- }
1631
- }
1632
- entries.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
1633
- return entries;
1634
- }
1635
- attributesToParams(attributes) {
1636
- if (!attributes)
1637
- return [];
1638
- return Object.entries(attributes).map(([key, value]) => ({
1639
- key,
1640
- value
1641
- }));
1642
- }
1643
- getStorage() {
1644
- return this.storage;
1645
- }
1646
- close() {
1647
- if (this.storage) {
1648
- this.storage.close();
1649
- this.storage = null;
1650
- }
1651
- if (this.sqliteDb) {
1652
- this.sqliteDb.close();
1653
- this.sqliteDb = null;
1654
- }
1655
- }
1656
- }
1657
-
1658
- // packages/core/src/env/debug/parser/regex-parser.ts
1659
- var TRACE_LINE_REGEX = /^(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}\.\d{3})\s+\[(\w+)\]\s+\[([^\]]*)\]\[([^\]]*)\]\s+\[TRACE\]\s+(>>>|<<<|!!!)\s+(.+?)(?:\s+\[requestId=([^\]]+)\])?\s+(enter|quit|error):\s+(.*)$/;
1660
- var REQUEST_ID_IN_CATEGORY_REGEX = /\[requestId=([^\]]+)\]/;
1661
-
1662
- class RegexParser {
1663
- parseLogLine(line) {
1664
- const trimmedLine = line.trim();
1665
- if (!trimmedLine) {
1666
- return null;
1667
- }
1668
- const match = trimmedLine.match(TRACE_LINE_REGEX);
1669
- if (!match) {
1670
- return null;
1671
- }
1672
- const [, timestamp, level, source, category, action, method, requestId, actionType, rawArgs] = match;
1673
- return {
1674
- raw: trimmedLine,
1675
- timestamp: timestamp.replace(" ", "T"),
1676
- level,
1677
- source,
1678
- category,
1679
- action,
1680
- method,
1681
- actionType,
1682
- rawArgs,
1683
- requestId: requestId || null
1684
- };
1685
- }
1686
- parseArgs(raw) {
1687
- if (!raw || !raw.trim()) {
1688
- return null;
1689
- }
1690
- const trimmed = raw.trim();
1691
- try {
1692
- const parsed = JSON.parse(trimmed);
1693
- if (Array.isArray(parsed)) {
1694
- return parsed;
1695
- }
1696
- return parsed;
1697
- } catch {
1698
- return trimmed;
1699
- }
1700
- }
1701
- isTraceLine(line) {
1702
- return line.includes("[TRACE]") && (line.includes(">>>") || line.includes("<<<") || line.includes("!!!"));
1703
- }
1704
- filterByLevel(lines, level) {
1705
- if (!level) {
1706
- return lines;
1707
- }
1708
- const levelPattern = `[${level.toUpperCase()}]`;
1709
- return lines.filter((line) => {
1710
- if (!this.isTraceLine(line)) {
1711
- return false;
1712
- }
1713
- return line.includes(levelPattern);
1714
- });
1715
- }
1716
- filterByFunction(lines, functionName) {
1717
- if (!functionName) {
1718
- return lines;
1719
- }
1720
- return lines.filter((line) => {
1721
- return line.includes(functionName);
1722
- });
1723
- }
1724
- extractTraceId(line) {
1725
- const categoryMatch = line.match(REQUEST_ID_IN_CATEGORY_REGEX);
1726
- if (categoryMatch) {
1727
- return categoryMatch[1];
1728
- }
1729
- const match = line.match(TRACE_LINE_REGEX);
1730
- if (match && match[7]) {
1731
- return match[7];
1732
- }
1733
- return null;
1734
- }
1735
- extractTraceIds(lines) {
1736
- const traceIdMap = new Map;
1737
- for (const line of lines) {
1738
- if (!this.isTraceLine(line))
1739
- continue;
1740
- const traceId = this.extractTraceId(line);
1741
- const parsed = this.parseLogLine(line);
1742
- if (traceId && parsed) {
1743
- const existing = traceIdMap.get(traceId) || [];
1744
- existing.push(line);
1745
- traceIdMap.set(traceId, existing);
1746
- }
1747
- }
1748
- return traceIdMap;
1749
- }
1750
- parseLines(lines) {
1751
- const results = [];
1752
- for (const line of lines) {
1753
- const parsed = this.parseLogLine(line);
1754
- if (parsed) {
1755
- results.push(parsed);
1756
- }
1757
- }
1758
- return results;
1759
- }
1760
- }
1761
-
1762
- // packages/core/src/env/debug/parser/span-builder.ts
1763
- class SpanBuilder {
1764
- parser;
1765
- constructor() {
1766
- this.parser = new RegexParser;
1767
- }
1768
- buildTraceEntries(lines) {
1769
- const entries = [];
1770
- for (const line of lines) {
1771
- const entry = this.buildTraceEntry(line);
1772
- if (entry) {
1773
- entries.push(entry);
1774
- }
1775
- }
1776
- entries.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
1777
- return entries;
1778
- }
1779
- buildTraceEntry(line) {
1780
- const traceId = line.requestId || this.extractTraceId(line.raw);
1781
- const entry = {
1782
- traceId: traceId || this.generateVirtualTraceId(line.method, line.timestamp),
1783
- timestamp: line.timestamp,
1784
- function: line.method,
1785
- action: line.actionType
1786
- };
1787
- switch (line.actionType) {
1788
- case "enter":
1789
- entry.params = this.parser.parseArgs(line.rawArgs);
1790
- break;
1791
- case "quit":
1792
- entry.result = this.parser.parseArgs(line.rawArgs);
1793
- break;
1794
- case "error":
1795
- entry.error = line.rawArgs;
1796
- break;
1797
- }
1798
- return entry;
1799
- }
1800
- generateVirtualTraceId(functionName, timestamp) {
1801
- const base = `${functionName}:${timestamp}`;
1802
- let hash = 0;
1803
- for (let i = 0;i < base.length; i++) {
1804
- const char = base.charCodeAt(i);
1805
- hash = (hash << 5) - hash + char;
1806
- hash = hash & hash;
1807
- }
1808
- return `vtrace_${Math.abs(hash).toString(36)}`;
1809
- }
1810
- extractTraceId(line) {
1811
- return this.parser.extractTraceId(line);
1812
- }
1813
- calculateDuration(enter, quit) {
1814
- try {
1815
- const enterTime = new Date(enter.timestamp).getTime();
1816
- const quitTime = new Date(quit.timestamp).getTime();
1817
- if (isNaN(enterTime) || isNaN(quitTime)) {
1818
- return 0;
1819
- }
1820
- return quitTime - enterTime;
1821
- } catch {
1822
- return 0;
1823
- }
1824
- }
1825
- pairEnterQuit(entries) {
1826
- const paired = [];
1827
- const enterStack = [];
1828
- for (const entry of entries) {
1829
- if (entry.action === "enter") {
1830
- enterStack.push(entry);
1831
- } else if (entry.action === "quit" && enterStack.length > 0) {
1832
- const enter = enterStack.pop();
1833
- const duration = this.calculateDuration(enter, entry);
1834
- paired.push({
1835
- enter,
1836
- quit: entry,
1837
- durationMs: duration
1838
- });
1839
- }
1840
- }
1841
- return paired;
1842
- }
1843
- buildCallTree(entries) {
1844
- if (entries.length === 0) {
1845
- return null;
1846
- }
1847
- const hasSpanHierarchy = entries.some((e) => e.spanId !== undefined || e.parentSpanId !== undefined);
1848
- if (hasSpanHierarchy) {
1849
- return this.buildCallTreeFromHierarchy(entries);
1850
- }
1851
- return this.buildCallTreeFromPairs(entries);
1852
- }
1853
- buildCallTreeFromHierarchy(entries) {
1854
- const nodeMap = new Map;
1855
- const rootNodes = [];
1856
- const addedToRoots = new Set;
1857
- const enterEntries = entries.filter((e) => e.action === "enter");
1858
- for (const entry of enterEntries) {
1859
- const spanId = entry.spanId;
1860
- const parentSpanId = entry.parentSpanId;
1861
- if (spanId && nodeMap.has(spanId)) {
1862
- continue;
1863
- }
1864
- const node = {
1865
- traceId: entry.traceId,
1866
- function: entry.function,
1867
- startTime: entry.timestamp,
1868
- endTime: undefined,
1869
- durationMs: entry.durationMs,
1870
- children: [],
1871
- entry,
1872
- spanId,
1873
- parentSpanId
1874
- };
1875
- if (spanId) {
1876
- nodeMap.set(spanId, node);
1877
- }
1878
- if (!parentSpanId || !nodeMap.has(parentSpanId)) {
1879
- rootNodes.push(node);
1880
- if (spanId)
1881
- addedToRoots.add(spanId);
1882
- }
1883
- }
1884
- const quitEntries = entries.filter((e) => e.action === "quit");
1885
- for (const quit of quitEntries) {
1886
- if (quit.spanId) {
1887
- const node = nodeMap.get(quit.spanId);
1888
- if (node) {
1889
- node.endTime = quit.timestamp;
1890
- node.durationMs = quit.durationMs || (node.endTime && node.startTime ? new Date(node.endTime).getTime() - new Date(node.startTime).getTime() : undefined);
1891
- }
1892
- }
1893
- }
1894
- for (const node of nodeMap.values()) {
1895
- if (node.parentSpanId && nodeMap.has(node.parentSpanId)) {
1896
- const parent = nodeMap.get(node.parentSpanId);
1897
- if (parent.traceId === node.traceId) {
1898
- parent.children.push(node);
1899
- rootNodes.splice(rootNodes.indexOf(node), 1);
1900
- }
1901
- }
1902
- }
1903
- if (rootNodes.length === 0) {
1904
- for (const entry of enterEntries) {
1905
- if (!entry.parentSpanId) {
1906
- const spanId = entry.spanId;
1907
- if (spanId && nodeMap.has(spanId) && !addedToRoots.has(spanId)) {
1908
- rootNodes.push(nodeMap.get(spanId));
1909
- }
1910
- }
1911
- }
1912
- }
1913
- rootNodes.sort((a, b) => a.startTime.localeCompare(b.startTime));
1914
- if (rootNodes.length === 0) {
1915
- return null;
1916
- }
1917
- if (rootNodes.length === 1) {
1918
- return rootNodes[0];
1919
- }
1920
- const allStartTimes = rootNodes.map((n) => new Date(n.startTime).getTime());
1921
- const allEndTimes = rootNodes.map((n) => n.endTime ? new Date(n.endTime).getTime() : 0).filter((t) => t > 0);
1922
- return {
1923
- traceId: entries[0]?.traceId || "merged",
1924
- function: "(root)",
1925
- children: rootNodes,
1926
- startTime: new Date(Math.min(...allStartTimes)).toISOString(),
1927
- endTime: allEndTimes.length > 0 ? new Date(Math.max(...allEndTimes)).toISOString() : undefined,
1928
- durationMs: allEndTimes.length > 0 && allStartTimes.length > 0 ? Math.max(...allEndTimes) - Math.min(...allStartTimes) : undefined
1929
- };
1930
- }
1931
- buildCallTreeFromPairs(entries) {
1932
- const sortedEntries = [...entries].sort((a, b) => a.timestamp.localeCompare(b.timestamp));
1933
- const paired = this.pairEnterQuit(sortedEntries);
1934
- if (paired.length === 0) {
1935
- return null;
1936
- }
1937
- const stack = [];
1938
- let root = null;
1939
- for (const entry of sortedEntries) {
1940
- if (entry.action === "enter") {
1941
- const span = paired.find((p) => p.enter === entry);
1942
- if (!span)
1943
- continue;
1944
- const node = this.buildNodeFromPaired(span);
1945
- if (stack.length === 0) {
1946
- root = node;
1947
- } else {
1948
- stack[stack.length - 1].node.children.push(node);
1949
- }
1950
- stack.push({ node, paired: span });
1951
- } else if (entry.action === "quit" && stack.length > 0) {
1952
- stack.pop();
1953
- }
1954
- }
1955
- return root;
1956
- }
1957
- buildNodeFromPaired(span) {
1958
- return {
1959
- traceId: span.enter.traceId,
1960
- function: span.enter.function,
1961
- startTime: span.enter.timestamp,
1962
- endTime: span.quit.timestamp,
1963
- durationMs: span.durationMs,
1964
- children: [],
1965
- entry: span.enter
1966
- };
1967
- }
1968
- buildMergedTree(entriesByFunction) {
1969
- const allEntries = [];
1970
- for (const entries of entriesByFunction.values()) {
1971
- allEntries.push(...entries);
1972
- }
1973
- allEntries.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
1974
- return this.buildCallTree(allEntries);
1975
- }
1976
- getDurationSummary(entries) {
1977
- const summary = new Map;
1978
- const paired = this.pairEnterQuit(entries);
1979
- for (const span of paired) {
1980
- const func = span.enter.function;
1981
- const existing = summary.get(func) || { count: 0, totalMs: 0, avgMs: 0 };
1982
- existing.count++;
1983
- existing.totalMs += span.durationMs;
1984
- existing.avgMs = Math.round(existing.totalMs / existing.count);
1985
- summary.set(func, existing);
1986
- }
1987
- return summary;
1988
- }
1989
- }
1990
-
1991
- // packages/core/src/env/debug/debug-component.ts
1992
- class DebugComponent extends BaseComponent {
1993
- name = "debug";
1994
- version = "1.0.0";
1995
- reader;
1996
- spanDbReader = null;
1997
- parser;
1998
- spanBuilder;
1999
- traceFormatter;
2000
- treeFormatter;
2001
- options;
2002
- constructor(options) {
2003
- super();
2004
- this.options = options || {};
2005
- this.reader = new LogReader({ logDir: this.options.logDir });
2006
- this.parser = new RegexParser;
2007
- this.spanBuilder = new SpanBuilder;
2008
- this.traceFormatter = new TraceFormatter;
2009
- this.treeFormatter = new TreeFormatter;
2010
- }
2011
- async initSpanDbReader(dbPath) {
2012
- if (!this.spanDbReader) {
2013
- this.spanDbReader = new SpanDbReader({ dbPath });
2014
- await this.spanDbReader.initialize();
2015
- }
2016
- }
2017
- getSpanDbReader() {
2018
- return this.spanDbReader;
2019
- }
2020
- async getLiveTrace(traceId) {
2021
- try {
2022
- const { getTracerProvider: getTracerProvider2 } = await Promise.resolve().then(() => (init_tracer_provider(), exports_tracer_provider));
2023
- const provider = getTracerProvider2();
2024
- if (!provider.isInitialized()) {
2025
- await provider.initialize();
2026
- }
2027
- const storage = provider.getStorage();
2028
- const spans = storage.findByTraceId(traceId);
2029
- if (spans.length === 0) {
2030
- return null;
2031
- }
2032
- const flattenSpans = (spanList) => {
2033
- const result = [];
2034
- for (const span of spanList) {
2035
- result.push({
2036
- traceId: span.traceId,
2037
- spanId: span.spanId,
2038
- parentSpanId: span.parentSpanId,
2039
- function: span.name,
2040
- action: "enter",
2041
- timestamp: new Date(span.startTime).toISOString(),
2042
- params: Object.entries(span.attributes || {}).map(([k, v]) => ({ key: k, value: v }))
2043
- });
2044
- if (span.children && span.children.length > 0) {
2045
- result.push(...flattenSpans(span.children));
2046
- }
2047
- }
2048
- return result;
2049
- };
2050
- const flatSpans = flattenSpans(spans);
2051
- const tree = this.spanBuilder.buildCallTree(flatSpans);
2052
- const rootSpans = spans.filter((s) => !s.parentSpanId);
2053
- return {
2054
- traceId,
2055
- spans,
2056
- callTree: tree,
2057
- spanCount: flatSpans.length,
2058
- rootSpans
2059
- };
2060
- } catch (error) {
2061
- console.error("Failed to get trace from live storage:", error);
2062
- return null;
2063
- }
2064
- }
2065
- async listLiveTraces(limit = 20) {
2066
- try {
2067
- const { getTracerProvider: getTracerProvider2 } = await Promise.resolve().then(() => (init_tracer_provider(), exports_tracer_provider));
2068
- const provider = getTracerProvider2();
2069
- if (!provider.isInitialized()) {
2070
- await provider.initialize();
2071
- }
2072
- const storage = provider.getStorage();
2073
- const traces = storage.listTraces(limit);
2074
- return {
2075
- traces,
2076
- count: traces.length
2077
- };
2078
- } catch (error) {
2079
- console.error("Failed to list live traces:", error);
2080
- return { traces: [], count: 0 };
2081
- }
2082
- }
2083
- async formatLiveTrace(traceId) {
2084
- try {
2085
- const { getTracerProvider: getTracerProvider2 } = await Promise.resolve().then(() => (init_tracer_provider(), exports_tracer_provider));
2086
- const provider = getTracerProvider2();
2087
- if (!provider.isInitialized()) {
2088
- await provider.initialize();
2089
- }
2090
- const storage = provider.getStorage();
2091
- const spans = storage.findByTraceId(traceId);
2092
- if (spans.length === 0) {
2093
- return `No trace found for traceId: ${traceId}`;
2094
- }
2095
- const flattenSpans = (spanList) => {
2096
- const result = [];
2097
- for (const span of spanList) {
2098
- result.push({
2099
- traceId: span.traceId,
2100
- spanId: span.spanId,
2101
- parentSpanId: span.parentSpanId,
2102
- function: span.name,
2103
- action: "enter",
2104
- timestamp: new Date(span.startTime).toISOString(),
2105
- params: Object.entries(span.attributes || {}).map(([k, v]) => ({ key: k, value: v }))
2106
- });
2107
- if (span.children && span.children.length > 0) {
2108
- result.push(...flattenSpans(span.children));
2109
- }
2110
- }
2111
- return result;
2112
- };
2113
- const flatSpans = flattenSpans(spans);
2114
- const tree = this.spanBuilder.buildCallTree(flatSpans);
2115
- if (!tree) {
2116
- return "No trace structure found";
2117
- }
2118
- return this.treeFormatter.formatTree(tree);
2119
- } catch (error) {
2120
- return `Failed to format trace: ${error}`;
2121
- }
2122
- }
2123
- async init(config) {
2124
- await super.init(config);
2125
- this.setStatus("running");
2126
- }
2127
- async stop() {
2128
- this.setStatus("stopping");
2129
- this.setStatus("stopped");
2130
- }
2131
- async getTraces(options) {
2132
- if (options?.source === "sqlite") {
2133
- return this.getTracesFromSqlite(options);
2134
- }
2135
- const logFile = options?.logFile || this.reader.getLogPath();
2136
- const lines = [];
2137
- for await (const line of this.reader.readLines(logFile, options)) {
2138
- if (options?.function && !line.includes(options.function)) {
2139
- continue;
2140
- }
2141
- if (options?.traceId && !line.includes(`requestId=${options.traceId}`)) {
2142
- continue;
2143
- }
2144
- if (this.parser.isTraceLine(line)) {
2145
- lines.push(line);
2146
- }
2147
- }
2148
- const parsedLines = this.parser.parseLines(lines);
2149
- const entries = this.spanBuilder.buildTraceEntries(parsedLines);
2150
- let filteredEntries = entries;
2151
- if (options?.function) {
2152
- filteredEntries = entries.filter((e) => e.function.includes(options.function));
2153
- }
2154
- const paired = this.spanBuilder.pairEnterQuit(filteredEntries);
2155
- const result = [];
2156
- for (const span of paired) {
2157
- result.push({
2158
- ...span.enter,
2159
- durationMs: span.durationMs
2160
- });
2161
- if (span.quit) {
2162
- result.push({
2163
- ...span.quit,
2164
- durationMs: span.durationMs
2165
- });
2166
- }
2167
- }
2168
- return result;
2169
- }
2170
- async getTracesFromSqlite(options) {
2171
- if (!options?.traceId) {
2172
- return [];
2173
- }
2174
- await this.initSpanDbReader(options.dbPath);
2175
- const reader = this.getSpanDbReader();
2176
- if (!reader) {
2177
- throw new Error("Failed to initialize span database reader");
2178
- }
2179
- const entries = await reader.getTraceEntries(options.traceId);
2180
- if (options?.function) {
2181
- return entries.filter((e) => e.function.includes(options.function));
2182
- }
2183
- return entries;
2184
- }
2185
- async listTraceIds(options) {
2186
- if (options?.source === "sqlite") {
2187
- return this.listTraceIdsFromSqlite(options);
2188
- }
2189
- const logFile = options?.logFile || this.reader.getLogPath();
2190
- const limit = options?.limit || 20;
2191
- const traceMap = new Map;
2192
- for await (const line of this.reader.readLines(logFile, options)) {
2193
- if (!this.parser.isTraceLine(line))
2194
- continue;
2195
- const parsed = this.parser.parseLogLine(line);
2196
- if (!parsed)
2197
- continue;
2198
- const traceId = this.parser.extractTraceId(line) || this.spanBuilder.generateVirtualTraceId(parsed.method, parsed.timestamp);
2199
- const existing = traceMap.get(traceId);
2200
- if (existing) {
2201
- existing.lastTime = parsed.timestamp;
2202
- existing.count++;
2203
- } else {
2204
- traceMap.set(traceId, {
2205
- firstTime: parsed.timestamp,
2206
- lastTime: parsed.timestamp,
2207
- count: 1
2208
- });
2209
- }
2210
- }
2211
- const traceIds = [];
2212
- for (const [traceId, info] of traceMap.entries()) {
2213
- traceIds.push({
2214
- traceId,
2215
- firstTime: info.firstTime,
2216
- lastTime: info.lastTime,
2217
- count: info.count
2218
- });
2219
- }
2220
- traceIds.sort((a, b) => b.firstTime.localeCompare(a.firstTime));
2221
- return {
2222
- traceIds: traceIds.slice(0, limit),
2223
- count: traceIds.length
2224
- };
2225
- }
2226
- async listTraceIdsFromSqlite(options) {
2227
- const limit = options?.limit || 20;
2228
- await this.initSpanDbReader(options?.dbPath);
2229
- const reader = this.getSpanDbReader();
2230
- if (!reader) {
2231
- throw new Error("Failed to initialize span database reader");
2232
- }
2233
- return reader.listTraceIds(limit);
2234
- }
2235
- async getCallTree(options) {
2236
- if (!options?.traceId) {
2237
- return null;
2238
- }
2239
- const traces = await this.getTraces({
2240
- ...options,
2241
- traceId: options.traceId
2242
- });
2243
- if (traces.length === 0) {
2244
- return null;
2245
- }
2246
- return this.spanBuilder.buildCallTree(traces);
2247
- }
2248
- getReader() {
2249
- return this.reader;
2250
- }
2251
- getParser() {
2252
- return this.parser;
2253
- }
2254
- getSpanBuilder() {
2255
- return this.spanBuilder;
2256
- }
2257
- getTraceFormatter() {
2258
- return this.traceFormatter;
2259
- }
2260
- getTreeFormatter() {
2261
- return this.treeFormatter;
2262
- }
2263
- formatTraces(entries, options) {
2264
- return this.traceFormatter.formatEntries(entries, options);
2265
- }
2266
- formatTraceEntry(entry, options) {
2267
- return this.traceFormatter.formatEntry(entry, options);
2268
- }
2269
- tracesToJSON(entries) {
2270
- return this.traceFormatter.toJSON(entries);
2271
- }
2272
- tracesToSummary(entries) {
2273
- return this.traceFormatter.toSummary(entries);
2274
- }
2275
- formatTree(node) {
2276
- return this.treeFormatter.formatTree(node);
2277
- }
2278
- formatTrees(trees) {
2279
- return this.treeFormatter.formatTrees(trees);
2280
- }
2281
- treesToJSON(trees) {
2282
- return this.treeFormatter.toJSON(trees);
2283
- }
2284
- formatTreeSummary(node) {
2285
- return this.treeFormatter.formatSummary(node);
2286
- }
2287
- formatTreeTimeline(node) {
2288
- return this.treeFormatter.formatTimeline(node);
2289
- }
2290
- }
2291
- export {
2292
- TreeFormatter,
2293
- TraceFormatter,
2294
- SpanDbReader,
2295
- SpanBuilder,
2296
- ReplFormatter,
2297
- RegexParser,
2298
- LogReader,
2299
- DebugComponent
2300
- };