@juspay/neurolink 12.14.1 → 12.14.2
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 +3 -2
- package/dist/browser/neurolink.min.js +192 -192
- package/dist/neurolink.js +16 -0
- package/dist/providers/anthropic/client.js +73 -4
- package/dist/types/aiCompat.d.ts +1 -0
- package/package.json +6 -5
package/dist/neurolink.js
CHANGED
|
@@ -4159,6 +4159,22 @@ Current user's request: ${currentInput}`;
|
|
|
4159
4159
|
middleware: options.middleware,
|
|
4160
4160
|
conversationMessages: options.conversationMessages,
|
|
4161
4161
|
credentials: options.credentials,
|
|
4162
|
+
// Extended thinking. Every provider gates it on `thinkingConfig`, so
|
|
4163
|
+
// omitting the field here meant it never reached one: the request went
|
|
4164
|
+
// out with no thinking block and the result carried no reasoning, with
|
|
4165
|
+
// nothing raised to say the option had been discarded. This is the same
|
|
4166
|
+
// failure the note above records for `disableInternalFallback` — an
|
|
4167
|
+
// allowlist that silently swallows a documented option.
|
|
4168
|
+
//
|
|
4169
|
+
// `thinkingConfig` is the only one of the documented thinking options
|
|
4170
|
+
// that `GenerateOptions` actually declares. `thinking`, `thinkingBudget`
|
|
4171
|
+
// and `thinkingLevel` are folded into a `thinkingConfig` only by the CLI,
|
|
4172
|
+
// in `src/lib/utils/thinkingConfig.ts`; nothing on the SDK path does that
|
|
4173
|
+
// merge. They exist solely on the internal `TextGenerationOptions`, so no
|
|
4174
|
+
// caller can pass them through
|
|
4175
|
+
// generate() today. Declaring them is a public-type decision and is
|
|
4176
|
+
// deliberately left out of this fix.
|
|
4177
|
+
thinkingConfig: options.thinkingConfig,
|
|
4162
4178
|
// Lifecycle callbacks must reach the provider so non-AI-SDK paths
|
|
4163
4179
|
// (Vertex's native @google/genai, native Bedrock, Ollama, etc.) can
|
|
4164
4180
|
// invoke them directly. Pipeline A also still receives them via the
|
|
@@ -292,6 +292,12 @@ const messagesToAnthropic = (msgs) => {
|
|
|
292
292
|
}
|
|
293
293
|
case "assistant": {
|
|
294
294
|
const blocks = [];
|
|
295
|
+
// Extended thinking must come back byte-identical — signature
|
|
296
|
+
// included — or Anthropic rejects the turn, and the loop replays this
|
|
297
|
+
// message on every tool step. Blocks are emitted in content order
|
|
298
|
+
// rather than hoisted: `interleaved-thinking-2025-05-14` (requested in
|
|
299
|
+
// the beta header) lets thinking appear between tool calls, so
|
|
300
|
+
// reordering would corrupt the chain it validates.
|
|
295
301
|
for (const part of partsOf(msg.content)) {
|
|
296
302
|
if (typeof part === "string") {
|
|
297
303
|
if (part.length > 0) {
|
|
@@ -300,6 +306,29 @@ const messagesToAnthropic = (msgs) => {
|
|
|
300
306
|
continue;
|
|
301
307
|
}
|
|
302
308
|
const p = part;
|
|
309
|
+
if (p?.type === "reasoning") {
|
|
310
|
+
const meta = p.providerOptions?.anthropic;
|
|
311
|
+
const redacted = meta?.redactedData;
|
|
312
|
+
if (typeof redacted === "string" && redacted.length > 0) {
|
|
313
|
+
blocks.push({ type: "redacted_thinking", data: redacted });
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
const signature = meta?.signature;
|
|
317
|
+
// Both halves required, matching loopAdapter's check on the
|
|
318
|
+
// streaming path: Anthropic rejects a thinking block that is
|
|
319
|
+
// unsigned, and equally one whose text is empty. Reasoning from a
|
|
320
|
+
// provider that never produced a signature (a reasoner model's
|
|
321
|
+
// plain text) is not an Anthropic thinking block at all, and an
|
|
322
|
+
// empty one carries nothing worth replaying — either way, dropping
|
|
323
|
+
// it beats sending a block that will be refused.
|
|
324
|
+
if (typeof signature === "string" &&
|
|
325
|
+
signature.length > 0 &&
|
|
326
|
+
typeof p.text === "string" &&
|
|
327
|
+
p.text.length > 0) {
|
|
328
|
+
blocks.push({ type: "thinking", thinking: p.text, signature });
|
|
329
|
+
}
|
|
330
|
+
continue;
|
|
331
|
+
}
|
|
303
332
|
if (p?.type === "text" && typeof p.text === "string") {
|
|
304
333
|
if (p.text.length > 0) {
|
|
305
334
|
const cc = cacheControlOf(p);
|
|
@@ -1118,15 +1147,28 @@ export class AnthropicProvider extends BaseProvider {
|
|
|
1118
1147
|
? { topP: options.topP }
|
|
1119
1148
|
: {}),
|
|
1120
1149
|
}, "anthropic.doGenerate");
|
|
1150
|
+
// Dropping a caller's explicit sampling parameters is exactly the
|
|
1151
|
+
// kind of silent discard this change fixes elsewhere, so say so.
|
|
1152
|
+
if (thinking &&
|
|
1153
|
+
(samplingParams.temperature !== undefined ||
|
|
1154
|
+
samplingParams.topP !== undefined)) {
|
|
1155
|
+
logger.debug("[anthropic] extended thinking is enabled, so temperature/top_p are omitted — Anthropic rejects any temperature but 1 while thinking is set");
|
|
1156
|
+
}
|
|
1121
1157
|
const params = {
|
|
1122
1158
|
model: modelId,
|
|
1123
1159
|
messages: cachedMessages,
|
|
1124
1160
|
max_tokens: resolveClaudeMaxTokens(modelId, options.maxOutputTokens),
|
|
1125
1161
|
...(system ? { system } : {}),
|
|
1126
|
-
|
|
1162
|
+
// Extended thinking fixes sampling: Anthropic rejects any
|
|
1163
|
+
// temperature but 1 while `thinking` is set, and does not honour
|
|
1164
|
+
// top_p there. The CLI always sends a default temperature, so
|
|
1165
|
+
// forwarding it alongside thinking turns a call that used to work
|
|
1166
|
+
// into a 400. Drop the sampling knobs for exactly those turns and
|
|
1167
|
+
// let Anthropic's thinking defaults stand.
|
|
1168
|
+
...(!thinking && samplingParams.temperature !== undefined
|
|
1127
1169
|
? { temperature: samplingParams.temperature }
|
|
1128
1170
|
: {}),
|
|
1129
|
-
...(samplingParams.topP !== undefined
|
|
1171
|
+
...(!thinking && samplingParams.topP !== undefined
|
|
1130
1172
|
? { top_p: samplingParams.topP }
|
|
1131
1173
|
: {}),
|
|
1132
1174
|
...(options.stopSequences && options.stopSequences.length > 0
|
|
@@ -1187,7 +1229,29 @@ export class AnthropicProvider extends BaseProvider {
|
|
|
1187
1229
|
let jsonToolAnswered = false;
|
|
1188
1230
|
for (const block of response.content) {
|
|
1189
1231
|
if (block.type === "thinking") {
|
|
1190
|
-
|
|
1232
|
+
// The signature rides along in providerOptions because Anthropic
|
|
1233
|
+
// rejects a replayed thinking block without it, and the tool loop
|
|
1234
|
+
// pushes this part straight back into the conversation.
|
|
1235
|
+
content.push({
|
|
1236
|
+
type: "reasoning",
|
|
1237
|
+
text: block.thinking,
|
|
1238
|
+
providerOptions: {
|
|
1239
|
+
anthropic: { signature: block.signature },
|
|
1240
|
+
},
|
|
1241
|
+
});
|
|
1242
|
+
}
|
|
1243
|
+
else if (block.type === "redacted_thinking") {
|
|
1244
|
+
// Encrypted reasoning: no readable text, but it must still be
|
|
1245
|
+
// replayed verbatim or the turn is rejected.
|
|
1246
|
+
content.push({
|
|
1247
|
+
type: "reasoning",
|
|
1248
|
+
text: "",
|
|
1249
|
+
providerOptions: {
|
|
1250
|
+
anthropic: {
|
|
1251
|
+
redactedData: block.data,
|
|
1252
|
+
},
|
|
1253
|
+
},
|
|
1254
|
+
});
|
|
1191
1255
|
}
|
|
1192
1256
|
else if (block.type === "text") {
|
|
1193
1257
|
// In forced-json mode the payload arrives via the tool input, not
|
|
@@ -1824,6 +1888,9 @@ export class AnthropicProvider extends BaseProvider {
|
|
|
1824
1888
|
const streamSamplingParams = resolveSamplingParams("anthropic", modelId, options.temperature !== undefined && options.temperature !== null
|
|
1825
1889
|
? { temperature: options.temperature }
|
|
1826
1890
|
: {}, "anthropic.executeStream");
|
|
1891
|
+
if (thinking && streamSamplingParams.temperature !== undefined) {
|
|
1892
|
+
logger.debug("[anthropic] extended thinking is enabled, so temperature is omitted on the stream path — Anthropic rejects any temperature but 1 while thinking is set");
|
|
1893
|
+
}
|
|
1827
1894
|
return {
|
|
1828
1895
|
model: modelId,
|
|
1829
1896
|
messages: cachedConversation,
|
|
@@ -1833,7 +1900,9 @@ export class AnthropicProvider extends BaseProvider {
|
|
|
1833
1900
|
// the adapter immediately overwrites — and forced this whole params
|
|
1834
1901
|
// object into the streaming variant for a field it does not own.
|
|
1835
1902
|
...(payload.system ? { system: payload.system } : {}),
|
|
1836
|
-
|
|
1903
|
+
// Same constraint on the streaming path: a temperature alongside
|
|
1904
|
+
// `thinking` is rejected outright.
|
|
1905
|
+
...(!thinking && streamSamplingParams.temperature !== undefined
|
|
1837
1906
|
? { temperature: streamSamplingParams.temperature }
|
|
1838
1907
|
: {}),
|
|
1839
1908
|
...(cachedTools && cachedTools.length > 0
|
package/dist/types/aiCompat.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juspay/neurolink",
|
|
3
|
-
"version": "12.14.
|
|
3
|
+
"version": "12.14.2",
|
|
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": {
|
|
@@ -110,6 +110,7 @@
|
|
|
110
110
|
"test:new-providers": "pnpm exec tsx test/continuous-test-suite-new-providers.ts",
|
|
111
111
|
"test:matrix": "pnpm exec tsx test/continuous-test-suite-provider-matrix.ts",
|
|
112
112
|
"test:matrix:cli": "pnpm exec tsx test/continuous-test-suite-provider-matrix-cli.ts",
|
|
113
|
+
"test:thinking-config": "pnpm exec tsx test/continuous-test-suite-sdk-thinking-config.ts",
|
|
113
114
|
"test:mcp:spans": "pnpm exec tsx test/continuous-test-suite-mcp-spans.ts",
|
|
114
115
|
"test:mcp:infra": "pnpm exec tsx test/continuous-test-suite-mcp-infra.ts",
|
|
115
116
|
"test:vendor-recovery": "pnpm exec tsx test/continuous-test-suite-native-vendor-recovery.ts",
|
|
@@ -179,10 +180,10 @@
|
|
|
179
180
|
"docs:validate": "tsx tools/content/documentationSync.ts --validate",
|
|
180
181
|
"docs:generate": "pnpm run docs:validate",
|
|
181
182
|
"// Documentation (Docusaurus)": "",
|
|
182
|
-
"docs:start": "pnpm --
|
|
183
|
-
"docs:build": "pnpm --
|
|
184
|
-
"docs:serve": "pnpm --
|
|
185
|
-
"docs:clear": "pnpm --
|
|
183
|
+
"docs:start": "pnpm --dir docs-site start",
|
|
184
|
+
"docs:build": "pnpm --dir docs-site build",
|
|
185
|
+
"docs:serve": "pnpm --dir docs-site serve",
|
|
186
|
+
"docs:clear": "pnpm --dir docs-site clear",
|
|
186
187
|
"// Proxy Observability (Local OpenObserve)": "",
|
|
187
188
|
"proxy:observability:setup": "bash scripts/observability/manage-local-openobserve.sh setup",
|
|
188
189
|
"proxy:observability:up": "bash scripts/observability/manage-local-openobserve.sh up",
|