@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,210 @@
1
+ <style lang="less" scoped>
2
+ .fqa-enter {
3
+ & {
4
+ background-color: @color-input;
5
+ }
6
+
7
+ &-prompt {
8
+ color: @color-text;
9
+ border-color: transparent !important;
10
+ background-color: transparent !important;
11
+ box-shadow: none !important;
12
+ resize: none !important;
13
+ transition: all @flash;
14
+
15
+ &::placeholder {
16
+ color: lighten(@color-text, 40%);
17
+ }
18
+
19
+ &:focus {
20
+ &::placeholder {
21
+ color: lighten(@color-text, 50%);
22
+ }
23
+ }
24
+ }
25
+
26
+ &-bar {
27
+ flex-direction: row-reverse;
28
+ }
29
+
30
+ &-menus {
31
+ color: darken(@color-text, 5%) !important;
32
+ border-color: @color-line !important;
33
+
34
+ &:hover {
35
+ color: @color-text !important;
36
+ border-color: lighten(@color-line, 10%) !important;
37
+ }
38
+ }
39
+ }
40
+ </style>
41
+
42
+ <template>
43
+ <!-- As -->
44
+ <a-form class="fqa-enter" layout="horizontal" :model="formic" @finish="onSubmit">
45
+ <!-- Prompt -->
46
+ <a-form-item name="content">
47
+ <a-textarea class="fqa-enter-prompt" ref="input" :auto-size="{ minRows: 1, maxRows: 10 }" :placeholder="$t('prompt.placeholder')" v-model:value="sseengine.prompt" @press-enter="enterHandler" />
48
+ </a-form-item>
49
+
50
+ <!-- Bar -->
51
+ <a-flex class="fqa-enter-bar" justify="space-between" align="middle">
52
+ <!-- Expantion -->
53
+ <a-space class="fqa-enter-expantion">
54
+ <sse-submit @click="onSubmit" />
55
+ </a-space>
56
+
57
+ <!-- Extension -->
58
+ <a-space class="fqa-enter-extension">
59
+ <a-tooltip v-if="false">
60
+ <template #title>上传文件(未开发)</template>
61
+ <fqa-button class="fqa-enter-menus" :radius="100" :size="36">
62
+ <fqa-icon icon="CloudUploadOutlined" size="20" />
63
+ </fqa-button>
64
+ </a-tooltip>
65
+
66
+ <a-switch class="fqa-enter-switch" v-model:checked="sseengine.rag" checked-children="深度思考" un-checked-children="常规问答" v-if="false" />
67
+
68
+ <a-dropdown class="fqa-enter-dropdown" placement="topRight" @click.prevent trigger="click" overlay-class-name="fqa-enter-dropdown-overlay">
69
+ <template #overlay>
70
+ <a-menu @click="onRagChange">
71
+ <a-menu-item key="false">
72
+ <span>{{ $t(`prompt.rag_false`) }}</span>
73
+ </a-menu-item>
74
+ <a-menu-item key="true">
75
+ <span>{{ $t(`prompt.rag_true`) }}</span>
76
+ </a-menu-item>
77
+ </a-menu>
78
+ </template>
79
+
80
+ <a-button>
81
+ {{ $t(`prompt.rag_${sseengine.rag}`) }}
82
+ <CaretUpOutlined />
83
+ </a-button>
84
+ </a-dropdown>
85
+
86
+ <div class="fqa-enter-presets">
87
+ <template v-if="sseengine.presets?.length" v-for="(param, index) in sseengine.presets">
88
+ <fqa-selection class="fqa-enter-selection" v-bind="param" v-if="param.field_name === 'data_sources'" v-model="sseengine.options[param.field_name]" :label="false" />
89
+ </template>
90
+ </div>
91
+ </a-space>
92
+ </a-flex>
93
+ </a-form>
94
+ </template>
95
+
96
+ <script>
97
+ export default {
98
+ data() {
99
+ return {
100
+ // 询问入口(锁)
101
+ entry: true,
102
+
103
+ // 伪数据
104
+ formic: {},
105
+ };
106
+ },
107
+
108
+ computed: {
109
+ info() {
110
+ return this.sseengine.info;
111
+ },
112
+
113
+ dom() {
114
+ return document.querySelector('#FinQAChat');
115
+ },
116
+ },
117
+
118
+ watch: {
119
+ 'sseengine.info': {
120
+ handler(info) {
121
+ console.log(info);
122
+ },
123
+
124
+ deep: true,
125
+ immediate: true,
126
+ },
127
+
128
+ 'sseengine.focus': {
129
+ handler(value) {
130
+ if (value) {
131
+ this.$nextTick(() => {
132
+ this.$refs.input.focus();
133
+ this.$store.dispatch('sseengine/FOCUS_OFF');
134
+ });
135
+ }
136
+ },
137
+
138
+ deep: true,
139
+ immediate: true,
140
+ },
141
+ },
142
+
143
+ methods: {
144
+ async onSubmit() {
145
+ const { produce, prompt: value } = this.sseengine;
146
+
147
+ if (produce) {
148
+ return;
149
+ }
150
+
151
+ if (!value) {
152
+ return;
153
+ }
154
+
155
+ // Another
156
+ const title = value;
157
+
158
+ // Cache Stream
159
+ await this.$store.dispatch('sseengine/STREAM_CACHE', value);
160
+
161
+ // Clean Prompt
162
+ await this.$store.dispatch('sseengine/PROMPT_UPDATE');
163
+
164
+ // No ID as New
165
+ if (!this.app.id) {
166
+ // Reset Menu Page
167
+ await this.$store.dispatch('sseengine/STATE_UPDATE', { menus: { page: 0 } });
168
+
169
+ // Create Chat
170
+ const { session_id } = await this.$store.dispatch('sseengine/ID_CREATE', title);
171
+
172
+ // For Web
173
+ this.$util.message.send({ id: session_id }, () => {
174
+ // For MNP
175
+ this.$router.push({ name: 'chat', query: { c: session_id } });
176
+ });
177
+
178
+ // Stop
179
+ return;
180
+ }
181
+
182
+ // Get ID from History
183
+ const { id: parent } = this.$util.last(this.sseengine.info.history);
184
+
185
+ // Start SSE
186
+ await this.$store.dispatch('sseengine/SSE_CONNECT', { session_id: this.app.id, parent });
187
+
188
+ // Clean Stream
189
+ await this.$store.dispatch('sseengine/STREAM_CACHE', null);
190
+
191
+ // Scrolling
192
+ await this.$store.dispatch('sseengine/SCROLLING');
193
+ },
194
+
195
+ // Enter for Textarea
196
+ enterHandler(event) {
197
+ if (event.shiftKey) {
198
+ return false;
199
+ }
200
+ this.onSubmit();
201
+ event.preventDefault();
202
+ },
203
+
204
+ // On Rag Change
205
+ onRagChange({ key: rag }) {
206
+ this.$store.dispatch('sseengine/RAG_UPDATE', rag);
207
+ },
208
+ },
209
+ };
210
+ </script>
@@ -0,0 +1,101 @@
1
+ .fqa-enter-extension {
2
+ height: auto;
3
+ }
4
+
5
+ .fqa-enter-switch {
6
+ & {
7
+ height: @size-submit;
8
+ line-height: @size-submit;
9
+ min-width: @size-submit;
10
+ border-radius: @size-submit;
11
+ padding-inline: calc(@size-submit / 5);
12
+ display: flex;
13
+ align-items: center;
14
+ justify-content: center;
15
+ }
16
+
17
+ .ant-switch-handle {
18
+ width: calc(@size-submit / 1.5);
19
+ height: calc(@size-submit / 1.5);
20
+ top: 50%;
21
+ transform: translateY(-50%);
22
+ inset-inline-start: 4px;
23
+
24
+ &::before {
25
+ border-radius: @size-submit;
26
+ background-color: @color-submit;
27
+ }
28
+ }
29
+
30
+ .ant-switch-inner {
31
+ .ant-switch-inner-unchecked {
32
+ margin-top: -@size-submit !important;
33
+ }
34
+ }
35
+
36
+ &.ant-switch-checked {
37
+ .ant-switch-handle {
38
+ inset-inline-start: calc(100% - 28px);
39
+ }
40
+ }
41
+ }
42
+
43
+ .fqa-enter-dropdown {
44
+ color: @color-text !important;
45
+ border-color: darken(@color-app, 4%) !important;
46
+ border-radius: @radiu;
47
+ background-color: @color-app;
48
+ box-shadow: none !important;
49
+ }
50
+
51
+ .fqa-enter-dropdown-overlay {
52
+ .ant-dropdown-menu {
53
+ border-color: darken(@color-app, 4%) !important;
54
+ background-color: @color-app;
55
+ box-shadow: none !important;
56
+ }
57
+
58
+ .ant-dropdown-menu-title-content {
59
+ color: @color-text !important;
60
+ }
61
+ }
62
+
63
+ .fqa-enter-presets {
64
+ & {
65
+ width: 120px;
66
+ }
67
+
68
+ .fqa-selection {
69
+ .ant-select {
70
+ &-selector {
71
+ color: @color-text;
72
+ border-color: darken(@color-app, 4%) !important;
73
+ background-color: @color-app;
74
+ box-shadow: none !important;
75
+
76
+ &,
77
+ &-item,
78
+ &-overflow,
79
+ &-overflow-item {
80
+ width: 100% !important;
81
+ }
82
+
83
+ &-item {
84
+ background: transparent !important;
85
+ }
86
+ }
87
+ }
88
+ }
89
+
90
+ .fqa-enter-selection {
91
+ border-radius: @radiu;
92
+ }
93
+
94
+ .css-dev-only-do-not-override-p1oxeb {
95
+ margin-bottom: 0;
96
+ }
97
+
98
+ .ant-form-item {
99
+ margin-bottom: 0 !important;
100
+ }
101
+ }
@@ -1,17 +1,17 @@
1
1
  <template>
2
2
  <!-- Root -->
3
3
  <template v-if="item.role === 0">
4
- <fqa-root :item="item" :active="active" @update:active="$emit('update:active', $event)" />
4
+ <sse-root :item="item" :active="active" @update:active="$emit('update:active', $event)" />
5
5
  </template>
6
6
 
7
7
  <!-- Query -->
8
8
  <template v-if="item.role === 1">
9
- <fqa-query :item="item" :active="active" @update:active="$emit('update:active', $event)" />
9
+ <sse-query :item="item" :active="active" @update:active="$emit('update:active', $event)" />
10
10
  </template>
11
11
 
12
12
  <!-- Answer -->
13
13
  <template v-if="item.role === 2">
14
- <fqa-answer :item="item" :active="active" @update:active="$emit('update:active', $event)" />
14
+ <sse-answer :item="item" :active="active" @update:active="$emit('update:active', $event)" />
15
15
  </template>
16
16
  </template>
17
17
 
@@ -40,7 +40,7 @@ export default {
40
40
  */
41
41
  handler(value) {
42
42
  // Get Father Node
43
- const father = this.$util.deepfind(this.chat.info.history, this.item.parent);
43
+ const father = this.$util.deepfind(this.sseengine.info.history, this.item.parent);
44
44
 
45
45
  // Set Active
46
46
  if (father) {
@@ -0,0 +1,288 @@
1
+ <style lang="less" scoped>
2
+ .fqa-menus {
3
+ & {
4
+ position: relative;
5
+ }
6
+
7
+ &-mask {
8
+ top: 0;
9
+ left: 0;
10
+ right: 0;
11
+ bottom: 0;
12
+ z-index: 9999;
13
+ position: absolute;
14
+ background: transparent;
15
+ }
16
+
17
+ &-item {
18
+ & {
19
+ position: relative;
20
+
21
+ &-touch {
22
+ width: 80%;
23
+ top: 0;
24
+ left: 0;
25
+ bottom: 0;
26
+ z-index: 1;
27
+ position: absolute;
28
+ }
29
+ }
30
+
31
+ &:hover {
32
+ .fqa-menus-more {
33
+ opacity: 1;
34
+ z-index: 1;
35
+ }
36
+ }
37
+ }
38
+
39
+ &-title {
40
+ max-width: calc(@size-assist - @gap * 4);
41
+ text-overflow: ellipsis;
42
+ white-space: nowrap;
43
+ overflow: hidden;
44
+ }
45
+
46
+ &-input {
47
+ & {
48
+ color: @color-text;
49
+ border-color: @color-line;
50
+ background-color: transparent;
51
+ }
52
+
53
+ &:focus {
54
+ box-shadow: none;
55
+ }
56
+ }
57
+
58
+ &-more {
59
+ & {
60
+ position: absolute;
61
+ right: 0;
62
+ top: 0;
63
+ bottom: 0;
64
+ opacity: 0;
65
+ z-index: -1;
66
+ transition: all @effect;
67
+ }
68
+
69
+ &.active {
70
+ opacity: 1;
71
+ z-index: 1;
72
+ }
73
+ }
74
+
75
+ &-options {
76
+ &-item {
77
+ & {
78
+ width: @space * 3;
79
+ line-height: @space;
80
+ padding-inline: @slit;
81
+ border-radius: @atom;
82
+ cursor: pointer;
83
+ transition: all @effect;
84
+ }
85
+
86
+ &:hover {
87
+ // background-color: @color-assist;
88
+ }
89
+ }
90
+ }
91
+
92
+ &-more,
93
+ &-no-more {
94
+ padding: @gap 0;
95
+ display: flex;
96
+ justify-content: center;
97
+ }
98
+
99
+ &-more {
100
+ }
101
+
102
+ &-no-more {
103
+ font-size: 1.25rem;
104
+ color: @color-subtext;
105
+ }
106
+ }
107
+ </style>
108
+
109
+ <template>
110
+ <!-- Menus -->
111
+ <a-menu class="fqa-menus" mode="inline" v-model:openKeys="sseengine.opener" v-model:selectedKeys="sseengine.select" @select="menuHandler">
112
+ <!-- Menus Mask -->
113
+ <!-- <div class="fqa-menus-mask" v-if="sseengine.produce"></div> -->
114
+
115
+ <!-- Menus Group -->
116
+ <a-menu-item-group class="popover-modify" v-for="{ key, label, children } of menus" :key="key" :title="label">
117
+ <!-- Menus Item -->
118
+ <a-menu-item v-for="item of children" :key="`${item.session_id}`" :class="{ 'fqa-menus-item': true, keep: item.keep, remove: item.remove }">
119
+ <!-- For IOS -->
120
+ <div class="fqa-menus-item-touch" @touchstart="event => touchLesser(item, event)" @touchend.prevent="event => touchHandler(item, event)"></div>
121
+
122
+ <!-- Input Rename -->
123
+ <a-input class="fqa-menus-input" :ref="e => setRef(item.session_id, e)" v-model:value="item.title" @click.stop @blur="renameHandler($event, item)" @keyup.enter="renameHandler($event, item)" v-if="item.input" />
124
+
125
+ <!-- Title -->
126
+ <div class="fqa-menus-title" v-else>{{ item.title }}</div>
127
+
128
+ <!-- Menus More -->
129
+ <a-popover placement="rightTop" v-model:open="item.more" trigger="click">
130
+ <template #content>
131
+ <a-flex vertical class="fqa-menus-options">
132
+ <!-- Button Rename -->
133
+ <a-space class="fqa-menus-options-item" @click="() => ((item.input = true), (item.more = false), $nextTick(() => inputRefs[item.session_id].focus()))">
134
+ <fqa-icon icon="EditOutlined" />
135
+ <span>{{ $t('global.rename') }}</span>
136
+ </a-space>
137
+
138
+ <!-- Button Delete -->
139
+ <!-- <a-space class="fqa-menus-options-item" @click="() => (item.confirm = true)"> -->
140
+ <a-space class="fqa-menus-options-item" @click="deleteHandler($event, item)">
141
+ <fqa-icon icon="DeleteOutlined" />
142
+ <span>{{ $t('global.delete') }}</span>
143
+ </a-space>
144
+ </a-flex>
145
+ </template>
146
+
147
+ <!-- Button More -->
148
+ <fqa-button :class="{ 'fqa-menus-more': true, active: item.more }" :width="40" :height="40" @click.stop="() => (item.more = true)">
149
+ <fqa-icon icon="MoreOutlined" cursor="pointer" />
150
+ </fqa-button>
151
+ </a-popover>
152
+
153
+ <!-- Confirm Delete -->
154
+ <a-modal v-model:open="item.confirm" :title="$t('menus.title')" :ok-text="$t('global.ok')" :cancel-text="$t('global.cancel')" @ok="deleteHandler($event, item)" @cancel="() => (item.confirm = false)">
155
+ <p>{{ $t('menus.delete') }}</p>
156
+ </a-modal>
157
+ </a-menu-item>
158
+ </a-menu-item-group>
159
+
160
+ <!-- Menu Observe -->
161
+ <vue-view-observer @subscribe="subscribe" container=".FinQA--Assist" v-if="sseengine.menus.more">
162
+ <div class="fqa-menus-more">
163
+ <a-spin />
164
+ </div>
165
+ </vue-view-observer>
166
+
167
+ <div class="fqa-menus-no-more" v-else>没有更多了</div>
168
+ </a-menu>
169
+ </template>
170
+
171
+ <script>
172
+ export default {
173
+ props: {
174
+ menus: {
175
+ type: Array,
176
+ default: [],
177
+ },
178
+ },
179
+
180
+ data() {
181
+ return {
182
+ inputRefs: {},
183
+ touchState: 0,
184
+ canObserve: true,
185
+ };
186
+ },
187
+
188
+ methods: {
189
+ setRef(session_id, e) {
190
+ this.inputRefs[session_id] = e;
191
+ },
192
+
193
+ async menuHandler(item) {
194
+ // For Web
195
+ this.$util.message.send({ id: item.key }, () => {
196
+ // For MNP
197
+ this.$router.push({ name: 'chat', query: { c: item.key } });
198
+ });
199
+ },
200
+
201
+ async touchLesser(item, event) {
202
+ this.touchState = event.touches[0].clientY;
203
+ },
204
+
205
+ async touchHandler(item, event) {
206
+ const touchMove = Math.abs(event.changedTouches[0].clientY - this.touchState);
207
+
208
+ if (touchMove > 10) {
209
+ return;
210
+ }
211
+
212
+ // Remake Item
213
+ item.key = item.session_id;
214
+ item.selectedKeys = [item.session_id];
215
+
216
+ // Trigger Menus
217
+ await this.menuHandler(item);
218
+ },
219
+
220
+ async renameHandler(e, item) {
221
+ // Stop Event
222
+ e.stopPropagation();
223
+
224
+ // Rename
225
+ await this.$store.dispatch('sseengine/MENUS_RENAME', item);
226
+
227
+ // Update Sync Title
228
+ if (this.sseengine.info.current_node === item.current_node) {
229
+ await this.$store.dispatch('sseengine/STATE_UPDATE', { info: { title: item.title } });
230
+ }
231
+
232
+ // Close Input
233
+ item.input = false;
234
+ },
235
+
236
+ async deleteHandler(e, item) {
237
+ // Stop Event
238
+ e.stopPropagation();
239
+
240
+ // Delete
241
+ const { success } = await this.$store.dispatch('sseengine/MENUS_DEL', item);
242
+
243
+ // Remove Item
244
+ if (success) {
245
+ item.remove = true;
246
+ }
247
+
248
+ // Close Popover
249
+ item.more = false;
250
+ item.confirm = false;
251
+
252
+ // Clean
253
+ if (item.session_id === this.app.id) {
254
+ // Trigger Clean
255
+ await this.$store.dispatch('sseengine/CLEAN');
256
+
257
+ // For Web
258
+ this.$util.message.send({ id: 'new' }, () => {
259
+ // For MNP
260
+ this.$router.push({ name: 'chat' });
261
+ });
262
+ }
263
+ },
264
+
265
+ async subscribe(intersecting) {
266
+ if (!intersecting) {
267
+ return;
268
+ }
269
+
270
+ if (!this.canObserve) {
271
+ return;
272
+ }
273
+
274
+ this.canObserve = false;
275
+
276
+ await this.$store.dispatch('sseengine/MENUS_UPDATE', { page: this.sseengine.menus.page + 1 });
277
+ await this.$store.dispatch('sseengine/MENUS_GET');
278
+
279
+ this.canObserve = true;
280
+ },
281
+ },
282
+
283
+ async mounted() {
284
+ await this.$util.kitchen.sleep(6);
285
+ await this.subscribe(true);
286
+ },
287
+ };
288
+ </script>
@@ -0,0 +1,26 @@
1
+ .popover-modify {
2
+ }
3
+
4
+ .ant-popover {
5
+ &-inner {
6
+ background-color: darken(@color-assist, 3%) !important;
7
+
8
+ &-content {
9
+ color: @color-text !important;
10
+ }
11
+ }
12
+
13
+ &-arrow {
14
+ &:before,
15
+ &::after {
16
+ background-color: darken(@color-assist, 3%) !important;
17
+ }
18
+ }
19
+ }
20
+
21
+ .ant-menu-item-selected {
22
+ .fqa-menus-more {
23
+ opacity: 1;
24
+ z-index: 1;
25
+ }
26
+ }