The open-source managed agents platform. Turn coding agents into real teammates — assign tasks, track progress, compound skills. https://multica.ai
Find a file
Jiayuan Zhang 81998e6309 fix(telegram): skip tool narration messages, only send final answer
When the agent uses tools (web search, etc.), it generates intermediate
narration text like "Let me search..." before each tool call. These were
being sent as separate Telegram messages, causing message spam. Now we
detect tool_use blocks in the message content and skip sending those
intermediate messages — only the final answer reaches the user.

Applied to both Desktop channel plugin and Gateway Telegram service.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 02:04:17 +08:00
.github/workflows chore(ci): add GitHub Actions workflow (#28) 2026-01-30 13:51:05 +08:00
apps fix(telegram): skip tool narration messages, only send final answer 2026-02-14 02:04:17 +08:00
docs refactor(web): replace devd proxy with Next.js rewrites 2026-02-13 13:25:08 +08:00
packages fix(telegram): skip tool narration messages, only send final answer 2026-02-14 02:04:17 +08:00
scripts chore: add OAuth login URL to local dev script 2026-02-14 01:05:24 +08:00
skills feat(skills): add Excel spreadsheet (xlsx) skill 2026-02-12 17:54:17 +08:00
.dockerignore Add Docker support for Gateway and SDK documentation 2026-01-28 17:56:22 +08:00
.env.example chore: add local dev script for Gateway + Desktop with Telegram bot 2026-02-14 00:39:43 +08:00
.gitignore feat(cli): add binary build support for interactive CLI 2026-01-30 15:22:53 +08:00
.npmrc refactor: restructure to monorepo architecture 2026-02-10 18:00:23 +08:00
AGENTS.md docs: add AGENTS.md for OpenAI Codex compatibility 2026-02-01 18:55:26 +08:00
CLAUDE.md Merge pull request #174 from multica-ai/forrestchang/arch-analysis 2026-02-14 00:13:24 +08:00
package.json chore: add local dev script for Gateway + Desktop with Telegram bot 2026-02-14 00:39:43 +08:00
pnpm-lock.yaml chore: update pnpm-lock.yaml 2026-02-13 12:25:12 +08:00
pnpm-workspace.yaml refactor: migrate from Hugeicons to Lucide icons 2026-02-12 10:12:56 +08:00
README.md chore(desktop): add deep link protocol and build scripts 2026-02-13 14:33:48 +08:00
tsconfig.base.json refactor: restructure to monorepo architecture 2026-02-10 18:00:23 +08:00
tsconfig.json Implement WebSocket Gateway with NestJS and client SDK 2026-01-28 16:46:51 +08:00
turbo.json fix(web): add API_URL to turbo.json globalEnv 2026-02-13 16:59:18 +08:00
vitest.config.ts test: add vitest setup with static mock policy checker 2026-02-13 22:03:36 +08:00
vitest.setup.ts test: add vitest setup with static mock policy checker 2026-02-13 22:03:36 +08:00

Super Multica

Multiplexed Information & Computing Agent

An always-on AI agent that pulls real data, runs real computation, and takes real action — monitoring, analyzing, and acting within user-defined authorization boundaries.

See Memo for product vision, architecture, and roadmap.

Project Structure

src/
├── agent/              # Core agent module
│   ├── context-window/ # Token-aware context management
│   ├── profile/        # Agent profile management
│   ├── session/        # Session persistence with compaction
│   ├── skills/         # Modular skill system
│   └── tools/          # Agent tools
│       └── web/        # Web fetch and search tools
├── gateway/            # WebSocket gateway for remote access
├── hub/                # Agent coordination hub
└── shared/             # Shared types

apps/
├── desktop/            # Electron desktop app (recommended)
└── web/                # Next.js web application

packages/
├── sdk/                # Gateway client SDK
├── store/              # Zustand state management
└── ui/                 # Shared UI components

skills/                 # Bundled skills (commit, code-review)

Getting Started

pnpm install

Development

# Desktop app (recommended for local development)
pnpm dev

# Web app (for browser-based access)
pnpm dev:web         # Start Web app on :3000

# Gateway (for remote/mobile clients)
pnpm dev:gateway     # Start Gateway on :3000
pnpm dev:all         # Start both Gateway and Web app

The Desktop app runs a standalone Hub with embedded Agent Engine - no Gateway required for local use.

Environment Configuration

Desktop (apps/desktop/.env.*):

Variable Description
MAIN_VITE_GATEWAY_URL WebSocket Gateway URL for remote device pairing
MAIN_VITE_WEB_URL Web app URL for OAuth login redirect

Web (apps/web/next.config.ts):

Variable Description
API_URL Backend API URL (default: https://api-dev.copilothub.ai)

Build for different environments:

# Desktop
pnpm --filter @multica/desktop build              # Production (.env.production)
pnpm --filter @multica/desktop build:staging      # Staging (.env.staging)

# Web (Vercel)
# Set API_URL in Vercel Dashboard → Settings → Environment Variables

See apps/desktop/.env.example and apps/web/.env.example for details.

Monorepo Development

Command Purpose
pnpm dev Full dev mode — watches core, types, utils packages
pnpm dev:desktop Desktop only — skip package watching

When modifying packages:

  1. Edit code in packages/core, packages/types, or packages/utils
  2. Terminal shows [core] ESM ⚡️ Build success (~100ms)
  3. Restart Desktop to apply changes (Ctrl+C, then pnpm dev)

Why restart? Electron main process does not support hot reload — this is an Electron limitation, not ours.

Credentials

multica credentials init

Creates:

  • ~/.super-multica/credentials.json5 — LLM providers + tools
  • ~/.super-multica/skills.env.json5 — skill/plugin API keys

Example credentials.json5:

{
  version: 1,
  llm: {
    provider: "openai",
    providers: {
      openai: { apiKey: "sk-xxx", model: "gpt-4o" }
    }
  },
  tools: {
    brave: { apiKey: "brv-..." }
  }
}

LLM Providers

OAuth Providers (external CLI login):

  • claude-code — requires claude login
  • openai-codex — requires codex login

API Key Providers (configure in credentials.json5):

  • anthropic, openai, kimi-coding, google, groq, mistral, xai, openrouter

Check status: /provider in interactive mode

CLI

multica                              # Interactive mode
multica run "prompt"                 # Single prompt
multica chat --profile my-agent      # Use profile
multica --session abc123             # Continue session
multica session list                 # List sessions
multica profile list                 # List profiles
multica skills list                  # List skills
multica help                         # Show help

Short alias: mu

Sessions

Sessions persist to ~/.super-multica/sessions/<id>/ with JSONL message history and JSON metadata. Context windows are automatically managed with token-aware compaction.

Profiles

Profiles define agent identity, personality, and memory in ~/.super-multica/agent-profiles/<id>/.

multica profile new my-agent    # Create profile
multica profile list            # List all
multica profile edit my-agent   # Open in file manager

Profile files: soul.md, user.md, workspace.md, memory.md, memory/*.md

Skills

Skills extend agent functionality via SKILL.md files. See Skills Documentation.

multica skills list              # List skills
multica skills add owner/repo    # Install from GitHub
multica skills status            # Check status

Built-in: commit, code-review, skill-creator

Tools

Available tools: read, write, edit, glob, exec, process, web_fetch, web_search, memory_search, sessions_spawn

See Tools Documentation for details.

Architecture

Desktop App (standalone, recommended)
  └─ Hub (embedded)
     └─ Agent Engine

Web/Mobile Clients
  → Gateway (WebSocket, :3000)
    → Hub
      → Agent Engine
  • Desktop App: Electron app with embedded Hub, no Gateway needed
  • Gateway: WebSocket server for remote clients
  • Hub: Agent lifecycle and event distribution

Time

Super Multica now uses message-level timestamp injection for time awareness. Instead of placing dynamic time text in the system prompt, user turns are stamped at runtime.

flowchart TD
  A[Incoming turn] --> B{Entry point}
  B -->|Desktop/Gateway/Cron/Subagent| C[AsyncAgent.write]
  B -->|Heartbeat poll| D[AsyncAgent.write injectTimestamp=false]
  C --> E{Already stamped or has 'Current time:'?}
  E -->|Yes| F[Keep original message]
  E -->|No| G[Prefix: [DOW YYYY-MM-DD HH:mm TZ]]
  D --> H[Keep original heartbeat prompt]
  F --> I[Agent.run]
  G --> I
  H --> I
  I --> J[LLM receives final turn text]

Injection Matrix

Path Runtime call Timestamp injected? Notes
Desktop direct chat agent.write(content) Yes Default behavior
Gateway/remote chat agent.write(content) Yes Same entry path as desktop
sessions_spawn child task childAgent.write(task) Yes Child turn gets current time context
Cron agent-turn payload agent.write(cronMessage) Yes (guarded) Skips if message already carries Current time:
Heartbeat runner agent.write(prompt, { injectTimestamp: false }) No Prevents heartbeat prompt matching from breaking
Internal orchestration writeInternal(...) No Uses separate internal run path

Why this design

  • Keeps system prompt cache-stable (no per-turn date churn in system prompt text)
  • Gives the model an explicit "now" reference on each user turn
  • Uses guardrails to avoid double-stamping and heartbeat regressions

Scripts

pnpm dev              # Desktop app (recommended)
pnpm dev:gateway      # Gateway only
pnpm dev:web          # Web app only
pnpm dev:all          # Gateway + Web

pnpm build            # Production build
pnpm typecheck        # Type check
pnpm test             # Run tests