Uh oh!
There was an error while loading. Please reload this page.
feat: obol buy inference <provider> — BYOK onboarding (Venice, OpenRouter & co.) on a single provider registry - #638
Conversation
…penRouter & co. Collapses provider knowledge (previously smeared across knownProviders, the setup dispatch switch, a default-model switch, detectCredentials, and buildModelEntries) into a single source-of-truth registry: one ProviderInfo row per provider carries id/env-var/Mode/BaseURL/Default/SignupURL/Free, and every layer reads from it. Adding a provider is now one row, no switch edits. New BYOK getting-started path (distinct from `obol buy inference`, which is x402 crypto-paid sellers): obol model setup venice --api-key $VENICE_API_KEY obol model setup openrouter --api-key $OPENROUTER_API_KEY --free - Mode=openai-compatible providers emit model_list entries openai/<id> + explicit api_base + key from env var (no wildcard). litellm-secrets is envFrom-mounted and record.go stores entries verbatim, so new providers persist across stack up with zero changes to those layers. - --model omitted → registry Default, else live GET <base>/v1/models (TTY picker / non-TTY error naming real ids) so we never ship guessed, rotating model ids as a hardcoded default. - --free seeds OpenRouter's curated free-tier snapshot (mapped from hermes-agent's free list). - detectCredentials + detectProvider are now registry-driven (BYOK env keys auto-detected; aggregator models labelled by api_base, not 'openai'). Providers seeded: venice, openrouter, nvidia, gmi, novita, huggingface (plus existing anthropic/openai/ollama). All OpenAI-compatible, so they are pure data — no new wiring.
…URL onboarding Adds the requested getting-started verb: `obol buy inference venice`, `obol buy inference openrouter --free`, etc. Dispatch keys on whether the positional arg matches a registry provider id — provider → BYOK onboarding, URL/none → the existing x402 crypto-paid seller flow (unchanged). Onboarding mirrors hermes-agent's api-key UX: resolve the key (--api-key → provider env var → prompt), open the provider's SignupURL in the browser (reuses openBrowser; skipped when a key is already in hand or non-TTY), then delegate to the shared setupCloudProvider engine (model resolution, --free seeding, LiteLLM patch, agent sync). No wallet, no x402 for this path. Also adds --api-key/--free to buy inference and corrects the CLAUDE.md framing (buy inference is now BOTH the BYOK door and the x402 door).
OisinKyne
commented
Jun 15, 2026
Brave to add this many providers in one go, you're telling me all 6 of them work? Have you tested them or are you hoping? |
How does Seems to me that maybe we mostly change I'm thinking if we do have |
OisinKyne
commented
Jun 15, 2026
added to my pr based on above thoughts. happy to merge that in here, and both into main. #644 |
Uh oh!
There was an error while loading. Please reload this page.
Why
Give a new user the shortest path to a working agent: bring an OpenRouter or Venice key and go. The headline command is the requested verb —
— which opens the provider's API-key page in the browser (hermes-agent-style), takes the key, and wires the agent's LiteLLM gateway to it.
obol buy inference <seller-url>(or no arg) is unchanged — still the x402 crypto-paid seller flow. Dispatch keys on whether the positional argument matches a known provider id, so the two doors coexist behind one verb.Two front doors, one engine
obol buy inference <provider>— friendly onboarding. Resolves the key (--api-key→ provider env var → prompt), opensSignupURLviaopenBrowser(skipped when a key is already in hand or non-TTY), then wires LiteLLM and syncs agents.obol model setup <provider> --api-key <key>— the scriptable, no-browser equivalent (CI/automation).Both call the same
setupCloudProviderengine, so behavior can't drift.The registry refactor (the DB smell)
Provider knowledge was smeared across five sites — adding one provider meant editing all of them:
knownProviders, the setup dispatchswitch, a default-modelswitch,detectCredentials, andbuildModelEntries. This PR collapses them into one source of truth: a richerProviderInforow (id,EnvVar/AltEnvVars,Mode,BaseURL,Default,SignupURL,Free) +ProviderByID. Every layer — buy/setup dispatch, default-model selection, credential auto-detection, LiteLLM entry shaping, andmodel statuslabelling — reads the registry. Adding a provider is one row, no switch edits.What's added
venicehttps://api.venice.ai/api/v1VENICE_API_KEYopenrouterhttps://openrouter.ai/api/v1OPENROUTER_API_KEYnvidiahttps://integrate.api.nvidia.com/v1NVIDIA_API_KEYgmihttps://api.gmi-serving.com/v1GMI_API_KEYnovitahttps://api.novita.ai/openai/v1NOVITA_API_KEYhuggingfacehttps://router.huggingface.co/v1HF_TOKENAll
Mode=openai-compatible: entries areopenai/<id>+ explicitapi_base+ key from env, no wildcard.litellm-secretsisenvFrom-mounted andrecord.gopersistsmodel_listverbatim, so new providers authenticate and surviveobol stack upwith zero changes to the secret/record layers.Model resolution (no guessed ids)
Aggregator catalogs rotate, so hardcoding model ids would ship 404s. With
--modelomitted: the registryDefaultis used if set (openrouter/auto; native flagships for anthropic/openai), otherwise setup lists the liveGET <base>/v1/models— a picker in a TTY, or a non-TTY error naming real ids.--freeseeds OpenRouter's curated free snapshot (mapped from our hermes-agent free list), documented as rotating.Tests
buildModelEntriesopenai-compatible shape + legacy fallback;ProviderByID;detectProviderlabelling aggregators byapi_base; registry invariants; themodel setupandbuy inferenceflag surfaces (incl.--free/--api-key) and the provider-vs-ollama dispatch gate. Existing anthropic/openai/ollama entry tests pass unchanged. Fullgo build+vet+test ./...green.Follow-ups (not here)
/v1/models; live free-tier discovery (filterpricing==0) instead of a static snapshot.🤖 Generated with Claude Code