@x12i/ai-gateway 9.7.8 → 10.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/README.md +67 -12
  2. package/dist/defaults/log-diagnostics.json +0 -68
  3. package/dist/gateway-config.d.ts +1 -15
  4. package/dist/gateway-config.js +17 -134
  5. package/dist/gateway-defaults.d.ts +23 -0
  6. package/dist/gateway-defaults.js +29 -0
  7. package/dist/gateway-log-diagnostics.d.ts +0 -4
  8. package/dist/gateway-log-diagnostics.js +1 -5
  9. package/dist/gateway-log-levels.d.ts +0 -1
  10. package/dist/gateway-log-levels.js +0 -1
  11. package/dist/gateway-messages.js +0 -3
  12. package/dist/gateway-meta.js +12 -10
  13. package/dist/gateway-mode.d.ts +3 -26
  14. package/dist/gateway-mode.js +3 -48
  15. package/dist/gateway-retry.js +7 -6
  16. package/dist/gateway-utils.d.ts +1 -19
  17. package/dist/gateway-utils.js +37 -199
  18. package/dist/gateway.d.ts +0 -3
  19. package/dist/gateway.js +4 -63
  20. package/dist/index.d.ts +4 -6
  21. package/dist/index.js +4 -7
  22. package/dist/instruction-errors.d.ts +9 -1
  23. package/dist/instruction-errors.js +15 -1
  24. package/dist/instruction-optimizer.js +5 -1
  25. package/dist/message-builder.d.ts +0 -6
  26. package/dist/message-builder.js +4 -145
  27. package/dist/types.d.ts +16 -57
  28. package/dist-cjs/defaults/log-diagnostics.json +0 -68
  29. package/dist-cjs/gateway-config.cjs +17 -134
  30. package/dist-cjs/gateway-config.d.ts +1 -15
  31. package/dist-cjs/gateway-defaults.cjs +29 -0
  32. package/dist-cjs/gateway-defaults.d.ts +23 -0
  33. package/dist-cjs/gateway-log-diagnostics.cjs +1 -5
  34. package/dist-cjs/gateway-log-diagnostics.d.ts +0 -4
  35. package/dist-cjs/gateway-log-levels.cjs +0 -1
  36. package/dist-cjs/gateway-log-levels.d.ts +0 -1
  37. package/dist-cjs/gateway-messages.cjs +0 -3
  38. package/dist-cjs/gateway-meta.cjs +12 -10
  39. package/dist-cjs/gateway-mode.cjs +3 -48
  40. package/dist-cjs/gateway-mode.d.ts +3 -26
  41. package/dist-cjs/gateway-retry.cjs +7 -6
  42. package/dist-cjs/gateway-utils.cjs +37 -199
  43. package/dist-cjs/gateway-utils.d.ts +1 -19
  44. package/dist-cjs/gateway.cjs +4 -63
  45. package/dist-cjs/gateway.d.ts +0 -3
  46. package/dist-cjs/index.cjs +4 -7
  47. package/dist-cjs/index.d.ts +4 -6
  48. package/dist-cjs/instruction-errors.cjs +15 -1
  49. package/dist-cjs/instruction-errors.d.ts +9 -1
  50. package/dist-cjs/instruction-optimizer.cjs +5 -1
  51. package/dist-cjs/message-builder.cjs +4 -145
  52. package/dist-cjs/message-builder.d.ts +0 -6
  53. package/dist-cjs/types.d.ts +16 -57
  54. package/package.json +2 -3
  55. package/dist/defaults/instructions-blocks.json +0 -61
  56. package/dist/defaults/model-config.json +0 -15
  57. package/dist/gateway-instructions.d.ts +0 -30
  58. package/dist/gateway-instructions.js +0 -62
  59. package/dist/gateway-rate-limiter-constants.d.ts +0 -16
  60. package/dist/gateway-rate-limiter-constants.js +0 -16
  61. package/dist/gateway-rate-limiter.d.ts +0 -56
  62. package/dist/gateway-rate-limiter.js +0 -107
  63. package/dist/optimixer-manager.d.ts +0 -33
  64. package/dist/optimixer-manager.js +0 -142
  65. package/dist/token-estimate.d.ts +0 -12
  66. package/dist/token-estimate.js +0 -30
  67. package/dist-cjs/defaults/instructions-blocks.json +0 -61
  68. package/dist-cjs/defaults/model-config.json +0 -15
  69. package/dist-cjs/gateway-instructions.cjs +0 -62
  70. package/dist-cjs/gateway-instructions.d.ts +0 -30
  71. package/dist-cjs/gateway-rate-limiter-constants.cjs +0 -16
  72. package/dist-cjs/gateway-rate-limiter-constants.d.ts +0 -16
  73. package/dist-cjs/gateway-rate-limiter.cjs +0 -107
  74. package/dist-cjs/gateway-rate-limiter.d.ts +0 -56
  75. package/dist-cjs/optimixer-manager.cjs +0 -142
  76. package/dist-cjs/optimixer-manager.d.ts +0 -33
  77. package/dist-cjs/token-estimate.cjs +0 -30
  78. package/dist-cjs/token-estimate.d.ts +0 -12
@@ -4,6 +4,7 @@
4
4
  * Uses AI to analyze and fix poorly-written instructions.
5
5
  * This is a meta-feature that uses the AI Gateway (via router) to improve AI instructions.
6
6
  */
7
+ import { MaxTokensRequiredError } from './instruction-errors.js';
7
8
  /**
8
9
  * The meta-instructions used to fix other instructions
9
10
  * Loaded from instructions-audit.md
@@ -128,6 +129,9 @@ export async function optimizeInstructions(gateway, originalInstructions, option
128
129
  if (enforceJsonOutput) {
129
130
  additionalContext += '\n\nIMPORTANT: The fixed instructions MUST include strict JSON-only output enforcement rules.';
130
131
  }
132
+ if (typeof internalConfig?.maxTokens !== 'number' || internalConfig.maxTokens <= 0) {
133
+ throw new MaxTokensRequiredError('maxTokens must be set in internalSystemActions.instructionOptimization for optimizeInstructions');
134
+ }
131
135
  const aiRequestId = `optimize-instructions-${Date.now()}`;
132
136
  const identity = {
133
137
  ...options.identity,
@@ -149,7 +153,7 @@ export async function optimizeInstructions(gateway, originalInstructions, option
149
153
  model,
150
154
  provider,
151
155
  temperature: internalConfig?.temperature ?? 0.3, // Use internal config or default
152
- maxTokens: internalConfig?.maxTokens ?? 4000 // Use internal config or default
156
+ maxTokens: internalConfig?.maxTokens
153
157
  },
154
158
  // Use JSON output type to ensure we get structured response
155
159
  primaryObjectType: {
@@ -5,137 +5,12 @@
5
5
  */
6
6
  import { parseTemplate } from './template-parser.js';
7
7
  import { mergeGatewayAndRequestTemplateRenderOptions } from './template-render-merge.js';
8
- import { resolveNestedInstructionsBlock } from './gateway-instructions.js';
9
8
  // Type guard
10
9
  // AIRequest is distinguished by having primaryObjectType or objectTypes
11
10
  // ChatRequest does not have these fields
12
11
  function isAIRequest(request) {
13
12
  return 'primaryObjectType' in request || ('objectTypes' in request && Array.isArray(request.objectTypes));
14
13
  }
15
- /**
16
- * Builds input recognition rules
17
- */
18
- async function buildInputRecognitionRules(request, config, options) {
19
- const { defaultInstructionsBlocks, instructionsBlockOverrides, logger } = config;
20
- if (!options.includeInputRecognition || !isAIRequest(request)) {
21
- return '';
22
- }
23
- const rules = [];
24
- // Add input recognition rules
25
- // Try direct access first (faster, more reliable), then fallback to resolver
26
- const rulePaths = [
27
- 'input.inputRecognitionRule',
28
- 'input.emptyInputHandling',
29
- 'input.testInputHandling',
30
- 'input.inputLocationClarifier'
31
- ];
32
- const requestInstructionsBlocks = isAIRequest(request) && request.config?.instructionsBlocks
33
- ? request.config.instructionsBlocks
34
- : undefined;
35
- const blockContext = {
36
- defaultInstructionsBlocks,
37
- instructionsBlockOverrides,
38
- requestInstructionsBlocks,
39
- config: {},
40
- logger
41
- };
42
- for (const rulePath of rulePaths) {
43
- try {
44
- // Try direct access to nested structure first
45
- const pathParts = rulePath.split('.');
46
- let rule;
47
- if (pathParts.length === 2) {
48
- const [parent, child] = pathParts;
49
- const parentObj = defaultInstructionsBlocks[parent];
50
- if (parentObj && typeof parentObj === 'object' && !Array.isArray(parentObj)) {
51
- rule = parentObj[child];
52
- if (rule && typeof rule === 'string') {
53
- logger.debug('Resolved rule via direct access', {
54
- rulePath,
55
- valueLength: rule.length
56
- });
57
- }
58
- }
59
- }
60
- // If direct access didn't work, try merged inline overrides / nested defaults
61
- if (!rule) {
62
- rule = await resolveNestedInstructionsBlock(rulePath, request.agentId || '', request.taskTypeId, blockContext);
63
- }
64
- if (rule && typeof rule === 'string' && rule.trim() !== '') {
65
- rules.push(rule);
66
- }
67
- }
68
- catch (error) {
69
- logger.debug('Failed to resolve input rule', {
70
- rulePath,
71
- error: error instanceof Error ? error.message : String(error)
72
- });
73
- }
74
- }
75
- return rules.join('\n\n');
76
- }
77
- /**
78
- * Builds reinforcement rules
79
- */
80
- async function buildReinforcementRules(request, config, options) {
81
- const { defaultInstructionsBlocks, instructionsBlockOverrides, logger } = config;
82
- if (!options.includeReinforcement || !isAIRequest(request)) {
83
- return '';
84
- }
85
- const rules = [];
86
- // Add reinforcement rules
87
- // Try direct access first (faster, more reliable), then fallback to resolver
88
- const rulePaths = [
89
- 'reinforcement.emptyIsSuccess',
90
- 'reinforcement.inputAlreadyProvided',
91
- 'reinforcement.noConversation',
92
- 'reinforcement.failureIndicators'
93
- ];
94
- const requestInstructionsBlocks = isAIRequest(request) && request.config?.instructionsBlocks
95
- ? request.config.instructionsBlocks
96
- : undefined;
97
- const blockContext = {
98
- defaultInstructionsBlocks,
99
- instructionsBlockOverrides,
100
- requestInstructionsBlocks,
101
- config: {},
102
- logger
103
- };
104
- for (const rulePath of rulePaths) {
105
- try {
106
- // Try direct access to nested structure first
107
- const pathParts = rulePath.split('.');
108
- let rule;
109
- if (pathParts.length === 2) {
110
- const [parent, child] = pathParts;
111
- const parentObj = defaultInstructionsBlocks[parent];
112
- if (parentObj && typeof parentObj === 'object' && !Array.isArray(parentObj)) {
113
- rule = parentObj[child];
114
- if (rule && typeof rule === 'string') {
115
- logger.debug('Resolved rule via direct access', {
116
- rulePath,
117
- valueLength: rule.length
118
- });
119
- }
120
- }
121
- }
122
- // If direct access didn't work, try merged inline overrides / nested defaults
123
- if (!rule) {
124
- rule = await resolveNestedInstructionsBlock(rulePath, request.agentId || '', request.taskTypeId, blockContext);
125
- }
126
- if (rule && typeof rule === 'string' && rule.trim() !== '') {
127
- rules.push(rule);
128
- }
129
- }
130
- catch (error) {
131
- logger.debug('Failed to resolve reinforcement rule', {
132
- rulePath,
133
- error: error instanceof Error ? error.message : String(error)
134
- });
135
- }
136
- }
137
- return rules.join('\n\n');
138
- }
139
14
  /**
140
15
  * Builds user message (prompt + input)
141
16
  */
@@ -369,10 +244,9 @@ async function hasFlexMdContract(instructionsText, complianceLevel = 'L0') {
369
244
  * Main function to build messages
370
245
  */
371
246
  export async function buildMessages(request, config, options = {}) {
372
- const { useSystemContextFallback = true, includeInputRecognition = true, includeReinforcement = true, parsedSnapshot } = options;
247
+ const { parsedSnapshot } = options;
373
248
  const { logger } = config;
374
249
  const messages = [];
375
- let usingSystemContext = false;
376
250
  // Step 1: Instructions as template text (parsed with full memory context)
377
251
  let instructionsText = '';
378
252
  // Extract memory context from options
@@ -403,27 +277,14 @@ export async function buildMessages(request, config, options = {}) {
403
277
  instructionsText = await parseTemplate(instructionsText, request.workingMemory, undefined, // taskConfig removed - no longer used
404
278
  shortTermMemory, experienceMemory, knowledgeMemory, templateRenderOptions, logger);
405
279
  }
406
- // Step 4: Add input recognition rules
407
- const inputRules = await buildInputRecognitionRules(request, config, options);
408
- if (inputRules) {
409
- instructionsText = `${instructionsText}\n\n${inputRules}`;
410
- }
411
- // Step 5: Add reinforcement rules
412
- const reinforcementRules = await buildReinforcementRules(request, config, options);
413
- if (reinforcementRules) {
414
- instructionsText = `${instructionsText}\n\n${reinforcementRules}`;
415
- }
416
- // Step 6: Add system message
417
- // CRITICAL: We must have instructions - this is a bad request if we don't
280
+ // Instructions must be provided explicitly — no packaged block injection
418
281
  if (!instructionsText || instructionsText.trim() === '') {
419
282
  const errorMessage = 'No instructions available - cannot proceed without clear instructions. This is a bad request.';
420
283
  logger.error(errorMessage, {
421
284
  jobId: request.identity.jobId,
422
285
  agentId: request.agentId,
423
286
  hasRequestInstructions: !!request.instructions,
424
- instructionType: typeof request.instructions,
425
- usedSystemContextFallback: usingSystemContext,
426
- systemContextFallbackEnabled: useSystemContextFallback
287
+ instructionType: typeof request.instructions
427
288
  });
428
289
  throw new Error(errorMessage);
429
290
  }
@@ -515,8 +376,6 @@ export async function buildMessages(request, config, options = {}) {
515
376
  });
516
377
  return {
517
378
  messages,
518
- metadata: {
519
- usingSystemContext
520
- }
379
+ metadata: {}
521
380
  };
522
381
  }
@@ -8,17 +8,11 @@ import type { TemplateRenderOptions } from '@x12i/rendrix';
8
8
  import type { Logxer } from '@x12i/logxer';
9
9
  type Request = ChatRequest | AIRequest;
10
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
11
  logger: Logxer;
15
12
  /** From packaged defaults + gateway `templateRendering`; merged per request with `templateRenderOptions`. */
16
13
  templateRendering?: TemplateRenderOptions;
17
14
  }
18
15
  export interface BuildMessagesOptions {
19
- useSystemContextFallback?: boolean;
20
- includeInputRecognition?: boolean;
21
- includeReinforcement?: boolean;
22
16
  parsedSnapshot?: any;
23
17
  shortTermMemory?: Record<string, any>;
24
18
  experienceMemory?: Record<string, any>;
@@ -398,9 +398,10 @@ export interface GatewayConfig extends Omit<RouterConfig, 'defaultEngine' | 'log
398
398
  prefer?: boolean;
399
399
  };
400
400
  /**
401
- * Operational mode override (`process.env.mode` / `MODE` when omitted).
402
- * - `prod`: unresolved models fall back to {@link AI_GATEWAY_DEFAULT_MODEL} / packaged default (with Logxer warn).
403
- * - `dev` / `debug`: unresolved models throw {@link ModelResolutionError} from `@x12i/ai-tools`.
401
+ * Operational mode override (`process.env.mode` / `MODE` when omitted; default `debug`).
402
+ * Downstream hosts (ai-skills, ai-tasks, graph-engine) should expose this to their clients.
403
+ * - `dev` / `debug`: unresolved profile/model names throw {@link ModelResolutionError} from `@x12i/ai-tools` when catalog resolution is enabled.
404
+ * - `prod`: same strict resolution — every invoke must include an explicit `model`; the gateway never substitutes a packaged or env default.
404
405
  */
405
406
  mode?: 'dev' | 'debug' | 'prod';
406
407
  /**
@@ -421,70 +422,24 @@ export interface GatewayConfig extends Omit<RouterConfig, 'defaultEngine' | 'log
421
422
  costIncludeBreakdown?: boolean;
422
423
  };
423
424
  /**
424
- * Adaptive `max_tokens` via @x12i/optimixer (embedded Activix mode).
425
- * When enabled, the gateway predicts completion budget before each LLM call unless
426
- * the caller explicitly sets `maxTokens` on the request / modelConfig / gateway config.
427
- */
428
- optimixer?: {
429
- /** @default false */
430
- enabled?: boolean;
431
- acceptableRisk?: 'very-low' | 'low' | 'medium' | 'high' | number;
432
- /** Cap predicted max tokens with flex-md model limit when available. @default true */
433
- useFlexMdCeiling?: boolean;
434
- /** Passed to Optimixer warmup on create. */
435
- warmupLimit?: number;
436
- };
437
- /**
438
- * InstructionsBlocks overrides
439
- * Key: block name, Value: block content
440
- */
441
- instructionsBlocks?: Record<string, string>;
442
- /**
443
- * Default temperature for LLM requests
425
+ * Default temperature for LLM requests when not set on the invoke request.
426
+ * @default 0.7 see {@link GATEWAY_DEFAULT_TEMPERATURE} in `@x12i/ai-gateway`.
444
427
  */
445
428
  temperature?: number;
446
429
  /**
447
- * Other LLM config options
430
+ * Gateway-wide completion budget. Merged when the invoke does not set `maxTokens` on
431
+ * `request.config` / `modelConfig` (lower priority than per-request values).
432
+ * Every invoke must end up with a positive `maxTokens` after merge — no code default.
448
433
  */
449
434
  maxTokens?: number;
450
435
  topP?: number;
451
436
  frequencyPenalty?: number;
452
437
  presencePenalty?: number;
453
438
  /**
454
- * Retry configuration for network and server errors
439
+ * Retry configuration for network and server errors on provider invoke.
440
+ * Defaults: {@link GATEWAY_DEFAULT_RETRY}. Override per request via `request.retry` or `request.config.retry`.
455
441
  */
456
442
  retry?: RetryConfig;
457
- /**
458
- * Rate limiting configuration
459
- * Smart rate limiting that tracks when the last API call was made
460
- * and only waits if necessary to maintain minimum intervals between calls.
461
- * Applied automatically to all provider calls via router interceptors.
462
- */
463
- rateLimit?: {
464
- /**
465
- * Enable rate limiting
466
- * @default true
467
- */
468
- enabled?: boolean;
469
- /**
470
- * Default minimum interval in milliseconds between API calls (used if provider-specific not set)
471
- * @default 500
472
- */
473
- defaultMinIntervalMs?: number;
474
- /**
475
- * Per-provider minimum intervals in milliseconds
476
- * Key: provider name (e.g., 'openai', 'grok')
477
- * Value: minimum milliseconds between calls for that provider
478
- *
479
- * @example
480
- * {
481
- * openai: 500, // 500ms between OpenAI calls
482
- * grok: 1000, // 1 second between Grok calls
483
- * anthropic: 300 // 300ms between Anthropic calls
484
- * }
485
- */
486
- providerIntervals?: Record<string, number>;
487
- };
488
443
  /**
489
444
  * Default task configuration for template rendering
490
445
  * @deprecated taskConfig is no longer used by Rendrix 3.0.0+
@@ -744,6 +699,10 @@ interface BaseLLMRequest extends Omit<LLMRequest, 'messages' | 'input' | 'reques
744
699
  * Merged the same way as `smartInput`; `templateRenderOptions.smartInputRenderOptions` wins when both are set.
745
700
  */
746
701
  smartInputRenderOptions?: SmartInputRenderOptions;
702
+ /**
703
+ * Per-request retry overrides (merged over gateway `retry` and {@link GATEWAY_DEFAULT_RETRY}).
704
+ */
705
+ retry?: RetryConfig;
747
706
  /**
748
707
  * Messages array - Optional, can be used instead of instructions/prompt
749
708
  * If provided, will be appended as-is after built messages; instructions template text is still parsed for the system message when present
@@ -1089,7 +1048,7 @@ export interface EnhancedLLMResponse<TContent = unknown> extends Omit<AIResponse
1089
1048
  usage?: GatewayTraceUsageSummary;
1090
1049
  /**
1091
1050
  * Merged gateway/router generation config actually used for the invocation (after
1092
- * {@link mergeConfig}: modelConfig / request.config / defaults / flex-md maxTokens).
1051
+ * {@link mergeConfig}: modelConfig / request.config / gateway maxTokens).
1093
1052
  * Only populated when diagnostics trace mode is enabled.
1094
1053
  */
1095
1054
  mergedRouterConfig?: GatewayTraceMergedConfig;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@x12i/ai-gateway",
3
- "version": "9.7.8",
3
+ "version": "10.0.0",
4
4
  "description": "AI Gateway - Unified interface for LLM provider routing and management",
5
5
  "type": "module",
6
6
  "exports": {
@@ -43,10 +43,9 @@
43
43
  "dependencies": {
44
44
  "@x12i/activix": "^8.5.0",
45
45
  "@x12i/ai-providers-router": "^4.9.2",
46
- "@x12i/ai-tools": "^2.2.0",
46
+ "@x12i/ai-tools": "^2.3.0",
47
47
  "@x12i/flex-md": "^4.8.0",
48
48
  "@x12i/logxer": "^4.6.0",
49
- "@x12i/optimixer": "^2.4.4",
50
49
  "@x12i/rendrix": "^4.3.0"
51
50
  },
52
51
  "devDependencies": {
@@ -1,61 +0,0 @@
1
- {
2
- "system-context": "You are performing the following task: {{taskDescription}}. Follow the instructions provided and respond according to the specified output format. Never ask follow-up questions.",
3
-
4
- "input": {
5
- "inputLabel": "INPUT:",
6
- "inputPrefix": "INPUT DATA (process this now):",
7
- "defaultPromptTemplate": "{{input}}",
8
- "inputRecognitionRule": "The user message below is the complete input to process. It has already been provided. Do not ask for more input.",
9
- "emptyInputHandling": "If input appears empty or minimal (e.g., 'No emails here', 'none', 'empty'), this IS valid input. Process it and return the success schema with empty arrays/values where appropriate.",
10
- "testInputHandling": "Even if input contains words like 'test', 'invalid', 'placeholder', or 'example', treat it as real input. Reply in Markdown. Return your entire answer inside a single ```markdown fenced block.",
11
- "inputLocationClarifier": "The user's message below is your input data. Please process it now. Reply in Markdown. Return your entire answer inside a single ```markdown fenced block."
12
- },
13
-
14
- "errorSchemas": {
15
- "instructions-error": {
16
- "type": "object",
17
- "additionalProperties": false,
18
- "properties": {
19
- "error": {
20
- "type": "string",
21
- "description": "What is wrong with the instructions that prevents completion."
22
- },
23
- "errorType": {
24
- "type": "string",
25
- "enum": ["bad-instructions", "missing-context", "bad-context"]
26
- },
27
- "suggestion": {
28
- "type": "string",
29
- "description": "How to fix the instruction issue."
30
- }
31
- },
32
- "required": ["error", "errorType"]
33
- },
34
- "prompt-error": {
35
- "type": "object",
36
- "additionalProperties": false,
37
- "properties": {
38
- "error": {
39
- "type": "string",
40
- "description": "What is wrong with the input that prevents completion."
41
- },
42
- "errorType": {
43
- "type": "string",
44
- "enum": ["missing-input", "bad-input"]
45
- },
46
- "suggestion": {
47
- "type": "string",
48
- "description": "How to fix the input issue."
49
- }
50
- },
51
- "required": ["error", "errorType"]
52
- }
53
- },
54
-
55
- "reinforcement": {
56
- "emptyIsSuccess": "Empty results (e.g., items: []) are SUCCESS cases, not errors.",
57
- "inputAlreadyProvided": "The input has been provided in the user message. Process it immediately.",
58
- "noConversation": "You are not having a conversation. Reply in Markdown. Return your entire answer inside a single ```markdown fenced block.",
59
- "failureIndicators": "If you write prose text outside the fenced block, you have FAILED. If you ask a question, you have FAILED. If you explain anything outside the ```markdown fenced block, you have FAILED."
60
- }
61
- }
@@ -1,15 +0,0 @@
1
- {
2
- "defaultEngine": "openrouter",
3
- "defaultModel": "cheap",
4
- "temperature": 0.7,
5
- "topP": 1.0,
6
- "frequencyPenalty": 0.0,
7
- "presencePenalty": 0.0,
8
- "rateLimit": {
9
- "defaultMinIntervalMs": 500,
10
- "enabled": true
11
- },
12
- "retry": {
13
- "throttlingDelay": 5000
14
- }
15
- }
@@ -1,30 +0,0 @@
1
- /**
2
- * Gateway Instructions Module
3
- * Handles instructions block resolution from inline config only (no content registry).
4
- */
5
- import type { Logxer } from '@x12i/logxer';
6
- export interface InstructionsContext {
7
- defaultInstructionsBlocks: Record<string, any>;
8
- /** Flat overrides from gateway `instructionsBlocks` (merged at init). */
9
- instructionsBlockOverrides: Record<string, string>;
10
- /** Per-request flat overrides from `request.config.instructionsBlocks`. */
11
- requestInstructionsBlocks?: Record<string, string>;
12
- config: {
13
- instructionsBlocks?: Record<string, any>;
14
- };
15
- logger: Logxer;
16
- }
17
- /**
18
- * Resolves nested instructionsBlocks (e.g., "input.inputRecognitionRule")
19
- * Supports dot notation for nested object access in defaultInstructionsBlocks,
20
- * then flat keys in merged overrides.
21
- */
22
- export declare function resolveNestedInstructionsBlock(blockPath: string, _agentId: string, _taskTypeId: string | undefined, context: InstructionsContext): Promise<string>;
23
- /**
24
- * Resolves instructionsBlocks from config overrides, request overrides, nested defaults, or flat defaults.
25
- */
26
- export declare function resolveInstructionsBlock(blockName: string, agentId: string, taskTypeId: string | undefined, context: InstructionsContext): Promise<string>;
27
- /**
28
- * Pre-parse instructions string for stable hashing (taskTypeId). No external resolution.
29
- */
30
- export declare function getPreParsedInstructions(instructions: string | undefined): string;
@@ -1,62 +0,0 @@
1
- /**
2
- * Gateway Instructions Module
3
- * Handles instructions block resolution from inline config only (no content registry).
4
- */
5
- import { InstructionNotFoundError } from './instruction-errors.js';
6
- function getNestedString(blocks, dotPath) {
7
- const parts = dotPath.split('.');
8
- let cur = blocks;
9
- for (const p of parts) {
10
- if (cur == null || typeof cur !== 'object')
11
- return undefined;
12
- cur = cur[p];
13
- }
14
- return typeof cur === 'string' ? cur : undefined;
15
- }
16
- /**
17
- * Resolves nested instructionsBlocks (e.g., "input.inputRecognitionRule")
18
- * Supports dot notation for nested object access in defaultInstructionsBlocks,
19
- * then flat keys in merged overrides.
20
- */
21
- export async function resolveNestedInstructionsBlock(blockPath, _agentId, _taskTypeId, context) {
22
- return resolveInstructionsBlock(blockPath, _agentId, _taskTypeId, context);
23
- }
24
- /**
25
- * Resolves instructionsBlocks from config overrides, request overrides, nested defaults, or flat defaults.
26
- */
27
- export async function resolveInstructionsBlock(blockName, agentId, taskTypeId, context) {
28
- const { config, logger, defaultInstructionsBlocks, instructionsBlockOverrides, requestInstructionsBlocks } = context;
29
- logger.verbose('Resolving instructionsBlock', {
30
- blockName,
31
- agentId,
32
- taskTypeId,
33
- hasConfigOverride: !!config.instructionsBlocks?.[blockName]
34
- });
35
- const configOverride = config.instructionsBlocks?.[blockName];
36
- if (typeof configOverride === 'string' && configOverride.trim()) {
37
- logger.debug('Using per-call config override for instructionsBlock', { blockName, agentId });
38
- return configOverride;
39
- }
40
- const fromRequest = requestInstructionsBlocks?.[blockName];
41
- if (typeof fromRequest === 'string' && fromRequest.trim()) {
42
- logger.debug('Using request.config.instructionsBlocks for instructionsBlock', { blockName, agentId });
43
- return fromRequest;
44
- }
45
- const fromGateway = instructionsBlockOverrides[blockName];
46
- if (typeof fromGateway === 'string' && fromGateway.trim()) {
47
- logger.debug('Using gateway instructionsBlocks override for instructionsBlock', { blockName, agentId });
48
- return fromGateway;
49
- }
50
- const nested = getNestedString(defaultInstructionsBlocks, blockName);
51
- if (nested?.trim()) {
52
- logger.debug('Using nested defaultInstructionsBlocks for instructionsBlock', { blockName, agentId });
53
- return nested;
54
- }
55
- throw new InstructionNotFoundError(blockName, 'instructions-blocks', `InstructionsBlock "${blockName}" not found. Provide it via packaged defaults, gateway instructionsBlocks, or request.config.instructionsBlocks.`, blockName);
56
- }
57
- /**
58
- * Pre-parse instructions string for stable hashing (taskTypeId). No external resolution.
59
- */
60
- export function getPreParsedInstructions(instructions) {
61
- return instructions ?? '';
62
- }
@@ -1,16 +0,0 @@
1
- /**
2
- * Rate Limiter Constants
3
- *
4
- * Default values for rate limiting configuration.
5
- * These defaults ensure the system works safely even if config is missing.
6
- */
7
- /**
8
- * Default minimum interval between API calls (in milliseconds)
9
- * Used when rateLimit.defaultMinIntervalMs is not specified
10
- */
11
- export declare const DEFAULT_RATE_LIMIT_MIN_INTERVAL_MS = 500;
12
- /**
13
- * Default enabled state for rate limiting
14
- * Used when rateLimit.enabled is not specified
15
- */
16
- export declare const DEFAULT_RATE_LIMIT_ENABLED = true;
@@ -1,16 +0,0 @@
1
- /**
2
- * Rate Limiter Constants
3
- *
4
- * Default values for rate limiting configuration.
5
- * These defaults ensure the system works safely even if config is missing.
6
- */
7
- /**
8
- * Default minimum interval between API calls (in milliseconds)
9
- * Used when rateLimit.defaultMinIntervalMs is not specified
10
- */
11
- export const DEFAULT_RATE_LIMIT_MIN_INTERVAL_MS = 500;
12
- /**
13
- * Default enabled state for rate limiting
14
- * Used when rateLimit.enabled is not specified
15
- */
16
- export const DEFAULT_RATE_LIMIT_ENABLED = true;
@@ -1,56 +0,0 @@
1
- /**
2
- * Gateway Rate Limiter
3
- *
4
- * Smart rate limiting for BETWEEN-CALLS (not retries).
5
- *
6
- * Two types of rate limiting in the system:
7
- * 1. RETRY delays (in gateway-retry.ts) - Simple sleep, not smart. Used when retrying after errors.
8
- * 2. BETWEEN-CALLS rate limiting (this class) - Smart, tracks last call time and only waits if needed.
9
- *
10
- * This class handles #2: it tracks when the last API call was made per provider
11
- * and only waits if necessary to maintain minimum intervals between separate API calls.
12
- * This prevents unnecessary delays when enough time has already passed.
13
- */
14
- import type { Logxer } from '@x12i/logxer';
15
- /**
16
- * Smart Rate Limiter (Between-Calls Only)
17
- *
18
- * Tracks the last API call time per provider and only waits if necessary.
19
- * Supports per-provider rate limits with safe defaults.
20
- *
21
- * NOTE: This is for BETWEEN-CALLS rate limiting (smart).
22
- * Retry delays are handled separately in gateway-retry.ts (simple sleep).
23
- *
24
- * This ensures minimum intervals between separate API calls regardless of what happens between them.
25
- */
26
- export declare class GatewayRateLimiter {
27
- private lastCallTimes;
28
- private defaultMinIntervalMs;
29
- private providerIntervals;
30
- private logger?;
31
- constructor(defaultMinIntervalMs?: number, providerIntervals?: Record<string, number>, logger?: Logxer);
32
- /**
33
- * Gets the minimum interval for a specific provider
34
- * Falls back to default if provider-specific interval not set
35
- */
36
- private getMinIntervalForProvider;
37
- /**
38
- * Waits only if necessary to maintain the minimum interval between calls for a provider
39
- * @param provider - Provider name (e.g., 'openai', 'grok')
40
- * @returns Promise that resolves when it's safe to make the next call
41
- */
42
- waitIfNeeded(provider?: string): Promise<void>;
43
- /**
44
- * Records that an API call was made (call this after the API call completes)
45
- * This ensures we track the actual call time, accounting for call duration
46
- */
47
- recordCall(provider?: string): void;
48
- /**
49
- * Gets the time since the last call for a provider
50
- */
51
- getTimeSinceLastCall(provider?: string): number;
52
- /**
53
- * Resets the rate limiter for a provider (useful for testing or reset scenarios)
54
- */
55
- reset(provider?: string): void;
56
- }