From 2f736d097ff639661d97c8cd8f8d5f22c8e26788 Mon Sep 17 00:00:00 2001 From: Enrico Ros Date: Thu, 18 May 2023 02:47:16 -0700 Subject: [PATCH] Relocate some files --- src/apps/chat/Chat.tsx | 8 +- .../composer/ContentReducerModal.tsx | 2 +- .../chat-stream.ts} | 5 +- .../imagine.ts => editors/image-generate.ts} | 2 +- .../agi-react.ts => editors/react-tangent.ts} | 4 +- src/apps/chat/util/ai-functions.ts | 91 ------------------- src/common/state/store-settings.ts | 1 + src/modules/aifn/autotitle/autoTitle.ts | 54 +++++++++++ .../aifn/imagine/imaginePromptFromText.ts | 39 ++++++++ .../llm-util => modules/aifn}/prompts.ts | 0 .../llm-util => modules/aifn/react}/react.ts | 4 +- .../aifn/summarize}/summerize.ts | 4 +- 12 files changed, 109 insertions(+), 105 deletions(-) rename src/apps/chat/{util/agi-immediate.ts => editors/chat-stream.ts} (98%) rename src/apps/chat/{util/imagine.ts => editors/image-generate.ts} (97%) rename src/apps/chat/{util/agi-react.ts => editors/react-tangent.ts} (94%) delete mode 100644 src/apps/chat/util/ai-functions.ts create mode 100644 src/modules/aifn/autotitle/autoTitle.ts create mode 100644 src/modules/aifn/imagine/imaginePromptFromText.ts rename src/{common/llm-util => modules/aifn}/prompts.ts (100%) rename src/{common/llm-util => modules/aifn/react}/react.ts (98%) rename src/{common/llm-util => modules/aifn/summarize}/summerize.ts (98%) diff --git a/src/apps/chat/Chat.tsx b/src/apps/chat/Chat.tsx index 47136cd3f..93a79a328 100644 --- a/src/apps/chat/Chat.tsx +++ b/src/apps/chat/Chat.tsx @@ -8,6 +8,7 @@ import { CmdRunReact } from '~/modules/search/search.client'; import { PasteGG } from '~/modules/pastegg/pastegg.types'; import { PublishedModal } from '~/modules/pastegg/PublishedModal'; import { callPublish } from '~/modules/pastegg/pastegg.client'; +import { imaginePromptFromText } from '~/modules/aifn/imagine/imaginePromptFromText'; import { useModelsStore } from '~/modules/llms/llm.store'; import { ConfirmationModal } from '~/common/components/ConfirmationModal'; @@ -26,10 +27,9 @@ import { ConversationItems } from './components/appbar/ConversationItems'; import { Dropdowns } from './components/appbar/Dropdowns'; import { Ephemerals } from './components/ephemerals/Ephemerals'; import { ImportedModal, ImportedOutcome } from './components/appbar/ImportedModal'; -import { imaginePromptFromText } from './util/ai-functions'; -import { runAssistantUpdatingState } from './util/agi-immediate'; -import { runImageGenerationUpdatingState } from './util/imagine'; -import { runReActUpdatingState } from './util/agi-react'; +import { runAssistantUpdatingState } from './editors/chat-stream'; +import { runImageGenerationUpdatingState } from './editors/image-generate'; +import { runReActUpdatingState } from './editors/react-tangent'; const SPECIAL_ID_ALL_CHATS = 'all-chats'; diff --git a/src/apps/chat/components/composer/ContentReducerModal.tsx b/src/apps/chat/components/composer/ContentReducerModal.tsx index a62448656..3a0f6b8c7 100644 --- a/src/apps/chat/components/composer/ContentReducerModal.tsx +++ b/src/apps/chat/components/composer/ContentReducerModal.tsx @@ -4,11 +4,11 @@ import { shallow } from 'zustand/shallow'; import { Alert, Box, Button, CircularProgress, Divider, FormControl, FormHelperText, FormLabel, Modal, ModalClose, ModalDialog, Option, Select, Slider, Stack, Textarea, Typography } from '@mui/joy'; import { DLLM, DLLMId } from '~/modules/llms/llm.types'; +import { summerizeToFitContextBudget } from '~/modules/aifn/summarize/summerize'; import { useModelsStore } from '~/modules/llms/llm.store'; import { Section } from '~/common/components/Section'; import { countModelTokens } from '~/common/llm-util/token-counter'; -import { summerizeToFitContextBudget } from '~/common/llm-util/summerize'; import { TokenBadge } from './TokenBadge'; diff --git a/src/apps/chat/util/agi-immediate.ts b/src/apps/chat/editors/chat-stream.ts similarity index 98% rename from src/apps/chat/util/agi-immediate.ts rename to src/apps/chat/editors/chat-stream.ts index fb42494d8..47f0205d0 100644 --- a/src/apps/chat/util/agi-immediate.ts +++ b/src/apps/chat/editors/chat-stream.ts @@ -2,13 +2,14 @@ import { SystemPurposeId, SystemPurposes } from '../../../data'; import { DLLMId } from '~/modules/llms/llm.types'; import { OpenAI } from '~/modules/openai/openai.types'; +import { autoTitle } from '~/modules/aifn/autotitle/autoTitle'; import { speakText } from '~/modules/elevenlabs/elevenlabs.client'; import { createDMessage, DMessage, useChatStore } from '~/common/state/store-chats'; import { useSettingsStore } from '~/common/state/store-settings'; import { findOpenAILlmRefOrThrow } from '~/modules/llms/llm.store'; -import { updateAutoConversationTitle } from './ai-functions'; + /** @@ -33,7 +34,7 @@ export const runAssistantUpdatingState = async (conversationId: string, history: startTyping(conversationId, null); // update text, if needed - await updateAutoConversationTitle(conversationId); + await autoTitle(conversationId); }; diff --git a/src/apps/chat/util/imagine.ts b/src/apps/chat/editors/image-generate.ts similarity index 97% rename from src/apps/chat/util/imagine.ts rename to src/apps/chat/editors/image-generate.ts index cf76ce22e..534169eef 100644 --- a/src/apps/chat/util/imagine.ts +++ b/src/apps/chat/editors/image-generate.ts @@ -4,7 +4,7 @@ import { prodiaDefaultModelId } from '~/modules/prodia/prodia.client'; import { useChatStore } from '~/common/state/store-chats'; import { useSettingsStore } from '~/common/state/store-settings'; -import { createAssistantTypingMessage } from './agi-immediate'; +import { createAssistantTypingMessage } from './chat-stream'; /** diff --git a/src/apps/chat/util/agi-react.ts b/src/apps/chat/editors/react-tangent.ts similarity index 94% rename from src/apps/chat/util/agi-react.ts rename to src/apps/chat/editors/react-tangent.ts index 916930e38..15f692498 100644 --- a/src/apps/chat/util/agi-react.ts +++ b/src/apps/chat/editors/react-tangent.ts @@ -1,9 +1,9 @@ +import { Agent } from '~/modules/aifn/react/react'; import { DLLMId } from '~/modules/llms/llm.types'; -import { Agent } from '~/common/llm-util/react'; import { createDEphemeral, DMessage, useChatStore } from '~/common/state/store-chats'; -import { createAssistantTypingMessage } from './agi-immediate'; +import { createAssistantTypingMessage } from './chat-stream'; /** diff --git a/src/apps/chat/util/ai-functions.ts b/src/apps/chat/util/ai-functions.ts deleted file mode 100644 index a7c695bd2..000000000 --- a/src/apps/chat/util/ai-functions.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { callChat } from '~/modules/openai/openai.client'; -import { useModelsStore } from '~/modules/llms/llm.store'; - -import { useChatStore } from '~/common/state/store-chats'; - - -/** - * Creates the AI titles for conversations, by taking the last 5 first-lines and asking AI what's that about - */ -export async function updateAutoConversationTitle(conversationId: string) { - - // external state - const { fastLLMId } = useModelsStore.getState(); - const { conversations } = useChatStore.getState(); - - // only operate on valid conversations, without any title - const conversation = conversations.find(c => c.id === conversationId) ?? null; - if (!fastLLMId || !conversation || conversation.autoTitle || conversation.userTitle) return; - - // first line of the last 5 messages - const historyLines: string[] = conversation.messages.filter(m => m.role !== 'system').slice(-5).map(m => { - let text = m.text.split('\n')[0]; - text = text.length > 50 ? text.substring(0, 50) + '...' : text; - text = `${m.role === 'user' ? 'You' : 'Assistant'}: ${text}`; - return `- ${text}`; - }); - - // LLM - callChat(fastLLMId, [ - { role: 'system', content: `You are an AI conversation titles assistant who specializes in creating expressive yet few-words chat titles.` }, - { - role: 'user', content: - 'Analyze the given short conversation (every line is truncated) and extract a concise chat title that ' + - 'summarizes the conversation in as little as a couple of words.\n' + - 'Only respond with the lowercase short title and nothing else.\n' + - '\n' + - '```\n' + - historyLines.join('\n') + - '```\n', - }, - ]).then(chatResponse => { - - const title = chatResponse?.content - ?.trim() - ?.replaceAll('"', '') - ?.replace('Title: ', '') - ?.replace('title: ', ''); - - if (title) - useChatStore.getState().setAutoTitle(conversationId, title); - - }); - -} - -// https://www.youtube.com/watch?v=XLG-qtZwxIw -/*const promptNew = - 'I want you to act as a prompt engineer. You will help me write prompts for an ai art generator.\n' + - '\n' + - 'I will provide you with short content ideas and your job is to elaborate these into full, detailed, coherent prompts.\n' + - '\n' + - 'Prompts involve describing the content and style of images in concise accurate language. It is useful to be explicit and use references to popular culture, artists and mediums. Your focus needs to be on nouns and adjectives. I will give you some example prompts for your reference. Please define the exact camera that should be used\n' + - '\n' + - 'Here is a formula for you to use(content insert nouns here)(medium: insert artistic medium here)(style: insert references to genres, artists and popular culture here)(lighting, reference the lighting here)(colours reference color styles and palettes here)(composition: reference cameras, specific lenses, shot types and positional elements here)\n' + - '\n' + - 'when giving a prompt remove the brackets, speak in natural language and be more specific, use precise, articulate language.'; -*/ - -// NOTE: formerly using this for GPT3.5Turbo -// 'You are an AI prompt writer for AI art generation. I will provide you with an input that may include ideas or context, and your task is to create coherent and complete prompts that guide the AI in creating visually captivating artwork.\n' + -// 'Prompts involve crafting descriptive compelling captions that describe scenes, settings, or subjects at a high level, using mostly adjectives and nouns to provide clear and focused guidance. You may also include references to artistic styles, techniques, or cultural influences to help achieve the desired aesthetic.\n' + -// 'To ensure the AI can interpret and generate the artwork based on the provided guidance, the output must be the lowercase prompt and nothing else.', -const simpleImagineSystemPrompt = 'As an AI art prompt writer, create captivating prompts using adjectives, nouns, and artistic references that a non-technical person can understand. Craft creative, coherent and descriptive captions to guide the AI in generating visually striking artwork. Provide output as a lowercase prompt and nothing else.'; - -/** - * Creates a caption for a drawing or photo given some description - used to elevate the quality of the imaging - */ -export async function imaginePromptFromText(messageText: string): Promise { - const { fastLLMId } = useModelsStore.getState(); - if (!fastLLMId) return null; - try { - const chatResponse = await callChat(fastLLMId, [ - { role: 'system', content: simpleImagineSystemPrompt }, - { role: 'user', content: 'Write a prompt, based on the following input.\n\n```\n' + messageText.slice(0, 1000) + '\n```\n' }, - ]); - return chatResponse.content?.trim() ?? null; - } catch (error: any) { - console.error('imaginePromptFromText: fetch request error:', error); - return null; - } -} diff --git a/src/common/state/store-settings.ts b/src/common/state/store-settings.ts index 2c6271b58..0b3f477f9 100644 --- a/src/common/state/store-settings.ts +++ b/src/common/state/store-settings.ts @@ -172,6 +172,7 @@ export const useSettingsStore = create()( googleCSEId: '', setGoogleCSEId: (cseId: string) => set({ googleCSEId: cseId }), + }), { name: 'app-settings', diff --git a/src/modules/aifn/autotitle/autoTitle.ts b/src/modules/aifn/autotitle/autoTitle.ts new file mode 100644 index 000000000..cc331fae4 --- /dev/null +++ b/src/modules/aifn/autotitle/autoTitle.ts @@ -0,0 +1,54 @@ +import { callChat } from '~/modules/openai/openai.client'; +import { useModelsStore } from '~/modules/llms/llm.store'; + +import { useChatStore } from '~/common/state/store-chats'; + + +/** + * Creates the AI titles for conversations, by taking the last 5 first-lines and asking AI what's that about + */ +export async function autoTitle(conversationId: string) { + + // external state + const { fastLLMId } = useModelsStore.getState(); + const { conversations } = useChatStore.getState(); + + // only operate on valid conversations, without any title + const conversation = conversations.find(c => c.id === conversationId) ?? null; + if (!fastLLMId || !conversation || conversation.autoTitle || conversation.userTitle) return; + + // first line of the last 5 messages + const historyLines: string[] = conversation.messages.filter(m => m.role !== 'system').slice(-5).map(m => { + let text = m.text.split('\n')[0]; + text = text.length > 50 ? text.substring(0, 50) + '...' : text; + text = `${m.role === 'user' ? 'You' : 'Assistant'}: ${text}`; + return `- ${text}`; + }); + + // LLM + callChat(fastLLMId, [ + { role: 'system', content: `You are an AI conversation titles assistant who specializes in creating expressive yet few-words chat titles.` }, + { + role: 'user', content: + 'Analyze the given short conversation (every line is truncated) and extract a concise chat title that ' + + 'summarizes the conversation in as little as a couple of words.\n' + + 'Only respond with the lowercase short title and nothing else.\n' + + '\n' + + '```\n' + + historyLines.join('\n') + + '```\n', + }, + ]).then(chatResponse => { + + const title = chatResponse?.content + ?.trim() + ?.replaceAll('"', '') + ?.replace('Title: ', '') + ?.replace('title: ', ''); + + if (title) + useChatStore.getState().setAutoTitle(conversationId, title); + + }); + +} \ No newline at end of file diff --git a/src/modules/aifn/imagine/imaginePromptFromText.ts b/src/modules/aifn/imagine/imaginePromptFromText.ts new file mode 100644 index 000000000..7d9901a43 --- /dev/null +++ b/src/modules/aifn/imagine/imaginePromptFromText.ts @@ -0,0 +1,39 @@ +import { callChat } from '~/modules/openai/openai.client'; +import { useModelsStore } from '~/modules/llms/llm.store'; + + +const simpleImagineSystemPrompt = + `As an AI art prompt writer, create captivating prompts using adjectives, nouns, and artistic references that a non-technical person can understand. +Craft creative, coherent and descriptive captions to guide the AI in generating visually striking artwork. +Provide output as a lowercase prompt and nothing else.`; + +/** + * Creates a caption for a drawing or photo given some description - used to elevate the quality of the imaging + */ +export async function imaginePromptFromText(messageText: string): Promise { + const { fastLLMId } = useModelsStore.getState(); + if (!fastLLMId) return null; + try { + const chatResponse = await callChat(fastLLMId, [ + { role: 'system', content: simpleImagineSystemPrompt }, + { role: 'user', content: 'Write a prompt, based on the following input.\n\n```\n' + messageText.slice(0, 1000) + '\n```\n' }, + ]); + return chatResponse.content?.trim() ?? null; + } catch (error: any) { + console.error('imaginePromptFromText: fetch request error:', error); + return null; + } +} + +// https://www.youtube.com/watch?v=XLG-qtZwxIw +/*const promptNext = + 'I want you to act as a prompt engineer. You will help me write prompts for an ai art generator.\n' + + '\n' + + 'I will provide you with short content ideas and your job is to elaborate these into full, detailed, coherent prompts.\n' + + '\n' + + 'Prompts involve describing the content and style of images in concise accurate language. It is useful to be explicit and use references to popular culture, artists and mediums. Your focus needs to be on nouns and adjectives. I will give you some example prompts for your reference. Please define the exact camera that should be used\n' + + '\n' + + 'Here is a formula for you to use(content insert nouns here)(medium: insert artistic medium here)(style: insert references to genres, artists and popular culture here)(lighting, reference the lighting here)(colours reference color styles and palettes here)(composition: reference cameras, specific lenses, shot types and positional elements here)\n' + + '\n' + + 'when giving a prompt remove the brackets, speak in natural language and be more specific, use precise, articulate language.'; +*/ \ No newline at end of file diff --git a/src/common/llm-util/prompts.ts b/src/modules/aifn/prompts.ts similarity index 100% rename from src/common/llm-util/prompts.ts rename to src/modules/aifn/prompts.ts diff --git a/src/common/llm-util/react.ts b/src/modules/aifn/react/react.ts similarity index 98% rename from src/common/llm-util/react.ts rename to src/modules/aifn/react/react.ts index 880a5455b..90422414a 100644 --- a/src/common/llm-util/react.ts +++ b/src/modules/aifn/react/react.ts @@ -1,9 +1,9 @@ +import { DLLMId } from '~/modules/llms/llm.types'; import { OpenAI } from '~/modules/openai/openai.types'; import { callApiSearchGoogle } from '~/modules/search/search.client'; import { callChat } from '~/modules/openai/openai.client'; -import { currentDate, reActPrompt } from './prompts'; -import { DLLMId } from '~/modules/llms/llm.types'; +import { currentDate, reActPrompt } from '../prompts'; const actionRe = /^Action: (\w+): (.*)$/; diff --git a/src/common/llm-util/summerize.ts b/src/modules/aifn/summarize/summerize.ts similarity index 98% rename from src/common/llm-util/summerize.ts rename to src/modules/aifn/summarize/summerize.ts index 41472aa53..612a4202a 100644 --- a/src/common/llm-util/summerize.ts +++ b/src/modules/aifn/summarize/summerize.ts @@ -1,9 +1,9 @@ import { DLLMId } from '~/modules/llms/llm.types'; import { callChat } from '~/modules/openai/openai.client'; - -import { cleanupPrompt } from './prompts'; import { findLLMOrThrow } from '~/modules/llms/llm.store'; +import { cleanupPrompt } from '../prompts'; + function breakDownChunk(chunk: string, targetWordCount: number): string[] { const words = chunk.split(' ');