fix: 网页端Anthropic Claude对话格式去除system角色,改为assistant角色

This commit is contained in:
Gsh
2026-02-07 01:17:51 +08:00
parent 57b03436f3
commit 4133b80d49
2 changed files with 36 additions and 23 deletions

View File

@@ -1,12 +1,13 @@
import { useHookFetch } from 'hook-fetch/vue';
import { ElMessage } from 'element-plus';
import { ref, computed } from 'vue';
import type { AnyObject } from 'typescript-api-pro'; import type { AnyObject } from 'typescript-api-pro';
import { deleteMessages, unifiedSend } from '@/api';
import { useModelStore } from '@/stores/modules/model';
import { convertToApiFormat, parseStreamChunk, type UnifiedMessage } from '@/utils/apiFormatConverter';
import type { BubbleProps } from 'vue-element-plus-x/types/Bubble'; import type { BubbleProps } from 'vue-element-plus-x/types/Bubble';
import type { ThinkingStatus } from 'vue-element-plus-x/types/Thinking'; import type { ThinkingStatus } from 'vue-element-plus-x/types/Thinking';
import type { UnifiedMessage } from '@/utils/apiFormatConverter';
import { ElMessage } from 'element-plus';
import { useHookFetch } from 'hook-fetch/vue';
import { ref } from 'vue';
import { unifiedSend } from '@/api';
import { useModelStore } from '@/stores/modules/model';
import { convertToApiFormat, parseStreamChunk } from '@/utils/apiFormatConverter';
export type MessageRole = 'ai' | 'user' | 'assistant' | string; export type MessageRole = 'ai' | 'user' | 'assistant' | string;
@@ -83,7 +84,8 @@ export function useChatSender(options: UseChatSenderOptions) {
); );
const latest = messages[messages.length - 1]; const latest = messages[messages.length - 1];
if (!latest) return; if (!latest)
return;
// 处理 token 使用情况 // 处理 token 使用情况
if (parsed.usage) { if (parsed.usage) {
@@ -99,7 +101,8 @@ export function useChatSender(options: UseChatSenderOptions) {
latest.thinkingStatus = 'thinking'; latest.thinkingStatus = 'thinking';
latest.loading = true; latest.loading = true;
latest.thinlCollapse = true; latest.thinlCollapse = true;
if (!latest.reasoning_content) latest.reasoning_content = ''; if (!latest.reasoning_content)
latest.reasoning_content = '';
latest.reasoning_content += parsed.reasoning_content; latest.reasoning_content += parsed.reasoning_content;
} }
@@ -108,21 +111,26 @@ export function useChatSender(options: UseChatSenderOptions) {
const thinkStart = parsed.content.includes('<think>'); const thinkStart = parsed.content.includes('<think>');
const thinkEnd = parsed.content.includes('</think>'); const thinkEnd = parsed.content.includes('</think>');
if (thinkStart) isThinking.value = true; if (thinkStart)
if (thinkEnd) isThinking.value = false; isThinking.value = true;
if (thinkEnd)
isThinking.value = false;
if (isThinking.value) { if (isThinking.value) {
latest.thinkingStatus = 'thinking'; latest.thinkingStatus = 'thinking';
latest.loading = true; latest.loading = true;
latest.thinlCollapse = true; latest.thinlCollapse = true;
if (!latest.reasoning_content) latest.reasoning_content = ''; if (!latest.reasoning_content)
latest.reasoning_content = '';
latest.reasoning_content += parsed.content latest.reasoning_content += parsed.content
.replace('<think>', '') .replace('<think>', '')
.replace('</think>', ''); .replace('</think>', '');
} else { }
else {
latest.thinkingStatus = 'end'; latest.thinkingStatus = 'end';
latest.loading = false; latest.loading = false;
if (!latest.content) latest.content = ''; if (!latest.content)
latest.content = '';
latest.content += parsed.content; latest.content += parsed.content;
} }
} }
@@ -144,7 +152,8 @@ export function useChatSender(options: UseChatSenderOptions) {
textFiles: any[], textFiles: any[],
onUpdate: (messages: MessageItem[]) => void, onUpdate: (messages: MessageItem[]) => void,
): Promise<void> { ): Promise<void> {
if (isSending.value) return; if (isSending.value)
return;
isSending.value = true; isSending.value = true;
currentRequestApiType.value = modelStore.currentModelInfo.modelApiType || 'Completions'; currentRequestApiType.value = modelStore.currentModelInfo.modelApiType || 'Completions';
@@ -207,7 +216,8 @@ export function useChatSender(options: UseChatSenderOptions) {
fileContent += `<FILE_NAME>${fileItem.name}</FILE_NAME>\n`; fileContent += `<FILE_NAME>${fileItem.name}</FILE_NAME>\n`;
fileContent += `<FILE_CONTENT>\n${fileItem.fileContent}\n</FILE_CONTENT>\n`; fileContent += `<FILE_CONTENT>\n${fileItem.fileContent}\n</FILE_CONTENT>\n`;
fileContent += `</ATTACHMENT_FILE>\n`; fileContent += `</ATTACHMENT_FILE>\n`;
if (index < textFiles.length - 1) fileContent += '\n'; if (index < textFiles.length - 1)
fileContent += '\n';
}); });
contentArray.push({ type: 'text', text: fileContent }); contentArray.push({ type: 'text', text: fileContent });
} }
@@ -225,7 +235,8 @@ export function useChatSender(options: UseChatSenderOptions) {
baseMessage.content = contentArray.length > 1 || imageFiles.length > 0 || textFiles.length > 0 baseMessage.content = contentArray.length > 1 || imageFiles.length > 0 || textFiles.length > 0
? contentArray ? contentArray
: item.content; : item.content;
} else { }
else {
baseMessage.content = (item.role === 'ai' || item.role === 'assistant') && item.content.length > 10000 baseMessage.content = (item.role === 'ai' || item.role === 'assistant') && item.content.length > 10000
? `${item.content.substring(0, 10000)}...(内容过长,已省略)` ? `${item.content.substring(0, 10000)}...(内容过长,已省略)`
: item.content; : item.content;

View File

@@ -127,18 +127,20 @@ export function toResponsesFormat(messages: UnifiedMessage[]): ResponsesMessage[
* 将统一格式的消息转换为 Anthropic Claude 格式 * 将统一格式的消息转换为 Anthropic Claude 格式
*/ */
export function toClaudeFormat(messages: UnifiedMessage[]): { messages: ClaudeMessage[]; system?: string } { export function toClaudeFormat(messages: UnifiedMessage[]): { messages: ClaudeMessage[]; system?: string } {
let systemPrompt: string | undefined;
const claudeMessages: ClaudeMessage[] = []; const claudeMessages: ClaudeMessage[] = [];
for (const msg of messages) { for (const msg of messages) {
// Claude 的 system 消息需要单独提取 // system 消息转换为 assistant 角色放入 messages 数组
let role: 'user' | 'assistant';
if (msg.role === 'system') { if (msg.role === 'system') {
msg.role = 'assistant'; role = 'assistant';
// systemPrompt = typeof msg.content === 'string' ? msg.content : msg.content.map(c => c.text || '').join(''); }
// continue; else if (msg.role === 'model') {
role = 'assistant';
}
else {
role = msg.role as 'user' | 'assistant';
} }
const role = msg.role === 'model' ? 'assistant' : msg.role;
// 处理内容格式 // 处理内容格式
let content: string | ClaudeContent[]; let content: string | ClaudeContent[];