omnigateway 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 +265 -0
- package/bin/omni.js +19582 -0
- package/gateway.js +39286 -0
- package/package.json +39 -0
- package/public/assets/Chip-D0YiqYkz.js +32 -0
- package/public/assets/CopyValue-BwjFnqW2.js +27 -0
- package/public/assets/Field-DdscQ9OO.js +65 -0
- package/public/assets/Lamp-CSv_5d5k.js +15 -0
- package/public/assets/Meter-Bm1oQE2U.js +14 -0
- package/public/assets/Modal-1tHwlj0o.js +82 -0
- package/public/assets/Rack-DANVhi_U.js +147 -0
- package/public/assets/Readout-CYg6UOop.js +27 -0
- package/public/assets/States-DPTTYUHL.js +54 -0
- package/public/assets/Table-LkPaHBsj.js +38 -0
- package/public/assets/Toggle-pWcL2A-N.js +42 -0
- package/public/assets/_app-C5mYmzgk.js +1 -0
- package/public/assets/_app.accounts-e7Mbaxdc.js +47 -0
- package/public/assets/_app.index-CxunMQ_m.js +57 -0
- package/public/assets/_app.keys-DTREQf0P.js +39 -0
- package/public/assets/_app.logs-Co3QPpc1.js +18 -0
- package/public/assets/_app.models-DPSKIyeq.js +144 -0
- package/public/assets/_app.settings-15ZMiM5O.js +16 -0
- package/public/assets/_app.usage-BBffCDCD.js +163 -0
- package/public/assets/archivo-latin-ext-standard-normal-7khWdh9v.woff2 +0 -0
- package/public/assets/archivo-latin-standard-normal-DY7AcnAa.woff2 +0 -0
- package/public/assets/archivo-vietnamese-standard-normal-rJmnGBSt.woff2 +0 -0
- package/public/assets/catalog-DmrbfYQe.js +1 -0
- package/public/assets/index-Co2s5xMk.css +1 -0
- package/public/assets/index-DnNTc35a.js +170 -0
- package/public/assets/login-DNvWG7Nv.js +33 -0
- package/public/assets/queries-vY5lJqBe.js +144 -0
- package/public/assets/spline-sans-mono-latin-ext-wght-normal-Dh0aNLWd.woff2 +0 -0
- package/public/assets/spline-sans-mono-latin-wght-normal-DlaB5ohX.woff2 +0 -0
- package/public/index.html +26 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Harismawan
|
|
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,265 @@
|
|
|
1
|
+
# OmniGateway
|
|
2
|
+
|
|
3
|
+
One endpoint in front of the AI accounts you already pay for.
|
|
4
|
+
|
|
5
|
+
OmniGateway is a self-hosted gateway that speaks the Anthropic and OpenAI APIs
|
|
6
|
+
and answers them using your own Anthropic, OpenAI, and Kimi Coding
|
|
7
|
+
subscriptions. Point any compatible client at it, ask for a model you defined,
|
|
8
|
+
and the gateway picks an account that can serve it — falling back to another
|
|
9
|
+
when one is rate-limited, expired, or out of quota.
|
|
10
|
+
|
|
11
|
+
It runs on one machine, stores everything in a local SQLite file, and never
|
|
12
|
+
logs the contents of your prompts or replies.
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
bun install -g omnigateway
|
|
16
|
+
omni start
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
> Status: in use and complete for its scope. Version 1 targets a single
|
|
20
|
+
> machine and a single operator — see [Scope](#scope-and-limits).
|
|
21
|
+
|
|
22
|
+
## What it does
|
|
23
|
+
|
|
24
|
+
- **Speaks both dialects.** `POST /v1/messages` (Anthropic) and
|
|
25
|
+
`POST /v1/chat/completions` (OpenAI), including streaming, translated to
|
|
26
|
+
whichever provider actually serves the request.
|
|
27
|
+
- **Routes across your accounts.** Define a virtual model like `fast` or
|
|
28
|
+
`smart` with several targets; the gateway ranks them by tier, health,
|
|
29
|
+
remaining quota, cost, and latency.
|
|
30
|
+
- **Fails over.** A rate-limited or broken account is skipped, its circuit
|
|
31
|
+
breaker opens, and the next candidate is tried — before the response starts
|
|
32
|
+
streaming.
|
|
33
|
+
- **Keeps OAuth alive.** Tokens refresh in the background, before a request
|
|
34
|
+
needs them.
|
|
35
|
+
- **Watches provider quota.** It asks each provider what you have left and
|
|
36
|
+
routes by *pace*: 5% remaining is fine minutes before a reset and urgent with
|
|
37
|
+
six days to run.
|
|
38
|
+
- **Issues its own keys.** Hand out gateway keys with per-key model allowlists
|
|
39
|
+
and rate limits instead of sharing provider credentials.
|
|
40
|
+
- **Reports usage.** Requests, tokens, and cost by provider, model, key, and
|
|
41
|
+
day — metadata only.
|
|
42
|
+
- **Ships an admin console and a CLI.** Both cover the same ground; use
|
|
43
|
+
whichever suits the machine you are on.
|
|
44
|
+
|
|
45
|
+
## Requirements
|
|
46
|
+
|
|
47
|
+
- [Bun](https://bun.sh/) 1.4 or later. Bun is the runtime, not just the
|
|
48
|
+
installer, so a Node-only machine cannot run OmniGateway.
|
|
49
|
+
- A directory that persists, for the SQLite database.
|
|
50
|
+
- At least one Anthropic, OpenAI, or Kimi Coding account to connect.
|
|
51
|
+
|
|
52
|
+
## Install
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
bun install -g omnigateway # or: npm i -g omnigateway
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
One package carries the `omni` CLI, the gateway server, and the admin console
|
|
59
|
+
the server hosts.
|
|
60
|
+
|
|
61
|
+
## Getting started
|
|
62
|
+
|
|
63
|
+
Pick a directory to hold the database and configuration. `~/.config/omnigateway`
|
|
64
|
+
is where `omni` looks by default:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
mkdir -p ~/.config/omnigateway && cd ~/.config/omnigateway
|
|
68
|
+
printf 'OMNI_ENCRYPTION_KEY=%s\n' "$(openssl rand -base64 32)" > .env
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
That key encrypts your provider credentials at rest. **Keep it. Changing it
|
|
72
|
+
makes every stored credential unreadable**, and there is no recovery path
|
|
73
|
+
except reconnecting the accounts.
|
|
74
|
+
|
|
75
|
+
Then set up and start:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
omni db migrate # create the database
|
|
79
|
+
omni admin set-password # prompts; the console signs in with this
|
|
80
|
+
omni start # serves the API and the console on 127.0.0.1:8787
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Connect an account. The CLI prints a URL to open, and waits:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
omni connect anthropic # or: openai, kimi
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Define a virtual model your clients will ask for, seeding its pricing and
|
|
90
|
+
capabilities from the built-in catalog:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
omni models catalog # what is available
|
|
94
|
+
omni models put fast --from-catalog anthropic:claude-sonnet-5
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Mint a key for your client. **It is printed once and stored only as a hash:**
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
omni keys create --label laptop
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Now use it:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
curl http://127.0.0.1:8787/v1/chat/completions \
|
|
107
|
+
-H 'content-type: application/json' \
|
|
108
|
+
-H 'authorization: Bearer <gateway-key>' \
|
|
109
|
+
-d '{"model": "fast", "messages": [{"role": "user", "content": "Hello"}]}'
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Everything above is also available in the browser at
|
|
113
|
+
`http://127.0.0.1:8787`, which walks the same steps.
|
|
114
|
+
|
|
115
|
+
## Using it from a client
|
|
116
|
+
|
|
117
|
+
| Method | Path | Compatible with |
|
|
118
|
+
| --- | --- | --- |
|
|
119
|
+
| `POST` | `/v1/messages` | Anthropic Messages API |
|
|
120
|
+
| `POST` | `/v1/chat/completions` | OpenAI Chat Completions API |
|
|
121
|
+
| `GET` | `/v1/models` | OpenAI-style listing, filtered by your key's allowlist |
|
|
122
|
+
| `GET` | `/health` | Unauthenticated liveness check |
|
|
123
|
+
|
|
124
|
+
Authenticate with either header — sending both is an error:
|
|
125
|
+
|
|
126
|
+
```http
|
|
127
|
+
Authorization: Bearer <gateway-key>
|
|
128
|
+
x-api-key: <gateway-key>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Ask for one of your virtual models by name. A bare provider model
|
|
132
|
+
(`claude-sonnet-5`, `gpt-5`) also works if an account can serve it.
|
|
133
|
+
|
|
134
|
+
Most tools that accept a custom base URL work unchanged: set it to
|
|
135
|
+
`http://127.0.0.1:8787` and use a gateway key where the provider key goes.
|
|
136
|
+
|
|
137
|
+
## The CLI
|
|
138
|
+
|
|
139
|
+
`omni --help` lists everything; `omni <command> --help` explains one. Every
|
|
140
|
+
command takes `--json` for scripting, and `--root <path>` to manage an
|
|
141
|
+
installation other than the default.
|
|
142
|
+
|
|
143
|
+
| | |
|
|
144
|
+
| --- | --- |
|
|
145
|
+
| `omni status` | the gateway, its accounts, and their quota, on one screen |
|
|
146
|
+
| `omni start` / `stop` / `restart` | run the gateway; `--foreground` attaches it to your terminal |
|
|
147
|
+
| `omni doctor` | which installation it resolved, and whether it can act on it |
|
|
148
|
+
| `omni logs` | recent requests as the gateway recorded them |
|
|
149
|
+
| `omni usage` | spend and tokens, by provider, model, key, or day |
|
|
150
|
+
| `omni connect <provider>` | authorize an account from the terminal |
|
|
151
|
+
| `omni credentials …` | list, show, enable, disable, retier, refresh, remove |
|
|
152
|
+
| `omni models …` | list, show, put, remove, `dry-run`, `catalog` |
|
|
153
|
+
| `omni keys …` | list, create, revoke |
|
|
154
|
+
| `omni settings get` / `set` | routing weights, retention, deadlines |
|
|
155
|
+
| `omni admin set-password` | change the console password |
|
|
156
|
+
| `omni db migrate` | create or upgrade the database |
|
|
157
|
+
|
|
158
|
+
Two worth knowing:
|
|
159
|
+
|
|
160
|
+
`omni models dry-run fast` shows exactly where a request would go and why —
|
|
161
|
+
each candidate's score, and every account that was excluded with the reason.
|
|
162
|
+
|
|
163
|
+
`omni status` is the "is anything wrong" command: process state, per-account
|
|
164
|
+
health, and how much provider quota each account has left.
|
|
165
|
+
|
|
166
|
+
## Running it as a service
|
|
167
|
+
|
|
168
|
+
On a machine with systemd:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
omni service install --enable # writes a user unit for this installation
|
|
172
|
+
omni start # from here on, start/stop delegate to systemctl
|
|
173
|
+
omni logs --service # reads the journal
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Use `--system` for a system-wide unit (needs root). Without systemd, `omni
|
|
177
|
+
start` supervises the process itself with a pidfile under
|
|
178
|
+
`~/.local/state/omnigateway`. Either way, `omni start` returns only once
|
|
179
|
+
`/health` actually answers.
|
|
180
|
+
|
|
181
|
+
## Configuration
|
|
182
|
+
|
|
183
|
+
Configuration is environment variables, read from the installation's `.env`:
|
|
184
|
+
|
|
185
|
+
| Variable | Required | Default | Purpose |
|
|
186
|
+
| --- | --- | --- | --- |
|
|
187
|
+
| `OMNI_ENCRYPTION_KEY` | Yes | — | Encrypts provider credentials at rest; 16 characters minimum |
|
|
188
|
+
| `OMNI_HOST` | No | `127.0.0.1` | Listener host |
|
|
189
|
+
| `OMNI_PORT` | No | `8787` | Listener port |
|
|
190
|
+
| `OMNI_DB_PATH` | No | `./omnigateway.db` | SQLite database path |
|
|
191
|
+
| `OMNI_BASE_URL` | No | derived from host and port | Public origin for OAuth callbacks; set this behind a reverse proxy |
|
|
192
|
+
| `OMNI_STATIC_DIR` | No | the console shipped with the server | Serve a different console build |
|
|
193
|
+
|
|
194
|
+
Routing behaviour — weights, retry limits, request deadline, log retention,
|
|
195
|
+
how often provider quota is polled — lives in the database, not the
|
|
196
|
+
environment. Edit it with `omni settings set` or in the console.
|
|
197
|
+
|
|
198
|
+
`.env.example` in the repository documents the optional provider
|
|
199
|
+
client-identity overrides.
|
|
200
|
+
|
|
201
|
+
## Docker
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
docker build -t omnigateway .
|
|
205
|
+
docker run --rm \
|
|
206
|
+
-p 8787:8787 \
|
|
207
|
+
-e OMNI_ENCRYPTION_KEY="$(openssl rand -base64 32)" \
|
|
208
|
+
-v omnigateway-data:/data \
|
|
209
|
+
omnigateway
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
The container listens on `0.0.0.0:8787` and keeps its database at
|
|
213
|
+
`/data/omnigateway.db`. Note that **the image builds the gateway only**: it
|
|
214
|
+
serves the APIs and returns 404 for the console. Use the CLI or the control API
|
|
215
|
+
against it, or install the npm package if you want the console.
|
|
216
|
+
|
|
217
|
+
## Scope and limits
|
|
218
|
+
|
|
219
|
+
Worth knowing before you deploy it:
|
|
220
|
+
|
|
221
|
+
- **One machine, one operator.** No multi-tenancy, no clustering, no shared
|
|
222
|
+
state. Rate limits are counted per process and reset when it restarts.
|
|
223
|
+
- **Two grains of usage history.** Detailed request logs are pruned after 30
|
|
224
|
+
days by default; a daily rollup is kept for 400 days. A day is your host's
|
|
225
|
+
local midnight, fixed when the row is written.
|
|
226
|
+
- **Quota readings come from the providers**, and their usage endpoints are
|
|
227
|
+
undocumented. An account with nothing reported is treated as unknown, never
|
|
228
|
+
as unlimited.
|
|
229
|
+
- **The gateway does not know which model accepts which request shape.** An
|
|
230
|
+
unsupported combination surfaces as the provider's own 400 rather than being
|
|
231
|
+
caught earlier.
|
|
232
|
+
- Not in scope for version 1: semantic caching, billing, prompt storage,
|
|
233
|
+
horizontal scaling.
|
|
234
|
+
|
|
235
|
+
## Security
|
|
236
|
+
|
|
237
|
+
- Treat `OMNI_ENCRYPTION_KEY`, gateway keys, and the SQLite file as secrets.
|
|
238
|
+
Anyone with the file *and* the key has your provider credentials.
|
|
239
|
+
- Prompts and responses are never logged. Request logs hold metadata and token
|
|
240
|
+
counts only.
|
|
241
|
+
- Gateway keys are stored as hashes. A lost key is reissued, not recovered.
|
|
242
|
+
- Secrets are never accepted on the command line — `omni` prompts for them or
|
|
243
|
+
reads stdin — so they stay out of your shell history and the process table.
|
|
244
|
+
- Behind a reverse proxy, set `OMNI_BASE_URL` to the public HTTPS origin so
|
|
245
|
+
OAuth callbacks match what the providers have registered.
|
|
246
|
+
- The gateway talks to your providers and to nobody else. No telemetry, no CDN
|
|
247
|
+
fonts, no third-party origins.
|
|
248
|
+
|
|
249
|
+
## Development
|
|
250
|
+
|
|
251
|
+
Contributing, or running from a checkout? See [CLAUDE.md](CLAUDE.md) for the
|
|
252
|
+
repository map, architectural boundaries, and conventions, and
|
|
253
|
+
`docs/superpowers/specs/` for the design documents behind each feature.
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
git clone https://github.com/harismawan/omnigateway.git
|
|
257
|
+
cd omnigateway
|
|
258
|
+
bun install
|
|
259
|
+
cp .env.example .env # then set OMNI_ENCRYPTION_KEY
|
|
260
|
+
bun run build:dashboard # the gateway serves this build
|
|
261
|
+
bun run dev # gateway on 8787, with file watching
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Releases are published to npm from a `v*` tag, with provenance attesting which
|
|
265
|
+
commit produced them.
|