feat: Google Gemini ❇️ (#1355)

* refactor: add gemini-pro to google Models list; use defaultModels for central model listing

* refactor(SetKeyDialog): create useMultipleKeys hook to use for Azure, export `isJson` from utils, use EModelEndpoint

* refactor(useUserKey): change variable names to make keyName setting more clear

* refactor(FileUpload): allow passing container className string

* feat(GoogleClient): Gemini support

* refactor(GoogleClient): alternate stream speed for Gemini models

* feat(Gemini): styling/settings configuration for Gemini

* refactor(GoogleClient): substract max response tokens from max context tokens if context is above 32k (I/O max is combined between the two)

* refactor(tokens): correct google max token counts and subtract max response tokens when input/output count are combined towards max context count

* feat(google/initializeClient): handle both local and user_provided credentials and write tests

* fix(GoogleClient): catch if credentials are undefined, handle if serviceKey is string or object correctly, handle no examples passed, throw error if not a Generative Language model and no service account JSON key is provided, throw error if it is a Generative m
odel, but not google API key was provided

* refactor(loadAsyncEndpoints/google): activate Google endpoint if either the service key JSON file is provided in /api/data, or a GOOGLE_KEY is defined.

* docs: updated Google configuration

* fix(ci): Mock import of Service Account Key JSON file (auth.json)

* Update apis_and_tokens.md

* feat: increase max output tokens slider for gemini pro

* refactor(GoogleSettings): handle max and default maxOutputTokens on model change

* chore: add sensitive redact regex

* docs: add warning about data privacy

* Update apis_and_tokens.md
This commit is contained in:
Danny Avila 2023-12-15 02:18:07 -05:00 committed by GitHub
parent d259431316
commit 561ce8e86a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
37 changed files with 702 additions and 219 deletions

View file

@ -22,6 +22,47 @@ export const defaultEndpoints: EModelEndpoint[] = [
EModelEndpoint.anthropic,
];
export const defaultModels = {
[EModelEndpoint.google]: [
'gemini-pro',
'chat-bison',
'chat-bison-32k',
'codechat-bison',
'codechat-bison-32k',
'text-bison',
'text-bison-32k',
'text-unicorn',
'code-gecko',
'code-bison',
'code-bison-32k',
],
[EModelEndpoint.anthropic]: [
'claude-2.1',
'claude-2',
'claude-1.2',
'claude-1',
'claude-1-100k',
'claude-instant-1',
'claude-instant-1-100k',
],
[EModelEndpoint.openAI]: [
'gpt-3.5-turbo-16k-0613',
'gpt-3.5-turbo-16k',
'gpt-4-1106-preview',
'gpt-3.5-turbo',
'gpt-3.5-turbo-1106',
'gpt-4-vision-preview',
'gpt-4',
'gpt-3.5-turbo-instruct-0914',
'gpt-3.5-turbo-0613',
'gpt-3.5-turbo-0301',
'gpt-3.5-turbo-instruct',
'gpt-4-0613',
'text-davinci-003',
'gpt-4-0314',
],
};
export const alternateName = {
[EModelEndpoint.openAI]: 'OpenAI',
[EModelEndpoint.assistant]: 'Assistants',
@ -33,6 +74,11 @@ export const alternateName = {
[EModelEndpoint.anthropic]: 'Anthropic',
};
export enum AuthKeys {
GOOGLE_SERVICE_KEY = 'GOOGLE_SERVICE_KEY',
GOOGLE_API_KEY = 'GOOGLE_API_KEY',
}
export const endpointSettings = {
[EModelEndpoint.google]: {
model: {
@ -43,6 +89,8 @@ export const endpointSettings = {
max: 2048,
step: 1,
default: 1024,
maxGeminiPro: 8192,
defaultGeminiPro: 8192,
},
temperature: {
min: 0,
@ -90,23 +138,6 @@ export const supportsFiles = {
[EModelEndpoint.assistant]: true,
};
export const openAIModels = [
'gpt-3.5-turbo-16k-0613',
'gpt-3.5-turbo-16k',
'gpt-4-1106-preview',
'gpt-3.5-turbo',
'gpt-3.5-turbo-1106',
'gpt-4-vision-preview',
'gpt-4',
'gpt-3.5-turbo-instruct-0914',
'gpt-3.5-turbo-0613',
'gpt-3.5-turbo-0301',
'gpt-3.5-turbo-instruct',
'gpt-4-0613',
'text-davinci-003',
'gpt-4-0314',
];
export const visionModels = ['gpt-4-vision', 'llava-13b'];
export const eModelEndpointSchema = z.nativeEnum(EModelEndpoint);
@ -309,17 +340,31 @@ export const googleSchema = tConversationSchema
topP: true,
topK: true,
})
.transform((obj) => ({
...obj,
model: obj.model ?? google.model.default,
modelLabel: obj.modelLabel ?? null,
promptPrefix: obj.promptPrefix ?? null,
examples: obj.examples ?? [{ input: { content: '' }, output: { content: '' } }],
temperature: obj.temperature ?? google.temperature.default,
maxOutputTokens: obj.maxOutputTokens ?? google.maxOutputTokens.default,
topP: obj.topP ?? google.topP.default,
topK: obj.topK ?? google.topK.default,
}))
.transform((obj) => {
const isGeminiPro = obj?.model?.toLowerCase()?.includes('gemini-pro');
const maxOutputTokensMax = isGeminiPro
? google.maxOutputTokens.maxGeminiPro
: google.maxOutputTokens.max;
const maxOutputTokensDefault = isGeminiPro
? google.maxOutputTokens.defaultGeminiPro
: google.maxOutputTokens.default;
let maxOutputTokens = obj.maxOutputTokens ?? maxOutputTokensDefault;
maxOutputTokens = Math.min(maxOutputTokens, maxOutputTokensMax);
return {
...obj,
model: obj.model ?? google.model.default,
modelLabel: obj.modelLabel ?? null,
promptPrefix: obj.promptPrefix ?? null,
examples: obj.examples ?? [{ input: { content: '' }, output: { content: '' } }],
temperature: obj.temperature ?? google.temperature.default,
maxOutputTokens,
topP: obj.topP ?? google.topP.default,
topK: obj.topK ?? google.topK.default,
};
})
.catch(() => ({
model: google.model.default,
modelLabel: null,
@ -579,6 +624,8 @@ export const getResponseSender = (endpointOption: TEndpointOption): string => {
if (endpoint === EModelEndpoint.google) {
if (modelLabel) {
return modelLabel;
} else if (model && model.includes('gemini')) {
return 'Gemini';
} else if (model && model.includes('code')) {
return 'Codey';
}