Skip to content

Commit 404d5ea

Browse files
polish models UX
1 parent e9401a7 commit 404d5ea

2 files changed

Lines changed: 377 additions & 157 deletions

File tree

packages/setupWizard/src/index.ts

Lines changed: 2 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/usr/bin/env node
2-
import { confirm, input, password, select } from '@inquirer/prompts';
2+
import { confirm, select } from '@inquirer/prompts';
33
import chalk from 'chalk';
44
import ora from 'ora';
55
import { existsSync, writeFileSync } from 'fs';
@@ -12,6 +12,7 @@ import { collectGiteaConfig } from './gitea.js';
1212
import { collectGitHubConfig } from './github.js';
1313
import { collectGitLabConfig } from './gitlab.js';
1414
import { collectLocalReposConfig } from './localRepos.js';
15+
import { collectModels, PROVIDER_ENV_KEYS } from './models.js';
1516
import {
1617
type CollectResult,
1718
type ConnectionConfig,
@@ -25,162 +26,6 @@ import {
2526
const DOCKER_COMPOSE_BRANCH = 'bkellam/setup-wizard';
2627
const DOCKER_COMPOSE_URL = `https://raw.githubusercontent.com/sourcebot-dev/sourcebot/${DOCKER_COMPOSE_BRANCH}/docker-compose.yml`;
2728

28-
type ModelConfig = Record<string, unknown>;
29-
30-
const PROVIDER_DEFAULT_MODELS: Record<string, string> = {
31-
'anthropic': 'claude-sonnet-4-6',
32-
'openai': 'gpt-4o',
33-
'google-generative-ai': 'gemini-2.0-flash',
34-
'deepseek': 'deepseek-chat',
35-
'mistral': 'mistral-large-latest',
36-
'xai': 'grok-2-latest',
37-
};
38-
39-
const PROVIDER_ENV_KEYS: Record<string, string> = {
40-
'anthropic': 'ANTHROPIC_API_KEY',
41-
'openai': 'OPENAI_API_KEY',
42-
'google-generative-ai': 'GOOGLE_GENERATIVE_AI_API_KEY',
43-
'deepseek': 'DEEPSEEK_API_KEY',
44-
'mistral': 'MISTRAL_API_KEY',
45-
'xai': 'XAI_API_KEY',
46-
'openrouter': 'OPENROUTER_API_KEY',
47-
'openai-compatible': 'OPENAI_COMPATIBLE_API_KEY',
48-
'azure': 'AZURE_OPENAI_API_KEY',
49-
};
50-
51-
async function collectModels(): Promise<{ models: ModelConfig[]; env: EnvVars }> {
52-
const models: ModelConfig[] = [];
53-
const env: EnvVars = {};
54-
55-
const wantsAI = await confirm({
56-
message: 'Would you like to configure AI features?',
57-
default: true,
58-
});
59-
60-
if (!wantsAI) {
61-
return { models, env };
62-
}
63-
64-
// eslint-disable-next-line no-constant-condition
65-
while (true) {
66-
const provider = await select<string>({
67-
message: 'Which AI provider?',
68-
choices: [
69-
{ value: 'anthropic', name: 'Anthropic', description: 'Claude' },
70-
{ value: 'openai', name: 'OpenAI', description: 'GPT-4o, o1' },
71-
{ value: 'google-generative-ai', name: 'Google Gemini' },
72-
{ value: 'deepseek', name: 'DeepSeek' },
73-
{ value: 'mistral', name: 'Mistral' },
74-
{ value: 'xai', name: 'xAI', description: 'Grok' },
75-
{ value: 'openrouter', name: 'OpenRouter' },
76-
{ value: 'openai-compatible', name: 'OpenAI-compatible', description: 'self-hosted / custom endpoint' },
77-
{ value: 'amazon-bedrock', name: 'Amazon Bedrock' },
78-
{ value: 'azure', name: 'Azure OpenAI' },
79-
],
80-
});
81-
82-
const modelConfig: ModelConfig = { provider };
83-
84-
const defaultModel = PROVIDER_DEFAULT_MODELS[provider];
85-
const model = await input({
86-
message: 'Model name',
87-
default: defaultModel ?? '',
88-
validate: (v) => !v?.trim() ? 'Model name is required' : true,
89-
});
90-
modelConfig.model = model;
91-
92-
if (provider === 'openai-compatible') {
93-
const baseUrl = await input({
94-
message: 'Base URL (e.g. https://your-endpoint.example.com/v1)',
95-
validate: (v) => {
96-
if (!v?.trim()) {
97-
return 'Base URL is required';
98-
}
99-
if (!/^https?:\/\//.test(v)) {
100-
return 'Must start with http:// or https://';
101-
}
102-
return true;
103-
},
104-
});
105-
modelConfig.baseUrl = baseUrl;
106-
}
107-
108-
if (provider === 'azure') {
109-
const resourceName = await input({
110-
message: 'Azure resource name',
111-
validate: (v) => !v?.trim() ? 'Resource name is required' : true,
112-
});
113-
modelConfig.resourceName = resourceName;
114-
115-
const apiVersion = await input({
116-
message: 'API version',
117-
default: '2024-08-01-preview',
118-
validate: (v) => !v?.trim() ? 'API version is required' : true,
119-
});
120-
modelConfig.apiVersion = apiVersion;
121-
}
122-
123-
if (provider === 'amazon-bedrock') {
124-
const useDefaultChain = await confirm({
125-
message: 'Use the default AWS credential chain? (No to provide Access Key ID and Secret explicitly)',
126-
default: true,
127-
});
128-
129-
if (!useDefaultChain) {
130-
if (!env['AWS_ACCESS_KEY_ID']) {
131-
const keyId = await input({
132-
message: 'AWS Access Key ID (stored as AWS_ACCESS_KEY_ID)',
133-
validate: (v) => !v?.trim() ? 'Access Key ID is required' : true,
134-
});
135-
env['AWS_ACCESS_KEY_ID'] = keyId;
136-
}
137-
modelConfig.accessKeyId = { env: 'AWS_ACCESS_KEY_ID' };
138-
139-
if (!env['AWS_SECRET_ACCESS_KEY']) {
140-
const secret = await password({
141-
message: 'AWS Secret Access Key (stored as AWS_SECRET_ACCESS_KEY)',
142-
mask: true,
143-
validate: (v) => !v?.trim() ? 'Secret Access Key is required' : true,
144-
});
145-
env['AWS_SECRET_ACCESS_KEY'] = secret;
146-
}
147-
modelConfig.accessKeySecret = { env: 'AWS_SECRET_ACCESS_KEY' };
148-
}
149-
150-
const region = await input({
151-
message: 'AWS region',
152-
default: 'us-east-1',
153-
validate: (v) => !v?.trim() ? 'Region is required' : true,
154-
});
155-
modelConfig.region = region;
156-
} else {
157-
const envKey = PROVIDER_ENV_KEYS[provider] ?? `${provider.toUpperCase().replace(/-/g, '_')}_API_KEY`;
158-
if (!env[envKey]) {
159-
const apiKey = await password({
160-
message: `API key (stored as ${envKey})`,
161-
mask: true,
162-
validate: (v) => !v?.trim() ? 'API key is required' : true,
163-
});
164-
env[envKey] = apiKey;
165-
}
166-
modelConfig.token = { env: envKey };
167-
}
168-
169-
models.push(modelConfig);
170-
171-
const addAnother = await confirm({
172-
message: 'Add another model?',
173-
default: false,
174-
});
175-
176-
if (!addAnother) {
177-
break;
178-
}
179-
}
180-
181-
return { models, env };
182-
}
183-
18429
const PLATFORM_LABELS: Record<string, string> = {
18530
github: 'GitHub',
18631
gitlab: 'GitLab',

0 commit comments

Comments
 (0)