@blueking/chat-helper 3.1.0-beta.2 → 3.1.0-beta.4

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.
@@ -167,6 +167,7 @@ export declare const useAgent: (mediator: IMediatorModule, protocol: ISSEProtoco
167
167
  function: {
168
168
  arguments: string;
169
169
  description?: string;
170
+ function_type?: import("../message").FunctionCallType;
170
171
  mcpName?: string;
171
172
  name: string;
172
173
  };
@@ -1185,6 +1186,7 @@ export declare const useAgent: (mediator: IMediatorModule, protocol: ISSEProtoco
1185
1186
  function: {
1186
1187
  arguments: string;
1187
1188
  description?: string;
1189
+ function_type?: import("../message").FunctionCallType;
1188
1190
  mcpName?: string;
1189
1191
  name: string;
1190
1192
  };
@@ -2106,7 +2108,7 @@ export declare const useAgent: (mediator: IMediatorModule, protocol: ISSEProtoco
2106
2108
  resendMessage: (messageId: string, sessionCode: string, newContent?: IUserMessage["content"], url?: string, config?: IRequestConfig, model?: string) => Promise<void>;
2107
2109
  resumeStreamingChat: (sessionCode: string, url?: string, config?: IRequestConfig, model?: string) => void;
2108
2110
  abortChat: () => void;
2109
- stopChat: (sessionCode: string) => Promise<void>;
2111
+ stopChat: (sessionCode: string) => Promise<unknown>;
2110
2112
  getAgentInfo: () => Promise<void>;
2111
2113
  getLlms: (params?: ILlmListQuery, config?: IRequestConfig) => Promise<ILlmItem[]>;
2112
2114
  reset: (protocol: ISSEProtocol) => void;
@@ -0,0 +1 @@
1
+ export {};
@@ -158,6 +158,9 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
158
158
  /** 当前轮次已静默重连次数 */ let reconnectAttempt = 0;
159
159
  /** 本轮流是否已收到 RUN_FINISHED */ let runFinished = false;
160
160
  /** 流世代号:新开流时递增,用于忽略已被替换的旧 SSE 回调 */ let activeStreamId = 0;
161
+ /** 尚未结束的那条流的世代号;仅当它仍等于 activeStreamId 时才可被 stopChat 封口 */ let openStreamId = null;
162
+ /** 正在进行中的停止请求;同会话下一轮 start 需等它落定后再开新 producer */ let pendingStop = null;
163
+ /** 正在排队等 pendingStop 的 start(尚未发出请求);被 stopChat / abortChat / 新的排队 start 替换即作废 */ let queuedStart = null;
161
164
  let reconnectTimer = null;
162
165
  let reconnectWaitResolve = null;
163
166
  let activeStreamContext = null;
@@ -272,6 +275,21 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
272
275
  var _mediator_session_current_value, _mediator_session_current, _mediator_session;
273
276
  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);
274
277
  };
278
+ /** 仅为最后一条用户消息回填后端 id(input 型流的乐观消息用),不整表替换列表 */ const backfillLastUserMessageId = (sessionCode)=>{
279
+ var _mediator_http_message, _mediator_http;
280
+ const request = (_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);
281
+ if (!request) {
282
+ return;
283
+ }
284
+ void request.then((res)=>{
285
+ var _mediator_message;
286
+ const lastUserMessage = (_mediator_message = mediator.message) === null || _mediator_message === void 0 ? void 0 : _mediator_message.list.value.findLast((item)=>item.role === MessageRole.User);
287
+ const lastApiUserMessage = res.findLast((item)=>item.role === MessageRole.User);
288
+ if (lastUserMessage && lastApiUserMessage) {
289
+ lastUserMessage.id = lastApiUserMessage.id;
290
+ }
291
+ }).catch(()=>undefined);
292
+ };
275
293
  /**
276
294
  * 尝试静默重连。
277
295
  * @param streamId - 发起重连的流世代;任一 await 后若已被新流/abort 取代则立即退出,避免 abort 掉更新流
@@ -334,6 +352,27 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
334
352
  const streamRequest = function() {
335
353
  var _ref = _async_to_generator(function*({ sessionCode, model, url, config, resume, input, lastMessageId, isReconnect = false, /** start 可启动新一轮执行;attach 仅接管/回放已有流 */ streamMode = 'start' }) {
336
354
  var _previousController_abort, _mediator_http;
355
+ // 同会话新一轮 start 必须等在途 stop 落定,避免新 producer 在取消标记生效前启动。
356
+ // attach(切会话/静默重连)不等待。
357
+ if (streamMode === 'start' && (pendingStop === null || pendingStop === void 0 ? void 0 : pendingStop.sessionCode) === sessionCode) {
358
+ const ticket = {
359
+ sessionCode
360
+ };
361
+ queuedStart = ticket;
362
+ // 等待期间保持生成态,界面仍展示停止按钮、禁止再次发送
363
+ isChatting.value = true;
364
+ yield pendingStop.promise.catch(()=>undefined);
365
+ const stillQueued = queuedStart === ticket;
366
+ if (stillQueued) {
367
+ queuedStart = null;
368
+ }
369
+ if (!stillQueued || !isSameActiveSession(sessionCode)) {
370
+ if (stillQueued) {
371
+ isChatting.value = false;
372
+ }
373
+ return;
374
+ }
375
+ }
337
376
  if (!isReconnect) {
338
377
  resetStreamReconnectState();
339
378
  }
@@ -342,14 +381,21 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
342
381
  model,
343
382
  url,
344
383
  config,
345
- streamMode
384
+ streamMode,
385
+ input
346
386
  };
347
387
  // 先递增世代再 abort 旧连接,避免旧流 onDone 误触发二次重连
348
388
  const streamId = ++activeStreamId;
389
+ openStreamId = streamId;
349
390
  const previousController = chatAbortController;
350
391
  chatAbortController = new AbortController();
351
392
  previousController === null || previousController === void 0 ? void 0 : (_previousController_abort = previousController.abort) === null || _previousController_abort === void 0 ? void 0 : _previousController_abort.call(previousController);
352
393
  const isActiveStream = ()=>streamId === activeStreamId;
394
+ const closeOpenStream = ()=>{
395
+ if (openStreamId === streamId) {
396
+ openStreamId = null;
397
+ }
398
+ };
353
399
  // ag-ui 协议需要注入消息模块
354
400
  if (usedProtocol instanceof AGUIProtocol) {
355
401
  usedProtocol.injectMessageModule(mediator.message);
@@ -369,19 +415,11 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
369
415
  if (!isActiveStream()) {
370
416
  return;
371
417
  }
418
+ closeOpenStream();
372
419
  isChatting.value = false;
373
420
  (_usedProtocol_onDone = usedProtocol.onDone) === null || _usedProtocol_onDone === void 0 ? void 0 : _usedProtocol_onDone.call(usedProtocol);
374
421
  if (input) {
375
- var // 刷新列表,获取前端 mock message 的 id,并更新到列表中
376
- _mediator_http_message, _mediator_http;
377
- (_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)=>{
378
- var _mediator_message;
379
- const lastUserMessage = (_mediator_message = mediator.message) === null || _mediator_message === void 0 ? void 0 : _mediator_message.list.value.findLast((item)=>item.role === MessageRole.User);
380
- const lastApiUserMessage = res.findLast((item)=>item.role === MessageRole.User);
381
- if (lastUserMessage && lastApiUserMessage) {
382
- lastUserMessage.id = lastApiUserMessage.id;
383
- }
384
- });
422
+ backfillLastUserMessageId(sessionCode);
385
423
  }
386
424
  // 轮询接口,判断是否可以继续聊天
387
425
  pollResumeSession(sessionCode);
@@ -391,6 +429,7 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
391
429
  if (!isActiveStream()) {
392
430
  return;
393
431
  }
432
+ closeOpenStream();
394
433
  isChatting.value = false;
395
434
  (_usedProtocol_onError = usedProtocol.onError) === null || _usedProtocol_onError === void 0 ? void 0 : _usedProtocol_onError.call(usedProtocol, error);
396
435
  };
@@ -422,6 +461,7 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
422
461
  }
423
462
  // abort / 切会话导致的失败:静默结束,不展示错误气泡
424
463
  if (manualAbort || !isSameActiveSession(sessionCode)) {
464
+ closeOpenStream();
425
465
  isChatting.value = false;
426
466
  return;
427
467
  }
@@ -439,6 +479,7 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
439
479
  var _mediator_session_current_value, _mediator_session;
440
480
  if (!isActiveStream() || manualAbort || !isSameActiveSession(sessionCode)) {
441
481
  if (isActiveStream()) {
482
+ closeOpenStream();
442
483
  isChatting.value = false;
443
484
  }
444
485
  return;
@@ -447,6 +488,7 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
447
488
  finishSuccessfully();
448
489
  return;
449
490
  }
491
+ closeOpenStream();
450
492
  isChatting.value = false;
451
493
  };
452
494
  const refresh = (_mediator_session = mediator.session) === null || _mediator_session === void 0 ? void 0 : _mediator_session.getSession(sessionCode);
@@ -473,6 +515,7 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
473
515
  return;
474
516
  }
475
517
  if (manualAbort || !isSameActiveSession(sessionCode)) {
518
+ closeOpenStream();
476
519
  isChatting.value = false;
477
520
  return;
478
521
  }
@@ -640,6 +683,34 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
640
683
  resumeAbortController = null;
641
684
  };
642
685
  /**
686
+ * 按流世代封口(用户主动停止时同步执行)。
687
+ * 使当前流世代失效,后续 SSE 事件不再进入协议层;但不断开连接,
688
+ * 让后端在原连接上完成取消收尾。无可封流时(已结束 / 已 abort)不做任何事。
689
+ * @returns 是否实际封住了一条流
690
+ */ const sealOpenStream = (sessionCode)=>{
691
+ var _mediator_message_settleStoppedTurn, _mediator_message, // 本轮唯一的 receive-end 出口;真实关流的 onDone 已因世代失效不会再触发
692
+ _usedProtocol_onDone;
693
+ if (openStreamId === null || openStreamId !== activeStreamId) {
694
+ return false;
695
+ }
696
+ if ((activeStreamContext === null || activeStreamContext === void 0 ? void 0 : activeStreamContext.sessionCode) !== sessionCode) {
697
+ return false;
698
+ }
699
+ const sealedInput = activeStreamContext.input;
700
+ (_mediator_message = mediator.message) === null || _mediator_message === void 0 ? void 0 : (_mediator_message_settleStoppedTurn = _mediator_message.settleStoppedTurn) === null || _mediator_message_settleStoppedTurn === void 0 ? void 0 : _mediator_message_settleStoppedTurn.call(_mediator_message, sessionCode);
701
+ if (sealedInput) {
702
+ backfillLastUserMessageId(sessionCode);
703
+ }
704
+ isChatting.value = false;
705
+ clearReconnectTimer(false);
706
+ clearLongPollTimer();
707
+ // 先失效世代:此后该连接的 onMessage/onDone/onError 与重连尝试都会直接返回
708
+ activeStreamId += 1;
709
+ openStreamId = null;
710
+ (_usedProtocol_onDone = usedProtocol.onDone) === null || _usedProtocol_onDone === void 0 ? void 0 : _usedProtocol_onDone.call(usedProtocol);
711
+ return true;
712
+ };
713
+ /**
643
714
  * 中止聊天(纯前端中止,后端继续处理)
644
715
  * 会使当前流世代失效,避免 abort 后的 onDone 误触发 finishSuccessfully / pollResumeSession
645
716
  */ const abortChat = ()=>{
@@ -647,6 +718,9 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
647
718
  manualAbort = true;
648
719
  // 先失效世代,再 abort:FetchClient 同步触发的 onDone 会因 isActiveStream=false 直接返回
649
720
  activeStreamId += 1;
721
+ openStreamId = null;
722
+ pendingStop = null;
723
+ queuedStart = null;
650
724
  clearReconnectTimer(false);
651
725
  clearLongPollTimer();
652
726
  isChatting.value = false;
@@ -654,12 +728,44 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
654
728
  chatAbortController = null;
655
729
  };
656
730
  /**
657
- * 停止会话,后端中止
731
+ * 取消排队中的 start:它尚未发到后端,本地结算即可,无需再发停止请求
732
+ * @returns 是否实际取消了排队的 start
733
+ */ const cancelQueuedStart = (sessionCode)=>{
734
+ var _mediator_message_settleStoppedTurn, _mediator_message;
735
+ if ((queuedStart === null || queuedStart === void 0 ? void 0 : queuedStart.sessionCode) !== sessionCode) {
736
+ return false;
737
+ }
738
+ queuedStart = null;
739
+ isChatting.value = false;
740
+ (_mediator_message = mediator.message) === null || _mediator_message === void 0 ? void 0 : (_mediator_message_settleStoppedTurn = _mediator_message.settleStoppedTurn) === null || _mediator_message_settleStoppedTurn === void 0 ? void 0 : _mediator_message_settleStoppedTurn.call(_mediator_message, sessionCode);
741
+ return true;
742
+ };
743
+ /**
744
+ * 停止会话,后端中止。
745
+ * 发请求前先同步封口,界面立即停止接受本轮流;请求记为 pendingStop,
746
+ * 同会话下一轮 start 会等它落定。失败仍 reject,且不解除封口。
747
+ * 若同会话有排队等待中的 start,只取消该 start 并等上一轮停止请求落定(其失败由上一轮调用方处理)。
658
748
  * @param sessionCode - 会话代码
659
749
  */ const stopChat = function() {
660
750
  var _ref = _async_to_generator(function*(sessionCode) {
661
- var _mediator_http_message;
662
- return (_mediator_http_message = mediator.http.message) === null || _mediator_http_message === void 0 ? void 0 : _mediator_http_message.stopChat(sessionCode);
751
+ var _mediator_http_message, _mediator_http;
752
+ if (cancelQueuedStart(sessionCode)) {
753
+ return pendingStop === null || pendingStop === void 0 ? void 0 : pendingStop.promise.catch(()=>undefined);
754
+ }
755
+ sealOpenStream(sessionCode);
756
+ const promise = Promise.resolve((_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.stopChat(sessionCode));
757
+ const record = {
758
+ sessionCode,
759
+ promise
760
+ };
761
+ pendingStop = record;
762
+ try {
763
+ return yield promise;
764
+ } finally{
765
+ if (pendingStop === record) {
766
+ pendingStop = null;
767
+ }
768
+ }
663
769
  });
664
770
  return function stopChat(sessionCode) {
665
771
  return _ref.apply(this, arguments);
@@ -511,7 +511,8 @@ import { transferMessageApi2Message } from '../http/transform/index.ts.js';
511
511
  mcpName: event.mcpName,
512
512
  name: event.toolCallName,
513
513
  arguments: '',
514
- description: event.description
514
+ description: event.description,
515
+ function_type: event.function_type
515
516
  }
516
517
  }
517
518
  ]
@@ -1,4 +1,4 @@
1
- import { type IMessageApi, type IMessageArtifact, type MessageRole, type MessageStatus } from '../message/type';
1
+ import { type FunctionCallType, type IMessageApi, type IMessageArtifact, type MessageRole, type MessageStatus } from '../message/type';
2
2
  import type { JSONSchema4 } from 'json-schema';
3
3
  export declare enum CustomEventName {
4
4
  ArtifactsGenerated = "artifacts_generated",
@@ -392,6 +392,7 @@ export interface IToolCallResultEvent extends IBaseEvent {
392
392
  }
393
393
  export interface IToolCallStartEvent extends IBaseEvent {
394
394
  description?: string;
395
+ function_type?: FunctionCallType;
395
396
  mcpName?: string;
396
397
  parentMessageId?: string;
397
398
  toolCallId: string;
@@ -143,6 +143,7 @@ import { ActivityType, MessageRole, MessageType, resolveMessageCreatedAt } from
143
143
  arguments: toolCall['function'].arguments,
144
144
  name: toolCall['function'].name,
145
145
  description: toolCall['function'].description,
146
+ function_type: toolCall['function'].function_type,
146
147
  mcpName: toolCall['function'].mcp_name
147
148
  },
148
149
  id: toolCall.id,
@@ -419,6 +420,7 @@ import { ActivityType, MessageRole, MessageType, resolveMessageCreatedAt } from
419
420
  arguments: toolCall['function'].arguments,
420
421
  name: toolCall['function'].name,
421
422
  description: toolCall['function'].description,
423
+ function_type: toolCall['function'].function_type,
422
424
  mcp_name: toolCall['function'].mcpName
423
425
  },
424
426
  id: toolCall.id,
package/dist/index.d.ts CHANGED
@@ -169,6 +169,7 @@ export declare const useChatHelper: (options: IUseChatHelperOptions) => {
169
169
  function: {
170
170
  arguments: string;
171
171
  description?: string;
172
+ function_type?: import("./message").FunctionCallType;
172
173
  mcpName?: string;
173
174
  name: string;
174
175
  };
@@ -1187,6 +1188,7 @@ export declare const useChatHelper: (options: IUseChatHelperOptions) => {
1187
1188
  function: {
1188
1189
  arguments: string;
1189
1190
  description?: string;
1191
+ function_type?: import("./message").FunctionCallType;
1190
1192
  mcpName?: string;
1191
1193
  name: string;
1192
1194
  };
@@ -2108,7 +2110,7 @@ export declare const useChatHelper: (options: IUseChatHelperOptions) => {
2108
2110
  resendMessage: (messageId: string, sessionCode: string, newContent?: import("./message").IUserMessage["content"], url?: string, config?: import("./http").IRequestConfig, model?: string) => Promise<void>;
2109
2111
  resumeStreamingChat: (sessionCode: string, url?: string, config?: import("./http").IRequestConfig, model?: string) => void;
2110
2112
  abortChat: () => void;
2111
- stopChat: (sessionCode: string) => Promise<void>;
2113
+ stopChat: (sessionCode: string) => Promise<unknown>;
2112
2114
  getAgentInfo: () => Promise<void>;
2113
2115
  getLlms: (params?: import("./agent").ILlmListQuery, config?: import("./http").IRequestConfig) => Promise<import("./agent").ILlmItem[]>;
2114
2116
  reset: (protocol: import("./http").ISSEProtocol) => void;
@@ -2241,6 +2243,7 @@ export declare const useChatHelper: (options: IUseChatHelperOptions) => {
2241
2243
  function: {
2242
2244
  arguments: string;
2243
2245
  description?: string;
2246
+ function_type?: import("./message").FunctionCallType;
2244
2247
  mcpName?: string;
2245
2248
  name: string;
2246
2249
  };
@@ -3197,6 +3200,7 @@ export declare const useChatHelper: (options: IUseChatHelperOptions) => {
3197
3200
  function: {
3198
3201
  arguments: string;
3199
3202
  description?: string;
3203
+ function_type?: import("./message").FunctionCallType;
3200
3204
  mcpName?: string;
3201
3205
  name: string;
3202
3206
  };
@@ -4174,6 +4178,7 @@ export declare const useChatHelper: (options: IUseChatHelperOptions) => {
4174
4178
  function: {
4175
4179
  arguments: string;
4176
4180
  description?: string;
4181
+ function_type?: import("./message").FunctionCallType;
4177
4182
  mcpName?: string;
4178
4183
  name: string;
4179
4184
  };
@@ -5130,6 +5135,7 @@ export declare const useChatHelper: (options: IUseChatHelperOptions) => {
5130
5135
  function: {
5131
5136
  arguments: string;
5132
5137
  description?: string;
5138
+ function_type?: import("./message").FunctionCallType;
5133
5139
  mcpName?: string;
5134
5140
  name: string;
5135
5141
  };
@@ -6108,6 +6114,7 @@ export declare const useChatHelper: (options: IUseChatHelperOptions) => {
6108
6114
  function: {
6109
6115
  arguments: string;
6110
6116
  description?: string;
6117
+ function_type?: import("./message").FunctionCallType;
6111
6118
  mcpName?: string;
6112
6119
  name: string;
6113
6120
  };
@@ -7064,6 +7071,7 @@ export declare const useChatHelper: (options: IUseChatHelperOptions) => {
7064
7071
  function: {
7065
7072
  arguments: string;
7066
7073
  description?: string;
7074
+ function_type?: import("./message").FunctionCallType;
7067
7075
  mcpName?: string;
7068
7076
  name: string;
7069
7077
  };
@@ -8041,6 +8049,7 @@ export declare const useChatHelper: (options: IUseChatHelperOptions) => {
8041
8049
  function: {
8042
8050
  arguments: string;
8043
8051
  description?: string;
8052
+ function_type?: import("./message").FunctionCallType;
8044
8053
  mcpName?: string;
8045
8054
  name: string;
8046
8055
  };
@@ -8997,6 +9006,7 @@ export declare const useChatHelper: (options: IUseChatHelperOptions) => {
8997
9006
  function: {
8998
9007
  arguments: string;
8999
9008
  description?: string;
9009
+ function_type?: import("./message").FunctionCallType;
9000
9010
  mcpName?: string;
9001
9011
  name: string;
9002
9012
  };
@@ -9998,6 +10008,7 @@ export declare const useChatHelper: (options: IUseChatHelperOptions) => {
9998
10008
  function: {
9999
10009
  arguments: string;
10000
10010
  description?: string;
10011
+ function_type?: import("./message").FunctionCallType;
10001
10012
  mcpName?: string;
10002
10013
  name: string;
10003
10014
  };
@@ -10951,6 +10962,7 @@ export declare const useChatHelper: (options: IUseChatHelperOptions) => {
10951
10962
  function: {
10952
10963
  arguments: string;
10953
10964
  description?: string;
10965
+ function_type?: import("./message").FunctionCallType;
10954
10966
  mcpName?: string;
10955
10967
  name: string;
10956
10968
  };
@@ -11909,6 +11921,7 @@ export declare const useChatHelper: (options: IUseChatHelperOptions) => {
11909
11921
  function: {
11910
11922
  arguments: string;
11911
11923
  description?: string;
11924
+ function_type?: import("./message").FunctionCallType;
11912
11925
  mcpName?: string;
11913
11926
  name: string;
11914
11927
  };
@@ -12766,6 +12779,7 @@ export declare const useChatHelper: (options: IUseChatHelperOptions) => {
12766
12779
  sessionCode?: string;
12767
12780
  status: import("./message").MessageStatus;
12768
12781
  };
12782
+ settleStoppedTurn: (sessionCode?: string) => void;
12769
12783
  getMessageByMessageId: (id: string) => {
12770
12784
  activityType: import("./message").ActivityType;
12771
12785
  content: {
@@ -12863,6 +12877,7 @@ export declare const useChatHelper: (options: IUseChatHelperOptions) => {
12863
12877
  function: {
12864
12878
  arguments: string;
12865
12879
  description?: string;
12880
+ function_type?: import("./message").FunctionCallType;
12866
12881
  mcpName?: string;
12867
12882
  name: string;
12868
12883
  };
@@ -43,6 +43,12 @@ export declare enum MessageType {
43
43
  Function = "function",
44
44
  Text = "text"
45
45
  }
46
+ export declare enum FunctionCallType {
47
+ Function = "function",
48
+ Mcp = "mcp",
49
+ Skill = "skill",
50
+ Subagent = "subagent"
51
+ }
46
52
  export declare enum UserOperation {
47
53
  FlowNodeRetry = "flow_node_retry",
48
54
  FlowNodeSkip = "flow_node_skip",
@@ -193,12 +199,14 @@ export interface IFlowAgentTaskNodeInfo {
193
199
  export interface IFunctionCall {
194
200
  arguments: string;
195
201
  description?: string;
202
+ function_type?: FunctionCallType;
196
203
  mcpName?: string;
197
204
  name: string;
198
205
  }
199
206
  export interface IFunctionCallApi {
200
207
  arguments: string;
201
208
  description?: string;
209
+ function_type?: FunctionCallType;
202
210
  mcp_name?: string;
203
211
  name: string;
204
212
  }
@@ -70,6 +70,13 @@ export var MessageType;
70
70
  MessageType["Function"] = "function";
71
71
  MessageType["Text"] = "text";
72
72
  })(MessageType || (MessageType = {}));
73
+ export var FunctionCallType;
74
+ (function(FunctionCallType) {
75
+ FunctionCallType["Function"] = "function";
76
+ FunctionCallType["Mcp"] = "mcp";
77
+ FunctionCallType["Skill"] = "skill";
78
+ FunctionCallType["Subagent"] = "subagent";
79
+ })(FunctionCallType || (FunctionCallType = {}));
73
80
  export var UserOperation;
74
81
  (function(UserOperation) {
75
82
  UserOperation["FlowNodeRetry"] = "flow_node_retry";
@@ -103,6 +103,7 @@ export declare const useMessage: (mediator: IMediatorModule) => {
103
103
  function: {
104
104
  arguments: string;
105
105
  description?: string;
106
+ function_type?: import("./type").FunctionCallType;
106
107
  mcpName?: string;
107
108
  name: string;
108
109
  };
@@ -1056,6 +1057,7 @@ export declare const useMessage: (mediator: IMediatorModule) => {
1056
1057
  function: {
1057
1058
  arguments: string;
1058
1059
  description?: string;
1060
+ function_type?: import("./type").FunctionCallType;
1059
1061
  mcpName?: string;
1060
1062
  name: string;
1061
1063
  };
@@ -2014,6 +2016,7 @@ export declare const useMessage: (mediator: IMediatorModule) => {
2014
2016
  function: {
2015
2017
  arguments: string;
2016
2018
  description?: string;
2019
+ function_type?: import("./type").FunctionCallType;
2017
2020
  mcpName?: string;
2018
2021
  name: string;
2019
2022
  };
@@ -2871,6 +2874,7 @@ export declare const useMessage: (mediator: IMediatorModule) => {
2871
2874
  sessionCode?: string;
2872
2875
  status: MessageStatus;
2873
2876
  };
2877
+ settleStoppedTurn: (sessionCode?: string) => void;
2874
2878
  getMessageByMessageId: (id: string) => {
2875
2879
  activityType: import("./type").ActivityType;
2876
2880
  content: {
@@ -2968,6 +2972,7 @@ export declare const useMessage: (mediator: IMediatorModule) => {
2968
2972
  function: {
2969
2973
  arguments: string;
2970
2974
  description?: string;
2975
+ function_type?: import("./type").FunctionCallType;
2971
2976
  mcpName?: string;
2972
2977
  name: string;
2973
2978
  };
@@ -142,6 +142,38 @@ import { MessageRole, MessageStatus } from './type.ts.js';
142
142
  MessageStatus.Streaming
143
143
  ].includes(item.status));
144
144
  };
145
+ /**
146
+ * 用户停止时把本轮尾段消息收成终态。
147
+ * 范围:最后一条 User 之后,跳过 Interrupt(中断卡片本身为 Pending,等待用户处理)。
148
+ * 尾段没有助手正文(仅有思考 / 工具调用,或完全为空)时补一条「用户已取消」(status=error),
149
+ * 与后端取消回写规则一致:后端仅在无助手文本输出时补写该条,刷新前后条目相同。
150
+ */ const settleStoppedTurn = (sessionCode)=>{
151
+ const messages = list.value;
152
+ let lastUserIndex = -1;
153
+ messages.forEach((item, index)=>{
154
+ if (item.role === MessageRole.User) {
155
+ lastUserIndex = index;
156
+ }
157
+ });
158
+ const tail = messages.slice(lastUserIndex + 1);
159
+ const nonInterruptTail = tail.filter((item)=>item.role !== MessageRole.Interrupt);
160
+ nonInterruptTail.forEach((item)=>{
161
+ if (item.status === MessageStatus.Streaming || item.status === MessageStatus.Pending) {
162
+ item.status = MessageStatus.Stop;
163
+ }
164
+ });
165
+ const hasAssistantText = nonInterruptTail.some((item)=>item.role === MessageRole.Assistant && typeof item.content === 'string' && item.content.trim() !== '');
166
+ if (!hasAssistantText) {
167
+ const cancelledMessage = _object_spread({
168
+ role: MessageRole.Assistant,
169
+ content: '用户已取消',
170
+ status: MessageStatus.Error
171
+ }, sessionCode ? {
172
+ sessionCode
173
+ } : {});
174
+ list.value.push(cancelledMessage);
175
+ }
176
+ };
145
177
  const getMessageByMessageId = (id)=>{
146
178
  return list.value.find((item)=>item.messageId === id);
147
179
  };
@@ -278,6 +310,7 @@ import { MessageRole, MessageStatus } from './type.ts.js';
278
310
  getMessages,
279
311
  clearMessages,
280
312
  getCurrentLoadingMessage,
313
+ settleStoppedTurn,
281
314
  getMessageByMessageId,
282
315
  modifyMessage,
283
316
  plusMessage,
@@ -119,6 +119,7 @@ export declare const useSession: (mediator: IMediatorModule) => {
119
119
  function: {
120
120
  arguments: string;
121
121
  description?: string;
122
+ function_type?: import("..").FunctionCallType;
122
123
  mcpName?: string;
123
124
  name: string;
124
125
  };
@@ -1075,6 +1076,7 @@ export declare const useSession: (mediator: IMediatorModule) => {
1075
1076
  function: {
1076
1077
  arguments: string;
1077
1078
  description?: string;
1079
+ function_type?: import("..").FunctionCallType;
1078
1080
  mcpName?: string;
1079
1081
  name: string;
1080
1082
  };
@@ -2052,6 +2054,7 @@ export declare const useSession: (mediator: IMediatorModule) => {
2052
2054
  function: {
2053
2055
  arguments: string;
2054
2056
  description?: string;
2057
+ function_type?: import("..").FunctionCallType;
2055
2058
  mcpName?: string;
2056
2059
  name: string;
2057
2060
  };
@@ -3008,6 +3011,7 @@ export declare const useSession: (mediator: IMediatorModule) => {
3008
3011
  function: {
3009
3012
  arguments: string;
3010
3013
  description?: string;
3014
+ function_type?: import("..").FunctionCallType;
3011
3015
  mcpName?: string;
3012
3016
  name: string;
3013
3017
  };
@@ -3986,6 +3990,7 @@ export declare const useSession: (mediator: IMediatorModule) => {
3986
3990
  function: {
3987
3991
  arguments: string;
3988
3992
  description?: string;
3993
+ function_type?: import("..").FunctionCallType;
3989
3994
  mcpName?: string;
3990
3995
  name: string;
3991
3996
  };
@@ -4942,6 +4947,7 @@ export declare const useSession: (mediator: IMediatorModule) => {
4942
4947
  function: {
4943
4948
  arguments: string;
4944
4949
  description?: string;
4950
+ function_type?: import("..").FunctionCallType;
4945
4951
  mcpName?: string;
4946
4952
  name: string;
4947
4953
  };
@@ -5919,6 +5925,7 @@ export declare const useSession: (mediator: IMediatorModule) => {
5919
5925
  function: {
5920
5926
  arguments: string;
5921
5927
  description?: string;
5928
+ function_type?: import("..").FunctionCallType;
5922
5929
  mcpName?: string;
5923
5930
  name: string;
5924
5931
  };
@@ -6875,6 +6882,7 @@ export declare const useSession: (mediator: IMediatorModule) => {
6875
6882
  function: {
6876
6883
  arguments: string;
6877
6884
  description?: string;
6885
+ function_type?: import("..").FunctionCallType;
6878
6886
  mcpName?: string;
6879
6887
  name: string;
6880
6888
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blueking/chat-helper",
3
- "version": "3.1.0-beta.2",
3
+ "version": "3.1.0-beta.4",
4
4
  "description": "",
5
5
  "main": "./dist/index.ts.js",
6
6
  "types": "./dist/index.d.ts",