Skip to content

Commit f825f58

Browse files
committed
Add anthropic tool use example
1 parent 147ab0c commit f825f58

File tree

1 file changed

+118
-0
lines changed

1 file changed

+118
-0
lines changed

examples/anthropic_tool_use.py

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
from __future__ import annotations
2+
3+
from gitpod import Gitpod
4+
import gitpod.lib as util
5+
from anthropic import Anthropic
6+
from anthropic.types import ToolParam, MessageParam
7+
8+
gpclient = Gitpod()
9+
llmclient = Anthropic()
10+
11+
user_message: MessageParam = {
12+
"role": "user",
13+
"content": "What is the test coverage for this repository: https://github.com/gitpod-io/gitpod-sdk-go",
14+
}
15+
tools: list[ToolParam] = [
16+
{
17+
"name": "create_environment",
18+
"description": "Create a new environment for a given context URL. This will create a new environment and return the ID of the environment.",
19+
"input_schema": {
20+
"type": "object",
21+
"properties": {"context_url": {"type": "string"}},
22+
},
23+
},
24+
{
25+
"name": "execute_command",
26+
"description": "Execute a command in a given environment ID. This will execute the command in the given environment and return the output of the command.",
27+
"input_schema": {
28+
"type": "object",
29+
"properties": {"environment_id": {"type": "string"}, "command": {"type": "string"}},
30+
},
31+
},
32+
]
33+
34+
def create_environment(args: dict[str, str]) -> str:
35+
env_class = util.find_most_used_environment_class(gpclient)
36+
if not env_class:
37+
raise Exception("No environment class found. Please create one first.")
38+
environment_id = gpclient.environments.create(
39+
spec={
40+
"desired_phase": "ENVIRONMENT_PHASE_RUNNING",
41+
"content": {
42+
"initializer": {"specs": [{"contextUrl": {"url": args["context_url"]}}]},
43+
},
44+
"machine": {"class": env_class.id},
45+
}
46+
).environment.id
47+
print(f"\nCreated environment: {environment_id} - waiting for it to be ready...")
48+
util.wait_for_environment_ready(gpclient, environment_id)
49+
print(f"\nEnvironment is ready: {environment_id}")
50+
return environment_id
51+
52+
async def execute_command(args: dict[str, str]) -> str:
53+
lines_iter = util.run_command(gpclient, args["environment_id"], args["command"])
54+
lines = []
55+
async for line in lines_iter:
56+
lines.append(line)
57+
return "\n".join(lines)
58+
59+
async def main():
60+
messages = [user_message]
61+
while True:
62+
message = llmclient.messages.create(
63+
model="claude-3-5-sonnet-latest",
64+
max_tokens=1024,
65+
messages=messages,
66+
tools=tools,
67+
)
68+
print(f"\nResponse: {message.model_dump_json(indent=2)}")
69+
70+
if message.stop_reason != "tool_use":
71+
print(f"\nFinal response reached! {message.model_dump_json(indent=2)}")
72+
break
73+
74+
messages.extend([
75+
{"role": message.role, "content": message.content}
76+
])
77+
78+
# Handle all tool calls in this response
79+
for tool in (c for c in message.content if c.type == "tool_use"):
80+
try:
81+
if tool.name == "create_environment":
82+
environment_id = create_environment(tool.input)
83+
messages.append({
84+
"role": "user",
85+
"content": [{
86+
"type": "tool_result",
87+
"tool_use_id": tool.id,
88+
"content": [{"type": "text", "text": f"The environment ID is {environment_id}"}],
89+
}],
90+
})
91+
elif tool.name == "execute_command":
92+
output = await execute_command(tool.input)
93+
messages.append({
94+
"role": "user",
95+
"content": [{
96+
"type": "tool_result",
97+
"tool_use_id": tool.id,
98+
"content": [{"type": "text", "text": output}],
99+
}],
100+
})
101+
else:
102+
raise Exception(f"Unknown tool: {tool.name}")
103+
except Exception as e:
104+
messages.append({
105+
"role": "user",
106+
"content": [{
107+
"type": "tool_result",
108+
"tool_use_id": tool.id,
109+
"is_error": True,
110+
"content": [{"type": "text", "text": f"Error: {e}"}],
111+
}],
112+
})
113+
114+
print("\nFinal response reached!")
115+
116+
if __name__ == "__main__":
117+
import asyncio
118+
asyncio.run(main())

0 commit comments

Comments
 (0)