@agentscope-ai/chat 1.1.70 → 1.1.71-beta.1781610744021

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 (44) hide show
  1. package/components/AgentScopeRuntimeWebUI/core/Chat/Input/index.tsx +38 -5
  2. package/components/AgentScopeRuntimeWebUI/core/Chat/InputQueue/Panel.tsx +82 -0
  3. package/components/AgentScopeRuntimeWebUI/core/Chat/InputQueue/__tests__/inputQueue.test.ts +112 -0
  4. package/components/AgentScopeRuntimeWebUI/core/Chat/InputQueue/index.ts +122 -0
  5. package/components/AgentScopeRuntimeWebUI/core/Chat/hooks/useChatController.tsx +111 -4
  6. package/components/AgentScopeRuntimeWebUI/core/Chat/index.tsx +21 -3
  7. package/components/AgentScopeRuntimeWebUI/core/Chat/styles.tsx +68 -1
  8. package/components/AgentScopeRuntimeWebUI/core/ChatAnywhere/index.tsx +1 -1
  9. package/components/AgentScopeRuntimeWebUI/core/Context/ChatAnywhereI18nContext.tsx +14 -0
  10. package/components/AgentScopeRuntimeWebUI/starter/index.tsx +100 -14
  11. package/components/AgentScopeRuntimeWebUI/starterForMe/index.tsx +31 -0
  12. package/lib/AgentScopeRuntimeWebUI/core/Chat/Input/index.d.ts +8 -0
  13. package/lib/AgentScopeRuntimeWebUI/core/Chat/Input/index.js +36 -8
  14. package/lib/AgentScopeRuntimeWebUI/core/Chat/InputQueue/Panel.d.ts +9 -0
  15. package/lib/AgentScopeRuntimeWebUI/core/Chat/InputQueue/Panel.js +78 -0
  16. package/lib/AgentScopeRuntimeWebUI/core/Chat/InputQueue/index.d.ts +37 -0
  17. package/lib/AgentScopeRuntimeWebUI/core/Chat/InputQueue/index.js +74 -0
  18. package/lib/AgentScopeRuntimeWebUI/core/Chat/hooks/useChatController.d.ts +7 -0
  19. package/lib/AgentScopeRuntimeWebUI/core/Chat/hooks/useChatController.js +204 -63
  20. package/lib/AgentScopeRuntimeWebUI/core/Chat/index.js +14 -2
  21. package/lib/AgentScopeRuntimeWebUI/core/Chat/styles.js +31 -1
  22. package/lib/AgentScopeRuntimeWebUI/core/Context/ChatAnywhereI18nContext.d.ts +11 -1
  23. package/lib/AgentScopeRuntimeWebUI/core/Context/ChatAnywhereI18nContext.js +12 -0
  24. package/lib/AgentScopeRuntimeWebUI/starter/index.js +144 -20
  25. package/lib/AgentScopeRuntimeWebUI/starterForMe/index.d.ts +1 -0
  26. package/lib/AgentScopeRuntimeWebUI/starterForMe/index.js +34 -0
  27. package/package.json +2 -1
  28. package/bin/starter_webui/README.md +0 -75
  29. package/bin/starter_webui/eslint.config.js +0 -28
  30. package/bin/starter_webui/index.html +0 -12
  31. package/bin/starter_webui/package.json +0 -34
  32. package/bin/starter_webui/src/App.tsx +0 -20
  33. package/bin/starter_webui/src/components/Chat/OptionsPanel/FormItem.tsx +0 -37
  34. package/bin/starter_webui/src/components/Chat/OptionsPanel/OptionsEditor.tsx +0 -160
  35. package/bin/starter_webui/src/components/Chat/OptionsPanel/defaultConfig.ts +0 -41
  36. package/bin/starter_webui/src/components/Chat/OptionsPanel/index.tsx +0 -27
  37. package/bin/starter_webui/src/components/Chat/index.tsx +0 -45
  38. package/bin/starter_webui/src/components/Chat/sessionApi/index.ts +0 -53
  39. package/bin/starter_webui/src/main.tsx +0 -9
  40. package/bin/starter_webui/src/vite-env.d.ts +0 -4
  41. package/bin/starter_webui/tsconfig.app.json +0 -24
  42. package/bin/starter_webui/tsconfig.json +0 -7
  43. package/bin/starter_webui/tsconfig.node.json +0 -22
  44. package/bin/starter_webui/vite.config.ts +0 -11
@@ -35,6 +35,13 @@ const messages = {
35
35
  'common.saveSuccess': '保存成功',
36
36
  'common.saveFailed': '保存失败',
37
37
 
38
+ // Queue 相关
39
+ 'queue.title': '待发送队列',
40
+ 'queue.clear': '清空队列',
41
+ 'queue.retry': '重试发送',
42
+ 'queue.failed': '发送失败',
43
+ 'queue.attachmentOnly': '附件消息',
44
+
38
45
  // Actions 相关
39
46
  'actions.regenerate': '重新生成',
40
47
 
@@ -73,6 +80,13 @@ const messages = {
73
80
  'common.saveSuccess': 'Saved successfully',
74
81
  'common.saveFailed': 'Failed to save',
75
82
 
83
+ // Queue related
84
+ 'queue.title': 'Queued inputs',
85
+ 'queue.clear': 'Clear queue',
86
+ 'queue.retry': 'Retry',
87
+ 'queue.failed': 'Failed to send',
88
+ 'queue.attachmentOnly': 'Attachment message',
89
+
76
90
  // Actions related
77
91
  'actions.regenerate': 'Regenerate',
78
92
 
@@ -1,11 +1,97 @@
1
- import { AgentScopeRuntimeWebUI, IAgentScopeRuntimeWebUIRef, ChatInput } from '@agentscope-ai/chat';
1
+ import { AgentScopeRuntimeWebUI, IAgentScopeRuntimeWebUIRef } from '@agentscope-ai/chat';
2
2
  import OptionsPanel from './OptionsPanel';
3
3
  import { useMemo, useRef } from 'react';
4
4
  import defaultConfig from './OptionsPanel/defaultConfig';
5
5
  import { useLocalStorageState } from 'ahooks';
6
- import { Flex } from 'antd';
6
+ import { Button, Flex } from 'antd';
7
7
  import MessageImport from './MessageImport';
8
8
 
9
+ const encoder = new TextEncoder();
10
+
11
+ const sleep = (ms: number) => new Promise(resolve => {
12
+ setTimeout(resolve, ms);
13
+ });
14
+
15
+ function getLastUserText(input: any[] = []) {
16
+ const lastMessage = input[input.length - 1];
17
+ const content = lastMessage?.content || [];
18
+ return content
19
+ .filter((item: any) => item?.type === 'text')
20
+ .map((item: any) => item.text)
21
+ .join('\n');
22
+ }
23
+
24
+ async function createMockQueueResponse(data: {
25
+ input?: any[];
26
+ signal?: AbortSignal;
27
+ }) {
28
+ const userText = getLastUserText(data.input);
29
+ const messageId = `queue-demo-${Date.now()}`;
30
+ const chunks = [
31
+ {
32
+ object: 'message',
33
+ id: messageId,
34
+ role: 'assistant',
35
+ type: 'message',
36
+ status: 'in_progress',
37
+ content: [],
38
+ },
39
+ {
40
+ object: 'content',
41
+ msg_id: messageId,
42
+ type: 'text',
43
+ status: 'in_progress',
44
+ delta: true,
45
+ text: `Received: ${userText || 'attachment message'}\n\n`,
46
+ },
47
+ {
48
+ object: 'content',
49
+ msg_id: messageId,
50
+ type: 'text',
51
+ status: 'in_progress',
52
+ delta: true,
53
+ text: 'This mock response is intentionally slow, ',
54
+ },
55
+ {
56
+ object: 'content',
57
+ msg_id: messageId,
58
+ type: 'text',
59
+ status: 'in_progress',
60
+ delta: true,
61
+ text: 'so later inputs can enter the queue.',
62
+ },
63
+ {
64
+ object: 'response',
65
+ id: messageId,
66
+ status: 'completed',
67
+ created_at: Math.floor(Date.now() / 1000),
68
+ output: [],
69
+ },
70
+ ];
71
+
72
+ const stream = new ReadableStream({
73
+ async start(controller) {
74
+ for (const chunk of chunks) {
75
+ if (data.signal?.aborted) {
76
+ controller.close();
77
+ return;
78
+ }
79
+ await sleep(700);
80
+ controller.enqueue(
81
+ encoder.encode(`data: ${JSON.stringify(chunk)}\n\n`),
82
+ );
83
+ }
84
+ controller.close();
85
+ },
86
+ });
87
+
88
+ return new Response(stream, {
89
+ headers: {
90
+ 'Content-Type': 'text/event-stream',
91
+ },
92
+ });
93
+ }
94
+
9
95
 
10
96
  export default function () {
11
97
 
@@ -20,6 +106,16 @@ export default function () {
20
106
 
21
107
  const options = useMemo(() => {
22
108
  const rightHeader = <Flex gap={16}>
109
+ <Button size="small" onClick={() => {
110
+ chatRef.current?.input.submit({ query: 'Queue demo 1: slow response' });
111
+ window.setTimeout(() => {
112
+ chatRef.current?.input.submit({ query: 'Queue demo 2: queued while busy' });
113
+ }, 400);
114
+ window.setTimeout(() => {
115
+ chatRef.current?.input.submit({ query: 'Queue demo 3: sent after demo 2' });
116
+ }, 800);
117
+ }}>Queue demo</Button>
118
+
23
119
  <OptionsPanel value={optionsConfig} onChange={v => {
24
120
  setOptionsConfig(prev => ({
25
121
  ...prev,
@@ -40,17 +136,6 @@ export default function () {
40
136
  },
41
137
  sender: {
42
138
  ...optionsConfig.sender,
43
- beforeUI: <ChatInput.BeforeUIContainer>
44
- <Flex gap={6}>
45
- {
46
- optionsConfig.welcome.prompts.map(prompt => (
47
- <a key={prompt.value} onClick={() => {
48
- chatRef.current?.input.submit({ query: prompt.value });
49
- }}>{prompt.value}</a>
50
- ))
51
- }
52
- </Flex>
53
- </ChatInput.BeforeUIContainer>,
54
139
  attachments: optionsConfig.sender.attachments ? {
55
140
  customRequest(options) {
56
141
  // 模拟上传进度
@@ -71,6 +156,7 @@ export default function () {
71
156
  },
72
157
  api: {
73
158
  ...optionsConfig.api,
159
+ ...(!optionsConfig.api.baseURL ? { fetch: createMockQueueResponse } : {}),
74
160
  cancel: (data) => {
75
161
  console.log('cancel', data);
76
162
  },
@@ -87,4 +173,4 @@ export default function () {
87
173
  options={options}
88
174
  />
89
175
  </div>;
90
- }
176
+ }
@@ -0,0 +1,31 @@
1
+ import { AgentScopeRuntimeWebUI } from '@agentscope-ai/chat';
2
+
3
+ export default function Page() {
4
+ return (
5
+ <div style={{ height: '100dvh' }}>
6
+ <AgentScopeRuntimeWebUI
7
+ options={{
8
+ api: {
9
+ baseURL: '/api/runtime/chat',
10
+ token: 'your-token',
11
+ },
12
+ session: {
13
+ multiple: true,
14
+ },
15
+ theme: {
16
+ locale: 'en',
17
+ colorPrimary: '#615CED',
18
+ },
19
+ sender: {
20
+ placeholder: 'Ask something',
21
+ maxLength: 10000,
22
+ },
23
+ welcome: {
24
+ greeting: 'Hello, how can I help you today?',
25
+ prompts: [{ value: 'What can you do?' }],
26
+ },
27
+ }}
28
+ />
29
+ </div>
30
+ );
31
+ }
@@ -1,6 +1,14 @@
1
1
  import { IAgentScopeRuntimeWebUIInputData } from "../../../..";
2
+ import type { QueuedInputItem } from "../InputQueue";
2
3
  export interface InputProps {
3
4
  onCancel: () => void;
4
5
  onSubmit: (data: IAgentScopeRuntimeWebUIInputData) => void;
6
+ queue?: {
7
+ items: QueuedInputItem[];
8
+ onEnqueue: (data: IAgentScopeRuntimeWebUIInputData) => void;
9
+ onRemove: (id: string) => void;
10
+ onClear: () => void;
11
+ onRetry: (id: string) => void;
12
+ };
5
13
  }
6
14
  export default function Input(props: InputProps): import("react/jsx-runtime").JSX.Element;
@@ -14,10 +14,12 @@ import { useChatAnywhereOptions } from "../../Context/ChatAnywhereOptionsContext
14
14
  import { useGetState } from 'ahooks';
15
15
  import { useChatAnywhereInput } from "../../Context/ChatAnywhereInputContext";
16
16
  import useAttachments from "./useAttachments";
17
+ import InputQueuePanel from "../InputQueue/Panel";
18
+ import { jsx as _jsx } from "react/jsx-runtime";
17
19
  import { Fragment as _Fragment } from "react/jsx-runtime";
18
20
  import { jsxs as _jsxs } from "react/jsx-runtime";
19
- import { jsx as _jsx } from "react/jsx-runtime";
20
21
  export default function Input(props) {
22
+ var _props$queue4, _props$queue5;
21
23
  var _useGetState = useGetState(''),
22
24
  _useGetState2 = _slicedToArray(_useGetState, 3),
23
25
  content = _useGetState2[0],
@@ -55,7 +57,8 @@ export default function Input(props) {
55
57
  uploadIconButton = _useAttachments.uploadIconButton,
56
58
  uploadFileListHeader = _useAttachments.uploadFileListHeader;
57
59
  var handleSubmit = useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
58
- var next, fileList;
60
+ var _props$queue;
61
+ var next, fileList, data, _props$queue2;
59
62
  return _regeneratorRuntime().wrap(function _callee$(_context) {
60
63
  while (1) switch (_context.prev = _context.next) {
61
64
  case 0:
@@ -73,26 +76,51 @@ export default function Input(props) {
73
76
  var _i$response;
74
77
  return (_i$response = i.response) === null || _i$response === void 0 ? void 0 : _i$response.url;
75
78
  });
76
- props.onSubmit({
79
+ data = {
77
80
  query: getContent(),
78
81
  fileList: fileList
79
- });
82
+ };
83
+ if (inputContext.loading || (_props$queue = props.queue) !== null && _props$queue !== void 0 && _props$queue.items.length) {
84
+ (_props$queue2 = props.queue) === null || _props$queue2 === void 0 || _props$queue2.onEnqueue(data);
85
+ } else {
86
+ props.onSubmit(data);
87
+ }
80
88
  setContent('');
81
- setFileList && setFileList([]);
82
- case 9:
89
+ setFileList === null || setFileList === void 0 || setFileList([]);
90
+ case 10:
83
91
  case "end":
84
92
  return _context.stop();
85
93
  }
86
94
  }, _callee);
87
- })), []);
95
+ })), [beforeSubmit, getContent, getFileList, inputContext.loading, props.onSubmit, props.queue, setContent, setFileList]);
96
+ var handleKeyDownCapture = useCallback(function (event) {
97
+ var _event$nativeEvent, _props$queue3;
98
+ if (event.key !== 'Enter' || event.shiftKey) return;
99
+ if ((_event$nativeEvent = event.nativeEvent) !== null && _event$nativeEvent !== void 0 && _event$nativeEvent.isComposing) return;
100
+ if (!inputContext.loading && !((_props$queue3 = props.queue) !== null && _props$queue3 !== void 0 && _props$queue3.items.length)) return;
101
+ var fileList = ((getFileList === null || getFileList === void 0 ? void 0 : getFileList()) || []).filter(function (i) {
102
+ var _i$response2;
103
+ return (_i$response2 = i.response) === null || _i$response2 === void 0 ? void 0 : _i$response2.url;
104
+ });
105
+ if (!getContent().trim() && fileList.length === 0) return;
106
+ event.preventDefault();
107
+ event.stopPropagation();
108
+ void handleSubmit();
109
+ }, [getContent, getFileList, handleSubmit, inputContext.loading, (_props$queue4 = props.queue) === null || _props$queue4 === void 0 ? void 0 : _props$queue4.items.length]);
88
110
  var handleCancel = useCallback(function () {
89
111
  props.onCancel();
90
112
  }, []);
91
113
  return /*#__PURE__*/_jsxs("div", {
92
114
  className: prefixCls,
115
+ onKeyDownCapture: handleKeyDownCapture,
93
116
  children: [/*#__PURE__*/_jsxs("div", {
94
117
  className: "".concat(prefixCls, "-wrapper"),
95
- children: [beforeUI, /*#__PURE__*/_jsx(ChatInput, {
118
+ children: [beforeUI, (_props$queue5 = props.queue) !== null && _props$queue5 !== void 0 && _props$queue5.items.length ? /*#__PURE__*/_jsx(InputQueuePanel, {
119
+ items: props.queue.items,
120
+ onRemove: props.queue.onRemove,
121
+ onClear: props.queue.onClear,
122
+ onRetry: props.queue.onRetry
123
+ }) : null, /*#__PURE__*/_jsx(ChatInput, {
96
124
  loading: inputContext.loading,
97
125
  disabled: inputContext.disabled,
98
126
  placeholder: placeholder,
@@ -0,0 +1,9 @@
1
+ import type { QueuedInputItem } from './index';
2
+ interface InputQueuePanelProps {
3
+ items: QueuedInputItem[];
4
+ onRemove: (id: string) => void;
5
+ onClear: () => void;
6
+ onRetry: (id: string) => void;
7
+ }
8
+ export default function InputQueuePanel(props: InputQueuePanelProps): import("react/jsx-runtime").JSX.Element;
9
+ export {};
@@ -0,0 +1,78 @@
1
+ import { IconButton } from '@agentscope-ai/design';
2
+ import { SparkClearLine, SparkDeleteLine, SparkRefreshLine } from '@agentscope-ai/icons';
3
+ import { Tooltip } from 'antd';
4
+ import { useProviderContext } from "../../../..";
5
+ import { useTranslation } from "../../Context/ChatAnywhereI18nContext";
6
+ import { jsxs as _jsxs } from "react/jsx-runtime";
7
+ import { jsx as _jsx } from "react/jsx-runtime";
8
+ export default function InputQueuePanel(props) {
9
+ var items = props.items,
10
+ onRemove = props.onRemove,
11
+ onClear = props.onClear,
12
+ onRetry = props.onRetry;
13
+ var prefixCls = useProviderContext().getPrefixCls('chat-anywhere-input-queue');
14
+ var _useTranslation = useTranslation(),
15
+ t = _useTranslation.t;
16
+ var tr = function tr(key) {
17
+ return (t === null || t === void 0 ? void 0 : t(key)) || key;
18
+ };
19
+ if (!items.length) return null;
20
+ return /*#__PURE__*/_jsxs("div", {
21
+ className: prefixCls,
22
+ children: [/*#__PURE__*/_jsxs("div", {
23
+ className: "".concat(prefixCls, "-header"),
24
+ children: [/*#__PURE__*/_jsxs("span", {
25
+ children: [tr('queue.title'), " (", items.length, ")"]
26
+ }), /*#__PURE__*/_jsx(Tooltip, {
27
+ title: tr('queue.clear'),
28
+ children: /*#__PURE__*/_jsx(IconButton, {
29
+ size: "small",
30
+ bordered: false,
31
+ icon: /*#__PURE__*/_jsx(SparkClearLine, {}),
32
+ onClick: onClear
33
+ })
34
+ })]
35
+ }), /*#__PURE__*/_jsx("div", {
36
+ className: "".concat(prefixCls, "-list"),
37
+ children: items.map(function (item, index) {
38
+ var failed = item.status === 'failed';
39
+ return /*#__PURE__*/_jsxs("div", {
40
+ className: "".concat(prefixCls, "-item"),
41
+ children: [/*#__PURE__*/_jsx("span", {
42
+ className: "".concat(prefixCls, "-index"),
43
+ children: index + 1
44
+ }), /*#__PURE__*/_jsxs("div", {
45
+ className: "".concat(prefixCls, "-content"),
46
+ children: [/*#__PURE__*/_jsx("div", {
47
+ className: "".concat(prefixCls, "-text"),
48
+ children: item.data.query || tr('queue.attachmentOnly')
49
+ }), failed ? /*#__PURE__*/_jsx("div", {
50
+ className: "".concat(prefixCls, "-error"),
51
+ children: item.errorMessage || tr('queue.failed')
52
+ }) : null]
53
+ }), failed ? /*#__PURE__*/_jsx(Tooltip, {
54
+ title: tr('queue.retry'),
55
+ children: /*#__PURE__*/_jsx(IconButton, {
56
+ size: "small",
57
+ bordered: false,
58
+ icon: /*#__PURE__*/_jsx(SparkRefreshLine, {}),
59
+ onClick: function onClick() {
60
+ return onRetry(item.id);
61
+ }
62
+ })
63
+ }) : null, /*#__PURE__*/_jsx(Tooltip, {
64
+ title: tr('common.delete'),
65
+ children: /*#__PURE__*/_jsx(IconButton, {
66
+ size: "small",
67
+ bordered: false,
68
+ icon: /*#__PURE__*/_jsx(SparkDeleteLine, {}),
69
+ onClick: function onClick() {
70
+ return onRemove(item.id);
71
+ }
72
+ })
73
+ })]
74
+ }, item.id);
75
+ })
76
+ })]
77
+ });
78
+ }
@@ -0,0 +1,37 @@
1
+ import type { IAgentScopeRuntimeWebUIInputData } from '../../types';
2
+ export type QueuedInputStatus = 'pending' | 'failed';
3
+ export interface QueuedInputItem {
4
+ id: string;
5
+ data: IAgentScopeRuntimeWebUIInputData;
6
+ status: QueuedInputStatus;
7
+ retryCount: number;
8
+ errorMessage?: string;
9
+ createdAt: number;
10
+ }
11
+ export interface EnqueueQueuedInputResult {
12
+ queue: QueuedInputItem[];
13
+ item?: QueuedInputItem;
14
+ reason?: 'full';
15
+ }
16
+ export declare const MAX_INPUT_QUEUE_SIZE = 50;
17
+ export declare function createQueuedInputItem(data: IAgentScopeRuntimeWebUIInputData, options?: {
18
+ id?: string;
19
+ now?: number;
20
+ }): QueuedInputItem;
21
+ export declare function enqueueQueuedInput(queue: QueuedInputItem[], data: IAgentScopeRuntimeWebUIInputData, options?: {
22
+ maxSize?: number;
23
+ id?: string;
24
+ now?: number;
25
+ }): EnqueueQueuedInputResult;
26
+ export declare function dequeueNextQueuedInput(queue: QueuedInputItem[]): {
27
+ item?: QueuedInputItem;
28
+ queue: QueuedInputItem[];
29
+ };
30
+ export declare function removeQueuedInput(queue: QueuedInputItem[], id: string): QueuedInputItem[];
31
+ export declare function retryQueuedInput(queue: QueuedInputItem[], id: string): QueuedInputItem[];
32
+ export declare function restoreFailedQueuedInput(queue: QueuedInputItem[], item: QueuedInputItem, error?: unknown): QueuedInputItem[];
33
+ export declare function canSubmitDirectly(options: {
34
+ loading: boolean | string;
35
+ queueLength: number;
36
+ draining: boolean;
37
+ }): boolean;
@@ -0,0 +1,74 @@
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
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
5
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
6
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
7
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
8
+ 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."); }
9
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
10
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
11
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
12
+ 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; }
13
+ export var MAX_INPUT_QUEUE_SIZE = 50;
14
+ var queueId = 0;
15
+ export function createQueuedInputItem(data, options) {
16
+ var _options$now;
17
+ return {
18
+ id: (options === null || options === void 0 ? void 0 : options.id) || "input-queue-".concat(Date.now().toString(36), "-").concat((++queueId).toString(36)),
19
+ data: data,
20
+ status: 'pending',
21
+ retryCount: 0,
22
+ createdAt: (_options$now = options === null || options === void 0 ? void 0 : options.now) !== null && _options$now !== void 0 ? _options$now : Date.now()
23
+ };
24
+ }
25
+ export function enqueueQueuedInput(queue, data, options) {
26
+ var _options$maxSize;
27
+ var maxSize = (_options$maxSize = options === null || options === void 0 ? void 0 : options.maxSize) !== null && _options$maxSize !== void 0 ? _options$maxSize : MAX_INPUT_QUEUE_SIZE;
28
+ if (queue.length >= maxSize) {
29
+ return {
30
+ queue: queue,
31
+ reason: 'full'
32
+ };
33
+ }
34
+ var item = createQueuedInputItem(data, options);
35
+ return {
36
+ queue: [].concat(_toConsumableArray(queue), [item]),
37
+ item: item
38
+ };
39
+ }
40
+ export function dequeueNextQueuedInput(queue) {
41
+ var next = queue[0];
42
+ if (!next || next.status !== 'pending') {
43
+ return {
44
+ queue: queue
45
+ };
46
+ }
47
+ return {
48
+ item: next,
49
+ queue: queue.slice(1)
50
+ };
51
+ }
52
+ export function removeQueuedInput(queue, id) {
53
+ return queue.filter(function (item) {
54
+ return item.id !== id;
55
+ });
56
+ }
57
+ export function retryQueuedInput(queue, id) {
58
+ return queue.map(function (item) {
59
+ return item.id === id ? _objectSpread(_objectSpread({}, item), {}, {
60
+ status: 'pending',
61
+ errorMessage: undefined
62
+ }) : item;
63
+ });
64
+ }
65
+ export function restoreFailedQueuedInput(queue, item, error) {
66
+ return [_objectSpread(_objectSpread({}, item), {}, {
67
+ status: 'failed',
68
+ retryCount: item.retryCount + 1,
69
+ errorMessage: error instanceof Error ? error.message : String(error || '')
70
+ })].concat(_toConsumableArray(queue));
71
+ }
72
+ export function canSubmitDirectly(options) {
73
+ return !options.loading && options.queueLength === 0 && !options.draining;
74
+ }
@@ -1,7 +1,14 @@
1
+ import { InputProps } from "../Input";
2
+ import { type QueuedInputItem } from "../InputQueue";
1
3
  /**
2
4
  * Chat controller hook — coordinates all chat-related operations.
3
5
  */
4
6
  export default function useChatController(): {
5
7
  handleSubmit: (data: import("../../../..").IAgentScopeRuntimeWebUIInputData) => void;
6
8
  handleCancel: () => void;
9
+ inputQueue: QueuedInputItem[];
10
+ enqueueQueuedInput: (data: Parameters<InputProps['onSubmit']>[0]) => void;
11
+ removeQueuedInput: (id: string) => void;
12
+ clearQueuedInputs: () => void;
13
+ retryQueuedInput: (id: string) => void;
7
14
  };