@rouvanpm/rouva 0.3.1 → 0.3.2

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
@@ -338,14 +338,14 @@ try {
338
338
  await rouva.chat.completions.create({ messages })
339
339
  } catch (e) {
340
340
  if (e instanceof RouvaError && e.status === 429) {
341
- console.log(e.refusal) // 'key_cap' | 'member_cap' | 'rate' — Rouva refused before calling the provider
341
+ console.log(e.refusal) // 'key_cap' | 'member_cap' | 'rate' | … — Rouva refused before calling the provider
342
342
  console.log(e.retryAfter) // seconds, from Retry-After
343
343
  console.log(e.error) // the gateway's message
344
344
  }
345
345
  }
346
346
  ```
347
347
 
348
- `refusal` (header `X-Rouva-Refusal`) names why Rouva itself refused the request before contacting the provider, when the gateway marks it: a monthly spend cap would be exceeded (`key_cap`, `member_cap`), the rate limit (`rate`), or — for spend-capped keys — a model with no known price (`unpriced`) or input whose cost can't be bounded (`unbounded`). Every Rouva refusal is marked, so a `429` without `refusal` came from the provider, not from Rouva. Every call also takes `{ signal }` as a second argument to abort it.
348
+ `refusal` (header `X-Rouva-Refusal`) names why Rouva itself refused the request before contacting the provider, when the gateway marks it: a monthly spend cap would be exceeded (`key_cap`, `member_cap`), the rate limit (`rate`), for spend-capped keys a model with no known price (`unpriced`) or input or a model whose cost can't be bounded (`unbounded`), or — a `504` — the request ran out of its time budget before the provider was called (`deadline`; nothing was sent, so it's safe to retry, and `retryAfter` is set). Every Rouva refusal is marked, so a `429` or `504` without `refusal` came from the provider, not from Rouva — with one exception: `rouva.run()` returns an unmarked `504` "Run deadline exceeded before completion" when the run runs out of time, because earlier turns were already billed and their tool handlers ran; check what completed before retrying it. Every call also takes `{ signal }` as a second argument to abort it.
349
349
 
350
350
  ## Getting your API key
351
351
 
package/dist/index.d.mts CHANGED
@@ -64,7 +64,7 @@ type RouvaProvider = 'anthropic' | 'openai' | 'gemini' | 'deepseek' | 'mistral'
64
64
  *
65
65
  * `'gpt-5.6'` is a deprecated alias the gateway maps to `'gpt-5.6-sol'`.
66
66
  */
67
- type RouvaModel = 'claude-fable-5-1' | 'claude-fable-5' | 'claude-opus-5-5' | 'claude-opus-5' | 'claude-opus-4-8' | 'claude-opus-4-7' | 'claude-opus-4-6' | 'claude-sonnet-5-5' | 'claude-sonnet-5' | 'claude-sonnet-4-6' | 'claude-haiku-4-5-20251001' | 'gpt-6.1-sol' | 'gpt-6-sol' | 'gpt-6-luna' | 'gpt-5.6-sol' | 'gpt-5.6-terra' | 'gpt-5.6-luna' | 'gpt-5.6' | 'gpt-5' | 'gpt-5.4-mini' | 'gpt-5-mini' | 'gpt-5-nano' | 'gpt-4.1' | 'gpt-4.1-mini' | 'gpt-4.1-nano' | 'gpt-4o' | 'gpt-4o-mini' | 'gemini-3.8-flash' | 'gemini-3.7-flash' | 'gemini-3.6-flash' | 'gemini-3.5-flash-lite' | 'gemini-2.5-pro' | 'gemini-2.5-flash' | 'deepseek-flash-4-1' | 'deepseek-v4-pro' | 'deepseek-v4-flash' | 'deepseek-v4-flash-think' | 'mistral-large-latest' | 'mistral-small-latest' | 'kimi-k3' | 'kimi-k2.6' | 'grok-4.7' | 'grok-4.6' | 'grok-4.5' | 'grok-4.3' | 'grok-4.20-0309-reasoning' | 'glm-5.3' | 'glm-5.2' | 'glm-4.7-flash' | 'qwen3.8-omni-flash' | 'qwen3.8-flash' | 'qwen3.7-plus' | 'qwen-max' | 'qwen-plus' | 'qwen-flash' | (string & {});
67
+ type RouvaModel = 'claude-fable-5-1' | 'claude-fable-5' | 'claude-opus-5-5' | 'claude-opus-5' | 'claude-opus-4-8' | 'claude-opus-4-7' | 'claude-opus-4-6' | 'claude-sonnet-5-5' | 'claude-sonnet-5' | 'claude-sonnet-4-6' | 'claude-haiku-4-5-20251001' | 'gpt-6.1-sol' | 'gpt-6-sol' | 'gpt-6-luna' | 'gpt-5.6-sol' | 'gpt-5.6-terra' | 'gpt-5.6-luna' | 'gpt-5.6' | 'gpt-5' | 'gpt-5.4-mini' | 'gpt-5-mini' | 'gpt-5-nano' | 'gpt-4.1' | 'gpt-4.1-mini' | 'gpt-4o' | 'gpt-4o-mini' | 'gemini-3.8-flash' | 'gemini-3.7-flash' | 'gemini-3.6-flash' | 'gemini-3.5-flash-lite' | 'gemini-2.5-pro' | 'gemini-2.5-flash' | 'deepseek-flash' | 'deepseek-flash-think' | 'deepseek-v4-pro' | 'mistral-large-latest' | 'mistral-small-latest' | 'kimi-k3' | 'kimi-k2.6' | 'grok-4.7' | 'grok-4.6' | 'grok-4.5' | 'grok-4.3' | 'grok-4.20-0309-reasoning' | 'glm-5.3' | 'glm-5.2' | 'glm-4.7-flash' | 'qwen3.8-omni-flash' | 'qwen3.8-flash' | 'qwen3.7-plus' | 'qwen-max' | 'qwen-plus' | 'qwen-flash' | (string & {});
68
68
  /** Anthropic-style text block — the array form of the `system` param */
69
69
  interface SystemTextBlock {
70
70
  type: 'text';
@@ -364,9 +364,14 @@ declare class RouvaError extends Error {
364
364
  * the gateway marks it (header `X-Rouva-Refusal`): `"key_cap"` /
365
365
  * `"member_cap"` (a monthly spend cap would be exceeded), `"rate"` (rate
366
366
  * limit), `"unpriced"` (a capped key can't use a model with no known price),
367
- * `"unbounded"` (a capped key can't send input whose cost can't be bounded).
368
- * Every Rouva cap, rate-limit and pricing refusal carries it, so a 429
369
- * without `refusal` came from the provider, not from Rouva.
367
+ * `"unbounded"` (a capped key can't send input, or use a model, whose cost
368
+ * can't be bounded), `"deadline"` (a 504: the request ran out of its time
369
+ * budget before the provider was called — nothing was sent, so it's safe to
370
+ * retry; `retryAfter` is set). Every Rouva cap, rate-limit, pricing and time
371
+ * refusal carries it, so a 429 or 504 without `refusal` came from the
372
+ * provider — except `rouva.run()`'s "Run deadline exceeded" 504, which is
373
+ * Rouva's but deliberately unmarked: earlier turns were billed and their
374
+ * tool handlers ran, so it must not be retried blindly.
370
375
  */
371
376
  readonly refusal?: string;
372
377
  /** Seconds to wait before retrying, from `Retry-After`, when present. */
package/dist/index.d.ts CHANGED
@@ -64,7 +64,7 @@ type RouvaProvider = 'anthropic' | 'openai' | 'gemini' | 'deepseek' | 'mistral'
64
64
  *
65
65
  * `'gpt-5.6'` is a deprecated alias the gateway maps to `'gpt-5.6-sol'`.
66
66
  */
67
- type RouvaModel = 'claude-fable-5-1' | 'claude-fable-5' | 'claude-opus-5-5' | 'claude-opus-5' | 'claude-opus-4-8' | 'claude-opus-4-7' | 'claude-opus-4-6' | 'claude-sonnet-5-5' | 'claude-sonnet-5' | 'claude-sonnet-4-6' | 'claude-haiku-4-5-20251001' | 'gpt-6.1-sol' | 'gpt-6-sol' | 'gpt-6-luna' | 'gpt-5.6-sol' | 'gpt-5.6-terra' | 'gpt-5.6-luna' | 'gpt-5.6' | 'gpt-5' | 'gpt-5.4-mini' | 'gpt-5-mini' | 'gpt-5-nano' | 'gpt-4.1' | 'gpt-4.1-mini' | 'gpt-4.1-nano' | 'gpt-4o' | 'gpt-4o-mini' | 'gemini-3.8-flash' | 'gemini-3.7-flash' | 'gemini-3.6-flash' | 'gemini-3.5-flash-lite' | 'gemini-2.5-pro' | 'gemini-2.5-flash' | 'deepseek-flash-4-1' | 'deepseek-v4-pro' | 'deepseek-v4-flash' | 'deepseek-v4-flash-think' | 'mistral-large-latest' | 'mistral-small-latest' | 'kimi-k3' | 'kimi-k2.6' | 'grok-4.7' | 'grok-4.6' | 'grok-4.5' | 'grok-4.3' | 'grok-4.20-0309-reasoning' | 'glm-5.3' | 'glm-5.2' | 'glm-4.7-flash' | 'qwen3.8-omni-flash' | 'qwen3.8-flash' | 'qwen3.7-plus' | 'qwen-max' | 'qwen-plus' | 'qwen-flash' | (string & {});
67
+ type RouvaModel = 'claude-fable-5-1' | 'claude-fable-5' | 'claude-opus-5-5' | 'claude-opus-5' | 'claude-opus-4-8' | 'claude-opus-4-7' | 'claude-opus-4-6' | 'claude-sonnet-5-5' | 'claude-sonnet-5' | 'claude-sonnet-4-6' | 'claude-haiku-4-5-20251001' | 'gpt-6.1-sol' | 'gpt-6-sol' | 'gpt-6-luna' | 'gpt-5.6-sol' | 'gpt-5.6-terra' | 'gpt-5.6-luna' | 'gpt-5.6' | 'gpt-5' | 'gpt-5.4-mini' | 'gpt-5-mini' | 'gpt-5-nano' | 'gpt-4.1' | 'gpt-4.1-mini' | 'gpt-4o' | 'gpt-4o-mini' | 'gemini-3.8-flash' | 'gemini-3.7-flash' | 'gemini-3.6-flash' | 'gemini-3.5-flash-lite' | 'gemini-2.5-pro' | 'gemini-2.5-flash' | 'deepseek-flash' | 'deepseek-flash-think' | 'deepseek-v4-pro' | 'mistral-large-latest' | 'mistral-small-latest' | 'kimi-k3' | 'kimi-k2.6' | 'grok-4.7' | 'grok-4.6' | 'grok-4.5' | 'grok-4.3' | 'grok-4.20-0309-reasoning' | 'glm-5.3' | 'glm-5.2' | 'glm-4.7-flash' | 'qwen3.8-omni-flash' | 'qwen3.8-flash' | 'qwen3.7-plus' | 'qwen-max' | 'qwen-plus' | 'qwen-flash' | (string & {});
68
68
  /** Anthropic-style text block — the array form of the `system` param */
69
69
  interface SystemTextBlock {
70
70
  type: 'text';
@@ -364,9 +364,14 @@ declare class RouvaError extends Error {
364
364
  * the gateway marks it (header `X-Rouva-Refusal`): `"key_cap"` /
365
365
  * `"member_cap"` (a monthly spend cap would be exceeded), `"rate"` (rate
366
366
  * limit), `"unpriced"` (a capped key can't use a model with no known price),
367
- * `"unbounded"` (a capped key can't send input whose cost can't be bounded).
368
- * Every Rouva cap, rate-limit and pricing refusal carries it, so a 429
369
- * without `refusal` came from the provider, not from Rouva.
367
+ * `"unbounded"` (a capped key can't send input, or use a model, whose cost
368
+ * can't be bounded), `"deadline"` (a 504: the request ran out of its time
369
+ * budget before the provider was called — nothing was sent, so it's safe to
370
+ * retry; `retryAfter` is set). Every Rouva cap, rate-limit, pricing and time
371
+ * refusal carries it, so a 429 or 504 without `refusal` came from the
372
+ * provider — except `rouva.run()`'s "Run deadline exceeded" 504, which is
373
+ * Rouva's but deliberately unmarked: earlier turns were billed and their
374
+ * tool handlers ran, so it must not be retried blindly.
370
375
  */
371
376
  readonly refusal?: string;
372
377
  /** Seconds to wait before retrying, from `Retry-After`, when present. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rouvanpm/rouva",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Official Node.js SDK for Rouva — managed AI gateway with intelligent routing and spend tracking",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",