@microfox/ai-router 2.1.1 → 2.1.2
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/CHANGELOG.md +6 -0
- package/dist/index.d.mts +15 -5
- package/dist/index.d.ts +15 -5
- package/dist/index.js +95 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +95 -18
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -130,6 +130,7 @@ type Layer<METADATA extends Record<string, any> = Record<string, any>, ContextSt
|
|
|
130
130
|
path: string | RegExp;
|
|
131
131
|
handler: AiMiddleware<METADATA, ContextState, PARAMS, PARTS, TOOLS>;
|
|
132
132
|
isAgent: boolean;
|
|
133
|
+
timing?: 'before' | 'after';
|
|
133
134
|
hasDynamicParams?: boolean;
|
|
134
135
|
paramNames?: string[];
|
|
135
136
|
};
|
|
@@ -212,13 +213,21 @@ declare class AiRouter<KIT_METADATA extends Record<string, any> = Record<string,
|
|
|
212
213
|
*/
|
|
213
214
|
agent<const TAgents extends (AiMiddleware<any, any, any, any, any> | AiRouter<any, any, any, any, any, any>)[]>(agentPath: string | RegExp | AiMiddleware<KIT_METADATA, ContextState, PARAMS, PARTS, TOOLS>, ...agents: TAgents): AiRouter<KIT_METADATA, ContextState, PARAMS, PARTS, TOOLS, REGISTERED_TOOLS & (TAgents[number] extends AiRouter<any, any, any, any, any, infer R> ? R : {})>;
|
|
214
215
|
/**
|
|
215
|
-
*
|
|
216
|
-
*
|
|
216
|
+
* Registers middleware that runs BEFORE agent execution for a specific path prefix, regex pattern, or wildcard.
|
|
217
|
+
* The middleware can modify the context and must call `next()` to pass control to the next handler.
|
|
217
218
|
*
|
|
218
|
-
* @param
|
|
219
|
+
* @param mountPathArg The path prefix, regex pattern, or "*" for wildcard matching.
|
|
219
220
|
* @param handler The middleware function or AiAgentKit router instance to mount.
|
|
220
221
|
*/
|
|
221
|
-
|
|
222
|
+
before<THandler extends AiMiddleware<KIT_METADATA, ContextState, PARAMS, PARTS, TOOLS> | AiRouter<any, any, any, any, any, any>>(mountPathArg: string | RegExp, handler: THandler): AiRouter<KIT_METADATA, ContextState, PARAMS, PARTS, TOOLS, REGISTERED_TOOLS & (THandler extends AiRouter<any, any, any, any, any, infer R> ? R : {})>;
|
|
223
|
+
/**
|
|
224
|
+
* Registers middleware that runs AFTER agent execution for a specific path prefix, regex pattern, or wildcard.
|
|
225
|
+
* The middleware can modify the context and must call `next()` to pass control to the next handler.
|
|
226
|
+
*
|
|
227
|
+
* @param mountPathArg The path prefix, regex pattern, or "*" for wildcard matching.
|
|
228
|
+
* @param handler The middleware function or AiAgentKit router instance to mount.
|
|
229
|
+
*/
|
|
230
|
+
after<THandler extends AiMiddleware<KIT_METADATA, ContextState, PARAMS, PARTS, TOOLS> | AiRouter<any, any, any, any, any, any>>(mountPathArg: string | RegExp, handler: THandler): AiRouter<KIT_METADATA, ContextState, PARAMS, PARTS, TOOLS, REGISTERED_TOOLS & (THandler extends AiRouter<any, any, any, any, any, infer R> ? R : {})>;
|
|
222
231
|
/**
|
|
223
232
|
* Pre-defines the schema and description for an agent when it is used as a tool by an LLM.
|
|
224
233
|
* This allows `next.agentAsTool()` to create a valid `Tool` object without needing the definition at call time.
|
|
@@ -242,8 +251,9 @@ declare class AiRouter<KIT_METADATA extends Record<string, any> = Record<string,
|
|
|
242
251
|
*/
|
|
243
252
|
registry(): {
|
|
244
253
|
map: Record<string, {
|
|
245
|
-
|
|
254
|
+
before: any[];
|
|
246
255
|
agents: any[];
|
|
256
|
+
after: any[];
|
|
247
257
|
}>;
|
|
248
258
|
tools: REGISTERED_TOOLS;
|
|
249
259
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -130,6 +130,7 @@ type Layer<METADATA extends Record<string, any> = Record<string, any>, ContextSt
|
|
|
130
130
|
path: string | RegExp;
|
|
131
131
|
handler: AiMiddleware<METADATA, ContextState, PARAMS, PARTS, TOOLS>;
|
|
132
132
|
isAgent: boolean;
|
|
133
|
+
timing?: 'before' | 'after';
|
|
133
134
|
hasDynamicParams?: boolean;
|
|
134
135
|
paramNames?: string[];
|
|
135
136
|
};
|
|
@@ -212,13 +213,21 @@ declare class AiRouter<KIT_METADATA extends Record<string, any> = Record<string,
|
|
|
212
213
|
*/
|
|
213
214
|
agent<const TAgents extends (AiMiddleware<any, any, any, any, any> | AiRouter<any, any, any, any, any, any>)[]>(agentPath: string | RegExp | AiMiddleware<KIT_METADATA, ContextState, PARAMS, PARTS, TOOLS>, ...agents: TAgents): AiRouter<KIT_METADATA, ContextState, PARAMS, PARTS, TOOLS, REGISTERED_TOOLS & (TAgents[number] extends AiRouter<any, any, any, any, any, infer R> ? R : {})>;
|
|
214
215
|
/**
|
|
215
|
-
*
|
|
216
|
-
*
|
|
216
|
+
* Registers middleware that runs BEFORE agent execution for a specific path prefix, regex pattern, or wildcard.
|
|
217
|
+
* The middleware can modify the context and must call `next()` to pass control to the next handler.
|
|
217
218
|
*
|
|
218
|
-
* @param
|
|
219
|
+
* @param mountPathArg The path prefix, regex pattern, or "*" for wildcard matching.
|
|
219
220
|
* @param handler The middleware function or AiAgentKit router instance to mount.
|
|
220
221
|
*/
|
|
221
|
-
|
|
222
|
+
before<THandler extends AiMiddleware<KIT_METADATA, ContextState, PARAMS, PARTS, TOOLS> | AiRouter<any, any, any, any, any, any>>(mountPathArg: string | RegExp, handler: THandler): AiRouter<KIT_METADATA, ContextState, PARAMS, PARTS, TOOLS, REGISTERED_TOOLS & (THandler extends AiRouter<any, any, any, any, any, infer R> ? R : {})>;
|
|
223
|
+
/**
|
|
224
|
+
* Registers middleware that runs AFTER agent execution for a specific path prefix, regex pattern, or wildcard.
|
|
225
|
+
* The middleware can modify the context and must call `next()` to pass control to the next handler.
|
|
226
|
+
*
|
|
227
|
+
* @param mountPathArg The path prefix, regex pattern, or "*" for wildcard matching.
|
|
228
|
+
* @param handler The middleware function or AiAgentKit router instance to mount.
|
|
229
|
+
*/
|
|
230
|
+
after<THandler extends AiMiddleware<KIT_METADATA, ContextState, PARAMS, PARTS, TOOLS> | AiRouter<any, any, any, any, any, any>>(mountPathArg: string | RegExp, handler: THandler): AiRouter<KIT_METADATA, ContextState, PARAMS, PARTS, TOOLS, REGISTERED_TOOLS & (THandler extends AiRouter<any, any, any, any, any, infer R> ? R : {})>;
|
|
222
231
|
/**
|
|
223
232
|
* Pre-defines the schema and description for an agent when it is used as a tool by an LLM.
|
|
224
233
|
* This allows `next.agentAsTool()` to create a valid `Tool` object without needing the definition at call time.
|
|
@@ -242,8 +251,9 @@ declare class AiRouter<KIT_METADATA extends Record<string, any> = Record<string,
|
|
|
242
251
|
*/
|
|
243
252
|
registry(): {
|
|
244
253
|
map: Record<string, {
|
|
245
|
-
|
|
254
|
+
before: any[];
|
|
246
255
|
agents: any[];
|
|
256
|
+
after: any[];
|
|
247
257
|
}>;
|
|
248
258
|
tools: REGISTERED_TOOLS;
|
|
249
259
|
};
|
package/dist/index.js
CHANGED
|
@@ -389,7 +389,20 @@ var AiRouter = class _AiRouter {
|
|
|
389
389
|
for (const handler of agents) {
|
|
390
390
|
if (typeof handler !== "function") {
|
|
391
391
|
if (handler instanceof _AiRouter && typeof prefix === "string") {
|
|
392
|
-
|
|
392
|
+
const router = handler;
|
|
393
|
+
const mountPath = prefix.toString().replace(/\/$/, "");
|
|
394
|
+
router.stack.forEach((layer) => {
|
|
395
|
+
const layerPath = layer.path.toString();
|
|
396
|
+
const relativeLayerPath = layerPath.startsWith("/") ? layerPath.substring(1) : layerPath;
|
|
397
|
+
const newPath = import_path.default.posix.join(mountPath, relativeLayerPath);
|
|
398
|
+
this.stack.push({ ...layer, path: newPath });
|
|
399
|
+
});
|
|
400
|
+
router.actAsToolDefinitions.forEach((value, key) => {
|
|
401
|
+
const keyPath = key.toString();
|
|
402
|
+
const relativeKeyPath = keyPath.startsWith("/") ? keyPath.substring(1) : keyPath;
|
|
403
|
+
const newKey = import_path.default.posix.join(mountPath, relativeKeyPath);
|
|
404
|
+
this.actAsToolDefinitions.set(newKey, value);
|
|
405
|
+
});
|
|
393
406
|
}
|
|
394
407
|
continue;
|
|
395
408
|
}
|
|
@@ -404,13 +417,13 @@ var AiRouter = class _AiRouter {
|
|
|
404
417
|
return this;
|
|
405
418
|
}
|
|
406
419
|
/**
|
|
407
|
-
*
|
|
408
|
-
*
|
|
420
|
+
* Registers middleware that runs BEFORE agent execution for a specific path prefix, regex pattern, or wildcard.
|
|
421
|
+
* The middleware can modify the context and must call `next()` to pass control to the next handler.
|
|
409
422
|
*
|
|
410
|
-
* @param
|
|
423
|
+
* @param mountPathArg The path prefix, regex pattern, or "*" for wildcard matching.
|
|
411
424
|
* @param handler The middleware function or AiAgentKit router instance to mount.
|
|
412
425
|
*/
|
|
413
|
-
|
|
426
|
+
before(mountPathArg, handler) {
|
|
414
427
|
if (mountPathArg instanceof RegExp && handler instanceof _AiRouter) {
|
|
415
428
|
throw new AiKitError(
|
|
416
429
|
"[AiAgentKit] Mounting a router on a RegExp path is not supported."
|
|
@@ -435,8 +448,50 @@ var AiRouter = class _AiRouter {
|
|
|
435
448
|
this.stack.push({
|
|
436
449
|
path: mountPathArg,
|
|
437
450
|
handler,
|
|
438
|
-
isAgent: false
|
|
451
|
+
isAgent: false,
|
|
439
452
|
// Middleware is not a terminal agent
|
|
453
|
+
timing: "before"
|
|
454
|
+
// Mark as before middleware
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
return this;
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Registers middleware that runs AFTER agent execution for a specific path prefix, regex pattern, or wildcard.
|
|
461
|
+
* The middleware can modify the context and must call `next()` to pass control to the next handler.
|
|
462
|
+
*
|
|
463
|
+
* @param mountPathArg The path prefix, regex pattern, or "*" for wildcard matching.
|
|
464
|
+
* @param handler The middleware function or AiAgentKit router instance to mount.
|
|
465
|
+
*/
|
|
466
|
+
after(mountPathArg, handler) {
|
|
467
|
+
if (mountPathArg instanceof RegExp && handler instanceof _AiRouter) {
|
|
468
|
+
throw new AiKitError(
|
|
469
|
+
"[AiAgentKit] Mounting a router on a RegExp path is not supported."
|
|
470
|
+
);
|
|
471
|
+
}
|
|
472
|
+
if (handler instanceof _AiRouter) {
|
|
473
|
+
const router = handler;
|
|
474
|
+
const mountPath = mountPathArg.toString().replace(/\/$/, "");
|
|
475
|
+
router.stack.forEach((layer) => {
|
|
476
|
+
const layerPath = layer.path.toString();
|
|
477
|
+
const relativeLayerPath = layerPath.startsWith("/") ? layerPath.substring(1) : layerPath;
|
|
478
|
+
const newPath = import_path.default.posix.join(mountPath, relativeLayerPath);
|
|
479
|
+
this.stack.push({ ...layer, path: newPath });
|
|
480
|
+
});
|
|
481
|
+
router.actAsToolDefinitions.forEach((value, key) => {
|
|
482
|
+
const keyPath = key.toString();
|
|
483
|
+
const relativeKeyPath = keyPath.startsWith("/") ? keyPath.substring(1) : keyPath;
|
|
484
|
+
const newKey = import_path.default.posix.join(mountPath, relativeKeyPath);
|
|
485
|
+
this.actAsToolDefinitions.set(newKey, value);
|
|
486
|
+
});
|
|
487
|
+
} else {
|
|
488
|
+
this.stack.push({
|
|
489
|
+
path: mountPathArg,
|
|
490
|
+
handler,
|
|
491
|
+
isAgent: false,
|
|
492
|
+
// Middleware is not a terminal agent
|
|
493
|
+
timing: "after"
|
|
494
|
+
// Mark as after middleware
|
|
440
495
|
});
|
|
441
496
|
}
|
|
442
497
|
return this;
|
|
@@ -502,7 +557,7 @@ var AiRouter = class _AiRouter {
|
|
|
502
557
|
for (const layer of this.stack) {
|
|
503
558
|
const pathKey = layer.path.toString();
|
|
504
559
|
if (!registryMap[pathKey]) {
|
|
505
|
-
registryMap[pathKey] = {
|
|
560
|
+
registryMap[pathKey] = { before: [], agents: [], after: [] };
|
|
506
561
|
}
|
|
507
562
|
if (layer.isAgent) {
|
|
508
563
|
const agentInfo = {
|
|
@@ -516,9 +571,17 @@ var AiRouter = class _AiRouter {
|
|
|
516
571
|
}
|
|
517
572
|
registryMap[pathKey].agents.push(agentInfo);
|
|
518
573
|
} else {
|
|
519
|
-
|
|
520
|
-
handler: layer.handler.name || "anonymous"
|
|
521
|
-
|
|
574
|
+
const middlewareInfo = {
|
|
575
|
+
handler: layer.handler.name || "anonymous",
|
|
576
|
+
timing: layer.timing || "middleware"
|
|
577
|
+
};
|
|
578
|
+
if (layer.timing === "before") {
|
|
579
|
+
registryMap[pathKey].before.push(middlewareInfo);
|
|
580
|
+
} else if (layer.timing === "after") {
|
|
581
|
+
registryMap[pathKey].after.push(middlewareInfo);
|
|
582
|
+
} else {
|
|
583
|
+
registryMap[pathKey].before.push(middlewareInfo);
|
|
584
|
+
}
|
|
522
585
|
}
|
|
523
586
|
}
|
|
524
587
|
return {
|
|
@@ -671,31 +734,45 @@ var AiRouter = class _AiRouter {
|
|
|
671
734
|
}
|
|
672
735
|
return shouldRun;
|
|
673
736
|
});
|
|
674
|
-
layersToRun.
|
|
737
|
+
const beforeLayers = layersToRun.filter(
|
|
738
|
+
(l) => !l.isAgent && l.timing === "before"
|
|
739
|
+
);
|
|
740
|
+
const agentLayers = layersToRun.filter((l) => l.isAgent);
|
|
741
|
+
const afterLayers = layersToRun.filter(
|
|
742
|
+
(l) => !l.isAgent && l.timing === "after"
|
|
743
|
+
);
|
|
744
|
+
beforeLayers.sort(
|
|
675
745
|
(a, b) => this._getSpecificityScore(a) - this._getSpecificityScore(b)
|
|
676
746
|
);
|
|
677
|
-
|
|
678
|
-
(
|
|
747
|
+
agentLayers.sort(
|
|
748
|
+
(a, b) => this._getSpecificityScore(a) - this._getSpecificityScore(b)
|
|
679
749
|
);
|
|
750
|
+
afterLayers.sort(
|
|
751
|
+
(a, b) => this._getSpecificityScore(a) - this._getSpecificityScore(b)
|
|
752
|
+
);
|
|
753
|
+
const orderedLayers = [...beforeLayers, ...agentLayers, ...afterLayers];
|
|
754
|
+
const layerDescriptions = orderedLayers.map((l) => {
|
|
755
|
+
const type = l.isAgent ? "agent" : l.timing === "before" ? "before" : l.timing === "after" ? "after" : "middleware";
|
|
756
|
+
return `${l.path.toString()} (${type})`;
|
|
757
|
+
});
|
|
680
758
|
ctx.logger.log(
|
|
681
|
-
`Found ${
|
|
759
|
+
`Found ${orderedLayers.length} layers to run: [${layerDescriptions.join(
|
|
682
760
|
", "
|
|
683
761
|
)}]`
|
|
684
762
|
);
|
|
685
|
-
|
|
686
|
-
if (!layersToRun.length) {
|
|
763
|
+
if (!agentLayers.length && !beforeLayers.length && !afterLayers.length) {
|
|
687
764
|
const errorMsg = `No agent or tool found for path: ${normalizedPath}`;
|
|
688
765
|
ctx.logger.error(errorMsg);
|
|
689
766
|
throw new AgentNotFoundError(normalizedPath);
|
|
690
767
|
}
|
|
691
768
|
const dispatch = async (index) => {
|
|
692
|
-
const layer =
|
|
769
|
+
const layer = orderedLayers[index];
|
|
693
770
|
if (!layer) {
|
|
694
771
|
return;
|
|
695
772
|
}
|
|
696
773
|
const next = () => dispatch(index + 1);
|
|
697
774
|
const layerPath = typeof layer.path === "string" ? layer.path : layer.path.toString();
|
|
698
|
-
const layerType = layer.isAgent ? "agent" : "middleware";
|
|
775
|
+
const layerType = layer.isAgent ? "agent" : layer.timing === "before" ? "before" : layer.timing === "after" ? "after" : "middleware";
|
|
699
776
|
ctx.logger.log(`-> Running ${layerType}: ${layerPath}`);
|
|
700
777
|
try {
|
|
701
778
|
if (ctx._onExecutionStart) {
|