chore: replace all cn comments of fe to en version by volc api (#320)

This commit is contained in:
tecvan
2025-07-31 10:32:15 +08:00
committed by GitHub
parent 716ec0cba8
commit 71f6245a01
2960 changed files with 15545 additions and 15545 deletions

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Mock from 'mockjs';
import { ChatCoreUploadPlugin } from '@/plugins/upload-plugin';
@@ -29,7 +29,7 @@ import ChatSDK from '@/chat-sdk';
const random = Mock.Random;
describe('创建消息', () => {
// 创建 ChatSDK 实例
// Create a ChatSDK instance
const sdkProps: CreateProps = {
bot_id: random.string(),
biz: 'third_part',
@@ -41,15 +41,15 @@ describe('创建消息', () => {
};
const chat = new ChatSDK(sdkProps);
// 注册插件
// @ts-expect-error -- 测试文件中不需要真实的插件
// Register plugin
// @ts-expect-error -- no real plugin is required in the test file
chat.registerPlugin('upload-plugin', ChatCoreUploadPlugin, {
userId: '123',
appId: 123,
});
it('createTextMessage', () => {
// 标准输出的 Message
// Standard Output Message
const messageStand = {
bot_id: sdkProps.bot_id,
role: 'user',
@@ -117,7 +117,7 @@ describe('创建消息', () => {
},
],
};
// 标准输出的 Message
// Standard Output Message
const messageStand = {
bot_id: sdkProps.bot_id,
role: 'user',
@@ -157,15 +157,15 @@ describe('创建消息', () => {
};
const options = { section_id: '123' };
// 注册插件
// @ts-expect-error -- test文件忽略
// Register plugin
// @ts-expect-error -- test file ignored
chat.registerPlugin('upload-plugin', ChatCoreUploadPlugin, {
userId: '123',
appId: 123,
});
// Execute
// @ts-expect-error -- 测试文件
// @ts-expect-error -- test file
const message = chat.createImageMessage(props, options);
// Assert
@@ -185,7 +185,7 @@ describe('创建消息', () => {
},
],
};
// 标准输出的 Message
// Standard Output Message
const messageStand = {
bot_id: sdkProps.bot_id,
role: 'user',
@@ -230,7 +230,7 @@ describe('创建消息', () => {
const options = { section_id: '123' };
// Execute
// @ts-expect-error -- 测试文件
// @ts-expect-error -- test file
const message = chat.createFileMessage(props, options);
// Assert
@@ -248,7 +248,7 @@ describe('创建消息', () => {
},
{
type: ContentType.File,
// @ts-expect-error -- 测试文件
// @ts-expect-error -- test file
file: {
type: 'pdf',
name: 'file.pdf',
@@ -258,7 +258,7 @@ describe('创建消息', () => {
},
{
type: ContentType.Image,
// @ts-expect-error -- 测试文件
// @ts-expect-error -- test file
file: {
type: 'png',
name: 'image.png',
@@ -310,7 +310,7 @@ describe('创建消息', () => {
],
};
// 标准输出的 Message
// Standard Output Message
const messageStand = {
bot_id: sdkProps.bot_id,
role: 'user',
@@ -395,7 +395,7 @@ describe('创建消息', () => {
],
};
// 标准输出的 Message
// Standard Output Message
const messageStand = {
bot_id: sdkProps.bot_id,
role: 'user',

View File

@@ -106,7 +106,7 @@ describe('SendMessageService', () => {
extra_info: { local_message_id: '456' },
};
const options: SendMessageOptions = {};
// 1s后上传成功
// Upload successful after 1s
setTimeout(() => {
preSendLocalMessageEventsManager.emit(
PreSendLocalMessageEventsEnum.FILE_UPLOAD_STATUS_CHANGE,
@@ -119,7 +119,7 @@ describe('SendMessageService', () => {
},
);
}, 1000);
// 2s后发送成功
// Sent successfully after 2s
setTimeout(() => {
preSendLocalMessageEventsManager.emit(
PreSendLocalMessageEventsEnum.MESSAGE_SEND_SUCCESS,
@@ -144,7 +144,7 @@ describe('SendMessageService', () => {
extra_info: { local_message_id: '789' },
};
const options: SendMessageOptions = {};
// 1s后上传成功
// Upload successful after 1s
setTimeout(() => {
preSendLocalMessageEventsManager.emit(
PreSendLocalMessageEventsEnum.FILE_UPLOAD_STATUS_CHANGE,

View File

@@ -65,10 +65,10 @@ const randomChunkRawList: ChunkRaw[] = Mock.mock({
content: '@string',
reasoning_content: '@string',
message_status: '@RANDOM_MESSAGE_STATUS',
message_id: '@string', // 后端消息 id, 可能有多条回复
reply_id: '999999999', // 回复 idquerymessageId
message_id: '@string', // Backend message id, there may be multiple replies
reply_id: '999999999', // Reply id, query messageId
extra_info: {
local_message_id: '88888888888', // 前端消息 id, 用于预发送消息体更新
local_message_id: '88888888888', // Front-end message id, used to pre-send message body updates
},
},
},
@@ -113,16 +113,16 @@ describe('消息接收测试', () => {
reasoning_content: 'I am the last!!!',
reply_id: firstTextChunk?.message.reply_id ?? '',
extra_info: {
input_tokens: '', // 用户 query 消耗的 token
output_tokens: '', // llm 输出消耗的 token
token: '', // 总的 token 消耗
input_tokens: '', // User query consumed token
output_tokens: '', // LLM output consumed token
token: '', // Total token consumption
plugin_status: 'success', // "success" or "fail"
time_cost: '', // 中间调用过程的时间
time_cost: '', // Intermediate invocation time of procedure
workflow_tokens: '',
bot_state: '', // { bot_id?: string;agent_id?: string;agent_name?: string; }
plugin_request: '', // plugin 请求的参数
tool_name: '', // 调用的 plugin 下具体的 api 名称
plugin: '', // 调用的 plugin 名称
plugin_request: '', // Parameters of the plugin request
tool_name: '', // Specific API name under the invoked plugin
plugin: '', // Name of the plugin invoked
local_message_id:
firstTextChunk?.message.extra_info.local_message_id ?? '',
},

View File

@@ -54,7 +54,7 @@ export const testSetup = () => {
}),
})),
}));
// mock上传插件实现
// Mock upload plugin implementation
vi.mock('../src/plugins/upload-plugin', () => ({
ChatCoreUploadPlugin: class {
eventBus = new eventEmitter();

View File

@@ -15,26 +15,26 @@
*/
export enum HttpChunkEvents {
// 收到消息
// Received message
MESSAGE_RECEIVED = 'http_chunk_message_received',
// 收到消息异常
// Abnormal message received
MESSAGE_RECEIVED_INVALID = 'http_chunk_message_received_invalid',
// 整体拉流超时
// overall pull timeout
TOTAL_FETCH_TIMEOUT = 'http_chunk_total_fetch_timeout',
// 包间超时
// Private room timeout
BETWEEN_CHUNK_TIMEOUT = 'http_chunk_between_chunk_timeout',
// 开始 fetch
// Start fetching
FETCH_START = 'http_chunk_fetch_start',
// fetch 请求成功
// Fetch request successful
FETCH_SUCCESS = 'http_chunk_fetch_success',
// fetch 请求异常
// Fetch request exception
FETCH_ERROR = 'http_chunk_fetch_error',
// 无效的消息格式
// Invalid message format
INVALID_MESSAGE = 'http_chunk_invalid_message',
// 拉流开始
// Pull flow starts
READ_STREAM_START = 'http_chunk_read_stream_start',
// 拉流异常
// Pull flow anomaly
READ_STREAM_ERROR = 'http_chunk_read_stream_error',
// 从 fetch read stream 完整成功
// Fetch to read stream full success
ALL_SUCCESS = 'http_chunk_all_success',
}

View File

@@ -15,9 +15,9 @@
*/
/**
* http chunk slardar 自定义事件
* HTTP chunk slardar custom event
*/
export enum SlardarEvents {
// 调用 controller.abort 的代码发生的报错 不在预期之内
// The error occurred in the code calling controller.abort, which is not expected
HTTP_CHUNK_UNEXPECTED_ABORT_ERROR = 'http_chunk_unexpected_abort_error',
}

View File

@@ -92,7 +92,7 @@ export class HttpChunk extends CustomEventEmitter {
}: HandleMessageParams) => {
const { logID, replyID } = fetchDataHelper;
// 从 fetch 中抛出的数据类型由断言得到 这里运行时保卫一下类型
// The data type thrown from fetch is obtained by assertions, here the runtime defends the type
if (!inValidChunkRaw(data)) {
this.customEmit(HttpChunkEvents.INVALID_MESSAGE, {
logID,
@@ -111,19 +111,19 @@ export class HttpChunk extends CustomEventEmitter {
private pullMessage = async ({
value,
// TODO: 本期没有做消息重试
// TODO: There is no message retry in this issue
isRePullMessage: _isRePullMessage,
fetchDataHelper,
fetchUrl,
scene,
}: {
value: Record<string, unknown>; // 短链入参直接透传body不做特化处理在外层处理业务逻辑
value: Record<string, unknown>; // Short URL imported parameters: direct pass-through body does not do specialized processing, external processing business logic
isRePullMessage: boolean;
fetchDataHelper: FetchDataHelper;
fetchUrl: string; // 短链链接
fetchUrl: string; // Short URL Link
scene: RequestScene;
}) => {
// TODO: hzf,不使用三元表达式
// TODO: hzf, does not use ternary expressions
const headers: [string, string][] = [
['content-type', 'application/json'],
...((this.tokenManager?.getApiKeyAuthorizationValue()
@@ -138,7 +138,7 @@ export class HttpChunk extends CustomEventEmitter {
const { hooks } = this.requestManager.getSceneConfig?.(scene) || {};
const { onBeforeSendMessage = [], onGetMessageStreamParser } = hooks || {};
// 如下参数可做修改
// The following parameters can be modified
let channelFetchInfo = {
url: fetchUrl,
body: JSON.stringify(value),
@@ -241,10 +241,10 @@ export class HttpChunk extends CustomEventEmitter {
return;
// TODO: 下面应该是重新拉取 message 的逻辑 本期服务端没有来得及做
// TODO: The following should be the logic to re-pull the message. The server level did not have time to do it in this issue.
// if (dataClump.retryCounter.matchMaxRetryAttempts()) {
// this.customOnError?.(errorInfo);
// // 放弃尝试重试
// //give up trying and try again
// this.handleFinish();
// return;
// }
@@ -252,12 +252,12 @@ export class HttpChunk extends CustomEventEmitter {
// dataClump.retryCounter.add();
};
// 调用chat、resume接口发送消息已经在上层抹平差异
// Call the chat and resume interfaces to send messages, which has smoothed the difference at the upper level.
sendMessage = (value: SendMessage, config?: SendMessageConfig) => {
const localMessageID = value.local_message_id;
if (!localMessageID) {
// TODO: 用同一的异常类
// TODO: Use the same exception class
this.customEmit(HttpChunkEvents.FETCH_ERROR, {
code: FetchStreamErrorCode.FetchException,
msg: 'SendMessageError: SendMessage is Invalid',
@@ -281,7 +281,7 @@ export class HttpChunk extends CustomEventEmitter {
this.fetchDataHelperMap.set(localMessageID, fetchDataHelper);
const scene = config?.requestScene || RequestScene.SendMessage;
// 获取消息短链请求链接
// Get short URL request link
const { url, baseURL } = this.requestManager.getSceneConfig?.(scene) || {};
const fetchUrl = baseURL ? `${baseURL}${url}` : url;

View File

@@ -55,7 +55,7 @@ export interface MessageLifecycleCallbackParams
export type OnMessageCallback = (messageEvent: OnMessageCallbackParams) => void;
/**
* 收到的消息结构体异常响应此错误
* The received message structure responded abnormally to this error
*/
export type OnMessageInvalidCallback = (
error: HttpChunkMessageInvalidErrorInfo,
@@ -68,7 +68,7 @@ export type OnMessageStartCallback = (
) => void;
/**
* HttpChunk 未能建连、意外断开、Abort
* HttpChunk failed to connect, accidentally disconnected, aborted
*/
export type OnErrorCallback = (errorInfo: ErrorInfo) => void;

View File

@@ -119,7 +119,7 @@ export const streamParser: FetchSteamConfig<
case ChunkEvent.DONE:
terminate();
return;
// 对话过程中出现异常例如token 消耗完了
// An exception occurs during the conversation, for example: the token is exhausted
case ChunkEvent.ERROR:
return { event, data };
default:

View File

@@ -17,7 +17,7 @@
export enum SdkEventsEnum {
MESSAGE_RECEIVED_AND_UPDATE = 'message_received_and_update',
/**
* 监测拉取回复消息状态变化
* Monitor pull reply message status changes
*/
MESSAGE_PULLING_STATUS = 'message_pulling_status',
ERROR = 'error',

View File

@@ -18,23 +18,23 @@ import { type ReportLog, type Tracer } from '../../report-log';
import type { ChatCoreError } from '../../custom-error';
/**
* 承接所有 sdk slardar 自定义事件
* Undertake all sdk slardar custom events
*/
export enum SlardarEvents {
// sdk初始化用于数据统计
// SDK initialization for data statistics
SDK_INIT = 'chat_sdk_init',
// 上传失败
// Upload failed.
SDK_MESSAGE_UPLOAD_FAIL = 'chat_sdk_message_upload_fail',
// 打断消息
// interrupt message
SDK_BREAK_MESSAGE = 'chat_sdk_break_message',
// 消息发送链路监控
// messaging link monitoring
SDK_MESSAGE_SEND_TRACER = 'chat_sdk_message_send_tracer',
// 拉流链路耗时监控
// Pull link time monitoring
SDK_PULL_STREAM_TRACER = 'chat_sdk_pull_stream_tracer',
}
/**
* slardar事件追踪
* Slardar Event Tracking
*/
export class ReportEventsTracer {
private reporter: ReportLog;
@@ -52,7 +52,7 @@ export class ReportEventsTracer {
}
/**
* 消息发送事件追踪
* Messaging Event Tracking
*/
sendMessageTracer = {
start: (local_message_id: string, meta?: Record<string, unknown>) => {
@@ -111,7 +111,7 @@ export class ReportEventsTracer {
};
/*
* 拉取流事件追踪
* Pull stream event tracking
*/
pullStreamTracer = {
start: (local_message_id: string, meta?: Record<string, unknown>) => {
@@ -139,7 +139,7 @@ export class ReportEventsTracer {
local_message_id,
SlardarEvents.SDK_PULL_STREAM_TRACER,
);
// 打断算成功
// Interrupt is successful
trace?.('success', {
meta,
});
@@ -202,14 +202,14 @@ export class ReportEventsTracer {
};
/**
* 组装获取唯一key
* Assemble to get unique key
*/
static getUniqueKey(local_message_id: string, event: SlardarEvents): string {
return `${local_message_id}_${event}`;
}
/**
* 根据local_message_idevent获取trace
* Get trace based on local_message_id, event
*/
getTracer(local_message_id: string, event: SlardarEvents) {
return (
@@ -222,7 +222,7 @@ export class ReportEventsTracer {
}
/**
* 根据local_message_id、event新增trace
* Add trace based on local_message_id and event
*/
setTracer(
local_message_id: string,
@@ -243,7 +243,7 @@ export class ReportEventsTracer {
}
/**
* 删除trace
* Delete trace
*/
deleteTracer(local_message_id: string, event: SlardarEvents) {
this.eventTracers.delete(
@@ -252,7 +252,7 @@ export class ReportEventsTracer {
}
/**
* 创建trace
* Create trace
*/
createTracer(eventName: SlardarEvents) {
return this.reporter.slardarTracer({

View File

@@ -16,7 +16,7 @@
/**
* @module @coze-common/chat-core
* 暴露所有对外接口
* Expose all external interfaces
*/
import EventEmitter from 'eventemitter3';
import { type InternalAxiosRequestConfig } from 'axios';
@@ -74,19 +74,19 @@ import { ReportEventsTracer, SlardarEvents } from './events/slardar-events';
export default class ChatSDK {
private static instances: Map<string, ChatSDK> = new Map();
/**
* 预发送消息工厂: 创建预发送消息用于上屏
* Pre-send Message Factory: Create pre-send messages for use on the screen
*/
private preSendLocalMessageFactory!: PreSendLocalMessageFactory;
/**
* 处理接收到的 chunk 消息,处理成统一 Message 格式
* Process received chunk messages into a unified message format
*/
private chunkProcessor!: ChunkProcessor;
private messageManager!: MessageManager;
/**
* stream拉流
* Streaming
*/
private httpChunk!: HttpChunk;
@@ -97,7 +97,7 @@ export default class ChatSDK {
private requestManager!: RequestManager;
/**
* 维护本地消息的发送事件:
* Maintain local message sending events:
*/
private preSendLocalMessageEventsManager!: PreSendLocalMessageEventsManager;
@@ -113,15 +113,15 @@ export default class ChatSDK {
preset_bot!: PresetBot;
/**
* 目前chat-core生命周期内以一个 bot_id、user 为维度
* 后续如果支持一个 user对应多个 conversation_id需要调整
* The current chat-core life cycle takes a bot_id and user as dimensions
* If one user is supported for multiple conversation_id, it needs to be adjusted
*/
user!: string;
scene?: Scene;
/**
* 使用环境
* usage environment
*/
env!: ENV;
@@ -156,7 +156,7 @@ export default class ChatSDK {
private pluginsService!: PluginsService;
constructor(props: CreateProps) {
/** 初始化构造参数 */
/** Initialize construction parameters */
this.initProps(props);
this.initModules(props);
this.initServices();
@@ -168,13 +168,13 @@ export default class ChatSDK {
}
/**
* 创建chatBot实例
*1. 对于同一个 bot_id/preset_bot, 重复调用sdk 只会创建一个实例
*2. 多个 bot_id/presetBot,对应多个 sdk 实例,维护自己的events
* Create a chatBot instance
*1. For the same bot_id/preset_bot, repeated calls, sdk will only create one instance
*2. Multiple bot_id/presetBot, corresponding to multiple SDK instances, maintaining its own events
*/
static create(props: CreateProps) {
const { unique_key } = ChatSDK.getUniqueKey(props);
// 对于同一个 bot_id/preset_bot, 重复调用create只会创建一个实例
// For the same bot_id/preset_bot, repeated calls, create will only create one instance
if (ChatSDK.instances.has(unique_key)) {
console.error('duplicate chat core instance error');
return ChatSDK.instances.get(unique_key);
@@ -186,7 +186,7 @@ export default class ChatSDK {
}
/**
* 获取 sdk 唯一键 preset_bot > bot_id
* Get sdk unique key preset_bot > bot_id
* @param props
* @returns
*/
@@ -240,7 +240,7 @@ export default class ChatSDK {
this.draft_mode = draft_mode;
}
/** 初始化依赖Module实例 */
/** Initializing Dependency Module Instances */
private initModules(props: CreateProps) {
this.initReportLog();
this.reportEventsTracer = new ReportEventsTracer(this.reportLogWithScope);
@@ -250,7 +250,7 @@ export default class ChatSDK {
new PreSendLocalMessageEventsManager({
reportLog: this.reportLog,
});
/** 初始化预发送消息工厂 */
/** Initialize the pre-sent message factory */
this.preSendLocalMessageFactory = new PreSendLocalMessageFactory({
bot_id: this.bot_id,
preset_bot: this.preset_bot,
@@ -260,7 +260,7 @@ export default class ChatSDK {
bot_version: this.bot_version,
draft_mode: this.draft_mode,
});
/** 初始化处理接收到的 chunk 消息,处理成统一 Message 格式 */
/** Initialize processing of received chunk messages into a unified message format */
this.chunkProcessor = new ChunkProcessor({
bot_id: this.bot_id,
preset_bot: this.preset_bot,
@@ -272,7 +272,7 @@ export default class ChatSDK {
reportLogWithScope: this.reportLogWithScope,
});
/**
* 初始化消息管理器:消息删除/历史等
* Initialize the message manager: message deletion/history, etc
*/
this.messageManager = new MessageManager({
reportLog: this.reportLog,
@@ -371,23 +371,23 @@ export default class ChatSDK {
}
/**
* 销毁 SDK 实例。
* 清空所有监听事件
* Destroy the SDK instance.
* Clear all listening events
*/
destroy() {
// 清空所有httpChunk监听事件
// Clear all htpChunk listening events
this.httpChunk.drop();
// 清空sdk时间
// Clear sdk time
this.eventBus.removeAllListeners();
// 清空所有缓存的 chunk 消息
// Clear all cached chunks
this.chunkProcessor.streamBuffer.clearMessageBuffer();
// 清除对应的实例
// Clear the corresponding instance
const { unique_key } = ChatSDK.getUniqueKey({
bot_id: this.bot_id,
preset_bot: this.preset_bot,
});
ChatSDK.instances.delete(unique_key);
// 清除预发送消息缓存
// Clear pre-sent message cache
this.preSendLocalMessageEventsManager.destroy();
this.reportLogWithScope.info({
message: 'SDK销毁',
@@ -395,10 +395,10 @@ export default class ChatSDK {
}
/**
* 监听sdk事件
* Monitor sdk events
*/
on<T extends SdkEventsEnum>(event: T, fn: SdkEventsCallbackMap[T]) {
// 重复监听,错误提示
// Repeated listening, error message
if (this.eventBus.eventNames().includes(event)) {
this.reportLogWithScope.slardarError({
message: '重复监听事件',

View File

@@ -56,7 +56,7 @@ export class CreateMessageService {
}
/**
* 创建文本消息
* Create text message
*/
createTextMessage(
props: TextMessageProps,
@@ -70,7 +70,7 @@ export class CreateMessageService {
}
/**
* 创建图片消息
* Create image message
*/
createImageMessage<M extends EventPayloadMaps = EventPayloadMaps>(
props: ImageMessageProps<M>,
@@ -94,7 +94,7 @@ export class CreateMessageService {
}
/**
* 创建文件消息
* Create file message
*/
createFileMessage<M extends EventPayloadMaps = EventPayloadMaps>(
props: FileMessageProps<M>,
@@ -118,7 +118,7 @@ export class CreateMessageService {
}
/**
* 创建图文混合消息
* Create a mixed message
*/
createTextAndFileMixMessage(
props: TextAndFileMixMessageProps,
@@ -132,7 +132,7 @@ export class CreateMessageService {
}
/**
* 创建标准化消息已经处理好payload content结构的消息
* Create standardized messages, messages with payload content structure already processed
*/
createNormalizedPayloadMessage<T extends ContentType>(
props: NormalizedMessageProps<T>,

View File

@@ -77,29 +77,29 @@ export class HttpChunkService {
this.chatSdkEventBus = chatSdkEventBus;
}
/**
* 处理channel监听到的事件
* Handle events listened to by the channel
*/
onHttpChunkEvents() {
this.httpChunk.on(
HttpChunkEvents.FETCH_START,
this.handleHttpChunkFetchStart,
);
// 读取流
// read stream
this.httpChunk.on(
HttpChunkEvents.MESSAGE_RECEIVED,
this.handleHttpChunkMessageReceived,
);
// 整体拉流成功
// Overall flow success
this.httpChunk.on(
HttpChunkEvents.ALL_SUCCESS,
this.handleHttpChunkStreamSuccess,
);
// 开始读取流
// Start reading stream
this.httpChunk.on(
HttpChunkEvents.READ_STREAM_START,
this.handleHttpChunkReadStreamStart,
);
// fetch阶段异常, 还没到读流阶段
// Fetch phase exception, not yet reached the read stream phase
this.httpChunk.on(
HttpChunkEvents.FETCH_ERROR,
this.handleHttpChunkFetchError,
@@ -108,7 +108,7 @@ export class HttpChunkService {
HttpChunkEvents.READ_STREAM_ERROR,
this.handleReadStreamError,
);
// 包间超时
// Private room timeout
this.httpChunk.on(
HttpChunkEvents.BETWEEN_CHUNK_TIMEOUT,
this.handleHttpChunkTimeout,
@@ -130,7 +130,7 @@ export class HttpChunkService {
ackMessage?.extra_info || receiveMessage.chunk.message.extra_info;
let pullingStatus: PullingStatus = 'pulling';
// 判断是否是final answer
// Is it the final answer?
if (this.chunkProcessor.isMessageAnswerEnd(chunk)) {
pullingStatus = 'answerEnd';
}
@@ -148,7 +148,7 @@ export class HttpChunkService {
.eventNames()
.includes(SdkEventsEnum.MESSAGE_RECEIVED_AND_UPDATE);
// 判断接收到的消息是否已经存在
// Determine whether the received message already exists
if (this.chunkProcessor.isFirstReplyMessage(chunk)) {
this.reportEventsTracer?.pullStreamTracer?.receiveFirstAnsChunk(
local_message_id,
@@ -189,7 +189,7 @@ export class HttpChunkService {
});
};
// 读取流异常
// read stream exception
private handleReadStreamError = (errorInfo: ErrorInfo) => {
const {
ext: {
@@ -212,7 +212,7 @@ export class HttpChunkService {
const stashedAckMessage =
this.chunkProcessor.getAckMessageByLocalMessageId(local_message_id);
// 读取流异常,要区分在首包接受到了么
// The read stream is abnormal, do you want to distinguish between receiving it in the first package?
if (!stashedAckMessage) {
this.preSendLocalMessageEventsManager.emit(
PreSendLocalMessageEventsEnum.MESSAGE_SEND_FAIL,
@@ -221,7 +221,7 @@ export class HttpChunkService {
return;
}
// 如果是发送消息成功,则表示是拉流阶段失败
// If the message is sent successfully, it means that the pull phase failed.
if (stashedAckMessage) {
this.chatSdkEventEmit(SdkEventsEnum.MESSAGE_PULLING_STATUS, {
name: SdkEventsEnum.MESSAGE_PULLING_STATUS,
@@ -240,7 +240,7 @@ export class HttpChunkService {
});
};
// fetch异常,还没到拉流阶段
// Fetch is abnormal, it has not yet reached the pull flow stage
private handleHttpChunkFetchError = (errorInfo: ErrorInfo) => {
const {
ext: {

View File

@@ -85,7 +85,7 @@ export class MessageManagerService {
this.reportLogWithScope = reportLogWithScope;
}
/**
* 获取历史消息
* Get chat history
*/
async getHistoryMessage(props: GetHistoryMessageParams) {
const params = filterEmptyField({
@@ -103,7 +103,7 @@ export class MessageManagerService {
MessageManager.convertMessageList(data);
/**
* 清空对话上下文
* Clear the conversation context
*/
async clearMessageContext(params: ClearMessageContextParams) {
return await this.messageManager.clearMessageContextUrl({
@@ -114,7 +114,7 @@ export class MessageManagerService {
}
/**
* 清空历史
* Clear history
*/
async clearHistory() {
return await this.messageManager.clearHistory({
@@ -125,7 +125,7 @@ export class MessageManagerService {
}
/**
* 删除消息
* delete message
*/
async deleteMessage(params: DeleteMessageParams) {
return await this.messageManager.deleteMessage({
@@ -137,7 +137,7 @@ export class MessageManagerService {
}
/**
* 点赞/点踩消息
* Like/click on the message
*/
async reportMessage(params: ReportMessageParams) {
return await this.messageManager.reportMessage({
@@ -149,7 +149,7 @@ export class MessageManagerService {
}
/**
* 打断消息
* interrupt message
*/
async breakMessage(params: BreakMessageParams) {
this.httpChunk.abort(params.local_message_id);
@@ -173,7 +173,7 @@ export class MessageManagerService {
}
/**
* ASR 语音转文字
* ASR speech-to-text
*/
async chatASR(params: ChatASRParams) {
return await this.messageManager.chatASR(params);

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { exhaustiveCheckSimple } from '@coze-common/chat-area-utils';
import type { UploadPluginConstructor } from '@/plugins/upload-plugin/types/plugin-upload';
@@ -21,12 +21,12 @@ import type { UploadPluginConstructor } from '@/plugins/upload-plugin/types/plug
import type { PluginKey, PluginValue } from '../types/interface';
export class PluginsService {
//eslint-disable-next-line @typescript-eslint/no-explicit-any -- 暂时没想到合适的类型体操, 先用 any,
//eslint-disable-next-line @typescript-eslint/no-explicit-any -- I didn't think of a suitable type of gymnastics for the time being, use any first,
UploadPlugin: UploadPluginConstructor<any> | null = null;
uploadPluginConstructorOptions: Record<string, unknown> = {};
/**
* 注册插件
* Register plugin
*/
registerPlugin<T extends PluginKey, P extends Record<string, unknown>>(
key: T,
@@ -40,7 +40,7 @@ export class PluginsService {
}
/**
* 检查插件是否已经注册过
* Check if the plugin has been registered
*/
checkPluginIsRegistered(key: PluginKey): boolean {
if (key === 'upload-plugin') {

View File

@@ -66,7 +66,7 @@ export class SendMessageService {
}
/**
* 发送resume消息
* Send resume message
*/
resumeMessage(message: Message<ContentType>, options?: SendMessageOptions) {
const mergedOptions: SendMessageMergedOptions = {
@@ -92,7 +92,7 @@ export class SendMessageService {
}
/**
* 发送消息
* Send message
*/
async sendMessage(
message: Message<ContentType>,
@@ -134,7 +134,7 @@ export class SendMessageService {
}
/**
* 发送图片消息
* Send picture message
*/
private async sendImageMessage(
message: PreSendLocalMessage<ContentType.Image>,
@@ -150,7 +150,7 @@ export class SendMessageService {
}
/**
* 发送文件消息
* Send file message
* @param message
* @param options
* @private
@@ -169,7 +169,7 @@ export class SendMessageService {
}
/**
* 发送文本消息
* Send a text message
*/
private async sendTextMessage(
message: PreSendLocalMessage<ContentType.Text>,
@@ -181,26 +181,26 @@ export class SendMessageService {
}
/**
* 上传图片&文件上传事件完成
* Upload image & file upload event complete
*/
private onUploadEventFinish<T extends ContentType.Image | ContentType.File>(
message: PreSendLocalMessage<T>,
sendMessageOptions?: SendMessageOptions,
): Promise<PreSendLocalMessage<T>> {
return new Promise((resolve, reject) => {
// 如果是重新生成消息,直接返回
// If it is to regenerate the message, return it directly.
if (sendMessageOptions?.isRegenMessage) {
resolve(message);
return;
}
// 根据 message_id 查询是否已经上传完成
// According to message_id, check whether the upload has been completed
const stashedLocalMessage =
this.preSendLocalMessageEventsManager.getStashedLocalMessage(
message.extra_info.local_message_id,
) as PreSendLocalMessage<T>;
if (stashedLocalMessage?.file_upload_result) {
if (stashedLocalMessage?.file_upload_result === 'success') {
// todo 改成直接 resolve messagestashed 不应存入全量 request容易引起误会
// Todo is changed to directly resolve message, stashed should not be stored in the full amount of requests, which is easy to cause misunderstandings
resolve(message);
return;
}
@@ -214,7 +214,7 @@ export class SendMessageService {
return;
}
// 消息上传完成
// Message upload complete
this.preSendLocalMessageEventsManager.on(
PreSendLocalMessageEventsEnum.FILE_UPLOAD_STATUS_CHANGE,
(preSendLocalMessage: Message<ContentType>) => {
@@ -241,9 +241,9 @@ export class SendMessageService {
}
/**
* httpChunk 发送消息事件模式改为 await 模式
* @param message 最终要发送给服务端的消息格式
* @param options 发送消息配置
* HttpChunk send message event mode changed to await mode
* @Param message The final message format to be sent to the server
* @Param options send message configuration
*/
private sendChannelMessage(
message: SendMessage,
@@ -282,7 +282,7 @@ export class SendMessageService {
headers,
requestScene: RequestScene.SendMessage,
});
// 监听消息发送成功
// The monitor message was sent successfully.
this.preSendLocalMessageEventsManager.once(
PreSendLocalMessageEventsEnum.MESSAGE_SEND_SUCCESS,
(receiveMessage: Message<ContentType>) => {
@@ -307,7 +307,7 @@ export class SendMessageService {
resolve(receiveMessage);
},
);
// 监听消息发送失败
// Listening message sending failed
this.preSendLocalMessageEventsManager.once(
PreSendLocalMessageEventsEnum.MESSAGE_SEND_FAIL,
(error: ChatCoreError) => {

View File

@@ -39,9 +39,9 @@ export type BotUnique =
}
| {
/**
* 使用的bot模版 代替bot_id bot_version draft_mode参数
* 非安全考虑仅不想暴露bot_id的情况下使用
* botIdpresetBot必传其一
* Use the bot template instead of bot_id bot_version draft_mode parameters
* For non-safety reasons, use only if you don't want to expose bot_id
* botId, presetBot must pass one
*/
preset_bot: PresetBot;
};
@@ -53,66 +53,66 @@ export const isPresetBotUnique = <T extends BotUnique>(
export type CreateProps = BotUnique & {
/**
* 用于计算资源点消耗
* For computing resource point consumption
*/
space_id?: string;
/**
* 业务方标识,用于埋点记录
* Business party ID for event tracking
*/
biz: Biz;
/**
* bot 版本号
* bot version number
*/
bot_version?: string;
/**
* 草稿bot or 线上bot,
* Draft bots or online bots,
*/
draft_mode?: boolean;
/**
* 会话 id
* session id
*/
conversation_id: string;
/**
* 指定发送的唯一用户
* Specify the unique user to send
*/
user?: string;
/**
* 场景值,主要用于服务端鉴权, 默认 0 default
* Scene value, mainly used for server level authentication, default 0 default
*/
scene?: Scene;
/**
* 环境变量,区分测试环境和线上环境
* 用于日志上报
* Environment variables to distinguish between testing environment and online environment
* For log reporting
*/
env: ENV;
/**
* 区分部署版本
* Differentiate deployment versions
*/
deployVersion: DeployVersion;
/**
* 是否开启 debug模式目前主要给 bot editor 使用
* 开启后每条回复消息新增debug_messages字段包含channel 吐出的所有 chunk消息
* Whether to enable debug mode, currently mainly used by the bot editor
* After opening, each reply message adds debug_messages field, including all chunk messages spat out by the channel
**/
enableDebug?: boolean;
/**
* sdk 控制台日志等级默认error, 后面层级会包含前面层级
* SDK console log level, default error, the following level will contain the previous level
**/
logLevel?: LogLevel;
/**
接口拦截器
Interface blocker
**/
requestManagerOptions?: RequestManagerOptions;
/**
* token 刷新机制
* Token refresh mechanism
*/
tokenManager?: TokenManager;
};
@@ -142,15 +142,15 @@ export interface SdkPullingStatusEvent {
name: SdkEventsEnum;
data: {
/**
* 拉取回复消息状态
* Pull reply message status
*/
pullingStatus: PullingStatus;
/**
* query 的本地 id
* Local ID of the query
*/
local_message_id: string;
/**
* query 的服务端 message_id
* The server level of the query message_id
*/
reply_id: string;
};
@@ -158,7 +158,7 @@ export interface SdkPullingStatusEvent {
error?: ChatCoreError;
/**
* timeout 状态下返回,用于终止拉取
* Returns in timeout state to terminate the pull
* @returns
*/
abort?: () => void;
@@ -180,17 +180,17 @@ export type PluginValue<
> = T extends 'upload-plugin' ? UploadPluginConstructor<P> : never;
/**
* 接入的业务方向
* 目前采用枚举接入,控制接入方向
* third_part给open_api sdk使用暴露给第三方
* Access business direction
* Currently, enumeration access is used to control the access direction
* third_part used by open_api SDK, exposed to third parties
*/
export type Biz = 'coze_home' | 'bot_editor' | 'third_part';
export type PresetBot = 'coze_home' | 'prompt_optimize' | '';
/**
* 接口也有这个定义 enum Scene.
* 注意前端定义与接口完全对齐:
* Interfaces also have this definition enum Scene.
* Note that the front-end definition is fully aligned with the interface.
* src/auto-generate/developer_api/namespaces/developer_api.ts
*/
export const enum Scene {
@@ -198,18 +198,18 @@ export const enum Scene {
Explore = 1,
BotStore = 2,
CozeHome = 3,
// 调试区 命名和服务端对齐的
// Debug area, named and server level aligned
Playground = 4,
AgentAPP = 6,
PromptOptimize = 7,
/**
* TODO: 前端单独增加,需要和后端对齐固定一个枚举
* TODO: The front end is increased separately, and an enumeration needs to be aligned with the back end.
*/
OpenAipSdk = 1000,
}
/**
* 对齐 developer_api/namespaces/developer_api.ts
* Align developer_api/namespaces/developer_api
*/
export const enum LoadDirection {
Unknown = 0,

View File

@@ -15,8 +15,8 @@
*/
/**
* 负责 token 验权,自动刷新 token
* 暴露给业务方,由业务方决定是否单例还是多例鉴权
* Responsible for token verification, automatically refresh the token
* Exposed to the service party, the service party decides whether to single-case or multiple-case authentication
*/
export interface TokenManagerProps {
token?: string;
@@ -39,10 +39,10 @@ export default class TokenManager {
}
/**
* 获取 token
* Get token
*/
getToken() {
// TODO: 没有 token,获取最新 token
// TODO: No token, get the latest token
return this.token;
}
updateToken(token: string) {
@@ -53,24 +53,24 @@ export default class TokenManager {
}
/**
* 获取 apiKey
* Get apiKey
*/
getApiKey() {
return this.apiKey;
}
/**
* 获取 apiKey 组装成的 Authorization
* Get the Authorization value assembled by apiKey
*/
getApiKeyAuthorizationValue() {
return `Bearer ${this?.getApiKey()}`;
}
/**
* 刷新 apiKey
* Refresh apiKey
*/
refreshApiKey(apiKey: string) {
this.apiKey = apiKey;
}
// TODO: 补充刷新机制
// TODO: Supplementary refresh mechanism
}

View File

@@ -30,7 +30,7 @@ export class ChatCoreError extends Error {
}
/**
* 扁平化错误信息方便在slardar中筛选错误信息
* Flatten error messages for easy filtering of error messages in slardar
*/
flatten = () => {
const { message, ext } = this;

View File

@@ -15,9 +15,9 @@
*/
/**
* 处理接收到的Chunk消息
* 1、预处理:反序列化
* 2、增量消息拼接
* Process received Chunk messages
* 1. Pretreatment: Deserialization
* 2. Incremental message splicing
*/
import { cloneDeep, flow } from 'lodash-es';
@@ -34,14 +34,14 @@ import {
} from './types';
export class StreamBufferHelper {
// 一次流式拉取的message消息缓存
// One-time streaming pull message message cache
streamMessageBuffer: Message<ContentType>[] = [];
// 一次流式拉取的Chunk消息缓存
// Chunk message cache for one-time streaming pull
streamChunkBuffer: ChunkRaw[] = [];
/**
* 新增Chunk消息缓存
* Added Chunk message cache
*/
pushChunk(chunk: ChunkRaw) {
this.streamChunkBuffer.push(chunk);
@@ -51,12 +51,12 @@ export class StreamBufferHelper {
const previousIndex = this.streamMessageBuffer.findIndex(
item => item.message_id === message.message_id,
);
// 新增
// new
if (previousIndex === -1) {
this.streamMessageBuffer.push(message);
return;
}
// 更新
// update
const previousMessage = this.streamMessageBuffer.at(previousIndex);
message.content = (previousMessage?.content || '') + message.content;
message.reasoning_content =
@@ -68,7 +68,7 @@ export class StreamBufferHelper {
}
/**
* 清空消息缓存
* Clear message cache
*/
clearMessageBuffer() {
this.streamMessageBuffer = [];
@@ -76,9 +76,9 @@ export class StreamBufferHelper {
}
/**
* 按reply_id清除相关消息缓存
* 1reply_id相等的回复
* 2reply_id message_id 的问题
* Clear related message cache reply_id
* 1. reply_id equal reply
* 2, reply_id message_id problem
*/
clearMessageBufferByReplyId(reply_id: string) {
this.streamMessageBuffer = this.streamMessageBuffer.filter(
@@ -93,7 +93,7 @@ export class StreamBufferHelper {
}
/**
* 根据message_id获取chunk buffer中的chunk
* Get the chunk in the chunk buffer according to message_id
*/
getChunkByMessageId(message_id: string) {
return this.streamChunkBuffer.filter(
@@ -125,7 +125,7 @@ export class ChunkProcessor {
this.enableDebug = enableDebug;
}
/**
* 新增chunk, 统一处理后的Chunk消息
* Added chunk, unified processing of chunk messages
*/
addChunkAndProcess(chunk: ChunkRaw, options?: AddChunkAndProcessOptions) {
this.streamBuffer.pushChunk(chunk);
@@ -137,7 +137,7 @@ export class ChunkProcessor {
}
/**
* 根据chunk获取处理后的消息
* Get the processed message according to the chunk
*/
getProcessedMessageByChunk(chunk: ChunkRaw) {
return this.streamBuffer.streamMessageBuffer.find(
@@ -146,7 +146,7 @@ export class ChunkProcessor {
}
/**
* 根据message_id获取处理后的消息
* Get processed messages according to message_id
*/
getProcessedMessageByMessageId(message_id: string) {
return this.streamBuffer.streamMessageBuffer.find(
@@ -155,7 +155,7 @@ export class ChunkProcessor {
}
/**
* 根据local_message_id获取接收到的ack消息
* Get the received ack message according to the local_message_id
*/
getAckMessageByLocalMessageId(local_message_id: string) {
return this.streamBuffer.streamMessageBuffer.find(
@@ -166,7 +166,7 @@ export class ChunkProcessor {
}
/**
* 根据chunk获取到第一条回复
* Got the first reply according to chunk
*/
getFirstReplyMessageByChunk(chunk: ChunkRaw) {
const hasAck = this.streamBuffer.streamMessageBuffer.find(
@@ -181,7 +181,7 @@ export class ChunkProcessor {
}
/**
* 根据chunk获取到ack
* Get ack according to chunk.
*/
getAckMessageByChunk(chunk: ChunkRaw) {
return this.streamBuffer.streamMessageBuffer.find(
@@ -190,11 +190,11 @@ export class ChunkProcessor {
}
/**
* 判断是否是第一条回复消息
* 除ack外的第一条回复
* Determine whether it is the first reply message.
* First reply except ack
*/
isFirstReplyMessage(chunk: ChunkRaw) {
// 还没有ack肯定没有第一条回复
// No ack yet, definitely no first reply.
if (!this.getAckMessageByChunk(chunk)) {
return false;
}
@@ -202,7 +202,7 @@ export class ChunkProcessor {
}
/**
* 根据reply_id获取所有回复消息
* Get all reply messages according to reply_id
*/
getReplyMessagesByReplyId(reply_id: string) {
return this.streamBuffer.streamMessageBuffer.filter(
@@ -211,7 +211,7 @@ export class ChunkProcessor {
}
/**
* 获取所有回复消息的长度
* Get the length of all reply messages
*/
getReplyMessagesLengthByReplyId(reply_id: string) {
return `${this.getReplyMessagesByReplyId(reply_id).reduce(
@@ -221,7 +221,7 @@ export class ChunkProcessor {
}
/**
* 给本地日志使用
* Use for local logs
* @param message
* @returns
*/
@@ -236,13 +236,13 @@ export class ChunkProcessor {
}
/**
* 获取是否是final answer
* Is getting the final answer?
*/
isMessageAnswerEnd(chunk: ChunkRaw): boolean {
const { message } = chunk;
// 找到对应的所有回复
// Find all corresponding replies
const replyMessages = this.getReplyMessagesByReplyId(message.reply_id);
// 查找是否有verbose消息, 并且标识answer结束并且过滤掉中断场景的finish
// Find if there is a verbose message, and identify the end of the answer, and filter out the finish of the interrupt scene
const finalAnswerVerboseMessage = replyMessages.find(replyMessage => {
const { type, content } = replyMessage;
if (type !== 'verbose') {
@@ -258,7 +258,7 @@ export class ChunkProcessor {
const { value: verboseContentData } =
safeJSONParse<AnswerFinishVerboseData>(verboseContent.data, null);
// 目前一个group内可能会有finish包需要通过finish_reason过滤掉中断场景的拿到的就是回答全部结束的finish
// At present, there may be a finish package in a group. If you need to filter out the interrupt scene through finish_reason, you will get the finish that answers all the ends.
return (
verboseContent.msg_type === VerboseMsgType.GENERATE_ANSWER_FINISH &&
verboseContentData?.finish_reason !== FinishReasonType.INTERRUPT
@@ -268,9 +268,9 @@ export class ChunkProcessor {
}
/**
* 预处理消息
* 1、反序列化
* 2、添加 bot_idis_finishindex, logId
* preprocess message
* 1. Deserialization
* 2. Add bot_id, is_finish, index, logId
* @param chunk
* @param options
* @returns
@@ -299,8 +299,8 @@ export class ChunkProcessor {
}
/**
* 增量消息拼接
* 1、对于增量消息,需要拼接上一次的消息
* incremental message stitching
* 1. For incremental messages, you need to splice the previous message
*/
private concatChunkMessage(
message: Message<ContentType>,
@@ -310,14 +310,14 @@ export class ChunkProcessor {
return message;
}
// debug_message 逻辑
// debug_message logic
private assembleDebugMessage(
message: Message<ContentType>,
): Message<ContentType> {
if (!this.enableDebug) {
return message;
}
// 一次 stream拉取的所有message_id一样的 chunk 消息一次返回
// All message_id chunk messages pulled by a stream are returned at once
message.debug_messages = this.streamBuffer.getChunkByMessageId(
message.message_id,
);

View File

@@ -15,21 +15,21 @@
*/
/**
* 承接所有 sdk slardar 自定义事件
* Undertake all sdk slardar custom events
*/
export enum SlardarEvents {
// 拉取历史异常
// pull historical exception
MESSAGE_FETCH_HISTORY_ERROR = 'message_fetch_history_error',
// 清空上下文异常
// clear context exception
MESSAGE_CLEAR_CONTEXT_ERROR = 'message_clear_context_error',
// 清空历史异常
// Clear historical anomalies
MESSAGE_CLEAR_HISTORY_ERROR = 'message_clear_history_error',
// 删除消息异常
// Delete message exception
MESSAGE_DELETE_ERROR = 'message_delete_error',
// 打断消息
// interrupt message
MESSAGE_INTERRUPT_ERROR = 'message_interrupt_error',
// 点赞/点踩消息
// Like/click on the message
MESSAGE_REPORT_ERROR = 'message_report_error',
// 语音转文字
// speech-to-text
CHAT_ASR_ERROR = 'chat_asr_error',
}

View File

@@ -15,8 +15,8 @@
*/
/**
* 1. 负责规范各种类型消息创建的入参出参,减少消息创建成本
* 2. 对于接收到的消息,针对不同消息类型,吐出指定的消息格式
* 1. Responsible for standardizing imported parameters exported parameters of various types of message creation to reduce message creation costs
* 2. For the received message, spit out the specified message format for different message types
*/
export { PreSendLocalMessageFactory } from './presend-local-message/presend-local-message-factory';

View File

@@ -15,11 +15,11 @@
*/
/**
* 消息管理相关
* 1、获取历史消息
* 2、清空对话上下文
* 3、清空历史
* 4、删除消息
* message management related
* 1. Get chat history
* 2. Clear the conversation context
* 3. Clear history
* 4. Delete messages
*/
import { safeJSONParse } from '../shared/utils/safe-json-parse';
@@ -70,7 +70,7 @@ export class MessageManager {
}
/**
* 将接口获取到的消息历史记录进行数据转换
* Data conversion of the message history obtained by the interface
*/
static convertMessageList = (
messageList: GetHistoryMessageResponse['message_list'],
@@ -86,7 +86,7 @@ export class MessageManager {
};
/**
* 获取历史消息
* Get chat history
*/
async getHistoryMessage(props: GetHistoryMessageProps) {
try {
@@ -102,13 +102,13 @@ export class MessageManager {
eventName: SlardarEvents.MESSAGE_FETCH_HISTORY_ERROR,
error: error as Error,
});
// 此处不应省略异常抛出,上游逻辑分支已检查,无风险
// Exception should not be omitted here, upstream logical branch checked, no risk
throw error;
}
}
/**
* 清空对话上下文
* Clear the conversation context
*/
async clearMessageContextUrl(props: ClearMessageContextProps) {
try {
@@ -127,7 +127,7 @@ export class MessageManager {
}
/**
* 清空历史
* Clear history
*/
async clearHistory(props: ClearHistoryProps) {
try {
@@ -145,7 +145,7 @@ export class MessageManager {
}
/**
* 删除消息
* delete message
*/
async deleteMessage(props: DeleteMessageProps) {
try {
@@ -163,7 +163,7 @@ export class MessageManager {
}
/**
* 打断消息
* interrupt message
*/
async breakMessage(props: BreakMessageProps) {
try {
@@ -181,7 +181,7 @@ export class MessageManager {
}
/**
* 点赞/点踩消息
* Like/click on the message
*/
async reportMessage(props: ReportMessageProps) {
try {
@@ -199,7 +199,7 @@ export class MessageManager {
}
/**
* 语音转文字
* speech-to-text
*/
async chatASR(props: ChatASRProps) {
try {
@@ -210,7 +210,7 @@ export class MessageManager {
headers: {
/**
* https://developer.mozilla.org/zh-CN/docs/Web/API/FormData
* 如果送出时的编码类型被设为 "multipart/form-data",它会使用和表单一样的格式。
* If the encoding type for sending is set to "multipart/form-data", it will use the same format as the form.
*/
'Content-Type': 'multipart/form-data',
},

View File

@@ -32,7 +32,7 @@ export interface PreSendLocalMessageEventsManagerProps {
}
/**
* 主要处理预发送消息的状态管理
* Mainly handles state management of pre-sent messages
*/
export class PreSendLocalMessageEventsManager {
private reportLog: ReportLog;
@@ -55,7 +55,7 @@ export class PreSendLocalMessageEventsManager {
PreSendLocalMessage<ContentType>
> = new Map();
// 新增需要缓存的本地消息
// Add local messages that need to be cached
add(message: Message<ContentType>) {
this.preSendLocalMessageEventsMap.set(
message.extra_info.local_message_id,
@@ -87,7 +87,7 @@ export class PreSendLocalMessageEventsManager {
}
}
// 获取缓存的本地消息
// Get cached local messages
getStashedLocalMessage(local_message_id: string) {
return this.preSendLocalMessageEventsMap.get(local_message_id);
}
@@ -111,7 +111,7 @@ export class PreSendLocalMessageEventsManager {
params: Parameters<PreSendLocalMessageEventsMap[T]>[0],
) {
this.preSendLocalMessageEvents.emit(event, params);
// 发送成功, 清除
// Sent successfully, clear
if (event === PreSendLocalMessageEventsEnum.MESSAGE_SEND_SUCCESS) {
const message = params as Message<ContentType>;
this.preSendLocalMessageEventsMap.delete(
@@ -126,7 +126,7 @@ export class PreSendLocalMessageEventsManager {
return;
}
// 发送失败/超时, 清除
// Send failed/timed out, clear
if (
[
PreSendLocalMessageEventsEnum.MESSAGE_SEND_FAIL,
@@ -145,7 +145,7 @@ export class PreSendLocalMessageEventsManager {
return;
}
// 上传状态修改
// Upload status modification
if (event === PreSendLocalMessageEventsEnum.FILE_UPLOAD_STATUS_CHANGE) {
const message = params as Message<ContentType>;
this.preSendLocalMessageEventsMap.set(
@@ -156,7 +156,7 @@ export class PreSendLocalMessageEventsManager {
}
/**
* 销毁
* destroy
*/
destroy() {
this.preSendLocalMessageEvents.removeAllListeners();

View File

@@ -15,8 +15,8 @@
*/
/**
* 1. 负责规范各种类型消息创建的入参出参,减少消息创建成本
* 2. 对于接收到的消息,针对不同消息类型,吐出指定的消息格式
* 1. Responsible for standardizing imported parameters exported parameters of various types of message creation to reduce message creation costs
* 2. For the received message, spit out the specified message format for different message types
*/
import { nanoid } from 'nanoid';
@@ -51,7 +51,7 @@ import { type PreSendLocalMessageEventsManager } from './presend-local-message-e
import { PreSendLocalMessage } from './presend-local-message';
/**
* 创建预发送消息
* Create a pre-sent message
*/
export interface PreSendLocalMessageFactoryProps {
bot_id?: string;
@@ -99,7 +99,7 @@ export class PreSendLocalMessageFactory {
}
/**
* 创建文本消息
* Create text message
*/
createTextMessage(
props: TextMessageProps,
@@ -121,7 +121,7 @@ export class PreSendLocalMessageFactory {
}
/**
* 创建图片消息
* Create image message
*/
createImageMessage<M extends EventPayloadMaps>(props: {
messageProps: ImageMessageProps<M>;
@@ -151,7 +151,7 @@ export class PreSendLocalMessageFactory {
}),
);
// 预发送消息保存本地
// Pre-sent messages are saved locally
messageEventsManager.add(message);
const uploaderPluginInstance = new UploadPlugin({
@@ -179,7 +179,7 @@ export class PreSendLocalMessageFactory {
}
/**
* 创建文件消息
* Create file message
*/
createFileMessage<M extends EventPayloadMaps>(props: {
messageProps: ImageMessageProps<M>;
@@ -208,7 +208,7 @@ export class PreSendLocalMessageFactory {
mention_list,
}),
);
// 预发送文件消息保存本地
// Pre-send file messages saved locally
messageEventsManager.add(message);
const uploaderPluginInstance = new UploadPlugin({
@@ -241,7 +241,7 @@ export class PreSendLocalMessageFactory {
}
/**
* 创建图文混合消息
* Create a mixed message
*/
createTextAndFileMixMessage(
props: TextAndFileMixMessageProps,
@@ -267,7 +267,7 @@ export class PreSendLocalMessageFactory {
}
/**
* 创建标准化过的消息
* Create standardized messages
*/
createNormalizedMessage<T extends ContentType>(
props: NormalizedMessageProps<T>,
@@ -292,7 +292,7 @@ export class PreSendLocalMessageFactory {
}
/**
* 组装图片消息content
* Assemble image message content
*/
private assembleImageMessageContent(
file: File,
@@ -319,7 +319,7 @@ export class PreSendLocalMessageFactory {
}
/**
* 更新图片消息content
* Update image message content
*/
private updateImageMessageContent(
message: PreSendLocalMessage<ContentType.Image>,
@@ -352,7 +352,7 @@ export class PreSendLocalMessageFactory {
}
/**
* 更新文件消息content
* Update file message content
*/
private updateFileMessageContent(
message: PreSendLocalMessage<ContentType.File>,
@@ -365,7 +365,7 @@ export class PreSendLocalMessageFactory {
}
/**
* 更新图片/文件消息上传状态:success | fail
* Update image/file message Upload status: success | failed
*/
private updateMessageUploadResult(
message: PreSendLocalMessage<ContentType.Image | ContentType.File>,
@@ -376,7 +376,7 @@ export class PreSendLocalMessageFactory {
}
/**
* 组装文件消息content
* Assemble file message content
*/
private assembleFileMessageContent(
file: File,
@@ -399,7 +399,7 @@ export class PreSendLocalMessageFactory {
}
/**
* 组装图文混合消息content
* Assemble mixed message content
*/
private assembleTextAndFileMixMessageContent(
mixList: TextAndFileMixMessagePropsPayload['mixList'],
@@ -455,7 +455,7 @@ export class PreSendLocalMessageFactory {
}
/**
* 组装消息通用字段
* Assembly message common field
*/
private assembleMessageCommonProps<T extends ContentType>(
props: Pick<
@@ -479,16 +479,16 @@ export class PreSendLocalMessageFactory {
// @ts-expect-error should be fixed
extra_info: {
local_message_id: nanoid(),
input_tokens: '', // 用户 query 消耗的 token
output_tokens: '', // llm 输出消耗的 token
token: '', // 总的 token 消耗
input_tokens: '', // User query consumed token
output_tokens: '', // LLM output consumed token
token: '', // Total token consumption
plugin_status: 'success', // "success" or "fail"
time_cost: '', // 中间调用过程的时间
time_cost: '', // Intermediate invocation time of procedure
workflow_tokens: '',
bot_state: '', // { bot_id?: string;agent_id?: string;agent_name?: string; }
plugin_request: '', // plugin 请求的参数
tool_name: '', // 调用的 plugin 下具体的 api 名称
plugin: '', // 调用的 plugin 名称
plugin_request: '', // Parameters of the plugin request
tool_name: '', // Specific API name under the invoked plugin
plugin: '', // Name of the plugin invoked
},
role: 'user',
type: 'question',
@@ -504,7 +504,7 @@ export class PreSendLocalMessageFactory {
}
/**
* 处理发送给服务端的消息结构
* Process the message structure sent to the server
*/
getSendMessageStructure(
message: PreSendLocalMessage<ContentType>,

View File

@@ -15,7 +15,7 @@
*/
/**
* 暴露预发送消息实例,预发送消息用于创建消息后上屏,消息格式和Message<T>一致
* Expose the pre-sent message instance, the pre-sent message is used to be uploaded to the screen after the message is created, and the message format is consistent with Message < T >
*/
import {
@@ -37,25 +37,25 @@ export class PreSendLocalMessage<T extends ContentType> implements Message<T> {
// @ts-expect-error should be fixed
extra_info: Message<T>['extra_info'] = {
local_message_id: '',
input_tokens: '', // 用户 query 消耗的 token
output_tokens: '', // llm 输出消耗的 token
token: '', // 总的 token 消耗
input_tokens: '', // User query consumed token
output_tokens: '', // LLM output consumed token
token: '', // Total token consumption
plugin_status: 'success', // "success" or "fail"
time_cost: '', // 中间调用过程的时间
time_cost: '', // Intermediate invocation time of procedure
workflow_tokens: '',
bot_state: '', // { bot_id?: string;agent_id?: string;agent_name?: string; }
plugin_request: '', // plugin 请求的参数
tool_name: '', // 调用的 plugin 下具体的 api 名称
plugin: '', // 调用的 plugin 名称
plugin_request: '', // Parameters of the plugin request
tool_name: '', // Specific API name under the invoked plugin
plugin: '', // Name of the plugin invoked
};
index?: number; // message在一次 response 的排序
is_finish?: boolean; // 消息状态
section_id: string; // 消息属于的上下文id
index?: number; // Order of messages in a response
is_finish?: boolean; // message status
section_id: string; // The context id to which the message belongs
content_type: ContentType;
debug_messages?: ChunkRaw[];
content: string;
content_obj: MessageContent<T>;
file_upload_result?: 'success' | 'fail'; // 文件上传状态
file_upload_result?: 'success' | 'fail'; // file upload status
role: MessageInfoRole;
type: MessageType;
message_status?: MessageStatus;

View File

@@ -27,20 +27,20 @@ import { type Scene } from '../../chat-sdk/types/interface';
type JSONstring<T = object> = T extends object ? string : never;
/** follow copilot 定义的枚举 */
/** Enumeration following copilot definition */
export enum ChatMessageMetaType {
/** Compatible value */
// eslint-disable-next-line @typescript-eslint/naming-convention
Default_0,
/** 端侧直接替换 */
/** End-to-side direct replacement */
Replaceable,
/** 插入引用 */
/** insert reference */
Insertable,
/** 文档引用 */
/** document citation */
DocumentRef,
/** 知识库引用卡片 */
/** Knowledge Base Reference Card */
KnowledgeCard,
/** 嵌入的多媒体信息只是alice给端上用的因为全链路复用这一个字段所以在这儿改了 */
/** The embedded multimedia information is only used by Alice for the end. Because full link multiplexing uses this field, it has been changed here. */
EmbeddedMultimedia = 100,
}
@@ -49,7 +49,7 @@ export interface ChatMessageMetaInfo {
info?: JSONstring;
}
// 服务端返回的chunk
// Server level returned chunks
export interface ChunkRaw {
index: number;
seq_id: number;
@@ -58,85 +58,85 @@ export interface ChunkRaw {
}
export interface MessageExtraInfo {
local_message_id: string; // 前端消息 id, 用于预发送消息体更新
input_tokens: string; // 用户 query 消耗的 token
output_tokens: string; // llm 输出消耗的 token
token: string; // 总的 token 消耗
local_message_id: string; // Front-end message id, used to pre-send message body updates
input_tokens: string; // User query consumed token
output_tokens: string; // LLM output consumed token
token: string; // Total token consumption
plugin_status: string; // "0" === success or "1" === fail
time_cost: string; // 中间调用过程的时间
time_cost: string; // Intermediate invocation time of procedure
workflow_tokens: string;
bot_state: string; // { bot_id?: string;agent_id?: string;agent_name?: string; }
plugin_request: string; // plugin 请求的参数
tool_name: string; // 调用的 plugin 下具体的 api 名称
plugin: string; // 调用的 plugin 名称
log_id?: string; // chat logId
mock_hit_info?: string; // plugin 命中 mockset 信息
execute_display_name: string; // 展示名称
/** 流式plugin返回的用于替换tool response内容的标识普通plugin没有 */
plugin_request: string; // Parameters of the plugin request
tool_name: string; // Specific API name under the invoked plugin
plugin: string; // Name of the plugin invoked
log_id?: string; // Chat logId
mock_hit_info?: string; // Plugin hit mockset info
execute_display_name: string; // display name
/** The identifier returned by the streaming plugin to replace the tool response content, which is not available in the normal plugin */
stream_plugin_running?: string;
/** 目前仅有中间消息返回*/
/** Currently only intermediate messages are returned.*/
message_title?: string;
remove_query_id?: string; // 有此字段代表触发擦除用户 qeury 安全策略, 值为需要擦出的用户消息的 message_id
new_section_id?: string; // 有此字段代表触发清除上下文安全策略
/** 对应定时任务task_type1-预设任务2-用户任务3-Plugin后台任务 */
remove_query_id?: string; // This field represents the trigger to erase the user qeury security policy, and the value is the message_id of the user message that needs to be erased
new_section_id?: string; // This field represents the trigger to clear the context security policy
/** Corresponding to timed task task_type, 1-preset task, 2-user task, 3-Plugin background task */
task_type?: string;
call_id?: string; // function_calltool_response匹配的id
call_id?: string; // function_call and tool_response matching IDs
}
// 服务端返回的原始Message结构
// Message structure returned by server level
export interface MessageRaw {
role: MessageInfoRole; // 信息发出方的角色
type: MessageType; // 主要用于区分role=assistant的bot返回信息类型
role: MessageInfoRole; // The role of the sender of the message
type: MessageType; // Mainly used to distinguish the type of bot return information for role = assistant
section_id: string;
content_type: ContentType;
content: string;
reasoning_content?: string;
content_time?: number; // 消息发送时间,服务端是 Int64接口拿到需要转一下
user?: string; // 用户唯一标识
content_time?: number; // Message sending time, server level is Int64, you need to transfer it when you get the interface.
user?: string; // user unique identity
/**
* 仅拉取历史返回
* Pull history only
*/
message_status?: MessageStatus;
message_id: string; // 后端消息 id, 可能有多条回复
reply_id: string; // 回复 idquerymessageId
broken_pos?: number; // 打断位置,仅对type = 'answer'生效
/** 拉流 ack 有, 后续没有 */
message_id: string; // Backend message id, there may be multiple replies
reply_id: string; // Reply id, query messageId
broken_pos?: number; // Interrupt position, only valid for type = 'answer'
/** LaLiu ack has it, no follow-up */
mention_list?: MessageMentionListFields['mention_list'];
/** 发送者 id */
/** Sender ID */
sender_id?: string;
extra_info: MessageExtraInfo;
source?: MessageSource;
reply_message?: Message<ContentType>;
meta_infos?: Array<ChatMessageMetaInfo>;
/** 中断消息服务端透传中台的参数,获取中断场景、续聊id */
/** Interrupt message server level pass through the parameters of the middle station, get the interrupt scene, continue chat id */
required_action?: RequiredAction;
/** 卡片状态 */
/** Card Status */
card_status?: Record<string, string>;
}
export const messageSource = {
/** 普通聊天消息 */
/** normal chat message */
Chat: 0,
/** 定时任务 */
/** timed task */
TaskManualTrigger: 1,
/** 通知 */
/** notify */
Notice: 2,
/** 异步结果 */
/** asynchronous result */
AsyncResult: 3,
} as const;
export const taskType = {
/** 预设任务 */
/** preset task */
PresetTask: '1',
/** 用户任务 */
/** user task */
CreatedByUserTask: '2',
/** Plugin 后台任务 */
/** Plugin background task */
PluginTask: '3',
} as const;
export type MessageSource = (typeof messageSource)[keyof typeof messageSource];
// 经过Processor处理后的chunk
// Processor processed chunks
export interface Chunk<T extends ContentType> {
index: number;
seq_id: number;
@@ -144,45 +144,45 @@ export interface Chunk<T extends ContentType> {
message: Message<T>;
}
// 经过Processor处理后的Message
// Message processed by Processor
export type Message<T extends ContentType, V = unknown> = MessageRaw &
MessageMentionListFields & {
bot_id?: string;
preset_bot?: string;
index?: number; // 临时状态,message在一次 response 的排序
is_finish?: boolean; // 临时状态,标识消息是否拉取完成
index?: number; // Temporary state, ordering of messages in a response
is_finish?: boolean; // Temporary state that identifies whether the message has been pulled
/**
* content 经过反序列化
* Content is deserialized
*/
content_obj: MessageContent<T, V>;
/**
* sdk开启了enableDebug模式每条回复消息新增debug_messages字段包含channel 吐出的所有 chunk消息
* SDK has enabled the enableDebug mode, and each reply message adds debug_messages field, including all chunk messages spit out by the channel
*/
debug_messages?: ChunkRaw[];
stream_chunk_buffer?: ChunkRaw[];
stream_message_buffer?: Message<ContentType>[];
/**
* 旧接口未必有该字段;仅 queryanswernotice 等常见显示类型会进行计数。
* - int64 类型,计数从 "1" 开始。
* - 尽管我不认为单聊会有超过 Number.MAX_SAFE_INTEGER 的数值,但是还是用了 big-integer 库来进行处理。
* - 不刷旧数据,因此 ① 旧数据 ② 非常规消息 的值取 "0"
* Older interfaces may not have this field; only common display types such as query, answer, notice, etc. are counted.
* - int64 type, counting starts at "1".
* - Although I don't think there will be more than Number. MAX_SAFE_INTEGER alone, I still use the big-integer library to handle it.
* - Do not brush old data, so ① old data ② unconventional messages, the value is "0"
*/
message_index?: string;
/**
* 仅预发送消息返回
* Pre-send message return only
*/
file_upload_result?: 'success' | 'fail'; // 文件上传状态
file_upload_result?: 'success' | 'fail'; // file upload status
/**
* 本地消息状态, 仅预发送消息返回
* Local message status, only pre-sent messages are returned
*/
local_message_status?: LocalMessageStatus;
/**
* 仅即使消息返回,拉取历史消息无
* Only if the message returns, pull chat history None
*/
logId?: string; // chat logId
logId?: string; // Chat logId
};
// 发送给服务端的消息结构
// The structure of the message sent to the server
export interface SendMessage
extends MessageMentionListFields,
ResumeMessage,
@@ -194,21 +194,21 @@ export interface SendMessage
user?: string;
query: string;
extra: Record<string, string>;
draft_mode?: boolean; // 草稿bot or 线上bot
content_type?: string; // 文件 file 图片 image
regen_message_id?: string; // 重试消息id
local_message_id: string; // 前端本地的message_id extra_info 里面透传返回
chat_history?: Message<ContentType>[]; // 指定聊天上下文, 服务端不落库
draft_mode?: boolean; // Draft bot or online bot
content_type?: string; // Files files pictures images etc
regen_message_id?: string; // Retry message id
local_message_id: string; // The local message_id on the front end is passed back in the extra_info
chat_history?: Message<ContentType>[]; // Specify the chat context, server level does not drop library
}
// 发送给服务端的resume结构体chat类型本身有缺失本期只补充resume相关
// The resume structure sent to the server, the chat type itself is missing, and this issue only supplements resume-related
export interface ResumeMessage {
conversation_id: string;
scene?: Scene; // 场景值
resume_message_id?: string; // 续聊场景服务端所需idreply_id
interrupt_message_id?: string; // 中断的verbose消息id
scene?: Scene; // scene value
resume_message_id?: string; // Continue chatting with the ID required for the scene server level, which is reply_id
interrupt_message_id?: string; // Interrupted verbose message id
tool_outputs?: {
tool_call_id?: string; // 透传中断verbose消息中的tool_call.id
output?: string; // 地理位置授权场景传经纬度
tool_call_id?: string; // Password interrupt tool_call.id in verbose messages
output?: string; // Geographical location authorization scene transmission longitude and latitude
}[];
}
@@ -333,7 +333,7 @@ export interface MessageExtProps {
}
export interface MessageMentionListFields {
/** \@bot 功能,在输入时提及的 bot id */
/** \ @bot function, the bot id mentioned when entering */
mention_list: { id: string }[];
}
@@ -426,11 +426,11 @@ export interface SendMessageOptions {
betweenChunkTimeout?: number;
stream?: boolean;
chatHistory?: Message<ContentType>[];
// 参数会透传给 chat 接口
// Parameters will be passed through to the chat interface
extendFiled?: Record<string, unknown>;
// 透传的header
// Password header
headers?: HeadersInit;
// 是否为重新生成消息, 默认false
// Whether to regenerate the message, the default is false
isRegenMessage?: boolean;
}
@@ -444,28 +444,28 @@ export interface CreateMessageOptions {
}
export enum VerboseMsgType {
/** 跳转节点 */
/** jump node */
JUMP_TO = 'multi_agents_jump_to_agent',
/** 回溯节点 */
/** backtracking node */
BACK_WORD = 'multi_agents_backwards',
/** 长期记忆节点 */
/** long-term memory node */
LONG_TERM_MEMORY = 'time_capsule_recall',
/** finish answer*/
GENERATE_ANSWER_FINISH = 'generate_answer_finish',
/** 流式插件调用状态 */
/** Streaming plugin call status */
STREAM_PLUGIN_FINISH = 'stream_plugin_finish',
/** 知识库召回 */
/** knowledge base recall */
KNOWLEDGE_RECALL = 'knowledge_recall',
/** 中断消息:目前用于地理位置授权 / workflow question 待回复 */
/** Interrupt message: Currently used for geolocation authorization/workflow question pending reply */
INTERRUPT = 'interrupt',
/** hooks调用 */
/** Hooks call */
HOOK_CALL = 'hook_call',
}
export enum InterruptToolCallsType {
FunctionType = 'function', // tool 结果上报
RequireInfoType = 'require_info', // 需要信息,如地理位置
ReplyMessage = 'reply_message', // question 节点
FunctionType = 'function', // Tool result reporting
RequireInfoType = 'require_info', // Required information, such as geographical location
ReplyMessage = 'reply_message', // Question Node
}
export interface VerboseContent {
@@ -474,9 +474,9 @@ export interface VerboseContent {
}
export enum FinishReasonType {
/** 正常回答全部结束 */
/** Normal answer all over */
ALL_FINISH = 0,
/** 中断结束 */
/** end of interrupt */
INTERRUPT = 1,
}

View File

@@ -48,7 +48,7 @@ export interface ParticipantInfo {
user_name?: string;
allow_mention: boolean;
access_path: string | undefined;
/** 是否允许被分享 */
/** Is it allowed to be shared? */
allow_share?: boolean;
}
@@ -106,21 +106,21 @@ export interface DeleteMessageResponse {
export interface BreakMessageProps {
conversation_id: string;
/**
* 被打断问题的 local_message_id
* local_message_id of interrupted questions
*/
local_message_id: string;
/**
* 被打断的问题id
* Interrupted question id
*/
query_message_id: string;
/**
* 当前问题下哪一条回复被打断了
* 仅但被打断的消息 type = 'answer' 时传递
* Which reply was interrupted under the current question?
* Only delivered if the interrupted message type = 'answer'
*/
answer_message_id?: string;
/**
* 打断位置
* 仅但被打断的消息 type = 'answer' 时传递
* interrupt position
* Only delivered if the interrupted message type = 'answer'
*/
broken_pos?: number;
@@ -138,7 +138,7 @@ export type ClearMessageContextParams = Pick<
>;
/*
消息点赞/点踩接口类型定义
Message Like/Click Interface Type Definition
*/
export enum MessageFeedbackType {
Default = 0,
@@ -148,16 +148,16 @@ export enum MessageFeedbackType {
export enum MessageFeedbackDetailType {
UnlikeDefault = 0,
UnlikeHarmful = 1, //有害信息
UnlikeIncorrect = 2, //信息有误
UnlikeNotFollowInstructions = 3, //未遵循指令
UnlikeOthers = 4, //其他
UnlikeHarmful = 1, //Harmful information
UnlikeIncorrect = 2, //incorrect information
UnlikeNotFollowInstructions = 3, //Did not follow instructions
UnlikeOthers = 4, //other
}
export interface MessageFeedback {
feedback_type?: MessageFeedbackType; //反馈类型
detail_types?: MessageFeedbackDetailType[]; //细分类型
detail_content?: string; //负反馈自定义内容,对应用户选择Others
feedback_type?: MessageFeedbackType; //feedback type
detail_types?: MessageFeedbackDetailType[]; //segmentation type
detail_content?: string; //Negative feedback custom content, corresponding to user selection Others
}
export enum ReportMessageAction {
@@ -168,12 +168,12 @@ export enum ReportMessageAction {
export interface ReportMessageProps {
bot_id?: string; //bot_id
biz_conversation_id: string; //会话ID
message_id: string; //消息ID
scene?: Scene; //当前会话所处场景
action: ReportMessageAction; //动作
biz_conversation_id: string; //Session ID
message_id: string; //Message ID
scene?: Scene; //The scene of the current session
action: ReportMessageAction; //action
message_feedback?: MessageFeedback;
// 卡片状态
// Card Status
attributes?: {
card_status?: Record<string, string>;
};
@@ -184,7 +184,7 @@ export interface ReportMessageResponse {
msg: string;
}
/* 消息点赞/点踩接口类型定义:end */
/* Message Like/Click Interface Type Definition: end */
export type ChatASRProps = FormData;

View File

@@ -53,7 +53,7 @@ export class ChatCoreUploadPlugin implements UploadPluginInterface {
try {
const dataAuth = await requestInstance.post(GET_AUTH_URL, {
data: {
// TODO: 确认参数是否要支持传入配置
// TODO: Confirm whether the parameter should support the incoming configuration
scene: 'bot_task',
},
});
@@ -65,9 +65,9 @@ export class ChatCoreUploadPlugin implements UploadPluginInterface {
schema,
useFileExtension: true,
// cp-disable-next-line
imageHost: `https://${upload_host}`, //imageX上传必填
imageHost: `https://${upload_host}`, //imageX upload required
imageConfig: {
serviceId: service_id || '', // 在视频云中申请的服务id
serviceId: service_id || '', // The service id applied for in the video cloud.
},
objectConfig: {
serviceId: service_id || '',

View File

@@ -16,16 +16,16 @@
export type UploadEventName = 'complete' | 'error' | 'progress';
export interface UploadResult {
// 图片 & 文件 uri资源标识用于换取url·
// Image & file URI resource ID, used in exchange for url ·
Uri?: string;
// 图片 & 文件 url
// Image & file url
Url?: string;
// 图片宽度
// image width
ImageWidth?: number;
// 图片高度
// image height
ImageHeight?: number;
}
@@ -33,8 +33,8 @@ export interface UploadResult {
export type FileType = 'object' | 'image' | undefined;
export interface BaseEventInfo {
type: 'success' | 'error'; // 当前任务状态,成功/失败
// 当前状态的描述(随着生命周期不断变化)
type: 'success' | 'error'; // Current task status, success/failure
// Description of the current state (constantly changing with the lifecycle)
extra: {
error?: unknown;
errorCode?: number;
@@ -42,11 +42,11 @@ export interface BaseEventInfo {
};
}
export interface CompleteEventInfo extends BaseEventInfo {
// 上传结果,注意对于不同 type 来说结构不一样,
// Upload the results, note that the structure is different for different types,
uploadResult: UploadResult;
}
export interface ProgressEventInfo extends BaseEventInfo {
// 当前上传总体进度百分比(%)
// Current Upload Overall Progress Percentage (%)
percent: number;
}
export interface EventPayloadMaps {
@@ -65,14 +65,14 @@ export interface UploadPluginProps {
type: FileType;
}
// 上传插件构造函数
// Upload plugin constructor
export interface UploadPluginConstructor<
P extends Record<string, unknown> = Record<string, unknown>,
> {
new (props: UploadPluginProps & P): UploadPluginInterface;
}
// 上传插件接口实现
// Upload plug-in interface implementation
export interface UploadPluginInterface<
M extends EventPayloadMaps = EventPayloadMaps,
> {

View File

@@ -26,22 +26,22 @@ import { type DeployVersion, type ENV } from '../shared/const';
import { slardarInstance, createSlardarConfig } from './slardar';
import { LogOptionsHelper } from './log-options-helper';
// 获取 ReportLog 类的实例类型
// Get the instance type of the ReportLog class
type ReportLogInstance = InstanceType<typeof ReportLog>;
// 获取 slardarTracer 方法的返回类型
// Get the return type of the slardarTracer method
type SlardarTracerReturnType = ReturnType<ReportLogInstance['slardarTracer']>;
// 获取 trace 方法的类型
// Gets the type of the trace method
export type Tracer = SlardarTracerReturnType['trace'];
export type ReportLogType = 'error' | 'info';
/**
* 日志上报
* log report
*/
export interface ReportLogProps {
// 后面等级上报,包含前面等级日志
// Back level report, including previous level log
logLevel?: 'disable' | 'error' | 'info';
env?: ENV;
namespace?: string;
@@ -61,7 +61,7 @@ const defaultReportLogProps: {
};
/**
* namespace不可覆盖
* Namespace cannot be overridden
*/
const unChangeProps = {
namespace: 'chat-core',
@@ -85,7 +85,7 @@ export class ReportLog {
}
/**
* 实例初始化,所有 scope 也只初始化一次
* Instance initialization, all scopes are initialized only once
*/
init() {
console.log('debugger slardar instance init', this.hasSlardarInitd);
@@ -115,7 +115,7 @@ export class ReportLog {
}
/**
* slardar 初始化
* slardar initialization
*/
private initReport(options?: ReportLogProps) {
this.reportLogWithBaseInfo = reporter.createReporterWithPreset(
@@ -125,7 +125,7 @@ export class ReportLog {
}
/**
* 控制台日志初始化
* Console log initialization
* @param options
*/
private initLog(options?: ReportLogProps) {
@@ -134,7 +134,7 @@ export class ReportLog {
});
}
// 判断是否需要上报
// Determine whether to report
private isNeedReport(logType: ReportLogType) {
const { logLevel } = this.ctx.get();
if (logLevel === 'disable') {
@@ -161,14 +161,14 @@ export class ReportLog {
}
/**
* slardar日志 info层级
* Slardar log info hierarchy
*/
slardarInfo(...args: Parameters<typeof reporter.info>) {
this.reportLogWithBaseInfo.info(...args);
}
/**
* slardar日志 success级别
* Slardar log success level
* @param args
*/
slardarSuccess(...args: Parameters<typeof reporter.success>) {
@@ -176,35 +176,35 @@ export class ReportLog {
}
/**
* slardar日志, error级别
* Slardar log, error level
*/
slardarError(...args: Parameters<typeof reporter.error>) {
this.reportLogWithBaseInfo.error(...args);
}
/**
* slardar 自定义事件,用于事件统计
* Slardar custom events for event statistics
*/
slardarEvent(...args: Parameters<typeof reporter.event>) {
this.reportLogWithBaseInfo.event(...args);
}
/**
* slardar 自定义成功事件,用于事件统计
* Slardar custom success events for event statistics
*/
slardarSuccessEvent(...args: Parameters<typeof reporter.event>) {
this.reportLogWithBaseInfo.successEvent(...args);
}
/**
* slardar 自定义错误事件,用于事件统计, 有错误堆栈信息
* Slardar custom error event, for event statistics, with error type information
*/
slardarErrorEvent(...args: Parameters<typeof reporter.errorEvent>) {
this.reportLogWithBaseInfo.errorEvent(...args);
}
/**
* 事件追踪, 用于链路性能统计
* Event tracking for link performance statistics
*/
slardarTracer(...args: Parameters<typeof reporter.tracer>) {
return this.reportLogWithBaseInfo.tracer(...args);

View File

@@ -84,10 +84,10 @@ export class RequestManager {
}
/**
* 传入的request hooks, 可以对每个scene单独做拦截
* Incoming request hooks can be intercepted separately for each scene
*/
private useRequestInterceptor() {
// 执行传入的统一的hooks
// Execute incoming unified hooks
const onCommonBeforeRequest = async (
config: InternalAxiosRequestConfig,
) => {
@@ -101,7 +101,7 @@ export class RequestManager {
}
return merge(config, rest);
};
// 执行每个scene的hooks
// Execute hooks for each scene
const onSceneBeforeRequest = async (config: InternalAxiosRequestConfig) => {
const { scenes } = this.mergedBaseOptions;
if (!scenes) {
@@ -124,22 +124,22 @@ export class RequestManager {
return merge({ ...rest }, config);
};
this.request.interceptors.request.use(async config => {
// eslint-disable-next-line @typescript-eslint/naming-convention -- 临时变量, 挺正常的
// eslint-disable-next-line @typescript-eslint/naming-convention -- temporary variable, quite normal
const _config = await onCommonBeforeRequest(config);
return await onSceneBeforeRequest(_config);
});
}
/**
* 传入的response hooks, 可以对每个scene单独做拦截
* Incoming response hooks, can be intercepted individually for each scene
*/
private useResponseInterceptor() {
// 执行传入的统一的hooks
// Execute incoming unified hooks
const onCommonAfterResponse = async (
response: AxiosResponse,
hooksName: 'onAfterResponse' | 'onErrrorResponse' = 'onAfterResponse',
): Promise<AxiosResponse> => {
// eslint-disable-next-line @typescript-eslint/naming-convention -- 临时变量, 挺正常的
// eslint-disable-next-line @typescript-eslint/naming-convention -- temporary variable, quite normal
let _response: AxiosResponse | Promise<AxiosResponse> = response;
const { hooks } = this.mergedBaseOptions;
if (!hooks) {
@@ -151,13 +151,13 @@ export class RequestManager {
}
return _response;
};
// 执行每个scene的hooks
// Execute hooks for each scene
const onSceneAfterResponse = async (
response: AxiosResponse,
hooksName: 'onAfterResponse' | 'onErrrorResponse' = 'onAfterResponse',
): Promise<AxiosResponse> => {
const { scenes } = this.mergedBaseOptions;
// eslint-disable-next-line @typescript-eslint/naming-convention -- 临时变量, 挺正常的
// eslint-disable-next-line @typescript-eslint/naming-convention -- temporary variable, quite normal
let _response: AxiosResponse | Promise<AxiosResponse> = response;
if (!scenes) {
return response;
@@ -180,12 +180,12 @@ export class RequestManager {
};
this.request.interceptors.response.use(
async response => {
// eslint-disable-next-line @typescript-eslint/naming-convention -- 临时变量, 挺正常的
// eslint-disable-next-line @typescript-eslint/naming-convention -- temporary variable, quite normal
const _response = await onCommonAfterResponse(response);
return await onSceneAfterResponse(_response);
},
async response => {
// eslint-disable-next-line @typescript-eslint/naming-convention -- 临时变量, 挺正常的
// eslint-disable-next-line @typescript-eslint/naming-convention -- temporary variable, quite normal
const _response = await onCommonAfterResponse(
response,
'onErrrorResponse',
@@ -196,7 +196,7 @@ export class RequestManager {
}
/**
* 获取配置信息
* Get configuration information
*/
getSceneConfig(scene: RequestScene): PartiallyRequired<SceneConfig, 'url'> {
const { hooks, scenes, ...rest } = this.mergedBaseOptions;

View File

@@ -37,10 +37,10 @@ const useCsrfRequestHook = (config: InternalAxiosRequestConfig) => {
config.method?.toLowerCase() === 'post' &&
!config.headers.get('content-type')
) {
// 新的 csrf 防护需要 post 请求全部带上这个 header
// The new CSRF protection requires all post requests to have this header.
config.headers.set('content-type', 'application/json');
if (!config.data) {
// axios 会自动在 data 为空时清除 content-type所以需要设置一个空对象
// Axios will automatically clear the content-type when the data is empty, so you need to set an empty object
config.data = {};
}
}

View File

@@ -62,7 +62,7 @@ interface Hooks {
| InternalChannelSendMessageConfig
| Promise<InternalChannelSendMessageConfig>
>;
//为何这样,是由于OpenSdk CozeSdk消息差异过大缺少了Ack消息需要构造出来。
//The reason for this is that OpenSdk and CozeSdk messages are too different, missing Ack messages and need to be constructed.
onGetMessageStreamParser?: (
requestMessageRawBody: Record<string, unknown>,
) => FetchSteamConfig<ParsedEvent>['streamParser'];

View File

@@ -15,19 +15,19 @@
*/
/**
* sdk版本号
* SDK version number
*/
export const CHAT_CORE_VERSION = '1.1.0';
/**
* 使用环境
* usage environment
*/
export type ENV = 'local' | 'boe' | 'production' | 'thirdPart';
/**
* 部署版本
* release: 正式版
* inhouse: 内部测试版本
* Deployment version
* Release: Official Version
* Inhouse: dogfooding version
*/
export type DeployVersion = 'release' | 'inhouse';
@@ -41,11 +41,11 @@ export const SECONDS_PER_SECOND = 1000;
// 1min -> 60*1000ms
export const MILLISECONDS_PER_MINUTE = SECONDS_PER_MINUTE * SECONDS_PER_SECOND;
// 拉流超时
// eslint-disable-next-line @typescript-eslint/no-magic-numbers -- 5min更语义化
// Pull stream timeout
// eslint-disable-next-line @typescript-eslint/no-magic-numbers -- 5min more semantic
export const BETWEEN_CHUNK_TIMEOUT = 5 * MILLISECONDS_PER_MINUTE;
// 发送消息超时
// Send message timed out
export const SEND_MESSAGE_TIMEOUT = MILLISECONDS_PER_MINUTE;
const MAX_RANDOM_NUMBER = 0x10000000;
@@ -56,7 +56,7 @@ function getRandomDeviceID() {
export const randomDeviceID = getRandomDeviceID();
// ws 最大重试次数
// WS maximum number of retries
export const WS_MAX_RETRY_COUNT = 10;
export {

View File

@@ -27,7 +27,7 @@ export const filterEmptyField = <T extends Record<string, unknown>>(
export type PartiallyRequired<T, K extends keyof T> = Omit<T, K> &
Required<Pick<T, K>>;
// enum转换为联合类型
// Enum to union type
export type EnumToUnion<T extends Record<string, string>> = T[keyof T];
export const muteMergeWithArray = (...args: Parameters<typeof merge>) =>

View File

@@ -17,8 +17,8 @@
import { type ENV, type DeployVersion } from '../const';
/**
* 获取 slardar 上报环境
* 不同环境之间数据隔离
* Get slardar report environment
* Data isolation between different environments
* @returns
*/
export const getSlardarEnv = ({