281 Commits

Author SHA1 Message Date
zyclove
f7ce9480bb fix:java.io.NotSerializableException: com.tencent.supersonic.common.pojo.Order (#2121)
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-03-03 16:56:23 +08:00
jerryjzhang
f8104687cc (fix)(launcher)Fix mysql schema DDL.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-03-03 11:12:49 +08:00
jerryjzhang
6eba693982 (fix)(docker)Fix Dockerfile.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
(fix)(docker)Fix Dockerfile.
2025-03-02 21:54:17 +08:00
jerryjzhang
b871ae542a (fix)(assembly)Fix windows daemon script. 2025-03-02 18:36:02 +08:00
jerryjzhang
3ca48e1ca1 (release)Release 0.9.10.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-03-02 11:56:23 +08:00
jerryjzhang
ea7238304d (fix)(docker)Fix Dockerfile by removing apt-get install.
(fix)(docker)Fix Dockerfile.

(fix)(docker)Fix Dockerfile.
2025-03-02 11:28:27 +08:00
williamhliu
1746db53c1 (fix)(supersonic-fe) fix the issue where adding, deleting, and modifying domain and model do not automatically update data (#2116)
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-03-01 16:16:29 +08:00
jerryjzhang
90c2f8b374 (fix)(headless)Fix occasional NPE in SqlBuilder.
Some checks failed
supersonic CentOS CI / build (21) (push) Has been cancelled
supersonic mac CI / build (21) (push) Has been cancelled
supersonic ubuntu CI / build (21) (push) Has been cancelled
supersonic windows CI / build (21) (push) Has been cancelled
2025-02-28 17:11:05 +08:00
jerryjzhang
bd64bf1f62 (improvement)(headless)Optimize relationship probe in translation of multi-table join scenarios.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-02-27 21:53:14 +08:00
jerryjzhang
56cfddea60 (improvement)(format)Follow the code style.
Some checks failed
supersonic CentOS CI / build (21) (push) Has been cancelled
supersonic mac CI / build (21) (push) Has been cancelled
supersonic ubuntu CI / build (21) (push) Has been cancelled
supersonic windows CI / build (21) (push) Has been cancelled
2025-02-26 19:19:25 +08:00
jerryjzhang
0aa002882d (improvement)(license)Change license from MIT to Apache 2.0. 2025-02-26 19:17:06 +08:00
zyclove
5e3bafb953 feat:Support kyuubi presto trino (#2109) 2025-02-26 17:33:14 +08:00
zyclove
11ff99cdbe fix: Caused by: java.io.NotSerializableException: DateConf、SchemaNameLengthComparator、SqlEvaluation and etc. (#2110) 2025-02-26 17:32:20 +08:00
mislayming
f9198cb8e0 (improvement)(chat) Enhancing the capability of embedding with LLM-based secondary judgment. (#2096) 2025-02-24 12:55:39 +08:00
jerryjzhang
b5aa6e046e (feature)(chat)Support agent-level permission management.
Some checks failed
supersonic CentOS CI / build (21) (push) Has been cancelled
supersonic mac CI / build (21) (push) Has been cancelled
supersonic ubuntu CI / build (21) (push) Has been cancelled
supersonic windows CI / build (21) (push) Has been cancelled
2025-02-24 09:25:12 +08:00
williamhliu
29271f7278 (feature)(supersonic-fe) add permission manage in agent (#2095) 2025-02-24 08:18:48 +08:00
jerryjzhang
50ed340ae0 (fix)(headless)Fix NPE issue.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-02-23 14:55:56 +08:00
jerryjzhang
75f623404d (fix)(headless)Fix aggregator parsing of struct query.
Some checks failed
supersonic CentOS CI / build (21) (push) Has been cancelled
supersonic mac CI / build (21) (push) Has been cancelled
supersonic ubuntu CI / build (21) (push) Has been cancelled
supersonic windows CI / build (21) (push) Has been cancelled
2025-02-21 20:04:12 +08:00
jerryjzhang
94e853f57e [improvement][headless]Support dataSetNames that contain dash.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
[improvement][headless]Support dataSetNames that contain dash.

[improvement][headless]Support dataSetNames that contain dash.
2025-02-21 01:25:02 +08:00
jerryjzhang
5fa3607874 [fix][chat]Fix NPE issue. 2025-02-21 00:07:14 +08:00
jerryjzhang
1e01f3ef60 (improvement)(headless)Optimize metric matching in populating data format.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-02-20 19:06:55 +08:00
beat4ocean
1155ac10d8 [fix][project] Fix the issue of SpringDoc not working. (#2081) 2025-02-20 18:31:50 +08:00
jacktpy
5a22590661 [fix]修复快速创建模型时不能自动创建维度 (#2083) 2025-02-20 18:24:33 +08:00
jerryjzhang
fc67411618 (fix)(launcher)Fix database initialization script of mysql and psotgresql.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-02-20 12:31:17 +08:00
jacktpy
c03be2f5d8 [fix]修复创建模型catalog校验异常 (#2077) 2025-02-20 11:02:40 +08:00
jerryjzhang
08a2e889e7 [feature][headless]Introduce TranslatorConfig to make result limit configurable via system parameter.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-02-19 23:25:56 +08:00
jerryjzhang
87fa778416 [fix][launcher]Fix S2VisitsDemo to avoid broken demo. 2025-02-19 22:00:55 +08:00
jerryjzhang
b70b7ed01a (improvement)(launcher)Auto increment init user.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-02-19 18:11:36 +08:00
jerryjzhang
335e1f9ada (fix)(headless)Fix updating measure agg doesn't take effect. 2025-02-19 18:11:02 +08:00
Hyman_bz
33268bf3d9 feat: add support starrocks and multiple catalog (#2066) 2025-02-19 18:00:22 +08:00
beat4ocean
86b9d2013a [fix][headless-fe] Fix the issue of incorrect time sorting in charts. (#2069) 2025-02-19 17:34:31 +08:00
jerryjzhang
aced1dfd3e (fix)(launcher)Fix swagger docs. 2025-02-19 14:15:09 +08:00
jerryjzhang
d1e5e8777a (improvement)(chat)Try to find all fields in the same model to avoid unnecessary join.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-02-18 21:29:39 +08:00
jerryjzhang
b743585d3e (fix)(headless)Fix NPE issue. 2025-02-18 19:07:39 +08:00
weimengdalao
9aa305ca7a [fix][headless]fix Check if metricFilters is empty not dimensionFilters (#2064) 2025-02-18 12:49:43 +08:00
jerryjzhang
fe51882031 Merge remote-tracking branch 'origin/master' 2025-02-18 12:48:35 +08:00
jerryjzhang
17a3dd052c (improvement)(chat)LLM might output table or column with `` enclose, should handle with it. 2025-02-18 12:48:26 +08:00
jerryjzhang
2e71b9b892 [improvement][docker]Deprecate and remove db_init container in docker-compose.yml.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-02-17 22:55:22 +08:00
jerryjzhang
a067d2cace Merge remote-tracking branch 'origin/master' 2025-02-17 21:21:49 +08:00
jerryjzhang
32793ecf69 (improvement)(chat)Determine if with statement is supported and send explicitly message in the prompt to the LLM. 2025-02-17 21:21:43 +08:00
zyclove
43b96edc77 fix: Cannot find module 'antd/lib/avatar/avatar' with antd 5.24.0 (#2062)
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-02-17 16:17:36 +08:00
jerryjzhang
f31db98aba (improvement)(project)Introduce aibi-env.sh script to simplify user settings.
(improvement)(project)Introduce aibi-env.sh script to simplify user settings.

(improvement)(project)Introduce aibi-env.sh script to simplify user settings.
2025-02-17 14:36:15 +08:00
jerryjzhang
348d6df6a2 [fix][headless]Fix table name of SqlQuery.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-02-16 20:27:51 +08:00
jerryjzhang
91768892cf [fix][chat]Fix parse state when error message is returned.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-02-16 18:18:21 +08:00
jerryjzhang
0868a18b08 Merge branch 'master' of https://github.com/tencentmusic/supersonic 2025-02-16 15:40:13 +08:00
jerryjzhang
46316cadcf [fix][headless]Adjust none operator enum. 2025-02-16 15:38:53 +08:00
williamhliu
f804371134 (fix) 修复修改密码问题 (#2060)
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
Co-authored-by: williamhliu <williamhliu@tencent.com>
2025-02-16 10:56:51 +08:00
jerryjzhang
d6620e6ea7 [fix][headless]Adjust none operator enum. 2025-02-16 10:40:11 +08:00
jerryjzhang
cc2d6a21c2 [fix][headless]Fix NPE issue.
Some checks failed
supersonic CentOS CI / build (21) (push) Has been cancelled
supersonic mac CI / build (21) (push) Has been cancelled
supersonic ubuntu CI / build (21) (push) Has been cancelled
supersonic windows CI / build (21) (push) Has been cancelled
2025-02-14 21:32:36 +08:00
beat4ocean
19395f369a [fix][headless] Fix models cannot be deleted if related indicators/dimensions are marked as deleted. (#2056) 2025-02-14 21:31:26 +08:00
zyclove
baae7f74b8 【feat】Optimize the web app build script to include checks for the build results, preventing partial successes. (#2058) 2025-02-14 21:22:42 +08:00
zyclove
e9d9c4591d feat:add create index scripts for opensearch (#2055) 2025-02-14 21:22:01 +08:00
jerryjzhang
6cc145935d [fix][auth]Fix user registration and resetPassword issue.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-02-14 00:28:36 +08:00
zyclove
89e07509de 【bug】Webapp fix error TS2551: Property 'nameEn' does not exist on type 'ColumnType'. Did you mean 'name'? (#2051)
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-02-13 14:05:55 +08:00
zyclove
d942d35c93 feat:add opensearch (#2049)
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-02-12 20:30:58 +08:00
jianjun.xu
198c7c69e6 [fix][headless] The output on the front-end dimension page is abnormal after the model management is modified (#2048) 2025-02-12 20:29:17 +08:00
zyclove
cb139a54e8 feat:add openapi supports ApiVersion (#2050) 2025-02-12 20:28:10 +08:00
Hwwwww
f412ae4539 [fix][headless] Fix having and alias column not enclosed in backticks. (#2042)
Some checks failed
supersonic CentOS CI / build (21) (push) Has been cancelled
supersonic mac CI / build (21) (push) Has been cancelled
supersonic ubuntu CI / build (21) (push) Has been cancelled
supersonic windows CI / build (21) (push) Has been cancelled
2025-02-10 18:55:32 +08:00
Hwwwww
3ca46bee36 [fix][headless] Fix order by and group by not enclosed in backticks. (#2041)
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-02-10 12:55:05 +08:00
Hwwwww
a8157ee769 [fix][headless] Solve the problem of SQL execution error when alias is Chinese (#2039)
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-02-09 22:59:35 +08:00
jerryjzhang
eef7b3c443 [improvement][chat]Make a few code restructure.
Some checks failed
supersonic CentOS CI / build (21) (push) Has been cancelled
supersonic mac CI / build (21) (push) Has been cancelled
supersonic ubuntu CI / build (21) (push) Has been cancelled
supersonic windows CI / build (21) (push) Has been cancelled
2025-02-08 14:39:23 +08:00
jerryjzhang
c34b85c8a4 [improvement][chat]Introduce new chat workflow state.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-02-08 09:24:23 +08:00
jerryjzhang
be2e380b4c [fix][headless]Fix published metrics issue.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-02-07 15:35:30 +08:00
jianjun.xu
eeaebe06aa [fix][chat-server] Compatible history data (#2033) 2025-02-07 14:48:48 +08:00
jianjun.xu
4ab9cd715d Fixed abnormal message rendering caused by abnormal value of indicator name field, Supplement for PR #2030 (#2031)
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-02-07 10:18:52 +08:00
jerryjzhang
fd306db3fe [fix][chat]Fix compatibility issue. 2025-02-07 09:52:03 +08:00
Ron Zhang
30adaa3f20 feat: 修复Bug #2029 (#2030) 2025-02-07 09:28:06 +08:00
jerryjzhang
cc66ebd684 [improvement][chat]Add queryId to QueryNLReq.
Some checks failed
supersonic CentOS CI / build (21) (push) Has been cancelled
supersonic mac CI / build (21) (push) Has been cancelled
supersonic ubuntu CI / build (21) (push) Has been cancelled
supersonic windows CI / build (21) (push) Has been cancelled
2025-02-05 17:24:48 +08:00
Jun Zhang
ef161fe1f2 [improvement][headless]Add ANY agg operator and remove table name from bizName of field. (#2028)
Some checks failed
supersonic CentOS CI / build (21) (push) Has been cancelled
supersonic mac CI / build (21) (push) Has been cancelled
supersonic ubuntu CI / build (21) (push) Has been cancelled
supersonic windows CI / build (21) (push) Has been cancelled
2025-02-02 19:43:43 +08:00
Jun Zhang
0417f12324 [fix][headless]Fix schema corrector test cases. (#2027) 2025-02-02 15:52:23 +08:00
Jun Zhang
d294fec2a0 [fix](headless)Fix a number of issues. (#2026)
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-02-02 12:50:29 +08:00
Jun Zhang
de92b357df (Fix)(headless)Fix expression replacement issue. (#2024)
Some checks failed
supersonic CentOS CI / build (21) (push) Has been cancelled
supersonic mac CI / build (21) (push) Has been cancelled
supersonic ubuntu CI / build (21) (push) Has been cancelled
supersonic windows CI / build (21) (push) Has been cancelled
2025-01-30 08:54:42 +08:00
LXW
be5eeae707 (improvement)(headless) Opt logic of obtaining faker user (#2014)
Some checks failed
supersonic CentOS CI / build (21) (push) Has been cancelled
supersonic mac CI / build (21) (push) Has been cancelled
supersonic ubuntu CI / build (21) (push) Has been cancelled
supersonic windows CI / build (21) (push) Has been cancelled
* (improvement)(headless) opt logic of obtaining faker user

* (improvement)(headless) Fill in default values for data set creating

* (improvement)(headless) modify dataEvent type when creating model

---------

Co-authored-by: lxwcodemonkey
2025-01-19 14:59:33 +08:00
jerryjzhang
65f0096724 [fix][headless]Fix expr conversion issue.
Some checks failed
supersonic CentOS CI / build (21) (push) Has been cancelled
supersonic mac CI / build (21) (push) Has been cancelled
supersonic ubuntu CI / build (21) (push) Has been cancelled
supersonic windows CI / build (21) (push) Has been cancelled
2025-01-17 20:43:05 +08:00
jerryjzhang
416488b919 [fix][headless]Fix create model exception.
Some checks failed
supersonic CentOS CI / build (21) (push) Has been cancelled
supersonic mac CI / build (21) (push) Has been cancelled
supersonic ubuntu CI / build (21) (push) Has been cancelled
supersonic windows CI / build (21) (push) Has been cancelled
2025-01-16 11:17:29 +08:00
jerryjzhang
8900fde4a3 [improvement][headless]Remove unnecessary model name checks.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-01-15 20:14:35 +08:00
jerryjzhang
2b28aeea6f [fix][headless]Fix a set of known issues.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-01-14 20:31:59 +08:00
jerryjzhang
329756056c [improvement][headless]Opt code format.
Some checks failed
supersonic CentOS CI / build (21) (push) Has been cancelled
supersonic mac CI / build (21) (push) Has been cancelled
supersonic ubuntu CI / build (21) (push) Has been cancelled
supersonic windows CI / build (21) (push) Has been cancelled
2025-01-11 09:25:27 +08:00
jianjun.xu
715adb5260 [fix][queryStat] bug Fixes exceptions caused by code merging (#2004)
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-01-10 16:07:29 +08:00
jerryjzhang
da6d28c18c [improvement][docker]Support multi-platform builds.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-01-09 14:45:01 +08:00
jerryjzhang
cd863705a4 [improvement][chat]Opt log infos.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-01-08 20:46:44 +08:00
czeeland
f264b3160f [improvement]QueryUtils.isNumberType method add type real、tinyint、smallint for database fields (#2001) 2025-01-08 20:45:39 +08:00
jerryjzhang
61e22c2104 [improvement][headless]Add sql field in the OntologyQuery. 2025-01-08 19:43:32 +08:00
jerryjzhang
6e4260f9f1 [improvement][headless]Enable ErrorMsgRewriteProcessor by default. 2025-01-08 19:38:58 +08:00
czeeland
ab74acc84a [improvement][headless]Update the model without updating the names of metrics and dimensions. (#1999)
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-01-08 16:25:58 +08:00
jerryjzhang
4e653c1fb1 [improvement][headless]Expression replacement logic supports more complex sql.
Some checks failed
supersonic CentOS CI / build (21) (push) Has been cancelled
supersonic mac CI / build (21) (push) Has been cancelled
supersonic ubuntu CI / build (21) (push) Has been cancelled
supersonic windows CI / build (21) (push) Has been cancelled
2025-01-05 16:09:42 +08:00
jerryjzhang
6fcfdc15e1 [improvement][headless]Remove deprecated tag related constructs. 2025-01-05 15:42:54 +08:00
jerryjzhang
4738b9d01b [improvement][headless]Release brand new version of Translator module.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-01-05 00:00:18 +08:00
jerryjzhang
e0f7ec0f40 [improvement][headless]Add modelId to QueryColumn.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-01-04 22:25:49 +08:00
jerryjzhang
7b46ef64fd [fix][headless]Fix getModelList filter issue. 2025-01-04 22:25:45 +08:00
lxwcodemonkey
6af345044a (fix)(headless) fix schemaItem useCnt always 0 2025-01-04 22:25:39 +08:00
lxwcodemonkey
4821f31e15 (improvement)(headless) Avoiding incorrect showType caused by converting header fields to lowercase 2025-01-04 22:25:32 +08:00
Jun Zhang
be59b051fc [fix][headless]Fix logic bug in s2sql parsing. (#1996)
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-01-04 14:58:48 +08:00
jerryjzhang
83cb6967e7 [improvement][headless]Setup thread pool for data event listeners. 2025-01-04 14:37:48 +08:00
jerryjzhang
22f6190e7c [improvement][chat]Introduce parameter to control # of semantic fields should be sent to the LLM.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-01-03 22:44:12 +08:00
RickyZZQ
43140e695b [fix]Fix user feedback for query memory bug (#1992)
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-01-03 09:05:28 +08:00
jerryjzhang
a46e89af56 [improvement][headless]Simplify query sql and fix demo.
Some checks failed
supersonic CentOS CI / build (21) (push) Has been cancelled
supersonic mac CI / build (21) (push) Has been cancelled
supersonic ubuntu CI / build (21) (push) Has been cancelled
supersonic windows CI / build (21) (push) Has been cancelled
2024-12-31 09:13:56 +08:00
jerryjzhang
a2f54d4c80 [improvement][headless]Remove unnecessary Database class
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2024-12-29 21:58:39 +08:00
jerryjzhang
24eaffb2d5 [improvement][headless]Adapt to new master version. 2024-12-29 19:44:37 +08:00
jerryjzhang
739514ddfa [fix][chat&headless]Adapt to new master. 2024-12-29 10:45:18 +08:00
jerryjzhang
6486257c9e [improvement][chat&headless]Remove deprecated system time fields. 2024-12-29 03:22:42 +08:00
HB
6f5e477e3c [fix][queryStat] Fields that are inconsistent between the table Filed and DO (#1986) 2024-12-28 15:15:06 +08:00
yxm-coding
683f01c33b 修复Network中所有前端路由资源请求均报404错误 #1982 (#1985) 2024-12-27 20:54:53 +08:00
yxm-coding
3e1e5ae209 fix(launchers): update addViewController to correctly redirect to the front-end page when accessing the domain while logged in (#1981) 2024-12-27 15:35:50 +08:00
jerryjzhang
0612833618 [fix][chat]Fix logic in s2sql parsing. 2024-12-27 14:18:20 +08:00
jerryjzhang
7145f27671 [fix][chat]Fix logic in s2sql parsing. 2024-12-27 14:12:10 +08:00
jerryjzhang
920d8f280a [improvement][headless]Add more checks to accept() of QueryParsers. 2024-12-27 11:57:23 +08:00
jerryjzhang
ade03627ce [improvement][headless]Support s2sql with union all statements. 2024-12-27 11:25:33 +08:00
lexluo09
a23d1071a3 [improvement][chat] Optimize the logic for obtaining the generic thread pool (#1979) 2024-12-26 23:37:55 +08:00
pisces
ce9ae1c0c1 feat(chat-sdk/chatitem): 消息支持导出图表图片 (#1937) 2024-12-26 23:30:29 +08:00
jerryjzhang
d834e98a66 [improvement][chat]Introduce AllFieldMapper to increase parsing robustness when normal pipeline fails. 2024-12-26 23:28:59 +08:00
jerryjzhang
94267f6028 [improvement][chat]Introduce AllFieldMapper to increase parsing robustness when normal pipeline fails.
[improvement][chat]Introduce `AllFieldMapper` to increase parsing robustness when normal pipeline fails.
2024-12-26 23:20:43 +08:00
jerryjzhang
a4d2df4063 [improvement][project]Adapt docker related scripts to new version. 2024-12-26 15:02:28 +08:00
jerryjzhang
8e03531424 [improvement][project]Adapt docker related scripts to new version. 2024-12-26 14:23:08 +08:00
jerryjzhang
16600ed6f0 [improvement][chat]Support reviewing query memory based on direct user feedback. 2024-12-26 09:49:47 +08:00
jerryjzhang
d04a086c88 [improvement][chat]Support reviewing query memory based on direct user feedback. 2024-12-26 09:47:13 +08:00
jerryjzhang
68963b9ec9 [improvement][project]Adjust files based on code style. 2024-12-26 09:12:12 +08:00
jerryjzhang
265e51c429 [fix][chat]Memory enabled by the review task should be stored in embedding store. 2024-12-26 09:03:32 +08:00
jerryjzhang
d40400d2a4 [fix][chat]Memory enabled by the review task should be stored in embedding store. 2024-12-26 00:11:12 +08:00
lexluo09
c483bb891a [fix][chat] Fix the issue with the order of parallel execution in the map. (#1976) 2024-12-25 20:52:52 +08:00
zehuiHuang
6738aba19e Issues 1974 (#1975)
* [fix][common]Support 'BETWEEN AND' query condition parameter parsing `CURRENT`. #1972
2024-12-25 19:33:40 +08:00
zehuiHuang
493a8035cd [fix][common]Support 'BETWEEN AND' query condition parameter parsing CURRENT. #1972 (#1973) 2024-12-25 19:33:26 +08:00
lwhy
b425c49c5b [fix][headless] Unexpected update of dimensions when modifying a model (#1971) 2024-12-25 19:33:10 +08:00
jerryjzhang
4dca6eec5a [improvement][project]Adjust github issue forms. 2024-12-23 20:24:35 +08:00
pisces
642d6a02e1 feat(chat-sdk/chatitem): 消息支持导出图表图片 (#1937) 2024-12-23 09:05:56 +08:00
jerryjzhang
5de5b0a5e2 [fix][headless]Fix issue in determining mysql version to support with statement. 2024-12-22 21:40:58 +08:00
jerryjzhang
214d90772d [improvement][headless]Move discovery of query models from SemanticNode to SqlQueryParser.
[improvement][headless]Move discovery of query models from SemanticNode to `SqlQueryParser`.
2024-12-22 21:15:23 +08:00
jerryjzhang
d8b8c4e6b9 [improvement][headless]Move discovery of query models from SemanticNode to QueryParser. 2024-12-22 17:45:32 +08:00
jerryjzhang
10a510409f [fix][headless]Fix issue in determining mysql version to support with statement. 2024-12-21 22:50:55 +08:00
jerryjzhang
19c1d306df [fix][headless]Fix issue in determining mysql version to support with statement. 2024-12-21 22:50:22 +08:00
lexluo09
8c6ae62522 [improvement][chat] Change the embedding to execute in parallel (#1967) 2024-12-21 20:32:03 +08:00
jerryjzhang
758d170bbf [fix][project]Use SpringDoc to support swagger in Spring 3.x 2024-12-21 19:48:38 +08:00
jerryjzhang
7dc013dfb3 [fix][project]Use SpringDoc to support swagger in Spring 3.x 2024-12-21 19:48:20 +08:00
lexluo09
72780f9acf [improvement][common] The thread pool adopts a generic thread pool configuration. (#1966) 2024-12-21 19:01:53 +08:00
jerryjzhang
7b49412bde Merge branch 'master' of github.com:tencentmusic/supersonic 2024-12-21 18:49:41 +08:00
jerryjzhang
9f63aca132 [fix][chat]Fix minor logic issue. 2024-12-21 18:49:27 +08:00
jerryjzhang
933b54085c [fix][chat]Fix minor logic issue. 2024-12-21 18:49:07 +08:00
lexluo09
f7fce0217f [improvement][chat] Use a generic thread pool to perform concurrent mapping. (#1965) 2024-12-21 11:58:02 +08:00
jerryjzhang
c2d155705f Merge remote-tracking branch 'origin/master' 2024-12-20 12:43:36 +08:00
jerryjzhang
5faf5f3ac4 [improvement][project]Adjust github issue forms. 2024-12-20 12:43:22 +08:00
jerryjzhang
d88d8b3beb [project]Adjust the LICENSE to impose stricter restrictions in commercial scenarios. 2024-12-19 22:49:03 +08:00
jerryjzhang
caf03588c6 [project]Adjust the LICENSE to impose stricter restrictions in commercial scenarios. 2024-12-19 22:48:13 +08:00
jerryjzhang
4cb2256351 [improvement][headless]Merge function of QueryConverter abstraction to QueryParser. 2024-12-19 21:45:24 +08:00
lexluo09
8b69d57c4b [improvement][chat] Fix the issue with the DatabaseMatchStrategy variable under multi-threading (#1963) 2024-12-19 10:04:17 +08:00
jerryjzhang
91856ddebd [improvement][chat]Inject schema info into the prompt of LLMSqlCorrector. 2024-12-19 09:55:32 +08:00
jerryjzhang
94e97c9a1d [improvement][chat]Use accept() pattern to improve code readability. 2024-12-19 09:47:38 +08:00
jerryjzhang
9faa858c22 [improvement][chat]Use accept() pattern to improve code readability. 2024-12-19 09:34:38 +08:00
jerryjzhang
6fcd105249 [improvement][chat]Inject schema info into the prompt of LLMSqlCorrector. 2024-12-18 12:04:06 +08:00
jerryjzhang
1d0f5612b7 [fix][headless]Fix NEP problem. 2024-12-18 09:05:32 +08:00
wwsheng009
b57eed47e2 SAP HANA DATABASE Source support improvement[优化SAPhana数据库的支持] (#1959)
* (improvement)(database) update the support for sap hana database source

* (fix)(common) add the default timeout for ZhipuAiEmbeddingModel,avoid the program error
2024-12-17 21:52:19 +08:00
jerryjzhang
aa3b8997bd [improvement][headless]Merge function of QueryConverter abstraction to QueryParser. 2024-12-17 19:45:37 +08:00
jerryjzhang
84944fa341 [improvement][headless]Support count(1) as metric calculation expression. 2024-12-17 16:36:12 +08:00
jerryjzhang
b4c19533a4 [improvement][headless]bizName of dimension and metric shall not be the same as the field name in the database table. 2024-12-17 15:18:08 +08:00
jerryjzhang
831fbfe475 [improvement][headless]Refactor translator module to make code logic cleaner and more readable. 2024-12-15 21:03:57 +08:00
Jun Zhang
62b64c74a3 Merge branch 'tencentmusic:master' into aibi 2024-12-15 18:26:41 +08:00
jerryjzhang
ed5c129a4a [improvement][headless]Enhance translation of derived metrics and refactor translator code. 2024-12-15 17:25:33 +08:00
jerryjzhang
14087825df Merge branch 'master' of github.com:supersonicbi/supersonic into ssmaster 2024-12-15 08:49:47 +08:00
jerryjzhang
f9cc395e49 [improvement][headless]Refactor translator module to make code logic cleaner and more readable. 2024-12-15 08:48:48 +08:00
lxwcodemonkey
d014a27aff [improvement][Headless] Publish event when creating and updating model 2024-12-14 17:46:01 +08:00
wwsheng009
2e28a4c7a5 Sap hanadb support,SAP HANA数据库适配支持 (#1958)
Some checks failed
supersonic CentOS CI / build (21) (push) Has been cancelled
supersonic mac CI / build (21) (push) Has been cancelled
supersonic ubuntu CI / build (21) (push) Has been cancelled
supersonic windows CI / build (21) (push) Has been cancelled
2024-12-13 09:06:21 +08:00
jerryjzhang
9f8793bfe2 [improvement][headless]Remove fixed TimeEnums fields. 2024-12-12 00:27:09 +08:00
Jun Zhang
a8868ba9ab Merge branch 'tencentmusic:master' into master 2024-12-11 22:48:14 +08:00
jerryjzhang
8c44c9f42f [improvement][headless]Remove fixed TimeEnums fields. 2024-12-11 21:33:43 +08:00
jerryjzhang
f97ac1da83 [improvement][headless]Introduce DerivedMetricConverter and optimize metric creation in S2VisitsDemo. 2024-12-11 17:51:02 +08:00
mislayming
07f6be51c7 SpringBoot3升级 (#1947)
Some checks failed
supersonic CentOS CI / build (21) (push) Has been cancelled
supersonic mac CI / build (21) (push) Has been cancelled
supersonic ubuntu CI / build (21) (push) Has been cancelled
supersonic windows CI / build (21) (push) Has been cancelled
2024-12-11 17:09:20 +08:00
Jun Zhang
4062a13126 Merge branch 'tencentmusic:master' into master 2024-12-11 09:06:51 +08:00
Jun Zhang
f6622319a4 [project]Fix centos unit tests. (#1955)
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2024-12-11 09:06:30 +08:00
jerryjzhang
2567742115 [project]Fix centos unit tests. 2024-12-11 09:05:30 +08:00
Jun Zhang
215391bb2d Merge branch 'tencentmusic:master' into master 2024-12-10 22:48:56 +08:00
Jun Zhang
4a6938956b [project]Only sanity test with JDK 21. (#1952)
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2024-12-10 21:15:38 +08:00
jerryjzhang
e586983ff1 [project]Only sanity test with JDK 21.
[project]Only sanity test with JDK 21.
2024-12-10 19:39:18 +08:00
Jun Zhang
a12486591b Merge branch 'tencentmusic:master' into master 2024-12-10 19:25:58 +08:00
mislayming
848b4a1e44 (fix)(chat-api) 小范围整理一下lombok标签,增加默认构造函数避免高版本json框架无法实例化报错 (#1951) 2024-12-10 19:14:32 +08:00
mislayming
a298c670ed (improvement)(auth) 增强UserStrategy的可配置性 (#1949) 2024-12-10 19:09:22 +08:00
Jun Zhang
f2f7caa32c Merge branch 'tencentmusic:master' into master 2024-12-09 22:13:50 +08:00
siriusbo
3db9a0dcec [improvement][headless-core] 提升join准确性,修复join条件错误问题 (#1945)
Some checks are pending
supersonic CentOS CI / build (11) (push) Waiting to run
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic CentOS CI / build (8) (push) Waiting to run
supersonic mac CI / build (11) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic mac CI / build (8) (push) Waiting to run
supersonic ubuntu CI / build (11) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (8) (push) Waiting to run
supersonic windows CI / build (11) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
supersonic windows CI / build (8) (push) Waiting to run
2024-12-09 22:13:27 +08:00
pisces
09ea5db0ba fix(agent): 助理管理列表切换分页后启用禁用状态展示错误 (#1946)
Some checks are pending
supersonic CentOS CI / build (11) (push) Waiting to run
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic CentOS CI / build (8) (push) Waiting to run
supersonic mac CI / build (11) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic mac CI / build (8) (push) Waiting to run
supersonic ubuntu CI / build (11) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (8) (push) Waiting to run
supersonic windows CI / build (11) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
supersonic windows CI / build (8) (push) Waiting to run
2024-12-09 18:46:52 +08:00
Jun Zhang
8000ee5237 Merge branch 'tencentmusic:master' into master 2024-12-08 13:32:53 +08:00
Jun Zhang
e55f43c737 [improvement]Use QueryWrapper in place of hard-coded SQLs (#1944)
Some checks are pending
supersonic CentOS CI / build (11) (push) Waiting to run
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic CentOS CI / build (8) (push) Waiting to run
supersonic mac CI / build (11) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic mac CI / build (8) (push) Waiting to run
supersonic ubuntu CI / build (11) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (8) (push) Waiting to run
supersonic windows CI / build (11) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
supersonic windows CI / build (8) (push) Waiting to run
* [improvement][launcher]Use API to get element ID avoiding hard-code.

* [fix][launcher]Fix mysql scripts.

* [improvement][launcher]Support DuckDB database and refactor translator code structure.

* [improvement][headless-fe] Revamped the interaction for semantic modeling routing and successfully implemented the switching between dimension and dataset management.

* [improvement][Headless] Add table ddl in Dbschema

* [improvement][Headless] Add get database by type

* [improvement][Headless] Supports automatic batch creation of models based on db table names.

* [improvement][Headless] Supports getting domain by bizName

* [improvement][launcher]Refactor unit tests and demo data.

* [fix][launcher]Change default vector dimension to 512.

* [improvement](Dict) add dimValueAliasMap info for KnowledgeBaseService

* [improvement][headless]Use QueryWrapper to replace hard-code SQL in mapper xml.

* [improvement][chat]Introduce ChatMemory to delegate ChatMemoryDO.

* [fix][common]Fix embedding store sys configs.

* [fix][common]Fix postgres schema, using varchar instead of char.

* [improvement][launcher]Change supersonic docker deployment from mysql to postgres.

* [Fix][launcher]Fix a number of issues related to semantic modeling.

* [Fix][headless]Fix the evaluation logic of agg type.

* [fix][assembly]Fix Dockerfile and add docker compose run script.

* [fix][chat]Fix "multiple assignments to same column "similar_queries".

* [improvement][headless]Use LamdaQueryWrapper to avoid hard-coded column names.

* [improvement][headless]Refactor headless infra to support advanced semantic modelling.

* [improvement][headless]Change class name `Dim` to `Dimension`.

* [improvement][chat]Introduce `TimeFieldMapper` to always map time field.

* [fix][headless]Remove unnecessary dimension existence check.

* [fix][chat]Fix adjusted filters don't take effect.

---------
2024-12-08 13:32:29 +08:00
jerryjzhang
43ba1a0ba6 [fix][chat]Fix adjusted filters don't take effect. 2024-12-08 13:27:34 +08:00
jerryjzhang
4bd521020a [fix][headless]Remove unnecessary dimension existence check. 2024-12-08 10:26:34 +08:00
jerryjzhang
aa400176a5 [improvement][chat]Introduce TimeFieldMapper to always map time field. 2024-12-04 23:48:43 +08:00
jerryjzhang
c98c5ade9e [improvement][headless]Change class name Dim to Dimension.
[improvement][headless]Change class name `Dim` to `Dimension`.
2024-12-04 22:06:41 +08:00
jerryjzhang
28d5f38ffb [improvement][headless]Refactor headless infra to support advanced semantic modelling. 2024-12-04 14:56:34 +08:00
jerryjzhang
9e24fd04a5 [fix][launcher]Fix mysql sql script. 2024-12-03 19:56:08 +08:00
jerryjzhang
02c6a7d404 [improvement][headless]Use LamdaQueryWrapper to avoid hard-coded column names. 2024-12-03 19:47:49 +08:00
jerryjzhang
fe57a4e5cf [fix][chat]Fix "multiple assignments to same column "similar_queries". 2024-12-03 19:33:41 +08:00
jerryjzhang
79ab1be306 [fix][assembly]Fix Dockerfile and add docker compose run script. 2024-12-03 19:11:02 +08:00
jerryjzhang
3e903b862e [Fix][headless]Fix the evaluation logic of agg type. 2024-12-02 23:39:53 +08:00
jerryjzhang
0ce79cbfc0 [Fix][launcher]Fix a number of issues related to semantic modeling. 2024-12-02 21:38:15 +08:00
tristanliu
cf79ac9ece [fix][chat-sdk] fix build warning 2024-12-02 14:20:36 +08:00
jerryjzhang
02f0063846 [improvement][launcher]Change supersonic docker deployment from mysql to postgres. 2024-12-02 12:57:47 +08:00
jerryjzhang
b8924ed45e [fix][common]Fix postgres schema, using varchar instead of char. 2024-12-02 09:33:33 +08:00
jerryjzhang
27c6b8ecb1 [fix][common]Fix embedding store sys configs. 2024-12-02 08:50:31 +08:00
jerryjzhang
7de3662259 [improvement][chat]Introduce ChatMemory to delegate ChatMemoryDO. 2024-12-02 01:31:37 +08:00
jerryjzhang
ba4d92e11c Merge remote-tracking branch 'ssbi/master' into ssmaster 2024-12-02 00:00:50 +08:00
jerryjzhang
350b6089dc [improvement][headless]Use QueryWrapper to replace hard-code SQL in mapper xml. 2024-12-02 00:00:35 +08:00
daikon12
350567755a Merge remote-tracking branch 'origin/master' 2024-12-01 23:49:04 +08:00
daikon12
efac1efdb0 [improvement](Dict) add dimValueAliasMap info for KnowledgeBaseService 2024-12-01 23:48:51 +08:00
jerryjzhang
4592131b55 [fix][launcher]Change default vector dimension to 512. 2024-12-01 23:17:38 +08:00
jerryjzhang
b3b1498af7 [fix][launcher]Change default vector dimension to 512. 2024-12-01 23:02:43 +08:00
Jun Zhang
83cfae609e Merge branch 'tencentmusic:master' into master 2024-12-01 21:08:59 +08:00
Jun Zhang
0fc29304a8 [improvement][launcher]Refactor unit tests and demo data. (#1935) 2024-12-01 21:08:26 +08:00
Jun Zhang
89d2ac802d Merge branch 'tencentmusic:master' into master 2024-12-01 21:06:59 +08:00
jerryjzhang
dee9b119eb [improvement][launcher]Refactor unit tests and demo data. 2024-12-01 20:54:55 +08:00
jerryjzhang
a232c2bc4f [improvement][launcher]Refactor unit tests and demo data. 2024-12-01 20:45:39 +08:00
jerryjzhang
0f1c50167d [improvement][launcher]Refactor unit tests and demo data.
[improvement][launcher]Refactor unit tests and demo data.

[improvement][launcher]Refactor unit tests and demo data.

[improvement][launcher]Refactor unit tests and demo data.
2024-12-01 20:14:25 +08:00
pisces
1c73453c5f perf: 在中文输入法的情况下,正在输入的过程中按下回车导致消息直接发送 (#1933) 2024-12-01 20:14:25 +08:00
pisces
639d1a78da perf: 在中文输入法的情况下,正在输入的过程中按下回车导致消息直接发送 (#1933) 2024-12-01 10:52:28 +08:00
lxwcodemonkey
5837a5b3ae [improvement][Headless] Supports getting domain by bizName 2024-11-30 23:17:49 +08:00
lxwcodemonkey
6ecc5a9362 [improvement][Headless] Supports automatic batch creation of models based on db table names. 2024-11-30 22:22:56 +08:00
lxwcodemonkey
8299084c95 [improvement][Headless] Add get database by type 2024-11-30 21:16:46 +08:00
lxwcodemonkey
bb60c93824 Merge remote-tracking branch 'origin/master' 2024-11-30 20:57:28 +08:00
lxwcodemonkey
d22a7d1cc6 [improvement][Headless] Add table ddl in Dbschema 2024-11-30 20:56:58 +08:00
Jun Zhang
4358ffe4a1 Merge branch 'tencentmusic:master' into master 2024-11-30 20:04:20 +08:00
Jun Zhang
82c63a7f22 [improvement][headless-fe] Revamped the interaction for semantic modeling routing and successfully implemented the switching between dimension and dataset management. (#1934)
Co-authored-by: tristanliu <tristanliu@tencent.com>
2024-11-30 20:03:41 +08:00
tristanliu
50accb152a Merge branch 'master' into feature/detail_style_rebuild 2024-11-30 17:56:58 +08:00
tristanliu
66ed711416 [improvement][headless-fe] Revamped the interaction for semantic modeling routing and successfully implemented the switching between dimension and dataset management. 2024-11-30 17:55:50 +08:00
lxwcodemonkey
4076d37b9b Merge remote-tracking branch 'origin/master' 2024-11-30 15:29:35 +08:00
Jun Zhang
67377bc7dc Merge branch 'tencentmusic:master' into master 2024-11-30 08:46:30 +08:00
Jun Zhang
593597fe26 Refactor translator module (#1932)
* [improvement][Chat] Support agent permission management #1143

* [improvement][chat]Iterate LLM prompts of parsing and correction.

* [improvement][headless]Clean code logic of headless core.

* (fix) (chat) 记忆管理更新不生效 (#1912)

* [improvement][headless-fe] Added null-check conditions to the data formatting function.

* [improvement][headless]Clean code logic of headless translator.

* [improvement][headless-fe] Added permissions management for agents.

* [improvement][headless-fe] Unified the assistant's permission settings interaction to match the system style.

* [improvement](Dict)Support returns dict task list of dimensions by page

* [improvement][headless-fe] Revised the interaction for semantic modeling routing and implemented the initial version of metric management switching.

* [improvement][launcher]Set system property `s2.test` in junit tests in order to facilitate conditional breakpoints.

* [improvement][headless] add validateAndQuery interface in SqlQueryApiController

* [improvement][launcher]Use API to get element ID avoiding hard-code.

* [improvement][launcher]Support DuckDB database and refactor translator code structure.

---------

Co-authored-by: lxwcodemonkey <jolunoluo@tencent.com>
Co-authored-by: tristanliu <tristanliu@tencent.com>
Co-authored-by: daikon12 <1059907724@qq.com>
Co-authored-by: lexluo09 <39718951+lexluo09@users.noreply.github.com>
2024-11-30 00:27:33 +08:00
jerryjzhang
a058dc8b6e [improvement][launcher]Support DuckDB database and refactor translator code structure. 2024-11-30 00:23:16 +08:00
jerryjzhang
13d4fc3feb [fix][launcher]Fix mysql scripts. 2024-11-29 14:50:32 +08:00
tristanliu
b4669cf110 [improvement][headless-fe] code stash 2024-11-28 20:29:12 +08:00
jerryjzhang
c80794e8fc [fix][launcher]Fix mysql scripts. 2024-11-28 09:44:49 +08:00
jerryjzhang
111304486b [improvement][launcher]Use API to get element ID avoiding hard-code. 2024-11-27 22:26:30 +08:00
lexluo09
25559fdaa5 [improvement][headless] add validateAndQuery interface in SqlQueryApiController 2024-11-27 15:03:00 +08:00
jerryjzhang
dad065d0ba [improvement][headless]Clean code logic of headless translator. 2024-11-27 11:29:29 +08:00
jerryjzhang
7bf1ba09c5 [fix][launcher]Struct unit tests must specify date filter. 2024-11-26 23:54:46 +08:00
Jun Zhang
97867ca015 Merge branch 'tencentmusic:master' into master 2024-11-26 23:22:36 +08:00
jerryjzhang
9bccbae3bc [improvement][launcher]Set system property s2.test in junit tests in order to facilitate conditional breakpoints. 2024-11-26 23:21:59 +08:00
wangk
224c114d20 fix:重启服务后存在多个闲聊助手 (#1928) 2024-11-26 21:41:20 +08:00
tristanliu
1de999dc1d Merge branch 'master' into feature/fontend_route_rebuild
# Conflicts:
#	webapp/packages/supersonic-fe/src/pages/SemanticModel/View/components/DataSetTable.tsx
#	webapp/packages/supersonic-fe/src/pages/SemanticModel/View/index.tsx
#	webapp/packages/supersonic-fe/src/pages/SemanticModel/components/DomainManagerTab.tsx
2024-11-26 20:32:34 +08:00
tristanliu
2eca2d1c14 [improvement][headless-fe] Revised the interaction for semantic modeling routing and implemented the initial version of metric management switching. 2024-11-26 20:28:24 +08:00
jerryjzhang
40bfcdce2c [improvement][headless]Clean code logic of headless translator. 2024-11-26 15:21:57 +08:00
jerryjzhang
b84dde3799 [improvement][headless]Clean code logic of headless translator. 2024-11-26 11:16:48 +08:00
jerryjzhang
91b16f95ff [improvement][headless]Add company demo schema and data to integration test.
[improvement][headless]Clean code logic of headless translator.
2024-11-25 23:51:39 +08:00
jerryjzhang
860fd5d299 [improvement][headless]Clean code logic of headless translator. 2024-11-25 21:12:03 +08:00
daikon12
c22e3ef2e8 [improvement](Dict)Support returns dict task list of dimensions by page 2024-11-24 16:20:57 +08:00
lxwcodemonkey
296ce5cc55 [improvement][Chat] Support agent permission management #1143 2024-11-24 11:32:57 +08:00
Siri-Ray
722f40cdf7 (improvement)(auth) Add user email info to jwt claim (#1921) 2024-11-24 09:41:33 +08:00
tristanliu
0edadd01eb [improvement][headless-fe] route rebuild stash 2024-11-23 17:23:16 +08:00
Jun Zhang
a942132b83 Merge branch 'tencentmusic:master' into master 2024-11-23 09:09:59 +08:00
Jun Zhang
cb183b7ac8 [improvement][Chat] Support agent permission management (#1923)
* [improvement][Chat] Support agent permission management #1143

* [improvement][chat]Iterate LLM prompts of parsing and correction.

* [improvement][headless-fe] Added null-check conditions to the data formatting function.

* [improvement][headless]Clean code logic of headless translator.

---------

Co-authored-by: lxwcodemonkey <jolunoluo@tencent.com>
Co-authored-by: tristanliu <tristanliu@tencent.com>
2024-11-23 09:09:04 +08:00
pisces
244052e806 fix(semanticModel): model options not exist when creating new dataset (#1919) 2024-11-22 10:37:15 +08:00
tristanliu
46d64d78f3 [improvement][headless-fe] Unified the assistant's permission settings interaction to match the system style. 2024-11-22 10:24:08 +08:00
tristanliu
62fc2dd18a [improvement][headless-fe] Added permissions management for agents. 2024-11-21 18:09:31 +08:00
jerryjzhang
be05f977d5 [improvement][headless]Clean code logic of headless translator. 2024-11-21 09:09:24 +08:00
jerryjzhang
d7586a5d3b [improvement][headless]Clean code logic of headless translator. 2024-11-20 22:23:53 +08:00
pisces
e990b37433 fix: 新建模型,存在多个度量的情况下,度量的扩展配置均会显示成第1个度量中的值; (#1909)
* fix(semantic-model): 新建模型,存在多个度量的情况下,度量的扩展配置均会显示成第1个度量中的值

* refactor(semantic-model): 新建模型,扩展配置的取值方式,find重构成解构

---------

Co-authored-by: tristanliu <37809633+sevenliu1896@users.noreply.github.com>
2024-11-20 12:04:05 +08:00
jerryjzhang
eb502e740c Merge remote-tracking branch 'ssbi/master' into ssmaster 2024-11-19 20:14:02 +08:00
jerryjzhang
62a4d60a0b [improvement][headless]Clean code logic of headless core. 2024-11-19 20:13:49 +08:00
tristanliu
8d63ed170a [improvement][headless-fe] Added null-check conditions to the data formatting function. 2024-11-19 14:28:29 +08:00
Jun Zhang
f4f0e58bfb Merge branch 'tencentmusic:master' into master 2024-11-18 23:11:35 +08:00
解(xie)先生🌽
534da49309 (fix) 同环比计算为null时最新日期的数据被覆盖前端显示一直为0 2024-11-18 23:10:37 +08:00
Jun Zhang
8c6da5dc54 Merge branch 'tencentmusic:master' into master 2024-11-18 19:29:36 +08:00
解(xie)先生🌽
159d91fd0f (fix) (chat) 记忆管理更新不生效 (#1912) 2024-11-18 19:27:42 +08:00
解(xie)先生🌽
5a8c20a00b (fix) (chat) 记忆管理更新不生效 (#1912) 2024-11-18 14:39:34 +08:00
jerryjzhang
cd889b479c [improvement][headless]Clean code logic of headless core. 2024-11-17 22:54:45 +08:00
jerryjzhang
a0f53359ef [improvement][chat]Iterate LLM prompts of parsing and correction. 2024-11-17 09:06:42 +08:00
lxwcodemonkey
36d221ab74 [improvement][Chat] Support agent permission management #1143 2024-11-16 21:54:59 +08:00
Jun Zhang
e8c9855163 [improvement][launcher]Clean code logic of s2demos and remove tag-related constructs. 2024-11-16 17:23:35 +08:00
Jun Zhang
ba1938f04b Merge fixes and improvements (#1910)
Co-authored-by: tristanliu <tristanliu@tencent.com>
2024-11-16 13:57:54 +08:00
zhaodongsheng
5e22b412c6 (fix) CoreDictionaryPath Incorrect Assignment (#1903) 2024-11-14 22:34:59 +08:00
LXW
87729956e8 (improvement)(Headless) Refactor the SemanticModeller to rule first and then llm, and automatically infer field types in the rule method. (#1900)
Co-authored-by: lxwcodemonkey
2024-11-11 00:10:58 +08:00
jerryjzhang
ea6a9ebc5f [improvement][launcher]Refactor built-in demos. 2024-11-10 21:29:49 +08:00
jerryjzhang
14a19a901f [improvement][project]Simplify code logic in multiple modules. 2024-11-10 14:31:12 +08:00
lexluo09
ca4545bb15 [improvement][chat] Only vector retrieval is enabled in loose mode (#1899) 2024-11-10 10:39:17 +08:00
Jun Zhang
e0e167fd40 [improvement][chat]Refactor code logic in rule-based parsing. 2024-11-09 15:49:08 +08:00
lexluo09
d4a9d5a7e6 [fix][chat] The terms in the descriptor of the term no longer undergo descriptor mapping (#1897) 2024-11-09 14:16:55 +08:00
Jun Zhang
c9c6dc4e44 Merge a number of fixes and improvements (#1896) 2024-11-09 00:23:02 +08:00
yudong
524ec38edc [improvement][chat]记忆评估性能优化 (#1887) 2024-11-08 23:06:43 +08:00
xiao liang
9edcb9f91c chat接口,匹配数据集逻辑错误,导致智能匹配第一个数据集 (#1884) 2024-11-04 17:10:41 +08:00
jerryjzhang
6f2af79756 [improvement][chat]Move processor related logic from headless to chat. 2024-11-04 16:27:26 +08:00
tristanliu
7be885d9c8 [improvement][headless-fe] Fixed a logic error in the editing process of dimension value aliases in the question-answering dialogue of the assistant module (#1880)
* [improvement][semantic-fe] Updating the logic for the fieldName.

* [improvement][semantic-fe] Adjusting the position of the metrics tab.

* [improvement][semantic-fe] Changing the 字段名称 to 英文名称.

* [improvement][semantic-fe] Fix metric measurement deletion.

* [improvement][semantic-fe] UI optimization for metric details page.

* [improvement][semantic-fe] UI optimization for metric details page.

* [improvement][semantic-fe] UI adjustment for metric details page.

* [improvement][semantic-fe] The granularity field in the time type of model editing now supports setting it as empty.

* [improvement][semantic-fe] Added field type and metric type to the metric creation options.

* [improvement][semantic-fe] The organization structure selection feature has been added to the permission management.

* [improvement][semantic-fe] Improved user experience for the metric list.

* [improvement][semantic-fe] fix update the metric list.

* [improvement][headless-fe] Added view management functionality.

* [improvement][headless-fe] The view management functionality has been added. This feature allows users to create, edit, and manage different views within the system.

* [improvement][headless-fe] Added model editing side effect detection.

* [improvement][headless-fe] Fixed the logic error in view editing.

* [improvement][headless-fe] Fixed the issue with initializing dimension associations in metric settings.

* [improvement][headless-fe] Added the ability to hide the Q&A settings entry point.

* [improvement][headless-fe] Fixed the issue with selecting search results in metric field creation.

* [improvement][headless-fe] Added search functionality to the field list in model editing.

* [improvement][headless-fe] fix the field list in model editing

* [improvement][headless-fe] Restructured the data for the dimension value settings interface.

* [improvement][headless-fe] Added dynamic variable functionality to model creation based on SQL scripts.

* [improvement][headless-fe] Added support for passing dynamic variables as parameters in the executeSql function.

* [improvement][headless-fe] Resolved the issue where users were unable to select all options for dimensions, metrics, and fields in the metric generation process.

* [improvement][headless-fe] Replaced the term "view" with "dataset"

* [improvement][headless-fe] Added the ability to export metrics and dimensions to a specific target.

* [improvement][headless-fe] Enhanced dataset creation to support the tag mode.

* [improvement][headless-fe] Added tag value setting.

* [improvement][headless-fe] Optimized the tag setting system.

* [improvement][headless-fe] Optimized the tag setting system.

* [improvement][headless-fe] Updated the data initialization for model editing to use API requests instead.

* [improvement][headless-fe] Added search functionality to model management.

* [improvement][headless-fe] Removed field null validation during model editing.

* [improvement][headless-fe] Updated the batch operation button component.

* [improvement][headless-fe] Optimized the logic for initializing indicators in dimension value settings.

* [improvement][headless-fe] Adjusted the length of the input field for model editing names.

* [improvement][headless-fe]  Lock the version of the @ant-design/pro-table component and replace it with @ant-design/pro-components.

* [improvement][headless-fe] Optimized the style of the metrics market and tags market.

* [improvement][headless-fe] The quick creation of model fields now defaults to using the "comment" field for filling.

* [improvement][headless-fe] The quick creation of model fields now defaults to using the "comment" field for filling

* [improvement][headless-fe] The quick creation of model fields now defaults to using the "comment" field for filling.

* [improvement][headless-fe] Fixed the issue where the conditions for metric measurement creation were not being saved correctly.

* [improvement][headless-fe] Default value setting for hiding dimensions.

* [improvement][headless-fe] Updated the file imports in the project.

* [improvement][headless-fe] Adjusted the logic for displaying the tab in the theme domain.

* [improvement][headless-fe] Added term management functionality.

* [improvement][headless-fe] When creating a model, the current metric operator now allows for clearance.

* [improvement][headless-fe] Term management interface transformation

* [improvement][headless-fe] Migrating scaffold version to @umi/max

* [improvement][headless-fe] remove modle column

* [improvement][headless-fe] 1.Added configuration for the large language model in the agent; 2.upgraded React version from 17 to 18; 3.modified some UI effects.

* [improvement][headless-fe] Added a simplified mode to the question-answering system.

* [improvement][headless-fe] remove pnpm-lock

* [improvement][headless-fe] add pnpm-lock

* [improvement][headless-fe] Fixed the issue with passing the modelId during initialization.

* [improvement][headless-fe] Fixed the issue with abnormal comments during model creation.

* [improvement][headless-fe] fix  build bugs

* [improvement][headless-fe]  change build config

* [improvement][headless-fe] route config change

* [improvement][headless-fe] Optimized data updating when switching domains.

* [improvement][headless-fe] css change

* [improvement][semantic-fe] logo css change

* [improvement][semantic-fe] system config add defaultValue support

* [improvement][semantic-fe] tag mode wording change

* [improvement][semantic-fe] fix metric edit page init error

* [improvement][supersonic-fe] Updated the way chat projects are imported in supersonic-fe.

* [improvement][chat-engine] Added a background silent mode for watching chat projects.

* [improvement][supersonic-fe] fix proxy url

* [improvement][headless-fe] agent setting update

* [improvement][headless-fe] Agent configuration: Added connectivity testing for large models.

* [improvement][headless-fe] Chat: Enabled integration with agent configuration.

* [improvement][headless-fe] SQL formatter: Updated the import method.

* [improvement][headless-fe] login fixed

* [improvement][headless-fe] Agent: Optimized the logic for saving.

* [improvement][headless-fe] Model management: Integrated into the main theme domain.

* [improvement][headless-fe] Sensitivity: Added bulk modification functionality.

* [improvement][headless-fe] wording change

* [improvement][headless-fe] Prompt configuration: Added the ability to configure prompts.

* [improvement][headless-fe] Added the ability to configure embedding models.

* [improvement][headless-fe] hidden configure embedding models.

* [improvement][headless-fe] Connection test prompt update for large language model settings.

* [improvement][headless-fe]  add memory review config

* [improvement][headless-fe] Rollback of data structure for large language model configuration.

* [improvement][headless-fe] Added dependency relationships between various items in system configuration.

* [improvement][headless-fe] Added password parsing to the generation rules of system settings.

* [improvement][headless-fe] Added slider parsing to the generation rules of system settings.

* [improvement][headless-fe] Optimized the logic for initializing values in system settings.

* [improvement][headless-fe] Optimized the time format

* [improvement][headless-fe] Unified the SQL generation method for data sets to ensure consistency and improve efficiency.

* [improvement][headless-fe] Added support for data sets with non-partitioned time fields

* [improvement][headless-fe] Added support for editing time formats in dimension settings

* [improvement][headless-fe] Rolled back the time parameter in the metric details page to its previous state

* [improvement][headless-fe] Fixed the issue with hidden field validation when editing dimensions

* [improvement][headless-fe] Added a connectivity test for large models in the system settings

* [improvement][headless-fe] Changed the METRIC type in ChatContextType queryType to AGGREGATE

* [improvement][headless-fe] Added query and batch delete operations to the terminology management feature

* [improvement][headless-fe] Enhanced the memory management feature by adding sorting functionality and other optimization features.

* [improvement][headless-fe] Resolved the compatibility issue with the backend service where the updatedAt and other time fields were not being properly converted to the updated_at format for sorting purposes.

* [improvement][headless-fe] Added a configuration interface for large language models

* [improvement][headless-fe] Introduced a new configuration option in the assistant module specifically for large model applications.

* [improvement][headless-fe] Replaced the agentConfig with toolConfig

* [improvement][headless-fe] Resolved the issue with the test connection parameters for the large model configuration.

* [improvement][headless-fe] Implemented a new feature where the tool configuration types can be fetched from the backend API

* [improvement][headless-fe] Updated the dimension value settings to retrieve and display values from a dictionary.

* [improvement][headless-fe] Adjusted the pageSize of the dimension value settings list to 20.

* [improvement][headless-fe] Introduced a revamped configuration for the large model in the assistant module.

* [improvement][headless-fe] Added new functionality to the assistant's memory management system

* [improvement][headless-fe] Optimized the management of CSS styles in the assistant module.

* [improvement][headless] fixed build config

* [improvement][headless-fe] Revamped the dimension value settings in the assistant module.

* [improvement][headless-fe] Optimized the initialization process of dimension value settings in the assistant module.

* [improvement][headless-fe] Added support for user confirmation mode in the question-answering dialogue of the assistant module.

* [improvement][headless-be] As part of the ongoing improvements to the question-answering dialogue, the datasetId will now be included as a parameter in the API endpoint /api/chat/query/search for querying the question-answering dataset.

* [improvement][headless-be] Optimized the logic for intent confirmation and streamlined mode in the question-answering dialogue of the assistant module.

* [improvement][headless-be] rollback proxy config

* [improvement][headless-fe] Enhanced the display of errMsg and textSummary in the question-answering dialogue of the assistant module

* [improvement][headless-fe] Fixed a logic error in the editing process of dimension value aliases in the question-answering dialogue of the assistant module

---------

Co-authored-by: tristanliu <tristanliu@tencent.com>
2024-11-04 11:21:26 +08:00
jerryjzhang
9a05b5cce6 [improvement][headless]Deprecate and remove entity-related abstraction and logic.#1876 2024-11-04 10:17:30 +08:00
lexluo09
3b65b1c80b [improvement][headless] Remove entities from the dictionary and search interface (#1878) 2024-11-04 10:06:10 +08:00
jerryjzhang
1e5bf7909e [improvement][headless]Deprecate and remove entity-related abstraction and logic.#1876 2024-11-04 09:53:18 +08:00
lexluo09
6a4458a572 [improvement][build] Optimize pushing images through GitHub Actions (#1875) 2024-11-02 21:33:15 +08:00
lexluo09
1867447b6e [improvement][build] Support manual pushing of images through GitHub Actions (#1874) 2024-11-02 18:09:11 +08:00
jerryjzhang
ff7fb50030 [release]Kick off v0.9.10 snapshot. 2024-11-01 22:59:54 +08:00
710 changed files with 16543 additions and 22567 deletions

View File

@@ -11,59 +11,28 @@ body:
If it is an idea or help wanted, please go to:
[Github Discussion](https://github.com/tencentmusic/supersonic/discussions)
- type: checkboxes
- type: input
id: version
attributes:
label: Search before asking
description: >
Please make sure to search in the [issues](https://github.com/tencentmusic/supersonic/issues?q=is%3Aissue) first to see
whether the same issue was reported already.
options:
- label: >
I had searched in the [issues](https://github.com/tencentmusic/supersonic/issues?q=is%3Aissue) and found no similar
issues.
required: true
label: SuperSonic version
description: Please tell us which version you are using.
placeholder: "0.9.8"
validations:
required: true
- type: textarea
- type: input
id: organization
attributes:
label: Version
description: What is the current version
placeholder: >
Please provide the version you are using.
If it is the trunk version, please input commit id.
label: Your organization
description: Please tell us your organization so that we can provide you better support and advice.
placeholder: "TME..."
validations:
required: true
- type: textarea
attributes:
label: What's Wrong?
description: Describe the bug.
placeholder: >
Describe the specific problem, the more detailed the better.
validations:
required: true
- type: textarea
attributes:
label: What You Expected?
validations:
required: true
- type: textarea
attributes:
label: How to Reproduce?
placeholder: >
Please try to give reproducing steps to facilitate quick location of the problem.
- What actions were performed
- Table building statement
- Import statement
- Cluster information: number of nodes, configuration, etc.
If it is hard to reproduce, please also explain the general scene.
- type: textarea
attributes:
label: Anything Else?
label: Description
description: Describe the bug you met.
- type: checkboxes
attributes:
@@ -74,16 +43,6 @@ body:
options:
- label: Yes I am willing to submit a PR!
- type: checkboxes
attributes:
label: Code of Conduct
description: The Code of Conduct helps create a safe space for everyone. We require that everyone agrees to it.
options:
- label: >
I agree to follow this project's
[Code of Conduct](https://www.apache.org/foundation/policies/conduct)
required: true
- type: markdown
attributes:
value: "Thanks for completing our form!"

View File

@@ -8,30 +8,20 @@ body:
attributes:
value: |
Thank you very much for your good enhancement for SuperSonic.
- type: checkboxes
attributes:
label: Search before asking
description: >
Please make sure to search in the [issues](https://github.com/tencentmusic/supersonic/issues?q=is%3Aissue) first to see
whether the same issue was reported already.
options:
- label: >
I had searched in the [issues](https://github.com/tencentmusic/supersonic/issues?q=is%3Aissue) and found no similar
issues.
required: true
- type: textarea
attributes:
label: Description
description: Describe the enhancement what you want, including motivation if it exists.
- type: textarea
- type: input
id: organization
attributes:
label: Solution
placeholder: >
Add overview of proposed solution.
Add related materials like links if they exist.
label: Your organization
description: Please tell us your organization so that we can provide you better support and advice.
placeholder: "TME..."
validations:
required: true
- type: checkboxes
attributes:
@@ -42,16 +32,6 @@ body:
options:
- label: Yes I am willing to submit a PR!
- type: checkboxes
attributes:
label: Code of Conduct
description: The Code of Conduct helps create a safe space for everyone. We require that everyone agrees to it.
options:
- label: >
I agree to follow this project's
[Code of Conduct](https://www.apache.org/foundation/policies/conduct)
required: true
- type: markdown
attributes:
value: "Thanks for completing our form!"

View File

@@ -8,33 +8,19 @@ body:
value: |
Thank you very much for your good ideas and suggestions for SuperSonic
- type: checkboxes
attributes:
label: Search before asking
description: >
Please make sure to search in the [issues](https://github.com/tencentmusic/supersonic/issues?q=is%3Aissue) first to see
whether the same issue was reported already.
options:
- label: >
I had searched in the [issues](https://github.com/tencentmusic/supersonic/issues?q=is%3Aissue) and found no similar
issues.
required: true
- type: textarea
attributes:
label: Description
description: Describe your ideas and needs.
- type: textarea
- type: input
id: organization
attributes:
label: Use case
placeholder: >
What problem does this feature mainly solve, or what scenarios it is suitable for.
- type: textarea
attributes:
label: Related issues
description: Is there currently another issue associated with this?
label: Your organization
description: Please tell us your organization so that we can provide you better support and advice.
placeholder: "TME..."
validations:
required: true
- type: checkboxes
attributes:
@@ -45,16 +31,4 @@ body:
options:
- label: Yes I am willing to submit a PR!
- type: checkboxes
attributes:
label: Code of Conduct
description: The Code of Conduct helps create a safe space for everyone. We require that everyone agrees to it.
options:
- label: >
I agree to follow this project's
[Code of Conduct](https://www.apache.org/foundation/policies/conduct)
required: true
- type: markdown
attributes:
value: "Thanks for completing our form!"

View File

@@ -8,6 +8,7 @@ body:
value: |
## Ask a Question about SuperSonic
Please provide a detailed description of your question or the clarification you seek regarding the SuperSonic project.
- type: textarea
id: describe-question
attributes:
@@ -16,43 +17,12 @@ body:
placeholder: "Type your question here..."
validations:
required: true
- type: textarea
id: additional-context
- type: input
id: organization
attributes:
label: Provide any additional context or information
description: If your question is related to a specific part of the SuperSonic project or if you have already looked through certain documentation, please provide that information here.
placeholder: "Add context here..."
label: Your organization
description: Please tell us your organization so that we can provide you better support and advice.
placeholder: "TME..."
validations:
required: false
- type: textarea
id: tried-to-resolve
attributes:
label: What have you tried to resolve your question
description: Let us know what you have done to try and understand or resolve your question. This can help us provide you with the most useful guidance.
placeholder: "I've already tried..."
validations:
required: false
- type: textarea
id: environment
attributes:
label: Your environment
description: Share details about your environment to help us reproduce the issue. Include your operating system, version of SuperSonic, and any other relevant details.
placeholder: "OS, SuperSonic version, etc..."
validations:
required: false
- type: textarea
id: screenshots-logs
attributes:
label: Screenshots or Logs
description: If applicable, add screenshots or logs to help explain your problem.
placeholder: "Paste your logs or attach screenshots here..."
validations:
required: false
- type: textarea
id: additional-information
attributes:
label: Additional information
description: Add any other context or details you think might be helpful for understanding your question.
placeholder: "Any other information..."
validations:
required: false
required: true

View File

@@ -15,11 +15,17 @@ jobs:
strategy:
matrix:
java-version: [8, 11, 21] # 定义要测试的JDK版本
java-version: [21] # 定义要测试的JDK版本
steps:
- uses: actions/checkout@v2
- name: Set up JDK ${{ matrix.java-version }}
uses: actions/setup-java@v2
with:
java-version: ${{ matrix.java-version }}
distribution: 'adopt'
- name: Reset DNF repositories
run: |
cd /etc/yum.repos.d/
@@ -29,21 +35,11 @@ jobs:
- name: Update DNF package index
run: dnf makecache
- name: Install Java and Maven with retry
- name: Install Maven with retry
run: |
if [ ${{ matrix.java-version }} -eq 8 ]; then
for i in {1..5}; do
dnf install -y java-1.8.0-openjdk-devel maven && break || sleep 15
done
elif [ ${{ matrix.java-version }} -eq 11 ]; then
for i in {1..5}; do
dnf install -y java-11-openjdk-devel maven && break || sleep 15
done
elif [ ${{ matrix.java-version }} -eq 21 ]; then
for i in {1..5}; do
dnf install -y java-21-openjdk-devel maven && break || sleep 15
done
fi
for i in {1..5}; do
dnf install -y maven && break || sleep 15
done
- name: Verify Java and Maven installation
run: |
@@ -61,4 +57,5 @@ jobs:
run: mvn -B package --file pom.xml
- name: Test with Maven
run: mvn test
run: mvn test

32
.github/workflows/docker-publish.yml vendored Normal file
View File

@@ -0,0 +1,32 @@
name: Docker Publish
on:
workflow_dispatch:
inputs:
version:
description: 'Version of the Docker image'
required: true
default: 'latest'
jobs:
build-and-publish:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Log in to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and publish Docker image
run: |
VERSION=${{ github.event.inputs.version }}
chmod +x docker/docker-build-publish.sh
sh docker/docker-build-publish.sh $VERSION

View File

@@ -14,7 +14,7 @@ jobs:
strategy:
matrix:
java-version: [8, 11, 21] # Define the JDK versions to test
java-version: [21] # Define the JDK versions to test
steps:
- uses: actions/checkout@v2

View File

@@ -14,7 +14,7 @@ jobs:
strategy:
matrix:
java-version: [8, 11, 21] # 定义要测试的JDK版本
java-version: [21] # 定义要测试的JDK版本
steps:
- uses: actions/checkout@v2

View File

@@ -14,7 +14,7 @@ jobs:
strategy:
matrix:
java-version: [8, 11, 21] # Add JDK 21 to the matrix
java-version: [21] # Add JDK 21 to the matrix
steps:
- uses: actions/checkout@v2

3
.gitignore vendored
View File

@@ -19,4 +19,5 @@ assembly/runtime/*
chm_db/
__pycache__/
/dict
assembly/build/*-SNAPSHOT
assembly/build/*-SNAPSHOT
**/node_modules/

View File

@@ -7,11 +7,11 @@
## SuperSonic [0.9.8] - 2024-11-01
- Add LLM management module to reuse connection across agents.
- Add ChatAPP configuration sub-module in Agent Management.
- Add dimension value management sub-module.
- Enhance dimension value management sub-module.
- Enhance memory management and term management sub-module.
- Support semantic translation of complex S2SQL.
- Enhance semantic translation of complex S2SQL.
- Enhance user experience in Chat UI.
- Introduce LLM-based semantic corrector and data interpreter.
- Introduce new experience in Chat UI.
## SuperSonic [0.9.2] - 2024-06-01

490
LICENSE
View File

@@ -1,489 +1,41 @@
SuperSonic is licensed under the MIT License, with the following additional conditions:
Apache License Version 2.0
1. You may provide SuperSonic to third parties as a commercial software or service. However,
when the following conditions are met, you must contact the producer to obtain a commercial license:
Copyright (2025) The SuperSonic Project Authors. All rights reserved.
a. Multi-tenant SaaS service: Unless explicitly authorized by SuperSonic in writing, you may not use the
SuperSonic source code to operate a multi-tenant SaaS service.
b. LOGO and copyright information: In the process of using SuperSonic, you may not remove or modify
the LOGO or copyright information on the SuperSonic UI. This restriction is inapplicable to uses of
SuperSonic that do not involve its frontend components.
----------
SuperSonic is licensed under the Apache License 2.0, with the following additional conditions:
1. The commercial usage of SuperSonic:
a. SuperSonic may be utilized commercially, including as a frontend and backend service without modifying the source
code and logo.
b. a commercial license must be obtained from the author if you want to develop and distribute a derivative work based
on SuperSonic.
Please contact zhangjun2915@163.com by email to inquire about licensing matters.
Please contact jerryjzhang@tencent.com by email to inquire about licensing matters.
2. As a contributor, you should agree that:
a. The producer can adjust the open-source agreement to be more strict or relaxed as deemed necessary.
b. Your contributed code may be used for commercial purposes, including but not limited to its business operations.
Terms of the MIT License:
--------------------------------------------------------------------
MIT License
b. Your contributed code may be used for commercial purposes, including but not limited to its cloud edition.
Copyright (c) 2023 Tencent Music Entertainment
Apart from the specific conditions mentioned above, all other rights and restrictions follow the Apache License 2.0.
Detailed information about the Apache License 2.0 can be found at http://www.apache.org/licenses/LICENSE-2.0.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
----------
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
END OF TERMS AND CONDITIONS
Other dependencies and licenses:
Open Source Software Licensed under the MIT License:
--------------------------------------------------------------------
1. Mybatis-PageHelper 1.2.10
Copyright (c) 2014-2022 abel533@gmail.com
2. lombok
Copyright (C) 2009-2021 The Project Lombok Authors.
3. react
Copyright (c) Facebook, Inc. and its affiliates.
4. ant-design
Copyright (c) 2015-present Ant UED, https://xtech.antfin.com/
5. ant-design-pro
Copyright (c) 2019 Alipay.inc
6. @ant-design/charts
Copyright (c) 2021 Ant Design
7. @ant-design/icons
Copyright (c) 2018-present Ant UED, https://xtech.antfin.com/
8. @antv/layout
Copyright (c) 2018 Alipay.inc
9. @antv/xflow
Copyright (c) 2021-2023 Alipay.inc
10. umi
Copyright (c) 2017-present ChenCheng (sorrycc@gmail.com)
11. @umijs/route-utils
Copyright (c) 2019-present chenshuai2144 (qixian.cs@outlook.com)
12. ahooks
Copyright (c) 2020 ahooks
13. axios
Copyright (c) 2014-present Matt Zabriskie & Collaborators
14. classnames
Copyright (c) 2018 Jed Watson
15. crypto-js
Copyright (c) 2009-2013 Jeff Mott
Copyright (c) 2013-2016 Evan Vosberg
16. immutability-helper
Copyright (c) 2017 Moshe Kolodny
17. lodash
Copyright JS Foundation and other contributors <https://js.foundation/>
18. moment
Copyright (c) JS Foundation and other contributors
19. numeral
Copyright (c) 2016 Adam Draper
20. omit.js
Copyright (c) 2016 Benjy Cui
21. rc-menu
Copyright (c) 2014-present yiminghe
22. rc-util
Copyright (c) 2014-present yiminghe
Copyright (c) 2015-present Alipay.com, https://www.alipay.com/
23. react-ace
Copyright (c) 2014 James Hrisho
24. react-dev-inspector
Copyright (c) zthxxx (https://blog.zthxxx.me)
25. react-lazyload
Copyright (c) 2015 Sen Yang
26. react-spinners
Copyright (c) 2017 David Hu
27.react-split-pane
Copyright (c) 2015 tomkp
28. snappyjs
Copyright (c) 2016 Zhipeng Jia
29. sql-formatter
Copyright (c) 2016-2020 ZeroTurnaround LLC
Copyright (c) 2020-2021 George Leslie-Waksman and other contributors
Copyright (c) 2021-Present inferrinizzard and other contributors
30. @ant-design/pro-cli
Copyright (c) 2017-2018 Alipay
31. cross-env
Copyright (c) 2017 Kent C. Dodds
32.cross-port-killer
Copyright (c) 2017 Rafael Milewski
33.detect-installer
Copyright (c) 2019-present chenshuai2144 (qixian.cs@outlook.com)
34.eslint
Copyright OpenJS Foundation and other contributors, <www.openjsf.org>
35.express
Copyright (c) 2009-2014 TJ Holowaychuk <tj@vision-media.ca>
Copyright (c) 2013-2014 Roman Shtylman <shtylman+expressjs@gmail.com>
Copyright (c) 2014-2015 Douglas Christopher Wilson <doug@somethingdoug.com>
36.gh-pages
Copyright (c) 2014 Tim Schaub
37.inflect
Copyright (C) 2020 Pavan Kumar Sunkara
38.lint-staged
Copyright (c) 2016 Andrey Okonetchnikov
39.prettier
Copyright © James Long and contributors
40.stylelint
Copyright (c) 2015 - present Maxime Thirouin, David Clark & Richard Hallows
41.umi-serve
Copyright (c) 2017-present ChenCheng (sorrycc@gmail.com)
42.webpack
Copyright JS Foundation and other contributors
43.react-dnd
Copyright (c) 2015 Dan Abramov
44.react-grid-layout
Copyright (c) 2016 Samuel Reed
45.slat
Copyright © 20162023, Ian Storm Taylor
46.html2canvas
Copyright (c) 2012 Niklas von Hertzen
47.core-js
Copyright (c) 2014-2020 Denis Pushkarev
48.immer 4.0.2
Copyright (c) 2017 Michel Weststrate
49.redux
Copyright (c) 2015-present Dan Abramov
The Redux logo is dedicated to the public domain and licensed under CC0.
50.redux-saga
Copyright (c) 2015 Yassine Elouafi
The Redux-Saga logo is dedicated to the public domain and licensed under CC0.
51.ts-loader
Copyright (c) 2015 TypeStrong
52.minimist
Fileshttps://github.com/minimistjs/minimist/tree/v1.2.3
License Detailshttps://github.com/minimistjs/minimist/blob/main/LICENSE
53.intl
copyright (c) 2013 Andy Earnshaw
A copy of the MIT License is included in this file.
Open Source Software Licensed under the Apache License Version 2.0:
--------------------------------------------------------------------
1. HanLP
Files: https://github.com/hankcs/HanLP/tree/v1.8.3
License Details: https://github.com/hankcs/HanLP/blob/v1.8.3/LICENSE
2. mybatis
iBATIS
This product includes software developed by
The Apache Software Foundation (http://www.apache.org/).
Copyright 2010 The Apache Software Foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
3. guava
Files: https://github.com/google/guava/tree/v20.0
License Details: https://github.com/google/guava/blob/master/LICENSE
4. hadoop
This product includes software developed by The Apache Software Foundation (http://www.apache.org/).
5. Jackson
Files: https://github.com/FasterXML/jackson-core/tree/2.11
License Details: https://github.com/FasterXML/jackson-core/blob/2.11/LICENSE
6. commons-lang
Apache Commons Lang
Copyright 2001-2017 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
This product includes software from the Spring Framework,
under the Apache License 2.0 (see: StringUtils.containsWhitespace())
7. testng
Fileshttps://github.com/testng-team/testng/tree/6.13.1
License Detailshttps://github.com/testng-team/testng/blob/6.13.1/LICENSE.txt
8. jackson-dataformat-yaml
Fileshttps://github.com/FasterXML/jackson-dataformat-yaml/tree/jackson-dataformat-yaml-2.8.11
License Detailshttps://www.apache.org/licenses/LICENSE-2.0.txt
9. druid
Copyright 1999-2018 Alibaba Group Holding Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
10. davinci
Licensed to Apereo under one or more contributor license
agreements. See the NOTICE file distributed with this work
for additional information regarding copyright ownership.
Apereo licenses this file to you under the Apache License,
Version 2.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a
copy of the License at the following location:
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
11. echarts
Apache ECharts
Copyright 2017-2023 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (https://www.apache.org/).
12. echarts-wordcloud
Apache ECharts
Copyright 2017-2023 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (https://www.apache.org/).
13. carlo
Fileshttps://github.com/GoogleChromeLabs/carlo
License Detailshttps://github.com/GoogleChromeLabs/carlo/blob/master/LICENSE
14. puppeteer-core
Copyright 2017 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
15. swagger-ui-react
swagger-ui
Copyright 2020-2021 SmartBear Software Inc.
16. typescript
fileshttps://github.com/microsoft/TypeScript
License Detailshttps://github.com/microsoft/TypeScript/blob/main/LICENSE.txt
17. io.jsonwebtoken
Copyright (C) 2014 jsonwebtoken.io
Files: https://repo1.maven.org/maven2/io/jsonwebtoken/jjwt/0.9.1/jjwt-0.9.1.jar
Terms of the Apache License Version 2.0:
--------------------------------------------------------------------
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of this License; and
You must cause any modified files to carry prominent notices stating that You changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
Open Source Software Licensed under the Modified BSD License:
--------------------------------------------------------------------
1. node-sha1
Copyright © 2009, Jeff Mott. All rights reserved.
Copyright © 2011, Paul Vorbach. All rights reserved.
This project is licensed under the terms of the Modified BSD License, as follows:
-------------------------------------------------------------------
Copyright (c) 2005-2023, NumPy Developers.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
Neither the name oCrypto-JS nor the names of any contributors
may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2. ace-builds
Copyright (c) 2010, Ajax.org B.V.
All rights reserved.
This project is licensed under the terms of the Modified BSD License, as follows:
-------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Ajax.org B.V. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Other Open Source Software
--------------------------------------------------------------------
1. jsencrypt
Fileshttps://github.com/travist/jsencrypt
License Detailshttps://github.com/travist/jsencrypt/blob/master/LICENSE.txt
limitations under the License.

View File

@@ -4,7 +4,7 @@
# SuperSonic
SuperSonic is the next-generation BI platform that unifies **Chat BI** (powered by LLM) and **Headless BI** (powered by semantic layer) paradigms. This unification ensures that Chat BI has access to the same curated and governed semantic data models as traditional BI. Furthermore, the implementation of both paradigms benefit from each other:
SuperSonic is the next-generation AI+BI platform that unifies **Chat BI** (powered by LLM) and **Headless BI** (powered by semantic layer) paradigms. This unification ensures that Chat BI has access to the same curated and governed semantic data models as traditional BI. Furthermore, the implementation of both paradigms benefit from each other:
- Chat BI's Text2SQL gets augmented with context-retrieval from semantic models.
- Headless BI's query interface gets extended with natural language API.

View File

@@ -4,7 +4,13 @@ sbinDir=$(cd "$(dirname "$0")"; pwd)
chmod +x $sbinDir/supersonic-common.sh
source $sbinDir/supersonic-common.sh
cd $projectDir
MVN_VERSION=$(mvn help:evaluate -Dexpression=project.version | grep -e '^[^\[]')
MVN_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout | grep -v '^\[' | sed -n '/^[0-9]/p')
if [ -z "$MVN_VERSION" ]; then
echo "Failed to retrieve Maven project version."
exit 1
fi
echo "Maven project version: $MVN_VERSION"
cd $baseDir
service=$1
@@ -29,12 +35,17 @@ function buildWebapp {
chmod +x $projectDir/webapp/start-fe-prod.sh
cd $projectDir/webapp
sh ./start-fe-prod.sh
cp -fr ./supersonic-webapp.tar.gz ${buildDir}/
# check build result
if [ $? -ne 0 ]; then
echo "Failed to build frontend webapp."
exit 1
fi
cp -fr ./supersonic-webapp.tar.gz ${buildDir}/
# check build result
if [ $? -ne 0 ]; then
echo "Failed to get supersonic webapp package."
exit 1
fi
echo "finished building supersonic webapp"
}
@@ -50,6 +61,11 @@ function packageRelease {
# package webapp
tar xvf supersonic-webapp.tar.gz
mv supersonic-webapp webapp
# check webapp build result
if [ $? -ne 0 ]; then
echo "Failed to get supersonic webapp package."
exit 1
fi
json='{"env": "''"}'
echo $json > webapp/supersonic.config.json
mv webapp $release_dir/

View File

@@ -4,6 +4,7 @@ chcp 65001
set "sbinDir=%~dp0"
call %sbinDir%/supersonic-common.bat %*
call %sbinDir%/supersonic-env.bat %*
set "command=%~1"
set "service=%~2"
@@ -14,7 +15,7 @@ if "%service%"=="" (
)
if "%profile%"=="" (
set "profile=local"
set "profile=%S2_DB_TYPE%"
)
set "model_name=%service%"
@@ -54,7 +55,8 @@ if "%command%"=="restart" (
set "webDir=%baseDir%\webapp"
set "logDir=%baseDir%\logs"
set "classpath=%baseDir%;%webDir%;%libDir%\*;%confDir%"
set "java-command=-Dfile.encoding=UTF-8 -Duser.language=Zh -Duser.region=CN -Duser.timezone=GMT+08 -Dspring.profiles.active=%profile% -Xms1024m -Xmx1024m -cp %CLASSPATH% %MAIN_CLASS%"
set "property=-Dfile.encoding=UTF-8 -Duser.language=Zh -Duser.region=CN -Duser.timezone=GMT+08 -Dspring.profiles.active=%profile%"
set "java-command=%property% -Xms1024m -Xmx1024m -cp %CLASSPATH% %MAIN_CLASS%"
if not exist %logDir% mkdir %logDir%
start /B java %java-command% >nul 2>&1
timeout /t 10 >nul

View File

@@ -2,6 +2,7 @@
sbinDir=$(cd "$(dirname "$0")"; pwd)
source $sbinDir/supersonic-common.sh
source $sbinDir/supersonic-env.sh
command=$1
service=$2
@@ -12,7 +13,7 @@ if [ -z "$service" ]; then
fi
if [ -z "$profile" ]; then
profile="local"
profile=${S2_DB_TYPE}
fi
model_name=$service

View File

@@ -0,0 +1,8 @@
:: Set below DB configs to connect to your own database
:: Supported DB_TYPE: h2, mysql, postgres
set "S2_DB_TYPE=h2"
set "S2_DB_HOST="
set "S2_DB_PORT="
set "S2_DB_USER="
set "S2_DB_PASSWORD="
set "S2_DB_DATABASE="

10
assembly/bin/supersonic-env.sh Executable file
View File

@@ -0,0 +1,10 @@
#!/usr/bin/env bash
#### Set below DB configs to connect to your own database
# Supported DB_TYPE: h2, mysql, postgres
export S2_DB_TYPE=h2
export S2_DB_HOST=
export S2_DB_PORT=
export S2_DB_USER=
export S2_DB_PASSWORD=
export S2_DB_DATABASE=

View File

@@ -1,11 +1,11 @@
package com.tencent.supersonic.auth.api.authentication.adaptor;
import javax.servlet.http.HttpServletRequest;
import com.tencent.supersonic.auth.api.authentication.pojo.Organization;
import com.tencent.supersonic.auth.api.authentication.pojo.UserToken;
import com.tencent.supersonic.auth.api.authentication.request.UserReq;
import com.tencent.supersonic.common.pojo.User;
import jakarta.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Set;

View File

@@ -18,6 +18,9 @@ public class AuthenticationConfig {
@Value("${s2.authentication.include.path:/api}")
private String includePath;
@Value("${s2.authentication.strategy:http}")
private String strategy;
@Value("${s2.authentication.enable:false}")
private boolean enabled;

View File

@@ -11,6 +11,7 @@ import java.util.Map;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_CREATE_TIME;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_IS_ADMIN;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_DISPLAY_NAME;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_EMAIL;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_ID;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_NAME;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_PASSWORD;
@@ -38,6 +39,7 @@ public class UserWithPassword extends User {
claims.put(TOKEN_USER_NAME, StringUtils.isEmpty(user.getName()) ? "" : user.getName());
claims.put(TOKEN_USER_PASSWORD,
StringUtils.isEmpty(user.getPassword()) ? "" : user.getPassword());
claims.put(TOKEN_USER_EMAIL, StringUtils.isEmpty(user.getEmail()) ? "" : user.getEmail());
claims.put(TOKEN_USER_DISPLAY_NAME, user.getDisplayName());
claims.put(TOKEN_CREATE_TIME, System.currentTimeMillis());
claims.put(TOKEN_IS_ADMIN, user.getIsAdmin());

View File

@@ -1,7 +1,7 @@
package com.tencent.supersonic.auth.api.authentication.request;
import javax.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@Data
@@ -12,4 +12,7 @@ public class UserReq {
@NotBlank(message = "password can not be null")
private String password;
@NotBlank(message = "password can not be null")
private String newPassword;
}

View File

@@ -1,7 +1,6 @@
package com.tencent.supersonic.auth.api.authentication.request;
import javax.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@Data

View File

@@ -1,12 +1,13 @@
package com.tencent.supersonic.auth.api.authentication.service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.tencent.supersonic.auth.api.authentication.pojo.Organization;
import com.tencent.supersonic.auth.api.authentication.pojo.UserToken;
import com.tencent.supersonic.auth.api.authentication.request.UserReq;
import com.tencent.supersonic.common.pojo.User;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Set;

View File

@@ -1,12 +1,13 @@
package com.tencent.supersonic.auth.api.authentication.service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.tencent.supersonic.common.pojo.User;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public interface UserStrategy {
String getStrategyName();
boolean accept(boolean isEnableAuthentication);
User findUser(HttpServletRequest request, HttpServletResponse response);

View File

@@ -1,13 +1,12 @@
package com.tencent.supersonic.auth.api.authentication.utils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.tencent.supersonic.auth.api.authentication.service.UserStrategy;
import com.tencent.supersonic.common.config.SystemConfig;
import com.tencent.supersonic.common.pojo.User;
import com.tencent.supersonic.common.service.SystemConfigService;
import com.tencent.supersonic.common.util.ContextUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.util.CollectionUtils;
public final class UserHolder {

View File

@@ -1,7 +1,5 @@
package com.tencent.supersonic.auth.authentication.adaptor;
import javax.servlet.http.HttpServletRequest;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.tencent.supersonic.auth.api.authentication.adaptor.UserAdaptor;
@@ -16,6 +14,7 @@ import com.tencent.supersonic.auth.authentication.utils.TokenService;
import com.tencent.supersonic.common.pojo.User;
import com.tencent.supersonic.common.util.AESEncryptionUtil;
import com.tencent.supersonic.common.util.ContextUtils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;

View File

@@ -1,21 +1,13 @@
package com.tencent.supersonic.auth.authentication.interceptor;
import javax.servlet.http.HttpServletRequest;
import com.tencent.supersonic.auth.api.authentication.config.AuthenticationConfig;
import com.tencent.supersonic.auth.api.authentication.constant.UserConstants;
import com.tencent.supersonic.auth.authentication.service.UserServiceImpl;
import com.tencent.supersonic.auth.authentication.utils.TokenService;
import com.tencent.supersonic.common.util.S2ThreadContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.connector.RequestFacade;
import org.apache.commons.lang3.StringUtils;
import org.apache.tomcat.util.http.MimeHeaders;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;
import org.springframework.web.servlet.HandlerInterceptor;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
@@ -28,8 +20,6 @@ public abstract class AuthenticationInterceptor implements HandlerInterceptor {
protected TokenService tokenService;
protected S2ThreadContext s2ThreadContext;
protected boolean isExcludedUri(String uri) {
String excludePathStr = authenticationConfig.getExcludePath();
if (StringUtils.isEmpty(excludePathStr)) {
@@ -54,52 +44,4 @@ public abstract class AuthenticationInterceptor implements HandlerInterceptor {
return includePaths.stream().anyMatch(uri::startsWith);
}
protected boolean isInternalRequest(HttpServletRequest request) {
String internal = request.getHeader(UserConstants.INTERNAL);
return "true".equalsIgnoreCase(internal);
}
protected boolean isAppRequest(HttpServletRequest request) {
String appId = request.getHeader(authenticationConfig.getAppId());
return StringUtils.isNotBlank(appId);
}
protected void reflectSetParam(HttpServletRequest request, String key, String value) {
try {
if (request instanceof StandardMultipartHttpServletRequest) {
RequestFacade servletRequest =
(RequestFacade) ((StandardMultipartHttpServletRequest) request)
.getRequest();
Class<? extends HttpServletRequest> servletRequestClazz = servletRequest.getClass();
Field request1 = servletRequestClazz.getDeclaredField("request");
request1.setAccessible(true);
Object o = request1.get(servletRequest);
Field coyoteRequest = o.getClass().getDeclaredField("coyoteRequest");
coyoteRequest.setAccessible(true);
Object o1 = coyoteRequest.get(o);
Field headers = o1.getClass().getDeclaredField("headers");
headers.setAccessible(true);
MimeHeaders o2 = (MimeHeaders) headers.get(o1);
if (o2.getValue(key) != null) {
o2.setValue(key).setString(value);
} else {
o2.addValue(key).setString(value);
}
} else {
Class<? extends HttpServletRequest> requestClass = request.getClass();
Field request1 = requestClass.getDeclaredField("request");
request1.setAccessible(true);
Object o = request1.get(request);
Field coyoteRequest = o.getClass().getDeclaredField("coyoteRequest");
coyoteRequest.setAccessible(true);
Object o1 = coyoteRequest.get(o);
Field headers = o1.getClass().getDeclaredField("headers");
headers.setAccessible(true);
MimeHeaders o2 = (MimeHeaders) headers.get(o1);
o2.addValue(key).setString(value);
}
} catch (Exception e) {
log.error("reflectSetParam error:", e);
}
}
}

View File

@@ -1,19 +1,15 @@
package com.tencent.supersonic.auth.authentication.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.tencent.supersonic.auth.api.authentication.annotation.AuthenticationIgnore;
import com.tencent.supersonic.auth.api.authentication.config.AuthenticationConfig;
import com.tencent.supersonic.auth.api.authentication.pojo.UserWithPassword;
import com.tencent.supersonic.auth.authentication.service.UserServiceImpl;
import com.tencent.supersonic.auth.authentication.utils.TokenService;
import com.tencent.supersonic.common.pojo.User;
import com.tencent.supersonic.common.pojo.exception.AccessException;
import com.tencent.supersonic.common.util.ContextUtils;
import com.tencent.supersonic.common.util.S2ThreadContext;
import com.tencent.supersonic.common.util.ThreadContext;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.method.HandlerMethod;
@@ -36,19 +32,10 @@ public class DefaultAuthenticationInterceptor extends AuthenticationInterceptor
authenticationConfig = ContextUtils.getBean(AuthenticationConfig.class);
userServiceImpl = ContextUtils.getBean(UserServiceImpl.class);
tokenService = ContextUtils.getBean(TokenService.class);
s2ThreadContext = ContextUtils.getBean(S2ThreadContext.class);
if (!authenticationConfig.isEnabled()) {
setFakerUser(request);
return true;
}
if (isInternalRequest(request)) {
setFakerUser(request);
return true;
}
if (isAppRequest(request)) {
setFakerUser(request);
return true;
}
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
@@ -69,35 +56,11 @@ public class DefaultAuthenticationInterceptor extends AuthenticationInterceptor
UserWithPassword user = getUserWithPassword(request);
if (user != null) {
setContext(user.getName(), request);
return true;
}
throw new AccessException("authentication failed, please login");
}
private void setFakerUser(HttpServletRequest request) {
String token = generateAdminToken(request);
reflectSetParam(request, authenticationConfig.getTokenHttpHeaderKey(), token);
setContext(User.getDefaultUser().getName(), request);
}
private void setContext(String userName, HttpServletRequest request) {
ThreadContext threadContext = ThreadContext.builder()
.token(request.getHeader(authenticationConfig.getTokenHttpHeaderKey()))
.userName(userName).build();
s2ThreadContext.set(threadContext);
}
public String generateAdminToken(HttpServletRequest request) {
UserWithPassword admin = new UserWithPassword("admin");
admin.setId(1L);
admin.setName("admin");
admin.setPassword("c3VwZXJzb25pY0BiaWNvbdktJJYWw6A3rEmBUPzbn/6DNeYnD+y3mAwDKEMS3KVT");
admin.setDisplayName("admin");
admin.setIsAdmin(1);
return tokenService.generateToken(UserWithPassword.convert(admin), request);
}
public UserWithPassword getUserWithPassword(HttpServletRequest request) {
final Optional<Claims> claimsOptional = tokenService.getClaims(request);
if (!claimsOptional.isPresent()) {

View File

@@ -1,7 +1,13 @@
package com.tencent.supersonic.auth.authentication.persistence.dataobject;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
@TableName("s2_user")
public class UserDO {
/** */
@TableId(type = IdType.AUTO)
private Long id;
/** */

View File

@@ -1,5 +1,7 @@
package com.tencent.supersonic.auth.authentication.persistence.mapper;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDO;
import com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDOExample;
import org.apache.ibatis.annotations.Mapper;
@@ -7,12 +9,8 @@ import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface UserDOMapper {
public interface UserDOMapper extends BaseMapper<UserDO> {
/** @mbg.generated */
int insert(UserDO record);
/** @mbg.generated */
List<UserDO> selectByExample(UserDOExample example);
void updateByPrimaryKey(UserDO userDO);

View File

@@ -51,7 +51,7 @@ public class UserRepositoryImpl implements UserRepository {
@Override
public List<UserTokenDO> getUserTokenListByName(String userName) {
QueryWrapper<UserTokenDO> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("user_name", userName);
queryWrapper.lambda().eq(UserTokenDO::getUserName, userName);
return userTokenDOMapper.selectList(queryWrapper);
}
@@ -68,7 +68,7 @@ public class UserRepositoryImpl implements UserRepository {
@Override
public void deleteUserTokenByName(String userName) {
QueryWrapper<UserTokenDO> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("user_name", userName);
queryWrapper.lambda().eq(UserTokenDO::getUserName, userName);
userTokenDOMapper.delete(queryWrapper);
}

View File

@@ -1,14 +1,13 @@
package com.tencent.supersonic.auth.authentication.rest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.tencent.supersonic.auth.api.authentication.pojo.Organization;
import com.tencent.supersonic.auth.api.authentication.pojo.UserToken;
import com.tencent.supersonic.auth.api.authentication.request.UserReq;
import com.tencent.supersonic.auth.api.authentication.request.UserTokenReq;
import com.tencent.supersonic.auth.api.authentication.service.UserService;
import com.tencent.supersonic.common.pojo.User;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@@ -73,6 +72,13 @@ public class UserController {
return userService.login(userCmd, request);
}
@PostMapping("/resetPassword")
public void resetPassword(@RequestBody UserReq userCmd, HttpServletRequest request,
HttpServletResponse response) {
User user = userService.getCurrentUser(request, response);
userService.resetPassword(user.getName(), userCmd.getPassword(), userCmd.getNewPassword());
}
@PostMapping("/generateToken")
public UserToken generateToken(@RequestBody UserTokenReq userTokenReq,
HttpServletRequest request, HttpServletResponse response) {

View File

@@ -1,8 +1,5 @@
package com.tencent.supersonic.auth.authentication.service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.tencent.supersonic.auth.api.authentication.pojo.Organization;
import com.tencent.supersonic.auth.api.authentication.pojo.UserToken;
import com.tencent.supersonic.auth.api.authentication.request.UserReq;
@@ -12,6 +9,8 @@ import com.tencent.supersonic.auth.authentication.utils.ComponentFactory;
import com.tencent.supersonic.common.config.SystemConfig;
import com.tencent.supersonic.common.pojo.User;
import com.tencent.supersonic.common.service.SystemConfigService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

View File

@@ -1,15 +1,21 @@
package com.tencent.supersonic.auth.authentication.strategy;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.tencent.supersonic.auth.api.authentication.service.UserStrategy;
import com.tencent.supersonic.common.pojo.User;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Service;
@Service
public class FakeUserStrategy implements UserStrategy {
public static final String STRATEGY_NAME = "fake";
@Override
public String getStrategyName() {
return STRATEGY_NAME;
}
@Override
public boolean accept(boolean isEnableAuthentication) {
return !isEnableAuthentication;

View File

@@ -1,13 +1,12 @@
package com.tencent.supersonic.auth.authentication.strategy;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.tencent.supersonic.auth.api.authentication.constant.UserConstants;
import com.tencent.supersonic.auth.api.authentication.service.UserStrategy;
import com.tencent.supersonic.auth.authentication.utils.TokenService;
import com.tencent.supersonic.common.pojo.User;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Service;
import java.util.Optional;
@@ -15,12 +14,18 @@ import java.util.Optional;
@Service
public class HttpHeaderUserStrategy implements UserStrategy {
public static final String STRATEGY_NAME = "http";
private final TokenService tokenService;
public HttpHeaderUserStrategy(TokenService tokenService) {
this.tokenService = tokenService;
}
@Override
public String getStrategyName() {
return STRATEGY_NAME;
}
@Override
public boolean accept(boolean isEnableAuthentication) {
return isEnableAuthentication;

View File

@@ -1,14 +1,15 @@
package com.tencent.supersonic.auth.authentication.strategy;
import javax.annotation.PostConstruct;
import com.tencent.supersonic.auth.api.authentication.config.AuthenticationConfig;
import com.tencent.supersonic.auth.api.authentication.service.UserStrategy;
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
import jakarta.annotation.PostConstruct;
import lombok.Data;
import org.springframework.context.annotation.Configuration;
import java.util.List;
import java.util.Optional;
@Configuration
@Data
@@ -26,10 +27,26 @@ public class UserStrategyFactory {
@PostConstruct
public void setUserStrategy() {
for (UserStrategy userStrategy : userStrategyList) {
if (userStrategy.accept(authenticationConfig.isEnabled())) {
UserHolder.setStrategy(userStrategy);
boolean enabled = authenticationConfig.isEnabled();
if (!enabled) {
for (UserStrategy userStrategy : userStrategyList) {
if (userStrategy.accept(authenticationConfig.isEnabled())) {
UserHolder.setStrategy(userStrategy);
}
}
return;
}
String strategy = authenticationConfig.getStrategy();
Optional<UserStrategy> strategyOptional = userStrategyList.stream()
.filter(t -> t.accept(true) && strategy.equalsIgnoreCase(t.getStrategyName()))
.findAny();
if (strategyOptional.isPresent()) {
UserHolder.setStrategy(strategyOptional.get());
} else {
throw new IllegalStateException("strategy is not found: " + strategy);
}
}
}

View File

@@ -1,7 +1,8 @@
package com.tencent.supersonic.auth.authentication.utils;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import com.tencent.supersonic.auth.api.authentication.config.AuthenticationConfig;
import com.tencent.supersonic.auth.api.authentication.pojo.UserWithPassword;
@@ -9,6 +10,7 @@ import com.tencent.supersonic.common.pojo.exception.AccessException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

View File

@@ -59,14 +59,6 @@
limit #{limitStart} , #{limitEnd}
</if>
</select>
<insert id="insert" parameterType="com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDO">
insert into s2_user (id, name, password, salt,
display_name, email, is_admin
)
values (#{id,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, #{salt,jdbcType=VARCHAR},
#{displayName,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR}, #{isAdmin,jdbcType=INTEGER}
)
</insert>
<insert id="insertSelective" parameterType="com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDO">
insert into s2_user
<trim prefix="(" suffix=")" suffixOverrides=",">

View File

@@ -12,8 +12,8 @@
<artifactId>auth-authorization</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>
<dependencies>

View File

@@ -1,14 +1,13 @@
package com.tencent.supersonic.auth.authorization.rest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
import com.tencent.supersonic.auth.api.authorization.pojo.AuthGroup;
import com.tencent.supersonic.auth.api.authorization.request.QueryAuthResReq;
import com.tencent.supersonic.auth.api.authorization.response.AuthorizedResourceResp;
import com.tencent.supersonic.auth.api.authorization.service.AuthService;
import com.tencent.supersonic.common.pojo.User;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

View File

@@ -8,7 +8,6 @@ import java.util.List;
/** extended information command about model */
@Data
@ToString
public class ChatConfigBaseReq {
private Long modelId;

View File

@@ -17,6 +17,8 @@ public class ChatMemoryFilter {
private Integer agentId;
private Long queryId;
private String question;
private List<String> questions;

View File

@@ -1,12 +1,17 @@
package com.tencent.supersonic.chat.api.pojo.request;
import javax.validation.constraints.NotNull;
import com.tencent.supersonic.chat.api.pojo.enums.MemoryReviewResult;
import com.tencent.supersonic.chat.api.pojo.enums.MemoryStatus;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ChatMemoryUpdateReq {
@NotNull(message = "id不可为空")
@@ -21,4 +26,8 @@ public class ChatMemoryUpdateReq {
private MemoryReviewResult humanReviewRet;
private String humanReviewCmt;
private MemoryReviewResult llmReviewRet;
private String llmReviewCmt;
}

View File

@@ -1,22 +0,0 @@
package com.tencent.supersonic.chat.api.pojo.request;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.util.List;
/** the entity info about the model */
@Data
@AllArgsConstructor
@ToString
@NoArgsConstructor
public class Entity {
/** uniquely identifies an entity */
private Long entityId;
/** entity name list */
private List<String> names;
}

View File

@@ -4,7 +4,6 @@ import lombok.Data;
import lombok.ToString;
@Data
@ToString
public class ItemNameVisibility {
private ItemNameVisibilityInfo aggVisibilityInfo;

View File

@@ -7,7 +7,6 @@ import java.util.ArrayList;
import java.util.List;
@Data
@ToString
public class ItemNameVisibilityInfo {
/** invisible dimensions */

View File

@@ -7,7 +7,6 @@ import java.util.ArrayList;
import java.util.List;
@Data
@ToString
public class ItemVisibility {
/** invisible dimensions */

View File

@@ -1,8 +1,7 @@
package com.tencent.supersonic.chat.api.pojo.request;
import javax.validation.constraints.NotNull;
import com.tencent.supersonic.common.pojo.enums.TypeEnums;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/** information about dictionary about the model */

View File

@@ -6,7 +6,6 @@ import lombok.NoArgsConstructor;
import lombok.ToString;
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class RecommendedQuestionReq {

View File

@@ -6,7 +6,6 @@ import lombok.ToString;
import java.util.Date;
@ToString
@Data
public class DictLatestTaskResp {

View File

@@ -1,14 +0,0 @@
package com.tencent.supersonic.chat.api.pojo.response;
import com.tencent.supersonic.headless.api.pojo.SchemaElement;
import lombok.Data;
import java.util.List;
@Data
public class EntityRichInfoResp {
/** entity alias */
private List<String> names;
private SchemaElement dimItem;
}

View File

@@ -3,7 +3,6 @@ package com.tencent.supersonic.chat.api.pojo.response;
import com.tencent.supersonic.common.pojo.QueryAuthorization;
import com.tencent.supersonic.common.pojo.QueryColumn;
import com.tencent.supersonic.headless.api.pojo.AggregateInfo;
import com.tencent.supersonic.headless.api.pojo.EntityInfo;
import com.tencent.supersonic.headless.api.pojo.SchemaElement;
import com.tencent.supersonic.headless.api.pojo.SemanticParseInfo;
import com.tencent.supersonic.headless.api.pojo.response.QueryState;
@@ -26,7 +25,6 @@ public class QueryResult {
private String textResult;
private String textSummary;
private Long queryTimeCost;
private EntityInfo entityInfo;
private List<SchemaElement> recommendedDimensions;
private AggregateInfo aggregateInfo;
private String errorMsg;

View File

@@ -3,10 +3,12 @@ package com.tencent.supersonic.chat.api.pojo.response;
import com.tencent.supersonic.chat.api.pojo.request.RecommendedQuestionReq;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class RecommendQuestionResp {
private Long modelId;

View File

@@ -1,10 +1,14 @@
package com.tencent.supersonic.chat.api.pojo.response;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SimilarQueryRecallResp {
private Long queryId;

View File

@@ -1,9 +1,11 @@
package com.tencent.supersonic.chat.server.agent;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.tencent.supersonic.chat.server.memory.MemoryReviewTask;
import com.tencent.supersonic.common.pojo.ChatApp;
import com.tencent.supersonic.common.pojo.RecordInfo;
import com.tencent.supersonic.common.pojo.User;
import lombok.Data;
import org.springframework.util.CollectionUtils;
@@ -12,6 +14,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
@Data
@@ -33,6 +36,11 @@ public class Agent extends RecordInfo {
private String toolConfig;
private Map<String, ChatApp> chatAppConfig = Collections.emptyMap();
private VisualConfig visualConfig;
private List<String> admins = Lists.newArrayList();
private List<String> viewers = Lists.newArrayList();
private List<String> adminOrgs = Lists.newArrayList();
private List<String> viewOrgs = Lists.newArrayList();
private Integer isOpen = 0;
public List<String> getTools(AgentToolType type) {
Map<String, Object> map = JSONObject.parseObject(toolConfig, Map.class);
@@ -105,4 +113,13 @@ public class Agent extends RecordInfo {
.filter(dataSetIds -> !CollectionUtils.isEmpty(dataSetIds))
.flatMap(Collection::stream).collect(Collectors.toSet());
}
public boolean contains(User user, Function<Agent, List<String>> list) {
return list.apply(this).contains(user.getName());
}
public boolean openToAll() {
return isOpen != null && isOpen == 1;
}
}

View File

@@ -26,7 +26,7 @@ import java.util.stream.Collectors;
public class PlainTextExecutor implements ChatQueryExecutor {
public static final String APP_KEY = "SMALL_TALK";
private static final String INSTRUCTION = "" + "#Role: You are a nice person to talk to."
private static final String INSTRUCTION = "#Role: You are a nice person to talk to."
+ "\n#Task: Respond quickly and nicely to the user."
+ "\n#Rules: 1.ALWAYS use the same language as the `#Current Input`."
+ "\n#History Inputs: %s" + "\n#Current Input: %s" + "\n#Response: ";

View File

@@ -2,8 +2,8 @@ package com.tencent.supersonic.chat.server.executor;
import com.tencent.supersonic.chat.api.pojo.enums.MemoryStatus;
import com.tencent.supersonic.chat.api.pojo.response.QueryResult;
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatMemoryDO;
import com.tencent.supersonic.chat.server.pojo.ChatContext;
import com.tencent.supersonic.chat.server.pojo.ChatMemory;
import com.tencent.supersonic.chat.server.pojo.ExecuteContext;
import com.tencent.supersonic.chat.server.service.ChatContextService;
import com.tencent.supersonic.chat.server.service.MemoryService;
@@ -44,7 +44,7 @@ public class SqlExecutor implements ChatQueryExecutor {
Text2SQLExemplar.class);
MemoryService memoryService = ContextUtils.getBean(MemoryService.class);
memoryService.createMemory(ChatMemoryDO.builder()
memoryService.createMemory(ChatMemory.builder().queryId(queryResult.getQueryId())
.agentId(executeContext.getAgent().getId()).status(MemoryStatus.PENDING)
.question(exemplar.getQuestion()).sideInfo(exemplar.getSideInfo())
.dbSchema(exemplar.getDbSchema()).s2sql(exemplar.getSql())
@@ -77,6 +77,7 @@ public class SqlExecutor implements ChatQueryExecutor {
long startTime = System.currentTimeMillis();
QueryResult queryResult = new QueryResult();
queryResult.setQueryId(executeContext.getRequest().getQueryId());
queryResult.setChatContext(parseInfo);
queryResult.setQueryMode(parseInfo.getQueryMode());
queryResult.setQueryTimeCost(System.currentTimeMillis() - startTime);

View File

@@ -1,11 +1,15 @@
package com.tencent.supersonic.chat.server.memory;
import com.tencent.supersonic.chat.api.pojo.enums.MemoryReviewResult;
import com.tencent.supersonic.chat.api.pojo.enums.MemoryStatus;
import com.tencent.supersonic.chat.api.pojo.request.ChatMemoryFilter;
import com.tencent.supersonic.chat.api.pojo.request.ChatMemoryUpdateReq;
import com.tencent.supersonic.chat.server.agent.Agent;
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatMemoryDO;
import com.tencent.supersonic.chat.server.pojo.ChatMemory;
import com.tencent.supersonic.chat.server.service.AgentService;
import com.tencent.supersonic.chat.server.service.MemoryService;
import com.tencent.supersonic.common.pojo.ChatApp;
import com.tencent.supersonic.common.pojo.User;
import com.tencent.supersonic.common.pojo.enums.AppModule;
import com.tencent.supersonic.common.util.ChatAppManager;
import com.tencent.supersonic.headless.server.utils.ModelConfigHelper;
@@ -21,6 +25,7 @@ import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -57,24 +62,36 @@ public class MemoryReviewTask {
@Scheduled(fixedDelay = 60 * 1000)
public void review() {
memoryService.getMemoriesForLlmReview().stream().forEach(memory -> {
try {
processMemory(memory);
} catch (Exception e) {
log.error("Exception occurred while processing memory with id {}: {}",
memory.getId(), e.getMessage(), e);
List<Agent> agentList = agentService.getAgents();
for (Agent agent : agentList) {
if (!agent.enableMemoryReview()) {
continue;
}
});
ChatMemoryFilter chatMemoryFilter =
ChatMemoryFilter.builder().agentId(agent.getId()).build();
memoryService.getMemories(chatMemoryFilter).forEach(memory -> {
try {
processMemory(memory, agent);
} catch (Exception e) {
log.error("Exception occurred while processing memory with id {}: {}",
memory.getId(), e.getMessage(), e);
}
});
}
}
private void processMemory(ChatMemoryDO m) {
Agent chatAgent = agentService.getAgent(m.getAgentId());
if (Objects.isNull(chatAgent)) {
private void processMemory(ChatMemory m, Agent agent) {
if (Objects.isNull(agent)) {
log.warn("Agent id {} not found or memory review disabled", m.getAgentId());
return;
}
ChatApp chatApp = chatAgent.getChatAppConfig().get(APP_KEY);
// if either LLM or human has reviewed, just return
if (Objects.nonNull(m.getLlmReviewRet()) || Objects.nonNull(m.getHumanReviewRet())) {
return;
}
ChatApp chatApp = agent.getChatAppConfig().get(APP_KEY);
if (Objects.isNull(chatApp) || !chatApp.isEnable()) {
return;
}
@@ -90,25 +107,28 @@ public class MemoryReviewTask {
response);
processResponse(response, m);
} else {
log.debug("ChatLanguageModel not found for agent:{}", chatAgent.getId());
log.debug("ChatLanguageModel not found for agent:{}", agent.getId());
}
}
private String createPromptString(ChatMemoryDO m, String promptTemplate) {
private String createPromptString(ChatMemory m, String promptTemplate) {
return String.format(promptTemplate, m.getQuestion(), m.getDbSchema(), m.getSideInfo(),
m.getS2sql());
}
private void processResponse(String response, ChatMemoryDO m) {
private void processResponse(String response, ChatMemory m) {
Matcher matcher = OUTPUT_PATTERN.matcher(response);
if (matcher.find()) {
m.setLlmReviewRet(MemoryReviewResult.getMemoryReviewResult(matcher.group(1)));
m.setLlmReviewCmt(matcher.group(2));
// directly enable memory if the LLM determines it positive
if (MemoryReviewResult.POSITIVE.equals(m.getLlmReviewRet())) {
memoryService.enableMemory(m);
m.setStatus(MemoryStatus.ENABLED);
}
memoryService.updateMemory(m);
ChatMemoryUpdateReq memoryUpdateReq = ChatMemoryUpdateReq.builder().id(m.getId())
.status(m.getStatus()).llmReviewRet(m.getLlmReviewRet())
.llmReviewCmt(m.getLlmReviewCmt()).build();
memoryService.updateMemory(memoryUpdateReq, User.getDefaultUser());
}
}
}

View File

@@ -83,11 +83,15 @@ public class NL2SQLParser implements ChatQueryParser {
if (Objects.isNull(parseContext.getRequest().getSelectedParse())) {
QueryNLReq queryNLReq = QueryReqConverter.buildQueryNLReq(parseContext);
queryNLReq.setText2SQLType(Text2SQLType.ONLY_RULE);
if (parseContext.enableLLM()) {
queryNLReq.setText2SQLType(Text2SQLType.NONE);
}
// for every requested dataSet, recursively invoke rule-based parser with different
// mapModes
Set<Long> requestedDatasets = queryNLReq.getDataSetIds();
List<SemanticParseInfo> candidateParses = Lists.newArrayList();
StringBuilder errMsg = new StringBuilder();
for (Long datasetId : requestedDatasets) {
queryNLReq.setDataSetIds(Collections.singleton(datasetId));
ChatParseResp parseResp = new ChatParseResp(parseContext.getRequest().getQueryId());
@@ -96,10 +100,16 @@ public class NL2SQLParser implements ChatQueryParser {
queryNLReq.setMapModeEnum(mode);
doParse(queryNLReq, parseResp);
}
if (parseResp.getSelectedParses().isEmpty()) {
if (parseResp.getSelectedParses().isEmpty() && candidateParses.isEmpty()) {
queryNLReq.setMapModeEnum(MapModeEnum.LOOSE);
doParse(queryNLReq, parseResp);
}
if (parseResp.getSelectedParses().isEmpty()) {
errMsg.append(parseResp.getErrorMsg());
continue;
}
// for one dataset select the top 1 parse after sorting
SemanticParseInfo.sort(parseResp.getSelectedParses());
candidateParses.add(parseResp.getSelectedParses().get(0));
@@ -110,6 +120,10 @@ public class NL2SQLParser implements ChatQueryParser {
SemanticParseInfo.sort(candidateParses);
parseContext.getResponse().setSelectedParses(
candidateParses.subList(0, Math.min(parserShowCount, candidateParses.size())));
if (parseContext.getResponse().getSelectedParses().isEmpty()) {
parseContext.getResponse().setState(ParseResp.ParseState.FAILED);
parseContext.getResponse().setErrorMsg(errMsg.toString());
}
}
// next go with llm-based parsers unless LLM is disabled or use feedback is needed.
@@ -125,11 +139,18 @@ public class NL2SQLParser implements ChatQueryParser {
SemanticParseInfo userSelectParse = parseContext.getRequest().getSelectedParse();
queryNLReq.setSelectedParseInfo(Objects.nonNull(userSelectParse) ? userSelectParse
: parseContext.getResponse().getSelectedParses().get(0));
parseContext.setResponse(new ChatParseResp(parseContext.getResponse().getQueryId()));
rewriteMultiTurn(parseContext, queryNLReq);
addDynamicExemplars(parseContext, queryNLReq);
doParse(queryNLReq, parseContext.getResponse());
// try again with all semantic fields passed to LLM
if (parseContext.getResponse().getState().equals(ParseResp.ParseState.FAILED)) {
queryNLReq.setSelectedParseInfo(null);
queryNLReq.setMapModeEnum(MapModeEnum.ALL);
doParse(queryNLReq, parseContext.getResponse());
}
}
}

View File

@@ -40,4 +40,14 @@ public class AgentDO {
private String chatModelConfig;
private String visualConfig;
private String admin;
private String viewer;
private String adminOrg;
private String viewOrg;
private Integer isOpen;
}

View File

@@ -1,5 +1,8 @@
package com.tencent.supersonic.chat.server.persistence.dataobject;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.ToString;
@@ -7,9 +10,10 @@ import java.util.Date;
@Data
@ToString
@TableName("s2_chat_config")
public class ChatConfigDO {
/** database auto-increment primary key */
@TableId(type = IdType.AUTO)
private Long id;
private Long modelId;

View File

@@ -1,16 +1,22 @@
package com.tencent.supersonic.chat.server.persistence.dataobject;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.time.Instant;
@Data
@TableName("s2_chat_context")
public class ChatContextDO implements Serializable {
@TableId
private Integer chatId;
private Instant modifiedAt;
private String user;
@TableField("query_user")
private String queryUser;
private String queryText;
private String semanticParse;
}

View File

@@ -4,17 +4,17 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.tencent.supersonic.chat.api.pojo.enums.MemoryReviewResult;
import com.tencent.supersonic.chat.api.pojo.enums.MemoryStatus;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.ToString;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
@TableName("s2_chat_memory")
public class ChatMemoryDO {
@TableId(type = IdType.AUTO)
@@ -23,6 +23,9 @@ public class ChatMemoryDO {
@TableField("agent_id")
private Integer agentId;
@TableField("query_id")
private Long queryId;
@TableField("question")
private String question;
@@ -36,16 +39,16 @@ public class ChatMemoryDO {
private String s2sql;
@TableField("status")
private MemoryStatus status;
private String status;
@TableField("llm_review")
private MemoryReviewResult llmReviewRet;
private String llmReviewRet;
@TableField("llm_comment")
private String llmReviewCmt;
@TableField("human_review")
private MemoryReviewResult humanReviewRet;
private String humanReviewRet;
@TableField("human_comment")
private String humanReviewCmt;

View File

@@ -5,9 +5,6 @@ import lombok.Data;
@Data
public class QueryDO {
public String aggregator = "trend";
public String startTime;
public String endTime;
private long id;
private long questionId;
private String createTime;
@@ -25,7 +22,6 @@ public class QueryDO {
private int topNum;
private String querySql;
private Object queryColumn;
private Object entityInfo;
private int score;
private String feedback;
}

View File

@@ -1,5 +1,6 @@
package com.tencent.supersonic.chat.server.persistence.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.tencent.supersonic.chat.server.config.ChatConfigFilterInternal;
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatConfigDO;
import org.apache.ibatis.annotations.Mapper;
@@ -7,11 +8,7 @@ import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface ChatConfigMapper {
Long addConfig(ChatConfigDO chaConfigPO);
Long editConfig(ChatConfigDO chaConfigPO);
public interface ChatConfigMapper extends BaseMapper<ChatConfigDO> {
List<ChatConfigDO> search(ChatConfigFilterInternal filterInternal);

View File

@@ -1,14 +1,11 @@
package com.tencent.supersonic.chat.server.persistence.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatContextDO;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface ChatContextMapper {
public interface ChatContextMapper extends BaseMapper<ChatContextDO> {
ChatContextDO getContextByChatId(Integer chatId);
int updateContext(ChatContextDO contextDO);
int addContext(ChatContextDO contextDO);
}

View File

@@ -32,15 +32,15 @@ public class ChatConfigRepositoryImpl implements ChatConfigRepository {
@Override
public Long createConfig(ChatConfig chaConfig) {
ChatConfigDO chaConfigDO = chatConfigHelper.chatConfig2DO(chaConfig);
chatConfigMapper.addConfig(chaConfigDO);
chatConfigMapper.insert(chaConfigDO);
return chaConfigDO.getId();
}
@Override
public Long updateConfig(ChatConfig chaConfig) {
ChatConfigDO chaConfigDO = chatConfigHelper.chatConfig2DO(chaConfig);
return chatConfigMapper.editConfig(chaConfigDO);
chatConfigMapper.updateById(chaConfigDO);
return chaConfigDO.getId();
}
@Override

View File

@@ -35,18 +35,13 @@ public class ChatContextRepositoryImpl implements ChatContextRepository {
@Override
public void updateContext(ChatContext chatCtx) {
ChatContextDO context = cast(chatCtx);
if (chatContextMapper.getContextByChatId(chatCtx.getChatId()) == null) {
chatContextMapper.addContext(context);
} else {
chatContextMapper.updateContext(context);
}
chatContextMapper.insertOrUpdate(cast(chatCtx));
}
private ChatContext cast(ChatContextDO contextDO) {
ChatContext chatContext = new ChatContext();
chatContext.setChatId(contextDO.getChatId());
chatContext.setUser(contextDO.getUser());
chatContext.setUser(contextDO.getQueryUser());
chatContext.setQueryText(contextDO.getQueryText());
if (contextDO.getSemanticParse() != null && !contextDO.getSemanticParse().isEmpty()) {
SemanticParseInfo semanticParseInfo =
@@ -60,7 +55,7 @@ public class ChatContextRepositoryImpl implements ChatContextRepository {
ChatContextDO chatContextDO = new ChatContextDO();
chatContextDO.setChatId(chatContext.getChatId());
chatContextDO.setQueryText(chatContext.getQueryText());
chatContextDO.setUser(chatContext.getUser());
chatContextDO.setQueryUser(chatContext.getUser());
if (chatContext.getParseInfo() != null) {
Gson g = new Gson();
chatContextDO.setSemanticParse(g.toJson(chatContext.getParseInfo()));

View File

@@ -17,10 +17,10 @@ import com.tencent.supersonic.chat.server.persistence.mapper.ChatParseMapper;
import com.tencent.supersonic.chat.server.persistence.mapper.ChatQueryDOMapper;
import com.tencent.supersonic.chat.server.persistence.mapper.custom.ShowCaseCustomMapper;
import com.tencent.supersonic.chat.server.persistence.repository.ChatQueryRepository;
import com.tencent.supersonic.common.pojo.QueryColumn;
import com.tencent.supersonic.common.util.JsonUtil;
import com.tencent.supersonic.common.util.PageUtils;
import com.tencent.supersonic.headless.api.pojo.SemanticParseInfo;
import com.tencent.supersonic.headless.api.pojo.response.ParseResp;
import com.tencent.supersonic.headless.api.pojo.response.ParseTimeCostResp;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@@ -117,6 +117,20 @@ public class ChatQueryRepositoryImpl implements ChatQueryRepository {
JsonUtil.toObject(chatQueryDO.getQueryResult(), QueryResult.class);
if (queryResult != null) {
queryResult.setQueryId(chatQueryDO.getQuestionId());
// fix bugs, compatible with bugs caused by history field changes
if (!CollectionUtils.isEmpty(queryResult.getQueryColumns())) {
List<QueryColumn> queryColumns = queryResult.getQueryColumns().stream().peek(x -> {
if (StringUtils.isEmpty(x.getBizName())
&& StringUtils.isNotEmpty(x.getNameEn())) {
x.setBizName(x.getNameEn());
}
if (StringUtils.isNotEmpty(x.getBizName())
&& StringUtils.isEmpty(x.getNameEn())) {
x.setNameEn(x.getBizName());
}
}).collect(Collectors.toList());
queryResult.setQueryColumns(queryColumns);
}
queryResp.setQueryResult(queryResult);
}
queryResp.setSimilarQueries(JSONObject.parseArray(chatQueryDO.getSimilarQueries(),

View File

@@ -7,7 +7,7 @@ import java.util.Map;
public class PluginQueryManager {
private static Map<String, PluginSemanticQuery> pluginQueries = new HashMap<>();
private static final Map<String, PluginSemanticQuery> pluginQueries = new HashMap<>();
public static void register(String queryMode, PluginSemanticQuery pluginSemanticQuery) {
pluginQueries.put(queryMode, pluginSemanticQuery);

View File

@@ -0,0 +1,46 @@
package com.tencent.supersonic.chat.server.pojo;
import com.tencent.supersonic.chat.api.pojo.enums.MemoryReviewResult;
import com.tencent.supersonic.chat.api.pojo.enums.MemoryStatus;
import lombok.*;
import java.util.Date;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class ChatMemory {
private Long id;
private Integer agentId;
private Long queryId;
private String question;
private String sideInfo;
private String dbSchema;
private String s2sql;
private MemoryStatus status;
private MemoryReviewResult llmReviewRet;
private String llmReviewCmt;
private MemoryReviewResult humanReviewRet;
private String humanReviewCmt;
private String createdBy;
private Date createdAt;
private String updatedBy;
private Date updatedAt;
}

View File

@@ -1,6 +1,7 @@
package com.tencent.supersonic.chat.server.pojo;
import com.tencent.supersonic.chat.api.pojo.request.ChatExecuteReq;
import com.tencent.supersonic.chat.api.pojo.response.QueryResult;
import com.tencent.supersonic.chat.server.agent.Agent;
import com.tencent.supersonic.headless.api.pojo.SemanticParseInfo;
import lombok.Data;
@@ -8,6 +9,7 @@ import lombok.Data;
@Data
public class ExecuteContext {
private ChatExecuteReq request;
private QueryResult response;
private Agent agent;
private SemanticParseInfo parseInfo;

View File

@@ -43,12 +43,17 @@ public class DataInterpretProcessor implements ExecuteResultProcessor {
@Override
public void process(ExecuteContext executeContext, QueryResult queryResult) {
public boolean accept(ExecuteContext executeContext) {
Agent agent = executeContext.getAgent();
ChatApp chatApp = agent.getChatAppConfig().get(APP_KEY);
return Objects.nonNull(chatApp) && chatApp.isEnable();
}
@Override
public void process(ExecuteContext executeContext) {
QueryResult queryResult = executeContext.getResponse();
Agent agent = executeContext.getAgent();
ChatApp chatApp = agent.getChatAppConfig().get(APP_KEY);
if (Objects.isNull(chatApp) || !chatApp.isEnable()) {
return;
}
Map<String, Object> variable = new HashMap<>();
variable.put("question", executeContext.getRequest().getQueryText());

View File

@@ -27,17 +27,18 @@ public class DimensionRecommendProcessor implements ExecuteResultProcessor {
private static final int recommend_dimension_size = 5;
@Override
public void process(ExecuteContext executeContext, QueryResult queryResult) {
public boolean accept(ExecuteContext executeContext) {
SemanticParseInfo semanticParseInfo = executeContext.getParseInfo();
return QueryType.AGGREGATE.equals(semanticParseInfo.getQueryType())
&& !CollectionUtils.isEmpty(semanticParseInfo.getMetrics());
}
@Override
public void process(ExecuteContext executeContext) {
QueryResult queryResult = executeContext.getResponse();
SemanticParseInfo semanticParseInfo = executeContext.getParseInfo();
if (!QueryType.AGGREGATE.equals(semanticParseInfo.getQueryType())
|| CollectionUtils.isEmpty(semanticParseInfo.getMetrics())) {
return;
}
Long dataSetId = semanticParseInfo.getDataSetId();
Optional<SchemaElement> firstMetric = semanticParseInfo.getMetrics().stream().findFirst();
if (!firstMetric.isPresent()) {
return;
}
List<SchemaElement> dimensionRecommended =
getDimensions(firstMetric.get().getId(), dataSetId);
queryResult.setRecommendedDimensions(dimensionRecommended);

View File

@@ -1,11 +1,12 @@
package com.tencent.supersonic.chat.server.processor.execute;
import com.tencent.supersonic.chat.api.pojo.response.QueryResult;
import com.tencent.supersonic.chat.server.pojo.ExecuteContext;
import com.tencent.supersonic.chat.server.processor.ResultProcessor;
/** A ExecuteResultProcessor wraps things up before returning execution results to the users. */
public interface ExecuteResultProcessor extends ResultProcessor {
void process(ExecuteContext executeContext, QueryResult queryResult);
boolean accept(ExecuteContext executeContext);
void process(ExecuteContext executeContext);
}

View File

@@ -59,14 +59,18 @@ import static com.tencent.supersonic.common.pojo.Constants.TIME_FORMAT;
public class MetricRatioCalcProcessor implements ExecuteResultProcessor {
@Override
public void process(ExecuteContext executeContext, QueryResult queryResult) {
public boolean accept(ExecuteContext executeContext) {
SemanticParseInfo semanticParseInfo = executeContext.getParseInfo();
AggregatorConfig aggregatorConfig = ContextUtils.getBean(AggregatorConfig.class);
if (CollectionUtils.isEmpty(semanticParseInfo.getMetrics())
|| !aggregatorConfig.getEnableRatio()
|| !QueryType.AGGREGATE.equals(semanticParseInfo.getQueryType())) {
return;
}
return !CollectionUtils.isEmpty(semanticParseInfo.getMetrics())
&& aggregatorConfig.getEnableRatio()
&& QueryType.AGGREGATE.equals(semanticParseInfo.getQueryType());
}
@Override
public void process(ExecuteContext executeContext) {
QueryResult queryResult = executeContext.getResponse();
SemanticParseInfo semanticParseInfo = executeContext.getParseInfo();
AggregateInfo aggregateInfo = getAggregateInfo(executeContext.getRequest().getUser(),
semanticParseInfo, queryResult);
queryResult.setAggregateInfo(aggregateInfo);
@@ -117,8 +121,12 @@ public class MetricRatioCalcProcessor implements ExecuteResultProcessor {
CompletableFuture.allOf(metricInfoRoll, metricInfoOver).join();
metricInfo.setName(metricInfoRoll.get().getName());
metricInfo.setValue(metricInfoRoll.get().getValue());
if (metricInfoRoll.get().getName() != null) {
metricInfo.setName(metricInfoRoll.get().getName());
}
if (metricInfoOver.get().getValue() != null) {
metricInfo.setValue(metricInfoRoll.get().getValue());
}
metricInfo.getStatistics().putAll(metricInfoRoll.get().getStatistics());
metricInfo.getStatistics().putAll(metricInfoOver.get().getStatistics());
@@ -134,7 +142,7 @@ public class MetricRatioCalcProcessor implements ExecuteResultProcessor {
return new HashSet<>();
}
return queryResult.getQueryColumns().stream()
.flatMap(c -> SqlSelectHelper.getColumnFromExpr(c.getNameEn()).stream())
.flatMap(c -> SqlSelectHelper.getFieldsFromExpr(c.getBizName()).stream())
.collect(Collectors.toSet());
}
@@ -159,16 +167,16 @@ public class MetricRatioCalcProcessor implements ExecuteResultProcessor {
Map<String, Object> result = queryResp.getResultList().get(0);
Optional<QueryColumn> valueColumn = queryResp.getColumns().stream()
.filter(c -> c.getNameEn().equals(metric.getBizName())).findFirst();
.filter(c -> c.getBizName().equals(metric.getBizName())).findFirst();
if (!valueColumn.isPresent()) {
return metricInfo;
}
String valueField = String.format("%s_%s", valueColumn.get().getNameEn(),
String valueField = String.format("%s_%s", valueColumn.get().getBizName(),
aggOperatorEnum.getOperator());
if (result.containsKey(valueColumn.get().getNameEn())) {
if (result.containsKey(valueColumn.get().getBizName())) {
DecimalFormat df = new DecimalFormat("#.####");
metricInfo.setValue(df.format(result.get(valueColumn.get().getNameEn())));
metricInfo.setValue(df.format(result.get(valueColumn.get().getBizName())));
}
String ratio = "";
if (Objects.nonNull(result.get(valueField))) {

View File

@@ -1,7 +1,6 @@
package com.tencent.supersonic.chat.server.processor.execute;
import com.alibaba.fastjson.JSONObject;
import com.tencent.supersonic.chat.api.pojo.response.QueryResult;
import com.tencent.supersonic.chat.server.pojo.ExecuteContext;
import com.tencent.supersonic.common.pojo.Constants;
import com.tencent.supersonic.common.pojo.enums.DictWordType;
@@ -16,14 +15,7 @@ import dev.langchain4j.store.embedding.RetrieveQuery;
import dev.langchain4j.store.embedding.RetrieveQueryResult;
import org.springframework.util.CollectionUtils;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
/**
@@ -34,16 +26,20 @@ public class MetricRecommendProcessor implements ExecuteResultProcessor {
private static final int METRIC_RECOMMEND_SIZE = 5;
@Override
public void process(ExecuteContext executeContext, QueryResult queryResult) {
public boolean accept(ExecuteContext executeContext) {
SemanticParseInfo parseInfo = executeContext.getParseInfo();
return Objects.nonNull(parseInfo.getQueryType())
&& parseInfo.getQueryType().equals(QueryType.AGGREGATE)
&& !CollectionUtils.isEmpty(parseInfo.getMetrics())
&& parseInfo.getMetrics().size() <= METRIC_RECOMMEND_SIZE;
}
@Override
public void process(ExecuteContext executeContext) {
fillSimilarMetric(executeContext.getParseInfo());
}
private void fillSimilarMetric(SemanticParseInfo parseInfo) {
if (!parseInfo.getQueryType().equals(QueryType.AGGREGATE)
|| parseInfo.getMetrics().size() > METRIC_RECOMMEND_SIZE
|| CollectionUtils.isEmpty(parseInfo.getMetrics())) {
return;
}
List<String> metricNames =
Collections.singletonList(parseInfo.getMetrics().iterator().next().getName());
Map<String, Object> filterCondition = new HashMap<>();

View File

@@ -4,6 +4,7 @@ import com.tencent.supersonic.chat.server.pojo.ParseContext;
import com.tencent.supersonic.common.pojo.ChatApp;
import com.tencent.supersonic.common.pojo.enums.AppModule;
import com.tencent.supersonic.common.util.ChatAppManager;
import com.tencent.supersonic.headless.api.pojo.response.ParseResp;
import com.tencent.supersonic.headless.server.utils.ModelConfigHelper;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.model.chat.ChatLanguageModel;
@@ -26,7 +27,7 @@ public class ErrorMsgRewriteProcessor implements ParseResultProcessor {
private static final Logger keyPipelineLog = LoggerFactory.getLogger("keyPipeline");
public static final String APP_KEY_ERROR_MESSAGE = "REWRITE_ERROR_MESSAGE";
public static final String APP_KEY = "REWRITE_ERROR_MESSAGE";
private static final String REWRITE_ERROR_MESSAGE_INSTRUCTION = ""
+ "#Role: You are a data business partner who closely interacts with business people.\n"
+ "#Task: Your will be provided with user input, system output and some examples, "
@@ -37,29 +38,36 @@ public class ErrorMsgRewriteProcessor implements ParseResultProcessor {
+ "#Examples: {{examples}}\n" + "#Response: ";
public ErrorMsgRewriteProcessor() {
ChatAppManager.register(APP_KEY_ERROR_MESSAGE,
ChatAppManager.register(APP_KEY,
ChatApp.builder().prompt(REWRITE_ERROR_MESSAGE_INSTRUCTION).name("异常提示改写")
.appModule(AppModule.CHAT).description("通过大模型将异常信息改写为更友好和引导性的提示用语")
.enable(false).build());
.enable(true).build());
}
@Override
public boolean accept(ParseContext parseContext) {
ChatApp chatApp = parseContext.getAgent().getChatAppConfig().get(APP_KEY);
return StringUtils.isNotBlank(parseContext.getResponse().getErrorMsg())
&& Objects.nonNull(chatApp) && chatApp.isEnable();
}
@Override
public void process(ParseContext parseContext) {
String errMsg = parseContext.getResponse().getErrorMsg();
ChatApp chatApp = parseContext.getAgent().getChatAppConfig().get(APP_KEY_ERROR_MESSAGE);
if (StringUtils.isBlank(errMsg) || Objects.isNull(chatApp) || !chatApp.isEnable()) {
return;
}
ChatApp chatApp = parseContext.getAgent().getChatAppConfig().get(APP_KEY);
Map<String, Object> variables = new HashMap<>();
variables.put("user_question", parseContext.getRequest().getQueryText());
variables.put("system_message", errMsg);
StringBuilder exampleStr = new StringBuilder();
parseContext.getResponse().getUsedExemplars().forEach(e -> exampleStr.append(
String.format("<Question:{%s},Schema:{%s}> ", e.getQuestion(), e.getDbSchema())));
parseContext.getAgent().getExamples()
.forEach(e -> exampleStr.append(String.format("<Question:{%s}> ", e)));
if (parseContext.getResponse().getUsedExemplars() != null) {
parseContext.getResponse().getUsedExemplars().forEach(e -> exampleStr.append(String
.format("<Question:{%s},Schema:{%s}> ", e.getQuestion(), e.getDbSchema())));
}
if (parseContext.getAgent().getExamples() != null) {
parseContext.getAgent().getExamples()
.forEach(e -> exampleStr.append(String.format("<Question:{%s}> ", e)));
}
variables.put("examples", exampleStr);
Prompt prompt = PromptTemplate.from(chatApp.getPrompt()).apply(variables);
@@ -68,6 +76,7 @@ public class ErrorMsgRewriteProcessor implements ParseResultProcessor {
Response<AiMessage> response = chatLanguageModel.generate(prompt.toUserMessage());
String rewrittenMsg = response.content().text();
parseContext.getResponse().setErrorMsg(rewrittenMsg);
parseContext.getResponse().setState(ParseResp.ParseState.FAILED);
keyPipelineLog.info("ErrorMessageProcessor modelReq:\n{} \nmodelResp:\n{}", prompt.text(),
rewrittenMsg);
}

View File

@@ -1,34 +1,52 @@
package com.tencent.supersonic.chat.server.processor.parse;
import com.tencent.supersonic.chat.server.plugin.PluginQueryManager;
import com.google.common.collect.Lists;
import com.tencent.supersonic.chat.server.pojo.ParseContext;
import com.tencent.supersonic.common.jsqlparser.FieldExpression;
import com.tencent.supersonic.common.jsqlparser.SqlSelectFunctionHelper;
import com.tencent.supersonic.common.jsqlparser.SqlSelectHelper;
import com.tencent.supersonic.common.pojo.DateConf;
import com.tencent.supersonic.common.pojo.enums.FilterOperatorEnum;
import com.tencent.supersonic.common.pojo.enums.QueryType;
import com.tencent.supersonic.common.util.ContextUtils;
import com.tencent.supersonic.headless.api.pojo.DataSetSchema;
import com.tencent.supersonic.headless.api.pojo.SchemaElement;
import com.tencent.supersonic.headless.api.pojo.SemanticParseInfo;
import com.tencent.supersonic.headless.api.pojo.SqlInfo;
import com.tencent.supersonic.headless.api.pojo.request.QueryFilter;
import com.tencent.supersonic.headless.server.facade.service.SemanticLayerService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
/**
* ParseInfoFormatProcessor formats parse info to make it more readable to the users.
**/
@Slf4j
public class ParseInfoFormatProcessor implements ParseResultProcessor {
@Override
public boolean accept(ParseContext parseContext) {
return !parseContext.getResponse().getSelectedParses().isEmpty();
}
@Override
public void process(ParseContext parseContext) {
parseContext.getResponse().getSelectedParses().forEach(p -> {
if (PluginQueryManager.isPluginQuery(p.getQueryMode())
|| "PLAIN_TEXT".equals(p.getQueryMode())) {
if (Objects.isNull(p.getDataSet()) || Objects.isNull(p.getSqlInfo().getParsedS2SQL())) {
return;
}
formatNL2SQLParseInfo(p);
buildParseInfoFromSQL(p);
buildTextInfo(p);
});
}
private static void formatNL2SQLParseInfo(SemanticParseInfo parseInfo) {
private void buildTextInfo(SemanticParseInfo parseInfo) {
StringBuilder textBuilder = new StringBuilder();
textBuilder.append("**数据集:** ").append(parseInfo.getDataSet().getName()).append(" ");
List<String> metricNames = parseInfo.getMetrics().stream().map(SchemaElement::getName)
@@ -60,4 +78,195 @@ public class ParseInfoFormatProcessor implements ParseResultProcessor {
}
parseInfo.setTextInfo(textBuilder.toString());
}
private void buildParseInfoFromSQL(SemanticParseInfo parseInfo) {
SqlInfo sqlInfo = parseInfo.getSqlInfo();
String s2SQL = sqlInfo.getCorrectedS2SQL();
if (StringUtils.isBlank(s2SQL)) {
return;
}
parseQueryType(parseInfo);
List<FieldExpression> expressions = SqlSelectHelper.getFilterExpression(s2SQL);
Long dataSetId = parseInfo.getDataSetId();
SemanticLayerService semanticLayerService =
ContextUtils.getBean(SemanticLayerService.class);
DataSetSchema dsSchema = semanticLayerService.getDataSetSchema(dataSetId);
// extract date filter from S2SQL
try {
if (!CollectionUtils.isEmpty(expressions)) {
parseInfo.setDateInfo(extractDateFilter(expressions, dsSchema));
}
} catch (Exception e) {
log.error("failed to extract date range:", e);
}
// extract dimension filters from S2SQL
try {
List<QueryFilter> queryFilters = extractDimensionFilter(dsSchema, expressions);
parseInfo.getDimensionFilters().addAll(queryFilters);
} catch (Exception e) {
log.error("failed to extract dimension filters:", e);
}
// extract metrics from S2SQL
List<String> allFields =
filterDateField(dsSchema, SqlSelectHelper.getAllSelectFields(s2SQL));
Set<SchemaElement> metrics = matchSchemaElements(allFields, dsSchema.getMetrics());
parseInfo.setMetrics(metrics);
// extract dimensions from S2SQL
if (QueryType.AGGREGATE.equals(parseInfo.getQueryType())) {
List<String> groupByFields = SqlSelectHelper.getGroupByFields(s2SQL);
List<String> groupByDimensions = filterDateField(dsSchema, groupByFields);
parseInfo.setDimensions(
matchSchemaElements(groupByDimensions, dsSchema.getDimensions()));
} else if (QueryType.DETAIL.equals(parseInfo.getQueryType())) {
List<String> selectFields = SqlSelectHelper.getSelectFields(s2SQL);
List<String> selectDimensions = filterDateField(dsSchema, selectFields);
parseInfo
.setDimensions(matchSchemaElements(selectDimensions, dsSchema.getDimensions()));
}
}
private Set<SchemaElement> matchSchemaElements(List<String> allFields,
Set<SchemaElement> elements) {
return elements.stream().filter(schemaElement -> {
if (CollectionUtils.isEmpty(schemaElement.getAlias())) {
return allFields.contains(schemaElement.getName());
}
Set<String> allFieldsSet = new HashSet<>(allFields);
Set<String> aliasSet = new HashSet<>(schemaElement.getAlias());
List<String> intersection =
allFieldsSet.stream().filter(aliasSet::contains).collect(Collectors.toList());
return allFields.contains(schemaElement.getName())
|| !CollectionUtils.isEmpty(intersection);
}).collect(Collectors.toSet());
}
private List<String> filterDateField(DataSetSchema dataSetSchema, List<String> allFields) {
return allFields.stream().filter(entry -> !isPartitionDimension(dataSetSchema, entry))
.collect(Collectors.toList());
}
private List<QueryFilter> extractDimensionFilter(DataSetSchema dsSchema,
List<FieldExpression> fieldExpressions) {
Map<String, SchemaElement> fieldNameToElement = getNameToElement(dsSchema);
List<QueryFilter> result = Lists.newArrayList();
for (FieldExpression expression : fieldExpressions) {
QueryFilter dimensionFilter = new QueryFilter();
dimensionFilter.setValue(expression.getFieldValue());
SchemaElement schemaElement = fieldNameToElement.get(expression.getFieldName());
if (Objects.isNull(schemaElement)
|| isPartitionDimension(dsSchema, schemaElement.getName())) {
continue;
}
dimensionFilter.setName(schemaElement.getName());
dimensionFilter.setBizName(schemaElement.getBizName());
dimensionFilter.setElementID(schemaElement.getId());
FilterOperatorEnum operatorEnum =
FilterOperatorEnum.getSqlOperator(expression.getOperator());
dimensionFilter.setOperator(operatorEnum);
dimensionFilter.setFunction(expression.getFunction());
result.add(dimensionFilter);
}
return result;
}
private DateConf extractDateFilter(List<FieldExpression> fieldExpressions,
DataSetSchema dataSetSchema) {
List<FieldExpression> dateExpressions = fieldExpressions.stream().filter(
expression -> isPartitionDimension(dataSetSchema, expression.getFieldName()))
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(dateExpressions)) {
return null;
}
DateConf dateInfo = new DateConf();
dateInfo.setDateMode(DateConf.DateMode.BETWEEN);
FieldExpression firstExpression = dateExpressions.get(0);
FilterOperatorEnum firstOperator =
FilterOperatorEnum.getSqlOperator(firstExpression.getOperator());
if (FilterOperatorEnum.EQUALS.equals(firstOperator)
&& Objects.nonNull(firstExpression.getFieldValue())) {
dateInfo.setStartDate(firstExpression.getFieldValue().toString());
dateInfo.setEndDate(firstExpression.getFieldValue().toString());
dateInfo.setDateMode(DateConf.DateMode.BETWEEN);
return dateInfo;
}
if (containOperators(firstExpression, firstOperator, FilterOperatorEnum.GREATER_THAN,
FilterOperatorEnum.GREATER_THAN_EQUALS)) {
dateInfo.setStartDate(firstExpression.getFieldValue().toString());
if (hasSecondDate(dateExpressions)) {
dateInfo.setEndDate(dateExpressions.get(1).getFieldValue().toString());
}
}
if (containOperators(firstExpression, firstOperator, FilterOperatorEnum.MINOR_THAN,
FilterOperatorEnum.MINOR_THAN_EQUALS)) {
dateInfo.setEndDate(firstExpression.getFieldValue().toString());
if (hasSecondDate(dateExpressions)) {
dateInfo.setStartDate(dateExpressions.get(1).getFieldValue().toString());
}
}
return dateInfo;
}
private static boolean isPartitionDimension(DataSetSchema dataSetSchema, String sqlFieldName) {
if (Objects.isNull(dataSetSchema) || Objects.isNull(dataSetSchema.getPartitionDimension())
|| Objects.isNull(dataSetSchema.getPartitionDimension().getName())) {
return false;
}
return sqlFieldName.equalsIgnoreCase(dataSetSchema.getPartitionDimension().getName());
}
private boolean containOperators(FieldExpression expression, FilterOperatorEnum firstOperator,
FilterOperatorEnum... operatorEnums) {
return (Arrays.asList(operatorEnums).contains(firstOperator)
&& Objects.nonNull(expression.getFieldValue()));
}
private boolean hasSecondDate(List<FieldExpression> dateExpressions) {
return dateExpressions.size() > 1
&& Objects.nonNull(dateExpressions.get(1).getFieldValue());
}
private Map<String, SchemaElement> getNameToElement(DataSetSchema dsSchema) {
Set<SchemaElement> dimensions = dsSchema.getDimensions();
Set<SchemaElement> metrics = dsSchema.getMetrics();
List<SchemaElement> allElements = Lists.newArrayList();
allElements.addAll(dimensions);
allElements.addAll(metrics);
// support alias
return allElements.stream().flatMap(schemaElement -> {
Set<Pair<String, SchemaElement>> result = new HashSet<>();
result.add(Pair.of(schemaElement.getName(), schemaElement));
List<String> aliasList = schemaElement.getAlias();
if (!org.springframework.util.CollectionUtils.isEmpty(aliasList)) {
for (String alias : aliasList) {
result.add(Pair.of(alias, schemaElement));
}
}
return result.stream();
}).collect(Collectors.toMap(Pair::getLeft, Pair::getRight, (value1, value2) -> value2));
}
private void parseQueryType(SemanticParseInfo parseInfo) {
parseInfo.setQueryType(QueryType.DETAIL);
SqlInfo sqlInfo = parseInfo.getSqlInfo();
if (Objects.isNull(sqlInfo) || StringUtils.isBlank(sqlInfo.getCorrectedS2SQL())) {
parseInfo.setQueryType(QueryType.DETAIL);
}
// 2. AGG queryType
if (Objects.nonNull(sqlInfo) && StringUtils.isNotBlank(sqlInfo.getParsedS2SQL())
&& SqlSelectFunctionHelper.hasAggregateFunction(sqlInfo.getCorrectedS2SQL())) {
parseInfo.setQueryType(QueryType.AGGREGATE);
}
}
}

View File

@@ -6,5 +6,7 @@ import com.tencent.supersonic.chat.server.processor.ResultProcessor;
/** A ParseResultProcessor wraps things up before returning parsing results to the users. */
public interface ParseResultProcessor extends ResultProcessor {
boolean accept(ParseContext parseContext);
void process(ParseContext parseContext);
}

View File

@@ -23,6 +23,11 @@ import java.util.stream.Collectors;
@Slf4j
public class QueryRecommendProcessor implements ParseResultProcessor {
@Override
public boolean accept(ParseContext parseContext) {
return true;
}
@Override
public void process(ParseContext parseContext) {
CompletableFuture.runAsync(() -> doProcess(parseContext));
@@ -56,8 +61,7 @@ public class QueryRecommendProcessor implements ParseResultProcessor {
private void updateChatQuery(ChatQueryDO chatQueryDO) {
ChatQueryRepository chatQueryRepository = ContextUtils.getBean(ChatQueryRepository.class);
UpdateWrapper<ChatQueryDO> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("question_id", chatQueryDO.getQuestionId());
updateWrapper.set("similar_queries", chatQueryDO.getSimilarQueries());
updateWrapper.lambda().eq(ChatQueryDO::getQuestionId, chatQueryDO.getQuestionId());
chatQueryRepository.updateChatQuery(chatQueryDO, updateWrapper);
}
}

View File

@@ -10,6 +10,11 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
public class TimeCostCalcProcessor implements ParseResultProcessor {
@Override
public boolean accept(ParseContext parseContext) {
return true;
}
@Override
public void process(ParseContext parseContext) {
ChatParseResp parseResp = parseContext.getResponse();

View File

@@ -1,13 +1,13 @@
package com.tencent.supersonic.chat.server.rest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
import com.tencent.supersonic.chat.server.agent.Agent;
import com.tencent.supersonic.chat.server.agent.AgentToolType;
import com.tencent.supersonic.chat.server.service.AgentService;
import com.tencent.supersonic.common.pojo.User;
import com.tencent.supersonic.common.pojo.enums.AuthType;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
@@ -15,6 +15,7 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@@ -48,8 +49,11 @@ public class AgentController {
}
@RequestMapping("/getAgentList")
public List<Agent> getAgentList() {
return agentService.getAgents();
public List<Agent> getAgentList(
@RequestParam(value = "authType", required = false) AuthType authType,
HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
User user = UserHolder.findUser(httpServletRequest, httpServletResponse);
return agentService.getAgents(user, authType);
}
@RequestMapping("/getToolTypes")

View File

@@ -1,8 +1,5 @@
package com.tencent.supersonic.chat.server.rest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
import com.tencent.supersonic.chat.api.pojo.request.ChatConfigBaseReq;
import com.tencent.supersonic.chat.api.pojo.request.ChatConfigEditReqReq;
@@ -14,6 +11,8 @@ import com.tencent.supersonic.common.pojo.User;
import com.tencent.supersonic.headless.api.pojo.DataSetSchema;
import com.tencent.supersonic.headless.api.pojo.response.ItemResp;
import com.tencent.supersonic.headless.server.facade.service.SemanticLayerService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

View File

@@ -1,8 +1,5 @@
package com.tencent.supersonic.chat.server.rest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.github.pagehelper.PageInfo;
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
import com.tencent.supersonic.chat.api.pojo.request.PageQueryInfoReq;
@@ -10,6 +7,8 @@ import com.tencent.supersonic.chat.api.pojo.response.QueryResp;
import com.tencent.supersonic.chat.api.pojo.response.ShowCaseResp;
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatDO;
import com.tencent.supersonic.chat.server.service.ChatManageService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@@ -54,7 +53,7 @@ public class ChatController {
}
@PostMapping("/updateQAFeedback")
public Boolean updateQAFeedback(@RequestParam(value = "id") Integer id,
public Boolean updateQAFeedback(@RequestParam(value = "id") Long id,
@RequestParam(value = "score") Integer score,
@RequestParam(value = "feedback", required = false) String feedback) {
return chatService.updateFeedback(id, score, feedback);

View File

@@ -1,9 +1,5 @@
package com.tencent.supersonic.chat.server.rest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
import com.tencent.supersonic.chat.api.pojo.request.ChatExecuteReq;
import com.tencent.supersonic.chat.api.pojo.request.ChatParseReq;
@@ -14,6 +10,9 @@ import com.tencent.supersonic.common.pojo.User;
import com.tencent.supersonic.common.pojo.exception.InvalidArgumentException;
import com.tencent.supersonic.headless.api.pojo.SemanticParseInfo;
import com.tencent.supersonic.headless.api.pojo.request.DimensionValueReq;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

View File

@@ -1,18 +1,17 @@
package com.tencent.supersonic.chat.server.rest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.github.pagehelper.PageInfo;
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
import com.tencent.supersonic.chat.api.pojo.enums.MemoryReviewResult;
import com.tencent.supersonic.chat.api.pojo.request.ChatMemoryCreateReq;
import com.tencent.supersonic.chat.api.pojo.request.ChatMemoryUpdateReq;
import com.tencent.supersonic.chat.api.pojo.request.PageMemoryReq;
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatMemoryDO;
import com.tencent.supersonic.chat.server.pojo.ChatMemory;
import com.tencent.supersonic.chat.server.service.MemoryService;
import com.tencent.supersonic.common.pojo.User;
import com.tencent.supersonic.headless.api.pojo.request.MetaBatchReq;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@@ -32,7 +31,7 @@ public class MemoryController {
public Boolean createMemory(@RequestBody ChatMemoryCreateReq chatMemoryCreateReq,
HttpServletRequest request, HttpServletResponse response) {
User user = UserHolder.findUser(request, response);
memoryService.createMemory(ChatMemoryDO.builder().agentId(chatMemoryCreateReq.getAgentId())
memoryService.createMemory(ChatMemory.builder().agentId(chatMemoryCreateReq.getAgentId())
.s2sql(chatMemoryCreateReq.getS2sql()).question(chatMemoryCreateReq.getQuestion())
.dbSchema(chatMemoryCreateReq.getDbSchema()).status(chatMemoryCreateReq.getStatus())
.humanReviewRet(MemoryReviewResult.POSITIVE).createdBy(user.getName())
@@ -49,7 +48,7 @@ public class MemoryController {
}
@RequestMapping("/pageMemories")
public PageInfo<ChatMemoryDO> pageMemories(@RequestBody PageMemoryReq pageMemoryReq) {
public PageInfo<ChatMemory> pageMemories(@RequestBody PageMemoryReq pageMemoryReq) {
return memoryService.pageMemories(pageMemoryReq);
}

View File

@@ -1,14 +1,13 @@
package com.tencent.supersonic.chat.server.rest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.tencent.supersonic.auth.api.authentication.annotation.AuthenticationIgnore;
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
import com.tencent.supersonic.chat.api.pojo.request.PluginQueryReq;
import com.tencent.supersonic.chat.server.plugin.ChatPlugin;
import com.tencent.supersonic.chat.server.service.PluginService;
import com.tencent.supersonic.common.pojo.User;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;

View File

@@ -2,10 +2,12 @@ package com.tencent.supersonic.chat.server.service;
import com.tencent.supersonic.chat.server.agent.Agent;
import com.tencent.supersonic.common.pojo.User;
import com.tencent.supersonic.common.pojo.enums.AuthType;
import java.util.List;
public interface AgentService {
List<Agent> getAgents(User user, AuthType authType);
List<Agent> getAgents();

View File

@@ -13,7 +13,6 @@ import com.tencent.supersonic.chat.server.persistence.dataobject.ChatParseDO;
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatQueryDO;
import com.tencent.supersonic.common.pojo.User;
import com.tencent.supersonic.headless.api.pojo.SemanticParseInfo;
import com.tencent.supersonic.headless.api.pojo.response.ParseResp;
import java.util.List;
@@ -24,7 +23,7 @@ public interface ChatManageService {
boolean updateChatName(Long chatId, String chatName, String userName);
boolean updateFeedback(Integer id, Integer score, String feedback);
boolean updateFeedback(Long id, Integer score, String feedback);
boolean updateChatIsTop(Long chatId, int isTop);

View File

@@ -4,27 +4,20 @@ import com.github.pagehelper.PageInfo;
import com.tencent.supersonic.chat.api.pojo.request.ChatMemoryFilter;
import com.tencent.supersonic.chat.api.pojo.request.ChatMemoryUpdateReq;
import com.tencent.supersonic.chat.api.pojo.request.PageMemoryReq;
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatMemoryDO;
import com.tencent.supersonic.chat.server.pojo.ChatMemory;
import com.tencent.supersonic.common.pojo.User;
import java.util.List;
public interface MemoryService {
void createMemory(ChatMemoryDO memory);
void createMemory(ChatMemory memory);
void updateMemory(ChatMemoryUpdateReq chatMemoryUpdateReq, User user);
void updateMemory(ChatMemoryDO memory);
void enableMemory(ChatMemoryDO memory);
void disableMemory(ChatMemoryDO memory);
void batchDelete(List<Long> ids);
PageInfo<ChatMemoryDO> pageMemories(PageMemoryReq pageMemoryReq);
PageInfo<ChatMemory> pageMemories(PageMemoryReq pageMemoryReq);
List<ChatMemoryDO> getMemories(ChatMemoryFilter chatMemoryFilter);
List<ChatMemory> getMemories(ChatMemoryFilter chatMemoryFilter);
List<ChatMemoryDO> getMemoriesForLlmReview();
}

View File

@@ -1,31 +1,34 @@
package com.tencent.supersonic.chat.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tencent.supersonic.auth.api.authentication.service.UserService;
import com.tencent.supersonic.chat.api.pojo.request.ChatMemoryFilter;
import com.tencent.supersonic.chat.api.pojo.request.ChatParseReq;
import com.tencent.supersonic.chat.server.agent.Agent;
import com.tencent.supersonic.chat.server.agent.VisualConfig;
import com.tencent.supersonic.chat.server.persistence.dataobject.AgentDO;
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatMemoryDO;
import com.tencent.supersonic.chat.server.persistence.mapper.AgentDOMapper;
import com.tencent.supersonic.chat.server.pojo.ChatMemory;
import com.tencent.supersonic.chat.server.service.AgentService;
import com.tencent.supersonic.chat.server.service.ChatQueryService;
import com.tencent.supersonic.chat.server.service.MemoryService;
import com.tencent.supersonic.common.config.ChatModel;
import com.tencent.supersonic.common.pojo.ChatApp;
import com.tencent.supersonic.common.pojo.User;
import com.tencent.supersonic.common.pojo.enums.AuthType;
import com.tencent.supersonic.common.service.ChatModelService;
import com.tencent.supersonic.common.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.Set;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;
@Slf4j
@@ -41,7 +44,35 @@ public class AgentServiceImpl extends ServiceImpl<AgentDOMapper, AgentDO> implem
@Autowired
private ChatModelService chatModelService;
private ExecutorService executorService = Executors.newFixedThreadPool(1);
@Autowired
private UserService userService;
@Autowired
@Qualifier("chatExecutor")
private ThreadPoolExecutor executor;
@Override
public List<Agent> getAgents(User user, AuthType authType) {
return getAgentDOList().stream().map(this::convert)
.filter(agent -> filterByAuth(agent, user, authType)).collect(Collectors.toList());
}
private boolean filterByAuth(Agent agent, User user, AuthType authType) {
Set<String> orgIds = userService.getUserAllOrgId(user.getName());
if (user.isSuperAdmin() || agent.openToAll()
|| user.getName().equals(agent.getCreatedBy())) {
return true;
}
authType = authType == null ? AuthType.VIEWER : authType;
switch (authType) {
case ADMIN:
return checkAdminPermission(orgIds, user, agent);
case VIEWER:
default:
return checkViewPermission(orgIds, user, agent);
}
}
@Override
public List<Agent> getAgents() {
@@ -86,7 +117,7 @@ public class AgentServiceImpl extends ServiceImpl<AgentDOMapper, AgentDO> implem
* @param agent
*/
private void executeAgentExamplesAsync(Agent agent) {
executorService.execute(() -> doExecuteAgentExamples(agent));
executor.execute(() -> doExecuteAgentExamples(agent));
}
private synchronized void doExecuteAgentExamples(Agent agent) {
@@ -99,7 +130,7 @@ public class AgentServiceImpl extends ServiceImpl<AgentDOMapper, AgentDO> implem
ChatMemoryFilter chatMemoryFilter =
ChatMemoryFilter.builder().agentId(agent.getId()).questions(examples).build();
List<String> memoriesExisted = memoryService.getMemories(chatMemoryFilter).stream()
.map(ChatMemoryDO::getQuestion).collect(Collectors.toList());
.map(ChatMemory::getQuestion).collect(Collectors.toList());
for (String example : examples) {
if (memoriesExisted.contains(example)) {
continue;
@@ -135,6 +166,11 @@ public class AgentServiceImpl extends ServiceImpl<AgentDOMapper, AgentDO> implem
c.setChatModelConfig(chatModelService.getChatModel(c.getChatModelId()).getConfig());
}
});
agent.setAdmins(JsonUtil.toList(agentDO.getAdmin(), String.class));
agent.setViewers(JsonUtil.toList(agentDO.getViewer(), String.class));
agent.setAdminOrgs(JsonUtil.toList(agentDO.getAdminOrg(), String.class));
agent.setViewOrgs(JsonUtil.toList(agentDO.getViewOrg(), String.class));
agent.setIsOpen(agentDO.getIsOpen());
return agent;
}
@@ -145,9 +181,58 @@ public class AgentServiceImpl extends ServiceImpl<AgentDOMapper, AgentDO> implem
agentDO.setExamples(JsonUtil.toString(agent.getExamples()));
agentDO.setChatModelConfig(JsonUtil.toString(agent.getChatAppConfig()));
agentDO.setVisualConfig(JsonUtil.toString(agent.getVisualConfig()));
agentDO.setAdmin(JsonUtil.toString(agent.getAdmins()));
agentDO.setViewer(JsonUtil.toString(agent.getViewers()));
agentDO.setAdminOrg(JsonUtil.toString(agent.getAdminOrgs()));
agentDO.setViewOrg(JsonUtil.toString(agent.getViewOrgs()));
agentDO.setIsOpen(agent.getIsOpen());
if (agentDO.getStatus() == null) {
agentDO.setStatus(1);
}
return agentDO;
}
private boolean checkAdminPermission(Set<String> orgIds, User user, Agent agent) {
List<String> admins = agent.getAdmins();
List<String> adminOrgs = agent.getAdminOrgs();
if (user.isSuperAdmin()) {
return true;
}
if (admins.contains(user.getName()) || agent.getCreatedBy().equals(user.getName())) {
return true;
}
if (CollectionUtils.isEmpty(adminOrgs)) {
return false;
}
for (String orgId : orgIds) {
if (adminOrgs.contains(orgId)) {
return true;
}
}
return false;
}
private boolean checkViewPermission(Set<String> orgIds, User user, Agent agent) {
if (checkAdminPermission(orgIds, user, agent)) {
return true;
}
List<String> viewers = agent.getViewers();
List<String> viewOrgs = agent.getViewOrgs();
if (agent.openToAll()) {
return true;
}
if (viewers.contains(user.getName())) {
return true;
}
if (CollectionUtils.isEmpty(viewOrgs)) {
return false;
}
for (String orgId : orgIds) {
if (viewOrgs.contains(orgId)) {
return true;
}
}
return false;
}
}

View File

@@ -2,9 +2,9 @@ package com.tencent.supersonic.chat.server.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.tencent.supersonic.chat.api.pojo.request.ChatExecuteReq;
import com.tencent.supersonic.chat.api.pojo.request.ChatParseReq;
import com.tencent.supersonic.chat.api.pojo.request.PageQueryInfoReq;
import com.tencent.supersonic.chat.api.pojo.enums.MemoryReviewResult;
import com.tencent.supersonic.chat.api.pojo.enums.MemoryStatus;
import com.tencent.supersonic.chat.api.pojo.request.*;
import com.tencent.supersonic.chat.api.pojo.response.ChatParseResp;
import com.tencent.supersonic.chat.api.pojo.response.QueryResp;
import com.tencent.supersonic.chat.api.pojo.response.QueryResult;
@@ -15,11 +15,12 @@ import com.tencent.supersonic.chat.server.persistence.dataobject.ChatQueryDO;
import com.tencent.supersonic.chat.server.persistence.dataobject.QueryDO;
import com.tencent.supersonic.chat.server.persistence.repository.ChatQueryRepository;
import com.tencent.supersonic.chat.server.persistence.repository.ChatRepository;
import com.tencent.supersonic.chat.server.pojo.ChatMemory;
import com.tencent.supersonic.chat.server.service.ChatManageService;
import com.tencent.supersonic.chat.server.service.MemoryService;
import com.tencent.supersonic.common.pojo.User;
import com.tencent.supersonic.common.util.JsonUtil;
import com.tencent.supersonic.headless.api.pojo.SemanticParseInfo;
import com.tencent.supersonic.headless.api.pojo.response.ParseResp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -38,6 +39,8 @@ public class ChatManageServiceImpl implements ChatManageService {
private ChatRepository chatRepository;
@Autowired
private ChatQueryRepository chatQueryRepository;
@Autowired
private MemoryService memoryService;
@Override
public Long addChat(User user, String chatName, Integer agentId) {
@@ -64,11 +67,28 @@ public class ChatManageServiceImpl implements ChatManageService {
}
@Override
public boolean updateFeedback(Integer id, Integer score, String feedback) {
public boolean updateFeedback(Long id, Integer score, String feedback) {
QueryDO intelligentQueryDO = new QueryDO();
intelligentQueryDO.setId(id);
intelligentQueryDO.setQuestionId(id);
intelligentQueryDO.setScore(score);
intelligentQueryDO.setFeedback(feedback);
// enable or disable memory based on user feedback
if (score >= 5 || score <= 1) {
ChatMemoryFilter memoryFilter = ChatMemoryFilter.builder().queryId(id).build();
List<ChatMemory> memories = memoryService.getMemories(memoryFilter);
memories.forEach(m -> {
MemoryStatus status = score >= 5 ? MemoryStatus.ENABLED : MemoryStatus.DISABLED;
MemoryReviewResult reviewResult =
score >= 5 ? MemoryReviewResult.POSITIVE : MemoryReviewResult.NEGATIVE;
ChatMemoryUpdateReq memoryUpdateReq = ChatMemoryUpdateReq.builder().id(m.getId())
.status(status).humanReviewRet(reviewResult)
.humanReviewCmt("Reviewed as per user feedback").build();
memoryService.updateMemory(memoryUpdateReq, User.getDefaultUser());
});
}
return chatRepository.updateFeedback(intelligentQueryDO);
}

View File

@@ -18,18 +18,12 @@ import com.tencent.supersonic.chat.server.service.ChatManageService;
import com.tencent.supersonic.chat.server.service.ChatQueryService;
import com.tencent.supersonic.chat.server.util.ComponentFactory;
import com.tencent.supersonic.chat.server.util.QueryReqConverter;
import com.tencent.supersonic.common.jsqlparser.FieldExpression;
import com.tencent.supersonic.common.jsqlparser.SqlAddHelper;
import com.tencent.supersonic.common.jsqlparser.SqlRemoveHelper;
import com.tencent.supersonic.common.jsqlparser.SqlReplaceHelper;
import com.tencent.supersonic.common.jsqlparser.SqlSelectHelper;
import com.tencent.supersonic.common.jsqlparser.*;
import com.tencent.supersonic.common.pojo.User;
import com.tencent.supersonic.common.pojo.enums.FilterOperatorEnum;
import com.tencent.supersonic.common.util.ContextUtils;
import com.tencent.supersonic.common.util.DateUtils;
import com.tencent.supersonic.common.util.JsonUtil;
import com.tencent.supersonic.headless.api.pojo.DataSetSchema;
import com.tencent.supersonic.headless.api.pojo.EntityInfo;
import com.tencent.supersonic.headless.api.pojo.SchemaElement;
import com.tencent.supersonic.headless.api.pojo.SemanticParseInfo;
import com.tencent.supersonic.headless.api.pojo.SqlInfo;
@@ -50,11 +44,7 @@ import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import net.sf.jsqlparser.expression.StringValue;
import net.sf.jsqlparser.expression.operators.relational.ComparisonOperator;
import net.sf.jsqlparser.expression.operators.relational.GreaterThanEquals;
import net.sf.jsqlparser.expression.operators.relational.InExpression;
import net.sf.jsqlparser.expression.operators.relational.MinorThanEquals;
import net.sf.jsqlparser.expression.operators.relational.ParenthesedExpressionList;
import net.sf.jsqlparser.expression.operators.relational.*;
import net.sf.jsqlparser.schema.Column;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
@@ -62,14 +52,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
@@ -108,11 +91,17 @@ public class ChatQueryServiceImpl implements ChatQueryService {
Long queryId = chatParseReq.getQueryId();
if (Objects.isNull(queryId)) {
queryId = chatManageService.createChatQuery(chatParseReq);
chatParseReq.setQueryId(queryId);
}
ParseContext parseContext = buildParseContext(chatParseReq, new ChatParseResp(queryId));
chatQueryParsers.forEach(p -> p.parse(parseContext));
parseResultProcessors.forEach(p -> p.process(parseContext));
for (ParseResultProcessor processor : parseResultProcessors) {
if (processor.accept(parseContext)) {
processor.process(parseContext);
}
}
if (!parseContext.needFeedback()) {
chatManageService.batchAddParse(chatParseReq, parseContext.getResponse());
@@ -133,9 +122,12 @@ public class ChatQueryServiceImpl implements ChatQueryService {
}
}
executeContext.setResponse(queryResult);
if (queryResult != null) {
for (ExecuteResultProcessor processor : executeResultProcessors) {
processor.process(executeContext, queryResult);
if (processor.accept(executeContext)) {
processor.process(executeContext);
}
}
saveQueryResult(chatExecuteReq, queryResult);
}
@@ -198,7 +190,7 @@ public class ChatQueryServiceImpl implements ChatQueryService {
handleRuleQueryMode(semanticQuery, dataSetSchema, user);
}
return executeQuery(semanticQuery, user, dataSetSchema);
return executeQuery(semanticQuery, user);
}
private List<String> getFieldsFromSql(SemanticParseInfo parseInfo) {
@@ -212,20 +204,22 @@ public class ChatQueryServiceImpl implements ChatQueryService {
private void handleLLMQueryMode(ChatQueryDataReq chatQueryDataReq, SemanticQuery semanticQuery,
DataSetSchema dataSetSchema, User user) throws Exception {
SemanticParseInfo parseInfo = semanticQuery.getParseInfo();
List<String> fields = getFieldsFromSql(parseInfo);
if (checkMetricReplace(fields, chatQueryDataReq.getMetrics())) {
log.info("llm begin replace metrics!");
String rebuiltS2SQL;
if (checkMetricReplace(chatQueryDataReq, parseInfo)) {
log.info("rebuild S2SQL with adjusted metrics!");
SchemaElement metricToReplace = chatQueryDataReq.getMetrics().iterator().next();
replaceMetrics(parseInfo, metricToReplace);
rebuiltS2SQL = replaceMetrics(parseInfo, metricToReplace);
} else {
log.info("llm begin revise filters!");
String correctorSql = reviseCorrectS2SQL(chatQueryDataReq, parseInfo, dataSetSchema);
parseInfo.getSqlInfo().setCorrectedS2SQL(correctorSql);
semanticQuery.setParseInfo(parseInfo);
SemanticQueryReq semanticQueryReq = semanticQuery.buildSemanticQueryReq();
SemanticTranslateResp explain = semanticLayerService.translate(semanticQueryReq, user);
parseInfo.getSqlInfo().setQuerySQL(explain.getQuerySQL());
log.info("rebuild S2SQL with adjusted filters!");
rebuiltS2SQL = replaceFilters(chatQueryDataReq, parseInfo, dataSetSchema);
}
// reset SqlInfo and request re-translation
parseInfo.getSqlInfo().setCorrectedS2SQL(rebuiltS2SQL);
parseInfo.getSqlInfo().setParsedS2SQL(rebuiltS2SQL);
parseInfo.getSqlInfo().setQuerySQL(null);
SemanticQueryReq semanticQueryReq = semanticQuery.buildSemanticQueryReq();
SemanticTranslateResp explain = semanticLayerService.translate(semanticQueryReq, user);
parseInfo.getSqlInfo().setQuerySQL(explain.getQuerySQL());
}
private void handleRuleQueryMode(SemanticQuery semanticQuery, DataSetSchema dataSetSchema,
@@ -233,23 +227,22 @@ public class ChatQueryServiceImpl implements ChatQueryService {
log.info("rule begin replace metrics and revise filters!");
validFilter(semanticQuery.getParseInfo().getDimensionFilters());
validFilter(semanticQuery.getParseInfo().getMetricFilters());
semanticQuery.initS2Sql(dataSetSchema, user);
semanticQuery.buildS2Sql(dataSetSchema);
}
private QueryResult executeQuery(SemanticQuery semanticQuery, User user,
DataSetSchema dataSetSchema) throws Exception {
private QueryResult executeQuery(SemanticQuery semanticQuery, User user) throws Exception {
SemanticQueryReq semanticQueryReq = semanticQuery.buildSemanticQueryReq();
SemanticParseInfo parseInfo = semanticQuery.getParseInfo();
QueryResult queryResult = doExecution(semanticQueryReq, parseInfo.getQueryMode(), user);
queryResult.setChatContext(semanticQuery.getParseInfo());
SemanticLayerService semanticService = ContextUtils.getBean(SemanticLayerService.class);
EntityInfo entityInfo = semanticService.getEntityInfo(parseInfo, dataSetSchema, user);
queryResult.setEntityInfo(entityInfo);
parseInfo.getSqlInfo().setQuerySQL(queryResult.getQuerySql());
return queryResult;
}
private boolean checkMetricReplace(List<String> oriFields, Set<SchemaElement> metrics) {
private boolean checkMetricReplace(ChatQueryDataReq chatQueryDataReq,
SemanticParseInfo parseInfo) {
List<String> oriFields = getFieldsFromSql(parseInfo);
Set<SchemaElement> metrics = chatQueryDataReq.getMetrics();
if (CollectionUtils.isEmpty(oriFields) || CollectionUtils.isEmpty(metrics)) {
return false;
}
@@ -258,7 +251,7 @@ public class ChatQueryServiceImpl implements ChatQueryService {
return !oriFields.containsAll(metricNames);
}
private String reviseCorrectS2SQL(ChatQueryDataReq queryData, SemanticParseInfo parseInfo,
private String replaceFilters(ChatQueryDataReq queryData, SemanticParseInfo parseInfo,
DataSetSchema dataSetSchema) {
String correctorSql = parseInfo.getSqlInfo().getCorrectedS2SQL();
log.info("correctorSql before replacing:{}", correctorSql);
@@ -296,7 +289,7 @@ public class ChatQueryServiceImpl implements ChatQueryService {
return correctorSql;
}
private void replaceMetrics(SemanticParseInfo parseInfo, SchemaElement metric) {
private String replaceMetrics(SemanticParseInfo parseInfo, SchemaElement metric) {
List<String> oriMetrics = parseInfo.getMetrics().stream().map(SchemaElement::getName)
.collect(Collectors.toList());
String correctorSql = parseInfo.getSqlInfo().getCorrectedS2SQL();
@@ -308,7 +301,7 @@ public class ChatQueryServiceImpl implements ChatQueryService {
correctorSql = SqlReplaceHelper.replaceAggFields(correctorSql, fieldMap);
}
log.info("after replaceMetrics:{}", correctorSql);
parseInfo.getSqlInfo().setCorrectedS2SQL(correctorSql);
return correctorSql;
}
private QueryResult doExecution(SemanticQueryReq semanticQueryReq, String queryMode, User user)
@@ -483,6 +476,9 @@ public class ChatQueryServiceImpl implements ChatQueryService {
}
private void mergeParseInfo(SemanticParseInfo parseInfo, ChatQueryDataReq queryData) {
if (Objects.nonNull(queryData.getDateInfo())) {
parseInfo.setDateInfo(queryData.getDateInfo());
}
if (LLMSqlQuery.QUERY_MODE.equals(parseInfo.getQueryMode())) {
return;
}
@@ -498,9 +494,7 @@ public class ChatQueryServiceImpl implements ChatQueryService {
if (!CollectionUtils.isEmpty(queryData.getMetricFilters())) {
parseInfo.setMetricFilters(queryData.getMetricFilters());
}
if (Objects.nonNull(queryData.getDateInfo())) {
parseInfo.setDateInfo(queryData.getDateInfo());
}
parseInfo.setSqlInfo(new SqlInfo());
}

View File

@@ -7,7 +7,6 @@ import com.tencent.supersonic.chat.api.pojo.request.ChatConfigEditReqReq;
import com.tencent.supersonic.chat.api.pojo.request.ChatConfigFilter;
import com.tencent.supersonic.chat.api.pojo.request.ChatDefaultConfigReq;
import com.tencent.supersonic.chat.api.pojo.request.ChatDetailConfigReq;
import com.tencent.supersonic.chat.api.pojo.request.Entity;
import com.tencent.supersonic.chat.api.pojo.request.ItemNameVisibilityInfo;
import com.tencent.supersonic.chat.api.pojo.request.ItemVisibility;
import com.tencent.supersonic.chat.api.pojo.request.KnowledgeInfoReq;
@@ -16,7 +15,6 @@ import com.tencent.supersonic.chat.api.pojo.response.ChatConfigResp;
import com.tencent.supersonic.chat.api.pojo.response.ChatConfigRichResp;
import com.tencent.supersonic.chat.api.pojo.response.ChatDefaultRichConfigResp;
import com.tencent.supersonic.chat.api.pojo.response.ChatDetailRichConfigResp;
import com.tencent.supersonic.chat.api.pojo.response.EntityRichInfoResp;
import com.tencent.supersonic.chat.api.pojo.response.ItemVisibilityInfo;
import com.tencent.supersonic.chat.server.config.ChatConfig;
import com.tencent.supersonic.chat.server.persistence.repository.ChatConfigRepository;
@@ -88,16 +86,6 @@ public class ConfigServiceImpl implements ConfigService {
return configEditCmd.getId();
}
public ItemNameVisibilityInfo getVisibilityByModelId(Long modelId) {
ChatConfigResp chatConfigResp = fetchConfigByModelId(modelId);
ChatConfig chatConfig = new ChatConfig();
chatConfig.setModelId(modelId);
chatConfig.setChatAggConfig(chatConfigResp.getChatAggConfig());
chatConfig.setChatDetailConfig(chatConfigResp.getChatDetailConfig());
ItemNameVisibilityInfo itemNameVisibility = getItemNameVisibility(chatConfig);
return itemNameVisibility;
}
public ItemNameVisibilityInfo getItemNameVisibility(ChatConfig chatConfig) {
Long modelId = chatConfig.getModelId();
@@ -240,19 +228,6 @@ public class ConfigServiceImpl implements ConfigService {
return detailRichConfig;
}
private EntityRichInfoResp generateRichEntity(Entity entity, DataSetSchema modelSchema) {
EntityRichInfoResp entityRichInfo = new EntityRichInfoResp();
if (Objects.isNull(entity) || Objects.isNull(entity.getEntityId())) {
return entityRichInfo;
}
BeanUtils.copyProperties(entity, entityRichInfo);
Map<Long, SchemaElement> dimIdAndRespPair = modelSchema.getDimensions().stream().collect(
Collectors.toMap(SchemaElement::getId, Function.identity(), (k1, k2) -> k1));
entityRichInfo.setDimItem(dimIdAndRespPair.get(entity.getEntityId()));
return entityRichInfo;
}
private ChatAggRichConfigResp fillChatAggRichConfig(DataSetSchema modelSchema,
ChatConfigResp chatConfigResp) {
if (Objects.isNull(chatConfigResp) || Objects.isNull(chatConfigResp.getChatAggConfig())) {
@@ -327,7 +302,7 @@ public class ConfigServiceImpl implements ConfigService {
}
Map<Long, SchemaElement> dimIdAndRespPair = modelSchema.getDimensions().stream().collect(
Collectors.toMap(SchemaElement::getId, Function.identity(), (k1, k2) -> k1));
knowledgeInfos.stream().forEach(knowledgeInfo -> {
knowledgeInfos.forEach(knowledgeInfo -> {
if (Objects.nonNull(knowledgeInfo)) {
SchemaElement dimSchemaResp = dimIdAndRespPair.get(knowledgeInfo.getItemId());
if (Objects.nonNull(dimSchemaResp)) {

View File

@@ -1,27 +1,33 @@
package com.tencent.supersonic.chat.server.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tencent.supersonic.chat.api.pojo.enums.MemoryReviewResult;
import com.tencent.supersonic.chat.api.pojo.enums.MemoryStatus;
import com.tencent.supersonic.chat.api.pojo.request.ChatMemoryFilter;
import com.tencent.supersonic.chat.api.pojo.request.ChatMemoryUpdateReq;
import com.tencent.supersonic.chat.api.pojo.request.PageMemoryReq;
import com.tencent.supersonic.chat.server.persistence.dataobject.ChatMemoryDO;
import com.tencent.supersonic.chat.server.persistence.mapper.ChatMemoryMapper;
import com.tencent.supersonic.chat.server.persistence.repository.ChatMemoryRepository;
import com.tencent.supersonic.chat.server.pojo.ChatMemory;
import com.tencent.supersonic.chat.server.service.MemoryService;
import com.tencent.supersonic.common.config.EmbeddingConfig;
import com.tencent.supersonic.common.pojo.Text2SQLExemplar;
import com.tencent.supersonic.common.pojo.User;
import com.tencent.supersonic.common.service.ExemplarService;
import com.tencent.supersonic.common.util.BeanMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@Service
public class MemoryServiceImpl implements MemoryService {
@@ -29,6 +35,9 @@ public class MemoryServiceImpl implements MemoryService {
@Autowired
private ChatMemoryRepository chatMemoryRepository;
@Autowired
private ChatMemoryMapper chatMemoryMapper;
@Autowired
private ExemplarService exemplarService;
@@ -36,34 +45,52 @@ public class MemoryServiceImpl implements MemoryService {
private EmbeddingConfig embeddingConfig;
@Override
public void createMemory(ChatMemoryDO memory) {
public void createMemory(ChatMemory memory) {
// if an existing enabled memory has the same question, just skip
List<ChatMemoryDO> memories =
List<ChatMemory> memories =
getMemories(ChatMemoryFilter.builder().agentId(memory.getAgentId())
.question(memory.getQuestion()).status(MemoryStatus.ENABLED).build());
if (memories.size() == 0) {
chatMemoryRepository.createMemory(memory);
if (memories.isEmpty()) {
ChatMemoryDO memoryDO = getMemoryDO(memory);
chatMemoryRepository.createMemory(memoryDO);
}
}
@Override
public void updateMemory(ChatMemoryUpdateReq chatMemoryUpdateReq, User user) {
ChatMemoryDO chatMemoryDO = chatMemoryRepository.getMemory(chatMemoryUpdateReq.getId());
chatMemoryDO.setUpdatedBy(user.getName());
chatMemoryDO.setUpdatedAt(new Date());
BeanMapper.mapper(chatMemoryUpdateReq, chatMemoryDO);
boolean hadEnabled = MemoryStatus.ENABLED.equals(chatMemoryDO.getStatus());
boolean hadEnabled =
MemoryStatus.ENABLED.toString().equals(chatMemoryDO.getStatus().trim());
if (MemoryStatus.ENABLED.equals(chatMemoryUpdateReq.getStatus()) && !hadEnabled) {
enableMemory(chatMemoryDO);
} else if (MemoryStatus.DISABLED.equals(chatMemoryUpdateReq.getStatus()) && hadEnabled) {
disableMemory(chatMemoryDO);
}
updateMemory(chatMemoryDO);
}
@Override
public void updateMemory(ChatMemoryDO memory) {
chatMemoryRepository.updateMemory(memory);
LambdaUpdateWrapper<ChatMemoryDO> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(ChatMemoryDO::getId, chatMemoryDO.getId());
if (Objects.nonNull(chatMemoryUpdateReq.getStatus())) {
updateWrapper.set(ChatMemoryDO::getStatus, chatMemoryUpdateReq.getStatus());
}
if (Objects.nonNull(chatMemoryUpdateReq.getLlmReviewRet())) {
updateWrapper.set(ChatMemoryDO::getLlmReviewRet,
chatMemoryUpdateReq.getLlmReviewRet().toString());
}
if (Objects.nonNull(chatMemoryUpdateReq.getLlmReviewCmt())) {
updateWrapper.set(ChatMemoryDO::getLlmReviewCmt, chatMemoryUpdateReq.getLlmReviewCmt());
}
if (Objects.nonNull(chatMemoryUpdateReq.getHumanReviewRet())) {
updateWrapper.set(ChatMemoryDO::getHumanReviewRet,
chatMemoryUpdateReq.getHumanReviewRet().toString());
}
if (Objects.nonNull(chatMemoryUpdateReq.getHumanReviewCmt())) {
updateWrapper.set(ChatMemoryDO::getHumanReviewCmt,
chatMemoryUpdateReq.getHumanReviewCmt());
}
updateWrapper.set(ChatMemoryDO::getUpdatedAt, new Date());
updateWrapper.set(ChatMemoryDO::getUpdatedBy, user.getName());
chatMemoryMapper.update(updateWrapper);
}
@Override
@@ -72,7 +99,7 @@ public class MemoryServiceImpl implements MemoryService {
}
@Override
public PageInfo<ChatMemoryDO> pageMemories(PageMemoryReq pageMemoryReq) {
public PageInfo<ChatMemory> pageMemories(PageMemoryReq pageMemoryReq) {
ChatMemoryFilter chatMemoryFilter = pageMemoryReq.getChatMemoryFilter();
chatMemoryFilter.setSort(pageMemoryReq.getSort());
chatMemoryFilter.setOrderCondition(pageMemoryReq.getOrderCondition());
@@ -81,11 +108,14 @@ public class MemoryServiceImpl implements MemoryService {
}
@Override
public List<ChatMemoryDO> getMemories(ChatMemoryFilter chatMemoryFilter) {
public List<ChatMemory> getMemories(ChatMemoryFilter chatMemoryFilter) {
QueryWrapper<ChatMemoryDO> queryWrapper = new QueryWrapper<>();
if (chatMemoryFilter.getAgentId() != null) {
queryWrapper.lambda().eq(ChatMemoryDO::getAgentId, chatMemoryFilter.getAgentId());
}
if (chatMemoryFilter.getQueryId() != null) {
queryWrapper.lambda().eq(ChatMemoryDO::getQueryId, chatMemoryFilter.getQueryId());
}
if (StringUtils.isNotBlank(chatMemoryFilter.getQuestion())) {
queryWrapper.lambda().like(ChatMemoryDO::getQuestion, chatMemoryFilter.getQuestion());
}
@@ -109,32 +139,52 @@ public class MemoryServiceImpl implements MemoryService {
queryWrapper.orderBy(true, chatMemoryFilter.isAsc(),
chatMemoryFilter.getOrderCondition());
}
return chatMemoryRepository.getMemories(queryWrapper);
List<ChatMemoryDO> chatMemoryDOS = chatMemoryRepository.getMemories(queryWrapper);
return chatMemoryDOS.stream().map(this::getMemory).collect(Collectors.toList());
}
@Override
public List<ChatMemoryDO> getMemoriesForLlmReview() {
QueryWrapper<ChatMemoryDO> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(ChatMemoryDO::getStatus, MemoryStatus.PENDING)
.isNull(ChatMemoryDO::getLlmReviewRet);
return chatMemoryRepository.getMemories(queryWrapper);
}
@Override
public void enableMemory(ChatMemoryDO memory) {
memory.setStatus(MemoryStatus.ENABLED);
memory.setStatus(MemoryStatus.ENABLED.toString());
exemplarService.storeExemplar(embeddingConfig.getMemoryCollectionName(memory.getAgentId()),
Text2SQLExemplar.builder().question(memory.getQuestion())
.sideInfo(memory.getSideInfo()).dbSchema(memory.getDbSchema())
.sql(memory.getS2sql()).build());
}
@Override
public void disableMemory(ChatMemoryDO memory) {
memory.setStatus(MemoryStatus.DISABLED);
memory.setStatus(MemoryStatus.DISABLED.toString());
exemplarService.removeExemplar(embeddingConfig.getMemoryCollectionName(memory.getAgentId()),
Text2SQLExemplar.builder().question(memory.getQuestion())
.sideInfo(memory.getSideInfo()).dbSchema(memory.getDbSchema())
.sql(memory.getS2sql()).build());
}
private ChatMemoryDO getMemoryDO(ChatMemory memory) {
ChatMemoryDO memoryDO = new ChatMemoryDO();
BeanUtils.copyProperties(memory, memoryDO);
memoryDO.setStatus(memory.getStatus().toString().trim());
if (Objects.nonNull(memory.getHumanReviewRet())) {
memoryDO.setHumanReviewRet(memory.getHumanReviewRet().toString().trim());
}
if (Objects.nonNull(memory.getLlmReviewRet())) {
memoryDO.setLlmReviewRet(memory.getLlmReviewRet().toString().trim());
}
return memoryDO;
}
private ChatMemory getMemory(ChatMemoryDO memoryDO) {
ChatMemory memory = new ChatMemory();
BeanUtils.copyProperties(memoryDO, memory);
memory.setStatus(MemoryStatus.valueOf(memoryDO.getStatus().trim()));
if (Objects.nonNull(memoryDO.getHumanReviewRet())) {
memory.setHumanReviewRet(
MemoryReviewResult.valueOf(memoryDO.getHumanReviewRet().trim()));
}
if (Objects.nonNull(memoryDO.getLlmReviewRet())) {
memory.setLlmReviewRet(MemoryReviewResult.valueOf(memoryDO.getLlmReviewRet().trim()));
}
return memory;
}
}

View File

@@ -28,7 +28,7 @@ public class ResultFormatter {
}
for (Map<String, Object> row : queryResults) {
for (QueryColumn column : queryColumns) {
String columnKey = column.getNameEn();
String columnKey = column.getBizName();
Object value = row.get(columnKey);
table.append("| ").append(value != null ? value.toString() : "").append(" ");
}

View File

@@ -20,54 +20,6 @@
<result column="updated_at" property="updatedAt"/>
</resultMap>
<insert id="addConfig"
parameterType="com.tencent.supersonic.chat.server.persistence.dataobject.ChatConfigDO"
useGeneratedKeys="true" keyProperty="id">
insert into s2_chat_config
(
model_id, `chat_detail_config`, chat_agg_config, recommended_questions, status, llm_examples, created_by, updated_by, created_at, updated_at
)
values
(
#{modelId}, #{chatDetailConfig}, #{chatAggConfig}, #{recommendedQuestions}, #{status}, #{llmExamples}, #{createdBy}, #{updatedBy}, #{createdAt}, #{updatedAt}
)
</insert>
<update id="editConfig">
update s2_chat_config
<set>
`updated_at` = #{updatedAt} ,
<if test="chatDetailConfig != null and chatDetailConfig != ''">
`chat_detail_config` = #{chatDetailConfig} ,
</if>
<if test="chatAggConfig != null and chatAggConfig != ''">
chat_agg_config = #{chatAggConfig} ,
</if>
<if test="recommendedQuestions != null and recommendedQuestions != ''">
recommended_questions = #{recommendedQuestions} ,
</if>
<if test="status != null and status != ''">
status = #{status} ,
</if>
<if test="updatedBy != null and updatedBy != ''">
updated_by = #{updatedBy} ,
</if>
<if test="llmExamples != null and llmExamples != ''">
llm_examples = #{llmExamples} ,
</if>
</set>
<where>
<if test="id != null and id != ''">
id = #{id}
</if>
<if test="modelId != null and modelId != ''">
and model_id = #{modelId}
</if>
</where>
</update>
<select id="search" resultMap="chaConfigDO">
select *
from s2_chat_config

View File

@@ -9,7 +9,7 @@
type="com.tencent.supersonic.chat.server.persistence.dataobject.ChatContextDO">
<id column="chat_id" property="chatId"/>
<result column="modified_at" property="modifiedAt"/>
<result column="user" property="user"/>
<result column="query_user" property="queryUser"/>
<result column="query_text" property="queryText"/>
<result column="semantic_parse" property="semanticParse"/>
<!--<result column="ext_data" property="extData"/>-->
@@ -20,11 +20,4 @@
from s2_chat_context where chat_id=#{chatId} limit 1
</select>
<insert id="addContext" parameterType="com.tencent.supersonic.chat.server.persistence.dataobject.ChatContextDO" >
insert into s2_chat_context (chat_id,user,query_text,semantic_parse) values (#{chatId}, #{user},#{queryText}, #{semanticParse})
</insert>
<update id="updateContext">
update s2_chat_context set query_text=#{queryText},semantic_parse=#{semanticParse} where chat_id=#{chatId}
</update>
</mapper>
</mapper>

Some files were not shown because too many files have changed in this diff Show More