@juspay/neurolink 12.47.3 → 12.47.4

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.
@@ -366,7 +366,7 @@ export function runAgenticLoop(adapter, initialConversation, options) {
366
366
  // The caller's span, when it passes one. withProviderRetry writes
367
367
  // gen_ai.provider.total_attempts here, so a loop that threaded a
368
368
  // span before it moved onto this engine keeps emitting it.
369
- options.span, `${adapter.providerLabel}.step`);
369
+ options.span, `${adapter.providerLabel}.step`, undefined, internalAbort.signal);
370
370
  }
371
371
  catch (err) {
372
372
  throw err instanceof PostEmissionStepError ? err.cause : err;
@@ -445,7 +445,10 @@ export class VideoProcessor extends BaseFileProcessor {
445
445
  metadata = this.buildMetadata(probeResult.data, buffer.length);
446
446
  }
447
447
  }
448
- if (!metadata) {
448
+ // mediabunny reports a duration of 0 for a clip it can open but not
449
+ // time, and ffprobe's "N/A" parses to NaN: neither is a missing
450
+ // result, so both take the ffmpeg fallback.
451
+ if (!metadata || !(metadata.duration > 0)) {
449
452
  // ffmpeg-static ships ffmpeg only, so a host that relies on it has
450
453
  // no ffprobe. Without a duration no frame timestamps can be chosen.
451
454
  const ffmpegProbe = await this.probeVideoWithFfmpeg(tempVideoPath);
@@ -456,7 +459,9 @@ export class VideoProcessor extends BaseFileProcessor {
456
459
  // Nothing downstream reports this: an empty duration selects no
457
460
  // frames, the request still succeeds, and the model is simply
458
461
  // told nothing about the video.
459
- logger.warn(`[NEUROLINK] No metadata could be read for ${filename} (mediabunny, ffprobe and ffmpeg all failed), so no keyframes will be extracted: ${ffmpegProbe.error}`);
462
+ logger.warn(metadata
463
+ ? `[NEUROLINK] No positive duration could be read for ${filename} (the first reader gave none and ffmpeg could not supply one), so frame times cannot be chosen: ${ffmpegProbe.error}`
464
+ : `[NEUROLINK] No metadata could be read for ${filename} (mediabunny, ffprobe and ffmpeg all failed), so no keyframes will be extracted: ${ffmpegProbe.error}`);
460
465
  }
461
466
  }
462
467
  if (!metadata) {
@@ -242,7 +242,7 @@ export class AmazonSageMakerProvider extends BaseProvider {
242
242
  ...(options.toolTimeoutMs !== undefined
243
243
  ? { toolTimeoutMs: options.toolTimeoutMs }
244
244
  : {}),
245
- runStep: (call) => withProviderRetry(call, undefined, "sagemaker generate").catch((err) => {
245
+ runStep: (call) => withProviderRetry(call, undefined, "sagemaker generate", undefined, options.abortSignal).catch((err) => {
246
246
  throw this.handleProviderError(err);
247
247
  }),
248
248
  }, toolExecutionSummaries);
@@ -1623,7 +1623,7 @@ export class AnthropicProvider extends BaseProvider {
1623
1623
  ...(options.toolTimeoutMs !== undefined
1624
1624
  ? { toolTimeoutMs: options.toolTimeoutMs }
1625
1625
  : {}),
1626
- runStep: (call) => withProviderRetry(call, trace.getActiveSpan() ?? undefined, "anthropic generate").catch((err) => {
1626
+ runStep: (call) => withProviderRetry(call, trace.getActiveSpan() ?? undefined, "anthropic generate", undefined, options.abortSignal).catch((err) => {
1627
1627
  throw this.handleProviderError(err);
1628
1628
  }),
1629
1629
  }, toolExecutionSummaries);
@@ -270,7 +270,9 @@ export class NvidiaNimProvider extends OpenAIChatCompletionsProvider {
270
270
  message: "NVIDIA NIM rate limit exceeded",
271
271
  },
272
272
  {
273
- match: (ctx) => /404|model_not_found/.test(ctx.message),
273
+ // NIM answers most of its roster with a 404 whose text ("Function …
274
+ // not found for account …") names no model, so the status decides.
275
+ match: (ctx) => ctx.statusCode === 404 || /404|model_not_found/.test(ctx.message),
274
276
  errorClass: InvalidModelError,
275
277
  message: () => `NVIDIA NIM model '${this.modelName}' not available. Browse the catalog at https://build.nvidia.com/models`,
276
278
  },
@@ -989,7 +989,7 @@ export class OpenAIChatCompletionsProvider extends BaseProvider {
989
989
  // supplied around each call: without them a 429 surfaces as a raw
990
990
  // upstream string instead of a RateLimitError, and a throttle is
991
991
  // never retried.
992
- runStep: (call) => withProviderRetry(call, trace.getActiveSpan() ?? undefined, `${this.providerName} generate`).catch((err) => {
992
+ runStep: (call) => withProviderRetry(call, trace.getActiveSpan() ?? undefined, `${this.providerName} generate`, undefined, options.abortSignal).catch((err) => {
993
993
  throw this.handleProviderError(err);
994
994
  }),
995
995
  }, toolExecutionSummaries);
@@ -2188,7 +2188,7 @@ export class OpenAIChatCompletionsProvider extends BaseProvider {
2188
2188
  };
2189
2189
  let res;
2190
2190
  try {
2191
- res = await withProviderRetry(doFetch, trace.getActiveSpan() ?? undefined, `${this.providerName} stream`);
2191
+ res = await withProviderRetry(doFetch, trace.getActiveSpan() ?? undefined, `${this.providerName} stream`, undefined, args.abortSignal);
2192
2192
  }
2193
2193
  catch (err) {
2194
2194
  // The one-shot 400 context-overflow fallback lives outside
@@ -272,9 +272,9 @@ export type ModelRoutingOptions = {
272
272
  /**
273
273
  * A single model's metadata inside a provider's manifest. This is the one
274
274
  * canonical shape every model-metadata consumer (context windows, pricing,
275
- * MODEL_REGISTRY, vision capability, output-token ceilings) is intended to
276
- * migrate onto — this PR is purely additive and does not yet move any
277
- * consumer over.
275
+ * MODEL_REGISTRY, vision capability, output-token ceilings) reads from —
276
+ * contextWindows.ts, pricing.ts, modelRegistry.ts, providerImageAdapter.ts and
277
+ * core/constants.ts.
278
278
  *
279
279
  * `pricingPerMTok` is optional by design: a model with no verified price
280
280
  * (e.g. a just-announced model pricing.ts hasn't priced yet) must not report
@@ -311,9 +311,10 @@ export type ProviderModelManifestEntry = {
311
311
  * forward verbatim for the ids that already had a MODEL_REGISTRY entry
312
312
  * before this migration. Absent for every id that never had one — those
313
313
  * get performance/useCases/category derived mechanically instead (see
314
- * Task 9's buildModelRegistryFromManifests). Never populate this for a
315
- * genuinely new model: mechanical derivation is the correct default, and
316
- * a fabricated "curated" value would be worse than an honestly-derived one.
314
+ * buildManifestDerivedEntries in src/lib/models/modelRegistry.ts). Never
315
+ * populate this for a genuinely new model: mechanical derivation is the
316
+ * correct default, and a fabricated "curated" value would be worse than an
317
+ * honestly-derived one.
317
318
  */
318
319
  curated?: {
319
320
  performance?: ModelPerformance;
@@ -2408,7 +2408,14 @@ export type ProviderDescriptor = {
2408
2408
  * checks to its own server (TypeSafe). See {@link DecisionLimits}.
2409
2409
  */
2410
2410
  decisionLimits?: DecisionLimits;
2411
- /** Ascending priority (1 = tried first) in the auto-select fallback chain used by getBestProvider(). Undefined = not part of the auto-select chain. */
2411
+ /**
2412
+ * Ascending priority (1 = tried first) in the auto-select fallback chain
2413
+ * used by getBestProvider(). Undefined = not part of the auto-select chain.
2414
+ *
2415
+ * Priorities favor local and self-hosted deployments first to avoid an
2416
+ * external dependency during fallback, then cloud providers according to
2417
+ * reliability, feature set and model coverage.
2418
+ */
2412
2419
  autoSelectPriority?: number;
2413
2420
  /** Format-validation regex sourced from providerConfig.ts's API_KEY_FORMATS, when one exists for this provider. */
2414
2421
  apiKeyFormatPattern?: RegExp;
@@ -21,10 +21,13 @@ export declare function classifyProviderError(error: unknown, rules: ProviderErr
21
21
  /**
22
22
  * Generic fallback rule table covering the five categories every
23
23
  * OpenAI-compatible provider already hand-rolled near-identically:
24
- * auth (401), rate limit (429), model-not-found (404), network/connection
25
- * errors, and 5xx server errors. Providers with a provider-specific auth
26
- * message (naming the exact env var) prepend one override rule and spread
27
- * this table after it — see errorClassifier usage in any migrated
24
+ * auth (401), rate limit (429), model-not-found, network/connection
25
+ * errors, and 5xx server errors. Model-not-found is a 404 whose text names
26
+ * the model or deployment as missing, or the old "model not found" message
27
+ * text at any status; any other 404 stays a plain `ProviderError` carrying
28
+ * the status and the vendor's message. Providers with a provider-specific
29
+ * auth message (naming the exact env var) prepend one override rule and
30
+ * spread this table after it — see errorClassifier usage in any migrated
28
31
  * provider's formatProviderError for the pattern.
29
32
  */
30
33
  export declare const DEFAULT_ERROR_RULES: ProviderErrorRule[];
@@ -113,13 +113,20 @@ export function classifyProviderError(error, rules, provider, modelName) {
113
113
  const message = typeof rule.message === "function" ? rule.message(ctx) : rule.message;
114
114
  return new rule.errorClass(message, provider);
115
115
  }
116
+ // A 404 alone is a route answer (a wrong base URL gives the same reply): it only
117
+ // means "missing model" when the text names a model or deployment as absent.
118
+ // The gap is bounded rather than "no dot" because real model ids contain dots.
119
+ const MODEL_404_TEXT = /model[_ ]?not[_ ]?found|unknown model|no such model|invalid model|unsupported model|\b(?:model|deployment)\b.{0,120}\b(?:does not exist|not found|unavailable|not (?:available|supported))\b|\b(?:does not exist|not found)\b.{0,120}\b(?:model|deployment)\b|unable to access.{0,60}\bmodel\b/i;
116
120
  /**
117
121
  * Generic fallback rule table covering the five categories every
118
122
  * OpenAI-compatible provider already hand-rolled near-identically:
119
- * auth (401), rate limit (429), model-not-found (404), network/connection
120
- * errors, and 5xx server errors. Providers with a provider-specific auth
121
- * message (naming the exact env var) prepend one override rule and spread
122
- * this table after it — see errorClassifier usage in any migrated
123
+ * auth (401), rate limit (429), model-not-found, network/connection
124
+ * errors, and 5xx server errors. Model-not-found is a 404 whose text names
125
+ * the model or deployment as missing, or the old "model not found" message
126
+ * text at any status; any other 404 stays a plain `ProviderError` carrying
127
+ * the status and the vendor's message. Providers with a provider-specific
128
+ * auth message (naming the exact env var) prepend one override rule and
129
+ * spread this table after it — see errorClassifier usage in any migrated
123
130
  * provider's formatProviderError for the pattern.
124
131
  */
125
132
  export const DEFAULT_ERROR_RULES = [
@@ -135,13 +142,18 @@ export const DEFAULT_ERROR_RULES = [
135
142
  message: (ctx) => `${ctx.provider} rate limit exceeded. Please try again later.`,
136
143
  },
137
144
  {
138
- match: (ctx) => ctx.statusCode === 404 ||
139
- /model_not_found|model not found/i.test(ctx.message),
145
+ match: (ctx) => /model_not_found|model not found/i.test(ctx.message) ||
146
+ (ctx.statusCode === 404 && MODEL_404_TEXT.test(ctx.message)),
140
147
  errorClass: InvalidModelError,
141
148
  message: (ctx) => ctx.modelName
142
149
  ? `${ctx.provider} model '${ctx.modelName}' not found.`
143
150
  : `${ctx.provider} model not found.`,
144
151
  },
152
+ {
153
+ match: (ctx) => ctx.statusCode === 404,
154
+ errorClass: ProviderError,
155
+ message: (ctx) => `${ctx.provider} returned HTTP 404: ${ctx.message}`,
156
+ },
145
157
  {
146
158
  // Message regex covers providers/SDKs that surface a code as text
147
159
  // (e.g. AWS SDK wrapping "ECONNRESET" into its own message). errorCode
@@ -2566,7 +2566,14 @@ mediaOptions = {}) {
2566
2566
  });
2567
2567
  try {
2568
2568
  const extracted = await parser.getText();
2569
- const pdfText = (extracted?.text ?? "").trim();
2569
+ // pdf-parse appends a "-- n of N --" marker after every page, so
2570
+ // extracted.text is never empty; a scan is detected from the
2571
+ // per-page text instead.
2572
+ const pageTexts = extracted?.pages?.map((page) => page.text) ?? [
2573
+ extracted?.text ?? "",
2574
+ ];
2575
+ const hasTextLayer = pageTexts.some((text) => text.trim().length > 0);
2576
+ const pdfText = hasTextLayer ? (extracted?.text ?? "").trim() : "";
2570
2577
  if (pdfText.length > 0) {
2571
2578
  content.push({
2572
2579
  type: "text",
@@ -2574,6 +2581,13 @@ mediaOptions = {}) {
2574
2581
  });
2575
2582
  logger.info(`[PDF→Text] ✅ Extracted text for non-vision provider ${provider}: ${name} (${pdfText.length} chars)`);
2576
2583
  }
2584
+ else if (providerCanSeeImages) {
2585
+ content.push({
2586
+ type: "text",
2587
+ text: `\n[Attached PDF: ${name} — no extractable text layer (likely a scanned document); page images are attached below.]`,
2588
+ });
2589
+ logger.warn(`[PDF→Text] ${name} has no text layer; page images follow`);
2590
+ }
2577
2591
  else {
2578
2592
  content.push({
2579
2593
  type: "text",
@@ -15,6 +15,13 @@ import type { CatalogProviderName, ModelChoice } from "../types/index.js";
15
15
  *
16
16
  * AUTO is also excluded — it never had an entry here either (matches
17
17
  * pre-existing behavior: `getDefaultModel(AUTO)` returns `undefined`).
18
+ *
19
+ * This table is not what a call with no model uses. The runtime order is the
20
+ * explicit model, then the provider's environment variable, then the default in
21
+ * the dynamic model configuration, then the registry default
22
+ * (`providerRegistry.ts`); the OpenAI row mirrors that registry default. Only
23
+ * an `OpenAIProvider` constructed directly with none of those falls back to
24
+ * `gpt-5.4` (`openAI/client.ts`).
18
25
  */
19
26
  export declare const DEFAULT_MODELS: Record<Exclude<AIProviderName, CatalogProviderName | AIProviderName.AUTO>, string>;
20
27
  /**
@@ -56,6 +63,9 @@ export declare function getAllProviderChoices(): string[];
56
63
  /**
57
64
  * Get the default model for a provider
58
65
  *
66
+ * Reads `DEFAULT_MODELS`, which mirrors the registry default rather than the
67
+ * runtime resolution order (see the note on that table).
68
+ *
59
69
  * @param provider - The AI provider
60
70
  * @returns Default model string for the provider
61
71
  */
@@ -43,14 +43,19 @@ function catalogTopModels(entry) {
43
43
  */
44
44
  const TOP_MODELS_CONFIG = {
45
45
  [AIProviderName.OPENAI]: [
46
+ {
47
+ model: OpenAIModels.GPT_5_4,
48
+ description: "Recommended - Direct OpenAI GPT-5.4 model",
49
+ },
50
+ { model: OpenAIModels.GPT_5_4_MINI, description: "Cost-effective, fast" },
46
51
  {
47
52
  model: OpenAIModels.GPT_4O,
48
- description: "Recommended - Latest multimodal model",
53
+ description: "Previous generation multimodal model",
49
54
  },
50
55
  { model: OpenAIModels.GPT_4O_MINI, description: "Cost-effective, fast" },
51
56
  {
52
57
  model: OpenAIModels.GPT_5_2,
53
- description: "Latest flagship with deep reasoning",
58
+ description: "Previous flagship with deep reasoning",
54
59
  },
55
60
  { model: OpenAIModels.O3, description: "Advanced reasoning model" },
56
61
  { model: OpenAIModels.GPT_4_TURBO, description: "Previous generation" },
@@ -422,9 +427,16 @@ const TOP_MODELS_CONFIG = {
422
427
  *
423
428
  * AUTO is also excluded — it never had an entry here either (matches
424
429
  * pre-existing behavior: `getDefaultModel(AUTO)` returns `undefined`).
430
+ *
431
+ * This table is not what a call with no model uses. The runtime order is the
432
+ * explicit model, then the provider's environment variable, then the default in
433
+ * the dynamic model configuration, then the registry default
434
+ * (`providerRegistry.ts`); the OpenAI row mirrors that registry default. Only
435
+ * an `OpenAIProvider` constructed directly with none of those falls back to
436
+ * `gpt-5.4` (`openAI/client.ts`).
425
437
  */
426
438
  export const DEFAULT_MODELS = {
427
- [AIProviderName.OPENAI]: OpenAIModels.GPT_4O,
439
+ [AIProviderName.OPENAI]: OpenAIModels.GPT_4O_MINI,
428
440
  [AIProviderName.ANTHROPIC]: AnthropicModels.CLAUDE_SONNET_4_5,
429
441
  [AIProviderName.GOOGLE_AI]: GoogleAIModels.GEMINI_2_5_FLASH,
430
442
  [AIProviderName.VERTEX]: VertexModels.GEMINI_2_5_FLASH,
@@ -572,6 +584,9 @@ export function getAllProviderChoices() {
572
584
  /**
573
585
  * Get the default model for a provider
574
586
  *
587
+ * Reads `DEFAULT_MODELS`, which mirrors the registry default rather than the
588
+ * runtime resolution order (see the note on that table).
589
+ *
575
590
  * @param provider - The AI provider
576
591
  * @returns Default model string for the provider
577
592
  */
@@ -305,10 +305,17 @@ export class ProviderHealthChecker {
305
305
  }
306
306
  return;
307
307
  }
308
+ // A descriptor with no apiKey variable at all (LM Studio, llama.cpp) would
309
+ // otherwise read process.env[""] below and report a missing key named by
310
+ // nothing; hasProviderEnvVars already treats these as usable with defaults.
311
+ const providerDescriptor = ProviderFactory.getDescriptor(providerName);
308
312
  // Providers that don't use API keys directly
309
313
  if (providerName === AIProviderName.OLLAMA ||
310
314
  providerName === AIProviderName.BEDROCK ||
311
- providerName === AIProviderName.LITELLM) {
315
+ providerName === AIProviderName.LITELLM ||
316
+ providerDescriptor?.localRuntime === true ||
317
+ (providerDescriptor?.envVars.optional === true &&
318
+ !providerDescriptor.envVars.apiKey)) {
312
319
  healthStatus.hasApiKey = true;
313
320
  return;
314
321
  }
@@ -996,8 +1003,10 @@ export class ProviderHealthChecker {
996
1003
  ];
997
1004
  case AIProviderName.OPENAI:
998
1005
  return [
999
- OpenAIModels.GPT_4O,
1006
+ OpenAIModels.GPT_5_4,
1007
+ OpenAIModels.GPT_5_4_MINI,
1000
1008
  OpenAIModels.GPT_4O_MINI,
1009
+ OpenAIModels.GPT_4O,
1001
1010
  OpenAIModels.GPT_3_5_TURBO,
1002
1011
  ];
1003
1012
  case AIProviderName.GOOGLE_AI:
@@ -1541,8 +1550,18 @@ export class ProviderHealthChecker {
1541
1550
  return provider;
1542
1551
  }
1543
1552
  }
1544
- // Fallback to first healthy provider
1545
- const firstHealthyProvider = healthStatuses.find((h) => h.isHealthy);
1553
+ // Fallback to first healthy provider. A local runtime that nothing probes
1554
+ // (LM Studio, llama.cpp) is "healthy" only in that it needs no
1555
+ // configuration, which says nothing about whether it is running, so it
1556
+ // must not outrank a provider the caller actually configured.
1557
+ const firstHealthyProvider = healthStatuses.find((h) => {
1558
+ if (!h.isHealthy) {
1559
+ return false;
1560
+ }
1561
+ const descriptor = ProviderFactory.getDescriptor(h.provider);
1562
+ return !(descriptor?.localRuntime === true &&
1563
+ descriptor.healthCheck === "env-only");
1564
+ });
1546
1565
  if (firstHealthyProvider) {
1547
1566
  logger.info(`Using fallback healthy provider: ${firstHealthyProvider.provider}`);
1548
1567
  return firstHealthyProvider.provider;
@@ -86,6 +86,10 @@ export declare function getErrorStatusCode(error: unknown): number | undefined;
86
86
  * @param operation - The async operation to execute (should already use `maxRetries: 0`)
87
87
  * @param span - The OTel span to annotate with retry events and attributes
88
88
  * @param label - A human-readable label for log messages (e.g. "generateText", "streamText")
89
+ * @param sleep - Wait between attempts; receives the delay and the caller's abort signal
90
+ * @param abortSignal - The caller's cancellation. An abort during the wait ends the call with the
91
+ * signal's reason instead of waiting out the delay and running the operation
92
+ * again, and an already-aborted signal is checked before every attempt.
89
93
  * @returns The result of the operation
90
94
  */
91
- export declare function withProviderRetry<T>(operation: () => Promise<T>, span: Span | undefined, label: string, sleep?: (delayMs: number) => Promise<void>): Promise<T>;
95
+ export declare function withProviderRetry<T>(operation: () => Promise<T>, span: Span | undefined, label: string, sleep?: (delayMs: number, abortSignal?: AbortSignal) => Promise<void>, abortSignal?: AbortSignal): Promise<T>;
@@ -33,7 +33,21 @@ export const NO_HINT_FLOOR_MS = 10_000;
33
33
  * get a prompt rate-limit error rather than a silent multi-minute stall.
34
34
  */
35
35
  export const MAX_RETRY_AFTER_MS = 60_000;
36
- const sleepWithTimeout = (delayMs) => new Promise((resolve) => setTimeout(resolve, delayMs));
36
+ const sleepWithTimeout = (delayMs, abortSignal) => new Promise((resolve, reject) => {
37
+ if (abortSignal?.aborted) {
38
+ reject(abortSignal.reason);
39
+ return;
40
+ }
41
+ const onAbort = () => {
42
+ clearTimeout(timer);
43
+ reject(abortSignal?.reason);
44
+ };
45
+ const timer = setTimeout(() => {
46
+ abortSignal?.removeEventListener("abort", onAbort);
47
+ resolve();
48
+ }, delayMs);
49
+ abortSignal?.addEventListener("abort", onAbort, { once: true });
50
+ });
37
51
  /**
38
52
  * Check whether an error thrown by the AI SDK is retryable.
39
53
  *
@@ -244,10 +258,15 @@ function getRetryAfterMs(error) {
244
258
  * @param operation - The async operation to execute (should already use `maxRetries: 0`)
245
259
  * @param span - The OTel span to annotate with retry events and attributes
246
260
  * @param label - A human-readable label for log messages (e.g. "generateText", "streamText")
261
+ * @param sleep - Wait between attempts; receives the delay and the caller's abort signal
262
+ * @param abortSignal - The caller's cancellation. An abort during the wait ends the call with the
263
+ * signal's reason instead of waiting out the delay and running the operation
264
+ * again, and an already-aborted signal is checked before every attempt.
247
265
  * @returns The result of the operation
248
266
  */
249
- export async function withProviderRetry(operation, span, label, sleep = sleepWithTimeout) {
267
+ export async function withProviderRetry(operation, span, label, sleep = sleepWithTimeout, abortSignal) {
250
268
  for (let attempt = 0; attempt <= MAX_PROVIDER_RETRIES; attempt++) {
269
+ abortSignal?.throwIfAborted();
251
270
  try {
252
271
  const result = await operation();
253
272
  // Record how many attempts it took on the span
@@ -314,7 +333,10 @@ export async function withProviderRetry(operation, span, label, sleep = sleepWit
314
333
  statusCode,
315
334
  error: errorMessage,
316
335
  });
317
- await sleep(delay);
336
+ await sleep(delay, abortSignal);
337
+ // A custom sleep may ignore the signal, and a signal can abort in the
338
+ // same tick the timer fires.
339
+ abortSignal?.throwIfAborted();
318
340
  }
319
341
  }
320
342
  // This should never be reached due to the throw inside the loop,
@@ -52,16 +52,8 @@ export async function getBestProvider(requestedProvider) {
52
52
  // Fall through to cloud providers
53
53
  }
54
54
  }
55
- /**
56
- * Provider priority order rationale:
57
- * - LiteLLM and Ollama are prioritized first for local/self-hosted deployments,
58
- * avoiding unnecessary dependence on external providers during fallback scenarios.
59
- * - Vertex (Google Cloud AI) follows for enterprise-grade reliability.
60
- * - Google AI follows as second cloud priority for comprehensive Google AI ecosystem support.
61
- * - OpenAI maintains high priority due to its consistent reliability and broad model support.
62
- * - Other providers are ordered based on a combination of reliability, feature set, and historical performance.
63
- * Please update this comment if the order is changed in the future, and document the rationale for maintainability.
64
- */
55
+ // Order comes from ProviderDescriptor.autoSelectPriority (lower = tried
56
+ // first); see providerDescriptors.ts and the catalog JSON.
65
57
  const providers = PROVIDER_DESCRIPTORS.filter((d) => d.autoSelectPriority !== undefined)
66
58
  .sort((a, b) => (a.autoSelectPriority ?? 0) - (b.autoSelectPriority ?? 0))
67
59
  .map((d) => d.name);
@@ -4727,7 +4727,7 @@
4727
4727
  {"objectID":"8b922e3ee9644559addad4738b5f0c6360fe12ae2d1d0c98d678ddaac03eede9","title":"Troubleshooting","url":"/docs/features/workflow-engine#troubleshooting","content":"| Problem | Solution |\n| --------------------------------- | ---------------------------------------------------------------------------------- |\n| Workflow not found in registry | Register it with registerWorkflow() before calling generate() with workflow: |\n| All models failed | Check API keys, increase timeout, verify provider availability |\n| Judge returns neutral scores (50) | Judge response parsing failed; check judge model supports JSON output |\n| Slow execution | Reduce model count, use faster models, increase parallelism |\n| High costs | Use consensus-3-fast, chain/adaptive workflows, or set costThreshold |\n| Low consensus in multi-judge | Normal for subjective queries; increase judge count or align criteria |","hierarchy":{"lvl0":"Features","lvl1":"Workflow Engine Guide","lvl2":"Troubleshooting","lvl3":""}},
4728
4728
  {"objectID":"e9de380e8339140c2951bda58d6eaaffb28f182c85fbfda7d7679ea6f5af270e","title":"Core Exports","url":"/docs/features/workflow-engine#core-exports","content":"Execution:\nrunWorkflow(config, options) -- Execute a complete workflow\nrunWorkflowWithStreaming(config, options) -- Execute with progressive streaming\nexecuteEnsemble(options) -- Low-level parallel model execution\nexecuteModelGroups(groups, prompt, config) -- Low-level layer-based execution\nscoreEnsemble(options) -- Low-level judge scoring\nconditionResponse(options) -- Low-level response conditioning\n\nConfiguration:\ncreateWorkflowConfig(partial) -- Create config with defaults\nvalidateWorkflow(config) -- Validate workflow configuration\nvalidateForExecution(config) -- Validate for execution readiness\n\nRegistry:\nregisterWorkflow(config, options) -- Register a workflow\nunregisterWorkflow(workflowId) -- Remove a workflow\ngetWorkflow(workflowId) -- Retrieve by ID\nlistWorkflows(options) -- List with filtering\ngetRegistryStats() -- Registry statistics\nclearRegistry() -- Remove all workflows\n\nPre-built Workflows:\nCONSENSUS_3_WORKFLOW -- 3-model ensemble with judge\nCONSENSUS_3_FAST_WORKFLOW -- Fast/cheap 3-model ensemble\nBALANCED_ADAPTIVE_WORKFLOW -- 2-tier balanced adaptive\nQUALITY_MAX_WORKFLOW -- 3-tier quality-maximizing adaptive\nSPEED_FIRST_WORKFLOW -- Speed-optimized adaptive\nAGGRESSIVE_FALLBACK_WORKFLOW -- Fast + parallel premium fallback\nFAST_FALLBACK_WORKFLOW -- Sequential 3-tier fallback\nMULTI_JUDGE_3_WORKFLOW -- 3 models, 2 judges\nMULTI_JUDGE_5_WORKFLOW -- 5 models, 3 judges\n\nFactory Functions:\ncreateConsensus3WithPrompt(systemPrompt) -- Consensus-3 with custom prompt\ncreateAdaptiveWorkflow(tiers, strategy) -- Custom adaptive workflow\ncreateMultiJudgeWorkflow(modelCount, judgeCount) -- Custom multi-judge\n\nMetrics:\ncalculateModelMetrics(responses) -- Per-model metrics\ncalculateConfidence(scores) -- Confidence calculation\ncalculateConsensus(scores) -- Consensus calculation\ngenerateSummaryStats(results) -- Summary statistics\ncompareWorkflows(stats1, stats2) -- Workflow comparison\nformatMetricsForLogging(result) -- Formatted logging output\n\nTypes:\nWorkflowConfig,","hierarchy":{"lvl0":"Features","lvl1":"Workflow Engine Guide","lvl2":"Core Exports","lvl3":""}},
4729
4729
  {"objectID":"fb91715f0910d539aa3342bb53890eb88ef04121ad496d9c8c982c55d6a645d5","title":"See Also","url":"/docs/features/workflow-engine#see-also","content":"Provider Orchestration Guide -- Multi-provider configuration\nObservability Guide -- Tracing workflow executions with Langfuse\nStructured Output Guide -- JSON schema output (note: incompatible with Gemini tools)","hierarchy":{"lvl0":"Features","lvl1":"Workflow Engine Guide","lvl2":"See Also","lvl3":""}},
4730
- {"objectID":"fcc71bbb437aec3313f917118186ae468e33d960b134ccbe3a8151a55970c6a9","title":"🔧 Environment Variables Configuration Guide","url":"/docs/getting-started/environment-variables","content":"🔧 Environment Variables Configuration Guide\n\nThis guide provides comprehensive setup instructions for all AI providers supported by NeuroLink. The CLI automatically loads environment variables from .env files, making configuration seamless.\n\n🚀 Quick Setup\n\nAutomatic .env Loading ✨ NEW!\n\nNeuroLink CLI automatically loads environment variables from .env files in your project directory:\n\nManual Export (Also Supported)\n\n🏗️ Enterprise Configuration Management\n\n✨ NEW: Automatic Backup System\n\nInterface Configuration\n\nPerformance & Optimization\n\n🆕 AI Enhancement Features\n\nBasic Enhancement Configuration\n\nDescription: Configures the AI model used for response quality evaluation when --enable-evaluation flag is used. Uses Google AI's fast Gemini 2.5 Flash model for quick quality assessment.\n\nSupported Models:\ngemini-2.5-flash (default) - Fast evaluation processing\ngemini-2.5-pro - More detailed evaluation (slower)\n\nUsage:\n\n🌐 Universal Evaluation System (Advanced)\n\nPrimary Configuration\n\nNEUROLINK_EVALUATION_PROVIDER: Primary AI provider for evaluation\nOptions: google-ai, openai, anthropic, vertex, bedrock, azure, ollama, huggingface, mistral\nDefault: google-ai\nUsage: Determines which AI provider performs the quality evaluation\n\nNEUROLINK_EVALUATION_MODE: Performance vs quality trade-off\nOptions: fast (cost-effective), balanced (optimal), quality (highest accuracy)\nDefault: fast\nUsage: Selects appropriate model for the provider (e.g., gemini-2.5-flash vs gemini-2.5-pro)\n\nFallback Configuration\n\nNEUROLINK_EVALUATION_FALLBACK_ENABLED: Enable intelligent fallback system\nOptions: true, false\nDefault: true\nUsage: When enabled, automatically tries backup providers if primary fails\n\nNEUROLINK_EVALUATION_FALLBACK_PROVIDERS: Backup provider order\nFormat: Comma-separated provider names\nDefault: openai,anthropic,vertex,bedrock\nUsage: Defines the order of providers to try if primary fails\n\nPerformance Tuning\n\nPerformance Variables:\nTIMEOUT: Maximum time to wait for evaluation (prevents hanging)\nMAX_TOKENS: Limits evaluation response length (controls cost)\nTEMPERATURE: Lower values = more consistent scoring\nRETRY_ATTEMPTS: Number of retry attempts for transient failures\n\nCost Optimization\n\nNEUROLINK_EVALUATION_PREFER_CHEAP: Cost optimization preference\nOptions: true, false\nDefault: true\nUsage: When enabled, prioritizes cheaper providers and models\n\nNEUROLINK_EVALUATION_MAX_COST_PER_EVAL: Cost limit per evaluation\nFormat: Decimal number (USD)\nDefault: 0.01 ($0.01)\nUsage: Prevents expensive evaluations, switches to cheaper providers if needed\n\nComplete Universal Evaluation Example\n\nTesting Universal Evaluation\n\n🏢 Enterprise Proxy Configuration\n\nProxy Environment Variables\n\n| Variable | Description | Example |\n| ------------- | ------------------------------- | ---------------------------------- |\n| HTTPS_PROXY | Proxy server for HTTPS requests | http://proxy.company.com:8080 |\n| HTTP_PROXY | Proxy server for HTTP requests | http://proxy.company.com:8080 |\n| NO_PROXY | Domains to bypass proxy | localhost,127.0.0.1,.company.com |\n\nAuthenticated Proxy\n\nAll NeuroLink providers automatically use proxy settings when configured.\n\nFor detailed proxy setup → See Enterprise & Proxy Setup Guide\n\n🤖 Provider Configuration\nOpenAI\n\nRequired Variables\n\nOptional Variables\n\nHow to Get OpenAI API Key\nVisit OpenAI Platform\nSign up or log in to your account\nNavigate to API Keys section\nClick Create new secret key\nCopy the key (starts with sk-proj- or sk-)\nAdd billing information if required\n\nSupported Models\ngpt-4o (default) - Latest GPT-4 Optimized\ngpt-4o-mini - Faster, cost-effective option\ngpt-4-turbo - High-performance model\ngpt-3.5-turbo - Legacy cost-effective option\nAmazon Bedrock\n\nRequired Variables\n\nModel Configuration (⚠️ Critical)\n\nOptional Variables\n\nHow to Get AWS Credentials\nSign up for AWS Account\nNavigate to IAM Console\nCreate new user with programmatic access\nAttach policy: AmazonBedrockFullAccess\nDownload access key and secret key\nImportant: Request model access in Bedrock console\n\nBedrock Model Access Setup\nGo to AWS Bedrock Console\nNavigate to Model access\nClick Request model access\nSelect desired models (Claude, Titan, etc.)\nSubmit request and wait for approval\n\nSupported Models\nAnthropic Claude:\narn:aws:bedrock:<region>:<account_id>:inference-profile/us.anthropic.claude-3-7-sonnet-20250219-v1:0\narn:aws:bedrock:<region>:<account_id>:inference-profile/us.anthropic.claude-3-5-sonnet-20241022-v2:0\nAmazon Titan:\namazon.titan-text-express-v1\namazon.titan-text-lite-v1\nGoogle Vertex AI\n\nGoogle Vertex AI supports three authentication methods. Choose the one that fits your deployment:\n\nMethod 1: Service Account File (Recommended)\n\nMethod 2: Service Account JSON String\n\nMethod 3: Individual Environment Variables\n\nOptional Variables\n\nHow to Set Up Google Vertex AI\nCreate Google Cloud Project\nEnable Vertex AI API\nCreate Service Account:\nGo to IAM & Admin > Service Ac","hierarchy":{"lvl0":"Getting Started","lvl1":"🔧 Environment Variables Configuration Guide","lvl2":"","lvl3":""}},
4730
+ {"objectID":"fcc71bbb437aec3313f917118186ae468e33d960b134ccbe3a8151a55970c6a9","title":"🔧 Environment Variables Configuration Guide","url":"/docs/getting-started/environment-variables","content":"🔧 Environment Variables Configuration Guide\n\nThis guide provides comprehensive setup instructions for all AI providers supported by NeuroLink. The CLI automatically loads environment variables from .env files, making configuration seamless.\n\n🚀 Quick Setup\n\nAutomatic .env Loading ✨ NEW!\n\nNeuroLink CLI automatically loads environment variables from .env files in your project directory:\n\nManual Export (Also Supported)\n\n🏗️ Enterprise Configuration Management\n\n✨ NEW: Automatic Backup System\n\nInterface Configuration\n\nPerformance & Optimization\n\n🆕 AI Enhancement Features\n\nBasic Enhancement Configuration\n\nDescription: Configures the AI model used for response quality evaluation when --enable-evaluation flag is used. Uses Google AI's fast Gemini 2.5 Flash model for quick quality assessment.\n\nSupported Models:\ngemini-2.5-flash (default) - Fast evaluation processing\ngemini-2.5-pro - More detailed evaluation (slower)\n\nUsage:\n\n🌐 Universal Evaluation System (Advanced)\n\nPrimary Configuration\n\nNEUROLINK_EVALUATION_PROVIDER: Primary AI provider for evaluation\nOptions: google-ai, openai, anthropic, vertex, bedrock, azure, ollama, huggingface, mistral\nDefault: google-ai\nUsage: Determines which AI provider performs the quality evaluation\n\nNEUROLINK_EVALUATION_MODE: Performance vs quality trade-off\nOptions: fast (cost-effective), balanced (optimal), quality (highest accuracy)\nDefault: fast\nUsage: Selects appropriate model for the provider (e.g., gemini-2.5-flash vs gemini-2.5-pro)\n\nFallback Configuration\n\nNEUROLINK_EVALUATION_FALLBACK_ENABLED: Enable intelligent fallback system\nOptions: true, false\nDefault: true\nUsage: When enabled, automatically tries backup providers if primary fails\n\nNEUROLINK_EVALUATION_FALLBACK_PROVIDERS: Backup provider order\nFormat: Comma-separated provider names\nDefault: openai,anthropic,vertex,bedrock\nUsage: Defines the order of providers to try if primary fails\n\nPerformance Tuning\n\nPerformance Variables:\nTIMEOUT: Maximum time to wait for evaluation (prevents hanging)\nMAX_TOKENS: Limits evaluation response length (controls cost)\nTEMPERATURE: Lower values = more consistent scoring\nRETRY_ATTEMPTS: Number of retry attempts for transient failures\n\nCost Optimization\n\nNEUROLINK_EVALUATION_PREFER_CHEAP: Cost optimization preference\nOptions: true, false\nDefault: true\nUsage: When enabled, prioritizes cheaper providers and models\n\nNEUROLINK_EVALUATION_MAX_COST_PER_EVAL: Cost limit per evaluation\nFormat: Decimal number (USD)\nDefault: 0.01 ($0.01)\nUsage: Prevents expensive evaluations, switches to cheaper providers if needed\n\nComplete Universal Evaluation Example\n\nTesting Universal Evaluation\n\n🏢 Enterprise Proxy Configuration\n\nProxy Environment Variables\n\n| Variable | Description | Example |\n| ------------- | ------------------------------- | ---------------------------------- |\n| HTTPS_PROXY | Proxy server for HTTPS requests | http://proxy.company.com:8080 |\n| HTTP_PROXY | Proxy server for HTTP requests | http://proxy.company.com:8080 |\n| NO_PROXY | Domains to bypass proxy | localhost,127.0.0.1,.company.com |\n\nAuthenticated Proxy\n\nAll NeuroLink providers automatically use proxy settings when configured.\n\nFor detailed proxy setup → See Enterprise & Proxy Setup Guide\n\n🤖 Provider Configuration\nOpenAI\n\nRequired Variables\n\nOptional Variables\n\nHow to Get OpenAI API Key\nVisit OpenAI Platform\nSign up or log in to your account\nNavigate to API Keys section\nClick Create new secret key\nCopy the key (starts with sk-proj- or sk-)\nAdd billing information if required\n\nSupported Models\ngpt-5.4 - GPT-5.4 model\ngpt-5.4-mini - Faster, cost-effective GPT-5.4 option\ngpt-4o-mini (default) - Cost-effective, fast\ngpt-4o - Previous generation multimodal model\ngpt-4-turbo - High-performance model\ngpt-3.5-turbo - Legacy cost-effective option\n\nWith no model set, NeuroLink uses the explicit model option, then OPENAI_MODEL, then the default in the model configuration (MODEL_CONFIG_URL, otherwise the repository's config/models.json), then the registry default gpt-4o-mini. Constructing OpenAIProvider directly with none of these falls back to gpt-5.4.\nAmazon Bedrock\n\nRequired Variables\n\nModel Configuration (⚠️ Critical)\n\nOptional Variables\n\nHow to Get AWS Credentials\nSign up for AWS Account\nNavigate to IAM Console\nCreate new user with programmatic access\nAttach policy: AmazonBedrockFullAccess\nDownload access key and secret key\nImportant: Request model access in Bedrock console\n\nBedrock Model Access Setup\nGo to AWS Bedrock Console\nNavigate to Model access\nClick Request model access\nSelect desired models (Claude, Titan, etc.)\nSubmit request and wait for approval\n\nSupported Models\nAnthropic Claude:\narn:aws:bedrock:<region>:<account_id>:inference-profile/us.anthropic.claude-3-7-sonnet-20250219-v1:0\narn:aws:bedrock:<region>:<account_id>:inference-profile/us.anthropic.claude-3-5-sonnet-20241022-v2:0\nAmazon Titan:\namazon.titan-text-express-v1\namazon.titan-text-lite-v1\nGoogle V","hierarchy":{"lvl0":"Getting Started","lvl1":"🔧 Environment Variables Configuration Guide","lvl2":"","lvl3":""}},
4731
4731
  {"objectID":"c81a81fd6221fc873edf4a381a6af70939b66519ee4d4ce31acce9afec8fb5f1","title":"🔧 Environment Variables Configuration Guide","url":"/docs/getting-started/environment-variables#-environment-variables-configuration-guide","content":"This guide provides comprehensive setup instructions for all AI providers supported by NeuroLink. The CLI automatically loads environment variables from .env files, making configuration seamless.","hierarchy":{"lvl0":"Getting Started","lvl1":"🔧 Environment Variables Configuration Guide","lvl2":"🔧 Environment Variables Configuration Guide","lvl3":""}},
4732
4732
  {"objectID":"a78ad3583ac3d28848100b6a1e832a69a5d8d6dd5538da571bcf5d184ef34789","title":"Automatic .env Loading ✨ NEW!","url":"/docs/getting-started/environment-variables#automatic-env-loading-new","content":"NeuroLink CLI automatically loads environment variables from .env files in your project directory:\n\n`bash","hierarchy":{"lvl0":"Getting Started","lvl1":"🔧 Environment Variables Configuration Guide","lvl2":"Automatic .env Loading ✨ NEW!","lvl3":""}},
4733
4733
  {"objectID":"7f0086c723d683ab77c7a74bfeaf8a61a34e60fc87f62f7c8abceeb385bebab3","title":"Create .env file (automatically loaded)","url":"/docs/getting-started/environment-variables#create-env-file-automatically-loaded","content":"echo 'OPENAIAPIKEY=\"sk-your-key\"' > .env\necho 'AWSACCESSKEY_ID=\"your-key\"' >> .env","hierarchy":{"lvl0":"Getting Started","lvl1":"🔧 Environment Variables Configuration Guide","lvl2":"Create .env file (automatically loaded)","lvl3":""}},
@@ -4771,7 +4771,7 @@
4771
4771
  {"objectID":"d5cabd5bf6ae965d7bf7274d74934ba63f7d8b3567bc4b54317270dade223d44","title":"Authenticated Proxy","url":"/docs/getting-started/environment-variables#authenticated-proxy","content":"`bash","hierarchy":{"lvl0":"Getting Started","lvl1":"🔧 Environment Variables Configuration Guide","lvl2":"Authenticated Proxy","lvl3":""}},
4772
4772
  {"objectID":"bf0792704fa31e90694a52e8e293682873f558d49131eba9f2e9a4d2f40498ec","title":"Proxy with username/password authentication","url":"/docs/getting-started/environment-variables#proxy-with-usernamepassword-authentication","content":"HTTPS_PROXY=\"http://username:password@proxy.company.com:8080\"\nHTTP_PROXY=\"http://username:password@proxy.company.com:8080\"\n`\n\nAll NeuroLink providers automatically use proxy settings when configured.\n\nFor detailed proxy setup → See Enterprise & Proxy Setup Guide","hierarchy":{"lvl0":"Getting Started","lvl1":"🔧 Environment Variables Configuration Guide","lvl2":"Proxy with username/password authentication","lvl3":""}},
4773
4773
  {"objectID":"010e6483ced7a9b1fba1740513766a58d6e77b2da14e91d6d3669cfb10eaecc8","title":"How to Get OpenAI API Key","url":"/docs/getting-started/environment-variables#how-to-get-openai-api-key","content":"Visit OpenAI Platform\nSign up or log in to your account\nNavigate to API Keys section\nClick Create new secret key\nCopy the key (starts with sk-proj- or sk-)\nAdd billing information if required","hierarchy":{"lvl0":"Getting Started","lvl1":"🔧 Environment Variables Configuration Guide","lvl2":"How to Get OpenAI API Key","lvl3":""}},
4774
- {"objectID":"dc3d270e290e8328b30e8814d306c2f91955a36a56e2204eba0e8ab3ac284bf1","title":"Supported Models","url":"/docs/getting-started/environment-variables#supported-models","content":"gpt-4o (default) - Latest GPT-4 Optimized\ngpt-4o-mini - Faster, cost-effective option\ngpt-4-turbo - High-performance model\ngpt-3.5-turbo - Legacy cost-effective option","hierarchy":{"lvl0":"Getting Started","lvl1":"🔧 Environment Variables Configuration Guide","lvl2":"Supported Models","lvl3":""}},
4774
+ {"objectID":"dc3d270e290e8328b30e8814d306c2f91955a36a56e2204eba0e8ab3ac284bf1","title":"Supported Models","url":"/docs/getting-started/environment-variables#supported-models","content":"gpt-5.4 - GPT-5.4 model\ngpt-5.4-mini - Faster, cost-effective GPT-5.4 option\ngpt-4o-mini (default) - Cost-effective, fast\ngpt-4o - Previous generation multimodal model\ngpt-4-turbo - High-performance model\ngpt-3.5-turbo - Legacy cost-effective option\n\nWith no model set, NeuroLink uses the explicit model option, then OPENAI_MODEL, then the default in the model configuration (MODEL_CONFIG_URL, otherwise the repository's config/models.json), then the registry default gpt-4o-mini. Constructing OpenAIProvider directly with none of these falls back to gpt-5.4.","hierarchy":{"lvl0":"Getting Started","lvl1":"🔧 Environment Variables Configuration Guide","lvl2":"Supported Models","lvl3":""}},
4775
4775
  {"objectID":"d73a5c2adb25974a196bb6ecad05bc436d23500f98110dc47bd16408df6000a0","title":"Model Configuration (⚠️ Critical)","url":"/docs/getting-started/environment-variables#model-configuration-critical","content":"`bash","hierarchy":{"lvl0":"Getting Started","lvl1":"🔧 Environment Variables Configuration Guide","lvl2":"Model Configuration (⚠️ Critical)","lvl3":""}},
4776
4776
  {"objectID":"122f80d8fffd22fa876007b951e16c9a6406ea21c25e0a4c6bdffa6fb4eb4fe3","title":"Use full inference profile ARN for Anthropic models","url":"/docs/getting-started/environment-variables#use-full-inference-profile-arn-for-anthropic-models","content":"BEDROCK_MODEL=\"arn:aws:bedrock:us-east-2::inference-profile/us.anthropic.claude-3-7-sonnet-20250219-v1:0\"","hierarchy":{"lvl0":"Getting Started","lvl1":"🔧 Environment Variables Configuration Guide","lvl2":"Use full inference profile ARN for Anthropic models","lvl3":""}},
4777
4777
  {"objectID":"760493b55dfa9f12d29701bdea240a7f20e48c40af9ae3cc5038c87ea0a60844","title":"OR use simple model names for non-Anthropic models","url":"/docs/getting-started/environment-variables#or-use-simple-model-names-for-non-anthropic-models","content":"BEDROCK_MODEL=\"amazon.titan-text-express-v1\"\n`","hierarchy":{"lvl0":"Getting Started","lvl1":"🔧 Environment Variables Configuration Guide","lvl2":"OR use simple model names for non-Anthropic models","lvl3":""}},
@@ -4938,7 +4938,9 @@
4938
4938
  {"objectID":"cc96a04c9f262c3c1f6f8b8e7c82407cc63406705250afd22947a3567e151721","title":"Other providers (setup guides in the Provider Guides index)","url":"/docs/getting-started/provider-setup#other-providers-setup-guides-in-the-provider-guides-index","content":"Onboarded via the zero-quirk OpenAI-wire-compatible catalog (Tier 2) — each has its own setup guide under providers/:\nGroq - LPU-accelerated inference; default openai/gpt-oss-120b\nCerebras - Wafer-scale inference; default gpt-oss-120b\nSambaNova - default Meta-Llama-3.3-70B-Instruct\nTogether AI - default meta-llama/Llama-3.3-70B-Instruct-Turbo\nFireworks AI - default accounts/fireworks/models/kimi-k3\nPerplexity - search-augmented models; default sonar\nCloudflare Workers AI - edge inference\nxAI - Grok models; default grok-4.6\nBaseten - default zai-org/GLM-5.3-Flash (BASETEN_API_KEY)\nGMI Cloud - default MiniMaxAI/MiniMax-M3 (GMICLOUD_API_KEY)\nInception Labs - diffusion LLMs; default mercury-2 (INCEPTION_LABS_API_KEY)\nio.net Intelligence - decentralized GPU inference; default meta-llama/Llama-3.3-70B-Instruct (IO_INTELLIGENCE_API_KEY)\nMancer - default deepseek-v4-flash (MANCER_API_KEY); no tool calling\nUpstage - Solar models; default solar-pro4 (UPSTAGE_API_KEY)\nAPI Route - OpenAI-compatible passthrough; default claude-sonnet-4-6 (API_ROUTE_API_KEY)\nDeepInfra - default deepseek-ai/DeepSeek-V4-Flash-0731 (DEEPINFRA_API_KEY); docs- and roster-verified, not yet live-verified\nFeatherless AI - default unsloth/Llama-3.3-70B-Instruct (FEATHERLESS_AI_API_KEY); docs- and roster-verified, not yet live-verified\nChutes - default moonshotai/Kimi-K2.6-TEE (CHUTES_API_KEY); docs- and roster-verified, not yet live-verified\nOVHcloud AI Endpoints - default gpt-oss-120b (OVH_AI_ENDPOINTS_ACCESS_TOKEN); docs- and roster-verified, not yet live-verified\nSarvam AI - default sarvam-105b (SARVAM_API_KEY); docs- and roster-verified, not yet live-verified\nSynthetic - default syn:large:text (SYNTHETIC_API_KEY); docs- and roster-verified, not yet live-verified\nAmbient - default ambient/large (AMBIENT_API_KEY); docs- and roster-verified, not yet live-verified\nInference.net - default glm-5.2 (INFERENCE_API_KEY); docs- and roster-verified, not yet live-verified\nEmpirioLabs AI - default glm-5-3","hierarchy":{"lvl0":"Getting Started","lvl1":"⚙️ Provider Configuration Guide","lvl2":"Other providers (setup guides in the Provider Guides index)","lvl3":""}},
4939
4939
  {"objectID":"d17be3311722218280d0e76731e7344c620c18f5073e07abbc826f3922db976a","title":"💰 Model Availability & Cost Considerations","url":"/docs/getting-started/provider-setup#-model-availability-cost-considerations","content":"Important Notes:\nModel Availability: Specific models may not be available in all regions or require special access\nCost Variations: Pricing differs significantly between providers and models (e.g., Claude 3.5 Sonnet vs GPT-4o)\nRate Limits: Each provider has different rate limits and quota restrictions\nLocal vs Cloud: Ollama (local) has no per-request cost but requires hardware resources\nEnterprise Tiers: AWS Bedrock, Google Vertex AI, and Azure typically offer enterprise pricing\n\nBest Practices:\nUse new NeuroLink() with automatic provider selection for cost-optimized routing\nMonitor usage through built-in analytics to track costs\nConsider local models (Ollama) for development and testing\nCheck provider documentation for current pricing and availability","hierarchy":{"lvl0":"Getting Started","lvl1":"⚙️ Provider Configuration Guide","lvl2":"💰 Model Availability & Cost Considerations","lvl3":""}},
4940
4940
  {"objectID":"3a1bd0ccb708d37a59e2db3650f689f77fba69e91ec88142c7c9b85f1c18057d","title":"🏢 Enterprise Proxy Support","url":"/docs/getting-started/provider-setup#-enterprise-proxy-support","content":"Providers support corporate proxy environments automatically. Simply set environment variables:\n\nNo code changes required - NeuroLink automatically detects and uses proxy settings.\n\nFor detailed proxy setup → See Enterprise & Proxy Setup Guide","hierarchy":{"lvl0":"Getting Started","lvl1":"⚙️ Provider Configuration Guide","lvl2":"🏢 Enterprise Proxy Support","lvl3":""}},
4941
- {"objectID":"1b0159447e4aee3ffd31efe28600cf755e4cc49d50f354e1a59d9574199213d2","title":"Supported Models","url":"/docs/getting-started/provider-setup#supported-models","content":"gpt-4o (default) - Latest multimodal model\ngpt-4o-mini - Cost-effective variant\ngpt-4-turbo - High-performance model","hierarchy":{"lvl0":"Getting Started","lvl1":"⚙️ Provider Configuration Guide","lvl2":"Supported Models","lvl3":""}},
4941
+ {"objectID":"4e800f7c6d1d49fcbf1a5a8613f3449ee6fc0585728904b2f4b2d36dea4ce9ea","title":"Optional Configuration","url":"/docs/getting-started/provider-setup#optional-configuration","content":"`bash","hierarchy":{"lvl0":"Getting Started","lvl1":"⚙️ Provider Configuration Guide","lvl2":"Optional Configuration","lvl3":""}},
4942
+ {"objectID":"f455604e5b971c306f68461570edeca70b81f3a7b6cd9edd89d7e158bdfaddf9","title":"Optional: override the default model (default: gpt-4o-mini)","url":"/docs/getting-started/provider-setup#optional-override-the-default-model-default-gpt-4o-mini","content":"`","hierarchy":{"lvl0":"Getting Started","lvl1":"⚙️ Provider Configuration Guide","lvl2":"Optional: override the default model (default: gpt-4o-mini)","lvl3":""}},
4943
+ {"objectID":"1b0159447e4aee3ffd31efe28600cf755e4cc49d50f354e1a59d9574199213d2","title":"Supported Models","url":"/docs/getting-started/provider-setup#supported-models","content":"gpt-5.4 - GPT-5.4 model\ngpt-5.4-mini - Cost-effective GPT-5.4 variant\ngpt-4o-mini (default) - Cost-effective variant\ngpt-4o - Previous generation multimodal model\ngpt-4-turbo - High-performance model\n\nSee the environment variables guide for the order in which the model is chosen when none is set.","hierarchy":{"lvl0":"Getting Started","lvl1":"⚙️ Provider Configuration Guide","lvl2":"Supported Models","lvl3":""}},
4942
4944
  {"objectID":"27581667470b332f3c1c5159d4345a675be587f71dfb0d0b5d2a342adf1d2d44","title":"Timeout Configuration","url":"/docs/getting-started/provider-setup#timeout-configuration","content":"Default Timeout: 30 seconds\nSupported Formats: Milliseconds (30000), human-readable ('30s', '1m', '5m')\nEnvironment Variable: OPENAI_TIMEOUT='45s' (optional)","hierarchy":{"lvl0":"Getting Started","lvl1":"⚙️ Provider Configuration Guide","lvl2":"Timeout Configuration","lvl3":""}},
4943
4945
  {"objectID":"9c310a3f365a46c6628ae6910d2bb72ec8560e43353e044f6c9b73e5ce8d1798","title":"🚨 Critical Setup Requirements","url":"/docs/getting-started/provider-setup#-critical-setup-requirements","content":"⚠️ IMPORTANT: Anthropic Models Require Inference Profile ARN\n\nFor Anthropic Claude models in Bedrock, you MUST use the full inference profile ARN, not simple model names:\n\n`bash","hierarchy":{"lvl0":"Getting Started","lvl1":"⚙️ Provider Configuration Guide","lvl2":"🚨 Critical Setup Requirements","lvl3":""}},
4944
4946
  {"objectID":"8f68b311be31716cccb17765bab6b712bc3ca441695a69967f7cc3c9cdf8929b","title":"export BEDROCK_MODEL=\"anthropic.claude-3-sonnet-20240229-v1:0\"","url":"/docs/getting-started/provider-setup#export-bedrock_modelanthropicclaude-3-sonnet-20240229-v10","content":"`","hierarchy":{"lvl0":"Getting Started","lvl1":"⚙️ Provider Configuration Guide","lvl2":"export BEDROCK_MODEL=\"anthropic.claude-3-sonnet-20240229-v1:0\"","lvl3":""}},
@@ -6789,7 +6791,7 @@
6789
6791
  {"objectID":"6102cd238f922f95762068dd3d2b3950e839a87ac388ee96bb805db79c47d00e","title":"Use specific model","url":"/docs/getting-started/providers/openai#use-specific-model","content":"pnpm run cli -- generate \"Write a haiku about AI\" \\\n --provider openai \\\n --model \"gpt-4o\"","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Provider Guide","lvl2":"Use specific model","lvl3":""}},
6790
6792
  {"objectID":"b56485bde526a3210810b768ba819d40dffdff5e3cf66309d26c5f53b89e30c1","title":"Interactive loop mode","url":"/docs/getting-started/providers/openai#interactive-loop-mode","content":"pnpm run cli -- loop \\\n --provider openai \\\n --model \"gpt-4o-mini\"\n`","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Provider Guide","lvl2":"Interactive loop mode","lvl3":""}},
6791
6793
  {"objectID":"dc674c0134ff9c1c707403e195849d7738176f984fe0c8226f05877f4951e0cd","title":"Available Models (from OpenAIModels enum)","url":"/docs/getting-started/providers/openai#available-models-from-openaimodels-enum","content":"| Enum Key | Model ID | Series | Context Window | Notes |\n| --------------------- | --------------------- | ------------ | -------------- | ------------------------ |\n| GPT_6_ASTRA | gpt-6-astra | GPT-6 | 1.05M | New (September 2026) |\n| GPT_6_SOL | gpt-6-sol | GPT-6 | 1.05M | New (September 2026) |\n| GPT_6_LUNA | gpt-6-luna | GPT-6 | 1.05M | New (September 2026) |\n| GPT_5_4 | gpt-5.4 | GPT-5.4 | 1.05M | New (March 2026) |\n| GPT_5_4_MINI | gpt-5.4-mini | GPT-5.4 | 400K | New (March 2026) |\n| GPT_5_4_NANO | gpt-5.4-nano | GPT-5.4 | 400K | New (March 2026) |\n| GPT_5_3_CODEX | gpt-5.3-codex | GPT-5.3 | 400K | |\n| GPT_5_2 | gpt-5.2 | GPT-5.2 | 400K | |\n| GPT_5_2_CHAT_LATEST | gpt-5.2-chat-latest | GPT-5.2 | 128K | |\n| GPT_5_2_PRO | gpt-5.2-pro | GPT-5.2 | 400K | |\n| GPT_5_2_CODEX | gpt-5.2-codex | GPT-5.2 | 400K | |\n| GPT_5_1 | gpt-5.1 | GPT-5.1 | 400K | |\n| GPT_5_1_CHAT_LATEST | gpt-5.1-chat-latest | GPT-5.1 | 128K | |\n| GPT_5_1_CODEX | gpt-5.1-codex | GPT-5.1 | 400K | |\n| GPT_5_1_CODEX_MAX | gpt-5.1-codex-max | GPT-5.1 | 400K | |\n| GPT_5_1_CODEX_MINI | gpt-5.1-codex-mini | GPT-5.1 | 400K | |\n| GPT_5 | gpt-5 | GPT-5 | 400K | |\n| GPT_5_MINI","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Provider Guide","lvl2":"Available Models (from OpenAIModels enum)","lvl3":""}},
6792
- {"objectID":"daaa71958d244b14e0a92247a5ea7890e487f466f9647915a9b274196dcf2cd3","title":"Default Model","url":"/docs/getting-started/providers/openai#default-model","content":"The default model when no model is specified is gpt-4o-mini (set via OpenAIModels.GPT_4O_MINI in the provider registry). This can be overridden with the OPENAI_MODEL environment variable.\n\nNote: When using NeuroLink SDK/CLI, the default is gpt-4o-mini. When instantiating OpenAIProvider directly without setting OPENAI_MODEL, the internal fallback is gpt-4o.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Provider Guide","lvl2":"Default Model","lvl3":""}},
6794
+ {"objectID":"daaa71958d244b14e0a92247a5ea7890e487f466f9647915a9b274196dcf2cd3","title":"Default Model","url":"/docs/getting-started/providers/openai#default-model","content":"The default model when no model is specified is gpt-4o-mini (set via OpenAIModels.GPT_4O_MINI in the provider registry). This can be overridden with the OPENAI_MODEL environment variable.\n\nNote: When using NeuroLink SDK/CLI, the default is gpt-4o-mini. When instantiating OpenAIProvider directly without setting OPENAI_MODEL, the internal fallback is gpt-5.4.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Provider Guide","lvl2":"Default Model","lvl3":""}},
6793
6795
  {"objectID":"a722c79038b2a55ddfff8bbe51cc124c6b52334826423cf1b4db83de4e7b9aef","title":"Multimodal Capabilities","url":"/docs/getting-started/providers/openai#multimodal-capabilities","content":"Models listed in VISION_CAPABILITIES for the openai provider support image analysis. This includes the GPT-5 family, GPT-4.1 family, GPT-4o family, and o-series models.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Provider Guide","lvl2":"Multimodal Capabilities","lvl3":""}},
6794
6796
  {"objectID":"c331cb5e1ae253efea1792e057d6a4178c61191fe30972b6974856225af3cb12","title":"Image Analysis","url":"/docs/getting-started/providers/openai#image-analysis","content":"`bash","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Provider Guide","lvl2":"Image Analysis","lvl3":""}},
6795
6797
  {"objectID":"38a79b6cfe051e6742d94758c2df3c0646cae963aab6b4e141db528eb2890eed","title":"From file path (CLI)","url":"/docs/getting-started/providers/openai#from-file-path-cli","content":"pnpm run cli -- generate \"Describe this image\" \\\n --provider openai \\\n --model gpt-4o \\\n --image ./photo.jpg\n\n\nThe provider supports up to **10 images per request** (defined in IMAGE_LIMITS in src/lib/adapters/providerImageAdapter.ts`).","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Provider Guide","lvl2":"From file path (CLI)","lvl3":""}},
@@ -9758,7 +9760,7 @@
9758
9760
  {"objectID":"72e3f0653f5610f5b565dde0eeb5fae0f9c2aa2e077546cf977d08fb5ba16d7a","title":"Environment Variables","url":"/docs/rag/CLI-COVERAGE#environment-variables","content":"The following environment variables can be used to configure default behavior:","hierarchy":{"lvl0":"Rag","lvl1":"RAG Processing - CLI Reference","lvl2":"Environment Variables","lvl3":""}},
9759
9761
  {"objectID":"08692e093a4e83ac5f475c624ccb93198b7787555cb016a315235c899937aa7e","title":"Provider & Authentication","url":"/docs/rag/CLI-COVERAGE#provider-authentication","content":"| Variable | Description | Default |\n| ------------------------- | ---------------------------------------- | -------- |\n| NEUROLINK_PROVIDER | Default AI provider | vertex |\n| AI_PROVIDER | Alternative env var for default provider | vertex |\n| GOOGLE_CLOUD_PROJECT_ID | Google Cloud project ID (for Vertex AI) | - |\n| GOOGLE_API_KEY | Google AI Studio API key | - |\n| OPENAI_API_KEY | OpenAI API key | - |\n| ANTHROPIC_API_KEY | Anthropic API key | - |","hierarchy":{"lvl0":"Rag","lvl1":"RAG Processing - CLI Reference","lvl2":"Provider & Authentication","lvl3":""}},
9760
9762
  {"objectID":"07f864c105b32f6b1fc50e0cb08e2125ef5503b8fba263eb75f440ededc69f8b","title":"Embedding Models (for index and query commands)","url":"/docs/rag/CLI-COVERAGE#embedding-models-for-index-and-query-commands","content":"| Variable | Description | Default |\n| ------------------------------ | ------------------------------ | ------------------------------ |\n| NEUROLINK_EMBEDDING_MODEL | Global default embedding model | Provider-specific default |\n| VERTEX_EMBEDDING_MODEL | Vertex AI embedding model | text-embedding-004 |\n| GOOGLE_EMBEDDING_MODEL | Google AI embedding model | text-embedding-004 |\n| OPENAI_EMBEDDING_MODEL | OpenAI embedding model | text-embedding-3-small |\n| AZURE_OPENAI_EMBEDDING_MODEL | Azure OpenAI embedding model | text-embedding-3-small |\n| BEDROCK_EMBEDDING_MODEL | AWS Bedrock embedding model | amazon.titan-embed-text-v2:0 |","hierarchy":{"lvl0":"Rag","lvl1":"RAG Processing - CLI Reference","lvl2":"Embedding Models (for index and query commands)","lvl3":""}},
9761
- {"objectID":"50663c177a070a66d4944fcf5d84f98d78f14bd15f71691772f0dc73015bf0f1","title":"Generation Models (for chunk --extract and other text generation)","url":"/docs/rag/CLI-COVERAGE#generation-models-for-chunk---extract-and-other-text-generation","content":"| Variable | Description | Default |\n| -------------------- | ------------------------------ | ------------------ |\n| VERTEX_MODEL | Default model for Vertex AI | gemini-2.5-flash |\n| OPENAI_MODEL | Default model for OpenAI | gpt-4o |\n| AZURE_OPENAI_MODEL | Default model for Azure OpenAI | Deployment-based |\n| BEDROCK_MODEL | Default model for AWS Bedrock | Provider-specific |","hierarchy":{"lvl0":"Rag","lvl1":"RAG Processing - CLI Reference","lvl2":"Generation Models (for chunk --extract and other text generation)","lvl3":""}},
9763
+ {"objectID":"50663c177a070a66d4944fcf5d84f98d78f14bd15f71691772f0dc73015bf0f1","title":"Generation Models (for chunk --extract and other text generation)","url":"/docs/rag/CLI-COVERAGE#generation-models-for-chunk---extract-and-other-text-generation","content":"| Variable | Description | Default |\n| -------------------- | ------------------------------ | ------------------ |\n| VERTEX_MODEL | Default model for Vertex AI | gemini-2.5-flash |\n| OPENAI_MODEL | Default model for OpenAI | gpt-4o-mini |\n| AZURE_OPENAI_MODEL | Default model for Azure OpenAI | Deployment-based |\n| BEDROCK_MODEL | Default model for AWS Bedrock | Provider-specific |","hierarchy":{"lvl0":"Rag","lvl1":"RAG Processing - CLI Reference","lvl2":"Generation Models (for chunk --extract and other text generation)","lvl3":""}},
9762
9764
  {"objectID":"6c018c3875b57f47baf2f47fba0097a6ce95bc6057d3455ad0d76888b62885bb","title":"Embedding Model Resolution Order","url":"/docs/rag/CLI-COVERAGE#embedding-model-resolution-order","content":"For index and query commands, the embedding model is resolved in this order:\nCLI --model flag (if it's an embedding model)\nNEUROLINK_EMBEDDING_MODEL (global embedding model)\nProvider-specific embedding env vars (e.g., VERTEX_EMBEDDING_MODEL)\nProvider's default model env var (if it's an embedding model, e.g., if VERTEX_MODEL=text-embedding-004)\nProvider-specific default embedding model (e.g., text-embedding-004 for Vertex)\nFallback: OpenAI text-embedding-3-small\n\nNote: The RAG CLI is smart about model selection. Even if you have VERTEX_MODEL=gemini-2.5-flash set for text generation, the index and query commands will automatically use the appropriate embedding model for your provider.\nIf you explicitly specify a model with --model, ensure it's an embedding model that supports the embed() operation.","hierarchy":{"lvl0":"Rag","lvl1":"RAG Processing - CLI Reference","lvl2":"Embedding Model Resolution Order","lvl3":""}},
9763
9765
  {"objectID":"89a49e923879e964391df538667a2f5c4215cb7d3fc33a55f5b27872411f621e","title":"Common Errors","url":"/docs/rag/CLI-COVERAGE#common-errors","content":"File not found:\n\nEnsure the file path is correct and the file exists.\n\nNo indexed documents:\n\nYou must index a document before querying. Run neurolink rag index <file> first.\n\nIndex not found:\n\nThe specified index name doesn't exist. Check available indices or use the default.","hierarchy":{"lvl0":"Rag","lvl1":"RAG Processing - CLI Reference","lvl2":"Common Errors","lvl3":""}},
9764
9766
  {"objectID":"e2ed24b27e4284131ff513d59ed982787d2eef74c8dcbe04f9c5f8b4e7f74687","title":"Notes","url":"/docs/rag/CLI-COVERAGE#notes","content":"In-memory storage: Currently, indexed documents are stored in memory and will be lost when the process exits. For persistence, use the SDK API with a vector database.\nAuto-detection: When --strategy is not specified, the chunking strategy is automatically detected based on file extension.\nGraph RAG: Building a Graph RAG index (--graph) requires additional processing time but enables context-aware traversal during queries.","hierarchy":{"lvl0":"Rag","lvl1":"RAG Processing - CLI Reference","lvl2":"Notes","lvl3":""}},
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/neurolink",
3
- "version": "12.47.3",
3
+ "version": "12.47.4",
4
4
  "packageManager": "pnpm@10.15.1",
5
5
  "description": "The pipe layer of an AI nervous system: one interface connecting provider neurons to your application, across three inference types — generate, stream and decide. `decide` returns typed, calibrated judgements from a non-generative model (~400ms, ~$0.00002/call) for routing, tool selection and context budgeting. MCP-native (4 transports), voice TTS/STT/realtime, RAG, agents, memory, compaction, 9 observability exporters. OpenAI · Anthropic · Gemini · Bedrock · Azure · Ollama · TypeSafe Jev and more.",
6
6
  "author": {
@@ -261,6 +261,7 @@
261
261
  "test:multimodal:sdk": "pnpm exec tsx test/continuous-test-suite-multimodal-sdk.ts",
262
262
  "test:video-frames": "pnpm exec tsx test/continuous-test-suite-video-frames.ts",
263
263
  "test:video-no-ffprobe": "pnpm exec tsx test/continuous-test-suite-video-no-ffprobe.ts",
264
+ "test:model-default-resolution": "pnpm exec tsx test/continuous-test-suite-model-default-resolution.ts",
264
265
  "test:video-native": "pnpm exec tsx test/continuous-test-suite-video-native.ts",
265
266
  "test:mcp-result-cache": "pnpm exec tsx test/continuous-test-suite-mcp-result-cache.ts",
266
267
  "test:mcp-breaker-resolved-errors": "pnpm exec tsx test/continuous-test-suite-mcp-breaker-resolved-errors.ts",