Skip to content

Instantly share code, notes, and snippets.

@nicognaW
Forked from leerob/agent.py
Created July 31, 2025 05:30
Show Gist options
  • Save nicognaW/d065b71a91765a83dc2389a852bb461d to your computer and use it in GitHub Desktop.
Save nicognaW/d065b71a91765a83dc2389a852bb461d to your computer and use it in GitHub Desktop.
agent.py
import os
import json
import subprocess
from anthropic import Anthropic
# Tool definitions
TOOLS = [
{
"name": "list_files",
"description": "List files and directories at a given path",
"input_schema": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Path to list (defaults to current directory)"
}
}
}
},
{
"name": "read_file",
"description": "Read the contents of a file",
"input_schema": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Path to the file to read"
}
},
"required": ["path"]
}
},
{
"name": "run_bash",
"description": "Run a bash command and return the output",
"input_schema": {
"type": "object",
"properties": {
"command": {
"type": "string",
"description": "The bash command to run"
}
},
"required": ["command"]
}
},
{
"name": "edit_file",
"description": "Edit a file by replacing old text with new text",
"input_schema": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Path to the file to edit"
},
"old_text": {
"type": "string",
"description": "Text to search for and replace"
},
"new_text": {
"type": "string",
"description": "Text to replace with"
}
},
"required": ["path", "old_text", "new_text"]
}
}
]
def execute_tool(name, arguments):
"""Execute a tool and return the result"""
if name == "list_files":
path = arguments.get("path", ".")
files = os.listdir(path)
return json.dumps(files, indent=2)
elif name == "read_file":
with open(arguments["path"], 'r') as f:
return f.read()
elif name == "run_bash":
result = subprocess.run(
arguments["command"],
shell=True,
capture_output=True,
text=True
)
return f"stdout:\n{result.stdout}\nstderr:\n{result.stderr}"
elif name == "edit_file":
path = arguments["path"]
old_text = arguments["old_text"]
new_text = arguments["new_text"]
# Create new file if old_text is empty
if old_text == "":
with open(path, 'w') as f:
f.write(new_text)
return "File created"
# Read existing file
with open(path, 'r') as f:
content = f.read()
# Replace text
new_content = content.replace(old_text, new_text)
# Write back
with open(path, 'w') as f:
f.write(new_content)
return "File edited"
def run_agent(prompt):
"""Run the agent with a given prompt"""
client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
messages = [{"role": "user", "content": prompt}]
print(f"🤖 Working on: {prompt}\n")
while True:
# Call the AI with tools
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
messages=messages,
tools=TOOLS
)
# Add AI response to conversation
messages.append({
"role": "assistant",
"content": response.content
})
# Check if we have tool calls
tool_calls = [c for c in response.content if c.type == "tool_use"]
if tool_calls:
# Execute each tool
tool_results = []
for call in tool_calls:
print(f"🔧 Using tool: {call.name}")
result = execute_tool(call.name, call.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": call.id,
"content": result
})
# Add results to conversation
messages.append({
"role": "user",
"content": tool_results
})
else:
# No more tools, we're done
text_blocks = [c for c in response.content if c.type == "text"]
if text_blocks:
print(f"\n✅ Done: {text_blocks[0].text}")
break
# Interactive CLI
if __name__ == "__main__":
while True:
try:
prompt = input("\n💬 What would you like me to do? (or 'quit' to exit)\n> ")
if prompt.lower() == 'quit':
break
run_agent(prompt)
except KeyboardInterrupt:
print("\n👋 Goodbye!")
break
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment