@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,430 @@
1
+ /**
2
+ * @x12i/ai-gateway
3
+ *
4
+ * Simplified AI Gateway - Clean proxy implementation
5
+ */
6
+ import { validateChatRequest, validateAIRequest } from './gateway-validation.js';
7
+ import { ensureGatewayRequestIdentity } from './activity-manager.js';
8
+ import { initializeGatewayComponents, loadConfig } from './gateway-config.js';
9
+ import { buildMessages } from './message-builder.js';
10
+ import { extractJsonFromFlexMd } from './flex-md-loader.js';
11
+ import { mergeConfig } from './gateway-utils.js';
12
+ import { autoRegisterProviders } from './gateway-provider-auto-register.js';
13
+ import { setGatewayLastJobId, setGatewayRuntimeClients } from './runtime-objects.js';
14
+ /** Error message thrown by the router when no provider is registered or specified */
15
+ const NO_PROVIDER_ERROR = 'No provider specified and no providers registered';
16
+ const NO_PROVIDER_HINT = ' Set OPEN_ROUTER_KEY (or OPENROUTER_API_KEY) in the environment to use OpenRouter, or register a provider with the router (e.g. via autoRegisterProviders or gateway config).';
17
+ /**
18
+ * Simplified AI Gateway - Clean proxy implementation
19
+ */
20
+ export class AIGateway {
21
+ router;
22
+ config;
23
+ logger;
24
+ activityManager;
25
+ messageBuilderConfig;
26
+ _autoRegisterDone = false;
27
+ constructor(config = {}, activityManager) {
28
+ this.config = config;
29
+ this.activityManager = activityManager;
30
+ // Load configuration and initialize components
31
+ const { defaultModelConfig, defaultInstructionsBlocks, defaultTemplateRendering } = loadConfig();
32
+ const components = initializeGatewayComponents(config, defaultModelConfig, defaultInstructionsBlocks, defaultTemplateRendering);
33
+ this.logger = components.logger;
34
+ this.router = components.router;
35
+ this.activityManager = components.activityManager;
36
+ this.messageBuilderConfig = components.messageBuilderConfig;
37
+ setGatewayRuntimeClients({
38
+ activix: this.activityManager?.getTracker(),
39
+ logger: this.logger
40
+ });
41
+ this.logger.info('AI Gateway initialized with full component stack', {
42
+ hasActivityManager: !!this.activityManager,
43
+ hasMessageBuilder: !!this.messageBuilderConfig
44
+ });
45
+ }
46
+ /**
47
+ * Invoke chat request (without structured output requirements)
48
+ */
49
+ async invokeChat(request) {
50
+ const startTime = Date.now();
51
+ // Basic validation
52
+ validateChatRequest(request);
53
+ if (!this.activityManager) {
54
+ ensureGatewayRequestIdentity(request);
55
+ }
56
+ setGatewayLastJobId(resolveRuntimeJobId(request));
57
+ // Generate simple task type ID
58
+ const taskTypeId = request.taskTypeId || `task-${Date.now()}`;
59
+ // Simple message construction
60
+ const messages = this.buildSimpleMessages(request);
61
+ // Merge config (modelConfig > request.config > gateway defaults)
62
+ const mergedConfig = await mergeConfig(request, this.config, this.logger);
63
+ // Lazy auto-register providers from env (OPENAI_API_KEY, etc.) so consumers don't have to call init
64
+ if (!this._autoRegisterDone) {
65
+ await autoRegisterProviders(this.router, this.logger);
66
+ this._autoRegisterDone = true;
67
+ }
68
+ // Start activity tracking if available
69
+ let activity = undefined;
70
+ if (this.activityManager) {
71
+ try {
72
+ activity = await this.activityManager.startActivity(request, startTime);
73
+ }
74
+ catch (activityError) {
75
+ // Log activity tracking error but don't fail the request
76
+ this.logger.warn('Failed to start activity tracking', {
77
+ aiRequestId: request.aiRequestId,
78
+ error: activityError instanceof Error ? activityError.message : String(activityError)
79
+ });
80
+ }
81
+ }
82
+ try {
83
+ // Call router directly with merged config
84
+ const response = await this.router.invoke({
85
+ request: {
86
+ messages,
87
+ config: mergedConfig,
88
+ identity: request.identity
89
+ },
90
+ mode: 'sync'
91
+ });
92
+ // Create enhanced response
93
+ const enhancedResponse = {
94
+ content: response.content || '',
95
+ metadata: {
96
+ aiRequestId: request.aiRequestId,
97
+ identity: request.identity,
98
+ latencyMs: Date.now() - startTime,
99
+ tokens: response.usage || { prompt: 0, completion: 0, total: 0 },
100
+ taskTypeId,
101
+ agentType: 'chat'
102
+ }
103
+ };
104
+ // Track activity success if activity was started
105
+ if (activity) {
106
+ try {
107
+ await this.activityManager.logSuccess(activity, {
108
+ response: enhancedResponse,
109
+ endTime: Date.now(),
110
+ duration: Date.now() - startTime
111
+ });
112
+ }
113
+ catch (activityError) {
114
+ // Log activity tracking error but don't fail the request
115
+ this.logger.warn('Failed to track activity success', {
116
+ aiRequestId: request.aiRequestId,
117
+ error: activityError instanceof Error ? activityError.message : String(activityError)
118
+ });
119
+ }
120
+ }
121
+ return enhancedResponse;
122
+ }
123
+ catch (error) {
124
+ const err = error instanceof Error ? error : new Error(String(error));
125
+ if (err.message.includes(NO_PROVIDER_ERROR)) {
126
+ throw new Error(err.message + NO_PROVIDER_HINT);
127
+ }
128
+ throw err;
129
+ }
130
+ }
131
+ /**
132
+ * Invoke AI request (with structured output support)
133
+ */
134
+ async invoke(request) {
135
+ const startTime = Date.now();
136
+ // Basic validation
137
+ validateAIRequest(request);
138
+ if (!this.activityManager) {
139
+ ensureGatewayRequestIdentity(request);
140
+ }
141
+ setGatewayLastJobId(resolveRuntimeJobId(request));
142
+ // Generate simple task type ID
143
+ const taskTypeId = request.taskTypeId || `task-${Date.now()}`;
144
+ // Resolve instructions and build messages using proper components
145
+ let resolvedRequest = request;
146
+ let messages = [];
147
+ // Create parsedSnapshot to store parsed request data and messages
148
+ const parsedSnapshot = {};
149
+ // Use proper instruction resolution and message building
150
+ let builtMessages;
151
+ try {
152
+ builtMessages = await buildMessages(request, this.messageBuilderConfig, {
153
+ parsedSnapshot
154
+ });
155
+ messages = builtMessages.messages;
156
+ resolvedRequest = request;
157
+ }
158
+ catch (error) {
159
+ // If message building fails (e.g., prompt/instruction resolution error), log as bad request
160
+ const err = error instanceof Error ? error : new Error(String(error));
161
+ const endTime = Date.now();
162
+ const duration = endTime - startTime;
163
+ // Determine if this is a prompt/instruction resolution error
164
+ // If a key was provided but couldn't be resolved to content, it's a bad request
165
+ const errWithCode = err; // Type assertion for error with optional code property
166
+ const isResolutionError = err.name === 'InstructionNotFoundError' ||
167
+ err.name === 'InstructionBackendError' ||
168
+ err.name === 'TemplateResolutionError' ||
169
+ errWithCode.code === 'PROMPT_NOT_FOUND' ||
170
+ errWithCode.code === 'PROMPT_RESOLUTION_ERROR' ||
171
+ errWithCode.code === 'PROMPT_RENDERED_EMPTY' ||
172
+ errWithCode.code === 'TEMPLATE_RESOLUTION_ERROR' ||
173
+ errWithCode.code === 'TEMPLATE_VARIABLE_MISSING' ||
174
+ err.message.includes('Failed to resolve') ||
175
+ err.message.includes('Failed to render prompt template') ||
176
+ err.message.includes('not found') ||
177
+ err.message.includes('Instruction not found') ||
178
+ err.message.includes('Prompt not found');
179
+ if (isResolutionError && this.activityManager) {
180
+ // Log to bad requests collection
181
+ await this.activityManager.logBadRequest(request, err, {
182
+ endTime,
183
+ duration,
184
+ error: err.message,
185
+ errorType: errWithCode.code || 'MessageBuildError',
186
+ diagnosticInfo: {
187
+ errorCode: errWithCode.code,
188
+ errorName: err.name,
189
+ failureType: 'validation-failure',
190
+ stage: 'message-building',
191
+ prompt: request.prompt,
192
+ instructions: typeof request.instructions === 'string' ? request.instructions.substring(0, 100) : '(object)'
193
+ },
194
+ failureType: 'validation-failure'
195
+ }, startTime);
196
+ }
197
+ // Re-throw the error so it propagates to the caller
198
+ throw err;
199
+ }
200
+ // Store messages in parsedSnapshot for activity tracking
201
+ parsedSnapshot.messages = messages;
202
+ // parsed.instructions and parsed.prompt are set by buildMessages to the resolved/rendered content
203
+ // (after key resolution and Rendrix). Do not overwrite with raw request keys.
204
+ if (parsedSnapshot.context === undefined) {
205
+ parsedSnapshot.context = request.context;
206
+ }
207
+ // Attach parsedSnapshot to request for activity tracking
208
+ request._parsedRequest = parsedSnapshot;
209
+ // Merge config (modelConfig > request.config > gateway defaults)
210
+ const mergedConfig = await mergeConfig(request, this.config, this.logger);
211
+ // Lazy auto-register providers from env (OPENAI_API_KEY, etc.) so consumers don't have to call init
212
+ if (!this._autoRegisterDone) {
213
+ await autoRegisterProviders(this.router, this.logger);
214
+ this._autoRegisterDone = true;
215
+ }
216
+ // Start activity tracking if available
217
+ let activity = undefined;
218
+ if (this.activityManager) {
219
+ try {
220
+ activity = await this.activityManager.startActivity(request, startTime);
221
+ }
222
+ catch (activityError) {
223
+ // Log activity tracking error but don't fail the request
224
+ this.logger.warn('Failed to start activity tracking', {
225
+ aiRequestId: request.aiRequestId,
226
+ error: activityError instanceof Error ? activityError.message : String(activityError)
227
+ });
228
+ }
229
+ }
230
+ try {
231
+ // Call router directly with merged config
232
+ const response = await this.router.invoke({
233
+ request: {
234
+ messages,
235
+ config: mergedConfig,
236
+ identity: request.identity
237
+ },
238
+ mode: 'sync'
239
+ });
240
+ // Contract output processing removed - expectedSchema no longer supported
241
+ // Create enhanced response - extract content properly from router response
242
+ const routerResponse = response;
243
+ // Extract content from router response - router returns outputText, not content
244
+ let content = routerResponse.content || routerResponse.outputText || '';
245
+ // If content is still empty, try to extract from ai-activities metadata
246
+ if (!content && routerResponse.metadata?.['ai-activities-response']?.outputText) {
247
+ content = routerResponse.metadata['ai-activities-response'].outputText;
248
+ }
249
+ // Parse content using available parsers (flex-md, content normalizer, etc.)
250
+ let parsedContent = undefined;
251
+ let contentType = undefined;
252
+ let parsingMethod = undefined;
253
+ // Actually use flex-md parsing - extract structured data from markdown
254
+ try {
255
+ this.logger.debug('Attempting flex-md extraction', {
256
+ aiRequestId: request.aiRequestId,
257
+ contentLength: content.length,
258
+ hasInstructions: !!resolvedRequest.instructions
259
+ });
260
+ // Let flex-md extract structured data from the response content
261
+ const extractionResult = await extractJsonFromFlexMd(content);
262
+ this.logger.debug('Flex-md extraction result', {
263
+ aiRequestId: request.aiRequestId,
264
+ hasResult: !!extractionResult,
265
+ hasJson: !!(extractionResult && extractionResult.json),
266
+ method: extractionResult?.method,
267
+ jsonType: extractionResult?.json ? typeof extractionResult.json : 'none'
268
+ });
269
+ if (extractionResult && extractionResult.json) {
270
+ // Successfully extracted structured data
271
+ parsedContent = extractionResult.json;
272
+ this.logger.info('Flex-md extraction successful - parsed into structured object', {
273
+ aiRequestId: request.aiRequestId,
274
+ method: extractionResult.method,
275
+ extractedKeys: Object.keys(extractionResult.json)
276
+ });
277
+ }
278
+ else {
279
+ // Extraction failed, fall back to raw text wrapper
280
+ this.logger.warn('Flex-md extraction failed - no structured data extracted', {
281
+ aiRequestId: request.aiRequestId,
282
+ hasResult: !!extractionResult,
283
+ method: extractionResult?.method || 'none'
284
+ });
285
+ parsedContent = { rawText: content };
286
+ }
287
+ }
288
+ catch (extractionError) {
289
+ // Extraction failed, fall back to raw text wrapper
290
+ const errorMessage = extractionError instanceof Error ? extractionError.message : String(extractionError);
291
+ this.logger.warn('Flex-md extraction failed - flex-md library compatibility issue', {
292
+ aiRequestId: request.aiRequestId,
293
+ error: errorMessage,
294
+ issue: 'flex-md uses require() in ES module context - needs fixing in flex-md-loader.ts',
295
+ fallback: 'using rawText wrapper'
296
+ });
297
+ parsedContent = { rawText: content };
298
+ }
299
+ contentType = 'structured';
300
+ parsingMethod = 'flex-md';
301
+ // Extract token usage properly
302
+ let tokens = { prompt: 0, completion: 0, total: 0 };
303
+ if (routerResponse.usage) {
304
+ tokens = {
305
+ prompt: routerResponse.usage.promptTokens || routerResponse.usage.inputTokens || 0,
306
+ completion: routerResponse.usage.completionTokens || routerResponse.usage.outputTokens || 0,
307
+ total: routerResponse.usage.totalTokens || 0
308
+ };
309
+ }
310
+ else if (routerResponse.metadata?.['ai-activities-response']?.usage) {
311
+ const usage = routerResponse.metadata['ai-activities-response'].usage;
312
+ tokens = {
313
+ prompt: usage.promptTokens || usage.inputTokens || 0,
314
+ completion: usage.completionTokens || usage.outputTokens || 0,
315
+ total: usage.totalTokens || 0
316
+ };
317
+ }
318
+ const enhancedResponse = {
319
+ content: content,
320
+ parsedContent: parsedContent,
321
+ metadata: {
322
+ aiRequestId: request.aiRequestId,
323
+ identity: request.identity,
324
+ latencyMs: Date.now() - startTime,
325
+ tokens: tokens,
326
+ taskTypeId,
327
+ agentType: 'ai',
328
+ contentType,
329
+ parsingMethod
330
+ }
331
+ };
332
+ // Track activity success if activity was started
333
+ if (activity) {
334
+ try {
335
+ // Create activity response with proper structure for ActivityTracker
336
+ const activityResponse = {
337
+ content: {
338
+ rawContent: content, // Store the actual response content as rawContent
339
+ fullResponse: routerResponse.rawResponse || routerResponse // Include full router response
340
+ },
341
+ parsed: parsedContent, // Include parsed content in activity record
342
+ metadata: enhancedResponse.metadata,
343
+ status: 'success',
344
+ error: null,
345
+ usage: tokens
346
+ };
347
+ await this.activityManager.logSuccess(activity, {
348
+ response: activityResponse,
349
+ endTime: Date.now(),
350
+ duration: Date.now() - startTime
351
+ });
352
+ }
353
+ catch (activityError) {
354
+ // Log activity tracking error but don't fail the request
355
+ this.logger.warn('Failed to track activity success', {
356
+ aiRequestId: request.aiRequestId,
357
+ error: activityError instanceof Error ? activityError.message : String(activityError)
358
+ });
359
+ }
360
+ }
361
+ console.debug('gateway: enhancedResponse:', enhancedResponse);
362
+ return enhancedResponse;
363
+ }
364
+ catch (error) {
365
+ const err = error instanceof Error ? error : new Error(String(error));
366
+ if (err.message.includes(NO_PROVIDER_ERROR)) {
367
+ throw new Error(err.message + NO_PROVIDER_HINT);
368
+ }
369
+ throw err;
370
+ }
371
+ }
372
+ /**
373
+ * Build simple messages from request (instructions and prompt as literal template text; no registry).
374
+ */
375
+ buildSimpleMessages(request) {
376
+ const messages = [];
377
+ // Add instructions as system message if present
378
+ if (request.instructions) {
379
+ const instructions = typeof request.instructions === 'string'
380
+ ? request.instructions
381
+ : 'Default instructions';
382
+ messages.push({ role: 'system', content: instructions });
383
+ }
384
+ // Add context as assistant message if present
385
+ if (request.context) {
386
+ const context = typeof request.context === 'string'
387
+ ? request.context
388
+ : JSON.stringify(request.context);
389
+ messages.push({ role: 'assistant', content: context });
390
+ }
391
+ // Add prompt/input as user message
392
+ // Input field has been removed - prompt template should contain {{input}} which resolves from workingMemory.input
393
+ const userContent = request.prompt || '';
394
+ if (userContent) {
395
+ messages.push({ role: 'user', content: userContent });
396
+ }
397
+ // Add direct messages if present
398
+ if (request.messages) {
399
+ messages.push(...request.messages);
400
+ }
401
+ return messages;
402
+ }
403
+ // Provider management methods
404
+ register(provider) {
405
+ this.router.registerProvider(provider);
406
+ }
407
+ listProviders() {
408
+ return this.router.listProviders ? this.router.listProviders() : [];
409
+ }
410
+ // Utility methods
411
+ getRouter() {
412
+ return this.router;
413
+ }
414
+ getLogger() {
415
+ return this.logger;
416
+ }
417
+ getActivityManager() {
418
+ return this.activityManager;
419
+ }
420
+ setActivityManager(activityManager) {
421
+ this.activityManager = activityManager;
422
+ setGatewayRuntimeClients({
423
+ activix: this.activityManager.getTracker(),
424
+ logger: this.logger
425
+ });
426
+ }
427
+ }
428
+ function resolveRuntimeJobId(request) {
429
+ return request.identity?.jobId ?? request.jobId ?? request.identity?.sessionId ?? request.aiRequestId;
430
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * @x12i/ai-gateway
3
+ *
4
+ * Unified gateway for LLM provider routing and management.
5
+ * This package exposes all functionality from @x12i/ai-providers-router
6
+ * with enhanced features: context propagation, usage tier tracking, and comprehensive metadata.
7
+ */
8
+ export { LLMProviderRouter } from '@x12i/ai-providers-router';
9
+ export type { RouterConfig, HealthCheckResult } from '@x12i/ai-providers-router';
10
+ export { createRouter, createRouterFromConfig } from '@x12i/ai-providers-router';
11
+ export type { CreateRouterConfig } from '@x12i/ai-providers-router';
12
+ export { ProviderNotFoundError, FallbackExhaustedError } from '@x12i/ai-providers-router';
13
+ export type { RequestInterceptor, ResponseInterceptor } from '@x12i/ai-providers-router';
14
+ export type { UsageTracker } from '@x12i/ai-providers-router';
15
+ export * from '@x12i/ai-providers-router';
16
+ export { AIGateway } from './gateway.js';
17
+ export { InstructionNotFoundError, InstructionBackendError } from './instruction-errors.js';
18
+ export { autoRegisterProviders } from './gateway-provider-auto-register.js';
19
+ export type { GatewayConfig, ProviderModelRef, ModelConfig, RetryConfig, ChatRequest, AIRequest, EnhancedLLMResponse, InstructionMetadata, ValidationRule, ResponseTransformationConfig, TemplateRenderOptions } from './types.js';
20
+ export { mergeTemplateRenderOptions } from './template-render-merge.js';
21
+ export type { UsageTier } from './types.js';
22
+ export { Activix } from '@x12i/activix';
23
+ export type { ActivixRunContext, FindByRunContextCriteria } from '@x12i/activix';
24
+ export { ActivityManager, ensureGatewayRequestIdentity } from './activity-manager.js';
25
+ export type { ActivityIdentity } from './types.js';
26
+ export { createLogxer } from '@x12i/logxer';
27
+ export type { Logxer } from '@x12i/logxer';
28
+ export { runtimeObjects } from './runtime-objects.js';
29
+ export type { ActivixQueryableClient, LogxerQueryableClient, PackageRuntimeObjects, RuntimeObjects } from './runtime-objects.js';
30
+ export { GatewayRateLimiter } from './gateway-rate-limiter.js';
31
+ export { DEFAULT_RATE_LIMIT_MIN_INTERVAL_MS, DEFAULT_RATE_LIMIT_ENABLED } from './gateway-rate-limiter-constants.js';
32
+ export { validateAIRequest, validateJSON, extractJSON, validateResponse, diagnoseRequest, diagnoseResponse, supportsJSONMode, createTestAIRequest, createValidationTestCases, runValidationTests, formatDiagnostic, assertValidAIRequest } from './troubleshooting-helper.js';
33
+ export type { ValidationResult, DiagnosticInfo } from './troubleshooting-helper.js';
34
+ export { OBJECT_TYPES_LIBRARY, getObjectType, getObjectTypesForAgent } from './object-types-library.js';
35
+ export type { ReasoningResult, AuditReport, ScopeDefinition, DiscoveryFindings, ActionPlan, ExecutionResult } from './object-types-library.js';
36
+ export { initializeObjectTypesLibrary, getObjectTypesLibrary, resetObjectTypesLibrary } from './object-types-library-integration.js';
package/dist/index.js ADDED
@@ -0,0 +1,55 @@
1
+ /**
2
+ * @x12i/ai-gateway
3
+ *
4
+ * Unified gateway for LLM provider routing and management.
5
+ * This package exposes all functionality from @x12i/ai-providers-router
6
+ * with enhanced features: context propagation, usage tier tracking, and comprehensive metadata.
7
+ */
8
+ // Re-export router class and types (base functionality)
9
+ export { LLMProviderRouter } from '@x12i/ai-providers-router';
10
+ // Re-export factory functions
11
+ export { createRouter, createRouterFromConfig } from '@x12i/ai-providers-router';
12
+ // Re-export error classes
13
+ export { ProviderNotFoundError, FallbackExhaustedError } from '@x12i/ai-providers-router';
14
+ // Re-export all from router (includes everything it exports)
15
+ export * from '@x12i/ai-providers-router';
16
+ // Export enhanced gateway
17
+ export { AIGateway } from './gateway.js';
18
+ export { InstructionNotFoundError, InstructionBackendError } from './instruction-errors.js';
19
+ export { autoRegisterProviders } from './gateway-provider-auto-register.js';
20
+ export { mergeTemplateRenderOptions } from './template-render-merge.js';
21
+ // Usage tracking: UsageTracker class methods are available but consumption calculation is disabled
22
+ // (x-models was previously used for RPM/TPM tracking but is no longer integrated)
23
+ // Re-export activity tracking primitives (Activix)
24
+ export { Activix } from '@x12i/activix';
25
+ export { ActivityManager, ensureGatewayRequestIdentity } from './activity-manager.js';
26
+ // Re-export logging (@x12i/logxer)
27
+ export { createLogxer } from '@x12i/logxer';
28
+ // Runtime observability surface (leaf package: no downstream runtime objects)
29
+ export { runtimeObjects } from './runtime-objects.js';
30
+ // Export rate limiter
31
+ export { GatewayRateLimiter } from './gateway-rate-limiter.js';
32
+ export { DEFAULT_RATE_LIMIT_MIN_INTERVAL_MS, DEFAULT_RATE_LIMIT_ENABLED } from './gateway-rate-limiter-constants.js';
33
+ // Export troubleshooting helpers
34
+ export { validateAIRequest, validateJSON, extractJSON, validateResponse, diagnoseRequest, diagnoseResponse, supportsJSONMode, createTestAIRequest, createValidationTestCases, runValidationTests, formatDiagnostic, assertValidAIRequest } from './troubleshooting-helper.js';
35
+ // Export object types library
36
+ export { OBJECT_TYPES_LIBRARY, getObjectType, getObjectTypesForAgent } from './object-types-library.js';
37
+ // Re-export outputs library integration functions
38
+ export { initializeObjectTypesLibrary, getObjectTypesLibrary, resetObjectTypesLibrary } from './object-types-library-integration.js';
39
+ // Re-export outputs library types and utilities for convenience
40
+ // Note: Since we use dynamic imports for the outputs library, these types may not be available
41
+ // at compile time if the package isn't installed. Users can import directly from
42
+ // @x12i/outputs-library if they need these types or utilities.
43
+ //
44
+ // Recommended: Import types and utilities directly from @x12i/outputs-library:
45
+ // import type { ClassificationOutput } from '@x12i/outputs-library/types';
46
+ // import { ResponseParser } from '@x12i/outputs-library/parsers';
47
+ // import type { ObjectTypesLibrary, FlexMdSupport } from '@x12i/outputs-library';
48
+ //
49
+ // The gateway integrates with the outputs library internally via dynamic imports,
50
+ // so these re-exports are optional and mainly for convenience.
51
+ //
52
+ // For outputs-library v3.3.1+ with flex-md support:
53
+ // - ObjectTypesLibrary class with flex-md methods (getFlexMdTemplate, getFlexMdFormatSpec, etc.)
54
+ // - FlexMdSupport type for object type definitions
55
+ // - All flex-md methods are available on the library instance returned by getObjectTypesLibrary()
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Errors for instruction / prompt template and instructions-block resolution.
3
+ */
4
+ export declare class InstructionNotFoundError extends Error {
5
+ key: string;
6
+ backend: string;
7
+ originalKey: string;
8
+ constructor(key: string, backend: string, message: string, originalKey: string);
9
+ }
10
+ export declare class InstructionBackendError extends Error {
11
+ key: string;
12
+ backend: string;
13
+ isRetryable: boolean;
14
+ originalError?: Error | undefined;
15
+ constructor(key: string, backend: string, message: string, isRetryable: boolean, originalError?: Error | undefined);
16
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Errors for instruction / prompt template and instructions-block resolution.
3
+ */
4
+ export class InstructionNotFoundError extends Error {
5
+ key;
6
+ backend;
7
+ originalKey;
8
+ constructor(key, backend, message, originalKey) {
9
+ super(message);
10
+ this.key = key;
11
+ this.backend = backend;
12
+ this.originalKey = originalKey;
13
+ this.name = 'InstructionNotFoundError';
14
+ }
15
+ }
16
+ export class InstructionBackendError extends Error {
17
+ key;
18
+ backend;
19
+ isRetryable;
20
+ originalError;
21
+ constructor(key, backend, message, isRetryable, originalError) {
22
+ super(message);
23
+ this.key = key;
24
+ this.backend = backend;
25
+ this.isRetryable = isRetryable;
26
+ this.originalError = originalError;
27
+ this.name = 'InstructionBackendError';
28
+ }
29
+ }