saros-proxy 1.0.0 → 1.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 +83 -16
- package/assets/models.json +3349 -0
- package/dist/cli/autostart.d.ts +13 -6
- package/dist/cli/autostart.js +317 -60
- package/dist/cli/autostart.js.map +1 -1
- package/dist/cli/daemon.js +89 -14
- package/dist/cli/daemon.js.map +1 -1
- package/dist/cli/harness-models.d.ts +5 -4
- package/dist/cli/harness-models.js +77 -30
- package/dist/cli/harness-models.js.map +1 -1
- package/dist/cli/help.js +5 -0
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/log-render.d.ts +16 -0
- package/dist/cli/log-render.js +82 -0
- package/dist/cli/log-render.js.map +1 -0
- package/dist/cli/opencode-config.d.ts +1 -0
- package/dist/cli/opencode-config.js +7 -6
- package/dist/cli/opencode-config.js.map +1 -1
- package/dist/config.js +20 -4
- package/dist/config.js.map +1 -1
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +2 -0
- package/dist/constants.js.map +1 -1
- package/dist/index.js +29 -36
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts +16 -0
- package/dist/logger.js +56 -23
- package/dist/logger.js.map +1 -1
- package/dist/model-ladder.d.ts +30 -0
- package/dist/model-ladder.js +45 -0
- package/dist/model-ladder.js.map +1 -0
- package/dist/models-catalog.d.ts +25 -4
- package/dist/models-catalog.js +41 -12
- package/dist/models-catalog.js.map +1 -1
- package/dist/models-dev.d.ts +72 -0
- package/dist/models-dev.js +196 -0
- package/dist/models-dev.js.map +1 -0
- package/dist/models-refresh.d.ts +144 -0
- package/dist/models-refresh.js +522 -0
- package/dist/models-refresh.js.map +1 -0
- package/dist/models-sync.d.ts +6 -10
- package/dist/models-sync.js +26 -60
- package/dist/models-sync.js.map +1 -1
- package/package.json +5 -5
- package/models.json +0 -1440
package/README.md
CHANGED
|
@@ -176,11 +176,11 @@ Saros tracks which keys are currently in use. A key handling a streaming request
|
|
|
176
176
|
|
|
177
177
|
### Prompt Install(for the lazy ones)
|
|
178
178
|
|
|
179
|
-
Don't feel like reading through everything? Copy this prompt and paste it to your AI assistant. It'll read [`LLM_INSTRUCTIONS.md`](LLM_INSTRUCTIONS.md) and guide you through setup — no keys shared in chat.
|
|
179
|
+
Don't feel like reading through everything? Copy this prompt and paste it to your AI assistant. It'll read [`docs/LLM_INSTRUCTIONS.md`](docs/LLM_INSTRUCTIONS.md) and guide you through setup — no keys shared in chat.
|
|
180
180
|
|
|
181
181
|
```
|
|
182
182
|
Install Saros Proxy for my opencode. (https://github.com/vitorvilaca3011/saros-proxy)
|
|
183
|
-
Follow the instructions on LLM_INSTRUCTIONS.md.
|
|
183
|
+
Follow the instructions on docs/LLM_INSTRUCTIONS.md.
|
|
184
184
|
```
|
|
185
185
|
|
|
186
186
|
---
|
|
@@ -481,14 +481,21 @@ into the "no passphrase source" boot error — a locked keyring is not reported
|
|
|
481
481
|
as an empty store.
|
|
482
482
|
|
|
483
483
|
**systemd-creds recipe** (keeps the passphrase out of the unit file and the
|
|
484
|
-
environment of the shell)
|
|
484
|
+
environment of the shell). This is a **system** unit recipe — run the encryption
|
|
485
|
+
as root, since the host key lives in `/var/lib/systemd/credential.secret`:
|
|
485
486
|
|
|
486
487
|
```bash
|
|
487
|
-
# One-time: encrypt stdin into a host
|
|
488
|
-
|
|
488
|
+
# One-time, as root: encrypt stdin into a host-bound credential.
|
|
489
|
+
# (--with-key=auto picks tpm2+host when the TPM is available, host otherwise.
|
|
490
|
+
# "host+user" is not a valid key type, and --user only exists from v256.)
|
|
491
|
+
systemd-creds encrypt --name=saros-passphrase --with-key=auto \
|
|
489
492
|
/dev/stdin /etc/saros/passphrase.cred
|
|
490
493
|
```
|
|
491
494
|
|
|
495
|
+
For the `systemd --user` unit created by `saros-proxy autostart install`, use
|
|
496
|
+
`Environment=`/`EnvironmentFile=` instead: user credentials need
|
|
497
|
+
`systemd-creds --user`, which only exists from systemd v256 (this host runs 255).
|
|
498
|
+
|
|
492
499
|
```ini
|
|
493
500
|
# /etc/systemd/system/saros-proxy.service
|
|
494
501
|
[Service]
|
|
@@ -544,7 +551,6 @@ export CIRCUIT_BREAKER_THRESHOLD=5
|
|
|
544
551
|
export CIRCUIT_BREAKER_COOLDOWN_MS=120000
|
|
545
552
|
export REQUEST_TIMEOUT_MS=45000
|
|
546
553
|
export LOG_LEVEL=debug
|
|
547
|
-
export NODE_ENV=development
|
|
548
554
|
|
|
549
555
|
npx tsx src/index.ts
|
|
550
556
|
```
|
|
@@ -591,16 +597,48 @@ saros-proxy probe
|
|
|
591
597
|
# Show per-key quota usage, token totals and most-used models
|
|
592
598
|
saros-proxy usage
|
|
593
599
|
|
|
594
|
-
# Install autostart (Windows: VBS script or Registry)
|
|
595
|
-
saros-proxy autostart install [--port <port>] [--method vbs|registry|auto]
|
|
600
|
+
# Install autostart (Linux: systemd --user; Windows: VBS script or Registry)
|
|
601
|
+
saros-proxy autostart install [--port <port>] [--method systemd|vbs|registry|auto]
|
|
596
602
|
|
|
597
603
|
# Uninstall autostart
|
|
598
|
-
saros-proxy autostart uninstall [--method vbs|registry|auto]
|
|
604
|
+
saros-proxy autostart uninstall [--method systemd|vbs|registry|auto]
|
|
599
605
|
|
|
600
606
|
# Check autostart status
|
|
601
|
-
saros-proxy autostart status [--method vbs|registry|auto]
|
|
607
|
+
saros-proxy autostart status [--method systemd|vbs|registry|auto]
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
On Linux the default is a `systemd --user` unit at
|
|
611
|
+
`~/.config/systemd/user/saros-proxy.service` (honouring `$XDG_CONFIG_HOME`), enabled
|
|
612
|
+
with `systemctl --user enable` and restarted with `systemctl --user restart`. On
|
|
613
|
+
Windows the default is AV-aware (`auto`): Registry when third-party antivirus is
|
|
614
|
+
detected, otherwise the Startup-folder VBS.
|
|
615
|
+
|
|
616
|
+
Manage the unit with systemd, not with the CLI: `saros-proxy stop` exits non-zero
|
|
617
|
+
while the service still answers `/health`, because the CLI does not own the unit's
|
|
618
|
+
process.
|
|
619
|
+
|
|
620
|
+
```bash
|
|
621
|
+
systemctl --user start|stop|restart|status saros-proxy.service
|
|
622
|
+
journalctl --user -u saros-proxy -f
|
|
602
623
|
```
|
|
603
624
|
|
|
625
|
+
The unit runs `serve` in the foreground: without a TTY it cannot prompt for a
|
|
626
|
+
passphrase, and the user manager does not inherit the environment of the shell
|
|
627
|
+
that ran `install`. If `config.yaml` holds `enc:v1:` envelopes, give the unit a
|
|
628
|
+
source through a drop-in (`systemctl --user edit saros-proxy.service`):
|
|
629
|
+
|
|
630
|
+
```ini
|
|
631
|
+
[Service]
|
|
632
|
+
Environment=SAROS_PASSPHRASE=your-passphrase
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
`EnvironmentFile=-%h/.config/saros/env` (mode 0600) keeps the value out of the
|
|
636
|
+
unit file. A credential is stronger, but `Environment=` can only carry the
|
|
637
|
+
credential *path* (`%d/<name>`), never its content — see the
|
|
638
|
+
[systemd-creds recipe](#api-key-encryption), which wraps `serve` in
|
|
639
|
+
`sh -c 'SAROS_PASSPHRASE="$(cat "$CREDENTIALS_DIRECTORY/<name>")" exec …'`.
|
|
640
|
+
`systemd-creds` only gained a `--user` mode in v256.
|
|
641
|
+
|
|
604
642
|
The `start` command automatically syncs model definitions to all enabled harnesses (see [Multi-Harness Integration](#multi-harness-integration-pi-oh-my-pi--dsh)).
|
|
605
643
|
|
|
606
644
|
### Model Sync Commands
|
|
@@ -752,7 +790,7 @@ Behavior:
|
|
|
752
790
|
- Sync never creates a harness config: harnesses whose config file is missing are skipped.
|
|
753
791
|
- Only `providers["saros-proxy"].models` is replaced; all other providers, fields, and settings are preserved, and a `<file>.backup` is created before the first write.
|
|
754
792
|
|
|
755
|
-
The model list written to each harness comes from the live provider catalogs (opencode-go) enriched with models.dev metadata, merged with any CommandCode-only models — falling back to bundled models when offline — so every harness stays current alongside OpenCode.
|
|
793
|
+
The model list written to each harness comes from the live provider catalogs (opencode-go) enriched with models.dev metadata, merged with any CommandCode-only models — falling back to the bundled `assets/models.json` when offline — so every harness stays current alongside OpenCode.
|
|
756
794
|
|
|
757
795
|
> **Why a static model list?** The harnesses use a static `models` list on purpose. `pi` has no `/v1/models` discovery for custom providers, and `oh-my-pi`'s discovery cannot recover reasoning/context/output metadata for provider model IDs. `dsh` replaces only `providers["saros-proxy"].models` in its patch layer (`cordis.patch.yml`), which dsh rewrites at every boot — a static, explicitly-managed list is the only reliable source. Dynamic discovery would silently break thinking-level (`:max`/`:high`) role configs.
|
|
758
796
|
|
|
@@ -781,14 +819,30 @@ Returns JSON with key counts, active requests, and circuit-breaker state.
|
|
|
781
819
|
|
|
782
820
|
### View logs
|
|
783
821
|
|
|
822
|
+
CLI commands (`status`, `start`, `usage`, …) and a foreground `serve` render
|
|
823
|
+
each log record as one human line: `·` info on stdout, `⚠` warning and `✗`
|
|
824
|
+
error on stderr. The line is the message plus, when the record carries them, a
|
|
825
|
+
gray tail with the public request fields
|
|
826
|
+
`status · keyLabel · provider · durationMs · requestId`. Nothing else from the
|
|
827
|
+
logger reaches the terminal:
|
|
828
|
+
|
|
784
829
|
```bash
|
|
785
|
-
|
|
786
|
-
|
|
830
|
+
saros-proxy status
|
|
831
|
+
```
|
|
787
832
|
|
|
788
|
-
|
|
789
|
-
|
|
833
|
+
Parsing the output from a script? Set `SAROS_LOG_JSON=1` to force the raw
|
|
834
|
+
NDJSON format in any mode:
|
|
835
|
+
|
|
836
|
+
```bash
|
|
837
|
+
SAROS_LOG_JSON=1 saros-proxy status
|
|
790
838
|
```
|
|
791
839
|
|
|
840
|
+
The daemon child, `daemon.log` and the systemd journal are always NDJSON
|
|
841
|
+
(`SAROS_DAEMON=1`, or `NODE_ENV=production` on `serve` — which is what the
|
|
842
|
+
systemd unit and the Docker service use); those lines are never rendered for a
|
|
843
|
+
terminal. Other commands stay human even when `NODE_ENV=production` is
|
|
844
|
+
inherited.
|
|
845
|
+
|
|
792
846
|
### See which key and provider served a request
|
|
793
847
|
|
|
794
848
|
Responses served by an upstream key carry three debug headers:
|
|
@@ -866,6 +920,18 @@ npm run build
|
|
|
866
920
|
|
|
867
921
|
Output goes to `dist/`.
|
|
868
922
|
|
|
923
|
+
### Refresh the bundled model catalog
|
|
924
|
+
|
|
925
|
+
`assets/models.json` is generated — do not edit it by hand. The generator merges models.dev metadata with the live opencode-go and CommandCode catalogs: a model that left upstream leaves the bundle, a model the upstream serves but models.dev does not list still enters with the live name and context window, and a field already in the file survives when models.dev omits it.
|
|
926
|
+
|
|
927
|
+
```bash
|
|
928
|
+
npm run models:refresh -- --dry-run # print the diff, write nothing
|
|
929
|
+
npm run models:refresh # rewrite assets/models.json
|
|
930
|
+
npm run models:refresh -- --allow-shrink # accept removing more than half of the models
|
|
931
|
+
```
|
|
932
|
+
|
|
933
|
+
A failed fetch — or a 2xx with an empty catalog — aborts before the file is read, and a merge that would remove more than half of the current models aborts unless `--allow-shrink` is given. The write goes through a temp file and an atomic rename, so a crash never leaves a truncated catalog.
|
|
934
|
+
|
|
869
935
|
### Project structure
|
|
870
936
|
|
|
871
937
|
```
|
|
@@ -879,7 +945,8 @@ src/
|
|
|
879
945
|
providers/ — Multi-provider key abstraction (KeyProvider, adapters, identifyKey)
|
|
880
946
|
models-fetcher.ts — Upstream model list fetching + caching
|
|
881
947
|
models-sync.ts — Auto-sync models from upstream to opencode config
|
|
882
|
-
models-catalog.ts — Single source of truth: loads
|
|
948
|
+
models-catalog.ts — Single source of truth: loads assets/models.json
|
|
949
|
+
models-refresh.ts — Generates that catalog (npm run models:refresh)
|
|
883
950
|
cli/
|
|
884
951
|
setup.ts — Interactive setup wizard
|
|
885
952
|
daemon.ts — Background process management
|