From 1da51b4913e1769182f8e12aa6aa70749bd0d9fd Mon Sep 17 00:00:00 2001
From: thucpn <thucsh2@gmail.com>
Date: Wed, 19 Mar 2025 12:29:09 +0700
Subject: [PATCH] move tool call to tools package

---
 packages/server/src/index.ts                  |  1 -
 packages/tools/src/index.ts                   |  2 +
 .../tools.ts => tools/src/tool-call.ts}       | 89 +++++--------------
 3 files changed, 22 insertions(+), 70 deletions(-)
 rename packages/{server/src/workflow/tools.ts => tools/src/tool-call.ts} (76%)

diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts
index 2f3a0aec6..a4caa0856 100644
--- a/packages/server/src/index.ts
+++ b/packages/server/src/index.ts
@@ -1,4 +1,3 @@
 export * from "./server";
 export * from "./workflow/stream";
-export * from "./workflow/tools";
 export * from "./workflow/type";
diff --git a/packages/tools/src/index.ts b/packages/tools/src/index.ts
index d4a0d4754..d13b32694 100644
--- a/packages/tools/src/index.ts
+++ b/packages/tools/src/index.ts
@@ -7,3 +7,5 @@ export * from "./tools/interpreter";
 export * from "./tools/openapi-action";
 export * from "./tools/weather";
 export * from "./tools/wikipedia";
+
+export * from "./tool-call";
diff --git a/packages/server/src/workflow/tools.ts b/packages/tools/src/tool-call.ts
similarity index 76%
rename from packages/server/src/workflow/tools.ts
rename to packages/tools/src/tool-call.ts
index 4e4633661..242949229 100644
--- a/packages/server/src/workflow/tools.ts
+++ b/packages/tools/src/tool-call.ts
@@ -1,97 +1,48 @@
+import { callTool } from "@llamaindex/core/agent";
 import {
   type BaseToolWithCall,
-  callTool,
   type ChatMessage,
   type ChatResponse,
   type ChatResponseChunk,
-  type HandlerContext,
   type PartialToolCall,
   type ToolCall,
   ToolCallLLM,
   type ToolCallLLMMessageOptions,
-} from "llamaindex";
-import crypto from "node:crypto";
-import { AgentRunEvent } from "./type";
+} from "@llamaindex/core/llms";
 
-/**
- * Call multiple tools and return the tool messages
- */
-export const callTools = async <T>({
+export async function callTools({
   tools,
   toolCalls,
-  ctx,
-  agentName,
-  writeEvent = true,
+  writeEvent,
 }: {
   toolCalls: ToolCall[];
   tools: BaseToolWithCall[];
-  ctx: HandlerContext<T>;
-  agentName: string;
-  writeEvent?: boolean;
-}): Promise<ChatMessage[]> => {
+  writeEvent?: (text: string, step: number, totalSteps: number) => void;
+}): Promise<ChatMessage[]> {
+  if (toolCalls.length === 0) return [];
+
   const toolMsgs: ChatMessage[] = [];
-  if (toolCalls.length === 0) {
-    return toolMsgs;
-  }
-  if (toolCalls.length === 1 && toolCalls[0]) {
-    const tool = tools.find(
-      (tool) => tool.metadata.name === toolCalls[0]!.name,
-    );
-    if (!tool) {
-      throw new Error(`Tool ${toolCalls[0].name} not found`);
-    }
-    return [
-      await callSingleTool(
-        tool,
-        toolCalls[0],
-        writeEvent
-          ? (msg: string) => {
-              ctx.sendEvent(
-                new AgentRunEvent({
-                  agent: agentName,
-                  text: msg,
-                  type: "text",
-                }),
-              );
-            }
-          : undefined,
-      ),
-    ];
-  }
-  // Multiple tool calls, show events in progress
-  const progressId = crypto.randomUUID();
+
   const totalSteps = toolCalls.length;
-  let currentStep = 0;
-  for (const toolCall of toolCalls) {
+  for (let step = 0; step < totalSteps; step++) {
+    const toolCall = toolCalls[step]!;
     const tool = tools.find((tool) => tool.metadata.name === toolCall.name);
-    if (!tool) {
-      throw new Error(`Tool ${toolCall.name} not found`);
-    }
-    const toolMsg = await callSingleTool(tool, toolCall, (msg: string) => {
-      ctx.sendEvent(
-        new AgentRunEvent({
-          agent: agentName,
-          text: msg,
-          type: "progress",
-          data: {
-            id: progressId,
-            total: totalSteps,
-            current: currentStep,
-          },
-        }),
-      );
-      currentStep++;
+    if (!tool) throw new Error(`Tool ${toolCall.name} not found`);
+
+    const toolMsg = await callSingleTool(tool, toolCall, (text) => {
+      writeEvent?.(text, step, totalSteps);
     });
     toolMsgs.push(toolMsg);
   }
+
   return toolMsgs;
-};
+}
 
-export const callSingleTool = async (
+export async function callSingleTool(
   tool: BaseToolWithCall,
   toolCall: ToolCall,
   eventEmitter?: (msg: string) => void,
-): Promise<ChatMessage> => {
+): Promise<ChatMessage> {
   if (eventEmitter) {
     eventEmitter(
       `Calling tool ${toolCall.name} with input: ${JSON.stringify(toolCall.input)}`,
@@ -135,7 +86,7 @@ export const callSingleTool = async (
       },
     },
   };
-};
+}
 
 class ChatWithToolsResponse {
   toolCalls: ToolCall[];
-- 
GitLab