@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.
- package/CHANGELOG.md +16 -0
- package/dist/adapters/tts/googleTTSHandler.d.ts +10 -0
- package/dist/adapters/tts/googleTTSHandler.js +27 -18
- package/dist/agent/directTools.js +1 -1
- package/dist/browser/neurolink.min.js +387 -365
- package/dist/core/baseProvider.d.ts +37 -3
- package/dist/core/baseProvider.js +167 -44
- package/dist/core/modules/GenerationHandler.js +7 -1
- package/dist/core/modules/ToolsManager.js +5 -0
- package/dist/core/toolDedup.js +4 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/lib/adapters/tts/googleTTSHandler.d.ts +10 -0
- package/dist/lib/adapters/tts/googleTTSHandler.js +27 -18
- package/dist/lib/agent/directTools.js +1 -1
- package/dist/lib/core/baseProvider.d.ts +37 -3
- package/dist/lib/core/baseProvider.js +167 -44
- package/dist/lib/core/modules/GenerationHandler.js +7 -1
- package/dist/lib/core/modules/ToolsManager.js +5 -0
- package/dist/lib/core/toolDedup.js +4 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.js +1 -1
- package/dist/lib/mcp/toolRegistry.js +7 -2
- package/dist/lib/neurolink.d.ts +31 -1
- package/dist/lib/neurolink.js +151 -26
- package/dist/lib/rag/index.d.ts +1 -0
- package/dist/lib/rag/index.js +2 -0
- package/dist/lib/rag/stores/chroma.d.ts +90 -0
- package/dist/lib/rag/stores/chroma.js +281 -0
- package/dist/lib/rag/stores/index.d.ts +21 -0
- package/dist/lib/rag/stores/index.js +22 -0
- package/dist/lib/rag/stores/pgvector.d.ts +95 -0
- package/dist/lib/rag/stores/pgvector.js +400 -0
- package/dist/lib/rag/stores/pinecone.d.ts +85 -0
- package/dist/lib/rag/stores/pinecone.js +159 -0
- package/dist/lib/server/routes/agentRoutes.js +25 -2
- package/dist/lib/tools/toolDiscovery.d.ts +48 -0
- package/dist/lib/tools/toolDiscovery.js +231 -0
- package/dist/lib/tools/toolGate.d.ts +16 -0
- package/dist/lib/tools/toolGate.js +51 -0
- package/dist/lib/tools/toolPolicy.d.ts +40 -0
- package/dist/lib/tools/toolPolicy.js +194 -0
- package/dist/lib/types/config.d.ts +43 -3
- package/dist/lib/types/index.d.ts +3 -0
- package/dist/lib/types/index.js +3 -0
- package/dist/lib/types/providers.d.ts +8 -0
- package/dist/lib/types/rag.d.ts +30 -0
- package/dist/lib/types/toolResolution.d.ts +73 -0
- package/dist/lib/types/toolResolution.js +11 -0
- package/dist/lib/types/vectorStoreChroma.d.ts +67 -0
- package/dist/lib/types/vectorStoreChroma.js +12 -0
- package/dist/lib/types/vectorStorePinecone.d.ts +48 -0
- package/dist/lib/types/vectorStorePinecone.js +12 -0
- package/dist/mcp/toolRegistry.js +7 -2
- package/dist/neurolink.d.ts +31 -1
- package/dist/neurolink.js +151 -26
- package/dist/rag/index.d.ts +1 -0
- package/dist/rag/index.js +2 -0
- package/dist/rag/stores/chroma.d.ts +90 -0
- package/dist/rag/stores/chroma.js +280 -0
- package/dist/rag/stores/index.d.ts +21 -0
- package/dist/rag/stores/index.js +21 -0
- package/dist/rag/stores/pgvector.d.ts +95 -0
- package/dist/rag/stores/pgvector.js +399 -0
- package/dist/rag/stores/pinecone.d.ts +85 -0
- package/dist/rag/stores/pinecone.js +158 -0
- package/dist/server/routes/agentRoutes.js +25 -2
- package/dist/tools/toolDiscovery.d.ts +48 -0
- package/dist/tools/toolDiscovery.js +230 -0
- package/dist/tools/toolGate.d.ts +16 -0
- package/dist/tools/toolGate.js +50 -0
- package/dist/tools/toolPolicy.d.ts +40 -0
- package/dist/tools/toolPolicy.js +193 -0
- package/dist/types/config.d.ts +43 -3
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.js +3 -0
- package/dist/types/providers.d.ts +8 -0
- package/dist/types/rag.d.ts +30 -0
- package/dist/types/toolResolution.d.ts +73 -0
- package/dist/types/toolResolution.js +10 -0
- package/dist/types/vectorStoreChroma.d.ts +67 -0
- package/dist/types/vectorStoreChroma.js +11 -0
- package/dist/types/vectorStorePinecone.d.ts +48 -0
- package/dist/types/vectorStorePinecone.js +11 -0
- package/package.json +12 -7
|
@@ -0,0 +1,194 @@
|
|
|
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
|
+
}
|
|
194
|
+
//# sourceMappingURL=toolPolicy.js.map
|
|
@@ -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
|
-
*
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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";
|
package/dist/lib/types/index.js
CHANGED
|
@@ -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)
|
package/dist/lib/types/rag.d.ts
CHANGED
|
@@ -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,11 @@
|
|
|
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 {};
|
|
11
|
+
//# sourceMappingURL=toolResolution.js.map
|
|
@@ -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,12 @@
|
|
|
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 {};
|
|
12
|
+
//# sourceMappingURL=vectorStoreChroma.js.map
|
|
@@ -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,12 @@
|
|
|
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 {};
|
|
12
|
+
//# sourceMappingURL=vectorStorePinecone.js.map
|
package/dist/mcp/toolRegistry.js
CHANGED
|
@@ -7,6 +7,7 @@ import { registryLogger } from "../utils/logger.js";
|
|
|
7
7
|
import { randomUUID } from "crypto";
|
|
8
8
|
import { shouldDisableBuiltinTools } from "../utils/toolUtils.js";
|
|
9
9
|
import { directAgentTools } from "../agent/directTools.js";
|
|
10
|
+
import { convertZodToJsonSchema } from "../utils/schemaConversion.js";
|
|
10
11
|
import { detectCategory, createMCPServerInfo } from "../utils/mcpDefaults.js";
|
|
11
12
|
import { FlexibleToolValidator } from "./flexibleToolValidator.js";
|
|
12
13
|
import { ErrorFactory } from "../utils/errorHandling.js";
|
|
@@ -57,10 +58,14 @@ export class MCPToolRegistry extends MCPRegistry {
|
|
|
57
58
|
continue;
|
|
58
59
|
}
|
|
59
60
|
const toolId = `direct.${toolName}`;
|
|
61
|
+
// Register the tool's real parameter schema (converted from Zod) instead
|
|
62
|
+
// of a `{}` placeholder — token-budget accounting and tool listings read
|
|
63
|
+
// this ToolInfo, and an empty schema makes both under-count reality.
|
|
64
|
+
const inputSchema = convertZodToJsonSchema(toolDef.inputSchema);
|
|
60
65
|
const toolInfo = {
|
|
61
66
|
name: toolName,
|
|
62
67
|
description: toolDef.description || `Direct tool: ${toolName}`,
|
|
63
|
-
inputSchema
|
|
68
|
+
inputSchema,
|
|
64
69
|
serverId: "direct",
|
|
65
70
|
category: detectCategory({ isBuiltIn: true, serverId: "direct" }),
|
|
66
71
|
};
|
|
@@ -98,7 +103,7 @@ export class MCPToolRegistry extends MCPRegistry {
|
|
|
98
103
|
}
|
|
99
104
|
},
|
|
100
105
|
description: toolDef.description,
|
|
101
|
-
inputSchema
|
|
106
|
+
inputSchema,
|
|
102
107
|
});
|
|
103
108
|
registryLogger.debug(`Registered direct tool: ${toolName} as ${toolId}`);
|
|
104
109
|
}
|
package/dist/neurolink.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* Uses real MCP infrastructure for tool discovery and execution.
|
|
7
7
|
*/
|
|
8
8
|
import type { AgentDefinition, AgentNetworkConfig, NetworkExecutionInput, NetworkExecutionOptions, NetworkExecutionResult, NetworkStreamChunk } from "./types/index.js";
|
|
9
|
-
import type { CompactionConfig, CompactionResult, SpanData, ObservabilityConfig, MetricsSummary, MCPToolAnnotations, TraceView, AuthenticatedContext, AuthProvider, JsonObject, NeuroLinkEvents, TypedEventEmitter, MCPEnhancementsConfig, NeuroLinkAuthConfig, NeurolinkConstructorConfig, ChatMessage, ExternalMCPOperationResult, ExternalMCPServerInstance, ExternalMCPToolInfo, GenerateOptions, GenerateResult, ProviderStatus, TextGenerationOptions, TextGenerationResult, MCPExecutableTool, MCPServerInfo, MCPStatus, StreamOptions, StreamResult, ToolExecutionContext, ToolExecutionSummary, ToolInfo, ToolRegistrationOptions, BatchOperationResult, StreamGenerationEndContext, ToolRoutingServerDescriptor, ToolDedupConfig } from "./types/index.js";
|
|
9
|
+
import type { CompactionConfig, CompactionResult, SpanData, ObservabilityConfig, MetricsSummary, MCPToolAnnotations, TraceView, AuthenticatedContext, AuthProvider, JsonObject, NeuroLinkEvents, TypedEventEmitter, MCPEnhancementsConfig, NeuroLinkAuthConfig, NeurolinkConstructorConfig, ChatMessage, ExternalMCPOperationResult, ExternalMCPServerInstance, ExternalMCPToolInfo, GenerateOptions, GenerateResult, ProviderStatus, TextGenerationOptions, TextGenerationResult, MCPExecutableTool, MCPServerInfo, MCPStatus, StreamOptions, StreamResult, ToolExecutionContext, ToolExecutionSummary, ToolInfo, ToolRegistrationOptions, BatchOperationResult, StreamGenerationEndContext, ToolRoutingServerDescriptor, ToolDedupConfig, ToolConfig } from "./types/index.js";
|
|
10
10
|
import { ConversationMemoryManager } from "./core/conversationMemoryManager.js";
|
|
11
11
|
import type { RedisConversationMemoryManager } from "./core/redisConversationMemoryManager.js";
|
|
12
12
|
import { ExternalServerManager } from "./mcp/externalServerManager.js";
|
|
@@ -107,6 +107,9 @@ export declare class NeuroLink {
|
|
|
107
107
|
private toolRoutingCacheInstance?;
|
|
108
108
|
private toolRoutingVectorCache?;
|
|
109
109
|
private toolDedupConfig?;
|
|
110
|
+
private toolsConfig?;
|
|
111
|
+
/** Session-scoped pins of tools discovered via search_tools (tools.discovery mode). */
|
|
112
|
+
private discoveryPins;
|
|
110
113
|
private enableOrchestration;
|
|
111
114
|
private authProvider?;
|
|
112
115
|
private pendingAuthConfig?;
|
|
@@ -812,6 +815,11 @@ export declare class NeuroLink {
|
|
|
812
815
|
/**
|
|
813
816
|
* Apply per-call tool filtering (whitelist/blacklist) to a ToolInfo array.
|
|
814
817
|
* Used to filter the tool list before building the system prompt.
|
|
818
|
+
*
|
|
819
|
+
* Resolves the SAME policy as the native gate (`BaseProvider`
|
|
820
|
+
* `applyToolFiltering`) — per-call options plus the instance-level `tools`
|
|
821
|
+
* config — so what the model is told about tools never diverges from the
|
|
822
|
+
* tools it can actually call.
|
|
815
823
|
*/
|
|
816
824
|
private applyToolInfoFiltering;
|
|
817
825
|
private createToolAwareSystemPrompt;
|
|
@@ -1194,6 +1202,28 @@ export declare class NeuroLink {
|
|
|
1194
1202
|
* parameter through the full call stack.
|
|
1195
1203
|
*/
|
|
1196
1204
|
getToolDedupConfig(): ToolDedupConfig | undefined;
|
|
1205
|
+
/**
|
|
1206
|
+
* Returns the instance-level `tools` config (master switch, include/exclude
|
|
1207
|
+
* lists, discovery mode), or `undefined` when not provided at construction.
|
|
1208
|
+
*
|
|
1209
|
+
* Called by `BaseProvider.applyToolFiltering` so the tool gate composes the
|
|
1210
|
+
* instance policy with per-call options on every generate/stream call.
|
|
1211
|
+
*/
|
|
1212
|
+
getToolsConfig(): ToolConfig | undefined;
|
|
1213
|
+
/**
|
|
1214
|
+
* Tools discovered via `search_tools` for a session (`tools.discovery`
|
|
1215
|
+
* mode). Pinned tools are sent in full on every subsequent call of that
|
|
1216
|
+
* session instead of being deferred — discovery cost is paid once.
|
|
1217
|
+
* Reading refreshes the session's recency (LRU), so active conversations
|
|
1218
|
+
* are never the ones evicted at the session cap.
|
|
1219
|
+
*/
|
|
1220
|
+
getDiscoveryPins(sessionKey: string): ReadonlySet<string>;
|
|
1221
|
+
/**
|
|
1222
|
+
* Pin discovered tools to a session (called by the `search_tools`
|
|
1223
|
+
* meta-tool on hydration). Append-only within a session; the map is
|
|
1224
|
+
* bounded by evicting the least-recently-used session past 1000 sessions.
|
|
1225
|
+
*/
|
|
1226
|
+
pinDiscoveredTools(sessionKey: string, toolNames: string[]): void;
|
|
1197
1227
|
/**
|
|
1198
1228
|
* Curator P1-1: synchronous credential health check for a single provider.
|
|
1199
1229
|
*
|