assistant.ts 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import type OpenAI from 'openai';
  2. import { configManager } from '~/server/service/config-manager';
  3. import { openaiClient } from '../client';
  4. const AssistantType = {
  5. SEARCH: 'Search',
  6. CHAT: 'Chat',
  7. } as const;
  8. type AssistantType = typeof AssistantType[keyof typeof AssistantType];
  9. const findAssistantByName = async(assistantName: string): Promise<OpenAI.Beta.Assistant | undefined> => {
  10. // declare finder
  11. const findAssistant = async(assistants: OpenAI.Beta.Assistants.AssistantsPage): Promise<OpenAI.Beta.Assistant | undefined> => {
  12. const found = assistants.data.find(assistant => assistant.name === assistantName);
  13. if (found != null) {
  14. return found;
  15. }
  16. // recursively find assistant
  17. if (assistants.hasNextPage()) {
  18. return findAssistant(await assistants.getNextPage());
  19. }
  20. };
  21. const storedAssistants = await openaiClient.beta.assistants.list({ order: 'desc' });
  22. return findAssistant(storedAssistants);
  23. };
  24. const getOrCreateAssistant = async(type: AssistantType): Promise<OpenAI.Beta.Assistant> => {
  25. const appSiteUrl = configManager.getConfig('crowi', 'app:siteUrl');
  26. const assistantName = `GROWI ${type} Assistant for ${appSiteUrl} ${configManager.getConfig('crowi', 'openai:assistantNameSuffix')}`;
  27. const assistantOnRemote = await findAssistantByName(assistantName);
  28. if (assistantOnRemote != null) {
  29. return assistantOnRemote;
  30. }
  31. const newAssistant = await openaiClient.beta.assistants.create({
  32. name: assistantName,
  33. model: 'gpt-4o',
  34. });
  35. return newAssistant;
  36. };
  37. let searchAssistant: OpenAI.Beta.Assistant | undefined;
  38. export const getOrCreateSearchAssistant = async(): Promise<OpenAI.Beta.Assistant> => {
  39. if (searchAssistant != null) {
  40. return searchAssistant;
  41. }
  42. searchAssistant = await getOrCreateAssistant(AssistantType.SEARCH);
  43. openaiClient.beta.assistants.update(searchAssistant.id, {
  44. instructions: configManager.getConfig('crowi', 'openai:searchAssistantInstructions'),
  45. tools: [{ type: 'file_search' }],
  46. });
  47. return searchAssistant;
  48. };
  49. let chatAssistant: OpenAI.Beta.Assistant | undefined;
  50. export const getOrCreateChatAssistant = async(): Promise<OpenAI.Beta.Assistant> => {
  51. if (chatAssistant != null) {
  52. return chatAssistant;
  53. }
  54. const instructions = configManager.getConfig('crowi', 'openai:chatAssistantInstructions');
  55. chatAssistant = await getOrCreateAssistant(AssistantType.CHAT);
  56. openaiClient.beta.assistants.update(chatAssistant.id, {
  57. instructions,
  58. tools: [{ type: 'file_search' }],
  59. });
  60. return chatAssistant;
  61. };