@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,109 @@
1
+ /**
2
+ * @x12i/flex-md Loader
3
+ *
4
+ * Handles ES Module loading and provides unified API for flex-md operations.
5
+ * @x12i/flex-md is an ES Module, so we use dynamic import() instead of require().
6
+ *
7
+ * Features:
8
+ * - extractJsonFromFlexMd: Extract and parse JSON from flex-md content
9
+ * - buildDynamicInstructions: Build output format instructions from schema objects (3.1+)
10
+ * - Embedded nx-md-parser: flex-md 4.x includes nx-md-parser functionality (no separate package needed)
11
+ * - Utilizes latest flex-md 4.x APIs: extractFromMarkdown, transformWithOfs, processResponseMarkdown
12
+ * - Memory/caching: flex-md 4.x functions may utilize internal memory/caching for performance
13
+ * - Native output format support: Extracts and uses flex-md native output formats from instructions
14
+ * based on compliance level when no explicit format is provided
15
+ */
16
+ /**
17
+ * Load flex-md module (ES Module) asynchronously
18
+ * Caches the result to avoid multiple imports
19
+ */
20
+ export declare function loadFlexMd(): Promise<any>;
21
+ /**
22
+ * Extract and parse JSON from flex-md content (unstructured parsing only)
23
+ * Uses flex-md 4.2.0 APIs with latest features for unstructured markdown conversion
24
+ *
25
+ * ARCHITECTURE: This function only handles unstructured parsing at ai-gateway layer
26
+ * Schema-driven parsing happens at skills layer with nx-md-parser
27
+ *
28
+ * Supports flex-md native output formats from instructions:
29
+ * - Extracts flex-md output format from instructions when provided
30
+ * - Uses the extracted format based on compliance level for parsing
31
+ * - Falls back to simple markdown parsing when flex-md is unavailable
32
+ *
33
+ * @param content - The markdown content to parse (unstructured)
34
+ * @param options - Optional flex-md options:
35
+ * - instructions: Instruction text to guide unstructured parsing
36
+ * - complianceLevel: Compliance level ('L0' | 'L1' | 'L2' | 'L3') for format extraction
37
+ * - spec: Pre-parsed flex-md output format spec
38
+ * - Other flex-md options
39
+ * @returns Parsed JSON object and method used, or null if parsing fails
40
+ */
41
+ export declare function extractJsonFromFlexMd(content: string): Promise<{
42
+ json: any;
43
+ method: string;
44
+ } | null>;
45
+ /**
46
+ * Check if flex-md module is available
47
+ */
48
+ export declare function isFlexMdAvailable(): boolean;
49
+ /**
50
+ * Get maxTokens for a model from flex-md if available
51
+ * Tries various flex-md APIs to get model information and maxTokens
52
+ *
53
+ * @param provider - Provider name (e.g., 'openai', 'anthropic')
54
+ * @param model - Model name (e.g., 'gpt-4', 'claude-3-opus')
55
+ * @returns maxTokens if found, null otherwise
56
+ */
57
+ export declare function getModelMaxTokensFromFlexMd(provider: string, model: string): Promise<number | null>;
58
+ /**
59
+ * Get flex-md module directly (must call loadFlexMd() first)
60
+ */
61
+ export declare function getFlexMdModule(): any;
62
+ export declare function buildDynamicInstructions(schemaObject: Record<string, any> | any, options?: {
63
+ title?: string;
64
+ description?: string;
65
+ includeExamples?: boolean;
66
+ }): Promise<string | null>;
67
+ /**
68
+ * Enrich instructions with flex-md compliance guidance (flex-md 3.0+ feature)
69
+ * Adds appropriate flex-md format instructions based on strictness level
70
+ *
71
+ * @param instructions - Base instructions text
72
+ * @param strictnessLevel - Compliance level ('L0' | 'L1' | 'L2' | 'L3')
73
+ * @returns Enriched instructions with flex-md guidance
74
+ */
75
+ export declare function enrichInstructionsWithFlexMd(instructions: string, strictnessLevel?: 'L0' | 'L1' | 'L2' | 'L3'): Promise<string>;
76
+ /**
77
+ * Get strictness defaults for a compliance level (flex-md 3.0+ feature)
78
+ * Returns configuration object for the specified compliance level
79
+ *
80
+ * @param strictnessLevel - Compliance level ('L0' | 'L1' | 'L2' | 'L3')
81
+ * @returns Configuration object with level-specific defaults
82
+ */
83
+ export declare function getStrictnessDefaults(strictnessLevel?: 'L0' | 'L1' | 'L2' | 'L3'): Promise<Record<string, any> | null>;
84
+ /**
85
+ * Enforce flex-md format in instructions (flex-md 3.0+ feature)
86
+ * Adds enforcement rules based on output format spec and strictness level
87
+ *
88
+ * @param instructions - Base instructions text
89
+ * @param outputFormatSpec - Output format specification (optional)
90
+ * @param strictnessLevel - Compliance level ('L0' | 'L1' | 'L2' | 'L3')
91
+ * @returns Instructions with flex-md enforcement rules
92
+ */
93
+ export declare function enforceFlexMdFormat(instructions: string, outputFormatSpec?: any, strictnessLevel?: 'L0' | 'L1' | 'L2' | 'L3'): Promise<string>;
94
+ /**
95
+ * Check if instructions meet a specific flex-md compliance level
96
+ *
97
+ * @param instructions - Instructions text to check
98
+ * @param complianceLevel - Required compliance level
99
+ * @returns true if instructions meet the compliance level
100
+ */
101
+ export declare function hasFlexMdContract(instructions: string, complianceLevel?: 'L0' | 'L1' | 'L2' | 'L3'): Promise<boolean>;
102
+ /**
103
+ * Detect the actual compliance level that instructions meet
104
+ * Checks from highest (L3) to lowest (L0) to find the highest level met
105
+ *
106
+ * @param instructions - Instructions text to check
107
+ * @returns The highest compliance level met ('L0' | 'L1' | 'L2' | 'L3' | null if none)
108
+ */
109
+ export declare function detectComplianceLevel(instructions: string): Promise<'L0' | 'L1' | 'L2' | 'L3' | null>;
@@ -0,0 +1,331 @@
1
+ "use strict";
2
+ /**
3
+ * Gateway Configuration Module
4
+ * Handles configuration loading and setup
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.loadConfig = loadConfig;
41
+ exports.getFlexMdMinComplianceLevel = getFlexMdMinComplianceLevel;
42
+ exports.setupRequestInterceptor = setupRequestInterceptor;
43
+ exports.initializeGatewayComponents = initializeGatewayComponents;
44
+ const fs = __importStar(require("fs"));
45
+ const path = __importStar(require("path"));
46
+ const url_1 = require("url");
47
+ /** Resolve current module directory across ESM/CJS builds. */
48
+ function getModuleDir() {
49
+ if (typeof __dirname !== 'undefined') {
50
+ return __dirname;
51
+ }
52
+ try {
53
+ const getMetaUrl = new Function('return import.meta.url');
54
+ const metaUrl = getMetaUrl();
55
+ if (metaUrl && metaUrl.startsWith('file:')) {
56
+ return path.dirname((0, url_1.fileURLToPath)(metaUrl));
57
+ }
58
+ }
59
+ catch {
60
+ // Fall through to cwd
61
+ }
62
+ return process.cwd();
63
+ }
64
+ /** Resolve directory containing defaults/ with package-local precedence. */
65
+ function getDefaultsDir() {
66
+ const moduleDir = getModuleDir();
67
+ const cwd = process.cwd();
68
+ const candidates = [
69
+ moduleDir,
70
+ path.resolve(moduleDir, '..'),
71
+ path.resolve(moduleDir, '../dist'),
72
+ path.resolve(moduleDir, '../dist-cjs'),
73
+ path.resolve(moduleDir, '../src'),
74
+ path.join(cwd, 'dist'),
75
+ path.join(cwd, 'dist-cjs'),
76
+ path.join(cwd, 'src'),
77
+ ];
78
+ for (const dir of candidates) {
79
+ const modelConfigPath = path.join(dir, 'defaults', 'model-config.json');
80
+ if (fs.existsSync(modelConfigPath)) {
81
+ return dir;
82
+ }
83
+ }
84
+ // Keep existing behavior as a last fallback.
85
+ return path.join(cwd, 'dist');
86
+ }
87
+ const ai_providers_router_1 = require("@x12i/ai-providers-router");
88
+ const logger_factory_js_1 = require("./logger-factory.cjs");
89
+ const activity_manager_js_1 = require("./activity-manager.cjs");
90
+ const usage_tracker_js_1 = require("./usage-tracker.cjs");
91
+ const template_render_merge_js_1 = require("./template-render-merge.cjs");
92
+ const gateway_rate_limiter_js_1 = require("./gateway-rate-limiter.cjs");
93
+ const gateway_rate_limiter_constants_js_1 = require("./gateway-rate-limiter-constants.cjs");
94
+ /**
95
+ * Loads configuration from JSON files (model config and instructionsBlocks)
96
+ * Note: Called before logger is initialized, so no logging here
97
+ */
98
+ function loadConfig() {
99
+ const defaultModelConfig = {};
100
+ const defaultInstructionsBlocks = {};
101
+ let defaultTemplateRendering;
102
+ try {
103
+ const defaultsDir = getDefaultsDir();
104
+ const templateRenderingPath = path.join(defaultsDir, 'defaults', 'template-rendering.json');
105
+ if (fs.existsSync(templateRenderingPath)) {
106
+ const trContent = fs.readFileSync(templateRenderingPath, 'utf-8');
107
+ defaultTemplateRendering = JSON.parse(trContent);
108
+ }
109
+ // Load model config (includes rate limiting and retry defaults)
110
+ const modelConfigPath = path.join(defaultsDir, 'defaults', 'model-config.json');
111
+ if (fs.existsSync(modelConfigPath)) {
112
+ const content = fs.readFileSync(modelConfigPath, 'utf-8');
113
+ const parsed = JSON.parse(content);
114
+ Object.assign(defaultModelConfig, parsed);
115
+ }
116
+ // Load instructionsBlocks
117
+ const instructionsBlocksPath = path.join(defaultsDir, 'defaults', 'instructions-blocks.json');
118
+ if (fs.existsSync(instructionsBlocksPath)) {
119
+ const content = fs.readFileSync(instructionsBlocksPath, 'utf-8');
120
+ const parsed = JSON.parse(content);
121
+ // Use Object.assign to merge, preserving nested structure
122
+ Object.assign(defaultInstructionsBlocks, parsed);
123
+ // Debug: Log what was loaded (only in development)
124
+ if (process.env.NODE_ENV !== 'production') {
125
+ console.log('Loaded instructions blocks:', {
126
+ topLevelKeys: Object.keys(defaultInstructionsBlocks),
127
+ hasOutput: 'output' in defaultInstructionsBlocks,
128
+ outputKeys: 'output' in defaultInstructionsBlocks ? Object.keys(defaultInstructionsBlocks.output) : []
129
+ });
130
+ }
131
+ }
132
+ else {
133
+ // Optional file: fallback defaults below still keep the gateway functional.
134
+ if (process.env.NODE_ENV !== 'production') {
135
+ console.debug('Optional instructions blocks file not found at:', instructionsBlocksPath);
136
+ }
137
+ }
138
+ }
139
+ catch (error) {
140
+ // Can't log here as logger isn't initialized yet
141
+ // Error will be logged after logger initialization in constructor
142
+ console.warn('Failed to load defaults from JSON files:', error);
143
+ }
144
+ // Ensure critical blocks exist even if file loading failed
145
+ if (!defaultInstructionsBlocks['outputObjectPrefix']) {
146
+ defaultInstructionsBlocks['outputObjectPrefix'] = "Reply in Markdown. Return your entire answer inside a single ```markdown fenced block and nothing else. The content must conform to the schema provided below. If no items are found, return empty arrays (e.g., emails: []). Never ask for more input. Do not write conversational text. Do not write explanations. Do not ask questions.\n\n";
147
+ }
148
+ if (!defaultInstructionsBlocks['outputObjectTypesPrefix']) {
149
+ defaultInstructionsBlocks['outputObjectTypesPrefix'] = "Reply in Markdown. Return your entire answer inside a single ```markdown fenced block and nothing else. Select ONE of the following object types based on the input. The content must conform to the chosen schema. Do not write conversational text. Do not write explanations.\n\n";
150
+ }
151
+ return { defaultModelConfig, defaultInstructionsBlocks, defaultTemplateRendering };
152
+ }
153
+ /**
154
+ * Gets the minimum flex-md compliance level from environment variable
155
+ * Defaults to 'L0' if not set or invalid
156
+ */
157
+ function getFlexMdMinComplianceLevel() {
158
+ const envValue = process.env.FLEX_MD_MIN_COMPLIANCE_LEVEL;
159
+ if (envValue === 'L0' || envValue === 'L1' || envValue === 'L2' || envValue === 'L3') {
160
+ return envValue;
161
+ }
162
+ return 'L0'; // Default: allow anything
163
+ }
164
+ /**
165
+ * Sets up request interceptor for jobId propagation and config cleanup
166
+ */
167
+ function setupRequestInterceptor(router, logger) {
168
+ logger.debug('Setting up request interceptor for jobId propagation and config cleanup');
169
+ router.addRequestInterceptor(async (request, provider) => {
170
+ // Propagate jobId to request metadata
171
+ if (request.jobId) {
172
+ logger.verbose('Propagating jobId to request metadata', {
173
+ jobId: request.jobId,
174
+ provider: provider?.getProviderName?.() || 'unknown'
175
+ });
176
+ if (!request.config) {
177
+ request.config = {};
178
+ }
179
+ if (!request.config.metadata) {
180
+ request.config.metadata = {};
181
+ }
182
+ request.config.metadata.jobId = request.jobId;
183
+ }
184
+ // Remove 'provider' from config - router uses it for routing but providers don't accept it
185
+ // Router reads config.provider to determine which provider to call, but then passes
186
+ // the entire config to the provider, which rejects 'provider' as invalid
187
+ if (request.config && 'provider' in request.config) {
188
+ logger.debug('Removing provider from config before passing to provider', {
189
+ provider: request.config.provider
190
+ });
191
+ const { provider: _, ...cleanConfig } = request.config;
192
+ request.config = cleanConfig;
193
+ }
194
+ return request;
195
+ });
196
+ logger.debug('Request interceptor configured');
197
+ }
198
+ /**
199
+ * Initializes gateway components
200
+ */
201
+ function initializeGatewayComponents(config, defaultModelConfig, defaultInstructionsBlocks, defaultTemplateRendering) {
202
+ // Initialize logger FIRST (before other components that might need it)
203
+ const logger = (0, logger_factory_js_1.createGatewayLogger)({
204
+ enableLogging: config.enableLogging ?? true,
205
+ packageName: config.packageName,
206
+ customLogger: config.logger
207
+ });
208
+ // Now that logger is initialized, log the defaults loading
209
+ logger.verbose('Gateway initializing', {
210
+ defaultEngine: config.defaultEngine,
211
+ hasDefaultInstructionsBlocks: Object.keys(defaultInstructionsBlocks).length > 0
212
+ });
213
+ // Activity tracking is handled by Activix internally.
214
+ // Initialize router - this is the ONLY way to access providers
215
+ // RouterConfig properties are inherited from RouterConfig interface
216
+ const routerConfig = {};
217
+ const defaultTarget = config.defaultTarget;
218
+ if (defaultTarget) {
219
+ routerConfig.defaultTarget = defaultTarget;
220
+ }
221
+ else if (config.defaultProvider !== undefined) {
222
+ routerConfig.defaultProvider = config.defaultProvider;
223
+ }
224
+ else if (config.defaultEngine !== undefined) {
225
+ routerConfig.defaultProvider = config.defaultEngine;
226
+ }
227
+ const fallbackChain = config.fallbackChain;
228
+ if (fallbackChain) {
229
+ routerConfig.fallbackChain = fallbackChain;
230
+ }
231
+ else if (config.fallbackChain !== undefined) {
232
+ routerConfig.fallbackChain = config.fallbackChain;
233
+ }
234
+ if (config.autoDiscover !== undefined)
235
+ routerConfig.autoDiscover = config.autoDiscover;
236
+ if (config.usageTracker !== undefined)
237
+ routerConfig.usageTracker = config.usageTracker;
238
+ // OpenRouter: enable when key is set and not explicitly disabled (so consumers get a working default without registering providers).
239
+ // Prefer explicit config from consumer (e.g. ai-skills) to avoid env-loading timing; fall back to process.env.
240
+ const explicitOpenRouterKey = config.openrouter?.apiKey;
241
+ const isExplicitKey = typeof explicitOpenRouterKey === 'string' && !explicitOpenRouterKey.startsWith('ENV.');
242
+ const openRouterKey = isExplicitKey ? explicitOpenRouterKey : (process.env.OPEN_ROUTER_KEY ?? process.env.OPENROUTER_API_KEY);
243
+ const useOpenRouter = config.openRouter?.enabled !== undefined ? config.openRouter?.enabled : process.env.USE_OPENROUTER;
244
+ if (openRouterKey && useOpenRouter !== false && useOpenRouter !== 'false') {
245
+ routerConfig.openRouter = { enabled: true };
246
+ routerConfig.openrouter = { apiKey: openRouterKey };
247
+ routerConfig.defaultMode = 'openrouter';
248
+ }
249
+ const router = new ai_providers_router_1.LLMProviderRouter(routerConfig);
250
+ // Set up BETWEEN-CALLS rate limiting as a request interceptor (applies to all provider calls)
251
+ // This ensures rate limiting works even when router is used directly without gateway
252
+ // Hidden in the flow - automatic and transparent
253
+ //
254
+ // NOTE: This is for BETWEEN-CALLS rate limiting (smart, tracks last call time).
255
+ // Retry delays are handled separately in gateway-retry.ts (simple sleep, not smart).
256
+ const rateLimitConfig = config.rateLimit;
257
+ // Get defaults from JSON config, fallback to constants
258
+ const jsonRateLimitConfig = defaultModelConfig.rateLimit || {};
259
+ const rateLimitEnabled = rateLimitConfig?.enabled ?? jsonRateLimitConfig.enabled ?? gateway_rate_limiter_constants_js_1.DEFAULT_RATE_LIMIT_ENABLED;
260
+ if (rateLimitEnabled) {
261
+ // Priority: explicit config > JSON defaults > constants
262
+ const defaultMinIntervalMs = rateLimitConfig?.defaultMinIntervalMs
263
+ ?? jsonRateLimitConfig.defaultMinIntervalMs
264
+ ?? gateway_rate_limiter_constants_js_1.DEFAULT_RATE_LIMIT_MIN_INTERVAL_MS;
265
+ const providerIntervals = rateLimitConfig?.providerIntervals;
266
+ const rateLimiter = new gateway_rate_limiter_js_1.GatewayRateLimiter(defaultMinIntervalMs, providerIntervals, logger);
267
+ // Add request interceptor for BETWEEN-CALLS rate limiting (hidden in the flow)
268
+ router.addRequestInterceptor(async (request, provider) => {
269
+ // Get provider name
270
+ const providerName = typeof provider?.getProviderName === 'function'
271
+ ? provider.getProviderName()
272
+ : 'global';
273
+ // Smart rate limiting: wait only if necessary based on last call time
274
+ // This is for BETWEEN-CALLS, not retries (retries use simple sleep in gateway-retry.ts)
275
+ await rateLimiter.waitIfNeeded(providerName);
276
+ // Return request unchanged (interceptor can modify request, but we just need to wait)
277
+ return request;
278
+ });
279
+ // Add response interceptor to record call completion
280
+ // Note: Type assertion needed due to ResponseInterceptor type definition mismatch
281
+ router.addResponseInterceptor((async (response, request, provider) => {
282
+ // Get provider name
283
+ const providerName = typeof provider?.getProviderName === 'function'
284
+ ? provider.getProviderName()
285
+ : 'global';
286
+ // Record the call time after completion (for smart between-calls rate limiting)
287
+ rateLimiter.recordCall(providerName);
288
+ // Return response unchanged
289
+ return response;
290
+ }));
291
+ logger.debug('Between-calls rate limiting configured as router interceptor', {
292
+ defaultMinIntervalMs,
293
+ providerIntervals: providerIntervals ? Object.keys(providerIntervals).length : 0,
294
+ enabled: true,
295
+ note: 'Smart rate limiting (between-calls only). Retry delays handled separately (simple sleep).'
296
+ });
297
+ }
298
+ else {
299
+ logger.debug('Rate limiting disabled');
300
+ }
301
+ // Initialize usage tracking
302
+ const usageTracker = new usage_tracker_js_1.UsageTracker({
303
+ enableUsageTracking: config.enableUsageTracking ?? true,
304
+ usageTier: config.usageTier,
305
+ logger
306
+ });
307
+ // Initialize activity tracking
308
+ const activityManager = new activity_manager_js_1.ActivityManager({
309
+ enableActivityTracking: config.enableActivityTracking ?? true,
310
+ customTracker: config.activityTracker,
311
+ logger
312
+ });
313
+ const templateRendering = (0, template_render_merge_js_1.mergeTemplateRenderOptions)(defaultTemplateRendering, config.templateRendering);
314
+ const instructionsBlockOverrides = {
315
+ ...(config.instructionsBlocks ?? {})
316
+ };
317
+ // Initialize message builder config - for direct message construction
318
+ const messageBuilderConfig = {
319
+ defaultInstructionsBlocks,
320
+ instructionsBlockOverrides,
321
+ logger,
322
+ templateRendering
323
+ };
324
+ return {
325
+ logger,
326
+ router,
327
+ activityManager,
328
+ usageTracker,
329
+ messageBuilderConfig
330
+ };
331
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Gateway Configuration Module
3
+ * Handles configuration loading and setup
4
+ */
5
+ import type { GatewayConfig } from './types.js';
6
+ import type { Logxer } from '@x12i/logxer';
7
+ import { LLMProviderRouter } from '@x12i/ai-providers-router';
8
+ import { ActivityManager } from './activity-manager.js';
9
+ import { UsageTracker } from './usage-tracker.js';
10
+ import type { MessageBuilderConfig } from './message-builder.js';
11
+ import type { TemplateRenderOptions } from '@x12i/rendrix';
12
+ export interface GatewayConfigContext {
13
+ defaultModelConfig: Record<string, unknown>;
14
+ defaultInstructionsBlocks: Record<string, any>;
15
+ config: GatewayConfig;
16
+ logger: Logxer;
17
+ router: LLMProviderRouter;
18
+ activityManager: ActivityManager;
19
+ usageTracker: UsageTracker;
20
+ messageBuilderConfig: MessageBuilderConfig;
21
+ }
22
+ /**
23
+ * Loads configuration from JSON files (model config and instructionsBlocks)
24
+ * Note: Called before logger is initialized, so no logging here
25
+ */
26
+ export declare function loadConfig(): {
27
+ defaultModelConfig: Record<string, unknown>;
28
+ defaultInstructionsBlocks: Record<string, any>;
29
+ defaultTemplateRendering?: TemplateRenderOptions;
30
+ };
31
+ /**
32
+ * Gets the minimum flex-md compliance level from environment variable
33
+ * Defaults to 'L0' if not set or invalid
34
+ */
35
+ export declare function getFlexMdMinComplianceLevel(): 'L0' | 'L1' | 'L2' | 'L3';
36
+ /**
37
+ * Sets up request interceptor for jobId propagation and config cleanup
38
+ */
39
+ export declare function setupRequestInterceptor(router: LLMProviderRouter, logger: Logxer): void;
40
+ /**
41
+ * Initializes gateway components
42
+ */
43
+ export declare function initializeGatewayComponents(config: GatewayConfig, defaultModelConfig: Record<string, unknown>, defaultInstructionsBlocks: Record<string, any>, defaultTemplateRendering?: TemplateRenderOptions): {
44
+ logger: Logxer;
45
+ router: LLMProviderRouter;
46
+ activityManager: ActivityManager;
47
+ usageTracker: UsageTracker;
48
+ messageBuilderConfig: MessageBuilderConfig;
49
+ };