Skip to main content

Chatty

Chatty

An advanced AI Chatbot CLI with a rich terminal interface, sandboxed file system tools, multi-provider LLM support (Ollama, OpenRouter, and custom providers via LiteLLM), syntax verification, dynamic skills, and cost/token optimization.

Chatty provides a local terminal loop that allows an LLM agent to interact with your codebase and system tools in a safe, sandboxed directory. It utilizes rich and prompt_toolkit to deliver a premium user experience, complete with formatting, status indicators, and autocompletion.


Features

  • Multi-Provider Flexibility: Switch seamlessly between local Ollama instances, cloud-based OpenRouter endpoints, or any custom API provider (such as Anthropic, Chatty, DeepSeek, Groq, etc.) via LiteLLM integration.
  • Oracle Query Delegation: Consult a more advanced oracle model dynamically during a session via the ask_oracle tool or the /oracle slash command.
  • Sandboxed Execution Backends: Restricts file modifications and commands strictly to a sandbox root (default ./sandbox). Supports a companion Docker container for hermetic isolation and reproducible toolchains, Linux Landlock kernel-level filesystem sandboxing, and direct execution.
  • User-Space AST Validation: Parses Python scripts executed via shell commands and blocks direct filesystem operations unless explicitly permitted or whitelisted by the user.
  • Interactive UI: Status bars showing the provider, active model, token counter, active loop count, and sandbox directory path. Autocomplete and multiline inputs are fully integrated.
  • Slash Commands: Modify settings dynamically mid-session, view tool metrics, or compress history to save tokens.
  • Dynamic & Static Skills: Dynamically import system prompts and guidelines from external files or directories via keyword/tag triggers or statically on initialization.
  • Context Optimization: Automates context truncation and history compression. Implements ephemeral cache_control tagging to maximize prompt caching efficiency for OpenRouter.
  • Google-Style Logging: Standardized process tracking via custom glog styling.

Installation & Setup

Prerequisites

  • Python 3.8 or higher.
  • A running Ollama instance locally (optional, for local models).
  • An OpenRouter API Key (optional, for remote models).

Installation

Install directly from PyPI:

pip install chatty-agent

Alternatively, install from the local repository directory:

pip install .

Developer Mode (Editable Install)

To develop or modify the codebase and have changes immediately visible without reinstalling:

pip install -e .

CLI Usage & Arguments

Once installed, invoke the chatbot using the chatty command or via Python:

chatty [options]
# OR
python3 -m chatty [options]

Full List of CLI Arguments

Parameter Short Type Default Description
--provider -p string ollama Backend provider to use (e.g., ollama, openrouter, anthropic, chatty, etc.). If omitted and --url is set, resolves automatically to the domain of the URL.
--model -m string Auto-resolved Model identifier(s) to load. Can be specified multiple times or as comma-separated values. The first becomes the active model. Ollama: auto-detects first local model (falls back to qwen2.5-coder:7b). OpenRouter: dynamically defaults to the most popular free model (falls back to google/gemini-2.5-flash:free). Custom: required (no fallback).
--oracle-model None string None Model identifier to use as the oracle. No default is assumed (the oracle tool is only active if an oracle model is explicitly configured).
--context-size -c integer 8192 Target context window length constraint in tokens.
--sandbox -s string ./sandbox Path to the sandboxed folder. All writes and runs are jailed inside this directory. If neither Docker nor Landlock is available and --sandbox is specified, Chatty aborts to prevent un-sandboxed execution unless --backend none is passed.
--skills-path -k string None Custom directory paths to scan for static/dynamic Skills (can be specified multiple times).
--ondemand-skills-path -o string None Custom directory paths to scan for on-demand Skills (can be specified multiple times).
--whitelist -w string None Add an out-of-sandbox path to the initial whitelist. Can end with :ro or :rw to set mode (defaults to ro). Can be specified multiple times.
--static-skills None flag Auto Load all skills statically into system instructions (defaults to True for OpenRouter, False for Ollama).
--prompt-caching None flag False Explicitly enable prompt caching for compatible models (adds cache_control tagging).
--max-loops -l integer 20 Maximum sequential tool executions allowed in a single user turn.
--config-prompt -f string None Path to a YAML or plain text file containing custom system prompt guidelines.
--prompt-mode -d string replace How to apply custom system prompt configuration (replace default prompt, or integrate/append to it).
--api-key -a string None Client API Key. Overrides OPENROUTER_API_KEY, CUSTOM_API_KEY, or OPENAI_API_KEY environment variables depending on the provider.
--url -u string None Custom Base URL override (required for custom providers; automatically resolves the provider name to the domain of the URL if --provider is not specified).
--max-read-chars None integer 40000 Maximum character limit when reading a text file to prevent context explosion.
--max-grep-results None integer 100 Limit on matching results returned from the regular expression search tool.
--max-command-chars None integer 16000 Maximum characters returned from stdout/stderr of executing commands.
--max-history-tool-chars None integer 1000 Token saving limit: compresses old/historical tool output messages to this size.
--history-keep-messages None integer 4 Number of recent messages to keep fully raw and uncompressed.
--max-url-chars None integer 24000 Limit on fetched website character outputs.
--max-dir-items None integer 200 Maximum number of directory items listed by directory explorer tool.
--log-file None string chatty.log File path where execution statements are logged. Set to "" to disable.
--log-level None string info Logging verbosity (debug, info, warning, error).
--headless None flag False Run the chatbot in headless mode (no console printing or terminal interactive loop; implicitly enables --auto-approve).
--auto-approve None flag False Automatically approve file changes without interactive diff confirmation prompts.
--max-thinking-chars None integer 12000 Maximum internal thinking characters before prompting the user.
--max-thinking-leeway-chars None integer 2000 Leeway in characters beyond the maximum before hard-aborting or prompting.
--api-delay None float 2.5 Minimum delay in seconds between consecutive API requests.
--api-timeout None float 60.0 Timeout in seconds for API requests and streams.
--repo-map / --no-repo-map None flag True Include a Tree-Sitter / PageRank repository map in the system prompt.
--repo-map-tokens None integer 1024 Target token budget for the repository map.
--discovery-model None string Auto-resolved Model identifier for the discovery/scout agent (dynamically selects a fast, low-cost coding model on OpenRouter, a local coder model on Ollama, or falls back to the active model).
--discovery-loops None integer 50 Maximum tool execution loops allowed for the discovery agent.
--backend -B string auto Execution backend for shell commands: auto (default: Docker if available, else Landlock on Linux, else fails if --sandbox specified), docker (companion container), landlock (Linux Landlock LSM), or none (direct host execution).
--docker-image None string chatty-sandbox:<user> Docker image tag to use for the companion container.
--dockerfile None string None Path to a custom Dockerfile to build and use for the companion container.
--docker-build None flag False Force building or rebuilding the Docker companion image on startup.
--docker-reset None flag False Reset (recreate) the Docker companion container for the current workspace.
--docker-ephemeral None flag False Run the companion container as ephemeral (destroy on session exit).
--docker-host None string None Custom Docker host endpoint (e.g. tcp://127.0.0.1:2375 or unix:///run/user/1000/docker.sock). Overrides DOCKER_HOST.
--mcp-config None string None Path to an MCP (Model Context Protocol) JSON configuration file.
--mcp / --no-mcp None flag True Enable or disable Model Context Protocol (MCP) server integration.

Custom OpenAI-Compatible & Multi-Provider Support

Chatty uses LiteLLM under the hood, meaning you can connect to any third-party cloud provider (like Anthropic or Chatty) or any OpenAI-compatible custom endpoint.

1. OpenAI-Compatible Custom Endpoints

To connect to custom endpoints (like DeepSeek, Groq, Together AI, or local vLLM servers), specify --url and --model (along with --api-key if required). The provider name will automatically be resolved to the domain name of your URL:

# Run using DeepSeek V3 (automatically sets provider to 'api.deepseek.com')
chatty --url https://api.deepseek.com/v1 --api-key YOUR_DEEPSEEK_KEY --model deepseek-chat

# Run using Groq (automatically sets provider to 'api.groq.com')
chatty --url https://api.groq.com/openai/v1 --api-key YOUR_GROQ_KEY --model llama-3.3-70b-versatile

# Run using Together AI (automatically sets provider to 'api.together.xyz')
chatty --url https://api.together.xyz/v1 --api-key YOUR_TOGETHER_KEY --model Qwen/Qwen2.5-Coder-32B-Instruct

2. Native Multi-Provider Support via LiteLLM

You can also call other native providers supported by LiteLLM (such as Anthropic or Google Chatty) directly by specifying their provider name and model:

# Run using Anthropic Claude 3.5 Sonnet (expects ANTHROPIC_API_KEY env variable)
chatty --provider anthropic --model claude-3-5-sonnet

# Run using Google Chatty Pro (expects CHATTY_API_KEY env variable)
chatty --provider chatty --model chatty-2.5-pro

Interactive Interface & Slash Commands

During a session, you can input direct queries to the model, or use Slash Commands to inspect/adjust configurations on the fly:

Command Expected Arguments Description
/help None Displays a formatted usage table of all slash commands.
/status None Shows active session variables (provider, model, oracle, sandbox, tokens, loops, etc.).
/tool_stats None Renders execution statistics (call counts, failures, and breakdowns for tools and binaries).
/provider [name] View current provider or switch backend on the fly. Accepts standard or custom provider names (e.g., ollama, openrouter, anthropic, chatty, api.deepseek.com).
/model [ID|name] View active model name or switch to another model by name or 1-based index/ID.
/models [add <name>|remove <ID|name>|available [--refresh]|search <query>|info <ID|name>] List, add, remove, search, or view details of LLM models.
/oracle [name] View active oracle model name or switch to another oracle model by name.
/discover <task> Run discovery agent to scout codebase context for a given task.
/discovery_model / /discover_model [name] View or switch the model used for discovery agent.
/research / /web_research <query> Run web scout agent to research technical documentation, issues, or APIs online.
/sandbox [path] View sandbox path or change it. Instantly loads any skills found in the new sandbox.
/whitelist / /permissions [add <path> [ro|rw] | remove <path> | clear] View or manage whitelisted out-of-sandbox paths.
/skill [NAME...|clear] Load on-demand skill(s) or clear explicitly loaded ones.
/context [tokens] View or update target context memory window limit in tokens.
/loops [iterations] View or modify the limit of sequential agent loops allowed per turn.
/api_key [key] Configure your client token dynamically.
/system [text] Inspect or update the base system prompt instructions directly.
/load <path> [append|replace] Read system instructions from a local YAML or text file, appending or replacing.
/save / /save_session <path> Save the whole status of the current conversation/session to a JSON file.
/load_session <path> Load a saved conversation/session status from a JSON file.
/history [N] Renders message records, estimated token counts, roles, and tool calls, or displays the N-th entry in full detail.
/undo [count] Reverts the last conversation turn(s), removing assistant responses, tool outputs, and the user prompt.
/pop <index> Truncates the conversation history by deleting all messages from the specified 1-based index onwards.
/backups <file_path> Lists all available timestamped backups for a given file.
/restore <file_path> [index_or_timestamp] Restores a file to a specific backup version (defaults to the latest).
/tools None Lists available sandboxed tools and their schema definitions.
/find_symbol <name> Search the global project-wide index for any symbol definition.
/repo_map / /map [refresh] Displays the Tree-Sitter / PageRank repository map.
/config [key=value] List, view, or change configuration parameters live (including auto_approve=true|false).
/auto_approve [on|off] Toggle or explicitly enable/disable interactive diff review before file modifications.
/mcp [list|reload] Inspect status and tools of connected Model Context Protocol (MCP) servers, or reload server processes.
/clear / /reset None Clears conversational context history.
/compress [N] Directs the model to summarize current conversational state using a structured format, resets older history, and keeps N (default 4) recent messages intact.
/copy / /clip [index|all] Copy a code block or the full AI response to the clipboard.
/write / /save_code <path> [index|all] Write a code block or the full AI response to a file.
/save_response / /save_reply <path> Save the entire last AI response to a file.
/show <path> Read and render a Markdown file beautifully in the terminal.
/docker / /container [<command>|reset] Inspect companion container status, execute commands inside the container, or reset its state.
/task / /tasks [list|show <task_id> [N]|kill <task_id>] Manage background tasks (list active tasks, view stdout/stderr, or terminate).
/exit / /quit None Cleanly terminates background processes and exits Chatty.

Model Discovery & Search Filters

When using OpenRouter or Ollama, you can discover, inspect, and filter available models:

# List available models
/models available [--refresh]

# Inspect detailed model specs
/models info <model_id_or_name>

# Multi-constraint search with AND logic
/models search cost<0.1 context>=1M ... qwen

The /models search command supports combining multiple conditions (all AND-ed together):

  • Cost / Pricing Filters: cost<0.1, cost<=0.5, cost>0.01, cost=0 (per 1M input tokens), out_cost<0.5 (output tokens).
  • Context Length Filters: context>=1M, context>=128k, ctx>32k, context<=2M (supports k and m multipliers).
  • Size Filters (Ollama): size<5g, size<=10gb, size>1g (supports g, m, k units).
  • Capabilities & Flags: cat:vision / is:vision, cat:free / is:free.
  • Sorting Options: sort:cost, sort:context, sort:newest, sort:size.
  • Text Keywords: Model name/ID keywords (e.g. qwen, coder, llama).
  • Flexible Syntax: Supports spaces around comparison operators (e.g. cost < 0.1 context >= 1M), optional commas, and chained conditions.

Autonomous Scout Agents (Codebase Discovery & Web Research)

Chatty features an integrated Scout Agent Engine powered by a secondary, fast model (--discovery-model) that runs multi-turn investigation loops in an isolated, ephemeral context. This prevents exploratory tool calls, voluminous file dumps, and raw web pages from littering the main conversation history:

1. Codebase Discovery Scout (discover_context / /discover)

Explores the workspace using read-only tools to gather precise context, target files, exact line ranges, symbol definitions, and architectural dependencies before code modifications begin:

  • Interactive Command: Use /discover <task> to run reconnaissance interactively. The resulting dossier is rendered in the terminal and injected directly into conversational memory.
  • Autonomous LLM Tool: The primary LLM can invoke discover_context(task) whenever it needs to survey the repository.
  • Code Intel & Repo Map: Injects the active Tree-Sitter / PageRank repo map and recent file history into the scout prompt.
  • Strict Tool Whitelist: Restricted strictly to inspection tools (read_file, search_grep, locate_files, get_outline, find_symbol, get_file_info, fetch_url). All write and execution tools are blocked.

2. Web Research Scout (web_research / /research)

Autonomously searches the web, inspects documentation pages and GitHub issues, and extracts verified answers without bloating the main model's context window:

  • Interactive Command: Use /research <query> (or /web_research <query>) to investigate documentation or error messages interactively.
  • Autonomous LLM Tool: The primary LLM invokes web_research(query) instead of performing manual search/scraping iterations.
  • Technical Fidelity: Enforces verbatim preservation of code snippets, exact type signatures, and library versions, along with source citations.
  • Strict Tool Whitelist: Restricted to internet search and URL fetching tools (search_web, fetch_url).

Scout Configuration & Model Tiering

  • Configurable Scout Model: Switch models anytime using /discovery_model <model> (with full Tab completion) or --discovery-model <model>.
  • Intelligent Provider Defaults: Automatically selects a fast, low-cost coding model on OpenRouter (dynamically filtered by cost bounds and popularity) or a local model on Ollama, ensuring exploration does not burn expensive primary model tokens.
  • Configurable Turns: Control maximum investigation iterations via --discovery-loops <N> (default: 50).

Sandboxed File System Tools

The chatbot uses function-calling to interface with the sandbox workspace. Directly invoking command-line file manipulation programs (e.g. cat, grep, find) in run_command is blocked by safety filters in validate_command_safety. The agent is required to use the appropriate structured tools:

File Manipulation Tools

  • list_dir: Explores directories inside the sandbox. Truncates output above --max-dir-items to prevent token flooding.
  • read_file: Reads text files. Accepts optional start_line and end_line parameters (1-indexed), supports displaying line numbers, and honors --max-read-chars.
  • write_file: Writes full text contents to a file.
  • patch_file: Replaces one or more unique blocks of code inside a file using Aider-style SEARCH/REPLACE blocks (or direct search/replace parameters). Highly robust to whitespace and indentation differences (automatically adjusts output indentation to match the file). Supports unique sub-line (intra-line) replacements, chaining multiple blocks sequentially in one patch parameter, detailed mismatch diagnostics, a dry_run simulation mode, and returns applied unified diffs.
  • format_file: Styles source files using appropriate project formatters (black/ruff/yapf for Python, clang-format for C/C++, prettier for web). Automatically detects repo configuration files (.style.yapf, .clang-format, pyproject.toml, .prettierrc) and discovered installed system formatters, or accepts custom formatter rules. Displays diff results.
  • move_file: Renames or moves files and directories safely inside the sandbox boundaries.
  • copy_file: Recursively copies file system structures.
  • delete_file: Permanently removes a file. Fails on directories.
  • delete_directory: Permanently removes a directory (optionally recursively).
  • make_directory: Recursively builds directory trees.
  • get_file_info: Retrieves file system metadata (modification dates, sizes, type, and line counts for text documents).
  • hex_dump: Performs a hex dump or parses slices of binary files into integers of various widths (8/16/32/64-bit), endianness, and signedness.
  • list_file_backups: Lists all available timestamped backups for a file path.
  • read_file_backup: Reads the contents of a specific timestamped file backup (with optional range read and line numbering).

Interactive Diff Review & File Approval (auto_approve)

Chatty provides human-in-the-loop review before files are modified on disk (write_file and patch_file):

  • Visual Color-Coded Diffs: Before applying changes, Chatty renders a syntax-highlighted unified diff showing exactly what will be added, modified, or removed.
  • Interactive Decision Prompt:
    • [y]es (or Enter): Approve and write the changes to disk.
    • [n]o: Reject the changes. Chatty returns a rejection status to the AI without modifying the file or creating a backup.
    • [c]omment: Provide direct textual feedback or instructions to the AI (e.g. "Please retain existing comments and docstrings"). The AI receives your guidance in the tool execution result and adapts immediately in the next loop.
    • [a]uto-approve: Approve this change and automatically approve all subsequent file changes for the remainder of the session.
  • In-Session Toggles:
    • /auto_approve [on|off]: Toggle or explicitly set auto-approval on the fly without restarting Chatty.
    • /config auto_approve=true|false: Dynamically view or update the configuration via /config.
  • Command-Line & Headless Options:
    • --auto-approve: Start Chatty with auto-approval enabled from the command line.
    • In --headless mode, auto-approval is enabled by default to allow unattended execution.

Model Context Protocol (MCP) Integration

Chatty natively supports the Model Context Protocol (MCP) standard over stdio, allowing you to connect external tool servers (databases, web scrapers, APIs, custom scripts) directly to Chatty:

1. Configuration & Server Setup

Chatty automatically detects MCP server definitions from any of the following standard locations:

  • .chatty/mcp.json (workspace or current working directory)
  • mcp.json or .mcp.json
  • ~/.config/chatty/mcp.json
  • Or explicitly via --mcp-config <path>

The configuration syntax follows the standard mcpServers format:

{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_..."
      }
    },
    "postgres": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://localhost/mydb"]
    }
  }
}

2. Automatic Tool Discovery & Execution

  • Dynamic Tool Schema: On session startup, Chatty initializes each server, retrieves its exposed tools, and registers them directly into the LLM's function schema with a server identifier tag ([MCP: server_name]).
  • Conflict-Free Namespacing: If tool names are unique across servers, the LLM can call them directly by name (e.g. get_issue). If multiple servers provide a tool with the same name, Chatty provides namespaced routing (mcp__<server>__<tool>).
  • Seamless Execution: When the LLM decides to call an MCP tool, Chatty dispatches the JSON-RPC request to the server process over stdio, collects the resulting text or image content, and feeds it back to the conversation.

3. In-Session Inspection (/mcp)

  • /mcp or /mcp list: Displays a formatted status table of all connected MCP servers, commands, connection health, and registered tools.
  • /mcp reload: Hot-reloads configuration files and restarts MCP server subprocesses without restarting Chatty.
  • --no-mcp: Disable MCP server discovery and execution for lightweight sessions.

Scratchpad & Workspace Cleanliness (.chatty/scratch/)

Chatty instructs the agent to store all temporary test scripts, one-off execution snippets, scratchpad notes, and intermediate debug files inside .chatty/scratch/ (relative to the sandbox root) to prevent workspace clutter and avoid polluting git status. When exiting Chatty, if any files exist in .chatty/scratch/, the CLI interactively prompts whether you want to clean them up or preserve them.

Code Search & Diagnostics

  • discover_context: Delegates codebase reconnaissance to a fast scout discovery agent. The discovery agent explores the workspace using read-only tools to compile a structured dossier of target files, line spans, key definitions, and architectural notes for a given task.
  • search_grep: Performs recursive regular expression string matching on files. Can report line numbers (line_numbers: true) to aid editing.
  • locate_files: Finds files recursively matching glob configurations (e.g., **/*.py).
  • get_outline: Extracts symbols (classes, functions, methods) defined in a specific file.
  • find_symbol: Searches symbol definitions across the entire workspace.
  • run_tests: Runs test scripts (pytest, npm test, custom targets).

Web & Information Retrieval

  • web_research: Primary web tool for the LLM. Delegates technical documentation research, API exploration, and troubleshooting to the autonomous web scout agent. The scout issues iterative queries, fetches and parses web pages, and synthesizes a concise technical briefing with verbatim code snippets and citations without cluttering the main conversation history.
  • fetch_url: Directly fetches the text content of an explicit public URL. Automatically parses both HTML (converting it to clean plain text) and PDF documents. For scanned PDFs (which lack a text layer), it features an optional zero-overhead OCR fallback utilizing pytesseract and pdf2image dynamically if available on the host system.
  • search_web: Search backend used by the web research scout (supporting multiple providers via environment variables in priority order):
    • Tavily: Set TAVILY_API_KEY (highly recommended for clean, parsed AI search results).
    • Brave Search: Set BRAVE_API_KEY (independent, privacy-focused search).
    • Google Custom Search: Set GOOGLE_API_KEY and GOOGLE_CSE_ID (legacy Google search engine).
    • Serper: Set SERPER_API_KEY (Google search proxy).
    • SerpApi: Set SERPAPI_API_KEY (Google search proxy).
    • Yahoo Scraper: Default fallback if no keys are provided (unreliable for heavy use).

Command & Background Execution

  • run_command: Runs shell commands from the sandbox directory.
    • Safety Restrictions: Monitored by safety checks to block commands that attempt directory escapes, or attempt to circumvent tool guidelines by calling commands like cat, grep, find, sed, awk, less, more, wc, kill, pkill, killall, cp, mv, rm, rmdir, mkdir, ls, dir.
    • Output Controls: Supports output_filter (regex matching), head_lines, and tail_lines parameters to prevent token overflow.
    • Asynchronous Process Execution: Commands that block or run indefinitely are automatically backgrounded by the session, returning a Task ID (e.g., task_1).
  • check_background_command: Inspects status, reads output, and checks exit status code of background processes using their task_id (supports wait timeouts up to 60s).
  • peek_task_output: Peeks at the currently accumulated output of a background task without blocking or changing its running status.
  • kill_process: Kills a running background subprocess.
  • Background Task Management (/task / /tasks): Interactively list running tasks (/task or /task list), inspect their live output (/task show <task_id> [N] or /task <task_id>), or terminate them (/task kill <task_id>).
  • sleep: Pauses execution for a specified number of seconds.
  • ask_question: Prompts the user with a question or selectable options to confirm decisions or resolve ambiguity.
  • ask_oracle: Consults a more advanced oracle model for advice or suggestions when stuck on a difficult reasoning step, logic problem, or complex code generation.

Sandboxing & Execution Architecture

Chatty implements a layered security approach to execute commands safely, isolate file operations, and protect the host system.

1. User-Space Safety Filtering

Every command sent to run_command is statically parsed and verified by validate_command_safety. It blocks common shell commands (such as cat, grep, find, cp, mv, rm, ls, etc.) to force the LLM to use structured sandbox API tools rather than arbitrary shell execution.

Additionally, Python script executions (either run inline with python -c or loaded from .py files) are parsed into an Abstract Syntax Tree (AST) to extract their structural signature. If direct filesystem operations (like open, write, os.remove, etc.) are detected, the execution is blocked, and the chatbot prompts the user interactively to allow or deny the script, or whitelist its signature.

2. Pluggable Execution Backends (--backend)

Chatty supports multiple execution backends to run commands generated by the LLM:

  • docker: Spawns and manages a companion Docker container for hermetic isolation.
  • landlock: Uses the Linux Landlock LSM to restrict filesystem access at the kernel level.
  • none: Direct user-space execution on the host without sandboxing.
  • auto (Default): Automatically selects the most secure available backend using the following resolution hierarchy:
    1. Docker companion container: Selected if Docker tools are installed and the daemon is reachable.
    2. Linux Landlock: Selected if Docker is unavailable, the host is Linux (kernel 5.13+), and Landlock binary compiles.
    3. Strict Sandboxing Check: If neither Docker nor Landlock is available and a --sandbox directory was explicitly specified, Chatty immediately aborts with an error to prevent accidental un-sandboxed execution. To run commands directly on the host, explicitly pass --backend none.

3. Companion Docker Container Backend

When the Docker backend is active, Chatty manages the entire lifecycle of an isolated companion container:

  • Hermetic Environment: Isolates network, process, and PID namespaces while preventing host filesystem pollution.
  • Persistent Workspace Containers: Companion containers are named deterministically per workspace (chatty-<folder>-<hash>). Any packages installed by the agent or user (sudo apt install, pip install, tools, compilers) persist across chat sessions and survive host reboots.
  • Resource Management: When exiting Chatty, the container is cleanly stopped (docker stop) to release host CPU and RAM without deleting its filesystem layers. On the next session, Chatty restarts it in ~0.2s.
  • Volume Mount: Mounts the host sandbox directory directly into /workspace inside the container (-v <host_sandbox>:/workspace:rw).
  • User & Environment Matching:
    • Runs commands using the host user's UID and GID, ensuring all files created inside the container are owned by your host user.
    • Sudo is pre-configured with NOPASSWD inside the container so the LLM or user can install system dependencies.
    • User binaries (~/.local/bin) and project virtual environments (/workspace/.venv/bin) are prioritized on PATH.
  • Interactive Container Command (/docker):
    • Run arbitrary shell commands directly inside the companion container: /docker <command> (or /container <command>).
    • Example: /docker pytest, /docker sudo apt update, /docker python3 -m pip install ....
    • Reset container to a pristine state: /docker reset.
  • Resetting & Ephemeral Containers:
    • --docker-reset: Recreate the container from the base image on startup.
    • --docker-ephemeral: Run as a throwaway container that is deleted immediately upon session exit.
  • Process Lifetime & Background Tasks: Commands taking longer than 10 seconds automatically transition to background tasks. Chatty tracks process IDs inside the container (/tmp/<task_id>.pid) to guarantee that terminating a background task cleanly terminates the remote process tree without leaving orphaned processes.
  • Automatic Image Management:
    • Built-in user-specific image tag (chatty-sandbox:<user>) built from Chatty's default Dockerfile template (Debian Bookworm with Python, pip, modern pytest, C/C++ compilers, and development tools).
    • Custom Dockerfile: Point to a custom Dockerfile via --dockerfile <path>.
    • Rebuilding: Force a rebuild using --docker-build (automatically recreates the container to use the new image).
    • Custom Image: Use an existing image tag via --docker-image <tag>.
  • Custom Docker Host: Specify a custom Docker endpoint (e.g. TCP forwarder, rootless Docker, Colima, OrbStack, or Podman socket) via --docker-host <endpoint>:
    chatty --docker-host tcp://127.0.0.1:2375
    chatty --docker-host unix:///run/user/1000/docker.sock
    

    Tip (Bridging into unprivileged containers or sandboxes with socat): If Chatty is running inside an isolated sandbox or container that shares the host network but does not have /var/run/docker.sock mounted (such as a Bubblewrap sandbox), you can forward the Docker socket to localhost on the host machine:

    # Run on host:
    socat TCP-LISTEN:2375,bind=127.0.0.1,reuseaddr,fork UNIX-CLIENT:/var/run/docker.sock &
    

    Then connect Chatty from inside the sandbox using:

    chatty --docker-host tcp://127.0.0.1:2375
    
  • Host Path Translation (HOST_PATH_MAP): When Chatty runs inside an outer container or sandbox namespace (such as Bubblewrap) and connects to a Docker daemon running on the host, volume mount sources must be specified using the host's physical paths rather than sandbox-internal paths. Set the HOST_PATH_MAP (or CHATTY_HOST_PATH_MAP) environment variable to translate prefixes:
    export HOST_PATH_MAP="/sandbox/path=/host/path:/other/sandbox=/other/host"
    
    Multiple mappings can be delimited by colons (:), semicolons (;), or commas (,). Longer and more specific prefixes automatically take precedence over parent paths.
  • Container Lifecycle & Pruning: Ephemeral containers are tagged with chatty.ephemeral=true and pruned automatically on startup, while persistent workspace containers are retained until explicitly reset.

4. Kernel-Level Linux Landlock Sandboxing

On Linux (kernel version 5.13+), Chatty provides transparent, compile-on-demand process isolation using the Linux Landlock LSM (Linux Security Module).

Compilation Flow

When a chatbot session is initialized (see ChatbotSession), Chatty checks if:

  1. The operating system is Linux.
  2. GCC or Clang is installed.

If these conditions are met, compile_landlock_binary builds the C-based wrapper helper landlock_exec.c into an executable binary landlock_exec. The binary is cached in the package directory or under the user's cache folder (~/.cache/chatty/) to avoid compilation overhead on subsequent startup.

Restrictive Access Rules

When executing a shell command via run_command, the execution argument is wrapped using wrap_command_with_landlock, transforming it into:

landlock_exec --ro / --rw <sandbox_dir> --rw <temp_dir> -- /bin/sh -c "<command>"

The landlock_exec binary interacts with the Linux kernel to apply rules before spawning the target process:

  • Read-Only Paths (--ro): Allows reading from / (the root filesystem). This enables reading standard system executables, Python runtimes, shared libraries (/lib, /usr/lib), and general command dependencies.
  • Read-Write Paths (--rw): Specifically permits file writes, directory creation, and removals only inside the target <sandbox_dir> and the system's temporary directory. Any attempts to write elsewhere on the filesystem will fail with a Permission denied error.
  • No New Privileges: Configures prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) so that processes cannot escalate privileges.
  • Kernel Enforcement: Enforces the ruleset using the landlock_restrict_self system call, sealing the sandbox rules for the current process and all future sub-processes.

5. Out-of-Sandbox Path Whitelisting

To allow the chatbot to access files or directories outside the sandboxed folder:

  • Default Permissions: By default, the system temporary directory (/tmp / tempfile.gettempdir()) is included in the Read-Write whitelist to allow temporary file operations matching the sandbox environment.
  • CLI Startup Whitelist: Use the --whitelist (or -w) option to whitelist paths at startup.
    chatty -w /usr/include:ro -w /home/user/project
    
    Paths default to Read-Only (ro) unless suffixed with :rw (Read-Write). Whitelisted paths are mounted into Docker companion containers or passed to Landlock accordingly.
  • Interactive Whitelisting: If the agent attempts to read or write a file outside the sandbox that is not whitelisted, Chatty will prompt you interactively:
    • [y]es: Allow access for this operation once.
    • [n]o: Deny access.
    • [a]lways: Whitelist the specific file for the rest of the session.
    • [p]arents: Show a menu to select and recursively whitelist a parent directory.
  • Session Management: Use the /whitelist (or /permissions) slash command to inspect or manage whitelisted paths on the fly.

Extending Chatty with Skills

Skills are modular system prompt extensions and runbooks that give the LLM custom domain knowledge. Under the standard, a skill is structured as a directory containing a required SKILL.md file (for example, see skills/greetings/SKILL.md) and optional helper subfolders:

skills/database_guidelines/
├── SKILL.md          # Required: Main instruction file with YAML frontmatter
├── scripts/          # Optional: Helper scripts and utilities
├── examples/         # Optional: Reference implementations
├── resources/        # Optional: Additional assets or templates
└── references/       # Optional: Detailed documentation or manuals

SKILL.md Structure

The SKILL.md must start with YAML frontmatter containing the name and description fields:

---
name: database-operations
description: Instructions for SQL query formatting and schemas.
---
Always format queries in uppercase... (Rest of system guidelines)

Discovery Locations

Chatty automatically discovers skills and plugins by searching recursive and machine-local customization roots:

  1. Workspace Customizations: Searches for folders named .agents/, .agent/, _agents/, _agent/, or .chatty/ by walking up parent directories from the current working directory to the repository root.
  2. Global Customizations: Loads customizations globally from ~/.chatty/config/.
  3. Built-in Package Skills: Automatically loads default skills packaged with Chatty.
  4. Configuration Manifests: Explicitly registers additional paths using skills.json and plugins.json configs placed in customization roots.

Progressive Disclosure

To conserve LLM context window size, Chatty uses progressive disclosure:

  • By default, only the names and descriptions of all discovered skills are injected into the system instructions.
  • The full content of a skill is loaded into context only when explicitly activated.
  • If a skill is running in static mode (or configured to load permanently), all skills can be loaded statically on initialization.

The /skill command

  • /skill: Lists all available skills and those currently explicitly loaded.
  • /skill name1 name2: Explicitly activates one or more skills.
  • /skill clear: Clears all explicitly loaded skills. Loaded skills persist through session clears (via /clear).

Context Optimization

To operate efficiently over long conversations, Chatty implements two main context optimization mechanisms:

1. Smart History Pruning

Before sending messages to the LLM, the prune_history method limits the total context:

  • Old tool outputs exceeding --max-history-tool-chars characters are truncated in memory and annotated with a [TRUNCATED] note.
  • The latest messages (configured via --history-keep-messages) are kept fully raw to ensure the model retains precise local context.

2. Prompt Caching

When --prompt-caching is explicitly enabled or when using static skills with OpenRouter, Chatty injects cache_control: {"type": "ephemeral"} metadata parameters:

  • Applied to the system prompt message.
  • Applied to the tools schema structure.
  • Applied to the last two messages in the conversation queue. This helps minimize token costs and reduces API response latencies for compatible model endpoints.

Logging & Diagnostics

Chatty records session activity in a log file (default: chatty.log). The logging mechanism (configured in setup_logging) uses the GlogFormatter to output in standard Google logging syntax:

Lyyyymmdd hh:mm:ss.uuuuuu process file:line] message

  • L: Level identifier letter (D for Debug, I for Info, W for Warning, E for Error, F for Critical/Fatal).
  • yyyyymmdd hh:mm:ss.uuuuuu: Precise timestamps.
  • process: OS Process ID.
  • file:line: Source code location reporting the logging output.

To disable file logging, run with --log-file "".


Testing

Chatty comes with a comprehensive unittest suite located in tests/. You can execute tests from the project root:

pytest
# OR
python3 -m unittest discover tests

Metadata

Release files for chatty-agent 0.5.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for chatty-agent 0.5.4
File Size Uploaded Provenance Actions
chatty_agent-0.5.4.tar.gz 229.2 kB Without provenance Details for chatty_agent-0.5.4.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for chatty-agent 0.5.4
File Interpreter ABI Platform Actions
chatty_agent-0.5.4-py3-none-any.whl Python 3 none any Details for chatty_agent-0.5.4-py3-none-any.whl

Total release size: 384.8 kB

Release files / chatty_agent-0.5.4.tar.gz

Download URL chatty_agent-0.5.4.tar.gz
Size 229.2 kB
Tags Source
SHA-256 checksum
How to use checksums
22aad696fae584b91632a15c6db99e7a1a9e6a160b4445a3d58d2ff0f3cbea73
BLAKE2b-256 checksum
How to use checksums
e01bcf2c5b91554601bf97686ea70ee7c59950721bae0639ad96911556234ea3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Release files / chatty_agent-0.5.4-py3-none-any.whl

Download URL chatty_agent-0.5.4-py3-none-any.whl
Size 155.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
90e1e019c12a84eac29823a5afe437e4fbaf634a0b426c321b7ba474bae4979b
BLAKE2b-256 checksum
How to use checksums
821248236bf508e5fa0dd97759c8ac849d71f183cd0eb682f86fde0c09294f1c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Security for chatty-agent 0.5.4

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page