@lacneu/atrium 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +129 -0
- package/package.json +64 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Olivier Neu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/assets/atrium-mark-dark.svg">
|
|
4
|
+
<img alt="" src="docs/assets/atrium-mark-light.svg" width="76" height="76">
|
|
5
|
+
</picture>
|
|
6
|
+
</p>
|
|
7
|
+
|
|
8
|
+
<h1 align="center">Atrium</h1>
|
|
9
|
+
|
|
10
|
+
<p align="center">A clean, self-hostable, multi-user web chat for your AI agents — one UI across agent gateways.</p>
|
|
11
|
+
|
|
12
|
+
<p align="center">
|
|
13
|
+
<img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-blue">
|
|
14
|
+
<img alt="Status: early / 0.x" src="https://img.shields.io/badge/status-early%20%2F%200.x-orange">
|
|
15
|
+
<!-- After the first push (once CI has run once), uncomment the CI badge:
|
|
16
|
+
<img alt="CI" src="https://github.com/lacneu/atrium/actions/workflows/ci.yml/badge.svg"> -->
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
An open-source, self-hostable web chat UI for **AI agent gateways**. It gives a
|
|
20
|
+
team a clean multi-user chat front end across one or more gateways, with streaming
|
|
21
|
+
replies, file exchange, per-user agent routing, and a built-in observability
|
|
22
|
+
surface. **OpenClaw is the first supported provider; Hermes is next** — each
|
|
23
|
+
provider lives behind a bridge adapter, so the UI stays the same as gateways are
|
|
24
|
+
added.
|
|
25
|
+
|
|
26
|
+
> Atrium is **provider-agnostic by design** and a community project — not
|
|
27
|
+
> affiliated with or endorsed by any gateway vendor. You bring your own gateway
|
|
28
|
+
> (OpenClaw today, Hermes next); Atrium is the chat surface in front of it.
|
|
29
|
+
|
|
30
|
+
## Status
|
|
31
|
+
|
|
32
|
+
Early but functional, designed as a public, forkable foundation. The project is
|
|
33
|
+
`0.x`: the bridge protocol and APIs are documented and versioned, but breaking
|
|
34
|
+
changes can still happen before `1.0`.
|
|
35
|
+
|
|
36
|
+
## What it is
|
|
37
|
+
|
|
38
|
+
Agent gateways are event-driven and best driven over a WebSocket: a single user
|
|
39
|
+
turn can produce multiple runs, intermediate replies, tool output, generated
|
|
40
|
+
media, auto-compaction restarts, and messages that arrive after a browser
|
|
41
|
+
reconnect. Atrium embraces that model instead of fighting it:
|
|
42
|
+
|
|
43
|
+
- A **React + Vite** front end (TypeScript, built on assistant-ui).
|
|
44
|
+
- A **Convex** self-hosted backend (TypeScript functions + reactive database)
|
|
45
|
+
that owns chats, messages, routing, auth, and the observability data.
|
|
46
|
+
- A **Node/TypeScript bridge** with a **per-provider adapter** (OpenClaw today,
|
|
47
|
+
Hermes planned) that holds a persistent operator WebSocket to the gateway,
|
|
48
|
+
normalizes the version-specific event stream into a small stable shape, and
|
|
49
|
+
relays turns to and from Convex. The provider is the only vendor-coupled layer.
|
|
50
|
+
- An external **agent gateway** (OpenClaw, or Hermes when available) that actually
|
|
51
|
+
runs the agents. Atrium never runs the model itself — you bring your own gateway.
|
|
52
|
+
|
|
53
|
+
The front end never parses raw gateway frames; it subscribes to Convex, which is
|
|
54
|
+
fed by the bridge. The result is a stable UI even as providers and versions evolve.
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
Browser ──▶ Convex (queries/mutations, reactive)
|
|
58
|
+
▲ │ schedules an outbound turn
|
|
59
|
+
│ live ▼
|
|
60
|
+
└────── Bridge ◀──▶ agent gateway (WebSocket: OpenClaw today, Hermes next)
|
|
61
|
+
(ingests normalized events back into Convex)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for the full picture.
|
|
65
|
+
|
|
66
|
+
## Features
|
|
67
|
+
|
|
68
|
+
- Google and Microsoft Entra sign-in (via `@convex-dev/auth`), restricted to
|
|
69
|
+
allowed email domains; the first sign-in from an allowed domain becomes admin.
|
|
70
|
+
- Multi-user, multi-agent, multi-instance routing: each user is routed to the
|
|
71
|
+
gateway instance and agent assigned to them.
|
|
72
|
+
- Streaming assistant replies with a stable contract (deltas, snapshots,
|
|
73
|
+
finalize, run status, tool status, media), resilient to provider and version
|
|
74
|
+
differences, empty/duplicate finals, follow-on runs, and auto-compaction.
|
|
75
|
+
- File exchange in both directions (inbound attachments, outbound generated
|
|
76
|
+
media served from Convex storage — server filesystem paths never reach the
|
|
77
|
+
browser).
|
|
78
|
+
- A key-authed observability API (`/api/v1`) and an MCP server (`mcp/`) for
|
|
79
|
+
traces, KPIs, anomalies, and diagnostics — metadata only, no chat content.
|
|
80
|
+
- Full internationalization (French default, English) via Paraglide JS.
|
|
81
|
+
|
|
82
|
+
## Quickstart
|
|
83
|
+
|
|
84
|
+
The frontend and bridge ship as Docker images; Convex runs self-hosted. The
|
|
85
|
+
canonical, env-driven deployment guide (Docker Compose and Helm) lives in
|
|
86
|
+
[`deploy/`](deploy/):
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
cd deploy/compose
|
|
90
|
+
cp .env.example .env # fill every required value (see comments inside)
|
|
91
|
+
docker compose up -d # convex backend + dashboard + frontend + bridge
|
|
92
|
+
./bootstrap-env.sh # push the Convex-scoped vars (auth, bridge wiring)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Open the app at your frontend origin and sign in. See
|
|
96
|
+
[`deploy/README.md`](deploy/README.md) for the full guide, including the
|
|
97
|
+
two-environment-scope gotcha and the stateful/stateless lifecycle.
|
|
98
|
+
|
|
99
|
+
For local development (no Docker), see [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md).
|
|
100
|
+
|
|
101
|
+
## Documentation
|
|
102
|
+
|
|
103
|
+
- [Architecture](docs/ARCHITECTURE.md) — components, data flow, auth.
|
|
104
|
+
- [Development](docs/DEVELOPMENT.md) — local dev workflow, tests, Convex, Vite.
|
|
105
|
+
- [Configuration](docs/CONFIGURATION.md) — environment variable reference.
|
|
106
|
+
- [Bridge protocol](docs/BRIDGE_PROTOCOL.md) — bridge ↔ Convex ↔ gateway contract.
|
|
107
|
+
- [Deployment](docs/DEPLOYMENT.md) → points to [`deploy/`](deploy/).
|
|
108
|
+
- [OpenClaw version compatibility](docs/OPENCLAW_VERSION_COMPAT.md).
|
|
109
|
+
- [Compliance / Trust Center](compliance/) — SOC 2 control mapping (incl. the
|
|
110
|
+
metadata-only `/api/v1` surface) + the software-vs-operator
|
|
111
|
+
shared-responsibility model.
|
|
112
|
+
- [Vision](VISION.md) · [Changelog](CHANGELOG.md) ·
|
|
113
|
+
[Third-party notices](THIRD_PARTY_NOTICES.md) ·
|
|
114
|
+
[Contributing & agent guide](AGENTS.md).
|
|
115
|
+
|
|
116
|
+
## Security
|
|
117
|
+
|
|
118
|
+
Gateway tokens and device identities live only in the bridge process — never in
|
|
119
|
+
Convex tables and never in the browser. Outbound media is served through Convex
|
|
120
|
+
storage with no server paths exposed. See [SECURITY.md](SECURITY.md).
|
|
121
|
+
|
|
122
|
+
## Contributing
|
|
123
|
+
|
|
124
|
+
Contributions are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md) and the
|
|
125
|
+
[Code of Conduct](CODE_OF_CONDUCT.md).
|
|
126
|
+
|
|
127
|
+
## License
|
|
128
|
+
|
|
129
|
+
MIT. See [LICENSE](LICENSE).
|
package/package.json
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lacneu/atrium",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Atrium — public, self-hostable Convex-backed chat UI for OpenClaw. Ships an origin-agnostic static bundle (Convex URL injected at runtime via /config.json).",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"README.md"
|
|
10
|
+
],
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"dev": "vite",
|
|
16
|
+
"dev:convex": "convex dev",
|
|
17
|
+
"build": "vite build",
|
|
18
|
+
"paraglide:compile": "paraglide-js compile --project ./project.inlang --outdir ./src/paraglide --emit-ts-declarations --strategy localStorage baseLocale",
|
|
19
|
+
"typecheck": "npm run paraglide:compile && tsc --noEmit",
|
|
20
|
+
"test": "npm run paraglide:compile && npm run i18n:check && vitest run",
|
|
21
|
+
"i18n:check": "npm run i18n:check-parity && npm run i18n:check-literals",
|
|
22
|
+
"i18n:check-parity": "node scripts/i18n-check-parity.mjs",
|
|
23
|
+
"i18n:check-literals": "node scripts/i18n-check-literals.mjs",
|
|
24
|
+
"preview": "vite preview"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@assistant-ui/react": "^0.14.13",
|
|
28
|
+
"@assistant-ui/react-markdown": "^0.14.1",
|
|
29
|
+
"@auth/core": "^0.37.0",
|
|
30
|
+
"@convex-dev/auth": "^0.0.80",
|
|
31
|
+
"@dnd-kit/core": "^6.3.1",
|
|
32
|
+
"@dnd-kit/modifiers": "^9.0.0",
|
|
33
|
+
"@dnd-kit/sortable": "^10.0.0",
|
|
34
|
+
"@dnd-kit/utilities": "^3.2.2",
|
|
35
|
+
"@inlang/paraglide-js": "^2.18.2",
|
|
36
|
+
"@tailwindcss/vite": "^4.3.0",
|
|
37
|
+
"@tanstack/react-router": "^1.170.11",
|
|
38
|
+
"class-variance-authority": "^0.7.1",
|
|
39
|
+
"clsx": "^2.1.1",
|
|
40
|
+
"convex": "^1.39.1",
|
|
41
|
+
"lucide-react": "^1.17.0",
|
|
42
|
+
"radix-ui": "^1.4.3",
|
|
43
|
+
"react": "^19.2.6",
|
|
44
|
+
"react-dom": "^19.2.6",
|
|
45
|
+
"remark-gfm": "^4.0.1",
|
|
46
|
+
"tailwind-merge": "^3.6.0",
|
|
47
|
+
"tailwindcss": "^4.3.0",
|
|
48
|
+
"tw-animate-css": "^1.4.0",
|
|
49
|
+
"zod": "^4.4.3"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@edge-runtime/vm": "^5.0.0",
|
|
53
|
+
"@tanstack/react-router-devtools": "^1.167.0",
|
|
54
|
+
"@types/node": "^25.9.1",
|
|
55
|
+
"@types/react": "^19.2.15",
|
|
56
|
+
"@types/react-dom": "^19.2.3",
|
|
57
|
+
"@vitejs/plugin-react": "^6.0.2",
|
|
58
|
+
"convex-test": "^0.0.53",
|
|
59
|
+
"shadcn": "^4.10.0",
|
|
60
|
+
"typescript": "^6.0.3",
|
|
61
|
+
"vite": "^8.0.14",
|
|
62
|
+
"vitest": "^4.1.8"
|
|
63
|
+
}
|
|
64
|
+
}
|