Skip to content

dejianwei/Wcode

Repository files navigation

Wcode — Personal AI Coding Agent

Wcode is a personal AI coding agent that runs in your terminal. It's model-agnostic (powered by LiteLLM), extensible via skills and MCP servers, and built for long-running autonomous sessions with fire-and-forget subagents, task management, cron scheduling, and persistent memory.

Architecture

agent.py              — Main orchestrator loop (LLM calls, tool execution, error handling)
├── config.py         — Paths, model selection, MCP server definitions, logging setup
├── tools.py          — Central TOOLS / TOOL_HANDLER registry (21+ tools)
├── utils.py          — Shared helpers (frontmatter parsing, tool_def, safe_path)
│
├── mcp_manager.py    — MCP server lifecycle: async event-loop thread, tool discovery & execution
├── memory.py         — File-based persistent memory (YAML frontmatter + markdown)
├── messaging.py      — Subagent spawning (sync teaching subagent & fire-and-forget async)
│
├── skills.py         — Skill discovery & loading from SKILL.md manifests
├── hooks.py          — Lifecycle hooks (PreToolUse, PostToolUse, Stop) & permission/safety checks
├── background.py     — Background task execution for slow commands (install, build, test)
├── context.py        — Context compaction, summarisation & large-output persistence
│
├── cron_system.py    — Cron-style recurring / one-shot task scheduler with persistence
└── task_system.py    — Task CRUD with dependency tracking & claim/complete workflow

Features

  • Model-agnostic — Uses LiteLLM; swap between OpenAI, Anthropic, DeepSeek, Ollama, and others via the MODEL env var.
  • Persistent memory — File-based memories in .memory/ with YAML frontmatter, relevance-based retrieval via LLM selection, automatic extraction from conversations, and periodic consolidation.
  • Skill system — Drop SKILL.md manifests into skills/<name>/ and they're auto-discovered. Built-in skills include code-review and pdf.
  • MCP support — Launch MCP servers as child processes; tools are auto-discovered and namespaced as mcp__<server>__<tool>. Runs its own asyncio event loop in a daemon thread for seamless sync/async bridging.
  • Subagent spawning — Fire-and-forget async subagents run in background threads and notify the main agent when done (via collect_subagent_results). A synchronous subagent is also available for teaching and quick blocking tasks.
  • Cron scheduler — Recurring or one-shot scheduled tasks via standard 5-field cron expressions. Jobs can be persisted to disk (durable) for survival across restarts.
  • Task system — Create, list, claim, and complete tasks with dependency tracking.
  • Hook systemPreToolUse, PostToolUse, Stop lifecycle hooks for extensibility.
  • Safety layer — Deny-list for dangerous commands (rm -rf /, sudo, shutdown, etc.) + workspace-bound path permission rules with user prompt on risky operations.
  • Background execution — Slow shell commands (installs, builds, tests) are auto-detected and dispatched to background threads; results are injected as XML notifications when complete.
  • Context management — Auto-compaction via LiteLLM's trim_messages, large-output persistence to disk, transcript saving, and LLM-based summarisation for context window recovery.
  • Rich logging — Console output via rich with rotating file handler (10 MB, 5 backups) in logs/wcode.log.

Quick Start

Prerequisites

  • Python 3.12+
  • An API key for your chosen model provider

Setup

# Clone the repo
git clone <repo-url> && cd Wcode

# Create and activate a virtual environment
python -m venv .venv && source .venv/bin/activate

# Install dependencies
pip install -r requirements.txt

# Configure your environment
cp .env.example .env   # or create .env manually (see below)

.env configuration

MODEL=deepseek/deepseek-v4-flash    # LiteLLM model string
DEEPSEEK_API_KEY=sk-...             # or OPENAI_API_KEY, ANTHROPIC_API_KEY, etc.

Other supported providers (examples):

# Ollama (local)
# MODEL=ollama_chat/qwen3.5:4b
# OLLAMA_BASE_URL=http://localhost:11434

# Custom OpenAI-compatible endpoint
# MODEL=gpt-5.4-nano
# BASE_URL=https://api.example.com/v1
# API_KEY=sk-...

Run

python agent.py

Type a question or command at the >> prompt. Type q or exit to quit.

Project Structure

.
├── agent.py                # Main entry point & orchestration loop
├── config.py               # Global configuration, paths, environment, logging
├── tools.py                # Tool registry (21+ tools: bash, file ops, cron, task, messaging, etc.)
├── utils.py                # Shared utilities (frontmatter parser, tool_def, safe_path)
├── mcp_manager.py          # MCP client lifecycle & tool execution (async event-loop thread)
├── memory.py               # Memory CRUD, relevance selection, extraction & consolidation
├── messaging.py            # Subagent spawning (sync & fire-and-forget async)
├── skills.py               # Skill discovery & loading from SKILL.md manifests
├── hooks.py                # Hook system, deny-list & permission checks
├── background.py           # Background task dispatch for slow commands
├── context.py              # Context compaction, summarisation & large-output persistence
├── cron_system.py          # Cron-style scheduler with validation & disk persistence
├── task_system.py          # File-backed task management with dependency tracking
├── requirements.txt        # Python dependencies
│
├── skills/                 # Skill definitions (SKILL.md manifests)
│   ├── code-review/        # Code review skill
│   └── pdf/                # PDF processing skill
│
├── tests/                  # Test suite
│   └── test_task_system.py # Comprehensive tests for task system
│
├── .memory/                # Persistent memory storage (auto-managed)

├── .tasks/                 # Task persistence store
├── logs/                   # Log files (rotating, 10 MB / 5 backups)
│   └── wcode.log
├── .transcripts/           # Conversation transcripts (saved on compaction)
└── .task_outputs/          # Large tool-output persistence

Tools Reference

The agent exposes 17+ tools grouped by domain:

Category Tools
Shell & FS run_bash, run_read_file, run_write_file, run_edit_file, run_glob
Skills run_load_skill
Tasks run_create_task, run_get_task, run_list_tasks, run_claim_task, run_complete_task
Cron run_schedule_cron, run_list_crons, run_cancel_cron
Subagents run_spawn_subagent (sync), run_spawn_teammate (fire-and-forget)
MCP Auto-discovered as mcp__<server>__<tool> (e.g. mcp__fetch__fetch)

Skills

Skills are auto-discovered from subdirectories of skills/. Each skill is a directory containing a SKILL.md file with YAML frontmatter:

skills/
└── my-skill/
    └── SKILL.md    # name, description in frontmatter; body = skill content

The agent lists available skills in its system prompt. Use run_load_skill(name) to load a skill's full content when relevant.

Built-in skills:

  • code-review — Structured code reviews covering security, correctness, performance, maintainability, and testing. Includes common anti-patterns and review workflow guidance.
  • pdf — Comprehensive PDF manipulation guide: merge, split, rotate, watermark, create, extract text/tables, OCR, fill forms, encrypt/decrypt, and extract images using Python libraries (pypdf, pdfplumber, reportlab, pytesseract) and CLI tools (qpdf, pdftotext, pdftk).

MCP Servers

Define MCP servers in config.py under MCP_SERVERS. Each entry specifies a command, arguments, and optional environment variables:

MCP_SERVERS: dict[str, dict] = {
    "fetch": {
        "command": "python",
        "args": ["-m", "mcp_server_fetch"],
    },
    "my_tool": {
        "command": "my-mcp-server",
        "args": [],
        "env": {"API_KEY": "..."},  # optional
    },
}

Tools from each server are exposed as mcp__<server_name>__<tool_name> and auto-discovered at startup via the MCPManager (runs an asyncio event loop in a daemon thread).

Memory System

Memories are stored as individual markdown files in .memory/ with YAML frontmatter:

---
name: my-memory-slug
description: One-line summary
type: user | feedback | project | reference
---

Memory body content here.

An MEMORY.md index file is auto-maintained. The system supports:

  • Relevance-based retrieval — LLM selects relevant memories each turn
  • Extraction — New preferences/constraints are extracted from conversations
  • Consolidation — Periodic merging of duplicates and removal of outdated entries

Subagent System

Wcode supports two subagent modes:

Async subagent (fire-and-forget)

  • Spawn via run_spawn_teammate(name, role, prompt) — returns immediately
  • Runs in a background daemon thread with its own LLM tool loop (max 15 turns)
  • Tool set: bash, read/write/edit files, glob
  • On completion, stores result in a thread-safe dict
  • Main agent collects results via collect_subagent_results() after each turn
  • Results are injected as <subagent_notification> messages

Sync subagent (teaching)

  • Spawn via run_spawn_subagent(description) — blocks until done
  • Same tool set and 15-turn limit as async
  • Best for teaching, quick code search, or small self-contained work

Cron System

Standard 5-field cron expressions with two job types:

  • Recurring — Fire repeatedly (e.g. 0 9 * * * for daily at 9 AM)
  • One-shot — Fire once, then auto-remove
  • Durable — Persisted to .scheduled_tasks.json, survive agent restarts
  • Session — Lost on agent shutdown

Task System

File-backed task management with dependency tracking:

  • Tasks have pendingin_progresscompleted lifecycle
  • Dependencies block task start until all deps are completed
  • Persisted as JSON files in .tasks/

Hook System

Three lifecycle hooks with built-in implementations:

  • PreToolUse — Permission checks (deny-list + rule-based + user prompt)
  • PostToolUse — Tool call logging
  • Stop — Session summary logging

Custom hooks can be registered via register_hook(HookType, callback).

Running Tests

pytest tests/ -v

Current test coverage: comprehensive task system tests covering creation, persistence, dependency resolution, claiming, completion, and edge cases.

Logging

  • Console — Rich-formatted output with timestamps and level indicators
  • File — Rotating file handler (10 MB, 5 backups) at logs/wcode.log
  • Third-party libraries (LiteLLM, httpx, openai, etc.) are suppressed to WARNING level by default

License

MIT

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages