@juspay/neurolink 12.15.1 → 12.17.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 +7 -2
- package/dist/browser/neurolink.min.js +377 -373
- package/dist/constants/enums.d.ts +11 -0
- package/dist/constants/enums.js +12 -0
- package/dist/context/nativeGenerateGuard.d.ts +6 -0
- package/dist/context/nativeGenerateGuard.js +192 -0
- package/dist/context/toolOutputLimits.js +76 -5
- package/dist/core/modules/ToolsManager.d.ts +45 -3
- package/dist/core/modules/ToolsManager.js +193 -8
- package/dist/core/nativeGenerateLoop.js +25 -5
- package/dist/providers/catalog/api-route.json +130 -0
- package/dist/providers/catalog/index.generated.d.ts +1 -1
- package/dist/providers/catalog/index.generated.js +3 -0
- package/dist/providers/catalog/schema.d.ts +1 -1
- package/dist/providers/openaiChatCompletionsBase.js +15 -0
- package/dist/types/config.d.ts +10 -0
- package/dist/types/context.d.ts +15 -0
- package/dist/types/generate.d.ts +9 -0
- package/dist/types/providerCatalog.generated.d.ts +2 -2
- package/dist/types/providers.d.ts +4 -0
- package/dist/utils/tokenEstimation.d.ts +13 -0
- package/dist/utils/tokenEstimation.js +6 -1
- package/package.json +3 -1
|
@@ -118,6 +118,20 @@ export async function runNativeGenerateLoop(args, toolExecutionSummaries) {
|
|
|
118
118
|
const hasTools = Boolean(args.tools && args.tools.length > 0);
|
|
119
119
|
for (let step = 0; step < args.maxSteps; step++) {
|
|
120
120
|
steps = step + 1;
|
|
121
|
+
// Per-step context reclaim. The pre-dispatch budget check runs ONCE and
|
|
122
|
+
// never sees the assistant turns and tool results this loop appends, which
|
|
123
|
+
// is how a long agentic run overflows the model window mid-loop and loses
|
|
124
|
+
// every completed step to a provider 400. The streaming paths have guarded
|
|
125
|
+
// this for a while; generate() did not, so the identical turn reclaimed on
|
|
126
|
+
// stream() and overflowed on generate().
|
|
127
|
+
//
|
|
128
|
+
// The provider supplies the guard because only it knows its wire shape.
|
|
129
|
+
// Returning undefined leaves the conversation byte-identical, so a turn
|
|
130
|
+
// that fits never pays a prompt-cache invalidation.
|
|
131
|
+
const guarded = args.guardConversation?.(args.conversation);
|
|
132
|
+
if (guarded) {
|
|
133
|
+
args.conversation.splice(0, args.conversation.length, ...guarded);
|
|
134
|
+
}
|
|
121
135
|
const runThisStep = () => args.runStep(() => args.doGenerate({
|
|
122
136
|
prompt: args.conversation,
|
|
123
137
|
...(args.tools && args.tools.length > 0 ? { tools: args.tools } : {}),
|
|
@@ -169,6 +183,7 @@ export async function runNativeGenerateLoop(args, toolExecutionSummaries) {
|
|
|
169
183
|
throw stepError;
|
|
170
184
|
}
|
|
171
185
|
reaskPending = false;
|
|
186
|
+
args.observeUsage?.(res.usage);
|
|
172
187
|
const parts = asParts(res.content);
|
|
173
188
|
// Each step REPLACES the text rather than appending: the final step's
|
|
174
189
|
// answer is the turn's answer, matching what generateText reported.
|
|
@@ -177,11 +192,16 @@ export async function runNativeGenerateLoop(args, toolExecutionSummaries) {
|
|
|
177
192
|
.map((p) => p.text)
|
|
178
193
|
.join("");
|
|
179
194
|
// Reasoner models (DeepSeek `reasoning_content`, gateway `reasoning`,
|
|
180
|
-
// OpenAI o-series) emit reasoning as its own V3 content part.
|
|
181
|
-
//
|
|
182
|
-
// `
|
|
183
|
-
//
|
|
184
|
-
|
|
195
|
+
// OpenAI o-series) emit reasoning as its own V3 content part.
|
|
196
|
+
//
|
|
197
|
+
// Unlike `text`, this ACCUMULATES across steps. Each step's answer
|
|
198
|
+
// supersedes the last, but each step's reasoning is its own thought:
|
|
199
|
+
// replacing meant a tool loop reported only whatever the final step
|
|
200
|
+
// happened to think, which is usually the shortest part and frequently
|
|
201
|
+
// empty once the model just answers from the tool result. Concatenating
|
|
202
|
+
// with nothing between them is what a stream() consumer accumulates from
|
|
203
|
+
// the per-step reasoning chunks, so both surfaces agree on the turn.
|
|
204
|
+
reasoning += parts
|
|
185
205
|
.filter((p) => p.type === "reasoning" && typeof p.text === "string")
|
|
186
206
|
.map((p) => p.text)
|
|
187
207
|
.join("");
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "./provider-catalog.schema.json",
|
|
3
|
+
"id": "api-route",
|
|
4
|
+
"displayName": "API Route",
|
|
5
|
+
"aliases": ["apiroute"],
|
|
6
|
+
"tier": 2,
|
|
7
|
+
"wire": {
|
|
8
|
+
"baseURL": "https://global.api-route.com/v1"
|
|
9
|
+
},
|
|
10
|
+
"models": {
|
|
11
|
+
"default": "claude-sonnet-4-6",
|
|
12
|
+
"fallbacks": ["claude-haiku-4-5", "deepseek-v4-flash", "gemini-3.8-flash"],
|
|
13
|
+
"defaultContextWindow": 1000000,
|
|
14
|
+
"defaultMaxOutputTokens": 64000,
|
|
15
|
+
"catalog": {
|
|
16
|
+
"claude-sonnet-4-6": {
|
|
17
|
+
"contextWindow": 1000000,
|
|
18
|
+
"maxOutputTokens": 64000,
|
|
19
|
+
"vision": true,
|
|
20
|
+
"status": "production",
|
|
21
|
+
"description": "Claude Sonnet 4.6 — flagship model with 1M context, tool calling, and multimodal vision"
|
|
22
|
+
},
|
|
23
|
+
"claude-haiku-4-5": {
|
|
24
|
+
"contextWindow": 200000,
|
|
25
|
+
"maxOutputTokens": 32768,
|
|
26
|
+
"vision": true,
|
|
27
|
+
"status": "production",
|
|
28
|
+
"description": "Claude Haiku 4.5 — fast, high-efficiency model with 200K context, tool calling, and vision"
|
|
29
|
+
},
|
|
30
|
+
"deepseek-v4-flash": {
|
|
31
|
+
"contextWindow": 1000000,
|
|
32
|
+
"maxOutputTokens": 64000,
|
|
33
|
+
"vision": false,
|
|
34
|
+
"status": "production",
|
|
35
|
+
"description": "DeepSeek V4 Flash — fast, cost-effective reasoning model with 1M context"
|
|
36
|
+
},
|
|
37
|
+
"deepseek-v4-pro": {
|
|
38
|
+
"contextWindow": 1000000,
|
|
39
|
+
"maxOutputTokens": 64000,
|
|
40
|
+
"vision": false,
|
|
41
|
+
"status": "production",
|
|
42
|
+
"description": "DeepSeek V4 Pro — powerful reasoning model with 1M context"
|
|
43
|
+
},
|
|
44
|
+
"gemini-3.8-flash": {
|
|
45
|
+
"contextWindow": 1000000,
|
|
46
|
+
"maxOutputTokens": 64000,
|
|
47
|
+
"vision": true,
|
|
48
|
+
"status": "production",
|
|
49
|
+
"description": "Gemini 3.8 Flash — high-speed multimodal model supporting image input and streaming"
|
|
50
|
+
},
|
|
51
|
+
"qwen3.8-flash": {
|
|
52
|
+
"contextWindow": 128000,
|
|
53
|
+
"maxOutputTokens": 16384,
|
|
54
|
+
"vision": false,
|
|
55
|
+
"status": "production",
|
|
56
|
+
"description": "Qwen 3.8 Flash — versatile, fast model for general instruction and coding tasks"
|
|
57
|
+
},
|
|
58
|
+
"kimi-k2.7-code": {
|
|
59
|
+
"contextWindow": 256000,
|
|
60
|
+
"maxOutputTokens": 32768,
|
|
61
|
+
"vision": false,
|
|
62
|
+
"status": "production",
|
|
63
|
+
"description": "Kimi K2.7 Code — specialized for coding and multi-step reasoning"
|
|
64
|
+
},
|
|
65
|
+
"glm-5.3-flash": {
|
|
66
|
+
"contextWindow": 128000,
|
|
67
|
+
"maxOutputTokens": 16384,
|
|
68
|
+
"vision": false,
|
|
69
|
+
"status": "production",
|
|
70
|
+
"description": "GLM 5.3 Flash — lightweight, fast conversational and instruction-following model"
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"visionModel": "claude-sonnet-4-6",
|
|
74
|
+
"topModels": [
|
|
75
|
+
"claude-sonnet-4-6",
|
|
76
|
+
"claude-haiku-4-5",
|
|
77
|
+
"deepseek-v4-flash",
|
|
78
|
+
"gemini-3.8-flash",
|
|
79
|
+
"qwen3.8-flash"
|
|
80
|
+
]
|
|
81
|
+
},
|
|
82
|
+
"capabilities": {
|
|
83
|
+
"text": true,
|
|
84
|
+
"streaming": true,
|
|
85
|
+
"tools": true,
|
|
86
|
+
"toolsWithStreaming": true,
|
|
87
|
+
"structuredOutput": true,
|
|
88
|
+
"structuredOutputWithTools": true,
|
|
89
|
+
"embeddings": false,
|
|
90
|
+
"thinking": false
|
|
91
|
+
},
|
|
92
|
+
"errorRules": [
|
|
93
|
+
{
|
|
94
|
+
"pattern": "该分组下模型无可用渠道|model_not_found",
|
|
95
|
+
"class": "invalid-model",
|
|
96
|
+
"message": "Model '{model}' not found or has no available channels on API Route."
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"pattern": "无效的令牌",
|
|
100
|
+
"class": "authentication",
|
|
101
|
+
"message": "Invalid API Route API key. Check {apiKeyEnvVar}."
|
|
102
|
+
}
|
|
103
|
+
],
|
|
104
|
+
"setup": {
|
|
105
|
+
"url": "https://api-route.com",
|
|
106
|
+
"apiKeyFormat": null,
|
|
107
|
+
"billingPolicy": "free-tier",
|
|
108
|
+
"instructions": [
|
|
109
|
+
"1. Visit: https://api-route.com and create an account",
|
|
110
|
+
"2. Generate an API key in your console / dashboard",
|
|
111
|
+
"3. Set {apiKeyEnvVar} in your .env file"
|
|
112
|
+
]
|
|
113
|
+
},
|
|
114
|
+
"evidence": {
|
|
115
|
+
"rosterVerified": {
|
|
116
|
+
"date": "2026-09-17",
|
|
117
|
+
"method": "authenticated GET /v1/models",
|
|
118
|
+
"status": 200
|
|
119
|
+
},
|
|
120
|
+
"authProbe": {
|
|
121
|
+
"date": "2026-09-17",
|
|
122
|
+
"status": 401
|
|
123
|
+
},
|
|
124
|
+
"liveMatrix": {
|
|
125
|
+
"date": "2026-09-17",
|
|
126
|
+
"result": "Verified live against https://global.api-route.com/v1: GET /v1/models returned 70 models. Chat completions, streaming, function calling, streamed function calling, and structured JSON output (json_object and json_schema) verified. Multimodal vision verified on claude-sonnet-4-6, claude-haiku-4-5, and gemini-3.8-flash. Invalid API key returns 401 (无效的令牌) and invalid model returns 503 (model_not_found)."
|
|
127
|
+
},
|
|
128
|
+
"addedInPR": "pending"
|
|
129
|
+
}
|
|
130
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { ProviderCatalogJson } from "../../types/index.js";
|
|
2
2
|
export declare const CATALOG_JSON_ENTRIES: ProviderCatalogJson[];
|
|
3
|
-
export declare const CATALOG_PROVIDER_IDS: readonly ["baseten", "cerebras", "cloudflare", "fireworks", "gmicloud", "groq", "inception-labs", "io-intelligence", "mancer", "mistral", "perplexity", "sambanova", "together-ai", "upstage", "xai"];
|
|
3
|
+
export declare const CATALOG_PROVIDER_IDS: readonly ["api-route", "baseten", "cerebras", "cloudflare", "fireworks", "gmicloud", "groq", "inception-labs", "io-intelligence", "mancer", "mistral", "perplexity", "sambanova", "together-ai", "upstage", "xai"];
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// GENERATED FILE — do not edit. Regenerate with `pnpm run codegen:catalog`.
|
|
2
2
|
// Source of truth: the per-provider JSON files in this directory.
|
|
3
|
+
import apiRouteJson from "./api-route.json" with { type: "json" };
|
|
3
4
|
import basetenJson from "./baseten.json" with { type: "json" };
|
|
4
5
|
import cerebrasJson from "./cerebras.json" with { type: "json" };
|
|
5
6
|
import cloudflareJson from "./cloudflare.json" with { type: "json" };
|
|
@@ -16,6 +17,7 @@ import togetherAiJson from "./together-ai.json" with { type: "json" };
|
|
|
16
17
|
import upstageJson from "./upstage.json" with { type: "json" };
|
|
17
18
|
import xaiJson from "./xai.json" with { type: "json" };
|
|
18
19
|
export const CATALOG_JSON_ENTRIES = [
|
|
20
|
+
apiRouteJson,
|
|
19
21
|
basetenJson,
|
|
20
22
|
cerebrasJson,
|
|
21
23
|
cloudflareJson,
|
|
@@ -33,6 +35,7 @@ export const CATALOG_JSON_ENTRIES = [
|
|
|
33
35
|
xaiJson,
|
|
34
36
|
];
|
|
35
37
|
export const CATALOG_PROVIDER_IDS = [
|
|
38
|
+
"api-route",
|
|
36
39
|
"baseten",
|
|
37
40
|
"cerebras",
|
|
38
41
|
"cloudflare",
|
|
@@ -73,8 +73,8 @@ export declare const providerCatalogJsonSchema: z.ZodObject<{
|
|
|
73
73
|
class: z.ZodEnum<{
|
|
74
74
|
network: "network";
|
|
75
75
|
provider: "provider";
|
|
76
|
-
authentication: "authentication";
|
|
77
76
|
"invalid-model": "invalid-model";
|
|
77
|
+
authentication: "authentication";
|
|
78
78
|
"rate-limit": "rate-limit";
|
|
79
79
|
}>;
|
|
80
80
|
message: z.ZodString;
|
|
@@ -20,6 +20,8 @@
|
|
|
20
20
|
import { trace } from "@opentelemetry/api";
|
|
21
21
|
import { getAvailableInputTokens, getRuntimeContextWindow, getRuntimeOutputCeiling, registerRuntimeContextWindow, } from "../constants/contextWindows.js";
|
|
22
22
|
import { guardOpenAICompatConversation } from "../context/openaiCompatLoopGuard.js";
|
|
23
|
+
import { estimateTokens, serializeForEstimate, } from "../utils/tokenEstimation.js";
|
|
24
|
+
import { createNativeGenerateGuard } from "../context/nativeGenerateGuard.js";
|
|
23
25
|
import { isContextOverflowError, parseProviderOverflowDetails, } from "../context/errorDetection.js";
|
|
24
26
|
import { ContextBudgetExceededError } from "../context/errors.js";
|
|
25
27
|
import { BaseProvider } from "../core/baseProvider.js";
|
|
@@ -899,6 +901,19 @@ export class OpenAIChatCompletionsProvider extends BaseProvider {
|
|
|
899
901
|
// legal again on a vendor that refuses the two together.
|
|
900
902
|
withTools = true) => runNativeGenerateLoop({
|
|
901
903
|
doGenerate,
|
|
904
|
+
...createNativeGenerateGuard({
|
|
905
|
+
provider: this.providerName,
|
|
906
|
+
availableInputTokens: getAvailableInputTokens(this.providerName, modelId, options.maxTokens ?? undefined),
|
|
907
|
+
// Runs on every step of the generate loop, so a cyclic or
|
|
908
|
+
// oversized tool schema must not throw the turn away. Shares the
|
|
909
|
+
// estimator's own serializer: its fallback over-reports, which
|
|
910
|
+
// makes the guard fire rather than silently size the overhead at
|
|
911
|
+
// nothing.
|
|
912
|
+
getFixedOverheadTokens: () => estimateTokens(serializeForEstimate({
|
|
913
|
+
tools: v3Tools,
|
|
914
|
+
responseFormat: format,
|
|
915
|
+
}), this.providerName),
|
|
916
|
+
}),
|
|
902
917
|
conversation: conv,
|
|
903
918
|
...(withTools && v3Tools ? { tools: v3Tools } : {}),
|
|
904
919
|
toolsRecord,
|
package/dist/types/config.d.ts
CHANGED
|
@@ -415,6 +415,16 @@ export type ToolConfig = {
|
|
|
415
415
|
enableMCPTools?: boolean;
|
|
416
416
|
/** Whether the bash command execution tool should be enabled (opt-in, defaults to false) */
|
|
417
417
|
enableBashTool?: boolean;
|
|
418
|
+
/**
|
|
419
|
+
* Byte ceiling for the safety-net truncation `ToolsManager` applies to
|
|
420
|
+
* every direct/custom/external-MCP tool result before it reaches the AI
|
|
421
|
+
* SDK accumulator (BZ-666). Independent of `mcp.outputLimits`, which only
|
|
422
|
+
* governs external MCP results earlier in the pipeline via its own
|
|
423
|
+
* externalize-to-artifact-store strategy. Default: 51200 (50 KB) —
|
|
424
|
+
* unchanged from the previous hard-coded ceiling, so existing consumers
|
|
425
|
+
* see no behavior change unless they set this explicitly.
|
|
426
|
+
*/
|
|
427
|
+
outputTruncationMaxBytes?: number;
|
|
418
428
|
};
|
|
419
429
|
/**
|
|
420
430
|
* Backup metadata information
|
package/dist/types/context.d.ts
CHANGED
|
@@ -373,6 +373,15 @@ export type ToolOutputPreviewOptions = {
|
|
|
373
373
|
headRatio?: number;
|
|
374
374
|
/** Fraction of preview budget allocated to the tail (default: 0.75) */
|
|
375
375
|
tailRatio?: number;
|
|
376
|
+
/**
|
|
377
|
+
* Override the omission notice spliced between head and tail. A string is
|
|
378
|
+
* used verbatim; a function receives the omitted byte count and returns
|
|
379
|
+
* the notice text. When omitted, the built-in default is used, which
|
|
380
|
+
* names the `retrieve_context` tool — pass this when that tool is not
|
|
381
|
+
* registered on the calling instance so the model isn't pointed at a tool
|
|
382
|
+
* that doesn't exist.
|
|
383
|
+
*/
|
|
384
|
+
notice?: string | ((omittedBytes: number) => string);
|
|
376
385
|
};
|
|
377
386
|
/** Result of tool output preview generation. */
|
|
378
387
|
export type ToolOutputPreviewResult = {
|
|
@@ -562,4 +571,10 @@ export type FileSummarizationServiceOptions = {
|
|
|
562
571
|
provider?: string;
|
|
563
572
|
model?: string;
|
|
564
573
|
};
|
|
574
|
+
/** Per-turn configuration for reclaiming a native V3 conversation. */
|
|
575
|
+
export type NativeGenerateGuardConfig = {
|
|
576
|
+
provider: string;
|
|
577
|
+
availableInputTokens: number;
|
|
578
|
+
getFixedOverheadTokens: () => number;
|
|
579
|
+
};
|
|
565
580
|
export {};
|
package/dist/types/generate.d.ts
CHANGED
|
@@ -1604,6 +1604,15 @@ export type GenerateOptionsNormalized = GenerateOptions & {
|
|
|
1604
1604
|
* `doGenerate`; the provider supplies the wire details.
|
|
1605
1605
|
*/
|
|
1606
1606
|
export type NativeGenerateLoopArgs = {
|
|
1607
|
+
/** Observed usage for calibrating the next step against the last request. */
|
|
1608
|
+
observeUsage?: (usage: unknown) => void;
|
|
1609
|
+
/**
|
|
1610
|
+
* Per-step context reclaim, called before every model call with the
|
|
1611
|
+
* conversation as it now stands. Return a replacement to have the loop adopt
|
|
1612
|
+
* it, or undefined to leave it untouched. The provider owns this because the
|
|
1613
|
+
* reclaim has to understand its wire shape.
|
|
1614
|
+
*/
|
|
1615
|
+
guardConversation?: (conversation: Array<Record<string, unknown>>) => Array<Record<string, unknown>> | undefined;
|
|
1607
1616
|
doGenerate: (options: Record<string, unknown>) => Promise<Record<string, unknown>>;
|
|
1608
1617
|
/** Conversation in the message-builder shape each doGenerate converts itself. */
|
|
1609
1618
|
conversation: Array<Record<string, unknown>>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export type CatalogProviderName = "baseten" | "cerebras" | "cloudflare" | "fireworks" | "gmicloud" | "groq" | "inception-labs" | "io-intelligence" | "mancer" | "mistral" | "perplexity" | "sambanova" | "together-ai" | "upstage" | "xai";
|
|
2
|
-
export type CatalogCredentialKey = "baseten" | "cerebras" | "cloudflare" | "fireworks" | "gmicloud" | "groq" | "inceptionLabs" | "ioIntelligence" | "mancer" | "mistral" | "perplexity" | "sambanova" | "together" | "upstage" | "xai";
|
|
1
|
+
export type CatalogProviderName = "api-route" | "baseten" | "cerebras" | "cloudflare" | "fireworks" | "gmicloud" | "groq" | "inception-labs" | "io-intelligence" | "mancer" | "mistral" | "perplexity" | "sambanova" | "together-ai" | "upstage" | "xai";
|
|
2
|
+
export type CatalogCredentialKey = "apiRoute" | "baseten" | "cerebras" | "cloudflare" | "fireworks" | "gmicloud" | "groq" | "inceptionLabs" | "ioIntelligence" | "mancer" | "mistral" | "perplexity" | "sambanova" | "together" | "upstage" | "xai";
|
|
@@ -47,6 +47,19 @@ export declare function getProviderMultiplier(provider?: string): number;
|
|
|
47
47
|
* @returns Estimated token count
|
|
48
48
|
*/
|
|
49
49
|
export declare function estimateTokens(text: string, provider?: string, isCode?: boolean): number;
|
|
50
|
+
/**
|
|
51
|
+
* Serialize an arbitrary value for estimation. Never throws: `JSON.stringify`
|
|
52
|
+
* raises RangeError once a value exceeds V8's max string length, and a tool
|
|
53
|
+
* argument blob is exactly the shape that gets there. A payload that large is
|
|
54
|
+
* charged at the fallback size rather than aborting the estimate (and with it
|
|
55
|
+
* the whole turn).
|
|
56
|
+
*/
|
|
57
|
+
/**
|
|
58
|
+
* Serialize a value for token estimation. The fallback is deliberately huge:
|
|
59
|
+
* an estimator that cannot measure a value must over-report, so a budget guard
|
|
60
|
+
* fires rather than waving through content it failed to size.
|
|
61
|
+
*/
|
|
62
|
+
export declare function serializeForEstimate(value: unknown): string;
|
|
50
63
|
/**
|
|
51
64
|
* Estimate token count for a single ChatMessage.
|
|
52
65
|
* Includes message framing overhead.
|
|
@@ -93,7 +93,12 @@ export function estimateTokens(text, provider, isCode) {
|
|
|
93
93
|
* charged at the fallback size rather than aborting the estimate (and with it
|
|
94
94
|
* the whole turn).
|
|
95
95
|
*/
|
|
96
|
-
|
|
96
|
+
/**
|
|
97
|
+
* Serialize a value for token estimation. The fallback is deliberately huge:
|
|
98
|
+
* an estimator that cannot measure a value must over-report, so a budget guard
|
|
99
|
+
* fires rather than waving through content it failed to size.
|
|
100
|
+
*/
|
|
101
|
+
export function serializeForEstimate(value) {
|
|
97
102
|
if (typeof value === "string") {
|
|
98
103
|
return value;
|
|
99
104
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juspay/neurolink",
|
|
3
|
-
"version": "12.
|
|
3
|
+
"version": "12.17.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": {
|
|
@@ -166,7 +166,9 @@
|
|
|
166
166
|
"test:agents-live": "tsx test/continuous-test-agents-live.ts",
|
|
167
167
|
"test:tool-routing-cli": "pnpm exec tsx test/continuous-test-suite-tool-routing-cli.ts",
|
|
168
168
|
"test:tool-dedup": "pnpm exec tsx test/continuous-test-suite-tool-dedup.ts",
|
|
169
|
+
"test:tools-manager-truncation": "pnpm exec tsx test/continuous-test-suite-tools-manager-truncation.ts",
|
|
169
170
|
"test:model-not-found-retryable": "pnpm exec tsx test/continuous-test-suite-model-not-found-retryable.ts",
|
|
171
|
+
"test:reasoning-parity-live": "pnpm exec tsx test/continuous-test-suite-reasoning-parity-live.ts",
|
|
170
172
|
"test:ci": "pnpm run test && pnpm run test:client && pnpm run test:hitl",
|
|
171
173
|
"// CI tier — fast, no live AI calls, safe for every commit (test:unit; also see the separate provider-safety-net CI job, which runs build + test:providers-mocked + test:provider-structure + test:error-classifier-contract on every PR)": "",
|
|
172
174
|
"test:tool-routing": "pnpm exec tsx test/continuous-test-suite-tool-routing.ts",
|