@ai-setting/roy-agent-core 1.4.11 → 1.4.13
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/index.d.ts +7825 -0
- package/dist/index.js +1040 -6526
- package/dist/shared/chunk-0q6s9wm6.js +249 -0
- package/dist/shared/chunk-1aakcfp1.js +15 -0
- package/dist/shared/chunk-1d4rwms4.js +25 -0
- package/dist/shared/chunk-1pf5mfgd.js +82 -0
- package/dist/shared/chunk-1qwabsm0.js +154 -0
- package/dist/shared/chunk-25x2pdtp.js +107 -0
- package/dist/shared/chunk-2b5kbhx3.js +366 -0
- package/dist/shared/chunk-91bas8w5.js +20 -0
- package/dist/shared/chunk-9qzt1v1p.js +10 -0
- package/dist/shared/chunk-a9qmy3sc.js +296 -0
- package/dist/shared/chunk-g6j5n3gv.js +549 -0
- package/dist/shared/chunk-hs7tbmje.js +24 -0
- package/dist/shared/chunk-mf5xqbdh.js +14 -0
- package/dist/shared/chunk-q9j99fsm.js +368 -0
- package/dist/shared/chunk-rncy3rtd.js +3140 -0
- package/dist/shared/chunk-t1rh6jtm.js +205 -0
- package/dist/shared/chunk-wbkh7wat.js +52 -0
- package/dist/shared/chunk-yqmx37vm.js +10 -0
- package/dist/shared/chunk-ze20rksg.js +102 -0
- package/package.json +8 -8
- package/dist/config/index.js +0 -1647
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__esm,
|
|
3
|
+
__export
|
|
4
|
+
} from "./chunk-wbkh7wat.js";
|
|
5
|
+
|
|
6
|
+
// src/env/workflow/decorators/decorator-node.ts
|
|
7
|
+
class DecoratorNode {
|
|
8
|
+
type = "decorator";
|
|
9
|
+
id;
|
|
10
|
+
methodName;
|
|
11
|
+
instance;
|
|
12
|
+
dependsOn;
|
|
13
|
+
timeout;
|
|
14
|
+
retryConfig;
|
|
15
|
+
constructor(definition) {
|
|
16
|
+
const config = definition.config;
|
|
17
|
+
this.id = definition.id;
|
|
18
|
+
this.methodName = config._methodName;
|
|
19
|
+
this.instance = config._instance;
|
|
20
|
+
this.dependsOn = definition.depends_on || [];
|
|
21
|
+
this.timeout = definition.timeout;
|
|
22
|
+
this.retryConfig = definition.retry;
|
|
23
|
+
}
|
|
24
|
+
async execute(context) {
|
|
25
|
+
const startTime = Date.now();
|
|
26
|
+
const method = this.instance[this.methodName];
|
|
27
|
+
if (typeof method !== "function") {
|
|
28
|
+
return {
|
|
29
|
+
success: false,
|
|
30
|
+
error: `Method '${this.methodName}' is not a function`,
|
|
31
|
+
duration: Date.now() - startTime
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const input = this.prepareInput(context);
|
|
35
|
+
const result = await this.executeWithRetry(input, context.abort);
|
|
36
|
+
return {
|
|
37
|
+
success: !result.error,
|
|
38
|
+
output: result.output,
|
|
39
|
+
error: result.error,
|
|
40
|
+
duration: Date.now() - startTime,
|
|
41
|
+
metadata: {
|
|
42
|
+
methodName: this.methodName
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
prepareInput(context) {
|
|
47
|
+
const nodeOutputs = context.nodeOutputs;
|
|
48
|
+
if (this.dependsOn.length === 0) {
|
|
49
|
+
return context.input || {};
|
|
50
|
+
}
|
|
51
|
+
const input = {};
|
|
52
|
+
for (const depId of this.dependsOn) {
|
|
53
|
+
const depOutput = nodeOutputs instanceof Map ? nodeOutputs.get(depId) : nodeOutputs?.[depId];
|
|
54
|
+
if (depOutput && typeof depOutput === "object") {
|
|
55
|
+
if ("output" in depOutput) {
|
|
56
|
+
input[depId] = depOutput.output;
|
|
57
|
+
} else {
|
|
58
|
+
input[depId] = depOutput;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return input;
|
|
63
|
+
}
|
|
64
|
+
async executeWithRetry(input, abort) {
|
|
65
|
+
const maxAttempts = this.retryConfig?.max_attempts ?? 1;
|
|
66
|
+
const backoff = this.retryConfig?.backoff ?? "exponential";
|
|
67
|
+
const initialDelay = this.retryConfig?.initial_delay ?? 1000;
|
|
68
|
+
let lastError;
|
|
69
|
+
for (let attempt = 1;attempt <= maxAttempts; attempt++) {
|
|
70
|
+
if (abort?.aborted) {
|
|
71
|
+
return { error: "Execution aborted" };
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
const output = await this.executeWithTimeout(input, abort);
|
|
75
|
+
return { output };
|
|
76
|
+
} catch (error) {
|
|
77
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
78
|
+
if (attempt < maxAttempts) {
|
|
79
|
+
const delay = this.calculateBackoff(backoff, initialDelay, attempt - 1);
|
|
80
|
+
await this.sleep(delay, abort);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return { error: lastError?.message || "Unknown error" };
|
|
85
|
+
}
|
|
86
|
+
async executeWithTimeout(input, abort) {
|
|
87
|
+
if (!this.timeout) {
|
|
88
|
+
return this.instance[this.methodName](input);
|
|
89
|
+
}
|
|
90
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
91
|
+
setTimeout(() => {
|
|
92
|
+
reject(new Error(`Execution timeout after ${this.timeout}ms`));
|
|
93
|
+
}, this.timeout);
|
|
94
|
+
});
|
|
95
|
+
return Promise.race([
|
|
96
|
+
this.instance[this.methodName](input),
|
|
97
|
+
timeoutPromise
|
|
98
|
+
]);
|
|
99
|
+
}
|
|
100
|
+
calculateBackoff(backoff, initialDelay, attempt) {
|
|
101
|
+
if (backoff === "exponential") {
|
|
102
|
+
return initialDelay * Math.pow(2, attempt);
|
|
103
|
+
}
|
|
104
|
+
return initialDelay;
|
|
105
|
+
}
|
|
106
|
+
sleep(ms, abort) {
|
|
107
|
+
return new Promise((resolve) => {
|
|
108
|
+
const timeout = setTimeout(resolve, ms);
|
|
109
|
+
abort?.addEventListener("abort", () => {
|
|
110
|
+
clearTimeout(timeout);
|
|
111
|
+
resolve();
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
var init_decorator_node = () => {};
|
|
117
|
+
|
|
118
|
+
// src/env/workflow/nodes/condition-node.ts
|
|
119
|
+
class ConditionNode {
|
|
120
|
+
definition;
|
|
121
|
+
type = "condition";
|
|
122
|
+
id;
|
|
123
|
+
constructor(definition) {
|
|
124
|
+
this.definition = definition;
|
|
125
|
+
this.id = definition.id;
|
|
126
|
+
}
|
|
127
|
+
async execute(context) {
|
|
128
|
+
const startTime = Date.now();
|
|
129
|
+
try {
|
|
130
|
+
const conditionConfig = this.definition.config?.condition;
|
|
131
|
+
if (conditionConfig === undefined) {
|
|
132
|
+
return {
|
|
133
|
+
output: { success: true, condition: true },
|
|
134
|
+
error: undefined,
|
|
135
|
+
durationMs: Date.now() - startTime
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
const resolvedCondition = this.resolveCondition(conditionConfig, context);
|
|
139
|
+
const result = this.evaluateCondition(resolvedCondition);
|
|
140
|
+
return {
|
|
141
|
+
output: { success: result, condition: resolvedCondition },
|
|
142
|
+
error: undefined,
|
|
143
|
+
durationMs: Date.now() - startTime
|
|
144
|
+
};
|
|
145
|
+
} catch (error) {
|
|
146
|
+
return {
|
|
147
|
+
output: undefined,
|
|
148
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
149
|
+
durationMs: Date.now() - startTime
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
resolveCondition(condition, context) {
|
|
154
|
+
if (typeof condition === "string") {
|
|
155
|
+
const templateMatch = condition.match(/^\{\{([^}]+)\}\}$/);
|
|
156
|
+
if (templateMatch) {
|
|
157
|
+
const path = templateMatch[1].trim();
|
|
158
|
+
return this.resolveTemplate(path, context);
|
|
159
|
+
}
|
|
160
|
+
if (condition === "true")
|
|
161
|
+
return true;
|
|
162
|
+
if (condition === "false")
|
|
163
|
+
return false;
|
|
164
|
+
return condition;
|
|
165
|
+
}
|
|
166
|
+
return condition;
|
|
167
|
+
}
|
|
168
|
+
resolveTemplate(path, context) {
|
|
169
|
+
const trimmed = path.trim();
|
|
170
|
+
if (trimmed.startsWith("input.")) {
|
|
171
|
+
const key = trimmed.slice(6);
|
|
172
|
+
return context.input?.[key];
|
|
173
|
+
}
|
|
174
|
+
if (trimmed.startsWith("nodes.")) {
|
|
175
|
+
const rest = trimmed.slice(6);
|
|
176
|
+
const segments2 = rest.split(".");
|
|
177
|
+
const nodeId2 = segments2[0];
|
|
178
|
+
let nodeOutput2 = context.previousOutputs.get(nodeId2);
|
|
179
|
+
if (nodeOutput2 === undefined) {
|
|
180
|
+
const normalizedUnderscore = nodeId2.replace(/-/g, "_");
|
|
181
|
+
const normalizedHyphen = nodeId2.replace(/_/g, "-");
|
|
182
|
+
if (normalizedUnderscore !== nodeId2) {
|
|
183
|
+
nodeOutput2 = context.previousOutputs.get(normalizedUnderscore);
|
|
184
|
+
}
|
|
185
|
+
if (nodeOutput2 === undefined && normalizedHyphen !== nodeId2) {
|
|
186
|
+
nodeOutput2 = context.previousOutputs.get(normalizedHyphen);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if (nodeOutput2 === undefined)
|
|
190
|
+
return;
|
|
191
|
+
let value2 = nodeOutput2;
|
|
192
|
+
for (const segment of segments2.slice(1)) {
|
|
193
|
+
if (value2 && typeof value2 === "object") {
|
|
194
|
+
value2 = value2[segment];
|
|
195
|
+
} else {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return value2;
|
|
200
|
+
}
|
|
201
|
+
const segments = trimmed.split(".");
|
|
202
|
+
const nodeId = segments[0];
|
|
203
|
+
let nodeOutput = context.previousOutputs.get(nodeId);
|
|
204
|
+
if (nodeOutput === undefined) {
|
|
205
|
+
const normalizedUnderscore = nodeId.replace(/-/g, "_");
|
|
206
|
+
const normalizedHyphen = nodeId.replace(/_/g, "-");
|
|
207
|
+
if (normalizedUnderscore !== nodeId) {
|
|
208
|
+
nodeOutput = context.previousOutputs.get(normalizedUnderscore);
|
|
209
|
+
}
|
|
210
|
+
if (nodeOutput === undefined && normalizedHyphen !== nodeId) {
|
|
211
|
+
nodeOutput = context.previousOutputs.get(normalizedHyphen);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (nodeOutput === undefined)
|
|
215
|
+
return;
|
|
216
|
+
let value = nodeOutput;
|
|
217
|
+
for (const segment of segments.slice(1)) {
|
|
218
|
+
if (value && typeof value === "object") {
|
|
219
|
+
value = value[segment];
|
|
220
|
+
} else {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return value;
|
|
225
|
+
}
|
|
226
|
+
evaluateCondition(value) {
|
|
227
|
+
if (typeof value === "boolean") {
|
|
228
|
+
return value;
|
|
229
|
+
}
|
|
230
|
+
if (typeof value === "string") {
|
|
231
|
+
return value.toLowerCase() === "true" || value === "1";
|
|
232
|
+
}
|
|
233
|
+
if (typeof value === "number") {
|
|
234
|
+
return value !== 0;
|
|
235
|
+
}
|
|
236
|
+
if (value === null || value === undefined) {
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
if (typeof value === "object") {
|
|
240
|
+
const obj = value;
|
|
241
|
+
if ("success" in obj) {
|
|
242
|
+
return Boolean(obj.success);
|
|
243
|
+
}
|
|
244
|
+
return Object.keys(obj).length > 0;
|
|
245
|
+
}
|
|
246
|
+
return Boolean(value);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
var init_condition_node = () => {};
|
|
250
|
+
|
|
251
|
+
// src/env/workflow/nodes/merge-node.ts
|
|
252
|
+
class MergeNode {
|
|
253
|
+
definition;
|
|
254
|
+
type = "merge";
|
|
255
|
+
id;
|
|
256
|
+
constructor(definition) {
|
|
257
|
+
this.definition = definition;
|
|
258
|
+
this.id = definition.id;
|
|
259
|
+
}
|
|
260
|
+
async execute(context) {
|
|
261
|
+
const startTime = Date.now();
|
|
262
|
+
try {
|
|
263
|
+
const strategy = this.definition.config?.strategy || "collect";
|
|
264
|
+
const deps = this.definition.depends_on || [];
|
|
265
|
+
const outputs = {};
|
|
266
|
+
for (const depId of deps) {
|
|
267
|
+
let output = context.previousOutputs.get(depId);
|
|
268
|
+
if (output === undefined) {
|
|
269
|
+
const normalizedUnderscore = depId.replace(/-/g, "_");
|
|
270
|
+
const normalizedHyphen = depId.replace(/_/g, "-");
|
|
271
|
+
if (normalizedUnderscore !== depId) {
|
|
272
|
+
output = context.previousOutputs.get(normalizedUnderscore);
|
|
273
|
+
}
|
|
274
|
+
if (output === undefined && normalizedHyphen !== depId) {
|
|
275
|
+
output = context.previousOutputs.get(normalizedHyphen);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
if (output !== undefined) {
|
|
279
|
+
outputs[depId] = output;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
let result;
|
|
283
|
+
switch (strategy) {
|
|
284
|
+
case "collect":
|
|
285
|
+
result = outputs;
|
|
286
|
+
break;
|
|
287
|
+
case "first":
|
|
288
|
+
const firstKey = Object.keys(outputs)[0];
|
|
289
|
+
result = firstKey ? outputs[firstKey] : undefined;
|
|
290
|
+
break;
|
|
291
|
+
case "last":
|
|
292
|
+
const lastKey = Object.keys(outputs).pop();
|
|
293
|
+
result = lastKey ? outputs[lastKey] : undefined;
|
|
294
|
+
break;
|
|
295
|
+
case "merge":
|
|
296
|
+
result = this.deepMerge(Object.values(outputs));
|
|
297
|
+
break;
|
|
298
|
+
default:
|
|
299
|
+
result = outputs;
|
|
300
|
+
}
|
|
301
|
+
return {
|
|
302
|
+
output: {
|
|
303
|
+
strategy,
|
|
304
|
+
results: result,
|
|
305
|
+
count: Object.keys(outputs).length
|
|
306
|
+
},
|
|
307
|
+
error: undefined,
|
|
308
|
+
durationMs: Date.now() - startTime
|
|
309
|
+
};
|
|
310
|
+
} catch (error) {
|
|
311
|
+
return {
|
|
312
|
+
output: undefined,
|
|
313
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
314
|
+
durationMs: Date.now() - startTime
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
deepMerge(objects) {
|
|
319
|
+
const result = {};
|
|
320
|
+
for (const obj of objects) {
|
|
321
|
+
if (obj && typeof obj === "object" && !Array.isArray(obj)) {
|
|
322
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
323
|
+
if (result[key] && typeof result[key] === "object" && !Array.isArray(result[key]) && value && typeof value === "object" && !Array.isArray(value)) {
|
|
324
|
+
result[key] = this.deepMerge([result[key], value]);
|
|
325
|
+
} else {
|
|
326
|
+
result[key] = value;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
return result;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
var init_merge_node = () => {};
|
|
335
|
+
|
|
336
|
+
// src/env/workflow/utils/node-registry-helper.ts
|
|
337
|
+
var exports_node_registry_helper = {};
|
|
338
|
+
__export(exports_node_registry_helper, {
|
|
339
|
+
registerDecoratorNodeType: () => registerDecoratorNodeType,
|
|
340
|
+
hasDecoratorNodes: () => hasDecoratorNodes,
|
|
341
|
+
getDecoratorNodes: () => getDecoratorNodes
|
|
342
|
+
});
|
|
343
|
+
function registerDecoratorNodeType(registry) {
|
|
344
|
+
registry.register("decorator", (definition) => {
|
|
345
|
+
return new DecoratorNode(definition);
|
|
346
|
+
});
|
|
347
|
+
registry.register("condition", (definition) => {
|
|
348
|
+
return new ConditionNode(definition);
|
|
349
|
+
});
|
|
350
|
+
registry.register("merge", (definition) => {
|
|
351
|
+
return new MergeNode(definition);
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
function hasDecoratorNodes(nodes) {
|
|
355
|
+
return nodes.some((node) => node.type === "decorator");
|
|
356
|
+
}
|
|
357
|
+
function getDecoratorNodes(nodes) {
|
|
358
|
+
return nodes.filter((node) => node.type === "decorator");
|
|
359
|
+
}
|
|
360
|
+
var init_node_registry_helper = __esm(() => {
|
|
361
|
+
init_decorator_node();
|
|
362
|
+
init_condition_node();
|
|
363
|
+
init_merge_node();
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
export { init_decorator_node, registerDecoratorNodeType, hasDecoratorNodes, getDecoratorNodes, exports_node_registry_helper, init_node_registry_helper };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
closeDatabase,
|
|
3
|
+
getDatabase,
|
|
4
|
+
getDatabasePath,
|
|
5
|
+
initDatabase,
|
|
6
|
+
initializeTables,
|
|
7
|
+
resetDatabase
|
|
8
|
+
} from "./chunk-1pf5mfgd.js";
|
|
9
|
+
import"./chunk-a9qmy3sc.js";
|
|
10
|
+
import"./chunk-q9j99fsm.js";
|
|
11
|
+
import"./chunk-1qwabsm0.js";
|
|
12
|
+
import"./chunk-wbkh7wat.js";
|
|
13
|
+
export {
|
|
14
|
+
resetDatabase,
|
|
15
|
+
initializeTables,
|
|
16
|
+
initDatabase,
|
|
17
|
+
getDatabasePath,
|
|
18
|
+
getDatabase,
|
|
19
|
+
closeDatabase
|
|
20
|
+
};
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getTracerProvider,
|
|
3
|
+
init_tracer_provider
|
|
4
|
+
} from "./chunk-q9j99fsm.js";
|
|
5
|
+
import {
|
|
6
|
+
__esm,
|
|
7
|
+
__require
|
|
8
|
+
} from "./chunk-wbkh7wat.js";
|
|
9
|
+
|
|
10
|
+
// src/env/log-trace/logger.ts
|
|
11
|
+
import { appendFileSync, existsSync, mkdirSync } from "fs";
|
|
12
|
+
import { join } from "path";
|
|
13
|
+
function simplifyFilePath(fullPath) {
|
|
14
|
+
let path = fullPath.replace(/\\/g, "/");
|
|
15
|
+
const bunfsMatch = path.match(/\/\$bunfs\/root\/(.+)$/);
|
|
16
|
+
if (bunfsMatch) {
|
|
17
|
+
const virtualPath = bunfsMatch[1];
|
|
18
|
+
const packagesMatch = virtualPath.match(/(packages\/[^/]+\/src\/[^/]+\/.+)$/);
|
|
19
|
+
if (packagesMatch) {
|
|
20
|
+
return packagesMatch[1];
|
|
21
|
+
}
|
|
22
|
+
return virtualPath;
|
|
23
|
+
}
|
|
24
|
+
const fileProtocolMatch = path.match(/@roy-agent\+core@file\+([^/]+)\/node_modules\/@roy-agent\/core\/(.+)$/);
|
|
25
|
+
if (fileProtocolMatch) {
|
|
26
|
+
const rootPkg = fileProtocolMatch[1].replace(/\+/g, "/");
|
|
27
|
+
const remaining = fileProtocolMatch[2];
|
|
28
|
+
const prefix = rootPkg;
|
|
29
|
+
const suffix = remaining.startsWith("src/") ? remaining : `src/${remaining}`;
|
|
30
|
+
return `${prefix}/${suffix}`;
|
|
31
|
+
}
|
|
32
|
+
const packagesRootMatch = path.match(/(packages\/[^/]+\/src\/[^/]+\/.+)$/);
|
|
33
|
+
if (packagesRootMatch) {
|
|
34
|
+
return packagesRootMatch[1];
|
|
35
|
+
}
|
|
36
|
+
const rootMarkers = ["packages/core/src", "packages/core", "packages"];
|
|
37
|
+
for (const marker of rootMarkers) {
|
|
38
|
+
const idx = path.indexOf(marker);
|
|
39
|
+
if (idx !== -1) {
|
|
40
|
+
return path.substring(idx);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return path;
|
|
44
|
+
}
|
|
45
|
+
function getDefaultLogDir() {
|
|
46
|
+
const home = process.env.HOME || process.env.USERPROFILE || "/tmp";
|
|
47
|
+
try {
|
|
48
|
+
const xdg = __require("xdg-basedir");
|
|
49
|
+
if (xdg.xdgData) {
|
|
50
|
+
return join(xdg.xdgData, "roy-agent", "logs");
|
|
51
|
+
}
|
|
52
|
+
} catch {}
|
|
53
|
+
return join(home, ".local", "share", "roy-agent", "logs");
|
|
54
|
+
}
|
|
55
|
+
function isQuietMode() {
|
|
56
|
+
return quietMode;
|
|
57
|
+
}
|
|
58
|
+
function setQuietMode(enabled) {
|
|
59
|
+
quietMode = enabled;
|
|
60
|
+
}
|
|
61
|
+
function setConfigComponent(component) {
|
|
62
|
+
configComponentInstance = component;
|
|
63
|
+
}
|
|
64
|
+
function getLogLevel() {
|
|
65
|
+
if (configComponentInstance) {
|
|
66
|
+
const level = configComponentInstance.get("log_trace.logging.level");
|
|
67
|
+
if (level && ["debug", "info", "warn", "error"].includes(level)) {
|
|
68
|
+
return level;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const envLevel = process.env.LOG_LEVEL;
|
|
72
|
+
if (envLevel && ["debug", "info", "warn", "error"].includes(envLevel)) {
|
|
73
|
+
return envLevel;
|
|
74
|
+
}
|
|
75
|
+
return "info";
|
|
76
|
+
}
|
|
77
|
+
function getCategoryLogLevel(category) {
|
|
78
|
+
if (configComponentInstance) {
|
|
79
|
+
const levels = configComponentInstance.get("log_trace.logging.levels");
|
|
80
|
+
if (levels && typeof levels === "object") {
|
|
81
|
+
const categoryLevel = levels[category];
|
|
82
|
+
if (categoryLevel && ["debug", "info", "warn", "error"].includes(categoryLevel)) {
|
|
83
|
+
return categoryLevel;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const directLevel = configComponentInstance.get(`log_trace.logging.levels.${category}`);
|
|
87
|
+
if (directLevel && ["debug", "info", "warn", "error"].includes(directLevel)) {
|
|
88
|
+
return directLevel;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const envKey = `LOG_LEVEL_${category.toUpperCase().replace(/:/g, "_")}`;
|
|
92
|
+
const envLevel = process.env[envKey];
|
|
93
|
+
if (envLevel && ["debug", "info", "warn", "error"].includes(envLevel)) {
|
|
94
|
+
return envLevel;
|
|
95
|
+
}
|
|
96
|
+
return getLogLevel();
|
|
97
|
+
}
|
|
98
|
+
function isAbsolutePath(path) {
|
|
99
|
+
if (path.startsWith("/")) {
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
if (/^[a-zA-Z]:[/\\]/.test(path)) {
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
function expandHomeDir(path) {
|
|
108
|
+
if (path.startsWith("~")) {
|
|
109
|
+
const home = process.env.HOME || process.env.USERPROFILE || "/tmp";
|
|
110
|
+
return join(home, path.slice(1));
|
|
111
|
+
}
|
|
112
|
+
return path;
|
|
113
|
+
}
|
|
114
|
+
function getLogFile() {
|
|
115
|
+
if (configComponentInstance) {
|
|
116
|
+
const file = configComponentInstance.get("log_trace.logging.file");
|
|
117
|
+
if (file) {
|
|
118
|
+
return file;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return "app.log";
|
|
122
|
+
}
|
|
123
|
+
function getLogDir() {
|
|
124
|
+
if (configComponentInstance) {
|
|
125
|
+
const dir = configComponentInstance.get("log_trace.logging.dir");
|
|
126
|
+
if (dir) {
|
|
127
|
+
return dir;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return getDefaultLogDir();
|
|
131
|
+
}
|
|
132
|
+
function getMaxOutput() {
|
|
133
|
+
if (configComponentInstance) {
|
|
134
|
+
const maxOutput = configComponentInstance.get("log-trace.logging.maxOutput");
|
|
135
|
+
if (typeof maxOutput === "number") {
|
|
136
|
+
return maxOutput;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
function setLogDirOverride(dir) {
|
|
142
|
+
logDirOverride = dir;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
class Logger {
|
|
146
|
+
prefix;
|
|
147
|
+
constructor(prefix) {
|
|
148
|
+
this.prefix = prefix;
|
|
149
|
+
}
|
|
150
|
+
shouldLog(level) {
|
|
151
|
+
const categoryLevel = getCategoryLogLevel(this.prefix);
|
|
152
|
+
return levelPriority[level] >= levelPriority[categoryLevel];
|
|
153
|
+
}
|
|
154
|
+
ensureLogDirectory(dir) {
|
|
155
|
+
if (!existsSync(dir)) {
|
|
156
|
+
try {
|
|
157
|
+
mkdirSync(dir, { recursive: true });
|
|
158
|
+
} catch (err) {
|
|
159
|
+
console.error("[Logger] Failed to create log directory:", dir, err);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
getCallerLocation() {
|
|
164
|
+
const originalLimit = Error.stackTraceLimit;
|
|
165
|
+
Error.stackTraceLimit = 10;
|
|
166
|
+
const err = new Error;
|
|
167
|
+
Error.captureStackTrace(err, this.formatMessage);
|
|
168
|
+
const stack = err.stack?.split(`
|
|
169
|
+
`) || [];
|
|
170
|
+
Error.stackTraceLimit = originalLimit;
|
|
171
|
+
for (let i = 1;i < stack.length; i++) {
|
|
172
|
+
const line = stack[i];
|
|
173
|
+
if (line.includes("at ") && !line.includes("logger.ts") && !line.includes("formatMessage")) {
|
|
174
|
+
const match = line.match(/at\s+.+\s+\((.+):(\d+):\d+\)/) || line.match(/at\s+(.+):(\d+):\d+/);
|
|
175
|
+
if (match) {
|
|
176
|
+
const filePath = match[1];
|
|
177
|
+
const relativePath = this.getRelativePath(filePath);
|
|
178
|
+
return {
|
|
179
|
+
file: relativePath,
|
|
180
|
+
line: parseInt(match[2], 10)
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
getRelativePath(fullPath) {
|
|
188
|
+
return simplifyFilePath(fullPath);
|
|
189
|
+
}
|
|
190
|
+
formatMessage(level, message, data) {
|
|
191
|
+
const now = new Date;
|
|
192
|
+
const timestamp = now.toLocaleString("zh-CN", {
|
|
193
|
+
timeZone: "Asia/Shanghai",
|
|
194
|
+
year: "numeric",
|
|
195
|
+
month: "2-digit",
|
|
196
|
+
day: "2-digit",
|
|
197
|
+
hour: "2-digit",
|
|
198
|
+
minute: "2-digit",
|
|
199
|
+
second: "2-digit",
|
|
200
|
+
hour12: false
|
|
201
|
+
}).replace(/\//g, "-") + "." + String(now.getMilliseconds()).padStart(3, "0");
|
|
202
|
+
const prefix = this.prefix ? `[${this.prefix}]` : "";
|
|
203
|
+
let traceIdStr = "";
|
|
204
|
+
try {
|
|
205
|
+
const provider = getTracerProvider();
|
|
206
|
+
const tracer = provider.getTracer("roy-tracer");
|
|
207
|
+
const context = tracer.getCurrentContext();
|
|
208
|
+
if (context?.traceId) {
|
|
209
|
+
traceIdStr = `[traceId=${context.traceId}]`;
|
|
210
|
+
}
|
|
211
|
+
} catch {}
|
|
212
|
+
let locationStr = "";
|
|
213
|
+
if (data && typeof data === "object" && "callerLocation" in data) {
|
|
214
|
+
const logData = data;
|
|
215
|
+
locationStr = logData.callerLocation ? ` [${logData.callerLocation}]` : "";
|
|
216
|
+
const { callerLocation: _callerLocation, ...rest } = logData;
|
|
217
|
+
data = Object.keys(rest).length > 0 ? rest : undefined;
|
|
218
|
+
} else {
|
|
219
|
+
const location = this.getCallerLocation();
|
|
220
|
+
if (location) {
|
|
221
|
+
locationStr = ` [${location.file}:${location.line}]`;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
let formatted = `${timestamp} [${level.toUpperCase()}]${traceIdStr}${locationStr}${prefix} ${message}`;
|
|
225
|
+
if (data !== undefined) {
|
|
226
|
+
if (typeof data === "object") {
|
|
227
|
+
formatted += " " + JSON.stringify(data).replace(/\n/g, "");
|
|
228
|
+
} else {
|
|
229
|
+
formatted += " " + String(data);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
const maxOutput = getMaxOutput();
|
|
233
|
+
if (maxOutput && maxOutput > 0 && formatted.length > maxOutput) {
|
|
234
|
+
formatted = formatted.substring(0, maxOutput) + " [TRUNCATED]";
|
|
235
|
+
}
|
|
236
|
+
return formatted;
|
|
237
|
+
}
|
|
238
|
+
writeToFile(message) {
|
|
239
|
+
try {
|
|
240
|
+
const dir = getLogDir();
|
|
241
|
+
const filename = getLogFile();
|
|
242
|
+
const expandedDir = expandHomeDir(dir);
|
|
243
|
+
const resolvedDir = isAbsolutePath(expandedDir) ? expandedDir : join(process.cwd(), expandedDir);
|
|
244
|
+
this.ensureLogDirectory(resolvedDir);
|
|
245
|
+
const logFile = join(resolvedDir, filename);
|
|
246
|
+
appendFileSync(logFile, message + `
|
|
247
|
+
`, "utf-8");
|
|
248
|
+
} catch (err) {
|
|
249
|
+
console.error("[Logger] Failed to write to log file:", err);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
log(level, message, data) {
|
|
253
|
+
if (!this.shouldLog(level))
|
|
254
|
+
return;
|
|
255
|
+
const formatted = this.formatMessage(level, message, data);
|
|
256
|
+
this.writeToFile(formatted);
|
|
257
|
+
if (!isQuietMode()) {
|
|
258
|
+
const consoleMethod = level === "error" ? console.error : level === "warn" ? console.warn : level === "info" ? console.log : console.debug;
|
|
259
|
+
consoleMethod(formatted);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
debug(message, data) {
|
|
263
|
+
this.log("debug", message, data);
|
|
264
|
+
}
|
|
265
|
+
info(message, data) {
|
|
266
|
+
this.log("info", message, data);
|
|
267
|
+
}
|
|
268
|
+
warn(message, data) {
|
|
269
|
+
this.log("warn", message, data);
|
|
270
|
+
}
|
|
271
|
+
error(message, data) {
|
|
272
|
+
this.log("error", message, data);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
function createLogger(prefix) {
|
|
276
|
+
if (!loggerCache.has(prefix)) {
|
|
277
|
+
loggerCache.set(prefix, new Logger(prefix));
|
|
278
|
+
}
|
|
279
|
+
return loggerCache.get(prefix);
|
|
280
|
+
}
|
|
281
|
+
function getLogLevels() {
|
|
282
|
+
return ["debug", "info", "warn", "error"];
|
|
283
|
+
}
|
|
284
|
+
var configComponentInstance = null, quietMode = false, logDirOverride, levelPriority, loggerCache;
|
|
285
|
+
var init_logger = __esm(() => {
|
|
286
|
+
init_tracer_provider();
|
|
287
|
+
levelPriority = {
|
|
288
|
+
debug: 0,
|
|
289
|
+
info: 1,
|
|
290
|
+
warn: 2,
|
|
291
|
+
error: 3
|
|
292
|
+
};
|
|
293
|
+
loggerCache = new Map;
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
export { simplifyFilePath, isQuietMode, setQuietMode, setConfigComponent, getLogLevel, getLogDir, getMaxOutput, setLogDirOverride, createLogger, getLogLevels, init_logger };
|