Overview
This example demonstrates how to use Anthropic’s Function Calling with GBOX to create an AI assistant that can execute Python code based on user queries.How It Works
- User Input - User asks a natural language question
- AI Analysis - Claude determines if code execution is needed
- Code Generation - AI generates Python code using the
execute_pythonfunction - Code Execution - GBOX executes the code and returns results
- Result Integration - AI incorporates results into the final response
Use Cases
- Data Analysis & Visualization - Process and display data
- Mathematical Problem Solving - Solve complex computational problems
- Interactive Code Generation - Real-time code generation and execution
Implementation Example
Step 1: Create the File
Copy the following code locally and create a new file namedindex.ts:
import Anthropic from "@anthropic-ai/sdk";
import GboxSDK from "gbox-sdk";
import * as dotenv from "dotenv";
dotenv.config();
// ==================== Initialize Clients ====================
const gboxSDK = new GboxSDK({
apiKey: process.env["GBOX_API_KEY"],
});
const anthropicClient = new Anthropic({
apiKey: process.env["ANTHROPIC_API_KEY"],
});
// ==================== Type Definitions ====================
interface ToolExecutionResult {
success: boolean;
result: string;
}
// ==================== Configuration Constants ====================
const DEFAULT_QUESTION =
"Please calculate the first 20 terms of the Fibonacci sequence and create a simple chart to visualize the growth trend";
// ==================== Utility Functions ====================
/**
* Get user question from command line arguments or use default
*/
function getUserQuestion(): string {
const args = process.argv.slice(2);
if (args.length > 0) {
const userQuestion = args.join(" ").trim();
if (userQuestion) {
console.info(`📝 Using user question: "${userQuestion}"`);
return userQuestion;
}
}
console.info(`📝 Using default question: "${DEFAULT_QUESTION}"`);
return DEFAULT_QUESTION;
}
/**
* Create initial conversation messages
*/
const createInitialMessages = (question: string): Anthropic.MessageParam[] => [
{
role: "user",
content: question,
},
];
/**
* Define available functions for function calling
*/
const createTools = (): Anthropic.Tool[] => [
{
name: "execute_python",
description:
"Execute Python code in a Linux environment and return results from stdout/stderr streams",
input_schema: {
type: "object",
properties: {
code: {
type: "string",
description:
"The Python code to execute. Results will be captured from standard output and standard error streams.",
},
},
required: ["code"],
},
},
];
// ==================== Core Execution Functions ====================
/**
* Execute Python code using GBOX
*/
async function executePythonCode(code: string): Promise<ToolExecutionResult> {
const box = await gboxSDK.create({ type: "linux" });
try {
console.info("📝 Executing Python code:");
console.log(code);
console.info("─".repeat(50));
const execution = await box.runCode(code);
const result = execution.stdout || execution.stderr || "No output";
console.info("✅ Execution result:");
console.log(result);
console.info("─".repeat(50));
return {
success: true,
result,
};
} catch (error) {
const errorMessage = `Error: ${error}`;
console.error("❌ Execution failed:", errorMessage);
return {
success: false,
result: errorMessage,
};
} finally {
await box.terminate();
}
}
/**
* Process function calls from Anthropic response
*/
async function processToolUse(
toolUseBlocks: Anthropic.ToolUseBlock[],
messages: Anthropic.MessageParam[]
): Promise<void> {
for (const toolUse of toolUseBlocks) {
if (toolUse.name === "execute_python") {
try {
const { code } = toolUse.input as { code: string };
const executionResult = await executePythonCode(code);
// Add function result to conversation
messages.push({
role: "user",
content: [
{
type: "tool_result",
tool_use_id: toolUse.id,
content: executionResult.result,
},
],
});
} catch (parseError) {
console.error("❌ Failed to parse function arguments:", parseError);
messages.push({
role: "user",
content: [
{
type: "tool_result",
tool_use_id: toolUse.id,
content: `Error parsing arguments: ${parseError}`,
},
],
});
}
}
}
}
/**
* Generate Anthropic message
*/
async function generateMessage(
messages: Anthropic.MessageParam[],
tools?: Anthropic.Tool[]
): Promise<Anthropic.Message> {
const response = await anthropicClient.messages.create({
model: "claude-3-7-sonnet-20250219",
max_tokens: 4000,
messages,
...(tools && { tools }),
});
return response;
}
// ==================== Main Execution Flow ====================
/**
* Main function - orchestrates the entire execution flow
*/
async function main(): Promise<void> {
try {
console.info("🚀 Starting Anthropic + GBOX integration");
console.info("═".repeat(50));
const userQuestion = getUserQuestion();
const messages = createInitialMessages(userQuestion);
const tools = createTools();
// Get initial response from Anthropic
console.info("💬 Getting initial response from Anthropic...");
const initialResponse = await generateMessage(messages, tools);
// Add assistant message to conversation
messages.push({
role: "assistant",
content: initialResponse.content,
});
// Check if there are function call blocks
const toolUseBlocks = initialResponse.content.filter(
(block): block is Anthropic.ToolUseBlock => block.type === "tool_use"
);
if (toolUseBlocks.length > 0) {
console.info(`🔧 Processing ${toolUseBlocks.length} function call(s)...`);
await processToolUse(toolUseBlocks, messages);
// Generate final response after function execution
console.info("💬 Getting final response from Anthropic...");
const finalResponse = await generateMessage(messages);
console.info("🎉 Final response:");
console.info("═".repeat(50));
for (const content of finalResponse.content) {
if (content.type === "text") {
console.log(content.text);
}
}
} else {
console.info("🎉 Response (no functions called):");
console.info("═".repeat(50));
for (const content of initialResponse.content) {
if (content.type === "text") {
console.log(content.text);
}
}
}
} catch (error) {
console.error("💥 Application error:", error);
process.exit(1);
}
}
// ==================== Help Information ====================
/**
* Display usage instructions
*/
if (process.argv.includes("--help") || process.argv.includes("-h")) {
console.log(`
🤖 Anthropic Claude + GBOX Cloud Integration Tool
Usage:
npx tsx index.ts [question]
Examples:
npx tsx index.ts
# Uses default question: "${DEFAULT_QUESTION}"
npx tsx index.ts "Write a Python function to sort a list"
# Uses custom question
npx tsx index.ts "Calculate prime numbers"
# Works with any natural language question
Options:
--help, -h Show this help message
`);
process.exit(0);
}
// Launch the application
main();
import os
import sys
from anthropic import Anthropic
from gbox_sdk import GboxSDK
from dotenv import load_dotenv
from typing import Dict, List, Any
# Load environment variables from .env file
load_dotenv()
# ==================== Initialize Clients ====================
gbox_sdk = GboxSDK(api_key=os.getenv("GBOX_API_KEY"))
anthropic_client = Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))
# ==================== Configuration Constants ====================
DEFAULT_QUESTION = "Please calculate the first 20 terms of the Fibonacci sequence and create a simple chart to visualize the growth trend"
# ==================== Utility Functions ====================
def get_user_question():
"""Get user question from command line arguments or use default"""
args = sys.argv[1:]
if args:
user_question = " ".join(args).strip()
if user_question:
print(f"📝 Using user question: \"{user_question}\"")
return user_question
print(f"📝 Using default question: \"{DEFAULT_QUESTION}\"")
return DEFAULT_QUESTION
def create_initial_messages(question: str) -> List[Dict[str, Any]]:
"""Create initial conversation messages"""
return [{"role": "user", "content": question}]
def create_tools() -> List[Dict[str, Any]]:
"""Define available functions for function calling"""
return [
{
"name": "execute_python",
"description": "Execute Python code in a Linux environment and return results from stdout/stderr streams",
"input_schema": {
"type": "object",
"properties": {
"code": {
"type": "string",
"description": "The Python code to execute. Results will be captured from standard output and standard error streams."
}
},
"required": ["code"]
}
}
]
# ==================== Core Execution Functions ====================
def execute_python_code(code: str) -> Dict[str, Any]:
"""Execute Python code using GBOX"""
box = gbox_sdk.create(type="linux")
try:
print("📝 Executing Python code:")
print(code)
print("─" * 50)
execution = box.run_code(code)
result = execution.stdout or execution.stderr or "No output"
print("✅ Execution result:")
print(result)
print("─" * 50)
return {"success": True, "result": result}
except Exception as error:
error_message = f"Error: {error}"
print(f"❌ Execution failed: {error_message}")
return {"success": False, "result": error_message}
finally:
box.terminate()
def process_tool_use(tool_use_blocks: List[Dict[str, Any]], messages: List[Dict[str, Any]]):
"""Process function calls from Anthropic response"""
for tool_use in tool_use_blocks:
if tool_use.name == "execute_python":
try:
code = tool_use.input["code"]
execution_result = execute_python_code(code)
# Add function result to conversation
messages.append({
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": tool_use.id,
"content": execution_result["result"]
}
]
})
except Exception as parse_error:
print(f"❌ Failed to parse function arguments: {parse_error}")
messages.append({
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": tool_use.id,
"content": f"Error parsing arguments: {parse_error}"
}
]
})
def generate_message(messages: List[Dict[str, Any]], tools: List[Dict[str, Any]] = None):
"""Generate Anthropic message"""
params = {
"model": "claude-3-7-sonnet-20250219",
"max_tokens": 4000,
"messages": messages
}
if tools:
params["tools"] = tools
return anthropic_client.messages.create(**params)
# ==================== Main Execution Flow ====================
def main():
"""Main function - orchestrates the entire execution flow"""
try:
print("🚀 Starting Anthropic + GBOX integration")
print("═" * 50)
user_question = get_user_question()
messages = create_initial_messages(user_question)
tools = create_tools()
# Get initial response from Anthropic
print("💬 Getting initial response from Anthropic...")
initial_response = generate_message(messages, tools)
# Add assistant message to conversation
messages.append({
"role": "assistant",
"content": initial_response.content
})
# Check if there are function call blocks
tool_use_blocks = [
block for block in initial_response.content
if block.type == "tool_use"
]
if tool_use_blocks:
print(f"🔧 Processing {len(tool_use_blocks)} function call(s)...")
process_tool_use(tool_use_blocks, messages)
# Generate final response after function execution
print("💬 Getting final response from Anthropic...")
final_response = generate_message(messages)
print("🎉 Final response:")
print("═" * 50)
for content in final_response.content:
if content.type == "text":
print(content.text)
else:
print("🎉 Response (no functions called):")
print("═" * 50)
for content in initial_response.content:
if content.type == "text":
print(content.text)
except Exception as error:
print(f"💥 Application error: {error}")
sys.exit(1)
# ==================== Help Information ====================
if "--help" in sys.argv or "-h" in sys.argv:
print(f"""
🤖 Anthropic Claude + GBOX Cloud Integration Tool
Usage:
python index.py [question]
Examples:
python index.py
# Uses default question: "{DEFAULT_QUESTION}"
python index.py "Write a Python function to sort a list"
# Uses custom question
python index.py "Calculate prime numbers"
# Works with any natural language question
Options:
--help, -h Show this help message
""")
sys.exit(0)
# Launch the application
if __name__ == "__main__":
main()
Step 2: Run the Code
Execute the following commands to run the code:# Use default question
npx tsx index.ts
# Use custom question
npx tsx index.ts "your question here"
# Use default question
python index.py
# Use custom question
python index.py "your question here"