@x12i/ai-gateway 7.9.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.
Files changed (179) hide show
  1. package/README.md +4259 -0
  2. package/config.defaults.json +31 -0
  3. package/dist/activity-manager.d.ts +206 -0
  4. package/dist/activity-manager.js +1051 -0
  5. package/dist/config/activity-tracking-config.d.ts +11 -0
  6. package/dist/config/activity-tracking-config.js +15 -0
  7. package/dist/config.defaults.json +31 -0
  8. package/dist/content-normalizer/content-normalizer.d.ts +46 -0
  9. package/dist/content-normalizer/content-normalizer.js +393 -0
  10. package/dist/content-normalizer/index.d.ts +7 -0
  11. package/dist/content-normalizer/index.js +6 -0
  12. package/dist/content-normalizer/types.d.ts +33 -0
  13. package/dist/content-normalizer/types.js +4 -0
  14. package/dist/defaults/instructions-blocks.json +61 -0
  15. package/dist/defaults/model-config.json +16 -0
  16. package/dist/defaults/template-rendering.json +6 -0
  17. package/dist/flex-md-loader.d.ts +109 -0
  18. package/dist/flex-md-loader.js +940 -0
  19. package/dist/gateway-config.d.ts +49 -0
  20. package/dist/gateway-config.js +292 -0
  21. package/dist/gateway-conversion.d.ts +29 -0
  22. package/dist/gateway-conversion.js +174 -0
  23. package/dist/gateway-instructions.d.ts +30 -0
  24. package/dist/gateway-instructions.js +62 -0
  25. package/dist/gateway-memory.d.ts +51 -0
  26. package/dist/gateway-memory.js +207 -0
  27. package/dist/gateway-messages.d.ts +23 -0
  28. package/dist/gateway-messages.js +83 -0
  29. package/dist/gateway-meta.d.ts +25 -0
  30. package/dist/gateway-meta.js +87 -0
  31. package/dist/gateway-provider-auto-register.d.ts +17 -0
  32. package/dist/gateway-provider-auto-register.js +159 -0
  33. package/dist/gateway-provider.d.ts +54 -0
  34. package/dist/gateway-provider.js +202 -0
  35. package/dist/gateway-rate-limiter-constants.d.ts +16 -0
  36. package/dist/gateway-rate-limiter-constants.js +16 -0
  37. package/dist/gateway-rate-limiter.d.ts +56 -0
  38. package/dist/gateway-rate-limiter.js +107 -0
  39. package/dist/gateway-retry.d.ts +49 -0
  40. package/dist/gateway-retry.js +204 -0
  41. package/dist/gateway-utils.d.ts +21 -0
  42. package/dist/gateway-utils.js +181 -0
  43. package/dist/gateway-validation.d.ts +13 -0
  44. package/dist/gateway-validation.js +50 -0
  45. package/dist/gateway.d.ts +39 -0
  46. package/dist/gateway.js +430 -0
  47. package/dist/index.d.ts +36 -0
  48. package/dist/index.js +55 -0
  49. package/dist/instruction-errors.d.ts +16 -0
  50. package/dist/instruction-errors.js +29 -0
  51. package/dist/instruction-optimizer.d.ts +113 -0
  52. package/dist/instruction-optimizer.js +293 -0
  53. package/dist/instructions-parser.d.ts +31 -0
  54. package/dist/instructions-parser.js +56 -0
  55. package/dist/logger-factory.d.ts +17 -0
  56. package/dist/logger-factory.js +42 -0
  57. package/dist/message-builder.d.ts +41 -0
  58. package/dist/message-builder.js +522 -0
  59. package/dist/object-types-library-integration.d.ts +22 -0
  60. package/dist/object-types-library-integration.js +27 -0
  61. package/dist/object-types-library.d.ts +351 -0
  62. package/dist/object-types-library.js +210 -0
  63. package/dist/output-auditor.d.ts +44 -0
  64. package/dist/output-auditor.js +49 -0
  65. package/dist/request-report-generator.d.ts +60 -0
  66. package/dist/request-report-generator.js +169 -0
  67. package/dist/response-analyzer/format-type-detector.d.ts +35 -0
  68. package/dist/response-analyzer/format-type-detector.js +115 -0
  69. package/dist/response-analyzer/index.d.ts +9 -0
  70. package/dist/response-analyzer/index.js +8 -0
  71. package/dist/response-analyzer/object-type-detector.d.ts +42 -0
  72. package/dist/response-analyzer/object-type-detector.js +95 -0
  73. package/dist/response-analyzer/response-analyzer.d.ts +38 -0
  74. package/dist/response-analyzer/response-analyzer.js +97 -0
  75. package/dist/response-analyzer/types.d.ts +97 -0
  76. package/dist/response-analyzer/types.js +4 -0
  77. package/dist/response-fallback-fixer.d.ts +11 -0
  78. package/dist/response-fallback-fixer.js +123 -0
  79. package/dist/runtime-objects.d.ts +52 -0
  80. package/dist/runtime-objects.js +46 -0
  81. package/dist/template-parser.d.ts +58 -0
  82. package/dist/template-parser.js +99 -0
  83. package/dist/template-render-merge.d.ts +9 -0
  84. package/dist/template-render-merge.js +40 -0
  85. package/dist/troubleshooting-helper.d.ts +123 -0
  86. package/dist/troubleshooting-helper.js +596 -0
  87. package/dist/types.d.ts +1173 -0
  88. package/dist/types.js +6 -0
  89. package/dist/usage-tracker.d.ts +78 -0
  90. package/dist/usage-tracker.js +79 -0
  91. package/dist-cjs/activity-manager.cjs +1056 -0
  92. package/dist-cjs/activity-manager.d.ts +206 -0
  93. package/dist-cjs/config/activity-tracking-config.cjs +18 -0
  94. package/dist-cjs/config/activity-tracking-config.d.ts +11 -0
  95. package/dist-cjs/config.defaults.json +31 -0
  96. package/dist-cjs/content-normalizer/content-normalizer.cjs +398 -0
  97. package/dist-cjs/content-normalizer/content-normalizer.d.ts +46 -0
  98. package/dist-cjs/content-normalizer/index.cjs +12 -0
  99. package/dist-cjs/content-normalizer/index.d.ts +7 -0
  100. package/dist-cjs/content-normalizer/types.cjs +5 -0
  101. package/dist-cjs/content-normalizer/types.d.ts +33 -0
  102. package/dist-cjs/defaults/instructions-blocks.json +61 -0
  103. package/dist-cjs/defaults/model-config.json +16 -0
  104. package/dist-cjs/defaults/template-rendering.json +6 -0
  105. package/dist-cjs/flex-md-loader.cjs +986 -0
  106. package/dist-cjs/flex-md-loader.d.ts +109 -0
  107. package/dist-cjs/gateway-config.cjs +331 -0
  108. package/dist-cjs/gateway-config.d.ts +49 -0
  109. package/dist-cjs/gateway-conversion.cjs +212 -0
  110. package/dist-cjs/gateway-conversion.d.ts +29 -0
  111. package/dist-cjs/gateway-instructions.cjs +67 -0
  112. package/dist-cjs/gateway-instructions.d.ts +30 -0
  113. package/dist-cjs/gateway-memory.cjs +211 -0
  114. package/dist-cjs/gateway-memory.d.ts +51 -0
  115. package/dist-cjs/gateway-messages.cjs +86 -0
  116. package/dist-cjs/gateway-messages.d.ts +23 -0
  117. package/dist-cjs/gateway-meta.cjs +90 -0
  118. package/dist-cjs/gateway-meta.d.ts +25 -0
  119. package/dist-cjs/gateway-provider-auto-register.cjs +195 -0
  120. package/dist-cjs/gateway-provider-auto-register.d.ts +17 -0
  121. package/dist-cjs/gateway-provider.cjs +214 -0
  122. package/dist-cjs/gateway-provider.d.ts +54 -0
  123. package/dist-cjs/gateway-rate-limiter-constants.cjs +19 -0
  124. package/dist-cjs/gateway-rate-limiter-constants.d.ts +16 -0
  125. package/dist-cjs/gateway-rate-limiter.cjs +111 -0
  126. package/dist-cjs/gateway-rate-limiter.d.ts +56 -0
  127. package/dist-cjs/gateway-retry.cjs +212 -0
  128. package/dist-cjs/gateway-retry.d.ts +49 -0
  129. package/dist-cjs/gateway-utils.cjs +219 -0
  130. package/dist-cjs/gateway-utils.d.ts +21 -0
  131. package/dist-cjs/gateway-validation.cjs +54 -0
  132. package/dist-cjs/gateway-validation.d.ts +13 -0
  133. package/dist-cjs/gateway.cjs +434 -0
  134. package/dist-cjs/gateway.d.ts +39 -0
  135. package/dist-cjs/index.cjs +108 -0
  136. package/dist-cjs/index.d.ts +36 -0
  137. package/dist-cjs/instruction-errors.cjs +34 -0
  138. package/dist-cjs/instruction-errors.d.ts +16 -0
  139. package/dist-cjs/instruction-optimizer.cjs +299 -0
  140. package/dist-cjs/instruction-optimizer.d.ts +113 -0
  141. package/dist-cjs/instructions-parser.cjs +61 -0
  142. package/dist-cjs/instructions-parser.d.ts +31 -0
  143. package/dist-cjs/logger-factory.cjs +45 -0
  144. package/dist-cjs/logger-factory.d.ts +17 -0
  145. package/dist-cjs/message-builder.cjs +558 -0
  146. package/dist-cjs/message-builder.d.ts +41 -0
  147. package/dist-cjs/object-types-library-integration.cjs +32 -0
  148. package/dist-cjs/object-types-library-integration.d.ts +22 -0
  149. package/dist-cjs/object-types-library.cjs +215 -0
  150. package/dist-cjs/object-types-library.d.ts +351 -0
  151. package/dist-cjs/output-auditor.cjs +52 -0
  152. package/dist-cjs/output-auditor.d.ts +44 -0
  153. package/dist-cjs/request-report-generator.cjs +172 -0
  154. package/dist-cjs/request-report-generator.d.ts +60 -0
  155. package/dist-cjs/response-analyzer/format-type-detector.cjs +119 -0
  156. package/dist-cjs/response-analyzer/format-type-detector.d.ts +35 -0
  157. package/dist-cjs/response-analyzer/index.cjs +14 -0
  158. package/dist-cjs/response-analyzer/index.d.ts +9 -0
  159. package/dist-cjs/response-analyzer/object-type-detector.cjs +99 -0
  160. package/dist-cjs/response-analyzer/object-type-detector.d.ts +42 -0
  161. package/dist-cjs/response-analyzer/response-analyzer.cjs +101 -0
  162. package/dist-cjs/response-analyzer/response-analyzer.d.ts +38 -0
  163. package/dist-cjs/response-analyzer/types.cjs +5 -0
  164. package/dist-cjs/response-analyzer/types.d.ts +97 -0
  165. package/dist-cjs/response-fallback-fixer.cjs +126 -0
  166. package/dist-cjs/response-fallback-fixer.d.ts +11 -0
  167. package/dist-cjs/runtime-objects.cjs +52 -0
  168. package/dist-cjs/runtime-objects.d.ts +52 -0
  169. package/dist-cjs/template-parser.cjs +136 -0
  170. package/dist-cjs/template-parser.d.ts +58 -0
  171. package/dist-cjs/template-render-merge.cjs +43 -0
  172. package/dist-cjs/template-render-merge.d.ts +9 -0
  173. package/dist-cjs/troubleshooting-helper.cjs +611 -0
  174. package/dist-cjs/troubleshooting-helper.d.ts +123 -0
  175. package/dist-cjs/types.cjs +7 -0
  176. package/dist-cjs/types.d.ts +1173 -0
  177. package/dist-cjs/usage-tracker.cjs +83 -0
  178. package/dist-cjs/usage-tracker.d.ts +78 -0
  179. package/package.json +91 -0
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ /**
3
+ * Gateway Messages Module
4
+ * Handles message construction using direct message builder
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.constructMessages = constructMessages;
8
+ const message_builder_js_1 = require("./message-builder.cjs");
9
+ // Type guard to check if request is AIRequest
10
+ // AIRequest is distinguished by having primaryObjectType, objectTypes, or other AIRequest-specific fields
11
+ function isAIRequest(request) {
12
+ return 'primaryObjectType' in request ||
13
+ ('objectTypes' in request && Array.isArray(request.objectTypes)) ||
14
+ 'skillId' in request ||
15
+ 'masterSkillId' in request ||
16
+ 'reasoningEncrypted' in request;
17
+ }
18
+ /**
19
+ * Constructs messages from instructions/prompt/input/context
20
+ *
21
+ * Uses direct message builder which handles:
22
+ * - Token resolution (3-tier system)
23
+ * - Template parsing (via Rendrix, @x12i/rendrix)
24
+ * - Instruction block resolution and composition
25
+ * - Flex-md format specification
26
+ * - Message assembly
27
+ */
28
+ async function constructMessages(request, config, logger, parsedSnapshot) {
29
+ logger.verbose('Constructing messages from request', {
30
+ jobId: request.jobId,
31
+ agentId: request.agentId,
32
+ hasInstructions: !!request.instructions,
33
+ hasContext: !!request.context,
34
+ hasPrompt: !!request.prompt,
35
+ hasWorkingMemory: !!request.workingMemory
36
+ });
37
+ // LOGGING: Construct messages phase (instructions should already be resolved)
38
+ const traceId = request.jobId || `trace-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
39
+ const agentId = request.agentId;
40
+ logger.info('instructions.constructMessages.entry', {
41
+ traceId,
42
+ jobId: request.jobId,
43
+ agentId,
44
+ 'instructionsType': typeof request.instructions,
45
+ 'instructionsLength': typeof request.instructions === 'string' ? request.instructions.length : 'N/A',
46
+ 'hasResolvedText': !!request.resolvedInstructionsText
47
+ });
48
+ // Always use flex-md format - no modes needed
49
+ let finalInstructions = request.instructions;
50
+ // Add examples for few-shot learning if using standard type
51
+ if (isAIRequest(request)) {
52
+ const resolvedType = request._resolvedTypes?.primary;
53
+ if (resolvedType?.isStandard && resolvedType.definition?.examples) {
54
+ const examples = resolvedType.definition.examples;
55
+ if (examples.length > 0) {
56
+ // Use first 3 examples for few-shot learning
57
+ const fewShotExamples = examples
58
+ .slice(0, 3)
59
+ .map((ex) => `Input: ${ex.input}\nOutput: ${ex.output}`)
60
+ .join('\n\n');
61
+ // Append to instructions
62
+ if (typeof finalInstructions === 'string') {
63
+ finalInstructions = `${finalInstructions}\n\nExamples:\n${fewShotExamples}`;
64
+ logger.debug('Added few-shot examples to instructions', {
65
+ jobId: request.jobId,
66
+ exampleCount: Math.min(examples.length, 3),
67
+ totalExamples: examples.length
68
+ });
69
+ }
70
+ }
71
+ }
72
+ }
73
+ // Update request with final instructions (for message builder)
74
+ const requestWithExamples = { ...request, instructions: finalInstructions };
75
+ // Build messages using direct message builder
76
+ const result = await (0, message_builder_js_1.buildMessages)(requestWithExamples, config, {
77
+ useSystemContextFallback: true,
78
+ includeInputRecognition: isAIRequest(request),
79
+ includeReinforcement: isAIRequest(request),
80
+ parsedSnapshot
81
+ });
82
+ if (parsedSnapshot && result.metadata) {
83
+ parsedSnapshot._requestBuilderMetadata = result.metadata;
84
+ }
85
+ return result.messages;
86
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Gateway Messages Module
3
+ * Handles message construction using direct message builder
4
+ */
5
+ import type { ChatRequest, AIRequest } from './types.js';
6
+ import type { Logxer } from '@x12i/logxer';
7
+ import { type MessageBuilderConfig } from './message-builder.js';
8
+ type Request = ChatRequest | AIRequest;
9
+ /**
10
+ * Constructs messages from instructions/prompt/input/context
11
+ *
12
+ * Uses direct message builder which handles:
13
+ * - Token resolution (3-tier system)
14
+ * - Template parsing (via Rendrix, @x12i/rendrix)
15
+ * - Instruction block resolution and composition
16
+ * - Flex-md format specification
17
+ * - Message assembly
18
+ */
19
+ export declare function constructMessages(request: Request, config: MessageBuilderConfig, logger: Logxer, parsedSnapshot?: any): Promise<Array<{
20
+ role: string;
21
+ content: string;
22
+ }>>;
23
+ export {};
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ /**
3
+ * Gateway Meta Operations Module
4
+ * Handles meta operations like instruction optimization and testing
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.testInstructions = testInstructions;
8
+ /**
9
+ * Test instructions by running them and analyzing the response
10
+ */
11
+ async function testInstructions(instructions, testInput, expectedSchema, options, config, gateway, logger) {
12
+ // Get internal system action config (instruction audit)
13
+ const internalConfig = config.internalSystemActions?.instructionAudit;
14
+ const defaultEngine = config.defaultEngine || 'openai';
15
+ const defaultModel = internalConfig?.model || 'gpt-5-nano';
16
+ const defaultProvider = internalConfig?.engine || defaultEngine;
17
+ const { agentId = 'instruction-tester', model = options.model || defaultModel, // Use internal config default if not provided
18
+ provider = options.provider || defaultProvider // Use internal config default if not provided
19
+ } = options;
20
+ if (!model) {
21
+ throw new Error('Model must be provided in options.model or configured as default');
22
+ }
23
+ // Create test request with internal system action config
24
+ const testRequest = {
25
+ jobId: `test-instructions-${Date.now()}`,
26
+ agentId,
27
+ instructions,
28
+ input: testInput,
29
+ config: {
30
+ model,
31
+ provider,
32
+ temperature: internalConfig?.temperature ?? 0.7, // Use internal config or default
33
+ maxTokens: internalConfig?.maxTokens ?? 2000 // Use internal config or default
34
+ }
35
+ };
36
+ // Run the test
37
+ const response = await gateway.invoke(testRequest);
38
+ // Analyze the response
39
+ const analysis = {
40
+ isValidJson: !!response.parsedContent && typeof response.parsedContent === 'object',
41
+ matchesSchema: false,
42
+ hasProse: false,
43
+ issues: [],
44
+ qualityScore: 0
45
+ };
46
+ // Check for prose
47
+ const contentStr = response.content || '';
48
+ const proseIndicators = ["I'm sorry", "Please provide", "Sure!", "Here is", "Let me", "I can", "I'll"];
49
+ analysis.hasProse = proseIndicators.some(indicator => contentStr.toLowerCase().includes(indicator.toLowerCase()));
50
+ // Check if matches schema
51
+ if (expectedSchema && response.parsedContent) {
52
+ const parsed = response.parsedContent;
53
+ const schemaKeys = Object.keys(expectedSchema);
54
+ const responseKeys = Object.keys(parsed);
55
+ analysis.matchesSchema = schemaKeys.every(key => responseKeys.includes(key));
56
+ }
57
+ else if (response.parsedContent) {
58
+ analysis.matchesSchema = true; // No schema to match against
59
+ }
60
+ // Collect issues
61
+ if (!analysis.isValidJson) {
62
+ analysis.issues.push('Response is not valid JSON');
63
+ }
64
+ if (analysis.hasProse) {
65
+ analysis.issues.push('Response contains conversational prose');
66
+ }
67
+ if (!analysis.matchesSchema && expectedSchema) {
68
+ analysis.issues.push('Response does not match expected schema');
69
+ }
70
+ if (!response.parsedContent) {
71
+ analysis.issues.push('Response missing parsedContent');
72
+ }
73
+ // Calculate quality score (0-10)
74
+ let score = 10;
75
+ if (!analysis.isValidJson)
76
+ score -= 5;
77
+ if (analysis.hasProse)
78
+ score -= 3;
79
+ if (!analysis.matchesSchema && expectedSchema)
80
+ score -= 2;
81
+ if (!response.parsedContent)
82
+ score -= 5;
83
+ analysis.qualityScore = Math.max(0, score);
84
+ const passed = analysis.issues.length === 0 && analysis.qualityScore >= 7;
85
+ return {
86
+ passed,
87
+ response,
88
+ analysis
89
+ };
90
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Gateway Meta Operations Module
3
+ * Handles meta operations like instruction optimization and testing
4
+ */
5
+ import type { EnhancedLLMResponse, GatewayConfig } from './types.js';
6
+ import type { Logxer } from '@x12i/logxer';
7
+ import type { AIGateway } from './gateway.js';
8
+ /**
9
+ * Test instructions by running them and analyzing the response
10
+ */
11
+ export declare function testInstructions(instructions: string, testInput: string, expectedSchema: Record<string, unknown> | undefined, options: {
12
+ agentId?: string;
13
+ model?: string;
14
+ provider?: string;
15
+ }, config: GatewayConfig, gateway: AIGateway, logger: Logxer): Promise<{
16
+ passed: boolean;
17
+ response: EnhancedLLMResponse;
18
+ analysis: {
19
+ isValidJson: boolean;
20
+ matchesSchema: boolean;
21
+ hasProse: boolean;
22
+ issues: string[];
23
+ qualityScore: number;
24
+ };
25
+ }>;
@@ -0,0 +1,195 @@
1
+ "use strict";
2
+ /**
3
+ * Gateway Provider Auto-Registration Module
4
+ * Automatically registers providers based on environment variables
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.autoRegisterProviders = autoRegisterProviders;
41
+ const PROVIDER_CONFIGS = [
42
+ {
43
+ name: 'openai',
44
+ packageName: '@x12i/ai-provider-openai',
45
+ className: 'OpenAIProvider',
46
+ envVar: 'OPENAI_API_KEY'
47
+ },
48
+ {
49
+ name: 'grok',
50
+ packageName: '@x12i/ai-provider-grok',
51
+ className: 'GrokProvider',
52
+ envVar: 'GROK_API_KEY'
53
+ },
54
+ {
55
+ name: 'anthropic',
56
+ packageName: '@x12i/ai-provider-anthropic',
57
+ className: 'AnthropicProvider',
58
+ envVar: 'ANTHROPIC_API_KEY',
59
+ optional: true // Optional - may not be installed
60
+ },
61
+ {
62
+ name: 'google',
63
+ packageName: '@x12i/ai-provider-google',
64
+ className: 'GoogleProvider',
65
+ envVar: 'GOOGLE_API_KEY',
66
+ optional: true // Optional - may not be installed
67
+ },
68
+ {
69
+ name: 'cohere',
70
+ packageName: '@x12i/ai-provider-cohere',
71
+ className: 'CohereProvider',
72
+ envVar: 'COHERE_API_KEY',
73
+ optional: true // Optional - may not be installed
74
+ },
75
+ {
76
+ name: 'mistral',
77
+ packageName: '@x12i/ai-provider-mistral',
78
+ className: 'MistralProvider',
79
+ envVar: 'MISTRAL_API_KEY',
80
+ optional: true // Optional - may not be installed
81
+ }
82
+ ];
83
+ /**
84
+ * Auto-registers providers based on environment variables
85
+ * Only registers providers that:
86
+ * 1. Have their API key set in environment variables
87
+ * 2. Have their provider package installed
88
+ *
89
+ * @param router - LLM provider router instance
90
+ * @param logger - Logger instance
91
+ * @returns Array of provider names that were successfully registered
92
+ */
93
+ async function autoRegisterProviders(router, logger) {
94
+ const registeredProviders = [];
95
+ logger.debug('Auto-registering providers from environment variables');
96
+ for (const providerConfig of PROVIDER_CONFIGS) {
97
+ const apiKey = process.env[providerConfig.envVar];
98
+ // Skip if API key is not set
99
+ if (!apiKey) {
100
+ if (!providerConfig.optional) {
101
+ logger.debug(`Skipping ${providerConfig.name} provider: ${providerConfig.envVar} not set`);
102
+ }
103
+ continue;
104
+ }
105
+ try {
106
+ // Dynamically import the provider package
107
+ // Use dynamic import() for ES module compatibility
108
+ let ProviderClass;
109
+ try {
110
+ const providerModule = await Promise.resolve(`${providerConfig.packageName}`).then(s => __importStar(require(s)));
111
+ ProviderClass = providerModule[providerConfig.className] || providerModule.default;
112
+ if (!ProviderClass) {
113
+ logger.debug(`Provider class ${providerConfig.className} not found in ${providerConfig.packageName}`);
114
+ continue;
115
+ }
116
+ }
117
+ catch (importError) {
118
+ if (!providerConfig.optional) {
119
+ logger.warn(`Failed to import ${providerConfig.packageName}`, {
120
+ error: importError instanceof Error ? importError.message : String(importError),
121
+ note: `Install it with: npm install ${providerConfig.packageName}`
122
+ });
123
+ }
124
+ continue;
125
+ }
126
+ // Instantiate the provider
127
+ const provider = new ProviderClass({
128
+ apiKey: apiKey
129
+ });
130
+ // Get provider name for both module creation and logging
131
+ const providerName = typeof provider.getProviderName === 'function'
132
+ ? provider.getProviderName()
133
+ : providerConfig.name;
134
+ // Register with router as ProviderModule
135
+ const providerModule = {
136
+ name: providerName,
137
+ capabilities: {
138
+ modes: {
139
+ sync: true,
140
+ stream: false,
141
+ batch: false
142
+ },
143
+ operations: ['invoke'],
144
+ maxConcurrency: 10
145
+ },
146
+ execute: async (request) => {
147
+ // Use aiCall if available, otherwise assume invoke
148
+ if (typeof provider.aiCall === 'function') {
149
+ return await provider.aiCall(request);
150
+ }
151
+ else if (typeof provider.invoke === 'function') {
152
+ return await provider.invoke(request);
153
+ }
154
+ else {
155
+ throw new Error(`Provider ${providerName} has neither aiCall nor invoke method`);
156
+ }
157
+ }
158
+ };
159
+ router.registerProvider(providerModule);
160
+ registeredProviders.push(providerName);
161
+ logger.info(`Auto-registered provider: ${providerName}`, {
162
+ provider: providerName,
163
+ envVar: providerConfig.envVar,
164
+ hasApiKey: !!apiKey
165
+ });
166
+ }
167
+ catch (error) {
168
+ logger.error(`Failed to auto-register ${providerConfig.name} provider`, {
169
+ provider: providerConfig.name,
170
+ package: providerConfig.packageName,
171
+ error: error instanceof Error ? error.message : String(error),
172
+ stack: error instanceof Error ? error.stack : undefined
173
+ });
174
+ // Continue with other providers even if one fails
175
+ }
176
+ }
177
+ if (registeredProviders.length === 0) {
178
+ logger.warn('No providers were auto-registered. Make sure API keys are set in environment variables:', {
179
+ requiredEnvVars: PROVIDER_CONFIGS
180
+ .filter(p => !p.optional)
181
+ .map(p => p.envVar),
182
+ optionalEnvVars: PROVIDER_CONFIGS
183
+ .filter(p => p.optional)
184
+ .map(p => p.envVar),
185
+ openRouter: 'Set OPEN_ROUTER_KEY or OPENROUTER_API_KEY (and do not set USE_OPENROUTER=false) to use OpenRouter without registering a provider.',
186
+ note: 'You can still manually register providers using gateway.register(provider)'
187
+ });
188
+ }
189
+ else {
190
+ logger.info(`Auto-registered ${registeredProviders.length} provider(s)`, {
191
+ providers: registeredProviders
192
+ });
193
+ }
194
+ return registeredProviders;
195
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Gateway Provider Auto-Registration Module
3
+ * Automatically registers providers based on environment variables
4
+ */
5
+ import type { LLMProviderRouter } from '@x12i/ai-providers-router';
6
+ import type { Logxer } from '@x12i/logxer';
7
+ /**
8
+ * Auto-registers providers based on environment variables
9
+ * Only registers providers that:
10
+ * 1. Have their API key set in environment variables
11
+ * 2. Have their provider package installed
12
+ *
13
+ * @param router - LLM provider router instance
14
+ * @param logger - Logger instance
15
+ * @returns Array of provider names that were successfully registered
16
+ */
17
+ export declare function autoRegisterProviders(router: LLMProviderRouter, logger: Logxer): Promise<string[]>;
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+ /**
3
+ * Gateway Provider Module
4
+ * Handles provider management
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.registerProvider = registerProvider;
8
+ exports.unregisterProvider = unregisterProvider;
9
+ exports.getProvider = getProvider;
10
+ exports.listProviders = listProviders;
11
+ exports.setDefaultProvider = setDefaultProvider;
12
+ exports.setFallbackChain = setFallbackChain;
13
+ exports.addRequestInterceptor = addRequestInterceptor;
14
+ exports.addResponseInterceptor = addResponseInterceptor;
15
+ exports.checkHealth = checkHealth;
16
+ exports.checkAllHealth = checkAllHealth;
17
+ /**
18
+ * Register a provider with the router
19
+ */
20
+ function registerProvider(provider, router, logger) {
21
+ // Get provider name - try multiple methods
22
+ let providerName = 'unknown';
23
+ if (typeof provider.getProviderName === 'function') {
24
+ providerName = provider.getProviderName();
25
+ }
26
+ else if (provider.name) {
27
+ providerName = provider.name;
28
+ }
29
+ else if (provider.constructor?.name) {
30
+ providerName = provider.constructor.name.replace('Provider', '').toLowerCase();
31
+ }
32
+ logger.debug('Registering provider', { provider: providerName });
33
+ // Check if provider has required methods
34
+ if (!provider || (typeof provider.invoke !== 'function' && typeof provider.aiCall !== 'function')) {
35
+ logger.error('Provider registration failed: must implement invoke() or aiCall()', {
36
+ provider: providerName,
37
+ hasInvoke: typeof provider.invoke === 'function',
38
+ hasAiCall: typeof provider.aiCall === 'function'
39
+ });
40
+ throw new Error('Provider must implement LLMProviderInterface (invoke) or AIProviderInterface (aiCall)');
41
+ }
42
+ // Create a ProviderModule wrapper for the provider instance
43
+ logger.debug('Creating ProviderModule wrapper for provider instance', { provider: providerName });
44
+ // Ensure provider has invoke method
45
+ let providerWithInvoke = provider;
46
+ if (typeof provider.aiCall === 'function' && typeof provider.invoke !== 'function') {
47
+ logger.debug('Provider uses aiCall, creating invoke wrapper', { provider: providerName });
48
+ providerWithInvoke = {
49
+ ...provider,
50
+ invoke: async (request) => {
51
+ // Convert LLMRequest to format expected by aiCall
52
+ return await provider.aiCall(request);
53
+ }
54
+ };
55
+ }
56
+ // Create ProviderModule wrapper
57
+ const providerModule = {
58
+ name: providerName,
59
+ capabilities: {
60
+ modes: {
61
+ sync: true,
62
+ stream: false,
63
+ batch: false
64
+ },
65
+ operations: ['invoke'],
66
+ maxConcurrency: 10
67
+ },
68
+ execute: async (request) => {
69
+ return await providerWithInvoke.invoke(request);
70
+ }
71
+ };
72
+ // Register with router using registerProvider
73
+ try {
74
+ router.registerProvider(providerModule);
75
+ logger.info('Provider registered as ProviderModule', {
76
+ provider: providerName,
77
+ totalProviders: router.listProviders().length
78
+ });
79
+ }
80
+ catch (error) {
81
+ logger.error('Failed to register provider with router.registerProvider, trying registry directly', {
82
+ provider: providerName,
83
+ error: error instanceof Error ? error.message : String(error)
84
+ });
85
+ // Fallback: try to access registry directly
86
+ try {
87
+ const registry = router.getProviderRegistry();
88
+ registry.register(providerModule);
89
+ logger.info('Provider registered via registry fallback', {
90
+ provider: providerName,
91
+ totalProviders: router.listProviders().length
92
+ });
93
+ }
94
+ catch (registryError) {
95
+ logger.error('Failed to register provider via registry', {
96
+ provider: providerName,
97
+ error: registryError instanceof Error ? registryError.message : String(registryError)
98
+ });
99
+ throw registryError;
100
+ }
101
+ }
102
+ }
103
+ /**
104
+ * Unregister a provider
105
+ */
106
+ function unregisterProvider(providerName, router, logger) {
107
+ try {
108
+ // Try to access registry directly to remove the provider
109
+ const registry = router.getProviderRegistry();
110
+ // Since registry doesn't have an unregister method, we'll need to manipulate the map directly
111
+ // This is a bit hacky but necessary since the API doesn't provide unregister
112
+ const map = registry.map;
113
+ if (map && map instanceof Map) {
114
+ map.delete(providerName);
115
+ logger.info('Provider unregistered from registry', { provider: providerName });
116
+ }
117
+ else {
118
+ logger.warn('Could not access provider registry map for unregistration', { provider: providerName });
119
+ }
120
+ }
121
+ catch (error) {
122
+ logger.error('Failed to unregister provider', {
123
+ provider: providerName,
124
+ error: error instanceof Error ? error.message : String(error)
125
+ });
126
+ }
127
+ }
128
+ /**
129
+ * Get a provider module
130
+ */
131
+ function getProvider(providerName, router) {
132
+ try {
133
+ const registry = router.getProviderRegistry();
134
+ return registry.get(providerName);
135
+ }
136
+ catch (error) {
137
+ // Fallback to any access if registry access fails
138
+ return router.getProvider?.(providerName);
139
+ }
140
+ }
141
+ /**
142
+ * List all registered providers
143
+ */
144
+ function listProviders(router) {
145
+ return router.listProviders();
146
+ }
147
+ /**
148
+ * Set default provider
149
+ *
150
+ * NOTE: Router doesn't support changing default provider after initialization.
151
+ * This method is kept for API compatibility but does nothing.
152
+ * Default provider must be set in router config during initialization.
153
+ */
154
+ function setDefaultProvider(provider, router, logger) {
155
+ // Router doesn't support changing default provider after initialization
156
+ // Default provider must be set in router config during initialization
157
+ logger.warn('setDefaultProvider called but router does not support changing default provider after initialization', {
158
+ provider,
159
+ note: 'Default provider must be set in router config during initialization'
160
+ });
161
+ }
162
+ /**
163
+ * Set fallback chain
164
+ *
165
+ * NOTE: Router doesn't support changing fallback chain after initialization.
166
+ * This method is kept for API compatibility but does nothing.
167
+ * Fallback chain must be set in router config during initialization.
168
+ */
169
+ function setFallbackChain(chain, router, logger) {
170
+ // Router doesn't support changing fallback chain after initialization
171
+ // Fallback chain must be set in router config during initialization
172
+ logger.warn('setFallbackChain called but router does not support changing fallback chain after initialization', {
173
+ chain,
174
+ note: 'Fallback chain must be set in router config during initialization'
175
+ });
176
+ }
177
+ /**
178
+ * Add request interceptor
179
+ */
180
+ function addRequestInterceptor(interceptor, router) {
181
+ router.addRequestInterceptor(interceptor);
182
+ }
183
+ /**
184
+ * Add response interceptor
185
+ */
186
+ function addResponseInterceptor(interceptor, router) {
187
+ router.addResponseInterceptor(interceptor);
188
+ }
189
+ /**
190
+ * Check health of a provider
191
+ */
192
+ async function checkHealth(provider, router) {
193
+ return router.checkHealth(provider);
194
+ }
195
+ /**
196
+ * Check health of all providers
197
+ */
198
+ async function checkAllHealth(router) {
199
+ const providers = listProviders(router);
200
+ const results = {};
201
+ for (const provider of providers) {
202
+ try {
203
+ results[provider] = await router.checkHealth(provider);
204
+ }
205
+ catch (error) {
206
+ results[provider] = {
207
+ provider,
208
+ healthy: false,
209
+ error: error instanceof Error ? error.message : String(error)
210
+ };
211
+ }
212
+ }
213
+ return results;
214
+ }