From d22a1fbb6bdc5860e2732bcc0136759b05ae1a9a Mon Sep 17 00:00:00 2001 From: hailin Date: Mon, 23 Jun 2025 13:01:24 +0800 Subject: [PATCH] . --- apps/blogai/app/[locale]/morphic/action.tsx | 73 ++++++--------------- 1 file changed, 20 insertions(+), 53 deletions(-) diff --git a/apps/blogai/app/[locale]/morphic/action.tsx b/apps/blogai/app/[locale]/morphic/action.tsx index 7cda0f9..122ad51 100644 --- a/apps/blogai/app/[locale]/morphic/action.tsx +++ b/apps/blogai/app/[locale]/morphic/action.tsx @@ -11,6 +11,25 @@ import { Section } from '@/components/mpv2/section' import { FollowupPanel } from '@/components/mpv2/followup-panel' import { inquire, researcher, taskManager, querySuggestor } from '@/lib/agents' +// ✅ 初始状态 +const initialAIState: ExperimentalMessage[] = [] + +const initialUIState: { + id: number + isGenerating: StreamableValue + component: React.ReactNode +}[] = [] + +// ✅ 先创建 AI +export const AI = createAI({ + actions: { + submit + }, + initialUIState, + initialAIState +}) + +// ✅ 再定义 submit,才能引用 AI async function submit(formData?: FormData, skip?: boolean) { 'use server' @@ -19,7 +38,6 @@ async function submit(formData?: FormData, skip?: boolean) { const isGenerating = createStreamableValue(true) const messages: ExperimentalMessage[] = aiState.get() as any - // Get the user input from the form data const userInput = skip ? `{"action": "skip"}` : (formData?.get('input') as string) @@ -28,7 +46,7 @@ async function submit(formData?: FormData, skip?: boolean) { : formData ? JSON.stringify(Object.fromEntries(formData)) : null - // Add the user message to the state + if (content) { const message = { role: 'user', content } messages.push(message as ExperimentalMessage) @@ -39,11 +57,9 @@ async function submit(formData?: FormData, skip?: boolean) { uiStream.update() let action: any = { object: { next: 'proceed' } } - // If the user skips the task, we proceed to the search if (!skip) action = await taskManager(messages) if (action.object.next === 'inquire') { - // Generate inquiry const inquiry = await inquire(uiStream, messages) uiStream.done() @@ -55,12 +71,10 @@ async function submit(formData?: FormData, skip?: boolean) { return } - // Generate the answer let answer = '' let errorOccurred = false const streamText = createStreamableValue() while (answer.length === 0) { - // Search the web and generate the answer const { fullResponse, hasError } = await researcher( uiStream, streamText, @@ -72,10 +86,7 @@ async function submit(formData?: FormData, skip?: boolean) { streamText.done() if (!errorOccurred) { - // Generate related queries await querySuggestor(uiStream, messages) - - // Add follow-up panel uiStream.append(
@@ -96,47 +107,3 @@ async function submit(formData?: FormData, skip?: boolean) { component: uiStream.value } } - -// Define the initial state of the AI. It can be any JSON object. -const initialAIState: { - role: 'user' | 'assistant' | 'system' | 'function' | 'tool' - content: string - id?: string - name?: string -}[] = [] - -// The initial UI state that the client will keep track of, which contains the message IDs and their UI nodes. -const initialUIState: { - id: number - isGenerating: StreamableValue - component: React.ReactNode -}[] = [] - -// AI is a provider you wrap your application with so you can access AI and UI state in your components. -// export const AI = createAI({ -// actions: { -// submit -// }, -// // Each state can be any shape of object, but for chat applications -// // it makes sense to have an array of messages. Or you may prefer something like { id: number, messages: Message[] } -// initialUIState, -// initialAIState -// }) - -// ✅ 第一步:先创建 AI -const AI = createAI({ - actions: { submit }, - initialUIState, - initialAIState -}) - -// ✅ 第二步:解构出 Provider 和 hooks -export const { - AIProvider, - useUIState, - useAIState, - useActions -} = AI - -// ✅ 第三步:导出 AI 给 getMutableAIState 用 -export { AI } \ No newline at end of file