Lightweight CLI-based AI coding assistant built with the Gemini API and a sandboxed local tool layer.
This project lets an LLM inspect and modify files inside a constrained working directory, execute Python scripts, and iterate on tasks through function-calling.
- Gemini function-calling loop with iterative tool execution
- Sandboxed filesystem access (path traversal checks enforced)
- Controlled Python execution (
.pyfiles only, 30s timeout) - Configurable limits for max iterations and max file read size
- Simple calculator sandbox app used as an execution target
The agent loop lives in main.py and delegates all tool invocations to call_function.py.
- Read CLI prompt (
user_prompt) - Send prompt + tool schemas + system prompt to Gemini
- If Gemini returns tool calls, dispatch via
call_function() - Append tool responses back to conversation state
- Repeat until final natural-language response or max iterations reached
main.py- CLI entrypoint and orchestration loopcall_function.py- tool schema registration + runtime dispatcherfunctions/- local tools exposed to the model:get_files_infoget_file_contentrun_python_filewrite_file
config.py- runtime constraints (MAX_CHARS,WORKING_DIR,MAX_ITERS)prompts.py- system instruction passed to Geminicalculator/- sample project used as the default sandbox
aiagent/
├── main.py
├── call_function.py
├── config.py
├── prompts.py
├── functions/
│ ├── get_files_info.py
│ ├── get_file_content.py
│ ├── run_python_file.py
│ └── write_file.py
├── calculator/
│ ├── main.py
│ └── pkg/
│ ├── calculator.py
│ └── render.py
├── pyproject.toml
└── test_*.py
- Python 3.13+
- Gemini API key
Dependencies are defined in pyproject.toml:
google-genai==1.12.1python-dotenv==1.1.0
Using uv:
uv syncOr with pip:
python -m venv .venv
source .venv/bin/activate
pip install -e .Create a .env file in the repository root:
GEMINI_API_KEY=your_api_key_hereRun the agent with a prompt:
python main.py "List files in the working directory"Verbose mode:
python main.py "Read calculator/main.py and summarize it" --verboseuser_prompt(required): user instruction sent to Gemini--verbose(optional): prints token usage and tool call details
All tools receive a working_directory (default: ./calculator) injected by the runtime.
Safety controls implemented in tools:
- Path confinement via
os.path.commonpath(...) == working_directory - Reject operations outside sandbox directory
- Reject invalid targets (e.g., non-file reads, writing to directories)
run_python_fileonly executes*.pyand applies a 30-second timeoutget_file_contenttruncates content atMAX_CHARS
The bundled calculator can be run directly:
python calculator/main.py "3 + 5 * 2"Expected output is JSON-formatted expression + result.
Current test files are executable script-style checks (not pytest test suites).
Run them individually:
python test_get_files_info.py
python test_get_file_content.py
python test_run_python_file.py
python test_write_file.pyEdit config.py to tune behavior:
MAX_CHARS: max bytes/chars returned by file-read toolWORKING_DIR: sandbox directory for tool operationsMAX_ITERS: max model-tool interaction rounds
- No streaming output in CLI
- Limited toolset (no rename/delete/search tools yet)
- Tests are integration-style scripts rather than isolated unit tests
- Error handling is functional but not yet standardized with custom exceptions
- Add
pytest+ CI workflow for deterministic automated testing - Introduce structured logging and log levels
- Move model/tool configuration to env-driven settings
- Add richer toolset (search, patch/diff edits, safe delete/rename)
- Add retry/backoff for transient API failures
No license file is currently included. Add a LICENSE file before public distribution.