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
/oracleslash 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_controltagging to maximize prompt caching efficiency for OpenRouter. - Google-Style Logging: Standardized process tracking via custom
glogstyling.
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). |
--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. |
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. |
/repo_map / /map |
[refresh] |
Displays the Tree-Sitter / PageRank repository map. |
/config |
[key=value] |
List, view, or change configuration parameters live. |
/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. |
/docker / /container |
[<command>|reset] |
Inspect companion container status, execute commands inside the container, or reset its state. |
/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(supportskandmmultipliers). - Size Filters (Ollama):
size<5g,size<=10gb,size>1g(supportsg,m,kunits). - 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-itemsto prevent token flooding.read_file: Reads text files. Accepts optionalstart_lineandend_lineparameters (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 directsearch/replaceparameters). 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, adry_runsimulation mode, and returns applied unified diffs.format_file: Styles source files using appropriate project formatters (black/ruff/yapffor Python,clang-formatfor C/C++,prettierfor 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).
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 utilizingpytesseractandpdf2imagedynamically 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_KEYandGOOGLE_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).
- Tavily: Set
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, andtail_linesparameters 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).
- Safety Restrictions: Monitored by safety checks to block commands that attempt directory escapes, or attempt to circumvent tool guidelines by calling commands like
check_background_command: Inspects status, reads output, and checks exit status code of background processes using theirtask_id.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.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:- Docker companion container: Selected if Docker tools are installed and the daemon is reachable.
- Linux Landlock: Selected if Docker is unavailable, the host is Linux (kernel 5.13+), and Landlock binary compiles.
- Strict Sandboxing Check: If neither Docker nor Landlock is available and a
--sandboxdirectory 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
/workspaceinside 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
NOPASSWDinside the container so the LLM or user can install system dependencies. - User binaries (
~/.local/bin) and project virtual environments (/workspace/.venv/bin) are prioritized onPATH.
- 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.
- Run arbitrary shell commands directly inside the companion container:
- 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>.
- Built-in user-specific 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.sockmounted (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
- Container Lifecycle & Pruning: Ephemeral containers are tagged with
chatty.ephemeral=trueand 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:
- The operating system is Linux.
- 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 aPermission deniederror. - 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_selfsystem 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:
- 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. - Global Customizations: Loads customizations globally from
~/.chatty/config/. - Built-in Package Skills: Automatically loads default skills packaged with Chatty.
- Configuration Manifests: Explicitly registers additional paths using
skills.jsonandplugins.jsonconfigs 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-charscharacters 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 (Dfor Debug,Ifor Info,Wfor Warning,Efor Error,Ffor 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:
python3 -m unittest discover tests
Metadata
Release files for chatty-agent 0.5.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| chatty_agent-0.5.3.tar.gz | 209.5 kB | Without provenance | Details for chatty_agent-0.5.3.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| chatty_agent-0.5.3-py3-none-any.whl | Python 3 | none | any | Details for chatty_agent-0.5.3-py3-none-any.whl |
Total release size: 354.3 kB
Release files / chatty_agent-0.5.3.tar.gz
| Download URL | chatty_agent-0.5.3.tar.gz |
|---|---|
| Size | 209.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
17b7bdd22299c04b8e02447d650cab6ae5388bda278ce80d26b3637e2bd9b7a9
|
|
BLAKE2b-256 checksum How to use checksums |
fc7b0ad6ae5e3fc00512ecc44f9fef11dabbb75e812ef981d5621d42dc0346c3
|
| 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.3-py3-none-any.whl
| Download URL | chatty_agent-0.5.3-py3-none-any.whl |
|---|---|
| Size | 144.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8ef173b248e00308f5e56c6f391ea6eb06844f7f86095ab53a5467863cb7d6a1
|
|
BLAKE2b-256 checksum How to use checksums |
153e42bf0a3493b2b28019f1d57ba11a10e839b50a737810055b8f8a764bcc5a
|
| 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.3
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.