Metadata-Version: 2.4
Name: agent-forge-installer
Version: 0.1.4
Summary: AgentForge — multi-agent Telegram bot framework powered by Claude Code
Author: Martin Rancourt
License: MIT
Project-URL: Homepage, https://github.com/Martin-Rancourt/agentforge
Project-URL: Repository, https://github.com/Martin-Rancourt/agentforge
Project-URL: Bug Tracker, https://github.com/Martin-Rancourt/agentforge/issues
Keywords: telegram,bot,ai,claude,multi-agent,framework
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Communications :: Chat
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: fastapi<1,>=0.116
Requires-Dist: uvicorn<1,>=0.35
Provides-Extra: http
Requires-Dist: requests>=2.28; extra == "http"
Provides-Extra: voice
Requires-Dist: faster-whisper>=1.0; extra == "voice"
Provides-Extra: full
Requires-Dist: requests>=2.28; extra == "full"
Requires-Dist: faster-whisper>=1.0; extra == "full"
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Requires-Dist: pytest-cov; extra == "dev"
Requires-Dist: httpx>=0.28; extra == "dev"

# AgentForge

A reusable framework for building multi-agent Telegram bots powered by Claude AI.

**Zero dependencies** by default — runs on Python 3.10+ stdlib. Optional extras for voice transcription and faster HTTP.

## Native App Scaffold

This repo now includes an Apple-platform scaffold under `apps/` for future native clients:

- `AgentForgeKit` shared Swift module for models, networking stubs, and utilities
- `AgentForgeiOS` SwiftUI app target for iOS 17+
- `AgentForgemacOS` SwiftUI app target for macOS 14+

Build commands:

```bash
make native-build      # Builds the shared Swift package
make native-test       # Runs the shared Swift package tests
make ios-build         # Builds the iOS app target with xcodebuild
make macos-build       # Builds the macOS app target with xcodebuild
make native-verify     # Runs all of the above
```

Open the native project in Xcode with `open apps/AgentForgeApps.xcodeproj`.

## Quick Start

```bash
# Clone and install
git clone https://github.com/Martin-Rancourt/AgentForge.git
cd AgentForge
./install.sh

# Configure
agentforge init              # Launch interactive setup wizard

# Create agents
agentforge agent create assistant --model sonnet --thread-id 11
agentforge agent create researcher --model opus --thread-id 12

# Run
agentforge bot
```

## How It Works

AgentForge turns a **Telegram Supergroup with Forum Topics** into a multi-agent workspace. Each topic routes to a different Claude-powered agent with its own identity, model, and memory.

```
Telegram Topic (thread_id: 12)
  → telegram_adapter.py (long-polling)
  → message_router.py (resolve agent config)
  → claude_runner.py (invoke Claude CLI with agent's soul.md)
  → Response sent back to Telegram
```

### Message Flow

1. Bot polls Telegram for new messages
2. `message_thread_id` determines which agent handles the message
3. Conversation history is loaded from SQLite (configurable context window)
4. Claude Code CLI is invoked with the agent's `soul.md` as system prompt
5. Response is stored in SQLite and sent back to Telegram

## Architecture

```
agentforge/
├── src/agentforge/
│   ├── telegram_adapter.py   # Main bot — polling, routing, sending
│   ├── claude_runner.py      # Claude Code CLI subprocess wrapper
│   ├── message_router.py     # Thread → agent config resolution
│   ├── config.py             # Typed config loader (dataclasses)
│   ├── memory_manager.py     # SQLite + FTS5 conversation database
│   ├── vault.py              # Structured memory store (per-agent)
│   ├── voice.py              # Voice note transcription (optional)
│   ├── http_client.py        # Dual-stack: requests or urllib
│   └── cli/                  # CLI commands (bot, agent, memory, init, vault)
├── scripts/                   # Bash utilities
│   ├── telegram_send.sh      # Send messages to topics (with dedup)
│   ├── heartbeat.sh          # Proactive task runner (cron)
│   ├── healthcheck.sh        # Daily system health check
│   ├── agent_task.sh         # Cross-agent task delegation
│   ├── log_action.sh         # Action logging (Google Sheets + local)
│   └── memory_consolidation.sh  # Weekly memory merge
├── tests/                     # Pytest suite (49 tests)
├── install.sh                # One-liner bootstrap
└── pyproject.toml            # Package metadata
```

## CLI Reference

### `agentforge bot`

Start the Telegram bot.

```bash
agentforge bot [--config path/to/config.json]
```

### `agentforge agent`

Manage agents declaratively.

```bash
# Create — scaffolds soul.md, memory.md, daily/ directory
agentforge agent create <name> --model <model> --thread-id <id>

# List all configured agents
agentforge agent list

# Remove an agent (--keep-files to preserve files on disk)
agentforge agent remove <name> [--keep-files]
```

**Models:** `sonnet` (fast, balanced), `opus` (strongest reasoning), `haiku` (fastest, cheapest)

### `agentforge memory`

Query the conversation database.

```bash
agentforge memory search "deployment error"    # Full-text search (FTS5)
agentforge memory recent 50                     # Last 50 messages
agentforge memory stats                         # Database statistics
```

### `agentforge vault`

Structured memory store — facts, preferences, and knowledge per agent.

```bash
agentforge vault write --agent victor --category knowledge --title "API design" --content "..."
agentforge vault search "deployment"
agentforge vault list --agent archie
```

### `agentforge init`

Bootstrap a new instance from scratch.

```bash
agentforge init [--dir /path/to/instance]
agentforge init --non-interactive [--dir /path/to/instance]
```

Default behavior launches an interactive wizard that validates the Telegram token, detects a chat ID after `/start`, checks Claude Code CLI readiness, captures bot identity, and writes `.env`, `bot/config.json`, and `memory/soul.md`.

Use `--non-interactive` to preserve the original scaffold-only flow.

## Configuration

### `bot/config.json`

```jsonc
{
  "telegram": {
    "token_env_var": "AGENTFORGE_TELEGRAM_TOKEN",  // env var name holding the token
    "allowed_chat_ids": [123456789],                // whitelist
    "group_chat_id": -100123456789,                 // supergroup ID
    "topics": {                                      // named topic shortcuts
      "general": 11,
      "dev": 12
    }
  },
  "claude": {
    "model": "sonnet",          // default model
    "max_budget_usd": 1.0       // per-invocation spend cap
  },
  "memory": {
    "context_messages": 10      // messages included as context
  },
  "threads": {
    "11": { "name": "assistant", "model": "sonnet", "context_messages": 10 },
    "12": { "name": "researcher", "model": "opus",  "context_messages": 15 }
  }
}
```

### `.env`

```bash
AGENTFORGE_TELEGRAM_TOKEN=your_bot_token_here
AGENTFORGE_ROOT=/path/to/instance    # defaults to /home/clawdia
```

## Multi-Agent System

Each agent gets its own identity via a `soul.md` file:

```
agents/
├── victor/
│   ├── soul.md        # Personality, role, instructions
│   ├── memory.md      # Long-term consolidated memory
│   └── daily/         # Daily learnings (YYYY-MM-DD.md)
├── archie/
└── catherine/
```

The `soul.md` is passed as `--system-prompt` to Claude, completely overriding the default identity. Agents can:

- Have different Claude models (opus for complex reasoning, haiku for quick tasks)
- Maintain separate conversation histories and context windows
- Store per-agent structured memory in the vault
- Delegate tasks to each other via `agent_task.sh`

### Project Topics

Beyond agent topics, you can configure **project topics** where multiple agents collaborate:

```json
"project_topics": {
  "42": {
    "label": "🏗 Dev",
    "agents": ["victor", "archie"],
    "default_agent": "victor"
  }
}
```

Use `@agentname` mentions to address a specific agent in a shared topic.

## Scripts

| Script | Purpose | Trigger |
|--------|---------|---------|
| `telegram_send.sh` | Send messages to topics | Manual / cross-agent |
| `heartbeat.sh` | Run proactive tasks from `heartbeat.md` | Cron |
| `healthcheck.sh` | System health report | Cron (daily) |
| `agent_task.sh` | Delegate tasks between agents | Inter-agent |
| `log_action.sh` | Log external actions to Sheets + file | After side-effects |
| `memory_consolidation.sh` | Merge daily logs → `memory.md` | Cron (weekly) |

### Dedup

`telegram_send.sh` has built-in deduplication: identical messages to the same topic within 60 seconds are silently dropped.

## Memory System

AgentForge provides three layers of memory:

| Layer | Storage | Purpose |
|-------|---------|---------|
| **Conversations** | SQLite + FTS5 | Full message history, searchable |
| **Vault** | SQLite + FTS5 | Structured facts/preferences per agent |
| **Files** | Markdown | `soul.md` (identity), `memory.md` (long-term), `daily/` (learnings) |

The weekly `memory_consolidation.sh` script merges daily learnings into each agent's `memory.md`.

## Dependencies

**Core:** Python 3.10+ stdlib only (no pip install required for basic operation)

**Optional extras:**

```bash
pip install agentforge[full]    # requests + faster-whisper
pip install agentforge[dev]     # pytest + pytest-cov
```

| Extra | Package | Purpose |
|-------|---------|---------|
| `full` | `requests>=2.28` | Faster HTTP client (falls back to urllib) |
| `full` | `faster-whisper>=1.0` | Voice note transcription |
| `dev` | `pytest>=7` | Test runner |
| `dev` | `pytest-cov` | Coverage reports |

## External Requirements

- **Claude Code CLI** — must be installed at `$AGENTFORGE_ROOT/.local/bin/claude`
- **Telegram Bot** — create one via [@BotFather](https://t.me/BotFather), enable Forum Topics in your supergroup

---

## Full Installation Guide (Fresh Linux Server)

This is the step-by-step procedure to install AgentForge on a fresh Linux machine (Ubuntu/Debian).

### Prerequisites

```bash
# System packages
sudo apt update && sudo apt install -y python3.12 python3.12-venv git curl

# Node.js (required for Claude Code CLI)
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
```

### Step 1 — Create a dedicated user

```bash
sudo adduser --disabled-password --gecos "AgentForge Bot" agentforge
sudo loginctl enable-linger agentforge   # allows systemd user services to run without login
```

### Step 2 — Install Claude Code CLI

```bash
sudo -u agentforge -i   # switch to agentforge user

# Install Claude Code
npm install -g @anthropic-ai/claude-code
# Verify
claude --version
```

> **Note:** Claude Code requires an Anthropic API key or Claude Max subscription. Run `claude` once to authenticate.

### Step 3 — Clone and install AgentForge

```bash
# Still as agentforge user
cd ~
git clone https://github.com/Martin-Rancourt/AgentForge.git
cd AgentForge
./install.sh ~
```

The installer will:
1. Check Python 3.10+ ✓
2. Check Claude CLI ✓
3. Create a virtual environment
4. Install the `agentforge` package
5. Run the interactive `agentforge init` wizard
6. Generate a systemd user service
7. Check for Syncthing

### Step 4 — Set up Telegram

Before running the bot, you need a Telegram Bot + Supergroup:

1. **Create a bot** — Talk to [@BotFather](https://t.me/BotFather) on Telegram:
   - `/newbot` → choose a name and username
   - Copy the **bot token**

2. **Create a Supergroup** with Forum Topics enabled:
   - Telegram → New Group → add your bot → make it a Supergroup
   - Group Settings → Topics → Enable
   - Create one topic per agent (e.g. "Assistant", "Researcher", "Dev")

3. **Get the chat ID and thread IDs**:
   - Send a message in each topic
   - Use `https://api.telegram.org/bot<TOKEN>/getUpdates` to see recent messages
   - Note the `chat.id` (negative number) and each `message_thread_id`

4. **Update config**:
   ```bash
   # Edit .env with your token
   nano ~/.env
   # → AGENTFORGE_TELEGRAM_TOKEN=your_token_here

   # Edit config with your chat ID and thread IDs
   nano ~/bot/config.json
   ```

### Step 5 — Create your agents

```bash
# Create agents matching your Telegram topics
agentforge agent create assistant --model sonnet --thread-id 11
agentforge agent create researcher --model opus --thread-id 12

# Edit each agent's personality
nano ~/agents/assistant/soul.md
nano ~/agents/researcher/soul.md
```

### Step 6 — Start the bot

```bash
# Enable and start the systemd service
systemctl --user daemon-reload
systemctl --user enable --now agentforge

# Verify it's running
systemctl --user status agentforge

# Watch logs
journalctl --user -u agentforge -f
```

### Step 7 — Set up cron jobs (optional but recommended)

```bash
crontab -e
```

Add:

```cron
# Heartbeat — proactive tasks every 30 minutes
*/30 * * * * AGENTFORGE_ROOT=$HOME $HOME/.venv/bin/agentforge heartbeat >> $HOME/logs/heartbeat.log 2>&1

# Daily health check at 08:00
0 8 * * * $HOME/scripts/healthcheck.sh >> $HOME/logs/healthcheck.log 2>&1

# Weekly memory consolidation (Sunday 23:00)
0 23 * * 0 $HOME/scripts/memory_consolidation.sh >> $HOME/logs/consolidation.log 2>&1
```

---

## Syncthing — Cross-Device Knowledge Sync

AgentForge uses [Syncthing](https://syncthing.net/) to sync your knowledge vault (Obsidian vault, agent memory, etc.) across devices. This is optional but recommended if you want to access your bot's brain from your phone or laptop.

### Architecture

```
┌──────────────┐     Syncthing      ┌──────────────┐
│ Linux Server │ ◄──────────────► │    macOS     │
│  (always-on) │                    │  (laptop)    │
└──────┬───────┘                    └──────────────┘
       │
       │  Syncthing
       ▼
┌──────────────┐
│   iPhone     │
│ (Möbius Sync)│
└──────────────┘
```

The Linux server is the **hub** — always on, always syncing. Other devices sync when they're online.

### Linux Server Setup

```bash
# Install Syncthing
sudo apt install -y syncthing

# Enable as a user service (runs without login thanks to lingering)
systemctl --user enable --now syncthing

# Access the web UI
# Syncthing listens on http://localhost:8384
# If remote: ssh -L 8384:localhost:8384 agentforge@your-server
```

**Configure the shared folder:**

1. Open Syncthing web UI (`http://localhost:8384`)
2. **Add Folder** → set the path to your knowledge vault (e.g. `~/obsidian-brain/`)
3. Set a **Folder ID** (e.g. `agentforge-vault`) — you'll need this on other devices
4. Under **Advanced** → set **Folder Type** to "Send & Receive"

### macOS Setup

```bash
# Install via Homebrew
brew install syncthing

# Start as a background service
brew services start syncthing
```

1. Open `http://localhost:8384` in your browser
2. **Add Remote Device** → paste the Linux server's **Device ID** (found in the server's Syncthing UI under Actions → Show ID)
3. On the **Linux server**, accept the incoming device request
4. The shared folder should auto-appear for approval on macOS — accept it
5. Choose a local path (e.g. `~/Documents/agentforge-vault/`)

**For Obsidian:** Point Obsidian's vault to the synced folder. Your bot's knowledge base stays in sync with your laptop.

### iOS Setup (Möbius Sync)

[Möbius Sync](https://apps.apple.com/app/m%C3%B6bius-sync/id1539203216) is the only Syncthing-compatible app for iOS. It costs ~$5 USD (one-time purchase).

1. **Install** [Möbius Sync](https://apps.apple.com/app/m%C3%B6bius-sync/id1539203216) from the App Store
2. Open the app → go to **Settings** → note your **Device ID**
3. On your **Linux server** Syncthing UI:
   - **Add Remote Device** → paste the iOS Device ID
   - Share the `agentforge-vault` folder with this device
4. Back in Möbius Sync:
   - Accept the incoming device connection
   - Accept the shared folder
   - Choose a local location (e.g. under "On My iPhone" or iCloud)
5. **For Obsidian Mobile:** Point Obsidian to the Möbius Sync folder to browse your vault on the go

> **Tip:** Möbius Sync works best with "Background Sync" enabled (Settings → Background Sync → On). iOS may still throttle it, so open the app occasionally to force a full sync.

### Syncthing Tips

- **Device IDs** are the only thing you exchange — no accounts, no cloud, fully P2P encrypted
- **Ignore patterns:** Add a `.stignore` file in your vault root to exclude files:
  ```
  .obsidian/workspace.json
  .DS_Store
  *.tmp
  ```
- **Conflict resolution:** Syncthing creates `.sync-conflict-*` files if two devices edit the same file simultaneously. Resolve manually.
- **Bandwidth:** Initial sync can be slow for large vaults. Subsequent syncs are incremental and near-instant.

---

## Testing

```bash
pip install -e ".[dev]"
pytest                      # Run all 49 tests
pytest --cov=agentforge     # With coverage
```

Tests cover: config validation, message routing, memory manager, vault operations.

## Releases

This project uses [release-please](https://github.com/googleapis/release-please) for automated releases:

1. Use **conventional commits** (`feat:`, `fix:`, `docs:`, `chore:`, etc.)
2. Release-please accumulates changes and opens a **Release PR** with version bump + changelog
3. Merge the Release PR → GitHub Release + git tag created automatically

## License

MIT
