在uni-app项目中使用 @coze/uniapp-api 0.3.1 版本,编译成微信小程序
遇到的问题:
流式接口返回内容时间过长时,接口直接 走了下面方法中的 catch, error 内容为空。但是我这边测试发现,内容还是在返回中的,并且再次进入页面,这条内容能完整的呈现出来。
期望行为:
1、增加流式接口响应的时长;
2、能否返回真正的流式接口底层错误码。
流式接口相关代码:
import { RoleType, ChatStatus, ChatEventType } from '@coze/api';
import { CozeAPI } from '@coze/uniapp-api';
import { parseJwt, getTokenFromStore } from "@/utils/jwt";
interface StreamChatOptions {
onMessage?: (content: string, data?: any) => void
onError?: (error: any) => void
onComplete?: (data: any) => void
onStatusChange?: (status: ChatStatus) => void
additionalMessages?: any[]
onEmptyError?: () => void
onChatInProgress?: (data: { conversationId: string; chatId: string }) => void
}
// Token 管理(简化版,仅保留 streamChat 依赖的部分)
async function getCozeToken(): Promise {
// 此处保留 token 获取逻辑,streamChat 依赖此函数
// 实际实现参考原文件的 tokenInfo.isTokenExpired()
return '';
}
// 按需创建带最新 token 的 CozeAPI 客户端
export async function getCozeClient(): Promise {
const token = await getCozeToken();
return new CozeAPI({
token,
baseURL: COZE_CN_BASE_URL,
allowPersonalAccessTokenInBrowser: import.meta.env.NODE_ENV !== 'production'
});
}
// ==================== 流式聊天核心接口 ====================
// 流式请求聊天
async function streamChat(
message: string,
conversation_id: string | null = null,
parameters: Record<string, any> | null = null,
options: StreamChatOptions = {}
) {
const botId = import.meta.env.VITE_COZE_BOT_ID;
if (!botId) {
const error = { msg: '缺少配置: cozeBotId', code: -1 };
console.error('[Chat Config Error]', error);
throw error;
}
const {
onMessage = (content: string, _data?: any) => console.log(content),
onError = (error: { msg: string; code?: number }) => console.error('聊天错误:', error),
onComplete = (data: any) => console.log('聊天完成', data),
onStatusChange = (status: ChatStatus) => console.log('聊天状态变化:', status),
additionalMessages = [],
onEmptyError,
onChatInProgress
} = options;
try {
const client = await getCozeClient();
const messages = [
{ role: RoleType.User, content: message, content_type: 'text' },
...additionalMessages
];
const obj: any = {
bot_id: botId,
additional_messages: messages,
auto_save_history: true
};
if (conversation_id) obj.conversation_id = conversation_id;
if (parameters) obj.parameters = parameters;
const payload = parseJwt(getTokenFromStore());
if (payload && payload.sub) {
obj.user_id = payload.sub;
}
console.log('[Chat Request]', {
bot_id: botId,
conversation_id: conversation_id || 'new',
user_id: obj.user_id || 'none',
message_length: message.length,
has_parameters: !!parameters
});
const stream = await client.chat.stream(obj);
let isCompleted = false;
let receivedTerminalEvent = false;
for await (const part of stream) {
console.log('[Chat Stream]', part);
if (!part?.event) {
console.error('[Chat Stream Protocol Error]', part);
throw part || new Error('流式响应格式异常');
}
if (part.event === ChatEventType.CONVERSATION_MESSAGE_DELTA) {
const deltaContent = typeof part?.data?.content === 'string' ? part.data.content : '';
if (deltaContent !== '') {
onMessage(deltaContent);
}
} else if (part.event === ChatEventType.CONVERSATION_CHAT_IN_PROGRESS) {
console.log('[Chat In Progress]', part.data);
onChatInProgress?.({
conversationId: part.data?.conversation_id,
chatId: part.data?.id
});
} else if (part.event === ChatEventType.CONVERSATION_CHAT_COMPLETED) {
receivedTerminalEvent = true;
console.log('[Chat Completed]', {
conversation_id: part.data?.conversation_id
});
onStatusChange?.(ChatStatus.COMPLETED);
onComplete?.(part.data);
isCompleted = true;
} else if (part.event === ChatEventType.CONVERSATION_CHAT_FAILED) {
receivedTerminalEvent = true;
console.error('[Chat Failed]', part.data);
throw part.data;
} else if (part.event === ChatEventType.ERROR) {
receivedTerminalEvent = true;
console.error('[Chat Stream Error]', part.data);
throw part.data;
} else if (part.event === ChatEventType.DONE) {
receivedTerminalEvent = true;
console.log('[Chat Stream Done]');
if (!isCompleted) {
throw new Error('流式响应异常结束');
}
}
}
// 检查是否收到终止事件
if (!receivedTerminalEvent) {
throw new Error('流式响应异常结束:未收到终止事件');
}
} catch (error: any) {
console.log('[Chat Error]', error);
// 检测空 Error:可能是流式请求网络中断,但服务端可能已保存数据
const isEmptyError = error instanceof Error &&
(!error.message || error.message.trim() === '');
if (isEmptyError) {
console.warn('[Chat Stream] 检测到空错误,触发空错误处理流程');
onEmptyError?.();
return;
}
console.error('[Chat Error]', error);
onStatusChange?.(ChatStatus.FAILED);
onError?.(error);
throw error;
}
}
在uni-app项目中使用 @coze/uniapp-api 0.3.1 版本,编译成微信小程序
遇到的问题:
流式接口返回内容时间过长时,接口直接 走了下面方法中的 catch, error 内容为空。但是我这边测试发现,内容还是在返回中的,并且再次进入页面,这条内容能完整的呈现出来。
期望行为:
1、增加流式接口响应的时长;
2、能否返回真正的流式接口底层错误码。
流式接口相关代码:
import { RoleType, ChatStatus, ChatEventType } from '@coze/api';
import { CozeAPI } from '@coze/uniapp-api';
import { parseJwt, getTokenFromStore } from "@/utils/jwt";
interface StreamChatOptions {
onMessage?: (content: string, data?: any) => void
onError?: (error: any) => void
onComplete?: (data: any) => void
onStatusChange?: (status: ChatStatus) => void
additionalMessages?: any[]
onEmptyError?: () => void
onChatInProgress?: (data: { conversationId: string; chatId: string }) => void
}
// Token 管理(简化版,仅保留 streamChat 依赖的部分)
async function getCozeToken(): Promise {
// 此处保留 token 获取逻辑,streamChat 依赖此函数
// 实际实现参考原文件的 tokenInfo.isTokenExpired()
return '';
}
// 按需创建带最新 token 的 CozeAPI 客户端
export async function getCozeClient(): Promise {
const token = await getCozeToken();
return new CozeAPI({
token,
baseURL: COZE_CN_BASE_URL,
allowPersonalAccessTokenInBrowser: import.meta.env.NODE_ENV !== 'production'
});
}
// ==================== 流式聊天核心接口 ====================
// 流式请求聊天
async function streamChat(
message: string,
conversation_id: string | null = null,
parameters: Record<string, any> | null = null,
options: StreamChatOptions = {}
) {
const botId = import.meta.env.VITE_COZE_BOT_ID;
if (!botId) {
const error = { msg: '缺少配置: cozeBotId', code: -1 };
console.error('[Chat Config Error]', error);
throw error;
}
}