+ type="checkbox"
+ class="checkbox"
+ id="enablePetals"
+ checked={!!$globalStorage.enablePetals}
+ on:click={setPetalsEnabled}
+ >
Use Petals API and Models (Llama 2)
{#if showPetalsSettings}
@@ -140,30 +183,11 @@ const setPetalsEnabled = (event: Event) => {
Save
-
-
-
- {#if !pedalsEndpoint}
-
- Please only use the default public API for testing. It's best to configure a private endpoint and enter it above for connection to the Petals swarm.
-
- {/if}
-
- Petals lets you run large language models at home by connecting to a public swarm, BitTorrent-style, without hefty GPU requirements.
-
-
- You are encouraged to set up a Petals server to share your GPU resources with the public swarm. Minimum requirements to contribute Llama 2 completions are a GTX 1080 8GB, but the larger/faster the better.
-
-
- If you're receiving errors while using Petals, check swarm health and consider adding your GPU to the swarm to help.
-
-
- Because Petals uses a public swarm, do not send sensitive information when using Petals.
-
{/if}
+
{#if apiKey}
@@ -173,4 +197,4 @@ const setPetalsEnabled = (event: Event) => {
{/if}
-
\ No newline at end of file
+
diff --git a/src/lib/Models.svelte b/src/lib/Models.svelte
index e19f620f..3c178528 100644
--- a/src/lib/Models.svelte
+++ b/src/lib/Models.svelte
@@ -1,17 +1,13 @@
+ await restartProfile(chatId)
+ replace(`/chat/${chatId}`)
+ })
+
\ No newline at end of file
diff --git a/src/lib/Profiles.svelte b/src/lib/Profiles.svelte
index 5ca44d68..91c07a8e 100644
--- a/src/lib/Profiles.svelte
+++ b/src/lib/Profiles.svelte
@@ -15,7 +15,9 @@ export const isStaticProfile = (key:string):boolean => {
return !!profiles[key]
}
-export const getProfiles = (forceUpdate:boolean = false):Record => {
+export const getProfiles = async (forceUpdate:boolean = false):Promise> => {
+ const defaultModel = await getDefaultModel()
+
const pc = get(profileCache)
if (!forceUpdate && Object.keys(pc).length) {
return pc
@@ -24,7 +26,7 @@ export const getProfiles = (forceUpdate:boolean = false):Record {
v = JSON.parse(JSON.stringify(v))
a[k] = v
- v.model = v.model || getDefaultModel()
+ v.model = v.model || defaultModel
return a
}, {} as Record)
Object.entries(getCustomProfiles()).forEach(([k, v]) => {
@@ -42,22 +44,23 @@ export const getProfiles = (forceUpdate:boolean = false):Record {
- return Object.entries(getProfiles()).reduce((a, [k, v]) => {
+export const getProfileSelect = async ():Promise => {
+ const allProfiles = await getProfiles()
+ return Object.entries(allProfiles).reduce((a, [k, v]) => {
a.push({ value: k, text: v.profileName } as SelectOption)
return a
}, [] as SelectOption[])
}
-export const getDefaultProfileKey = ():string => {
- const allProfiles = getProfiles()
+export const getDefaultProfileKey = async ():Promise => {
+ const allProfiles = await getProfiles()
return (allProfiles[getGlobalSettings().defaultProfile || ''] ||
profiles[defaultProfile] ||
profiles[Object.keys(profiles)[0]]).profile
}
-export const getProfile = (key:string, forReset:boolean = false):ChatSettings => {
- const allProfiles = getProfiles()
+export const getProfile = async (key:string, forReset:boolean = false):Promise => {
+ const allProfiles = await getProfiles()
let profile = allProfiles[key] ||
allProfiles[getGlobalSettings().defaultProfile || ''] ||
profiles[defaultProfile] ||
@@ -108,9 +111,9 @@ export const setSystemPrompt = (chatId: number) => {
}
// Restart currently loaded profile
-export const restartProfile = (chatId:number, noApply:boolean = false) => {
+export const restartProfile = async (chatId:number, noApply:boolean = false) => {
const settings = getChatSettings(chatId)
- if (!settings.profile && !noApply) return applyProfile(chatId, '', true)
+ if (!settings.profile && !noApply) return await applyProfile(chatId, '', true)
// Clear current messages
clearMessages(chatId)
// Add the system prompt
@@ -129,16 +132,16 @@ export const restartProfile = (chatId:number, noApply:boolean = false) => {
setGlobalSettingValueByKey('lastProfile', settings.profile)
}
-export const newNameForProfile = (name:string) => {
- const profiles = getProfileSelect()
+export const newNameForProfile = async (name:string) => {
+ const profiles = await getProfileSelect()
return newName(name, profiles.reduce((a, p) => { a[p.text] = p; return a }, {}))
}
// Apply currently selected profile
-export const applyProfile = (chatId:number, key:string = '', resetChat:boolean = false) => {
- resetChatSettings(chatId, resetChat) // Fully reset
+export const applyProfile = async (chatId:number, key:string = '', resetChat:boolean = false) => {
+ await resetChatSettings(chatId, resetChat) // Fully reset
if (!resetChat) return
- return restartProfile(chatId, true)
+ return await restartProfile(chatId, true)
}
const summaryPrompts = {
diff --git a/src/lib/Settings.svelte b/src/lib/Settings.svelte
index 2cdf58c1..f46992d7 100644
--- a/src/lib/Settings.svelte
+++ b/src/lib/Settings.svelte
@@ -18,14 +18,17 @@ import {
type ChatSortOption
} from './Types.svelte'
- import { getModelDetail, getTokens } from './Models.svelte'
+import { getChatModelOptions, getModelDetail, getTokens } from './Models.svelte'
-const defaultModel:Model = 'gpt-3.5-turbo'
-const defaultModelPetals:Model = 'stabilityai/StableBeluga2'
+// We are adding default model names explicitly here to avoid
+// circular dependencies. Alternative would be a big refactor,
+// which we want to avoid for now.
+export const getDefaultModel = async (): Promise => {
+ if (!get(apiKeyStorage)) return 'stabilityai/StableBeluga2'
-export const getDefaultModel = (): Model => {
- if (!get(apiKeyStorage)) return defaultModelPetals
- return defaultModel
+ const models = await getChatModelOptions()
+
+ return models[0].text
}
export const getChatSettingList = (): ChatSetting[] => {
@@ -136,7 +139,8 @@ export const globalDefaults: GlobalSettings = {
chatSort: 'created',
openAICompletionEndpoint: '',
enablePetals: false,
- pedalsEndpoint: ''
+ pedalsEndpoint: '',
+ openAiEndpoint: 'https://api.openai.com'
}
const excludeFromProfile = {
@@ -721,6 +725,11 @@ const globalSettingsList:GlobalSetting[] = [
key: 'pedalsEndpoint',
name: 'Petals API Endpoint',
type: 'text'
+ },
+ {
+ key: 'openAiEndpoint',
+ name: 'OpenAI API Endpoint',
+ type: 'text'
}
]
diff --git a/src/lib/Sidebar.svelte b/src/lib/Sidebar.svelte
index e090c9ad..0ee2b8a9 100644
--- a/src/lib/Sidebar.svelte
+++ b/src/lib/Sidebar.svelte
@@ -82,7 +82,7 @@
>
{:else}
- { $pinMainMenu = false; startNewChatWithWarning(activeChatId) }} class="panel-block button" title="Start new chat with default profile" class:is-disabled={!hasModels}
+ { $pinMainMenu = false; await startNewChatWithWarning(activeChatId) }} class="panel-block button" title="Start new chat with default profile" class:is-disabled={!hasModels}
> New chat
{/if}
diff --git a/src/lib/Storage.svelte b/src/lib/Storage.svelte
index 38556801..60f078f2 100644
--- a/src/lib/Storage.svelte
+++ b/src/lib/Storage.svelte
@@ -14,6 +14,7 @@
export const latestModelMap = persisted('latestModelMap', {} as Record) // What was returned when a model was requested
export const globalStorage = persisted('global', {} as GlobalSettings)
const apiKeyFromEnv = import.meta.env.VITE_OPENAI_API_KEY || ''
+ const apiBaseUriFromEnv = import.meta.env.VITE_API_BASE || 'https://api.openai.com/v1'
export const apiKeyStorage = persisted('apiKey', apiKeyFromEnv as string)
export let checkStateChange = writable(0) // Trigger for Chat
export let showSetChatSettings = writable(false) //
@@ -31,19 +32,30 @@
return get(apiKeyStorage)
}
+ // Avoid user input errors. Trailing slashes or "/v1" break
+ // the API. So we clean it up here.
+ const cleanApiBase = (endpoint: string): string => {
+ return endpoint.replace(/\/v1$/, '').replace(/\/$/, '')
+ }
+
+ export const getApiBase = (): string => {
+ const endpoint = get(globalStorage).openAiEndpoint || apiBaseUriFromEnv
+ return cleanApiBase(endpoint)
+ }
+
export const newChatID = (): number => {
const chats = get(chatsStorage)
const chatId = chats.reduce((maxId, chat) => Math.max(maxId, chat.id), 0) + 1
return chatId
}
- export const addChat = (profile:ChatSettings|undefined = undefined): number => {
+ export const addChat = async (profile:ChatSettings|undefined = undefined): Promise => {
const chats = get(chatsStorage)
// Find the max chatId
const chatId = newChatID()
- profile = JSON.parse(JSON.stringify(profile || getProfile(''))) as ChatSettings
+ profile = JSON.parse(JSON.stringify(profile || await getProfile(''))) as ChatSettings
const nameMap = chats.reduce((a, chat) => { a[chat.name] = chat; return a }, {})
// Add a new chat
@@ -61,7 +73,7 @@
})
chatsStorage.set(chats)
// Apply defaults and prepare it to start
- restartProfile(chatId)
+ await restartProfile(chatId)
return chatId
}
@@ -152,10 +164,10 @@
}
// Reset all setting to current profile defaults
- export const resetChatSettings = (chatId, resetAll:boolean = false) => {
+ export const resetChatSettings = async (chatId, resetAll:boolean = false) => {
const chats = get(chatsStorage)
const chat = chats.find((chat) => chat.id === chatId) as Chat
- const profile = getProfile(chat.settings.profile)
+ const profile = await getProfile(chat.settings.profile)
const exclude = getExcludeFromProfile()
if (resetAll) {
// Reset to base defaults first, then apply profile
@@ -483,7 +495,7 @@
return store.profiles || {}
}
- export const deleteCustomProfile = (chatId:number, profileId:string) => {
+ export const deleteCustomProfile = async (chatId:number, profileId:string) => {
if (isStaticProfile(profileId)) {
throw new Error('Sorry, you can\'t delete a static profile.')
}
@@ -495,10 +507,10 @@
}
delete store.profiles[profileId]
globalStorage.set(store)
- getProfiles(true) // force update profile cache
+ await getProfiles(true) // force update profile cache
}
- export const saveCustomProfile = (profile:ChatSettings) => {
+ export const saveCustomProfile = async (profile:ChatSettings) => {
const store = get(globalStorage)
let profiles = store.profiles
if (!profiles) {
@@ -521,7 +533,7 @@
if (isStaticProfile(profile.profile)) {
// throw new Error('Sorry, you can\'t modify a static profile. You can clone it though!')
// Save static profile as new custom
- profile.profileName = newNameForProfile(profile.profileName)
+ profile.profileName = await newNameForProfile(profile.profileName)
profile.profile = uuidv4()
}
const clone = JSON.parse(JSON.stringify(profile)) // Always store a copy
@@ -537,7 +549,7 @@
globalStorage.set(store)
profile.isDirty = false
saveChatStore()
- getProfiles(true) // force update profile cache
+ await getProfiles(true) // force update profile cache
}
export const getChatSortOption = (): ChatSortOption => {
diff --git a/src/lib/Types.svelte b/src/lib/Types.svelte
index 89cfc234..0454bd15 100644
--- a/src/lib/Types.svelte
+++ b/src/lib/Types.svelte
@@ -162,6 +162,7 @@ export type GlobalSettings = {
openAICompletionEndpoint: string;
enablePetals: boolean;
pedalsEndpoint: string;
+ openAiEndpoint: string;
};
type SettingNumber = {
diff --git a/src/lib/Util.svelte b/src/lib/Util.svelte
index dda585c3..7ddb6b62 100644
--- a/src/lib/Util.svelte
+++ b/src/lib/Util.svelte
@@ -122,15 +122,15 @@
})
}
- export const startNewChatFromChatId = (chatId: number) => {
- const newChatId = addChat(getChat(chatId).settings)
+ export const startNewChatFromChatId = async (chatId: number) => {
+ const newChatId = await addChat(getChat(chatId).settings)
// go to new chat
replace(`/chat/${newChatId}`)
}
- export const startNewChatWithWarning = (activeChatId: number|undefined, profile?: ChatSettings|undefined) => {
- const newChat = () => {
- const chatId = addChat(profile)
+ export const startNewChatWithWarning = async (activeChatId: number|undefined, profile?: ChatSettings|undefined) => {
+ const newChat = async () => {
+ const chatId = await addChat(profile)
replace(`/chat/${chatId}`)
}
// if (activeChatId && getChat(activeChatId).settings.isDirty) {
@@ -146,7 +146,7 @@
// } else {
// newChat()
// }
- newChat()
+ await newChat()
}
export const valueOf = (chatId: number, value: any) => {
diff --git a/src/lib/providers/openai/models.svelte b/src/lib/providers/openai/models.svelte
index ede0ad12..8affc3ae 100644
--- a/src/lib/providers/openai/models.svelte
+++ b/src/lib/providers/openai/models.svelte
@@ -1,11 +1,11 @@