diff --git a/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/corrector/BaseSemanticCorrector.java b/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/corrector/BaseSemanticCorrector.java index fe8ab673f..e66afe3d6 100644 --- a/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/corrector/BaseSemanticCorrector.java +++ b/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/corrector/BaseSemanticCorrector.java @@ -30,11 +30,10 @@ public abstract class BaseSemanticCorrector implements SemanticCorrector { public void correct(ChatQueryContext chatQueryContext, SemanticParseInfo semanticParseInfo) { try { - String s2SQL = semanticParseInfo.getSqlInfo().getParsedS2SQL(); + String s2SQL = semanticParseInfo.getSqlInfo().getCorrectedS2SQL(); if (Objects.isNull(s2SQL)) { return; } - semanticParseInfo.getSqlInfo().setCorrectedS2SQL(s2SQL); doCorrect(chatQueryContext, semanticParseInfo); log.debug("sqlCorrection:{} sql:{}", this.getClass().getSimpleName(), semanticParseInfo.getSqlInfo()); diff --git a/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/parser/QueryTypeParser.java b/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/parser/QueryTypeParser.java index 178c6958c..c11182988 100644 --- a/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/parser/QueryTypeParser.java +++ b/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/parser/QueryTypeParser.java @@ -6,8 +6,6 @@ import com.tencent.supersonic.headless.api.pojo.SemanticParseInfo; import com.tencent.supersonic.headless.chat.ChatQueryContext; import lombok.extern.slf4j.Slf4j; -import java.util.Objects; - /** QueryTypeParser resolves query type as either AGGREGATE or DETAIL */ @Slf4j public class QueryTypeParser implements SemanticParser { @@ -17,14 +15,12 @@ public class QueryTypeParser implements SemanticParser { chatQueryContext.getCandidateQueries().forEach(query -> { SemanticParseInfo parseInfo = query.getParseInfo(); String s2SQL = parseInfo.getSqlInfo().getParsedS2SQL(); - if (Objects.isNull(s2SQL)) { - return; - } - QueryType queryType = QueryType.DETAIL; + if (SqlSelectFunctionHelper.hasAggregateFunction(s2SQL)) { queryType = QueryType.AGGREGATE; } + parseInfo.setQueryType(queryType); }); } diff --git a/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/parser/llm/LLMResponseService.java b/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/parser/llm/LLMResponseService.java index 9b0aeb554..59b1d8560 100644 --- a/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/parser/llm/LLMResponseService.java +++ b/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/parser/llm/LLMResponseService.java @@ -49,6 +49,7 @@ public class LLMResponseService { parseInfo.setScore(queryCtx.getRequest().getQueryText().length() * (1 + weight)); parseInfo.setQueryMode(semanticQuery.getQueryMode()); parseInfo.getSqlInfo().setParsedS2SQL(s2SQL); + parseInfo.getSqlInfo().setCorrectedS2SQL(s2SQL); queryCtx.getCandidateQueries().add(semanticQuery); } diff --git a/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/parser/rule/RuleSqlParser.java b/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/parser/rule/RuleSqlParser.java index c8feb94ba..bb3e65305 100644 --- a/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/parser/rule/RuleSqlParser.java +++ b/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/parser/rule/RuleSqlParser.java @@ -40,9 +40,7 @@ public class RuleSqlParser implements SemanticParser { auxiliaryParsers.forEach(p -> p.parse(chatQueryContext)); - if (chatQueryContext.needSQL()) { - candidateQueries.forEach(query -> query.buildS2Sql( - chatQueryContext.getDataSetSchema(query.getParseInfo().getDataSetId()))); - } + candidateQueries.forEach(query -> query.buildS2Sql( + chatQueryContext.getDataSetSchema(query.getParseInfo().getDataSetId()))); } } diff --git a/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/query/llm/s2sql/LLMSqlQuery.java b/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/query/llm/s2sql/LLMSqlQuery.java index 76f5fd880..775bb4202 100644 --- a/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/query/llm/s2sql/LLMSqlQuery.java +++ b/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/query/llm/s2sql/LLMSqlQuery.java @@ -1,6 +1,7 @@ package com.tencent.supersonic.headless.chat.query.llm.s2sql; import com.tencent.supersonic.headless.api.pojo.DataSetSchema; +import com.tencent.supersonic.headless.api.pojo.SqlInfo; import com.tencent.supersonic.headless.chat.query.QueryManager; import com.tencent.supersonic.headless.chat.query.llm.LLMSemanticQuery; import lombok.extern.slf4j.Slf4j; @@ -22,5 +23,8 @@ public class LLMSqlQuery extends LLMSemanticQuery { } @Override - public void buildS2Sql(DataSetSchema dataSetSchema) {} + public void buildS2Sql(DataSetSchema dataSetSchema) { + SqlInfo sqlInfo = parseInfo.getSqlInfo(); + sqlInfo.setCorrectedS2SQL(sqlInfo.getParsedS2SQL()); + } } diff --git a/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/query/rule/RuleSemanticQuery.java b/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/query/rule/RuleSemanticQuery.java index 7552cb377..a2c0895ca 100644 --- a/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/query/rule/RuleSemanticQuery.java +++ b/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/query/rule/RuleSemanticQuery.java @@ -60,6 +60,7 @@ public abstract class RuleSemanticQuery extends BaseSemanticQuery { convertBizNameToName(dataSetSchema, queryStructReq); QuerySqlReq querySQLReq = queryStructReq.convert(); parseInfo.getSqlInfo().setParsedS2SQL(querySQLReq.getSql()); + parseInfo.getSqlInfo().setCorrectedS2SQL(querySQLReq.getSql()); } protected QueryStructReq convertQueryStruct() { diff --git a/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/utils/QueryReqBuilder.java b/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/utils/QueryReqBuilder.java index a1b6f45ea..c84e526ad 100644 --- a/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/utils/QueryReqBuilder.java +++ b/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/utils/QueryReqBuilder.java @@ -147,6 +147,12 @@ public class QueryReqBuilder { return aggregateType.name(); } + private static boolean isDateFieldAlreadyPresent(SemanticParseInfo parseInfo, + String dateField) { + return parseInfo.getDimensions().stream() + .anyMatch(dimension -> dimension.getBizName().equalsIgnoreCase(dateField)); + } + public static Set getOrder(Set existingOrders, AggregateTypeEnum aggregator, SchemaElement metric) { if (existingOrders != null && !existingOrders.isEmpty()) { diff --git a/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2CompanyDemo.java b/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2CompanyDemo.java index 2664d1ef6..77b942f0a 100644 --- a/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2CompanyDemo.java +++ b/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2CompanyDemo.java @@ -56,13 +56,13 @@ public class S2CompanyDemo extends S2BaseDemo { ModelResp model_company = addModel_1(domain, demoDatabase); ModelResp model_brand = addModel_2(domain, demoDatabase); - ModelResp model_company_revenue = addModel_3(domain, demoDatabase); + ModelResp company_brand_revenue_proportion = addModel_3(domain, demoDatabase); ModelResp model_brand_revenue = addModel_4(domain, demoDatabase); - addModelRela_1(domain, model_company_revenue, model_company); - addModelRela_2(domain, model_brand, model_company); - addModelRela_3(domain, model_brand_revenue, model_brand); - addModelRela_4(domain, model_company_revenue, model_brand); + addModelRela(domain, company_brand_revenue_proportion, model_company, "company_id"); + addModelRela(domain, company_brand_revenue_proportion, model_brand, "brand_id"); + addModelRela(domain, model_brand, model_company, "company_id"); + addModelRela(domain, model_brand_revenue, model_brand, "brand_id"); DataSetResp dataset = addDataSet(domain); addAgent(dataset.getId()); @@ -85,7 +85,7 @@ public class S2CompanyDemo extends S2BaseDemo { public DomainResp addDomain() { DomainReq domainReq = new DomainReq(); - domainReq.setName("企业数据"); + domainReq.setName("企业数据域"); domainReq.setBizName("corporate"); domainReq.setParentId(0L); domainReq.setViewers(Arrays.asList("admin", "tom", "jack")); @@ -188,7 +188,7 @@ public class S2CompanyDemo extends S2BaseDemo { public ModelResp addModel_3(DomainResp domain, DatabaseResp database) throws Exception { ModelReq modelReq = new ModelReq(); modelReq.setName("公司品牌收入占比"); - modelReq.setBizName("company_revenue"); + modelReq.setBizName("company_brand_revenue_proportion"); modelReq.setDatabaseId(database.getId()); modelReq.setDomainId(domain.getId()); modelReq.setViewers(Arrays.asList("admin", "tom", "jack")); @@ -210,8 +210,7 @@ public class S2CompanyDemo extends S2BaseDemo { modelDetail.setIdentifiers(identifiers); List measures = new ArrayList<>(); - Measure measure = new Measure("营收占比", "revenue_proportion", AggOperatorEnum.MAX.name(), 1); - measures.add(measure); + measures.add(new Measure("营收占比", "revenue_proportion", AggOperatorEnum.MAX.name(), 1)); measures.add(new Measure("利润占比", "profit_proportion", AggOperatorEnum.MAX.name(), 1)); measures.add(new Measure("支出占比", "expenditure_proportion", AggOperatorEnum.MAX.name(), 1)); modelDetail.setMeasures(measures); @@ -268,7 +267,7 @@ public class S2CompanyDemo extends S2BaseDemo { dataSetReq.setName("企业数据集"); dataSetReq.setBizName("CorporateData"); dataSetReq.setDomainId(domain.getId()); - dataSetReq.setDescription("互联网企业核心经营数据"); + dataSetReq.setDescription("巨头公司核心经营数据"); dataSetReq.setAdmins(Lists.newArrayList("admin")); List dataSetModelConfigs = getDataSetModelConfigs(domain.getId()); @@ -289,10 +288,10 @@ public class S2CompanyDemo extends S2BaseDemo { return dataSetService.save(dataSetReq, defaultUser); } - public void addModelRela_1(DomainResp domain, ModelResp fromModel, ModelResp toModel) { + public void addModelRela(DomainResp domain, ModelResp fromModel, ModelResp toModel, + String joinField) { List joinConditions = Lists.newArrayList(); - joinConditions - .add(new JoinCondition("company_id", "company_id", FilterOperatorEnum.EQUALS)); + joinConditions.add(new JoinCondition(joinField, joinField, FilterOperatorEnum.EQUALS)); ModelRela modelRelaReq = new ModelRela(); modelRelaReq.setDomainId(domain.getId()); modelRelaReq.setFromModelId(fromModel.getId()); diff --git a/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2SingerDemo.java b/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2SingerDemo.java index 3743749c6..310c90828 100644 --- a/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2SingerDemo.java +++ b/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2SingerDemo.java @@ -51,9 +51,7 @@ public class S2SingerDemo extends S2BaseDemo { public void doRun() { try { DomainResp singerDomain = addDomain(); - TagObjectResp singerTagObject = addTagObjectSinger(singerDomain); - ModelResp singerModel = addModel(singerDomain, demoDatabase, singerTagObject); - addTags(singerModel); + ModelResp singerModel = addModel(singerDomain, demoDatabase); long dataSetId = addDataSet(singerDomain, singerModel); addAgent(dataSetId); } catch (Exception e) { @@ -83,7 +81,7 @@ public class S2SingerDemo extends S2BaseDemo { public DomainResp addDomain() { DomainReq domainReq = new DomainReq(); - domainReq.setName("歌手数据"); + domainReq.setName("歌手数据域"); domainReq.setBizName("singer"); domainReq.setParentId(0L); domainReq.setStatus(StatusEnum.ONLINE.getCode()); @@ -95,15 +93,13 @@ public class S2SingerDemo extends S2BaseDemo { return domainService.createDomain(domainReq, defaultUser); } - public ModelResp addModel(DomainResp singerDomain, DatabaseResp s2Database, - TagObjectResp singerTagObject) throws Exception { + public ModelResp addModel(DomainResp singerDomain, DatabaseResp s2Database) throws Exception { ModelReq modelReq = new ModelReq(); modelReq.setName("歌手库"); modelReq.setBizName("singer"); modelReq.setDescription("歌手库"); modelReq.setDatabaseId(s2Database.getId()); modelReq.setDomainId(singerDomain.getId()); - modelReq.setTagObjectId(singerTagObject.getId()); modelReq.setViewers(Arrays.asList("admin", "tom", "jack")); modelReq.setViewOrgs(Collections.singletonList("1")); modelReq.setAdmins(Collections.singletonList("admin")); @@ -128,7 +124,14 @@ public class S2SingerDemo extends S2BaseDemo { modelDetail.setSqlQuery("select singer_name, act_area, song_name, genre, " + "js_play_cnt, down_cnt, favor_cnt from singer"); modelReq.setModelDetail(modelDetail); - return modelService.createModel(modelReq, defaultUser); + ModelResp modelResp = modelService.createModel(modelReq, defaultUser); + + // create dict conf for dimensions + enableDimensionValue(getDimension("act_area", modelResp)); + enableDimensionValue(getDimension("genre", modelResp)); + enableDimensionValue(getDimension("singer_name", modelResp)); + + return modelResp; } private void addTags(ModelResp model) { diff --git a/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2VisitsDemo.java b/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2VisitsDemo.java index 813f8842c..d4d3e3051 100644 --- a/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2VisitsDemo.java +++ b/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2VisitsDemo.java @@ -182,7 +182,7 @@ public class S2VisitsDemo extends S2BaseDemo { public DomainResp addDomain() { DomainReq domainReq = new DomainReq(); - domainReq.setName("产品数据"); + domainReq.setName("产品数据域"); domainReq.setBizName("supersonic"); domainReq.setParentId(0L); domainReq.setStatus(StatusEnum.ONLINE.getCode()); diff --git a/launchers/standalone/src/main/resources/db/data-h2-demo.sql b/launchers/standalone/src/main/resources/db/data-h2-demo.sql index 310c3bc0e..db779c512 100644 --- a/launchers/standalone/src/main/resources/db/data-h2-demo.sql +++ b/launchers/standalone/src/main/resources/db/data-h2-demo.sql @@ -1044,11 +1044,11 @@ insert INTO artist(artist_name,citizenship,gender,g_name) VALUES ('Michel','英 -------S2CompanyDemo -insert into company(imp_date,company_id,company_name,headquarter_address,company_established_time,founder,ceo,annual_turnover,employee_count) VALUES (DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_131','微软','西雅图','1975','盖茨','纳德拉',102300000000,40000); -insert into company(imp_date,company_id,company_name,headquarter_address,company_established_time,founder,ceo,annual_turnover,employee_count) VALUES (DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_132','特斯拉','加州','2003','艾伯哈德','马斯克',376800000000,103699); -insert into company(imp_date,company_id,company_name,headquarter_address,company_established_time,founder,ceo,annual_turnover,employee_count) VALUES (DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_133','谷歌','加州','1998','拉里佩奇','劈柴',321600000000,56310); -insert into company(imp_date,company_id,company_name,headquarter_address,company_established_time,founder,ceo,annual_turnover,employee_count) VALUES (DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_134','亚马逊','加州','1994','贝索斯','贝索斯',28800000000,179000); -insert into company(imp_date,company_id,company_name,headquarter_address,company_established_time,founder,ceo,annual_turnover,employee_count) VALUES (DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_135','英伟达','杭州','1993','黄仁勋','黄仁勋',67500000000,20000); +insert into company(imp_date,company_id,company_name,headquarter_address,company_established_time,founder,ceo,annual_turnover,employee_count) VALUES (DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_131','微软','西雅图','1975','盖茨','纳德拉',102300000000,210000); +insert into company(imp_date,company_id,company_name,headquarter_address,company_established_time,founder,ceo,annual_turnover,employee_count) VALUES (DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_132','特斯拉','加州','2003','艾伯哈德','马斯克',376800000000,140473); +insert into company(imp_date,company_id,company_name,headquarter_address,company_established_time,founder,ceo,annual_turnover,employee_count) VALUES (DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_133','谷歌','加州','1998','拉里佩奇','劈柴',321600000000,182503); +insert into company(imp_date,company_id,company_name,headquarter_address,company_established_time,founder,ceo,annual_turnover,employee_count) VALUES (DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_134','亚马逊','加州','1994','贝索斯','贝索斯',28800000000,950000); +insert into company(imp_date,company_id,company_name,headquarter_address,company_established_time,founder,ceo,annual_turnover,employee_count) VALUES (DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_135','英伟达','杭州','1993','黄仁勋','黄仁勋',67500000000,29000); insert into brand(imp_date,brand_id,brand_name,brand_established_time,company_id,legal_representative,registered_capital) VALUES (DATEADD('DAY', -1, CURRENT_DATE()),'item_brand_13_131','Office','1990','item_enterprise_13_131','盖茨',50000000); insert into brand(imp_date,brand_id,brand_name,brand_established_time,company_id,legal_representative,registered_capital) VALUES (DATEADD('DAY', -1, CURRENT_DATE()),'item_brand_13_132','Windows','1991','item_enterprise_13_131','盖茨',50000000); @@ -1063,24 +1063,22 @@ insert into brand(imp_date,brand_id,brand_name,brand_established_time,company_id insert into company_revenue(imp_date,company_id,brand_id,revenue_proportion,profit_proportion,expenditure_proportion) VALUES ( DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_131','item_brand_13_131',10,10,30); insert into company_revenue(imp_date,company_id,brand_id,revenue_proportion,profit_proportion,expenditure_proportion) VALUES ( DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_131','item_brand_13_132',10,10,30); -insert into company_revenue(imp_date,company_id,brand_id,revenue_proportion,profit_proportion,expenditure_proportion) VALUES ( DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_132','item_brand_13_133',80,80,60); -insert into company_revenue(imp_date,company_id,brand_id,revenue_proportion,profit_proportion,expenditure_proportion) VALUES ( DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_132','item_brand_13_134',80,80,60); -insert into company_revenue(imp_date,company_id,brand_id,revenue_proportion,profit_proportion,expenditure_proportion) VALUES ( DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_133','item_brand_13_135',80,80,60); -insert into company_revenue(imp_date,company_id,brand_id,revenue_proportion,profit_proportion,expenditure_proportion) VALUES ( DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_133','item_brand_13_136',80,80,60); -insert into company_revenue(imp_date,company_id,brand_id,revenue_proportion,profit_proportion,expenditure_proportion) VALUES ( DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_134','item_brand_13_137',80,80,60); -insert into company_revenue(imp_date,company_id,brand_id,revenue_proportion,profit_proportion,expenditure_proportion) VALUES ( DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_134','item_brand_13_138',80,80,60); -insert into company_revenue(imp_date,company_id,brand_id,revenue_proportion,profit_proportion,expenditure_proportion) VALUES ( DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_135','item_brand_13_139',10,10,30); -insert into company_revenue(imp_date,company_id,brand_id,revenue_proportion,profit_proportion,expenditure_proportion) VALUES ( DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_135','item_brand_13_140',10,10,30); - -insert into company_brand_revenue(imp_date,year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '2024','item_brand_13_131',500000000, 300000000,10,10); -insert into company_brand_revenue(imp_date,year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '2024','item_brand_13_132',600000000, 300000000,20,20); -insert into company_brand_revenue(imp_date,year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '2024','item_brand_13_133',700000000, 300000000,30,30); -insert into company_brand_revenue(imp_date,year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '2024','item_brand_13_134',500000000, 300000000,10,10); -insert into company_brand_revenue(imp_date,year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '2024','item_brand_13_135',600000000, 300000000,30,30); -insert into company_brand_revenue(imp_date,year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '2024','item_brand_13_136',700000000, 300000000,40,40); -insert into company_brand_revenue(imp_date,year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '2024','item_brand_13_137',800000000, 300000000,50,50); -insert into company_brand_revenue(imp_date,year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '2024','item_brand_13_138',400000000, 300000000,20,10); -insert into company_brand_revenue(imp_date,year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '2024','item_brand_13_139',300000000, 300000000,60,70); -insert into company_brand_revenue(imp_date,year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '2024','item_brand_13_140',900000000, 300000000,80,100); - +insert into company_revenue(imp_date,company_id,brand_id,revenue_proportion,profit_proportion,expenditure_proportion) VALUES ( DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_132','item_brand_13_133',30,30,60); +insert into company_revenue(imp_date,company_id,brand_id,revenue_proportion,profit_proportion,expenditure_proportion) VALUES ( DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_132','item_brand_13_134',20,20,30); +insert into company_revenue(imp_date,company_id,brand_id,revenue_proportion,profit_proportion,expenditure_proportion) VALUES ( DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_133','item_brand_13_135',40,50,60); +insert into company_revenue(imp_date,company_id,brand_id,revenue_proportion,profit_proportion,expenditure_proportion) VALUES ( DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_133','item_brand_13_136',20,30,40); +insert into company_revenue(imp_date,company_id,brand_id,revenue_proportion,profit_proportion,expenditure_proportion) VALUES ( DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_134','item_brand_13_137',10,30,50); +insert into company_revenue(imp_date,company_id,brand_id,revenue_proportion,profit_proportion,expenditure_proportion) VALUES ( DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_134','item_brand_13_138',40,30,60); +insert into company_revenue(imp_date,company_id,brand_id,revenue_proportion,profit_proportion,expenditure_proportion) VALUES ( DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_135','item_brand_13_139',20,10,80); +insert into company_revenue(imp_date,company_id,brand_id,revenue_proportion,profit_proportion,expenditure_proportion) VALUES ( DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_135','item_brand_13_140',20,10,30); +insert into company_brand_revenue(imp_date,year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '2024','item_brand_13_131',500000000, 13100000000,10,10); +insert into company_brand_revenue(imp_date,year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '2024','item_brand_13_132',600000000, 13200000000,20,20); +insert into company_brand_revenue(imp_date,year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '2024','item_brand_13_133',700000000, 13300000000,30,30); +insert into company_brand_revenue(imp_date,year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '2024','item_brand_13_134',500000000, 13400000000,10,10); +insert into company_brand_revenue(imp_date,year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '2024','item_brand_13_135',600000000, 13500000000,30,30); +insert into company_brand_revenue(imp_date,year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '2024','item_brand_13_136',700000000, 13600000000,40,40); +insert into company_brand_revenue(imp_date,year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '2024','item_brand_13_137',800000000, 13700000000,50,50); +insert into company_brand_revenue(imp_date,year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '2024','item_brand_13_138',400000000, 13800000000,20,10); +insert into company_brand_revenue(imp_date,year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '2024','item_brand_13_139',300000000, 13900000000,60,70); +insert into company_brand_revenue(imp_date,year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '2024','item_brand_13_140',900000000, 14000000000,80,100); diff --git a/launchers/standalone/src/main/resources/s2-config.yaml b/launchers/standalone/src/main/resources/s2-config.yaml index 5382a1e4d..8a26f1936 100644 --- a/launchers/standalone/src/main/resources/s2-config.yaml +++ b/launchers/standalone/src/main/resources/s2-config.yaml @@ -21,7 +21,7 @@ s2: date: true demo: - names: S2VisitsDemo,S2SingerDemo,S2CompanyDemo,S2SmallTalkDemo, + names: S2VisitsDemo,S2SingerDemo,S2CompanyDemo,S2SmallTalkDemo enableLLM: true authentication: diff --git a/launchers/standalone/src/test/java/com/tencent/supersonic/chat/MetricTest.java b/launchers/standalone/src/test/java/com/tencent/supersonic/chat/MetricTest.java index 83c9042b4..d0e251eed 100644 --- a/launchers/standalone/src/test/java/com/tencent/supersonic/chat/MetricTest.java +++ b/launchers/standalone/src/test/java/com/tencent/supersonic/chat/MetricTest.java @@ -27,6 +27,11 @@ import static com.tencent.supersonic.common.pojo.enums.AggregateTypeEnum.SUM; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class MetricTest extends BaseTest { + @Test + public void testMetric() throws Exception { + QueryResult actualResult = submitNewChat("超音数 访问次数", DataUtils.metricAgentId); + } + @Test public void testMetricFilter() throws Exception { QueryResult actualResult = submitNewChat("alice的访问次数", DataUtils.metricAgentId); diff --git a/webapp/packages/chat-sdk/src/components/ChatItem/ExecuteItem.tsx b/webapp/packages/chat-sdk/src/components/ChatItem/ExecuteItem.tsx index 36ba2e776..a72332883 100644 --- a/webapp/packages/chat-sdk/src/components/ChatItem/ExecuteItem.tsx +++ b/webapp/packages/chat-sdk/src/components/ChatItem/ExecuteItem.tsx @@ -1,10 +1,12 @@ -import { Spin, Switch, Tooltip } from 'antd'; +import { Space, Spin, Switch, Tooltip, message } from 'antd'; import { CheckCircleFilled, InfoCircleOutlined } from '@ant-design/icons'; import { PREFIX_CLS, MsgContentTypeEnum } from '../../common/constants'; import { MsgDataType } from '../../common/type'; import ChatMsg from '../ChatMsg'; import WebPage from '../ChatMsg/WebPage'; import Loading from './Loading'; +import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; +import { solarizedlight } from 'react-syntax-highlighter/dist/esm/styles/prism'; import React, { ReactNode, useState } from 'react'; type Props = { @@ -43,10 +45,10 @@ const ExecuteItem: React.FC = ({ const prefixCls = `${PREFIX_CLS}-item`; const [showMsgContentTable, setShowMsgContentTable] = useState(false); const [msgContentType, setMsgContentType] = useState(); - + const [showErrMsg, setShowErrMsg] = useState(false); const titlePrefix = queryMode === 'PLAIN_TEXT' || queryMode === 'WEB_SERVICE' ? '问答' : '数据'; - const getNodeTip = (title: ReactNode, tip?: string) => { + const getNodeTip = (title: ReactNode, tip?: string | ReactNode) => { return ( <>
@@ -65,21 +67,38 @@ const ExecuteItem: React.FC = ({ return getNodeTip(`${titlePrefix}查询中`); } + const handleCopy = (_: string, result: any) => { + result ? message.success('复制SQL成功', 1) : message.error('复制SQL失败', 1); + }; + if (executeTip) { return getNodeTip( <> {titlePrefix}查询失败 {executeErrorMsg && ( - + - + { + setShowErrMsg(!showErrMsg); + }} + > + {!showErrMsg ? '查看' : '收起'} + + )} - {!!data?.queryTimeCost && isDeveloper && ( (耗时: {data.queryTimeCost}ms) )} , - executeTip + + <> + {showErrMsg && ( + + {executeErrorMsg} + + )} + ); } diff --git a/webapp/packages/chat-sdk/src/components/ChatItem/index.tsx b/webapp/packages/chat-sdk/src/components/ChatItem/index.tsx index 72b77fb0c..9c7573503 100644 --- a/webapp/packages/chat-sdk/src/components/ChatItem/index.tsx +++ b/webapp/packages/chat-sdk/src/components/ChatItem/index.tsx @@ -443,7 +443,6 @@ const ChatItem: React.FC = ({ : ''}
- {/* {!isSimpleMode && ( */} <> {currentAgent?.enableFeedback === 1 && !questionId && showExpandParseTip && (
@@ -489,7 +488,6 @@ const ChatItem: React.FC = ({ /> )} - {/* )} */} {executeMode && ( diff --git a/webapp/packages/chat-sdk/src/components/ChatItem/style.less b/webapp/packages/chat-sdk/src/components/ChatItem/style.less index 055970433..ee2a5c0c4 100644 --- a/webapp/packages/chat-sdk/src/components/ChatItem/style.less +++ b/webapp/packages/chat-sdk/src/components/ChatItem/style.less @@ -207,6 +207,15 @@ color: var(--text-color); } + &-code { + margin-top: 10px !important; + padding: 6px 14px 8px !important; + border: 1px solid var(--border-color-base) !important; + border-radius: 4px !important; + background: #f5f8fb !important; + max-width: calc(100vw - 410px); + } + &-execute-title-bar { display: flex; align-items: center; diff --git a/webapp/packages/chat-sdk/src/components/ChatMsg/Table/index.tsx b/webapp/packages/chat-sdk/src/components/ChatMsg/Table/index.tsx index 30907aea1..22ae04df5 100644 --- a/webapp/packages/chat-sdk/src/components/ChatMsg/Table/index.tsx +++ b/webapp/packages/chat-sdk/src/components/ChatMsg/Table/index.tsx @@ -13,11 +13,12 @@ import moment from 'moment'; type Props = { data: MsgDataType; size?: SizeType; + question: string; loading?: boolean; onApplyAuth?: (model: string) => void; }; -const Table: React.FC = ({ data, size, loading, onApplyAuth }) => { +const Table: React.FC = ({ data, size, loading, question, onApplyAuth }) => { const { entityInfo, queryColumns, queryResults } = data; const prefixCls = `${CLS_PREFIX}-table`; @@ -27,6 +28,13 @@ const Table: React.FC = ({ data, size, loading, onApplyAuth }) => { dataIndex: nameEn, key: nameEn, title: name || nameEn, + defaultSortOrder: 'descend', + sorter: + showType === 'NUMBER' + ? (a, b) => { + return a[nameEn] - b[nameEn]; + } + : undefined, render: (value: string | number) => { if (!authorized) { return ( @@ -76,9 +84,11 @@ const Table: React.FC = ({ data, size, loading, onApplyAuth }) => { const dataSource = dateColumn ? queryResults.sort((a, b) => moment(a[dateColumn.nameEn]).diff(moment(b[dateColumn.nameEn]))) : queryResults; - return (
+
+
{question}
+
= ({ case MsgContentTypeEnum.TABLE: return ( @@ -221,6 +222,7 @@ const ChatMsg: React.FC = ({ default: return (
diff --git a/webapp/packages/supersonic-fe/config/config.ts b/webapp/packages/supersonic-fe/config/config.ts index 95fa5d527..cbb160b86 100644 --- a/webapp/packages/supersonic-fe/config/config.ts +++ b/webapp/packages/supersonic-fe/config/config.ts @@ -18,6 +18,7 @@ export default defineConfig({ API_BASE_URL: '/api/semantic/', // 直接在define中挂载裸露的全局变量还需要配置eslint,ts相关配置才能导致在使用中不会飘红,冗余较高,这里挂在进程环境下 CHAT_API_BASE_URL: '/api/chat/', AUTH_API_BASE_URL: '/api/auth/', + SHOW_TAG: false, ...ENV_CONFIG, }, }, diff --git a/webapp/packages/supersonic-fe/config/routes.ts b/webapp/packages/supersonic-fe/config/routes.ts index 3eb7c478a..0326eabf3 100644 --- a/webapp/packages/supersonic-fe/config/routes.ts +++ b/webapp/packages/supersonic-fe/config/routes.ts @@ -115,12 +115,12 @@ const ROUTES = [ }, ], }, - { path: '/tag', name: 'tag', component: './SemanticModel/Insights', envEnableList: [ENV_KEY.SEMANTIC], + hideInMenu: process.env.SHOW_TAG ? false : true, routes: [ { path: '/tag', diff --git a/webapp/packages/supersonic-fe/package.json b/webapp/packages/supersonic-fe/package.json index 6d4504ad4..59cdc5ed3 100644 --- a/webapp/packages/supersonic-fe/package.json +++ b/webapp/packages/supersonic-fe/package.json @@ -69,7 +69,7 @@ "@umijs/route-utils": "2.2.2", "ace-builds": "^1.4.12", "ahooks": "^3.7.7", - "antd": "5.11.2", + "antd": "^5.17.4", "classnames": "^2.2.6", "compression-webpack-plugin": "^11.0.0", "copy-to-clipboard": "^3.3.1", diff --git a/webapp/packages/supersonic-fe/src/components/BatchCtrlDropDownButton/index.tsx b/webapp/packages/supersonic-fe/src/components/BatchCtrlDropDownButton/index.tsx index 7219e5eeb..4e9337e5b 100644 --- a/webapp/packages/supersonic-fe/src/components/BatchCtrlDropDownButton/index.tsx +++ b/webapp/packages/supersonic-fe/src/components/BatchCtrlDropDownButton/index.tsx @@ -38,6 +38,7 @@ const BatchCtrlDropDownButton: FC = ({ exportTagButton: { key: 'exportTagButton', label: '导出为标签', + hidden: !!!process.env.SHOW_TAG, icon: , disabled: disabledList?.includes('exportTagButton'), }, @@ -142,9 +143,11 @@ const BatchCtrlDropDownButton: FC = ({ icon: , disabled: disabledList?.includes('batchDelete'), }, - ].filter((item) => { - return !hiddenList.includes(item.key); - }); + ] + .filter((item) => { + return !hiddenList.includes(item.key); + }) + .filter((item) => !!!item.hidden); const popoverConfig = { title: '选择下载区间', diff --git a/webapp/packages/supersonic-fe/src/pages/Agent/MemorySection.tsx b/webapp/packages/supersonic-fe/src/pages/Agent/MemorySection.tsx index 65fedb48f..7546ee5b5 100644 --- a/webapp/packages/supersonic-fe/src/pages/Agent/MemorySection.tsx +++ b/webapp/packages/supersonic-fe/src/pages/Agent/MemorySection.tsx @@ -217,7 +217,11 @@ const MemorySection = ({ agentId }: Props) => { }; const loadMemoryList = async ( - { filtersValue, current }: { filtersValue?: any; current?: number } = {}, + { + filtersValue, + current, + pageSize, + }: { filtersValue?: any; current?: number; pageSize?: number } = {}, sort?: any, ) => { if (!agentId) { @@ -249,10 +253,11 @@ const MemorySection = ({ agentId }: Props) => { agentId, chatMemoryFilter: filtersValue || filters, current: current || 1, + pageSize, ...sortParams, }); setLoading(false); - const { list, total, pageSize, pageNum } = res.data; + const { list, total, pageNum } = res.data; setDataSource(list); setPagination({ pageSize, diff --git a/webapp/packages/supersonic-fe/src/pages/Agent/service.ts b/webapp/packages/supersonic-fe/src/pages/Agent/service.ts index 1d3be5c47..f7d58d301 100644 --- a/webapp/packages/supersonic-fe/src/pages/Agent/service.ts +++ b/webapp/packages/supersonic-fe/src/pages/Agent/service.ts @@ -35,15 +35,20 @@ export function getMetricList(modelId: number) { }); } -export function getMemeoryList(data: { agentId: number; chatMemoryFilter: any; current: number }) { - const { agentId, chatMemoryFilter, current } = data; +export function getMemeoryList(data: { + agentId: number; + chatMemoryFilter: any; + current: number; + pageSize: number; +}) { + const { agentId, chatMemoryFilter, current, pageSize } = data; return request>('/api/chat/memory/pageMemories', { method: 'POST', data: { ...data, chatMemoryFilter: { agentId, ...chatMemoryFilter }, current, - pageSize: 10, + pageSize: pageSize || 10, sort: 'desc', // orderCondition: 'updatedAt', }, diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Datasource/components/ModelBasicForm.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Datasource/components/ModelBasicForm.tsx index 6d12e115c..0c9f248dc 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Datasource/components/ModelBasicForm.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Datasource/components/ModelBasicForm.tsx @@ -190,14 +190,14 @@ const ModelBasicForm: React.FC = ({