jamis
Version:
一种支持通过JSON配置方式生成页面的组件库
109 lines (108 loc) • 4.8 kB
TypeScript
import type { IListenerAction, ISendChatCompletionsActionArgs, IServiceStore, MessageBlock, OnEventProps, PickClassStyleType, RendererProps, RendererPropsData, SchemaBoolean, SchemaExpression } from 'jamis-core';
import type { MutableRefObject, ReactNode } from 'react';
import type { BaseSchema, RenderSlotBodyType, SchemaSlots } from '../types';
export interface ChatbotSchema extends BaseSchema {
type: 'chatbot';
/**
* 大模型配置
*/
modelProvider: IModelProvider | SchemaExpression;
/** 默认显示在输入框中的消息 */
question?: SchemaExpression;
/**
* 消息在最后发送前的过滤器, 支持表达式和函数
*/
questionFilter?: SchemaExpression | ((data: ChatbotRendererData) => string);
readOnly?: SchemaBoolean;
/**
* 是否可以强制停止, 默认是true
*/
canForceStop?: SchemaBoolean;
/**
* 聊天历史记录
*/
messageHistory?: IMessageItem[] | SchemaExpression;
/**
* 消息框中的占位符
*/
placeholder?: SchemaExpression;
/**
* 是否自动重连上一次的消息, 作为`chatbot`组件时默认不开启, 而在`fai-chatbot`下默认开启
*/
latestMessageAutoReconnect?: SchemaBoolean;
onEvent?: OnEventProps<'mounted' | 'beforeSend' | 'llmResponse' | 'llmEventStreamStart' | 'llmResponseFailed' | 'latestMessageBlocksIsEmpty'>;
slots?: SchemaSlots<'Chatbot-msgItem-answerAvatar' | 'Chatbot-msgItem-answerContent' | 'Chatbot-msgItem-answerHeader' | 'Chatbot-msgItem-answering' | 'Chatbot-msgItem-answerItem' | 'Chatbot-msgItem-answerTitle' | 'Chatbot-msgItem-answerToolbars' | 'Chatbot-msgItem-answerWrap' | 'Chatbot-msgItem-askItem' | 'Chatbot-msgItem-cititionBlock' | 'Chatbot-msgItem-cititionBlockCollapse' | 'Chatbot-msgItem-cititionBlockHeader' | 'Chatbot-msgItem-cititionItemMd' | 'Chatbot-msgItem-copyBtn' | 'Chatbot-msgItem-errorMarkdown' | 'Chatbot-msgItem-mainTextBlock' | 'Chatbot-msgItem-mcpMarkdown' | 'Chatbot-msgItem-oldAnswer' | 'Chatbot-msgItem-placeholder' | 'Chatbot-msgItem-placeholderBlock' | 'Chatbot-msgItem-regenerateBtn' | 'Chatbot-msgItem-toolBlock' | 'Chatbot-msgItem-toolBlockCollapse' | 'Chatbot-msgItem-toolBlockHeader' | 'Chatbot-msgItem' | 'Chatbot-msgList-advices' | 'Chatbot-msgList-header' | 'Chatbot-msgList-placeholder' | 'Chatbot-msgList' | 'Chatbot-sendbox-toolbars' | 'Chatbot-sendbox' | 'Chatbot-disclaimer' | 'Chatbot-sendboxBefore' | 'Chatbot-sendbtn' | 'Chatbot' | (string & {})>;
}
export interface FaiChatbotSchema extends Omit<ChatbotSchema, 'type'> {
type: 'fai-chatbot';
}
/**
* `Chatbot`组件支持的`组件动作`
*/
export type ChatbotActions = IListenerAction<'sendMessage', Partial<IMessageItem>> | IListenerAction<'updateMessageItem', {
messageIndex: number;
messageItem: IMessageItem;
}> | IListenerAction<'updateMessageItems'>;
export interface IModelItem {
/** 模型标识, 如 deepseek-chat / deepseek-reasoner */
id: string;
/** 模型名称, 不填就取 id 值 */
name?: string;
/** 模型分组 */
group?: string;
/** 是否默认 */
default?: boolean;
}
/**
* AI 对话类型配置
*/
export interface IModelProvider extends Omit<ISendChatCompletionsActionArgs, 'onChunk' | 'question' | 'requestHeaders' | 'requestBody'> {
/** 模型名称 */
name: string;
icon?: string;
requestHeaders?: Record<string, any> | ((data: RendererPropsData) => Record<string, any>);
requestBody?: Record<string, any> | ((data: RendererPropsData) => Record<string, any>);
[key: string]: any;
}
interface IMessageItemBase {
id?: string;
question: string;
/**
* @deprecated 请使用`blocks`
*/
answer?: string;
blocks?: MessageBlock[];
/** 答复的模型 */
model?: string;
/**
* 是否有错
*/
error?: boolean | string;
/** 创建时间 */
created?: number | Date;
llmUsage?: any;
/**
* 支持定制单条记录里的样式
*/
slots?: ChatbotSchema['slots'];
}
export type IMessageItem<T = Record<string, any>> = IMessageItemBase & T;
export interface ChatbotRendererData extends RendererPropsData {
activeMessage?: IMessageItem;
sendStatus?: 'waiting' | 'sending' | 'done';
}
export interface ChatbotRendererProps extends RendererProps, Omit<ChatbotSchema, 'onEvent'> {
store: IServiceStore;
data: ChatbotRendererData;
}
export interface MessageItemProps extends PickClassStyleType {
item: IMessageItem;
index: number;
data: ChatbotRendererProps['data'];
forceInView?: boolean;
msgListRef: MutableRefObject<HTMLDivElement | null | undefined>;
render: ChatbotRendererProps['render'];
renderSlotBody: RenderSlotBodyType;
renderAnswerSegment: () => ReactNode;
}
export {};