This commit is contained in:
hailin 2025-06-23 13:21:43 +08:00
parent ea8768003b
commit 0b9998528f
2 changed files with 91 additions and 86 deletions

View File

@ -5,17 +5,40 @@ import {
createStreamableValue, createStreamableValue,
getMutableAIState getMutableAIState
} from 'ai/rsc' } from 'ai/rsc'
import { ExperimentalMessage } from 'ai' import { ExperimentalMessage } from 'ai'
import { Spinner } from '@/components/ui-v2/spinner' import { Spinner } from '@/components/ui-v2/spinner'
import { Section } from '@/components/mpv2/section' import { Section } from '@/components/mpv2/section'
import { FollowupPanel } from '@/components/mpv2/followup-panel' import { FollowupPanel } from '@/components/mpv2/followup-panel'
import { inquire, researcher, taskManager, querySuggestor } from '@/lib/agents' import { inquire, researcher, taskManager, querySuggestor } from '@/lib/agents'
async function submit(formData?: FormData, skip?: boolean) { const initialAIState: {
role: 'user' | 'assistant' | 'system' | 'function' | 'tool'
content: string
id?: string
name?: string
}[] = []
const initialUIState: {
id: number
isGenerating: StreamableValue<boolean>
component: React.ReactNode
}[] = []
// ① 先声明 submit不引用 AI
let submit: any
// ② 先生成 AI再写 submit
export const {
AIProvider,
useAIState,
useUIState,
useActions
} = createAI({
actions: {
submit: async function(formData?: FormData, skip?: boolean) {
'use server' 'use server'
const aiState = getMutableAIState<typeof AI>() const aiState = getMutableAIState<typeof AIProvider>() // 这里用 AIProvider
const uiStream = createStreamableUI() const uiStream = createStreamableUI()
const isGenerating = createStreamableValue(true) const isGenerating = createStreamableValue(true)
@ -55,7 +78,6 @@ async function submit(formData?: FormData, skip?: boolean) {
let answer = '' let answer = ''
let errorOccurred = false let errorOccurred = false
const streamText = createStreamableValue<string>() const streamText = createStreamableValue<string>()
while (answer.length === 0) { while (answer.length === 0) {
const { fullResponse, hasError } = await researcher( const { fullResponse, hasError } = await researcher(
uiStream, uiStream,
@ -65,12 +87,10 @@ async function submit(formData?: FormData, skip?: boolean) {
answer = fullResponse answer = fullResponse
errorOccurred = hasError errorOccurred = hasError
} }
streamText.done() streamText.done()
if (!errorOccurred) { if (!errorOccurred) {
await querySuggestor(uiStream, messages) await querySuggestor(uiStream, messages)
uiStream.append( uiStream.append(
<Section title="Follow-up"> <Section title="Follow-up">
<FollowupPanel /> <FollowupPanel />
@ -90,23 +110,8 @@ async function submit(formData?: FormData, skip?: boolean) {
isGenerating: isGenerating.value, isGenerating: isGenerating.value,
component: uiStream.value component: uiStream.value
} }
} }
},
const initialAIState: ExperimentalMessage[] = [] initialUIState,
initialAIState
const initialUIState: {
id: number
isGenerating: StreamableValue<boolean>
component: React.ReactNode
}[] = []
export const {
AIProvider,
useAIState,
useUIState,
useActions
} = createAI({
actions: { submit },
initialAIState,
initialUIState
}) })

View File

@ -1,6 +1,6 @@
import type { Metadata, Viewport } from 'next' import type { Metadata, Viewport } from 'next'
import { Inter as FontSans } from 'next/font/google' import { Inter as FontSans } from 'next/font/google'
import { AIProvider } from './action' // ⬅️ 正确导入 import { AIProvider } from './action'
import '../../globals.css' import '../../globals.css'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
import { ThemeProvider } from '@/components/mpv2/theme-provider' import { ThemeProvider } from '@/components/mpv2/theme-provider'