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.

Revisions

  1. @leerob leerob renamed this gist Jul 30, 2025. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  2. @leerob leerob created this gist Jul 30, 2025.
    176 changes: 176 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,176 @@
    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