Initial commit — AI-powered coding tutor (Professor)
Next.js 16, React 19, Monaco editor, Anthropic SDK, multi-provider AI, Wandbox Python execution, iframe HTML preview, SQLite auth + session persistence. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
95
lib/providers.ts
Normal file
95
lib/providers.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
import type { ProviderId, ProviderConfig } from '@/types';
|
||||
|
||||
export interface ProviderDefinition {
|
||||
id: ProviderId;
|
||||
label: string;
|
||||
requiresApiKey: boolean;
|
||||
hasCustomBaseUrl: boolean;
|
||||
defaultBaseUrl: string;
|
||||
defaultModel: string;
|
||||
modelSuggestions: string[];
|
||||
}
|
||||
|
||||
export const PROVIDERS: ProviderDefinition[] = [
|
||||
{
|
||||
id: 'anthropic',
|
||||
label: 'Anthropic (Claude)',
|
||||
requiresApiKey: true,
|
||||
hasCustomBaseUrl: false,
|
||||
defaultBaseUrl: 'https://api.anthropic.com',
|
||||
defaultModel: 'claude-sonnet-4-6',
|
||||
modelSuggestions: [
|
||||
'claude-sonnet-4-6',
|
||||
'claude-haiku-4-5-20251001',
|
||||
'claude-opus-4-6',
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'openrouter',
|
||||
label: 'OpenRouter',
|
||||
requiresApiKey: true,
|
||||
hasCustomBaseUrl: false,
|
||||
defaultBaseUrl: 'https://openrouter.ai/api/v1',
|
||||
defaultModel: 'meta-llama/llama-3.1-8b-instruct:free',
|
||||
modelSuggestions: [
|
||||
'meta-llama/llama-3.1-8b-instruct:free',
|
||||
'google/gemma-3-27b-it:free',
|
||||
'mistralai/mistral-7b-instruct:free',
|
||||
'deepseek/deepseek-chat-v3-0324:free',
|
||||
'qwen/qwen3-8b:free',
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'lmstudio',
|
||||
label: 'LM Studio',
|
||||
requiresApiKey: false,
|
||||
hasCustomBaseUrl: true,
|
||||
defaultBaseUrl: 'http://localhost:1234/v1',
|
||||
defaultModel: 'local-model',
|
||||
modelSuggestions: [],
|
||||
},
|
||||
{
|
||||
id: 'ollama',
|
||||
label: 'Ollama',
|
||||
requiresApiKey: false,
|
||||
hasCustomBaseUrl: true,
|
||||
defaultBaseUrl: 'http://localhost:11434/v1',
|
||||
defaultModel: 'llama3.2',
|
||||
modelSuggestions: [
|
||||
'llama3.2',
|
||||
'llama3.1',
|
||||
'mistral',
|
||||
'qwen2.5-coder',
|
||||
'deepseek-coder-v2',
|
||||
'phi4',
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export const PROVIDER_MAP = Object.fromEntries(PROVIDERS.map((p) => [p.id, p])) as Record<
|
||||
ProviderId,
|
||||
ProviderDefinition
|
||||
>;
|
||||
|
||||
export const DEFAULT_PROVIDER_CONFIG: ProviderConfig = {
|
||||
provider: 'anthropic',
|
||||
model: 'claude-sonnet-4-6',
|
||||
};
|
||||
|
||||
const STORAGE_KEY = 'professor_provider_config';
|
||||
|
||||
export function loadProviderConfig(): ProviderConfig {
|
||||
if (typeof window === 'undefined') return DEFAULT_PROVIDER_CONFIG;
|
||||
try {
|
||||
const raw = localStorage.getItem(STORAGE_KEY);
|
||||
if (!raw) return DEFAULT_PROVIDER_CONFIG;
|
||||
return JSON.parse(raw) as ProviderConfig;
|
||||
} catch {
|
||||
return DEFAULT_PROVIDER_CONFIG;
|
||||
}
|
||||
}
|
||||
|
||||
export function saveProviderConfig(config: ProviderConfig): void {
|
||||
if (typeof window === 'undefined') return;
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(config));
|
||||
}
|
||||
Reference in New Issue
Block a user