|
| 1 | +# Multi-Language Code-Editing Agent |
| 2 | + |
| 3 | +This project is a small, fully functional **code-editing agent** implemented in **Go, Python, JavaScript (Node), and Java**, inspired by the Amp blog post “How to Build an Agent”. Each implementation connects to Anthropic’s Claude models and exposes tools to **read, list, and edit files on your local filesystem**, so you can collaborate with Claude directly on your codebase from the terminal. |
| 4 | + |
| 5 | +### What the Agent Does (Common Across Languages) |
| 6 | + |
| 7 | +- **Interactive chat loop**: |
| 8 | + - Maintains a full conversation history with Claude. |
| 9 | + - Lets you talk to Claude in your terminal (question/answer style). |
| 10 | +- **Tool-enabled “agent” behavior**: |
| 11 | + - Claude can decide when to call tools to inspect or modify your files. |
| 12 | + - Tool calls are executed by your local code, and results are fed back so Claude can continue reasoning. |
| 13 | +- **Supported tools**: |
| 14 | + - **`read_file`**: Read the contents of a given file path. |
| 15 | + - **`list_files`**: Recursively list files and directories from a given starting path. |
| 16 | + - **`edit_file`**: Replace text inside a file or create a new file (including parent directories) when appropriate. |
| 17 | + |
| 18 | +In practice, this lets Claude: |
| 19 | + |
| 20 | +- Explore your project (`list_files`) |
| 21 | +- Open specific files to inspect code (`read_file`) |
| 22 | +- Apply modifications or create new files (`edit_file`) |
| 23 | + |
| 24 | +All edits happen on your local machine; the agent just orchestrates between your terminal, your filesystem, and the Anthropic API. |
| 25 | + |
| 26 | +### Conceptual Flow (Pseudocode) |
| 27 | + |
| 28 | +Regardless of language, the core loop looks like this: |
| 29 | + |
| 30 | +```text |
| 31 | +tools = [read_file, list_files, edit_file] |
| 32 | +conversation = [] |
| 33 | +
|
| 34 | +print("Chat with Claude...") |
| 35 | +
|
| 36 | +loop: |
| 37 | + if expecting_user_input: |
| 38 | + user_text = read_line_from_stdin() |
| 39 | + conversation.append({ role: "user", content: [text_block(user_text)] }) |
| 40 | +
|
| 41 | + message = call_claude_api( |
| 42 | + model = "claude-3-7-sonnet-latest", |
| 43 | + messages = conversation, |
| 44 | + tools = tools_as_json_schemas |
| 45 | + ) |
| 46 | +
|
| 47 | + conversation.append({ role: "assistant", content: message.content }) |
| 48 | +
|
| 49 | + tool_results = [] |
| 50 | + for block in message.content: |
| 51 | + if block.type == "text": |
| 52 | + print("Claude:", block.text) |
| 53 | + if block.type == "tool_use": |
| 54 | + result = execute_named_tool(block.name, block.input) |
| 55 | + tool_results.append(tool_result_block(block.id, result)) |
| 56 | +
|
| 57 | + if tool_results is empty: |
| 58 | + expecting_user_input = true |
| 59 | + else: |
| 60 | + expecting_user_input = false |
| 61 | + conversation.append({ role: "user", content: tool_results }) |
| 62 | +``` |
| 63 | + |
| 64 | +### Using the Tools (What You Can Ask It To Do) |
| 65 | + |
| 66 | +Although you *can* talk to Claude like a normal chat, the interesting part is when it uses tools to work with your files. You don’t need to know the exact tool names; just describe what you want to do in natural language. |
| 67 | + |
| 68 | +Examples of useful prompts once the agent is running: |
| 69 | + |
| 70 | +- **Inspect the project** |
| 71 | + - “List all files in the current directory and any subdirectories that look interesting to edit.” |
| 72 | + - “Show me the contents of `main.go`.” |
| 73 | +- **Ask for code changes** |
| 74 | + - “Create a new file `examples/fizzbuzz.js` that prints FizzBuzz from 1 to 100.” |
| 75 | + - “Update the agent so the help text mentions the three tools: `read_file`, `list_files`, and `edit_file`.” |
| 76 | + - “Refactor the agent so the tool definitions are moved into a separate file and explain what you changed.” |
| 77 | + |
| 78 | +Under the hood, Claude will: |
| 79 | + |
| 80 | +- Call `list_files` to discover files and directories. |
| 81 | +- Call `read_file` to inspect existing code. |
| 82 | +- Call `edit_file` one or more times to patch or create files. |
| 83 | + |
| 84 | +The agent prints every tool call it executes in the terminal, so you can see exactly what’s happening. |
| 85 | + |
| 86 | +### Notes and Safety |
| 87 | + |
| 88 | +- **Edits are real**: `edit_file` will modify or create files in your working directory. Use version control (e.g., `git`) if you want easy rollback. |
| 89 | +- **Project root**: Paths are interpreted relative to where you run the process. Stay consistent and run from the project root. |
| 90 | +- **API usage**: Each turn is a real API call to Anthropic; your usage will count against your Anthropic quota/billing. |
| 91 | + |
| 92 | +### Where to Look in the Code |
| 93 | + |
| 94 | +- **Go** |
| 95 | + - `main.go`: `Agent` struct, `Run`, `runInference`, `executeTool`, and tool definitions (`read_file`, `list_files`, `edit_file`), plus JSON schema generation using `github.com/invopop/jsonschema`. |
| 96 | +- **Python** |
| 97 | + - `python_agent.py`: `Agent` class, `ToolDefinition` dataclass, and Python implementations of the same three tools. |
| 98 | +- **JavaScript / Node** |
| 99 | + - `js-agent/index.mjs`: `Agent` class, `ToolDefinition` helper, and Node implementations of the tools using `@anthropic-ai/sdk`. |
| 100 | +- **Java** |
| 101 | + - `java-agent/src/main/java/com/example/agent/JavaAgent.java`: `JavaAgent` class, `ToolDefinition` record, and tool implementations using OkHttp + Jackson against the Claude HTTP API. |
| 102 | + |
| 103 | +All implementations are commented at the level of intent and architecture to show how the loop and tools turn a plain LLM call into a simple but powerful code-editing agent. |
| 104 | + |
| 105 | +--- |
| 106 | + |
| 107 | +## Language-Specific Setup and Usage |
| 108 | + |
| 109 | +Below are per-language instructions as collapsible sections. Pick the language you care about, or mix and match. |
| 110 | + |
| 111 | +<details> |
| 112 | +<summary><strong>Go</strong></summary> |
| 113 | + |
| 114 | +- **Prerequisites**: |
| 115 | + - **Go** 1.22+. |
| 116 | + - An **Anthropic API key** in `ANTHROPIC_API_KEY`. |
| 117 | + |
| 118 | +- **One-time setup** (from the project root, e.g. `c:\Users\shrey\Desktop\codesbyshrey\Cursor`): |
| 119 | + |
| 120 | + ```powershell |
| 121 | + cd c:\Users\shrey\Desktop\codesbyshrey\Cursor |
| 122 | + [System.Environment]::SetEnvironmentVariable("ANTHROPIC_API_KEY", "your-key-here", "User") |
| 123 | + go mod tidy |
| 124 | + ``` |
| 125 | + |
| 126 | +- **Run the Go agent**: |
| 127 | + |
| 128 | + ```powershell |
| 129 | + cd c:\Users\shrey\Desktop\codesbyshrey\Cursor |
| 130 | + go run main.go |
| 131 | + ``` |
| 132 | + |
| 133 | + You should see: |
| 134 | + |
| 135 | + ```text |
| 136 | + Chat with Claude (use 'ctrl-c' to quit) |
| 137 | + You: |
| 138 | + ``` |
| 139 | + |
| 140 | + Type your messages after `You:` and press Enter to chat and let Claude edit files via tools. |
| 141 | + |
| 142 | +</details> |
| 143 | + |
| 144 | +<details> |
| 145 | +<summary><strong>Python</strong></summary> |
| 146 | + |
| 147 | +- **Prerequisites**: |
| 148 | + - **Python** 3.9+. |
| 149 | + - An **Anthropic API key** in `ANTHROPIC_API_KEY`. |
| 150 | + |
| 151 | +- **Install dependencies** (from the project root): |
| 152 | + |
| 153 | + ```powershell |
| 154 | + cd c:\Users\shrey\Desktop\codesbyshrey\Cursor |
| 155 | + python -m venv .venv |
| 156 | + .\.venv\Scripts\Activate.ps1 |
| 157 | + pip install -r requirements.txt |
| 158 | + ``` |
| 159 | + |
| 160 | +- **Set your API key** (for the current PowerShell session): |
| 161 | + |
| 162 | + ```powershell |
| 163 | + $env:ANTHROPIC_API_KEY = "your-key-here" |
| 164 | + ``` |
| 165 | + |
| 166 | +- **Run the Python agent**: |
| 167 | + |
| 168 | + ```powershell |
| 169 | + cd c:\Users\shrey\Desktop\codesbyshrey\Cursor |
| 170 | + python python_agent.py |
| 171 | + ``` |
| 172 | + |
| 173 | + The behavior matches the Go agent: terminal chat loop, and Claude uses `read_file`, `list_files`, and `edit_file` implemented in Python. |
| 174 | + |
| 175 | +</details> |
| 176 | + |
| 177 | +<details> |
| 178 | +<summary><strong>JavaScript / Node</strong></summary> |
| 179 | + |
| 180 | +- **Prerequisites**: |
| 181 | + - **Node.js** 18+. |
| 182 | + - An **Anthropic API key** in `ANTHROPIC_API_KEY`. |
| 183 | + |
| 184 | +- **Install dependencies**: |
| 185 | + |
| 186 | + ```powershell |
| 187 | + cd c:\Users\shrey\Desktop\codesbyshrey\Cursor\js-agent |
| 188 | + npm install |
| 189 | + ``` |
| 190 | + |
| 191 | +- **Set your API key**: |
| 192 | + |
| 193 | + ```powershell |
| 194 | + $env:ANTHROPIC_API_KEY = "your-key-here" |
| 195 | + ``` |
| 196 | + |
| 197 | +- **Run the Node agent**: |
| 198 | + |
| 199 | + ```powershell |
| 200 | + cd c:\Users\shrey\Desktop\codesbyshrey\Cursor\js-agent |
| 201 | + node index.mjs |
| 202 | + ``` |
| 203 | + |
| 204 | + You’ll get the same interactive chat loop, with tools wired through `@anthropic-ai/sdk`. |
| 205 | + |
| 206 | +</details> |
| 207 | + |
| 208 | +<details> |
| 209 | +<summary><strong>Java</strong></summary> |
| 210 | + |
| 211 | +- **Prerequisites**: |
| 212 | + - **Java** 17+ (JDK). |
| 213 | + - **Maven**. |
| 214 | + - An **Anthropic API key** in `ANTHROPIC_API_KEY`. |
| 215 | + |
| 216 | +- **Build the Java agent**: |
| 217 | + |
| 218 | + ```powershell |
| 219 | + cd c:\Users\shrey\Desktop\codesbyshrey\Cursor\java-agent |
| 220 | + $env:ANTHROPIC_API_KEY = "your-key-here" |
| 221 | + mvn package |
| 222 | + ``` |
| 223 | + |
| 224 | +- **Run the fat JAR**: |
| 225 | + |
| 226 | + ```powershell |
| 227 | + cd c:\Users\shrey\Desktop\codesbyshrey\Cursor\java-agent |
| 228 | + java -jar target/java-agent-1.0.0-jar-with-dependencies.jar |
| 229 | + ``` |
| 230 | + |
| 231 | + This version talks directly to the Claude HTTP API via OkHttp but uses the same conversation + tools pattern. |
| 232 | + |
| 233 | +</details> |
| 234 | + |
0 commit comments