Metadata-Version: 2.4
Name: xtype-agent
Version: 1.0.0
Summary: CLI multi-agent autonomous coding assistant — orchestrator, planner, analyst, coder, reviewer powered by LangGraph and OpenAI-compatible APIs
Project-URL: Homepage, https://github.com/abhishek-talwar/xtype-agent
Project-URL: Documentation, https://github.com/abhishek-talwar/xtype-agent#readme
Project-URL: Repository, https://github.com/abhishek-talwar/xtype-agent
Project-URL: Issues, https://github.com/abhishek-talwar/xtype-agent/issues
Project-URL: Changelog, https://github.com/abhishek-talwar/xtype-agent/releases
Author-email: Abhishek Talwar <abhishektalwar@zohomail.in>
License: MIT
License-File: LICENSE
Keywords: agent,ai,cli,coding,langgraph,llm,multi-agent,ollama,openai,openai-compatible
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Build Tools
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.11
Requires-Dist: httpx>=0.27.0
Requires-Dist: langgraph>=0.2.0
Requires-Dist: openai>=1.40.0
Requires-Dist: pydantic>=2.6.0
Requires-Dist: pyyaml>=6.0.1
Requires-Dist: rich>=13.7.0
Requires-Dist: typer>=0.12.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: ruff>=0.4.0; extra == 'dev'
Provides-Extra: figlet
Requires-Dist: pyfiglet>=1.0.0; extra == 'figlet'
Description-Content-Type: text/markdown

# XTypeAgent — Open-Source Multi-Agent Coding Assistant

> Built by [Abhishek Talwar](https://github.com/abhishek-talwar) — A terminal-native autonomous coding teammate powered by [LangGraph](https://github.com/langchain-ai/langgraph) and OpenAI-compatible APIs.

---

## Table of Contents

1. [What is XTypeAgent?](#what-is-xtype)
2. [How It Thinks — The 5-Agent Architecture](#how-it-thinks--the-5-agent-architecture)
3. [Key Features Explained](#key-features-explained)
4. [Supported Providers](#supported-providers)
5. [Quick Start](#quick-start)
6. [Commands Reference](#commands-reference)
7. [Slash Commands (REPL)](#slash-commands-repl)
8. [Options Reference](#options-reference)
9. [Environment Variables](#environment-variables)
10. [Global Install / Uninstall](#global-install--uninstall)
11. [How Configuration Works](#how-configuration-works)
12. [How Memory Works](#how-memory-works)
13. [How AGENTS.md Works](#how-agentsmd-works)
14. [Safety Model](#safety-model)
15. [Development](#development)

---

## What is XTypeAgent?

XTypeAgent is a CLI tool that acts like a **senior software engineering teammate** living in your terminal. Unlike a simple chatbot, it uses a graph-based multi-agent system where 5 specialist agents collaborate to understand your codebase, plan a solution, implement it, and review the results — all autonomously.

Think of it as having a **mini engineering team** on call:
- An **orchestrator** who decides what needs to be done next
- A **planner** who maps out the approach
- An **analyst** who understands your codebase
- A **coder** who writes the code
- A **reviewer** who checks quality

All running inside a **LangGraph** workflow that routes between them intelligently.

---

## How It Thinks — The 5-Agent Architecture

XTypeAgent isn't one monolithic AI. It's a **directed graph** of specialized agents, each with a distinct role and prompt. Here's how they collaborate:

```
User Input
    │
    ▼
┌────────────────┐
│  Orchestrator  │ ◄── Routes to the right specialist
└───────┬────────┘
        │
        ├────────────────────────────┐
        ▼            ▼              ▼         ▼
   [planner]    [analyst]     [coder]   [reviewer]
        │            │              │         │
        └────────────┴──────┬──────┴─────────┘
                             │
                        [end / respond]
```

### The Orchestrator (The Manager)
The orchestrator reads every message and decides **which specialist should act next**. It responds with a single word — `planner`, `analyst`, `coder`, `reviewer`, or `end`. It has two modes:

- **Social mode**: If you say "hello" or "how are you?", it routes to planner which gives a brief 2-3 sentence greeting, then routes to `end`. It won't dump a technical plan on you for a casual greeting.
- **Work mode**: For actual tasks, it starts with `planner`, routes through `analyst` for codebase understanding, `coder` for implementation, and `reviewer` for quality checks.

### The Planner
The planner receives the user's goal and drafts a structured approach. It breaks the problem into steps, identifies what's needed from the codebase, and sets the direction. Think of it as the architect who draws the blueprint.

### The Analyst
The analyst dives into your workspace — reads files, explores structure, understands conventions, and builds a mental model of your project. It doesn't write code; it **understands what's there** so the coder can write code that fits.

### The Coder
The coder does the actual implementation — creates files, edits code, runs tools, and executes approved shell commands. It follows the plan from the planner and the context from the analyst.

### The Reviewer
The reviewer checks the coder's work — looks for bugs, style issues, missing edge cases, and validates the approach. It gives feedback that loops back to the coder if needed.

---

## Key Features Explained

### Token Streaming
As the model generates text, XTypeAgent streams each token to your terminal **in real time**. You see the response as it's being written, like watching someone type. This works through a `StreamPrinter` class that registers a callback with the LangGraph node. Every time a token arrives from the API, it's immediately printed — no waiting for the full response.

> **Note on REPL**: During interactive REPL sessions (`xtype-agent start`), streaming is intentionally disabled. Instead, a **thinking animation** plays while the background thread runs the graph. Clean output is printed only when the agent finishes. This prevents duplicate/racy output from interleaving with the animation.

### Workspace-Bounded Tools
All file operations, git commands, and glob searches are **confined to your project directory** (`--workspace`). The `ToolContext` wraps every tool call and validates that no path escapes outside the workspace root using `_resolve_under_root`. This means:
- Read/write/delete operations cannot touch files outside the workspace
- Git operations stay within the project
- Glob patterns only match files inside the project

This is enforced at the tool layer, not at the prompt level — so even a rogue model can't escape.

### Shell Access (Allowlisted)
Shell execution is **disabled by default**. When you pass `--allow-shell`, XTypeAgent enables a curated list of safe commands: `git`, `uv`, `python`, `pytest`, `ruff`, `npm`, `pnpm`, `yarn`, `cargo`, `go`. Complex shell metacharacters (`;`, `|`, `&`, `$`, etc.) are rejected. No shell scripts, no pipes, no redirects.

### Memory Persistence
XTypeAgent remembers things across sessions using a **SQLite vector store** (see [How Memory Works](#how-memory-works) below).

### AGENTS.md Injection
If a `AGENTS.md` file exists in your workspace, its contents are injected into **every agent's system prompt** — automatically. The wizard asks if you want one created. It's a way to tell XTypeAgent about your project's conventions, build commands, and rules without editing code (see [How AGENTS.md Works](#how-agentsmd-works) below).

### REPL Mode (`xtype-agent start`)
An interactive shell where you can have **multi-turn conversations** with the agent team. Unlike `xtype-agent run TASK` which is fire-and-forget, the REPL:
- Keeps a session ID for memory continuity
- Shows a thinking animation while agents work
- Supports slash commands (`/help`, `/model`, `/models`, `/swap`, `/context`, `/clear`, `/retry`, `/status`)
- Remembers context within the session
- Lets you swap models on the fly without re-initing

### Multi-Provider Support
XTypeAgent isn't locked to one provider. The `ProviderDef` registry in `config.py` defines 8 providers, each with their own base URL, API key environment variable, docs URL, and model listing logic. The wizard (`xtype-agent init`) walks you through all of them, fetches their live model catalog, and lets you pick your default and fast/routing models.

### API Key Masking
During `xtype-agent init`, when you paste or type an API key, it's **masked with `*`** as you type — character by character. This works using `msvcrt` on Windows and `termios` on Unix. Keys are stored in your user config directory only, never in the project repo.

### Graceful Degradation
Ollama Cloud doesn't support `/v1/embeddings`. When memory persistence tries to embed text and the API returns an error, it silently falls back to **recency-based recall** (most recent memories instead of semantic similarity). The feature doesn't break — it just works a bit differently.

---

## Supported Providers

| Provider | Label | API Key Env Var | Base URL |
|---|---|---|---|
| `ollama` | Ollama Cloud | `OLLAMA_API_KEY` | `https://ollama.com/v1` |
| `openai` | OpenAI | `OPENAI_API_KEY` | `https://api.openai.com/v1` |
| `openrouter` | OpenRouter | `OPENROUTER_API_KEY` | `https://openrouter.ai/api/v1` |
| `groq` | Groq | `GROQ_API_KEY` | `https://api.groq.com/openai/v1` |
| `minimax` | MiniMax | `MINIMAX_API_KEY` | `https://api.minimax.chat/v1` |
| `anthropic` | Anthropic | `ANTHROPIC_API_KEY` | `https://api.anthropic.com/v1` |
| `deepseek` | DeepSeek | `DEEPSEEK_API_KEY` | `https://api.deepseek.com/v1` |
| `nvidia` | NVIDIA NIM | `NVIDIA_API_KEY` | `https://integrate.api.nvidia.com/v1` |
| `custom` | Custom OpenAI-Compatible | `OPENAI_API_KEY` | User-specified |

All providers use the **OpenAI chat completions API format** (the `v1/chat/completions` endpoint). This means any API that speaks OpenAI-compatible JSON works out of the box.

---

## Quick Start

```bash
# Install globally (recommended)
pip install xtype

# Or from source
pip install -e ".[dev]"

# First-time setup — choose your provider, pick models, set API key
xtype-agent init

# Interactive REPL — talk to your agent team
xtype-agent start

# Run a one-shot task
xtype-agent run "Add dark mode to my React app"

# Quick planning only
xtype-agent plan "Design the auth system for my backend"
```

---

## Commands Reference

| Command | What it does |
|---|---|
| `xtype` | Shows the ASCII banner, version, and available commands |
| `xtype-agent init` | Interactive setup wizard — choose provider, fetch models, set API key, optionally create `AGENTS.md` |
| `xtype-agent doctor` | Diagnostics: shows your config, checks which models are available from your current provider |
| `xtype-agent run TASK` | Fires up the full 5-agent orchestration loop for `TASK`. Streams tokens to the terminal. |
| `xtype-agent plan TASK` | A single-shot planner call — good for quickly drafting an approach before a full run |
| `xtype-agent start` | Launches the interactive REPL with persistent session context and slash commands |
| `xtype-agent -v` / `--version` | Print version and ASCII banner |

---

## Slash Commands (REPL)

When inside `xtype-agent start` (the REPL), these commands are available:

| Command | What it does |
|---|---|
| `/help` | Show this list of slash commands |
| `/model` | Interactive model picker — fetches the provider's live catalog and lets you pick by number |
| `/model MODEL_NAME` | Switch model by name directly (e.g. `/model gpt-4o-mini`) |
| `/models` | List all available models from the current provider |
| `/swap` | Swap the default and fast/routing models without re-configuring |
| `/context` | Show recent memory entries from this session (what XTypeAgent remembers) |
| `/clear` | Clear REPL conversation history |
| `/retry` | Re-run the last task |
| `/status` | Show session ID, workspace, current model, provider, theme, shell status |

---

## Options Reference

| Option | Default | What it does |
|---|---|---|
| `--workspace`, `-w` | `.` (current dir) | Root directory for all file/git operations. Acts as a **sandbox boundary**. |
| `--allow-shell` | `false` | Enable allowlisted shell commands. **Disabled by default for safety.** |
| `--max-turns` | `24` | Maximum number of agent routing loops before the graph terminates. Prevents infinite loops. |
| `--version`, `-v` | — | Print version and exit |

---

## Environment Variables

These let you override the config file or run XTypeAgent without running `init`:

| Variable | What it does |
|---|---|
| `XTYPE_AGENT_PROVIDER` | Provider name (`ollama`, `openai`, `openrouter`, `groq`, `minimax`, `anthropic`, `deepseek`, `nvidia`, `custom`) |
| `XTYPE_AGENT_BASE_URL` | Override the provider's base URL |
| `XTYPE_AGENT_FAST_MODEL` | Separate fast model used by the orchestrator for routing decisions |
| `XTYPE_AGENT_THEME` | CLI theme (`default` or `high`) |
| `OLLAMA_API_KEY` | Ollama Cloud API key |
| `OPENAI_API_KEY` | OpenAI / compatible API key |
| `OPENROUTER_API_KEY` | OpenRouter API key |
| `GROQ_API_KEY` | Groq API key |
| `MINIMAX_API_KEY` | MiniMax API key |
| `ANTHROPIC_API_KEY` | Anthropic API key |
| `DEEPSEEK_API_KEY` | DeepSeek API key |
| `NVIDIA_API_KEY` | NVIDIA NIM API key |

Environment variables **override** the saved config file. This is useful for CI/CD, testing different providers, or running on a remote machine without a config file.

---

## Global Install / Uninstall

### macOS / Linux

```bash
# Install via curl
bash <(curl -sL https://raw.githubusercontent.com/abhishek-talwar/xtype/main/scripts/install-global.sh)

# Or from the repo
bash scripts/install-global.sh

# Uninstall
bash scripts/uninstall-global.sh

# Uninstall and wipe all config (API keys, memory, settings)
bash scripts/uninstall-global.sh --remove-config
```

### Windows (PowerShell)

```powershell
# Install via curl
irm https://raw.githubusercontent.com/abhishek-talwar/xtype/main/scripts/install-global.ps1 | iex

# Or from the repo
.\scripts\install-global.ps1

# Uninstall
.\scripts\uninstall-global.ps1

# Uninstall and wipe all config
.\scripts\uninstall-global.ps1 -RemoveConfig
```

The installer uses **pipx** if available (recommended — keeps the package isolated), falls back to **pip**, and auto-generates an uninstaller script at install time. The uninstaller script knows exactly where the package was installed and removes it cleanly.

---

## How Configuration Works

When you run `xtype-agent init`, the wizard:
1. Asks you to pick a provider from the 8 options
2. Fetches the provider's live model catalog via `GET /v1/models`
3. Lets you pick a **default model** (used by all agents) and an optional **fast model** (used by the orchestrator for routing decisions)
4. Reads your API key (masked as you type) and validates it
5. Saves to `config.yaml` in your **user config directory**:
   - **Linux/macOS**: `~/.config/xtype/config.yaml`
   - **Windows**: `%LOCALAPPDATA%\xtype_agent\config.yaml`

The `XTypeAgentConfig` model reads this file on every command. It also checks environment variables — if a variable like `XTYPE_AGENT_PROVIDER` is set, it overrides the file config. This means you can run XTypeAgent on a different machine or CI environment without a config file, just by setting env vars.

**Legacy migration**: If you have an old config with `ollama_api_key` or `ollama_base_url` fields (from a previous version), `load_config()` automatically migrates them to the new `api_key` / `base_url` fields.

---

## How Memory Works

XTypeAgent has a **session-scoped and cross-session memory system** powered by embeddings + SQLite:

```
Every task in REPL
       │
       ▼
 embed(user_query)
       │
       ▼
 cosine_similarity_search(memory_store.sqlite)
       │
       ▼
 top 3 relevant memories injected as context
       │
       ▼
 Agent responds with memory context
       │
       ▼
 store_memory(user_task + agent_response)
       │
       ▼
 SQLite (persisted across restarts)
```

### The Pipeline

1. **Before each task**, `build_memory_context()` embeds your query using `text-embedding-3-small` and searches the SQLite store for the top 3 semantically similar past entries.
2. **After each task**, `store_memory()` embeds the conversation (your task + agent output) and saves it to the SQLite database.
3. **In the REPL**, `/context` shows you what XTypeAgent remembered from the current session.

### Graceful Degradation
If the provider doesn't support embeddings (like Ollama Cloud), `embed_text()` catches the exception and returns `None`. When that happens, `recall_memories()` falls back to **recency-based recall** — it returns the most recent memories instead of semantically similar ones. The system never breaks; it just degrades to a simpler mode.

### Storage Location
Memory lives in `memory_store.sqlite` inside your user config directory — alongside the config file. Not in your project.

---

## How AGENTS.md Works

If `AGENTS.md` exists in your workspace, every agent's system prompt is assembled as follows:

```
kernel.md (core XTypeAgent identity)
        │
        ▼
AGENTS.md (your project rules — injected here)
        │
        ▼
role.md (e.g. planner.md, coder.md — the specialist prompt)
```

### Example AGENTS.md

```markdown
# XTypeAgent — project rules

- **Build**: `npm run build`
- **Test**: `npm test -- --coverage`
- **Never**: Commit directly to main. Never use `eval()`.
```

The wizard asks if you want one created during `xtype-agent init`. You can also create/edit it manually — it's just a markdown file that gets read at prompt assembly time.

---

## Safety Model

XTypeAgent is designed to be safe to run on your laptop:

| Safety Feature | How it works |
|---|---|
| **File confinement** | `ToolContext` validates every file path stays inside `--workspace` |
| **Git confinement** | Git operations are sandboxed to the workspace |
| **Shell off by default** | `--allow-shell` is required to run any shell commands |
| **Allowlisted commands** | Only `git`, `uv`, `python`, `pytest`, `ruff`, `npm`, `pnpm`, `yarn`, `cargo`, `go` are allowed |
| **No shell metacharacters** | Pipes, redirects, subshells, command substitution are all blocked |
| **API keys in user dir only** | Config and memory live in `~/.config/xtype/` or `%LOCALAPPDATA%\xtype_agent\`, never in the project |
| **401 handling** | Authentication errors show a clear message pointing to `xtype-agent init` |

---

## Development

```bash
# Clone the repo
git clone https://github.com/abhishek-talwar/xtype
cd xtype

# Install in dev mode (includes test dependencies)
pip install -e ".[dev]"

# Run tests
pytest

# Lint with ruff
ruff check src/

# Auto-fix lint issues
ruff check src/ --fix

# Build a wheel package
pip install build
python -m build --wheel
```

The project uses:
- **Ruff** for linting and import sorting (configured in `pyproject.toml`)
- **Pytest** for testing
- **Hatch** for wheel packaging
- **Typer** for the CLI
- **LangGraph** for the agent orchestration graph
- **Rich** for terminal UI (banners, tables, panels, streaming)

### Project Structure

```
src/xtype/
├── cli.py                  # Typer entry point (all commands)
├── repl.py                 # Interactive REPL with slash commands
├── onboarding/
│   ├── config.py          # ProviderDef registry, config load/save
│   └── wizard.py          # Interactive init with masked API input
├── models/
│   └── client.py          # OpenAI-compatible client + streaming
├── graph/
│   ├── build.py           # LangGraph assembly + initial_state
│   ├── state.py           # HiveState TypedDict
│   ├── nodes.py           # 5 agent nodes + tool execution
│   └── context.py         # RunContext (thread-local for tool access)
├── prompts/
│   ├── assembly.py        # assemble_system_prompt() with AGENTS.md
│   └── *.md               # Role prompts (kernel, planner, analyst, etc.)
├── tools/
│   ├── dispatch.py        # Tool call dispatcher
│   └── workspace.py       # File/git tools with sandboxing
├── memory/
│   └── vector_store.py    # SQLite + cosine similarity memory
├── ui/
│   ├── banner.py          # ASCII art banner rendering
│   └── render.py          # StreamPrinter + section output
└── py.typed               # PEP 561 typed package marker
```

---

## License

MIT-compatible — see [LICENSE](LICENSE) for the full terms. Free to use, modify,
and distribute with attribution. No illegal or unethical use. — free to use, modify, and distribute.