@juspay/neurolink 10.3.0 → 10.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/browser/neurolink.min.js +430 -417
- package/dist/cli/loop/optionsSchema.js +4 -0
- package/dist/constants/contextWindows.d.ts +24 -0
- package/dist/constants/contextWindows.js +50 -0
- package/dist/context/errorDetection.d.ts +6 -0
- package/dist/context/errorDetection.js +18 -0
- package/dist/context/stepBudgetGuard.d.ts +17 -3
- package/dist/context/stepBudgetGuard.js +53 -14
- package/dist/core/baseProvider.d.ts +12 -0
- package/dist/core/baseProvider.js +18 -0
- package/dist/core/modules/GenerationHandler.js +208 -42
- package/dist/core/modules/ToolsManager.d.ts +17 -0
- package/dist/core/modules/ToolsManager.js +99 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -0
- package/dist/knowledge/context.d.ts +18 -0
- package/dist/knowledge/context.js +91 -0
- package/dist/knowledge/defaults.d.ts +24 -0
- package/dist/knowledge/defaults.js +29 -0
- package/dist/knowledge/engine.d.ts +35 -0
- package/dist/knowledge/engine.js +179 -0
- package/dist/knowledge/index.d.ts +15 -0
- package/dist/knowledge/index.js +15 -0
- package/dist/knowledge/indexCache.d.ts +19 -0
- package/dist/knowledge/indexCache.js +109 -0
- package/dist/knowledge/knowledgeIndex.d.ts +41 -0
- package/dist/knowledge/knowledgeIndex.js +204 -0
- package/dist/knowledge/normalize.d.ts +32 -0
- package/dist/knowledge/normalize.js +74 -0
- package/dist/knowledge/resolve.d.ts +18 -0
- package/dist/knowledge/resolve.js +156 -0
- package/dist/knowledge/retrieval.d.ts +16 -0
- package/dist/knowledge/retrieval.js +221 -0
- package/dist/lib/constants/contextWindows.d.ts +24 -0
- package/dist/lib/constants/contextWindows.js +50 -0
- package/dist/lib/context/errorDetection.d.ts +6 -0
- package/dist/lib/context/errorDetection.js +18 -0
- package/dist/lib/context/stepBudgetGuard.d.ts +17 -3
- package/dist/lib/context/stepBudgetGuard.js +53 -14
- package/dist/lib/core/baseProvider.d.ts +12 -0
- package/dist/lib/core/baseProvider.js +18 -0
- package/dist/lib/core/modules/GenerationHandler.js +208 -42
- package/dist/lib/core/modules/ToolsManager.d.ts +17 -0
- package/dist/lib/core/modules/ToolsManager.js +99 -1
- package/dist/lib/files/fileTools.d.ts +1 -1
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/index.js +3 -0
- package/dist/lib/knowledge/context.d.ts +18 -0
- package/dist/lib/knowledge/context.js +92 -0
- package/dist/lib/knowledge/defaults.d.ts +24 -0
- package/dist/lib/knowledge/defaults.js +30 -0
- package/dist/lib/knowledge/engine.d.ts +35 -0
- package/dist/lib/knowledge/engine.js +180 -0
- package/dist/lib/knowledge/index.d.ts +15 -0
- package/dist/lib/knowledge/index.js +16 -0
- package/dist/lib/knowledge/indexCache.d.ts +19 -0
- package/dist/lib/knowledge/indexCache.js +110 -0
- package/dist/lib/knowledge/knowledgeIndex.d.ts +41 -0
- package/dist/lib/knowledge/knowledgeIndex.js +205 -0
- package/dist/lib/knowledge/normalize.d.ts +32 -0
- package/dist/lib/knowledge/normalize.js +75 -0
- package/dist/lib/knowledge/resolve.d.ts +18 -0
- package/dist/lib/knowledge/resolve.js +157 -0
- package/dist/lib/knowledge/retrieval.d.ts +16 -0
- package/dist/lib/knowledge/retrieval.js +222 -0
- package/dist/lib/mcp/toolDiscoveryService.js +59 -20
- package/dist/lib/neurolink.d.ts +14 -1
- package/dist/lib/neurolink.js +142 -12
- package/dist/lib/providers/litellm.d.ts +27 -19
- package/dist/lib/providers/litellm.js +171 -92
- package/dist/lib/providers/openaiChatCompletionsBase.d.ts +37 -1
- package/dist/lib/providers/openaiChatCompletionsBase.js +201 -33
- package/dist/lib/providers/openaiChatCompletionsClient.d.ts +23 -5
- package/dist/lib/providers/openaiChatCompletionsClient.js +94 -14
- package/dist/lib/proxy/proxyFetch.d.ts +17 -0
- package/dist/lib/proxy/proxyFetch.js +42 -4
- package/dist/lib/types/config.d.ts +12 -0
- package/dist/lib/types/conversation.d.ts +1 -1
- package/dist/lib/types/dynamic.d.ts +12 -0
- package/dist/lib/types/generate.d.ts +32 -2
- package/dist/lib/types/index.d.ts +1 -0
- package/dist/lib/types/index.js +1 -0
- package/dist/lib/types/knowledge.d.ts +342 -0
- package/dist/lib/types/knowledge.js +30 -0
- package/dist/lib/types/openaiCompatible.d.ts +2 -0
- package/dist/lib/types/providers.d.ts +9 -0
- package/dist/lib/types/stream.d.ts +14 -0
- package/dist/lib/utils/errorHandling.js +8 -2
- package/dist/lib/utils/schemaConversion.d.ts +16 -0
- package/dist/lib/utils/schemaConversion.js +165 -8
- package/dist/lib/utils/timeout.d.ts +22 -0
- package/dist/lib/utils/timeout.js +72 -12
- package/dist/lib/utils/tokenLimits.js +22 -0
- package/dist/lib/utils/toolCallRepair.d.ts +8 -0
- package/dist/lib/utils/toolCallRepair.js +4 -1
- package/dist/mcp/toolDiscoveryService.js +59 -20
- package/dist/neurolink.d.ts +14 -1
- package/dist/neurolink.js +142 -12
- package/dist/providers/litellm.d.ts +27 -19
- package/dist/providers/litellm.js +171 -92
- package/dist/providers/openaiChatCompletionsBase.d.ts +37 -1
- package/dist/providers/openaiChatCompletionsBase.js +201 -33
- package/dist/providers/openaiChatCompletionsClient.d.ts +23 -5
- package/dist/providers/openaiChatCompletionsClient.js +94 -14
- package/dist/proxy/proxyFetch.d.ts +17 -0
- package/dist/proxy/proxyFetch.js +42 -4
- package/dist/types/config.d.ts +12 -0
- package/dist/types/conversation.d.ts +1 -1
- package/dist/types/dynamic.d.ts +12 -0
- package/dist/types/generate.d.ts +32 -2
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/knowledge.d.ts +342 -0
- package/dist/types/knowledge.js +29 -0
- package/dist/types/openaiCompatible.d.ts +2 -0
- package/dist/types/providers.d.ts +9 -0
- package/dist/types/stream.d.ts +14 -0
- package/dist/utils/errorHandling.js +8 -2
- package/dist/utils/schemaConversion.d.ts +16 -0
- package/dist/utils/schemaConversion.js +165 -8
- package/dist/utils/timeout.d.ts +22 -0
- package/dist/utils/timeout.js +72 -12
- package/dist/utils/tokenLimits.js +22 -0
- package/dist/utils/toolCallRepair.d.ts +8 -0
- package/dist/utils/toolCallRepair.js +4 -1
- package/package.json +4 -1
package/dist/utils/timeout.d.ts
CHANGED
|
@@ -128,8 +128,30 @@ export declare function createTimeoutController(timeout: number | string | undef
|
|
|
128
128
|
* @returns Combined AbortSignal, or undefined if neither is present
|
|
129
129
|
*/
|
|
130
130
|
export declare function composeAbortSignals(externalSignal?: AbortSignal, timeoutSignal?: AbortSignal): AbortSignal | undefined;
|
|
131
|
+
/**
|
|
132
|
+
* Scoped variant of {@link composeAbortSignals} for per-step / per-request
|
|
133
|
+
* composition against a LONG-LIVED external signal (e.g. the generate-call
|
|
134
|
+
* signal inside a multi-step agent loop). `AbortSignal.any` keeps its source
|
|
135
|
+
* registration alive until the derived signal is GC'd, so composing per step
|
|
136
|
+
* accumulates listeners on the outer signal for the whole turn
|
|
137
|
+
* (MaxListenersExceededWarning at 10+ steps). This helper registers plain
|
|
138
|
+
* listeners instead and returns a `dispose()` that removes them the moment
|
|
139
|
+
* the step settles.
|
|
140
|
+
*/
|
|
141
|
+
export declare function composeAbortSignalsScoped(externalSignal?: AbortSignal, timeoutSignal?: AbortSignal): {
|
|
142
|
+
signal: AbortSignal | undefined;
|
|
143
|
+
dispose: () => void;
|
|
144
|
+
};
|
|
131
145
|
/**
|
|
132
146
|
* Merge abort signals (for combining user abort with timeout)
|
|
147
|
+
*
|
|
148
|
+
* Implemented via `AbortSignal.any` with a single once-listener forward, so
|
|
149
|
+
* no per-source listeners are left behind on long-lived input signals once
|
|
150
|
+
* the merged controller becomes unreachable (registrations are released with
|
|
151
|
+
* the derived signal). The previous implementation attached one permanent
|
|
152
|
+
* listener per source per call — repeated stream calls sharing one caller
|
|
153
|
+
* signal accumulated listeners for the life of that signal.
|
|
154
|
+
*
|
|
133
155
|
* @param signals - Array of abort signals to merge
|
|
134
156
|
* @returns Combined abort controller
|
|
135
157
|
*/
|
package/dist/utils/timeout.js
CHANGED
|
@@ -342,25 +342,85 @@ export function composeAbortSignals(externalSignal, timeoutSignal) {
|
|
|
342
342
|
}
|
|
343
343
|
return externalSignal ?? timeoutSignal;
|
|
344
344
|
}
|
|
345
|
+
/**
|
|
346
|
+
* Scoped variant of {@link composeAbortSignals} for per-step / per-request
|
|
347
|
+
* composition against a LONG-LIVED external signal (e.g. the generate-call
|
|
348
|
+
* signal inside a multi-step agent loop). `AbortSignal.any` keeps its source
|
|
349
|
+
* registration alive until the derived signal is GC'd, so composing per step
|
|
350
|
+
* accumulates listeners on the outer signal for the whole turn
|
|
351
|
+
* (MaxListenersExceededWarning at 10+ steps). This helper registers plain
|
|
352
|
+
* listeners instead and returns a `dispose()` that removes them the moment
|
|
353
|
+
* the step settles.
|
|
354
|
+
*/
|
|
355
|
+
export function composeAbortSignalsScoped(externalSignal, timeoutSignal) {
|
|
356
|
+
if (!externalSignal || !timeoutSignal) {
|
|
357
|
+
return { signal: externalSignal ?? timeoutSignal, dispose: () => { } };
|
|
358
|
+
}
|
|
359
|
+
const controller = new AbortController();
|
|
360
|
+
const sources = [externalSignal, timeoutSignal];
|
|
361
|
+
const listeners = [];
|
|
362
|
+
const dispose = () => {
|
|
363
|
+
for (const { source, listener } of listeners) {
|
|
364
|
+
source.removeEventListener("abort", listener);
|
|
365
|
+
}
|
|
366
|
+
listeners.length = 0;
|
|
367
|
+
};
|
|
368
|
+
const onAbort = (source) => {
|
|
369
|
+
if (!controller.signal.aborted) {
|
|
370
|
+
controller.abort(source.reason);
|
|
371
|
+
}
|
|
372
|
+
// Self-clean on abort: once the composed signal fired, no source
|
|
373
|
+
// listener has any work left — detach from the OTHER source too (the
|
|
374
|
+
// firing one auto-removed via `once`), so callers that only observe
|
|
375
|
+
// `signal.aborted` and never reach their dispose() leave nothing behind.
|
|
376
|
+
dispose();
|
|
377
|
+
};
|
|
378
|
+
for (const source of sources) {
|
|
379
|
+
const listener = () => onAbort(source);
|
|
380
|
+
source.addEventListener("abort", listener, { once: true });
|
|
381
|
+
listeners.push({ source, listener });
|
|
382
|
+
}
|
|
383
|
+
for (const source of sources) {
|
|
384
|
+
if (source.aborted) {
|
|
385
|
+
onAbort(source);
|
|
386
|
+
break;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
return { signal: controller.signal, dispose };
|
|
390
|
+
}
|
|
345
391
|
/**
|
|
346
392
|
* Merge abort signals (for combining user abort with timeout)
|
|
393
|
+
*
|
|
394
|
+
* Implemented via `AbortSignal.any` with a single once-listener forward, so
|
|
395
|
+
* no per-source listeners are left behind on long-lived input signals once
|
|
396
|
+
* the merged controller becomes unreachable (registrations are released with
|
|
397
|
+
* the derived signal). The previous implementation attached one permanent
|
|
398
|
+
* listener per source per call — repeated stream calls sharing one caller
|
|
399
|
+
* signal accumulated listeners for the life of that signal.
|
|
400
|
+
*
|
|
347
401
|
* @param signals - Array of abort signals to merge
|
|
348
402
|
* @returns Combined abort controller
|
|
349
403
|
*/
|
|
350
404
|
export function mergeAbortSignals(signals) {
|
|
351
405
|
const controller = new AbortController();
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
}
|
|
358
|
-
});
|
|
359
|
-
}
|
|
360
|
-
if (signal?.aborted) {
|
|
361
|
-
controller.abort(signal.reason);
|
|
362
|
-
break;
|
|
363
|
-
}
|
|
406
|
+
const active = signals.filter((s) => s !== undefined);
|
|
407
|
+
const aborted = active.find((s) => s.aborted);
|
|
408
|
+
if (aborted) {
|
|
409
|
+
controller.abort(aborted.reason);
|
|
410
|
+
return controller;
|
|
364
411
|
}
|
|
412
|
+
if (active.length === 0) {
|
|
413
|
+
return controller;
|
|
414
|
+
}
|
|
415
|
+
const merged = AbortSignal.any(active);
|
|
416
|
+
merged.addEventListener("abort", () => {
|
|
417
|
+
if (!controller.signal.aborted) {
|
|
418
|
+
controller.abort(merged.reason);
|
|
419
|
+
}
|
|
420
|
+
}, { once: true });
|
|
421
|
+
// Pin the derived signal to the returned controller: sources hold only
|
|
422
|
+
// weak refs to `any()` dependents, so without this strong ref the derived
|
|
423
|
+
// signal (and the forward listener with it) could be GC'd before firing.
|
|
424
|
+
controller.__nlMergedSignal = merged;
|
|
365
425
|
return controller;
|
|
366
426
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Provider-specific token limit utilities
|
|
3
3
|
* Provides safe maxTokens values based on provider and model capabilities
|
|
4
4
|
*/
|
|
5
|
+
import { getRuntimeOutputCeiling } from "../constants/contextWindows.js";
|
|
5
6
|
import { PROVIDER_MAX_TOKENS } from "../core/constants.js";
|
|
6
7
|
import { logger } from "./logger.js";
|
|
7
8
|
import { hasRestrictedOutputLimit, RESTRICTED_OUTPUT_TOKEN_LIMIT, } from "./modelDetection.js";
|
|
@@ -34,6 +35,27 @@ export function getSafeMaxTokens(provider, model, requestedMaxTokens) {
|
|
|
34
35
|
// Otherwise, use the requested value (it's within limits, including 0)
|
|
35
36
|
return requestedMaxTokens;
|
|
36
37
|
}
|
|
38
|
+
// Runtime-discovered output ceiling (e.g. LiteLLM /model/info
|
|
39
|
+
// max_output_tokens): the serving infrastructure's own number for the
|
|
40
|
+
// deployed model, authoritative over the static per-provider table. This
|
|
41
|
+
// both clamps over-large requests to the real cap AND replaces the static
|
|
42
|
+
// provider default for callers that pass no maxTokens — the litellm
|
|
43
|
+
// blanket default (128000) is a context-window-sized value that slashed
|
|
44
|
+
// usable input on total-context backends. Checked AFTER the
|
|
45
|
+
// restricted-model branch so hard caps proven at the origin API (Gemini 3
|
|
46
|
+
// / image models) still win over a proxy that over-advertises them.
|
|
47
|
+
const runtimeCeiling = getRuntimeOutputCeiling(provider, model);
|
|
48
|
+
if (runtimeCeiling !== undefined) {
|
|
49
|
+
if (requestedMaxTokens === undefined || requestedMaxTokens === null) {
|
|
50
|
+
return runtimeCeiling;
|
|
51
|
+
}
|
|
52
|
+
if (requestedMaxTokens > runtimeCeiling) {
|
|
53
|
+
logger.warn(`Requested maxTokens ${requestedMaxTokens} exceeds the advertised ` +
|
|
54
|
+
`${provider}/${model} output ceiling of ${runtimeCeiling}. Using ${runtimeCeiling} instead.`);
|
|
55
|
+
return runtimeCeiling;
|
|
56
|
+
}
|
|
57
|
+
return requestedMaxTokens;
|
|
58
|
+
}
|
|
37
59
|
// Get provider-specific limits
|
|
38
60
|
const providerLimits = PROVIDER_MAX_TOKENS[provider];
|
|
39
61
|
if (!providerLimits) {
|
|
@@ -4,3 +4,11 @@ import type { ToolCallRepairFunction, ToolSet } from "../types/index.js";
|
|
|
4
4
|
* Fully dynamic — reads the tool schema at repair time, no configuration needed.
|
|
5
5
|
*/
|
|
6
6
|
export declare function createToolCallRepair(): ToolCallRepairFunction<ToolSet>;
|
|
7
|
+
/**
|
|
8
|
+
* Coerce a value to match the expected schema type.
|
|
9
|
+
* Handles: string→number, JSON string→object, JSON string→array, value→[value].
|
|
10
|
+
* Exported for reuse by the MCP-layer parameter validator
|
|
11
|
+
* (toolDiscoveryService), which coerces before rejecting so a recoverable
|
|
12
|
+
* mismatch doesn't cost the agent loop a full model round-trip.
|
|
13
|
+
*/
|
|
14
|
+
export declare function coerceType(value: unknown, propSchema: Record<string, unknown>): unknown;
|
|
@@ -173,8 +173,11 @@ function findMatchingKey(inputKey, schemaKeys) {
|
|
|
173
173
|
/**
|
|
174
174
|
* Coerce a value to match the expected schema type.
|
|
175
175
|
* Handles: string→number, JSON string→object, JSON string→array, value→[value].
|
|
176
|
+
* Exported for reuse by the MCP-layer parameter validator
|
|
177
|
+
* (toolDiscoveryService), which coerces before rejecting so a recoverable
|
|
178
|
+
* mismatch doesn't cost the agent loop a full model round-trip.
|
|
176
179
|
*/
|
|
177
|
-
function coerceType(value, propSchema) {
|
|
180
|
+
export function coerceType(value, propSchema) {
|
|
178
181
|
const expectedType = propSchema.type;
|
|
179
182
|
if (!expectedType || value === null || value === undefined) {
|
|
180
183
|
return value;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juspay/neurolink",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.4.0",
|
|
4
4
|
"packageManager": "pnpm@10.15.1",
|
|
5
5
|
"description": "TypeScript AI SDK with 24+ LLM providers behind one consistent API. MCP-native (connect any MCP server), voice TTS/STT/realtime, RAG, agents, memory, context compaction. OpenAI · Anthropic · Gemini · Bedrock · Azure · Ollama · DeepSeek · NVIDIA NIM and more.",
|
|
6
6
|
"author": {
|
|
@@ -80,6 +80,7 @@
|
|
|
80
80
|
"test:mcp:cli": "npx tsx test/continuous-test-suite-mcp-cli.ts",
|
|
81
81
|
"test:mcp:full": "pnpm run test:mcp:infra && pnpm run test:mcp:bash && pnpm run test:mcp:limits && pnpm run test:mcp:spans && pnpm run test:mcp:sdk && pnpm run test:mcp:cli && pnpm run test:mcp:http",
|
|
82
82
|
"test:media": "npx tsx test/continuous-test-suite-media-gen.ts",
|
|
83
|
+
"test:litellm-parity": "npx tsx test/continuous-test-suite-litellm-parity.ts",
|
|
83
84
|
"test:memory": "npx tsx test/continuous-test-suite-memory.ts",
|
|
84
85
|
"test:middleware": "npx tsx test/continuous-test-suite-middleware.ts",
|
|
85
86
|
"test:observability": "npx tsx test/continuous-test-suite-observability.ts",
|
|
@@ -346,6 +347,7 @@
|
|
|
346
347
|
"@anthropic-ai/sdk": "^0.102.0",
|
|
347
348
|
"@anthropic-ai/vertex-sdk": "^0.16.0",
|
|
348
349
|
"@aws-sdk/types": "^3.862.0",
|
|
350
|
+
"@cfworker/json-schema": "^4.1.1",
|
|
349
351
|
"@google/genai": "^1.43.0",
|
|
350
352
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
351
353
|
"@opentelemetry/api-logs": "^0.214.0",
|
|
@@ -382,6 +384,7 @@
|
|
|
382
384
|
"p-limit": "^7.3.0",
|
|
383
385
|
"redis": "^5.11.0",
|
|
384
386
|
"tar-stream": "^3.1.8",
|
|
387
|
+
"type-decoder": "^2.3.1",
|
|
385
388
|
"undici": ">=7.24.0 <8.0.0",
|
|
386
389
|
"ws": "^8.20.1",
|
|
387
390
|
"yargs": "^18.0.0",
|