multiagent/¶
Multi-agent runtime: run multiple independent sygen agents in one process.
Files¶
multiagent/supervisor.py:AgentSupervisorlifecycle, health, crash recovery, agents watchermultiagent/stack.py:AgentStackcontainer (config + bot + orchestrator)multiagent/bus.py:InterAgentBus(sync + async inter-agent messaging)multiagent/internal_api.py: localhost HTTP bridge for tool scripts (/interagent/*,/tasks/*)multiagent/models.py:SubAgentConfig, merge helpersmultiagent/registry.py:agents.jsonread/writemultiagent/health.py: per-agent health modelmultiagent/shared_knowledge.py: shared knowledge sync (SHAREDMEMORY.md)multiagent/commands.py: Telegram commands (/agents,/agent_start,/agent_stop,/agent_restart)
Runtime model¶
AgentSupervisor
+-- AgentStack "main"
+-- AgentStack "sub-*" (0..n)
+-- InterAgentBus
+-- InternalAgentAPI (localhost bridge)
+-- optional TaskHub (shared)
+-- SharedKnowledgeSync
+-- FileWatcher(agents.json)
Each stack is isolated (token/workspace/sessions), but shares process/event-loop infrastructure.
Startup sequence (AgentSupervisor.start)¶
- start inter-agent bus
- start internal API
- optional shared task hub
- create/start main stack
- wait for main readiness
- start sub-agents from
agents.json - start shared knowledge sync
- start
agents.jsonwatcher
Dynamic agent changes¶
Watcher polls agents.json every 5s.
- added entry -> start sub-agent
- removed entry -> stop sub-agent
- restart triggers for running sub-agents:
transportchanged- Telegram identity changed (
telegram_token) - Matrix identity changed (
matrix.homeserverormatrix.user_id) - other field changes do not auto-restart running agent
Crash/restart policy¶
Per agent _supervised_run behavior:
- clean exit -> stop
- exit code
42: - main -> propagate full process/service restart
- sub-agent -> in-process hot-reload
- crash -> exponential backoff retries (5 attempts max), then mark
crashed
Sub-agent config (agents.json)¶
Minimal entry:
{
"name": "coder",
"telegram_token": "123456:ABC...",
"allowed_user_ids": [12345678],
"allowed_group_ids": [],
"provider": "codex",
"model": "o3"
}
Merge behavior:
- base: main
AgentConfig - override: non-null
SubAgentConfigfields - always forced:
sygen_home=~/.sygen/agents/<name>/- sub-agent
telegram_token,allowed_user_ids,allowed_group_ids api.enabled=falseunless explicitly provided for sub-agent
Shared vs isolated¶
Isolated per sub-agent:
- transport credentials and auth (Telegram token or Matrix account)
- workspace and files under
~/.sygen/agents/<name>/ sessions.json,named_sessions.json, cron/webhook state
Shared across process:
InterAgentBusInternalAgentAPI- optional shared
TaskHub - central log file (
~/.sygen/logs/agent.log) - shared knowledge source (
~/.sygen/SHAREDMEMORY.md)
Inter-agent communication¶
In-memory bus¶
- sync: waits for target response (
send) - async: returns task ID immediately (
send_async)
Recipient processing uses deterministic named session ia-<sender>.
Provider-switch safeguard:
- if recipient provider changed since prior
ia-<sender>session, old session is ended and recreated - provider-switch notice is surfaced back to sender side
Activity log¶
Each agent automatically maintains AGENT_ACTIVITY.md in its workspace — a rolling log of inter-agent interactions it handled. When a user opens a direct chat, the agent reads this file and has context about recent delegated work.
Format: - [MM-DD HH:MM] from:<sender> [ok (Ns)] <message> → <result>
Cleanup:
- FIFO cap: 15 entries (oldest evicted on write)
- Age expiry: entries older than 7 days are dropped on write
- Memory cleanup cron covers this file for all agents
Async timeout behavior¶
Async inter-agent tasks are fire-and-forget. If a task times out, the timeout is logged but not delivered to the user's chat. This prevents confusing "Inter-Agent Request Failed" messages for tasks that may have been resolved by other means.
Local HTTP bridge for tool scripts¶
InternalAgentAPI runs on config.interagent_port (default 8799):
- host mode:
127.0.0.1:<port> - Docker mode:
0.0.0.0:<port>
Inter-agent endpoints:
POST /interagent/sendPOST /interagent/send_asyncGET /interagent/agentsGET /interagent/health
Task endpoints (shared hub):
POST /tasks/createPOST /tasks/resumePOST /tasks/ask_parentGET /tasks/listPOST /tasks/cancelPOST /tasks/delete
Ownership checks apply for resume/cancel/delete when from=<agent> is present.
TaskHub integration¶
When enabled, supervisor wires each stack into shared TaskHub:
- per-agent CLI service
- per-agent paths (
tasks_dir) - task result callback
- task question callback
- agent primary chat ID mapping
This enables task submission from any agent while preserving owner routing.
Shared knowledge sync¶
SharedKnowledgeSync watches ~/.sygen/SHAREDMEMORY.md and mirrors content into each agent's MAINMEMORY.md block.
Legacy HTML marker format is migrated to current block markers when rewritten.
Chat and CLI commands¶
Main-agent chat commands:
- Telegram:
/agents,/agent_start <name>,/agent_stop <name>,/agent_restart <name> - Matrix:
!agents,!agent_start <name>,!agent_stop <name>,!agent_restart <name>(/prefix also works)
CLI:
sygen agentssygen agents listsygen agents add <name>sygen agents remove <name>
sygen agents list fetches live health from internal API when main bot is running.
Important CLI nuance:
sygen agents add <name>currently prompts for Telegram token/user/group data only.- Matrix sub-agents are supported by the runtime and merge logic, but are created via manual
agents.jsonediting or the bundledcreate_agent.py --transport matrixtool script.