An AI agent with tools, memory, and a step-by-step execution trace.
A small Python project by Leo Zhao. Give it a task such as “calculate a number and remember it,” then expand the execution record to check the result. Restart the app and retrieve the saved fact from SQLite.
The design question: how can a reader verify an agent's work instead of trusting its final answer? Loop Agent makes the execution record part of the product: tool arguments, success or failure, loop limits, and durable state are visible. The scope stays small enough to follow in source.
Open the interactive walkthrough →
No installation. Three recorded Python runs: save a result, recall it after restart, and inspect a failure. The hosted page replays actual execution records; run locally to enter your own tasks.
Watch the three examples (short step-through GIF)
Captured from the interactive replay, with pauses between examples; not a real-time LLM recording.
| Time | Start here | What you will see |
|---|---|---|
| 30 seconds | This page | The problem, working example, and engineering choices |
| 3 minutes | Run the demo | A calculation, saved memory, and a checkable execution record |
| 5 minutes, no setup | Annotated walkthrough | Expand each step, including a failure case |
| 10 minutes | Architecture and tradeoffs | Source links, data flow, limits, and what would change for production |
Requires Python 3.11+ and Git. The default demo has no dependencies, no API key, and no model charges.
Use python instead of python3 if that is your Python 3.11+ command.
git clone https://github.com/LobsterQBA/loop-agent.git
cd loop-agent
python3 -m agent_systemOpen localhost:8787, then:
- Run the prefilled instruction: Calculate 17 × 23 and remember the result as launch score. Expect 391, 2 tool calls, and 3 planner calls.
- Expand Inspect recorded data under a tool call and its observation. Compare the requested expression, returned number, and saved value. Download turn JSON exports that completed turn.
- Stop the server with Ctrl+C, start it with the same command from the same directory, then click
recall memory and run it. Expect
launch score: 391; the database survived the restart. - Click try a failure and run it. Division by zero returns an error, and no result is saved.
No browser? Run the same core flow, including a restart check, in an isolated temporary database:
python3 -m agent_system.walkthroughIt exits with a nonzero status if an expected behavior fails. It does not touch your saved app state. See the walkthrough for expected output and troubleshooting.
| Engineering choice | Why it matters | Evidence |
|---|---|---|
| A readable tool loop | Separate a requested action from its observed result | Loop, expandable UI trace |
| A deterministic demo and an optional LLM adapter | Make the project reproducible before adding model variability | Adapters, walkthrough |
| Explicit SQLite memory | Show what persists; don't pretend a new turn remembers the conversation | Store, restart check |
| Structured tool errors | A failed calculation must not become a saved result | Regression tests |
| A bounded tool surface | Explore agent control with four local functions | Registry and calculator |
The default planner uses rules, not an LLM. It runs real tools and writes real SQLite records. Live mode uses the same loop with an OpenAI-compatible function-calling model. The trace records calls and results; it does not expose private model reasoning. It appears after the turn completes, not as a live stream.
flowchart LR
U[Instruction] --> L[Bounded loop]
L --> M[Demo planner or LLM]
M -->|Tool request| T[Registered local function]
T -->|Observed result| L
T <-->|Remember / recall| D[(SQLite)]
M -->|Final text| R[Reply]
R --> P[Persist turn and trace]
P --> V[Expandable execution record]
Each iteration asks the planner/model what to do next. A tool result becomes input to the next iteration. A text reply ends the loop; a six-iteration budget prevents indefinite repetition. A single iteration can request multiple tools, so this is not a six-tool-call or dollar-cost cap.
Read the architecture for the full lifecycle, source map, and limitations.
Optional: connect a live model
python3 -m venv .venv
source .venv/bin/activate
pip install -e '.[live]'
cp .env.example .env
# Set AGENT_API_KEY and AGENT_MODEL in .env
loop-agentOn Windows, activate with .venv\Scripts\activate. Set AGENT_BASE_URL only if using another
OpenAI-compatible endpoint. Select Live in the app after restarting the server.
The API key stays on the server. The provider receives the instruction, tool schemas, and tool results;
provider fees apply. Demo tests do not establish live-model quality or provider compatibility.
Optional: use the local JSON API
curl -X POST http://127.0.0.1:8787/api/run \
-H 'Content-Type: application/json' \
-d '{"message":"Calculate 8 * 9","mode":"demo"}'The response includes reply, trace, iterations, tool_calls, mode, model, and turn_id.
GET /api/status describes configuration; GET /api/memory returns up to 20 recent memories and
8 recent turn summaries. These are limited lists, not lifetime totals.
Requests require JSON (otherwise HTTP 415), a nonempty string of at most 2,000 characters, and mode
demo or live. Invalid input returns HTTP 400 before a turn is created. Unconfigured live mode
returns HTTP 409. State lives at .agent-mini/state.db, relative to the launch directory, unless
AGENT_HOME is set.
python3 -m venv .venv
source .venv/bin/activate
pip install -e '.[dev]'
pytest -q
ruff check .
python -m agent_system.walkthroughCI runs the deterministic tests and walkthrough on Python 3.11 and 3.12. Tests cover multi-tool execution, restart persistence, failed calculations, iteration exhaustion, restricted arithmetic, and HTTP input validation. They do not benchmark LLM accuracy, latency, or production throughput.
The GitHub Pages walkthrough is generated from real demo turns in fresh processes. It serves static assets and no API keys or visitor state. Build and deployment details · Resume and interview notes.
This is a local portfolio project, not a hosted service. There is no shell, browser, messaging, or arbitrary-file tool. The server binds to localhost; it has no authentication or multi-user isolation. Memory writes and the final trace are separate database transactions, so a failed turn can leave partial effects. The failed turn and its trace are persisted to make those effects inspectable; a process crash can still interrupt before that record is written.
The next engineering priority would be transactional policies for partial tool effects, followed by live-model evaluation against task-specific criteria. See the tradeoffs.
Architecture inspiration: Waku. This repository was implemented from scratch with a smaller scope. MIT license.

