@microfox/ai-router 2.0.0 → 2.0.1-beta.1

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.mjs DELETED
@@ -1,1347 +0,0 @@
1
- import "./chunk-BJTO5JO5.mjs";
2
-
3
- // src/router.ts
4
- import {
5
- createUIMessageStream,
6
- createUIMessageStreamResponse,
7
- generateId,
8
- tool,
9
- convertToModelMessages,
10
- readUIMessageStream
11
- } from "ai";
12
-
13
- // ../../node_modules/nanoid/index.js
14
- import crypto from "crypto";
15
- var POOL_SIZE_MULTIPLIER = 128;
16
- var pool;
17
- var poolOffset;
18
- var fillPool = (bytes) => {
19
- if (!pool || pool.length < bytes) {
20
- pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
21
- crypto.randomFillSync(pool);
22
- poolOffset = 0;
23
- } else if (poolOffset + bytes > pool.length) {
24
- crypto.randomFillSync(pool);
25
- poolOffset = 0;
26
- }
27
- poolOffset += bytes;
28
- };
29
- var random = (bytes) => {
30
- fillPool(bytes |= 0);
31
- return pool.subarray(poolOffset - bytes, poolOffset);
32
- };
33
- var customRandom = (alphabet, defaultSize, getRandom) => {
34
- let mask = (2 << 31 - Math.clz32(alphabet.length - 1 | 1)) - 1;
35
- let step = Math.ceil(1.6 * mask * defaultSize / alphabet.length);
36
- return (size = defaultSize) => {
37
- let id = "";
38
- while (true) {
39
- let bytes = getRandom(step);
40
- let i = step;
41
- while (i--) {
42
- id += alphabet[bytes[i] & mask] || "";
43
- if (id.length === size) return id;
44
- }
45
- }
46
- };
47
- };
48
- var customAlphabet = (alphabet, size = 21) => customRandom(alphabet, size, random);
49
-
50
- // src/helper.ts
51
- var findLastElement = (array) => {
52
- return array[array.length - 1];
53
- };
54
- var findFirstElement = (array) => {
55
- return array[0];
56
- };
57
- var StreamWriter = class {
58
- constructor(writer) {
59
- this.generateId = () => {
60
- return customAlphabet("1234567890abcdefghijklmnopqrstuvwxyz", 10)();
61
- };
62
- this.writeMessageMetadata = (metadata) => {
63
- return this.writer.write({
64
- type: "message-metadata",
65
- messageMetadata: metadata
66
- });
67
- };
68
- this.writeCustomTool = (tool2) => {
69
- const toolCallId = tool2.toolCallId || tool2.toolName?.toString() + "-" + this.generateId();
70
- if ("input" in tool2 && tool2.input) {
71
- this.writer.write({
72
- type: "tool-input-available",
73
- input: tool2.input,
74
- toolCallId,
75
- toolName: tool2.toolName
76
- });
77
- }
78
- if (tool2.inputTextDelta && tool2.inputTextDelta.length > 0 || "output" in tool2 && tool2.output) {
79
- this.writer.write({
80
- type: "tool-input-start",
81
- toolCallId,
82
- toolName: tool2.toolName
83
- });
84
- if (tool2.inputTextDelta) {
85
- for (const delta of tool2.inputTextDelta) {
86
- this.writer.write({
87
- type: "tool-input-delta",
88
- toolCallId,
89
- inputTextDelta: delta
90
- });
91
- }
92
- }
93
- }
94
- if ("output" in tool2 && tool2.output) {
95
- this.writer.write({
96
- type: "tool-output-available",
97
- toolCallId,
98
- output: tool2.output
99
- });
100
- }
101
- };
102
- this.writeObjectAsTool = (tool2) => {
103
- if (!tool2.result?.object) {
104
- throw new Error("No object found in the GenerateObjectResult");
105
- }
106
- const toolCallId = tool2.toolName.toString() + "-" + this.generateId();
107
- this.writer.write({
108
- type: "tool-input-start",
109
- toolCallId,
110
- toolName: tool2.toolName
111
- });
112
- this.writer.write({
113
- type: "tool-input-available",
114
- toolCallId,
115
- input: tool2.input ?? tool2.result ? {
116
- usage: tool2.result?.usage,
117
- warnings: tool2.result?.warnings,
118
- finishReason: tool2.result?.finishReason
119
- } : void 0,
120
- toolName: tool2.toolName
121
- });
122
- this.writer.write({
123
- type: "tool-output-available",
124
- toolCallId,
125
- output: tool2.result?.object
126
- });
127
- };
128
- this.writer = writer;
129
- }
130
- };
131
- var getTextParts = (message) => {
132
- if (!message) return [];
133
- return message.parts.filter((part) => part.type === "text").map((part) => part.text);
134
- };
135
- var getTextPartsContent = (message) => {
136
- if (!message) return "";
137
- return message.parts.filter((part) => part.type === "text").map((part) => part.text).join("").trim();
138
- };
139
- var findLastMessageWith = (message, filters) => {
140
- if (!message) return null;
141
- return message.filter((m) => {
142
- if (filters.role && m.role !== filters.role) return false;
143
- if (filters.metadata) {
144
- for (const key in filters.metadata) {
145
- }
146
- }
147
- return true;
148
- }).pop();
149
- };
150
-
151
- // src/router.ts
152
- import path from "path";
153
-
154
- // src/store.ts
155
- var MemoryStore = class {
156
- constructor() {
157
- this.store = /* @__PURE__ */ new Map();
158
- }
159
- async get(key) {
160
- return this.store.get(key);
161
- }
162
- async set(key, value) {
163
- this.store.set(key, value);
164
- }
165
- async delete(key) {
166
- this.store.delete(key);
167
- }
168
- async has(key) {
169
- return this.store.has(key);
170
- }
171
- };
172
-
173
- // src/router.ts
174
- var globalLogger = void 0;
175
- function setGlobalLogger(logger) {
176
- globalLogger = logger;
177
- }
178
- function getGlobalLogger() {
179
- return globalLogger;
180
- }
181
- function clubParts(parts) {
182
- if (!parts || parts.length === 0) return parts;
183
- const clubbedParts = [];
184
- const toolCallIdGroups = /* @__PURE__ */ new Map();
185
- const dataIdGroups = /* @__PURE__ */ new Map();
186
- for (const part of parts) {
187
- if (part.type?.startsWith("tool-") && part.toolCallId) {
188
- const toolCallId = part.toolCallId;
189
- if (!toolCallIdGroups.has(toolCallId)) {
190
- toolCallIdGroups.set(toolCallId, []);
191
- }
192
- toolCallIdGroups.get(toolCallId).push(part);
193
- } else if (part.type?.startsWith("data-") && part.id) {
194
- const id = part.id;
195
- if (!dataIdGroups.has(id)) {
196
- dataIdGroups.set(id, []);
197
- }
198
- dataIdGroups.get(id).push(part);
199
- } else {
200
- clubbedParts.push(part);
201
- }
202
- }
203
- for (const [toolCallId, toolParts] of toolCallIdGroups) {
204
- if (toolParts.length === 1) {
205
- clubbedParts.push(toolParts[0]);
206
- } else {
207
- const mergedPart = { ...toolParts[0] };
208
- for (let i = 1; i < toolParts.length; i++) {
209
- const currentPart = toolParts[i];
210
- Object.keys(currentPart).forEach((key) => {
211
- if (key !== "type" && key !== "toolCallId") {
212
- mergedPart[key] = currentPart[key];
213
- }
214
- });
215
- }
216
- clubbedParts.push(mergedPart);
217
- }
218
- }
219
- for (const [id, dataParts] of dataIdGroups) {
220
- if (dataParts.length === 1) {
221
- clubbedParts.push(dataParts[0]);
222
- } else {
223
- const mergedPart = { ...dataParts[0] };
224
- for (let i = 1; i < dataParts.length; i++) {
225
- const currentPart = dataParts[i];
226
- Object.keys(currentPart).forEach((key) => {
227
- if (key !== "type" && key !== "id") {
228
- mergedPart[key] = currentPart[key];
229
- }
230
- });
231
- }
232
- clubbedParts.push(mergedPart);
233
- }
234
- }
235
- return clubbedParts;
236
- }
237
- var AiKitError = class extends Error {
238
- constructor(message) {
239
- super(message);
240
- this.name = "AiKitError";
241
- }
242
- };
243
- var AgentNotFoundError = class extends AiKitError {
244
- constructor(path2) {
245
- super(`[AiAgentKit] Agent not found for path: ${path2}`);
246
- this.name = "AgentNotFoundError";
247
- }
248
- };
249
- var ToolNotFoundError = class extends AiKitError {
250
- constructor(path2) {
251
- super(`[AiAgentKit] Tool not found at path: ${path2}`);
252
- this.name = "ToolNotFoundError";
253
- }
254
- };
255
- var ToolValidationError = class extends AiKitError {
256
- constructor(path2, validationError) {
257
- const message = `[AiAgentKit] Tool call validation failed for path: ${path2}: ${validationError.message}`;
258
- super(message);
259
- this.name = "ToolValidationError";
260
- }
261
- };
262
- var MaxCallDepthExceededError = class extends AiKitError {
263
- constructor(maxDepth) {
264
- super(`[AiAgentKit] Agent call depth limit (${maxDepth}) exceeded.`);
265
- this.name = "MaxCallDepthExceededError";
266
- }
267
- };
268
- var AgentDefinitionMissingError = class extends AiKitError {
269
- constructor(path2) {
270
- super(
271
- `[AiAgentKit] agentAsTool: No definition found for "${path2}". Please define it using '.actAsTool()' or pass a definition as the second argument.`
272
- );
273
- this.name = "AgentDefinitionMissingError";
274
- }
275
- };
276
- function parsePathPattern(pattern) {
277
- const paramNames = [];
278
- const parts = pattern.split(/(\/:[^\/]+)/);
279
- const regexPattern = parts.map((part) => {
280
- if (part.startsWith("/:")) {
281
- paramNames.push(part.substring(2));
282
- return "/([^/]+)";
283
- }
284
- return part.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
285
- }).join("");
286
- const regex = new RegExp(`^${regexPattern}$`);
287
- return { regex, paramNames };
288
- }
289
- function extractPathParams(pattern, path2) {
290
- const { regex, paramNames } = parsePathPattern(pattern);
291
- const match = path2.match(regex);
292
- if (!match) {
293
- return null;
294
- }
295
- const params = {};
296
- paramNames.forEach((paramName, index) => {
297
- const value = match[index + 1];
298
- if (value !== void 0) {
299
- params[paramName] = value;
300
- }
301
- });
302
- return params;
303
- }
304
- function hasDynamicParams(pattern) {
305
- return /\/:[^\/]+/.test(pattern);
306
- }
307
- var AiRouter = class _AiRouter {
308
- /**
309
- * Constructs a new AiAgentKit router.
310
- * @param stack An optional initial stack of layers, used for composing routers.
311
- * @param options Optional configuration for the router.
312
- */
313
- constructor(stack, options) {
314
- this.stack = [];
315
- this.actAsToolDefinitions = /* @__PURE__ */ new Map();
316
- this.logger = void 0;
317
- this._store = new MemoryStore();
318
- this.toolExecutionPromise = Promise.resolve();
319
- /** Configuration options for the router instance. */
320
- this.options = {
321
- maxCallDepth: 10
322
- };
323
- this.pendingExecutions = 0;
324
- if (stack) {
325
- this.stack = stack;
326
- }
327
- if (options?.maxCallDepth) {
328
- this.options.maxCallDepth = options.maxCallDepth;
329
- }
330
- }
331
- setStore(store) {
332
- this._store = store;
333
- }
334
- /**
335
- * Sets a logger for this router instance.
336
- * If no logger is set, the router will fall back to the global logger.
337
- * @param logger The logger to use for this router instance, or undefined to use global logger
338
- */
339
- setLogger(logger) {
340
- this.logger = logger;
341
- }
342
- /**
343
- * Gets the effective logger for this router instance.
344
- * Returns instance logger if set, otherwise falls back to global logger.
345
- * @returns The effective logger or undefined if no logging should occur
346
- */
347
- _getEffectiveLogger() {
348
- return this.logger ?? globalLogger;
349
- }
350
- /**
351
- * Registers a middleware-style agent that runs for a specific path prefix, regex pattern, or wildcard.
352
- * Agents can modify the context and must call `next()` to pass control to the next handler in the chain.
353
- * This method is primarily for middleware. For terminal agents, see `.agent()` on an instance.
354
- *
355
- * @param path The path prefix, regex pattern, or "*" for wildcard matching.
356
- * @param agents The agent middleware function(s).
357
- */
358
- agent(agentPath, ...agents) {
359
- let prefix = "/";
360
- if (typeof agentPath === "string" || agentPath instanceof RegExp) {
361
- prefix = agentPath;
362
- } else {
363
- agents.unshift(agentPath);
364
- }
365
- for (const handler of agents) {
366
- if (typeof handler !== "function") {
367
- if (handler instanceof _AiRouter && typeof prefix === "string") {
368
- const stackToMount = handler.getStackWithPrefix(prefix);
369
- this.stack.push(...stackToMount);
370
- this.logger?.log(
371
- `Router mounted: path=${prefix}, layers=${stackToMount.length}`
372
- );
373
- const mountPath = prefix.toString();
374
- handler.actAsToolDefinitions.forEach((value, key) => {
375
- const keyPath = key.toString();
376
- const relativeKeyPath = keyPath.startsWith("/") ? keyPath.substring(1) : keyPath;
377
- const newKey = path.posix.join(mountPath, relativeKeyPath);
378
- this.actAsToolDefinitions.set(newKey, value);
379
- });
380
- }
381
- continue;
382
- }
383
- this.stack.push({
384
- path: prefix,
385
- handler,
386
- isTool: false,
387
- isAgent: true
388
- // Mark as an agent
389
- });
390
- this.logger?.log(`Agent registered: path=${prefix}`);
391
- }
392
- return this;
393
- }
394
- /**
395
- * Mounts a middleware function or another AiAgentKit router at a specific path.
396
- * This is the primary method for composing routers and applying cross-cutting middleware.
397
- *
398
- * @param path The path prefix to mount the handler on.
399
- * @param handler The middleware function or AiAgentKit router instance to mount.
400
- */
401
- use(mountPathArg, handler) {
402
- if (mountPathArg instanceof RegExp && handler instanceof _AiRouter) {
403
- throw new AiKitError(
404
- "[AiAgentKit] Mounting a router on a RegExp path is not supported."
405
- );
406
- }
407
- if (handler instanceof _AiRouter) {
408
- const router = handler;
409
- const mountPath = mountPathArg.toString().replace(/\/$/, "");
410
- router.stack.forEach((layer) => {
411
- const layerPath = layer.path.toString();
412
- const relativeLayerPath = layerPath.startsWith("/") ? layerPath.substring(1) : layerPath;
413
- const newPath = path.posix.join(mountPath, relativeLayerPath);
414
- this.stack.push({ ...layer, path: newPath });
415
- });
416
- router.actAsToolDefinitions.forEach((value, key) => {
417
- const keyPath = key.toString();
418
- const relativeKeyPath = keyPath.startsWith("/") ? keyPath.substring(1) : keyPath;
419
- const newKey = path.posix.join(mountPath, relativeKeyPath);
420
- this.actAsToolDefinitions.set(newKey, value);
421
- });
422
- } else {
423
- this.stack.push({
424
- path: mountPathArg,
425
- handler,
426
- isTool: false,
427
- isAgent: false
428
- // Middleware is not a terminal agent
429
- });
430
- }
431
- return this;
432
- }
433
- /**
434
- * Pre-defines the schema and description for an agent when it is used as a tool by an LLM.
435
- * This allows `next.agentAsTool()` to create a valid `Tool` object without needing the definition at call time.
436
- * @param path The path of the agent being defined.
437
- * @param options The tool definition, including a Zod schema and description.
438
- */
439
- actAsTool(path2, options) {
440
- this.actAsToolDefinitions.set(path2, options);
441
- this.logger?.log(`[actAsTool] Added definition: at path ${path2}`);
442
- this.logger?.log(
443
- `[actAsTool] Router now has ${this.actAsToolDefinitions.size} definitions`
444
- );
445
- return this;
446
- }
447
- getToolSet() {
448
- let allTools = Array.from(this.actAsToolDefinitions.entries()).map(
449
- ([key, value]) => {
450
- return {
451
- ...value,
452
- metadata: {
453
- ...value.metadata,
454
- absolutePath: key
455
- }
456
- };
457
- }
458
- );
459
- return allTools.reduce((acc, _tool) => {
460
- const { inputSchema, outputSchema } = _tool;
461
- acc[_tool.id] = {
462
- ...tool(
463
- _tool
464
- ),
465
- metadata: {
466
- ..._tool.metadata,
467
- toolKey: _tool.id,
468
- name: _tool.name,
469
- description: _tool.description
470
- }
471
- };
472
- return acc;
473
- }, {});
474
- }
475
- getToolDefinition(path2) {
476
- let definition = this.actAsToolDefinitions.get(path2);
477
- if (!definition) {
478
- this.logger?.error(
479
- `[getToolDefinition] No definition found for path: ${path2}`
480
- );
481
- throw new AgentDefinitionMissingError(path2);
482
- }
483
- return definition;
484
- }
485
- /**
486
- * @deprecated Use agent-as-tools pattern instead. Create an agent and use `.actAsTool()` to expose it as a tool.
487
- * This method will be removed in a future version.
488
- */
489
- // Implementation
490
- tool(path2, optionsOrFactory, handler) {
491
- this.logger?.warn(
492
- `[DEPRECATION WARNING] router.tool() is deprecated and will be removed in a future version. Please migrate to the agent-as-tools pattern: router.agent('${path2}', async (ctx) => {...}).actAsTool('${path2}', {...})`
493
- );
494
- this.logger?.log(`[AiAgentKit][tool] Registering tool at path:`, path2);
495
- if (this.stack.some((l) => l.isTool && l.path === path2)) {
496
- this.logger?.error(
497
- `[AiAgentKit][tool] Tool already registered for path: ${path2}`
498
- );
499
- throw new AiKitError(`A tool is already registered for path: ${path2}`);
500
- }
501
- if (typeof optionsOrFactory === "function" && !handler) {
502
- const factory = optionsOrFactory;
503
- const isDynamicPath = typeof path2 === "string" && hasDynamicParams(path2);
504
- const toolMiddleware = async (ctx, _next) => {
505
- this.logger?.log(
506
- `[Tool Middleware] Executing factory for path "${path2}". Messages in context: ${ctx.request.messages?.length ?? "undefined"}`
507
- );
508
- const toolObject = factory(ctx);
509
- if (!toolObject.execute) {
510
- throw new AiKitError(
511
- `[AiAgentKit] Tool from factory at path ${path2} does not have an execute method.`
512
- );
513
- }
514
- const schema = toolObject.inputSchema;
515
- if (!schema) {
516
- this.logger?.warn(
517
- `[AiAgentKit][tool] Factory-based tool at path ${path2} has no inputSchema. Executing without params.`
518
- );
519
- return toolObject.execute({}, {});
520
- }
521
- const parsedParams = schema.safeParse(ctx.request.params);
522
- if (!parsedParams.success) {
523
- this.logger?.error(
524
- `[AiAgentKit][tool] Tool call validation failed for path: ${path2}:`,
525
- parsedParams.error.message
526
- );
527
- throw new ToolValidationError(path2.toString(), parsedParams.error);
528
- }
529
- return toolObject.execute(parsedParams.data, {
530
- messages: convertToModelMessages(ctx.request.messages ?? []),
531
- toolCallId: "tool-" + (path2.toString()?.split("/").pop() ?? "direct-call") + "-" + generateId()
532
- });
533
- };
534
- this.stack.push({
535
- path: path2,
536
- handler: toolMiddleware,
537
- isTool: true,
538
- toolOptions: {
539
- type: "factory",
540
- factory
541
- },
542
- isAgent: false,
543
- hasDynamicParams: isDynamicPath
544
- });
545
- this.logger?.log(
546
- `Tool registered: path=${path2}, type=factory${isDynamicPath ? " (dynamic)" : ""}`
547
- );
548
- return this;
549
- }
550
- if (typeof optionsOrFactory === "object" && handler) {
551
- const options = optionsOrFactory;
552
- const isDynamicPath = typeof path2 === "string" && hasDynamicParams(path2);
553
- const dynamicParamInfo = isDynamicPath ? parsePathPattern(path2) : null;
554
- const toolMiddleware = async (ctx, _next) => {
555
- if (isDynamicPath && typeof path2 === "string") {
556
- const pathParams = extractPathParams(path2, ctx.request.path || "");
557
- this.logger?.log(
558
- `[AiAgentKit][tool] Extracted dynamic path params:`,
559
- pathParams
560
- );
561
- if (pathParams) {
562
- ctx.request.params = {
563
- ...ctx.request.params,
564
- ...pathParams
565
- };
566
- }
567
- }
568
- const parsedParams = options.schema.safeParse(ctx.request.params);
569
- if (!parsedParams.success) {
570
- this.logger?.error(
571
- `[AiAgentKit][tool] Tool call validation failed for path: ${path2}:`,
572
- parsedParams.error.message
573
- );
574
- throw new ToolValidationError(path2.toString(), parsedParams.error);
575
- }
576
- const staticHandler = handler;
577
- return staticHandler(ctx, parsedParams.data);
578
- };
579
- this.stack.push({
580
- path: path2,
581
- handler: toolMiddleware,
582
- isTool: true,
583
- toolOptions: {
584
- type: "static",
585
- schema: options.schema,
586
- description: options.description,
587
- handler
588
- },
589
- isAgent: false,
590
- hasDynamicParams: isDynamicPath,
591
- paramNames: dynamicParamInfo?.paramNames
592
- });
593
- this.logger?.log(
594
- `Tool registered: path=${path2}, type=static${isDynamicPath ? " (dynamic)" : ""}`
595
- );
596
- return this;
597
- }
598
- this.logger?.error(
599
- `[AiAgentKit][tool] Invalid arguments for tool registration at path: ${path2}`
600
- );
601
- throw new AiKitError(
602
- `Invalid arguments for tool registration at path: ${path2}`
603
- );
604
- }
605
- /**
606
- * Returns the internal stack of layers. Primarily used for manual router composition.
607
- * @deprecated Prefer using `.use()` for router composition.
608
- */
609
- getStack() {
610
- return this.stack;
611
- }
612
- /**
613
- * Returns the internal stack with a path prefix applied to each layer.
614
- * @param prefix The prefix to add to each path.
615
- * @deprecated Prefer using `.use()` for router composition.
616
- */
617
- getStackWithPrefix(prefix) {
618
- return this.stack.map((layer) => {
619
- let newPath;
620
- if (layer.path instanceof RegExp) {
621
- newPath = new RegExp(prefix.replace(/\\/g, "\\\\") + layer.path.source);
622
- } else {
623
- const layerPathStr = layer.path.toString();
624
- const relativeLayerPath = layerPathStr.startsWith("/") ? layerPathStr.substring(1) : layerPathStr;
625
- newPath = path.posix.join(prefix, relativeLayerPath);
626
- }
627
- return {
628
- ...layer,
629
- path: newPath
630
- };
631
- });
632
- }
633
- /**
634
- * Outputs all registered paths, and the tool definitions, middlewares, and agents registered on each path.
635
- * @returns A map of paths to their registered handlers.
636
- */
637
- registry() {
638
- const registryMap = {};
639
- for (const layer of this.stack) {
640
- const pathKey = layer.path.toString();
641
- if (!registryMap[pathKey]) {
642
- registryMap[pathKey] = { middlewares: [], tools: [], agents: [] };
643
- }
644
- if (layer.isTool) {
645
- let toolInfo = { type: layer.toolOptions?.type };
646
- if (layer.toolOptions?.type === "static") {
647
- toolInfo = {
648
- ...toolInfo,
649
- schema: layer.toolOptions.schema,
650
- description: layer.toolOptions.description
651
- };
652
- } else if (layer.toolOptions?.type === "factory") {
653
- toolInfo = {
654
- ...toolInfo,
655
- factory: layer.toolOptions.factory.toString()
656
- };
657
- }
658
- registryMap[pathKey].tools.push(toolInfo);
659
- } else if (layer.isAgent) {
660
- const agentInfo = {
661
- handler: layer.handler.name || "anonymous"
662
- };
663
- const actAsToolDef = this.actAsToolDefinitions.get(layer.path);
664
- if (actAsToolDef) {
665
- agentInfo.actAsTool = {
666
- ...actAsToolDef
667
- };
668
- }
669
- registryMap[pathKey].agents.push(agentInfo);
670
- } else {
671
- registryMap[pathKey].middlewares.push({
672
- handler: layer.handler.name || "anonymous"
673
- });
674
- }
675
- }
676
- return {
677
- map: registryMap,
678
- tools: this.getToolSet()
679
- };
680
- }
681
- /**
682
- * Resolves a path based on the parent path and the requested path.
683
- * - If path starts with `@/`, it's an absolute path from the root.
684
- * - Otherwise, it's a relative path.
685
- * @internal
686
- */
687
- _resolvePath(parentPath, newPath) {
688
- if (newPath.startsWith("@/")) {
689
- return path.posix.normalize(newPath.substring(1));
690
- }
691
- const joinedPath = path.posix.join(parentPath, newPath);
692
- return joinedPath;
693
- }
694
- /**
695
- * Creates a new context for an internal agent or tool call.
696
- * It inherits from the parent context but gets a new logger and call depth.
697
- * @internal
698
- */
699
- _createSubContext(parentCtx, options) {
700
- const parentDepth = parentCtx.executionContext.callDepth ?? 0;
701
- const newCallDepth = parentDepth + (options.type === "agent" ? 1 : 0);
702
- const subContext = {
703
- ...parentCtx,
704
- // State is passed by reference to allow sub-agents to modify the parent's state.
705
- // The execution context is a shallow copy to ensure call-specific data is isolated.
706
- state: parentCtx.state,
707
- store: parentCtx.store,
708
- executionContext: {
709
- ...parentCtx.executionContext,
710
- currentPath: options.path,
711
- callDepth: newCallDepth
712
- },
713
- request: {
714
- ...parentCtx.request,
715
- messages: options.messages || parentCtx.request.messages || [],
716
- params: options.params,
717
- path: options.path
718
- // The path to execute
719
- },
720
- logger: this._createLogger(
721
- parentCtx.requestId,
722
- options.path,
723
- newCallDepth
724
- ),
725
- next: void 0
726
- // Will be replaced right after
727
- };
728
- subContext.executionContext.currentPath = options.path;
729
- subContext.next = new NextHandler(
730
- subContext,
731
- this,
732
- parentCtx._onExecutionStart,
733
- parentCtx._onExecutionEnd,
734
- parentCtx.next
735
- );
736
- return subContext;
737
- }
738
- /**
739
- * Creates a new logger instance with a structured prefix.
740
- * @internal
741
- */
742
- _createLogger(requestId, path2, callDepth = 0) {
743
- const effectiveLogger = this._getEffectiveLogger();
744
- if (!effectiveLogger) {
745
- return {
746
- log: () => {
747
- },
748
- warn: () => {
749
- },
750
- error: () => {
751
- }
752
- };
753
- }
754
- const indent = " ".repeat(callDepth);
755
- const prefix = `${indent}[${path2.toString()}]`;
756
- const fullPrefix = `[${requestId}]${prefix}`;
757
- return {
758
- log: (...args) => effectiveLogger.log(fullPrefix, ...args),
759
- warn: (...args) => effectiveLogger.warn(fullPrefix, ...args),
760
- error: (...args) => effectiveLogger.error(fullPrefix, ...args)
761
- };
762
- }
763
- /**
764
- * Calculates a specificity score for a layer to enable Express-style routing.
765
- * Higher score means more specific.
766
- * - Middleware is less specific than an agent/tool.
767
- * - Deeper paths are more specific.
768
- * - Static segments are more specific than dynamic segments.
769
- * @internal
770
- */
771
- _getSpecificityScore(layer) {
772
- const path2 = layer.path.toString();
773
- let score = 0;
774
- score += path2.split("/").length * 100;
775
- score -= (path2.match(/:/g) || []).length * 10;
776
- if (layer.path instanceof RegExp) {
777
- score -= 50;
778
- }
779
- if (layer.isAgent || layer.isTool) {
780
- score += 1;
781
- }
782
- return score;
783
- }
784
- /**
785
- * The core execution engine. It finds all matching layers for a given path
786
- * and runs them in a middleware-style chain.
787
- * @internal
788
- */
789
- async _execute(path2, ctx, isInternalCall = false) {
790
- try {
791
- const normalizedPath = path2.length > 1 && path2.endsWith("/") ? path2.slice(0, -1) : path2;
792
- ctx.logger.log(`Executing path. isInternalCall=${isInternalCall}`);
793
- const layersToRun = this.stack.filter((layer) => {
794
- let shouldRun = false;
795
- if (layer.path instanceof RegExp) {
796
- if (isInternalCall) {
797
- const exactRegex = new RegExp(`^${layer.path.source}$`);
798
- shouldRun = exactRegex.test(normalizedPath);
799
- } else {
800
- shouldRun = layer.path.test(normalizedPath);
801
- }
802
- } else if (typeof layer.path === "string") {
803
- const layerPath = layer.path;
804
- if (layerPath === "*") {
805
- return !isInternalCall;
806
- }
807
- const normalizedLayerPath = layerPath.length > 1 && layerPath.endsWith("/") ? layerPath.slice(0, -1) : layerPath;
808
- const isExactMatch = normalizedPath === normalizedLayerPath;
809
- if (isInternalCall) {
810
- if (layer.isTool && layer.hasDynamicParams) {
811
- shouldRun = extractPathParams(layerPath, normalizedPath) !== null;
812
- } else {
813
- shouldRun = isExactMatch;
814
- }
815
- } else {
816
- if (layer.isTool) {
817
- if (layer.hasDynamicParams) {
818
- shouldRun = extractPathParams(layerPath, normalizedPath) !== null;
819
- } else {
820
- shouldRun = isExactMatch;
821
- }
822
- } else if (layer.isAgent) {
823
- shouldRun = isExactMatch;
824
- } else {
825
- shouldRun = normalizedPath.startsWith(normalizedLayerPath);
826
- }
827
- }
828
- }
829
- if (shouldRun) {
830
- ctx.logger.log(
831
- `[AiAgentKit][_execute] Layer MATCH: path=${normalizedPath}, layer.path=${layer.path}, isTool=${layer.isTool}, isAgent=${layer.isAgent}, isInternal=${isInternalCall}`
832
- );
833
- }
834
- return shouldRun;
835
- });
836
- layersToRun.sort(
837
- (a, b) => this._getSpecificityScore(a) - this._getSpecificityScore(b)
838
- );
839
- const layerDescriptions = layersToRun.map(
840
- (l) => `${l.path.toString()} (${l.isTool ? "tool" : l.isAgent ? "agent" : "middleware"})`
841
- );
842
- ctx.logger.log(
843
- `Found ${layersToRun.length} layers to run: [${layerDescriptions.join(
844
- ", "
845
- )}]`
846
- );
847
- const hasTool = layersToRun.some((l) => l.isTool);
848
- const hasAgent = layersToRun.some((l) => l.isAgent);
849
- if (!layersToRun.length) {
850
- const errorMsg = `No agent or tool found for path: ${normalizedPath}`;
851
- ctx.logger.error(errorMsg);
852
- throw new AgentNotFoundError(normalizedPath);
853
- }
854
- const dispatch = async (index) => {
855
- const layer = layersToRun[index];
856
- if (!layer) {
857
- return;
858
- }
859
- const next = () => dispatch(index + 1);
860
- const layerPath = typeof layer.path === "string" ? layer.path : layer.path.toString();
861
- const layerType = layer.isTool ? "tool" : layer.isAgent ? "agent" : "middleware";
862
- ctx.logger.log(`-> Running ${layerType}: ${layerPath}`);
863
- try {
864
- if (ctx._onExecutionStart) {
865
- ctx._onExecutionStart();
866
- }
867
- const result = await layer.handler(ctx, next);
868
- ctx.logger.log(`<- Finished ${layerType}: ${layerPath}`);
869
- return result;
870
- } catch (err) {
871
- ctx.logger.error(
872
- `Error in ${layerType} layer for path: ${layerPath}`,
873
- err
874
- );
875
- throw err;
876
- } finally {
877
- if (ctx._onExecutionEnd) {
878
- ctx._onExecutionEnd();
879
- }
880
- }
881
- };
882
- return await dispatch(0);
883
- } finally {
884
- }
885
- }
886
- /**
887
- * The main public entry point for the router. It handles an incoming request,
888
- * sets up the response stream, creates the root context, and starts the execution chain.
889
- *
890
- * @param path The path of the agent or tool to execute.
891
- * @param initialContext The initial context for the request, typically containing messages.
892
- * @returns A standard `Response` object containing the rich UI stream.
893
- */
894
- handle(path2, initialContext) {
895
- this.logger?.log(`Handling request for path: ${path2}`);
896
- const self = this;
897
- let executionCompletionResolver = null;
898
- const executionCompletionPromise = new Promise((resolve) => {
899
- executionCompletionResolver = resolve;
900
- });
901
- return createUIMessageStreamResponse({
902
- stream: self.handleStream(
903
- path2,
904
- initialContext,
905
- executionCompletionPromise,
906
- executionCompletionResolver
907
- )
908
- });
909
- }
910
- handleStream(path2, initialContext, executionCompletionPromise, executionCompletionResolver) {
911
- const self = this;
912
- return createUIMessageStream({
913
- originalMessages: initialContext.request.messages,
914
- execute: async ({ writer }) => {
915
- const streamWriter = new StreamWriter(writer);
916
- const requestId = generateId();
917
- const store = self._store instanceof MemoryStore ? new MemoryStore() : self._store;
918
- const ctx = {
919
- ...initialContext,
920
- request: {
921
- ...initialContext.request,
922
- path: path2
923
- // Set the initial path for the root context
924
- },
925
- state: {},
926
- store,
927
- executionContext: { currentPath: path2, callDepth: 0 },
928
- requestId,
929
- logger: self._createLogger(requestId, path2, 0),
930
- response: {
931
- ...streamWriter.writer,
932
- writeMessageMetadata: streamWriter.writeMessageMetadata,
933
- writeCustomTool: streamWriter.writeCustomTool,
934
- writeObjectAsTool: streamWriter.writeObjectAsTool,
935
- generateId
936
- },
937
- next: void 0,
938
- // Will be replaced right after
939
- _onExecutionStart: () => {
940
- self.pendingExecutions++;
941
- self.logger?.log(
942
- `[AiAgentKit][lifecycle] Execution started. Pending: ${self.pendingExecutions}`
943
- );
944
- },
945
- _onExecutionEnd: () => {
946
- self.pendingExecutions--;
947
- self.logger?.log(
948
- `[AiAgentKit][lifecycle] Execution ended. Pending: ${self.pendingExecutions}`
949
- );
950
- if (self.pendingExecutions === 0 && executionCompletionResolver) {
951
- self.logger?.log(
952
- `[AiAgentKit][lifecycle] All executions finished. Resolving promise.`
953
- );
954
- executionCompletionResolver();
955
- }
956
- }
957
- };
958
- ctx.next = new NextHandler(
959
- ctx,
960
- self,
961
- ctx._onExecutionStart,
962
- ctx._onExecutionEnd
963
- );
964
- ctx._onExecutionStart();
965
- self.logger?.log(
966
- `[AiAgentKit][lifecycle] Main execution chain started.`
967
- );
968
- try {
969
- const response = await self._execute(path2, ctx);
970
- const toolDefinition = this.actAsToolDefinitions.get(path2);
971
- if (toolDefinition && !toolDefinition.metadata?.hideUI) {
972
- ctx.response.writeCustomTool({
973
- toolName: toolDefinition.id,
974
- toolCallId: toolDefinition.id + "-" + ctx.response.generateId(),
975
- output: response
976
- });
977
- }
978
- return response;
979
- } catch (err) {
980
- ctx.logger.error("Unhandled error in main execution chain", err);
981
- } finally {
982
- ctx._onExecutionEnd();
983
- self.logger?.log(
984
- `[AiAgentKit][lifecycle] Main execution chain finished.`
985
- );
986
- }
987
- await executionCompletionPromise;
988
- self.logger?.log(
989
- `[AiAgentKit][lifecycle] All executions truly finished. Stream can be safely closed.`
990
- );
991
- }
992
- });
993
- }
994
- /**
995
- * Handles an incoming request and returns a promise that resolves with the full,
996
- * non-streamed response. This is useful for environments where streaming is not
997
- * desired or for testing.
998
- *
999
- * @param path The path of the agent or tool to execute.
1000
- * @param initialContext The initial context for the request, typically containing messages.
1001
- * @returns A `Promise<Response>` that resolves with the final JSON response.
1002
- */
1003
- async toAwaitResponse(path2, initialContext) {
1004
- this.logger?.log(`Handling request for path: ${path2}`);
1005
- const self = this;
1006
- let executionCompletionResolver = null;
1007
- const executionCompletionPromise = new Promise((resolve) => {
1008
- executionCompletionResolver = resolve;
1009
- });
1010
- const stream = this.handleStream(
1011
- path2,
1012
- initialContext,
1013
- executionCompletionPromise,
1014
- executionCompletionResolver
1015
- );
1016
- const messageStream = readUIMessageStream({
1017
- stream,
1018
- onError: (error) => {
1019
- this.logger?.error("Error reading UI message stream", error);
1020
- }
1021
- });
1022
- let finalMessages = [];
1023
- const thisMessageId = generateId();
1024
- for await (const message of messageStream) {
1025
- if (message.id?.length > 0) {
1026
- finalMessages.push(message);
1027
- } else if (finalMessages.find((m) => m.id === thisMessageId)) {
1028
- finalMessages = finalMessages.map(
1029
- (m) => m.id === thisMessageId ? {
1030
- ...m,
1031
- metadata: {
1032
- ...m.metadata ?? {},
1033
- ...message.metadata ?? {}
1034
- },
1035
- parts: clubParts([
1036
- ...m.parts ?? [],
1037
- ...message.parts ?? []
1038
- ])
1039
- } : m
1040
- );
1041
- } else {
1042
- finalMessages.push({
1043
- ...message,
1044
- id: thisMessageId
1045
- });
1046
- }
1047
- }
1048
- const responseBody = JSON.stringify(finalMessages);
1049
- return new Response(responseBody, {
1050
- headers: { "Content-Type": "application/json" }
1051
- });
1052
- }
1053
- };
1054
- var NextHandler = class {
1055
- constructor(ctx, router, onExecutionStart, onExecutionEnd, parentNext) {
1056
- this.ctx = ctx;
1057
- this.router = router;
1058
- this.onExecutionStart = onExecutionStart;
1059
- this.onExecutionEnd = onExecutionEnd;
1060
- this.maxCallDepth = this.router.options.maxCallDepth;
1061
- }
1062
- async callAgent(agentPath, params, options) {
1063
- this.onExecutionStart();
1064
- try {
1065
- const currentDepth = this.ctx.executionContext.callDepth ?? 0;
1066
- if (currentDepth >= this.maxCallDepth) {
1067
- const err = new MaxCallDepthExceededError(this.maxCallDepth);
1068
- this.ctx.logger.error(`[callAgent] Aborting. ${err.message}`);
1069
- throw err;
1070
- }
1071
- const parentPath = this.ctx.executionContext.currentPath || "/";
1072
- const resolvedPath = this.router._resolvePath(
1073
- parentPath,
1074
- agentPath
1075
- );
1076
- this.ctx.logger.log(`Calling agent: resolvedPath='${resolvedPath}'`);
1077
- const subContext = this.router._createSubContext(this.ctx, {
1078
- type: "agent",
1079
- path: resolvedPath,
1080
- params: params ?? {},
1081
- messages: this.ctx.request.messages
1082
- });
1083
- const definition = this.router.actAsToolDefinitions.get(resolvedPath);
1084
- const toolCallId = definition?.id + "-" + this.ctx.response.generateId();
1085
- if (options?.streamToUI && definition) {
1086
- this.ctx.response.writeCustomTool({
1087
- toolName: definition?.id,
1088
- toolCallId,
1089
- input: subContext.request.params
1090
- });
1091
- }
1092
- const data = await this.router._execute(
1093
- resolvedPath,
1094
- subContext,
1095
- true
1096
- );
1097
- if (options?.streamToUI && definition) {
1098
- this.ctx.response.writeCustomTool({
1099
- toolName: definition?.id,
1100
- toolCallId,
1101
- output: data
1102
- });
1103
- }
1104
- return { ok: true, data };
1105
- } catch (error) {
1106
- this.ctx.logger.error(`[callAgent] Error:`, error);
1107
- return { ok: false, error };
1108
- } finally {
1109
- this.onExecutionEnd();
1110
- }
1111
- }
1112
- /**
1113
- * @deprecated Use agent-as-tools pattern instead. Use `ctx.next.callAgent()` to call agents that are exposed as tools.
1114
- * This method will be removed in a future version.
1115
- *
1116
- * Example migration:
1117
- * ```typescript
1118
- * // Old way (deprecated):
1119
- * const result = await ctx.next.callTool('/calculator', { a: 5, b: 3 });
1120
- *
1121
- * // New way (recommended):
1122
- * const result = await ctx.next.callAgent('/calculator', { a: 5, b: 3 });
1123
- * ```
1124
- */
1125
- async callTool(toolPath, params, options) {
1126
- this.ctx.logger.warn(
1127
- `[DEPRECATION WARNING] ctx.next.callTool() is deprecated and will be removed in a future version. Please use ctx.next.callAgent() instead to call agents that are exposed as tools.`
1128
- );
1129
- this.onExecutionStart();
1130
- try {
1131
- const parentPath = this.ctx.executionContext.currentPath || "/";
1132
- const resolvedPath = this.router._resolvePath(
1133
- parentPath,
1134
- toolPath
1135
- );
1136
- this.ctx.logger.log(`Calling tool: resolvedPath='${resolvedPath}'`);
1137
- const subContext = this.router._createSubContext(this.ctx, {
1138
- type: "tool",
1139
- path: resolvedPath,
1140
- params: params ?? {},
1141
- messages: this.ctx.request.messages
1142
- });
1143
- const data = await this.router._execute(
1144
- resolvedPath,
1145
- subContext,
1146
- true
1147
- );
1148
- return { ok: true, data };
1149
- } catch (error) {
1150
- this.ctx.logger.error(`[callTool] Error:`, error);
1151
- return { ok: false, error };
1152
- } finally {
1153
- this.onExecutionEnd();
1154
- }
1155
- }
1156
- /**
1157
- * @deprecated Use agent-as-tools pattern instead. Use `ctx.next.agentAsTool()` to attach agents as tools.
1158
- * This method will be removed in a future version.
1159
- *
1160
- * Example migration:
1161
- * ```typescript
1162
- * // Old way (deprecated):
1163
- * const tool = ctx.next.attachTool('/calculator');
1164
- *
1165
- * // New way (recommended):
1166
- * const tool = ctx.next.agentAsTool('/calculator');
1167
- * ```
1168
- */
1169
- attachTool(toolPath, _tool) {
1170
- this.ctx.logger.warn(
1171
- `[DEPRECATION WARNING] ctx.next.attachTool() is deprecated and will be removed in a future version. Please use ctx.next.agentAsTool() instead to attach agents as tools.`
1172
- );
1173
- const parentPath = this.ctx.executionContext.currentPath || "/";
1174
- const resolvedPath = this.router._resolvePath(
1175
- parentPath,
1176
- toolPath
1177
- );
1178
- this.ctx.logger.log(`Attaching tool: resolvedPath='${resolvedPath}'`);
1179
- const layer = this.router.stack.find((l) => {
1180
- if (!l.isTool) return false;
1181
- if (l.path === resolvedPath) return true;
1182
- if (l.hasDynamicParams && typeof l.path === "string") {
1183
- return extractPathParams(l.path, resolvedPath) !== null;
1184
- }
1185
- return false;
1186
- });
1187
- if (!layer || !layer.toolOptions) {
1188
- this.ctx.logger.error(
1189
- `[attachTool] Tool not found at resolved path: ${resolvedPath}`
1190
- );
1191
- throw new ToolNotFoundError(resolvedPath);
1192
- }
1193
- if (layer.toolOptions.type === "factory") {
1194
- return layer.toolOptions.factory(this.ctx);
1195
- }
1196
- const { description, schema } = layer.toolOptions;
1197
- return {
1198
- description,
1199
- inputSchema: schema,
1200
- ..._tool ?? {},
1201
- execute: async (params, options) => {
1202
- if (_tool?.execute) {
1203
- return await _tool.execute?.(params, options);
1204
- }
1205
- const result = await this.callTool(toolPath, params, options);
1206
- if (!result.ok) {
1207
- throw result.error;
1208
- }
1209
- return result.data;
1210
- }
1211
- };
1212
- }
1213
- agentAsTool(agentPath, toolDefinition) {
1214
- const parentPath = this.ctx.executionContext.currentPath || "/";
1215
- const resolvedPath = this.router._resolvePath(
1216
- parentPath,
1217
- agentPath
1218
- );
1219
- let preDefined;
1220
- const pathsToTry = [resolvedPath];
1221
- if (agentPath.startsWith("/")) {
1222
- pathsToTry.unshift(agentPath);
1223
- }
1224
- for (const pathToTry of pathsToTry) {
1225
- for (const [key, value] of this.router.actAsToolDefinitions) {
1226
- if (typeof key === "string") {
1227
- if (key === pathToTry) {
1228
- preDefined = value;
1229
- break;
1230
- }
1231
- if (extractPathParams(key, pathToTry) !== null) {
1232
- preDefined = value;
1233
- break;
1234
- }
1235
- }
1236
- if (key instanceof RegExp && key.test(pathToTry)) {
1237
- preDefined = value;
1238
- break;
1239
- }
1240
- }
1241
- if (preDefined) break;
1242
- }
1243
- const definition = toolDefinition || preDefined;
1244
- if (!definition) {
1245
- this.ctx.logger.error(
1246
- `[agentAsTool] No definition found for agent at resolved path: ${resolvedPath}`
1247
- );
1248
- throw new AgentDefinitionMissingError(resolvedPath);
1249
- }
1250
- const { id, metadata, ...restDefinition } = definition;
1251
- return {
1252
- [id]: {
1253
- ...restDefinition,
1254
- metadata: {
1255
- ...metadata,
1256
- toolKey: id,
1257
- name: restDefinition.name,
1258
- description: restDefinition.description,
1259
- absolutePath: restDefinition.path
1260
- },
1261
- execute: (params, options) => {
1262
- const executeInternal = async () => {
1263
- const result = await this.callAgent(agentPath, params, options);
1264
- if (!result.ok) {
1265
- throw result.error;
1266
- }
1267
- return result.data;
1268
- };
1269
- const newPromise = this.router.toolExecutionPromise.then(
1270
- executeInternal,
1271
- executeInternal
1272
- );
1273
- this.router.toolExecutionPromise = newPromise;
1274
- return newPromise;
1275
- }
1276
- }
1277
- };
1278
- }
1279
- getToolDefinition(agentPath) {
1280
- const parentPath = this.ctx.executionContext.currentPath || "/";
1281
- const resolvedPath = this.router._resolvePath(
1282
- parentPath,
1283
- agentPath
1284
- );
1285
- let preDefined;
1286
- const pathsToTry = [resolvedPath];
1287
- if (typeof agentPath === "string" && agentPath.startsWith("/")) {
1288
- pathsToTry.unshift(agentPath);
1289
- }
1290
- for (const pathToTry of pathsToTry) {
1291
- for (const [key, value] of this.router.actAsToolDefinitions) {
1292
- if (typeof key === "string") {
1293
- if (key === pathToTry) {
1294
- preDefined = value;
1295
- break;
1296
- }
1297
- if (extractPathParams(key, pathToTry) !== null) {
1298
- preDefined = value;
1299
- break;
1300
- }
1301
- }
1302
- if (key instanceof RegExp && key.test(pathToTry)) {
1303
- preDefined = value;
1304
- break;
1305
- }
1306
- }
1307
- if (preDefined) break;
1308
- }
1309
- const definition = preDefined;
1310
- if (!definition) {
1311
- this.ctx.logger.error(
1312
- `[agentAsTool] No definition found for agent at resolved path: ${resolvedPath}`
1313
- );
1314
- throw new AgentDefinitionMissingError(resolvedPath);
1315
- }
1316
- const { metadata, ...restDefinition } = definition;
1317
- return {
1318
- ...restDefinition,
1319
- metadata: {
1320
- ...metadata,
1321
- toolKey: restDefinition.id,
1322
- name: restDefinition.name,
1323
- description: restDefinition.description,
1324
- absolutePath: restDefinition.path
1325
- }
1326
- };
1327
- }
1328
- };
1329
- export {
1330
- AgentDefinitionMissingError,
1331
- AgentNotFoundError,
1332
- AiKitError,
1333
- AiRouter,
1334
- MaxCallDepthExceededError,
1335
- MemoryStore,
1336
- StreamWriter,
1337
- ToolNotFoundError,
1338
- ToolValidationError,
1339
- findFirstElement,
1340
- findLastElement,
1341
- findLastMessageWith,
1342
- getGlobalLogger,
1343
- getTextParts,
1344
- getTextPartsContent,
1345
- setGlobalLogger
1346
- };
1347
- //# sourceMappingURL=index.mjs.map