@agentscope-ai/chat 1.1.42 → 1.1.43-beta.1765432918432

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.
@@ -1,4 +1,4 @@
1
- import React, { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react'
1
+ import React, { forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react'
2
2
  import { UploadFile } from 'antd';
3
3
  import { useProviderContext, ChatInput, uuid, Sender, Attachments } from '@agentscope-ai/chat';
4
4
  import cls from 'classnames';
@@ -138,8 +138,19 @@ export default forwardRef(function (_, ref) {
138
138
 
139
139
  const submitFileList = attachedFiles.map(files => files.filter(file => file.status === 'done'));
140
140
  const fileLoading = attachedFiles.some(files => files.some(file => file.status === 'uploading'));
141
-
142
-
141
+
142
+ // 检查是否有必需的上传项没有文件
143
+ const requiredFileMissing = useMemo(() => {
144
+ return onUpload?.some((item, index) => {
145
+ if (item.required) {
146
+ const files = attachedFiles[index] || [];
147
+ return files.length === 0;
148
+ }
149
+ return false;
150
+ }) ?? false;
151
+ }, [onUpload, attachedFiles]);
152
+
153
+ const sendDisabled = requiredFileMissing;
143
154
 
144
155
  return <>
145
156
  <Style />
@@ -163,6 +174,7 @@ export default forwardRef(function (_, ref) {
163
174
  onChange={setContent}
164
175
  maxLength={onInput.maxLength}
165
176
  disabled={fileLoading || inputContext.disabled}
177
+ sendDisabled={sendDisabled}
166
178
  scalable={onInput?.zoomable}
167
179
  header={senderHeader}
168
180
  prefix={<>
@@ -194,6 +194,11 @@ export interface IChatAnywhereConfigOnUpload {
194
194
  * @descriptionEn Pre-upload processing function
195
195
  */
196
196
  beforeUpload?: GetProp<typeof Upload, 'beforeUpload'>;
197
+ /**
198
+ * @description 是否必传
199
+ * @descriptionEn Whether to required
200
+ */
201
+ required?: boolean;
197
202
  /**
198
203
  * @description 自定义上传请求函数
199
204
  * @descriptionEn Custom upload request function
@@ -28,6 +28,12 @@ export interface IRagProps {
28
28
  images?: string[];
29
29
  link?: string;
30
30
  }[]
31
+ /**
32
+ * @description 默认展开
33
+ * @descriptionEn Default Open
34
+ * @default true
35
+ */
36
+ defaultOpen?: boolean;
31
37
  }
32
38
 
33
39
  function Images({ images }: { images: string[] }) {
@@ -54,7 +60,7 @@ function Images({ images }: { images: string[] }) {
54
60
  export default function (props: IRagProps) {
55
61
  const { getPrefixCls } = useProviderContext();
56
62
  const prefixCls = getPrefixCls('operate-card');
57
- const { title = '知识库检索', subTitle } = props;
63
+ const { title = '知识库检索', subTitle, defaultOpen = true } = props;
58
64
 
59
65
  return <OperateCard
60
66
  header={{
@@ -63,7 +69,7 @@ export default function (props: IRagProps) {
63
69
  description: subTitle,
64
70
  }}
65
71
  body={{
66
- defaultOpen: true,
72
+ defaultOpen,
67
73
  children: <OperateCard.LineBody>
68
74
  {props.list.map((item, index) => {
69
75
  return <div key={index} className={`${prefixCls}-rag-item`}>
@@ -79,7 +79,7 @@ export function ActionButton(props: ActionButtonProps) {
79
79
  const { prefixCls, disabled: rootDisabled } = context;
80
80
 
81
81
  const onClick = context[action];
82
- const mergedDisabled = rootDisabled ?? restProps.disabled ?? context[`${action}Disabled`];
82
+ const mergedDisabled = rootDisabled || restProps.disabled || context[`${action}Disabled`] || false;
83
83
 
84
84
  return (
85
85
  <IconButton
@@ -76,6 +76,12 @@ export interface SenderProps extends Pick<TextareaProps, 'placeholder' | 'onKeyP
76
76
  */
77
77
  disabled?: boolean;
78
78
 
79
+ /**
80
+ * @description 是否禁用发送按钮
81
+ * @descriptionEn Whether to disable the send button
82
+ */
83
+ sendDisabled?: boolean;
84
+
79
85
  /**
80
86
  * @description 是否启用用户focus时展开输入框组件
81
87
  * @descriptionEn Whether to enable the user focus to expand the input box component
@@ -211,6 +217,7 @@ const ForwardSender = React.forwardRef<SenderRef, SenderProps>((props, ref) => {
211
217
  value,
212
218
  readOnly,
213
219
  enableFocusExpand = false,
220
+ sendDisabled = false,
214
221
  submitType = 'enter',
215
222
  onSubmit,
216
223
  loading,
@@ -326,7 +333,7 @@ const ForwardSender = React.forwardRef<SenderRef, SenderProps>((props, ref) => {
326
333
 
327
334
  // ============================ Events ============================
328
335
  const triggerSend = () => {
329
- if (innerValue && onSubmit && !loading) {
336
+ if (!contextValue.onSendDisabled && onSubmit && !loading) {
330
337
  onSubmit(innerValue);
331
338
  }
332
339
  };
@@ -431,7 +438,7 @@ const ForwardSender = React.forwardRef<SenderRef, SenderProps>((props, ref) => {
431
438
  const contextValue = {
432
439
  prefixCls: actionBtnCls,
433
440
  onSend: triggerSend,
434
- onSendDisabled: !innerValue,
441
+ onSendDisabled: !innerValue || sendDisabled,
435
442
  onClear: triggerClear,
436
443
  onClearDisabled: !innerValue,
437
444
  onCancel,
@@ -13,7 +13,7 @@ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o =
13
13
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
14
14
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
15
15
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
16
- import React, { forwardRef, useEffect, useRef, useState } from 'react';
16
+ import React, { forwardRef, useEffect, useMemo, useRef, useState } from 'react';
17
17
  import { useProviderContext, ChatInput, Sender, Attachments } from "../..";
18
18
  import cls from 'classnames';
19
19
  import { useChatAnywhere } from "../hooks/ChatAnywhereProvider";
@@ -170,6 +170,19 @@ export default /*#__PURE__*/forwardRef(function (_, ref) {
170
170
  return file.status === 'uploading';
171
171
  });
172
172
  });
173
+
174
+ // 检查是否有必需的上传项没有文件
175
+ var requiredFileMissing = useMemo(function () {
176
+ var _onUpload$some;
177
+ return (_onUpload$some = onUpload === null || onUpload === void 0 ? void 0 : onUpload.some(function (item, index) {
178
+ if (item.required) {
179
+ var files = attachedFiles[index] || [];
180
+ return files.length === 0;
181
+ }
182
+ return false;
183
+ })) !== null && _onUpload$some !== void 0 ? _onUpload$some : false;
184
+ }, [onUpload, attachedFiles]);
185
+ var sendDisabled = requiredFileMissing;
173
186
  return /*#__PURE__*/_jsxs(_Fragment, {
174
187
  children: [/*#__PURE__*/_jsx(Style, {}), /*#__PURE__*/_jsxs("div", {
175
188
  className: cls("".concat(prefixCls, "-wrapper"), _defineProperty(_defineProperty({}, "".concat(prefixCls, "-wrapper-focus"), focus && onInput.enableFocusExpand), "".concat(prefixCls, "-wrapper-blur"), !focus && onInput.enableFocusExpand)),
@@ -183,6 +196,7 @@ export default /*#__PURE__*/forwardRef(function (_, ref) {
183
196
  onChange: setContent,
184
197
  maxLength: onInput.maxLength,
185
198
  disabled: fileLoading || inputContext.disabled,
199
+ sendDisabled: sendDisabled,
186
200
  scalable: onInput === null || onInput === void 0 ? void 0 : onInput.zoomable,
187
201
  header: senderHeader,
188
202
  prefix: /*#__PURE__*/_jsxs(_Fragment, {
@@ -191,6 +191,11 @@ export interface IChatAnywhereConfigOnUpload {
191
191
  * @descriptionEn Pre-upload processing function
192
192
  */
193
193
  beforeUpload?: GetProp<typeof Upload, 'beforeUpload'>;
194
+ /**
195
+ * @description 是否必传
196
+ * @descriptionEn Whether to required
197
+ */
198
+ required?: boolean;
194
199
  /**
195
200
  * @description 自定义上传请求函数
196
201
  * @descriptionEn Custom upload request function
@@ -23,5 +23,11 @@ export interface IRagProps {
23
23
  images?: string[];
24
24
  link?: string;
25
25
  }[];
26
+ /**
27
+ * @description 默认展开
28
+ * @descriptionEn Default Open
29
+ * @default true
30
+ */
31
+ defaultOpen?: boolean;
26
32
  }
27
33
  export default function (props: IRagProps): import("react/jsx-runtime").JSX.Element;
@@ -32,7 +32,9 @@ export default function (props) {
32
32
  var prefixCls = getPrefixCls('operate-card');
33
33
  var _props$title = props.title,
34
34
  title = _props$title === void 0 ? '知识库检索' : _props$title,
35
- subTitle = props.subTitle;
35
+ subTitle = props.subTitle,
36
+ _props$defaultOpen = props.defaultOpen,
37
+ defaultOpen = _props$defaultOpen === void 0 ? true : _props$defaultOpen;
36
38
  return /*#__PURE__*/_jsx(OperateCard, {
37
39
  header: {
38
40
  icon: /*#__PURE__*/_jsx(SparkBookLine, {}),
@@ -40,7 +42,7 @@ export default function (props) {
40
42
  description: subTitle
41
43
  },
42
44
  body: {
43
- defaultOpen: true,
45
+ defaultOpen: defaultOpen,
44
46
  children: /*#__PURE__*/_jsx(OperateCard.LineBody, {
45
47
  children: props.list.map(function (item, index) {
46
48
  return /*#__PURE__*/_jsxs("div", {
@@ -13,7 +13,6 @@ import * as React from 'react';
13
13
  import { jsx as _jsx } from "react/jsx-runtime";
14
14
  export var ActionButtonContext = /*#__PURE__*/React.createContext(null);
15
15
  export function ActionButton(props) {
16
- var _ref;
17
16
  var className = props.className,
18
17
  action = props.action,
19
18
  outClick = props.onClick,
@@ -22,7 +21,7 @@ export function ActionButton(props) {
22
21
  var prefixCls = context.prefixCls,
23
22
  rootDisabled = context.disabled;
24
23
  var _onClick = context[action];
25
- var mergedDisabled = (_ref = rootDisabled !== null && rootDisabled !== void 0 ? rootDisabled : restProps.disabled) !== null && _ref !== void 0 ? _ref : context["".concat(action, "Disabled")];
24
+ var mergedDisabled = rootDisabled || restProps.disabled || context["".concat(action, "Disabled")] || false;
26
25
  return /*#__PURE__*/_jsx(IconButton, _objectSpread(_objectSpread({
27
26
  bordered: false,
28
27
  disabled: mergedDisabled
@@ -46,6 +46,11 @@ export interface SenderProps extends Pick<TextareaProps, 'placeholder' | 'onKeyP
46
46
  * @descriptionEn Whether to disable the entire sender component, including input field and buttons
47
47
  */
48
48
  disabled?: boolean;
49
+ /**
50
+ * @description 是否禁用发送按钮
51
+ * @descriptionEn Whether to disable the send button
52
+ */
53
+ sendDisabled?: boolean;
49
54
  /**
50
55
  * @description 是否启用用户focus时展开输入框组件
51
56
  * @descriptionEn Whether to enable the user focus to expand the input box component
@@ -1,5 +1,5 @@
1
1
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
- var _excluded = ["styles", "classNames", "className", "rootClassName", "style", "defaultValue", "value", "readOnly", "enableFocusExpand", "submitType", "onSubmit", "loading", "onCancel", "onChange", "onFocus", "onBlur", "actions", "onKeyPress", "onKeyDown", "disabled", "header", "onPaste", "allowSpeech", "onPasteFile", "components", "initialRows", "scalable"];
2
+ var _excluded = ["styles", "classNames", "className", "rootClassName", "style", "defaultValue", "value", "readOnly", "enableFocusExpand", "sendDisabled", "submitType", "onSubmit", "loading", "onCancel", "onChange", "onFocus", "onBlur", "actions", "onKeyPress", "onKeyDown", "disabled", "header", "onPaste", "allowSpeech", "onPasteFile", "components", "initialRows", "scalable"];
3
3
  function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
4
4
  function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
5
5
  function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
@@ -57,6 +57,8 @@ var ForwardSender = /*#__PURE__*/React.forwardRef(function (props, ref) {
57
57
  readOnly = _ref.readOnly,
58
58
  _ref$enableFocusExpan = _ref.enableFocusExpand,
59
59
  enableFocusExpand = _ref$enableFocusExpan === void 0 ? false : _ref$enableFocusExpan,
60
+ _ref$sendDisabled = _ref.sendDisabled,
61
+ sendDisabled = _ref$sendDisabled === void 0 ? false : _ref$sendDisabled,
60
62
  _ref$submitType = _ref.submitType,
61
63
  submitType = _ref$submitType === void 0 ? 'enter' : _ref$submitType,
62
64
  onSubmit = _ref.onSubmit,
@@ -163,7 +165,7 @@ var ForwardSender = /*#__PURE__*/React.forwardRef(function (props, ref) {
163
165
 
164
166
  // ============================ Events ============================
165
167
  var triggerSend = function triggerSend() {
166
- if (innerValue && onSubmit && !loading) {
168
+ if (!contextValue.onSendDisabled && onSubmit && !loading) {
167
169
  onSubmit(innerValue);
168
170
  }
169
171
  };
@@ -254,7 +256,7 @@ var ForwardSender = /*#__PURE__*/React.forwardRef(function (props, ref) {
254
256
  var contextValue = {
255
257
  prefixCls: actionBtnCls,
256
258
  onSend: triggerSend,
257
- onSendDisabled: !innerValue,
259
+ onSendDisabled: !innerValue || sendDisabled,
258
260
  onClear: triggerClear,
259
261
  onClearDisabled: !innerValue,
260
262
  onCancel: onCancel,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentscope-ai/chat",
3
- "version": "1.1.42",
3
+ "version": "1.1.43-beta.1765432918432",
4
4
  "description": "a free and open-source chat framework for building excellent LLM-powered chat experiences",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": [