@easynet/agent-llm 1.0.7 → 1.0.9
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/cli.d.ts +2 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +14 -5
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* CLI for @easynet/agent-llm:
|
|
3
|
+
* CLI for @easynet/agent-llm: chat with the configured LLM (default: simple invoke, no tools).
|
|
4
4
|
* Usage: agent-llm "your question"
|
|
5
5
|
* or: agent-llm --config ./config/llm.yaml "hi"
|
|
6
6
|
* or: npx @easynet/agent-llm "hi"
|
|
7
|
+
* Use --tools to enable the agent loop with get_weather/add_numbers tools.
|
|
7
8
|
*/
|
|
8
9
|
export {};
|
|
9
10
|
//# sourceMappingURL=cli.d.ts.map
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;GAMG"}
|
package/dist/cli.js
CHANGED
|
@@ -10,17 +10,20 @@ import { HumanMessage, ToolMessage } from "@langchain/core/messages";
|
|
|
10
10
|
function parseArgv() {
|
|
11
11
|
const args = process.argv.slice(2);
|
|
12
12
|
let configPath;
|
|
13
|
+
let useTools = false;
|
|
13
14
|
const rest = [];
|
|
14
15
|
for (let i = 0; i < args.length; i++) {
|
|
15
16
|
if (args[i] === "--config" && args[i + 1]) {
|
|
16
17
|
configPath = args[i + 1];
|
|
17
18
|
i++;
|
|
19
|
+
} else if (args[i] === "--tools") {
|
|
20
|
+
useTools = true;
|
|
18
21
|
} else {
|
|
19
22
|
rest.push(args[i]);
|
|
20
23
|
}
|
|
21
24
|
}
|
|
22
25
|
const query = rest.join(" ").trim() || "hi";
|
|
23
|
-
return { configPath, query };
|
|
26
|
+
return { configPath, useTools, query };
|
|
24
27
|
}
|
|
25
28
|
var getWeather = tool(
|
|
26
29
|
(input) => {
|
|
@@ -55,10 +58,16 @@ var addNumbers = tool(
|
|
|
55
58
|
var tools = [getWeather, addNumbers];
|
|
56
59
|
var toolsByName = new Map(tools.map((t) => [t.name, t]));
|
|
57
60
|
var MAX_TURNS = 10;
|
|
58
|
-
async function
|
|
61
|
+
async function runSimpleChat(model, query) {
|
|
62
|
+
const messages = [new HumanMessage(query)];
|
|
63
|
+
const response = await model.invoke(messages);
|
|
64
|
+
const content = typeof response.content === "string" ? response.content : Array.isArray(response.content) ? response.content.map((c) => "text" in c ? c.text : "").join("") : String(response.content ?? "");
|
|
65
|
+
return content;
|
|
66
|
+
}
|
|
67
|
+
async function runAgentWithTools(model, query) {
|
|
59
68
|
const withTools = model.bindTools?.(tools, { tool_choice: "auto" });
|
|
60
|
-
if (!withTools) throw new Error("Model does not support bindTools");
|
|
61
69
|
const messages = [new HumanMessage(query)];
|
|
70
|
+
if (!withTools) return runSimpleChat(model, query);
|
|
62
71
|
for (let turn = 0; turn < MAX_TURNS; turn++) {
|
|
63
72
|
const response = await withTools.invoke(messages);
|
|
64
73
|
const aiMessage = response;
|
|
@@ -89,11 +98,11 @@ async function runAgent(model, query) {
|
|
|
89
98
|
return "Agent reached max turns without a final answer.";
|
|
90
99
|
}
|
|
91
100
|
async function main() {
|
|
92
|
-
const { configPath, query } = parseArgv();
|
|
101
|
+
const { configPath, useTools, query } = parseArgv();
|
|
93
102
|
const model = await createAgentLlM(configPath ? { configPath } : void 0);
|
|
94
103
|
console.log("Query:", query);
|
|
95
104
|
console.log("---");
|
|
96
|
-
const answer = await
|
|
105
|
+
const answer = useTools ? await runAgentWithTools(model, query) : await runSimpleChat(model, query);
|
|
97
106
|
console.log("Answer:", answer);
|
|
98
107
|
console.log("---");
|
|
99
108
|
console.log("Done.");
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * CLI for @easynet/agent-llm:
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * CLI for @easynet/agent-llm: chat with the configured LLM (default: simple invoke, no tools).\n * Usage: agent-llm \"your question\"\n * or: agent-llm --config ./config/llm.yaml \"hi\"\n * or: npx @easynet/agent-llm \"hi\"\n * Use --tools to enable the agent loop with get_weather/add_numbers tools.\n */\n\nimport { createAgentLlM } from \"./createAgentLlM.js\";\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { HumanMessage, AIMessage, ToolMessage } from \"@langchain/core/messages\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\n\nfunction parseArgv(): { configPath: string | undefined; useTools: boolean; query: string } {\n const args = process.argv.slice(2);\n let configPath: string | undefined;\n let useTools = false;\n const rest: string[] = [];\n for (let i = 0; i < args.length; i++) {\n if (args[i] === \"--config\" && args[i + 1]) {\n configPath = args[i + 1];\n i++;\n } else if (args[i] === \"--tools\") {\n useTools = true;\n } else {\n rest.push(args[i]);\n }\n }\n const query = rest.join(\" \").trim() || \"hi\";\n return { configPath, useTools, query };\n}\n\nconst getWeather = tool(\n (input: { location: string }) => {\n const loc = input.location.toLowerCase();\n if ([\"sf\", \"san francisco\"].includes(loc)) {\n return \"It's 60°F and foggy in San Francisco.\";\n }\n if ([\"ny\", \"new york\"].includes(loc)) {\n return \"It's 72°F and partly cloudy in New York.\";\n }\n return `Weather for ${input.location}: 70°F and sunny.`;\n },\n {\n name: \"get_weather\",\n description: \"Get the current weather for a location.\",\n schema: z.object({\n location: z.string().describe(\"City or place name (e.g. SF, New York)\"),\n }),\n }\n);\n\nconst addNumbers = tool(\n (input: { a: number; b: number }) => String(input.a + input.b),\n {\n name: \"add_numbers\",\n description: \"Add two numbers.\",\n schema: z.object({\n a: z.number().describe(\"First number\"),\n b: z.number().describe(\"Second number\"),\n }),\n }\n);\n\nconst tools = [getWeather, addNumbers];\nconst toolsByName = new Map(tools.map((t) => [t.name, t]));\n\nconst MAX_TURNS = 10;\n\nasync function runSimpleChat(\n model: BaseChatModel,\n query: string\n): Promise<string> {\n const messages: BaseMessage[] = [new HumanMessage(query)];\n const response = await model.invoke(messages);\n const content =\n typeof response.content === \"string\"\n ? response.content\n : Array.isArray(response.content)\n ? (response.content as { type?: string; text?: string }[])\n .map((c) => (\"text\" in c ? c.text : \"\"))\n .join(\"\")\n : String(response.content ?? \"\");\n return content;\n}\n\nasync function runAgentWithTools(\n model: BaseChatModel,\n query: string\n): Promise<string> {\n const withTools = model.bindTools?.(tools, { tool_choice: \"auto\" });\n const messages: BaseMessage[] = [new HumanMessage(query)];\n if (!withTools) return runSimpleChat(model, query);\n\n for (let turn = 0; turn < MAX_TURNS; turn++) {\n const response = await withTools.invoke(messages);\n const aiMessage = response as AIMessage;\n\n if (!aiMessage.tool_calls?.length) {\n const content =\n typeof aiMessage.content === \"string\"\n ? aiMessage.content\n : Array.isArray(aiMessage.content)\n ? (aiMessage.content as { type?: string; text?: string }[])\n .map((c) => (\"text\" in c ? c.text : \"\"))\n .join(\"\")\n : String(aiMessage.content ?? \"\");\n return content;\n }\n\n messages.push(aiMessage);\n\n for (const tc of aiMessage.tool_calls) {\n const id = tc.id ?? `call_${turn}_${tc.name}`;\n const toolFn = toolsByName.get(tc.name as \"get_weather\" | \"add_numbers\");\n let result: string;\n if (toolFn) {\n try {\n const out = await (toolFn as { invoke: (args: Record<string, unknown>) => Promise<unknown> }).invoke(\n tc.args as Record<string, unknown>\n );\n result = typeof out === \"string\" ? out : JSON.stringify(out);\n } catch (err) {\n result = `Error: ${err instanceof Error ? err.message : String(err)}`;\n }\n } else {\n result = `Unknown tool: ${tc.name}`;\n }\n messages.push(new ToolMessage({ content: result, tool_call_id: id }));\n }\n }\n\n return \"Agent reached max turns without a final answer.\";\n}\n\nasync function main() {\n const { configPath, useTools, query } = parseArgv();\n // createAgentLlM resolves npm: providers (e.g. npm:wallee-llm#cis) and loads packages\n const model = await createAgentLlM(configPath ? { configPath } : undefined);\n\n console.log(\"Query:\", query);\n console.log(\"---\");\n\n const answer = useTools\n ? await runAgentWithTools(model, query)\n : await runSimpleChat(model, query);\n console.log(\"Answer:\", answer);\n console.log(\"---\");\n console.log(\"Done.\");\n}\n\nmain().catch((err) => {\n console.error(err);\n process.exit(1);\n});\n"],"mappings":"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","names":[]}
|