mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-01-29 13:46:18 +01:00
🤖 feat: OpenAI Assistants v2 (initial support) (#2781)
* 🤖 Assistants V2 Support: Part 1 - Separated Azure Assistants to its own endpoint - File Search / Vector Store integration is incomplete, but can toggle and use storage from playground - Code Interpreter resource files can be added but not deleted - GPT-4o is supported - Many improvements to the Assistants Endpoint overall data-provider v2 changes copy existing route as v1 chore: rename new endpoint to reduce comparison operations and add new azure filesource api: add azureAssistants part 1 force use of version for assistants/assistantsAzure chore: switch name back to azureAssistants refactor type version: string | number Ensure assistants endpoints have version set fix: isArchived type issue in ConversationListParams refactor: update assistants mutations/queries with endpoint/version definitions, update Assistants Map structure chore: FilePreview component ExtendedFile type assertion feat: isAssistantsEndpoint helper chore: remove unused useGenerations chore(buildTree): type issue chore(Advanced): type issue (unused component, maybe in future) first pass for multi-assistant endpoint rewrite fix(listAssistants): pass params correctly feat: list separate assistants by endpoint fix(useTextarea): access assistantMap correctly fix: assistant endpoint switching, resetting ID fix: broken during rewrite, selecting assistant mention fix: set/invalidate assistants endpoint query data correctly feat: Fix issue with assistant ID not being reset correctly getOpenAIClient helper function feat: add toast for assistant deletion fix: assistants delete right after create issue for azure fix: assistant patching refactor: actions to use getOpenAIClient refactor: consolidate logic into helpers file fix: issue where conversation data was not initially available v1 chat support refactor(spendTokens): only early return if completionTokens isNaN fix(OpenAIClient): ensure spendTokens has all necessary params refactor: route/controller logic fix(assistants/initializeClient): use defaultHeaders field fix: sanitize default operation id chore: bump openai package first pass v2 action service feat: retroactive domain parsing for actions added via v1 feat: delete db records of actions/assistants on openai assistant deletion chore: remove vision tools from v2 assistants feat: v2 upload and delete assistant vision images WIP first pass, thread attachments fix: show assistant vision files (save local/firebase copy) v2 image continue fix: annotations fix: refine annotations show analyze as error if is no longer submitting before progress reaches 1 and show file_search as retrieval tool fix: abort run, undefined endpoint issue refactor: consolidate capabilities logic and anticipate versioning frontend version 2 changes fix: query selection and filter add endpoint to unknown filepath add file ids to resource, deleting in progress enable/disable file search remove version log * 🤖 Assistants V2 Support: Part 2 🎹 fix: Autocompletion Chrome Bug on Action API Key Input chore: remove `useOriginNavigate` chore: set correct OpenAI Storage Source fix: azure file deletions, instantiate clients by source for deletion update code interpret files info feat: deleteResourceFileId chore: increase poll interval as azure easily rate limits fix: openai file deletions, TODO: evaluate rejected deletion settled promises to determine which to delete from db records file source icons update table file filters chore: file search info and versioning fix: retrieval update with necessary tool_resources if specified fix(useMentions): add optional chaining in case listMap value is undefined fix: force assistant avatar roundedness fix: azure assistants, check correct flag chore: bump data-provider * fix: merge conflict * ci: fix backend tests due to new updates * chore: update .env.example * meilisearch improvements * localization updates * chore: update comparisons * feat: add additional metadata: endpoint, author ID * chore: azureAssistants ENDPOINTS exclusion warning
This commit is contained in:
parent
af8bcb08d6
commit
1a452121fa
158 changed files with 4184 additions and 1204 deletions
|
|
@ -1,21 +1,22 @@
|
|||
import { Plus } from 'lucide-react';
|
||||
import { useCallback, useEffect, useRef } from 'react';
|
||||
import {
|
||||
defaultAssistantFormValues,
|
||||
defaultOrderQuery,
|
||||
isImageVisionTool,
|
||||
EModelEndpoint,
|
||||
Capabilities,
|
||||
Tools,
|
||||
FileSources,
|
||||
Capabilities,
|
||||
EModelEndpoint,
|
||||
LocalStorageKeys,
|
||||
isImageVisionTool,
|
||||
defaultAssistantFormValues,
|
||||
} from 'librechat-data-provider';
|
||||
import type { UseFormReset } from 'react-hook-form';
|
||||
import type { UseMutationResult } from '@tanstack/react-query';
|
||||
import type { Assistant, AssistantCreateParams } from 'librechat-data-provider';
|
||||
import type { Assistant, AssistantCreateParams, AssistantsEndpoint } from 'librechat-data-provider';
|
||||
import type {
|
||||
AssistantForm,
|
||||
Actions,
|
||||
TAssistantOption,
|
||||
ExtendedFile,
|
||||
AssistantForm,
|
||||
TAssistantOption,
|
||||
LastSelectedModels,
|
||||
} from '~/common';
|
||||
import SelectDropDown from '~/components/ui/SelectDropDown';
|
||||
|
|
@ -29,12 +30,14 @@ const keys = new Set(['name', 'id', 'description', 'instructions', 'model']);
|
|||
export default function AssistantSelect({
|
||||
reset,
|
||||
value,
|
||||
endpoint,
|
||||
selectedAssistant,
|
||||
setCurrentAssistantId,
|
||||
createMutation,
|
||||
}: {
|
||||
reset: UseFormReset<AssistantForm>;
|
||||
value: TAssistantOption;
|
||||
endpoint: AssistantsEndpoint;
|
||||
selectedAssistant: string | null;
|
||||
setCurrentAssistantId: React.Dispatch<React.SetStateAction<string | undefined>>;
|
||||
createMutation: UseMutationResult<Assistant, Error, AssistantCreateParams>;
|
||||
|
|
@ -43,42 +46,69 @@ export default function AssistantSelect({
|
|||
const fileMap = useFileMapContext();
|
||||
const lastSelectedAssistant = useRef<string | null>(null);
|
||||
const [lastSelectedModels] = useLocalStorage<LastSelectedModels>(
|
||||
'lastSelectedModel',
|
||||
LocalStorageKeys.LAST_MODEL,
|
||||
{} as LastSelectedModels,
|
||||
);
|
||||
|
||||
const assistants = useListAssistantsQuery(defaultOrderQuery, {
|
||||
const assistants = useListAssistantsQuery(endpoint, undefined, {
|
||||
select: (res) =>
|
||||
res.data.map((_assistant) => {
|
||||
const source =
|
||||
endpoint === EModelEndpoint.assistants ? FileSources.openai : FileSources.azure;
|
||||
const assistant = {
|
||||
..._assistant,
|
||||
label: _assistant?.name ?? '',
|
||||
value: _assistant.id,
|
||||
files: _assistant?.file_ids ? ([] as Array<[string, ExtendedFile]>) : undefined,
|
||||
code_files: _assistant?.tool_resources?.code_interpreter?.file_ids
|
||||
? ([] as Array<[string, ExtendedFile]>)
|
||||
: undefined,
|
||||
};
|
||||
|
||||
const handleFile = (file_id: string, list?: Array<[string, ExtendedFile]>) => {
|
||||
const file = fileMap?.[file_id];
|
||||
if (file) {
|
||||
list?.push([
|
||||
file_id,
|
||||
{
|
||||
file_id: file.file_id,
|
||||
type: file.type,
|
||||
filepath: file.filepath,
|
||||
filename: file.filename,
|
||||
width: file.width,
|
||||
height: file.height,
|
||||
size: file.bytes,
|
||||
preview: file.filepath,
|
||||
progress: 1,
|
||||
source,
|
||||
},
|
||||
]);
|
||||
} else {
|
||||
list?.push([
|
||||
file_id,
|
||||
{
|
||||
file_id,
|
||||
type: '',
|
||||
filename: '',
|
||||
size: 1,
|
||||
progress: 1,
|
||||
filepath: endpoint,
|
||||
source,
|
||||
},
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
if (assistant.files && _assistant.file_ids) {
|
||||
_assistant.file_ids.forEach((file_id) => {
|
||||
const file = fileMap?.[file_id];
|
||||
if (file) {
|
||||
assistant.files?.push([
|
||||
file_id,
|
||||
{
|
||||
file_id: file.file_id,
|
||||
type: file.type,
|
||||
filepath: file.filepath,
|
||||
filename: file.filename,
|
||||
width: file.width,
|
||||
height: file.height,
|
||||
size: file.bytes,
|
||||
preview: file.filepath,
|
||||
progress: 1,
|
||||
source: FileSources.openai,
|
||||
},
|
||||
]);
|
||||
}
|
||||
});
|
||||
_assistant.file_ids.forEach((file_id) => handleFile(file_id, assistant.files));
|
||||
}
|
||||
|
||||
if (assistant.code_files && _assistant.tool_resources?.code_interpreter?.file_ids) {
|
||||
_assistant.tool_resources?.code_interpreter?.file_ids?.forEach((file_id) =>
|
||||
handleFile(file_id, assistant.code_files),
|
||||
);
|
||||
}
|
||||
|
||||
return assistant;
|
||||
}),
|
||||
});
|
||||
|
|
@ -92,7 +122,7 @@ export default function AssistantSelect({
|
|||
setCurrentAssistantId(undefined);
|
||||
return reset({
|
||||
...defaultAssistantFormValues,
|
||||
model: lastSelectedModels?.[EModelEndpoint.assistants] ?? '',
|
||||
model: lastSelectedModels?.[endpoint] ?? '',
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -112,6 +142,9 @@ export default function AssistantSelect({
|
|||
?.filter((tool) => tool.type !== 'function' || isImageVisionTool(tool))
|
||||
?.map((tool) => tool?.function?.name || tool.type)
|
||||
.forEach((tool) => {
|
||||
if (tool === Tools.file_search) {
|
||||
actions[Capabilities.retrieval] = true;
|
||||
}
|
||||
actions[tool] = true;
|
||||
});
|
||||
|
||||
|
|
@ -141,7 +174,7 @@ export default function AssistantSelect({
|
|||
reset(formValues);
|
||||
setCurrentAssistantId(assistant?.id);
|
||||
},
|
||||
[assistants.data, reset, setCurrentAssistantId, createMutation, lastSelectedModels],
|
||||
[assistants.data, reset, setCurrentAssistantId, createMutation, endpoint, lastSelectedModels],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue