mirror of
https://github.com/tencentmusic/supersonic.git
synced 2026-04-17 11:54:19 +08:00
[feature](weaapp) add agent
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { Spin } from 'antd';
|
||||
import { PREFIX_CLS } from '../../common/constants';
|
||||
import { MsgDataType } from '../../common/type';
|
||||
import ChatMsg from '../ChatMsg';
|
||||
@@ -8,6 +9,7 @@ import Typing from './Typing';
|
||||
type Props = {
|
||||
question: string;
|
||||
executeLoading: boolean;
|
||||
entitySwitchLoading: boolean;
|
||||
chartIndex: number;
|
||||
executeTip?: string;
|
||||
data?: MsgDataType;
|
||||
@@ -21,6 +23,7 @@ type Props = {
|
||||
const ExecuteItem: React.FC<Props> = ({
|
||||
question,
|
||||
executeLoading,
|
||||
entitySwitchLoading,
|
||||
chartIndex,
|
||||
executeTip,
|
||||
data,
|
||||
@@ -50,13 +53,15 @@ const ExecuteItem: React.FC<Props> = ({
|
||||
|
||||
return (
|
||||
<div className={`${prefixCls}-msg-content`}>
|
||||
<ChatMsg
|
||||
question={question}
|
||||
data={data}
|
||||
chartIndex={chartIndex}
|
||||
isMobileMode={isMobileMode}
|
||||
triggerResize={triggerResize}
|
||||
/>
|
||||
<Spin spinning={entitySwitchLoading}>
|
||||
<ChatMsg
|
||||
question={question}
|
||||
data={data}
|
||||
chartIndex={chartIndex}
|
||||
isMobileMode={isMobileMode}
|
||||
triggerResize={triggerResize}
|
||||
/>
|
||||
</Spin>
|
||||
{!isMetricCard && (
|
||||
<Tools
|
||||
data={data}
|
||||
|
||||
@@ -76,17 +76,7 @@ const ParseTip: React.FC<Props> = ({
|
||||
const entityAlias = entity?.alias?.[0]?.split('.')?.[0];
|
||||
const entityName = elementMatches?.find(item => item.element?.type === 'ID')?.element.name;
|
||||
|
||||
const pluginName = properties?.CONTEXT?.plugin?.name;
|
||||
|
||||
const modeName = pluginName
|
||||
? '调插件'
|
||||
: queryMode.includes('METRIC')
|
||||
? '算指标'
|
||||
: queryMode === 'ENTITY_DETAIL'
|
||||
? '查明细'
|
||||
: queryMode === 'ENTITY_LIST_FILTER'
|
||||
? '做圈选'
|
||||
: '';
|
||||
const { type: agentType, name: agentName } = properties || {};
|
||||
|
||||
const fields =
|
||||
queryMode === 'ENTITY_DETAIL' ? dimensionItems?.concat(metrics || []) : dimensionItems;
|
||||
@@ -101,11 +91,10 @@ const ParseTip: React.FC<Props> = ({
|
||||
}}
|
||||
>
|
||||
{index !== undefined && <div>{index + 1}.</div>}
|
||||
{!pluginName && isOptions && <div className={`${prefixCls}-mode-name`}>{modeName}:</div>}
|
||||
{!!pluginName ? (
|
||||
{!!agentType ? (
|
||||
<div className={`${prefixCls}-tip-item`}>
|
||||
将由问答插件
|
||||
<span className={itemValueClass}>{pluginName}</span>来解答
|
||||
将由{agentType === 'plugin' ? '插件' : '内置'}工具
|
||||
<span className={itemValueClass}>{agentName}</span>来解答
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
@@ -123,7 +112,7 @@ const ParseTip: React.FC<Props> = ({
|
||||
<div className={itemValueClass}>{modelName}</div>
|
||||
</div>
|
||||
)}
|
||||
{modeName === '算指标' && metric && (
|
||||
{metric && (
|
||||
<div className={`${prefixCls}-tip-item`}>
|
||||
<div className={`${prefixCls}-tip-item-name`}>指标:</div>
|
||||
<div className={itemValueClass}>{metric.name}</div>
|
||||
@@ -153,9 +142,13 @@ const ParseTip: React.FC<Props> = ({
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{['METRIC_FILTER', 'METRIC_ENTITY', 'ENTITY_DETAIL', 'ENTITY_LIST_FILTER'].includes(
|
||||
queryMode
|
||||
) &&
|
||||
{[
|
||||
'METRIC_FILTER',
|
||||
'METRIC_ENTITY',
|
||||
'ENTITY_DETAIL',
|
||||
'ENTITY_LIST_FILTER',
|
||||
'ENTITY_ID',
|
||||
].includes(queryMode) &&
|
||||
dimensionFilters &&
|
||||
dimensionFilters?.length > 0 && (
|
||||
<div className={`${prefixCls}-tip-item`}>
|
||||
@@ -198,10 +191,10 @@ const ParseTip: React.FC<Props> = ({
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
const pluginName = parseInfoOptions[0]?.properties?.CONTEXT?.plugin?.name;
|
||||
const agentType = parseInfoOptions[0]?.properties?.type;
|
||||
tipNode = (
|
||||
<div className={`${prefixCls}-tip`}>
|
||||
<div>{!!pluginName ? '您的问题' : '您的问题解析为:'}</div>
|
||||
<div>{!!agentType ? '您的问题' : '您的问题解析为:'}</div>
|
||||
{getTipNode(parseInfoOptions[0])}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -5,11 +5,14 @@ import { PARSE_ERROR_TIP, PREFIX_CLS, SEARCH_EXCEPTION_TIP } from '../../common/
|
||||
import IconFont from '../IconFont';
|
||||
import ParseTip from './ParseTip';
|
||||
import ExecuteItem from './ExecuteItem';
|
||||
import { isMobile } from '../../utils/utils';
|
||||
import classNames from 'classnames';
|
||||
|
||||
type Props = {
|
||||
msg: string;
|
||||
conversationId?: number;
|
||||
modelId?: number;
|
||||
agentId?: number;
|
||||
filter?: any[];
|
||||
isLastMessage?: boolean;
|
||||
msgData?: MsgDataType;
|
||||
@@ -24,6 +27,7 @@ const ChatItem: React.FC<Props> = ({
|
||||
msg,
|
||||
conversationId,
|
||||
modelId,
|
||||
agentId,
|
||||
filter,
|
||||
isLastMessage,
|
||||
isMobileMode,
|
||||
@@ -41,7 +45,7 @@ const ChatItem: React.FC<Props> = ({
|
||||
const [executeLoading, setExecuteLoading] = useState(false);
|
||||
const [executeTip, setExecuteTip] = useState('');
|
||||
const [executeMode, setExecuteMode] = useState(false);
|
||||
const [entitySwitching, setEntitySwitching] = useState(false);
|
||||
const [entitySwitchLoading, setEntitySwitchLoading] = useState(false);
|
||||
|
||||
const [chartIndex, setChartIndex] = useState(0);
|
||||
|
||||
@@ -76,37 +80,42 @@ const ChatItem: React.FC<Props> = ({
|
||||
) => {
|
||||
setExecuteMode(true);
|
||||
setExecuteLoading(true);
|
||||
const { data } = await chatExecute(msg, conversationId!, parseInfoValue);
|
||||
setExecuteLoading(false);
|
||||
const valid = updateData(data);
|
||||
if (onMsgDataLoaded) {
|
||||
let parseOptions: ChatContextType[] = parseInfoOptions || [];
|
||||
if (
|
||||
parseInfoOptions &&
|
||||
parseInfoOptions.length > 1 &&
|
||||
(parseInfoOptions[0].queryMode.includes('METRIC') ||
|
||||
parseInfoOptions[0].queryMode.includes('ENTITY'))
|
||||
) {
|
||||
parseOptions = parseInfoOptions.filter(
|
||||
(item, index) =>
|
||||
index === 0 ||
|
||||
(!item.queryMode.includes('METRIC') && !item.queryMode.includes('ENTITY'))
|
||||
try {
|
||||
const { data } = await chatExecute(msg, conversationId!, parseInfoValue);
|
||||
setExecuteLoading(false);
|
||||
const valid = updateData(data);
|
||||
if (onMsgDataLoaded) {
|
||||
let parseOptions: ChatContextType[] = parseInfoOptions || [];
|
||||
if (
|
||||
parseInfoOptions &&
|
||||
parseInfoOptions.length > 1 &&
|
||||
(parseInfoOptions[0].queryMode.includes('METRIC') ||
|
||||
parseInfoOptions[0].queryMode.includes('ENTITY'))
|
||||
) {
|
||||
parseOptions = parseInfoOptions.filter(
|
||||
(item, index) =>
|
||||
index === 0 ||
|
||||
(!item.queryMode.includes('METRIC') && !item.queryMode.includes('ENTITY'))
|
||||
);
|
||||
}
|
||||
onMsgDataLoaded(
|
||||
{
|
||||
...data.data,
|
||||
chatContext: parseInfoValue,
|
||||
parseOptions: parseOptions.length > 1 ? parseOptions.slice(1) : undefined,
|
||||
},
|
||||
valid
|
||||
);
|
||||
}
|
||||
onMsgDataLoaded(
|
||||
{
|
||||
...data.data,
|
||||
chatContext: parseInfoValue,
|
||||
parseOptions: parseOptions.length > 1 ? parseOptions.slice(1) : undefined,
|
||||
},
|
||||
valid
|
||||
);
|
||||
} catch (e) {
|
||||
setExecuteLoading(false);
|
||||
setExecuteTip(SEARCH_EXCEPTION_TIP);
|
||||
}
|
||||
};
|
||||
|
||||
const onSendMsg = async () => {
|
||||
setParseLoading(true);
|
||||
const { data: parseData } = await chatParse(msg, conversationId, modelId, filter);
|
||||
const { data: parseData } = await chatParse(msg, conversationId, modelId, agentId, filter);
|
||||
setParseLoading(false);
|
||||
const { code, data } = parseData || {};
|
||||
const { state, selectedParses } = data || {};
|
||||
@@ -115,10 +124,9 @@ const ChatItem: React.FC<Props> = ({
|
||||
state === ParseStateEnum.FAILED ||
|
||||
selectedParses == null ||
|
||||
selectedParses.length === 0 ||
|
||||
(selectedParses.length === 1 &&
|
||||
!selectedParses[0]?.modelName &&
|
||||
!selectedParses[0]?.properties?.CONTEXT?.plugin?.name &&
|
||||
selectedParses[0]?.queryMode !== 'WEB_PAGE')
|
||||
(selectedParses.length > 0 &&
|
||||
!selectedParses[0]?.properties?.type &&
|
||||
!selectedParses[0]?.queryMode)
|
||||
) {
|
||||
setParseTip(PARSE_ERROR_TIP);
|
||||
return;
|
||||
@@ -146,9 +154,9 @@ const ChatItem: React.FC<Props> = ({
|
||||
}, [msg, msgData]);
|
||||
|
||||
const onSwitchEntity = async (entityId: string) => {
|
||||
setEntitySwitching(true);
|
||||
setEntitySwitchLoading(true);
|
||||
const res = await switchEntity(entityId, data?.chatContext?.modelId, conversationId || 0);
|
||||
setEntitySwitching(false);
|
||||
setEntitySwitchLoading(false);
|
||||
setData(res.data.data);
|
||||
};
|
||||
|
||||
@@ -164,11 +172,15 @@ const ChatItem: React.FC<Props> = ({
|
||||
}
|
||||
};
|
||||
|
||||
const contentClass = classNames(`${prefixCls}-content`, {
|
||||
[`${prefixCls}-content-mobile`]: isMobile,
|
||||
});
|
||||
|
||||
return (
|
||||
<div className={prefixCls}>
|
||||
<div className={`${prefixCls}-section`}>
|
||||
<IconFont type="icon-zhinengsuanfa" className={`${prefixCls}-avatar`} />
|
||||
<div className={`${prefixCls}-content`}>
|
||||
{!isMobile && <IconFont type="icon-zhinengsuanfa" className={`${prefixCls}-avatar`} />}
|
||||
<div className={contentClass}>
|
||||
<ParseTip
|
||||
parseLoading={parseLoading}
|
||||
parseInfoOptions={parseOptions || parseInfoOptions.slice(0, 1)}
|
||||
@@ -181,11 +193,12 @@ const ChatItem: React.FC<Props> = ({
|
||||
</div>
|
||||
{executeMode && data?.queryMode !== 'WEB_PAGE' && (
|
||||
<div className={`${prefixCls}-section`}>
|
||||
<IconFont type="icon-zhinengsuanfa" className={`${prefixCls}-avatar`} />
|
||||
<div className={`${prefixCls}-content`}>
|
||||
{!isMobile && <IconFont type="icon-zhinengsuanfa" className={`${prefixCls}-avatar`} />}
|
||||
<div className={contentClass}>
|
||||
<ExecuteItem
|
||||
question={msg}
|
||||
executeLoading={executeLoading}
|
||||
entitySwitchLoading={entitySwitchLoading}
|
||||
executeTip={executeTip}
|
||||
chartIndex={chartIndex}
|
||||
data={data}
|
||||
|
||||
@@ -117,6 +117,10 @@
|
||||
width: calc(100% - 50px);
|
||||
}
|
||||
|
||||
&-content-mobile {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&-metric-info-list {
|
||||
margin-top: 30px;
|
||||
display: flex;
|
||||
@@ -136,7 +140,6 @@
|
||||
|
||||
&-typing-bubble {
|
||||
width: fit-content;
|
||||
// padding: 16px !important;
|
||||
}
|
||||
|
||||
&-text-bubble {
|
||||
|
||||
Reference in New Issue
Block a user