Follow Discord
Sweep 22 Oct 2026 · 04:32Z Build v2.1.308 527 read Stable v2.1.308 Latest v2.1.308 Next v2.1.308 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One change · api

build-a-tool-using-agent changedagents-and-tools/tool-use/build-a-tool-using-agent

Nearest release: v2.1.304, published 6 hours before this site recorded the change. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.

Recorded here
Lines+112added
Lines−98removed
From line 146 where the diff opens
First seen 14 Aug 2026 this site's first read of the page
Recorded edits12to this page, all time

The whole hunk

from line 146, old and new numbered
/
lines
from line 146
146146 const tools: Anthropic.Tool[] = [
147147 {
148148 name: "create_calendar_event",
149 description:
150 "Create a calendar event with attendees and optional recurrence.",
149 description: "Create a calendar event with attendees and optional recurrence.",
151150 input_schema: {
152151 type: "object",
153152 properties: {
from line 155
156155 end: { type: "string", format: "date-time" },
157156 attendees: {
158157 type: "array",
159 items: { type: "string", format: "email" },
158 items: { type: "string", format: "email" }
160159 },
161160 recurrence: {
162161 type: "object",
163162 properties: {
164163 frequency: { enum: ["daily", "weekly", "monthly"] },
165 count: { type: "integer", minimum: 1 },
166 },
167 },
164 count: { type: "integer", minimum: 1 }
165 }
166 }
168167 },
169 required: ["title", "start", "end"],
170 },
171 },
168 required: ["title", "start", "end"]
169 }
170 }
172171 ];
173172 
174173 // Send the user's request along with the tool definition. Claude decides
from line 181
182181 {
183182 role: "user",
184183 content:
185 "Schedule a 30-minute sync with [email protected] and [email protected] on Monday, March 30, 2026 at 10am.",
186 },
187 ],
184 "Schedule a 30-minute sync with [email protected] and [email protected] on Monday, March 30, 2026 at 10am."
185 }
186 ]
188187 });
189188 
190189 // When Claude calls a tool, the response has stop_reason "tool_use"
from line 192
193192 
194193 // Find the tool_use block. A response may contain text blocks before the
195194 // tool_use block, so scan the content array rather than assuming position.
196 const toolUse = response.content.find(
197 (block): block is Anthropic.ToolUseBlock => block.type === "tool_use",
198 )!;
195 const toolUse = response.content.find((block) => block.type === "tool_use")!;
199196 console.log(`Tool: ${toolUse.name}`);
200197 console.log(`Input: ${JSON.stringify(toolUse.input)}`);
201198 
from line 212
215212 {
216213 role: "user",
217214 content:
218 "Schedule a 30-minute sync with [email protected] and [email protected] on Monday, March 30, 2026 at 10am.",
215 "Schedule a 30-minute sync with [email protected] and [email protected] on Monday, March 30, 2026 at 10am."
219216 },
220217 { role: "assistant", content: response.content },
221218 {
from line 221
224221 {
225222 type: "tool_result",
226223 tool_use_id: toolUse.id,
227 content: JSON.stringify(result),
228 },
229 ],
230 },
231 ],
224 content: JSON.stringify(result)
225 }
226 ]
227 }
228 ]
232229 });
233230 
234231 // With the tool result in hand, Claude produces a final natural-language
from line 890
893890 
894891 def run_tool(name, tool_input):
895892 if name == "create_calendar_event":
896 return {"event_id": "evt_123", "status": "created", "title": tool_input["title"]}
893 return {
894 "event_id": "evt_123",
895 "status": "created",
896 "title": tool_input["title"],
897 }
897898 return {"error": f"Unknown tool: {name}"}
898899 
899900 
from line 956
955956 const tools: Anthropic.Tool[] = [
956957 {
957958 name: "create_calendar_event",
958 description:
959 "Create a calendar event with attendees and optional recurrence.",
959 description: "Create a calendar event with attendees and optional recurrence.",
960960 input_schema: {
961961 type: "object",
962962 properties: {
from line 965
965965 end: { type: "string", format: "date-time" },
966966 attendees: {
967967 type: "array",
968 items: { type: "string", format: "email" },
968 items: { type: "string", format: "email" }
969969 },
970970 recurrence: {
971971 type: "object",
972972 properties: {
973973 frequency: { enum: ["daily", "weekly", "monthly"] },
974 count: { type: "integer", minimum: 1 },
975 },
976 },
974 count: { type: "integer", minimum: 1 }
975 }
976 }
977977 },
978 required: ["title", "start", "end"],
979 },
980 },
978 required: ["title", "start", "end"]
979 }
980 }
981981 ];
982982 
983983 function runTool(name: string, input: Record<string, unknown>) {
from line 992
992992 {
993993 role: "user",
994994 content:
995 "Schedule a weekly team standup every Monday at 9am for the next 4 weeks, starting Monday, March 30, 2026. Invite the whole team: [email protected], [email protected], [email protected].",
996 },
995 "Schedule a weekly team standup every Monday at 9am for the next 4 weeks, starting Monday, March 30, 2026. Invite the whole team: [email protected], [email protected], [email protected]."
996 }
997997 ];
998998 
999999 let response = await client.messages.create({
from line 1001
10011001 max_tokens: 1024,
10021002 tools,
10031003 tool_choice: { type: "auto", disable_parallel_tool_use: true },
1004 messages,
1004 messages
10051005 });
10061006 
10071007 // Loop until Claude stops asking for tools. Each iteration runs the requested
10081008 // tool, appends the result to history, and asks Claude to continue.
10091009 while (response.stop_reason === "tool_use") {
1010 const toolUse = response.content.find(
1011 (block): block is Anthropic.ToolUseBlock => block.type === "tool_use",
1012 )!;
1010 const toolUse = response.content.find((block) => block.type === "tool_use")!;
10131011 const result = runTool(toolUse.name, toolUse.input as Record<string, unknown>);
10141012 
10151013 messages.push({ role: "assistant", content: response.content });
from line 1017
10191017 {
10201018 type: "tool_result",
10211019 tool_use_id: toolUse.id,
1022 content: JSON.stringify(result),
1023 },
1024 ],
1020 content: JSON.stringify(result)
1021 }
1022 ]
10251023 });
10261024 
10271025 response = await client.messages.create({
from line 1027
10291027 max_tokens: 1024,
10301028 tools,
10311029 tool_choice: { type: "auto", disable_parallel_tool_use: true },
1032 messages,
1030 messages
10331031 });
10341032 }
10351033 
from line 1672
16741672 
16751673 def run_tool(name, tool_input):
16761674 if name == "create_calendar_event":
1677 return {"event_id": "evt_123", "status": "created", "title": tool_input["title"]}
1675 return {
1676 "event_id": "evt_123",
1677 "status": "created",
1678 "title": tool_input["title"],
1679 }
16781680 if name == "list_calendar_events":
1679 return {"events": [{"title": "Existing meeting", "start": "14:00", "end": "15:00"}]}
1681 return {
1682 "events": [{"title": "Existing meeting", "start": "14:00", "end": "15:00"}]
1683 }
16801684 return {"error": f"Unknown tool: {name}"}
16811685 
16821686 
from line 1737
17331737 const tools: Anthropic.Tool[] = [
17341738 {
17351739 name: "create_calendar_event",
1736 description:
1737 "Create a calendar event with attendees and optional recurrence.",
1740 description: "Create a calendar event with attendees and optional recurrence.",
17381741 input_schema: {
17391742 type: "object",
17401743 properties: {
from line 1746
17431746 end: { type: "string", format: "date-time" },
17441747 attendees: {
17451748 type: "array",
1746 items: { type: "string", format: "email" },
1749 items: { type: "string", format: "email" }
17471750 },
17481751 recurrence: {
17491752 type: "object",
17501753 properties: {
17511754 frequency: { enum: ["daily", "weekly", "monthly"] },
1752 count: { type: "integer", minimum: 1 },
1753 },
1754 },
1755 count: { type: "integer", minimum: 1 }
1756 }
1757 }
17551758 },
1756 required: ["title", "start", "end"],
1757 },
1759 required: ["title", "start", "end"]
1760 }
17581761 },
17591762 {
17601763 name: "list_calendar_events",
from line 1765
17621765 input_schema: {
17631766 type: "object",
17641767 properties: {
1765 date: { type: "string", format: "date" },
1768 date: { type: "string", format: "date" }
17661769 },
1767 required: ["date"],
1768 },
1769 },
1770 required: ["date"]
1771 }
1772 }
17701773 ];
17711774 
17721775 function runTool(name: string, input: Record<string, unknown>) {
from line 1778
17751778 }
17761779 if (name === "list_calendar_events") {
17771780 return {
1778 events: [{ title: "Existing meeting", start: "14:00", end: "15:00" }],
1781 events: [{ title: "Existing meeting", start: "14:00", end: "15:00" }]
17791782 };
17801783 }
17811784 return { error: `Unknown tool: ${name}` };
from line 1788
17851788 {
17861789 role: "user",
17871790 content:
1788 "Check what I have on Monday, March 30, 2026, then schedule a one-hour planning session that day that avoids any conflicts.",
1789 },
1791 "Check what I have on Monday, March 30, 2026, then schedule a one-hour planning session that day that avoids any conflicts."
1792 }
17901793 ];
17911794 
17921795 let response = await client.messages.create({
from line 1796
17931796 model: "claude-opus-5-5",
17941797 max_tokens: 1024,
17951798 tools,
1796 messages,
1799 messages
17971800 });
17981801 
17991802 while (response.stop_reason === "tool_use") {
from line 1809
18061809 toolResults.push({
18071810 type: "tool_result",
18081811 tool_use_id: block.id,
1809 content: JSON.stringify(result),
1812 content: JSON.stringify(result)
18101813 });
18111814 }
18121815 }
from line 1821
18181821 model: "claude-opus-5-5",
18191822 max_tokens: 1024,
18201823 tools,
1821 messages,
1824 messages
18221825 });
18231826 }
18241827 
from line 2491
24882491 if name == "create_calendar_event":
24892492 if "attendees" in tool_input and len(tool_input["attendees"]) > 10:
24902493 raise ValueError("Too many attendees (max 10)")
2491 return {"event_id": "evt_123", "status": "created", "title": tool_input["title"]}
2494 return {
2495 "event_id": "evt_123",
2496 "status": "created",
2497 "title": tool_input["title"],
2498 }
24922499 if name == "list_calendar_events":
2493 return {"events": [{"title": "Existing meeting", "start": "14:00", "end": "15:00"}]}
2500 return {
2501 "events": [{"title": "Existing meeting", "start": "14:00", "end": "15:00"}]
2502 }
24942503 raise ValueError(f"Unknown tool: {name}")
24952504 
24962505 
from line 2506
24972506 messages = [
24982507 {
24992508 "role": "user",
2500 "content": "Schedule a one-hour all-hands on Monday, March 30, 2026 at 10am with everyone: " + ", ".join(f"user{i}@example.com" for i in range(15)),
2509 "content": "Schedule a one-hour all-hands on Monday, March 30, 2026 at 10am with everyone: "
2510 + ", ".join(f"user{i}@example.com" for i in range(15)),
25012511 }
25022512 ]
25032513 
from line 2525
25152525 try:
25162526 result = run_tool(block.name, block.input)
25172527 tool_results.append(
2518 {"type": "tool_result", "tool_use_id": block.id, "content": json.dumps(result)}
2528 {
2529 "type": "tool_result",
2530 "tool_use_id": block.id,
2531 "content": json.dumps(result),
2532 }
25192533 )
25202534 except Exception as exc:
25212535 # Signal failure so Claude can retry or ask for clarification.
from line 2566
25522566 const tools: Anthropic.Tool[] = [
25532567 {
25542568 name: "create_calendar_event",
2555 description:
2556 "Create a calendar event with attendees and optional recurrence.",
2569 description: "Create a calendar event with attendees and optional recurrence.",
25572570 input_schema: {
25582571 type: "object",
25592572 properties: {
from line 2575
25622575 end: { type: "string", format: "date-time" },
25632576 attendees: {
25642577 type: "array",
2565 items: { type: "string", format: "email" },
2578 items: { type: "string", format: "email" }
25662579 },
25672580 recurrence: {
25682581 type: "object",
25692582 properties: {
25702583 frequency: { enum: ["daily", "weekly", "monthly"] },
2571 count: { type: "integer", minimum: 1 },
2572 },
2573 },
2584 count: { type: "integer", minimum: 1 }
2585 }
2586 }
25742587 },
2575 required: ["title", "start", "end"],
2576 },
2588 required: ["title", "start", "end"]
2589 }
25772590 },
25782591 {
25792592 name: "list_calendar_events",
from line 2594
25812594 input_schema: {
25822595 type: "object",
25832596 properties: {
2584 date: { type: "string", format: "date" },
2597 date: { type: "string", format: "date" }
25852598 },
2586 required: ["date"],
2587 },
2588 },
2599 required: ["date"]
2600 }
2601 }
25892602 ];
25902603 
25912604 function runTool(name: string, input: Record<string, unknown>) {
from line 2611
25982611 }
25992612 if (name === "list_calendar_events") {
26002613 return {
2601 events: [{ title: "Existing meeting", start: "14:00", end: "15:00" }],
2614 events: [{ title: "Existing meeting", start: "14:00", end: "15:00" }]
26022615 };
26032616 }
26042617 throw new Error(`Unknown tool: ${name}`);
26052618 }
26062619 
2607 const emails = Array.from({ length: 15 }, (_, i) => `user${i}@example.com`);
2620 const emails = Array.from({ length: 15 }, (_, i) => `user${i}@example.com`).join(", ");
26082621 const messages: Anthropic.MessageParam[] = [
26092622 {
26102623 role: "user",
2611 content: `Schedule a one-hour all-hands on Monday, March 30, 2026 at 10am with everyone: ${emails.join(", ")}`,
2612 },
2624 content: `Schedule a one-hour all-hands on Monday, March 30, 2026 at 10am with everyone: ${emails}`
2625 }
26132626 ];
26142627 
26152628 let response = await client.messages.create({
from line 2629
26162629 model: "claude-opus-5-5",
26172630 max_tokens: 1024,
26182631 tools,
2619 messages,
2632 messages
26202633 });
26212634 
26222635 while (response.stop_reason === "tool_use") {
from line 2641
26282641 toolResults.push({
26292642 type: "tool_result",
26302643 tool_use_id: block.id,
2631 content: JSON.stringify(result),
2644 content: JSON.stringify(result)
26322645 });
26332646 } catch (err) {
26342647 // Signal failure so Claude can retry or ask for clarification.
from line 2649
26362649 type: "tool_result",
26372650 tool_use_id: block.id,
26382651 content: String(err),
2639 is_error: true,
2652 is_error: true
26402653 });
26412654 }
26422655 }
from line 2662
26492662 model: "claude-opus-5-5",
26502663 max_tokens: 1024,
26512664 tools,
2652 messages,
2665 messages
26532666 });
26542667 }
26552668 
from line 3387
33743387 Args:
33753388 date: Date in YYYY-MM-DD format.
33763389 """
3377 return json.dumps({"events": [{"title": "Existing meeting", "start": "14:00", "end": "15:00"}]})
3390 return json.dumps(
3391 {"events": [{"title": "Existing meeting", "start": "14:00", "end": "15:00"}]}
3392 )
33783393 
33793394 
33803395 final_message = client.beta.messages.tool_runner(
from line 3420
34053420 
34063421 const createCalendarEvent = betaZodTool({
34073422 name: "create_calendar_event",
3408 description:
3409 "Create a calendar event with attendees and optional recurrence.",
3423 description: "Create a calendar event with attendees and optional recurrence.",
34103424 inputSchema: z.object({
34113425 title: z.string(),
34123426 start: z.string().datetime(),
from line 3429
34153429 recurrence: z
34163430 .object({
34173431 frequency: z.enum(["daily", "weekly", "monthly"]),
3418 count: z.number().int().min(1),
3432 count: z.number().int().min(1)
34193433 })
3420 .optional(),
3434 .optional()
34213435 }),
34223436 run: async (input) => {
34233437 if (input.attendees && input.attendees.length > 10) {
from line 3440
34263440 return JSON.stringify({
34273441 event_id: "evt_123",
34283442 status: "created",
3429 title: input.title,
3443 title: input.title
34303444 });
3431 },
3445 }
34323446 });
34333447 
34343448 const listCalendarEvents = betaZodTool({
from line 3449
34353449 name: "list_calendar_events",
34363450 description: "List all calendar events on a given date.",
34373451 inputSchema: z.object({
3438 date: z.string().date(),
3452 date: z.string().date()
34393453 }),
34403454 run: async () => {
34413455 return JSON.stringify({
3442 events: [{ title: "Existing meeting", start: "14:00", end: "15:00" }],
3456 events: [{ title: "Existing meeting", start: "14:00", end: "15:00" }]
34433457 });
3444 },
3458 }
34453459 });
34463460 
34473461 const finalMessage = await client.beta.messages.toolRunner({
from line 3466
34523466 {
34533467 role: "user",
34543468 content:
3455 "Check what I have on Monday, March 30, 2026, then schedule a one-hour planning session that day that avoids any conflicts.",
3456 },
3457 ],
3469 "Check what I have on Monday, March 30, 2026, then schedule a one-hour planning session that day that avoids any conflicts."
3470 }
3471 ]
34583472 });
34593473 
34603474 for (const block of finalMessage.content) {
Feedback