@juspay/neurolink 10.6.0 → 10.6.2

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 (151) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/adapters/video/vertexVideoHandler.js +4 -1
  3. package/dist/agent/directTools.d.ts +2 -2
  4. package/dist/agent/orchestration/orchestrator.js +2 -0
  5. package/dist/auth/errors.d.ts +1 -1
  6. package/dist/auth/middleware/AuthMiddleware.d.ts +1 -1
  7. package/dist/auth/providers/BaseAuthProvider.d.ts +1 -1
  8. package/dist/auth/providers/auth0.js +1 -1
  9. package/dist/auth/providers/betterAuth.js +1 -1
  10. package/dist/auth/providers/clerk.js +1 -1
  11. package/dist/auth/providers/firebase.js +1 -1
  12. package/dist/auth/providers/jwt.js +1 -1
  13. package/dist/auth/providers/oauth2.js +1 -1
  14. package/dist/auth/providers/supabase.js +1 -1
  15. package/dist/auth/providers/workos.js +1 -1
  16. package/dist/browser/neurolink.min.js +338 -338
  17. package/dist/cli/commands/proxy.js +2 -0
  18. package/dist/cli/commands/rag.js +2 -4
  19. package/dist/cli/factories/commandFactory.js +3 -2
  20. package/dist/cli/loop/conversationSelector.js +4 -6
  21. package/dist/client/auth.js +2 -7
  22. package/dist/client/reactHooks.js +2 -2
  23. package/dist/client/reactHooks.tsx +5 -10
  24. package/dist/core/baseProvider.d.ts +1 -1
  25. package/dist/core/baseProvider.js +16 -6
  26. package/dist/core/factory.d.ts +4 -3
  27. package/dist/core/modules/GenerationHandler.d.ts +1 -1
  28. package/dist/core/modules/GenerationHandler.js +7 -5
  29. package/dist/core/modules/TelemetryHandler.js +2 -2
  30. package/dist/core/toolExecutionRecorder.d.ts +1 -1
  31. package/dist/core/toolExecutionRecorder.js +1 -2
  32. package/dist/evaluation/errors/EvaluationError.d.ts +1 -1
  33. package/dist/evaluation/scorers/rule/contentSimilarityScorer.js +2 -0
  34. package/dist/evaluation/scorers/rule/formatScorer.js +1 -1
  35. package/dist/factories/providerFactory.d.ts +4 -3
  36. package/dist/factories/providerRegistry.d.ts +9 -4
  37. package/dist/factories/providerRegistry.js +9 -4
  38. package/dist/features/ppt/slideGenerator.js +6 -5
  39. package/dist/features/ppt/utils.d.ts +2 -1
  40. package/dist/features/ppt/utils.js +1 -0
  41. package/dist/lib/adapters/video/vertexVideoHandler.js +4 -1
  42. package/dist/lib/agent/orchestration/orchestrator.js +2 -0
  43. package/dist/lib/auth/providers/auth0.js +1 -1
  44. package/dist/lib/auth/providers/betterAuth.js +1 -1
  45. package/dist/lib/auth/providers/clerk.js +1 -1
  46. package/dist/lib/auth/providers/firebase.js +1 -1
  47. package/dist/lib/auth/providers/jwt.js +1 -1
  48. package/dist/lib/auth/providers/oauth2.js +1 -1
  49. package/dist/lib/auth/providers/supabase.js +1 -1
  50. package/dist/lib/auth/providers/workos.js +1 -1
  51. package/dist/lib/client/auth.js +2 -7
  52. package/dist/lib/client/reactHooks.js +2 -2
  53. package/dist/lib/core/baseProvider.d.ts +1 -1
  54. package/dist/lib/core/baseProvider.js +16 -6
  55. package/dist/lib/core/factory.d.ts +4 -3
  56. package/dist/lib/core/modules/GenerationHandler.d.ts +1 -1
  57. package/dist/lib/core/modules/GenerationHandler.js +7 -5
  58. package/dist/lib/core/modules/TelemetryHandler.js +2 -2
  59. package/dist/lib/core/toolExecutionRecorder.d.ts +1 -1
  60. package/dist/lib/core/toolExecutionRecorder.js +1 -2
  61. package/dist/lib/evaluation/scorers/rule/contentSimilarityScorer.js +2 -0
  62. package/dist/lib/evaluation/scorers/rule/formatScorer.js +1 -1
  63. package/dist/lib/factories/providerFactory.d.ts +4 -3
  64. package/dist/lib/factories/providerRegistry.d.ts +9 -4
  65. package/dist/lib/factories/providerRegistry.js +9 -4
  66. package/dist/lib/features/ppt/slideGenerator.js +6 -5
  67. package/dist/lib/features/ppt/utils.d.ts +2 -1
  68. package/dist/lib/features/ppt/utils.js +1 -0
  69. package/dist/lib/mcp/elicitationProtocol.js +1 -1
  70. package/dist/lib/mcp/mcpRegistryClient.js +1 -1
  71. package/dist/lib/middleware/utils/guardrailsUtils.js +1 -1
  72. package/dist/lib/neurolink.js +15 -7
  73. package/dist/lib/processors/document/ExcelProcessor.js +5 -1
  74. package/dist/lib/processors/media/index.js +0 -10
  75. package/dist/lib/providers/amazonBedrock.js +4 -5
  76. package/dist/lib/providers/amazonSagemaker.d.ts +18 -0
  77. package/dist/lib/providers/amazonSagemaker.js +9 -3
  78. package/dist/lib/providers/anthropic.js +6 -1
  79. package/dist/lib/providers/googleAiStudio.js +5 -12
  80. package/dist/lib/providers/googleVertex.js +26 -5
  81. package/dist/lib/providers/openaiChatCompletionsBase.js +2 -0
  82. package/dist/lib/providers/sagemaker/errors.js +2 -1
  83. package/dist/lib/proxy/proxyFetch.js +6 -2
  84. package/dist/lib/rag/ChunkerFactory.js +1 -1
  85. package/dist/lib/rag/chunking/semanticChunker.js +1 -2
  86. package/dist/lib/rag/document/MDocument.js +1 -2
  87. package/dist/lib/rag/document/loaders.js +16 -3
  88. package/dist/lib/rag/pipeline/RAGPipeline.js +1 -2
  89. package/dist/lib/rag/retrieval/hybridSearch.js +1 -2
  90. package/dist/lib/rag/retrieval/vectorQueryTool.js +1 -2
  91. package/dist/lib/sdk/toolRegistration.js +6 -2
  92. package/dist/lib/server/middleware/cache.d.ts +4 -0
  93. package/dist/lib/server/middleware/cache.js +7 -3
  94. package/dist/lib/server/middleware/validation.js +2 -1
  95. package/dist/lib/server/utils/redaction.js +31 -39
  96. package/dist/lib/server/websocket/WebSocketHandler.js +3 -3
  97. package/dist/lib/services/server/ai/observability/instrumentation.js +8 -5
  98. package/dist/lib/types/classifierRouter.d.ts +2 -1
  99. package/dist/lib/types/providers.d.ts +22 -2
  100. package/dist/lib/utils/pdfProcessor.js +2 -0
  101. package/dist/lib/utils/safeFetch.js +20 -0
  102. package/dist/lib/utils/schemaConversion.d.ts +1 -1
  103. package/dist/lib/utils/schemaConversion.js +5 -1
  104. package/dist/lib/workflow/config.d.ts +1 -1
  105. package/dist/lib/workflow/config.js +1 -1
  106. package/dist/lib/workflow/core/workflowRegistry.js +1 -1
  107. package/dist/lib/workflow/core/workflowRunner.js +1 -1
  108. package/dist/lib/workflow/utils/workflowMetrics.d.ts +1 -1
  109. package/dist/lib/workflow/utils/workflowMetrics.js +1 -1
  110. package/dist/mcp/elicitationProtocol.js +1 -1
  111. package/dist/mcp/mcpRegistryClient.js +1 -1
  112. package/dist/middleware/utils/guardrailsUtils.js +1 -1
  113. package/dist/neurolink.js +15 -7
  114. package/dist/processors/document/ExcelProcessor.js +5 -1
  115. package/dist/processors/media/index.js +0 -10
  116. package/dist/providers/amazonBedrock.js +4 -5
  117. package/dist/providers/amazonSagemaker.d.ts +18 -0
  118. package/dist/providers/amazonSagemaker.js +9 -3
  119. package/dist/providers/anthropic.js +6 -1
  120. package/dist/providers/googleAiStudio.js +5 -12
  121. package/dist/providers/googleVertex.js +26 -5
  122. package/dist/providers/openaiChatCompletionsBase.js +2 -0
  123. package/dist/providers/sagemaker/errors.js +2 -1
  124. package/dist/proxy/proxyFetch.js +6 -2
  125. package/dist/rag/ChunkerFactory.js +1 -1
  126. package/dist/rag/chunking/semanticChunker.js +1 -2
  127. package/dist/rag/document/MDocument.js +1 -2
  128. package/dist/rag/document/loaders.js +16 -3
  129. package/dist/rag/pipeline/RAGPipeline.js +1 -2
  130. package/dist/rag/retrieval/hybridSearch.js +1 -2
  131. package/dist/rag/retrieval/vectorQueryTool.js +1 -2
  132. package/dist/sdk/toolRegistration.js +6 -2
  133. package/dist/server/middleware/cache.d.ts +4 -0
  134. package/dist/server/middleware/cache.js +7 -3
  135. package/dist/server/middleware/validation.js +2 -1
  136. package/dist/server/utils/redaction.js +31 -39
  137. package/dist/server/websocket/WebSocketHandler.js +3 -3
  138. package/dist/services/server/ai/observability/instrumentation.js +8 -5
  139. package/dist/types/classifierRouter.d.ts +2 -1
  140. package/dist/types/providers.d.ts +22 -2
  141. package/dist/utils/pdfProcessor.js +2 -0
  142. package/dist/utils/safeFetch.js +20 -0
  143. package/dist/utils/schemaConversion.d.ts +1 -1
  144. package/dist/utils/schemaConversion.js +5 -1
  145. package/dist/workflow/config.d.ts +2 -2
  146. package/dist/workflow/config.js +1 -1
  147. package/dist/workflow/core/workflowRegistry.js +1 -1
  148. package/dist/workflow/core/workflowRunner.js +1 -1
  149. package/dist/workflow/utils/workflowMetrics.d.ts +1 -1
  150. package/dist/workflow/utils/workflowMetrics.js +1 -1
  151. package/package.json +1 -1
@@ -318,7 +318,7 @@ export function applyContentFiltering(text, badWordsConfig, context = "unknown")
318
318
  logger.debug(`[ContentFiltering:${context}] Applying regex pattern filtering with ${badWordsConfig.regexPatterns.length} patterns using replacement: "${replacementText}".`);
319
319
  for (const pattern of badWordsConfig.regexPatterns) {
320
320
  try {
321
- // TODO: Add blocking for overly complex or long patterns
321
+ // TODO(#1179): Add blocking for overly complex or long patterns
322
322
  if (pattern.length > 1000) {
323
323
  logger.warn(`[ContentFiltering:${context}] Regex pattern exceeds max length (1000 chars): "${pattern.substring(0, 50)}..."`);
324
324
  }
package/dist/neurolink.js CHANGED
@@ -327,13 +327,23 @@ export function isNeuroLink(value) {
327
327
  value !== null &&
328
328
  value[NEUROLINK_BRAND] === true);
329
329
  }
330
+ /**
331
+ * Create a Node {@link EventEmitter} exposed through the typed-emitter
332
+ * surface. The runtime object is a plain EventEmitter — the typed view only
333
+ * narrows the event-name/payload relationship for callers, so the widening
334
+ * hop through `unknown` is contained here once.
335
+ */
336
+ function createTypedEmitter() {
337
+ const emitter = new EventEmitter();
338
+ return emitter;
339
+ }
330
340
  export class NeuroLink {
331
341
  /** @internal Brand for cross-module identification — see {@link isNeuroLink}. */
332
342
  [NEUROLINK_BRAND] = true;
333
343
  mcpInitialized = false;
334
344
  mcpSkipped = false;
335
345
  mcpInitPromise = null;
336
- emitter = new EventEmitter();
346
+ emitter = createTypedEmitter();
337
347
  // TaskManager — lazy-initialized on first access via `this.tasks`
338
348
  _taskManager;
339
349
  _taskManagerConfig;
@@ -1306,8 +1316,7 @@ export class NeuroLink {
1306
1316
  description: retrieveContextDef.description ?? "Retrieve context or artifacts",
1307
1317
  // Pass the Zod schema so ToolsManager gives the LLM full parameter types.
1308
1318
  // registerTool() detects isZodSchema on inputSchema and preserves it.
1309
- inputSchema: retrieveContextDef
1310
- .inputSchema,
1319
+ inputSchema: retrieveContextDef.inputSchema,
1311
1320
  execute: async (params) => {
1312
1321
  // Lazy: conversationMemory is initialized on the first generate() call.
1313
1322
  // When only an artifact store is present (no Redis), memoryManager is
@@ -1362,8 +1371,7 @@ export class NeuroLink {
1362
1371
  description: toolDef.description ?? toolName,
1363
1372
  // Zod schema — registerTool() detects isZodSchema and preserves it
1364
1373
  // so ToolsManager gives the LLM full parameter types.
1365
- inputSchema: toolDef
1366
- .inputSchema,
1374
+ inputSchema: toolDef.inputSchema,
1367
1375
  execute: async (params) => withTimeout(toolDef.execute(params, { toolCallId: "skill-tool", messages: [] }), TOOL_TIMEOUTS.EXECUTION_DEFAULT_MS, ErrorFactory.toolTimeout(toolName, TOOL_TIMEOUTS.EXECUTION_DEFAULT_MS)),
1368
1376
  });
1369
1377
  }
@@ -8915,7 +8923,7 @@ Current user's request: ${currentInput}`;
8915
8923
  // ========================================
8916
8924
  // ENHANCED: Tool Event Emission API
8917
8925
  // ========================================
8918
- // TODO: Add ToolExecutionEvent utility methods in future version
8926
+ // TODO(#1179): Add ToolExecutionEvent utility methods in future version
8919
8927
  // Will provide structured event format for consistent tool event processing
8920
8928
  /**
8921
8929
  * Emit tool start event with execution tracking
@@ -9038,7 +9046,7 @@ Current user's request: ${currentInput}`;
9038
9046
  clearCurrentStreamExecutions() {
9039
9047
  this.currentStreamToolExecutions = [];
9040
9048
  }
9041
- // TODO: Add getToolExecutionEvents() method in future version
9049
+ // TODO(#1179): Add getToolExecutionEvents() method in future version
9042
9050
  // Will return properly formatted ToolExecutionEvent objects for structured event processing
9043
9051
  // ========================================
9044
9052
  // Tool Registration API
@@ -271,7 +271,11 @@ export class ExcelProcessor extends BaseFileProcessor {
271
271
  */
272
272
  async parseWorkbook(buffer) {
273
273
  const ExcelJS = await loadExcelJS();
274
- const workbook = new ExcelJS.Workbook();
274
+ // The exceljs constructor comes from a normalised CJS/ESM interop
275
+ // namespace (see loadExcelJS); probe the instance as `unknown` and
276
+ // narrow to the structural subset this processor uses.
277
+ const workbookInstance = new ExcelJS.Workbook();
278
+ const workbook = workbookInstance;
275
279
  // ExcelJS load() types expect Buffer but Node 22+ Buffer<ArrayBufferLike>
276
280
  // is not directly assignable. Extract a clean ArrayBuffer for the exact
277
281
  // byte range via slice, then cast for type compatibility.
@@ -27,13 +27,3 @@
27
27
  // VIDEO PROCESSOR
28
28
  // =============================================================================
29
29
  export { isVideoFile, processVideo, VideoProcessor, videoProcessor, } from "./VideoProcessor.js";
30
- // =============================================================================
31
- // AUDIO PROCESSOR (placeholder for future implementation)
32
- // =============================================================================
33
- // export {
34
- // AudioProcessor,
35
- // audioProcessor,
36
- // isAudioFile,
37
- // processAudio,
38
- // } from "./AudioProcessor.js";
39
- // export type { ProcessedAudio } from "./AudioProcessor.js";
@@ -155,7 +155,8 @@ export class AmazonBedrockProvider extends BaseProvider {
155
155
  // Clear conversation history for new generation
156
156
  this.conversationHistory = [];
157
157
  // Check for multimodal input (images, PDFs, CSVs, files)
158
- // Cast to any to access multimodal properties (runtime check is safe)
158
+ // Narrow to the StreamOptions input shape to access multimodal
159
+ // properties (runtime check is safe)
159
160
  const input = options.input;
160
161
  const hasMultimodalInput = !!(input?.images?.length ||
161
162
  input?.content?.length ||
@@ -917,10 +918,8 @@ export class AmazonBedrockProvider extends BaseProvider {
917
918
  logger.debug("[TRACE] executeStream CATCH - error caught from streamingConversationLoop");
918
919
  const errorObj = error;
919
920
  // Check if error is related to streaming permissions
920
- const isPermissionError = errorObj?.name ===
921
- "AccessDeniedException" ||
922
- errorObj?.name ===
923
- "UnauthorizedOperation" ||
921
+ const isPermissionError = errorObj?.name === "AccessDeniedException" ||
922
+ errorObj?.name === "UnauthorizedOperation" ||
924
923
  errorObj?.message?.includes("bedrock:InvokeModelWithResponseStream") ||
925
924
  errorObj?.message?.includes("streaming") ||
926
925
  errorObj?.message?.includes("ConverseStream");
@@ -54,6 +54,24 @@ export declare class AmazonSageMakerProvider extends BaseProvider {
54
54
  * Get model capabilities and information
55
55
  */
56
56
  getModelCapabilities(): {
57
+ capabilities: {
58
+ streaming: boolean;
59
+ toolCalling: boolean;
60
+ structuredOutput: boolean;
61
+ batchInference: boolean;
62
+ supportedResponseFormats: string[];
63
+ supportedToolTypes: string[];
64
+ maxBatchSize: number;
65
+ adaptiveConcurrency: boolean;
66
+ errorRecovery: boolean;
67
+ };
68
+ modelId: string;
69
+ provider: string;
70
+ specificationVersion: "v2";
71
+ endpointName: string;
72
+ modelType: "huggingface" | "mistral" | "custom" | "llama" | "claude" | "jumpstart" | undefined;
73
+ region: string;
74
+ } | {
57
75
  capabilities: {
58
76
  streaming: boolean;
59
77
  toolCalling: boolean;
@@ -10,6 +10,9 @@ import { SageMakerLanguageModel } from "./sagemaker/language-model.js";
10
10
  * Amazon SageMaker Provider extending BaseProvider
11
11
  */
12
12
  export class AmazonSageMakerProvider extends BaseProvider {
13
+ // Kept as the concrete class so SageMaker-specific members
14
+ // (testConnectivity, getModelCapabilities) stay typed; getAISDKModel()
15
+ // narrows to the AI SDK handle shape at its boundary.
13
16
  sagemakerModel;
14
17
  sagemakerConfig;
15
18
  modelConfig;
@@ -41,8 +44,7 @@ export class AmazonSageMakerProvider extends BaseProvider {
41
44
  // SageMakerLanguageModel implements SageMakerAsLanguageModel which is
42
45
  // structurally compatible with LanguageModelV2 (specificationVersion "v2",
43
46
  // modelId, provider, supportedUrls, doGenerate, doStream).
44
- const smModel = new SageMakerLanguageModel(this.modelName, this.sagemakerConfig, this.modelConfig);
45
- this.sagemakerModel = smModel;
47
+ this.sagemakerModel = new SageMakerLanguageModel(this.modelName, this.sagemakerConfig, this.modelConfig);
46
48
  logger.debug("Amazon SageMaker Provider initialized", {
47
49
  modelName: this.modelName,
48
50
  endpointName: this.modelConfig.endpointName,
@@ -66,7 +68,11 @@ export class AmazonSageMakerProvider extends BaseProvider {
66
68
  return getSageMakerModel();
67
69
  }
68
70
  getAISDKModel() {
69
- return this.sagemakerModel;
71
+ // Same sanctioned two-step as construction previously used: the class
72
+ // satisfies the structural SageMakerAsLanguageModel shape, which is
73
+ // single-assertable to the AI SDK LanguageModel handle.
74
+ const smModel = this.sagemakerModel;
75
+ return smModel;
70
76
  }
71
77
  async executeStream(_options, _analysisSchema) {
72
78
  return withSpan({
@@ -1072,7 +1072,11 @@ export class AnthropicProvider extends BaseProvider {
1072
1072
  const modelId = this.modelName || getDefaultAnthropicModel();
1073
1073
  const getTimeoutForOptions = (opts) => this.getTimeout((opts ?? {}));
1074
1074
  const refreshAuth = () => this.refreshAuthIfNeeded();
1075
- return {
1075
+ // Structural AI-SDK model shape (`SageMakerAsLanguageModel`, the
1076
+ // sanctioned intermediate from src/lib/types/providers.ts): assigning the
1077
+ // literal to it keeps the compiler's member checks, and the intermediate
1078
+ // is single-assertable to the ai-package `LanguageModel` handle.
1079
+ const delegatingModel = {
1076
1080
  specificationVersion: "v3",
1077
1081
  provider: providerName,
1078
1082
  modelId,
@@ -1259,6 +1263,7 @@ export class AnthropicProvider extends BaseProvider {
1259
1263
  throw new Error(`${providerName}: doStream is not implemented on the delegating model — the streaming path uses executeStream directly.`);
1260
1264
  },
1261
1265
  };
1266
+ return delegatingModel;
1262
1267
  }
1263
1268
  formatProviderError(error) {
1264
1269
  if (error instanceof TimeoutError) {
@@ -1282,10 +1282,9 @@ export class GoogleAIStudioProvider extends BaseProvider {
1282
1282
  if (queue.length > 0) {
1283
1283
  const item = queue.shift();
1284
1284
  if (!item) {
1285
- return {
1286
- value: undefined,
1287
- done: true,
1288
- };
1285
+ // `done: true` selects the IteratorReturnResult arm, whose
1286
+ // value type accepts undefined.
1287
+ return { value: undefined, done: true };
1289
1288
  }
1290
1289
  if (item.type === "audio") {
1291
1290
  return {
@@ -1295,10 +1294,7 @@ export class GoogleAIStudioProvider extends BaseProvider {
1295
1294
  }
1296
1295
  if (item.type === "end") {
1297
1296
  done = true;
1298
- return {
1299
- value: undefined,
1300
- done: true,
1301
- };
1297
+ return { value: undefined, done: true };
1302
1298
  }
1303
1299
  if (item.type === "error") {
1304
1300
  done = true;
@@ -1308,10 +1304,7 @@ export class GoogleAIStudioProvider extends BaseProvider {
1308
1304
  }
1309
1305
  }
1310
1306
  if (done) {
1311
- return {
1312
- value: undefined,
1313
- done: true,
1314
- };
1307
+ return { value: undefined, done: true };
1315
1308
  }
1316
1309
  return await new Promise((resolve) => {
1317
1310
  resolveNext = resolve;
@@ -1443,6 +1443,9 @@ export class GoogleVertexProvider extends BaseProvider {
1443
1443
  const maxSteps = Number.isFinite(rawMaxSteps) && rawMaxSteps > 0
1444
1444
  ? Math.min(Math.floor(rawMaxSteps), 100) // Cap at 100 for safety
1445
1445
  : Math.min(DEFAULT_MAX_STEPS, 100);
1446
+ // Widened per-turn copy: the agentic loop appends functionCall /
1447
+ // functionResponse parts on top of the plain text/inlineData parts the
1448
+ // initial contents carry.
1446
1449
  const currentContents = [...contents];
1447
1450
  let finalText = "";
1448
1451
  // Last SDK finish reason seen across steps (Bug 2: previously never read,
@@ -1671,7 +1674,8 @@ export class GoogleVertexProvider extends BaseProvider {
1671
1674
  functionCall: fc,
1672
1675
  })),
1673
1676
  });
1674
- // Execute each function and collect responses
1677
+ // Execute each function and collect responses (plus an optional
1678
+ // trailing wrap-up nudge text part).
1675
1679
  const functionResponses = [];
1676
1680
  // Per-step bookkeeping for conversation-memory storage.
1677
1681
  const stepStorageCalls = [];
@@ -2080,6 +2084,10 @@ export class GoogleVertexProvider extends BaseProvider {
2080
2084
  // (assistant text empty but tools ran) and downstream consumers see
2081
2085
  // the same shape AI-SDK-driven providers expose.
2082
2086
  toolsUsed: externalToolCalls.map((tc) => tc.toolName),
2087
+ // transformToolExecutions' record shape (name/input/output/duration) is
2088
+ // what downstream consumers read at runtime; it shares no required
2089
+ // members with the declared ToolExecutionSummary element type, so the
2090
+ // assertion carries both shapes instead of erasing the real one.
2083
2091
  toolExecutions: transformToolExecutions(externalToolExecutions),
2084
2092
  metadata: {
2085
2093
  streamId: `native-vertex-${Date.now()}`,
@@ -2378,6 +2386,9 @@ export class GoogleVertexProvider extends BaseProvider {
2378
2386
  const maxSteps = Number.isFinite(rawMaxSteps) && rawMaxSteps > 0
2379
2387
  ? Math.min(Math.floor(rawMaxSteps), 100) // Cap at 100 for safety
2380
2388
  : Math.min(DEFAULT_MAX_STEPS, 100);
2389
+ // Widened per-turn copy: the agentic loop appends functionCall /
2390
+ // functionResponse parts on top of the plain text/inlineData parts the
2391
+ // initial contents carry.
2381
2392
  const currentContents = [...contents];
2382
2393
  let finalText = "";
2383
2394
  // Cross-step text accumulation + last SDK finish reason, so the
@@ -2595,7 +2606,8 @@ export class GoogleVertexProvider extends BaseProvider {
2595
2606
  functionCall: fc,
2596
2607
  })),
2597
2608
  });
2598
- // Execute each function and collect responses
2609
+ // Execute each function and collect responses (plus an optional
2610
+ // trailing wrap-up nudge text part).
2599
2611
  const functionResponses = [];
2600
2612
  const toolCallsBefore = allToolCalls.length;
2601
2613
  const toolExecsBefore = toolExecutions.length;
@@ -3094,9 +3106,18 @@ export class GoogleVertexProvider extends BaseProvider {
3094
3106
  // `prepareOptions()` is a separate continuation and still surfaces auth
3095
3107
  // errors to callers. `void` flags the returned promise as deliberately
3096
3108
  // ignored (codebase convention for fire-and-forget).
3097
- void client._authClientPromise?.catch(() => {
3098
- // Intentionally ignored see above.
3099
- });
3109
+ //
3110
+ // `_authClientPromise` is a private SDK internal, so it is reached via
3111
+ // runtime narrowing (`in` + `instanceof`) rather than a type assertion.
3112
+ const clientInternals = client;
3113
+ if ("_authClientPromise" in clientInternals) {
3114
+ const authClientPromise = clientInternals._authClientPromise;
3115
+ if (authClientPromise instanceof Promise) {
3116
+ void authClientPromise.catch(() => {
3117
+ // Intentionally ignored — see above.
3118
+ });
3119
+ }
3120
+ }
3100
3121
  return client;
3101
3122
  }
3102
3123
  /**
@@ -291,6 +291,8 @@ export class OpenAIChatCompletionsProvider extends BaseProvider {
291
291
  */
292
292
  async getAISDKModel() {
293
293
  const modelId = await this.resolveModelName();
294
+ // buildDelegatingModel returns `unknown`, so this is a single
295
+ // unknown-to-target assertion.
294
296
  return this.buildDelegatingModel(modelId);
295
297
  }
296
298
  async resolveModelName() {
@@ -192,7 +192,8 @@ export function handleSageMakerError(error, endpoint) {
192
192
  /**
193
193
  * Extract request ID from AWS SDK error for debugging
194
194
  *
195
- * @param error - Error object that might contain request ID
195
+ * @param error - Error object that might contain request ID (AWS SDK errors
196
+ * carry it as an untyped extra field, so the value is treated as opaque)
196
197
  * @returns Request ID if found, undefined otherwise
197
198
  */
198
199
  function extractRequestId(error) {
@@ -509,10 +509,14 @@ async function executeProxiedFetch(input, init, proxyEnv) {
509
509
  fetchInput = input;
510
510
  }
511
511
  const undici = await import("undici");
512
- const response = await undici.fetch(fetchInput, {
512
+ // undici's fetch types and lib.dom's diverge on iterator helper details,
513
+ // so the runtime-identical response is typed as either flavor (widening
514
+ // assertion so control flow keeps the union) and narrowed
515
+ // (overlap-checked) back to the DOM flavor at the return boundary.
516
+ const response = (await undici.fetch(fetchInput, {
513
517
  ...fetchInit,
514
518
  dispatcher,
515
- });
519
+ }));
516
520
  if (logger.shouldLog("debug")) {
517
521
  const { parsed: responseBody, size: responseSize, type: responseType, headers: responseHeaders, } = await readResponseBody(response);
518
522
  logger.debug("[Observability] HTTP response from LLM provider", {
@@ -177,7 +177,7 @@ export class ChunkerFactory extends BaseFactory {
177
177
  }, DEFAULT_CHUNKER_METADATA.latex);
178
178
  // Register semantic chunker (placeholder - uses recursive as fallback)
179
179
  this.registerChunker("semantic", async (config) => {
180
- // TODO: Implement dedicated SemanticChunker with LLM support
180
+ // TODO(#1179): Implement dedicated SemanticChunker with LLM support
181
181
  // For now, fall back to RecursiveChunker with semantic defaults
182
182
  const { RecursiveChunker } = await import("./chunkers/RecursiveChunker.js");
183
183
  return new RecursiveChunker(config);
@@ -138,8 +138,7 @@ export class SemanticChunker {
138
138
  async getEmbeddings(segments, provider, modelName) {
139
139
  const embeddingProvider = await ProviderFactory.createProvider(provider, modelName);
140
140
  // Check if provider has embed method
141
- if (typeof embeddingProvider.embed !==
142
- "function") {
141
+ if (typeof embeddingProvider.embed !== "function") {
143
142
  throw new Error(`Provider ${provider} does not support embeddings`);
144
143
  }
145
144
  const embeddings = [];
@@ -210,8 +210,7 @@ export class MDocument {
210
210
  model: modelName,
211
211
  });
212
212
  const embeddingProvider = await ProviderFactory.createProvider(provider, modelName);
213
- if (typeof embeddingProvider.embed !==
214
- "function") {
213
+ if (typeof embeddingProvider.embed !== "function") {
215
214
  throw new Error(`Provider ${provider} does not support embeddings`);
216
215
  }
217
216
  this.state.embeddings = [];
@@ -273,14 +273,27 @@ export class PDFLoader {
273
273
  return ext === ".pdf";
274
274
  }
275
275
  async loadPdfParser() {
276
+ // pdf-parse is an optional dependency — resolve it dynamically and
277
+ // validate at runtime that it exposes a callable parser (either the
278
+ // module itself or its default export) instead of blindly asserting.
279
+ let pdfParseModule;
276
280
  try {
277
- // pdf-parse is an optional dependency - use dynamic import with type assertion
278
- const pdfParse = (await import("pdf-parse"));
279
- return pdfParse.default || pdfParse;
281
+ pdfParseModule = await import("pdf-parse");
280
282
  }
281
283
  catch {
282
284
  throw new Error("pdf-parse module not available");
283
285
  }
286
+ const candidate = (typeof pdfParseModule === "object" &&
287
+ pdfParseModule !== null &&
288
+ "default" in pdfParseModule
289
+ ? pdfParseModule.default
290
+ : undefined) || pdfParseModule;
291
+ if (typeof candidate !== "function") {
292
+ // Outside the try/catch so this message isn't swallowed by the
293
+ // module-not-available rethrow.
294
+ throw new Error("pdf-parse module does not export a parse function");
295
+ }
296
+ return candidate;
284
297
  }
285
298
  parsePageRange(range, totalPages) {
286
299
  const pages = [];
@@ -371,8 +371,7 @@ export class RAGPipeline {
371
371
  if (!this.embeddingProvider) {
372
372
  throw new Error("Embedding provider not initialized");
373
373
  }
374
- if (typeof this.embeddingProvider
375
- .embed !== "function") {
374
+ if (typeof this.embeddingProvider.embed !== "function") {
376
375
  throw new Error(`Provider ${this.config.embeddingModel.provider} does not support embeddings`);
377
376
  }
378
377
  return await withTimeout(this.embeddingProvider.embed(text), DEFAULT_TIMEOUT_MS, "Embedding generation timed out");
@@ -177,8 +177,7 @@ export function createHybridSearch(options) {
177
177
  try {
178
178
  // Generate query embedding
179
179
  const embeddingProvider = await ProviderFactory.createProvider(embeddingModel?.provider, embeddingModel?.modelName);
180
- if (typeof embeddingProvider
181
- .embed !== "function") {
180
+ if (typeof embeddingProvider.embed !== "function") {
182
181
  throw new Error(`Embedding provider does not support the embed() method. ` +
183
182
  `Please use a provider that supports embeddings (e.g., OpenAI text-embedding-3-small, Vertex text-embedding-004).`);
184
183
  }
@@ -66,8 +66,7 @@ export function createVectorQueryTool(config, vectorStore) {
66
66
  // Generate query embedding
67
67
  const embeddingProvider = await ProviderFactory.createProvider(embeddingModel.provider, embeddingModel.modelName);
68
68
  // Check if provider has embed method
69
- if (typeof embeddingProvider
70
- .embed !== "function") {
69
+ if (typeof embeddingProvider.embed !== "function") {
71
70
  throw new Error(`Provider ${embeddingModel.provider} does not support embeddings`);
72
71
  }
73
72
  const queryEmbedding = await embeddingProvider.embed(params.query);
@@ -249,8 +249,12 @@ export function validateTool(name, tool) {
249
249
  throw new Error(`Tool '${name}' parameters must be an object. ` +
250
250
  `Received: ${typeof tool.parameters}`);
251
251
  }
252
- // Check for common schema validation methods (Zod uses 'parse', others might use 'validate')
253
- const params = tool.parameters;
252
+ // Check for common schema validation methods (Zod uses 'parse', others might use 'validate').
253
+ // Despite the declared Zod type, callers may pass custom schema objects at
254
+ // runtime — this function's whole purpose is to validate that; probe as
255
+ // `unknown` and narrow to a generic record for feature detection.
256
+ const paramsCandidate = tool.parameters;
257
+ const params = paramsCandidate;
254
258
  const hasValidationMethod = typeof params.parse === "function" ||
255
259
  typeof params.validate === "function" ||
256
260
  "_def" in params; // Zod schemas have _def property
@@ -83,6 +83,10 @@ export declare class LRUCache<K, V> {
83
83
  * Check if a key exists in the cache
84
84
  */
85
85
  has(key: K): boolean;
86
+ /**
87
+ * Iterate over all keys currently in the cache
88
+ */
89
+ keys(): IterableIterator<K>;
86
90
  /**
87
91
  * Delete a key from the cache
88
92
  */
@@ -219,6 +219,12 @@ export class LRUCache {
219
219
  has(key) {
220
220
  return this.cache.has(key);
221
221
  }
222
+ /**
223
+ * Iterate over all keys currently in the cache
224
+ */
225
+ keys() {
226
+ return this.cache.keys();
227
+ }
222
228
  /**
223
229
  * Delete a key from the cache
224
230
  */
@@ -335,9 +341,7 @@ export class ResponseCacheStore {
335
341
  // For production, consider using a more efficient data structure
336
342
  let invalidated = 0;
337
343
  const keysToDelete = [];
338
- // Get all keys (requires accessing internal cache)
339
- const internalCache = this.cache.cache;
340
- for (const key of internalCache.keys()) {
344
+ for (const key of this.cache.keys()) {
341
345
  const matches = pattern instanceof RegExp ? pattern.test(key) : key.includes(pattern);
342
346
  if (matches) {
343
347
  keysToDelete.push(key);
@@ -75,7 +75,8 @@ export function createRequestValidationMiddleware(config) {
75
75
  const formattedError = errorFormatter(errors.map((e) => new ServerValidationError([e], ctx.requestId)));
76
76
  const error = new ServerValidationError(errors, ctx.requestId);
77
77
  // Attach formatted response to error
78
- error.response = formattedError;
78
+ error.response =
79
+ formattedError;
79
80
  throw error;
80
81
  }
81
82
  return next();