@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
@@ -2,12 +2,19 @@ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" ==
2
2
  function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
3
3
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
4
4
  function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
5
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
6
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
7
+ 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); }
8
+ 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; }
9
+ 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; } }
10
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
5
11
  import { sleep } from "../../../..";
6
- import { useCallback, useEffect, useRef } from "react";
12
+ import { useCallback, useEffect, useRef, useState } from "react";
7
13
  import { useContextSelector } from "use-context-selector";
8
14
  import { ChatAnywhereInputContext } from "../../Context/ChatAnywhereInputContext";
9
15
  import { ChatAnywhereSessionsContext } from "../../Context/ChatAnywhereSessionsContext";
10
16
  import useChatAnywhereEventEmitter from "../../Context/useChatAnywhereEventEmitter";
17
+ import { canSubmitDirectly, dequeueNextQueuedInput, enqueueQueuedInput, MAX_INPUT_QUEUE_SIZE, removeQueuedInput as _removeQueuedInput, restoreFailedQueuedInput, retryQueuedInput as _retryQueuedInput } from "../InputQueue";
11
18
  import useChatMessageHandler from "./useChatMessageHandler";
12
19
  import useChatRequest from "./useChatRequest";
13
20
  import useChatSessionHandler from "./useChatSessionHandler";
@@ -22,6 +29,9 @@ export default function useChatController() {
22
29
  var setLoading = useContextSelector(ChatAnywhereInputContext, function (v) {
23
30
  return v.setLoading;
24
31
  });
32
+ var getLoading = useContextSelector(ChatAnywhereInputContext, function (v) {
33
+ return v.getLoading;
34
+ });
25
35
  var currentSessionId = useContextSelector(ChatAnywhereSessionsContext, function (v) {
26
36
  return v.currentSessionId;
27
37
  });
@@ -35,6 +45,17 @@ export default function useChatController() {
35
45
  var currentQARef = useRef({
36
46
  activeRequestId: 0
37
47
  });
48
+ var _useState = useState([]),
49
+ _useState2 = _slicedToArray(_useState, 2),
50
+ inputQueue = _useState2[0],
51
+ setInputQueue = _useState2[1];
52
+ var inputQueueRef = useRef([]);
53
+ var drainTimerRef = useRef(null);
54
+ var drainingRef = useRef(false);
55
+ var drainQueueRef = useRef(null);
56
+ useEffect(function () {
57
+ inputQueueRef.current = inputQueue;
58
+ }, [inputQueue]);
38
59
 
39
60
  // Message handler
40
61
  var messageHandler = useChatMessageHandler({
@@ -47,6 +68,16 @@ export default function useChatController() {
47
68
  /**
48
69
  * Finalize the current response and reset UI loading state.
49
70
  */
71
+ var scheduleDrainQueue = useCallback(function () {
72
+ if (drainTimerRef.current) {
73
+ clearTimeout(drainTimerRef.current);
74
+ }
75
+ drainTimerRef.current = setTimeout(function () {
76
+ var _drainQueueRef$curren;
77
+ drainTimerRef.current = null;
78
+ void ((_drainQueueRef$curren = drainQueueRef.current) === null || _drainQueueRef$curren === void 0 ? void 0 : _drainQueueRef$curren.call(drainQueueRef));
79
+ }, 0);
80
+ }, []);
50
81
  var finishResponse = useCallback(function () {
51
82
  var status = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'finished';
52
83
  if (!currentQARef.current.response) return;
@@ -56,7 +87,8 @@ export default function useChatController() {
56
87
  messageHandler.updateMessage(currentQARef.current.response);
57
88
  });
58
89
  sessionHandler.syncSessionMessages(messageHandler.getMessages());
59
- }, [setLoading, messageHandler, sessionHandler]);
90
+ scheduleDrainQueue();
91
+ }, [setLoading, messageHandler, sessionHandler, scheduleDrainQueue]);
60
92
 
61
93
  // API request handling
62
94
  var _useChatRequest = useChatRequest({
@@ -73,7 +105,7 @@ export default function useChatController() {
73
105
  /**
74
106
  * Handle user message submission.
75
107
  */
76
- var handleSubmit = useCallback( /*#__PURE__*/function () {
108
+ var submitNow = useCallback( /*#__PURE__*/function () {
77
109
  var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(data) {
78
110
  var _currentQARef$current;
79
111
  var myRequestId, messages, historyMessages;
@@ -139,14 +171,102 @@ export default function useChatController() {
139
171
  return _ref.apply(this, arguments);
140
172
  };
141
173
  }(), [messageHandler, sessionHandler, request, setLoading]);
174
+ var enqueueInput = useCallback(function (data) {
175
+ var result = enqueueQueuedInput(inputQueueRef.current, data, {
176
+ maxSize: MAX_INPUT_QUEUE_SIZE
177
+ });
178
+ inputQueueRef.current = result.queue;
179
+ setInputQueue(result.queue);
180
+ }, []);
181
+ var drainQueue = useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2() {
182
+ var result, nextItem, restored;
183
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
184
+ while (1) switch (_context2.prev = _context2.next) {
185
+ case 0:
186
+ if (!(drainingRef.current || getLoading())) {
187
+ _context2.next = 2;
188
+ break;
189
+ }
190
+ return _context2.abrupt("return");
191
+ case 2:
192
+ result = dequeueNextQueuedInput(inputQueueRef.current);
193
+ nextItem = result.item;
194
+ if (nextItem) {
195
+ _context2.next = 6;
196
+ break;
197
+ }
198
+ return _context2.abrupt("return");
199
+ case 6:
200
+ inputQueueRef.current = result.queue;
201
+ setInputQueue(result.queue);
202
+ drainingRef.current = true;
203
+ _context2.prev = 9;
204
+ _context2.next = 12;
205
+ return submitNow(nextItem.data);
206
+ case 12:
207
+ _context2.next = 20;
208
+ break;
209
+ case 14:
210
+ _context2.prev = 14;
211
+ _context2.t0 = _context2["catch"](9);
212
+ setLoading(false);
213
+ restored = restoreFailedQueuedInput(inputQueueRef.current, nextItem, _context2.t0);
214
+ inputQueueRef.current = restored;
215
+ setInputQueue(restored);
216
+ case 20:
217
+ _context2.prev = 20;
218
+ drainingRef.current = false;
219
+ return _context2.finish(20);
220
+ case 23:
221
+ case "end":
222
+ return _context2.stop();
223
+ }
224
+ }, _callee2, null, [[9, 14, 20, 23]]);
225
+ })), [getLoading, setLoading, submitNow]);
226
+ useEffect(function () {
227
+ drainQueueRef.current = drainQueue;
228
+ }, [drainQueue]);
229
+ var handleSubmit = useCallback( /*#__PURE__*/function () {
230
+ var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(data) {
231
+ return _regeneratorRuntime().wrap(function _callee3$(_context3) {
232
+ while (1) switch (_context3.prev = _context3.next) {
233
+ case 0:
234
+ if (canSubmitDirectly({
235
+ loading: getLoading(),
236
+ queueLength: inputQueueRef.current.length,
237
+ draining: drainingRef.current
238
+ })) {
239
+ _context3.next = 3;
240
+ break;
241
+ }
242
+ enqueueInput(data);
243
+ return _context3.abrupt("return");
244
+ case 3:
245
+ _context3.next = 5;
246
+ return submitNow(data);
247
+ case 5:
248
+ case "end":
249
+ return _context3.stop();
250
+ }
251
+ }, _callee3);
252
+ }));
253
+ return function (_x2) {
254
+ return _ref3.apply(this, arguments);
255
+ };
256
+ }(), [enqueueInput, getLoading, submitNow]);
257
+ useEffect(function () {
258
+ if (!getLoading() && inputQueue.length > 0) {
259
+ scheduleDrainQueue();
260
+ }
261
+ }, [getLoading, inputQueue.length, scheduleDrainQueue]);
142
262
  var handleApproval = useCallback( /*#__PURE__*/function () {
143
- var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(_ref2) {
263
+ var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(_ref4) {
144
264
  var _currentQARef$current2;
145
265
  var input, myRequestId, historyMessages;
146
- return _regeneratorRuntime().wrap(function _callee2$(_context2) {
147
- while (1) switch (_context2.prev = _context2.next) {
266
+ return _regeneratorRuntime().wrap(function _callee4$(_context4) {
267
+ while (1) switch (_context4.prev = _context4.next) {
148
268
  case 0:
149
- input = _ref2.input;
269
+ input = _ref4.input;
150
270
  (_currentQARef$current2 = currentQARef.current.abortController) === null || _currentQARef$current2 === void 0 || _currentQARef$current2.abort();
151
271
  // Snapshot the current session id BEFORE bumping requestId, then bump.
152
272
  // Order matches handleSubmit so a concurrent session-change effect cannot
@@ -155,30 +275,30 @@ export default function useChatController() {
155
275
  myRequestId = ++currentQARef.current.activeRequestId;
156
276
  messageHandler.createApprovalMessage(input);
157
277
  setLoading(true);
158
- _context2.next = 8;
278
+ _context4.next = 8;
159
279
  return sleep(100);
160
280
  case 8:
161
281
  if (!(myRequestId !== currentQARef.current.activeRequestId)) {
162
- _context2.next = 10;
282
+ _context4.next = 10;
163
283
  break;
164
284
  }
165
- return _context2.abrupt("return");
285
+ return _context4.abrupt("return");
166
286
  case 10:
167
287
  messageHandler.createResponseMessage();
168
288
  historyMessages = messageHandler.getHistoryMessages();
169
- _context2.next = 14;
289
+ _context4.next = 14;
170
290
  return sessionHandler.syncSessionMessages(messageHandler.getMessages());
171
291
  case 14:
172
- _context2.next = 16;
292
+ _context4.next = 16;
173
293
  return request(historyMessages, undefined, myRequestId);
174
294
  case 16:
175
295
  case "end":
176
- return _context2.stop();
296
+ return _context4.stop();
177
297
  }
178
- }, _callee2);
298
+ }, _callee4);
179
299
  }));
180
- return function (_x2) {
181
- return _ref3.apply(this, arguments);
300
+ return function (_x3) {
301
+ return _ref5.apply(this, arguments);
182
302
  };
183
303
  }(), [messageHandler, sessionHandler, request, setLoading]);
184
304
 
@@ -222,11 +342,11 @@ export default function useChatController() {
222
342
  * Handle regenerate (retry the last assistant response).
223
343
  */
224
344
  var handleRegenerate = useCallback( /*#__PURE__*/function () {
225
- var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(messageId) {
345
+ var _ref6 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(messageId) {
226
346
  var _currentQARef$current4;
227
347
  var myRequestId, historyMessages;
228
- return _regeneratorRuntime().wrap(function _callee3$(_context3) {
229
- while (1) switch (_context3.prev = _context3.next) {
348
+ return _regeneratorRuntime().wrap(function _callee5$(_context5) {
349
+ while (1) switch (_context5.prev = _context5.next) {
230
350
  case 0:
231
351
  (_currentQARef$current4 = currentQARef.current.abortController) === null || _currentQARef$current4 === void 0 || _currentQARef$current4.abort();
232
352
  currentQARef.current.activeSessionId = sessionHandler.getCurrentSessionId();
@@ -242,16 +362,16 @@ export default function useChatController() {
242
362
 
243
363
  // 3. Fire the request
244
364
  historyMessages = messageHandler.getHistoryMessages();
245
- _context3.next = 10;
365
+ _context5.next = 10;
246
366
  return request(historyMessages, undefined, myRequestId);
247
367
  case 10:
248
368
  case "end":
249
- return _context3.stop();
369
+ return _context5.stop();
250
370
  }
251
- }, _callee3);
371
+ }, _callee5);
252
372
  }));
253
- return function (_x3) {
254
- return _ref4.apply(this, arguments);
373
+ return function (_x4) {
374
+ return _ref6.apply(this, arguments);
255
375
  };
256
376
  }(), [messageHandler, request, sessionHandler, setLoading]);
257
377
 
@@ -261,11 +381,11 @@ export default function useChatController() {
261
381
  * treat it as idle: remove the empty placeholder and reset loading.
262
382
  */
263
383
  var handleReconnect = useCallback( /*#__PURE__*/function () {
264
- var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(sessionId) {
384
+ var _ref7 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(sessionId) {
265
385
  var _currentQARef$current5, _currentQARef$current6;
266
386
  var myRequestId, _currentQARef$current7;
267
- return _regeneratorRuntime().wrap(function _callee4$(_context4) {
268
- while (1) switch (_context4.prev = _context4.next) {
387
+ return _regeneratorRuntime().wrap(function _callee6$(_context6) {
388
+ while (1) switch (_context6.prev = _context6.next) {
269
389
  case 0:
270
390
  (_currentQARef$current5 = currentQARef.current.abortController) === null || _currentQARef$current5 === void 0 || _currentQARef$current5.abort();
271
391
  currentQARef.current.abortController = new AbortController();
@@ -273,14 +393,14 @@ export default function useChatController() {
273
393
  currentQARef.current.activeSessionId = sessionId;
274
394
  setLoading(true);
275
395
  messageHandler.createResponseMessage();
276
- _context4.next = 8;
396
+ _context6.next = 8;
277
397
  return reconnect(sessionId, myRequestId);
278
398
  case 8:
279
399
  if (!(myRequestId !== currentQARef.current.activeRequestId)) {
280
- _context4.next = 10;
400
+ _context6.next = 10;
281
401
  break;
282
402
  }
283
- return _context4.abrupt("return");
403
+ return _context6.abrupt("return");
284
404
  case 10:
285
405
  // If the response is still in 'generating' state after reconnect completes,
286
406
  // onFinish() was never called (no response body, or stream closed without a completion event).
@@ -296,12 +416,12 @@ export default function useChatController() {
296
416
  }
297
417
  case 11:
298
418
  case "end":
299
- return _context4.stop();
419
+ return _context6.stop();
300
420
  }
301
- }, _callee4);
421
+ }, _callee6);
302
422
  }));
303
- return function (_x4) {
304
- return _ref5.apply(this, arguments);
423
+ return function (_x5) {
424
+ return _ref7.apply(this, arguments);
305
425
  };
306
426
  }(), [messageHandler, reconnect, setLoading]);
307
427
 
@@ -333,6 +453,10 @@ export default function useChatController() {
333
453
  };
334
454
  return function () {
335
455
  var _currentQARef$current9;
456
+ if (drainTimerRef.current) {
457
+ clearTimeout(drainTimerRef.current);
458
+ drainTimerRef.current = null;
459
+ }
336
460
  (_currentQARef$current9 = currentQARef.current.abortController) === null || _currentQARef$current9 === void 0 || _currentQARef$current9.abort();
337
461
  currentQARef.current.activeRequestId += 1;
338
462
  };
@@ -342,19 +466,19 @@ export default function useChatController() {
342
466
  useChatAnywhereEventEmitter({
343
467
  type: 'handleReconnect',
344
468
  callback: function () {
345
- var _callback = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(data) {
346
- return _regeneratorRuntime().wrap(function _callee5$(_context5) {
347
- while (1) switch (_context5.prev = _context5.next) {
469
+ var _callback = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7(data) {
470
+ return _regeneratorRuntime().wrap(function _callee7$(_context7) {
471
+ while (1) switch (_context7.prev = _context7.next) {
348
472
  case 0:
349
- _context5.next = 2;
473
+ _context7.next = 2;
350
474
  return handleReconnect(data.detail.session_id);
351
475
  case 2:
352
476
  case "end":
353
- return _context5.stop();
477
+ return _context7.stop();
354
478
  }
355
- }, _callee5);
479
+ }, _callee7);
356
480
  }));
357
- function callback(_x5) {
481
+ function callback(_x6) {
358
482
  return _callback.apply(this, arguments);
359
483
  }
360
484
  return callback;
@@ -365,19 +489,19 @@ export default function useChatController() {
365
489
  useChatAnywhereEventEmitter({
366
490
  type: 'handleReplace',
367
491
  callback: function () {
368
- var _callback2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(data) {
369
- return _regeneratorRuntime().wrap(function _callee6$(_context6) {
370
- while (1) switch (_context6.prev = _context6.next) {
492
+ var _callback2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee8(data) {
493
+ return _regeneratorRuntime().wrap(function _callee8$(_context8) {
494
+ while (1) switch (_context8.prev = _context8.next) {
371
495
  case 0:
372
- _context6.next = 2;
496
+ _context8.next = 2;
373
497
  return handleRegenerate(data.detail.id);
374
498
  case 2:
375
499
  case "end":
376
- return _context6.stop();
500
+ return _context8.stop();
377
501
  }
378
- }, _callee6);
502
+ }, _callee8);
379
503
  }));
380
- function callback(_x6) {
504
+ function callback(_x7) {
381
505
  return _callback2.apply(this, arguments);
382
506
  }
383
507
  return callback;
@@ -386,19 +510,19 @@ export default function useChatController() {
386
510
  useChatAnywhereEventEmitter({
387
511
  type: 'handleSubmit',
388
512
  callback: function () {
389
- var _callback3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7(data) {
390
- return _regeneratorRuntime().wrap(function _callee7$(_context7) {
391
- while (1) switch (_context7.prev = _context7.next) {
513
+ var _callback3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee9(data) {
514
+ return _regeneratorRuntime().wrap(function _callee9$(_context9) {
515
+ while (1) switch (_context9.prev = _context9.next) {
392
516
  case 0:
393
- _context7.next = 2;
517
+ _context9.next = 2;
394
518
  return handleSubmit(data.detail);
395
519
  case 2:
396
520
  case "end":
397
- return _context7.stop();
521
+ return _context9.stop();
398
522
  }
399
- }, _callee7);
523
+ }, _callee9);
400
524
  }));
401
- function callback(_x7) {
525
+ function callback(_x8) {
402
526
  return _callback3.apply(this, arguments);
403
527
  }
404
528
  return callback;
@@ -407,19 +531,19 @@ export default function useChatController() {
407
531
  useChatAnywhereEventEmitter({
408
532
  type: 'handleApproval',
409
533
  callback: function () {
410
- var _callback4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee8(data) {
411
- return _regeneratorRuntime().wrap(function _callee8$(_context8) {
412
- while (1) switch (_context8.prev = _context8.next) {
534
+ var _callback4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee10(data) {
535
+ return _regeneratorRuntime().wrap(function _callee10$(_context10) {
536
+ while (1) switch (_context10.prev = _context10.next) {
413
537
  case 0:
414
- _context8.next = 2;
538
+ _context10.next = 2;
415
539
  return handleApproval(data.detail);
416
540
  case 2:
417
541
  case "end":
418
- return _context8.stop();
542
+ return _context10.stop();
419
543
  }
420
- }, _callee8);
544
+ }, _callee10);
421
545
  }));
422
- function callback(_x8) {
546
+ function callback(_x9) {
423
547
  return _callback4.apply(this, arguments);
424
548
  }
425
549
  return callback;
@@ -427,6 +551,23 @@ export default function useChatController() {
427
551
  }, [handleApproval]);
428
552
  return {
429
553
  handleSubmit: handleSubmit,
430
- handleCancel: handleCancel
554
+ handleCancel: handleCancel,
555
+ inputQueue: inputQueue,
556
+ enqueueQueuedInput: enqueueInput,
557
+ removeQueuedInput: function removeQueuedInput(id) {
558
+ var next = _removeQueuedInput(inputQueueRef.current, id);
559
+ inputQueueRef.current = next;
560
+ setInputQueue(next);
561
+ },
562
+ clearQueuedInputs: function clearQueuedInputs() {
563
+ inputQueueRef.current = [];
564
+ setInputQueue([]);
565
+ },
566
+ retryQueuedInput: function retryQueuedInput(id) {
567
+ var next = _retryQueuedInput(inputQueueRef.current, id);
568
+ inputQueueRef.current = next;
569
+ setInputQueue(next);
570
+ scheduleDrainQueue();
571
+ }
431
572
  };
432
573
  }
@@ -11,7 +11,12 @@ export default function Chat() {
11
11
  var prefixCls = useProviderContext().getPrefixCls('chat-anywhere-chat');
12
12
  var _useChatController = useChatController(),
13
13
  handleSubmit = _useChatController.handleSubmit,
14
- handleCancel = _useChatController.handleCancel;
14
+ handleCancel = _useChatController.handleCancel,
15
+ inputQueue = _useChatController.inputQueue,
16
+ enqueueQueuedInput = _useChatController.enqueueQueuedInput,
17
+ removeQueuedInput = _useChatController.removeQueuedInput,
18
+ clearQueuedInputs = _useChatController.clearQueuedInputs,
19
+ retryQueuedInput = _useChatController.retryQueuedInput;
15
20
  useChatAnywhereSessionLoader();
16
21
  return /*#__PURE__*/_jsxs(_Fragment, {
17
22
  children: [/*#__PURE__*/_jsx(Style, {}), /*#__PURE__*/_jsxs("div", {
@@ -20,7 +25,14 @@ export default function Chat() {
20
25
  onSubmit: handleSubmit
21
26
  }), /*#__PURE__*/_jsx(Input, {
22
27
  onCancel: handleCancel,
23
- onSubmit: handleSubmit
28
+ onSubmit: handleSubmit,
29
+ queue: {
30
+ items: inputQueue,
31
+ onEnqueue: enqueueQueuedInput,
32
+ onRemove: removeQueuedInput,
33
+ onClear: clearQueuedInputs,
34
+ onRetry: retryQueuedInput
35
+ }
24
36
  })]
25
37
  })]
26
38
  });
@@ -1,7 +1,7 @@
1
1
  var _templateObject;
2
2
  function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
3
3
  import { createGlobalStyle } from 'antd-style';
4
- export default createGlobalStyle(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n.", "-chat-anywhere-chat {\n display: flex;\n flex-direction: column;\n height: 100%;\n align-items: stretch;\n}\n\n.", "-chat-anywhere-message-list {\n flex: 1;\n height: 0;\n\n &-welcome {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n }\n}\n\n\n\n.", "-chat-anywhere-message-list .", "-bubble-list-scroll::-webkit-scrollbar {\n display: none;\n}\n\n@keyframes message-list-fade-in {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n.", "-chat-anywhere-message-list .", "-bubble-list-wrapper {\n animation: message-list-fade-in 0.4s ease-in-out;\n}\n\n.", "-chat-anywhere-message-list .", "-bubble-list {\n margin: 0 auto;\n max-width: 850px;\n min-width: 300px;\n}\n\n.", "-chat-anywhere-input {\n padding: 0 16px;\n}\n\n.", "-chat-anywhere-input-wrapper {\n max-width: 850px;\n min-width: 300px;\n margin: 0 auto;\n}\n.", "-chat-anywhere-input-blank {\n height: 16px;\n"])), function (p) {
4
+ export default createGlobalStyle(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n.", "-chat-anywhere-chat {\n display: flex;\n flex-direction: column;\n height: 100%;\n align-items: stretch;\n}\n\n.", "-chat-anywhere-message-list {\n flex: 1;\n height: 0;\n\n &-welcome {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n }\n}\n\n\n\n.", "-chat-anywhere-message-list .", "-bubble-list-scroll::-webkit-scrollbar {\n display: none;\n}\n\n@keyframes message-list-fade-in {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n.", "-chat-anywhere-message-list .", "-bubble-list-wrapper {\n animation: message-list-fade-in 0.4s ease-in-out;\n}\n\n.", "-chat-anywhere-message-list .", "-bubble-list {\n margin: 0 auto;\n max-width: 850px;\n min-width: 300px;\n}\n\n.", "-chat-anywhere-input {\n padding: 0 16px;\n}\n\n.", "-chat-anywhere-input-wrapper {\n max-width: 850px;\n min-width: 300px;\n margin: 0 auto;\n}\n\n.", "-chat-anywhere-input-queue {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-bottom: 8px;\n padding: 8px;\n border: 1px solid ", ";\n border-radius: 8px;\n background: ", ";\n}\n\n.", "-chat-anywhere-input-queue-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n color: ", ";\n font-size: 12px;\n line-height: 20px;\n}\n\n.", "-chat-anywhere-input-queue-list {\n display: flex;\n max-height: 180px;\n flex-direction: column;\n gap: 4px;\n overflow-y: auto;\n}\n\n.", "-chat-anywhere-input-queue-item {\n display: grid;\n grid-template-columns: 20px minmax(0, 1fr) auto auto;\n align-items: center;\n gap: 6px;\n min-height: 32px;\n padding: 4px 6px;\n border-radius: 6px;\n background: ", ";\n}\n\n.", "-chat-anywhere-input-queue-index {\n color: ", ";\n font-size: 12px;\n text-align: center;\n}\n\n.", "-chat-anywhere-input-queue-content {\n min-width: 0;\n}\n\n.", "-chat-anywhere-input-queue-text {\n overflow: hidden;\n color: ", ";\n font-size: 12px;\n line-height: 18px;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.", "-chat-anywhere-input-queue-error {\n overflow: hidden;\n color: ", ";\n font-size: 11px;\n line-height: 16px;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.", "-chat-anywhere-input-blank {\n height: 16px;\n"])), function (p) {
5
5
  return p.theme.prefixCls;
6
6
  }, function (p) {
7
7
  return p.theme.prefixCls;
@@ -23,4 +23,34 @@ export default createGlobalStyle(_templateObject || (_templateObject = _taggedTe
23
23
  return p.theme.prefixCls;
24
24
  }, function (p) {
25
25
  return p.theme.prefixCls;
26
+ }, function (p) {
27
+ return p.theme.colorBorderSecondary;
28
+ }, function (p) {
29
+ return p.theme.colorFillTertiary;
30
+ }, function (p) {
31
+ return p.theme.prefixCls;
32
+ }, function (p) {
33
+ return p.theme.colorTextSecondary;
34
+ }, function (p) {
35
+ return p.theme.prefixCls;
36
+ }, function (p) {
37
+ return p.theme.prefixCls;
38
+ }, function (p) {
39
+ return p.theme.colorBgContainer;
40
+ }, function (p) {
41
+ return p.theme.prefixCls;
42
+ }, function (p) {
43
+ return p.theme.colorTextQuaternary;
44
+ }, function (p) {
45
+ return p.theme.prefixCls;
46
+ }, function (p) {
47
+ return p.theme.prefixCls;
48
+ }, function (p) {
49
+ return p.theme.colorText;
50
+ }, function (p) {
51
+ return p.theme.prefixCls;
52
+ }, function (p) {
53
+ return p.theme.colorError;
54
+ }, function (p) {
55
+ return p.theme.prefixCls;
26
56
  });
@@ -25,6 +25,11 @@ declare const messages: {
25
25
  'common.loading': string;
26
26
  'common.saveSuccess': string;
27
27
  'common.saveFailed': string;
28
+ 'queue.title': string;
29
+ 'queue.clear': string;
30
+ 'queue.retry': string;
31
+ 'queue.failed': string;
32
+ 'queue.attachmentOnly': string;
28
33
  'actions.regenerate': string;
29
34
  'messageImport.title': string;
30
35
  'messageImport.placeholder': string;
@@ -54,6 +59,11 @@ declare const messages: {
54
59
  'common.loading': string;
55
60
  'common.saveSuccess': string;
56
61
  'common.saveFailed': string;
62
+ 'queue.title': string;
63
+ 'queue.clear': string;
64
+ 'queue.retry': string;
65
+ 'queue.failed': string;
66
+ 'queue.attachmentOnly': string;
57
67
  'actions.regenerate': string;
58
68
  'messageImport.title': string;
59
69
  'messageImport.placeholder': string;
@@ -71,7 +81,7 @@ export interface I18nContextValue {
71
81
  declare const ChatAnywhereI18nContext: import("use-context-selector").Context<I18nContextValue>;
72
82
  export declare function useChatAnywhereI18n<Selected>(selector: (value: I18nContextValue) => Selected): Selected;
73
83
  export declare function useTranslation(): {
74
- t: (key: "approval.title" | "approval.pending" | "approval.confirmed" | "approval.canceled" | "approval.cancel" | "approval.confirm" | "approval.taskRunning" | "cancelPopover.title" | "cancelPopover.placeholder" | "cancelPopover.cancel" | "cancelPopover.confirm" | "cancelPopover.options.notNeeded" | "cancelPopover.options.poorResult" | "cancelPopover.options.tooSlow" | "cancelPopover.options.wrongInput" | "common.save" | "common.cancel" | "common.confirm" | "common.delete" | "common.edit" | "common.loading" | "common.saveSuccess" | "common.saveFailed" | "actions.regenerate" | "messageImport.title" | "messageImport.placeholder" | "messageImport.saveToLocalStorage", params?: Record<string, string | number>) => string;
84
+ t: (key: "approval.title" | "approval.pending" | "approval.confirmed" | "approval.canceled" | "approval.cancel" | "approval.confirm" | "approval.taskRunning" | "cancelPopover.title" | "cancelPopover.placeholder" | "cancelPopover.cancel" | "cancelPopover.confirm" | "cancelPopover.options.notNeeded" | "cancelPopover.options.poorResult" | "cancelPopover.options.tooSlow" | "cancelPopover.options.wrongInput" | "common.save" | "common.cancel" | "common.confirm" | "common.delete" | "common.edit" | "common.loading" | "common.saveSuccess" | "common.saveFailed" | "queue.title" | "queue.clear" | "queue.retry" | "queue.failed" | "queue.attachmentOnly" | "actions.regenerate" | "messageImport.title" | "messageImport.placeholder" | "messageImport.saveToLocalStorage", params?: Record<string, string | number>) => string;
75
85
  locale: Locale;
76
86
  setLocale: (locale: Locale) => void;
77
87
  };
@@ -36,6 +36,12 @@ var messages = {
36
36
  'common.loading': '加载中...',
37
37
  'common.saveSuccess': '保存成功',
38
38
  'common.saveFailed': '保存失败',
39
+ // Queue 相关
40
+ 'queue.title': '待发送队列',
41
+ 'queue.clear': '清空队列',
42
+ 'queue.retry': '重试发送',
43
+ 'queue.failed': '发送失败',
44
+ 'queue.attachmentOnly': '附件消息',
39
45
  // Actions 相关
40
46
  'actions.regenerate': '重新生成',
41
47
  // MessageImport 相关
@@ -70,6 +76,12 @@ var messages = {
70
76
  'common.loading': 'Loading...',
71
77
  'common.saveSuccess': 'Saved successfully',
72
78
  'common.saveFailed': 'Failed to save',
79
+ // Queue related
80
+ 'queue.title': 'Queued inputs',
81
+ 'queue.clear': 'Clear queue',
82
+ 'queue.retry': 'Retry',
83
+ 'queue.failed': 'Failed to send',
84
+ 'queue.attachmentOnly': 'Attachment message',
73
85
  // Actions related
74
86
  'actions.regenerate': 'Regenerate',
75
87
  // MessageImport related