pool-anything 0.1.0 → 0.1.1
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/README.md +13 -4
- package/data/providers.json +1 -1
- package/dist/admin/branding.js +1 -0
- package/dist/admin/pages.js +632 -46
- package/dist/admin/seo.js +58 -0
- package/dist/admin/shell.js +45 -2
- package/dist/cli/commands.js +276 -0
- package/dist/cli/nl.js +10 -0
- package/dist/cli/repl.js +95 -331
- package/dist/cli/tui.js +254 -0
- package/dist/cli/ui.js +2 -0
- package/dist/cli.js +11 -3
- package/dist/data/providers.json +1 -1
- package/dist/playground/adapters.js +304 -0
- package/dist/pool/index.js +39 -0
- package/dist/proxy/forward.js +44 -2
- package/dist/router/api.js +2 -2
- package/dist/server.js +43 -4
- package/dist/upstream/index.js +10 -0
- package/dist/version.js +160 -0
- package/package.json +8 -3
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache%202.0-blue.svg" alt="License" /></a>
|
|
12
12
|
<a href="https://nodejs.org"><img src="https://img.shields.io/badge/node-%3E%3D22.5-brightgreen.svg" alt="Node" /></a>
|
|
13
13
|
<a href="tsconfig.json"><img src="https://img.shields.io/badge/TypeScript-strict-blue.svg" alt="TypeScript" /></a>
|
|
14
|
-
<a href="package.json"><img src="https://img.shields.io/badge/
|
|
14
|
+
<a href="package.json"><img src="https://img.shields.io/badge/server%20core-0%20dependencies-brightgreen.svg" alt="Server core dependencies" /></a>
|
|
15
15
|
</p>
|
|
16
16
|
|
|
17
17
|
<p align="center">
|
|
@@ -29,7 +29,7 @@ Most AI/API providers hand you a free tier: a rate limit, a daily quota, a handf
|
|
|
29
29
|
- 🌐 **Drop-in HTTP proxy** — point your client at pool-anything; it forwards with the right key, header, and auth scheme
|
|
30
30
|
- 🔌 **36 providers preconfigured** — Groq, OpenRouter, Gemini, OpenAI, Anthropic, and more (plus any custom provider)
|
|
31
31
|
- 🖥️ **Built-in web UI** — search providers, gather keys, watch usage on the Analytics dashboard
|
|
32
|
-
- 🧰 **
|
|
32
|
+
- 🧰 **Dependency-free server core** — the proxy, API, and web UI run on Node built-ins + `node:sqlite` only; the interactive shell adds Ink + React
|
|
33
33
|
|
|
34
34
|
## Quick start
|
|
35
35
|
|
|
@@ -45,6 +45,8 @@ That's it — an interactive assistant shell opens (`pool-anything >`). Type pla
|
|
|
45
45
|
```bash
|
|
46
46
|
pool-anything serve --port 4000 --open # web UI + API on :4000, open the browser
|
|
47
47
|
pool-anything "list pools" # run one command without the shell
|
|
48
|
+
pool-anything "update" # upgrade to the latest version (also an Update pill in the web UI header)
|
|
49
|
+
pool-anything "uninstall" # remove the global CLI (shell only, asks to confirm)
|
|
48
50
|
echo "gsk_abc" | pool-anything -e "add keys to groq" # pipe keys in
|
|
49
51
|
pool-anything --help # all options (serve, -e/--exec, -p/--port, -H/--host, --db, --data-dir, --open)
|
|
50
52
|
```
|
|
@@ -62,8 +64,10 @@ No subcommands to memorize — just say what you want:
|
|
|
62
64
|
| `watch groq` | Live usage, 2s refresh (`q` exits) |
|
|
63
65
|
| `next for groq` / `consume 100 on groq` | Rotate / record usage |
|
|
64
66
|
| `serve` | Start the web UI + API from inside the shell |
|
|
67
|
+
| `update` (or `/update`) | Check npm and upgrade to the latest version |
|
|
68
|
+
| `uninstall` (or `/uninstall`, CLI only) | Remove the global CLI (asks to confirm; pools/keys in SQLite stay) |
|
|
65
69
|
|
|
66
|
-
Keys always print masked (`gsk_…ab`); misunderstood input gets a "Did you mean …?" nudge.
|
|
70
|
+
Keys always print masked (`gsk_…ab`); misunderstood input gets a "Did you mean …?" nudge. The shell is a rich terminal UI (colors, bordered panels, live `watch` view, `↑`/`↓` history) with a plain-text fallback when Ink can't initialize.
|
|
67
71
|
|
|
68
72
|
### Run from source
|
|
69
73
|
|
|
@@ -140,6 +144,7 @@ All responses are JSON. `:id` is a pool ID.
|
|
|
140
144
|
| `GET` | `/api/pools/:id/next` | Rotate: return the next key (masked — never the raw key) |
|
|
141
145
|
| `POST` | `/api/pools/:id/consume` | Record usage — `{ tokens: <positive int ≤ 1000000>, key_id? }` (with `key_id`, bills that key without rotating) |
|
|
142
146
|
| `GET` | `/api/pools/:id/usage` | Usage rollup — `{ used, usedInWindow, quota, quotaWindow, remaining, perKey }` (`used` is lifetime; `remaining`/`usedInWindow`/`perKey` are windowed for monthly quotas) |
|
|
147
|
+
| `GET` | `/api/pools/:id/calls?limit=` | Recent upstream attempts — status, tokens, response body (4000 chars text, ~2MB retained media), per key (default 50, max 200) |
|
|
143
148
|
| `POST` | `/api/pools/:id/proxy` | Proxy a request through the pool (see below) |
|
|
144
149
|
|
|
145
150
|
### Keys
|
|
@@ -183,6 +188,8 @@ The response reports which key was used and the upstream status:
|
|
|
183
188
|
| `GET` | `/health` | Liveness check → `ok` |
|
|
184
189
|
| `GET` | `/api/db/ping` | SQLite reachability → `{ ok: true }` |
|
|
185
190
|
| `GET` | `/api/analytics` | Totals + 7-day deltas + 14-day daily series (drives the dashboard) |
|
|
191
|
+
| `GET` | `/api/version` | Current vs latest npm version + `updateAvailable` (drives the header Update pill) |
|
|
192
|
+
| `POST` | `/api/update` | Self-update via `npm install -g pool-anything@latest` (needs `POOL_API_TOKEN` bearer when auth is on) |
|
|
186
193
|
|
|
187
194
|
## Web UI
|
|
188
195
|
|
|
@@ -222,6 +229,7 @@ Open the Pages URL with `?api=https://your-backend` once (or use the Backend pil
|
|
|
222
229
|
| `LOCAL_DB_PATH` | `data/pool-anything.db` (checkout) / `~/.pool-anything/*.db` (global) | SQLite database location (exact file; `--db` flag equivalent) |
|
|
223
230
|
| `POOL_DATA_DIR` | _(unset)_ | Data directory holding the SQLite file (`<dir>/pool-anything.db`; `--data-dir` flag equivalent) |
|
|
224
231
|
| `PROXY_TIMEOUT_MS` | `30000` | Per-attempt upstream timeout for `/proxy` |
|
|
232
|
+
| `POOL_DEBUG` | _(unset)_ | `1` logs per-request proxy traces (`[proxy] METHOD path pool=N tried=[...]`) to stderr — no bodies/keys; playground also keeps a per-session Debug log pane |
|
|
225
233
|
| `ALLOW_PRIVATE_UPSTREAM` | _(unset)_ | `1` disables SSRF protections — tests/loopback only, never in prod |
|
|
226
234
|
|
|
227
235
|
Providers are defined in [`data/providers.json`](data/providers.json). See [CONTRIBUTING.md](CONTRIBUTING.md#adding-a-provider) for the schema — adding a provider is a one-line JSON edit, no code changes.
|
|
@@ -232,7 +240,8 @@ Providers are defined in [`data/providers.json`](data/providers.json). See [CONT
|
|
|
232
240
|
src/
|
|
233
241
|
server.ts Thin HTTP front door (delegates to router/admin/observability)
|
|
234
242
|
cli.ts Entry dispatch: assistant shell (default) vs `serve` vs one-shot
|
|
235
|
-
cli/ Interactive shell —
|
|
243
|
+
cli/ Interactive shell — commands.ts (presentation-free core), nl.ts (parser), ui.ts (text rendering), repl.ts (plain fallback + one-shot), tui.tsx (Ink shell)
|
|
244
|
+
version.ts Self-update (npm version check / install / uninstall) shared by the CLI and the web UI
|
|
236
245
|
router/api.ts Route matchers + abuse caps (MAX_POOLS / MAX_KEYS_PER_POOL)
|
|
237
246
|
admin/branding.ts Logo version, docs URL, sidebar icons
|
|
238
247
|
admin/shell.ts Shared shell CSS/nav/JS
|
package/data/providers.json
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
{"id":"perplexity","name":"Perplexity","baseUrl":"https://api.perplexity.ai","keyHeader":"Authorization","keyPrefix":"Bearer ","extraHeaders":{},"quota":"$5 credit on signup","docsUrl":"https://docs.perplexity.ai/getting-started/quickstart","keyFields":["api_key"],"hint":"perplexity.ai/settings/api, pplx-…","logo":"public/logos/perplexity.svg"},
|
|
14
14
|
{"id":"anyscale","name":"Anyscale Endpoints","baseUrl":"https://api.endpoints.anyscale.com/v1","keyHeader":"Authorization","keyPrefix":"Bearer ","extraHeaders":{},"quota":"legacy, deprecated","docsUrl":"https://docs.anyscale.com/endpoints/overview","keyFields":["api_key"],"hint":"app.endpoints.anyscale.com/credentials","logo":"public/logos/anyscale.svg"},
|
|
15
15
|
{"id":"elevenlabs","name":"ElevenLabs","baseUrl":"https://api.elevenlabs.io/v1","keyHeader":"xi-api-key","keyPrefix":"","extraHeaders":{},"quota":"10k credits/mo free","docsUrl":"https://elevenlabs.io/docs","keyFields":["api_key"],"hint":"elevenlabs.io API key","logo":"public/logos/elevenlabs.svg"},
|
|
16
|
-
{"id":"deepgram","name":"Deepgram","baseUrl":"https://api.deepgram.com
|
|
16
|
+
{"id":"deepgram","name":"Deepgram","baseUrl":"https://api.deepgram.com","keyHeader":"Authorization","keyPrefix":"Token ","extraHeaders":{},"quota":"$200 credit on signup","docsUrl":"https://developers.deepgram.com/docs","keyFields":["api_key"],"hint":"Authorization: Token …","logo":"public/logos/deepgram.svg"},
|
|
17
17
|
{"id":"cartesia","name":"Cartesia","baseUrl":"https://api.cartesia.ai","keyHeader":"X-API-Key","keyPrefix":"","extraHeaders":{"Cartesia-Version":"2024-06-10"},"quota":"20,000 free tokens","docsUrl":"https://docs.cartesia.ai","keyFields":["api_key"],"hint":"Paste a Cartesia API key","logo":"public/logos/cartesia.svg"},
|
|
18
18
|
{"id":"tavily","name":"Tavily","baseUrl":"https://api.tavily.com","keyHeader":"Authorization","keyPrefix":"Bearer ","extraHeaders":{},"quota":"1,000 credits/mo free","docsUrl":"https://docs.tavily.com/documentation/api-reference/endpoint/search","keyFields":["api_key"],"hint":"app.tavily.com/home, tvly-…","logo":"public/logos/tavily.svg"},
|
|
19
19
|
{"id":"brave-search","name":"Brave Search","baseUrl":"https://api.search.brave.com/res/v1","keyHeader":"X-Subscription-Token","keyPrefix":"","extraHeaders":{},"quota":"2,000 queries/mo free","docsUrl":"https://brave.com/search/api/","keyFields":["api_key"],"hint":"brave.com/search/api/","logo":"public/logos/brave.svg"},
|
package/dist/admin/branding.js
CHANGED
|
@@ -21,6 +21,7 @@ export const ICONS = {
|
|
|
21
21
|
keys: svgIcon('<circle cx="8" cy="16" r="4.5"/><path d="m11.2 12.8 8.3-8.3"/><path d="M17 5.5l2.5 2.5M14.5 8l2.5 2.5"/>'),
|
|
22
22
|
analytics: svgIcon('<path d="M3 21h18"/><path d="M6 21v-7M11 21V5M16 21v-11M21 21v-4"/>'),
|
|
23
23
|
playground: svgIcon('<circle cx="12" cy="12" r="9"/><path d="m10 8.5 5 3.5-5 3.5v-7Z"/>'),
|
|
24
|
+
history: svgIcon('<path d="M3.5 12a8.5 8.5 0 1 1 2.4 6"/><path d="M3.5 12H7"/><path d="M3.5 12V8.5"/><path d="M12 7.5V12l3 2"/>'),
|
|
24
25
|
docs: svgIcon('<path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/>'),
|
|
25
26
|
/** Attach-row media icons: same 24px stroke family as sidebar (currentColor, 1.8, round).
|
|
26
27
|
* Sized down to 14px via `.filebtn svg` in playground CSS. */
|