assistant.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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. EDIT: 'Edit',
  8. } as const;
  9. const getAssistantModelByType = (type: AssistantType): OpenAI.Chat.ChatModel => {
  10. const configValue = (() => {
  11. switch (type) {
  12. case AssistantType.SEARCH:
  13. // return configManager.getConfig('openai:assistantModel:search');
  14. return 'gpt-4.1-mini';
  15. case AssistantType.CHAT:
  16. return configManager.getConfig('openai:assistantModel:chat');
  17. case AssistantType.EDIT:
  18. return configManager.getConfig('openai:assistantModel:edit');
  19. }
  20. })();
  21. return configValue;
  22. };
  23. type AssistantType = typeof AssistantType[keyof typeof AssistantType];
  24. const findAssistantByName = async(assistantName: string): Promise<OpenAI.Beta.Assistant | undefined> => {
  25. // declare finder
  26. const findAssistant = async(assistants: OpenAI.Beta.Assistants.AssistantsPage): Promise<OpenAI.Beta.Assistant | undefined> => {
  27. const found = assistants.data.find(assistant => assistant.name === assistantName);
  28. if (found != null) {
  29. return found;
  30. }
  31. // recursively find assistant
  32. if (assistants.hasNextPage()) {
  33. return findAssistant(await assistants.getNextPage());
  34. }
  35. };
  36. const storedAssistants = await openaiClient.beta.assistants.list({ order: 'desc' });
  37. return findAssistant(storedAssistants);
  38. };
  39. const getOrCreateAssistant = async(type: AssistantType, nameSuffix?: string): Promise<OpenAI.Beta.Assistant> => {
  40. const appSiteUrl = configManager.getConfig('app:siteUrl');
  41. const assistantName = `GROWI ${type} Assistant for ${appSiteUrl}${nameSuffix != null ? ` ${nameSuffix}` : ''}`;
  42. const assistantModel = getAssistantModelByType(type);
  43. const assistant = await findAssistantByName(assistantName)
  44. ?? (
  45. await openaiClient.beta.assistants.create({
  46. name: assistantName,
  47. model: assistantModel,
  48. }));
  49. // update instructions
  50. const instructions = configManager.getConfig('openai:chatAssistantInstructions');
  51. openaiClient.beta.assistants.update(assistant.id, {
  52. instructions,
  53. model: assistantModel,
  54. tools: [{ type: 'file_search' }],
  55. });
  56. return assistant;
  57. };
  58. // let searchAssistant: OpenAI.Beta.Assistant | undefined;
  59. // export const getOrCreateSearchAssistant = async(): Promise<OpenAI.Beta.Assistant> => {
  60. // if (searchAssistant != null) {
  61. // return searchAssistant;
  62. // }
  63. // searchAssistant = await getOrCreateAssistant(AssistantType.SEARCH);
  64. // openaiClient.beta.assistants.update(searchAssistant.id, {
  65. // instructions: configManager.getConfig('openai:searchAssistantInstructions'),
  66. // tools: [{ type: 'file_search' }],
  67. // });
  68. // return searchAssistant;
  69. // };
  70. let chatAssistant: OpenAI.Beta.Assistant | undefined;
  71. export const getOrCreateChatAssistant = async(): Promise<OpenAI.Beta.Assistant> => {
  72. if (chatAssistant != null) {
  73. return chatAssistant;
  74. }
  75. chatAssistant = await getOrCreateAssistant(AssistantType.CHAT);
  76. return chatAssistant;
  77. };
  78. let editorAssistant: OpenAI.Beta.Assistant | undefined;
  79. export const getOrCreateEditorAssistant = async(): Promise<OpenAI.Beta.Assistant> => {
  80. if (editorAssistant != null) {
  81. return editorAssistant;
  82. }
  83. editorAssistant = await getOrCreateAssistant(AssistantType.EDIT);
  84. return editorAssistant;
  85. };