@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,558 @@
1
+ "use strict";
2
+ /**
3
+ * Message Builder
4
+ * Direct message construction without request-builder package dependency
5
+ * Handles flex-md format exclusively
6
+ */
7
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ var desc = Object.getOwnPropertyDescriptor(m, k);
10
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
+ desc = { enumerable: true, get: function() { return m[k]; } };
12
+ }
13
+ Object.defineProperty(o, k2, desc);
14
+ }) : (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ o[k2] = m[k];
17
+ }));
18
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
20
+ }) : function(o, v) {
21
+ o["default"] = v;
22
+ });
23
+ var __importStar = (this && this.__importStar) || (function () {
24
+ var ownKeys = function(o) {
25
+ ownKeys = Object.getOwnPropertyNames || function (o) {
26
+ var ar = [];
27
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28
+ return ar;
29
+ };
30
+ return ownKeys(o);
31
+ };
32
+ return function (mod) {
33
+ if (mod && mod.__esModule) return mod;
34
+ var result = {};
35
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36
+ __setModuleDefault(result, mod);
37
+ return result;
38
+ };
39
+ })();
40
+ Object.defineProperty(exports, "__esModule", { value: true });
41
+ exports.buildMessages = buildMessages;
42
+ const template_parser_js_1 = require("./template-parser.cjs");
43
+ const template_render_merge_js_1 = require("./template-render-merge.cjs");
44
+ const gateway_instructions_js_1 = require("./gateway-instructions.cjs");
45
+ // Type guard
46
+ // AIRequest is distinguished by having primaryObjectType or objectTypes
47
+ // ChatRequest does not have these fields
48
+ function isAIRequest(request) {
49
+ return 'primaryObjectType' in request || ('objectTypes' in request && Array.isArray(request.objectTypes));
50
+ }
51
+ /**
52
+ * Builds input recognition rules
53
+ */
54
+ async function buildInputRecognitionRules(request, config, options) {
55
+ const { defaultInstructionsBlocks, instructionsBlockOverrides, logger } = config;
56
+ if (!options.includeInputRecognition || !isAIRequest(request)) {
57
+ return '';
58
+ }
59
+ const rules = [];
60
+ // Add input recognition rules
61
+ // Try direct access first (faster, more reliable), then fallback to resolver
62
+ const rulePaths = [
63
+ 'input.inputRecognitionRule',
64
+ 'input.emptyInputHandling',
65
+ 'input.testInputHandling',
66
+ 'input.inputLocationClarifier'
67
+ ];
68
+ const requestInstructionsBlocks = isAIRequest(request) && request.config?.instructionsBlocks
69
+ ? request.config.instructionsBlocks
70
+ : undefined;
71
+ const blockContext = {
72
+ defaultInstructionsBlocks,
73
+ instructionsBlockOverrides,
74
+ requestInstructionsBlocks,
75
+ config: {},
76
+ logger
77
+ };
78
+ for (const rulePath of rulePaths) {
79
+ try {
80
+ // Try direct access to nested structure first
81
+ const pathParts = rulePath.split('.');
82
+ let rule;
83
+ if (pathParts.length === 2) {
84
+ const [parent, child] = pathParts;
85
+ const parentObj = defaultInstructionsBlocks[parent];
86
+ if (parentObj && typeof parentObj === 'object' && !Array.isArray(parentObj)) {
87
+ rule = parentObj[child];
88
+ if (rule && typeof rule === 'string') {
89
+ logger.debug('Resolved rule via direct access', {
90
+ rulePath,
91
+ valueLength: rule.length
92
+ });
93
+ }
94
+ }
95
+ }
96
+ // If direct access didn't work, try merged inline overrides / nested defaults
97
+ if (!rule) {
98
+ rule = await (0, gateway_instructions_js_1.resolveNestedInstructionsBlock)(rulePath, request.agentId || '', request.taskTypeId, blockContext);
99
+ }
100
+ if (rule && typeof rule === 'string' && rule.trim() !== '') {
101
+ rules.push(rule);
102
+ }
103
+ }
104
+ catch (error) {
105
+ logger.debug('Failed to resolve input rule', {
106
+ rulePath,
107
+ error: error instanceof Error ? error.message : String(error)
108
+ });
109
+ }
110
+ }
111
+ return rules.join('\n\n');
112
+ }
113
+ /**
114
+ * Builds reinforcement rules
115
+ */
116
+ async function buildReinforcementRules(request, config, options) {
117
+ const { defaultInstructionsBlocks, instructionsBlockOverrides, logger } = config;
118
+ if (!options.includeReinforcement || !isAIRequest(request)) {
119
+ return '';
120
+ }
121
+ const rules = [];
122
+ // Add reinforcement rules
123
+ // Try direct access first (faster, more reliable), then fallback to resolver
124
+ const rulePaths = [
125
+ 'reinforcement.emptyIsSuccess',
126
+ 'reinforcement.inputAlreadyProvided',
127
+ 'reinforcement.noConversation',
128
+ 'reinforcement.failureIndicators'
129
+ ];
130
+ const requestInstructionsBlocks = isAIRequest(request) && request.config?.instructionsBlocks
131
+ ? request.config.instructionsBlocks
132
+ : undefined;
133
+ const blockContext = {
134
+ defaultInstructionsBlocks,
135
+ instructionsBlockOverrides,
136
+ requestInstructionsBlocks,
137
+ config: {},
138
+ logger
139
+ };
140
+ for (const rulePath of rulePaths) {
141
+ try {
142
+ // Try direct access to nested structure first
143
+ const pathParts = rulePath.split('.');
144
+ let rule;
145
+ if (pathParts.length === 2) {
146
+ const [parent, child] = pathParts;
147
+ const parentObj = defaultInstructionsBlocks[parent];
148
+ if (parentObj && typeof parentObj === 'object' && !Array.isArray(parentObj)) {
149
+ rule = parentObj[child];
150
+ if (rule && typeof rule === 'string') {
151
+ logger.debug('Resolved rule via direct access', {
152
+ rulePath,
153
+ valueLength: rule.length
154
+ });
155
+ }
156
+ }
157
+ }
158
+ // If direct access didn't work, try merged inline overrides / nested defaults
159
+ if (!rule) {
160
+ rule = await (0, gateway_instructions_js_1.resolveNestedInstructionsBlock)(rulePath, request.agentId || '', request.taskTypeId, blockContext);
161
+ }
162
+ if (rule && typeof rule === 'string' && rule.trim() !== '') {
163
+ rules.push(rule);
164
+ }
165
+ }
166
+ catch (error) {
167
+ logger.debug('Failed to resolve reinforcement rule', {
168
+ rulePath,
169
+ error: error instanceof Error ? error.message : String(error)
170
+ });
171
+ }
172
+ }
173
+ return rules.join('\n\n');
174
+ }
175
+ /**
176
+ * Builds user message (prompt + input)
177
+ */
178
+ async function buildUserMessage(request, config, shortTermMemory, experienceMemory, knowledgeMemory, templateRenderOptions) {
179
+ const { logger } = config;
180
+ const parts = [];
181
+ // Validate that input field is not provided (removed - use workingMemory.input instead)
182
+ if ('input' in request && request.input !== undefined) {
183
+ const err = new Error(`The 'input' field has been removed. Use workingMemory.input instead for template rendering. Prompt templates should contain {{input}} which will be resolved from workingMemory.input.`);
184
+ err.code = 'INPUT_FIELD_DEPRECATED';
185
+ err.details = {
186
+ field: 'input',
187
+ alternative: 'workingMemory.input',
188
+ message: 'Input data must be provided via workingMemory.input for template rendering'
189
+ };
190
+ logger.error('Input field provided but has been removed', {
191
+ jobId: request.jobId,
192
+ agentId: request.agentId,
193
+ errorCode: 'INPUT_FIELD_DEPRECATED',
194
+ hasPrompt: !!request.prompt,
195
+ hasWorkingMemory: !!request.workingMemory,
196
+ hasInputInWorkingMemory: !!request.workingMemory?.input
197
+ });
198
+ throw err;
199
+ }
200
+ // Determine if we have user content to process (prompt is required for user message)
201
+ const hasUserContent = isAIRequest(request) && request.prompt;
202
+ // Input prefix is no longer used - prompt templates handle all formatting
203
+ // If no prompt is provided, that's an error (prompt is required for user message)
204
+ if (isAIRequest(request) && !request.prompt) {
205
+ const err = new Error(`Prompt is required for AI requests. Provide prompt template text. The template should contain variables such as {{input}} resolved from workingMemory.input.`);
206
+ err.code = 'PROMPT_REQUIRED';
207
+ err.details = {
208
+ missingField: 'prompt',
209
+ hasWorkingMemory: !!request.workingMemory,
210
+ hasInputInWorkingMemory: !!request.workingMemory?.input
211
+ };
212
+ logger.error('Prompt is required for AI requests', {
213
+ jobId: request.jobId,
214
+ agentId: request.agentId,
215
+ errorCode: 'PROMPT_REQUIRED'
216
+ });
217
+ throw err;
218
+ }
219
+ // Add prompt if provided (always template text; parsed with memory context)
220
+ if (request.prompt) {
221
+ if (typeof request.prompt === 'string') {
222
+ logger.info('Parsing prompt template text', {
223
+ jobId: request.jobId,
224
+ agentId: request.agentId,
225
+ promptLength: request.prompt.length,
226
+ promptPreview: request.prompt.substring(0, 200),
227
+ hasWorkingMemory: !!request.workingMemory
228
+ });
229
+ try {
230
+ if (!request.workingMemory) {
231
+ const err = new Error(`workingMemory is required for prompt template rendering but was not provided.`);
232
+ err.code = 'WORKING_MEMORY_REQUIRED';
233
+ err.details = { requiresVariables: true };
234
+ logger.error('workingMemory required for prompt template rendering', {
235
+ jobId: request.jobId,
236
+ agentId: request.agentId,
237
+ errorCode: 'WORKING_MEMORY_REQUIRED'
238
+ });
239
+ throw err;
240
+ }
241
+ const parsedPrompt = await (0, template_parser_js_1.parseTemplate)(request.prompt, request.workingMemory, undefined, shortTermMemory, experienceMemory, knowledgeMemory, templateRenderOptions);
242
+ if (!parsedPrompt || parsedPrompt.trim() === '') {
243
+ const workingMemoryObj = request.workingMemory;
244
+ const err = new Error(`Prompt template rendered to empty string. This may indicate missing template variables or empty template content.`);
245
+ err.code = 'PROMPT_RENDERED_EMPTY';
246
+ err.details = {
247
+ promptLength: request.prompt.length,
248
+ renderedLength: 0,
249
+ hasWorkingMemory: !!request.workingMemory,
250
+ workingMemoryKeys: workingMemoryObj ? Object.keys(workingMemoryObj) : []
251
+ };
252
+ logger.error('Prompt template rendered to empty string', {
253
+ jobId: request.jobId,
254
+ agentId: request.agentId,
255
+ errorCode: 'PROMPT_RENDERED_EMPTY',
256
+ hasWorkingMemory: !!request.workingMemory,
257
+ workingMemoryKeys: workingMemoryObj ? Object.keys(workingMemoryObj) : []
258
+ });
259
+ throw err;
260
+ }
261
+ logger.info('Prompt text parsed successfully', {
262
+ jobId: request.jobId,
263
+ agentId: request.agentId,
264
+ originalLength: request.prompt.length,
265
+ parsedLength: parsedPrompt.length,
266
+ parsedPreview: parsedPrompt.substring(0, 200)
267
+ });
268
+ parts.push(parsedPrompt);
269
+ }
270
+ catch (error) {
271
+ const err = error instanceof Error ? error : new Error(String(error));
272
+ let errorCode = 'PROMPT_TEMPLATE_ERROR';
273
+ let errorMessage = `Failed to render prompt template: ${err.message}`;
274
+ if (err.message.includes('not found') || err.message.includes('does not exist')) {
275
+ errorCode = 'PROMPT_NOT_FOUND';
276
+ errorMessage = err.message;
277
+ }
278
+ else if (err.message.includes('rendered to empty')) {
279
+ errorCode = 'PROMPT_RENDERED_EMPTY';
280
+ errorMessage = err.message;
281
+ }
282
+ else if (err.name === 'TemplateResolutionError') {
283
+ errorCode = 'TEMPLATE_RESOLUTION_ERROR';
284
+ errorMessage = err.message;
285
+ }
286
+ else if (err.message.includes('Template variable') || err.message.includes('missing')) {
287
+ errorCode = 'TEMPLATE_VARIABLE_MISSING';
288
+ errorMessage = err.message;
289
+ }
290
+ logger.error('Failed to render prompt template', {
291
+ jobId: request.jobId,
292
+ agentId: request.agentId,
293
+ errorCode,
294
+ error: err.message,
295
+ errorName: err.name,
296
+ errorStack: err.stack
297
+ });
298
+ const structuredError = new Error(errorMessage);
299
+ structuredError.code = errorCode;
300
+ structuredError.details = {
301
+ type: 'prompt',
302
+ originalError: err.message
303
+ };
304
+ throw structuredError;
305
+ }
306
+ }
307
+ else {
308
+ const err = new Error(`Prompt must be a string template, but received: ${typeof request.prompt}`);
309
+ logger.error('Prompt provided as non-string - not supported', {
310
+ jobId: request.jobId,
311
+ agentId: request.agentId,
312
+ promptType: typeof request.prompt
313
+ });
314
+ throw err;
315
+ }
316
+ }
317
+ // Input field has been removed - all input must come from workingMemory.input
318
+ // Prompt templates should contain {{input}} which will be resolved from workingMemory.input
319
+ // No need to add input separately - it's already in the rendered prompt template
320
+ const userMessage = parts.join('\n\n');
321
+ // If prompt was provided, we MUST have a non-empty user message
322
+ if (request.prompt && (!userMessage || userMessage.trim() === '')) {
323
+ const err = new Error(`Prompt template was provided but resulted in empty user message. The template may have rendered to empty or failed to resolve.`);
324
+ err.code = 'PROMPT_NO_USER_MESSAGE';
325
+ err.details = {
326
+ promptPreview: typeof request.prompt === 'string' ? request.prompt.substring(0, 200) : request.prompt,
327
+ hasWorkingMemory: !!request.workingMemory,
328
+ workingMemoryKeys: request.workingMemory ? Object.keys(request.workingMemory) : [],
329
+ partsLength: parts.length
330
+ };
331
+ logger.error('Prompt provided but resulted in empty user message', {
332
+ jobId: request.jobId,
333
+ agentId: request.agentId,
334
+ prompt: request.prompt,
335
+ errorCode: 'PROMPT_NO_USER_MESSAGE',
336
+ partsLength: parts.length,
337
+ parts: parts.map(p => ({ length: p.length, preview: p.substring(0, 50) }))
338
+ });
339
+ throw err;
340
+ }
341
+ return userMessage;
342
+ }
343
+ /**
344
+ * Checks if instructions already meet the required flex-md compliance level
345
+ * Uses flex-md SDK to validate compliance
346
+ *
347
+ * @param instructionsText - Instructions to check
348
+ * @param complianceLevel - Required compliance level (L0, L1, L2, L3)
349
+ * @returns true if instructions meet the compliance level
350
+ */
351
+ async function hasFlexMdContract(instructionsText, complianceLevel = 'L0') {
352
+ if (!instructionsText || instructionsText.trim() === '') {
353
+ return false;
354
+ }
355
+ try {
356
+ // Try to use flex-md SDK to validate compliance
357
+ const { loadFlexMd } = await Promise.resolve().then(() => __importStar(require('./flex-md-loader.cjs')));
358
+ const flexMd = await loadFlexMd();
359
+ // Check if validateMarkdownAgainstOfs is available
360
+ if (flexMd.validateMarkdownAgainstOfs && typeof flexMd.validateMarkdownAgainstOfs === 'function') {
361
+ try {
362
+ // Try to validate - this might require a spec, so we catch errors
363
+ const result = flexMd.validateMarkdownAgainstOfs(instructionsText, { strictness: complianceLevel });
364
+ // If validation passes, instructions meet compliance
365
+ if (result && result.valid !== false) {
366
+ return true;
367
+ }
368
+ }
369
+ catch (e) {
370
+ // Validation function might need more parameters, fall through to pattern matching
371
+ }
372
+ }
373
+ }
374
+ catch (error) {
375
+ // flex-md SDK not available or error - fall through to pattern matching
376
+ }
377
+ // Fallback: Pattern-based checking
378
+ const text = instructionsText.toLowerCase();
379
+ // Check for key flex-md enforcement phrases
380
+ const flexMdIndicators = [
381
+ 'markdown',
382
+ 'fenced block',
383
+ '```markdown',
384
+ '```json',
385
+ 'reply in markdown',
386
+ 'return your entire answer'
387
+ ];
388
+ // Check for enforcement language based on compliance level
389
+ const enforcementIndicators = [];
390
+ if (complianceLevel === 'L2' || complianceLevel === 'L3') {
391
+ // L2/L3 require fenced block container
392
+ enforcementIndicators.push('fenced block', '```markdown', 'single ```markdown', 'entire answer inside', 'nothing else');
393
+ }
394
+ if (complianceLevel === 'L1' || complianceLevel === 'L2' || complianceLevel === 'L3') {
395
+ // L1+ requires section headings
396
+ enforcementIndicators.push('section', 'heading', 'include these');
397
+ }
398
+ // Must have at least one flex-md indicator AND appropriate enforcement indicators
399
+ const hasFlexMd = flexMdIndicators.some(indicator => text.includes(indicator));
400
+ const hasEnforcement = enforcementIndicators.length === 0 ||
401
+ enforcementIndicators.some(indicator => text.includes(indicator));
402
+ return hasFlexMd && hasEnforcement;
403
+ }
404
+ /**
405
+ * Main function to build messages
406
+ */
407
+ async function buildMessages(request, config, options = {}) {
408
+ const { useSystemContextFallback = true, includeInputRecognition = true, includeReinforcement = true, parsedSnapshot } = options;
409
+ const { logger } = config;
410
+ const messages = [];
411
+ let usingSystemContext = false;
412
+ // Step 1: Instructions as template text (parsed with full memory context)
413
+ let instructionsText = '';
414
+ // Extract memory context from options
415
+ const shortTermMemory = options.shortTermMemory;
416
+ const experienceMemory = options.experienceMemory;
417
+ const knowledgeMemory = options.knowledgeMemory;
418
+ const templateRenderOptions = (0, template_render_merge_js_1.mergeTemplateRenderOptions)(config.templateRendering, request.templateRenderOptions);
419
+ if (request.instructions) {
420
+ if (typeof request.instructions === 'string') {
421
+ logger.info('Using instructions as template text', {
422
+ jobId: request.jobId,
423
+ agentId: request.agentId,
424
+ instructionsLength: request.instructions.length,
425
+ instructionsPreview: request.instructions.substring(0, 200)
426
+ });
427
+ instructionsText = request.instructions;
428
+ }
429
+ else {
430
+ instructionsText = JSON.stringify(request.instructions);
431
+ }
432
+ }
433
+ // NO SYSTEM CONTEXT FALLBACK - removed default instruction fallback
434
+ // Instructions must be provided explicitly - no defaults allowed
435
+ // If instructionsText is empty here, it's a bad request
436
+ // Step 2: Parse instructions template with full memory context
437
+ // Rendrix handles token resolution, so we just parse directly
438
+ if (instructionsText) {
439
+ instructionsText = await (0, template_parser_js_1.parseTemplate)(instructionsText, request.workingMemory, undefined, // taskConfig removed - no longer used
440
+ shortTermMemory, experienceMemory, knowledgeMemory, templateRenderOptions);
441
+ }
442
+ // Step 4: Add input recognition rules
443
+ const inputRules = await buildInputRecognitionRules(request, config, options);
444
+ if (inputRules) {
445
+ instructionsText = `${instructionsText}\n\n${inputRules}`;
446
+ }
447
+ // Step 5: Add reinforcement rules
448
+ const reinforcementRules = await buildReinforcementRules(request, config, options);
449
+ if (reinforcementRules) {
450
+ instructionsText = `${instructionsText}\n\n${reinforcementRules}`;
451
+ }
452
+ // Step 6: Add system message
453
+ // CRITICAL: We must have instructions - this is a bad request if we don't
454
+ if (!instructionsText || instructionsText.trim() === '') {
455
+ const errorMessage = 'No instructions available - cannot proceed without clear instructions. This is a bad request.';
456
+ logger.error(errorMessage, {
457
+ jobId: request.jobId,
458
+ agentId: request.agentId,
459
+ hasRequestInstructions: !!request.instructions,
460
+ instructionType: typeof request.instructions,
461
+ usedSystemContextFallback: usingSystemContext,
462
+ systemContextFallbackEnabled: useSystemContextFallback
463
+ });
464
+ throw new Error(errorMessage);
465
+ }
466
+ messages.push({
467
+ role: 'system',
468
+ content: instructionsText
469
+ });
470
+ // Store resolved/parsed content for activity (parsed = content after resolution + Rendrix, not the key)
471
+ if (parsedSnapshot) {
472
+ parsedSnapshot.instructions = instructionsText;
473
+ }
474
+ // Log the final system message for verification
475
+ logger.info('Final system message constructed', {
476
+ jobId: request.jobId,
477
+ agentId: request.agentId,
478
+ messageLength: instructionsText.length,
479
+ hasMarkdown: instructionsText.toLowerCase().includes('markdown'),
480
+ hasFencedBlock: instructionsText.includes('```markdown'),
481
+ hasJson: instructionsText.toLowerCase().includes('json'),
482
+ messagePreview: instructionsText.substring(0, 500),
483
+ fullMessage: instructionsText // Log full message for debugging
484
+ });
485
+ // Step 7: Add context (if provided) with full memory context
486
+ if (request.context) {
487
+ const contextText = typeof request.context === 'string' ? request.context : JSON.stringify(request.context);
488
+ const parsedContext = await (0, template_parser_js_1.parseTemplate)(contextText, request.workingMemory, undefined, // taskConfig removed - no longer used
489
+ shortTermMemory, experienceMemory, knowledgeMemory, templateRenderOptions);
490
+ if (parsedContext && parsedContext.trim() !== '') {
491
+ messages.push({
492
+ role: 'assistant',
493
+ content: parsedContext
494
+ });
495
+ }
496
+ }
497
+ // Step 8: Build user message with full memory context
498
+ const userMessage = await buildUserMessage(request, config, shortTermMemory, experienceMemory, knowledgeMemory, templateRenderOptions);
499
+ if (userMessage && userMessage.trim() !== '') {
500
+ messages.push({
501
+ role: 'user',
502
+ content: userMessage
503
+ });
504
+ // Store resolved/parsed prompt for activity (parsed = content after resolution + Rendrix, not the key)
505
+ if (parsedSnapshot) {
506
+ parsedSnapshot.prompt = userMessage;
507
+ }
508
+ // Log the user message for verification
509
+ logger.info('Final user message constructed', {
510
+ jobId: request.jobId,
511
+ agentId: request.agentId,
512
+ messageLength: userMessage.length,
513
+ messagePreview: userMessage.substring(0, 200),
514
+ fullMessage: userMessage // Log full message for debugging
515
+ });
516
+ }
517
+ else {
518
+ // If prompt was provided, we MUST have a user message - this is an error
519
+ if (request.prompt) {
520
+ const err = new Error(`Prompt template was provided but no user message was created. The template may have rendered to empty or failed to resolve.`);
521
+ err.code = 'PROMPT_NO_USER_MESSAGE';
522
+ err.details = {
523
+ promptPreview: typeof request.prompt === 'string' ? request.prompt.substring(0, 200) : request.prompt,
524
+ hasWorkingMemory: !!request.workingMemory
525
+ };
526
+ logger.error('Prompt provided but no user message created', {
527
+ jobId: request.jobId,
528
+ agentId: request.agentId,
529
+ prompt: request.prompt,
530
+ errorCode: 'PROMPT_NO_USER_MESSAGE'
531
+ });
532
+ throw err;
533
+ }
534
+ // If no prompt was provided, it's just a warning (input-only requests are valid)
535
+ logger.warn('No user message to add', {
536
+ jobId: request.jobId,
537
+ agentId: request.agentId,
538
+ hasPrompt: !!request.prompt
539
+ });
540
+ }
541
+ // Log complete message structure
542
+ logger.info('Complete message structure', {
543
+ jobId: request.jobId,
544
+ agentId: request.agentId,
545
+ totalMessages: messages.length,
546
+ systemMessages: messages.filter(m => m.role === 'system').length,
547
+ userMessages: messages.filter(m => m.role === 'user').length,
548
+ messageRoles: messages.map(m => m.role),
549
+ systemMessageLengths: messages.filter(m => m.role === 'system').map(m => m.content.length),
550
+ userMessageLengths: messages.filter(m => m.role === 'user').map(m => m.content.length)
551
+ });
552
+ return {
553
+ messages,
554
+ metadata: {
555
+ usingSystemContext
556
+ }
557
+ };
558
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Message Builder
3
+ * Direct message construction without request-builder package dependency
4
+ * Handles flex-md format exclusively
5
+ */
6
+ import type { ChatRequest, AIRequest } from './types.js';
7
+ import type { TemplateRenderOptions } from '@x12i/rendrix';
8
+ import type { Logxer } from '@x12i/logxer';
9
+ type Request = ChatRequest | AIRequest;
10
+ export interface MessageBuilderConfig {
11
+ defaultInstructionsBlocks: Record<string, any>;
12
+ /** Flat block overrides from gateway `instructionsBlocks` (merged at init). */
13
+ instructionsBlockOverrides: Record<string, string>;
14
+ logger: Logxer;
15
+ /** From packaged defaults + gateway `templateRendering`; merged per request with `templateRenderOptions`. */
16
+ templateRendering?: TemplateRenderOptions;
17
+ }
18
+ export interface BuildMessagesOptions {
19
+ useSystemContextFallback?: boolean;
20
+ includeInputRecognition?: boolean;
21
+ includeReinforcement?: boolean;
22
+ parsedSnapshot?: any;
23
+ shortTermMemory?: Record<string, any>;
24
+ experienceMemory?: Record<string, any>;
25
+ knowledgeMemory?: Record<string, any>;
26
+ }
27
+ export interface BuiltMessages {
28
+ messages: Array<{
29
+ role: string;
30
+ content: string;
31
+ }>;
32
+ metadata?: {
33
+ usingSystemContext?: boolean;
34
+ hasObjectTypes?: boolean;
35
+ };
36
+ }
37
+ /**
38
+ * Main function to build messages
39
+ */
40
+ export declare function buildMessages(request: Request, config: MessageBuilderConfig, options?: BuildMessagesOptions): Promise<BuiltMessages>;
41
+ export {};
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ /**
3
+ * Object Types Library Integration - REMOVED
4
+ *
5
+ * The @x12i/outputs-library dependency has been removed.
6
+ * This file now provides stub functions for backward compatibility.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.initializeObjectTypesLibrary = initializeObjectTypesLibrary;
10
+ exports.getObjectTypesLibrary = getObjectTypesLibrary;
11
+ exports.resetObjectTypesLibrary = resetObjectTypesLibrary;
12
+ /**
13
+ * Initialize ObjectTypesLibrary singleton - STUB
14
+ * Since ObjectTypesLibrary is removed, this function does nothing
15
+ */
16
+ async function initializeObjectTypesLibrary(config, logger) {
17
+ logger.info('ObjectTypesLibrary dependency removed - using simplified object type handling');
18
+ return null;
19
+ }
20
+ /**
21
+ * Get the current ObjectTypesLibrary instance - STUB
22
+ * Always returns null since the library is removed
23
+ */
24
+ function getObjectTypesLibrary() {
25
+ return null;
26
+ }
27
+ /**
28
+ * Reset the library instance (for testing) - STUB
29
+ */
30
+ function resetObjectTypesLibrary() {
31
+ // Nothing to reset since library is removed
32
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Object Types Library Integration - REMOVED
3
+ *
4
+ * The @x12i/outputs-library dependency has been removed.
5
+ * This file now provides stub functions for backward compatibility.
6
+ */
7
+ import type { GatewayConfig } from './types.js';
8
+ import type { Logxer } from '@x12i/logxer';
9
+ /**
10
+ * Initialize ObjectTypesLibrary singleton - STUB
11
+ * Since ObjectTypesLibrary is removed, this function does nothing
12
+ */
13
+ export declare function initializeObjectTypesLibrary(config: GatewayConfig, logger: Logxer): Promise<any>;
14
+ /**
15
+ * Get the current ObjectTypesLibrary instance - STUB
16
+ * Always returns null since the library is removed
17
+ */
18
+ export declare function getObjectTypesLibrary(): any;
19
+ /**
20
+ * Reset the library instance (for testing) - STUB
21
+ */
22
+ export declare function resetObjectTypesLibrary(): void;