diff --git a/docs/docs/configure/providers.md b/docs/docs/configure/providers.md index b310e58b7..4de05c409 100644 --- a/docs/docs/configure/providers.md +++ b/docs/docs/configure/providers.md @@ -48,9 +48,16 @@ For pricing, security, and data handling details, see the [Altimate LLM Gateway ## Altimate Base -Altimate Base is the hosted Qwen 3.8 free model. It requires no signup or user-managed API key and -is subject to rate limits and abuse protection. Requests and responses are logged and may be used -to improve Altimate products and services. Do not send secrets or confidential code. +Altimate Base is a free, hosted model — no signup, no account, no user-managed API +key. Accept a one-time consent disclosure and it just works. It supports up to 131K tokens of +context and up to 65K tokens of output. + +Requests and responses are logged and may be used to improve Altimate's products, including the +model. Secrets are automatically masked before storage, but don't rely on it — avoid sending +secrets or confidential code. Altimate Base is pseudonymous, not anonymous: a stable +per-installation identifier links your requests across launches and `altimate providers logout +altimate-base` does not reset it (see the [security FAQ](../reference/security-faq.md)). Usage is +rate limited. Choose **Altimate Base** from the first-run picker or `/connect`. A disclosure is shown before any registration request; **No** is selected by default. After registration, the model is available as @@ -58,6 +65,21 @@ registration request; **No** is selected by default. After registration, the mod explicit model is selected. Big Pickle is no longer selected implicitly, but remains available in the full OpenCode model catalog for users who choose it explicitly. +### Usage limits + +Altimate Base is fair-use, not unlimited: + +- **Your personal allowance** is a one-time grant tied to this installation. It does not renew. + Once it's used up, sign up at [app.myaltimate.com](https://app.myaltimate.com) for a paid plan + (the Altimate LLM Gateway) to keep going, or switch to another model. +- **Shared daily capacity** is a pool covering every free-tier user. It resets daily. If it's + exhausted, try again tomorrow or switch models in the meantime. +- **Rate limiting** protects the service from bursts. If you hit it, wait a moment and retry. +- **Request size limits** apply per request. If a request is rejected as too large, shorten it — + start a new session or trim the context — and try again. + +Each of these is reported back to you as a specific, actionable error message when it happens. + Official release binaries embed the current gateway endpoint at build time. Operators and local development can override it without changing code: diff --git a/packages/opencode/src/altimate/free/client.ts b/packages/opencode/src/altimate/free/client.ts index 71e81e50a..193cbc7a9 100644 --- a/packages/opencode/src/altimate/free/client.ts +++ b/packages/opencode/src/altimate/free/client.ts @@ -510,8 +510,14 @@ export function describeRateLimit( } if (kind === "budget_exceeded") { if (detail.includes("ExceededBudget: User=")) { + // The per-user wallet (GRANT_NEW_PRINCIPAL_USD) is a one-time lifetime grant with no + // budget_duration — it never resets. Only the shared global ceiling below resets daily. + // See altimate-gateway issuer/config.py (grant_budget_duration, validate()) and + // accounting_db.py's one-time registration grant. Points to the paid Altimate LLM Gateway + // sign-up (app.myaltimate.com) since switching models is the only other option here. return { - message: "You've used today's free Altimate Base allowance. It resets tomorrow—switch models to keep going.", + message: + "You've used your free Altimate Base allowance — it's a one-time grant and won't renew. Sign up at app.myaltimate.com to keep going, or switch models.", retryable: false, } } diff --git a/packages/opencode/test/altimate/altimate-base-rate-limit-messages.test.ts b/packages/opencode/test/altimate/altimate-base-rate-limit-messages.test.ts index e7d5de5af..88b8442c0 100644 --- a/packages/opencode/test/altimate/altimate-base-rate-limit-messages.test.ts +++ b/packages/opencode/test/altimate/altimate-base-rate-limit-messages.test.ts @@ -124,14 +124,18 @@ describe("describeRateLimit — via the fake gateway (every ChatMode failure kno expect(response.status).toBe(429) const described = FreeTier.describeRateLimit({ body: await response.text() }) - // Pinning today's message as written. Flagged ambiguity (plan Deliverable 1, Suite E / - // Summary #2): "It resets tomorrow" is arguably inaccurate for the wallet case — the - // per-principal grant (GRANT_NEW_PRINCIPAL_USD) has no budget_duration and never resets; only - // the separate global daily ceiling actually resets daily. This test asserts current - // behavior, not the plan's suggested fix, per the plan's explicit instruction not to - // silently "correct" it. + // Confirmed against altimate-gateway (issuer/config.py `grant_budget_duration` defaults to + // "" and `validate()` refuses to boot if it's ever set; issuer/accounting_db.py grants a + // one-time registration credit with "without later top-ups" in the docstring; issuer/ + // budget_sync.py mirrors the lifetime allowance into LiteLLM's max_budget with no + // budget_duration). The per-user wallet is a one-time lifetime grant that never renews — + // unlike the separate global $50/day ceiling (litellm/config.yaml `budget_duration: 1d`), + // which genuinely does reset daily and is covered by the budget-global case below. The + // message nudges toward the paid Altimate LLM Gateway (app.myaltimate.com) since switching + // models is the only other option when a lifetime grant is gone for good. expect(described).toEqual({ - message: "You've used today's free Altimate Base allowance. It resets tomorrow—switch models to keep going.", + message: + "You've used your free Altimate Base allowance — it's a one-time grant and won't renew. Sign up at app.myaltimate.com to keep going, or switch models.", retryable: false, }) })