highperfocused c24a4721bd
All checks were successful
Build and Push Docker Image / build (pull_request) Successful in 1m32s
Implement multi-tenant platform API and standalone Vite control plane
2026-03-12 22:16:54 +01:00

MoA Agent Gateway

This project now runs as a chat gateway in front of @mariozechner/pi-coding-agent.

It supports:

  • long-lived agent conversations
  • HTTP JSON API
  • streaming responses via Server-Sent Events (SSE)
  • a built-in browser chat UI at /

You can also keep one-shot mode (RUN_MODE=single) for script usage.


Documentation

  • Gateway internals: docs/gateway.md
  • Web UI internals: docs/web-ui.md
  • Channel integrations (Web UI, Slack, Matrix, custom): docs/channels.md
  • Multi-tenant platform API + Swarm orchestration: docs/platform.md

Run

cp .env.example .env
# set provider/model/key in .env

docker compose up --build

Gateway default URL:

  • http://localhost:8787

Health check:

curl http://localhost:8787/health

One-shot mode (legacy behavior):

RUN_MODE=single PROMPT="List files" npm start

API

Create/list conversations

curl -X POST http://localhost:8787/v1/conversations \
  -H 'content-type: application/json' \
  -d '{"conversationId":"web:user-42:chat-a"}'

curl http://localhost:8787/v1/conversations

Chat (non-streaming)

curl -X POST http://localhost:8787/v1/chat \
  -H 'content-type: application/json' \
  -d '{"conversationId":"web:user-42:chat-a","message":"Summarize this repo"}'

Chat (streaming SSE)

curl -N -X POST http://localhost:8787/v1/chat/stream \
  -H 'content-type: application/json' \
  -d '{"conversationId":"web:user-42:chat-a","message":"List TypeScript files"}'

Adapter-friendly endpoint (Slack/Matrix/etc)

Instead of constructing conversationId in your adapter, you can call:

  • POST /v1/adapters/chat
  • POST /v1/adapters/chat/stream

Body fields:

{
  "source": "slack",
  "workspaceId": "T123",
  "channelId": "C456",
  "threadId": "1712233.991",
  "userId": "U789",
  "message": "Summarize the thread"
}

The gateway derives a stable conversation id: source:workspaceId:channelId:threadId

SSE events include:

  • assistant_text_delta
  • assistant_thinking_delta
  • tool_start, tool_update, tool_end
  • agent_start, agent_end
  • done (final response payload)
  • error

Built-in Web UI

Open:

  • http://localhost:8787/

The UI stores conversationId in local storage and reuses it to keep context.


Auth and CORS

Optional env vars:

  • GATEWAY_AUTH_TOKEN: require Authorization: Bearer <token>
  • GATEWAY_CORS_ORIGIN: e.g. * or https://my-ui.example

Multi-client strategy (Slack / Matrix / custom UI)

The gateway is transport-agnostic. For each upstream client, map its thread identity to a stable conversationId, for example:

  • Web: web:<userId>:<chatId>
  • Slack: slack:<teamId>:<channelId>:<threadTs>
  • Matrix: matrix:<roomId>:<threadRootEventId>

Then post messages to /v1/chat or /v1/chat/stream with that conversationId.

This keeps one agent session per thread across transports. For detailed setup guidance per transport, see docs/channels.md.


Multi-tenant Platform API

Additional endpoints exist under /v1/platform/* for:

  • user register/login
  • tenant workspaces + RBAC
  • spawning/scaling/restarting/removing agent services on Docker Swarm
  • tenant-scoped audit logs and SSE lifecycle events

See docs/platform.md for full endpoint reference and env vars.


Separate Vite Platform UI

A standalone Vite app now lives in platform-ui/.

It is intended as the frontend control plane for a multi-tenant setup (tenant onboarding + spawning agent services on Docker Swarm).

Run it locally:

cd platform-ui
npm install
npm run dev

This UI is not included in the backend Docker runtime image.

Description
No description provided
Readme 216 KiB
Languages
TypeScript 97.3%
Dockerfile 2.7%