@nodetool-ai/node-sdk 0.7.0-rc.11
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/dist/base-node.d.ts +141 -0
- package/dist/base-node.d.ts.map +1 -0
- package/dist/base-node.js +225 -0
- package/dist/base-node.js.map +1 -0
- package/dist/decorators.d.ts +19 -0
- package/dist/decorators.d.ts.map +1 -0
- package/dist/decorators.js +42 -0
- package/dist/decorators.js.map +1 -0
- package/dist/docs/index.d.ts +4 -0
- package/dist/docs/index.d.ts.map +1 -0
- package/dist/docs/index.js +4 -0
- package/dist/docs/index.js.map +1 -0
- package/dist/docs/nodes.d.ts +10 -0
- package/dist/docs/nodes.d.ts.map +1 -0
- package/dist/docs/nodes.js +99 -0
- package/dist/docs/nodes.js.map +1 -0
- package/dist/docs/overview.d.ts +6 -0
- package/dist/docs/overview.d.ts.map +1 -0
- package/dist/docs/overview.js +71 -0
- package/dist/docs/overview.js.map +1 -0
- package/dist/docs/workflows.d.ts +10 -0
- package/dist/docs/workflows.d.ts.map +1 -0
- package/dist/docs/workflows.js +112 -0
- package/dist/docs/workflows.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/metadata.d.ts +76 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/metadata.js +247 -0
- package/dist/metadata.js.map +1 -0
- package/dist/node-metadata.d.ts +16 -0
- package/dist/node-metadata.d.ts.map +1 -0
- package/dist/node-metadata.js +266 -0
- package/dist/node-metadata.js.map +1 -0
- package/dist/nodes/test-nodes.d.ts +215 -0
- package/dist/nodes/test-nodes.d.ts.map +1 -0
- package/dist/nodes/test-nodes.js +436 -0
- package/dist/nodes/test-nodes.js.map +1 -0
- package/dist/package-registry-client.d.ts +12 -0
- package/dist/package-registry-client.d.ts.map +1 -0
- package/dist/package-registry-client.js +40 -0
- package/dist/package-registry-client.js.map +1 -0
- package/dist/python-package-scan.d.ts +45 -0
- package/dist/python-package-scan.d.ts.map +1 -0
- package/dist/python-package-scan.js +158 -0
- package/dist/python-package-scan.js.map +1 -0
- package/dist/registry.d.ts +55 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +188 -0
- package/dist/registry.js.map +1 -0
- package/dist/search.d.ts +58 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +127 -0
- package/dist/search.js.map +1 -0
- package/dist/validation.d.ts +63 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +138 -0
- package/dist/validation.js.map +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scan a nodetool Python node package by invoking `nodetool.package_tools`
|
|
3
|
+
* (shipped inside `nodetool-core`) as a one-shot subprocess.
|
|
4
|
+
*
|
|
5
|
+
* Produces a `PackageMetadata` (same shape as what `loadPythonPackageMetadata`
|
|
6
|
+
* reads back from disk). Does not require a running server.
|
|
7
|
+
*/
|
|
8
|
+
import { spawn } from "node:child_process";
|
|
9
|
+
import { homedir } from "node:os";
|
|
10
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
11
|
+
import { basename, join } from "node:path";
|
|
12
|
+
export class PythonScanError extends Error {
|
|
13
|
+
exitCode;
|
|
14
|
+
stderr;
|
|
15
|
+
constructor(message, exitCode, stderr) {
|
|
16
|
+
super(message);
|
|
17
|
+
this.exitCode = exitCode;
|
|
18
|
+
this.stderr = stderr;
|
|
19
|
+
this.name = "PythonScanError";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Run `python -m nodetool.package_tools scan` and return the parsed result.
|
|
24
|
+
*
|
|
25
|
+
* Requires `nodetool-core` to be installed in the target Python environment.
|
|
26
|
+
*/
|
|
27
|
+
export async function scanPythonPackage(opts) {
|
|
28
|
+
const python = opts.python ?? resolvePythonBin();
|
|
29
|
+
const args = [
|
|
30
|
+
"-m",
|
|
31
|
+
"nodetool.package_tools",
|
|
32
|
+
"scan",
|
|
33
|
+
"--package-dir",
|
|
34
|
+
opts.packageDir
|
|
35
|
+
];
|
|
36
|
+
if (opts.enrich)
|
|
37
|
+
args.push("--enrich");
|
|
38
|
+
if (opts.write)
|
|
39
|
+
args.push("--write");
|
|
40
|
+
if (opts.verbose)
|
|
41
|
+
args.push("--verbose");
|
|
42
|
+
return await new Promise((resolve, reject) => {
|
|
43
|
+
const child = spawn(python, args, {
|
|
44
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
45
|
+
signal: opts.signal
|
|
46
|
+
});
|
|
47
|
+
const stdoutChunks = [];
|
|
48
|
+
const stderrChunks = [];
|
|
49
|
+
let stderrBuffer = "";
|
|
50
|
+
child.stdout.on("data", (chunk) => {
|
|
51
|
+
stdoutChunks.push(chunk);
|
|
52
|
+
});
|
|
53
|
+
child.stderr.on("data", (chunk) => {
|
|
54
|
+
stderrChunks.push(chunk);
|
|
55
|
+
if (opts.onProgress) {
|
|
56
|
+
stderrBuffer += chunk.toString("utf8");
|
|
57
|
+
let idx;
|
|
58
|
+
while ((idx = stderrBuffer.indexOf("\n")) !== -1) {
|
|
59
|
+
const line = stderrBuffer.slice(0, idx).trimEnd();
|
|
60
|
+
stderrBuffer = stderrBuffer.slice(idx + 1);
|
|
61
|
+
if (line.startsWith("SCAN"))
|
|
62
|
+
opts.onProgress(line);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
child.once("error", (err) => {
|
|
67
|
+
reject(new PythonScanError(`Failed to spawn python: ${err.message}`, null, Buffer.concat(stderrChunks).toString("utf8")));
|
|
68
|
+
});
|
|
69
|
+
child.once("close", (code) => {
|
|
70
|
+
const stderr = Buffer.concat(stderrChunks).toString("utf8");
|
|
71
|
+
if (code !== 0) {
|
|
72
|
+
reject(new PythonScanError(`nodetool-pkg scan exited with code ${code}`, code, stderr));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
let metadata;
|
|
77
|
+
if (opts.write) {
|
|
78
|
+
// --write: no JSON on stdout; read the file the scanner wrote.
|
|
79
|
+
const name = findWrittenMetadataName(stderr);
|
|
80
|
+
if (!name) {
|
|
81
|
+
throw new Error("scanner did not report a SCAN write path line");
|
|
82
|
+
}
|
|
83
|
+
const metadataPath = join(opts.packageDir, "src", "nodetool", "package_metadata", `${name}.json`);
|
|
84
|
+
metadata = JSON.parse(readFileSync(metadataPath, "utf8"));
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
const stdout = Buffer.concat(stdoutChunks).toString("utf8");
|
|
88
|
+
metadata = JSON.parse(stdout);
|
|
89
|
+
}
|
|
90
|
+
resolve({ metadata, stderr });
|
|
91
|
+
}
|
|
92
|
+
catch (e) {
|
|
93
|
+
reject(new PythonScanError(`Failed to parse scanner output: ${String(e)}`, code, stderr));
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Parse "SCAN write path=/.../<name>.json" and return "<name>".
|
|
100
|
+
*/
|
|
101
|
+
function findWrittenMetadataName(stderr) {
|
|
102
|
+
const match = stderr.match(/SCAN write path=(.+\/([^/\\]+)\.json)\s*$/m);
|
|
103
|
+
return match?.[2] ?? null;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Resolve a Python executable, matching the convention used by
|
|
107
|
+
* `PythonStdioBridge` in `@nodetool-ai/runtime`.
|
|
108
|
+
*/
|
|
109
|
+
export function resolvePythonBin() {
|
|
110
|
+
const explicit = process.env["NODETOOL_PYTHON"];
|
|
111
|
+
if (explicit)
|
|
112
|
+
return explicit;
|
|
113
|
+
const condaPrefix = process.env["CONDA_PREFIX"];
|
|
114
|
+
if (condaPrefix && looksLikeNodetoolEnv(condaPrefix)) {
|
|
115
|
+
const bin = process.platform === "win32"
|
|
116
|
+
? join(condaPrefix, "python.exe")
|
|
117
|
+
: join(condaPrefix, "bin", "python");
|
|
118
|
+
if (existsSync(bin))
|
|
119
|
+
return bin;
|
|
120
|
+
}
|
|
121
|
+
for (const candidate of managedCandidates()) {
|
|
122
|
+
if (existsSync(candidate))
|
|
123
|
+
return candidate;
|
|
124
|
+
}
|
|
125
|
+
return "python";
|
|
126
|
+
}
|
|
127
|
+
function looksLikeNodetoolEnv(envPath) {
|
|
128
|
+
const normalized = envPath.replaceAll("\\", "/").toLowerCase();
|
|
129
|
+
const name = basename(envPath).toLowerCase();
|
|
130
|
+
return (name === "nodetool" ||
|
|
131
|
+
name === "conda_env" ||
|
|
132
|
+
normalized.includes("/nodetool/conda_env"));
|
|
133
|
+
}
|
|
134
|
+
function managedCandidates() {
|
|
135
|
+
const home = homedir();
|
|
136
|
+
if (process.platform === "darwin") {
|
|
137
|
+
return [
|
|
138
|
+
join(home, "nodetool_env", "bin", "python"),
|
|
139
|
+
join(home, "miniconda3", "envs", "nodetool", "bin", "python"),
|
|
140
|
+
join(home, "anaconda3", "envs", "nodetool", "bin", "python"),
|
|
141
|
+
join(home, "conda", "envs", "nodetool", "bin", "python")
|
|
142
|
+
];
|
|
143
|
+
}
|
|
144
|
+
if (process.platform === "linux") {
|
|
145
|
+
return [
|
|
146
|
+
join(home, ".local", "share", "nodetool", "conda_env", "bin", "python"),
|
|
147
|
+
"/opt/nodetool/conda_env/bin/python",
|
|
148
|
+
join(home, "miniconda3", "envs", "nodetool", "bin", "python"),
|
|
149
|
+
join(home, "anaconda3", "envs", "nodetool", "bin", "python")
|
|
150
|
+
];
|
|
151
|
+
}
|
|
152
|
+
return [
|
|
153
|
+
join(home, "Miniconda3", "envs", "nodetool", "python.exe"),
|
|
154
|
+
join(home, "miniconda3", "envs", "nodetool", "python.exe"),
|
|
155
|
+
join(home, "Anaconda3", "envs", "nodetool", "python.exe")
|
|
156
|
+
];
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=python-package-scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"python-package-scan.js","sourceRoot":"","sources":["../src/python-package-scan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { NodeDescriptor } from "@nodetool-ai/protocol";
|
|
2
|
+
import type { NodeExecutor, ResolvedNodeType } from "@nodetool-ai/kernel";
|
|
3
|
+
import type { NodeClass } from "./base-node.js";
|
|
4
|
+
import type { NodeMetadata, PythonMetadataLoadOptions, PythonMetadataLoadResult } from "./metadata.js";
|
|
5
|
+
import type { NodePropertyValidationIssue } from "./validation.js";
|
|
6
|
+
export interface NodeRegistryOptions {
|
|
7
|
+
metadataByType?: Map<string, NodeMetadata>;
|
|
8
|
+
strictMetadata?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface RegisterNodeOptions {
|
|
11
|
+
metadata?: NodeMetadata;
|
|
12
|
+
}
|
|
13
|
+
export interface RegistryGraphResolverOptions {
|
|
14
|
+
loadNamespace?: (namespace: string, registry: NodeRegistry) => Promise<void> | void;
|
|
15
|
+
}
|
|
16
|
+
export declare class NodeRegistry {
|
|
17
|
+
private _classes;
|
|
18
|
+
private _loadedMetadataByType;
|
|
19
|
+
private _registeredMetadataByType;
|
|
20
|
+
private _strictMetadata;
|
|
21
|
+
constructor(options?: NodeRegistryOptions);
|
|
22
|
+
register(nodeClass: NodeClass, options?: RegisterNodeOptions): void;
|
|
23
|
+
/**
|
|
24
|
+
* Validate a node descriptor against its registered class's @prop schema.
|
|
25
|
+
*
|
|
26
|
+
* Returns an empty array when:
|
|
27
|
+
* - the class is not registered (the runner will surface that elsewhere), or
|
|
28
|
+
* - all required/model fields are populated.
|
|
29
|
+
*/
|
|
30
|
+
validateNode(descriptor: NodeDescriptor, connectedHandles?: ReadonlySet<string> | ReadonlyArray<string>): NodePropertyValidationIssue[];
|
|
31
|
+
/**
|
|
32
|
+
* Create a validator function compatible with WorkflowRunnerOptions.validateNode.
|
|
33
|
+
* Bound to this registry, so the runner can call it without holding a
|
|
34
|
+
* reference to the registry itself.
|
|
35
|
+
*/
|
|
36
|
+
createNodeValidator(): (descriptor: NodeDescriptor, connectedHandles: ReadonlySet<string>) => NodePropertyValidationIssue[];
|
|
37
|
+
resolve(descriptor: NodeDescriptor): NodeExecutor;
|
|
38
|
+
getClass(nodeType: string): NodeClass | undefined;
|
|
39
|
+
has(nodeType: string): boolean;
|
|
40
|
+
list(): string[];
|
|
41
|
+
getMetadata(nodeType: string): NodeMetadata | undefined;
|
|
42
|
+
resolveMetadata(nodeType: string): NodeMetadata | undefined;
|
|
43
|
+
listMetadata(): NodeMetadata[];
|
|
44
|
+
listRegisteredNodeTypesWithoutMetadata(): string[];
|
|
45
|
+
/** Add or replace metadata for a node type (e.g. from Python bridge). */
|
|
46
|
+
loadMetadata(nodeType: string, metadata: NodeMetadata): void;
|
|
47
|
+
loadPythonMetadata(options?: PythonMetadataLoadOptions): PythonMetadataLoadResult;
|
|
48
|
+
clear(): void;
|
|
49
|
+
static readonly global: NodeRegistry;
|
|
50
|
+
}
|
|
51
|
+
export declare function register(nodeClass: NodeClass): void;
|
|
52
|
+
export declare function createGraphNodeTypeResolver(registry: NodeRegistry, options?: RegistryGraphResolverOptions): {
|
|
53
|
+
resolveNodeType: (nodeType: string) => Promise<ResolvedNodeType | null>;
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EACV,YAAY,EACZ,yBAAyB,EACzB,wBAAwB,EACzB,MAAM,eAAe,CAAC;AAGvB,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAEnE,MAAM,WAAW,mBAAmB;IAClC,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAC3C,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB;AAED,MAAM,WAAW,4BAA4B;IAC3C,aAAa,CAAC,EAAE,CACd,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,YAAY,KACnB,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC3B;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAgC;IAChD,OAAO,CAAC,qBAAqB,CAAmC;IAChE,OAAO,CAAC,yBAAyB,CAAmC;IACpE,OAAO,CAAC,eAAe,CAAU;gBAErB,OAAO,GAAE,mBAAwB;IAS7C,QAAQ,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,GAAE,mBAAwB,GAAG,IAAI;IAqBvE;;;;;;OAMG;IACH,YAAY,CACV,UAAU,EAAE,cAAc,EAC1B,gBAAgB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,GAC7D,2BAA2B,EAAE;IAWhC;;;;OAIG;IACH,mBAAmB,IAAI,CACrB,UAAU,EAAE,cAAc,EAC1B,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAAC,KAClC,2BAA2B,EAAE;IAKlC,OAAO,CAAC,UAAU,EAAE,cAAc,GAAG,YAAY;IAgBjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAIjD,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAI9B,IAAI,IAAI,MAAM,EAAE;IAIhB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAOvD,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAS3D,YAAY,IAAI,YAAY,EAAE;IAc9B,sCAAsC,IAAI,MAAM,EAAE;IAMlD,yEAAyE;IACzE,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI;IAI5D,kBAAkB,CAChB,OAAO,GAAE,yBAA8B,GACtC,wBAAwB;IAQ3B,KAAK,IAAI,IAAI;IAMb,MAAM,CAAC,QAAQ,CAAC,MAAM,eAAsB;CAC7C;AAED,wBAAgB,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAEnD;AAoBD,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,YAAY,EACtB,OAAO,GAAE,4BAAiC,GACzC;IAAE,eAAe,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;CAAE,CA2D7E"}
|
package/dist/registry.js
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { loadPythonPackageMetadata } from "./metadata.js";
|
|
2
|
+
import { getNodeMetadata } from "./node-metadata.js";
|
|
3
|
+
export class NodeRegistry {
|
|
4
|
+
_classes = new Map();
|
|
5
|
+
_loadedMetadataByType = new Map();
|
|
6
|
+
_registeredMetadataByType = new Map();
|
|
7
|
+
_strictMetadata;
|
|
8
|
+
constructor(options = {}) {
|
|
9
|
+
this._strictMetadata = options.strictMetadata ?? false;
|
|
10
|
+
if (options.metadataByType) {
|
|
11
|
+
for (const [nodeType, metadata] of options.metadataByType.entries()) {
|
|
12
|
+
this._loadedMetadataByType.set(nodeType, metadata);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
register(nodeClass, options = {}) {
|
|
17
|
+
if (!nodeClass.nodeType) {
|
|
18
|
+
throw new Error(`Cannot register node class without nodeType: ${nodeClass.name}`);
|
|
19
|
+
}
|
|
20
|
+
// TS class definitions are the source of truth for TS nodes.
|
|
21
|
+
// Python metadata is NOT merged — it is only used for Python-only
|
|
22
|
+
// node packs (huggingface, mlx, etc.) that have no TS class.
|
|
23
|
+
const metadata = options.metadata ?? getNodeMetadata(nodeClass);
|
|
24
|
+
if (metadata) {
|
|
25
|
+
this._registeredMetadataByType.set(nodeClass.nodeType, metadata);
|
|
26
|
+
}
|
|
27
|
+
else if (this._strictMetadata) {
|
|
28
|
+
throw new Error(`Missing resolved metadata for node type: ${nodeClass.nodeType}`);
|
|
29
|
+
}
|
|
30
|
+
this._classes.set(nodeClass.nodeType, nodeClass);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Validate a node descriptor against its registered class's @prop schema.
|
|
34
|
+
*
|
|
35
|
+
* Returns an empty array when:
|
|
36
|
+
* - the class is not registered (the runner will surface that elsewhere), or
|
|
37
|
+
* - all required/model fields are populated.
|
|
38
|
+
*/
|
|
39
|
+
validateNode(descriptor, connectedHandles) {
|
|
40
|
+
const NodeClass = this._classes.get(descriptor.type);
|
|
41
|
+
if (!NodeClass)
|
|
42
|
+
return [];
|
|
43
|
+
const properties = descriptor.properties ?? {};
|
|
44
|
+
return NodeClass.validateProperties(properties, {
|
|
45
|
+
connectedHandles,
|
|
46
|
+
nodeId: descriptor.id
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Create a validator function compatible with WorkflowRunnerOptions.validateNode.
|
|
51
|
+
* Bound to this registry, so the runner can call it without holding a
|
|
52
|
+
* reference to the registry itself.
|
|
53
|
+
*/
|
|
54
|
+
createNodeValidator() {
|
|
55
|
+
return (descriptor, connectedHandles) => this.validateNode(descriptor, connectedHandles);
|
|
56
|
+
}
|
|
57
|
+
resolve(descriptor) {
|
|
58
|
+
const NodeClass = this._classes.get(descriptor.type);
|
|
59
|
+
if (!NodeClass) {
|
|
60
|
+
throw new Error(`Unknown node type: ${descriptor.type}`);
|
|
61
|
+
}
|
|
62
|
+
const instance = new NodeClass(descriptor.properties ?? {});
|
|
63
|
+
instance.__node_id = descriptor.id;
|
|
64
|
+
instance.__node_name = descriptor.name ?? descriptor.type;
|
|
65
|
+
if (descriptor.dynamic_outputs) {
|
|
66
|
+
instance._dynamic_outputs = descriptor.dynamic_outputs;
|
|
67
|
+
}
|
|
68
|
+
return instance.toExecutor();
|
|
69
|
+
}
|
|
70
|
+
getClass(nodeType) {
|
|
71
|
+
return this._classes.get(nodeType);
|
|
72
|
+
}
|
|
73
|
+
has(nodeType) {
|
|
74
|
+
return this._classes.has(nodeType);
|
|
75
|
+
}
|
|
76
|
+
list() {
|
|
77
|
+
return [...this._classes.keys()];
|
|
78
|
+
}
|
|
79
|
+
getMetadata(nodeType) {
|
|
80
|
+
return (this._registeredMetadataByType.get(nodeType) ??
|
|
81
|
+
this._loadedMetadataByType.get(nodeType));
|
|
82
|
+
}
|
|
83
|
+
resolveMetadata(nodeType) {
|
|
84
|
+
const exact = this.getMetadata(nodeType);
|
|
85
|
+
if (exact)
|
|
86
|
+
return exact;
|
|
87
|
+
if (nodeType.endsWith("Node")) {
|
|
88
|
+
return this.getMetadata(nodeType.slice(0, -4));
|
|
89
|
+
}
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
listMetadata() {
|
|
93
|
+
const merged = new Map();
|
|
94
|
+
for (const [nodeType, metadata] of this._loadedMetadataByType.entries()) {
|
|
95
|
+
merged.set(nodeType, metadata);
|
|
96
|
+
}
|
|
97
|
+
for (const [nodeType, metadata] of this._registeredMetadataByType.entries()) {
|
|
98
|
+
merged.set(nodeType, metadata);
|
|
99
|
+
}
|
|
100
|
+
return [...merged.values()];
|
|
101
|
+
}
|
|
102
|
+
listRegisteredNodeTypesWithoutMetadata() {
|
|
103
|
+
return this.list().filter((nodeType) => this.getMetadata(nodeType) === undefined);
|
|
104
|
+
}
|
|
105
|
+
/** Add or replace metadata for a node type (e.g. from Python bridge). */
|
|
106
|
+
loadMetadata(nodeType, metadata) {
|
|
107
|
+
this._loadedMetadataByType.set(nodeType, metadata);
|
|
108
|
+
}
|
|
109
|
+
loadPythonMetadata(options = {}) {
|
|
110
|
+
const loaded = loadPythonPackageMetadata(options);
|
|
111
|
+
for (const [nodeType, metadata] of loaded.nodesByType.entries()) {
|
|
112
|
+
this._loadedMetadataByType.set(nodeType, metadata);
|
|
113
|
+
}
|
|
114
|
+
return loaded;
|
|
115
|
+
}
|
|
116
|
+
clear() {
|
|
117
|
+
this._classes.clear();
|
|
118
|
+
this._loadedMetadataByType.clear();
|
|
119
|
+
this._registeredMetadataByType.clear();
|
|
120
|
+
}
|
|
121
|
+
static global = new NodeRegistry();
|
|
122
|
+
}
|
|
123
|
+
export function register(nodeClass) {
|
|
124
|
+
NodeRegistry.global.register(nodeClass);
|
|
125
|
+
}
|
|
126
|
+
function typeMetadataToString(typeMeta) {
|
|
127
|
+
const args = (typeMeta.type_args ?? [])
|
|
128
|
+
.map(typeMetadataToString)
|
|
129
|
+
.filter(Boolean);
|
|
130
|
+
return args.length > 0
|
|
131
|
+
? `${typeMeta.type}[${args.join(", ")}]`
|
|
132
|
+
: typeMeta.type;
|
|
133
|
+
}
|
|
134
|
+
function deriveNamespace(nodeType) {
|
|
135
|
+
const lastDot = nodeType.lastIndexOf(".");
|
|
136
|
+
return lastDot > 0 ? nodeType.slice(0, lastDot) : "";
|
|
137
|
+
}
|
|
138
|
+
export function createGraphNodeTypeResolver(registry, options = {}) {
|
|
139
|
+
return {
|
|
140
|
+
resolveNodeType: async (nodeType) => {
|
|
141
|
+
let metadata = registry.resolveMetadata(nodeType);
|
|
142
|
+
if (!metadata) {
|
|
143
|
+
const namespace = deriveNamespace(nodeType);
|
|
144
|
+
if (namespace && options.loadNamespace) {
|
|
145
|
+
await options.loadNamespace(namespace, registry);
|
|
146
|
+
metadata = registry.resolveMetadata(nodeType);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (!metadata)
|
|
150
|
+
return null;
|
|
151
|
+
const propertyTypes = Object.fromEntries((metadata.properties ?? []).map((prop) => [
|
|
152
|
+
prop.name,
|
|
153
|
+
typeMetadataToString(prop.type)
|
|
154
|
+
]));
|
|
155
|
+
const propertyMeta = Object.fromEntries((metadata.properties ?? [])
|
|
156
|
+
.filter((p) => p.description || p.min != null || p.max != null)
|
|
157
|
+
.map((p) => [
|
|
158
|
+
p.name,
|
|
159
|
+
{
|
|
160
|
+
...(p.description ? { description: p.description } : {}),
|
|
161
|
+
...(p.min != null ? { min: p.min } : {}),
|
|
162
|
+
...(p.max != null ? { max: p.max } : {})
|
|
163
|
+
}
|
|
164
|
+
]));
|
|
165
|
+
const outputs = Object.fromEntries((metadata.outputs ?? []).map((output) => [
|
|
166
|
+
output.name,
|
|
167
|
+
typeMetadataToString(output.type)
|
|
168
|
+
]));
|
|
169
|
+
const NodeClass = registry.getClass(nodeType);
|
|
170
|
+
const syncMode = NodeClass?.syncMode;
|
|
171
|
+
return {
|
|
172
|
+
nodeType: metadata.node_type,
|
|
173
|
+
propertyTypes,
|
|
174
|
+
outputs,
|
|
175
|
+
isDynamic: metadata.is_dynamic ?? false,
|
|
176
|
+
descriptorDefaults: {
|
|
177
|
+
name: metadata.title,
|
|
178
|
+
...(metadata.is_streaming_input && { is_streaming_input: true }),
|
|
179
|
+
...(metadata.is_streaming_output && { is_streaming_output: true }),
|
|
180
|
+
...(metadata.is_controlled && { is_controlled: true }),
|
|
181
|
+
...(syncMode !== undefined && { sync_mode: syncMode }),
|
|
182
|
+
...(Object.keys(propertyMeta).length > 0 && { propertyMeta })
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAmBrD,MAAM,OAAO,YAAY;IACf,QAAQ,GAAG,IAAI,GAAG,EAAqB,CAAC;IACxC,qBAAqB,GAAG,IAAI,GAAG,EAAwB,CAAC;IACxD,yBAAyB,GAAG,IAAI,GAAG,EAAwB,CAAC;IAC5D,eAAe,CAAU;IAEjC,YAAY,UAA+B,EAAE;QAC3C,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,cAAc,IAAI,KAAK,CAAC;QACvD,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;YAC3B,KAAK,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,OAAO,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,CAAC;gBACpE,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YACrD,CAAC;QACH,CAAC;IACH,CAAC;IAED,QAAQ,CAAC,SAAoB,EAAE,UAA+B,EAAE;QAC9D,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CACb,gDAAgD,SAAS,CAAC,IAAI,EAAE,CACjE,CAAC;QACJ,CAAC;QACD,6DAA6D;QAC7D,kEAAkE;QAClE,6DAA6D;QAC7D,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,eAAe,CAAC,SAAS,CAAC,CAAC;QAEhE,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACnE,CAAC;aAAM,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CACb,4CAA4C,SAAS,CAAC,QAAQ,EAAE,CACjE,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACnD,CAAC;IAED;;;;;;OAMG;IACH,YAAY,CACV,UAA0B,EAC1B,gBAA8D;QAE9D,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACrD,IAAI,CAAC,SAAS;YAAE,OAAO,EAAE,CAAC;QAC1B,MAAM,UAAU,GACb,UAAU,CAAC,UAAkD,IAAI,EAAE,CAAC;QACvE,OAAO,SAAS,CAAC,kBAAkB,CAAC,UAAU,EAAE;YAC9C,gBAAgB;YAChB,MAAM,EAAE,UAAU,CAAC,EAAE;SACtB,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACH,mBAAmB;QAIjB,OAAO,CAAC,UAAU,EAAE,gBAAgB,EAAE,EAAE,CACtC,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;IACpD,CAAC;IAED,OAAO,CAAC,UAA0B;QAChC,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACrD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,sBAAsB,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3D,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,SAAS,CAC3B,UAAU,CAAC,UAAkD,IAAI,EAAE,CACrE,CAAC;QACF,QAAQ,CAAC,SAAS,GAAG,UAAU,CAAC,EAAE,CAAC;QACnC,QAAQ,CAAC,WAAW,GAAG,UAAU,CAAC,IAAI,IAAI,UAAU,CAAC,IAAI,CAAC;QAC1D,IAAI,UAAU,CAAC,eAAe,EAAE,CAAC;YAC9B,QAAgB,CAAC,gBAAgB,GAAG,UAAU,CAAC,eAAe,CAAC;QAClE,CAAC;QACD,OAAO,QAAQ,CAAC,UAAU,EAAE,CAAC;IAC/B,CAAC;IAED,QAAQ,CAAC,QAAgB;QACvB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC;IAED,GAAG,CAAC,QAAgB;QAClB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC;IAED,IAAI;QACF,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IACnC,CAAC;IAED,WAAW,CAAC,QAAgB;QAC1B,OAAO,CACL,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,QAAQ,CAAC;YAC5C,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,QAAQ,CAAC,CACzC,CAAC;IACJ,CAAC;IAED,eAAe,CAAC,QAAgB;QAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QACzC,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;QACxB,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,YAAY;QACV,MAAM,MAAM,GAAG,IAAI,GAAG,EAAwB,CAAC;QAC/C,KAAK,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC,qBAAqB,CAAC,OAAO,EAAE,EAAE,CAAC;YACxE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACjC,CAAC;QACD,KAAK,MAAM,CACT,QAAQ,EACR,QAAQ,CACT,IAAI,IAAI,CAAC,yBAAyB,CAAC,OAAO,EAAE,EAAE,CAAC;YAC9C,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACjC,CAAC;QACD,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9B,CAAC;IAED,sCAAsC;QACpC,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,CACvB,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,SAAS,CACvD,CAAC;IACJ,CAAC;IAED,yEAAyE;IACzE,YAAY,CAAC,QAAgB,EAAE,QAAsB;QACnD,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACrD,CAAC;IAED,kBAAkB,CAChB,UAAqC,EAAE;QAEvC,MAAM,MAAM,GAAG,yBAAyB,CAAC,OAAO,CAAC,CAAC;QAClD,KAAK,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;YAChE,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK;QACH,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,CAAC;QACnC,IAAI,CAAC,yBAAyB,CAAC,KAAK,EAAE,CAAC;IACzC,CAAC;IAED,MAAM,CAAU,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;;AAG9C,MAAM,UAAU,QAAQ,CAAC,SAAoB;IAC3C,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;AAC1C,CAAC;AAED,SAAS,oBAAoB,CAC3B,QAE2C;IAE3C,MAAM,IAAI,GAAG,CAAC,QAAQ,CAAC,SAAS,IAAI,EAAE,CAAC;SACpC,GAAG,CAAC,oBAAoB,CAAC;SACzB,MAAM,CAAC,OAAO,CAAC,CAAC;IACnB,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC;QACpB,CAAC,CAAC,GAAG,QAAQ,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;QACxC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;AACpB,CAAC;AAED,SAAS,eAAe,CAAC,QAAgB;IACvC,MAAM,OAAO,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC1C,OAAO,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,2BAA2B,CACzC,QAAsB,EACtB,UAAwC,EAAE;IAE1C,OAAO;QACL,eAAe,EAAE,KAAK,EACpB,QAAgB,EACkB,EAAE;YACpC,IAAI,QAAQ,GAAG,QAAQ,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;YAElD,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,SAAS,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;gBAC5C,IAAI,SAAS,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;oBACvC,MAAM,OAAO,CAAC,aAAa,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;oBACjD,QAAQ,GAAG,QAAQ,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;gBAChD,CAAC;YACH,CAAC;YAED,IAAI,CAAC,QAAQ;gBAAE,OAAO,IAAI,CAAC;YAE3B,MAAM,aAAa,GAAG,MAAM,CAAC,WAAW,CACtC,CAAC,QAAQ,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;gBACxC,IAAI,CAAC,IAAI;gBACT,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC;aAChC,CAAC,CACH,CAAC;YACF,MAAM,YAAY,GAAG,MAAM,CAAC,WAAW,CACrC,CAAC,QAAQ,CAAC,UAAU,IAAI,EAAE,CAAC;iBACxB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,GAAG,IAAI,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC;iBAC9D,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;gBACV,CAAC,CAAC,IAAI;gBACN;oBACE,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACxD,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACxC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACzC;aACF,CAAC,CACL,CAAC;YACF,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,CAChC,CAAC,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;gBACvC,MAAM,CAAC,IAAI;gBACX,oBAAoB,CAAC,MAAM,CAAC,IAAI,CAAC;aAClC,CAAC,CACH,CAAC;YACF,MAAM,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAC9C,MAAM,QAAQ,GAAG,SAAS,EAAE,QAAQ,CAAC;YACrC,OAAO;gBACL,QAAQ,EAAE,QAAQ,CAAC,SAAS;gBAC5B,aAAa;gBACb,OAAO;gBACP,SAAS,EAAE,QAAQ,CAAC,UAAU,IAAI,KAAK;gBACvC,kBAAkB,EAAE;oBAClB,IAAI,EAAE,QAAQ,CAAC,KAAK;oBACpB,GAAG,CAAC,QAAQ,CAAC,kBAAkB,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC;oBAChE,GAAG,CAAC,QAAQ,CAAC,mBAAmB,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC;oBAClE,GAAG,CAAC,QAAQ,CAAC,aAAa,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;oBACtD,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;oBACtD,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC;iBAC9D;aACF,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/search.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Namespace-aware scorer for node metadata search.
|
|
3
|
+
*
|
|
4
|
+
* Used by the agent's local search tool to bias results toward
|
|
5
|
+
* provider-agnostic core nodes (`nodetool.*`) and away from provider-specific
|
|
6
|
+
* nodes (`openai.*`, `anthropic.*`, `gemini.*`, etc.).
|
|
7
|
+
*
|
|
8
|
+
* Pure functions only — no provider or runtime imports — so this module can
|
|
9
|
+
* live in node-sdk and be consumed by any package that has node metadata.
|
|
10
|
+
*/
|
|
11
|
+
import type { NodeMetadata } from "./metadata.js";
|
|
12
|
+
/**
|
|
13
|
+
* Root namespace prefixes that identify provider-specific node packages.
|
|
14
|
+
* Nodes whose namespace starts with one of these (e.g. `openai.tts`,
|
|
15
|
+
* `anthropic.agents`, `replicate.image`) are treated as provider nodes.
|
|
16
|
+
*
|
|
17
|
+
* The agent's search tool hides these by default; users browsing the node
|
|
18
|
+
* picker UI still see them via the unbiased HTTP endpoint.
|
|
19
|
+
*/
|
|
20
|
+
export declare const PROVIDER_NAMESPACES: readonly string[];
|
|
21
|
+
export type NamespaceClass = "core" | "provider" | "other";
|
|
22
|
+
/**
|
|
23
|
+
* Classify a node namespace into one of three buckets used for ranking.
|
|
24
|
+
* - `core`: starts with `nodetool.` (the curated, provider-agnostic surface)
|
|
25
|
+
* - `provider`: root segment is in `PROVIDER_NAMESPACES`
|
|
26
|
+
* - `other`: utility libs like `lib.*`, third-party `mcp.*`, etc.
|
|
27
|
+
*/
|
|
28
|
+
export declare function namespaceClass(namespace: string | undefined): NamespaceClass;
|
|
29
|
+
export interface ScoreOptions {
|
|
30
|
+
/** Include provider-specific nodes in results (default: false). */
|
|
31
|
+
includeProviderNodes?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Restrict to nodes whose namespace starts with this prefix.
|
|
34
|
+
* Applied as a hard filter before scoring.
|
|
35
|
+
*/
|
|
36
|
+
namespacePrefix?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Score a node against a list of search terms.
|
|
40
|
+
* Returns 0 if the node should be hidden (no match, or provider node when
|
|
41
|
+
* `includeProviderNodes` is false). Higher is more relevant.
|
|
42
|
+
*
|
|
43
|
+
* Terms are matched case-insensitively. Each matching field contributes
|
|
44
|
+
* `FIELD_WEIGHTS[field]` plus an exact-token bonus when the term appears as a
|
|
45
|
+
* whole token. Core (`nodetool.*`) namespaces get a 1.5× multiplier.
|
|
46
|
+
*/
|
|
47
|
+
export declare function scoreNodeMetadata(meta: NodeMetadata, terms: readonly string[], options?: ScoreOptions): number;
|
|
48
|
+
export interface ScoredNode<T extends NodeMetadata = NodeMetadata> {
|
|
49
|
+
meta: T;
|
|
50
|
+
score: number;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Score and rank a list of node metadata against search terms.
|
|
54
|
+
* Returns nodes with score > 0, sorted by score descending; ties broken
|
|
55
|
+
* alphabetically on `node_type` for deterministic output.
|
|
56
|
+
*/
|
|
57
|
+
export declare function rankNodeMetadata<T extends NodeMetadata>(nodes: readonly T[], terms: readonly string[], options?: ScoreOptions): ScoredNode<T>[];
|
|
58
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAgBhD,CAAC;AAIF,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC;AAE3D;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,cAAc,CAQ5E;AAED,MAAM,WAAW,YAAY;IAC3B,mEAAmE;IACnE,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AA2BD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,OAAO,GAAE,YAAiB,GACzB,MAAM,CAyBR;AAED,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,YAAY,GAAG,YAAY;IAC/D,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,YAAY,EACrD,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,OAAO,GAAE,YAAiB,GACzB,UAAU,CAAC,CAAC,CAAC,EAAE,CAWjB"}
|
package/dist/search.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Namespace-aware scorer for node metadata search.
|
|
3
|
+
*
|
|
4
|
+
* Used by the agent's local search tool to bias results toward
|
|
5
|
+
* provider-agnostic core nodes (`nodetool.*`) and away from provider-specific
|
|
6
|
+
* nodes (`openai.*`, `anthropic.*`, `gemini.*`, etc.).
|
|
7
|
+
*
|
|
8
|
+
* Pure functions only — no provider or runtime imports — so this module can
|
|
9
|
+
* live in node-sdk and be consumed by any package that has node metadata.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Root namespace prefixes that identify provider-specific node packages.
|
|
13
|
+
* Nodes whose namespace starts with one of these (e.g. `openai.tts`,
|
|
14
|
+
* `anthropic.agents`, `replicate.image`) are treated as provider nodes.
|
|
15
|
+
*
|
|
16
|
+
* The agent's search tool hides these by default; users browsing the node
|
|
17
|
+
* picker UI still see them via the unbiased HTTP endpoint.
|
|
18
|
+
*/
|
|
19
|
+
export const PROVIDER_NAMESPACES = [
|
|
20
|
+
"openai",
|
|
21
|
+
"anthropic",
|
|
22
|
+
"gemini",
|
|
23
|
+
"mistral",
|
|
24
|
+
"groq",
|
|
25
|
+
"cohere",
|
|
26
|
+
"voyage",
|
|
27
|
+
"huggingface",
|
|
28
|
+
"fal",
|
|
29
|
+
"replicate",
|
|
30
|
+
"kie",
|
|
31
|
+
"comfyui",
|
|
32
|
+
"apify",
|
|
33
|
+
"messaging",
|
|
34
|
+
"search"
|
|
35
|
+
];
|
|
36
|
+
const PROVIDER_NAMESPACE_SET = new Set(PROVIDER_NAMESPACES);
|
|
37
|
+
/**
|
|
38
|
+
* Classify a node namespace into one of three buckets used for ranking.
|
|
39
|
+
* - `core`: starts with `nodetool.` (the curated, provider-agnostic surface)
|
|
40
|
+
* - `provider`: root segment is in `PROVIDER_NAMESPACES`
|
|
41
|
+
* - `other`: utility libs like `lib.*`, third-party `mcp.*`, etc.
|
|
42
|
+
*/
|
|
43
|
+
export function namespaceClass(namespace) {
|
|
44
|
+
if (!namespace)
|
|
45
|
+
return "other";
|
|
46
|
+
if (namespace.startsWith("nodetool.") || namespace === "nodetool") {
|
|
47
|
+
return "core";
|
|
48
|
+
}
|
|
49
|
+
const root = namespace.split(".")[0] ?? "";
|
|
50
|
+
if (PROVIDER_NAMESPACE_SET.has(root))
|
|
51
|
+
return "provider";
|
|
52
|
+
return "other";
|
|
53
|
+
}
|
|
54
|
+
const FIELD_WEIGHTS = {
|
|
55
|
+
title: 6,
|
|
56
|
+
nodeType: 4,
|
|
57
|
+
namespace: 2,
|
|
58
|
+
description: 1
|
|
59
|
+
};
|
|
60
|
+
const EXACT_TOKEN_BONUS = 2;
|
|
61
|
+
const CORE_MULTIPLIER = 1.5;
|
|
62
|
+
function fieldScore(field, term, weight) {
|
|
63
|
+
if (!field)
|
|
64
|
+
return 0;
|
|
65
|
+
const lower = field.toLowerCase();
|
|
66
|
+
if (!lower.includes(term))
|
|
67
|
+
return 0;
|
|
68
|
+
let score = weight;
|
|
69
|
+
// Exact-token bonus: term appears as a whole word/segment.
|
|
70
|
+
const tokens = lower.split(/[\s._\-/]+/).filter(Boolean);
|
|
71
|
+
if (tokens.includes(term))
|
|
72
|
+
score += weight * EXACT_TOKEN_BONUS;
|
|
73
|
+
return score;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Score a node against a list of search terms.
|
|
77
|
+
* Returns 0 if the node should be hidden (no match, or provider node when
|
|
78
|
+
* `includeProviderNodes` is false). Higher is more relevant.
|
|
79
|
+
*
|
|
80
|
+
* Terms are matched case-insensitively. Each matching field contributes
|
|
81
|
+
* `FIELD_WEIGHTS[field]` plus an exact-token bonus when the term appears as a
|
|
82
|
+
* whole token. Core (`nodetool.*`) namespaces get a 1.5× multiplier.
|
|
83
|
+
*/
|
|
84
|
+
export function scoreNodeMetadata(meta, terms, options = {}) {
|
|
85
|
+
if (terms.length === 0)
|
|
86
|
+
return 0;
|
|
87
|
+
if (options.namespacePrefix &&
|
|
88
|
+
!(meta.namespace ?? "").startsWith(options.namespacePrefix)) {
|
|
89
|
+
return 0;
|
|
90
|
+
}
|
|
91
|
+
const cls = namespaceClass(meta.namespace);
|
|
92
|
+
if (cls === "provider" && !options.includeProviderNodes)
|
|
93
|
+
return 0;
|
|
94
|
+
let raw = 0;
|
|
95
|
+
for (const rawTerm of terms) {
|
|
96
|
+
const term = rawTerm.toLowerCase();
|
|
97
|
+
if (!term)
|
|
98
|
+
continue;
|
|
99
|
+
raw += fieldScore(meta.title, term, FIELD_WEIGHTS.title);
|
|
100
|
+
raw += fieldScore(meta.node_type, term, FIELD_WEIGHTS.nodeType);
|
|
101
|
+
raw += fieldScore(meta.namespace, term, FIELD_WEIGHTS.namespace);
|
|
102
|
+
raw += fieldScore(meta.description, term, FIELD_WEIGHTS.description);
|
|
103
|
+
}
|
|
104
|
+
if (raw === 0)
|
|
105
|
+
return 0;
|
|
106
|
+
return cls === "core" ? raw * CORE_MULTIPLIER : raw;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Score and rank a list of node metadata against search terms.
|
|
110
|
+
* Returns nodes with score > 0, sorted by score descending; ties broken
|
|
111
|
+
* alphabetically on `node_type` for deterministic output.
|
|
112
|
+
*/
|
|
113
|
+
export function rankNodeMetadata(nodes, terms, options = {}) {
|
|
114
|
+
const scored = [];
|
|
115
|
+
for (const meta of nodes) {
|
|
116
|
+
const score = scoreNodeMetadata(meta, terms, options);
|
|
117
|
+
if (score > 0)
|
|
118
|
+
scored.push({ meta, score });
|
|
119
|
+
}
|
|
120
|
+
scored.sort((a, b) => {
|
|
121
|
+
if (b.score !== a.score)
|
|
122
|
+
return b.score - a.score;
|
|
123
|
+
return a.meta.node_type.localeCompare(b.meta.node_type);
|
|
124
|
+
});
|
|
125
|
+
return scored;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"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"}
|