plain-design 1.0.0-beta.162 → 1.0.0-beta.164

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "plain-design",
3
- "version": "1.0.0-beta.162",
3
+ "version": "1.0.0-beta.164",
4
4
  "description": "",
5
5
  "main": "dist/plain-design.min.js",
6
6
  "module": "dist/plain-design.commonjs.min.js",
@@ -10,6 +10,7 @@ import {uuid} from "@peryl/utils/uuid";
10
10
  import {PlainObject} from "@peryl/utils/event";
11
11
  import {defer} from "@peryl/utils/defer";
12
12
  import {toArray} from "@peryl/utils/toArray";
13
+ import {iEffects} from "@peryl/utils/createEffects";
13
14
 
14
15
  export const $ai = (() => {
15
16
 
@@ -100,9 +101,13 @@ export const $ai = (() => {
100
101
  onThinking,
101
102
  onThinkEnd,
102
103
  onThinkStart,
104
+ abortEffects,
103
105
  }: iAiChatStreamParameter
104
106
  ) => {
105
107
  const aiConfig = _aiConfig ?? getConfig();
108
+
109
+ const controller = new AbortController();
110
+ !!abortEffects && abortEffects.push(() => {controller.abort('abort stream.');});
106
111
  // 发送请求
107
112
  const response = await fetch(aiConfig.url, {
108
113
  method: 'POST',
@@ -115,7 +120,8 @@ export const $ai = (() => {
115
120
  "messages": messages,
116
121
  // "messages": [{ role: 'user', content: '你好' }],
117
122
  stream: true // 请求流式响应
118
- })
123
+ }),
124
+ signal: controller.signal,
119
125
  });
120
126
 
121
127
  if (!response.ok || !response.body) {throw response;}
@@ -140,6 +146,7 @@ export const $ai = (() => {
140
146
  if (message.slice(0, 7) === '```json' && message.slice(-3) === '```') {
141
147
  message = message.slice(7, -3).trim();
142
148
  }
149
+ onReceiving({ fullText: fullText, chunkText: '' });
143
150
  onFinish?.(message);
144
151
  }
145
152
  if (!value?.length) {
@@ -357,4 +364,5 @@ export interface iAiChatStreamParameter {
357
364
  onThinking?: (thinkText: string) => void,
358
365
  onThinkStart?: () => void,
359
366
  onThinkEnd?: () => void,
367
+ abortEffects?: iEffects,
360
368
  }
@@ -1,4 +1,4 @@
1
- import {designComponent, getComponentCls, iKeyboardEvent, PropType, reactive, useClasses, useRefs} from "@peryl/react-compose";
1
+ import {designComponent, getComponentCls, iKeyboardEvent, PropType, reactive, useClasses, useModel, useRefs} from "@peryl/react-compose";
2
2
  import Input from "../Input";
3
3
  import {EditProps, useEdit} from "../../uses/useEdit";
4
4
  import {StyleProps, useStyle} from "../../uses/useStyle";
@@ -13,6 +13,7 @@ import Scroll from "../Scroll";
13
13
  import {delay} from "@peryl/utils/delay";
14
14
  import {toArray} from "@peryl/utils/toArray";
15
15
  import {lastItem} from "@peryl/utils/lastItem";
16
+ import {createEffects} from "@peryl/utils/createEffects";
16
17
 
17
18
  export const AiChatBox = designComponent({
18
19
  props: {
@@ -26,6 +27,8 @@ export const AiChatBox = designComponent({
26
27
  histories: { type: Array as PropType<iChatBoxHistory[]> },
27
28
  /*系统提示词*/
28
29
  systemContent: { type: String },
30
+ /*用户输入的内容*/
31
+ modelValue: { type: String },
29
32
  /*手动处理大模型返回的message*/
30
33
  handleMessage: { type: Function as PropType<iChatBoxHandleMessage> },
31
34
  handleReceive: { type: Function as PropType<(data: { fullText?: string, chunkText?: string }) => void> },
@@ -33,9 +36,16 @@ export const AiChatBox = designComponent({
33
36
  handleChatStream: { type: Function as PropType<(parameter: iAiChatStreamParameter & { userContent: string }) => Promise<any>> },
34
37
  inputMinHeight: { type: String, default: '80px' },
35
38
  inputMaxHeight: { type: String, default: '225px' },
39
+ enableMemory: { type: Boolean },
40
+ memoryLimit: { type: Number, default: 15 },
36
41
  },
37
42
  slots: ['prepend'],
38
- setup({ props, slots }) {
43
+ emits: {
44
+ onUpdateModelValue: (val?: string) => true,
45
+ },
46
+ setup({ props, slots, event: { emit } }) {
47
+
48
+ const model = useModel(() => props.modelValue, emit.onUpdateModelValue);
39
49
 
40
50
  const { refs, onRef } = useRefs({ scroll: Scroll });
41
51
 
@@ -53,11 +63,12 @@ export const AiChatBox = designComponent({
53
63
  ]);
54
64
 
55
65
  const state = reactive({
56
- userContent: '',
57
66
  histories: props.histories || [] as iChatBoxHistory[],
58
67
  loading: false
59
68
  });
60
69
 
70
+ const { effects: abortEffects } = createEffects();
71
+
61
72
  const methods = {
62
73
  scrollEnd: async () => {
63
74
  if (!!refs.scroll) {
@@ -73,11 +84,16 @@ export const AiChatBox = designComponent({
73
84
  },
74
85
  send: async (userContent: string) => {
75
86
  await delay(23);
76
- state.userContent = '';
77
- await methods.addHistory({ role: 'user', content: userContent, id: uuid() });
87
+ model.value = '';
88
+ const newUserHistory: iChatBoxHistory = { role: 'user', content: userContent, id: uuid() };
89
+ await methods.addHistory(newUserHistory);
78
90
 
79
91
  /*const { message, chatData } = await $ai.chatSystem(userContent, props.systemContent, aiConfig);*/
80
- const messages: iAiHistory[] = [{ role: 'user', content: userContent }];
92
+ let messages: iAiHistory[] = props.enableMemory ? state.histories : (() => {
93
+ const { role, content } = newUserHistory;
94
+ return [{ role, content }];
95
+ })();
96
+ messages = messages.slice(props.memoryLimit * -1);
81
97
  await props.beforeSendUserContent?.({ userContent, messages });
82
98
  if (!!props.systemContent?.trim().length) {messages.unshift({ role: 'system', content: props.systemContent });}
83
99
  let chatBoxHistory: iChatBoxHistory | undefined = undefined;
@@ -87,6 +103,7 @@ export const AiChatBox = designComponent({
87
103
  aiConfig,
88
104
  messages,
89
105
  userContent,
106
+ abortEffects,
90
107
  onReceiving: ({ fullText, chunkText }) => {
91
108
  // console.log('receiving', fullText);
92
109
  props.handleReceive?.({ fullText, chunkText });
@@ -98,7 +115,6 @@ export const AiChatBox = designComponent({
98
115
  methods.scrollEnd();
99
116
  },
100
117
  onFinish: (fullText) => {
101
- chatBoxHistory!.content = fullText;
102
118
  message = fullText;
103
119
  },
104
120
  };
@@ -133,9 +149,18 @@ export const AiChatBox = designComponent({
133
149
 
134
150
  const handler = {
135
151
  onClickSend: async () => {
152
+ if (state.loading) {
153
+ console.log('abort');
154
+ abortEffects.clear();
155
+ return;
156
+ }
157
+
158
+ console.log('send');
159
+ abortEffects.clear();
160
+ abortEffects.push(() => state.loading = false);
136
161
  state.loading = true;
137
162
  try {
138
- const userContent = state.userContent;
163
+ const userContent = model.value;
139
164
  if (!userContent?.trim().length) {
140
165
  $message.error(i18n.$it('ai.require').d('提问的内容不能为空'));
141
166
  return;
@@ -187,13 +212,13 @@ export const AiChatBox = designComponent({
187
212
  <Input
188
213
  readonly={state.loading}
189
214
  textarea
190
- v-model={state.userContent}
215
+ v-model={model.value}
191
216
  placeholder={props.placeholder || i18n.$it('ai.placeholder').d('请输入要发送给ai的内容如:你是谁')}
192
217
  minHeight={props.inputMinHeight}
193
218
  maxHeight={props.inputMaxHeight}
194
219
  onEnter={handler.onEnterTextarea}
195
220
  />
196
- <Button shape="round" mode="fill" icon="pi-send" className="ai-chat-box-send-button" onClick={handler.onClickSend} loading={state.loading}/>
221
+ <Button shape="round" mode="fill" icon={state.loading ? 'ie-stop' : 'ie-send'} className="ai-chat-box-send-button" onClick={handler.onClickSend}/>
197
222
  </div>
198
223
  </div>
199
224
  )
@@ -145,7 +145,6 @@ export const useTableOptionAi = AutoModule.createRegistration((option) => {
145
145
  await scrollEnd();
146
146
  },
147
147
  onFinish: (fullText) => {
148
- history.content = fullText;
149
148
  console.log('search', history.content);
150
149
  operateItems.push({ type: "search", data: JSON.parse(fullText) });
151
150
  },
@@ -163,7 +162,6 @@ export const useTableOptionAi = AutoModule.createRegistration((option) => {
163
162
  await scrollEnd();
164
163
  },
165
164
  onFinish: (fullText) => {
166
- history.content = fullText;
167
165
  console.log('sort', history.content);
168
166
  operateItems.push({ type: "sort", data: JSON.parse(fullText) });
169
167
  },
@@ -181,7 +179,6 @@ export const useTableOptionAi = AutoModule.createRegistration((option) => {
181
179
  await scrollEnd();
182
180
  },
183
181
  onFinish: (fullText) => {
184
- history.content = fullText;
185
182
  console.log('config', history.content);
186
183
  operateItems.push({ type: "config", data: JSON.parse(fullText) });
187
184
  },
@@ -103,5 +103,15 @@ export const IconExternal: Record<string, () => RenderNode> = {
103
103
  <path
104
104
  d="M15.5355 2.80744C17.0976 1.24534 19.6303 1.24534 21.1924 2.80744C22.7545 4.36953 22.7545 6.90219 21.1924 8.46429L18.3638 11.2929L18.7175 11.6466C19.108 12.0371 19.108 12.6703 18.7175 13.0608C18.327 13.4513 17.6938 13.4513 17.3033 13.0608L16.9498 12.7073L10.7351 18.922C10.1767 19.4804 9.46547 19.861 8.6911 20.0159L6.93694 20.3667C6.54976 20.4442 6.19416 20.6345 5.91496 20.9137L4.92894 21.8997C4.53841 22.2902 3.90525 22.2902 3.51472 21.8997L2.10051 20.4855C1.70999 20.095 1.70999 19.4618 2.10051 19.0713L3.08653 18.0852C3.36574 17.806 3.55605 17.4504 3.63348 17.0633L3.98431 15.3091C4.13919 14.5347 4.51981 13.8235 5.07821 13.2651L11.2929 7.05045L10.9393 6.69686C10.5488 6.30634 10.5488 5.67317 10.9393 5.28265C11.3299 4.89212 11.963 4.89212 12.3535 5.28265L12.7069 5.63604L15.5355 2.80744ZM12.7071 8.46466L6.49242 14.6794C6.21322 14.9586 6.02291 15.3142 5.94548 15.7013L5.59464 17.4555C5.43977 18.2299 5.05915 18.9411 4.50075 19.4995C5.05915 18.9411 5.77035 18.5604 6.54471 18.4056L8.29887 18.0547C8.68605 17.9773 9.04165 17.787 9.32085 17.5078L15.5355 11.2931L12.7071 8.46466Z"></path>
105
105
  </svg>
106
+ ),
107
+ 'ie-send': () => (
108
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
109
+ <path d="M1.94607 9.31543C1.42353 9.14125 1.4194 8.86022 1.95682 8.68108L21.043 2.31901C21.5715 2.14285 21.8746 2.43866 21.7265 2.95694L16.2733 22.0432C16.1223 22.5716 15.8177 22.59 15.5944 22.0876L11.9999 14L17.9999 6.00005L9.99992 12L1.94607 9.31543Z"></path>
110
+ </svg>
111
+ ),
112
+ 'ie-stop': () => (
113
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
114
+ <path d="M6 5H18C18.5523 5 19 5.44772 19 6V18C19 18.5523 18.5523 19 18 19H6C5.44772 19 5 18.5523 5 18V6C5 5.44772 5.44772 5 6 5Z"></path>
115
+ </svg>
106
116
  )
107
117
  };