@juspay/neurolink 11.22.5 → 11.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -2
- package/dist/browser/neurolink.min.js +277 -277
- package/dist/providers/litellm/client.d.ts +12 -0
- package/dist/providers/litellm/client.js +14 -0
- package/dist/providers/openaiChatCompletionsBase.d.ts +13 -0
- package/dist/providers/openaiChatCompletionsBase.js +92 -4
- package/dist/providers/openaiChatCompletionsClient.js +6 -0
- package/dist/rag/ChunkerFactory.d.ts +19 -9
- package/dist/rag/ChunkerFactory.js +23 -8
- package/dist/rag/reranker/RerankerFactory.d.ts +10 -10
- package/dist/rag/reranker/RerankerFactory.js +16 -9
- package/dist/types/openaiCompatible.d.ts +4 -0
- package/dist/utils/timeout.d.ts +7 -0
- package/dist/utils/timeout.js +11 -3
- package/package.json +1 -1
|
@@ -52,6 +52,18 @@ export declare class LiteLLMProvider extends OpenAIChatCompletionsProvider {
|
|
|
52
52
|
protected getDefaultModel(): string;
|
|
53
53
|
protected getFallbackModelName(): string;
|
|
54
54
|
protected getFallbackModels(): string[];
|
|
55
|
+
/**
|
|
56
|
+
* generate() rides the SSE wire for LiteLLM: deployments commonly sit
|
|
57
|
+
* behind proxies/tunnels (e.g. Cloudflare, which 524s an origin that is
|
|
58
|
+
* silent for ~100s), and a non-streaming completion from a slow model
|
|
59
|
+
* sends nothing until it is fully done. Streaming keeps bytes flowing for
|
|
60
|
+
* the whole generation while the base class aggregates into the same
|
|
61
|
+
* complete result — structuredData coercion, tool calls, stopReason,
|
|
62
|
+
* usage and the JSON damage flags are unchanged for callers.
|
|
63
|
+
* Escape hatch: NEUROLINK_LITELLM_SSE_GENERATE=false restores the plain
|
|
64
|
+
* JSON wire.
|
|
65
|
+
*/
|
|
66
|
+
protected useStreamingWireForGenerate(): boolean;
|
|
55
67
|
/**
|
|
56
68
|
* Gemini 2.5 models on LiteLLM have a known compatibility issue with
|
|
57
69
|
* `max_tokens` — strip it before the wire body is built. Applies to
|
|
@@ -248,6 +248,20 @@ export class LiteLLMProvider extends OpenAIChatCompletionsProvider {
|
|
|
248
248
|
"google/gemini-2.5-flash",
|
|
249
249
|
]);
|
|
250
250
|
}
|
|
251
|
+
/**
|
|
252
|
+
* generate() rides the SSE wire for LiteLLM: deployments commonly sit
|
|
253
|
+
* behind proxies/tunnels (e.g. Cloudflare, which 524s an origin that is
|
|
254
|
+
* silent for ~100s), and a non-streaming completion from a slow model
|
|
255
|
+
* sends nothing until it is fully done. Streaming keeps bytes flowing for
|
|
256
|
+
* the whole generation while the base class aggregates into the same
|
|
257
|
+
* complete result — structuredData coercion, tool calls, stopReason,
|
|
258
|
+
* usage and the JSON damage flags are unchanged for callers.
|
|
259
|
+
* Escape hatch: NEUROLINK_LITELLM_SSE_GENERATE=false restores the plain
|
|
260
|
+
* JSON wire.
|
|
261
|
+
*/
|
|
262
|
+
useStreamingWireForGenerate() {
|
|
263
|
+
return process.env.NEUROLINK_LITELLM_SSE_GENERATE !== "false";
|
|
264
|
+
}
|
|
251
265
|
/**
|
|
252
266
|
* Gemini 2.5 models on LiteLLM have a known compatibility issue with
|
|
253
267
|
* `max_tokens` — strip it before the wire body is built. Applies to
|
|
@@ -77,6 +77,19 @@ export declare abstract class OpenAIChatCompletionsProvider extends BaseProvider
|
|
|
77
77
|
* (OpenAI, Azure OpenAI) override this to false.
|
|
78
78
|
*/
|
|
79
79
|
protected suppressResponseFormatWithTools(): boolean;
|
|
80
|
+
/**
|
|
81
|
+
* When true, `doGenerate` puts `stream: true` on the wire and aggregates
|
|
82
|
+
* the SSE stream into the SAME complete result the JSON wire returns —
|
|
83
|
+
* callers still get one awaited result with structuredData coercion, tool
|
|
84
|
+
* calls, finish reason and usage intact. Bytes then flow continuously, so
|
|
85
|
+
* proxy/tunnel idle limits (e.g. Cloudflare's ~100s 524 on tunneled
|
|
86
|
+
* gateways) cannot kill a slow completion, and the request timeout is
|
|
87
|
+
* re-armed on every chunk (idle semantics) instead of capping total
|
|
88
|
+
* duration. Default false: some OpenAI-compatible backends mishandle
|
|
89
|
+
* `stream_options` or omit usage on streams, so each provider opts in
|
|
90
|
+
* deliberately. LiteLLM overrides this to true.
|
|
91
|
+
*/
|
|
92
|
+
protected useStreamingWireForGenerate(): boolean;
|
|
80
93
|
/**
|
|
81
94
|
* Hook to adjust the fully-built wire request body before it is sent, on
|
|
82
95
|
* both the streaming and non-streaming paths. Default identity. Override for
|
|
@@ -108,6 +108,21 @@ export class OpenAIChatCompletionsProvider extends BaseProvider {
|
|
|
108
108
|
suppressResponseFormatWithTools() {
|
|
109
109
|
return true;
|
|
110
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* When true, `doGenerate` puts `stream: true` on the wire and aggregates
|
|
113
|
+
* the SSE stream into the SAME complete result the JSON wire returns —
|
|
114
|
+
* callers still get one awaited result with structuredData coercion, tool
|
|
115
|
+
* calls, finish reason and usage intact. Bytes then flow continuously, so
|
|
116
|
+
* proxy/tunnel idle limits (e.g. Cloudflare's ~100s 524 on tunneled
|
|
117
|
+
* gateways) cannot kill a slow completion, and the request timeout is
|
|
118
|
+
* re-armed on every chunk (idle semantics) instead of capping total
|
|
119
|
+
* duration. Default false: some OpenAI-compatible backends mishandle
|
|
120
|
+
* `stream_options` or omit usage on streams, so each provider opts in
|
|
121
|
+
* deliberately. LiteLLM overrides this to true.
|
|
122
|
+
*/
|
|
123
|
+
useStreamingWireForGenerate() {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
111
126
|
/**
|
|
112
127
|
* Hook to adjust the fully-built wire request body before it is sent, on
|
|
113
128
|
* both the streaming and non-streaming paths. Default identity. Override for
|
|
@@ -387,6 +402,7 @@ export class OpenAIChatCompletionsProvider extends BaseProvider {
|
|
|
387
402
|
const correctBodyAfterContextOverflow = this.correctBodyAfterContextOverflow.bind(this);
|
|
388
403
|
const resolveWireMaxTokens = this.resolveWireMaxTokens.bind(this);
|
|
389
404
|
const suppressResponseFormatWithTools = this.suppressResponseFormatWithTools.bind(this);
|
|
405
|
+
const useStreamingWireForGenerate = this.useStreamingWireForGenerate.bind(this);
|
|
390
406
|
const getTimeoutForOptions = (opts) => this.getTimeout((opts ?? {}));
|
|
391
407
|
return {
|
|
392
408
|
specificationVersion: "v3",
|
|
@@ -414,6 +430,10 @@ export class OpenAIChatCompletionsProvider extends BaseProvider {
|
|
|
414
430
|
// Fit max_tokens to the runtime-discovered output ceiling and
|
|
415
431
|
// context window (no-op when nothing was discovered).
|
|
416
432
|
const wireMaxTokens = resolveWireMaxTokens(modelId, options.maxOutputTokens, baseMessages, wireTools);
|
|
433
|
+
// SSE wire for generate (opt-in per provider): stream on the wire,
|
|
434
|
+
// aggregate below into the same complete response the JSON wire
|
|
435
|
+
// yields. See useStreamingWireForGenerate.
|
|
436
|
+
const sseWire = useStreamingWireForGenerate();
|
|
417
437
|
const body = ensureJsonWordInBody(adjustRequestBody(buildBody({
|
|
418
438
|
modelId,
|
|
419
439
|
messages: baseMessages,
|
|
@@ -432,7 +452,7 @@ export class OpenAIChatCompletionsProvider extends BaseProvider {
|
|
|
432
452
|
toolChoice: v3ToolChoiceToOpenAI(options.toolChoice, wireNameMaps?.toWire),
|
|
433
453
|
}
|
|
434
454
|
: {}),
|
|
435
|
-
streaming:
|
|
455
|
+
streaming: sseWire,
|
|
436
456
|
...(responseFormat ? { responseFormat } : {}),
|
|
437
457
|
}), modelId));
|
|
438
458
|
// Per-step timeout: the AI-SDK V3 call options never carry `timeout`,
|
|
@@ -451,6 +471,10 @@ export class OpenAIChatCompletionsProvider extends BaseProvider {
|
|
|
451
471
|
// this step's listeners the moment the request settles.
|
|
452
472
|
const { signal: composedSignal, dispose: disposeComposedSignal } = composeAbortSignalsScoped(options.abortSignal, timeoutController?.controller.signal);
|
|
453
473
|
let json;
|
|
474
|
+
// Whether the response we end up consuming is SSE. Starts as the
|
|
475
|
+
// provider's wire preference; the 400 fallback below can flip it
|
|
476
|
+
// when a backend rejects `stream`/`stream_options` outright.
|
|
477
|
+
let wireIsStreaming = sseWire;
|
|
454
478
|
try {
|
|
455
479
|
let res = await fetchImpl(url, {
|
|
456
480
|
method: "POST",
|
|
@@ -474,14 +498,26 @@ export class OpenAIChatCompletionsProvider extends BaseProvider {
|
|
|
474
498
|
// attempt, so the configured timeout caps the overall call —
|
|
475
499
|
// matching the streaming path, which reuses its composed signal
|
|
476
500
|
// for the retry.
|
|
477
|
-
const
|
|
501
|
+
const typedErr = apiErr;
|
|
502
|
+
let retryBody = res.status === 400
|
|
478
503
|
? (() => {
|
|
479
|
-
const typedErr = apiErr;
|
|
480
504
|
const overflowCorrected = correctBodyAfterContextOverflow(body, typedErr);
|
|
481
505
|
return (adjustBodyAfter400(overflowCorrected ?? body, typedErr) ??
|
|
482
506
|
overflowCorrected);
|
|
483
507
|
})()
|
|
484
508
|
: undefined;
|
|
509
|
+
// SSE-wire net: a backend that rejects streaming itself (the 400
|
|
510
|
+
// names `stream`/`stream_options`) gets ONE retry on the plain
|
|
511
|
+
// JSON wire. Gated on the error text so a genuine bad request
|
|
512
|
+
// isn't replayed just to fail identically a second time.
|
|
513
|
+
if (!retryBody &&
|
|
514
|
+
sseWire &&
|
|
515
|
+
res.status === 400 &&
|
|
516
|
+
/stream/i.test(typedErr.responseBody ?? "")) {
|
|
517
|
+
const { stream: _stream, stream_options: _streamOptions, ...jsonWireBody } = body;
|
|
518
|
+
retryBody = jsonWireBody;
|
|
519
|
+
wireIsStreaming = false;
|
|
520
|
+
}
|
|
485
521
|
if (!retryBody) {
|
|
486
522
|
throw apiErr;
|
|
487
523
|
}
|
|
@@ -502,7 +538,59 @@ export class OpenAIChatCompletionsProvider extends BaseProvider {
|
|
|
502
538
|
// after cleanup(), so a response whose headers arrived but whose
|
|
503
539
|
// body stalled mid-transfer was bounded by nothing but the caller's
|
|
504
540
|
// outer wall-clock.
|
|
505
|
-
|
|
541
|
+
if (wireIsStreaming) {
|
|
542
|
+
if (!res.body) {
|
|
543
|
+
throw new Error(`${providerName}: streaming generate response had no body`);
|
|
544
|
+
}
|
|
545
|
+
// Idle-timeout semantics: every raw chunk re-arms the timeout,
|
|
546
|
+
// so the configured window bounds silence, not total duration —
|
|
547
|
+
// the whole point of the SSE wire is that a slow-but-alive
|
|
548
|
+
// completion keeps the connection (and the timer) fed.
|
|
549
|
+
const monitored = timeoutController
|
|
550
|
+
? res.body.pipeThrough(new TransformStream({
|
|
551
|
+
transform(chunk, controller) {
|
|
552
|
+
timeoutController.reset();
|
|
553
|
+
controller.enqueue(chunk);
|
|
554
|
+
},
|
|
555
|
+
}))
|
|
556
|
+
: res.body;
|
|
557
|
+
const sse = await parseSSEStream(monitored, () => { });
|
|
558
|
+
// Re-shape the aggregate into the JSON-wire response so every
|
|
559
|
+
// line below this point (content parts, finish-reason mapping,
|
|
560
|
+
// usage clamping, response metadata) is shared verbatim between
|
|
561
|
+
// the two wires and cannot drift.
|
|
562
|
+
json = {
|
|
563
|
+
...(sse.id ? { id: sse.id } : {}),
|
|
564
|
+
...(sse.model ? { model: sse.model } : {}),
|
|
565
|
+
choices: [
|
|
566
|
+
{
|
|
567
|
+
index: 0,
|
|
568
|
+
message: {
|
|
569
|
+
role: "assistant",
|
|
570
|
+
content: sse.text.length > 0 ? sse.text : null,
|
|
571
|
+
...(sse.reasoning ? { reasoning: sse.reasoning } : {}),
|
|
572
|
+
...(sse.toolCalls.size > 0
|
|
573
|
+
? {
|
|
574
|
+
tool_calls: [...sse.toolCalls.values()].map((tc) => ({
|
|
575
|
+
id: tc.id,
|
|
576
|
+
type: "function",
|
|
577
|
+
function: {
|
|
578
|
+
name: tc.name,
|
|
579
|
+
arguments: tc.argsBuffered,
|
|
580
|
+
},
|
|
581
|
+
})),
|
|
582
|
+
}
|
|
583
|
+
: {}),
|
|
584
|
+
},
|
|
585
|
+
finish_reason: sse.finishReason ?? "stop",
|
|
586
|
+
},
|
|
587
|
+
],
|
|
588
|
+
...(sse.usage ? { usage: sse.usage } : {}),
|
|
589
|
+
};
|
|
590
|
+
}
|
|
591
|
+
else {
|
|
592
|
+
json = (await res.json());
|
|
593
|
+
}
|
|
506
594
|
}
|
|
507
595
|
finally {
|
|
508
596
|
timeoutController?.cleanup();
|
|
@@ -531,6 +531,12 @@ export const parseSSEStream = async (body, onTextDelta, onReasoningDelta) => {
|
|
|
531
531
|
if (chunk.usage) {
|
|
532
532
|
result.usage = chunk.usage;
|
|
533
533
|
}
|
|
534
|
+
if (chunk.id && !result.id) {
|
|
535
|
+
result.id = chunk.id;
|
|
536
|
+
}
|
|
537
|
+
if (chunk.model && !result.model) {
|
|
538
|
+
result.model = chunk.model;
|
|
539
|
+
}
|
|
534
540
|
const choice = chunk.choices?.[0];
|
|
535
541
|
if (!choice) {
|
|
536
542
|
return;
|
|
@@ -37,13 +37,23 @@ export declare class ChunkerFactory extends BaseFactory<Chunker, ChunkerConfig>
|
|
|
37
37
|
*/
|
|
38
38
|
createChunker(strategyOrAlias: string, config?: ChunkerConfig): Promise<Chunker>;
|
|
39
39
|
/**
|
|
40
|
-
* Get metadata for a chunker
|
|
40
|
+
* Get metadata for a chunker.
|
|
41
|
+
*
|
|
42
|
+
* Awaits registration first. `metadataMap` and the alias map are populated by
|
|
43
|
+
* `registerAll()`, which only runs via the async `ensureInitialized()` — and
|
|
44
|
+
* the only place that awaited it was `create()`. So on a fresh process this
|
|
45
|
+
* returned `undefined` for every strategy until something happened to build a
|
|
46
|
+
* chunker first, and returned real metadata after. Order-dependent, silent,
|
|
47
|
+
* and `undefined` rather than a throw.
|
|
48
|
+
*
|
|
49
|
+
* `createChunker()` and `getAvailableStrategies()` were already async for
|
|
50
|
+
* exactly this reason; these readers were the ones that had not caught up.
|
|
41
51
|
*/
|
|
42
|
-
getChunkerMetadata(strategyOrAlias: string): ChunkerMetadata | undefined
|
|
52
|
+
getChunkerMetadata(strategyOrAlias: string): Promise<ChunkerMetadata | undefined>;
|
|
43
53
|
/**
|
|
44
54
|
* Get default configuration for a chunker
|
|
45
55
|
*/
|
|
46
|
-
getDefaultConfig(strategyOrAlias: string): ChunkerConfig | undefined
|
|
56
|
+
getDefaultConfig(strategyOrAlias: string): Promise<ChunkerConfig | undefined>;
|
|
47
57
|
/**
|
|
48
58
|
* Get available chunking strategies (not including aliases)
|
|
49
59
|
*/
|
|
@@ -51,19 +61,19 @@ export declare class ChunkerFactory extends BaseFactory<Chunker, ChunkerConfig>
|
|
|
51
61
|
/**
|
|
52
62
|
* Get all aliases mapped to their strategies
|
|
53
63
|
*/
|
|
54
|
-
getStrategyAliases(): Map<string, string
|
|
64
|
+
getStrategyAliases(): Promise<Map<string, string>>;
|
|
55
65
|
/**
|
|
56
66
|
* Check if a strategy exists
|
|
57
67
|
*/
|
|
58
|
-
hasStrategy(strategyOrAlias: string): boolean
|
|
68
|
+
hasStrategy(strategyOrAlias: string): Promise<boolean>;
|
|
59
69
|
/**
|
|
60
70
|
* Get chunkers suitable for a use case
|
|
61
71
|
*/
|
|
62
|
-
getChunkersForUseCase(useCase: string): ChunkingStrategy[]
|
|
72
|
+
getChunkersForUseCase(useCase: string): Promise<ChunkingStrategy[]>;
|
|
63
73
|
/**
|
|
64
74
|
* Get all chunker metadata
|
|
65
75
|
*/
|
|
66
|
-
getAllMetadata(): Map<string, ChunkerMetadata
|
|
76
|
+
getAllMetadata(): Promise<Map<string, ChunkerMetadata>>;
|
|
67
77
|
/**
|
|
68
78
|
* Clear factory and metadata
|
|
69
79
|
*/
|
|
@@ -84,8 +94,8 @@ export declare function getAvailableStrategies(): Promise<ChunkingStrategy[]>;
|
|
|
84
94
|
/**
|
|
85
95
|
* Convenience function to get chunker metadata
|
|
86
96
|
*/
|
|
87
|
-
export declare function getChunkerMetadata(strategyOrAlias: string): ChunkerMetadata | undefined
|
|
97
|
+
export declare function getChunkerMetadata(strategyOrAlias: string): Promise<ChunkerMetadata | undefined>;
|
|
88
98
|
/**
|
|
89
99
|
* Convenience function to get default config
|
|
90
100
|
*/
|
|
91
|
-
export declare function getDefaultConfig(strategyOrAlias: string): ChunkerConfig | undefined
|
|
101
|
+
export declare function getDefaultConfig(strategyOrAlias: string): Promise<ChunkerConfig | undefined>;
|
|
@@ -229,17 +229,28 @@ export class ChunkerFactory extends BaseFactory {
|
|
|
229
229
|
}
|
|
230
230
|
}
|
|
231
231
|
/**
|
|
232
|
-
* Get metadata for a chunker
|
|
232
|
+
* Get metadata for a chunker.
|
|
233
|
+
*
|
|
234
|
+
* Awaits registration first. `metadataMap` and the alias map are populated by
|
|
235
|
+
* `registerAll()`, which only runs via the async `ensureInitialized()` — and
|
|
236
|
+
* the only place that awaited it was `create()`. So on a fresh process this
|
|
237
|
+
* returned `undefined` for every strategy until something happened to build a
|
|
238
|
+
* chunker first, and returned real metadata after. Order-dependent, silent,
|
|
239
|
+
* and `undefined` rather than a throw.
|
|
240
|
+
*
|
|
241
|
+
* `createChunker()` and `getAvailableStrategies()` were already async for
|
|
242
|
+
* exactly this reason; these readers were the ones that had not caught up.
|
|
233
243
|
*/
|
|
234
|
-
getChunkerMetadata(strategyOrAlias) {
|
|
244
|
+
async getChunkerMetadata(strategyOrAlias) {
|
|
245
|
+
await this.ensureInitialized();
|
|
235
246
|
const resolvedName = this.resolveName(strategyOrAlias);
|
|
236
247
|
return this.metadataMap.get(resolvedName);
|
|
237
248
|
}
|
|
238
249
|
/**
|
|
239
250
|
* Get default configuration for a chunker
|
|
240
251
|
*/
|
|
241
|
-
getDefaultConfig(strategyOrAlias) {
|
|
242
|
-
const metadata = this.getChunkerMetadata(strategyOrAlias);
|
|
252
|
+
async getDefaultConfig(strategyOrAlias) {
|
|
253
|
+
const metadata = await this.getChunkerMetadata(strategyOrAlias);
|
|
243
254
|
return metadata?.defaultConfig;
|
|
244
255
|
}
|
|
245
256
|
/**
|
|
@@ -252,20 +263,23 @@ export class ChunkerFactory extends BaseFactory {
|
|
|
252
263
|
/**
|
|
253
264
|
* Get all aliases mapped to their strategies
|
|
254
265
|
*/
|
|
255
|
-
getStrategyAliases() {
|
|
266
|
+
async getStrategyAliases() {
|
|
267
|
+
await this.ensureInitialized();
|
|
256
268
|
return this.getAliases();
|
|
257
269
|
}
|
|
258
270
|
/**
|
|
259
271
|
* Check if a strategy exists
|
|
260
272
|
*/
|
|
261
|
-
hasStrategy(strategyOrAlias) {
|
|
273
|
+
async hasStrategy(strategyOrAlias) {
|
|
274
|
+
await this.ensureInitialized();
|
|
262
275
|
const resolved = this.resolveName(strategyOrAlias);
|
|
263
276
|
return this.has(resolved);
|
|
264
277
|
}
|
|
265
278
|
/**
|
|
266
279
|
* Get chunkers suitable for a use case
|
|
267
280
|
*/
|
|
268
|
-
getChunkersForUseCase(useCase) {
|
|
281
|
+
async getChunkersForUseCase(useCase) {
|
|
282
|
+
await this.ensureInitialized();
|
|
269
283
|
const matches = [];
|
|
270
284
|
const useCaseLower = useCase.toLowerCase();
|
|
271
285
|
for (const [strategy, metadata] of this.metadataMap) {
|
|
@@ -279,7 +293,8 @@ export class ChunkerFactory extends BaseFactory {
|
|
|
279
293
|
/**
|
|
280
294
|
* Get all chunker metadata
|
|
281
295
|
*/
|
|
282
|
-
getAllMetadata() {
|
|
296
|
+
async getAllMetadata() {
|
|
297
|
+
await this.ensureInitialized();
|
|
283
298
|
return new Map(this.metadataMap);
|
|
284
299
|
}
|
|
285
300
|
/**
|
|
@@ -64,11 +64,11 @@ export declare class RerankerFactory extends BaseFactory<Reranker, RerankerConfi
|
|
|
64
64
|
/**
|
|
65
65
|
* Get metadata for a reranker
|
|
66
66
|
*/
|
|
67
|
-
getRerankerMetadata(typeOrAlias: string): RerankerMetadata | undefined
|
|
67
|
+
getRerankerMetadata(typeOrAlias: string): Promise<RerankerMetadata | undefined>;
|
|
68
68
|
/**
|
|
69
69
|
* Get default configuration for a reranker
|
|
70
70
|
*/
|
|
71
|
-
getDefaultConfig(typeOrAlias: string): Partial<RerankerConfig> | undefined
|
|
71
|
+
getDefaultConfig(typeOrAlias: string): Promise<Partial<RerankerConfig> | undefined>;
|
|
72
72
|
/**
|
|
73
73
|
* Get available reranker types (not including aliases)
|
|
74
74
|
*/
|
|
@@ -76,27 +76,27 @@ export declare class RerankerFactory extends BaseFactory<Reranker, RerankerConfi
|
|
|
76
76
|
/**
|
|
77
77
|
* Get all aliases mapped to their types
|
|
78
78
|
*/
|
|
79
|
-
getTypeAliases(): Map<string, string
|
|
79
|
+
getTypeAliases(): Promise<Map<string, string>>;
|
|
80
80
|
/**
|
|
81
81
|
* Check if a type exists
|
|
82
82
|
*/
|
|
83
|
-
hasType(typeOrAlias: string): boolean
|
|
83
|
+
hasType(typeOrAlias: string): Promise<boolean>;
|
|
84
84
|
/**
|
|
85
85
|
* Get rerankers suitable for a use case
|
|
86
86
|
*/
|
|
87
|
-
getRerankersForUseCase(useCase: string): RerankerType[]
|
|
87
|
+
getRerankersForUseCase(useCase: string): Promise<RerankerType[]>;
|
|
88
88
|
/**
|
|
89
89
|
* Get rerankers that don't require external APIs
|
|
90
90
|
*/
|
|
91
|
-
getLocalRerankers(): RerankerType[]
|
|
91
|
+
getLocalRerankers(): Promise<RerankerType[]>;
|
|
92
92
|
/**
|
|
93
93
|
* Get rerankers that don't require AI models
|
|
94
94
|
*/
|
|
95
|
-
getModelFreeRerankers(): RerankerType[]
|
|
95
|
+
getModelFreeRerankers(): Promise<RerankerType[]>;
|
|
96
96
|
/**
|
|
97
97
|
* Get all reranker metadata
|
|
98
98
|
*/
|
|
99
|
-
getAllMetadata(): Map<RerankerType, RerankerMetadata
|
|
99
|
+
getAllMetadata(): Promise<Map<RerankerType, RerankerMetadata>>;
|
|
100
100
|
/**
|
|
101
101
|
* Clear factory and metadata
|
|
102
102
|
*/
|
|
@@ -117,8 +117,8 @@ export declare function getAvailableRerankerTypes(): Promise<RerankerType[]>;
|
|
|
117
117
|
/**
|
|
118
118
|
* Convenience function to get reranker metadata
|
|
119
119
|
*/
|
|
120
|
-
export declare function getRerankerMetadata(typeOrAlias: string): RerankerMetadata | undefined
|
|
120
|
+
export declare function getRerankerMetadata(typeOrAlias: string): Promise<RerankerMetadata | undefined>;
|
|
121
121
|
/**
|
|
122
122
|
* Convenience function to get default config
|
|
123
123
|
*/
|
|
124
|
-
export declare function getRerankerDefaultConfig(typeOrAlias: string): Partial<RerankerConfig> | undefined
|
|
124
|
+
export declare function getRerankerDefaultConfig(typeOrAlias: string): Promise<Partial<RerankerConfig> | undefined>;
|
|
@@ -316,15 +316,16 @@ export class RerankerFactory extends BaseFactory {
|
|
|
316
316
|
/**
|
|
317
317
|
* Get metadata for a reranker
|
|
318
318
|
*/
|
|
319
|
-
getRerankerMetadata(typeOrAlias) {
|
|
319
|
+
async getRerankerMetadata(typeOrAlias) {
|
|
320
|
+
await this.ensureInitialized();
|
|
320
321
|
const resolvedName = this.resolveName(typeOrAlias);
|
|
321
322
|
return this.metadataMap.get(resolvedName);
|
|
322
323
|
}
|
|
323
324
|
/**
|
|
324
325
|
* Get default configuration for a reranker
|
|
325
326
|
*/
|
|
326
|
-
getDefaultConfig(typeOrAlias) {
|
|
327
|
-
const metadata = this.getRerankerMetadata(typeOrAlias);
|
|
327
|
+
async getDefaultConfig(typeOrAlias) {
|
|
328
|
+
const metadata = await this.getRerankerMetadata(typeOrAlias);
|
|
328
329
|
return metadata?.defaultConfig;
|
|
329
330
|
}
|
|
330
331
|
/**
|
|
@@ -337,20 +338,23 @@ export class RerankerFactory extends BaseFactory {
|
|
|
337
338
|
/**
|
|
338
339
|
* Get all aliases mapped to their types
|
|
339
340
|
*/
|
|
340
|
-
getTypeAliases() {
|
|
341
|
+
async getTypeAliases() {
|
|
342
|
+
await this.ensureInitialized();
|
|
341
343
|
return this.getAliases();
|
|
342
344
|
}
|
|
343
345
|
/**
|
|
344
346
|
* Check if a type exists
|
|
345
347
|
*/
|
|
346
|
-
hasType(typeOrAlias) {
|
|
348
|
+
async hasType(typeOrAlias) {
|
|
349
|
+
await this.ensureInitialized();
|
|
347
350
|
const resolved = this.resolveName(typeOrAlias);
|
|
348
351
|
return this.has(resolved);
|
|
349
352
|
}
|
|
350
353
|
/**
|
|
351
354
|
* Get rerankers suitable for a use case
|
|
352
355
|
*/
|
|
353
|
-
getRerankersForUseCase(useCase) {
|
|
356
|
+
async getRerankersForUseCase(useCase) {
|
|
357
|
+
await this.ensureInitialized();
|
|
354
358
|
const matches = [];
|
|
355
359
|
const useCaseLower = useCase.toLowerCase();
|
|
356
360
|
for (const [type, metadata] of this.metadataMap) {
|
|
@@ -364,7 +368,8 @@ export class RerankerFactory extends BaseFactory {
|
|
|
364
368
|
/**
|
|
365
369
|
* Get rerankers that don't require external APIs
|
|
366
370
|
*/
|
|
367
|
-
getLocalRerankers() {
|
|
371
|
+
async getLocalRerankers() {
|
|
372
|
+
await this.ensureInitialized();
|
|
368
373
|
const matches = [];
|
|
369
374
|
for (const [type, metadata] of this.metadataMap) {
|
|
370
375
|
if (!metadata.requiresExternalAPI) {
|
|
@@ -376,7 +381,8 @@ export class RerankerFactory extends BaseFactory {
|
|
|
376
381
|
/**
|
|
377
382
|
* Get rerankers that don't require AI models
|
|
378
383
|
*/
|
|
379
|
-
getModelFreeRerankers() {
|
|
384
|
+
async getModelFreeRerankers() {
|
|
385
|
+
await this.ensureInitialized();
|
|
380
386
|
const matches = [];
|
|
381
387
|
for (const [type, metadata] of this.metadataMap) {
|
|
382
388
|
if (!metadata.requiresModel) {
|
|
@@ -388,7 +394,8 @@ export class RerankerFactory extends BaseFactory {
|
|
|
388
394
|
/**
|
|
389
395
|
* Get all reranker metadata
|
|
390
396
|
*/
|
|
391
|
-
getAllMetadata() {
|
|
397
|
+
async getAllMetadata() {
|
|
398
|
+
await this.ensureInitialized();
|
|
392
399
|
return new Map(this.metadataMap);
|
|
393
400
|
}
|
|
394
401
|
/**
|
|
@@ -199,6 +199,10 @@ export type OpenAICompatSSEResult = {
|
|
|
199
199
|
}>;
|
|
200
200
|
finishReason: "stop" | "length" | "tool_calls" | "function_call" | "content_filter" | null;
|
|
201
201
|
usage?: OpenAICompatUsage;
|
|
202
|
+
/** Response id from the first stream chunk that carried one. */
|
|
203
|
+
id?: string;
|
|
204
|
+
/** Served model from the first stream chunk that carried one. */
|
|
205
|
+
model?: string;
|
|
202
206
|
};
|
|
203
207
|
export type OpenAICompatStreamChunk = {
|
|
204
208
|
content: string;
|
package/dist/utils/timeout.d.ts
CHANGED
|
@@ -116,6 +116,13 @@ export declare function withStreamingTimeout<T>(generator: AsyncGenerator<T>, ti
|
|
|
116
116
|
export declare function createTimeoutController(timeout: number | string | undefined, provider: string, operation: "generate" | "stream"): {
|
|
117
117
|
controller: AbortController;
|
|
118
118
|
cleanup: () => void;
|
|
119
|
+
/**
|
|
120
|
+
* Re-arm the timeout window from now. Streaming consumers call this on
|
|
121
|
+
* every chunk so the timeout bounds *idle* time rather than total
|
|
122
|
+
* duration — a slow-but-alive upstream is not killed mid-generation.
|
|
123
|
+
* No-op once the controller has already aborted.
|
|
124
|
+
*/
|
|
125
|
+
reset: () => void;
|
|
119
126
|
timeoutMs: number;
|
|
120
127
|
} | null;
|
|
121
128
|
/**
|
package/dist/utils/timeout.js
CHANGED
|
@@ -313,7 +313,7 @@ export function createTimeoutController(timeout, provider, operation) {
|
|
|
313
313
|
return null;
|
|
314
314
|
}
|
|
315
315
|
const controller = new AbortController();
|
|
316
|
-
const
|
|
316
|
+
const fire = () => {
|
|
317
317
|
// NOTE: we cannot stamp the AI SDK's ai.streamText/ai.generateText span
|
|
318
318
|
// from here — the setTimeout callback runs in the async context captured
|
|
319
319
|
// at schedule time, which is BEFORE the AI SDK span exists. Instead we
|
|
@@ -321,11 +321,19 @@ export function createTimeoutController(timeout, provider, operation) {
|
|
|
321
321
|
// wrapper, which sets span.status = ERROR + message. ContextEnricher's
|
|
322
322
|
// SpanStatusCode.ERROR branch then surfaces level=ERROR + status_message.
|
|
323
323
|
controller.abort(new TimeoutError(`${provider} ${operation} operation timed out after ${timeout}`, timeoutMs, provider, operation));
|
|
324
|
-
}
|
|
324
|
+
};
|
|
325
|
+
let timer = setTimeout(fire, timeoutMs);
|
|
325
326
|
const cleanup = () => {
|
|
326
327
|
clearTimeout(timer);
|
|
327
328
|
};
|
|
328
|
-
|
|
329
|
+
const reset = () => {
|
|
330
|
+
if (controller.signal.aborted) {
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
clearTimeout(timer);
|
|
334
|
+
timer = setTimeout(fire, timeoutMs);
|
|
335
|
+
};
|
|
336
|
+
return { controller, cleanup, reset, timeoutMs };
|
|
329
337
|
}
|
|
330
338
|
/**
|
|
331
339
|
* Compose an external abort signal with a timeout controller's signal.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juspay/neurolink",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.23.1",
|
|
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": {
|