Version 1.1 — see Changelog for release history.
This is a highly focused coding agent that operates exclusively on a small, explicitly selected set of files provided by the user. By limiting its scope, it keeps token usage low and predictable while enabling precise, targeted edits.
This design is critical because real software development happens in increments. While LLM agents can accelerate greenfield projects or assist beginners, production-grade software demands precision. This agent is built for incremental development and continuous code improvement, ensuring that changes are safe, controlled, and context-aware.
In addition to the full agent run for convenience, you can also ask the LLM directly. This is a single, stateless call (no agent loop, no file access) that streams a direct LLM response—useful for quick questions or one-off completions.
- Python 3.12+ — the project targets modern Python syntax and dependencies.
- uv — a fast Python package manager and runner. Install it from https://docs.astral.sh/uv/ (e.g.
curl -LsSf https://astral.sh/uv/install.sh | shon macOS/Linux). - An LLM API key — the agent needs access to a large language model to reason about the task and generate edits. Set the required environment variable
LLM_API_KEYbefore running. See Configuration for details.
uv syncThis installs the runtime dependencies plus the dev group (pytest, httpx). Run the test suite with:
uv run pytestThe app is a FastAPI service (a port of the original Streamlit SideKick app). Start it with:
uv run uvicorn sidekick.api.main:app --port 8005Then open http://localhost:8005 in a browser for the web UI, or use the REST API directly.
The web UI (served at /) is a single-page interface for driving the agent without touching the REST API directly. It is split into two areas:
- Workspace (sidebar) — where you define the context the agent is allowed to work with:
- Root directory — the base path the provided files are resolved against.
- Files to provide — a list of files (one per line) to make available to the agent.
*glob patterns are supported (e.g.src/models/*).
- Task (main area) — where you describe what you want done and start a run:
- Task — a free-text description of the change you want.
- Run Agent — starts a new agent run with the workspace and task above.
- Ask LLM — sends the task text as a single, direct LLM question (no agent loop, no file access) and shows the streamed answer in a separate "LLM answer" section.
While a run is in progress, the UI shows a status section with the current state and a live log of the agent's activity. If the agent requests to create a new file, an approval dialog appears showing the requested file and its content, with Approve Creation / Reject Creation buttons.
When the run finishes, a results section appears with:
- Final summary — the agent's summary of what it did.
- Changed files — the list of files that were modified.
Users can register themselves through the application, but they must be activated by an administrator before they can gain access. Additionally, each user must provide a folder during registration; every root directory they run the agent against must be that folder or a directory inside it. The server enforces this on resolved paths, so .. segments and symlinks cannot be used to escape.
POST /api/login returns a Bearer token. Every /api/* route except register, login and logout requires it in the Authorization: Bearer <token> header and returns 401 otherwise. Tokens are kept in memory and are invalidated by POST /api/logout or a server restart. Agent runs are bound to the user who started them: another user's status, resume and clear calls on that thread return 404, and /api/metrics only returns the caller's own runs.
On first start the app seeds a default admin / admin1234 account whose folder is the installed package directory. Change or remove that account before exposing the service beyond localhost.
To activate a user (add them to the whitelist), you can run the add_active_user.py script:
uv run python src/add_active_user.pyNote: The user must already exist in the users table of the database. You can also import activate_user from src/add_active_user.py to activate users programmatically.
The agent is built on top of a large language model (LLM) and needs credentials to call it. Configure the following environment variables (or a .env file at the project root):
| Variable | Description |
|---|---|
LLM_API_KEY |
API key for the LLM provider used to generate edits. |
LLM_BASE_URL |
Base URL of the LLM endpoint, useful for proxies or self-hosted models. |
LLM_MODEL |
Model name to use (e.g. qwen3.8:30b). Defaults to a sensible built-in value. |
APPROVE_FILE_CREATION |
When set to t or true, file creation is auto-approved (no manual approval prompt). |
SIDEKICK_DB_PATH |
Path of the SQLite user database. Defaults to src/sidekick/api/users.db. |
LLM_API_KEY=ollama
LLM_MODEL=gemma4:cloud
LLM_BASE_URL=http://localhost:11434/v1
APPROVE_FILE_CREATION=t
The agent is intentionally constrained to keep token usage low and edits precise:
- File selection — You provide a root directory plus an explicit list of files (or globs). Only those files are made available to the agent; it cannot read or modify anything outside that set.
- Task — You describe what you want done (for example, "add a docstring to the main function").
- Reasoning — The LLM inspects the provided files and the task, then plans the smallest correct change needed.
- Edits — Edits are applied as targeted, exact text replacements against the provided files. Each replacement must match the original text exactly, so changes stay surgical and reviewable.
- Iteration — After an edit, the agent re-reads the affected file to verify the change and can continue iterating until the task is complete.
This design means the agent never touches files you didn't select, and every change is a small, explicit diff rather than a full-file rewrite.
Token usage is tracked per run and reported in the token_usage field of the status response (and in the final done event of the /api/llm stream), so you can see exactly how many tokens each run consumed.
- 0.5 — Initial release.
- 0.75 — Added direct LLM call (no agent loop).
- 1.0 — Added user management.
- 1.1 — API routes require a login token; workspace roots are restricted to the user's registered folder; runs are private to their owner; fixed "Changed files" not listing edited files; dropped the unused Streamlit dependency.