This commit is contained in:
parent
ea8768003b
commit
0b9998528f
|
|
@ -5,94 +5,18 @@ import {
|
|||
createStreamableValue,
|
||||
getMutableAIState
|
||||
} from 'ai/rsc'
|
||||
|
||||
import { ExperimentalMessage } from 'ai'
|
||||
import { Spinner } from '@/components/ui-v2/spinner'
|
||||
import { Section } from '@/components/mpv2/section'
|
||||
import { FollowupPanel } from '@/components/mpv2/followup-panel'
|
||||
import { inquire, researcher, taskManager, querySuggestor } from '@/lib/agents'
|
||||
|
||||
async function submit(formData?: FormData, skip?: boolean) {
|
||||
'use server'
|
||||
|
||||
const aiState = getMutableAIState<typeof AI>()
|
||||
const uiStream = createStreamableUI()
|
||||
const isGenerating = createStreamableValue(true)
|
||||
|
||||
const messages: ExperimentalMessage[] = aiState.get() as any
|
||||
const userInput = skip
|
||||
? `{"action": "skip"}`
|
||||
: (formData?.get('input') as string)
|
||||
const content = skip
|
||||
? userInput
|
||||
: formData
|
||||
? JSON.stringify(Object.fromEntries(formData))
|
||||
: null
|
||||
|
||||
if (content) {
|
||||
const message = { role: 'user', content }
|
||||
messages.push(message as ExperimentalMessage)
|
||||
aiState.update([...(aiState.get() as any), message])
|
||||
}
|
||||
|
||||
async function processEvents() {
|
||||
uiStream.update(<Spinner />)
|
||||
|
||||
let action: any = { object: { next: 'proceed' } }
|
||||
if (!skip) action = await taskManager(messages)
|
||||
|
||||
if (action.object.next === 'inquire') {
|
||||
const inquiry = await inquire(uiStream, messages)
|
||||
uiStream.done()
|
||||
isGenerating.done()
|
||||
aiState.done([
|
||||
...aiState.get(),
|
||||
{ role: 'assistant', content: `inquiry: ${inquiry?.question}` }
|
||||
])
|
||||
return
|
||||
}
|
||||
|
||||
let answer = ''
|
||||
let errorOccurred = false
|
||||
const streamText = createStreamableValue<string>()
|
||||
|
||||
while (answer.length === 0) {
|
||||
const { fullResponse, hasError } = await researcher(
|
||||
uiStream,
|
||||
streamText,
|
||||
messages
|
||||
)
|
||||
answer = fullResponse
|
||||
errorOccurred = hasError
|
||||
}
|
||||
|
||||
streamText.done()
|
||||
|
||||
if (!errorOccurred) {
|
||||
await querySuggestor(uiStream, messages)
|
||||
|
||||
uiStream.append(
|
||||
<Section title="Follow-up">
|
||||
<FollowupPanel />
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
|
||||
isGenerating.done(false)
|
||||
uiStream.done()
|
||||
aiState.done([...aiState.get(), { role: 'assistant', content: answer }])
|
||||
}
|
||||
|
||||
processEvents()
|
||||
|
||||
return {
|
||||
id: Date.now(),
|
||||
isGenerating: isGenerating.value,
|
||||
component: uiStream.value
|
||||
}
|
||||
}
|
||||
|
||||
const initialAIState: ExperimentalMessage[] = []
|
||||
const initialAIState: {
|
||||
role: 'user' | 'assistant' | 'system' | 'function' | 'tool'
|
||||
content: string
|
||||
id?: string
|
||||
name?: string
|
||||
}[] = []
|
||||
|
||||
const initialUIState: {
|
||||
id: number
|
||||
|
|
@ -100,13 +24,94 @@ const initialUIState: {
|
|||
component: React.ReactNode
|
||||
}[] = []
|
||||
|
||||
// ① 先声明 submit(不引用 AI)
|
||||
let submit: any
|
||||
|
||||
// ② 先生成 AI,再写 submit
|
||||
export const {
|
||||
AIProvider,
|
||||
useAIState,
|
||||
useUIState,
|
||||
useActions
|
||||
} = createAI({
|
||||
actions: { submit },
|
||||
initialAIState,
|
||||
initialUIState
|
||||
actions: {
|
||||
submit: async function(formData?: FormData, skip?: boolean) {
|
||||
'use server'
|
||||
|
||||
const aiState = getMutableAIState<typeof AIProvider>() // 这里用 AIProvider
|
||||
const uiStream = createStreamableUI()
|
||||
const isGenerating = createStreamableValue(true)
|
||||
|
||||
const messages: ExperimentalMessage[] = aiState.get() as any
|
||||
const userInput = skip
|
||||
? `{"action": "skip"}`
|
||||
: (formData?.get('input') as string)
|
||||
const content = skip
|
||||
? userInput
|
||||
: formData
|
||||
? JSON.stringify(Object.fromEntries(formData))
|
||||
: null
|
||||
|
||||
if (content) {
|
||||
const message = { role: 'user', content }
|
||||
messages.push(message as ExperimentalMessage)
|
||||
aiState.update([...(aiState.get() as any), message])
|
||||
}
|
||||
|
||||
async function processEvents() {
|
||||
uiStream.update(<Spinner />)
|
||||
|
||||
let action: any = { object: { next: 'proceed' } }
|
||||
if (!skip) action = await taskManager(messages)
|
||||
|
||||
if (action.object.next === 'inquire') {
|
||||
const inquiry = await inquire(uiStream, messages)
|
||||
uiStream.done()
|
||||
isGenerating.done()
|
||||
aiState.done([
|
||||
...aiState.get(),
|
||||
{ role: 'assistant', content: `inquiry: ${inquiry?.question}` }
|
||||
])
|
||||
return
|
||||
}
|
||||
|
||||
let answer = ''
|
||||
let errorOccurred = false
|
||||
const streamText = createStreamableValue<string>()
|
||||
while (answer.length === 0) {
|
||||
const { fullResponse, hasError } = await researcher(
|
||||
uiStream,
|
||||
streamText,
|
||||
messages
|
||||
)
|
||||
answer = fullResponse
|
||||
errorOccurred = hasError
|
||||
}
|
||||
streamText.done()
|
||||
|
||||
if (!errorOccurred) {
|
||||
await querySuggestor(uiStream, messages)
|
||||
uiStream.append(
|
||||
<Section title="Follow-up">
|
||||
<FollowupPanel />
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
|
||||
isGenerating.done(false)
|
||||
uiStream.done()
|
||||
aiState.done([...aiState.get(), { role: 'assistant', content: answer }])
|
||||
}
|
||||
|
||||
processEvents()
|
||||
|
||||
return {
|
||||
id: Date.now(),
|
||||
isGenerating: isGenerating.value,
|
||||
component: uiStream.value
|
||||
}
|
||||
}
|
||||
},
|
||||
initialUIState,
|
||||
initialAIState
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import type { Metadata, Viewport } from 'next'
|
||||
import { Inter as FontSans } from 'next/font/google'
|
||||
import { AIProvider } from './action' // ⬅️ 正确导入
|
||||
import { AIProvider } from './action'
|
||||
import '../../globals.css'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { ThemeProvider } from '@/components/mpv2/theme-provider'
|
||||
|
|
|
|||
Loading…
Reference in New Issue