Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions libs/langchain/src/agents/middlewareAgent/ReactAgent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ export class ReactAgent<
/**
* add single tool node for all tools
*/
if (toolClasses.length > 0) {
if (toolClasses.filter(isClientTool).length > 0) {
const toolNode = new ToolNode(toolClasses.filter(isClientTool), {
signal: this.options.signal,
});
Expand Down Expand Up @@ -354,7 +354,7 @@ export class ReactAgent<
/**
* add edges for tools node
*/
if (toolClasses.length > 0) {
if (toolClasses.filter(isClientTool).length > 0) {
// Tools should return to first beforeModel node or agent
let toolReturnTarget: string;
if (beforeModelNodes.length > 0) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { describe, it, expect } from "vitest";
import { ChatAnthropic } from "@langchain/anthropic";
import { HumanMessage, AIMessage } from "@langchain/core/messages";

import { createAgent } from "../index.js";

describe("Code Execution Tool", () => {
it("should use Anthropic code_execution tool to calculate statistics", async () => {
// Create ChatAnthropic model with code execution beta header
const model = new ChatAnthropic({
model: "claude-3-5-haiku-20241022",
temperature: 0,
clientOptions: {
defaultHeaders: {
"anthropic-beta": "code-execution-2025-08-25",
},
},
});

// Define the built-in code_execution tool
const codeExecutionTool = {
type: "code_execution_20250825",
name: "code_execution",
};

// Create agent with the built-in tool
const agent = createAgent({
model,
tools: [codeExecutionTool],
});

// Invoke the agent with a statistics calculation task
const result = await agent.invoke({
messages: [
new HumanMessage(
"Calculate the mean and standard deviation of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]"
),
],
});

// Verify the result contains messages
expect(result.messages).toBeDefined();
expect(result.messages.length).toBeGreaterThan(0);

// Find the final AI response
const aiResponse = result.messages.find((msg) => msg.type === "ai") as
| AIMessage
| undefined;
expect(aiResponse).toBeDefined();

// The response should contain content blocks
const content = Array.isArray(aiResponse?.content)
? aiResponse.content
: [];
expect(content.length).toBeGreaterThan(0);

// Verify that code_execution tool was used (server_tool_use block)
expect(content.some((block) => block.type === "server_tool_use")).toBe(
true
);

// Verify that we got a code execution result
expect(
content.some((block) => block.type === "bash_code_execution_tool_result")
).toBe(true);

// The response should contain text with the calculated values
const textBlocks = content.filter((block) => block.type === "text");
const responseText = textBlocks
.map((block) => block.text)
.join(" ")
.toLowerCase();

// The response should mention the mean (5.5) and standard deviation (~2.87)
expect(responseText).toMatch(/mean|average/i);
expect(responseText).toMatch(/standard deviation|std/i);
expect(responseText).toMatch(/5\.5/); // Expected mean
expect(responseText).toMatch(/2\.[89]|3\./); // Expected stdev (approximately 2.87)
}, 60000); // Set timeout to 60s for API call
});