@askalf/dario 6.0.49 → 6.0.51

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 CHANGED
@@ -283,7 +283,7 @@ Two consumer plans, no API keys, and neither one able to take you down on its ow
283
283
  dario proxy --pool-fallback=gpt-5.6-sol,claude-sonnet-5
284
284
  ```
285
285
 
286
- That is a **chain**, read left to right; each provider takes the first entry it can actually serve. Prefix every entry with a tier and the same flag becomes a **tier map**: `--pool-fallback=haiku:gpt-5.4-mini,sonnet:gpt-5.6-terra,opus:gpt-5.6-sol` picks one rung per request from the tier of the model asked for (`default:` catches the rest, otherwise the first rung), so heartbeat work on Haiku never overflows onto a flagship. That shipped in 6.0.17, the same day a Haiku-tier fleet spent 79% of a weekly allowance doing exactly that. When the Claude pool is drained or cooling, the request is served as `gpt-5.6-sol` from your ChatGPT subscription. When the subscription is rate-limited or down, the request is handed back to the Claude pool as `claude-sonnet-5`. Every substituted response carries `x-dario-pool-fallback: <model>` — a silently swapped model family is exactly the surprise this project exists to avoid.
286
+ That is a **chain**, read left to right; each provider takes the first entry it can actually serve. Prefix every entry with a tier and the same flag becomes a **tier map**: `--pool-fallback=haiku:gpt-5.6-luna,sonnet:gpt-5.6-terra,opus:gpt-5.6-sol` picks one rung per request from the tier of the model asked for (`default:` catches the rest, otherwise the first rung), so heartbeat work on Haiku never overflows onto a flagship. That shipped in 6.0.17, the same day a Haiku-tier fleet spent 79% of a weekly allowance doing exactly that. When the Claude pool is drained or cooling, the request is served as `gpt-5.6-sol` from your ChatGPT subscription. When the subscription is rate-limited or down, the request is handed back to the Claude pool as `claude-sonnet-5`. Every substituted response carries `x-dario-pool-fallback: <model>` — a silently swapped model family is exactly the surprise this project exists to avoid.
287
287
 
288
288
  <img src=".github/readme/failover.jpg" alt="A tool sends a request to dario. The Claude plan answers 429, so dario re-serves the same request from the ChatGPT plan, which answers 200, and the response returns to the tool carrying the x-dario-pool-fallback header." width="100%">
289
289
 
@@ -106,6 +106,36 @@ curl http://localhost:3456/analytics # per-account / per-model stats, burn ra
106
106
 
107
107
  **When every seat is parked.** A pool whose seats are all `rejected` inside live windows does not probe them again: dario answers the request itself with `429`, `retry-after` set to the earliest reset, `x-dario-upstream-rejection: pool_parked`, and nothing sent upstream. One log line marks the transition (`pool parked: all 6 seats are over their rate-limit windows, earliest resets in 21m`). Before 6.0.35 every such request re-probed the earliest-reset seat, so `rejectedCount` on that seat grew by one per request — a seat reading `rejected_count: 500` next to `request_count: 1` was that, not a seat that needed a re-login. With a `--pool-fallback` armed, the request goes to the fallback instead, as before.
108
108
 
109
+ **Spending extra usage while the pool is parked (dario#1282).** The parked answer is decided
110
+ from the seats' own rate-limit verdicts, before anything is sent. Disarming the overage-guard
111
+ does **not** change it: the guard is reactive — it reads the `representative-claim` on a
112
+ response that already came back — so the two knobs act at different moments and neither one
113
+ unlocks the other. If the account has extra usage and you want a request to reach it anyway,
114
+ pin the request to a seat:
115
+
116
+ ```bash
117
+ curl -sS localhost:4000/v1/messages \
118
+ -H 'content-type: application/json' \
119
+ -H 'x-dario-account: <alias>' \
120
+ -H "x-dario-admin-token: $DARIO_ADMIN_TOKEN" \
121
+ -d '{"model":"claude-sonnet-5","max_tokens":16,"messages":[{"role":"user","content":"ping"}]}'
122
+ ```
123
+
124
+ A pinned request is assigned its seat before the parked check runs, so it goes upstream and the
125
+ real status comes back — which is the only way to learn what Anthropic does with a request into a
126
+ spent window. Two consequences are worth knowing before you use it:
127
+
128
+ - **The guard will halt the proxy on the way back.** A response billing to anything other than the
129
+ subscription halts dario by default, and every request after it — pinned or not — gets
130
+ `503 dario_overage_guard`. Pair the pin with `--overage-behavior=warn` (or the guard off) or the
131
+ answer costs you the proxy.
132
+ - **A successful pinned response un-parks that seat for everyone.** Its snapshot is replaced by the
133
+ new response's, so the seat leaves `rejected` and ordinary traffic starts landing on it again
134
+ until the next 429. The pin opens the door; it does not hold it open for one request only.
135
+
136
+ `--pool-fallback` is a different answer to the same situation: it keeps the gateway serving by
137
+ sending the request to another provider, which means it never spends Anthropic extra usage.
138
+
109
139
  The proxy logs every parking as it happens, once per window: `rate limited (429) on account "spare": 5h 104%, 7d 25%, claim five_hour, resets in 37m — parked until the window rolls`. The re-probes the all-exhausted fallback makes of an already-parked seat are logged only under `-v`.
110
140
 
111
141
  `dario accounts list --live` prints the same view from the running proxy — status with its countdown, the reading and its age, requests served and 429s answered, the organization, shared windows, grant age — where the plain `dario accounts list` only knows what is on disk.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askalf/dario",
3
- "version": "6.0.49",
3
+ "version": "6.0.51",
4
4
  "description": "Use your Claude and ChatGPT subscriptions in Cursor, Cline, Aider, Claude Code and the Agent SDK — at subscription pricing, not per-token API bills. One local Anthropic + OpenAI-compatible endpoint: either plan answers either wire shape, with automatic failover when one hits its limit.",
5
5
  "type": "module",
6
6
  "bin": {