██████╗ ██╗ █████╗ ██╗██╗
██╔════╝ ██║ ██╔══██╗██║██║
██║ ██║ ███████║██║██║
██║ ██║ ██╔══██║██║██║
╚██████╗ ███████╗██║ ██║██║██║
╚═════╝ ╚══════╝╚═╝ ╚═╝╚═╝╚═╝
(CLAII)
CLAII (pronounced “clay”) is a command-line–first AI coding agent that can:
- Inspect and navigate your project files
- Read file contents
- Write / overwrite files
- Execute Python code inside a sandboxed working directory
- Iterate in an agent loop using tool calls (function calling) until a task is done
- Use a local knowledge base and lightweight memory to stay context-aware
It’s designed as a small, hackable core that you can extend with more tools, providers, and agent behaviors over time.
CLAII calls an LLM in a loop, planning tool calls step-by-step until it can give a final answer or finishes a sequence of edits/tests.
get_files_info– list files & directories with size andis_dirget_file_content– read file contents with a max-length guard (MAX_FILE_CHARS)write_file– write/overwrite files (within a permitted working dir)run_python_file– execute Python scripts with timeout and output capture
All tools are restricted to a configured working directory (by default ./calculator) to avoid the agent wandering across your machine.
kb/folder under the working directory@kb/<path>– inline knowledge-base content directly into the prompt@file:<path>– hint CLAII to inspect a specific project file viaget_file_content
- Stores a compressed conversation history in
.claii_memory.jsonper project - Can be disabled with
--no-memory - History pruning can be toggled via
--no-prune
A small calculator app (calculator/) that CLAII can read, modify, and run—used as a testbed for automated bug fixing and refactoring.
Run claii "your prompt here" and get greeted with the CLAII banner before the agent spins up.
Intended directions for the extended AgencySwarm / CLAII version:
Support multiple backends (e.g. Google Gemini, OpenAI, Anthropic, local LLMs) via a simple config/CLI switch, with a unified tool-calling interface exposed to the agent.
- Store summaries, decisions, and architectural notes per project
- Offer commands to inspect/prune/clear memory explicitly
- Register new tools (e.g. Neo4j via MCP, HTTP APIs, git operations)
- Auto-register them via a simple
functions/convention and schema declarations
- Specialized agents: bug-fixer, refactorer, doc-writer, test-runner, etc.
- Parallel operations on different files/directories with a coordination layer
- KB-aware planning (“read design docs first, then refactor”)
- Structured KB summaries and embedding-based retrieval
- Color-coded input/output and tool traces
- Optional diff previews when files are modified
- “Quiet” and “debug” modes for different levels of verbosity
Current high-level layout:
claii/
__init__.py
cli.py # CLI entrypoint (prints logo, parses args, calls run_agent)
agent.py # Core agent loop + function dispatch + memory + @mentions
memory.py # Load/save compressed conversation history
config.py # Provider config (CLAII_PROVIDER, CLAII_MODEL)
providers.py # GeminiProvider and future multi-provider abstractions
functions/
__init__.py
config.py # e.g. MAX_FILE_CHARS / function-level config
get_files_info.py # get_files_info(...) + schema_get_files_info
get_file_content.py # get_file_content(...) + schema_get_file_content
write_file.py # write_file(...) + schema_write_file
run_python.py # run_python_file(...) + schema_run_python_file
get_kb_file.py # get_kb_file(...) + schema_get_kb_file
calculator/
__init__.py
main.py # Calculator CLI app (demo project)
tests.py # Unit tests for calculator
main.txt # Example text file
README.md
pkg/
__init__.py
calculator.py
render.py
morelorem.txt
pyproject.toml
README.md
.env.example # Example environment file (optional)
.claii_memory.json # Created at runtime (per-project memory)
At a high level, the agent is instructed along these lines:
- List files and directories
- Read file contents
- Execute Python files with optional arguments
- Write or overwrite files
- Keep paths relative to the working directory
- Use tools instead of guessing file contents
- Make a plan before making changes
- Validate changes by running tests when available
- Use
get_files_infoto discover relevant files - Use
get_file_contentto inspect code - Describe a brief plan in natural language
- Use
write_fileto apply focused changes - Use
run_python_fileto run tests or scripts to verify
@kb/<path>→ treated as a reference tokb/<path>under the working directory@file:<path>→ treated as a hint to inspect that project file viaget_file_content
The agent loop keeps calling the provider’s generate(...) method until:
- There are no more tool calls requested, and
- The model returns non-empty final text.
Requires Python 3.11+.
# Clone the repo
git clone git@github.com:agencyswarm/CLAII.git
cd CLAII
# Create & activate a virtualenv (recommended)
python -m venv .venv
source .venv/bin/activate # on Windows: .venv\Scripts�ctivate
# Install in editable/dev mode
pip install -e .
# Run once to verify the CLI is installed
claii --help # (future: help text; for now, just try a prompt)Core dependencies (declared in pyproject.toml):
google-genai– Gemini API clientpython-dotenv– loadGEMINI_API_KEYand other env vars
Create a .env file in the project root with at least:
GEMINI_API_KEY=your_gemini_api_key_hereCurrent provider abstraction lives in claii/providers.py:
GeminiProviderwrapsgoogle-genaiand handles:- API key loading (
dotenv) - Model selection (
gemini-2.0-flash-001by default)
- API key loading (
Optional future configuration (already scaffolded via claii/config.py):
CLAII_PROVIDER=google-genai
CLAII_MODEL=gemini-2.0-flash-001At the moment, get_provider() simply returns a GeminiProvider, but the config class is in place to add more providers later.
Once installed (and your venv is active):
claii "explain how the calculator works"You should see:
- The CLAII ASCII logo
- Tool call lines (e.g.
Calling function: get_files_info({...})) - A final explanation
The current CLI is wired like this:
claii "<prompt>" [--verbose] [--no-memory] [--no-prune]-
--verbose
Prints tool call arguments and raw tool results (useful for debugging). -
--no-memory
Disables loading/saving.claii_memory.jsonfor the current project.
The agent works just on the current prompt + steps in this run. -
--no-prune
Disables pruning of message history before saving.
By default, only the lastMAX_MEMORY_MESSAGES(e.g. 200) are kept.
# Normal run, memory enabled and pruned
claii "fix the bug where 3 + 7 * 2 returns 20 instead of 17"
# Debug everything, but do not persist history
claii "run the calculator tests" --verbose --no-memory
# Long-running debugging session, keep full history
claii "help me refactor calculator/pkg/calculator.py" --no-pruneUnder the working directory (default calculator/), you can create:
calculator/
kb/
design.md
architecture/decisions.md
lang/agent-architecture.md
Use them in prompts like:
# Inline KB context from kb/design.md
claii "Using @kb/design.md, refactor the calculator to follow the design guidelines."
# Hint to a specific project file
claii "Based on @kb/lang/agent-architecture.md, review @file:calculator/pkg/calculator.py and suggest improvements."-
@kb/<path>-
Matches
KB_PATTERN = r"@kb/([^\s]+)" -
CLAII expands it into inline text:
Below is the content of knowledge base file "kb/<path>": --- KB START [<path>] --- ... file contents (truncated if very long) ... --- KB END [<path>] ---
-
-
@file:<path>-
Matches
FILE_PATTERN = r"@file:([^\s]+)" -
CLAII does not auto-load the file, but rewrites it as a hint:
"<path>" (project file reference; use get_file_content with file_path="<path>")
-
Other uses of @ (emails, social handles, normal text) are not touched, because only these specific patterns are recognized.
List directory contents:
claii "what files are in the root of the calculator project?" --verboseRead a file:
claii "read the contents of calculator/main.py"Write a file (within working dir):
claii "create a new file calculator/notes.txt summarising what the calculator does"Run tests:
claii "run the calculator tests in calculator/tests.py"Classic bugfix demo:
claii "fix the bug where '3 + 7 * 2' evaluates to 20 instead of 17 in the calculator"Memory is implemented in claii/memory.py as a simple JSON log:
- File:
.claii_memory.jsonin the project root - Schema: list of
{ "role": "...", "text": "..." }records - Only role and concatenated text parts are persisted to keep it compact
On startup:
If memory is enabled (default), CLAII calls:
messages = load_memory(project_root)Then it appends the current (possibly expanded) user prompt:
messages.append(
types.Content(role="user", parts=[types.Part(text=expanded_prompt)])
)On shutdown:
If memory is enabled, it optionally prunes the messages via _prune_messages and then:
save_memory(project_root, messages)You can always disable memory for a run with --no-memory, or prevent pruning with --no-prune.
Provider abstraction lives in claii/providers.py:
class GeminiProvider:
def __init__(self, model_name: str = "gemini-2.0-flash-001") -> None:
load_dotenv()
api_key = os.getenv("GEMINI_API_KEY")
...
self.client = genai.Client(api_key=api_key)
self.model_name = model_name
def generate(self, *, messages, tools, system_prompt):
return self.client.models.generate_content(
model=self.model_name,
contents=messages,
config=types.GenerateContentConfig(
tools=tools,
system_instruction=system_prompt,
),
)The agent only calls:
provider = get_provider()
response = provider.generate(
messages=messages,
tools=[tools],
system_prompt=system_prompt,
)Future additions:
OpenAIProviderAnthropicProviderLocalProvider(e.g. vLLM, LM Studio, etc.)
Each just needs to implement the same generate(...) signature.
Some directions you can take this project:
Add modules under functions/ and register them in agent.py:
functions/git_tools.pyfunctions/http_request.pyfunctions/test_runner.py
Each should export:
your_tool(...)– pure Python string-in/string-outschema_your_tool–types.FunctionDeclarationdescribing its parameters
Then include them in:
_build_tools()– add tofunction_declarations=[...]_call_function()– extendfn_map = { ... }
Build a higher-level controller that:
- Spawns multiple
run_agentcalls with different system prompts/roles - Shares a common memory file or passes summaries between agents
Orchestration ideas:
- Planner → Implementer → Tester → Reviewer
- Long-running refactor pipelines
- Color output using
richorcolorama - Add a
--diffflag that prints a minimal diff whenwrite_filechanges a file - Add
--plan-onlymode where the agent only inspects and proposes a plan without writing files
Copyright (C) Swarmic LLC. All Rights Reserved.