@nebulars/sseengine 1.0.0 → 1.3.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/.prettierignore +0 -0
  2. package/.prettierrc.cjs +8 -0
  3. package/dist/sseengine.css +1 -0
  4. package/dist/sseengine.umd.js +1 -0
  5. package/package.json +19 -4
  6. package/src/components/{fqa-answer → sse-answer}/index.vue +7 -6
  7. package/src/components/{fqa-chat → sse-chat}/index.vue +9 -9
  8. package/src/components/sse-drawer/index.vue +256 -0
  9. package/src/components/sse-drawer/modify.less +38 -0
  10. package/src/components/sse-enter/index.vue +210 -0
  11. package/src/components/sse-enter/modify.less +101 -0
  12. package/src/components/{fqa-hub → sse-hub}/index.vue +4 -4
  13. package/src/components/sse-menus/index.vue +288 -0
  14. package/src/components/sse-menus/popover-modify.less +26 -0
  15. package/src/components/sse-notes/index.vue +236 -0
  16. package/src/components/sse-notes/modify.less +3 -0
  17. package/src/components/{fqa-query → sse-query}/index.vue +12 -12
  18. package/src/components/{fqa-recursion → sse-recursion}/index.vue +4 -4
  19. package/src/components/{fqa-root → sse-root}/index.vue +1 -1
  20. package/src/components/sse-submit/index.vue +63 -0
  21. package/src/components/sse-submit/modify.less +8 -0
  22. package/src/index.js +11 -2
  23. package/src/index.vue +2 -2
  24. package/src/store/feedback.js +8 -0
  25. package/src/store/index.js +166 -3
  26. package/src/store/info.js +20 -0
  27. package/src/store/launch.js +18 -0
  28. package/src/store/menus.js +45 -0
  29. package/src/store/modify.less +127 -0
  30. package/src/store/presets.js +95 -0
  31. package/src/store/remote.js +34 -0
  32. package/src/store/session.js +57 -0
  33. package/src/store/sevani.js +15 -0
  34. package/src/store/sse.js +223 -0
  35. package/src/store/sup.js +7 -0
  36. package/sseengine.zip +0 -0
  37. package/src/components/fqa-icon/index.vue +0 -36
  38. /package/src/components/{fqa-chat → sse-chat}/conversation.less +0 -0
  39. /package/src/components/{fqa-chat → sse-chat}/sup.less +0 -0
  40. /package/src/components/{fqa-flip → sse-flip}/index.vue +0 -0
@@ -0,0 +1,45 @@
1
+ export default ({ http }) => {
2
+ return {
3
+ async MENUS_UPDATE({ state }, params = {}) {
4
+ const { menus } = state;
5
+ Object.assign(menus, params);
6
+ return { menus };
7
+ },
8
+
9
+ async MENUS_INIT({ state }) {
10
+ return {
11
+ list: [],
12
+ };
13
+ },
14
+
15
+ async MENUS_GET({ state }) {
16
+ const { list, menus } = state;
17
+ const { data } = await http.api.sessionPage(menus);
18
+ const { items } = data;
19
+
20
+ if (!items.length) {
21
+ menus.more = false;
22
+ }
23
+
24
+ return { list: menus.page === 1 ? items : list.concat(items), menus };
25
+ },
26
+
27
+ async MENUS_DEL({ state }, { session_id }) {
28
+ const { data: success } = await http.api.sessionDelete({ session_id });
29
+ const { list } = state;
30
+
31
+ const index = list.findIndex(({ session_id: id }) => id === session_id);
32
+
33
+ if (~index) {
34
+ list.splice(index, 1);
35
+ }
36
+
37
+ return { success, list };
38
+ },
39
+
40
+ async MENUS_RENAME({}, { session_id, title }) {
41
+ const { data: success } = await http.api.sessionRename({ session_id, title });
42
+ return success;
43
+ },
44
+ };
45
+ };
@@ -0,0 +1,127 @@
1
+ @space: FinQA;
2
+
3
+ /**
4
+ * Layout
5
+ * ======== ======== ========
6
+ */
7
+ .@{space}--Container {
8
+ position: relative;
9
+ background-color: transparent;
10
+ }
11
+
12
+ .@{space}--Header,
13
+ .@{space}--Footer,
14
+ .@{space}--Main {
15
+ display: flex;
16
+ }
17
+
18
+ .@{space}--Header,
19
+ .@{space}--Footer {
20
+ flex-direction: row;
21
+ }
22
+
23
+ .@{space}--Main {
24
+ flex-direction: column;
25
+ }
26
+
27
+ .@{space}--Main,
28
+ .@{space}--Chat {
29
+ flex: 1;
30
+ }
31
+
32
+ .@{space}--Header,
33
+ .@{space}--Footer,
34
+ .@{space}--Main {
35
+ align-items: center;
36
+ }
37
+
38
+ .@{space}--Header,
39
+ .@{space}--Footer {
40
+ justify-content: space-between;
41
+ }
42
+
43
+ .@{space}--Header,
44
+ .@{space}--Footer,
45
+ .@{space}--Main {
46
+ transition: all @fast;
47
+ }
48
+
49
+ /**
50
+ * Interface
51
+ * ======== ======== ========
52
+ */
53
+ .@{space}--Header,
54
+ .@{space}--Footer,
55
+ .@{space}--Chat,
56
+ .@{space}--Mention {
57
+ padding-inline: @gap;
58
+ }
59
+
60
+ .@{space}--Input {
61
+ padding: @gap;
62
+ }
63
+
64
+ .@{space}--Header,
65
+ .@{space}--Footer,
66
+ .@{space}--Main {
67
+ width: 100%;
68
+ }
69
+
70
+ .@{space}--Input {
71
+ height: 100%;
72
+ }
73
+
74
+ .@{space}--Header {
75
+ height: @size-header;
76
+ }
77
+
78
+ .@{space}--Footer {
79
+ height: @size-footer;
80
+ }
81
+
82
+ .@{space}--Main {
83
+ }
84
+
85
+ .@{space}--Chat,
86
+ .@{space}--Mention {
87
+ width: @size-main;
88
+ }
89
+
90
+ .@{space}--Mention {
91
+ // height: @size-mention;
92
+ }
93
+
94
+ .@{space}--Welcome {
95
+ height: 100%;
96
+ }
97
+
98
+ /**
99
+ * Colour
100
+ * ======== ======== ========
101
+ */
102
+ .@{space}--Input {
103
+ background-color: @color-input;
104
+ }
105
+
106
+ /**
107
+ * Responsive
108
+ * ======== ======== ========
109
+ */
110
+ .@{space}--Main {
111
+ }
112
+
113
+ /**
114
+ * Modify
115
+ * ======== ======== ========
116
+ */
117
+ .@{space}--Header {
118
+ background-color: @color-input;
119
+ }
120
+
121
+ .@{space}--Input {
122
+ border-radius: @gap;
123
+ }
124
+
125
+ .@{space}--Mention {
126
+ position: relative;
127
+ }
@@ -0,0 +1,95 @@
1
+ export default [
2
+ {
3
+ "option_name": "模型",
4
+ "field_name": "model_name",
5
+ "type": "single selection dropdown",
6
+ "defaults": "gpt-4.1",
7
+ "selections": [
8
+ {
9
+ "show_name": "gpt-4.1",
10
+ "field_value": "gpt-4.1"
11
+ }
12
+ ],
13
+ "description": "选择agent执行的llm"
14
+ },
15
+ {
16
+ "option_name": "工具选择",
17
+ "field_name": "tools",
18
+ "type": "multiple selection dropdown",
19
+ "defaults": [
20
+ "MixRetriever",
21
+ "Calculator",
22
+ "FinDataFetcher",
23
+ "BatchQuery",
24
+ "EntityListFinder",
25
+ "TimeParser",
26
+ "ContextFiller"
27
+ ],
28
+ "selections": [
29
+ {
30
+ "show_name": "混合检索工具",
31
+ "field_value": "MixRetriever"
32
+ },
33
+ {
34
+ "show_name": "计算工具",
35
+ "field_value": "Calculator"
36
+ },
37
+ {
38
+ "show_name": "金融数据获取工具",
39
+ "field_value": "FinDataFetcher"
40
+ },
41
+ {
42
+ "show_name": "批量数据获取工具",
43
+ "field_value": "BatchQuery"
44
+ },
45
+ {
46
+ "show_name": "金融实体获取工具",
47
+ "field_value": "EntityListFinder"
48
+ },
49
+ {
50
+ "show_name": "时间解析工具",
51
+ "field_value": "TimeParser"
52
+ },
53
+ {
54
+ "show_name": "上下文填充工具",
55
+ "field_value": "ContextFiller"
56
+ }
57
+ ],
58
+ "description": "选择智能体可使用的工具,以增强其能力"
59
+ },
60
+ {
61
+ "option_name": "业务数据",
62
+ "field_name": "data_sources",
63
+ "type": "multiple selection dropdown",
64
+ "defaults": [
65
+ "FinQA数据库",
66
+ "机构研究",
67
+ "公告",
68
+ "专家信息",
69
+ "互联网信息"
70
+ ],
71
+ "selections": [
72
+ {
73
+ "show_name": "FinQA数据库",
74
+ "field_value": "FinQA数据库"
75
+ },
76
+ {
77
+ "show_name": "机构研究",
78
+ "field_value": "机构研究"
79
+ },
80
+ {
81
+ "show_name": "公告",
82
+ "field_value": "公告"
83
+ },
84
+ {
85
+ "show_name": "专家信息",
86
+ "field_value": "专家信息"
87
+ },
88
+ {
89
+ "show_name": "互联网信息",
90
+ "field_value": "互联网信息"
91
+ }
92
+ ],
93
+ "description": "选择业务数据来源"
94
+ }
95
+ ]
@@ -0,0 +1,34 @@
1
+ export default ({ scrolling, kitchen }) => {
2
+ return {
3
+ async SCROLLING() {
4
+ await kitchen.sleep(3);
5
+ scrolling(`#FinQAChat`, 'end');
6
+ },
7
+
8
+ async PROMPT_UPDATE({}, prompt) {
9
+ return { prompt };
10
+ },
11
+
12
+ async FOCUS_ON() {
13
+ return { focus: true };
14
+ },
15
+
16
+ async FOCUS_OFF() {
17
+ return { focus: false };
18
+ },
19
+
20
+ async PRODUCE_ON({ dispatch }) {
21
+ await dispatch('CODE_UPDATE');
22
+ return { produce: true };
23
+ },
24
+
25
+ async PRODUCE_OFF({ dispatch }) {
26
+ await dispatch('CODE_UPDATE');
27
+ return { produce: false };
28
+ },
29
+
30
+ async CODE_UPDATE({}, code = 0) {
31
+ return { code };
32
+ },
33
+ };
34
+ };
@@ -0,0 +1,57 @@
1
+ // Use Presets
2
+ import { default as presets } from './presets';
3
+
4
+ export default ({ http, dom }) => {
5
+ return {
6
+ /**
7
+ * @param chat_type
8
+ * @prop { String } intent_chat
9
+ * @prop { String } db_chat
10
+ * @prop { String } mix_search
11
+ * ========== ========== ==========
12
+ */
13
+ async PRESETS_GET({}, session_id) {
14
+ const chat_type = 'intent_chat';
15
+ // const { data: presets } = await http.api.utilsPresetOptions({ session_id, chat_type });
16
+ return { presets };
17
+ },
18
+
19
+ async OPTION_SET({}, presets) {
20
+ const options = Object.fromEntries(presets.map(({ field_name, defaults }) => [field_name, defaults]));
21
+ return { options };
22
+ },
23
+
24
+ async OPTION_UPDATE({ state }, { session_id }) {
25
+ const { data } = await http.api.sessionUpdateParams({ session_id, params: state.options });
26
+ return data;
27
+ },
28
+
29
+ async ID_CREATE({ state }, prompt) {
30
+ const { prompt: title = prompt, options } = state;
31
+ const { data: session_id } = await http.api.sessionCreate({ title, params: options });
32
+ return { session_id };
33
+ },
34
+
35
+ async NOTES_UPDATE({ state }, { id }) {
36
+ const { notes } = state;
37
+ notes[id] = true;
38
+ return { notes };
39
+ },
40
+
41
+ async CURRENT_SET({ state }, current = null) {
42
+ const { info } = state;
43
+ info.current = current;
44
+
45
+ return { info };
46
+ },
47
+
48
+ async RAG_UPDATE({ state }, rag) {
49
+ return { rag };
50
+ },
51
+
52
+ async COMPLIANCE({}, answer_id) {
53
+ const { data } = await http.api.sseUpdateCompliance({ answer_id, compliance: 1 });
54
+ return data;
55
+ },
56
+ };
57
+ };
@@ -0,0 +1,15 @@
1
+ export default ({ http }) => {
2
+ return {
3
+ async SEVANI_UPDATE({}, { target: sevani }) {
4
+ return { sevani };
5
+ },
6
+
7
+ async SEVANI_CLEAN({}, classname) {
8
+ Array.from(document.querySelectorAll(`.${classname}`)).forEach(e => e.classList.remove('hover'));
9
+ },
10
+
11
+ async SEVANI_FIND({ state }, classname) {
12
+ return Array.from(state.sevani.children).find(e => e.classList.contains(classname));
13
+ },
14
+ };
15
+ };
@@ -0,0 +1,223 @@
1
+ export default ({ $api, sse, http, deepfind, last, toast }) => {
2
+ // // Hard Code
3
+ // const getLastNode = () => dom.last(['query-id', 'answer-id']);
4
+
5
+ // // Hard Code
6
+ // const getNextNode = source => (source.children.length ? source.children[0] : source);
7
+
8
+ // Update Store
9
+ return {
10
+ async STREAM_CACHE({}, stream) {
11
+ return { stream };
12
+ },
13
+
14
+ async SSE_STOP({ state, dispatch }, session_id) {
15
+ // SSE Stop
16
+ const { data } = await http.api.sseStopSse(session_id);
17
+
18
+ // Get Status
19
+ const { status } = data;
20
+
21
+ // Get Tower
22
+ const { tower } = state;
23
+
24
+ // Check Stopping
25
+ if (status === 'stopping') {
26
+ // Stop Produce
27
+ await dispatch('PRODUCE_OFF');
28
+
29
+ // Clean Current
30
+ await dispatch('CURRENT_SET');
31
+
32
+ // Tower is Live
33
+ if (tower) {
34
+ // Close
35
+ tower.close();
36
+
37
+ // Update as Null
38
+ return { tower: null };
39
+ }
40
+ }
41
+ },
42
+
43
+ /**
44
+ * Scenario 1: New Question - Parent is Null
45
+ * Scenario 2: Continue Question - Parent is Last
46
+ * Scenario 3: Node Question - Parent is Item.Parent
47
+ * ======== ======== ======== ======== ======== ========
48
+ */
49
+ async SSE_CONNECT({ state, dispatch }, { session_id, content, parent = null }) {
50
+ // Update Option First
51
+ await dispatch('OPTION_UPDATE', { session_id });
52
+
53
+ // Set Link
54
+ const link = `${$api.sse}?rag=${state.rag}&session_id=${session_id}&parent=${parent}&content=${encodeURIComponent(content || state.stream)}`;
55
+
56
+ // SSE
57
+ const tower = sse(link, {
58
+ // Connect Open
59
+ async open(data, event) {
60
+ // Start Produce
61
+ await dispatch('PRODUCE_ON');
62
+ },
63
+
64
+ // Connect Error
65
+ async error(data, event) {
66
+ // Show Toast - 因为每次 SSE 都会执行 Error,故暂时隐藏报错
67
+ // toast.error(`${data || '发生错误,请刷新重试'}`);
68
+
69
+ // Stop Produce
70
+ await dispatch('PRODUCE_OFF');
71
+
72
+ // Clean Current
73
+ await dispatch('CURRENT_SET');
74
+ },
75
+
76
+ // Connect Message
77
+ async message({ type, data, msg }) {
78
+ // Abnormal Status
79
+ if (['success', 'close', 'timeout'].includes(type)) {
80
+ // Stop Produce
81
+ await dispatch('PRODUCE_OFF');
82
+
83
+ // Clean Current
84
+ await dispatch('CURRENT_SET');
85
+ }
86
+
87
+ // Success as Endness
88
+ if (type === 'success') {
89
+ return;
90
+ }
91
+
92
+ // Close as Endness
93
+ if (type === 'close') {
94
+ return;
95
+ }
96
+
97
+ // Timeout as Endness
98
+ if (type === 'timeout') {
99
+ // Error Tip
100
+ return toast.error(msg);
101
+ }
102
+
103
+ // Update Code
104
+ if (type === 'status_code') {
105
+ await dispatch('CODE_UPDATE', data.status_code);
106
+ }
107
+
108
+ // Update Query
109
+ await dispatch('QUERY_UPDATE', { ...data, type, parent });
110
+
111
+ // Scrolling
112
+ // await dispatch('SCROLLING');
113
+ },
114
+ });
115
+
116
+ // Update Tower
117
+ return { tower };
118
+ },
119
+
120
+ /**
121
+ * @name QUERY_UPDATE
122
+ * ========== ========== ==========
123
+ * @param conversation_id - from Service
124
+ * @param msg - special notice
125
+ * @param content
126
+ * @param role - 1 or 2
127
+ * @param type
128
+ * @prop { String } ready
129
+ * @prop { String } message
130
+ * @prop { String } success
131
+ * @prop { String } thinks
132
+ * @prop { String } references
133
+ * @prop { String } workflows
134
+ * @param think
135
+ * @param references
136
+ * @param workflows
137
+ * ========== ========== ==========
138
+ */
139
+ async QUERY_UPDATE({ state, dispatch }, { conversation_id: id, x_trace_id = null, msg, content = '', role = 2, type, parent, parent_origin, think, references, workflows, item = null }) {
140
+ // Get Params
141
+ const { info, options: params } = state;
142
+
143
+ // SSE Keep Message
144
+ if (id) {
145
+ item = deepfind(info.history, id);
146
+ // item = info.history.find(item => {
147
+ // return item.id === id;
148
+ // });
149
+ }
150
+
151
+ // Time First
152
+ if (!item) {
153
+ // Reset Parent
154
+ parent = info.current || parent || parent_origin;
155
+
156
+ // Create Item
157
+ item = {
158
+ id,
159
+ x_trace_id,
160
+ parent,
161
+ content,
162
+ role,
163
+ charts: [],
164
+ thinks: [],
165
+ references: [],
166
+ workflows: [],
167
+ params,
168
+ active: 1,
169
+ type,
170
+ children: [],
171
+ };
172
+
173
+ // Has Root
174
+ if (parent) {
175
+ const { children } = deepfind(info.history, parent);
176
+ children.push(item);
177
+ }
178
+
179
+ // Is Root
180
+ else {
181
+ // Hard code for Bug
182
+ if (info.history.length) {
183
+ const { children } = info.history[0];
184
+ children.push(item);
185
+ }
186
+
187
+ // Empty History
188
+ else {
189
+ info.history.push(item);
190
+ }
191
+ }
192
+ }
193
+
194
+ if (id) {
195
+ // Only For First Answer after Query
196
+ await dispatch('CURRENT_SET', id);
197
+ }
198
+
199
+ if (think) {
200
+ item.thinks.push(think);
201
+ }
202
+
203
+ if (references) {
204
+ item.references.push(...references);
205
+ }
206
+
207
+ if (workflows) {
208
+ item.workflows.push(...workflows);
209
+ }
210
+
211
+ if (item.content !== content) {
212
+ item.content += content;
213
+ }
214
+
215
+ if (type === 'success') {
216
+ await dispatch('PRODUCE_OFF');
217
+ await dispatch('CURRENT_SET');
218
+ }
219
+
220
+ return { info };
221
+ },
222
+ };
223
+ };
@@ -0,0 +1,7 @@
1
+ export default ({ http }) => {
2
+ return {
3
+ async SUP_UPDATE({ dispatch }, sup) {
4
+ return { sup };
5
+ },
6
+ };
7
+ };
package/sseengine.zip ADDED
Binary file
@@ -1,36 +0,0 @@
1
- <style lang="less" scoped>
2
- .fqa-icon {
3
- transition: all @effect;
4
- }
5
- </style>
6
-
7
- <template>
8
- <component class="fqa-icon" :is="icon" :style="{ fontSize: `${size}px`, color, cursor, transitionDuration: `${duration}s` }" />
9
- </template>
10
-
11
- <script>
12
- export default {
13
- props: {
14
- icon: {
15
- type: String,
16
- default: '',
17
- },
18
- size: {
19
- type: [Number, String],
20
- default: 14,
21
- },
22
- color: {
23
- type: String,
24
- default: 'inherit',
25
- },
26
- cursor: {
27
- type: String,
28
- default: 'default',
29
- },
30
- duration: {
31
- type: [Number, String],
32
- default: 0.36,
33
- },
34
- },
35
- };
36
- </script>
File without changes
File without changes