A small, educational coding agent that uses an OpenAI-compatible chat-completions API through OpenRouter. Given a command-line prompt, the agent can inspect, modify, and run code in a deliberately restricted workspace.
The repository also includes a calculator project under calculator/. It is both
an example application and the only directory exposed to the agent's tools by
default.
main.pyloadsOPENROUTER_API_KEY, sends the system and user prompts to OpenRouter, and advertises the available function tools.- The selected model can respond normally or request one or more tool calls.
call_function.pyvalidates the tool name, injects./calculatoras the working directory, invokes the matching local Python function, and appends its result to the conversation.- The loop repeats for up to 20 model responses. A response without tool calls is printed as the final answer.
The agent currently requests the openrouter/free model with temperature 0.
| Tool | Purpose | Important behavior |
|---|---|---|
get_files_info |
List a directory | Reports each entry's size and whether it is a directory. |
get_file_content |
Read a text file | Returns at most 10,000 characters and marks truncated results. |
write_file |
Create or overwrite a text file | Creates missing parent directories. |
run_python_file |
Execute a Python file | Accepts optional arguments and has a 30-second timeout. |
All paths supplied by the model are resolved beneath ./calculator. Each tool
rejects paths that escape that directory, including absolute paths outside it and
.. traversal. This boundary limits accidental access, but it is not a complete
security sandbox: Python code executed inside the calculator project still runs
as a normal local process with the permissions of the current user. Review the
code and run the agent only in an environment you trust.
- Python 3.12 or newer
- An OpenRouter API key
uv(recommended), or another Python environment manager capable of installing the dependencies inpyproject.toml
Runtime dependencies are pinned in pyproject.toml and uv.lock:
openai==2.44.0for the OpenAI-compatible clientpython-dotenv==1.2.2for loading local environment variables
Clone the repository and install the locked dependencies:
git clone <repository-url>
cd Coding-AI-Agent
uv syncCreate a .env file in the repository root (or export the variable in your
shell):
OPENROUTER_API_KEY=your_openrouter_api_keyDo not commit real API keys.
Pass the request as one quoted positional argument:
uv run python main.py "Inspect the calculator and explain how it evaluates expressions"Ask the agent to edit or test the example project:
uv run python main.py "Add exponentiation support to the calculator and run its tests"Use --verbose to print every invoked function (including its arguments) and
token usage for each model response:
uv run python main.py --verbose "List the files and summarize the calculator project"If OPENROUTER_API_KEY is missing, the program exits with a RuntimeError. If no
final answer is produced within 20 model responses, it exits with status 1.
The bundled calculator evaluates space-separated infix expressions using
+, -, *, and /, with standard multiplication/division precedence. Its CLI
prints JSON containing the original expression and result:
uv run python calculator/main.py "2 * 3 - 8 / 2 + 5"{
"expression": "2 * 3 - 8 / 2 + 5",
"result": 7
}Operators and operands must be separated by spaces; for example, use 3 + 5
rather than 3+5. Parentheses and unary operators are not implemented.
Run the calculator's unit tests from its own directory so its pkg imports
resolve correctly:
cd calculator
python -m unittest tests.pyThe root-level test_*.py files are lightweight manual smoke scripts for the four
tools:
python test_get_files_info.py
python test_get_file_content.py
python test_run_python_file.py
python test_write_file.pyNote:
test_write_file.pyis destructive: it overwritescalculator/lorem.txtandcalculator/pkg/morelorem.txt. Restore those fixtures with Git after running it if you need their previous contents.
.
├── main.py # CLI and model/tool-call loop
├── prompts.py # System prompt presented to the model
├── call_function.py # Tool registry and dispatcher
├── functions/
│ ├── get_files_info.py # Directory listing tool and JSON schema
│ ├── get_file_content.py # Bounded file-reading tool and schema
│ ├── write_file.py # File-writing tool and schema
│ └── run_python_file.py # Python execution tool and schema
├── calculator/ # Agent workspace and example project
│ ├── main.py
│ ├── tests.py
│ └── pkg/
├── test_*.py # Manual tool smoke scripts
├── pyproject.toml
└── uv.lock
To add a tool:
- Implement a function in
functions/that acceptsworking_directoryplus its tool-specific arguments and returns a string. - Define its OpenAI function-tool JSON schema in the same module.
- Import the function and schema in
call_function.py. - Add the schema to
available_functionsand the callable tofunction_map. - Update
prompts.pywhen the model needs additional guidance about the new capability.
Keep the injected working-directory boundary in place for every filesystem or execution tool, and add success, invalid-input, and path-traversal checks when introducing new behavior.