Created
January 13, 2026 16:19
-
-
Save dabit3/e956f6b1efbe05ede7a6c156ff89f25f to your computer and use it in GitHub Desktop.
Full example of programmatic tool calling
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import Anthropic from "@anthropic-ai/sdk"; | |
| import { Pool } from "pg"; | |
| const anthropic = new Anthropic(); | |
| // dn connection - Claude never sees this | |
| const db = new Pool({ | |
| host: "your-database-host.com", | |
| port: 5432, | |
| database: "sales_db", | |
| user: "your_username", | |
| password: "your_secret_password", | |
| }); | |
| const tools = [ | |
| { | |
| type: "code_execution_20250825" as const, | |
| name: "code_execution", | |
| }, | |
| { | |
| name: "query_database", | |
| description: | |
| "Execute a SQL query against the sales database. Returns a list of rows as JSON objects with fields: region (string), revenue (number), quarter (string).", | |
| input_schema: { | |
| type: "object" as const, | |
| properties: { | |
| sql: { | |
| type: "string", | |
| description: "SQL query to execute", | |
| }, | |
| }, | |
| required: ["sql"], | |
| }, | |
| allowed_callers: ["code_execution_20250825" as const], | |
| }, | |
| ]; | |
| async function executeQuery(sql: string): Promise<string> { | |
| try { | |
| const result = await db.query(sql); | |
| return JSON.stringify(result.rows); | |
| } catch (error) { | |
| return JSON.stringify({ error: error.message }); | |
| } | |
| } | |
| async function chat(userMessage: string) { | |
| let messages: Anthropic.MessageParam[] = [ | |
| { role: "user", content: userMessage }, | |
| ]; | |
| let containerId: string | undefined; | |
| while (true) { | |
| // ════════════════════════════════════════════════════════════════ | |
| // API CALL - where Claude's Python code runs (or resumes) | |
| // ════════════════════════════════════════════════════════════════ | |
| const response = await anthropic.beta.messages.create({ | |
| model: "claude-sonnet-4-5", | |
| betas: ["advanced-tool-use-2025-11-20"], | |
| max_tokens: 4096, | |
| messages, | |
| tools, | |
| ...(containerId && { container: containerId }), | |
| }); | |
| // ════════════════════════════════════════════════════════════════ | |
| // At this point, Claude's code is either PAUSED or FINISHED | |
| // ════════════════════════════════════════════════════════════════ | |
| if (response.container?.id) { | |
| containerId = response.container.id; | |
| } | |
| // Code FINISHED - Python script completed, Claude gives final answer | |
| if (response.stop_reason === "end_turn") { | |
| const textBlock = response.content.find((block) => block.type === "text"); | |
| return textBlock?.type === "text" ? textBlock.text : "No response"; | |
| } | |
| // Code PAUSED - waiting at an `await query_database(...)` call | |
| if (response.stop_reason === "tool_use") { | |
| messages.push({ role: "assistant", content: response.content }); | |
| const toolResults: Anthropic.ToolResultBlockParam[] = []; | |
| for (const block of response.content) { | |
| if (block.type === "tool_use" && block.name === "query_database") { | |
| // Run query on YOUR infrastructure | |
| console.log(`Executing query: ${block.input.sql}`); | |
| const result = await executeQuery(block.input.sql as string); | |
| // This becomes the return value of the paused await | |
| toolResults.push({ | |
| type: "tool_result", | |
| tool_use_id: block.id, | |
| content: result, | |
| }); | |
| } | |
| } | |
| // Add results to messages - next API call will resume the code | |
| if (toolResults.length > 0) { | |
| messages.push({ role: "user", content: toolResults }); | |
| } | |
| } | |
| } | |
| } | |
| chat( | |
| "Query sales data for West, East, and Central regions, then tell me which had the highest revenue" | |
| ).then(console.log); | |
| ``` |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment