A CLI-based AI agent that can inspect, execute, and debug a Python project using Google Gemini. This repository demonstrates how to build a minimal but practical agentic loop around a large language model (LLM) with tool/function calling.
The project is intentionally small, explicit, and educational, while remaining useful as a base for further experimentation or extension.
- Overview
- Core Concepts
- Features
- Project Structure
- Requirements
- Setup
- Usage
- Agent Execution Flow
- Implementation Overview
- Testing
- Limitations
- Extending the Project
- License
This agent can answer questions such as:
“How does the calculator render results to the console?”
by dynamically:
- Inspecting source files
- Executing Python code
- Iterating over tool calls until a final answer is produced
The target project (calculator/) is deliberately simple, allowing the focus to remain on agent mechanics, not application complexity.
This project demonstrates:
- LLM invocation via API
- Tool / function calling
- Controlled file inspection and execution
- Stateful conversation management
- Iterative reasoning with a bounded loop
It can be viewed as a minimal reference implementation of an LLM-powered code inspection agent.
- Interact with the agent using natural-language prompts from the terminal.
- Uses Google Gemini (
gemini-2.5-flashby default).
The model may request execution of the following tools:
get_files_info— list available project filesget_file_content— read file contentsrun_python_file— execute Python files and capture outputwrite_file— modify files (e.g., apply fixes)
-
Maintains a structured
messagesconversation history. -
Appends:
- Model responses
- Tool execution results
-
Iterates until:
- A final natural-language response is produced, or
- A maximum iteration limit is reached
.
├── main.py
├── config.py
├── prompts.py
├── call_function.py
├── functions/
│ ├── get_files_info.py
│ ├── get_file_content.py
│ ├── run_python_file.py
│ └── write_file.py
├── calculator/
│ └── (example calculator project)
├── test_*.py
├── pyproject.toml
└── .python-version
-
main.pyCLI entry point. Initializes the Gemini client and runs the agent loop. -
config.pyCentralized configuration (e.g.,MAX_ITERS). -
prompts.pyDefines the system prompt that constrains and guides model behavior. -
call_function.pyDispatch layer for executing model-requested tools. -
functions/Individual tool implementations. -
calculator/Example target project used for inspection and execution.
- Python version specified in
.python-version/pyproject.toml - A virtual environment manager (recommended: uv)
- A Google AI Studio API key for Gemini
All Python dependencies are declared in pyproject.toml.
git clone <your-repo-url>
cd <your-repo-dir>Using uv:
uv syncCreate a .env file in the project root:
echo "GEMINI_API_KEY=your_api_key_here" > .envOr export it directly:
export GEMINI_API_KEY=your_api_key_hereThe project uses python-dotenv to load environment variables.
Run the agent from the project root:
uv run main.py "how does the calculator render results to the console?"--verbosePrints additional details such as token usage and tool call results.
uv run main.py "list the files in the calculator project" --verbose-
The user prompt and system prompt are sent to Gemini.
-
The model may request tool calls.
-
Requested tools are executed locally.
-
Tool outputs are appended to the conversation history.
-
The loop continues until:
- The model returns a final response, or
MAX_ITERSis exceeded
If the iteration limit is reached without completion, the program:
- Prints an error message
- Exits with status code
1
- Parses CLI arguments
- Loads environment variables
- Initializes the message history
- Runs the agent loop (bounded by
MAX_ITERS)
-
Calls
client.models.generate_content()with:- Current conversation history
- Tool definitions
- System prompt
-
Appends model responses to
messages -
If tool calls are present:
- Executes them via
call_function() - Appends tool results as a new user message
- Returns control to the loop
- Executes them via
-
If no tool calls remain:
- Returns the final response
This structure forms a minimal, explicit agentic reasoning loop.
Run the test suite using:
uv run python -m pytestor, if tests are simple scripts:
uv run python calculator/tests.py(Adjust based on your test layout.)
- Tools are explicitly whitelisted and limited to those in
functions/ - The agent uses a fixed iteration cap to prevent infinite loops
- Error handling is intentionally minimal
- The project is not sandboxed; tools execute local code
Possible extensions include:
- Adding new tools (e.g., file search, static analysis, test runners)
- Persisting conversation history to disk
- Supporting multiple models or providers
- Exposing the agent via an HTTP API
- Adding structured logging and tracing
- Hardening execution with sandboxing or permissions