feat(ai-proxy): server-authoritative models (provider switch = env only)
If the client asks for a model not in the allowlist, the proxy now uses its configured default instead of 400-ing. So switching the upstream to a Routstr node is purely server-env (SASQUATCH_AI_BASE/KEY/MODELS) with no client redeploy. AGENTS.md documents Routstr discovery (kind 38421, endpoints in 'u' tags), the live nodes found, and the fund->key recipe.
This commit is contained in:
parent
a5a134c6c0
commit
00aab5369b
2 changed files with 16 additions and 4 deletions
12
AGENTS.md
12
AGENTS.md
|
|
@ -126,8 +126,16 @@ session with **no other memory of this project**. So:
|
|||
override the Netlify gateway (any OpenAI-compatible endpoint). For a
|
||||
**sats-only** provider use Routstr (`SASQUATCH_AI_BASE=https://api.routstr.com/v1`,
|
||||
key = a cashu…/sk- session token; `SASQUATCH_MODELS` must match `PROXY_MODELS`).
|
||||
⚠️ As of 2026-09-27 **`api.routstr.com` returned 404 for every endpoint and its
|
||||
model list was empty** — do not switch to it until it serves models.
|
||||
⚠️ The **aggregator `api.routstr.com` is DOWN** (404 everywhere) but the
|
||||
network is alive: nodes announce on Nostr as **kind 38421** with the endpoint
|
||||
in a `u` tag (`d=<pubkey>`), and ~9 were serving models on 2026-09-27
|
||||
(e.g. `https://ai.orangesync.tech`, `routstr.cypherpunk.today`,
|
||||
`routstr.githappens.space`). To use a node: fund an `sk-` key via
|
||||
`POST <node>/v2/lightning/invoice {amount_sats,purpose:"create"}` (or import a
|
||||
Cashu token via `GET <node>/v1/balance/create?initial_balance_token=cashuA…`),
|
||||
then set `SASQUATCH_AI_BASE=<node>/v1`, `SASQUATCH_AI_KEY=sk-…`,
|
||||
`SASQUATCH_MODELS=<slugs>` in Netlify env — **no client redeploy needed** (the
|
||||
server falls back to its configured model if the client's slug isn't allowed).
|
||||
**AI answers are Pro-only**: free users get the static FAQ/glossary + local
|
||||
relay lookups only (`if (isPro)` gates the AI block in `SasquatchGuide`).
|
||||
Pro access (`useSasquatchPro`) is granted by a provider-authored zap receipt,
|
||||
|
|
|
|||
|
|
@ -237,8 +237,12 @@ export default async function handler(request) {
|
|||
return json({ error: 'Invalid JSON' }, 400, headers);
|
||||
}
|
||||
|
||||
const model = String(body.model ?? '');
|
||||
if (!ALLOWED_MODELS.has(model)) return json({ error: 'Model not allowed' }, 400, headers);
|
||||
// The server is authoritative on models: if the client asks for a slug we
|
||||
// don't allow, use our configured default instead of erroring. That makes a
|
||||
// provider switch a server-env change (SASQUATCH_MODELS) with no client
|
||||
// redeploy needed — the client's list is just a preference.
|
||||
const requested = String(body.model ?? '');
|
||||
const model = ALLOWED_MODELS.has(requested) ? requested : ALLOWED_MODELS.values().next().value;
|
||||
|
||||
const messages = Array.isArray(body.messages) ? body.messages.slice(-20) : [];
|
||||
const maxTokens = Math.min(Number(body.max_tokens) || 400, 800);
|
||||
|
|
|
|||
Loading…
Reference in a new issue