@juspay/neurolink 10.3.0 → 10.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/browser/neurolink.min.js +430 -417
- package/dist/cli/loop/optionsSchema.js +4 -0
- package/dist/constants/contextWindows.d.ts +24 -0
- package/dist/constants/contextWindows.js +50 -0
- package/dist/context/errorDetection.d.ts +6 -0
- package/dist/context/errorDetection.js +18 -0
- package/dist/context/stepBudgetGuard.d.ts +17 -3
- package/dist/context/stepBudgetGuard.js +53 -14
- package/dist/core/baseProvider.d.ts +12 -0
- package/dist/core/baseProvider.js +18 -0
- package/dist/core/modules/GenerationHandler.js +208 -42
- package/dist/core/modules/ToolsManager.d.ts +17 -0
- package/dist/core/modules/ToolsManager.js +99 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -0
- package/dist/knowledge/context.d.ts +18 -0
- package/dist/knowledge/context.js +91 -0
- package/dist/knowledge/defaults.d.ts +24 -0
- package/dist/knowledge/defaults.js +29 -0
- package/dist/knowledge/engine.d.ts +35 -0
- package/dist/knowledge/engine.js +179 -0
- package/dist/knowledge/index.d.ts +15 -0
- package/dist/knowledge/index.js +15 -0
- package/dist/knowledge/indexCache.d.ts +19 -0
- package/dist/knowledge/indexCache.js +109 -0
- package/dist/knowledge/knowledgeIndex.d.ts +41 -0
- package/dist/knowledge/knowledgeIndex.js +204 -0
- package/dist/knowledge/normalize.d.ts +32 -0
- package/dist/knowledge/normalize.js +74 -0
- package/dist/knowledge/resolve.d.ts +18 -0
- package/dist/knowledge/resolve.js +156 -0
- package/dist/knowledge/retrieval.d.ts +16 -0
- package/dist/knowledge/retrieval.js +221 -0
- package/dist/lib/constants/contextWindows.d.ts +24 -0
- package/dist/lib/constants/contextWindows.js +50 -0
- package/dist/lib/context/errorDetection.d.ts +6 -0
- package/dist/lib/context/errorDetection.js +18 -0
- package/dist/lib/context/stepBudgetGuard.d.ts +17 -3
- package/dist/lib/context/stepBudgetGuard.js +53 -14
- package/dist/lib/core/baseProvider.d.ts +12 -0
- package/dist/lib/core/baseProvider.js +18 -0
- package/dist/lib/core/modules/GenerationHandler.js +208 -42
- package/dist/lib/core/modules/ToolsManager.d.ts +17 -0
- package/dist/lib/core/modules/ToolsManager.js +99 -1
- package/dist/lib/files/fileTools.d.ts +1 -1
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/index.js +3 -0
- package/dist/lib/knowledge/context.d.ts +18 -0
- package/dist/lib/knowledge/context.js +92 -0
- package/dist/lib/knowledge/defaults.d.ts +24 -0
- package/dist/lib/knowledge/defaults.js +30 -0
- package/dist/lib/knowledge/engine.d.ts +35 -0
- package/dist/lib/knowledge/engine.js +180 -0
- package/dist/lib/knowledge/index.d.ts +15 -0
- package/dist/lib/knowledge/index.js +16 -0
- package/dist/lib/knowledge/indexCache.d.ts +19 -0
- package/dist/lib/knowledge/indexCache.js +110 -0
- package/dist/lib/knowledge/knowledgeIndex.d.ts +41 -0
- package/dist/lib/knowledge/knowledgeIndex.js +205 -0
- package/dist/lib/knowledge/normalize.d.ts +32 -0
- package/dist/lib/knowledge/normalize.js +75 -0
- package/dist/lib/knowledge/resolve.d.ts +18 -0
- package/dist/lib/knowledge/resolve.js +157 -0
- package/dist/lib/knowledge/retrieval.d.ts +16 -0
- package/dist/lib/knowledge/retrieval.js +222 -0
- package/dist/lib/mcp/toolDiscoveryService.js +59 -20
- package/dist/lib/neurolink.d.ts +14 -1
- package/dist/lib/neurolink.js +142 -12
- package/dist/lib/providers/litellm.d.ts +27 -19
- package/dist/lib/providers/litellm.js +171 -92
- package/dist/lib/providers/openaiChatCompletionsBase.d.ts +37 -1
- package/dist/lib/providers/openaiChatCompletionsBase.js +201 -33
- package/dist/lib/providers/openaiChatCompletionsClient.d.ts +23 -5
- package/dist/lib/providers/openaiChatCompletionsClient.js +94 -14
- package/dist/lib/proxy/proxyFetch.d.ts +17 -0
- package/dist/lib/proxy/proxyFetch.js +42 -4
- package/dist/lib/types/config.d.ts +12 -0
- package/dist/lib/types/conversation.d.ts +1 -1
- package/dist/lib/types/dynamic.d.ts +12 -0
- package/dist/lib/types/generate.d.ts +32 -2
- package/dist/lib/types/index.d.ts +1 -0
- package/dist/lib/types/index.js +1 -0
- package/dist/lib/types/knowledge.d.ts +342 -0
- package/dist/lib/types/knowledge.js +30 -0
- package/dist/lib/types/openaiCompatible.d.ts +2 -0
- package/dist/lib/types/providers.d.ts +9 -0
- package/dist/lib/types/stream.d.ts +14 -0
- package/dist/lib/utils/errorHandling.js +8 -2
- package/dist/lib/utils/schemaConversion.d.ts +16 -0
- package/dist/lib/utils/schemaConversion.js +165 -8
- package/dist/lib/utils/timeout.d.ts +22 -0
- package/dist/lib/utils/timeout.js +72 -12
- package/dist/lib/utils/tokenLimits.js +22 -0
- package/dist/lib/utils/toolCallRepair.d.ts +8 -0
- package/dist/lib/utils/toolCallRepair.js +4 -1
- package/dist/mcp/toolDiscoveryService.js +59 -20
- package/dist/neurolink.d.ts +14 -1
- package/dist/neurolink.js +142 -12
- package/dist/providers/litellm.d.ts +27 -19
- package/dist/providers/litellm.js +171 -92
- package/dist/providers/openaiChatCompletionsBase.d.ts +37 -1
- package/dist/providers/openaiChatCompletionsBase.js +201 -33
- package/dist/providers/openaiChatCompletionsClient.d.ts +23 -5
- package/dist/providers/openaiChatCompletionsClient.js +94 -14
- package/dist/proxy/proxyFetch.d.ts +17 -0
- package/dist/proxy/proxyFetch.js +42 -4
- package/dist/types/config.d.ts +12 -0
- package/dist/types/conversation.d.ts +1 -1
- package/dist/types/dynamic.d.ts +12 -0
- package/dist/types/generate.d.ts +32 -2
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/knowledge.d.ts +342 -0
- package/dist/types/knowledge.js +29 -0
- package/dist/types/openaiCompatible.d.ts +2 -0
- package/dist/types/providers.d.ts +9 -0
- package/dist/types/stream.d.ts +14 -0
- package/dist/utils/errorHandling.js +8 -2
- package/dist/utils/schemaConversion.d.ts +16 -0
- package/dist/utils/schemaConversion.js +165 -8
- package/dist/utils/timeout.d.ts +22 -0
- package/dist/utils/timeout.js +72 -12
- package/dist/utils/tokenLimits.js +22 -0
- package/dist/utils/toolCallRepair.d.ts +8 -0
- package/dist/utils/toolCallRepair.js +4 -1
- package/package.json +4 -1
|
@@ -14,8 +14,72 @@
|
|
|
14
14
|
* module is to be the native replacement for the AI SDK's OpenAI wrapper.
|
|
15
15
|
*/
|
|
16
16
|
import { createParser } from "eventsource-parser";
|
|
17
|
-
import {
|
|
17
|
+
import { sanitizeToolName } from "../mcp/toolConverter.js";
|
|
18
|
+
import { convertZodToJsonSchema, normalizeWireToolSchema, } from "../utils/schemaConversion.js";
|
|
19
|
+
import { estimateTokens, TOKENS_PER_MESSAGE, } from "../utils/tokenEstimation.js";
|
|
18
20
|
export const stripTrailingSlash = (s) => s.replace(/\/+$/, "");
|
|
21
|
+
// OpenAI-compatible wire tool names: first char letter/underscore (some
|
|
22
|
+
// chat templates treat a leading digit or hyphen as invalid identifiers),
|
|
23
|
+
// then letters/digits/underscore/hyphen, 64 chars total — exactly the
|
|
24
|
+
// pattern below, which mirrors sanitizeToolName's output alphabet. MCP
|
|
25
|
+
// servers can register names outside it (dots, colons, spaces); sent
|
|
26
|
+
// verbatim they make backends reject the tools block or emit tool_calls
|
|
27
|
+
// that no longer match the registry.
|
|
28
|
+
const WIRE_TOOL_NAME_RE = /^[a-zA-Z_][a-zA-Z0-9_-]{0,63}$/;
|
|
29
|
+
/**
|
|
30
|
+
* Build a bijective original ↔ wire tool-name map. Returns undefined when
|
|
31
|
+
* every name is already wire-valid (the common case — the wire then uses
|
|
32
|
+
* original names untouched and callers skip all mapping). Sanitized names
|
|
33
|
+
* that collide get a deterministic numeric suffix so the map stays
|
|
34
|
+
* invertible.
|
|
35
|
+
*/
|
|
36
|
+
export const buildWireToolNameMaps = (names) => {
|
|
37
|
+
if (names.every((name) => WIRE_TOOL_NAME_RE.test(name))) {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
const toWire = new Map();
|
|
41
|
+
const fromWire = new Map();
|
|
42
|
+
for (const name of names) {
|
|
43
|
+
let wire = WIRE_TOOL_NAME_RE.test(name) ? name : sanitizeToolName(name);
|
|
44
|
+
if (fromWire.has(wire)) {
|
|
45
|
+
let suffix = 2;
|
|
46
|
+
let candidate;
|
|
47
|
+
do {
|
|
48
|
+
const tail = `_${suffix}`;
|
|
49
|
+
candidate = `${wire.slice(0, 64 - tail.length)}${tail}`;
|
|
50
|
+
suffix++;
|
|
51
|
+
} while (fromWire.has(candidate));
|
|
52
|
+
wire = candidate;
|
|
53
|
+
}
|
|
54
|
+
toWire.set(name, wire);
|
|
55
|
+
fromWire.set(wire, name);
|
|
56
|
+
}
|
|
57
|
+
return { toWire, fromWire };
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Estimate the input-token cost of a fully-built wire request (messages +
|
|
61
|
+
* tool definitions). Used by the per-request max_tokens fit against a
|
|
62
|
+
* RUNTIME-DISCOVERED context window — deliberately the same char-based
|
|
63
|
+
* estimator the budget pipeline uses, so both layers agree.
|
|
64
|
+
*/
|
|
65
|
+
export const estimateWireTokens = (messages, tools, provider) => {
|
|
66
|
+
let total = 0;
|
|
67
|
+
for (const message of messages) {
|
|
68
|
+
const content = typeof message.content === "string"
|
|
69
|
+
? message.content
|
|
70
|
+
: safeStringify(message.content);
|
|
71
|
+
total += estimateTokens(content, provider) + TOKENS_PER_MESSAGE;
|
|
72
|
+
// tool_calls only exists on the assistant variant of the message union.
|
|
73
|
+
const toolCalls = message.tool_calls;
|
|
74
|
+
if (toolCalls) {
|
|
75
|
+
total += estimateTokens(safeStringify(toolCalls), provider);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (tools && tools.length > 0) {
|
|
79
|
+
total += estimateTokens(safeStringify(tools), provider);
|
|
80
|
+
}
|
|
81
|
+
return total;
|
|
82
|
+
};
|
|
19
83
|
export const safeStringify = (value) => {
|
|
20
84
|
try {
|
|
21
85
|
return JSON.stringify(value ?? "");
|
|
@@ -132,7 +196,7 @@ export const convertContentForOpenAI = (content) => {
|
|
|
132
196
|
}
|
|
133
197
|
return out;
|
|
134
198
|
};
|
|
135
|
-
export const messageBuilderToOpenAI = (messages) => {
|
|
199
|
+
export const messageBuilderToOpenAI = (messages, toolNameToWire) => {
|
|
136
200
|
const out = [];
|
|
137
201
|
for (const msg of messages) {
|
|
138
202
|
switch (msg.role) {
|
|
@@ -165,11 +229,14 @@ export const messageBuilderToOpenAI = (messages) => {
|
|
|
165
229
|
}
|
|
166
230
|
else if (p.type === "tool-call") {
|
|
167
231
|
const tc = part;
|
|
232
|
+
// History tool-call names must match the wire `tools` block —
|
|
233
|
+
// forward-map when a wire-name map is in effect.
|
|
234
|
+
const historyName = tc.toolName ?? "";
|
|
168
235
|
toolCalls.push({
|
|
169
236
|
id: tc.toolCallId ?? "",
|
|
170
237
|
type: "function",
|
|
171
238
|
function: {
|
|
172
|
-
name:
|
|
239
|
+
name: toolNameToWire?.get(historyName) ?? historyName,
|
|
173
240
|
arguments: stringifyToolInput(tc.input),
|
|
174
241
|
},
|
|
175
242
|
});
|
|
@@ -223,7 +290,7 @@ export const messageBuilderToOpenAI = (messages) => {
|
|
|
223
290
|
}
|
|
224
291
|
return out;
|
|
225
292
|
};
|
|
226
|
-
export const buildToolsForOpenAI = (tools) => {
|
|
293
|
+
export const buildToolsForOpenAI = (tools, toolNameToWire) => {
|
|
227
294
|
const entries = Object.entries(tools);
|
|
228
295
|
if (entries.length === 0) {
|
|
229
296
|
return undefined;
|
|
@@ -235,14 +302,16 @@ export const buildToolsForOpenAI = (tools) => {
|
|
|
235
302
|
// tool.inputSchema may be a Zod schema, an AI SDK jsonSchema() wrapper,
|
|
236
303
|
// or plain JSON Schema — convertZodToJsonSchema normalizes all three.
|
|
237
304
|
// Sending raw Zod internals (with `_def`) gets rejected by most
|
|
238
|
-
// OpenAI-compatible endpoints.
|
|
305
|
+
// OpenAI-compatible endpoints. normalizeWireToolSchema then strips
|
|
306
|
+
// $schema/$defs indirection that proxied backends render into chat
|
|
307
|
+
// templates verbatim (degrading argument generation).
|
|
239
308
|
const parameters = rawSchema
|
|
240
|
-
? convertZodToJsonSchema(rawSchema)
|
|
309
|
+
? normalizeWireToolSchema(convertZodToJsonSchema(rawSchema))
|
|
241
310
|
: { type: "object", properties: {} };
|
|
242
311
|
out.push({
|
|
243
312
|
type: "function",
|
|
244
313
|
function: {
|
|
245
|
-
name,
|
|
314
|
+
name: toolNameToWire?.get(name) ?? name,
|
|
246
315
|
...(t.description ? { description: t.description } : {}),
|
|
247
316
|
parameters,
|
|
248
317
|
},
|
|
@@ -254,7 +323,7 @@ export const buildToolsForOpenAI = (tools) => {
|
|
|
254
323
|
// path that BaseProvider's `generate()` still drives via the AI SDK's
|
|
255
324
|
// `generateText`. The streaming path doesn't need these — it consumes
|
|
256
325
|
// NeuroLink-shaped options directly.
|
|
257
|
-
export const v3ToolsToOpenAI = (tools) => {
|
|
326
|
+
export const v3ToolsToOpenAI = (tools, toolNameToWire) => {
|
|
258
327
|
if (!tools || tools.length === 0) {
|
|
259
328
|
return undefined;
|
|
260
329
|
}
|
|
@@ -264,9 +333,12 @@ export const v3ToolsToOpenAI = (tools) => {
|
|
|
264
333
|
out.push({
|
|
265
334
|
type: "function",
|
|
266
335
|
function: {
|
|
267
|
-
name: t.name,
|
|
336
|
+
name: toolNameToWire?.get(t.name) ?? t.name,
|
|
268
337
|
...(t.description ? { description: t.description } : {}),
|
|
269
|
-
|
|
338
|
+
// The AI SDK serializes inputSchema to JSON Schema before
|
|
339
|
+
// doGenerate; normalize the wire form ($ref/$defs inlining,
|
|
340
|
+
// annotation stripping, nullable collapse) for proxied backends.
|
|
341
|
+
parameters: normalizeWireToolSchema(t.inputSchema),
|
|
270
342
|
...(t.strict !== undefined ? { strict: t.strict } : {}),
|
|
271
343
|
},
|
|
272
344
|
});
|
|
@@ -276,14 +348,19 @@ export const v3ToolsToOpenAI = (tools) => {
|
|
|
276
348
|
}
|
|
277
349
|
return out.length > 0 ? out : undefined;
|
|
278
350
|
};
|
|
279
|
-
export const v3ToolChoiceToOpenAI = (choice) => {
|
|
351
|
+
export const v3ToolChoiceToOpenAI = (choice, toolNameToWire) => {
|
|
280
352
|
switch (choice.type) {
|
|
281
353
|
case "auto":
|
|
282
354
|
case "none":
|
|
283
355
|
case "required":
|
|
284
356
|
return choice.type;
|
|
285
357
|
case "tool":
|
|
286
|
-
return {
|
|
358
|
+
return {
|
|
359
|
+
type: "function",
|
|
360
|
+
function: {
|
|
361
|
+
name: toolNameToWire?.get(choice.toolName) ?? choice.toolName,
|
|
362
|
+
},
|
|
363
|
+
};
|
|
287
364
|
}
|
|
288
365
|
};
|
|
289
366
|
export const v3ResponseFormatToOpenAI = (rf) => {
|
|
@@ -303,7 +380,7 @@ export const v3ResponseFormatToOpenAI = (rf) => {
|
|
|
303
380
|
},
|
|
304
381
|
};
|
|
305
382
|
};
|
|
306
|
-
export const mapNeuroLinkToolChoice = (choice) => {
|
|
383
|
+
export const mapNeuroLinkToolChoice = (choice, toolNameToWire) => {
|
|
307
384
|
if (!choice) {
|
|
308
385
|
return undefined;
|
|
309
386
|
}
|
|
@@ -313,7 +390,10 @@ export const mapNeuroLinkToolChoice = (choice) => {
|
|
|
313
390
|
if (typeof choice === "object" && choice !== null) {
|
|
314
391
|
const c = choice;
|
|
315
392
|
if (c.type === "tool" && c.toolName) {
|
|
316
|
-
return {
|
|
393
|
+
return {
|
|
394
|
+
type: "function",
|
|
395
|
+
function: { name: toolNameToWire?.get(c.toolName) ?? c.toolName },
|
|
396
|
+
};
|
|
317
397
|
}
|
|
318
398
|
}
|
|
319
399
|
return undefined;
|
|
@@ -3,6 +3,23 @@
|
|
|
3
3
|
* Supports HTTP/HTTPS, SOCKS4/5, authentication, and NO_PROXY bypass
|
|
4
4
|
* Lightweight implementation extracted from research of major proxy packages
|
|
5
5
|
*/
|
|
6
|
+
/**
|
|
7
|
+
* Classify a fetch failure as a transient network error worth retrying.
|
|
8
|
+
*
|
|
9
|
+
* undici's `fetch()` wraps the real failure in `TypeError: fetch failed`
|
|
10
|
+
* with the actionable code (`ECONNRESET`, `UND_ERR_SOCKET`, ...) on
|
|
11
|
+
* `error.cause` — sometimes nested another level (e.g. SocketError inside
|
|
12
|
+
* a ConnectTimeoutError). Walk the cause chain so those are recognized;
|
|
13
|
+
* checking only the top-level error silently classified every undici
|
|
14
|
+
* connection death as non-retryable.
|
|
15
|
+
*
|
|
16
|
+
* Deliberately NOT retried: `UND_ERR_HEADERS_TIMEOUT` / `UND_ERR_BODY_TIMEOUT`
|
|
17
|
+
* — those already waited out undici's own long deadline (default 300s), and
|
|
18
|
+
* replaying them can triple a stall under the caller's wall-clock budget.
|
|
19
|
+
*
|
|
20
|
+
* Exported for direct coverage by the no-API test suite.
|
|
21
|
+
*/
|
|
22
|
+
export declare function isTransientNetworkError(error: unknown): boolean;
|
|
6
23
|
/**
|
|
7
24
|
* Create a proxy-aware fetch function with enhanced capabilities
|
|
8
25
|
* Supports HTTP/HTTPS, SOCKS4/5, authentication, and NO_PROXY bypass
|
package/dist/proxy/proxyFetch.js
CHANGED
|
@@ -79,6 +79,47 @@ function extractHostname(url) {
|
|
|
79
79
|
return "[unknown]";
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
|
+
/** Error codes classified as transient (module-scope: the retry path is hot). */
|
|
83
|
+
const TRANSIENT_NETWORK_CODES = new Set([
|
|
84
|
+
"ECONNRESET",
|
|
85
|
+
"ETIMEDOUT",
|
|
86
|
+
"ECONNREFUSED",
|
|
87
|
+
"EPIPE",
|
|
88
|
+
"UND_ERR_SOCKET",
|
|
89
|
+
"UND_ERR_CONNECT_TIMEOUT",
|
|
90
|
+
]);
|
|
91
|
+
/**
|
|
92
|
+
* Classify a fetch failure as a transient network error worth retrying.
|
|
93
|
+
*
|
|
94
|
+
* undici's `fetch()` wraps the real failure in `TypeError: fetch failed`
|
|
95
|
+
* with the actionable code (`ECONNRESET`, `UND_ERR_SOCKET`, ...) on
|
|
96
|
+
* `error.cause` — sometimes nested another level (e.g. SocketError inside
|
|
97
|
+
* a ConnectTimeoutError). Walk the cause chain so those are recognized;
|
|
98
|
+
* checking only the top-level error silently classified every undici
|
|
99
|
+
* connection death as non-retryable.
|
|
100
|
+
*
|
|
101
|
+
* Deliberately NOT retried: `UND_ERR_HEADERS_TIMEOUT` / `UND_ERR_BODY_TIMEOUT`
|
|
102
|
+
* — those already waited out undici's own long deadline (default 300s), and
|
|
103
|
+
* replaying them can triple a stall under the caller's wall-clock budget.
|
|
104
|
+
*
|
|
105
|
+
* Exported for direct coverage by the no-API test suite.
|
|
106
|
+
*/
|
|
107
|
+
export function isTransientNetworkError(error) {
|
|
108
|
+
let current = error;
|
|
109
|
+
for (let depth = 0; depth < 5 && current; depth++) {
|
|
110
|
+
const err = current;
|
|
111
|
+
if (err.code && TRANSIENT_NETWORK_CODES.has(err.code)) {
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
if (err.message?.includes("socket hang up") ||
|
|
115
|
+
err.message?.includes("network socket disconnected") ||
|
|
116
|
+
err.message?.includes("other side closed")) {
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
current = err.cause;
|
|
120
|
+
}
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
82
123
|
/**
|
|
83
124
|
* Retry-aware fetch wrapper for transient network errors (ECONNRESET, ETIMEDOUT, socket hang up).
|
|
84
125
|
* Protects all LLM API calls and token refreshes that go through createProxyFetch().
|
|
@@ -104,11 +145,8 @@ async function fetchWithRetry(url, init, maxRetries = 3, baseDelay = 500) {
|
|
|
104
145
|
return response;
|
|
105
146
|
}
|
|
106
147
|
catch (error) {
|
|
148
|
+
const isRetryable = isTransientNetworkError(error);
|
|
107
149
|
const err = error;
|
|
108
|
-
const isRetryable = err?.code === "ECONNRESET" ||
|
|
109
|
-
err?.code === "ETIMEDOUT" ||
|
|
110
|
-
err?.message?.includes("socket hang up") ||
|
|
111
|
-
err?.message?.includes("network socket disconnected");
|
|
112
150
|
if (!isRetryable || attempt === maxRetries) {
|
|
113
151
|
// Final failure — record on span and rethrow
|
|
114
152
|
span.setAttribute("http.request.total_attempts", totalAttempts);
|
package/dist/types/config.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ import type { ModelPoolConfig } from "./modelPool.js";
|
|
|
13
13
|
import type { RequestRouter } from "./requestRouter.js";
|
|
14
14
|
import type { ClassifierRouterConfig } from "./classifierRouter.js";
|
|
15
15
|
import type { SkillsConfig } from "./skills.js";
|
|
16
|
+
import type { KnowledgeGroundingConfig } from "./knowledge.js";
|
|
16
17
|
/**
|
|
17
18
|
* Main NeuroLink configuration type
|
|
18
19
|
*/
|
|
@@ -130,6 +131,17 @@ export type NeurolinkConstructorConfig = {
|
|
|
130
131
|
* Opt-in and fails open on read paths. See {@link SkillsConfig}.
|
|
131
132
|
*/
|
|
132
133
|
skills?: SkillsConfig;
|
|
134
|
+
/**
|
|
135
|
+
* Knowledge grounding: lexical-first host-supplied knowledge retrieval. When
|
|
136
|
+
* enabled with at least one source, a deterministic in-memory retrieval runs
|
|
137
|
+
* before each generate()/stream() turn — independently of tool routing — and
|
|
138
|
+
* attaches a token-bounded, ephemeral knowledge block to the model call. No
|
|
139
|
+
* embeddings or vector store. Opt-in (`enabled: false` by default) and fails
|
|
140
|
+
* open: any retrieval failure leaves the turn ungrounded. Sources are fixed
|
|
141
|
+
* for the lifetime of the instance. See
|
|
142
|
+
* {@link KnowledgeGroundingConfig}.
|
|
143
|
+
*/
|
|
144
|
+
knowledgeGrounding?: KnowledgeGroundingConfig;
|
|
133
145
|
};
|
|
134
146
|
/**
|
|
135
147
|
* Configuration for MCP enhancement modules wired into generate()/stream() paths.
|
|
@@ -429,7 +429,7 @@ export type SessionMetadata = {
|
|
|
429
429
|
* Report type for agentic loop reports
|
|
430
430
|
* Identifies the platform or category of the report
|
|
431
431
|
*/
|
|
432
|
-
export type AgenticLoopReportType = "META" | "GOOGLEADS" | "GOOGLEGA4" | "OTHER";
|
|
432
|
+
export type AgenticLoopReportType = "META" | "GOOGLEADS" | "GOOGLEGA4" | "SHOPIFY" | "BREEZE" | "OTHER";
|
|
433
433
|
/**
|
|
434
434
|
* Status of an agentic loop report
|
|
435
435
|
*/
|
package/dist/types/dynamic.d.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* @module types/dynamic
|
|
8
8
|
*/
|
|
9
9
|
import type { AIProviderName } from "../constants/enums.js";
|
|
10
|
+
import type { KnowledgeRequestScope } from "./knowledge.js";
|
|
10
11
|
/**
|
|
11
12
|
* Context passed to context-aware dynamic argument functions.
|
|
12
13
|
* `requestContext` is whatever the consumer passed as `dynamicContext` —
|
|
@@ -39,6 +40,17 @@ export type DynamicArgument<T> = T | (() => T) | (() => Promise<T>) | ((context:
|
|
|
39
40
|
* instead of static values for context-aware resolution.
|
|
40
41
|
*/
|
|
41
42
|
export type DynamicOptions = {
|
|
43
|
+
/**
|
|
44
|
+
* Opt this call into the knowledge grounding configured on the NeuroLink
|
|
45
|
+
* instance. This flag is intentionally static because grounding runs before
|
|
46
|
+
* dynamic arguments are resolved.
|
|
47
|
+
*/
|
|
48
|
+
useKnowledgeGrounding?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Enabled integrations used to scope knowledge retrieval for this turn.
|
|
51
|
+
* This scope is intentionally static for the same reason.
|
|
52
|
+
*/
|
|
53
|
+
knowledgeContext?: KnowledgeRequestScope;
|
|
42
54
|
model?: DynamicArgument<string>;
|
|
43
55
|
provider?: DynamicArgument<AIProviderName | string>;
|
|
44
56
|
temperature?: DynamicArgument<number>;
|
package/dist/types/generate.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AIProviderName } from "../constants/enums.js";
|
|
2
2
|
import type { RAGConfig } from "./rag.js";
|
|
3
|
+
import type { KnowledgeGroundingMetadata, KnowledgeRequestScope } from "./knowledge.js";
|
|
3
4
|
import type { SkillsCallOptions } from "./skills.js";
|
|
4
5
|
import type { AnalyticsData, TokenUsage } from "./analytics.js";
|
|
5
6
|
import type { JsonValue } from "./common.js";
|
|
@@ -323,8 +324,15 @@ export type GenerateOptions = {
|
|
|
323
324
|
* never the step-cap text. Unset = no turn-level deadline (the library
|
|
324
325
|
* imposes no product policy).
|
|
325
326
|
*
|
|
326
|
-
* Enforced by the native Vertex loops (Gemini + Claude)
|
|
327
|
-
* providers
|
|
327
|
+
* Enforced by the native Vertex loops (Gemini + Claude) AND the AI-SDK
|
|
328
|
+
* loop path (litellm and other OpenAI-compatible providers). On the AI-SDK
|
|
329
|
+
* path, an explicit `timeout` also engages the same wrap-up when
|
|
330
|
+
* `turnTimeoutMs` is unset. Once the wrap-up window begins (see
|
|
331
|
+
* `wrapupTimeLeadMs`), the loop forcibly sets `toolChoice: "none"` for the
|
|
332
|
+
* remaining steps — overriding any caller-supplied `toolChoice` or
|
|
333
|
+
* `prepareStep` tool selection — and appends an honest time message that a
|
|
334
|
+
* caller's `prepareStep` callback does not observe (it runs before the
|
|
335
|
+
* wrap-up nudge is applied). An honest partial beats a discarded turn.
|
|
328
336
|
*/
|
|
329
337
|
turnTimeoutMs?: number;
|
|
330
338
|
/**
|
|
@@ -340,6 +348,11 @@ export type GenerateOptions = {
|
|
|
340
348
|
* next tool-result turn telling the model to consolidate what it has and
|
|
341
349
|
* produce its final answer. Defaults to 120_000 when `turnTimeoutMs` is
|
|
342
350
|
* set; ignored when it is not.
|
|
351
|
+
*
|
|
352
|
+
* On the AI-SDK loop path the lead is clamped to a quarter of the turn
|
|
353
|
+
* budget (so short budgets don't wrap up on step one) and wrap-up steps
|
|
354
|
+
* run with a forced `toolChoice: "none"` — see `turnTimeoutMs` for the
|
|
355
|
+
* exact override semantics.
|
|
343
356
|
*/
|
|
344
357
|
wrapupTimeLeadMs?: number;
|
|
345
358
|
/**
|
|
@@ -350,6 +363,8 @@ export type GenerateOptions = {
|
|
|
350
363
|
toolTimeoutMs?: number;
|
|
351
364
|
/** AbortSignal for external cancellation of the AI call */
|
|
352
365
|
abortSignal?: AbortSignal;
|
|
366
|
+
/** Disable the schema-driven tool call repair mechanism (BZ-665). Default: false (repair enabled). */
|
|
367
|
+
disableToolCallRepair?: boolean;
|
|
353
368
|
/**
|
|
354
369
|
* Disable tool execution (including built-in tools)
|
|
355
370
|
*
|
|
@@ -531,6 +546,17 @@ export type GenerateOptions = {
|
|
|
531
546
|
onError?: OnErrorCallback;
|
|
532
547
|
/** Pre-validated user context for the request */
|
|
533
548
|
requestContext?: Record<string, unknown>;
|
|
549
|
+
/**
|
|
550
|
+
* Opt this generation call into the knowledge grounding configured on the
|
|
551
|
+
* NeuroLink instance. Defaults to `false` when omitted.
|
|
552
|
+
*/
|
|
553
|
+
useKnowledgeGrounding?: boolean;
|
|
554
|
+
/**
|
|
555
|
+
* Enabled integrations used to scope knowledge retrieval for this turn.
|
|
556
|
+
* Used only when `useKnowledgeGrounding` is true and knowledge grounding is
|
|
557
|
+
* enabled on the NeuroLink instance.
|
|
558
|
+
*/
|
|
559
|
+
knowledgeContext?: KnowledgeRequestScope;
|
|
534
560
|
/** Raw auth token — validated by configured auth provider */
|
|
535
561
|
auth?: {
|
|
536
562
|
token: string;
|
|
@@ -676,6 +702,8 @@ export type GenerateStopReason = "completed" | "step-cap" | "context-cap" | "tim
|
|
|
676
702
|
*/
|
|
677
703
|
export type GenerateResult = {
|
|
678
704
|
content: string;
|
|
705
|
+
/** Knowledge-grounding diagnostics for this turn (present only when grounding ran). */
|
|
706
|
+
knowledge?: KnowledgeGroundingMetadata;
|
|
679
707
|
/**
|
|
680
708
|
* Parsed structured object when a `schema` was requested. Populated from
|
|
681
709
|
* AI-SDK experimental_output, or from text-mode coercion (balanced-scan +
|
|
@@ -1015,6 +1043,8 @@ export type TextGenerationOptions = {
|
|
|
1015
1043
|
/** AbortSignal for external cancellation of the AI call */
|
|
1016
1044
|
abortSignal?: AbortSignal;
|
|
1017
1045
|
disableTools?: boolean;
|
|
1046
|
+
/** Disable the schema-driven tool call repair mechanism (BZ-665). Default: false (repair enabled). */
|
|
1047
|
+
disableToolCallRepair?: boolean;
|
|
1018
1048
|
maxSteps?: number;
|
|
1019
1049
|
/** Include only these tools by name (whitelist). If set, only matching tools are available. */
|
|
1020
1050
|
toolFilter?: string[];
|
package/dist/types/index.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ export * from "./generate.js";
|
|
|
28
28
|
export * from "./grounding.js";
|
|
29
29
|
export * from "./guardrails.js";
|
|
30
30
|
export * from "./hitl.js";
|
|
31
|
+
export * from "./knowledge.js";
|
|
31
32
|
export * from "./livekit.js";
|
|
32
33
|
export * from "./mcp.js";
|
|
33
34
|
export * from "./mcpOutput.js";
|
package/dist/types/index.js
CHANGED
|
@@ -29,6 +29,7 @@ export * from "./generate.js";
|
|
|
29
29
|
export * from "./grounding.js";
|
|
30
30
|
export * from "./guardrails.js";
|
|
31
31
|
export * from "./hitl.js";
|
|
32
|
+
export * from "./knowledge.js";
|
|
32
33
|
export * from "./livekit.js";
|
|
33
34
|
export * from "./mcp.js";
|
|
34
35
|
export * from "./mcpOutput.js";
|