@easynet/agent-tool-hub 1.0.15 → 1.0.16
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/langchain-tools.cjs +4 -1
- package/dist/langchain-tools.cjs.map +1 -1
- package/dist/langchain-tools.d.cts +2 -0
- package/dist/langchain-tools.d.ts +2 -0
- package/dist/langchain-tools.js +4 -1
- package/dist/langchain-tools.js.map +1 -1
- package/examples/agent-toolhub-react-stock-bin.cjs +21 -0
- package/examples/agent-toolhub-react-stock.mjs +1 -0
- package/package.json +5 -5
package/dist/langchain-tools.cjs
CHANGED
|
@@ -31,11 +31,14 @@ function extractToolArgs(args) {
|
|
|
31
31
|
}
|
|
32
32
|
return {};
|
|
33
33
|
}
|
|
34
|
+
function toolNameForLLM(name) {
|
|
35
|
+
return name.replace(/[/.-]/g, "_");
|
|
36
|
+
}
|
|
34
37
|
function toolHubToLangChainTools(hub) {
|
|
35
38
|
const specs = hub.getRegistry().snapshot();
|
|
36
39
|
return specs.map((spec) => {
|
|
37
40
|
const opts = {
|
|
38
|
-
name: spec.name,
|
|
41
|
+
name: toolNameForLLM(spec.name),
|
|
39
42
|
description: spec.description ?? `Tool: ${spec.name}`,
|
|
40
43
|
schema: TOOL_ARGS_SCHEMA
|
|
41
44
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/langchain-tools.ts"],"names":["z","tool","createAgentToolHub"],"mappings":";;;;;;;;AA4BA,IAAM,gBAAA,GAAmBA,KAAA,CACtB,MAAA,CAAOA,KAAA,CAAE,MAAA,EAAO,EAAGA,KAAA,CAAE,OAAA,EAAS,CAAA,CAC9B,QAAA,CAAS,oCAAoC,CAAA;AAMhD,SAAS,gBAAgB,IAAA,EAAwC;AAC/D,EAAA,IAAI,IAAA,IAAQ,QAAQ,OAAO,IAAA,KAAS,YAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,EAAG;AACpE,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,MAAM,OAAO,IAAA,KAAS,WAAW,IAAA,GAAO,MAAA,CAAO,QAAQ,EAAE,CAAA;AAC/D,EAAA,IAAI,CAAC,GAAA,CAAI,IAAA,EAAK,SAAU,EAAC;AAEzB,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC7B,IAAA,IAAI,MAAA,IAAU,QAAQ,OAAO,MAAA,KAAW,YAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,EAAG;AAC1E,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AAEA,EAAA,MAAM,SAAA,GAAY,GAAA,CAAI,WAAA,CAAY,GAAG,CAAA;AACrC,EAAA,IAAI,SAAA,KAAc,EAAA,EAAI,OAAO,EAAC;AAC9B,EAAA,IAAI;AACF,IAAA,MAAM,SAAS,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,KAAA,CAAM,SAAS,CAAC,CAAA;AAC9C,IAAA,IAAI,MAAA,IAAU,QAAQ,OAAO,MAAA,KAAW,YAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,EAAG;AAC1E,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,OAAO,EAAC;AACV;
|
|
1
|
+
{"version":3,"sources":["../src/langchain-tools.ts"],"names":["z","tool","createAgentToolHub"],"mappings":";;;;;;;;AA4BA,IAAM,gBAAA,GAAmBA,KAAA,CACtB,MAAA,CAAOA,KAAA,CAAE,MAAA,EAAO,EAAGA,KAAA,CAAE,OAAA,EAAS,CAAA,CAC9B,QAAA,CAAS,oCAAoC,CAAA;AAMhD,SAAS,gBAAgB,IAAA,EAAwC;AAC/D,EAAA,IAAI,IAAA,IAAQ,QAAQ,OAAO,IAAA,KAAS,YAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,EAAG;AACpE,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,MAAM,OAAO,IAAA,KAAS,WAAW,IAAA,GAAO,MAAA,CAAO,QAAQ,EAAE,CAAA;AAC/D,EAAA,IAAI,CAAC,GAAA,CAAI,IAAA,EAAK,SAAU,EAAC;AAEzB,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC7B,IAAA,IAAI,MAAA,IAAU,QAAQ,OAAO,MAAA,KAAW,YAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,EAAG;AAC1E,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AAEA,EAAA,MAAM,SAAA,GAAY,GAAA,CAAI,WAAA,CAAY,GAAG,CAAA;AACrC,EAAA,IAAI,SAAA,KAAc,EAAA,EAAI,OAAO,EAAC;AAC9B,EAAA,IAAI;AACF,IAAA,MAAM,SAAS,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,KAAA,CAAM,SAAS,CAAC,CAAA;AAC9C,IAAA,IAAI,MAAA,IAAU,QAAQ,OAAO,MAAA,KAAW,YAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,EAAG;AAC1E,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,OAAO,EAAC;AACV;AAMA,SAAS,eAAe,IAAA,EAAsB;AAC5C,EAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,QAAA,EAAU,GAAG,CAAA;AACnC;AAaO,SAAS,wBAAwB,GAAA,EAA6B;AACnE,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,WAAA,EAAY,CAAE,QAAA,EAAS;AACzC,EAAA,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,KAAS;AACzB,IAAA,MAAM,IAAA,GAAO;AAAA,MACX,IAAA,EAAM,cAAA,CAAe,IAAA,CAAK,IAAI,CAAA;AAAA,MAC9B,WAAA,EAAa,IAAA,CAAK,WAAA,IAAe,CAAA,MAAA,EAAS,KAAK,IAAI,CAAA,CAAA;AAAA,MACnD,MAAA,EAAQ;AAAA,KACV;AAEA,IAAA,MAAM,CAAA,GAAIC,cAAA;AAAA,MACR,OAAO,IAAA,KAAkB;AACvB,QAAA,MAAM,UAAA,GAAa,gBAAgB,IAAI,CAAA;AACvC,QAAA,MAAM,SAAS,MAAM,GAAA,CAAI,UAAA,CAAW,IAAA,CAAK,MAAM,UAAU,CAAA;AACzD,QAAA,OAAO,MAAA,CAAO,KACV,MAAA,CAAO,MAAA,GACP,EAAE,KAAA,EAAO,MAAA,CAAO,KAAA,EAAO,OAAA,IAAW,aAAA,EAAc;AAAA,MACtD,CAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,OAAO,CAAA;AAAA,EACT,CAAC,CAAA;AACH;AASA,eAAsBC,oBAAmB,UAAA,EAAoB;AAC3D,EAAA,MAAM,GAAA,GAAM,MAAMA,oCAAA,CAA8B,UAAU,CAAA;AAC1D,EAAA,OAAO,MAAA,CAAO,OAAO,GAAA,EAAK;AAAA,IACxB,IAAI,KAAA,GAAmB;AACrB,MAAA,OAAO,wBAAwB,GAAG,CAAA;AAAA,IACpC;AAAA,GACD,CAAA;AACH","file":"langchain-tools.cjs","sourcesContent":["/**\n * Bridge: ToolHub registry → LangChain tools (for use with LangChain agents, e.g. DeepAgents).\n *\n * Requires peer dependencies: langchain, zod. Use this entry when integrating ToolHub\n * with LangChain 1.x agents. Main package entry does not depend on LangChain.\n *\n * @example\n * ```ts\n * import { createAgentToolHub, toolHubToLangChainTools } from \"@easynet/agent-tool-hub/langchain-tools\";\n * const hub = await createAgentToolHub(\"toolhub.yaml\");\n * // hub.tools is the LangChain tools array\n * const agent = createDeepAgent({ tools: hub.tools, ... });\n * // Or: const tools = toolHubToLangChainTools(hub);\n * ```\n */\n\nimport { createAgentToolHub as createAgentToolHubFromRuntime } from \"./toolhub-runtime.js\";\nimport { tool } from \"langchain\";\nimport { z } from \"zod\";\nimport type { ToolSpec } from \"./types/ToolSpec.js\";\nimport type { ToolResult } from \"./types/ToolResult.js\";\n\n/** Minimal interface for a hub that can list tools and invoke them (e.g. ToolHub, AgentToolHub). */\nexport interface ToolHubLike {\n getRegistry(): { snapshot(): ToolSpec[] };\n invokeTool(name: string, args: unknown): Promise<ToolResult>;\n}\n\nconst TOOL_ARGS_SCHEMA = z\n .record(z.string(), z.unknown())\n .describe(\"Tool arguments as key-value object\");\n\n/**\n * Extracts a JSON object from tool args. Handles models that send text + JSON\n * (e.g. \"Let's fetch.{\\\"symbol\\\":\\\"GOOGL\\\"}\") by finding the last {...} and parsing.\n */\nfunction extractToolArgs(args: unknown): Record<string, unknown> {\n if (args != null && typeof args === \"object\" && !Array.isArray(args)) {\n return args as Record<string, unknown>;\n }\n const str = typeof args === \"string\" ? args : String(args ?? \"\");\n if (!str.trim()) return {};\n // Try parse whole string first\n try {\n const parsed = JSON.parse(str) as unknown;\n if (parsed != null && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed as Record<string, unknown>;\n }\n } catch {\n // ignore\n }\n // Find last { ... } and parse\n const lastBrace = str.lastIndexOf(\"{\");\n if (lastBrace === -1) return {};\n try {\n const parsed = JSON.parse(str.slice(lastBrace)) as unknown;\n if (parsed != null && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed as Record<string, unknown>;\n }\n } catch {\n // ignore\n }\n return {};\n}\n\n/**\n * Sanitize tool name for LLM/API: slashes and chars that some backends mangle become underscores.\n * Invoke still uses the original spec.name.\n */\nfunction toolNameForLLM(name: string): string {\n return name.replace(/[/.-]/g, \"_\");\n}\n\n/**\n * Converts a ToolHub (or AgentToolHub) registry into an array of LangChain tools.\n * Each tool delegates to hub.invokeTool(spec.name, args). Use with LangChain 1.x agents\n * (e.g. createDeepAgent from deepagents). Tool args are normalized: if the model\n * sends text + JSON (e.g. \"reasoning{\\\"symbol\\\":\\\"AAPL\\\"}\"), the JSON is extracted.\n * Tool names are sanitized for the LLM (e.g. tools/yahoo-finance → tools_yahoo_finance)\n * so OpenAI-compatible backends that mangle slashes still get a stable, matchable name.\n *\n * @param hub - Instance with getRegistry() and invokeTool(name, args)\n * @returns Array of LangChain tool instances (compatible with agent tools array)\n */\nexport function toolHubToLangChainTools(hub: ToolHubLike): unknown[] {\n const specs = hub.getRegistry().snapshot();\n return specs.map((spec) => {\n const opts = {\n name: toolNameForLLM(spec.name),\n description: spec.description ?? `Tool: ${spec.name}`,\n schema: TOOL_ARGS_SCHEMA,\n };\n // Cast opts to avoid TS2589 (excessively deep type instantiation) from langchain tool()\n const t = tool(\n async (args: unknown) => {\n const normalized = extractToolArgs(args);\n const result = await hub.invokeTool(spec.name, normalized);\n return result.ok\n ? result.result\n : { error: result.error?.message ?? \"Tool failed\" };\n },\n opts as Parameters<typeof tool>[1],\n );\n return t as unknown;\n });\n}\n\n/**\n * Create an AgentToolHub from a config path and return it with a `.tools` getter\n * that returns LangChain tools. Use with LangChain/DeepAgents agents.\n *\n * @param configPath - Path to toolhub.yaml (or other config file)\n * @returns AgentToolHub instance with `.tools` (array of LangChain tools)\n */\nexport async function createAgentToolHub(configPath: string) {\n const hub = await createAgentToolHubFromRuntime(configPath);\n return Object.assign(hub, {\n get tools(): unknown[] {\n return toolHubToLangChainTools(hub);\n },\n });\n}\n"]}
|
|
@@ -16,6 +16,8 @@ interface ToolHubLike {
|
|
|
16
16
|
* Each tool delegates to hub.invokeTool(spec.name, args). Use with LangChain 1.x agents
|
|
17
17
|
* (e.g. createDeepAgent from deepagents). Tool args are normalized: if the model
|
|
18
18
|
* sends text + JSON (e.g. "reasoning{\"symbol\":\"AAPL\"}"), the JSON is extracted.
|
|
19
|
+
* Tool names are sanitized for the LLM (e.g. tools/yahoo-finance → tools_yahoo_finance)
|
|
20
|
+
* so OpenAI-compatible backends that mangle slashes still get a stable, matchable name.
|
|
19
21
|
*
|
|
20
22
|
* @param hub - Instance with getRegistry() and invokeTool(name, args)
|
|
21
23
|
* @returns Array of LangChain tool instances (compatible with agent tools array)
|
|
@@ -16,6 +16,8 @@ interface ToolHubLike {
|
|
|
16
16
|
* Each tool delegates to hub.invokeTool(spec.name, args). Use with LangChain 1.x agents
|
|
17
17
|
* (e.g. createDeepAgent from deepagents). Tool args are normalized: if the model
|
|
18
18
|
* sends text + JSON (e.g. "reasoning{\"symbol\":\"AAPL\"}"), the JSON is extracted.
|
|
19
|
+
* Tool names are sanitized for the LLM (e.g. tools/yahoo-finance → tools_yahoo_finance)
|
|
20
|
+
* so OpenAI-compatible backends that mangle slashes still get a stable, matchable name.
|
|
19
21
|
*
|
|
20
22
|
* @param hub - Instance with getRegistry() and invokeTool(name, args)
|
|
21
23
|
* @returns Array of LangChain tool instances (compatible with agent tools array)
|
package/dist/langchain-tools.js
CHANGED
|
@@ -29,11 +29,14 @@ function extractToolArgs(args) {
|
|
|
29
29
|
}
|
|
30
30
|
return {};
|
|
31
31
|
}
|
|
32
|
+
function toolNameForLLM(name) {
|
|
33
|
+
return name.replace(/[/.-]/g, "_");
|
|
34
|
+
}
|
|
32
35
|
function toolHubToLangChainTools(hub) {
|
|
33
36
|
const specs = hub.getRegistry().snapshot();
|
|
34
37
|
return specs.map((spec) => {
|
|
35
38
|
const opts = {
|
|
36
|
-
name: spec.name,
|
|
39
|
+
name: toolNameForLLM(spec.name),
|
|
37
40
|
description: spec.description ?? `Tool: ${spec.name}`,
|
|
38
41
|
schema: TOOL_ARGS_SCHEMA
|
|
39
42
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/langchain-tools.ts"],"names":["createAgentToolHub"],"mappings":";;;;;;AA4BA,IAAM,gBAAA,GAAmB,CAAA,CACtB,MAAA,CAAO,CAAA,CAAE,MAAA,EAAO,EAAG,CAAA,CAAE,OAAA,EAAS,CAAA,CAC9B,QAAA,CAAS,oCAAoC,CAAA;AAMhD,SAAS,gBAAgB,IAAA,EAAwC;AAC/D,EAAA,IAAI,IAAA,IAAQ,QAAQ,OAAO,IAAA,KAAS,YAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,EAAG;AACpE,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,MAAM,OAAO,IAAA,KAAS,WAAW,IAAA,GAAO,MAAA,CAAO,QAAQ,EAAE,CAAA;AAC/D,EAAA,IAAI,CAAC,GAAA,CAAI,IAAA,EAAK,SAAU,EAAC;AAEzB,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC7B,IAAA,IAAI,MAAA,IAAU,QAAQ,OAAO,MAAA,KAAW,YAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,EAAG;AAC1E,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AAEA,EAAA,MAAM,SAAA,GAAY,GAAA,CAAI,WAAA,CAAY,GAAG,CAAA;AACrC,EAAA,IAAI,SAAA,KAAc,EAAA,EAAI,OAAO,EAAC;AAC9B,EAAA,IAAI;AACF,IAAA,MAAM,SAAS,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,KAAA,CAAM,SAAS,CAAC,CAAA;AAC9C,IAAA,IAAI,MAAA,IAAU,QAAQ,OAAO,MAAA,KAAW,YAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,EAAG;AAC1E,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,OAAO,EAAC;AACV;
|
|
1
|
+
{"version":3,"sources":["../src/langchain-tools.ts"],"names":["createAgentToolHub"],"mappings":";;;;;;AA4BA,IAAM,gBAAA,GAAmB,CAAA,CACtB,MAAA,CAAO,CAAA,CAAE,MAAA,EAAO,EAAG,CAAA,CAAE,OAAA,EAAS,CAAA,CAC9B,QAAA,CAAS,oCAAoC,CAAA;AAMhD,SAAS,gBAAgB,IAAA,EAAwC;AAC/D,EAAA,IAAI,IAAA,IAAQ,QAAQ,OAAO,IAAA,KAAS,YAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,EAAG;AACpE,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,MAAM,OAAO,IAAA,KAAS,WAAW,IAAA,GAAO,MAAA,CAAO,QAAQ,EAAE,CAAA;AAC/D,EAAA,IAAI,CAAC,GAAA,CAAI,IAAA,EAAK,SAAU,EAAC;AAEzB,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC7B,IAAA,IAAI,MAAA,IAAU,QAAQ,OAAO,MAAA,KAAW,YAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,EAAG;AAC1E,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AAEA,EAAA,MAAM,SAAA,GAAY,GAAA,CAAI,WAAA,CAAY,GAAG,CAAA;AACrC,EAAA,IAAI,SAAA,KAAc,EAAA,EAAI,OAAO,EAAC;AAC9B,EAAA,IAAI;AACF,IAAA,MAAM,SAAS,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,KAAA,CAAM,SAAS,CAAC,CAAA;AAC9C,IAAA,IAAI,MAAA,IAAU,QAAQ,OAAO,MAAA,KAAW,YAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,EAAG;AAC1E,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,OAAO,EAAC;AACV;AAMA,SAAS,eAAe,IAAA,EAAsB;AAC5C,EAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,QAAA,EAAU,GAAG,CAAA;AACnC;AAaO,SAAS,wBAAwB,GAAA,EAA6B;AACnE,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,WAAA,EAAY,CAAE,QAAA,EAAS;AACzC,EAAA,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,KAAS;AACzB,IAAA,MAAM,IAAA,GAAO;AAAA,MACX,IAAA,EAAM,cAAA,CAAe,IAAA,CAAK,IAAI,CAAA;AAAA,MAC9B,WAAA,EAAa,IAAA,CAAK,WAAA,IAAe,CAAA,MAAA,EAAS,KAAK,IAAI,CAAA,CAAA;AAAA,MACnD,MAAA,EAAQ;AAAA,KACV;AAEA,IAAA,MAAM,CAAA,GAAI,IAAA;AAAA,MACR,OAAO,IAAA,KAAkB;AACvB,QAAA,MAAM,UAAA,GAAa,gBAAgB,IAAI,CAAA;AACvC,QAAA,MAAM,SAAS,MAAM,GAAA,CAAI,UAAA,CAAW,IAAA,CAAK,MAAM,UAAU,CAAA;AACzD,QAAA,OAAO,MAAA,CAAO,KACV,MAAA,CAAO,MAAA,GACP,EAAE,KAAA,EAAO,MAAA,CAAO,KAAA,EAAO,OAAA,IAAW,aAAA,EAAc;AAAA,MACtD,CAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,OAAO,CAAA;AAAA,EACT,CAAC,CAAA;AACH;AASA,eAAsBA,oBAAmB,UAAA,EAAoB;AAC3D,EAAA,MAAM,GAAA,GAAM,MAAM,kBAAA,CAA8B,UAAU,CAAA;AAC1D,EAAA,OAAO,MAAA,CAAO,OAAO,GAAA,EAAK;AAAA,IACxB,IAAI,KAAA,GAAmB;AACrB,MAAA,OAAO,wBAAwB,GAAG,CAAA;AAAA,IACpC;AAAA,GACD,CAAA;AACH","file":"langchain-tools.js","sourcesContent":["/**\n * Bridge: ToolHub registry → LangChain tools (for use with LangChain agents, e.g. DeepAgents).\n *\n * Requires peer dependencies: langchain, zod. Use this entry when integrating ToolHub\n * with LangChain 1.x agents. Main package entry does not depend on LangChain.\n *\n * @example\n * ```ts\n * import { createAgentToolHub, toolHubToLangChainTools } from \"@easynet/agent-tool-hub/langchain-tools\";\n * const hub = await createAgentToolHub(\"toolhub.yaml\");\n * // hub.tools is the LangChain tools array\n * const agent = createDeepAgent({ tools: hub.tools, ... });\n * // Or: const tools = toolHubToLangChainTools(hub);\n * ```\n */\n\nimport { createAgentToolHub as createAgentToolHubFromRuntime } from \"./toolhub-runtime.js\";\nimport { tool } from \"langchain\";\nimport { z } from \"zod\";\nimport type { ToolSpec } from \"./types/ToolSpec.js\";\nimport type { ToolResult } from \"./types/ToolResult.js\";\n\n/** Minimal interface for a hub that can list tools and invoke them (e.g. ToolHub, AgentToolHub). */\nexport interface ToolHubLike {\n getRegistry(): { snapshot(): ToolSpec[] };\n invokeTool(name: string, args: unknown): Promise<ToolResult>;\n}\n\nconst TOOL_ARGS_SCHEMA = z\n .record(z.string(), z.unknown())\n .describe(\"Tool arguments as key-value object\");\n\n/**\n * Extracts a JSON object from tool args. Handles models that send text + JSON\n * (e.g. \"Let's fetch.{\\\"symbol\\\":\\\"GOOGL\\\"}\") by finding the last {...} and parsing.\n */\nfunction extractToolArgs(args: unknown): Record<string, unknown> {\n if (args != null && typeof args === \"object\" && !Array.isArray(args)) {\n return args as Record<string, unknown>;\n }\n const str = typeof args === \"string\" ? args : String(args ?? \"\");\n if (!str.trim()) return {};\n // Try parse whole string first\n try {\n const parsed = JSON.parse(str) as unknown;\n if (parsed != null && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed as Record<string, unknown>;\n }\n } catch {\n // ignore\n }\n // Find last { ... } and parse\n const lastBrace = str.lastIndexOf(\"{\");\n if (lastBrace === -1) return {};\n try {\n const parsed = JSON.parse(str.slice(lastBrace)) as unknown;\n if (parsed != null && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed as Record<string, unknown>;\n }\n } catch {\n // ignore\n }\n return {};\n}\n\n/**\n * Sanitize tool name for LLM/API: slashes and chars that some backends mangle become underscores.\n * Invoke still uses the original spec.name.\n */\nfunction toolNameForLLM(name: string): string {\n return name.replace(/[/.-]/g, \"_\");\n}\n\n/**\n * Converts a ToolHub (or AgentToolHub) registry into an array of LangChain tools.\n * Each tool delegates to hub.invokeTool(spec.name, args). Use with LangChain 1.x agents\n * (e.g. createDeepAgent from deepagents). Tool args are normalized: if the model\n * sends text + JSON (e.g. \"reasoning{\\\"symbol\\\":\\\"AAPL\\\"}\"), the JSON is extracted.\n * Tool names are sanitized for the LLM (e.g. tools/yahoo-finance → tools_yahoo_finance)\n * so OpenAI-compatible backends that mangle slashes still get a stable, matchable name.\n *\n * @param hub - Instance with getRegistry() and invokeTool(name, args)\n * @returns Array of LangChain tool instances (compatible with agent tools array)\n */\nexport function toolHubToLangChainTools(hub: ToolHubLike): unknown[] {\n const specs = hub.getRegistry().snapshot();\n return specs.map((spec) => {\n const opts = {\n name: toolNameForLLM(spec.name),\n description: spec.description ?? `Tool: ${spec.name}`,\n schema: TOOL_ARGS_SCHEMA,\n };\n // Cast opts to avoid TS2589 (excessively deep type instantiation) from langchain tool()\n const t = tool(\n async (args: unknown) => {\n const normalized = extractToolArgs(args);\n const result = await hub.invokeTool(spec.name, normalized);\n return result.ok\n ? result.result\n : { error: result.error?.message ?? \"Tool failed\" };\n },\n opts as Parameters<typeof tool>[1],\n );\n return t as unknown;\n });\n}\n\n/**\n * Create an AgentToolHub from a config path and return it with a `.tools` getter\n * that returns LangChain tools. Use with LangChain/DeepAgents agents.\n *\n * @param configPath - Path to toolhub.yaml (or other config file)\n * @returns AgentToolHub instance with `.tools` (array of LangChain tools)\n */\nexport async function createAgentToolHub(configPath: string) {\n const hub = await createAgentToolHubFromRuntime(configPath);\n return Object.assign(hub, {\n get tools(): unknown[] {\n return toolHubToLangChainTools(hub);\n },\n });\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
const { spawnSync } = require("child_process");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
|
|
6
|
+
const scriptDir = __dirname;
|
|
7
|
+
const mjsPath = path.join(scriptDir, "agent-toolhub-react-stock.mjs");
|
|
8
|
+
const packageRoot = path.join(scriptDir, "..");
|
|
9
|
+
|
|
10
|
+
// Use tsx so dependencies (e.g. @easynet/n8n-local) that ship .ts can be loaded
|
|
11
|
+
let nodeArgs = [mjsPath];
|
|
12
|
+
try {
|
|
13
|
+
require.resolve("tsx", { paths: [packageRoot] });
|
|
14
|
+
nodeArgs = ["--import", "tsx", mjsPath];
|
|
15
|
+
} catch (_) {
|
|
16
|
+
// tsx not available; run without it (may fail if a dep ships .ts)
|
|
17
|
+
}
|
|
18
|
+
const result = spawnSync(process.execPath, [...nodeArgs, ...process.argv.slice(2)], {
|
|
19
|
+
stdio: "inherit",
|
|
20
|
+
});
|
|
21
|
+
process.exitCode = result.status !== null ? result.status : 1;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@easynet/agent-tool-hub",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.16",
|
|
4
4
|
"description": "Agent Tool Hub: multi-protocol tool registry, PTC runtime, and adapter layer for MCP/LangChain/n8n/SKILL",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
9
9
|
"bin": {
|
|
10
10
|
"agent-tool-hub": "dist/cli.js",
|
|
11
|
-
"agent-toolhub-react-stock": "examples/agent-toolhub-react-stock.
|
|
11
|
+
"agent-toolhub-react-stock": "examples/agent-toolhub-react-stock-bin.cjs"
|
|
12
12
|
},
|
|
13
13
|
"exports": {
|
|
14
14
|
".": {
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"access": "public"
|
|
31
31
|
},
|
|
32
32
|
"scripts": {
|
|
33
|
-
"build": "tsup",
|
|
34
|
-
"dev": "tsup --watch",
|
|
33
|
+
"build": "npx tsup",
|
|
34
|
+
"dev": "npx tsup --watch",
|
|
35
35
|
"example:agent-toolhub": "node examples/agent-toolhub-example.mjs",
|
|
36
36
|
"example:agent-toolhub-react-stock": "node --import tsx examples/agent-toolhub-react-stock.mjs",
|
|
37
37
|
"test": "vitest run",
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"mustache": "^4.2.0",
|
|
54
54
|
"p-retry": "^6.2.1",
|
|
55
55
|
"p-timeout": "^6.1.4",
|
|
56
|
+
"tsx": "^4.21.0",
|
|
56
57
|
"uuid": "^11.0.5"
|
|
57
58
|
},
|
|
58
59
|
"devDependencies": {
|
|
@@ -67,7 +68,6 @@
|
|
|
67
68
|
"langchain": "^1.0.0",
|
|
68
69
|
"semantic-release": "^24.2.0",
|
|
69
70
|
"tsup": "^8.3.5",
|
|
70
|
-
"tsx": "^4.21.0",
|
|
71
71
|
"typescript": "^5.7.2",
|
|
72
72
|
"vitest": "^2.1.8",
|
|
73
73
|
"zod": "^3.23.0"
|