Skip to content

Commit 3a5c4af

Browse files
committed
feat(model): add sign up nudge for venice
1 parent f258e29 commit 3a5c4af

3 files changed

Lines changed: 34 additions & 10 deletions

File tree

cmd/obol/buy.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,18 @@ func runBuyInferenceProvider(cfg *config.Config, cmd *cli.Command, prof model.Pr
194194
}
195195
}
196196

197-
// openurl: send the operator to the provider's key page before we
198-
// prompt for the key (skipped when a key is already in hand or non-TTY).
199-
if apiKey == "" && prof.SignupURL != "" && u.IsTTY() && !u.IsJSON() {
200-
u.Infof("Opening %s to create an API key …", prof.SignupURL)
201-
if err := openBrowser(prof.SignupURL); err != nil {
202-
u.Dim(fmt.Sprintf("(couldn't open a browser — visit %s)", prof.SignupURL))
197+
// openurl: send the operator to the provider's onboarding page before
198+
// we prompt for the key (skipped when a key is already in hand or
199+
// non-TTY). Prefer JoinURL (the new-user landing page, possibly
200+
// referral-tagged) when set; fall back to SignupURL (keys dashboard).
201+
onboardURL := prof.JoinURL
202+
if onboardURL == "" {
203+
onboardURL = prof.SignupURL
204+
}
205+
if apiKey == "" && onboardURL != "" && u.IsTTY() && !u.IsJSON() {
206+
u.Infof("Opening %s to sign up / create an API key …", onboardURL)
207+
if err := openBrowser(onboardURL); err != nil {
208+
u.Dim(fmt.Sprintf("(couldn't open a browser — visit %s)", onboardURL))
203209
}
204210
}
205211

cmd/obol/model.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,16 +97,24 @@ func modelSetupCommand(cfg *config.Config) *cli.Command {
9797
providers, _ := model.GetAvailableProviders(cfg)
9898

9999
options := make([]string, len(providers))
100+
// Default to Venice — the friendliest BYOK on-ramp (cheap,
101+
// no credit card to start, referral link in the JoinURL).
102+
// Falls back to index 0 if Venice is ever removed from the
103+
// registry.
104+
defaultIdx := 0
100105
for i, p := range providers {
101106
label := fmt.Sprintf("%s (%s)", p.Name, p.ID)
102107
if det, ok := creds[p.ID]; ok {
103108
label += " — detected: " + det.source
104109
}
110+
if p.ID == "venice" {
111+
defaultIdx = i
112+
}
105113

106114
options[i] = label
107115
}
108116

109-
idx, err := u.Select("Select a provider:", options, 0)
117+
idx, err := u.Select("Select a provider:", options, defaultIdx)
110118
if err != nil {
111119
return err
112120
}
@@ -194,6 +202,9 @@ func setupOllama(cfg *config.Config, u *ui.UI, models []string) error {
194202

195203
func setupCloudProvider(cfg *config.Config, u *ui.UI, prof model.ProviderInfo, apiKey string, models []string, free bool) error {
196204
if apiKey == "" {
205+
if prof.JoinURL != "" {
206+
u.Dim(fmt.Sprintf("New to %s? Sign up: %s", prof.Name, prof.JoinURL))
207+
}
197208
if prof.SignupURL != "" {
198209
u.Dim(fmt.Sprintf("Get a %s API key: %s", prof.Name, prof.SignupURL))
199210
}

internal/model/model.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,13 @@ type ProviderInfo struct {
6969
Mode apiMode // how model_list entries are shaped
7070
BaseURL string // OpenAI-compatible base_url (modeOpenAICompatible only)
7171
Default string // default chat model when --model is omitted ("" = ask/require)
72-
SignupURL string // where to obtain an API key (shown as a hint)
73-
Free []string // curated zero-marginal-cost model ids (seeded by --free)
72+
SignupURL string // where to obtain an API key (assumes existing account)
73+
JoinURL string // optional landing page for users without an account yet
74+
// (may carry a referral tag). When set, `obol buy inference <provider>`
75+
// opens this in preference to SignupURL, and `obol model setup`'s
76+
// missing-key Dim hint surfaces it as a "new to X? sign up" line above
77+
// the keys-dashboard hint.
78+
Free []string // curated zero-marginal-cost model ids (seeded by --free)
7479
}
7580

7681
// IsBYOK reports whether the provider is a BYOK OpenAI-compatible
@@ -103,7 +108,9 @@ var knownProviders = []ProviderInfo{
103108
// model from the live /v1/models list or --model.
104109
{
105110
ID: "venice", Name: "Venice", EnvVar: "VENICE_API_KEY", Mode: modeOpenAICompatible,
106-
BaseURL: "https://api.venice.ai/api/v1", SignupURL: "https://venice.ai/settings/api",
111+
BaseURL: "https://api.venice.ai/api/v1",
112+
SignupURL: "https://venice.ai/settings/api",
113+
JoinURL: "https://venice.ai/chat?ref=ZynMuD",
107114
},
108115
{
109116
ID: "openrouter", Name: "OpenRouter", EnvVar: "OPENROUTER_API_KEY", Mode: modeOpenAICompatible,

0 commit comments

Comments
 (0)