From 62771058aa3e04e34e940f15b48c2be04b1db6a3 Mon Sep 17 00:00:00 2001
From: Alex Yang <himself65@outlook.com>
Date: Fri, 26 Apr 2024 13:10:57 -0500
Subject: [PATCH] fix: empty tools (#772)

---
 .changeset/brown-dodos-relax.md    |  6 ++++++
 packages/core/src/llm/anthropic.ts | 10 ++++++++--
 packages/core/src/llm/openai.ts    |  8 ++++++++
 3 files changed, 22 insertions(+), 2 deletions(-)
 create mode 100644 .changeset/brown-dodos-relax.md

diff --git a/.changeset/brown-dodos-relax.md b/.changeset/brown-dodos-relax.md
new file mode 100644
index 000000000..a3c8068ad
--- /dev/null
+++ b/.changeset/brown-dodos-relax.md
@@ -0,0 +1,6 @@
+---
+"llamaindex": patch
+"@llamaindex/edge": patch
+---
+
+fix: allow passing empty tools to llms
diff --git a/packages/core/src/llm/anthropic.ts b/packages/core/src/llm/anthropic.ts
index a708d9b0a..e6d4bfa4e 100644
--- a/packages/core/src/llm/anthropic.ts
+++ b/packages/core/src/llm/anthropic.ts
@@ -1,6 +1,7 @@
 import type { ClientOptions } from "@anthropic-ai/sdk";
 import { Anthropic as SDKAnthropic } from "@anthropic-ai/sdk";
 import type {
+  MessageCreateParamsNonStreaming,
   Tool,
   ToolResultBlockParam,
   ToolUseBlock,
@@ -264,7 +265,7 @@ export class Anthropic extends ToolCallLLM<AnthropicAdditionalChatOptions> {
     const anthropic = this.session.anthropic;
 
     if (tools) {
-      const response = await anthropic.beta.tools.messages.create({
+      const params: MessageCreateParamsNonStreaming = {
         messages: this.formatMessages<true>(messages),
         tools: tools.map(Anthropic.toTool),
         model: this.getModelName(this.model),
@@ -272,7 +273,12 @@ export class Anthropic extends ToolCallLLM<AnthropicAdditionalChatOptions> {
         max_tokens: this.maxTokens ?? 4096,
         top_p: this.topP,
         ...(systemPrompt && { system: systemPrompt }),
-      });
+      };
+      // Remove tools if there are none, as it will cause an error
+      if (tools.length === 0) {
+        delete params.tools;
+      }
+      const response = await anthropic.beta.tools.messages.create(params);
 
       const toolUseBlock = response.content.find(
         (content): content is ToolUseBlock => content.type === "tool_use",
diff --git a/packages/core/src/llm/openai.ts b/packages/core/src/llm/openai.ts
index af450826c..5941f522b 100644
--- a/packages/core/src/llm/openai.ts
+++ b/packages/core/src/llm/openai.ts
@@ -349,6 +349,14 @@ export class OpenAI extends ToolCallLLM<OpenAIAdditionalChatOptions> {
       ...Object.assign({}, this.additionalChatOptions, additionalChatOptions),
     };
 
+    if (
+      Array.isArray(baseRequestParams.tools) &&
+      baseRequestParams.tools.length === 0
+    ) {
+      // remove empty tools array to avoid OpenAI error
+      delete baseRequestParams.tools;
+    }
+
     // Streaming
     if (stream) {
       return this.streamChat(baseRequestParams);
-- 
GitLab