ai.matey.patterns 0.2.0

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 (40) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/LICENSE +21 -0
  3. package/dist/cjs/batch-processor.js +136 -0
  4. package/dist/cjs/batch-processor.js.map +1 -0
  5. package/dist/cjs/complexity-router.js +85 -0
  6. package/dist/cjs/complexity-router.js.map +1 -0
  7. package/dist/cjs/cost-optimizer.js +66 -0
  8. package/dist/cjs/cost-optimizer.js.map +1 -0
  9. package/dist/cjs/failover.js +55 -0
  10. package/dist/cjs/failover.js.map +1 -0
  11. package/dist/cjs/index.js +23 -0
  12. package/dist/cjs/index.js.map +1 -0
  13. package/dist/cjs/parallel-aggregator.js +68 -0
  14. package/dist/cjs/parallel-aggregator.js.map +1 -0
  15. package/dist/esm/batch-processor.js +133 -0
  16. package/dist/esm/batch-processor.js.map +1 -0
  17. package/dist/esm/complexity-router.js +81 -0
  18. package/dist/esm/complexity-router.js.map +1 -0
  19. package/dist/esm/cost-optimizer.js +63 -0
  20. package/dist/esm/cost-optimizer.js.map +1 -0
  21. package/dist/esm/failover.js +52 -0
  22. package/dist/esm/failover.js.map +1 -0
  23. package/dist/esm/index.js +14 -0
  24. package/dist/esm/index.js.map +1 -0
  25. package/dist/esm/parallel-aggregator.js +65 -0
  26. package/dist/esm/parallel-aggregator.js.map +1 -0
  27. package/dist/types/batch-processor.d.ts +66 -0
  28. package/dist/types/batch-processor.d.ts.map +1 -0
  29. package/dist/types/complexity-router.d.ts +55 -0
  30. package/dist/types/complexity-router.d.ts.map +1 -0
  31. package/dist/types/cost-optimizer.d.ts +57 -0
  32. package/dist/types/cost-optimizer.d.ts.map +1 -0
  33. package/dist/types/failover.d.ts +40 -0
  34. package/dist/types/failover.d.ts.map +1 -0
  35. package/dist/types/index.d.ts +14 -0
  36. package/dist/types/index.d.ts.map +1 -0
  37. package/dist/types/parallel-aggregator.d.ts +45 -0
  38. package/dist/types/parallel-aggregator.d.ts.map +1 -0
  39. package/package.json +71 -0
  40. package/readme.md +54 -0
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Complexity-Based Routing
3
+ *
4
+ * Route requests to different backends by estimated query complexity —
5
+ * cheap/fast models for simple queries, capable models for hard ones.
6
+ * Extracted from docs/PATTERNS.md §1.
7
+ *
8
+ * @module
9
+ */
10
+ import { Router } from 'ai.matey.core';
11
+ /**
12
+ * Heuristic complexity score (0-100) from message length, question depth,
13
+ * and reasoning keywords.
14
+ */
15
+ export function defaultComplexityAnalyzer(request) {
16
+ const text = request.messages
17
+ .map((message) => typeof message.content === 'string'
18
+ ? message.content
19
+ : message.content.map((block) => (block.type === 'text' ? block.text : '')).join(' '))
20
+ .join(' ');
21
+ let score = 0;
22
+ // Length: up to 40 points at ~2000 chars
23
+ score += Math.min(40, text.length / 50);
24
+ // Reasoning indicators: up to 40 points
25
+ const reasoningKeywords = [
26
+ 'why',
27
+ 'how',
28
+ 'explain',
29
+ 'analyze',
30
+ 'compare',
31
+ 'evaluate',
32
+ 'design',
33
+ 'architect',
34
+ 'prove',
35
+ 'derive',
36
+ 'step by step',
37
+ 'trade-off',
38
+ 'tradeoff',
39
+ ];
40
+ const lower = text.toLowerCase();
41
+ const hits = reasoningKeywords.filter((keyword) => lower.includes(keyword)).length;
42
+ score += Math.min(40, hits * 10);
43
+ // Code blocks / structured content: up to 20 points
44
+ if (lower.includes('```') || lower.includes('function ') || lower.includes('class ')) {
45
+ score += 20;
46
+ }
47
+ return Math.min(100, Math.round(score));
48
+ }
49
+ /**
50
+ * Create a Router that picks its backend by query complexity.
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * const router = createComplexityRouter({
55
+ * tiers: [
56
+ * { backend: 'fast', maxComplexity: 30 },
57
+ * { backend: 'balanced', maxComplexity: 70 },
58
+ * { backend: 'powerful', maxComplexity: 100 },
59
+ * ],
60
+ * backends: { fast, balanced, powerful },
61
+ * });
62
+ * ```
63
+ */
64
+ export function createComplexityRouter(config) {
65
+ const analyzer = config.analyzer ?? defaultComplexityAnalyzer;
66
+ const tiers = [...config.tiers].sort((a, b) => a.maxComplexity - b.maxComplexity);
67
+ const router = new Router({
68
+ ...config.routerConfig,
69
+ routingStrategy: 'custom',
70
+ customRouter: (request, availableBackends) => {
71
+ const complexity = analyzer(request);
72
+ const tier = tiers.find((candidate) => complexity <= candidate.maxComplexity && availableBackends.includes(candidate.backend)) ?? tiers[tiers.length - 1];
73
+ return Promise.resolve(tier?.backend ?? null);
74
+ },
75
+ });
76
+ for (const [name, adapter] of Object.entries(config.backends)) {
77
+ router.register(name, adapter);
78
+ }
79
+ return router;
80
+ }
81
+ //# sourceMappingURL=complexity-router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"complexity-router.js","sourceRoot":"","sources":["../../src/complexity-router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Cost-Optimized Provider Selection
3
+ *
4
+ * A cost-optimizing Router plus a budget-window middleware: route to the
5
+ * cheapest capable backend and enforce a spending ceiling. Extracted from
6
+ * docs/PATTERNS.md §4.
7
+ *
8
+ * @module
9
+ */
10
+ import { Router } from 'ai.matey.core';
11
+ import { AdapterError, ErrorCode } from 'ai.matey.errors';
12
+ /**
13
+ * Create a cost-optimized router with an optional budget window.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const { router, middleware, recordSpend } = createCostOptimizer({
18
+ * backends: { cheap, premium },
19
+ * budget: { limitUSD: 10, windowMs: 3600_000 },
20
+ * });
21
+ * const bridge = new Bridge(frontend, router).use(middleware);
22
+ * ```
23
+ */
24
+ export function createCostOptimizer(config) {
25
+ const router = new Router({
26
+ trackCost: true,
27
+ capabilityBasedRouting: true,
28
+ optimization: 'cost',
29
+ ...config.routerConfig,
30
+ });
31
+ for (const [name, adapter] of Object.entries(config.backends)) {
32
+ router.register(name, adapter);
33
+ }
34
+ // Sliding-window spend ledger
35
+ const windowMs = config.budget?.windowMs ?? 3_600_000;
36
+ let entries = [];
37
+ const prune = () => {
38
+ const cutoff = Date.now() - windowMs;
39
+ entries = entries.filter((entry) => entry.at >= cutoff);
40
+ };
41
+ const getSpend = () => {
42
+ prune();
43
+ return entries.reduce((sum, entry) => sum + entry.costUSD, 0);
44
+ };
45
+ const recordSpend = (costUSD) => {
46
+ entries.push({ at: Date.now(), costUSD });
47
+ };
48
+ const middleware = async (_context, next) => {
49
+ if (config.budget && getSpend() >= config.budget.limitUSD) {
50
+ if ((config.budget.onExceeded ?? 'error') === 'error') {
51
+ throw new AdapterError({
52
+ code: ErrorCode.RATE_LIMIT_EXCEEDED,
53
+ message: `Budget of $${config.budget.limitUSD} exceeded for the current window`,
54
+ isRetryable: true,
55
+ provenance: { router: router.metadata.name },
56
+ });
57
+ }
58
+ }
59
+ return next();
60
+ };
61
+ return { router, middleware, getSpend, recordSpend };
62
+ }
63
+ //# sourceMappingURL=cost-optimizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost-optimizer.js","sourceRoot":"","sources":["../../src/cost-optimizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AA0C1D;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAA2B;IAC7D,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC;QACxB,SAAS,EAAE,IAAI;QACf,sBAAsB,EAAE,IAAI;QAC5B,YAAY,EAAE,MAAM;QACpB,GAAG,MAAM,CAAC,YAAY;KACvB,CAAC,CAAC;IAEH,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9D,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC;IAED,8BAA8B;IAC9B,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,QAAQ,IAAI,SAAS,CAAC;IACtD,IAAI,OAAO,GAA2C,EAAE,CAAC;IAEzD,MAAM,KAAK,GAAG,GAAS,EAAE;QACvB,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC;QACrC,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,IAAI,MAAM,CAAC,CAAC;IAC1D,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,GAAW,EAAE;QAC5B,KAAK,EAAE,CAAC;QACR,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAChE,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,CAAC,OAAe,EAAQ,EAAE;QAC5C,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IAC5C,CAAC,CAAC;IAEF,MAAM,UAAU,GAAe,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;QACtD,IAAI,MAAM,CAAC,MAAM,IAAI,QAAQ,EAAE,IAAI,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YAC1D,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,IAAI,OAAO,CAAC,KAAK,OAAO,EAAE,CAAC;gBACtD,MAAM,IAAI,YAAY,CAAC;oBACrB,IAAI,EAAE,SAAS,CAAC,mBAAmB;oBACnC,OAAO,EAAE,cAAc,MAAM,CAAC,MAAM,CAAC,QAAQ,kCAAkC;oBAC/E,WAAW,EAAE,IAAI;oBACjB,UAAU,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE;iBAC7C,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC;IAEF,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;AACvD,CAAC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Automatic Failover Middleware
3
+ *
4
+ * Bridge-level failover: when the primary backend fails, retry the request
5
+ * against fallback adapters in order. For Router users, prefer the Router's
6
+ * built-in fallback chains — this pattern serves plain-Bridge setups.
7
+ * Extracted from docs/PATTERNS.md §3.
8
+ *
9
+ * @module
10
+ */
11
+ import { AdapterError } from 'ai.matey.errors';
12
+ /**
13
+ * Create failover middleware for a Bridge.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * bridge.use(createFailoverMiddleware({
18
+ * fallbacks: [new AnthropicBackendAdapter({ apiKey }), new GroqBackendAdapter({ apiKey })],
19
+ * }));
20
+ * ```
21
+ */
22
+ export function createFailoverMiddleware(config) {
23
+ const shouldFailover = config.shouldFailover ??
24
+ ((error) => (error instanceof AdapterError ? error.isRetryable : true));
25
+ return async (context, next) => {
26
+ try {
27
+ return await next();
28
+ }
29
+ catch (primaryError) {
30
+ const error = primaryError instanceof Error ? primaryError : new Error(String(primaryError));
31
+ if (!shouldFailover(error)) {
32
+ throw error;
33
+ }
34
+ let lastError = error;
35
+ for (const fallback of config.fallbacks) {
36
+ config.onFailover?.({ to: fallback.metadata.name, error: lastError });
37
+ try {
38
+ return await fallback.execute(context.request, context.signal);
39
+ }
40
+ catch (fallbackError) {
41
+ lastError =
42
+ fallbackError instanceof Error ? fallbackError : new Error(String(fallbackError));
43
+ if (!shouldFailover(lastError)) {
44
+ throw lastError;
45
+ }
46
+ }
47
+ }
48
+ throw lastError;
49
+ }
50
+ };
51
+ }
52
+ //# sourceMappingURL=failover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"failover.js","sourceRoot":"","sources":["../../src/failover.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAoB/C;;;;;;;;;GASG;AACH,MAAM,UAAU,wBAAwB,CAAC,MAAsB;IAC7D,MAAM,cAAc,GAClB,MAAM,CAAC,cAAc;QACrB,CAAC,CAAC,KAAY,EAAE,EAAE,CAAC,CAAC,KAAK,YAAY,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAEjF,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;QAC7B,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,EAAE,CAAC;QACtB,CAAC;QAAC,OAAO,YAAY,EAAE,CAAC;YACtB,MAAM,KAAK,GAAG,YAAY,YAAY,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;YAE7F,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC3B,MAAM,KAAK,CAAC;YACd,CAAC;YAED,IAAI,SAAS,GAAU,KAAK,CAAC;YAC7B,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;gBACxC,MAAM,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;gBACtE,IAAI,CAAC;oBACH,OAAO,MAAM,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;gBACjE,CAAC;gBAAC,OAAO,aAAa,EAAE,CAAC;oBACvB,SAAS;wBACP,aAAa,YAAY,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC;oBACpF,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE,CAAC;wBAC/B,MAAM,SAAS,CAAC;oBAClB,CAAC;gBACH,CAAC;YACH,CAAC;YAED,MAAM,SAAS,CAAC;QAClB,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * ai.matey.patterns
3
+ *
4
+ * Production integration patterns, extracted from the validated pattern
5
+ * library (docs/PATTERNS.md) into importable utilities.
6
+ *
7
+ * @module
8
+ */
9
+ export { createComplexityRouter, defaultComplexityAnalyzer, } from './complexity-router.js';
10
+ export { createParallelAggregator, } from './parallel-aggregator.js';
11
+ export { createFailoverMiddleware } from './failover.js';
12
+ export { createCostOptimizer, } from './cost-optimizer.js';
13
+ export { createBatchProcessor, } from './batch-processor.js';
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,sBAAsB,EACtB,yBAAyB,GAG1B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,wBAAwB,GAGzB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,wBAAwB,EAAuB,MAAM,eAAe,CAAC;AAE9E,OAAO,EACL,mBAAmB,GAGpB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,oBAAoB,GAIrB,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Parallel Provider Aggregation
3
+ *
4
+ * Query several backends at once and aggregate: fastest-wins, all-results,
5
+ * or a custom judge. The aggregator is itself a BackendAdapter, so it plugs
6
+ * into a Bridge like any single backend. Extracted from docs/PATTERNS.md §2.
7
+ *
8
+ * @module
9
+ */
10
+ import { Router } from 'ai.matey.core';
11
+ /**
12
+ * Create a BackendAdapter that fans requests out to all configured
13
+ * backends in parallel.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const consensus = createParallelAggregator({
18
+ * backends: { openai, anthropic, gemini },
19
+ * strategy: (results) => results[0].response, // custom judge
20
+ * });
21
+ * const bridge = new Bridge(new OpenAIFrontendAdapter(), consensus);
22
+ * ```
23
+ */
24
+ export function createParallelAggregator(config) {
25
+ const strategy = config.strategy ?? 'fastest';
26
+ const router = new Router();
27
+ for (const [name, adapter] of Object.entries(config.backends)) {
28
+ router.register(name, adapter);
29
+ }
30
+ const metadata = {
31
+ name: 'parallel-aggregator',
32
+ version: '1.0.0',
33
+ provider: 'ai.matey.patterns',
34
+ capabilities: {
35
+ streaming: false,
36
+ multiModal: true,
37
+ tools: true,
38
+ systemMessageStrategy: 'in-messages',
39
+ supportsMultipleSystemMessages: true,
40
+ },
41
+ };
42
+ return {
43
+ metadata,
44
+ fromIR: (request) => request,
45
+ toIR: () => {
46
+ throw new Error('toIR() not applicable for parallel aggregator');
47
+ },
48
+ async execute(request, signal) {
49
+ if (typeof strategy === 'function') {
50
+ const result = await router.dispatchParallel(request, { strategy: 'all', timeout: config.timeout }, signal);
51
+ return strategy([...(result.allResponses ?? [])]);
52
+ }
53
+ const result = await router.dispatchParallel(request, {
54
+ strategy: strategy === 'fastest' ? 'fastest' : 'all',
55
+ timeout: config.timeout,
56
+ }, signal);
57
+ return result.response;
58
+ },
59
+ // eslint-disable-next-line @typescript-eslint/require-await, require-yield -- adapter interface requires an async generator; aggregation cannot stream
60
+ async *executeStream() {
61
+ throw new Error('Parallel aggregation does not support streaming; use a single backend for streams');
62
+ },
63
+ };
64
+ }
65
+ //# sourceMappingURL=parallel-aggregator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parallel-aggregator.js","sourceRoot":"","sources":["../../src/parallel-aggregator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAkCvC;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,wBAAwB,CAAC,MAAgC;IACvE,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,SAAS,CAAC;IAE9C,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;IAC5B,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9D,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC;IAED,MAAM,QAAQ,GAAoB;QAChC,IAAI,EAAE,qBAAqB;QAC3B,OAAO,EAAE,OAAO;QAChB,QAAQ,EAAE,mBAAmB;QAC7B,YAAY,EAAE;YACZ,SAAS,EAAE,KAAK;YAChB,UAAU,EAAE,IAAI;YAChB,KAAK,EAAE,IAAI;YACX,qBAAqB,EAAE,aAAa;YACpC,8BAA8B,EAAE,IAAI;SACrC;KACF,CAAC;IAEF,OAAO;QACL,QAAQ;QAER,MAAM,EAAE,CAAC,OAAsB,EAAE,EAAE,CAAC,OAAO;QAC3C,IAAI,EAAE,GAAG,EAAE;YACT,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACnE,CAAC;QAED,KAAK,CAAC,OAAO,CAAC,OAAsB,EAAE,MAAoB;YACxD,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACnC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAC1C,OAAO,EACP,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,EAC5C,MAAM,CACP,CAAC;gBACF,OAAO,QAAQ,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YACpD,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAC1C,OAAO,EACP;gBACE,QAAQ,EAAE,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK;gBACpD,OAAO,EAAE,MAAM,CAAC,OAAO;aACxB,EACD,MAAM,CACP,CAAC;YACF,OAAO,MAAM,CAAC,QAAQ,CAAC;QACzB,CAAC;QAED,uJAAuJ;QACvJ,KAAK,CAAC,CAAC,aAAa;YAClB,MAAM,IAAI,KAAK,CACb,mFAAmF,CACpF,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Batch Processing with Rate Limiting
3
+ *
4
+ * High-throughput request processing with bounded concurrency, an optional
5
+ * token-bucket rate limit, retries, and progress reporting. Zero-dependency.
6
+ * Extracted from docs/PATTERNS.md §6.
7
+ *
8
+ * @module
9
+ */
10
+ /**
11
+ * Configuration for the batch processor.
12
+ */
13
+ export interface BatchProcessorConfig<TReq, TRes> {
14
+ /** Execute one request (typically `(r) => bridge.chat(r)`). */
15
+ readonly execute: (request: TReq) => Promise<TRes>;
16
+ /** Maximum concurrent in-flight requests. @default 5 */
17
+ readonly concurrency?: number;
18
+ /** Sustained request rate (token bucket, burst = one second's tokens). */
19
+ readonly requestsPerSecond?: number;
20
+ /** Reject `add()` beyond this many queued requests. @default Infinity */
21
+ readonly maxQueueSize?: number;
22
+ /** Retry attempts per request after the first failure. @default 0 */
23
+ readonly retries?: number;
24
+ /** Progress callback after each settled request. */
25
+ readonly onProgress?: (stats: BatchStats) => void;
26
+ }
27
+ /**
28
+ * Processing statistics.
29
+ */
30
+ export interface BatchStats {
31
+ readonly completed: number;
32
+ readonly failed: number;
33
+ readonly pending: number;
34
+ readonly inFlight: number;
35
+ }
36
+ /**
37
+ * A batch processor instance.
38
+ */
39
+ export interface BatchProcessor<TReq, TRes> {
40
+ /** Enqueue one request; resolves/rejects with its result. */
41
+ add(request: TReq): Promise<TRes>;
42
+ /** Enqueue many; resolves when all settle. */
43
+ addAll(requests: readonly TReq[]): Promise<PromiseSettledResult<TRes>[]>;
44
+ /** Resolve when the queue is empty and nothing is in flight. */
45
+ drain(): Promise<void>;
46
+ /** Current statistics. */
47
+ stats(): BatchStats;
48
+ /** Stop the scheduler (pending requests are rejected). */
49
+ dispose(): void;
50
+ }
51
+ /**
52
+ * Create a batch processor.
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * const processor = createBatchProcessor({
57
+ * execute: (request) => bridge.chat(request),
58
+ * concurrency: 5,
59
+ * requestsPerSecond: 10,
60
+ * retries: 2,
61
+ * });
62
+ * const results = await processor.addAll(requests);
63
+ * ```
64
+ */
65
+ export declare function createBatchProcessor<TReq, TRes>(config: BatchProcessorConfig<TReq, TRes>): BatchProcessor<TReq, TRes>;
66
+ //# sourceMappingURL=batch-processor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch-processor.d.ts","sourceRoot":"","sources":["../../src/batch-processor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;GAEG;AACH,MAAM,WAAW,oBAAoB,CAAC,IAAI,EAAE,IAAI;IAC9C,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnD,wDAAwD;IACxD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAE9B,0EAA0E;IAC1E,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAEpC,yEAAyE;IACzE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAE/B,qEAAqE;IACrE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAE1B,oDAAoD;IACpD,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;CACnD;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,cAAc,CAAC,IAAI,EAAE,IAAI;IACxC,6DAA6D;IAC7D,GAAG,CAAC,OAAO,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElC,8CAA8C;IAC9C,MAAM,CAAC,QAAQ,EAAE,SAAS,IAAI,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEzE,gEAAgE;IAChE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB,0BAA0B;IAC1B,KAAK,IAAI,UAAU,CAAC;IAEpB,0DAA0D;IAC1D,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAC7C,MAAM,EAAE,oBAAoB,CAAC,IAAI,EAAE,IAAI,CAAC,GACvC,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,CA+H5B"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Complexity-Based Routing
3
+ *
4
+ * Route requests to different backends by estimated query complexity —
5
+ * cheap/fast models for simple queries, capable models for hard ones.
6
+ * Extracted from docs/PATTERNS.md §1.
7
+ *
8
+ * @module
9
+ */
10
+ import { Router } from 'ai.matey.core';
11
+ import type { RouterConfig } from 'ai.matey.types';
12
+ import type { BackendAdapter, IRChatRequest } from 'ai.matey.types';
13
+ /**
14
+ * A complexity tier: requests scoring at or below `maxComplexity` go to
15
+ * `backend`.
16
+ */
17
+ export interface ComplexityTier {
18
+ readonly backend: string;
19
+ readonly maxComplexity: number;
20
+ }
21
+ /**
22
+ * Configuration for the complexity router.
23
+ */
24
+ export interface ComplexityRouterConfig {
25
+ /** Tiers sorted ascending by maxComplexity; the last tier is the catch-all. */
26
+ readonly tiers: readonly ComplexityTier[];
27
+ /** Backends keyed by the names used in tiers. */
28
+ readonly backends: Readonly<Record<string, BackendAdapter>>;
29
+ /** Score a request 0-100. Defaults to {@link defaultComplexityAnalyzer}. */
30
+ readonly analyzer?: (request: IRChatRequest) => number;
31
+ /** Extra Router configuration (fallback, circuit breaker, ...). */
32
+ readonly routerConfig?: Partial<RouterConfig>;
33
+ }
34
+ /**
35
+ * Heuristic complexity score (0-100) from message length, question depth,
36
+ * and reasoning keywords.
37
+ */
38
+ export declare function defaultComplexityAnalyzer(request: IRChatRequest): number;
39
+ /**
40
+ * Create a Router that picks its backend by query complexity.
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * const router = createComplexityRouter({
45
+ * tiers: [
46
+ * { backend: 'fast', maxComplexity: 30 },
47
+ * { backend: 'balanced', maxComplexity: 70 },
48
+ * { backend: 'powerful', maxComplexity: 100 },
49
+ * ],
50
+ * backends: { fast, balanced, powerful },
51
+ * });
52
+ * ```
53
+ */
54
+ export declare function createComplexityRouter(config: ComplexityRouterConfig): Router;
55
+ //# sourceMappingURL=complexity-router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"complexity-router.d.ts","sourceRoot":"","sources":["../../src/complexity-router.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpE;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,CAAC;IAE1C,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC;IAE5D,4EAA4E;IAC5E,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,MAAM,CAAC;IAEvD,mEAAmE;IACnE,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;CAC/C;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAwCxE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,sBAAsB,GAAG,MAAM,CAuB7E"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Cost-Optimized Provider Selection
3
+ *
4
+ * A cost-optimizing Router plus a budget-window middleware: route to the
5
+ * cheapest capable backend and enforce a spending ceiling. Extracted from
6
+ * docs/PATTERNS.md §4.
7
+ *
8
+ * @module
9
+ */
10
+ import { Router } from 'ai.matey.core';
11
+ import type { RouterConfig } from 'ai.matey.types';
12
+ import type { BackendAdapter, Middleware } from 'ai.matey.types';
13
+ /**
14
+ * Configuration for the cost optimizer.
15
+ */
16
+ export interface CostOptimizerConfig {
17
+ /** Backends keyed by name. */
18
+ readonly backends: Readonly<Record<string, BackendAdapter>>;
19
+ /** Optional budget ceiling over a sliding window. */
20
+ readonly budget?: {
21
+ /** Spending ceiling in USD within the window. */
22
+ readonly limitUSD: number;
23
+ /** Window length in milliseconds. @default 3600000 (1 hour) */
24
+ readonly windowMs?: number;
25
+ /** What to do when the ceiling is hit. @default 'error' */
26
+ readonly onExceeded?: 'error' | 'allow';
27
+ };
28
+ /** Extra Router configuration. */
29
+ readonly routerConfig?: Partial<RouterConfig>;
30
+ }
31
+ /**
32
+ * Result of createCostOptimizer.
33
+ */
34
+ export interface CostOptimizer {
35
+ /** Cost-optimizing router (usable as a Bridge backend). */
36
+ readonly router: Router;
37
+ /** Budget-enforcing middleware (no-op when no budget configured). */
38
+ readonly middleware: Middleware;
39
+ /** Spend recorded within the current window, in USD. */
40
+ getSpend(): number;
41
+ /** Record spend (call from cost-tracking middleware or manually). */
42
+ recordSpend(costUSD: number): void;
43
+ }
44
+ /**
45
+ * Create a cost-optimized router with an optional budget window.
46
+ *
47
+ * @example
48
+ * ```typescript
49
+ * const { router, middleware, recordSpend } = createCostOptimizer({
50
+ * backends: { cheap, premium },
51
+ * budget: { limitUSD: 10, windowMs: 3600_000 },
52
+ * });
53
+ * const bridge = new Bridge(frontend, router).use(middleware);
54
+ * ```
55
+ */
56
+ export declare function createCostOptimizer(config: CostOptimizerConfig): CostOptimizer;
57
+ //# sourceMappingURL=cost-optimizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost-optimizer.d.ts","sourceRoot":"","sources":["../../src/cost-optimizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjE;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,8BAA8B;IAC9B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC;IAE5D,qDAAqD;IACrD,QAAQ,CAAC,MAAM,CAAC,EAAE;QAChB,iDAAiD;QACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,+DAA+D;QAC/D,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAC3B,2DAA2D;QAC3D,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;KACzC,CAAC;IAEF,kCAAkC;IAClC,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;CAC/C;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,qEAAqE;IACrE,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAEhC,wDAAwD;IACxD,QAAQ,IAAI,MAAM,CAAC;IAEnB,qEAAqE;IACrE,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,aAAa,CA6C9E"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Automatic Failover Middleware
3
+ *
4
+ * Bridge-level failover: when the primary backend fails, retry the request
5
+ * against fallback adapters in order. For Router users, prefer the Router's
6
+ * built-in fallback chains — this pattern serves plain-Bridge setups.
7
+ * Extracted from docs/PATTERNS.md §3.
8
+ *
9
+ * @module
10
+ */
11
+ import type { BackendAdapter, Middleware } from 'ai.matey.types';
12
+ /**
13
+ * Configuration for the failover middleware.
14
+ */
15
+ export interface FailoverConfig {
16
+ /** Backends to try, in order, after the primary fails. */
17
+ readonly fallbacks: readonly BackendAdapter[];
18
+ /**
19
+ * Decide whether an error triggers failover.
20
+ * @default retryable AdapterErrors and all non-Adapter errors
21
+ */
22
+ readonly shouldFailover?: (error: Error) => boolean;
23
+ /** Observability hook fired on each failover hop. */
24
+ readonly onFailover?: (info: {
25
+ to: string;
26
+ error: Error;
27
+ }) => void;
28
+ }
29
+ /**
30
+ * Create failover middleware for a Bridge.
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * bridge.use(createFailoverMiddleware({
35
+ * fallbacks: [new AnthropicBackendAdapter({ apiKey }), new GroqBackendAdapter({ apiKey })],
36
+ * }));
37
+ * ```
38
+ */
39
+ export declare function createFailoverMiddleware(config: FailoverConfig): Middleware;
40
+ //# sourceMappingURL=failover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"failover.d.ts","sourceRoot":"","sources":["../../src/failover.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,0DAA0D;IAC1D,QAAQ,CAAC,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;IAE9C;;;OAGG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC;IAEpD,qDAAqD;IACrD,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,KAAK,IAAI,CAAC;CACpE;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,cAAc,GAAG,UAAU,CAgC3E"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * ai.matey.patterns
3
+ *
4
+ * Production integration patterns, extracted from the validated pattern
5
+ * library (docs/PATTERNS.md) into importable utilities.
6
+ *
7
+ * @module
8
+ */
9
+ export { createComplexityRouter, defaultComplexityAnalyzer, type ComplexityRouterConfig, type ComplexityTier, } from './complexity-router.js';
10
+ export { createParallelAggregator, type ParallelAggregatorConfig, type AggregationStrategy, } from './parallel-aggregator.js';
11
+ export { createFailoverMiddleware, type FailoverConfig } from './failover.js';
12
+ export { createCostOptimizer, type CostOptimizerConfig, type CostOptimizer, } from './cost-optimizer.js';
13
+ export { createBatchProcessor, type BatchProcessorConfig, type BatchProcessor, type BatchStats, } from './batch-processor.js';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,cAAc,GACpB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,wBAAwB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,mBAAmB,GACzB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,wBAAwB,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAE9E,OAAO,EACL,mBAAmB,EACnB,KAAK,mBAAmB,EACxB,KAAK,aAAa,GACnB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,oBAAoB,EACpB,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,UAAU,GAChB,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Parallel Provider Aggregation
3
+ *
4
+ * Query several backends at once and aggregate: fastest-wins, all-results,
5
+ * or a custom judge. The aggregator is itself a BackendAdapter, so it plugs
6
+ * into a Bridge like any single backend. Extracted from docs/PATTERNS.md §2.
7
+ *
8
+ * @module
9
+ */
10
+ import type { BackendAdapter, IRChatResponse } from 'ai.matey.types';
11
+ /**
12
+ * Aggregation strategy: fastest response, all responses (primary = first),
13
+ * or a custom judge over the full result set.
14
+ */
15
+ export type AggregationStrategy = 'fastest' | 'all' | ((results: Array<{
16
+ backend: string;
17
+ response: IRChatResponse;
18
+ latencyMs: number;
19
+ }>) => IRChatResponse);
20
+ /**
21
+ * Configuration for the parallel aggregator.
22
+ */
23
+ export interface ParallelAggregatorConfig {
24
+ /** Backends to query, keyed by name. */
25
+ readonly backends: Readonly<Record<string, BackendAdapter>>;
26
+ /** @default 'fastest' */
27
+ readonly strategy?: AggregationStrategy;
28
+ /** Per-dispatch timeout in milliseconds. */
29
+ readonly timeout?: number;
30
+ }
31
+ /**
32
+ * Create a BackendAdapter that fans requests out to all configured
33
+ * backends in parallel.
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * const consensus = createParallelAggregator({
38
+ * backends: { openai, anthropic, gemini },
39
+ * strategy: (results) => results[0].response, // custom judge
40
+ * });
41
+ * const bridge = new Bridge(new OpenAIFrontendAdapter(), consensus);
42
+ * ```
43
+ */
44
+ export declare function createParallelAggregator(config: ParallelAggregatorConfig): BackendAdapter;
45
+ //# sourceMappingURL=parallel-aggregator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parallel-aggregator.d.ts","sourceRoot":"","sources":["../../src/parallel-aggregator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EACV,cAAc,EAGd,cAAc,EAEf,MAAM,gBAAgB,CAAC;AAExB;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAC3B,SAAS,GACT,KAAK,GACL,CAAC,CACC,OAAO,EAAE,KAAK,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,cAAc,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,KAC7E,cAAc,CAAC,CAAC;AAEzB;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,wCAAwC;IACxC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC;IAE5D,yBAAyB;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAExC,4CAA4C;IAC5C,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,wBAAwB,GAAG,cAAc,CAyDzF"}