mirror of
https://github.com/langgenius/dify.git
synced 2026-08-02 10:46:38 +08:00
143 lines
4.7 KiB
TypeScript
143 lines
4.7 KiB
TypeScript
'use client'
|
|
|
|
import type { AgentIconType, AgentSoulConfig } from '@dify/contracts/api/console/agent/types.gen'
|
|
import type { ReactNode } from 'react'
|
|
import { skipToken, useQuery } from '@tanstack/react-query'
|
|
import { useCallback, useEffect, useMemo, useState } from 'react'
|
|
import Loading from '@/app/components/base/loading'
|
|
import { consoleQuery } from '@/service/client'
|
|
import { getFormattedAgentDebugChatTree, getLastWorkflowRunId } from './chat-history'
|
|
import { AgentPreviewChatSession } from './chat-session'
|
|
|
|
export type AgentChatRuntimeEmptyStateProps = {
|
|
agentIcon?: string | null
|
|
agentIconBackground?: string | null
|
|
agentIconType?: AgentIconType | null
|
|
agentName?: string
|
|
hasInstructions: boolean
|
|
}
|
|
|
|
export type AgentChatRuntimeProps = {
|
|
agentId: string
|
|
agentIcon?: string | null
|
|
agentIconBackground?: string | null
|
|
agentIconType?: AgentIconType | null
|
|
agentName?: string
|
|
agentSoulConfig?: AgentSoulConfig
|
|
clearChatList: boolean
|
|
conversationId?: string | null
|
|
draftType?: 'debug_build'
|
|
inputPlaceholder: string
|
|
inputAutoFocus?: boolean
|
|
sendButtonLabel?: string
|
|
renderEmptyState: (props: AgentChatRuntimeEmptyStateProps) => ReactNode
|
|
onClearChatListChange: (clearChatList: boolean) => void
|
|
onConversationComplete?: (conversationId: string, workflowRunId?: string) => void
|
|
onConversationIdChange?: (conversationId: string) => void
|
|
onWorkflowRunIdChange?: (workflowRunId: string | null) => void
|
|
onBeforeSpeechToText?: () => Promise<unknown>
|
|
onSaveDraftBeforeRun?: () => Promise<AgentSoulConfig | void>
|
|
onSendInterrupted?: () => void
|
|
}
|
|
|
|
export function AgentChatRuntime({
|
|
agentId,
|
|
agentIcon,
|
|
agentIconBackground,
|
|
agentIconType,
|
|
agentName,
|
|
agentSoulConfig,
|
|
clearChatList,
|
|
conversationId,
|
|
draftType,
|
|
inputPlaceholder,
|
|
inputAutoFocus,
|
|
sendButtonLabel,
|
|
renderEmptyState,
|
|
onClearChatListChange,
|
|
onConversationComplete,
|
|
onConversationIdChange,
|
|
onWorkflowRunIdChange,
|
|
onBeforeSpeechToText,
|
|
onSendInterrupted,
|
|
onSaveDraftBeforeRun,
|
|
}: AgentChatRuntimeProps) {
|
|
const [currentSessionConversationId, setCurrentSessionConversationId] = useState<string | null>(
|
|
null,
|
|
)
|
|
const handleClearChatListChange = useCallback(
|
|
(nextClearChatList: boolean) => {
|
|
if (!nextClearChatList) setCurrentSessionConversationId(null)
|
|
onClearChatListChange(nextClearChatList)
|
|
},
|
|
[onClearChatListChange],
|
|
)
|
|
const historyQuery = useQuery(
|
|
consoleQuery.agent.byAgentId.chatMessages.get.queryOptions({
|
|
input: conversationId
|
|
? {
|
|
params: {
|
|
agent_id: agentId,
|
|
},
|
|
query: {
|
|
conversation_id: conversationId,
|
|
},
|
|
}
|
|
: skipToken,
|
|
}),
|
|
)
|
|
const conversationBelongsToCurrentSession =
|
|
!!conversationId && conversationId === currentSessionConversationId
|
|
const initialChatTree = useMemo(
|
|
() => getFormattedAgentDebugChatTree(historyQuery.data?.data ?? []),
|
|
[historyQuery.data?.data],
|
|
)
|
|
useEffect(() => {
|
|
if (!conversationId || !historyQuery.data) return
|
|
|
|
onWorkflowRunIdChange?.(getLastWorkflowRunId(historyQuery.data.data ?? []))
|
|
}, [conversationId, historyQuery.data, onWorkflowRunIdChange])
|
|
|
|
if (conversationId && historyQuery.isPending && !conversationBelongsToCurrentSession) {
|
|
return (
|
|
<div className="flex h-full items-center justify-center">
|
|
<Loading type="app" />
|
|
</div>
|
|
)
|
|
}
|
|
const inputSessionKey =
|
|
!conversationId || conversationBelongsToCurrentSession ? 'current-session' : conversationId
|
|
const conversationSessionKey =
|
|
!conversationId || conversationBelongsToCurrentSession
|
|
? 'current-session'
|
|
: `${conversationId}-${historyQuery.dataUpdatedAt}`
|
|
|
|
return (
|
|
<AgentPreviewChatSession
|
|
key={inputSessionKey}
|
|
conversationSessionKey={conversationSessionKey}
|
|
agentId={agentId}
|
|
agentIcon={agentIcon}
|
|
agentIconBackground={agentIconBackground}
|
|
agentIconType={agentIconType}
|
|
agentName={agentName}
|
|
agentSoulConfig={agentSoulConfig}
|
|
clearChatList={clearChatList}
|
|
conversationId={conversationId}
|
|
draftType={draftType}
|
|
initialChatTree={initialChatTree}
|
|
inputPlaceholder={inputPlaceholder}
|
|
inputAutoFocus={inputAutoFocus}
|
|
sendButtonLabel={sendButtonLabel}
|
|
renderEmptyState={renderEmptyState}
|
|
onClearChatListChange={handleClearChatListChange}
|
|
onConversationComplete={onConversationComplete}
|
|
onConversationIdChange={onConversationIdChange}
|
|
onCurrentSessionConversationIdChange={setCurrentSessionConversationId}
|
|
onBeforeSpeechToText={onBeforeSpeechToText}
|
|
onSendInterrupted={onSendInterrupted}
|
|
onSaveDraftBeforeRun={onSaveDraftBeforeRun}
|
|
/>
|
|
)
|
|
}
|