wip, changing the logic in useStreamResponse
This commit is contained in:
parent
6429f48763
commit
022747ba04
3 changed files with 35 additions and 63 deletions
|
|
@ -115,10 +115,6 @@ export const useStreamResponse = ({
|
|||
const streamResponse = async (messages: Message[]) => {
|
||||
let aiResponse = ''
|
||||
let currentReasoning = ''
|
||||
let currentReasoningStartTime: number | undefined = undefined
|
||||
let currentReasoningEndTime: number | undefined = undefined
|
||||
let assistantMessageIndex = -1 // Track the index of our assistant message
|
||||
let assistantMessageCreated = false // Track if we've created the assistant message yet
|
||||
|
||||
// Check if API key is available
|
||||
let apiKey = getApiKey(selectedModel.provider.id)
|
||||
|
|
@ -165,51 +161,38 @@ export const useStreamResponse = ({
|
|||
console.log(JSON.stringify(event))
|
||||
try {
|
||||
if (event.type === 'reasoning') {
|
||||
// Track reasoning start time and create assistant message if needed
|
||||
if (!currentReasoningStartTime) {
|
||||
currentReasoningStartTime = Date.now()
|
||||
currentReasoning = '' // Reset reasoning content for new session
|
||||
setConversations((prev) => {
|
||||
const updated = [...prev]
|
||||
const conv = updated.find((c) => c.id === conversationId)
|
||||
if (!conv) {
|
||||
console.error(`Missing conversation for ID ${conversationId}! Ignoring ${JSON.stringify(event)}`)
|
||||
return updated
|
||||
}
|
||||
const lastMessage = conv.messages?.at(-1)
|
||||
|
||||
// Create a new assistant message for reasoning (even if we already have one)
|
||||
// This handles multiple reasoning sessions in the same conversation turn
|
||||
setConversations((prev) => {
|
||||
const updated = [...prev]
|
||||
const conv = updated.find((c) => c.id === conversationId)
|
||||
if (lastMessage?.role === 'assistant' && lastMessage.type === 'reasoning') {
|
||||
// We have an existing reasoning block!
|
||||
lastMessage.content = lastMessage.content + event.textDelta.trim()
|
||||
} else {
|
||||
// We need a new reasoning block!
|
||||
const currentReasoningStartTime = Date.now()
|
||||
|
||||
// Create a new assistant message for reasoning (even if we already have one)
|
||||
// This handles multiple reasoning sessions in the same conversation turn
|
||||
if (conv) {
|
||||
conv.messages.push({
|
||||
role: 'assistant',
|
||||
content: '',
|
||||
reasoning: '',
|
||||
type: 'reasoning',
|
||||
content: event.textDelta.trim(),
|
||||
isReasoningStreaming: true,
|
||||
reasoningStartTime: currentReasoningStartTime,
|
||||
reasoningStartTime: currentReasoningStartTime!,
|
||||
})
|
||||
assistantMessageIndex = conv.messages.length - 1
|
||||
debugMessages('Added new reasoning assistant message at index', assistantMessageIndex)
|
||||
debugMessages('Added new reasoning assistant message at index', conv.messages.length - 1)
|
||||
debugMessages('Current messages:', JSON.stringify(conv.messages))
|
||||
}
|
||||
return updated
|
||||
})
|
||||
assistantMessageCreated = true
|
||||
}
|
||||
|
||||
currentReasoning += (event as any).textDelta || ''
|
||||
|
||||
// Update the assistant message with streaming reasoning in real-time
|
||||
if (assistantMessageCreated) {
|
||||
setConversations((prev) => {
|
||||
const updated = [...prev]
|
||||
const conv = updated.find((c) => c.id === conversationId)
|
||||
if (conv && assistantMessageIndex >= 0) {
|
||||
const assistantMessage = conv.messages[assistantMessageIndex]
|
||||
if (assistantMessage && hasContent(assistantMessage) && assistantMessage.role === 'assistant') {
|
||||
assistantMessage.reasoning = currentReasoning.trim()
|
||||
assistantMessage.isReasoningStreaming = true
|
||||
assistantMessage.reasoningStartTime = currentReasoningStartTime
|
||||
}
|
||||
}
|
||||
return updated
|
||||
})
|
||||
}
|
||||
}
|
||||
return updated
|
||||
})
|
||||
} else if (event.type === 'tool-call') {
|
||||
// End reasoning phase immediately when we see a tool call for linear flow
|
||||
if (currentReasoningStartTime && !currentReasoningEndTime) {
|
||||
|
|
@ -345,21 +328,6 @@ export const useStreamResponse = ({
|
|||
aiResponse = aiResponse.replace(/<chat-title>.*?<\/chat-title>/, '').trim()
|
||||
}
|
||||
|
||||
// Remove thinking tags from the display text (they should be extracted by middleware)
|
||||
let cleanedResponse = aiResponse
|
||||
if (supportsReasoning(selectedModel)) {
|
||||
// Remove complete thinking blocks
|
||||
cleanedResponse = aiResponse.replace(/<think>[\s\S]*?<\/think>/g, '').trim()
|
||||
// Remove unclosed think tags (everything from <think> to end)
|
||||
cleanedResponse = cleanedResponse.replace(/<think>[\s\S]*$/g, '').trim()
|
||||
// Remove any remaining opening think tags
|
||||
cleanedResponse = cleanedResponse.replace(/<think>/g, '').trim()
|
||||
// Remove any remaining closing think tags
|
||||
cleanedResponse = cleanedResponse.replace(/<\/think>/g, '').trim()
|
||||
// Clean up any remaining whitespace or newlines at the start
|
||||
cleanedResponse = cleanedResponse.replace(/^\s+/, '')
|
||||
}
|
||||
|
||||
setConversations((prev) => {
|
||||
const updated = [...prev]
|
||||
const conv = updated.find((c) => c.id === conversationId)
|
||||
|
|
@ -367,8 +335,7 @@ export const useStreamResponse = ({
|
|||
// Update the specific assistant message we created, not just the last message
|
||||
const assistantMessage = conv.messages[assistantMessageIndex]
|
||||
if (assistantMessage && hasContent(assistantMessage) && assistantMessage.role === 'assistant') {
|
||||
assistantMessage.content = cleanedResponse
|
||||
} else {
|
||||
assistantMessage.content = aiResponse
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,10 +12,15 @@ export interface SystemMessage extends BaseMessage {
|
|||
|
||||
export interface AssistantMessage extends BaseMessage {
|
||||
role: 'assistant'
|
||||
reasoning?: string
|
||||
reasoningStartTime?: number
|
||||
type: 'content'
|
||||
}
|
||||
|
||||
export interface AssistantReasoningMessage extends BaseMessage {
|
||||
role: 'assistant'
|
||||
type: 'reasoning'
|
||||
reasoningStartTime: number
|
||||
reasoningEndTime?: number
|
||||
isReasoningStreaming?: boolean
|
||||
isReasoningStreaming: boolean
|
||||
}
|
||||
|
||||
export interface ToolCallMessage {
|
||||
|
|
@ -33,7 +38,7 @@ export interface ToolResultMessage {
|
|||
callId: string
|
||||
}
|
||||
|
||||
export type Message = UserMessage | SystemMessage | AssistantMessage | ToolCallMessage | ToolResultMessage
|
||||
export type Message = UserMessage | SystemMessage | AssistantMessage | AssistantReasoningMessage | ToolCallMessage | ToolResultMessage
|
||||
|
||||
export interface Conversation {
|
||||
id?: number
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||
"target": "ES2020",
|
||||
"useDefineForClassFields": true,
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
||||
"module": "ESNext",
|
||||
"skipLibCheck": true,
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue