微信小程序流式调用扣子智能体

定义一个 支持SSE请求方法chat_requestTaskfunction chat_requestTask(authorization, conversation_id, data) {let header{}header[Aut

  1. 定义一个 支持SSE请求方法chat_requestTask
function chat_requestTask(authorization, conversation_id, data) {
	let header = {}
	header['Authorization'] = `Bearer ${authorization}`
	header['Content-Type'] = "application/json"
	return uni.request({
		url: `https://api.coze/v3/chat?conversation_id=${conversation_id}`,
		method: "POST",
		data,
		responseType: 'text',
		header,
		enableChunked: true
	});
}
  1. 将ArrayBuffer转换为Base64字符串
// 将ArrayBuffer转换为Base64字符串
// fixbug:String.fromCharCode.apply 数据截断问题
// https://stackoverflow/questions/38432611/converting-arraybuffer-to-string-maximum-call-stack-size-exceeded/
const arrayBufferToBase64 = (buffer: any) => {
	const uint8Array = new Uint8Array(buffer);
	const data = uint8Array.reduce(
		(acc, i) => (acc += String.fromCharCode.apply(null, [i])),
		''
	);
	return data;
};
  1. 定义一个方法,getAnswerByCoze并使用chat_requestTask请求获取答案
export interface paramsType {
	authorization: string
	conversation_id: string
	bot_id: string
	user_id: string
}

export interface payloadType {
	text: string
	file_url?: string
}
// 通过扣子获取答案
export function getAnswerByCoze(params: paramsType, payload: payloadType, callBack: Function) {
	// coze接口参数
	let { authorization, conversation_id, bot_id, user_id } = params
	// 问题参数
	let { text, file_url } = payload
	let additional_messages = [] as Array<messageType>
	// 有图的问答
	if (file_url) {
		additional_messages.push({
			type: "question",
			role: "user",
			content_type: "object_string",
			content: JSON.stringify([
				{
					type: "image",
					file_url
				}, {
					type: "text",
					text
				},

			])
		})
	} else {
		// 无图的纯文字的问答
		additional_messages.push({
			type: "question",
			role: "user",
			content_type: "text",
			content: text
		})
	}
	let answer = { content:'', follow_up: [], status: { describe: '', code: '' } }
	chat_requestTask(authorization, conversation_id, {
		bot_id,
		user_id,
		stream: true,
		auto_save_history: true,
		additional_messages
	}).onChunkReceived((res) => {
		// 将二进制的流转换成文本 String.fromCharCode.apply有数据截断问题 已弃用
		// const uint8Array = new Uint8Array(res.data);
		// let text = uint8Array && String.fromCharCode.apply(null, uint8Array);
		// text = text && decodeURIComponent(escape(text));
		
		// 小程序真机暂时不支持 TextDecoder 已弃用
		// const uint8Array = new Uint8Array(res.data);
		// const decoder = new TextDecoder('utf-8');
		// let text = decoder.decode(uint8Array,{ stream: true })		
		arrayBufferToBase64(res.data)
		if (text) {
			// 根据 event 和 data 提取文本内容
			const regex = /event:(.+)\ndata:(.+)/g;
			const matches = [] as Array<{ event: string, data?: object }>;
			let match;

			// 使用循环将提取的内容拼装成json
			while ((match = regex.exec(text)) !== null) {
				const event = match[1];
				const data =  JSON.parse(match[2])
				matches.push({ event, data });
			}
			// 处理每条内容的 event 事件和具体的内容 data,根据事件将内容返回给调用者
			matches.map((item) => {
				answer.status.code = item.event
				switch (item.event) {
					case 'conversation.chat.created':
						answer.status.describe = '对话开始'
						break;
					case 'conversation.chat.in_progress':
						answer.status.describe = '服务端正在处理对话'
						break;
					case 'conversation.message.delta':
						answer.status.describe = '消息推送中'
						// 只获取文字类型的消息
						if(item.data.content_type === "text"){
							answer.content += item.data.content
						}
						break;
					case 'conversation.messagepleted':
						answer.status.describe = '消息推送完成'
						if (item.data.type === "answer" && item.data.content_type === "text") {
							answer.content = item.data.content
						} else if (item.data.type === "follow_up") {
							answer.follow_up.push({ content: item.data.content, id: "" })
						}
						break;
					case 'conversation.chatpleted':
						answer.status.describe = '对话完成'
						break;
					case 'conversation.chat.failed':
						answer.status.describe = '对话失败'
						break;
					case 'done':
						answer.status.describe = '对话结束'
						break;
					case 'error':
						answer.status.describe = '对话错误'
						break;
					default:
						break;
				}
				callBack(answer)
			})
		}
	})
}
  1. 内容的上屏
	getAnswerByCoze(cozeParams,{text:value, file_url: image?.file_url},(answer)=>{
	if( 'conversation.chat.created'.includes(answer.status.code)){
		// 连接成功
	} else if ('conversation.message.delta'.includes(answer.status.code)){
		// 实时上屏的内容 
		content = answer.content
	} else if ( 'done,error'.includes(answer.status.code)){
		// 连接结束 
		// 完整的答案
		answer = answer.content
		// 相关的答案
		 relatedanswer = answer.follow_up
	}
})

发布者:admin,转转请注明出处:http://www.yc00.com/web/1754606041a5181610.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信