@juspay/neurolink 9.89.0 → 9.91.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.
Files changed (85) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/adapters/tts/googleTTSHandler.d.ts +10 -0
  3. package/dist/adapters/tts/googleTTSHandler.js +27 -18
  4. package/dist/agent/directTools.js +1 -1
  5. package/dist/browser/neurolink.min.js +387 -365
  6. package/dist/core/baseProvider.d.ts +37 -3
  7. package/dist/core/baseProvider.js +167 -44
  8. package/dist/core/modules/GenerationHandler.js +7 -1
  9. package/dist/core/modules/ToolsManager.js +5 -0
  10. package/dist/core/toolDedup.js +4 -1
  11. package/dist/index.d.ts +1 -1
  12. package/dist/index.js +1 -1
  13. package/dist/lib/adapters/tts/googleTTSHandler.d.ts +10 -0
  14. package/dist/lib/adapters/tts/googleTTSHandler.js +27 -18
  15. package/dist/lib/agent/directTools.js +1 -1
  16. package/dist/lib/core/baseProvider.d.ts +37 -3
  17. package/dist/lib/core/baseProvider.js +167 -44
  18. package/dist/lib/core/modules/GenerationHandler.js +7 -1
  19. package/dist/lib/core/modules/ToolsManager.js +5 -0
  20. package/dist/lib/core/toolDedup.js +4 -1
  21. package/dist/lib/index.d.ts +1 -1
  22. package/dist/lib/index.js +1 -1
  23. package/dist/lib/mcp/toolRegistry.js +7 -2
  24. package/dist/lib/neurolink.d.ts +31 -1
  25. package/dist/lib/neurolink.js +151 -26
  26. package/dist/lib/rag/index.d.ts +1 -0
  27. package/dist/lib/rag/index.js +2 -0
  28. package/dist/lib/rag/stores/chroma.d.ts +90 -0
  29. package/dist/lib/rag/stores/chroma.js +281 -0
  30. package/dist/lib/rag/stores/index.d.ts +21 -0
  31. package/dist/lib/rag/stores/index.js +22 -0
  32. package/dist/lib/rag/stores/pgvector.d.ts +95 -0
  33. package/dist/lib/rag/stores/pgvector.js +400 -0
  34. package/dist/lib/rag/stores/pinecone.d.ts +85 -0
  35. package/dist/lib/rag/stores/pinecone.js +159 -0
  36. package/dist/lib/server/routes/agentRoutes.js +25 -2
  37. package/dist/lib/tools/toolDiscovery.d.ts +48 -0
  38. package/dist/lib/tools/toolDiscovery.js +231 -0
  39. package/dist/lib/tools/toolGate.d.ts +16 -0
  40. package/dist/lib/tools/toolGate.js +51 -0
  41. package/dist/lib/tools/toolPolicy.d.ts +40 -0
  42. package/dist/lib/tools/toolPolicy.js +194 -0
  43. package/dist/lib/types/config.d.ts +43 -3
  44. package/dist/lib/types/index.d.ts +3 -0
  45. package/dist/lib/types/index.js +3 -0
  46. package/dist/lib/types/providers.d.ts +8 -0
  47. package/dist/lib/types/rag.d.ts +30 -0
  48. package/dist/lib/types/toolResolution.d.ts +73 -0
  49. package/dist/lib/types/toolResolution.js +11 -0
  50. package/dist/lib/types/vectorStoreChroma.d.ts +67 -0
  51. package/dist/lib/types/vectorStoreChroma.js +12 -0
  52. package/dist/lib/types/vectorStorePinecone.d.ts +48 -0
  53. package/dist/lib/types/vectorStorePinecone.js +12 -0
  54. package/dist/mcp/toolRegistry.js +7 -2
  55. package/dist/neurolink.d.ts +31 -1
  56. package/dist/neurolink.js +151 -26
  57. package/dist/rag/index.d.ts +1 -0
  58. package/dist/rag/index.js +2 -0
  59. package/dist/rag/stores/chroma.d.ts +90 -0
  60. package/dist/rag/stores/chroma.js +280 -0
  61. package/dist/rag/stores/index.d.ts +21 -0
  62. package/dist/rag/stores/index.js +21 -0
  63. package/dist/rag/stores/pgvector.d.ts +95 -0
  64. package/dist/rag/stores/pgvector.js +399 -0
  65. package/dist/rag/stores/pinecone.d.ts +85 -0
  66. package/dist/rag/stores/pinecone.js +158 -0
  67. package/dist/server/routes/agentRoutes.js +25 -2
  68. package/dist/tools/toolDiscovery.d.ts +48 -0
  69. package/dist/tools/toolDiscovery.js +230 -0
  70. package/dist/tools/toolGate.d.ts +16 -0
  71. package/dist/tools/toolGate.js +50 -0
  72. package/dist/tools/toolPolicy.d.ts +40 -0
  73. package/dist/tools/toolPolicy.js +193 -0
  74. package/dist/types/config.d.ts +43 -3
  75. package/dist/types/index.d.ts +3 -0
  76. package/dist/types/index.js +3 -0
  77. package/dist/types/providers.d.ts +8 -0
  78. package/dist/types/rag.d.ts +30 -0
  79. package/dist/types/toolResolution.d.ts +73 -0
  80. package/dist/types/toolResolution.js +10 -0
  81. package/dist/types/vectorStoreChroma.d.ts +67 -0
  82. package/dist/types/vectorStoreChroma.js +11 -0
  83. package/dist/types/vectorStorePinecone.d.ts +48 -0
  84. package/dist/types/vectorStorePinecone.js +11 -0
  85. package/package.json +12 -7
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Tool policy resolution — the single, pure mapping from every tool-selection
3
+ * surface (per-call legacy options + instance-level `tools` config) to one
4
+ * ResolvedToolPolicy that the gate applies.
5
+ *
6
+ * Legacy semantics are preserved deliberately:
7
+ * - `toolFilter: []` and `enabledToolNames: []` are no-ops (fail-open), as
8
+ * they always were.
9
+ * - Malformed shapes (non-string-arrays) are ignored with a once-per-process
10
+ * WARN instead of throwing — some internal callers historically passed
11
+ * wrong shapes and relied on the silent no-op.
12
+ * - `enabledToolNames` now filters the native tool set (its docs always
13
+ * promised this; it previously only filtered the system-prompt listing) —
14
+ * but ONLY when `toolFilter` is absent. When both are set, `toolFilter`
15
+ * alone bounds the native set, exactly as before this refactor: the native
16
+ * set must never become WIDER than a caller's `toolFilter`.
17
+ *
18
+ * New semantics:
19
+ * - `tools.include: []` (the instance config surface) means NO tools
20
+ * (fail-closed); legacy empty arrays stay fail-open as above.
21
+ * - A per-call `toolFilter` is bounded by `tools.include` — it can narrow
22
+ * the instance allowlist but never widen past it.
23
+ * - Pattern entries containing `*` match as globs (e.g. `"github*"`) on ALL
24
+ * surfaces. Real tool names cannot contain `*` (MCP names are sanitized),
25
+ * so a legacy list entry with `*` previously matched nothing (dead entry);
26
+ * it now matches as a glob. Entries without `*` match exactly, unchanged.
27
+ */
28
+ import { logger } from "../utils/logger.js";
29
+ const warnedOnce = new Set();
30
+ function warnOnce(key, message, detail) {
31
+ if (!warnedOnce.has(key)) {
32
+ warnedOnce.add(key);
33
+ logger.warn(message, detail);
34
+ }
35
+ }
36
+ function escapeRegExp(s) {
37
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
38
+ }
39
+ /**
40
+ * Compile a list of tool-name patterns into a matcher. Patterns without `*`
41
+ * match exactly (case-sensitive, preserving legacy toolFilter semantics);
42
+ * patterns containing `*` match as globs.
43
+ */
44
+ export function toolNameMatcher(patterns) {
45
+ const exact = new Set();
46
+ const globs = [];
47
+ for (const pattern of patterns) {
48
+ if (pattern.includes("*")) {
49
+ // Split on RUNS of asterisks: "a**b" must compile to /^a.*b$/, not
50
+ // /^a.*.*b$/ — adjacent .* pairs invite catastrophic backtracking on
51
+ // long non-matching names (ReDoS).
52
+ const source = "^" + pattern.split(/\*+/).map(escapeRegExp).join(".*") + "$";
53
+ globs.push(new RegExp(source));
54
+ }
55
+ else {
56
+ exact.add(pattern);
57
+ }
58
+ }
59
+ return (name) => exact.has(name) || globs.some((g) => g.test(name));
60
+ }
61
+ /**
62
+ * Normalize a possibly-malformed option value to a string array.
63
+ * Returns undefined (and WARNs once per source) for anything that is not a
64
+ * proper string array — preserving the historical silent-no-op behavior for
65
+ * wrong shapes while making it observable. Used for the LEGACY per-call
66
+ * surfaces only; the new config surface uses normalizeConfigList, which does
67
+ * not fail open.
68
+ */
69
+ function asStringArray(value, sourceName) {
70
+ if (value === undefined || value === null) {
71
+ return undefined;
72
+ }
73
+ if (Array.isArray(value) && value.every((v) => typeof v === "string")) {
74
+ return value;
75
+ }
76
+ warnOnce(`shape:${sourceName}`, `[ToolPolicy] Ignoring ${sourceName}: expected string[]`, { receivedType: typeof value });
77
+ return undefined;
78
+ }
79
+ /**
80
+ * Normalize a `tools.include`/`tools.exclude` config value. Unlike the
81
+ * legacy surfaces, the NEW config surface must not silently fail open — a
82
+ * caller who fat-fingers `tools.include` intending to lock an instance down
83
+ * must not get every tool exposed:
84
+ * - a bare string is coerced to a one-element list (obvious intent),
85
+ * - an array is salvaged to its string entries (dropping the rest, WARNed —
86
+ * for `include` this converges toward fewer tools, never more),
87
+ * - anything else fails CLOSED for `include` (empty list = no tools) and is
88
+ * ignored-with-WARN for `exclude` (a denylist has no safe "closed" other
89
+ * than excluding everything, which would be equally surprising).
90
+ */
91
+ function normalizeConfigList(value, sourceName, failClosed) {
92
+ if (value === undefined || value === null) {
93
+ return undefined;
94
+ }
95
+ if (typeof value === "string") {
96
+ warnOnce(`shape:${sourceName}`, `[ToolPolicy] ${sourceName} was a bare string; coercing to a one-element list`, { received: value });
97
+ return [value];
98
+ }
99
+ if (Array.isArray(value)) {
100
+ const strings = value.filter((v) => typeof v === "string");
101
+ if (strings.length !== value.length) {
102
+ warnOnce(`shape:${sourceName}`, `[ToolPolicy] Dropped ${value.length - strings.length} non-string entr(ies) from ${sourceName}`);
103
+ }
104
+ return strings;
105
+ }
106
+ warnOnce(`shape:${sourceName}`, failClosed
107
+ ? `[ToolPolicy] ${sourceName} is malformed (expected string[]); failing CLOSED — no tools will be sent until it is fixed`
108
+ : `[ToolPolicy] Ignoring malformed ${sourceName}: expected string[]`, { receivedType: typeof value });
109
+ return failClosed ? [] : undefined;
110
+ }
111
+ /**
112
+ * Resolve the effective tool policy for one request. Pure function — all
113
+ * inputs are explicit, so the legacy→policy mapping is unit-testable as a
114
+ * table.
115
+ */
116
+ export function resolveToolPolicy(input) {
117
+ const { options, instanceConfig, builtinToolNames } = input;
118
+ const sources = [];
119
+ // --- enabled -------------------------------------------------------------
120
+ let enabled = true;
121
+ if (options.disableTools === true) {
122
+ enabled = false;
123
+ sources.push("options.disableTools");
124
+ }
125
+ if (instanceConfig?.enabled === false) {
126
+ enabled = false;
127
+ sources.push("tools.enabled");
128
+ }
129
+ // --- allowlist -----------------------------------------------------------
130
+ // Legacy per-call allowlists: fail-open on empty (historical behavior).
131
+ const toolFilter = asStringArray(options.toolFilter, "options.toolFilter");
132
+ const enabledNames = asStringArray(options.enabledToolNames, "options.enabledToolNames");
133
+ let legacyInclude;
134
+ if (toolFilter && toolFilter.length > 0) {
135
+ // toolFilter alone bounds the native set — merging enabledToolNames in
136
+ // as a union would WIDEN the set beyond toolFilter, breaking the
137
+ // pre-refactor contract in the unsafe direction.
138
+ legacyInclude = [...new Set(toolFilter)];
139
+ sources.push("options.toolFilter");
140
+ if (enabledNames && enabledNames.length > 0) {
141
+ warnOnce("both-allowlists", "[ToolPolicy] Both toolFilter and enabledToolNames are set; toolFilter bounds the native tool set and enabledToolNames is ignored for it (pre-existing contract).");
142
+ }
143
+ }
144
+ else if (enabledNames && enabledNames.length > 0) {
145
+ legacyInclude = [...new Set(enabledNames)];
146
+ sources.push("options.enabledToolNames");
147
+ }
148
+ // New instance allowlist: fail-closed on empty ([] = no tools) AND on
149
+ // malformed shapes — a broken lockdown config must never expose all tools.
150
+ const configInclude = normalizeConfigList(instanceConfig?.include, "tools.include", true);
151
+ if (configInclude !== undefined) {
152
+ sources.push("tools.include");
153
+ }
154
+ let include;
155
+ let includeBound;
156
+ if (legacyInclude !== undefined && configInclude !== undefined) {
157
+ // Per-call filter is bounded by the instance allowlist: a tool must
158
+ // match BOTH lists. Kept as two matcher clauses (include AND
159
+ // includeBound) because glob pattern lists cannot be losslessly
160
+ // pre-intersected into one pattern array — filtering one list's pattern
161
+ // STRINGS through the other list's matcher would zero out overlapping
162
+ // globs like toolFilter:["github*"] vs include:["github_read*"].
163
+ include = legacyInclude;
164
+ includeBound = configInclude;
165
+ }
166
+ else {
167
+ include = legacyInclude ?? configInclude;
168
+ }
169
+ // --- denylist ------------------------------------------------------------
170
+ const exclude = [];
171
+ const optExclude = asStringArray(options.excludeTools, "options.excludeTools");
172
+ if (optExclude && optExclude.length > 0) {
173
+ exclude.push(...optExclude);
174
+ sources.push("options.excludeTools");
175
+ }
176
+ const cfgExclude = normalizeConfigList(instanceConfig?.exclude, "tools.exclude", false);
177
+ if (cfgExclude && cfgExclude.length > 0) {
178
+ exclude.push(...cfgExclude);
179
+ sources.push("tools.exclude");
180
+ }
181
+ if (instanceConfig?.disableBuiltinTools === true &&
182
+ builtinToolNames &&
183
+ builtinToolNames.length > 0) {
184
+ exclude.push(...builtinToolNames);
185
+ sources.push("tools.disableBuiltinTools");
186
+ }
187
+ // --- discovery -----------------------------------------------------------
188
+ const discovery = instanceConfig?.discovery === true;
189
+ if (discovery) {
190
+ sources.push("tools.discovery");
191
+ }
192
+ return { enabled, include, includeBound, exclude, discovery, sources };
193
+ }
@@ -42,6 +42,12 @@ export type NeurolinkConstructorConfig = {
42
42
  conversationMemory?: Partial<ConversationMemoryConfig>;
43
43
  enableOrchestration?: boolean;
44
44
  hitl?: HITLConfig;
45
+ /**
46
+ * Instance-level tool policy: master switch, include/exclude lists
47
+ * (with `*` glob support), and on-demand MCP tool discovery.
48
+ * See {@link ToolConfig}.
49
+ */
50
+ tools?: ToolConfig;
45
51
  toolRegistry?: MCPToolRegistry;
46
52
  observability?: ObservabilityConfig;
47
53
  modelAliasConfig?: ModelAliasConfig;
@@ -329,14 +335,48 @@ export type AnalyticsConfig = {
329
335
  };
330
336
  };
331
337
  /**
332
- * Tool configuration
338
+ * Instance-level tool configuration (`new NeuroLink({ tools: {...} })`).
339
+ *
340
+ * The four primary keys (`enabled`, `include`, `exclude`, `discovery`) form
341
+ * the complete modern surface; per-call options (`toolFilter`,
342
+ * `excludeTools`, `enabledToolNames`, `disableTools`) keep working and are
343
+ * merged with this config by `resolveToolPolicy()`.
333
344
  */
334
345
  export type ToolConfig = {
335
- /** Whether built-in tools should be disabled */
346
+ /**
347
+ * Master switch. `false` disables all tools for every call from this
348
+ * instance (equivalent to passing `disableTools: true` on each call).
349
+ * Default: true.
350
+ */
351
+ enabled?: boolean;
352
+ /**
353
+ * Allowlist of tool names. Supports `*` globs (e.g. `"github*"`).
354
+ * Undefined = all tools; an EMPTY array means no tools (fail-closed).
355
+ * Per-call `toolFilter` is bounded by this list (a per-call filter can
356
+ * narrow it further but never widen past it).
357
+ */
358
+ include?: string[];
359
+ /** Denylist of tool names (supports `*` globs). Applied after `include`. */
360
+ exclude?: string[];
361
+ /**
362
+ * Defer external MCP tool schemas behind a `search_tools` meta-tool: the
363
+ * model sees a compact name+summary catalog instead of full schemas and
364
+ * loads a tool on demand by searching for it. Built-in tools, per-call
365
+ * tools, per-call whitelists (`toolFilter`/`enabledToolNames`), forced
366
+ * `toolChoice` tools, and already-discovered tools are always sent in
367
+ * full. Note: the instance-level `include` list deliberately does NOT
368
+ * force tools hot — it scopes the catalog, and discovery defers within
369
+ * that scope (a scoped-but-large catalog is exactly where deferral pays).
370
+ * Default: false.
371
+ */
372
+ discovery?: boolean;
373
+ /** Whether built-in tools should be disabled (equivalent to excluding all direct tools) */
336
374
  disableBuiltinTools?: boolean;
337
375
  /** Whether custom tools are allowed */
338
376
  allowCustomTools?: boolean;
339
- /** Maximum number of tools per provider */
377
+ /**
378
+ * @deprecated Never enforced; retained for compile compatibility only.
379
+ */
340
380
  maxToolsPerProvider?: number;
341
381
  /** Whether MCP tools should be enabled */
342
382
  enableMCPTools?: boolean;
@@ -52,8 +52,11 @@ export * from "./subscription.js";
52
52
  export * from "./task.js";
53
53
  export * from "./taskClassification.js";
54
54
  export * from "./toolDedup.js";
55
+ export * from "./toolResolution.js";
55
56
  export * from "./toolRouting.js";
56
57
  export * from "./tools.js";
58
+ export * from "./vectorStoreChroma.js";
59
+ export * from "./vectorStorePinecone.js";
57
60
  export * from "./voice.js";
58
61
  export * from "./universalProviderOptions.js";
59
62
  export * from "./utilities.js";
@@ -53,8 +53,11 @@ export * from "./subscription.js";
53
53
  export * from "./task.js";
54
54
  export * from "./taskClassification.js";
55
55
  export * from "./toolDedup.js";
56
+ export * from "./toolResolution.js";
56
57
  export * from "./toolRouting.js";
57
58
  export * from "./tools.js";
59
+ export * from "./vectorStoreChroma.js";
60
+ export * from "./vectorStorePinecone.js";
58
61
  export * from "./voice.js";
59
62
  export * from "./universalProviderOptions.js";
60
63
  export * from "./utilities.js";
@@ -593,6 +593,14 @@ export type AIProvider = {
593
593
  traceId: string;
594
594
  parentSpanId: string;
595
595
  } | null): void;
596
+ /**
597
+ * Whether this provider supports native tool/function calling for the
598
+ * current model. Implemented by BaseProvider (default true); overridden by
599
+ * providers with model-dependent or absent tool support (ollama,
600
+ * huggingface, image providers). Optional for compile compatibility with
601
+ * external AIProvider implementations — callers treat absence as `true`.
602
+ */
603
+ supportsTools?(): boolean;
596
604
  };
597
605
  /**
598
606
  * Provider attempt result for iteration tracking (converted from interface)
@@ -419,6 +419,36 @@ export type VectorStore = {
419
419
  includeVectors?: boolean;
420
420
  }): Promise<VectorQueryResult[]>;
421
421
  };
422
+ /** Minimal shape of a query result, satisfied by both `pg` and `pglite`. */
423
+ export type PgQueryResult<T = unknown> = {
424
+ rows: T[];
425
+ };
426
+ /**
427
+ * Minimal structural interface a caller-supplied Postgres client must
428
+ * satisfy. Both `pg.Pool` (`node-postgres`) and `@electric-sql/pglite`
429
+ * instances already expose a compatible `query(text, values?)` method —
430
+ * neither is a dependency of this package. Callers construct and own the
431
+ * client; `PgVectorStore` only ever calls `query()` on it.
432
+ */
433
+ export type PgClientLike = {
434
+ query(text: string, values?: unknown[]): Promise<PgQueryResult>;
435
+ };
436
+ /** Construction options for `PgVectorStore`. */
437
+ export type PgVectorStoreOptions = {
438
+ /**
439
+ * Prefix prepended to `indexName` to derive the backing table name.
440
+ * Must itself be a valid, unquoted Postgres identifier.
441
+ * @default "neurolink_vs_"
442
+ */
443
+ tablePrefix?: string;
444
+ };
445
+ /** Row shape returned by `PgVectorStore`'s SELECT queries. */
446
+ export type PgVectorStoreRow = {
447
+ id: string;
448
+ metadata: unknown;
449
+ score: unknown;
450
+ embedding?: unknown;
451
+ };
422
452
  /**
423
453
  * Document loader options
424
454
  */
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Tool resolution types — the single tool-policy pipeline that decides which
3
+ * tools are sent to a provider for a given request.
4
+ *
5
+ * One policy object is resolved per request from (a) per-call legacy options
6
+ * (`toolFilter`, `excludeTools`, `enabledToolNames`, `disableTools`) and
7
+ * (b) the instance-level `tools` config, then applied at the single gate in
8
+ * `BaseProvider` that every generate/stream path passes through.
9
+ */
10
+ import type { ToolConfig } from "./config.js";
11
+ /**
12
+ * The resolved, merged tool policy for one request. Produced by
13
+ * `resolveToolPolicy()` (src/lib/tools/toolPolicy.ts) and consumed by
14
+ * `applyToolGate()` (src/lib/tools/toolGate.ts).
15
+ */
16
+ export type ResolvedToolPolicy = {
17
+ /** false = no tools at all for this request (drops caller-supplied tools too). */
18
+ enabled: boolean;
19
+ /**
20
+ * Allowlist of tool-name patterns (exact names or `*` globs).
21
+ * `undefined` = all tools pass. An empty array means "no tools" — it can
22
+ * only come from the new `tools.include` config surface; legacy
23
+ * `toolFilter: []` is normalized to `undefined` (fail-open, preserving
24
+ * historical behavior) before it reaches here.
25
+ */
26
+ include?: string[];
27
+ /**
28
+ * Secondary allowlist clause ANDed with `include` — set when both a
29
+ * legacy per-call allowlist and the instance `tools.include` are present.
30
+ * Kept as a separate clause because two glob pattern lists cannot be
31
+ * losslessly pre-intersected into a single pattern array (a name must
32
+ * match BOTH lists to pass).
33
+ */
34
+ includeBound?: string[];
35
+ /** Denylist of tool-name patterns (exact names or `*` globs), applied after include. */
36
+ exclude: string[];
37
+ /** Defer external MCP tool schemas behind the search_tools meta-tool. */
38
+ discovery: boolean;
39
+ /** Which option/config sources contributed to this policy (telemetry/debugging). */
40
+ sources: string[];
41
+ };
42
+ /**
43
+ * Inputs to `resolveToolPolicy()`. Kept as a named type so the mapping is
44
+ * unit-testable as a pure function.
45
+ */
46
+ export type ToolPolicyResolutionInput = {
47
+ /** Per-call options (the legacy per-call filtering surface). */
48
+ options: {
49
+ disableTools?: boolean;
50
+ toolFilter?: string[];
51
+ enabledToolNames?: string[];
52
+ excludeTools?: string[];
53
+ };
54
+ /** Instance-level `tools` config passed to the NeuroLink constructor. */
55
+ instanceConfig?: ToolConfig;
56
+ /**
57
+ * Names of the built-in (direct) tools of the calling provider — used to
58
+ * honor `tools.disableBuiltinTools` without this module importing the
59
+ * direct-tools registry.
60
+ */
61
+ builtinToolNames?: string[];
62
+ };
63
+ /**
64
+ * One entry in the deferred-tool catalog embedded in the `search_tools`
65
+ * meta-tool description when `tools.discovery` is enabled.
66
+ */
67
+ export type DeferredToolIndexEntry = {
68
+ name: string;
69
+ /** One-line description (truncated) shown in the search_tools catalog. */
70
+ summary: string;
71
+ /** Originating MCP server id, when known. */
72
+ serverId?: string;
73
+ };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Tool resolution types — the single tool-policy pipeline that decides which
3
+ * tools are sent to a provider for a given request.
4
+ *
5
+ * One policy object is resolved per request from (a) per-call legacy options
6
+ * (`toolFilter`, `excludeTools`, `enabledToolNames`, `disableTools`) and
7
+ * (b) the instance-level `tools` config, then applied at the single gate in
8
+ * `BaseProvider` that every generate/stream path passes through.
9
+ */
10
+ export {};
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Structural types for the Chroma vector store adapter
3
+ * (`src/lib/rag/stores/chroma.ts`).
4
+ *
5
+ * These mirror the subset of the `chromadb` package's API the adapter
6
+ * calls (`ChromaClient.getOrCreateCollection`, `Collection.upsert/query/
7
+ * delete`). NeuroLink has zero runtime dependency on `chromadb` — callers
8
+ * construct their own client and inject an object satisfying
9
+ * `ChromaClientLike`.
10
+ */
11
+ export type ChromaMetadataValue = string | number | boolean;
12
+ export type ChromaMetadata = Record<string, ChromaMetadataValue>;
13
+ /** Chroma's metadata `where` filter payload shape. */
14
+ export type ChromaWhere = Record<string, unknown>;
15
+ export type ChromaIncludeField = "embeddings" | "metadatas" | "documents" | "distances";
16
+ export type ChromaUpsertParams = {
17
+ ids: string[];
18
+ embeddings?: number[][];
19
+ metadatas?: Array<ChromaMetadata | null>;
20
+ documents?: Array<string | null>;
21
+ };
22
+ export type ChromaQueryParams = {
23
+ queryEmbeddings: number[][];
24
+ nResults?: number;
25
+ where?: ChromaWhere;
26
+ include?: ChromaIncludeField[];
27
+ };
28
+ export type ChromaQueryResponse = {
29
+ ids: string[][];
30
+ embeddings?: Array<Array<number[] | null>> | null;
31
+ metadatas?: Array<Array<ChromaMetadata | null>> | null;
32
+ documents?: Array<Array<string | null>> | null;
33
+ distances?: Array<Array<number | null>> | null;
34
+ };
35
+ export type ChromaDeleteParams = {
36
+ ids?: string[];
37
+ where?: ChromaWhere;
38
+ };
39
+ /**
40
+ * Minimal structural interface for a Chroma collection handle, matching the
41
+ * subset of `Collection` (from `chromadb`) the adapter calls.
42
+ */
43
+ export type ChromaCollectionLike = {
44
+ upsert(params: ChromaUpsertParams): Promise<unknown>;
45
+ query(params: ChromaQueryParams): Promise<ChromaQueryResponse>;
46
+ delete(params: ChromaDeleteParams): Promise<unknown>;
47
+ };
48
+ /**
49
+ * Minimal structural interface for a Chroma client, matching the subset of
50
+ * `ChromaClient` (from `chromadb`) the adapter calls.
51
+ */
52
+ export type ChromaClientLike = {
53
+ getOrCreateCollection(params: {
54
+ name: string;
55
+ metadata?: Record<string, unknown>;
56
+ }): Promise<ChromaCollectionLike>;
57
+ };
58
+ export type ChromaDistanceMetric = "cosine" | "l2" | "ip";
59
+ export type ChromaVectorStoreOptions = {
60
+ /**
61
+ * The distance metric configured on the underlying Chroma collection(s)
62
+ * (Chroma's `hnsw:space`). Used only to convert returned distances into a
63
+ * `score`; see `src/lib/rag/stores/chroma.ts` module doc comment.
64
+ * Defaults to `"cosine"`.
65
+ */
66
+ distanceMetric?: ChromaDistanceMetric;
67
+ };
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Structural types for the Chroma vector store adapter
3
+ * (`src/lib/rag/stores/chroma.ts`).
4
+ *
5
+ * These mirror the subset of the `chromadb` package's API the adapter
6
+ * calls (`ChromaClient.getOrCreateCollection`, `Collection.upsert/query/
7
+ * delete`). NeuroLink has zero runtime dependency on `chromadb` — callers
8
+ * construct their own client and inject an object satisfying
9
+ * `ChromaClientLike`.
10
+ */
11
+ export {};
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Structural types for the Pinecone vector store adapter
3
+ * (`src/lib/rag/stores/pinecone.ts`).
4
+ *
5
+ * These mirror the subset of the `@pinecone-database/pinecone` package's API
6
+ * the adapter calls (`Index.query/upsert/deleteMany`, optional
7
+ * `Index.namespace`). NeuroLink has zero runtime dependency on the Pinecone
8
+ * SDK — callers construct their own client/index and inject an object
9
+ * satisfying `PineconeIndexLike`.
10
+ */
11
+ /** A single scored match as returned by Pinecone's query API. */
12
+ export type PineconeMatch = {
13
+ id: string;
14
+ score?: number;
15
+ values?: number[];
16
+ metadata?: Record<string, unknown>;
17
+ };
18
+ /** Shape of the response returned by `PineconeIndexLike.query()`. */
19
+ export type PineconeQueryResponse = {
20
+ matches?: PineconeMatch[];
21
+ };
22
+ /** Request payload accepted by `PineconeIndexLike.query()`. */
23
+ export type PineconeQueryRequest = {
24
+ vector: number[];
25
+ topK: number;
26
+ filter?: Record<string, unknown>;
27
+ includeMetadata?: boolean;
28
+ includeValues?: boolean;
29
+ };
30
+ /** A single record accepted by `PineconeIndexLike.upsert()`. */
31
+ export type PineconeUpsertRecord = {
32
+ id: string;
33
+ values: number[];
34
+ metadata?: Record<string, unknown>;
35
+ };
36
+ /**
37
+ * Minimal structural interface modeled on the `@pinecone-database/pinecone`
38
+ * `Index` object. Satisfied by the real SDK's `Index` without modification;
39
+ * callers never need to install the Pinecone SDK as a dependency of this
40
+ * package — they bring their own already-constructed client instance.
41
+ */
42
+ export type PineconeIndexLike = {
43
+ /** Returns a client scoped to the given namespace, if the client supports namespacing. */
44
+ namespace?(ns: string): PineconeIndexLike;
45
+ query(request: PineconeQueryRequest): Promise<PineconeQueryResponse>;
46
+ upsert(records: PineconeUpsertRecord[]): Promise<unknown>;
47
+ deleteMany(ids: string[]): Promise<unknown>;
48
+ };
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Structural types for the Pinecone vector store adapter
3
+ * (`src/lib/rag/stores/pinecone.ts`).
4
+ *
5
+ * These mirror the subset of the `@pinecone-database/pinecone` package's API
6
+ * the adapter calls (`Index.query/upsert/deleteMany`, optional
7
+ * `Index.namespace`). NeuroLink has zero runtime dependency on the Pinecone
8
+ * SDK — callers construct their own client/index and inject an object
9
+ * satisfying `PineconeIndexLike`.
10
+ */
11
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/neurolink",
3
- "version": "9.89.0",
3
+ "version": "9.91.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": {
@@ -74,6 +74,7 @@
74
74
  "test:cache": "npx tsx test/continuous-test-suite-cache-breakpoints.ts",
75
75
  "test:evaluation": "npx tsx test/continuous-test-suite-evaluation.ts",
76
76
  "test:mcp": "npx tsx test/continuous-test-suite-mcp-infra.ts",
77
+ "test:tool-resolution": "npx tsx test/continuous-test-suite-tool-resolution.ts",
77
78
  "test:mcp:http": "npx tsx test/continuous-test-suite-mcp-http.ts",
78
79
  "test:mcp:sdk": "npx tsx test/continuous-test-suite-mcp-sdk.ts",
79
80
  "test:mcp:cli": "npx tsx test/continuous-test-suite-mcp-cli.ts",
@@ -93,6 +94,9 @@
93
94
  "test:mcp:infra": "npx tsx test/continuous-test-suite-mcp-infra.ts",
94
95
  "test:providers-mocked": "npx tsx test/continuous-test-suite-providers-mocked.ts",
95
96
  "test:rag": "npx tsx test/continuous-test-suite-rag.ts",
97
+ "test:vector-pinecone": "npx tsx test/continuous-test-suite-vector-pinecone.ts",
98
+ "test:vector-pgvector": "npx tsx test/continuous-test-suite-vector-pgvector.ts",
99
+ "test:vector-chroma": "npx tsx test/continuous-test-suite-vector-chroma.ts",
96
100
  "test:skills": "npx tsx test/continuous-test-suite-skills.ts",
97
101
  "test:servers": "npx tsx test/continuous-test-suite-servers.ts",
98
102
  "test:tool-reliability": "npx tsx test/continuous-test-suite-tool-reliability.ts",
@@ -332,15 +336,9 @@
332
336
  "@ai-sdk/provider": "^3.0.8",
333
337
  "@anthropic-ai/sdk": "^0.102.0",
334
338
  "@anthropic-ai/vertex-sdk": "^0.16.0",
335
- "@aws-sdk/client-bedrock": "^3.1000.0",
336
- "@aws-sdk/client-bedrock-runtime": "^3.1000.0",
337
339
  "@aws-sdk/client-sagemaker-runtime": "^3.1000.0",
338
- "@aws-sdk/credential-provider-node": "^3.886.0",
339
340
  "@aws-sdk/types": "^3.862.0",
340
- "@google-cloud/text-to-speech": "^6.4.0",
341
- "@google-cloud/vertexai": "^1.10.0",
342
341
  "@google/genai": "^1.43.0",
343
- "@huggingface/inference": "^4.13.14",
344
342
  "@modelcontextprotocol/sdk": "^1.27.1",
345
343
  "@opentelemetry/api-logs": "^0.214.0",
346
344
  "@opentelemetry/context-async-hooks": "^2.6.1",
@@ -399,10 +397,16 @@
399
397
  }
400
398
  },
401
399
  "optionalDependencies": {
400
+ "@aws-sdk/client-bedrock": "^3.1000.0",
401
+ "@aws-sdk/client-bedrock-runtime": "^3.1000.0",
402
402
  "@aws-sdk/client-sagemaker": "^3.1000.0",
403
+ "@aws-sdk/credential-provider-node": "^3.886.0",
403
404
  "@fastify/cors": "^11.2.0",
404
405
  "@fastify/rate-limit": "^10.3.0",
406
+ "@google-cloud/text-to-speech": "^6.4.0",
407
+ "@google-cloud/vertexai": "^1.10.0",
405
408
  "@hono/node-server": "^1.19.13",
409
+ "@huggingface/inference": "^4.13.14",
406
410
  "@koa/cors": "^5.0.0",
407
411
  "@koa/router": "^15.3.1",
408
412
  "@langfuse/otel": "^5.0.1",
@@ -442,6 +446,7 @@
442
446
  "@biomejs/biome": "^2.4.4",
443
447
  "@changesets/changelog-github": "^0.6.0",
444
448
  "@changesets/cli": "^2.29.8",
449
+ "@electric-sql/pglite": "^0.4.6",
445
450
  "@eslint/js": "^10.0.1",
446
451
  "@juspay/hippocampus": ">=0.1.7",
447
452
  "@opentelemetry/api": "^1.9.0",