Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

372 Commits

Folders and files

Repository files navigation

Toddler

A personal Python CLI coding agent — an AI-powered assistant that reads, searches, edits files, runs shell commands, and interacts with git from your terminal.

Installation

python -m venv .venv
.venv/bin/pip install -e ".[dev]"

Set your API key and optional base URL via environment variables (or a .env file):

export DEEPSEEK_API_KEY="your-key"      # defaults to DeepSeek
export DEEPSEEK_BASE_URL="https://api.deepseek.com"
export TODDLER_DEFAULT_MODEL="deepseek-flash"

OpenAI-compatible providers work too — use the OPENAI_* env prefix as a fallback.

Models: three slots — default, pro, flash — are selected with --model, or switched mid-session with /model, and valued from TODDLER_DEFAULT_MODEL, TODDLER_PRO_MODEL and TODDLER_FLASH_MODEL (all three ship as deepseek-flash). A slot value may carry a [1m] suffix (deepseek-v4-pro[1m]) naming a 1,000K-token context window; without one the model is accounted for at 200K. The suffix is Toddler's own notation and is stripped from the request.

Every slot must name a deepseek- family model. The reasoning echo-back is DeepSeek-specific, so a foreign model is refused at startup rather than left to fail mid-turn.

Thinking effort is selected with --reasoning-effort, or switched with /effort (TODDLER_EFFORT_LEVEL, default high), and it sets the output budget: 4K with thinking off, 64K at max or above, 32K otherwise.

A conversation remembers both, so resuming restores the model and effort it was running with.

Troubleshooting: thinking is paid for out of the same budget as the answer, so a thinking-heavy turn can exhaust max_tokens, ending with finish_reason="length" and empty output — raise the effort. The budget follows it. reasoning_tokens in the recorded usage shows the reasoning/output split.

Usage

tod                     # Interactive REPL with slash commands
tod "refactor auth.py"  # One-shot: run a single task
tod --plan "add tests"  # One-shot in plan mode (research → propose → execute)
tod --session <id>      # Resume a previous session
tod --list-sessions     # List saved sessions
tod serve               # Browser-based web UI (see Web UI below)

Sessions are bound to the directory tod starts in. With no --session, the most recently used session that directory has (CLI or web) is resumed; a fresh one is created only when there is none. --new-session forces a fresh session, and --session <id> resumes a specific one whatever directory it came from.

A session is held by one live process at a time: a claim file under ~/.toddler/sessions/ (an OS file lock) stops a second tod or tod serve in the same project from appending to the same transcript — it gets a fresh session instead. --session <id> naming a session another process holds exits with an error rather than silently opening a different one. The claim file is removed on exit and swept up on the next start if a process was killed before it could release.

CLI Options

Flag Purpose
--plan Force plan mode — agent researches before making changes
--session <id> Resume a previous session by ID
--new-session Start fresh instead of resuming this directory's last session
--list-sessions List saved sessions and exit
--model <name> Override the LLM model
--base-url <url> Override the API base URL
--api-key <key> Override the API key
--max-iterations <n> Cap agent loop iterations
--no-stream Disable streaming output
--verbose, -v Enable debug logging

Web UI

tod serve runs the browser frontend (FastAPI + Vue) against the same agent backend and SQLite session database as the CLI:

tod serve                    # serve at http://127.0.0.1:8000, open browser
tod serve --port 9000        # custom port
tod serve --no-open          # don't auto-open the browser

It accepts the shared flags (--model, --base-url, --api-key, --no-stream, --max-iterations, --new-session); --dev enables CORS for the Vite dev server. Like the CLI, the server resumes the last session used in the directory it was started from.

Slash commands work in the input bar too (/help, /mode, /clear, /session, …) — they dispatch server-side and never reach the LLM. /quit and /view are not available in the browser.

The model and the thinking effort are also switchable from the pill beside the input box: it reads deepseek-flash high and opens onto the three slots and an eight-stop effort slider — the same tiers /effort and TODDLER_EFFORT_LEVEL take, in the same order. Note that the endpoint collapses some of them (minimal/low are both low to DeepSeek, medium/high/xhigh are all high, max/ultra are both max), so moving between those pairs changes the label and not the request.

Development workflow:

cd website && npm run dev    # Vite :5173, proxies /api and /ws to :8000
# keep `tod serve` running in another terminal while editing frontend code

cd website && npm run build  # production bundle into website/dist
tod serve                    # serves the built bundle directly

Architecture

toddler/
  main.py             CLI entry point, arg parsing, component wiring
  agent/              Agent loop, state machine, event handling, stop conditions
  cli/                Terminal app, commands, display, input handler, renderer
  config/             Settings (env + CLI overrides), defaults
  context/            Context window, compaction, conversation context,
                      persistent memory, project map, system prompt
  llm/                LLM provider abstraction (OpenAI-compatible), types,
                      token counting
  storage/            SQLite-backed session persistence, store, models
  tools/              Tool registry, base protocol, executor, filesystem, git,
                      search, shell subprocess
  checkpoint/         Snapshot/checkpoint management

Highlights

  • LLM-agnostic — OpenAI-compatible provider works with DeepSeek, OpenAI, and any compatible endpoint.
  • Permission model — Tools declare a tier (READ, WRITE, SHELL_SAFE, SHELL_DANGEROUS) and the scope of the files a call reaches (the workspace, outside it, or a restricted path); the agent pauses before destructive work or anything out of the workspace, and refuses restricted paths such as .env outright.
  • Plan mode — State machine that detects complex tasks, researches first, proposes a plan, then executes after user approval.
  • Context window — Automatic token counting with LLM-powered compaction to handle long sessions.
  • Session persistence — SQLite-backed history at ~/.toddler/sessions.db with multi-conversation support. Sessions are bound to the directory they were started in and that project's last one resumes automatically — one live process per session, claimed with a file lock.
  • Streaming — Real-time token output via Rich with animated tool-call status.

Roadmap

  • Web frontend — browser-based GUI with a split-pane layout: file viewer/editor on the left, agent console with scrollback on the right. Coexists with the CLI via a tod serve command and shares the same agent backend and session database.

Development

Always use the project virtual environment:

.venv/bin/python
.venv/bin/pip
.venv/bin/pytest
.venv/bin/ruff check .

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages