Merge branch 'main' into context-optimization

This commit is contained in:
Anirban Kar
2024-12-12 02:44:36 +05:30
25 changed files with 657 additions and 571 deletions

View File

@@ -11,6 +11,7 @@ import { createOpenRouter } from '@openrouter/ai-sdk-provider';
import { createMistral } from '@ai-sdk/mistral';
import { createCohere } from '@ai-sdk/cohere';
import type { LanguageModelV1 } from 'ai';
import type { IProviderSetting } from '~/types/model';
export const DEFAULT_NUM_CTX = process.env.DEFAULT_NUM_CTX ? parseInt(process.env.DEFAULT_NUM_CTX, 10) : 32768;
@@ -127,14 +128,20 @@ export function getXAIModel(apiKey: OptionalApiKey, model: string) {
return openai(model);
}
export function getModel(provider: string, model: string, env: Env, apiKeys?: Record<string, string>) {
export function getModel(
provider: string,
model: string,
env: Env,
apiKeys?: Record<string, string>,
providerSettings?: Record<string, IProviderSetting>,
) {
/*
* let apiKey; // Declare first
* let baseURL;
*/
const apiKey = getAPIKey(env, provider, apiKeys); // Then assign
const baseURL = getBaseURL(env, provider);
const baseURL = providerSettings?.[provider].baseUrl || getBaseURL(env, provider);
switch (provider) {
case 'Anthropic':

View File

@@ -4,6 +4,7 @@ import { MAX_TOKENS } from './constants';
import { getSystemPrompt } from './prompts';
import { DEFAULT_MODEL, DEFAULT_PROVIDER, getModelList, MODEL_REGEX, PROVIDER_REGEX } from '~/utils/constants';
import ignore from 'ignore';
import type { IProviderSetting } from '~/types/model';
interface ToolResult<Name extends string, Args, Result> {
toolCallId: string;
@@ -131,16 +132,18 @@ function extractPropertiesFromMessage(message: Message): { model: string; provid
return { model, provider, content: cleanedContent };
}
export async function streamText(
messages: Messages,
env: Env,
options?: StreamingOptions,
apiKeys?: Record<string, string>,
files?: FileMap,
) {
export async function streamText(props: {
messages: Messages;
env: Env;
options?: StreamingOptions;
apiKeys?: Record<string, string>;
files?: FileMap;
providerSettings?: Record<string, IProviderSetting>;
}) {
const { messages, env, options, apiKeys, files, providerSettings } = props;
let currentModel = DEFAULT_MODEL;
let currentProvider = DEFAULT_PROVIDER.name;
const MODEL_LIST = await getModelList(apiKeys || {});
const MODEL_LIST = await getModelList(apiKeys || {}, providerSettings);
const processedMessages = messages.map((message) => {
if (message.role === 'user') {
const { model, provider, content } = extractPropertiesFromMessage(message);
@@ -175,7 +178,7 @@ export async function streamText(
}
return _streamText({
model: getModel(currentProvider, currentModel, env, apiKeys) as any,
model: getModel(currentProvider, currentModel, env, apiKeys, providerSettings) as any,
system: systemPrompt,
maxTokens: dynamicMaxTokens,
messages: convertToCoreMessages(processedMessages as any),

View File

@@ -0,0 +1,97 @@
import { useStore } from '@nanostores/react';
import { isDebugMode, isLocalModelsEnabled, LOCAL_PROVIDERS, providersStore } from '~/lib/stores/settings';
import { useCallback, useEffect, useState } from 'react';
import Cookies from 'js-cookie';
import type { IProviderSetting, ProviderInfo } from '~/types/model';
export function useSettings() {
const providers = useStore(providersStore);
const debug = useStore(isDebugMode);
const isLocalModel = useStore(isLocalModelsEnabled);
const [activeProviders, setActiveProviders] = useState<ProviderInfo[]>([]);
// reading values from cookies on mount
useEffect(() => {
const savedProviders = Cookies.get('providers');
if (savedProviders) {
try {
const parsedProviders: Record<string, IProviderSetting> = JSON.parse(savedProviders);
Object.keys(parsedProviders).forEach((provider) => {
const currentProvider = providers[provider];
providersStore.setKey(provider, {
...currentProvider,
settings: {
...parsedProviders[provider],
enabled: parsedProviders[provider].enabled || true,
},
});
});
} catch (error) {
console.error('Failed to parse providers from cookies:', error);
}
}
// load debug mode from cookies
const savedDebugMode = Cookies.get('isDebugEnabled');
if (savedDebugMode) {
isDebugMode.set(savedDebugMode === 'true');
}
// load local models from cookies
const savedLocalModels = Cookies.get('isLocalModelsEnabled');
if (savedLocalModels) {
isLocalModelsEnabled.set(savedLocalModels === 'true');
}
}, []);
// writing values to cookies on change
useEffect(() => {
const providers = providersStore.get();
const providerSetting: Record<string, IProviderSetting> = {};
Object.keys(providers).forEach((provider) => {
providerSetting[provider] = providers[provider].settings;
});
Cookies.set('providers', JSON.stringify(providerSetting));
}, [providers]);
useEffect(() => {
let active = Object.entries(providers)
.filter(([_key, provider]) => provider.settings.enabled)
.map(([_k, p]) => p);
if (!isLocalModel) {
active = active.filter((p) => !LOCAL_PROVIDERS.includes(p.name));
}
setActiveProviders(active);
}, [providers, isLocalModel]);
// helper function to update settings
const updateProviderSettings = useCallback((provider: string, config: IProviderSetting) => {
const settings = providers[provider].settings;
providersStore.setKey(provider, { ...providers[provider], settings: { ...settings, ...config } });
}, []);
const enableDebugMode = useCallback((enabled: boolean) => {
isDebugMode.set(enabled);
Cookies.set('isDebugEnabled', String(enabled));
}, []);
const enableLocalModels = useCallback((enabled: boolean) => {
isLocalModelsEnabled.set(enabled);
Cookies.set('isLocalModelsEnabled', String(enabled));
}, []);
return {
providers,
activeProviders,
updateProviderSettings,
debug,
enableDebugMode,
isLocalModel,
enableLocalModels,
};
}

View File

@@ -1,5 +1,7 @@
import { map } from 'nanostores';
import { atom, map } from 'nanostores';
import { workbenchStore } from './workbench';
import { PROVIDER_LIST } from '~/utils/constants';
import type { IProviderConfig } from '~/types/model';
export interface Shortcut {
key: string;
@@ -15,32 +17,10 @@ export interface Shortcuts {
toggleTerminal: Shortcut;
}
export interface Provider {
name: string;
isEnabled: boolean;
}
export const URL_CONFIGURABLE_PROVIDERS = ['Ollama', 'LMStudio', 'OpenAILike'];
export const LOCAL_PROVIDERS = ['OpenAILike', 'LMStudio', 'Ollama'];
export interface Settings {
shortcuts: Shortcuts;
providers: Provider[];
}
export const providersList: Provider[] = [
{ name: 'Groq', isEnabled: false },
{ name: 'HuggingFace', isEnabled: false },
{ name: 'OpenAI', isEnabled: false },
{ name: 'Anthropic', isEnabled: false },
{ name: 'OpenRouter', isEnabled: false },
{ name: 'Google', isEnabled: false },
{ name: 'Ollama', isEnabled: false },
{ name: 'OpenAILike', isEnabled: false },
{ name: 'Together', isEnabled: false },
{ name: 'Deepseek', isEnabled: false },
{ name: 'Mistral', isEnabled: false },
{ name: 'Cohere', isEnabled: false },
{ name: 'LMStudio', isEnabled: false },
{ name: 'xAI', isEnabled: false },
];
export type ProviderSetting = Record<string, IProviderConfig>;
export const shortcutsStore = map<Shortcuts>({
toggleTerminal: {
@@ -50,14 +30,17 @@ export const shortcutsStore = map<Shortcuts>({
},
});
export const settingsStore = map<Settings>({
shortcuts: shortcutsStore.get(),
providers: providersList,
const initialProviderSettings: ProviderSetting = {};
PROVIDER_LIST.forEach((provider) => {
initialProviderSettings[provider.name] = {
...provider,
settings: {
enabled: false,
},
};
});
export const providersStore = map<ProviderSetting>(initialProviderSettings);
shortcutsStore.subscribe((shortcuts) => {
settingsStore.set({
...settingsStore.get(),
shortcuts,
});
});
export const isDebugMode = atom(false);
export const isLocalModelsEnabled = atom(true);