Ai-Mee Help Centre
Home
Features
How-To Guides
FAQ
Need Help?
Home
Features
How-To Guides
FAQ
Need Help?

GoClaw Replacement: Direct Bot Migration

Status: Planning
Started: 2026-05-04
Prerequisite: Pre-production — no live users to migrate

Why

GoClaw's tenant isolation model is fundamentally incompatible with a SaaS that shares one Telegram bot token across all users. The current architecture requires:

  • One GoClaw tenant per Supabase user (provisioned via fragile HTTP scripts)
  • Three-layer identity mapping: Supabase user → GoClaw tenant → Telegram chat_id
  • Static X-User-Id headers baked into per-tenant MCP server registrations
  • A separate PostgreSQL instance (pgvector) + Docker container just for GoClaw
  • Four-hop message routing: Telegram → GoClaw → MCP → API

The Node.js API already contains all business logic as stateless service functions. GoClaw is a pass-through orchestrator that adds more complexity than value for a single-bot-token multi-user SaaS.

What Changes

Replace GoClaw with a channel-agnostic bot module at api/src/bot/. A ChannelAdapter interface abstracts Telegram, WhatsApp, and future channels. The LLM agent calls existing service functions directly — no MCP serialization, no tenant provisioning, no seeding scripts.

Architecture

api/src/bot/
├── index.ts                  # Adapter registry + boot
├── types.ts                  # ChannelAdapter, IncomingMessage, OutgoingMessage
├── agent.ts                  # LangChain tool-calling agent (Aimee)
├── tools.ts                  # Service functions wrapped as LangChain tools
├── memory.ts                 # Conversation state (Supabase-backed)
├── cron.ts                   # node-cron (briefing, reminders, weekly summary)
├── channels/
│   ├── telegram.ts           # Telegraf adapter (first channel)
│   └── (whatsapp.ts)         # Future channel
└── prompts/
    ├── system.ts             # Merged SKILL + IDENTITY + SOUL
    └── briefing.ts           # Morning briefing prompt template

Message Flow

Telegram/WhatsApp → ChannelAdapter.onMessage()
  → resolve (channel, externalId) → user_id via messaging_users table
  → load conversation history
  → invoke LangChain agent with message + history + tools
  → agent calls service functions directly (no MCP)
  → agent returns response
  → ChannelAdapter.sendMessage() → formatted for channel
  → save conversation turn to chat_history

Phases

PhaseNameDepends OnDoc
1Bot Core + Telegram Adapter—Foundation: types, Telegraf adapter, DB tables, pairing
2Agent + ToolsPhase 1LangChain agent, tool wrappers, conversation memory
3Cron JobsPhase 1Morning briefing, approval reminders, weekly summary
4Cleanup + CutoverPhases 1-3 verifiedRemove GoClaw, MCP, tenant provisioning, seeding scripts

Phase 3 can run in parallel with Phase 2 — both depend only on Phase 1.

What We Lose vs Gain

Lost (must rebuild or accept)

FeatureGoClawReplacementEffort
Conversation memoryGemini embeddings + vector searchLangChain BufferWindowMemory + Supabase chat_historyMedium
Multi-agent delegationliaison → research spawningSingle agent with all tools (research = scrape + search tools)Low
Agent personas/skillsSKILL.md + IDENTITY.md + SOUL.mdMerged system prompt in prompts/system.tsLow
Cron engineTenant-aware, in GoClaw DBnode-cron in API processLow
Context window mgmtAuto-truncation, 50-msg historyLangChain BufferWindowMemoryMedium
Admin UIGoClaw dashboardLogging; build admin later if neededLow

Gained

BenefitImpact
Simple multi-tenancyOne bot, chat_id → user_id is one DB query
Multi-channel readyChannelAdapter supports Telegram, WhatsApp, future channels
~60% less infrastructureRemove GoClaw container + its PostgreSQL
Direct function callsNo MCP serialization overhead
Single log streamTwo-hop (Telegram → API) instead of four
No vendor dependencyAll open-source (Telegraf, LangChain)
Faster iterationEdit code, not upload skills via HTTP API

Key Decisions

  • Bot in api/src/bot/ — same package, direct service calls, shared deployment
  • Channel-agnostic from day one — ChannelAdapter interface; adding a channel = one adapter file
  • Single agent — no multi-agent delegation at current scale
  • Memory: BufferWindowMemory (last N messages) + Supabase. Vector search later if needed
  • Don't touch content generation — createPosts.ts, llm.ts, llm-models.ts unchanged
  • Keep bot/ directory during migration for prompt reference; delete after cutover