@blueking/chat-helper 0.0.12-beta.1 → 0.0.12-beta.11

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.
@@ -80,9 +80,38 @@ function _object_spread(target) {
80
80
  return target;
81
81
  }
82
82
  import { ref } from 'vue';
83
- import { AGUIProtocol } from '../event/index.ts.js';
84
- import { MessageRole, MessageStatus } from '../message/index.ts.js';
83
+ import { AGUIProtocol, ApprovalInterruptTicketStatus, EventType, ResumeStatus, RunFinishedOutcomeType } from '../event/index.ts.js';
84
+ import { MessageRole, MessageStatus, UserOperation } from '../message/index.ts.js';
85
85
  import { SessionStatus } from '../session/type.ts.js';
86
+ /** SSE 静默重连最大次数(退避总时长约 23s,落在后端 orphan grace ~30s 内) */ const MAX_RECONNECT_ATTEMPTS = 5;
87
+ const RECONNECT_BASE_DELAY_MS = 1000;
88
+ const RECONNECT_MAX_DELAY_MS = 8000;
89
+ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.pow(2, attempt - 1), RECONNECT_MAX_DELAY_MS);
90
+ /**
91
+ * 判断流式错误是否可静默重连。
92
+ * 不重试:Abort、401/403 等业务 4xx(408/429 除外);可重试:网络错误、5xx、无状态码的中断。
93
+ */ const isRecoverableStreamError = (error)=>{
94
+ var _requestError_response;
95
+ if (error.name === 'AbortError') {
96
+ return false;
97
+ }
98
+ const requestError = error;
99
+ const statusFromResponse = (_requestError_response = requestError.response) === null || _requestError_response === void 0 ? void 0 : _requestError_response.status;
100
+ const statusFromMessage = error.message.match(/status code (\d+)/i);
101
+ const status = statusFromResponse !== null && statusFromResponse !== void 0 ? statusFromResponse : statusFromMessage ? Number(statusFromMessage[1]) : undefined;
102
+ if (status !== undefined) {
103
+ if (status === 408 || status === 429) {
104
+ return true;
105
+ }
106
+ if (status >= 400 && status < 500) {
107
+ return false;
108
+ }
109
+ if (status >= 500) {
110
+ return true;
111
+ }
112
+ }
113
+ return true;
114
+ };
86
115
  /**
87
116
  * Agent 模块
88
117
  * @param options - 配置选项
@@ -92,7 +121,15 @@ import { SessionStatus } from '../session/type.ts.js';
92
121
  const isInfoLoading = ref(false);
93
122
  const isChatting = ref(false);
94
123
  let usedProtocol = protocol || new AGUIProtocol();
95
- let abortController = null;
124
+ let chatAbortController = null;
125
+ let resumeAbortController = null;
126
+ let longPollTimer = null;
127
+ /** 用户主动中止(abortChat),禁止自动重连 */ let manualAbort = false;
128
+ /** 当前轮次已静默重连次数 */ let reconnectAttempt = 0;
129
+ /** 本轮流是否已收到 RUN_FINISHED */ let runFinished = false;
130
+ let reconnectTimer = null;
131
+ let reconnectWaitResolve = null;
132
+ let activeStreamContext = null;
96
133
  const getAgentInfo = ()=>{
97
134
  var _mediator_http;
98
135
  isInfoLoading.value = true;
@@ -121,27 +158,221 @@ import { SessionStatus } from '../session/type.ts.js';
121
158
  });
122
159
  }
123
160
  };
161
+ const userOperationStreamRequest = (sessionCode, operation, payload, config)=>{
162
+ var _mediator_http;
163
+ return (_mediator_http = mediator.http) === null || _mediator_http === void 0 ? void 0 : _mediator_http.message.userOperation(sessionCode, operation, payload, config).then(()=>{
164
+ if (operation !== UserOperation.ApprovalCancel) {
165
+ streamRequest({
166
+ sessionCode,
167
+ config
168
+ });
169
+ } else {
170
+ clearLongPollTimer();
171
+ pollResumeSession(sessionCode);
172
+ }
173
+ });
174
+ };
175
+ const clearReconnectTimer = (continued = false)=>{
176
+ if (reconnectTimer) {
177
+ clearTimeout(reconnectTimer);
178
+ reconnectTimer = null;
179
+ }
180
+ if (reconnectWaitResolve) {
181
+ const resolve = reconnectWaitResolve;
182
+ reconnectWaitResolve = null;
183
+ resolve(continued);
184
+ }
185
+ };
186
+ const waitForReconnectDelay = (ms)=>new Promise((resolve)=>{
187
+ reconnectWaitResolve = resolve;
188
+ reconnectTimer = setTimeout(()=>{
189
+ reconnectTimer = null;
190
+ reconnectWaitResolve = null;
191
+ resolve(true);
192
+ }, ms);
193
+ });
194
+ const resetStreamReconnectState = ()=>{
195
+ manualAbort = false;
196
+ reconnectAttempt = 0;
197
+ runFinished = false;
198
+ clearReconnectTimer(false);
199
+ };
200
+ /** 裁掉尾部尚未完成的非用户消息,避免 DLQ 重放时重复气泡 */ const pruneTrailingIncompleteMessages = ()=>{
201
+ var _mediator_message;
202
+ const list = (_mediator_message = mediator.message) === null || _mediator_message === void 0 ? void 0 : _mediator_message.list.value;
203
+ if (!(list === null || list === void 0 ? void 0 : list.length)) {
204
+ return;
205
+ }
206
+ while(list.length > 0){
207
+ const last = list[list.length - 1];
208
+ if (last.role === MessageRole.User) {
209
+ break;
210
+ }
211
+ if (last.status === MessageStatus.Streaming || last.status === MessageStatus.Pending) {
212
+ list.pop();
213
+ continue;
214
+ }
215
+ break;
216
+ }
217
+ };
218
+ const isSameActiveSession = (sessionCode)=>{
219
+ var _mediator_session_current_value, _mediator_session_current, _mediator_session;
220
+ return sessionCode === ((_mediator_session = mediator.session) === null || _mediator_session === void 0 ? void 0 : (_mediator_session_current = _mediator_session.current) === null || _mediator_session_current === void 0 ? void 0 : (_mediator_session_current_value = _mediator_session_current.value) === null || _mediator_session_current_value === void 0 ? void 0 : _mediator_session_current_value.sessionCode);
221
+ };
222
+ /**
223
+ * 尝试静默重连。
224
+ * @returns reconnected | finished(服务端已结束)| failed(需对外报错或中止)
225
+ */ const attemptSilentReconnect = function() {
226
+ var _ref = _async_to_generator(function*(sessionCode) {
227
+ var _mediator_session_current_value, _mediator_session, _mediator_session_current_value1, _mediator_session1, _mediator_message_list_value_at, _mediator_message;
228
+ if (manualAbort || !isSameActiveSession(sessionCode)) {
229
+ return 'failed';
230
+ }
231
+ try {
232
+ var _mediator_session2;
233
+ yield (_mediator_session2 = mediator.session) === null || _mediator_session2 === void 0 ? void 0 : _mediator_session2.getSession(sessionCode);
234
+ } catch (e) {
235
+ // 状态刷新失败时沿用本地 session.status
236
+ }
237
+ if (manualAbort || !isSameActiveSession(sessionCode)) {
238
+ return 'failed';
239
+ }
240
+ if (((_mediator_session = mediator.session) === null || _mediator_session === void 0 ? void 0 : (_mediator_session_current_value = _mediator_session.current.value) === null || _mediator_session_current_value === void 0 ? void 0 : _mediator_session_current_value.status) !== SessionStatus.Running) {
241
+ return 'finished';
242
+ }
243
+ if (reconnectAttempt >= MAX_RECONNECT_ATTEMPTS) {
244
+ return 'failed';
245
+ }
246
+ reconnectAttempt += 1;
247
+ // 静默重连期间保持「生成中」态
248
+ isChatting.value = true;
249
+ const delayMs = getReconnectDelayMs(reconnectAttempt);
250
+ const waited = yield waitForReconnectDelay(delayMs);
251
+ if (!waited || manualAbort || !isSameActiveSession(sessionCode)) {
252
+ return 'failed';
253
+ }
254
+ if (((_mediator_session1 = mediator.session) === null || _mediator_session1 === void 0 ? void 0 : (_mediator_session_current_value1 = _mediator_session1.current.value) === null || _mediator_session_current_value1 === void 0 ? void 0 : _mediator_session_current_value1.status) !== SessionStatus.Running) {
255
+ return 'finished';
256
+ }
257
+ pruneTrailingIncompleteMessages();
258
+ const lastMessageId = (_mediator_message = mediator.message) === null || _mediator_message === void 0 ? void 0 : (_mediator_message_list_value_at = _mediator_message.list.value.at(-1)) === null || _mediator_message_list_value_at === void 0 ? void 0 : _mediator_message_list_value_at.id;
259
+ const ctx = activeStreamContext;
260
+ streamRequest({
261
+ sessionCode,
262
+ url: ctx === null || ctx === void 0 ? void 0 : ctx.url,
263
+ config: ctx === null || ctx === void 0 ? void 0 : ctx.config,
264
+ lastMessageId: lastMessageId !== undefined ? String(lastMessageId) : undefined,
265
+ isReconnect: true
266
+ });
267
+ return 'reconnected';
268
+ });
269
+ return function attemptSilentReconnect(sessionCode) {
270
+ return _ref.apply(this, arguments);
271
+ };
272
+ }();
124
273
  const streamRequest = function() {
125
- var _ref = _async_to_generator(function*(sessionCode, url, config) {
126
- var // 发起聊天
127
- _mediator_http;
274
+ var _ref = _async_to_generator(function*({ sessionCode, url, config, resume, input, lastMessageId, isReconnect = false }) {
275
+ var _mediator_http;
276
+ if (!isReconnect) {
277
+ resetStreamReconnectState();
278
+ }
279
+ activeStreamContext = {
280
+ sessionCode,
281
+ url,
282
+ config
283
+ };
128
284
  // ag-ui 协议需要注入消息模块
129
285
  if (usedProtocol instanceof AGUIProtocol) {
130
286
  usedProtocol.injectMessageModule(mediator.message);
131
287
  }
132
- // 事件代理
133
- const onDone = ()=>{
288
+ if (input) {
289
+ var // 列表新增一个用户消息
290
+ _mediator_message;
291
+ (_mediator_message = mediator.message) === null || _mediator_message === void 0 ? void 0 : _mediator_message.list.value.push({
292
+ role: MessageRole.User,
293
+ content: input,
294
+ status: MessageStatus.Complete,
295
+ sessionCode
296
+ });
297
+ }
298
+ const finishSuccessfully = ()=>{
134
299
  var _usedProtocol_onDone;
135
300
  isChatting.value = false;
136
301
  (_usedProtocol_onDone = usedProtocol.onDone) === null || _usedProtocol_onDone === void 0 ? void 0 : _usedProtocol_onDone.call(usedProtocol);
302
+ if (input) {
303
+ var // 刷新列表,获取前端 mock message 的 id,并更新到列表中
304
+ _mediator_http_message, _mediator_http;
305
+ (_mediator_http = mediator.http) === null || _mediator_http === void 0 ? void 0 : (_mediator_http_message = _mediator_http.message) === null || _mediator_http_message === void 0 ? void 0 : _mediator_http_message.getMessages(sessionCode).then((res)=>{
306
+ var _mediator_message;
307
+ const lastUserMessage = (_mediator_message = mediator.message) === null || _mediator_message === void 0 ? void 0 : _mediator_message.list.value.findLast((item)=>item.role === MessageRole.User);
308
+ const lastApiUserMessage = res.findLast((item)=>item.role === MessageRole.User);
309
+ if (lastUserMessage && lastApiUserMessage) {
310
+ lastUserMessage.id = lastApiUserMessage.id;
311
+ }
312
+ });
313
+ }
314
+ // 轮询接口,判断是否可以继续聊天
315
+ pollResumeSession(sessionCode);
137
316
  };
138
- const onError = (error)=>{
317
+ const failWithError = (error)=>{
139
318
  var _usedProtocol_onError;
140
319
  isChatting.value = false;
141
320
  (_usedProtocol_onError = usedProtocol.onError) === null || _usedProtocol_onError === void 0 ? void 0 : _usedProtocol_onError.call(usedProtocol, error);
142
321
  };
322
+ // 事件代理
323
+ const onDone = ()=>{
324
+ // 用户 abort:FetchClient 将 AbortError 转为 onDone,不重连
325
+ if (manualAbort || runFinished) {
326
+ finishSuccessfully();
327
+ return;
328
+ }
329
+ // 连接被干净掐断且未收到 RUN_FINISHED:尝试静默重连
330
+ void attemptSilentReconnect(sessionCode).then((result)=>{
331
+ if (result === 'reconnected') {
332
+ // 保持 isChatting=true,不展示错误
333
+ return;
334
+ }
335
+ if (result === 'finished') {
336
+ finishSuccessfully();
337
+ return;
338
+ }
339
+ // abort / 切会话导致的失败:静默结束,不展示错误气泡
340
+ if (manualAbort || !isSameActiveSession(sessionCode)) {
341
+ isChatting.value = false;
342
+ return;
343
+ }
344
+ failWithError(new Error('Connection lost, please try again'));
345
+ });
346
+ };
347
+ const onError = (error)=>{
348
+ if (manualAbort) {
349
+ return;
350
+ }
351
+ if (!isRecoverableStreamError(error)) {
352
+ failWithError(error);
353
+ return;
354
+ }
355
+ void attemptSilentReconnect(sessionCode).then((result)=>{
356
+ if (result === 'reconnected') {
357
+ return;
358
+ }
359
+ if (result === 'finished') {
360
+ finishSuccessfully();
361
+ return;
362
+ }
363
+ if (manualAbort || !isSameActiveSession(sessionCode)) {
364
+ isChatting.value = false;
365
+ return;
366
+ }
367
+ failWithError(error);
368
+ });
369
+ };
143
370
  const onMessage = (event)=>{
144
371
  var _usedProtocol_onMessage;
372
+ const typedEvent = event;
373
+ if ((typedEvent === null || typedEvent === void 0 ? void 0 : typedEvent.type) === EventType.RunFinished) {
374
+ runFinished = true;
375
+ }
145
376
  (_usedProtocol_onMessage = usedProtocol.onMessage) === null || _usedProtocol_onMessage === void 0 ? void 0 : _usedProtocol_onMessage.call(usedProtocol, event);
146
377
  };
147
378
  const onStart = ()=>{
@@ -150,24 +381,31 @@ import { SessionStatus } from '../session/type.ts.js';
150
381
  (_usedProtocol_onStart = usedProtocol.onStart) === null || _usedProtocol_onStart === void 0 ? void 0 : _usedProtocol_onStart.call(usedProtocol);
151
382
  };
152
383
  // 创建 AbortController
153
- abortController = new AbortController();
154
- (_mediator_http = mediator.http) === null || _mediator_http === void 0 ? void 0 : _mediator_http.fetchClient.streamRequest(_object_spread({
384
+ chatAbortController = new AbortController();
385
+ // 发起聊天
386
+ void ((_mediator_http = mediator.http) === null || _mediator_http === void 0 ? void 0 : _mediator_http.fetchClient.streamRequest(_object_spread({
155
387
  url: url || 'chat_completion/',
156
388
  method: 'POST',
157
389
  data: {
158
390
  session_code: sessionCode,
391
+ input,
159
392
  execute_kwargs: {
160
- stream: true
393
+ stream: true,
394
+ persist_input: !!input,
395
+ last_message_id: lastMessageId,
396
+ resume
161
397
  }
162
398
  },
163
- controller: abortController,
399
+ controller: chatAbortController,
164
400
  onDone,
165
401
  onError,
166
402
  onMessage,
167
403
  onStart
168
- }, config));
404
+ }, config)).catch(()=>{
405
+ // 非 abort 错误已通过 onError 回调处理;abort 为正常结束
406
+ }));
169
407
  });
170
- return function streamRequest(sessionCode, url, config) {
408
+ return function streamRequest(_) {
171
409
  return _ref.apply(this, arguments);
172
410
  };
173
411
  }();
@@ -191,7 +429,11 @@ import { SessionStatus } from '../session/type.ts.js';
191
429
  property
192
430
  }));
193
431
  // 发起聊天
194
- streamRequest(sessionCode, url, config);
432
+ streamRequest({
433
+ sessionCode,
434
+ url,
435
+ config
436
+ });
195
437
  });
196
438
  return function chat(userInput, sessionCode, url, config, property) {
197
439
  return _ref.apply(this, arguments);
@@ -206,15 +448,78 @@ import { SessionStatus } from '../session/type.ts.js';
206
448
  */ const resumeStreamingChat = (sessionCode, url, config)=>{
207
449
  var _mediator_session_current_value, _mediator_session;
208
450
  if (((_mediator_session = mediator.session) === null || _mediator_session === void 0 ? void 0 : (_mediator_session_current_value = _mediator_session.current.value) === null || _mediator_session_current_value === void 0 ? void 0 : _mediator_session_current_value.status) === SessionStatus.Running) {
209
- streamRequest(sessionCode, url, config);
451
+ var _mediator_message_list_value_at, _mediator_message;
452
+ const lastMessageId = (_mediator_message = mediator.message) === null || _mediator_message === void 0 ? void 0 : (_mediator_message_list_value_at = _mediator_message.list.value.at(-1)) === null || _mediator_message_list_value_at === void 0 ? void 0 : _mediator_message_list_value_at.id;
453
+ streamRequest({
454
+ sessionCode,
455
+ url,
456
+ config,
457
+ lastMessageId
458
+ });
210
459
  }
211
460
  };
212
461
  /**
462
+ * 轮询接口,判断是否可以继续聊天
463
+ * @param sessionCode - 会话编码
464
+ * @returns 是否可以继续聊天
465
+ */ const pollResumeSession = (sessionCode)=>{
466
+ var _mediator_message, _lastMessage_content_outcome, _lastMessage_content;
467
+ const lastMessage = (_mediator_message = mediator.message) === null || _mediator_message === void 0 ? void 0 : _mediator_message.list.value.at(-1);
468
+ const pendingApprovalInterrupt = (lastMessage === null || lastMessage === void 0 ? void 0 : (_lastMessage_content = lastMessage.content) === null || _lastMessage_content === void 0 ? void 0 : (_lastMessage_content_outcome = _lastMessage_content.outcome) === null || _lastMessage_content_outcome === void 0 ? void 0 : _lastMessage_content_outcome.type) === RunFinishedOutcomeType.Interrupt ? lastMessage.content.outcome.interrupts.find((interrupt)=>{
469
+ var _interrupt_metadata_ticket, _interrupt_metadata;
470
+ return [
471
+ ApprovalInterruptTicketStatus.Pending,
472
+ ApprovalInterruptTicketStatus.Draft
473
+ ].includes((_interrupt_metadata = interrupt.metadata) === null || _interrupt_metadata === void 0 ? void 0 : (_interrupt_metadata_ticket = _interrupt_metadata.ticket) === null || _interrupt_metadata_ticket === void 0 ? void 0 : _interrupt_metadata_ticket.status);
474
+ }) : undefined;
475
+ const getIsTicketLoading = ()=>{
476
+ const isInterruptMessage = (lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.role) === MessageRole.Interrupt;
477
+ return isInterruptMessage && !!pendingApprovalInterrupt;
478
+ };
479
+ if (getIsTicketLoading()) {
480
+ var // 轮询接口,判断是否可以继续聊天
481
+ _mediator_http;
482
+ // 清除轮询定时器和中断轮询控制器
483
+ clearLongPollTimer();
484
+ resumeAbortController = new AbortController();
485
+ (_mediator_http = mediator.http) === null || _mediator_http === void 0 ? void 0 : _mediator_http.session.isResumeSession(sessionCode, {
486
+ controller: resumeAbortController
487
+ }).then((res)=>{
488
+ if (res) {
489
+ // 可以继续聊天,重新发起聊天(携带 execute_kwargs.resume 通知后端恢复中断)
490
+ streamRequest({
491
+ sessionCode,
492
+ resume: {
493
+ interruptId: pendingApprovalInterrupt.id,
494
+ status: ResumeStatus.Resolved
495
+ }
496
+ });
497
+ } else {
498
+ longPollTimer = setTimeout(()=>{
499
+ var _mediator_session_current_value, _mediator_session_current, _mediator_session;
500
+ // 如果会话不匹配,则不继续轮询
501
+ if (sessionCode !== ((_mediator_session = mediator.session) === null || _mediator_session === void 0 ? void 0 : (_mediator_session_current = _mediator_session.current) === null || _mediator_session_current === void 0 ? void 0 : (_mediator_session_current_value = _mediator_session_current.value) === null || _mediator_session_current_value === void 0 ? void 0 : _mediator_session_current_value.sessionCode)) return;
502
+ pollResumeSession(sessionCode);
503
+ }, 10000);
504
+ }
505
+ });
506
+ }
507
+ };
508
+ const clearLongPollTimer = ()=>{
509
+ var _resumeAbortController_abort;
510
+ clearTimeout(longPollTimer);
511
+ longPollTimer = null;
512
+ resumeAbortController === null || resumeAbortController === void 0 ? void 0 : (_resumeAbortController_abort = resumeAbortController.abort) === null || _resumeAbortController_abort === void 0 ? void 0 : _resumeAbortController_abort.call(resumeAbortController);
513
+ resumeAbortController = null;
514
+ };
515
+ /**
213
516
  * 中止聊天(纯前端中止,后端继续处理)
214
517
  */ const abortChat = ()=>{
215
- var _abortController_abort;
216
- abortController === null || abortController === void 0 ? void 0 : (_abortController_abort = abortController.abort) === null || _abortController_abort === void 0 ? void 0 : _abortController_abort.call(abortController);
217
- abortController = null;
518
+ var _chatAbortController_abort;
519
+ manualAbort = true;
520
+ clearReconnectTimer(false);
521
+ chatAbortController === null || chatAbortController === void 0 ? void 0 : (_chatAbortController_abort = chatAbortController.abort) === null || _chatAbortController_abort === void 0 ? void 0 : _chatAbortController_abort.call(chatAbortController);
522
+ chatAbortController = null;
218
523
  };
219
524
  /**
220
525
  * 停止会话,后端中止
@@ -269,7 +574,11 @@ import { SessionStatus } from '../session/type.ts.js';
269
574
  property: originalProperty
270
575
  }));
271
576
  // 6. 立即发起流式请求(不等待删除和创建的 API 完成)
272
- streamRequest(sessionCode, url, config);
577
+ streamRequest({
578
+ sessionCode,
579
+ url,
580
+ config
581
+ });
273
582
  // 7. 在后台等待 API 完成,处理可能的错误
274
583
  Promise.all([
275
584
  deletePromise,
@@ -283,10 +592,15 @@ import { SessionStatus } from '../session/type.ts.js';
283
592
  };
284
593
  }();
285
594
  const reset = (protocol)=>{
286
- // 重置状态
595
+ abortChat();
596
+ // 重置状态(保留 manualAbort=true,避免 abort 异步 onDone 误触发重连;下次 streamRequest 会复位)
287
597
  usedProtocol = protocol || new AGUIProtocol();
288
598
  info.value = null;
289
599
  isInfoLoading.value = false;
600
+ isChatting.value = false;
601
+ activeStreamContext = null;
602
+ reconnectAttempt = 0;
603
+ runFinished = false;
290
604
  };
291
605
  return {
292
606
  info,
@@ -299,6 +613,10 @@ import { SessionStatus } from '../session/type.ts.js';
299
613
  abortChat,
300
614
  stopChat,
301
615
  getAgentInfo,
302
- reset
616
+ reset,
617
+ pollResumeSession,
618
+ clearLongPollTimer,
619
+ userOperationStreamRequest,
620
+ streamRequest
303
621
  };
304
622
  };
@@ -26,7 +26,7 @@ export declare class AGUIProtocol implements ISSEProtocol {
26
26
  * 处理活动快照事件
27
27
  * 记录活动的完整状态
28
28
  */
29
- handleActivitySnapshotEvent(_event: IActivitySnapshotEvent): void;
29
+ handleActivitySnapshotEvent(event: IActivitySnapshotEvent): void;
30
30
  /**
31
31
  * 处理自定义事件
32
32
  */
@@ -35,6 +35,10 @@ export declare class AGUIProtocol implements ISSEProtocol {
35
35
  * 自定义事件 处理流程编排任务结束
36
36
  */
37
37
  handleFlowAgentEndCustomEvent(event: ICustomEvent): void;
38
+ /**
39
+ * 自定义事件 处理流程编排任务重启
40
+ */
41
+ handleFlowAgentRestartCustomEvent(event: ICustomEvent): void;
38
42
  /**
39
43
  * 自定义事件 处理流程编排任务结果(增量更新节点状态)
40
44
  */
@@ -43,6 +47,10 @@ export declare class AGUIProtocol implements ISSEProtocol {
43
47
  * 自定义事件 处理流程编排任务开始
44
48
  */
45
49
  handleFlowAgentStartCustomEvent(event: ICustomEvent): void;
50
+ /**
51
+ * 自定义事件 处理流程编排任务更新
52
+ */
53
+ handleFlowAgentUpdateCustomEvent(event: ICustomEvent): void;
46
54
  /**
47
55
  * 自定义事件 处理意图识别结束
48
56
  */
@@ -80,7 +88,7 @@ export declare class AGUIProtocol implements ISSEProtocol {
80
88
  /**
81
89
  * 处理运行完成事件
82
90
  */
83
- handleRunFinishedEvent(_event: IRunFinishedEvent): void;
91
+ handleRunFinishedEvent(event: IRunFinishedEvent): void;
84
92
  /**
85
93
  * 处理运行开始事件
86
94
  */
@@ -105,6 +113,10 @@ export declare class AGUIProtocol implements ISSEProtocol {
105
113
  * 自定义事件 处理临时消息,转换为 AI 文本消息
106
114
  */
107
115
  handleTempMessageCustomEvent(event: ICustomEvent): void;
116
+ /**
117
+ * 自定义事件 处理审批结果
118
+ */
119
+ handleApprovalResultCustomEvent(event: ICustomEvent): void;
108
120
  /**
109
121
  * 处理文本消息块事件
110
122
  */
@@ -119,6 +131,7 @@ export declare class AGUIProtocol implements ISSEProtocol {
119
131
  handleTextMessageEndEvent(event: ITextMessageEndEvent): void;
120
132
  /**
121
133
  * 处理文本消息开始事件
134
+ * 断线续传时 DLQ 会重放事件:同 messageId 已存在则重置内容,避免重复气泡/文本翻倍
122
135
  */
123
136
  handleTextMessageStartEvent(event: ITextMessageStartEvent): void;
124
137
  /**