@juspay/neurolink 12.12.11 → 12.12.13
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 +2 -2
- package/dist/browser/neurolink.min.js +216 -216
- package/dist/constants/contextWindows.js +1 -0
- package/dist/constants/enums.d.ts +1 -0
- package/dist/constants/enums.js +7 -0
- package/dist/core/baseProvider.js +4 -4
- package/dist/core/modules/structuredOutputPolicy.d.ts +6 -6
- package/dist/core/modules/structuredOutputPolicy.js +6 -6
- package/dist/core/nativeGenerateLoop.js +11 -0
- package/dist/core/nativeToolFormat.js +2 -2
- package/dist/factories/providerDescriptors.js +1 -1
- package/dist/factories/providerRegistry.js +4 -1
- package/dist/neurolink.js +1 -1
- package/dist/providers/amazonSagemaker.js +1 -0
- package/dist/providers/anthropic/cacheControl.d.ts +3 -3
- package/dist/providers/anthropic/cacheControl.js +3 -3
- package/dist/providers/anthropic/client.js +26 -8
- package/dist/providers/configuredOpenAICompat.d.ts +1 -1
- package/dist/providers/configuredOpenAICompat.js +1 -1
- package/dist/providers/googleAiStudio/client.js +2 -3
- package/dist/providers/googleVertex/client.js +2 -2
- package/dist/providers/nvidiaNim/client.js +11 -1
- package/dist/providers/openaiChatCompletionsBase.d.ts +4 -4
- package/dist/providers/openaiChatCompletionsBase.js +11 -10
- package/dist/types/context.d.ts +0 -22
- package/dist/types/generate.d.ts +2 -17
- package/dist/types/providers.d.ts +1 -27
- package/dist/utils/anthropicCacheBreakpoints.d.ts +6 -6
- package/dist/utils/anthropicCacheBreakpoints.js +6 -6
- package/dist/utils/json/coerce.d.ts +3 -2
- package/dist/utils/json/coerce.js +3 -2
- package/dist/utils/modelChoices.js +1 -1
- package/dist/utils/pricing.js +8 -0
- package/dist/utils/tokenUtils.d.ts +0 -1
- package/dist/utils/tokenUtils.js +0 -1
- package/dist/utils/tool.js +0 -3
- package/docs-site/static/search-index.json +1 -1
- package/package.json +3 -1
- package/dist/context/stepBudgetGuard.d.ts +0 -61
- package/dist/context/stepBudgetGuard.js +0 -357
- package/dist/core/serviceRegistry.d.ts +0 -40
- package/dist/core/serviceRegistry.js +0 -112
|
@@ -644,6 +644,7 @@ export declare enum DeepSeekModels {
|
|
|
644
644
|
* Note: NIM hosts hundreds of models; pass arbitrary IDs via --model.
|
|
645
645
|
*/
|
|
646
646
|
export declare enum NvidiaNimModels {
|
|
647
|
+
GPT_OSS_20B = "openai/gpt-oss-20b",
|
|
647
648
|
LLAMA_3_3_70B_INSTRUCT = "meta/llama-3.3-70b-instruct",
|
|
648
649
|
LLAMA_3_1_405B_INSTRUCT = "meta/llama-3.1-405b-instruct",
|
|
649
650
|
LLAMA_3_1_70B_INSTRUCT = "meta/llama-3.1-70b-instruct",
|
package/dist/constants/enums.js
CHANGED
|
@@ -872,6 +872,13 @@ export var DeepSeekModels;
|
|
|
872
872
|
*/
|
|
873
873
|
export var NvidiaNimModels;
|
|
874
874
|
(function (NvidiaNimModels) {
|
|
875
|
+
// NVIDIA retired a large part of this list upstream on 2026-08-26 —
|
|
876
|
+
// llama-3.3-70b, llama-3.1-70b, llama-3.2-90b-vision, the deepseek-r1
|
|
877
|
+
// distill and gemma-3-27b all answer "no longer available" now. The members
|
|
878
|
+
// are kept so existing callers still compile, but the provider default
|
|
879
|
+
// below must point at something live: gpt-oss-20b is on the current roster
|
|
880
|
+
// and was probed for text, streaming, tool calling and structured output.
|
|
881
|
+
NvidiaNimModels["GPT_OSS_20B"] = "openai/gpt-oss-20b";
|
|
875
882
|
// Meta Llama
|
|
876
883
|
NvidiaNimModels["LLAMA_3_3_70B_INSTRUCT"] = "meta/llama-3.3-70b-instruct";
|
|
877
884
|
NvidiaNimModels["LLAMA_3_1_405B_INSTRUCT"] = "meta/llama-3.1-405b-instruct";
|
|
@@ -1260,7 +1260,7 @@ export class BaseProvider {
|
|
|
1260
1260
|
[ATTR.NL_PROVIDER]: this.providerName || "unknown",
|
|
1261
1261
|
},
|
|
1262
1262
|
});
|
|
1263
|
-
// Set this span as the active context so child spans (
|
|
1263
|
+
// Set this span as the active context so child spans (provider calls, tool executions) become descendants
|
|
1264
1264
|
const activeCtx = trace.setSpan(context.active(), otelSpan);
|
|
1265
1265
|
const otelSpanState = { ended: false };
|
|
1266
1266
|
return await context.with(activeCtx, async () => this.runGenerateInActiveContext(options, startTime, otelSpan, otelSpanState));
|
|
@@ -1706,9 +1706,9 @@ export class BaseProvider {
|
|
|
1706
1706
|
analytics: result.analytics,
|
|
1707
1707
|
evaluation: result.evaluation,
|
|
1708
1708
|
audio: result.audio,
|
|
1709
|
-
// Forward reasoning fields populated by
|
|
1710
|
-
// reasoning parts (DeepSeek `reasoning_content`, Anthropic
|
|
1711
|
-
// Gemini thought parts, OpenAI o1).
|
|
1709
|
+
// Forward reasoning fields populated by the native generate loop from
|
|
1710
|
+
// vendor reasoning parts (DeepSeek `reasoning_content`, Anthropic
|
|
1711
|
+
// thinking, Gemini thought parts, OpenAI o1).
|
|
1712
1712
|
reasoning: result.reasoning,
|
|
1713
1713
|
reasoningTokens: result.reasoningTokens,
|
|
1714
1714
|
};
|
|
@@ -25,12 +25,12 @@ export declare function isGeminiProvider(providerName: string, modelName: string
|
|
|
25
25
|
* matched here (different transport, no conflict).
|
|
26
26
|
*
|
|
27
27
|
* Being excluded here no longer means the schema is LOST for provider
|
|
28
|
-
* "anthropic":
|
|
29
|
-
* `providerOptions.anthropic.finalResultSchema
|
|
30
|
-
* additive `final_result` tool (see providers/anthropic/structuredOutput.ts)
|
|
31
|
-
* schema enforcement without giving up tool calling. "bedrock" has no such
|
|
32
|
-
* handling (it talks to the raw AWS SDK directly
|
|
33
|
-
*
|
|
28
|
+
* "anthropic": the client puts the JSON Schema on
|
|
29
|
+
* `providerOptions.anthropic.finalResultSchema` and its `doGenerate` appends
|
|
30
|
+
* an additive `final_result` tool (see providers/anthropic/structuredOutput.ts)
|
|
31
|
+
* — schema enforcement without giving up tool calling. "bedrock" has no such
|
|
32
|
+
* handling (it talks to the raw AWS SDK directly) and still falls back to
|
|
33
|
+
* text-mode coercion.
|
|
34
34
|
*/
|
|
35
35
|
export declare function isNativeAnthropicProvider(providerName: string): boolean;
|
|
36
36
|
/**
|
|
@@ -35,12 +35,12 @@ export function isGeminiProvider(providerName, modelName) {
|
|
|
35
35
|
* matched here (different transport, no conflict).
|
|
36
36
|
*
|
|
37
37
|
* Being excluded here no longer means the schema is LOST for provider
|
|
38
|
-
* "anthropic":
|
|
39
|
-
* `providerOptions.anthropic.finalResultSchema
|
|
40
|
-
* additive `final_result` tool (see providers/anthropic/structuredOutput.ts)
|
|
41
|
-
* schema enforcement without giving up tool calling. "bedrock" has no such
|
|
42
|
-
* handling (it talks to the raw AWS SDK directly
|
|
43
|
-
*
|
|
38
|
+
* "anthropic": the client puts the JSON Schema on
|
|
39
|
+
* `providerOptions.anthropic.finalResultSchema` and its `doGenerate` appends
|
|
40
|
+
* an additive `final_result` tool (see providers/anthropic/structuredOutput.ts)
|
|
41
|
+
* — schema enforcement without giving up tool calling. "bedrock" has no such
|
|
42
|
+
* handling (it talks to the raw AWS SDK directly) and still falls back to
|
|
43
|
+
* text-mode coercion.
|
|
44
44
|
*/
|
|
45
45
|
export function isNativeAnthropicProvider(providerName) {
|
|
46
46
|
return providerName === "anthropic" || providerName === "bedrock";
|
|
@@ -96,6 +96,7 @@ export const appendJsonSchemaInstruction = (conversation, schema) => {
|
|
|
96
96
|
export async function runNativeGenerateLoop(args, toolExecutionSummaries) {
|
|
97
97
|
const toolsUsed = [];
|
|
98
98
|
let text = "";
|
|
99
|
+
let reasoning = "";
|
|
99
100
|
let finishReason = "stop";
|
|
100
101
|
let rawFinishReason;
|
|
101
102
|
let inputTokens = 0;
|
|
@@ -175,6 +176,15 @@ export async function runNativeGenerateLoop(args, toolExecutionSummaries) {
|
|
|
175
176
|
.filter((p) => p.type === "text" && typeof p.text === "string")
|
|
176
177
|
.map((p) => p.text)
|
|
177
178
|
.join("");
|
|
179
|
+
// Reasoner models (DeepSeek `reasoning_content`, gateway `reasoning`,
|
|
180
|
+
// OpenAI o-series) emit reasoning as its own V3 content part. Join it on
|
|
181
|
+
// the same replace-per-step rule as the text so the caller can surface
|
|
182
|
+
// `result.reasoning`; without this the provider builds the part and the
|
|
183
|
+
// loop drops it.
|
|
184
|
+
reasoning = parts
|
|
185
|
+
.filter((p) => p.type === "reasoning" && typeof p.text === "string")
|
|
186
|
+
.map((p) => p.text)
|
|
187
|
+
.join("");
|
|
178
188
|
const fr = res.finishReason;
|
|
179
189
|
if (typeof fr === "string") {
|
|
180
190
|
finishReason = fr;
|
|
@@ -287,6 +297,7 @@ export async function runNativeGenerateLoop(args, toolExecutionSummaries) {
|
|
|
287
297
|
}
|
|
288
298
|
return {
|
|
289
299
|
text,
|
|
300
|
+
...(reasoning ? { reasoning } : {}),
|
|
290
301
|
finishReason,
|
|
291
302
|
...(rawFinishReason ? { rawFinishReason } : {}),
|
|
292
303
|
inputTokens,
|
|
@@ -16,8 +16,8 @@ export function toNativeToolDeclarations(tools, format) {
|
|
|
16
16
|
const input_schema = (rawSchema
|
|
17
17
|
? convertZodToJsonSchema(rawSchema)
|
|
18
18
|
: { type: "object", properties: {} });
|
|
19
|
-
//
|
|
20
|
-
//
|
|
19
|
+
// Honor a cache breakpoint the caller set on this tool. The direct
|
|
20
|
+
// Anthropic path marks the last tool itself, on the assembled request.
|
|
21
21
|
const cc = cacheControlOf(tool);
|
|
22
22
|
const declaration = {
|
|
23
23
|
name,
|
|
@@ -321,7 +321,7 @@ const HAND_DESCRIPTORS = [
|
|
|
321
321
|
baseURL: "NVIDIA_NIM_BASE_URL",
|
|
322
322
|
model: "NVIDIA_NIM_MODEL",
|
|
323
323
|
},
|
|
324
|
-
defaultModel: NvidiaNimModels.
|
|
324
|
+
defaultModel: NvidiaNimModels.GPT_OSS_20B,
|
|
325
325
|
toolSupport: "native",
|
|
326
326
|
localRuntime: false,
|
|
327
327
|
healthCheck: "env-only",
|
|
@@ -174,7 +174,10 @@ export class ProviderRegistry {
|
|
|
174
174
|
const nimCreds = credentials;
|
|
175
175
|
const { NvidiaNimProvider } = await import("../providers/nvidiaNim/index.js");
|
|
176
176
|
return new NvidiaNimProvider(modelName, sdk, undefined, nimCreds);
|
|
177
|
-
}, process.env.NVIDIA_NIM_MODEL ||
|
|
177
|
+
}, process.env.NVIDIA_NIM_MODEL ||
|
|
178
|
+
PROVIDER_DESCRIPTORS_BY_NAME.get(AIProviderName.NVIDIA_NIM)
|
|
179
|
+
?.defaultModel ||
|
|
180
|
+
NvidiaNimModels.GPT_OSS_20B, ["nvidia", "nim", "nvidia-nim"], PROVIDER_DESCRIPTORS_BY_NAME.get(AIProviderName.NVIDIA_NIM));
|
|
178
181
|
// Register LM Studio provider (local)
|
|
179
182
|
ProviderFactory.registerProvider(AIProviderName.LM_STUDIO, async (modelName, _providerName, sdk, _region, credentials) => {
|
|
180
183
|
const lmStudioCreds = credentials;
|
package/dist/neurolink.js
CHANGED
|
@@ -4386,7 +4386,7 @@ Current user's request: ${currentInput}`;
|
|
|
4386
4386
|
music: textResult.music,
|
|
4387
4387
|
ppt: textResult.ppt,
|
|
4388
4388
|
// Forward reasoning/reasoningTokens from the provider layer.
|
|
4389
|
-
//
|
|
4389
|
+
// The native generate loop extracts these from vendor reasoning
|
|
4390
4390
|
// parts (DeepSeek's `reasoning_content`, Anthropic thinking blocks,
|
|
4391
4391
|
// Gemini thought parts, OpenAI o1) and they're declared on
|
|
4392
4392
|
// `GenerateResult`, but the builder previously dropped them on the
|
|
@@ -197,6 +197,7 @@ export class AmazonSageMakerProvider extends BaseProvider {
|
|
|
197
197
|
total: loop.inputTokens + loop.outputTokens,
|
|
198
198
|
},
|
|
199
199
|
responseTime: Date.now() - startTime,
|
|
200
|
+
...(loop.reasoning ? { reasoning: loop.reasoning } : {}),
|
|
200
201
|
toolsUsed: loop.toolsUsed,
|
|
201
202
|
toolCalls: toolCallsFromSummaries(toolExecutionSummaries),
|
|
202
203
|
toolExecutions: resolveToolExecutionRecords(options, transformToolExecutions(toolExecutionSummaries)),
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type Anthropic from "@anthropic-ai/sdk";
|
|
2
2
|
/**
|
|
3
3
|
* Read an Anthropic cache breakpoint from a message/part/tool carrier.
|
|
4
|
-
* MessageBuilder marks system messages
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* MessageBuilder marks system messages with
|
|
5
|
+
* `providerOptions.anthropic.cacheControl`; the Anthropic client marks the last
|
|
6
|
+
* tool definition on the assembled request. This reader is what honors both.
|
|
7
7
|
*
|
|
8
8
|
* Extracted from anthropic/client.ts so `src/lib/core/nativeToolFormat.ts`
|
|
9
9
|
* can share it without importing the provider client (which would create a
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Read an Anthropic cache breakpoint from a message/part/tool carrier.
|
|
3
|
-
* MessageBuilder marks system messages
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* MessageBuilder marks system messages with
|
|
4
|
+
* `providerOptions.anthropic.cacheControl`; the Anthropic client marks the last
|
|
5
|
+
* tool definition on the assembled request. This reader is what honors both.
|
|
6
6
|
*
|
|
7
7
|
* Extracted from anthropic/client.ts so `src/lib/core/nativeToolFormat.ts`
|
|
8
8
|
* can share it without importing the provider client (which would create a
|
|
@@ -1027,8 +1027,8 @@ export class AnthropicProvider extends BaseProvider {
|
|
|
1027
1027
|
let tools = (options.tools ?? [])
|
|
1028
1028
|
.filter((t) => t.type === "function")
|
|
1029
1029
|
.map((t) => {
|
|
1030
|
-
//
|
|
1031
|
-
//
|
|
1030
|
+
// Honor a cache breakpoint the caller set on this tool. When no
|
|
1031
|
+
// tool carries one, the last tool is marked further below.
|
|
1032
1032
|
const cc = cacheControlOf(t);
|
|
1033
1033
|
return {
|
|
1034
1034
|
name: t.name,
|
|
@@ -1069,10 +1069,10 @@ export class AnthropicProvider extends BaseProvider {
|
|
|
1069
1069
|
}
|
|
1070
1070
|
// Additive structured output: when the caller wants a schema AND real
|
|
1071
1071
|
// tools, the forced-json path above cannot be used (it replaces the
|
|
1072
|
-
// tools array), and
|
|
1073
|
-
//
|
|
1074
|
-
//
|
|
1075
|
-
// tool — tool_choice stays auto, so every real tool keeps working and
|
|
1072
|
+
// tools array), and structured output is excluded for this surface
|
|
1073
|
+
// by structuredOutputPolicy. The schema arrives instead on
|
|
1074
|
+
// `providerOptions.anthropic.finalResultSchema` and we APPEND a
|
|
1075
|
+
// `final_result` tool — tool_choice stays auto, so every real tool keeps working and
|
|
1076
1076
|
// the model self-selects final_result when it is ready to answer.
|
|
1077
1077
|
const finalResultSchema = options.providerOptions?.anthropic
|
|
1078
1078
|
?.finalResultSchema;
|
|
@@ -1087,9 +1087,26 @@ export class AnthropicProvider extends BaseProvider {
|
|
|
1087
1087
|
}
|
|
1088
1088
|
// Extended thinking passthrough (providerOptions.anthropic.thinking).
|
|
1089
1089
|
const thinking = options.providerOptions?.anthropic?.thinking;
|
|
1090
|
+
// Close the stable prefix with a breakpoint on the LAST tool. Tool
|
|
1091
|
+
// definitions sit between the system prompt and the conversation and
|
|
1092
|
+
// rarely change, so without this the whole tools block is re-billed
|
|
1093
|
+
// every turn. Applied after every tool mutation above (including the
|
|
1094
|
+
// appended final_result tool) so the marker really is last, and before
|
|
1095
|
+
// the count below so the history budget accounts for it. A caller that
|
|
1096
|
+
// marked a tool itself wins.
|
|
1097
|
+
if (tools && tools.length > 0) {
|
|
1098
|
+
const alreadyMarked = tools.some((t) => cacheControlOf(t));
|
|
1099
|
+
if (!alreadyMarked) {
|
|
1100
|
+
const last = tools[tools.length - 1];
|
|
1101
|
+
tools = [
|
|
1102
|
+
...tools.slice(0, -1),
|
|
1103
|
+
{ ...last, cache_control: { type: "ephemeral" } },
|
|
1104
|
+
];
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1090
1107
|
// Prompt-cache parity with the native Vertex+Claude path: upstream
|
|
1091
|
-
// layers mark
|
|
1092
|
-
// last tool
|
|
1108
|
+
// layers mark the stable prefix (system via MessageBuilder, and the
|
|
1109
|
+
// last tool just above) — the growing conversation
|
|
1093
1110
|
// history has no breakpoint, so on every turn it falls after the
|
|
1094
1111
|
// last marker and is re-billed as fresh input. Add rolling history
|
|
1095
1112
|
// breakpoints in whatever budget remains under Anthropic's
|
|
@@ -1469,6 +1486,7 @@ export class AnthropicProvider extends BaseProvider {
|
|
|
1469
1486
|
...(loop.rawFinishReason
|
|
1470
1487
|
? { rawFinishReason: loop.rawFinishReason }
|
|
1471
1488
|
: {}),
|
|
1489
|
+
...(loop.reasoning ? { reasoning: loop.reasoning } : {}),
|
|
1472
1490
|
usage: {
|
|
1473
1491
|
input: loop.inputTokens,
|
|
1474
1492
|
output: loop.outputTokens,
|
|
@@ -44,7 +44,7 @@ export declare class ConfiguredOpenAICompatProvider extends OpenAIChatCompletion
|
|
|
44
44
|
* a `tools` array — Mancer's free model rejects one with 400 — so the
|
|
45
45
|
* declaration wins here and the registry is only consulted otherwise.
|
|
46
46
|
* Like the other entry-reading overrides above, this runs only after
|
|
47
|
-
* construction: BaseProvider merely closes over it
|
|
47
|
+
* construction: BaseProvider merely closes over it.
|
|
48
48
|
*/
|
|
49
49
|
supportsTools(): boolean;
|
|
50
50
|
protected adjustRequestBody(body: OpenAICompatChatRequest, modelId: string): OpenAICompatChatRequest;
|
|
@@ -94,7 +94,7 @@ export class ConfiguredOpenAICompatProvider extends OpenAIChatCompletionsProvide
|
|
|
94
94
|
* a `tools` array — Mancer's free model rejects one with 400 — so the
|
|
95
95
|
* declaration wins here and the registry is only consulted otherwise.
|
|
96
96
|
* Like the other entry-reading overrides above, this runs only after
|
|
97
|
-
* construction: BaseProvider merely closes over it
|
|
97
|
+
* construction: BaseProvider merely closes over it.
|
|
98
98
|
*/
|
|
99
99
|
supportsTools() {
|
|
100
100
|
if (this.entry.supportsTools === false) {
|
|
@@ -1307,9 +1307,8 @@ export class GoogleAIStudioProvider extends BaseProvider {
|
|
|
1307
1307
|
try {
|
|
1308
1308
|
// Wrap in `neurolink.executeGeneration` so the observability span
|
|
1309
1309
|
// chain (Test: Generate Span Chain) sees a third inner span on the
|
|
1310
|
-
// native @google/genai path
|
|
1311
|
-
//
|
|
1312
|
-
// GenerationHandler so we add the span here.
|
|
1310
|
+
// native @google/genai path. This provider overrides generate() instead
|
|
1311
|
+
// of using BaseProvider's shared flow, so the span is added here.
|
|
1313
1312
|
let result = await withSpan({
|
|
1314
1313
|
name: "neurolink.executeGeneration",
|
|
1315
1314
|
tracer: tracers.provider,
|
|
@@ -5245,8 +5245,8 @@ export class GoogleVertexProvider extends BaseProvider {
|
|
|
5245
5245
|
// Wrap the actual native generate call in `neurolink.executeGeneration`
|
|
5246
5246
|
// so the observability span chain (tested by
|
|
5247
5247
|
// "Tracing: Generate Span Chain") sees a third inner span on the
|
|
5248
|
-
// native @google/genai / @anthropic-ai/vertex-sdk path
|
|
5249
|
-
//
|
|
5248
|
+
// native @google/genai / @anthropic-ai/vertex-sdk path. This
|
|
5249
|
+
// provider overrides generate(), so the span is added here.
|
|
5250
5250
|
result = await withSpan({
|
|
5251
5251
|
name: "neurolink.executeGeneration",
|
|
5252
5252
|
tracer: tracers.provider,
|
|
@@ -5,6 +5,7 @@ import { logger } from "../../utils/logger.js";
|
|
|
5
5
|
import { redactUrlCredentials } from "../../utils/logSanitize.js";
|
|
6
6
|
import { createNvidiaNimConfig, getProviderModel, validateApiKey, } from "../../utils/providerConfig.js";
|
|
7
7
|
import { OpenAIChatCompletionsProvider } from "../openaiChatCompletionsBase.js";
|
|
8
|
+
import { PROVIDER_DESCRIPTORS_BY_NAME } from "../../factories/providerDescriptors.js";
|
|
8
9
|
/**
|
|
9
10
|
* Decide whether a NIM 400 response body is a rejection of the named
|
|
10
11
|
* field (as opposed to an unrelated 400 that happens to mention the
|
|
@@ -136,7 +137,16 @@ const getNimApiKey = () => {
|
|
|
136
137
|
return validateApiKey(createNvidiaNimConfig());
|
|
137
138
|
};
|
|
138
139
|
const getDefaultNimModel = () => {
|
|
139
|
-
|
|
140
|
+
// NVIDIA retired meta/llama-3.3-70b-instruct upstream on 2026-08-26, so this
|
|
141
|
+
// fallback answered "no longer available" for anyone who selected nvidia-nim
|
|
142
|
+
// without naming a model. gpt-oss-20b is on the current roster and was
|
|
143
|
+
// probed for text, streaming, tool calling and structured output.
|
|
144
|
+
// Read the descriptor rather than repeating the literal. Review on this PR
|
|
145
|
+
// pointed out the default lived in four places and that changing only some
|
|
146
|
+
// of them is a no-op — which happened twice while tracking this down. The
|
|
147
|
+
// descriptor is the Factory+Registry convention's source of truth.
|
|
148
|
+
return getProviderModel("NVIDIA_NIM_MODEL", PROVIDER_DESCRIPTORS_BY_NAME.get("nvidia-nim")
|
|
149
|
+
?.defaultModel ?? NvidiaNimModels.GPT_OSS_20B);
|
|
140
150
|
};
|
|
141
151
|
/**
|
|
142
152
|
* NVIDIA NIM Provider — native HTTP+SSE, no AI SDK.
|
|
@@ -76,13 +76,13 @@ export declare abstract class OpenAIChatCompletionsProvider extends BaseProvider
|
|
|
76
76
|
protected adjustResponseFormat(rf: OpenAICompatResponseFormat | undefined, _modelId: string): OpenAICompatResponseFormat | undefined;
|
|
77
77
|
/**
|
|
78
78
|
* When true (default), `response_format` is NOT sent on requests that carry
|
|
79
|
-
* tools. The
|
|
80
|
-
* generic/proxy backends (LiteLLM→vllm/GLM, openai-compatible, local
|
|
79
|
+
* tools. The generate loop sets responseFormat on EVERY step of a tool
|
|
80
|
+
* loop, and generic/proxy backends (LiteLLM→vllm/GLM, openai-compatible, local
|
|
81
81
|
* servers) may silently honor it over tool calling — answering with
|
|
82
82
|
* final-shape JSON on step 1 instead of running the agentic loop. No error
|
|
83
83
|
* is raised, so the runtime tools↔schema conflict detector cannot catch it.
|
|
84
|
-
* The schema is still enforced post-hoc (
|
|
85
|
-
*
|
|
84
|
+
* The schema is still enforced post-hoc (`coerceJsonToSchema` runs against
|
|
85
|
+
* the final text) — the same contract as the Gemini tools↔schema exclusion.
|
|
86
86
|
* Mirrors the streaming path, which never sends response_format.
|
|
87
87
|
*
|
|
88
88
|
* Backends with first-party support for tools + json_schema in one request
|
|
@@ -199,13 +199,13 @@ export class OpenAIChatCompletionsProvider extends BaseProvider {
|
|
|
199
199
|
}
|
|
200
200
|
/**
|
|
201
201
|
* When true (default), `response_format` is NOT sent on requests that carry
|
|
202
|
-
* tools. The
|
|
203
|
-
* generic/proxy backends (LiteLLM→vllm/GLM, openai-compatible, local
|
|
202
|
+
* tools. The generate loop sets responseFormat on EVERY step of a tool
|
|
203
|
+
* loop, and generic/proxy backends (LiteLLM→vllm/GLM, openai-compatible, local
|
|
204
204
|
* servers) may silently honor it over tool calling — answering with
|
|
205
205
|
* final-shape JSON on step 1 instead of running the agentic loop. No error
|
|
206
206
|
* is raised, so the runtime tools↔schema conflict detector cannot catch it.
|
|
207
|
-
* The schema is still enforced post-hoc (
|
|
208
|
-
*
|
|
207
|
+
* The schema is still enforced post-hoc (`coerceJsonToSchema` runs against
|
|
208
|
+
* the final text) — the same contract as the Gemini tools↔schema exclusion.
|
|
209
209
|
* Mirrors the streaming path, which never sends response_format.
|
|
210
210
|
*
|
|
211
211
|
* Backends with first-party support for tools + json_schema in one request
|
|
@@ -709,7 +709,7 @@ export class OpenAIChatCompletionsProvider extends BaseProvider {
|
|
|
709
709
|
const content = [];
|
|
710
710
|
// Reasoner-model output (DeepSeek `reasoning_content`, gateway
|
|
711
711
|
// `reasoning`) becomes a V3 reasoning part ahead of the text part —
|
|
712
|
-
//
|
|
712
|
+
// the native generate loop joins those parts into `result.reasoning`.
|
|
713
713
|
// `||` so an empty-string reasoning_content falls through to a
|
|
714
714
|
// non-empty `reasoning` field instead of shadowing it.
|
|
715
715
|
const reasoningText = choice?.message?.reasoning_content || choice?.message?.reasoning;
|
|
@@ -921,11 +921,11 @@ export class OpenAIChatCompletionsProvider extends BaseProvider {
|
|
|
921
921
|
// words instead: drop `response_format` and spell the JSON Schema into the
|
|
922
922
|
// system prompt, letting coerceJsonToSchema recover the object from text.
|
|
923
923
|
//
|
|
924
|
-
// Ported from GenerationHandler's `promptJsonInstruction` fallback
|
|
925
|
-
//
|
|
926
|
-
//
|
|
927
|
-
//
|
|
928
|
-
//
|
|
924
|
+
// Ported from GenerationHandler's `promptJsonInstruction` fallback on the
|
|
925
|
+
// ai-package path, which has since been deleted — GMI Cloud's MiniMax
|
|
926
|
+
// endpoint, the one it was written for, is a Tier-2 catalog provider on
|
|
927
|
+
// this very base class, so without this the recovery would simply not
|
|
928
|
+
// happen for it.
|
|
929
929
|
let loop;
|
|
930
930
|
try {
|
|
931
931
|
loop = await runLoop(conversation, responseFormat);
|
|
@@ -991,6 +991,7 @@ export class OpenAIChatCompletionsProvider extends BaseProvider {
|
|
|
991
991
|
: {}),
|
|
992
992
|
},
|
|
993
993
|
responseTime: Date.now() - startTime,
|
|
994
|
+
...(loop.reasoning ? { reasoning: loop.reasoning } : {}),
|
|
994
995
|
toolsUsed,
|
|
995
996
|
toolCalls: toolCallsFromSummaries(toolExecutionSummaries),
|
|
996
997
|
toolExecutions: resolveToolExecutionRecords(options, transformToolExecutions(toolExecutionSummaries)),
|
package/dist/types/context.d.ts
CHANGED
|
@@ -219,28 +219,6 @@ export type BudgetCheckResult = {
|
|
|
219
219
|
fileAttachments: number;
|
|
220
220
|
};
|
|
221
221
|
};
|
|
222
|
-
/**
|
|
223
|
-
* Configuration for the per-step context budget guard that compacts the
|
|
224
|
-
* AI-SDK tool loop's messages before they overflow the model window
|
|
225
|
-
* (context/stepBudgetGuard.ts).
|
|
226
|
-
*/
|
|
227
|
-
export type StepBudgetGuardConfig = {
|
|
228
|
-
provider: string;
|
|
229
|
-
model?: string;
|
|
230
|
-
/** The caller's requested output budget (reserved out of the window). */
|
|
231
|
-
maxTokens?: number;
|
|
232
|
-
/** Static token cost of the hoisted system prompt + tool definitions. */
|
|
233
|
-
fixedOverheadTokens?: number;
|
|
234
|
-
/**
|
|
235
|
-
* Dynamic overhead resolver, re-evaluated on EVERY guard invocation. Takes
|
|
236
|
-
* precedence over `fixedOverheadTokens`. Use when the tool set can grow
|
|
237
|
-
* mid-loop (search_tools hydration) so newly added definitions count toward
|
|
238
|
-
* the budget.
|
|
239
|
-
*/
|
|
240
|
-
getFixedOverheadTokens?: () => number;
|
|
241
|
-
/** Override the trigger ratio; defaults to DEFAULT_CONTEXT_GUARD_RATIO. */
|
|
242
|
-
thresholdRatio?: number;
|
|
243
|
-
};
|
|
244
222
|
/** Parameters for budget checking. */
|
|
245
223
|
export type BudgetCheckParams = {
|
|
246
224
|
provider: string;
|
package/dist/types/generate.d.ts
CHANGED
|
@@ -1567,23 +1567,6 @@ export type ModelAliasConfig = {
|
|
|
1567
1567
|
export type GenerateOptionsNormalized = GenerateOptions & {
|
|
1568
1568
|
input: NonNullable<GenerateOptions["input"]>;
|
|
1569
1569
|
};
|
|
1570
|
-
/**
|
|
1571
|
-
* Per-call configuration for GenerationHandler's AI-SDK loop invocation,
|
|
1572
|
-
* shared by the initial call and every fallback retry so they cannot drift.
|
|
1573
|
-
*/
|
|
1574
|
-
export type GenerationCallConfig = {
|
|
1575
|
-
shouldUseTools: boolean;
|
|
1576
|
-
includeStructuredOutput: boolean;
|
|
1577
|
-
/** Anchor for the turn deadline — the ORIGINAL executeGeneration start,
|
|
1578
|
-
* shared across fallback/provider retries so they can't refresh the
|
|
1579
|
-
* wall-clock budget. */
|
|
1580
|
-
turnStartMs: number;
|
|
1581
|
-
/** Structured-output fallback retry: also spell the JSON Schema out in the
|
|
1582
|
-
* system prompt, for vendors that ignore `response_format`. */
|
|
1583
|
-
promptJsonInstruction?: boolean;
|
|
1584
|
-
/** Set on the single toolChoice:"none" re-ask so it can never recurse. */
|
|
1585
|
-
isToolReask?: boolean;
|
|
1586
|
-
};
|
|
1587
1570
|
/**
|
|
1588
1571
|
* Inputs to the shared native generate loop (`core/nativeGenerateLoop.ts`).
|
|
1589
1572
|
* One loop serves every provider whose delegating model exposes a v3-shaped
|
|
@@ -1611,6 +1594,8 @@ export type NativeGenerateLoopArgs = {
|
|
|
1611
1594
|
};
|
|
1612
1595
|
export type NativeGenerateLoopResult = {
|
|
1613
1596
|
text: string;
|
|
1597
|
+
/** Joined reasoning content parts from the final step, when the vendor sent any. */
|
|
1598
|
+
reasoning?: string;
|
|
1614
1599
|
finishReason: string;
|
|
1615
1600
|
rawFinishReason?: string;
|
|
1616
1601
|
inputTokens: number;
|
|
@@ -5,7 +5,7 @@ import type { UnknownRecord, JsonValue, StreamingCapability } from "./common.js"
|
|
|
5
5
|
import type { NeuroLink } from "../neurolink.js";
|
|
6
6
|
import { AIProviderName, AnthropicModels, BedrockModels, DeepSeekModels, GoogleAIModels, LlamaCppModels, LMStudioModels, NvidiaNimModels, OpenAIModels, VertexModels } from "../constants/enums.js";
|
|
7
7
|
import type { ValidationSchema } from "./aliases.js";
|
|
8
|
-
import type { EnhancedGenerateResult,
|
|
8
|
+
import type { EnhancedGenerateResult, TextGenerationOptions } from "./generate.js";
|
|
9
9
|
import type { MultimodalAudioEntry } from "./file.js";
|
|
10
10
|
import type { StreamOptions, StreamResult } from "./stream.js";
|
|
11
11
|
import type { ProviderError, ProviderErrorRule } from "./errors.js";
|
|
@@ -824,20 +824,6 @@ export type ProviderCapability = "text-generation" | "streaming" | "tool-calling
|
|
|
824
824
|
* Extended tool type that combines AI SDK tools with external MCP tool info
|
|
825
825
|
*/
|
|
826
826
|
export type ExtendedTool = Tool & Partial<ExternalMCPToolInfo>;
|
|
827
|
-
/**
|
|
828
|
-
* AI SDK generate result with steps support (extends GenerateResult)
|
|
829
|
-
*/
|
|
830
|
-
export type AISDKGenerateResult = GenerateResult & {
|
|
831
|
-
steps?: Array<{
|
|
832
|
-
toolCalls?: Array<{
|
|
833
|
-
toolName?: string;
|
|
834
|
-
name?: string;
|
|
835
|
-
[key: string]: unknown;
|
|
836
|
-
}>;
|
|
837
|
-
[key: string]: unknown;
|
|
838
|
-
}>;
|
|
839
|
-
[key: string]: unknown;
|
|
840
|
-
};
|
|
841
827
|
/**
|
|
842
828
|
* Bedrock tool usage structure
|
|
843
829
|
*/
|
|
@@ -1852,18 +1838,6 @@ export type LanguageModelObject = {
|
|
|
1852
1838
|
readonly modelId: string;
|
|
1853
1839
|
readonly provider: string;
|
|
1854
1840
|
};
|
|
1855
|
-
/** Step finish event shape for multi-step generation. */
|
|
1856
|
-
export type StepFinishEvent = {
|
|
1857
|
-
readonly toolCalls: ReadonlyArray<unknown>;
|
|
1858
|
-
readonly toolResults: ReadonlyArray<unknown>;
|
|
1859
|
-
readonly text: string;
|
|
1860
|
-
readonly finishReason: string;
|
|
1861
|
-
readonly usage: {
|
|
1862
|
-
inputTokens?: number;
|
|
1863
|
-
outputTokens?: number;
|
|
1864
|
-
};
|
|
1865
|
-
[key: string]: unknown;
|
|
1866
|
-
};
|
|
1867
1841
|
/**
|
|
1868
1842
|
* Represents an AI SDK Tool that may carry a legacy `parameters` field
|
|
1869
1843
|
* (from AI SDK v3/v4) in addition to the current `inputSchema`.
|
|
@@ -17,11 +17,11 @@ export declare const ANTHROPIC_MAX_CACHE_BREAKPOINTS = 4;
|
|
|
17
17
|
export declare function applyVertexAnthropicCacheBreakpoints(input: VertexAnthropicCacheInput): VertexAnthropicCacheOutput;
|
|
18
18
|
/**
|
|
19
19
|
* Count the `cache_control` markers already present on a request. The direct
|
|
20
|
-
* Anthropic path
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
20
|
+
* Anthropic path arrives with markers the upstream layers placed —
|
|
21
|
+
* MessageBuilder tags the system prompt, the client tags the last tool
|
|
22
|
+
* definition, and message content blocks may carry their own. Anthropic
|
|
23
|
+
* rejects requests with more than four markers, so any additional history
|
|
24
|
+
* breakpoints must fit in the remaining budget.
|
|
25
25
|
*/
|
|
26
26
|
export declare function countAnthropicCacheMarkers(input: {
|
|
27
27
|
system?: string | ReadonlyArray<{
|
|
@@ -35,7 +35,7 @@ export declare function countAnthropicCacheMarkers(input: {
|
|
|
35
35
|
/**
|
|
36
36
|
* Rolling history breakpoints for request paths whose stable-prefix markers
|
|
37
37
|
* are managed upstream (direct Anthropic: system via MessageBuilder, last
|
|
38
|
-
* tool via
|
|
38
|
+
* tool via the provider client). Marks the last content block of up to `budget`
|
|
39
39
|
* tail messages; a tail block that already carries a marker is left as-is
|
|
40
40
|
* without consuming budget (it already serves as that breakpoint). Pure —
|
|
41
41
|
* the input array is cloned, never mutated.
|
|
@@ -63,11 +63,11 @@ export function applyVertexAnthropicCacheBreakpoints(input) {
|
|
|
63
63
|
}
|
|
64
64
|
/**
|
|
65
65
|
* Count the `cache_control` markers already present on a request. The direct
|
|
66
|
-
* Anthropic path
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
66
|
+
* Anthropic path arrives with markers the upstream layers placed —
|
|
67
|
+
* MessageBuilder tags the system prompt, the client tags the last tool
|
|
68
|
+
* definition, and message content blocks may carry their own. Anthropic
|
|
69
|
+
* rejects requests with more than four markers, so any additional history
|
|
70
|
+
* breakpoints must fit in the remaining budget.
|
|
71
71
|
*/
|
|
72
72
|
export function countAnthropicCacheMarkers(input) {
|
|
73
73
|
let count = 0;
|
|
@@ -87,7 +87,7 @@ export function countAnthropicCacheMarkers(input) {
|
|
|
87
87
|
/**
|
|
88
88
|
* Rolling history breakpoints for request paths whose stable-prefix markers
|
|
89
89
|
* are managed upstream (direct Anthropic: system via MessageBuilder, last
|
|
90
|
-
* tool via
|
|
90
|
+
* tool via the provider client). Marks the last content block of up to `budget`
|
|
91
91
|
* tail messages; a tail block that already carries a marker is left as-is
|
|
92
92
|
* without consuming budget (it already serves as that breakpoint). Pure —
|
|
93
93
|
* the input array is cloned, never mutated.
|
|
@@ -15,8 +15,9 @@ export declare function schemaAccepts(schema: ValidationSchema | undefined, valu
|
|
|
15
15
|
* object/array case is handled by `coerceJsonToSchema`; this covers the
|
|
16
16
|
* residual scalar root after that path returns null. Encapsulates the JSON
|
|
17
17
|
* parsing, the empty-string normalization, and the `schemaAccepts` gate so the
|
|
18
|
-
* same policy cannot drift between consumers
|
|
19
|
-
*
|
|
18
|
+
* same policy cannot drift between consumers. `neurolink.recoverStructuredData`
|
|
19
|
+
* is the only one left; `GenerationHandler.coerceTextMode` was the other until
|
|
20
|
+
* the ai-package path was deleted.
|
|
20
21
|
*/
|
|
21
22
|
export declare function recoverScalarRoot(text: string, schema: ValidationSchema | undefined): ScalarRecoveryDecision;
|
|
22
23
|
/**
|
|
@@ -44,8 +44,9 @@ export function schemaAccepts(schema, value) {
|
|
|
44
44
|
* object/array case is handled by `coerceJsonToSchema`; this covers the
|
|
45
45
|
* residual scalar root after that path returns null. Encapsulates the JSON
|
|
46
46
|
* parsing, the empty-string normalization, and the `schemaAccepts` gate so the
|
|
47
|
-
* same policy cannot drift between consumers
|
|
48
|
-
*
|
|
47
|
+
* same policy cannot drift between consumers. `neurolink.recoverStructuredData`
|
|
48
|
+
* is the only one left; `GenerationHandler.coerceTextMode` was the other until
|
|
49
|
+
* the ai-package path was deleted.
|
|
49
50
|
*/
|
|
50
51
|
export function recoverScalarRoot(text, schema) {
|
|
51
52
|
try {
|