feat(AnthropicProvider, MessagesService): Add empty message filtering and stream processing improvements
- Introduce filterEmptyMessages function to remove empty messages - Update AnthropicProvider to use filterEmptyMessages in message preparation - Refactor stream processing with minor improvements and return statement fixes - Simplify tool response and message handling logic
This commit is contained in:
parent
e61618f1b4
commit
632b0c17aa
@ -11,7 +11,11 @@ import { getStoreSetting } from '@renderer/hooks/useSettings'
|
||||
import i18n from '@renderer/i18n'
|
||||
import { getAssistantSettings, getDefaultModel, getTopNamingModel } from '@renderer/services/AssistantService'
|
||||
import { EVENT_NAMES } from '@renderer/services/EventService'
|
||||
import { filterContextMessages, filterUserRoleStartMessages } from '@renderer/services/MessagesService'
|
||||
import {
|
||||
filterContextMessages,
|
||||
filterEmptyMessages,
|
||||
filterUserRoleStartMessages
|
||||
} from '@renderer/services/MessagesService'
|
||||
import { Assistant, FileTypes, MCPToolResponse, Message, Model, Provider, Suggestion } from '@renderer/types'
|
||||
import { removeSpecialCharactersForTopicName } from '@renderer/utils'
|
||||
import { first, flatten, sum, takeRight } from 'lodash'
|
||||
@ -136,7 +140,10 @@ export default class AnthropicProvider extends BaseProvider {
|
||||
const { contextCount, maxTokens, streamOutput } = getAssistantSettings(assistant)
|
||||
|
||||
const userMessagesParams: MessageParam[] = []
|
||||
const _messages = filterUserRoleStartMessages(filterContextMessages(takeRight(messages, contextCount + 2)))
|
||||
|
||||
const _messages = filterUserRoleStartMessages(
|
||||
filterContextMessages(filterEmptyMessages(takeRight(messages, contextCount + 2)))
|
||||
)
|
||||
|
||||
onFilterMessages(_messages)
|
||||
|
||||
@ -200,8 +207,9 @@ export default class AnthropicProvider extends BaseProvider {
|
||||
const { abortController, cleanup } = this.createAbortController(lastUserMessage?.id)
|
||||
const { signal } = abortController
|
||||
const toolResponses: MCPToolResponse[] = []
|
||||
|
||||
const processStream = async (body: MessageCreateParamsNonStreaming) => {
|
||||
new Promise<void>((resolve, reject) => {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
const toolCalls: ToolUseBlock[] = []
|
||||
let hasThinkingContent = false
|
||||
const stream = this.sdk.messages
|
||||
@ -211,6 +219,7 @@ export default class AnthropicProvider extends BaseProvider {
|
||||
stream.controller.abort()
|
||||
return resolve()
|
||||
}
|
||||
|
||||
if (time_first_token_millsec == 0) {
|
||||
time_first_token_millsec = new Date().getTime() - start_time_millsec
|
||||
}
|
||||
@ -224,6 +233,7 @@ export default class AnthropicProvider extends BaseProvider {
|
||||
: 0
|
||||
|
||||
const time_completion_millsec = new Date().getTime() - start_time_millsec
|
||||
|
||||
onChunk({
|
||||
text,
|
||||
metrics: {
|
||||
@ -236,11 +246,13 @@ export default class AnthropicProvider extends BaseProvider {
|
||||
})
|
||||
.on('thinking', (thinking) => {
|
||||
hasThinkingContent = true
|
||||
|
||||
if (time_first_token_millsec == 0) {
|
||||
time_first_token_millsec = new Date().getTime() - start_time_millsec
|
||||
}
|
||||
|
||||
const time_completion_millsec = new Date().getTime() - start_time_millsec
|
||||
|
||||
onChunk({
|
||||
reasoning_content: thinking,
|
||||
text: '',
|
||||
@ -262,30 +274,10 @@ export default class AnthropicProvider extends BaseProvider {
|
||||
for (const toolCall of toolCalls) {
|
||||
const mcpTool = anthropicToolUseToMcpTool(mcpTools, toolCall)
|
||||
if (mcpTool) {
|
||||
upsertMCPToolResponse(
|
||||
toolResponses,
|
||||
{
|
||||
tool: mcpTool,
|
||||
status: 'invoking'
|
||||
},
|
||||
onChunk
|
||||
)
|
||||
|
||||
upsertMCPToolResponse(toolResponses, { tool: mcpTool, status: 'invoking' }, onChunk)
|
||||
const resp = await callMCPTool(mcpTool)
|
||||
toolCallResults.push({
|
||||
type: 'tool_result',
|
||||
tool_use_id: toolCall.id,
|
||||
content: resp.content
|
||||
})
|
||||
upsertMCPToolResponse(
|
||||
toolResponses,
|
||||
{
|
||||
tool: mcpTool,
|
||||
status: 'done',
|
||||
response: resp
|
||||
},
|
||||
onChunk
|
||||
)
|
||||
toolCallResults.push({ type: 'tool_result', tool_use_id: toolCall.id, content: resp.content })
|
||||
upsertMCPToolResponse(toolResponses, { tool: mcpTool, status: 'done', response: resp }, onChunk)
|
||||
}
|
||||
}
|
||||
|
||||
@ -294,6 +286,7 @@ export default class AnthropicProvider extends BaseProvider {
|
||||
role: message.role,
|
||||
content: message.content
|
||||
})
|
||||
|
||||
userMessages.push({
|
||||
role: 'user',
|
||||
content: toolCallResults
|
||||
@ -301,6 +294,7 @@ export default class AnthropicProvider extends BaseProvider {
|
||||
|
||||
const newBody = body
|
||||
body.messages = userMessages
|
||||
|
||||
await processStream(newBody)
|
||||
}
|
||||
}
|
||||
@ -309,6 +303,7 @@ export default class AnthropicProvider extends BaseProvider {
|
||||
const time_thinking_millsec = time_first_content_millsec
|
||||
? time_first_content_millsec - start_time_millsec
|
||||
: 0
|
||||
|
||||
onChunk({
|
||||
text: '',
|
||||
usage: {
|
||||
@ -324,6 +319,7 @@ export default class AnthropicProvider extends BaseProvider {
|
||||
},
|
||||
mcpToolResponse: toolResponses
|
||||
})
|
||||
|
||||
resolve()
|
||||
})
|
||||
.on('error', (error) => reject(error))
|
||||
|
||||
@ -39,6 +39,19 @@ export function filterUserRoleStartMessages(messages: Message[]): Message[] {
|
||||
return messages.slice(firstUserMessageIndex)
|
||||
}
|
||||
|
||||
export function filterEmptyMessages(messages: Message[]): Message[] {
|
||||
return messages.filter((message) => {
|
||||
const content = message.content as string | any[]
|
||||
if (typeof content === 'string') {
|
||||
return !isEmpty(content.trim())
|
||||
}
|
||||
if (Array.isArray(content)) {
|
||||
return content.some((c) => !isEmpty(c.text.trim()))
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
export function filterUsefulMessages(messages: Message[]): Message[] {
|
||||
const _messages = messages
|
||||
const groupedMessages = getGroupedMessages(messages)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user