mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-12 12:37:55 +00:00
(feature)(webapp) add multiple parse infos in history message (#256)
Co-authored-by: williamhliu <williamhliu@tencent.com>
This commit is contained in:
@@ -75,6 +75,7 @@ const MessageContainer: React.FC<Props> = ({
|
|||||||
msgValue,
|
msgValue,
|
||||||
score,
|
score,
|
||||||
identityMsg,
|
identityMsg,
|
||||||
|
parseInfos,
|
||||||
msgData,
|
msgData,
|
||||||
filters,
|
filters,
|
||||||
} = msgItem;
|
} = msgItem;
|
||||||
@@ -91,6 +92,7 @@ const MessageContainer: React.FC<Props> = ({
|
|||||||
{identityMsg && <Text position="left" data={identityMsg} />}
|
{identityMsg && <Text position="left" data={identityMsg} />}
|
||||||
<ChatItem
|
<ChatItem
|
||||||
msg={msgValue || msg || ''}
|
msg={msgValue || msg || ''}
|
||||||
|
parseInfos={parseInfos}
|
||||||
msgData={msgData}
|
msgData={msgData}
|
||||||
conversationId={chatId}
|
conversationId={chatId}
|
||||||
modelId={modelId}
|
modelId={modelId}
|
||||||
|
|||||||
@@ -41,101 +41,6 @@
|
|||||||
.ss-chat-table-even-row {
|
.ss-chat-table-even-row {
|
||||||
background-color: #fbfbfb;
|
background-color: #fbfbfb;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-table-wrapper .ant-table-pagination {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: center;
|
|
||||||
margin: 16px 0 1px;
|
|
||||||
row-gap: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-pagination .ant-pagination-prev,
|
|
||||||
.ant-pagination .ant-pagination-next {
|
|
||||||
display: inline-block;
|
|
||||||
min-width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
color: rgba(0, 0, 0, 0.88);
|
|
||||||
line-height: 32px;
|
|
||||||
text-align: center;
|
|
||||||
vertical-align: middle;
|
|
||||||
list-style: none;
|
|
||||||
border-radius: 6px;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.2s;
|
|
||||||
|
|
||||||
.ant-pagination-item-link {
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
padding: 0;
|
|
||||||
font-size: 12px;
|
|
||||||
text-align: center;
|
|
||||||
background-color: transparent;
|
|
||||||
border: 1px solid transparent;
|
|
||||||
border-radius: 6px;
|
|
||||||
outline: none;
|
|
||||||
transition: border 0.2s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-pagination-jump-prev,
|
|
||||||
.ant-pagination-jump-next {
|
|
||||||
.ant-pagination-item-link {
|
|
||||||
display: inline-block;
|
|
||||||
min-width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
color: rgba(0, 0, 0, 0.25);
|
|
||||||
line-height: 32px;
|
|
||||||
text-align: center;
|
|
||||||
vertical-align: middle;
|
|
||||||
list-style: none;
|
|
||||||
border-radius: 6px;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.2s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-pagination-options {
|
|
||||||
display: inline-block;
|
|
||||||
margin-left: 16px;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-pagination .ant-pagination-item {
|
|
||||||
display: inline-block;
|
|
||||||
min-width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
line-height: 30px;
|
|
||||||
text-align: center;
|
|
||||||
vertical-align: middle;
|
|
||||||
list-style: none;
|
|
||||||
background-color: transparent;
|
|
||||||
border: 1px solid transparent;
|
|
||||||
border-radius: 6px;
|
|
||||||
outline: 0;
|
|
||||||
cursor: pointer;
|
|
||||||
user-select: none;
|
|
||||||
margin-inline-end: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-pagination .ant-pagination-item-active {
|
|
||||||
font-weight: 600;
|
|
||||||
background-color: #ffffff;
|
|
||||||
border-color: var(--primary-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-pagination {
|
|
||||||
box-sizing: border-box;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
color: #606266;
|
|
||||||
font-size: 14px;
|
|
||||||
font-variant: tabular-nums;
|
|
||||||
line-height: 1.5715;
|
|
||||||
list-style: none;
|
|
||||||
font-feature-settings: 'tnum', 'tnum';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ const Chat: ForwardRefRenderFunction<any, Props> = (
|
|||||||
{
|
{
|
||||||
id: uuid(),
|
id: uuid(),
|
||||||
type: MessageTypeEnum.AGENT_LIST,
|
type: MessageTypeEnum.AGENT_LIST,
|
||||||
msg: agent?.name || currentAgent?.name || agentList?.[0].name,
|
msg: agent?.name || currentAgent?.name || agentList?.[0]?.name,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
@@ -175,6 +175,7 @@ const Chat: ForwardRefRenderFunction<any, Props> = (
|
|||||||
id: item.questionId,
|
id: item.questionId,
|
||||||
type: MessageTypeEnum.QUESTION,
|
type: MessageTypeEnum.QUESTION,
|
||||||
msg: item.queryText,
|
msg: item.queryText,
|
||||||
|
parseInfos: item.parseInfos,
|
||||||
msgData: item.queryResult,
|
msgData: item.queryResult,
|
||||||
score: item.score,
|
score: item.score,
|
||||||
agentId: currentAgent?.id,
|
agentId: currentAgent?.id,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MsgDataType, SendMsgParamsType } from "../common/type";
|
import { ChatContextType, MsgDataType, SendMsgParamsType } from "../common/type";
|
||||||
|
|
||||||
export enum MessageTypeEnum {
|
export enum MessageTypeEnum {
|
||||||
TEXT = 'text', // 指标文本
|
TEXT = 'text', // 指标文本
|
||||||
@@ -22,6 +22,7 @@ export type MessageItem = {
|
|||||||
modelId?: number;
|
modelId?: number;
|
||||||
agentId?: number;
|
agentId?: number;
|
||||||
entityId?: string;
|
entityId?: string;
|
||||||
|
parseInfos?: ChatContextType[];
|
||||||
msgData?: MsgDataType;
|
msgData?: MsgDataType;
|
||||||
quote?: string;
|
quote?: string;
|
||||||
score?: number;
|
score?: number;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ const ShowCase: React.FC<Props> = ({ agentId, onSendMsg }) => {
|
|||||||
if (pageNo === 1) {
|
if (pageNo === 1) {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
}
|
}
|
||||||
const res = await queryShowCase(agentId, pageNo, 20);
|
const res = await queryShowCase(agentId, pageNo, 30);
|
||||||
if (pageNo === 1) {
|
if (pageNo === 1) {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -210,6 +210,7 @@ export type SuggestionDataType = {
|
|||||||
export type HistoryMsgItemType = {
|
export type HistoryMsgItemType = {
|
||||||
questionId: number;
|
questionId: number;
|
||||||
queryText: string;
|
queryText: string;
|
||||||
|
parseInfos: ChatContextType[];
|
||||||
queryResult: MsgDataType;
|
queryResult: MsgDataType;
|
||||||
chatId: number;
|
chatId: number;
|
||||||
createTime: string;
|
createTime: string;
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import { CheckCircleFilled } from '@ant-design/icons';
|
|||||||
import Loading from './Loading';
|
import Loading from './Loading';
|
||||||
import FilterItem from './FilterItem';
|
import FilterItem from './FilterItem';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import { isMobile } from '../../utils/utils';
|
||||||
|
|
||||||
const { RangePicker } = DatePicker;
|
const { RangePicker } = DatePicker;
|
||||||
|
|
||||||
@@ -84,9 +86,7 @@ const ParseTip: React.FC<Props> = ({
|
|||||||
nativeQuery,
|
nativeQuery,
|
||||||
} = currentParseInfo || {};
|
} = currentParseInfo || {};
|
||||||
|
|
||||||
const { type } = properties || {};
|
|
||||||
const entityAlias = entity?.alias?.[0]?.split('.')?.[0];
|
const entityAlias = entity?.alias?.[0]?.split('.')?.[0];
|
||||||
const entityName = elementMatches?.find(item => item.element?.type === 'ID')?.element.name;
|
|
||||||
|
|
||||||
const entityDimensions = entityInfo?.dimensions?.filter(
|
const entityDimensions = entityInfo?.dimensions?.filter(
|
||||||
item =>
|
item =>
|
||||||
@@ -172,16 +172,15 @@ const ParseTip: React.FC<Props> = ({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{queryMode !== 'ENTITY_ID' &&
|
{queryMode !== 'ENTITY_ID' &&
|
||||||
entityDimensions &&
|
|
||||||
entityDimensions?.length > 0 &&
|
|
||||||
!dimensions?.some(item => item.bizName?.includes('_id')) &&
|
!dimensions?.some(item => item.bizName?.includes('_id')) &&
|
||||||
entityDimensions.some(dimension => dimension.value != null) &&
|
entityDimensions
|
||||||
entityDimensions.map(dimension => (
|
?.filter(dimension => dimension.value != null)
|
||||||
<div className={`${prefixCls}-tip-item`} key={dimension.itemId}>
|
.map(dimension => (
|
||||||
<div className={`${prefixCls}-tip-item-name`}>{dimension.name}:</div>
|
<div className={`${prefixCls}-tip-item`} key={dimension.itemId}>
|
||||||
<div className={itemValueClass}>{dimension.value}</div>
|
<div className={`${prefixCls}-tip-item-name`}>{dimension.name}:</div>
|
||||||
</div>
|
<div className={itemValueClass}>{dimension.value}</div>
|
||||||
))}
|
</div>
|
||||||
|
))}
|
||||||
{(queryMode === 'METRIC_ORDERBY' || queryMode === 'METRIC_MODEL') &&
|
{(queryMode === 'METRIC_ORDERBY' || queryMode === 'METRIC_MODEL') &&
|
||||||
aggType &&
|
aggType &&
|
||||||
aggType !== 'NONE' && (
|
aggType !== 'NONE' && (
|
||||||
@@ -199,9 +198,12 @@ const ParseTip: React.FC<Props> = ({
|
|||||||
const getFilterContent = (filters: any) => {
|
const getFilterContent = (filters: any) => {
|
||||||
const itemValueClass = `${prefixCls}-tip-item-value`;
|
const itemValueClass = `${prefixCls}-tip-item-value`;
|
||||||
const { startDate, endDate } = dateInfo || {};
|
const { startDate, endDate } = dateInfo || {};
|
||||||
|
const tipItemOptionClass = classNames(`${prefixCls}-tip-item-option`, {
|
||||||
|
[`${prefixCls}-mobile-tip-item-option`]: isMobile,
|
||||||
|
});
|
||||||
return (
|
return (
|
||||||
<div className={`${prefixCls}-tip-item-filter-content`}>
|
<div className={`${prefixCls}-tip-item-filter-content`}>
|
||||||
<div className={`${prefixCls}-tip-item-option`}>
|
<div className={tipItemOptionClass}>
|
||||||
<span className={`${prefixCls}-tip-item-filter-name`}>数据时间:</span>
|
<span className={`${prefixCls}-tip-item-filter-name`}>数据时间:</span>
|
||||||
{nativeQuery ? (
|
{nativeQuery ? (
|
||||||
<span className={itemValueClass}>
|
<span className={itemValueClass}>
|
||||||
@@ -209,9 +211,9 @@ const ParseTip: React.FC<Props> = ({
|
|||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
<RangePicker
|
<RangePicker
|
||||||
className={`${prefixCls}-range-picker`}
|
|
||||||
value={[moment(startDate), moment(endDate)]}
|
value={[moment(startDate), moment(endDate)]}
|
||||||
onChange={onDateInfoChange}
|
onChange={onDateInfoChange}
|
||||||
|
getPopupContainer={trigger => trigger.parentNode as HTMLElement}
|
||||||
allowClear={false}
|
allowClear={false}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ const SqlItem: React.FC<Props> = ({ integrateSystem, sqlInfo }) => {
|
|||||||
setSqlType(sqlType === 's2QL' ? '' : 's2QL');
|
setSqlType(sqlType === 's2QL' ? '' : 's2QL');
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
LLM解析SQL
|
S2QL
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{sqlInfo.logicSql && (
|
{sqlInfo.logicSql && (
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ type Props = {
|
|||||||
score?: number;
|
score?: number;
|
||||||
filter?: any[];
|
filter?: any[];
|
||||||
isLastMessage?: boolean;
|
isLastMessage?: boolean;
|
||||||
|
parseInfos?: ChatContextType[];
|
||||||
msgData?: MsgDataType;
|
msgData?: MsgDataType;
|
||||||
triggerResize?: boolean;
|
triggerResize?: boolean;
|
||||||
isDeveloper?: boolean;
|
isDeveloper?: boolean;
|
||||||
@@ -48,6 +49,7 @@ const ChatItem: React.FC<Props> = ({
|
|||||||
filter,
|
filter,
|
||||||
isLastMessage,
|
isLastMessage,
|
||||||
triggerResize,
|
triggerResize,
|
||||||
|
parseInfos,
|
||||||
msgData,
|
msgData,
|
||||||
isDeveloper,
|
isDeveloper,
|
||||||
integrateSystem,
|
integrateSystem,
|
||||||
@@ -152,11 +154,15 @@ const ChatItem: React.FC<Props> = ({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (msgData) {
|
if (msgData) {
|
||||||
const parseInfoValue = { ...msgData.chatContext, queryId: msgData.queryId };
|
const parseInfoOptionsValue =
|
||||||
setParseInfoOptions([parseInfoValue]);
|
parseInfos && parseInfos.length > 0
|
||||||
|
? parseInfos.map(item => ({ ...item, queryId: msgData.queryId }))
|
||||||
|
: [{ ...msgData.chatContext, queryId: msgData.queryId }];
|
||||||
|
const parseInfoValue = parseInfoOptionsValue[0];
|
||||||
|
setParseInfoOptions(parseInfoOptionsValue);
|
||||||
setParseInfo(parseInfoValue);
|
setParseInfo(parseInfoValue);
|
||||||
setDimensionFilters(msgData.chatContext?.dimensionFilters || []);
|
setDimensionFilters(parseInfoValue.dimensionFilters || []);
|
||||||
setDateInfo(msgData.chatContext?.dateInfo);
|
setDateInfo(parseInfoValue.dateInfo);
|
||||||
setExecuteMode(true);
|
setExecuteMode(true);
|
||||||
updateData({ code: 200, data: msgData, msg: 'success' });
|
updateData({ code: 200, data: msgData, msg: 'success' });
|
||||||
} else if (msg) {
|
} else if (msg) {
|
||||||
@@ -238,10 +244,6 @@ const ChatItem: React.FC<Props> = ({
|
|||||||
[`${prefixCls}-content-mobile`]: isMobile,
|
[`${prefixCls}-content-mobile`]: isMobile,
|
||||||
});
|
});
|
||||||
|
|
||||||
const isMetricCard =
|
|
||||||
(data?.queryMode === 'METRIC_DOMAIN' || data?.queryMode === 'METRIC_FILTER') &&
|
|
||||||
data?.queryResults?.length === 1;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={prefixCls}>
|
<div className={prefixCls}>
|
||||||
{!isMobile && integrateSystem !== 'wiki' && (
|
{!isMobile && integrateSystem !== 'wiki' && (
|
||||||
@@ -266,7 +268,7 @@ const ChatItem: React.FC<Props> = ({
|
|||||||
/>
|
/>
|
||||||
{executeMode && (
|
{executeMode && (
|
||||||
<>
|
<>
|
||||||
{parseInfo?.sqlInfo && isDeveloper && integrateSystem !== 'c2' && (
|
{!isMobile && parseInfo?.sqlInfo && isDeveloper && integrateSystem !== 'c2' && (
|
||||||
<SqlItem integrateSystem={integrateSystem} sqlInfo={parseInfo.sqlInfo} />
|
<SqlItem integrateSystem={integrateSystem} sqlInfo={parseInfo.sqlInfo} />
|
||||||
)}
|
)}
|
||||||
<ExecuteItem
|
<ExecuteItem
|
||||||
@@ -292,13 +294,11 @@ const ChatItem: React.FC<Props> = ({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{integrateSystem !== 'showcase' && (
|
{(parseTip !== '' || (executeMode && !executeLoading)) &&
|
||||||
<Tools
|
integrateSystem !== 'c2' &&
|
||||||
queryId={parseInfo?.queryId || 0}
|
integrateSystem !== 'showcase' && (
|
||||||
scoreValue={score}
|
<Tools queryId={parseInfo?.queryId || 0} scoreValue={score} />
|
||||||
// isLastMessage={isLastMessage}
|
)}
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -265,6 +265,20 @@
|
|||||||
row-gap: 6px;
|
row-gap: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-tip-item-option {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
row-gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-mobile-tip-item-option {
|
||||||
|
.ant-picker-panel-container .ant-picker-panels {
|
||||||
|
flex-wrap: wrap !important;
|
||||||
|
width: 280px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&-tip-item-filter-name {
|
&-tip-item-filter-name {
|
||||||
color: var(--text-color-secondary);
|
color: var(--text-color-secondary);
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
@@ -342,6 +356,8 @@
|
|||||||
.@{filter-item-prefix-cls} {
|
.@{filter-item-prefix-cls} {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
row-gap: 6px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
|
||||||
&-filter-name {
|
&-filter-name {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
column-gap: 6px;
|
column-gap: 6px;
|
||||||
|
row-gap: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-metric-card {
|
&-metric-card {
|
||||||
|
|||||||
@@ -49,4 +49,4 @@
|
|||||||
background-color: #efefef !important;
|
background-color: #efefef !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user