@juspay/neurolink 13.6.3 → 13.6.4
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 +410 -410
- package/dist/core/nativeGenerateLoop.d.ts +13 -0
- package/dist/core/nativeGenerateLoop.js +38 -5
- package/dist/providers/amazonSagemaker.js +2 -12
- package/dist/providers/anthropic/client.js +2 -12
- package/dist/providers/openaiChatCompletionsBase.js +5 -23
- package/dist/types/generate.d.ts +6 -5
- package/package.json +1 -1
|
@@ -86,6 +86,19 @@ export declare const hasNativeDoGenerate: (value: unknown) => value is {
|
|
|
86
86
|
};
|
|
87
87
|
/** A tool's inputSchema with its lazy (function) form, if any, resolved. */
|
|
88
88
|
export declare const resolveToolInputSchema: (schema: Tool["inputSchema"]) => Exclude<Tool["inputSchema"], (...args: never[]) => unknown>;
|
|
89
|
+
/**
|
|
90
|
+
* The provider-neutral declaration of one tool: the shape every provider's
|
|
91
|
+
* `doGenerate` already converts to its own wire format. The loop uses it for
|
|
92
|
+
* the tools discovery loads mid-turn, and the providers that run the loop use
|
|
93
|
+
* it for their initial declarations, so a tool is declared the same way
|
|
94
|
+
* whether it is there at the start or joins later.
|
|
95
|
+
*/
|
|
96
|
+
export declare const toNativeToolDeclaration: (name: string, tool: Tool) => {
|
|
97
|
+
type: "function";
|
|
98
|
+
name: string;
|
|
99
|
+
description: string;
|
|
100
|
+
inputSchema: object;
|
|
101
|
+
};
|
|
89
102
|
/**
|
|
90
103
|
* Spell a JSON Schema into the conversation's system turn.
|
|
91
104
|
*
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
import { observeGeneration } from "../telemetry/observation.js";
|
|
17
17
|
import { StepSpans, withGeneration } from "../telemetry/withSpan.js";
|
|
18
18
|
import { logger } from "../utils/logger.js";
|
|
19
|
+
import { convertZodToJsonSchema } from "../utils/schemaConversion.js";
|
|
19
20
|
import { guardToolExecutor } from "./toolExecutionGuards.js";
|
|
20
21
|
import { resolveLiveTool } from "../tools/toolDiscovery.js";
|
|
21
22
|
const DEFAULT_TOOL_CHOICE_STEPS = 1;
|
|
@@ -339,6 +340,35 @@ const parseToolInput = (raw) => {
|
|
|
339
340
|
};
|
|
340
341
|
/** A tool's inputSchema with its lazy (function) form, if any, resolved. */
|
|
341
342
|
export const resolveToolInputSchema = (schema) => typeof schema === "function" ? resolveToolInputSchema(schema()) : schema;
|
|
343
|
+
/**
|
|
344
|
+
* The provider-neutral declaration of one tool: the shape every provider's
|
|
345
|
+
* `doGenerate` already converts to its own wire format. The loop uses it for
|
|
346
|
+
* the tools discovery loads mid-turn, and the providers that run the loop use
|
|
347
|
+
* it for their initial declarations, so a tool is declared the same way
|
|
348
|
+
* whether it is there at the start or joins later.
|
|
349
|
+
*/
|
|
350
|
+
export const toNativeToolDeclaration = (name, tool) => ({
|
|
351
|
+
type: "function",
|
|
352
|
+
name,
|
|
353
|
+
description: tool.description ?? "",
|
|
354
|
+
inputSchema: declaredInputSchema(name, tool),
|
|
355
|
+
});
|
|
356
|
+
// A lazy schema that throws must not take the whole request down: SageMaker and
|
|
357
|
+
// Anthropic declared any function-valued schema as the empty object schema
|
|
358
|
+
// before the lazy form was resolved here, so a broken one falls back to that.
|
|
359
|
+
function declaredInputSchema(name, tool) {
|
|
360
|
+
const empty = { type: "object", properties: {} };
|
|
361
|
+
if (!tool.inputSchema) {
|
|
362
|
+
return empty;
|
|
363
|
+
}
|
|
364
|
+
try {
|
|
365
|
+
return convertZodToJsonSchema(resolveToolInputSchema(tool.inputSchema));
|
|
366
|
+
}
|
|
367
|
+
catch (error) {
|
|
368
|
+
logger.warn(`[nativeGenerateLoop] input schema of tool "${name}" could not be resolved; declaring it with an empty object schema`, { error: error instanceof Error ? error.message : String(error) });
|
|
369
|
+
return empty;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
342
372
|
/**
|
|
343
373
|
* Validate parsed input against the tool's own schema when it exposes one.
|
|
344
374
|
*
|
|
@@ -486,20 +516,23 @@ async function runGenerateSteps(args, toolExecutionSummaries, stepSpans) {
|
|
|
486
516
|
// answer is that result — not a thrown turn.
|
|
487
517
|
let preReask;
|
|
488
518
|
const hasTools = Boolean(args.tools && args.tools.length > 0);
|
|
489
|
-
// The declarations actually sent.
|
|
490
|
-
// a tool joins toolsRecord mid-turn (discovery loads tools into
|
|
491
|
-
|
|
519
|
+
// The declarations actually sent. It is the caller's own array and grows in
|
|
520
|
+
// place when a tool joins toolsRecord mid-turn (discovery loads tools into
|
|
521
|
+
// it), so anything the caller sized from it, such as the context guard's
|
|
522
|
+
// fixed-overhead estimate, counts the new tools too.
|
|
523
|
+
const liveTools = args.tools;
|
|
524
|
+
const declare = args.declareTool ?? toNativeToolDeclaration;
|
|
492
525
|
const declaredNames = declaredToolRecord(args.tools);
|
|
493
526
|
// Completed-step records for `prepareStep`; one per step that returned.
|
|
494
527
|
const stepRecords = [];
|
|
495
528
|
for (let step = 0; step < args.maxSteps; step++) {
|
|
496
529
|
steps = step + 1;
|
|
497
530
|
stepSpans.begin(steps);
|
|
498
|
-
if (liveTools
|
|
531
|
+
if (liveTools) {
|
|
499
532
|
const loaded = [];
|
|
500
533
|
for (const name of Object.keys(args.toolsRecord)) {
|
|
501
534
|
if (!declaredNames[name]) {
|
|
502
|
-
liveTools.push(
|
|
535
|
+
liveTools.push(declare(name, args.toolsRecord[name]));
|
|
503
536
|
declaredNames[name] = true;
|
|
504
537
|
loaded.push(name);
|
|
505
538
|
}
|
|
@@ -9,7 +9,7 @@ import { convertZodToJsonSchema } from "../utils/schemaConversion.js";
|
|
|
9
9
|
import { withProviderRetry } from "../utils/providerRetry.js";
|
|
10
10
|
import { resolveToolChoice } from "../utils/toolChoice.js";
|
|
11
11
|
import { DEFAULT_MAX_STEPS } from "../core/constants.js";
|
|
12
|
-
import { hasNativeDoGenerate, runNativeGenerateLoop, } from "../core/nativeGenerateLoop.js";
|
|
12
|
+
import { hasNativeDoGenerate, runNativeGenerateLoop, toNativeToolDeclaration, } from "../core/nativeGenerateLoop.js";
|
|
13
13
|
import { generationName } from "../telemetry/observationNames.js";
|
|
14
14
|
import { observeGeneration } from "../telemetry/observation.js";
|
|
15
15
|
import { tracers } from "../telemetry/tracers.js";
|
|
@@ -208,17 +208,7 @@ export class AmazonSageMakerProvider extends BaseProvider {
|
|
|
208
208
|
const toolsRecord = shouldUseTools
|
|
209
209
|
? options.tools || {}
|
|
210
210
|
: {};
|
|
211
|
-
const v3Tools = Object.entries(toolsRecord).map(([name, t]) =>
|
|
212
|
-
const tool = t;
|
|
213
|
-
return {
|
|
214
|
-
type: "function",
|
|
215
|
-
name,
|
|
216
|
-
description: tool.description ?? "",
|
|
217
|
-
inputSchema: (tool.inputSchema
|
|
218
|
-
? convertZodToJsonSchema(tool.inputSchema)
|
|
219
|
-
: { type: "object", properties: {} }),
|
|
220
|
-
};
|
|
221
|
-
});
|
|
211
|
+
const v3Tools = Object.entries(toolsRecord).map(([name, t]) => toNativeToolDeclaration(name, t));
|
|
222
212
|
// Structured output was dropped entirely on this path: the schema never
|
|
223
213
|
// reached the request, and nothing downstream re-imposed it, so a caller
|
|
224
214
|
// asking for an object got whatever JSON coerceJsonToSchema could scrape
|
|
@@ -25,7 +25,7 @@ import { stringifyAnthropicToolOutput } from "./toolOutput.js";
|
|
|
25
25
|
import { createAnthropicLoopAdapter } from "./loopAdapter.js";
|
|
26
26
|
import { DEFAULT_BEFORE_STEP_TIMEOUT_MS } from "../../utils/parameterValidation.js";
|
|
27
27
|
import { runAgenticLoop } from "../../core/loopEngine.js";
|
|
28
|
-
import { hasNativeDoGenerate, resolveStepToolChoice, runNativeGenerateLoop, toPrepareStepRecord, } from "../../core/nativeGenerateLoop.js";
|
|
28
|
+
import { hasNativeDoGenerate, resolveStepToolChoice, runNativeGenerateLoop, toNativeToolDeclaration, toPrepareStepRecord, } from "../../core/nativeGenerateLoop.js";
|
|
29
29
|
import { withProviderRetry } from "../../utils/providerRetry.js";
|
|
30
30
|
import { resolveRequestKind } from "../../core/resolveRequestKind.js";
|
|
31
31
|
import { resolveToolExecutionRecords, toolCallsFromSummaries, } from "../../core/toolExecutionRecorder.js";
|
|
@@ -1528,17 +1528,7 @@ export class AnthropicProvider extends BaseProvider {
|
|
|
1528
1528
|
const toolsRecord = shouldUseTools
|
|
1529
1529
|
? options.tools || {}
|
|
1530
1530
|
: {};
|
|
1531
|
-
const v3Tools = Object.entries(toolsRecord).map(([name, t]) =>
|
|
1532
|
-
const tool = t;
|
|
1533
|
-
return {
|
|
1534
|
-
type: "function",
|
|
1535
|
-
name,
|
|
1536
|
-
description: tool.description ?? "",
|
|
1537
|
-
inputSchema: (tool.inputSchema
|
|
1538
|
-
? convertZodToJsonSchema(tool.inputSchema)
|
|
1539
|
-
: { type: "object", properties: {} }),
|
|
1540
|
-
};
|
|
1541
|
-
});
|
|
1531
|
+
const v3Tools = Object.entries(toolsRecord).map(([name, t]) => toNativeToolDeclaration(name, t));
|
|
1542
1532
|
const hasTools = v3Tools.length > 0;
|
|
1543
1533
|
// Two structured-output routes, and doGenerate implements both. With no
|
|
1544
1534
|
// tools it replaces the tool list with one forced json tool; with tools it
|
|
@@ -36,7 +36,7 @@ import { NoOutputGeneratedError } from "../utils/generationErrors.js";
|
|
|
36
36
|
import { buildNoOutputSentinel, stampNoOutputSpan, } from "../utils/noOutputSentinel.js";
|
|
37
37
|
import { composeAbortSignalsScoped, createTimeoutController, mergeAbortSignals, TimeoutError, } from "../utils/timeout.js";
|
|
38
38
|
import { resolveRequestKind } from "../core/resolveRequestKind.js";
|
|
39
|
-
import { appendJsonSchemaInstruction, hasNativeDoGenerate,
|
|
39
|
+
import { appendJsonSchemaInstruction, hasNativeDoGenerate, resolveStepToolChoice, runNativeGenerateLoop, toNativeToolDeclaration, toPrepareStepRecord, } from "../core/nativeGenerateLoop.js";
|
|
40
40
|
import { resolveToolExecutionRecords, toolCallsFromSummaries, } from "../core/toolExecutionRecorder.js";
|
|
41
41
|
import { convertZodToJsonSchema } from "../utils/schemaConversion.js";
|
|
42
42
|
import { coerceJsonToSchema, recoverScalarRoot, schemaAccepts, } from "../utils/json/coerce.js";
|
|
@@ -925,19 +925,8 @@ export class OpenAIChatCompletionsProvider extends BaseProvider {
|
|
|
925
925
|
? options.tools || (await this.getAllTools())
|
|
926
926
|
: {};
|
|
927
927
|
// v3 tool shape — the same one doGenerate already converts internally.
|
|
928
|
-
// Also handed to the loop, which declares tools discovery loads mid-turn.
|
|
929
|
-
const declareTool = (name, tool) => {
|
|
930
|
-
return {
|
|
931
|
-
type: "function",
|
|
932
|
-
name,
|
|
933
|
-
description: tool.description ?? "",
|
|
934
|
-
inputSchema: tool.inputSchema
|
|
935
|
-
? convertZodToJsonSchema(resolveToolInputSchema(tool.inputSchema))
|
|
936
|
-
: { type: "object", properties: {} },
|
|
937
|
-
};
|
|
938
|
-
};
|
|
939
928
|
const v3Tools = shouldUseTools
|
|
940
|
-
? Object.entries(toolsRecord).map(([name, t]) =>
|
|
929
|
+
? Object.entries(toolsRecord).map(([name, t]) => toNativeToolDeclaration(name, t))
|
|
941
930
|
: undefined;
|
|
942
931
|
const hasTools = !!v3Tools && v3Tools.length > 0;
|
|
943
932
|
// Structured output rides response_format, which is what Output.object did
|
|
@@ -965,14 +954,9 @@ export class OpenAIChatCompletionsProvider extends BaseProvider {
|
|
|
965
954
|
// model has already given. Dropping them is what makes `response_format`
|
|
966
955
|
// legal again on a vendor that refuses the two together.
|
|
967
956
|
withTools = true) => {
|
|
968
|
-
// What this pass sends: the initial declarations
|
|
969
|
-
// for tools discovery loads mid-turn, so the guard counts them too.
|
|
957
|
+
// What this pass sends: the initial declarations, which the loop appends
|
|
958
|
+
// to for tools discovery loads mid-turn, so the guard counts them too.
|
|
970
959
|
const passTools = withTools && v3Tools ? [...v3Tools] : undefined;
|
|
971
|
-
const declarePassTool = (name, tool) => {
|
|
972
|
-
const declaration = declareTool(name, tool);
|
|
973
|
-
passTools?.push(declaration);
|
|
974
|
-
return declaration;
|
|
975
|
-
};
|
|
976
960
|
return runNativeGenerateLoop({
|
|
977
961
|
doGenerate,
|
|
978
962
|
provider: this.providerName,
|
|
@@ -997,9 +981,7 @@ export class OpenAIChatCompletionsProvider extends BaseProvider {
|
|
|
997
981
|
}), this.providerName),
|
|
998
982
|
}),
|
|
999
983
|
conversation: conv,
|
|
1000
|
-
...(passTools
|
|
1001
|
-
? { tools: [...passTools], declareTool: declarePassTool }
|
|
1002
|
-
: {}),
|
|
984
|
+
...(passTools ? { tools: passTools } : {}),
|
|
1003
985
|
toolsRecord,
|
|
1004
986
|
...(withTools && hasTools && options.toolChoice
|
|
1005
987
|
? { toolChoice: resolveToolChoice(options, toolsRecord, true) }
|
package/dist/types/generate.d.ts
CHANGED
|
@@ -1846,11 +1846,12 @@ export type NativeGenerateLoopArgs = {
|
|
|
1846
1846
|
*/
|
|
1847
1847
|
toolsRecord: Record<string, Tool>;
|
|
1848
1848
|
/**
|
|
1849
|
-
* Builds the
|
|
1850
|
-
*
|
|
1851
|
-
*
|
|
1852
|
-
*
|
|
1853
|
-
*
|
|
1849
|
+
* Builds the declaration for a tool that joined `toolsRecord` mid-turn
|
|
1850
|
+
* (discovery's search_tools loads tools into it). Optional: by default the
|
|
1851
|
+
* loop declares such a tool in the provider-neutral shape every provider's
|
|
1852
|
+
* `doGenerate` converts (`toNativeToolDeclaration`), for every provider that
|
|
1853
|
+
* runs this loop. Set it only to declare in another shape. The loop appends
|
|
1854
|
+
* the declarations to `tools` in place.
|
|
1854
1855
|
*/
|
|
1855
1856
|
declareTool?: (name: string, tool: Tool) => Record<string, unknown>;
|
|
1856
1857
|
/** The turn's resolved tool choice, applied per step via `resolveStepToolChoice`. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juspay/neurolink",
|
|
3
|
-
"version": "13.6.
|
|
3
|
+
"version": "13.6.4",
|
|
4
4
|
"packageManager": "pnpm@10.15.1",
|
|
5
5
|
"description": "The pipe layer of an AI nervous system: one interface connecting provider neurons to your application, across three inference types — generate, stream and decide. `decide` returns typed, calibrated judgements from a non-generative model (~400ms, ~$0.00002/call) for routing, tool selection and context budgeting. MCP-native (4 transports), voice TTS/STT/realtime, RAG, agents, memory, compaction, 9 observability exporters. OpenAI · Anthropic · Gemini · Bedrock · Azure · Ollama · TypeSafe Jev and more.",
|
|
6
6
|
"author": {
|