Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion app/lib/.server/llm/api-key.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,24 @@
import { env } from 'node:process';

export function getAPIKey(cloudflareEnv: Env) {
export type Provider = 'anthropic' | 'aistupidlevel';

export function getAPIKey(cloudflareEnv: Env, provider: Provider = 'anthropic') {
/**
* The `cloudflareEnv` is only used when deployed or when previewing locally.
* In development the environment variables are available through `env`.
*/
if (provider === 'aistupidlevel') {
return env.AI_STUPID_LEVEL_API_KEY || cloudflareEnv.AI_STUPID_LEVEL_API_KEY;
}

return env.ANTHROPIC_API_KEY || cloudflareEnv.ANTHROPIC_API_KEY;
}

export function getProvider(cloudflareEnv: Env): Provider {
const provider = env.LLM_PROVIDER || cloudflareEnv.LLM_PROVIDER || 'anthropic';
return provider as Provider;
}

export function getAIStupidLevelModel(cloudflareEnv: Env): string {
return env.AI_STUPID_LEVEL_MODEL || cloudflareEnv.AI_STUPID_LEVEL_MODEL || 'auto-coding';
}
10 changes: 10 additions & 0 deletions app/lib/.server/llm/model.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { createAnthropic } from '@ai-sdk/anthropic';
import { createOpenAI } from '@ai-sdk/openai';

export function getAnthropicModel(apiKey: string) {
const anthropic = createAnthropic({
Expand All @@ -7,3 +8,12 @@ export function getAnthropicModel(apiKey: string) {

return anthropic('claude-3-5-sonnet-20240620');
}

export function getAIStupidLevelModel(apiKey: string, model: string = 'auto-coding') {
const openai = createOpenAI({
apiKey,
baseURL: 'https://aistupidlevel.info/v1',
});

return openai(model);
}
34 changes: 30 additions & 4 deletions app/lib/.server/llm/stream-text.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { streamText as _streamText, convertToCoreMessages } from 'ai';
import { getAPIKey } from '~/lib/.server/llm/api-key';
import { getAnthropicModel } from '~/lib/.server/llm/model';
import { getAPIKey, getProvider, getAIStupidLevelModel as getAIStupidLevelModelName } from '~/lib/.server/llm/api-key';
import { getAnthropicModel, getAIStupidLevelModel } from '~/lib/.server/llm/model';
import { MAX_TOKENS } from './constants';
import { getSystemPrompt } from './prompts';

Expand All @@ -22,14 +22,40 @@ export type Messages = Message[];
export type StreamingOptions = Omit<Parameters<typeof _streamText>[0], 'model'>;

export function streamText(messages: Messages, env: Env, options?: StreamingOptions) {
const provider = getProvider(env);

if (provider === 'aistupidlevel') {
const modelName = getAIStupidLevelModelName(env);
const apiKey = getAPIKey(env, 'aistupidlevel');

if (!apiKey) {
throw new Error('AI Stupid Level API key is required when using aistupidlevel provider');
}

return _streamText({
model: getAIStupidLevelModel(apiKey, modelName) as any,
system: getSystemPrompt(),
maxTokens: MAX_TOKENS,
messages: convertToCoreMessages(messages as any),
...options,
});
}

// Default to Anthropic
const anthropicApiKey = getAPIKey(env, 'anthropic');

if (!anthropicApiKey) {
throw new Error('Anthropic API key is required');
}

return _streamText({
model: getAnthropicModel(getAPIKey(env)),
model: getAnthropicModel(anthropicApiKey) as any,
system: getSystemPrompt(),
maxTokens: MAX_TOKENS,
headers: {
'anthropic-beta': 'max-tokens-3-5-sonnet-2024-07-15',
},
messages: convertToCoreMessages(messages),
messages: convertToCoreMessages(messages as any),
...options,
});
}
Loading
Loading