@blueking/chat-helper 0.0.12-beta.13 → 0.0.12-beta.14

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.
@@ -120,6 +120,8 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
120
120
  const info = ref(null);
121
121
  const isInfoLoading = ref(false);
122
122
  const isChatting = ref(false);
123
+ const models = ref([]);
124
+ const isModelsLoading = ref(false);
123
125
  let usedProtocol = protocol || new AGUIProtocol();
124
126
  let chatAbortController = null;
125
127
  let resumeAbortController = null;
@@ -130,6 +132,27 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
130
132
  let reconnectTimer = null;
131
133
  let reconnectWaitResolve = null;
132
134
  let activeStreamContext = null;
135
+ /**
136
+ * 获取可用模型列表,写入 models;失败时清空列表并抛出
137
+ */ const getLlms = (params, config)=>{
138
+ var _mediator_http;
139
+ isModelsLoading.value = true;
140
+ const request = (_mediator_http = mediator.http) === null || _mediator_http === void 0 ? void 0 : _mediator_http.agent.getLlms(params, config);
141
+ if (!request) {
142
+ isModelsLoading.value = false;
143
+ models.value = [];
144
+ return Promise.resolve([]);
145
+ }
146
+ return request.then((res)=>{
147
+ models.value = res;
148
+ return res;
149
+ })['catch']((error)=>{
150
+ models.value = [];
151
+ throw error;
152
+ })['finally'](()=>{
153
+ isModelsLoading.value = false;
154
+ });
155
+ };
133
156
  const getAgentInfo = ()=>{
134
157
  var _mediator_http;
135
158
  isInfoLoading.value = true;
@@ -158,17 +181,18 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
158
181
  });
159
182
  }
160
183
  };
161
- const userOperationStreamRequest = (sessionCode, operation, payload, config)=>{
184
+ const userOperationStreamRequest = (sessionCode, operation, payload, config, model)=>{
162
185
  var _mediator_http;
163
186
  return (_mediator_http = mediator.http) === null || _mediator_http === void 0 ? void 0 : _mediator_http.message.userOperation(sessionCode, operation, payload, config).then(()=>{
164
187
  if (operation !== UserOperation.ApprovalCancel) {
165
188
  streamRequest({
166
189
  sessionCode,
167
- config
190
+ config,
191
+ model
168
192
  });
169
193
  } else {
170
194
  clearLongPollTimer();
171
- pollResumeSession(sessionCode);
195
+ pollResumeSession(sessionCode, model);
172
196
  }
173
197
  });
174
198
  };
@@ -259,6 +283,7 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
259
283
  const ctx = activeStreamContext;
260
284
  streamRequest({
261
285
  sessionCode,
286
+ model: ctx === null || ctx === void 0 ? void 0 : ctx.model,
262
287
  url: ctx === null || ctx === void 0 ? void 0 : ctx.url,
263
288
  config: ctx === null || ctx === void 0 ? void 0 : ctx.config,
264
289
  lastMessageId: lastMessageId !== undefined ? String(lastMessageId) : undefined,
@@ -271,13 +296,14 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
271
296
  };
272
297
  }();
273
298
  const streamRequest = function() {
274
- var _ref = _async_to_generator(function*({ sessionCode, url, config, resume, input, lastMessageId, isReconnect = false }) {
299
+ var _ref = _async_to_generator(function*({ sessionCode, model, url, config, resume, input, lastMessageId, isReconnect = false }) {
275
300
  var _mediator_http;
276
301
  if (!isReconnect) {
277
302
  resetStreamReconnectState();
278
303
  }
279
304
  activeStreamContext = {
280
305
  sessionCode,
306
+ model: model,
281
307
  url,
282
308
  config
283
309
  };
@@ -388,6 +414,7 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
388
414
  method: 'POST',
389
415
  data: {
390
416
  session_code: sessionCode,
417
+ model,
391
418
  input,
392
419
  execute_kwargs: {
393
420
  stream: true,
@@ -416,8 +443,9 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
416
443
  * @param url - 请求 URL(可选)
417
444
  * @param config - 请求配置(可选)
418
445
  * @param property - 消息属性,用于传递引用内容或快捷键相关信息(可选)
446
+ * @param model - 模型标识(可选)
419
447
  */ const chat = function() {
420
- var _ref = _async_to_generator(function*(userInput, sessionCode, url, config, property) {
448
+ var _ref = _async_to_generator(function*(userInput, sessionCode, url, config, property, model) {
421
449
  var _mediator_message;
422
450
  // 先新增一个 message
423
451
  yield (_mediator_message = mediator.message) === null || _mediator_message === void 0 ? void 0 : _mediator_message.createAndPlusMessage(_object_spread({
@@ -431,11 +459,12 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
431
459
  // 发起聊天
432
460
  streamRequest({
433
461
  sessionCode,
462
+ model,
434
463
  url,
435
464
  config
436
465
  });
437
466
  });
438
- return function chat(userInput, sessionCode, url, config, property) {
467
+ return function chat(userInput, sessionCode, url, config, property, model) {
439
468
  return _ref.apply(this, arguments);
440
469
  };
441
470
  }();
@@ -445,13 +474,15 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
445
474
  * @param sessionCode - 会话代码
446
475
  * @param url - 请求 URL(可选)
447
476
  * @param config - 请求配置(可选)
448
- */ const resumeStreamingChat = (sessionCode, url, config)=>{
477
+ * @param model - 模型标识(可选)
478
+ */ const resumeStreamingChat = (sessionCode, url, config, model)=>{
449
479
  var _mediator_session_current_value, _mediator_session;
450
480
  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) {
451
481
  var _mediator_message_list_value_at, _mediator_message;
452
482
  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
483
  streamRequest({
454
484
  sessionCode,
485
+ model,
455
486
  url,
456
487
  config,
457
488
  lastMessageId
@@ -462,7 +493,7 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
462
493
  * 轮询接口,判断是否可以继续聊天
463
494
  * @param sessionCode - 会话编码
464
495
  * @returns 是否可以继续聊天
465
- */ const pollResumeSession = (sessionCode)=>{
496
+ */ const pollResumeSession = (sessionCode, model)=>{
466
497
  var _mediator_message, _lastMessage_content_outcome, _lastMessage_content;
467
498
  const lastMessage = (_mediator_message = mediator.message) === null || _mediator_message === void 0 ? void 0 : _mediator_message.list.value.at(-1);
468
499
  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)=>{
@@ -489,6 +520,7 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
489
520
  // 可以继续聊天,重新发起聊天(携带 execute_kwargs.resume 通知后端恢复中断)
490
521
  streamRequest({
491
522
  sessionCode,
523
+ model,
492
524
  resume: {
493
525
  interruptId: pendingApprovalInterrupt.id,
494
526
  status: ResumeStatus.Resolved
@@ -499,7 +531,7 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
499
531
  var _mediator_session_current_value, _mediator_session_current, _mediator_session;
500
532
  // 如果会话不匹配,则不继续轮询
501
533
  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);
534
+ pollResumeSession(sessionCode, model);
503
535
  }, 10000);
504
536
  }
505
537
  });
@@ -542,8 +574,9 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
542
574
  * @param newContent - 新内容(可选,不传则使用原消息内容;支持多模态)
543
575
  * @param url - 请求 URL(可选)
544
576
  * @param config - 请求配置(可选)
577
+ * @param model - 模型标识(可选)
545
578
  */ const resendMessage = function() {
546
- var _ref = _async_to_generator(function*(messageId, sessionCode, newContent, url, config) {
579
+ var _ref = _async_to_generator(function*(messageId, sessionCode, newContent, url, config, model) {
547
580
  var _mediator_message, _mediator_message1, _mediator_message2;
548
581
  const messages = ((_mediator_message = mediator.message) === null || _mediator_message === void 0 ? void 0 : _mediator_message.list.value) || [];
549
582
  // 1. 找到目标用户消息
@@ -576,6 +609,7 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
576
609
  // 6. 立即发起流式请求(不等待删除和创建的 API 完成)
577
610
  streamRequest({
578
611
  sessionCode,
612
+ model,
579
613
  url,
580
614
  config
581
615
  });
@@ -587,7 +621,7 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
587
621
  console.error('[resendMessage] API error:', error);
588
622
  });
589
623
  });
590
- return function resendMessage(messageId, sessionCode, newContent, url, config) {
624
+ return function resendMessage(messageId, sessionCode, newContent, url, config, model) {
591
625
  return _ref.apply(this, arguments);
592
626
  };
593
627
  }();
@@ -598,6 +632,8 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
598
632
  info.value = null;
599
633
  isInfoLoading.value = false;
600
634
  isChatting.value = false;
635
+ models.value = [];
636
+ isModelsLoading.value = false;
601
637
  activeStreamContext = null;
602
638
  reconnectAttempt = 0;
603
639
  runFinished = false;
@@ -606,6 +642,8 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
606
642
  info,
607
643
  isInfoLoading,
608
644
  isChatting,
645
+ models,
646
+ isModelsLoading,
609
647
  chat,
610
648
  handleRole,
611
649
  resendMessage,
@@ -613,6 +651,7 @@ const getReconnectDelayMs = (attempt)=>Math.min(RECONNECT_BASE_DELAY_MS * Math.p
613
651
  abortChat,
614
652
  stopChat,
615
653
  getAgentInfo,
654
+ getLlms,
616
655
  reset,
617
656
  pollResumeSession,
618
657
  clearLongPollTimer,
@@ -27,6 +27,7 @@ export declare class AGUIProtocol implements ISSEProtocol {
27
27
  * 记录活动的完整状态
28
28
  */
29
29
  handleActivitySnapshotEvent(event: IActivitySnapshotEvent): void;
30
+ handleArtifactsGeneratedCustomEvent(event: ICustomEvent): void;
30
31
  /**
31
32
  * 处理自定义事件
32
33
  */
@@ -51,6 +52,7 @@ export declare class AGUIProtocol implements ISSEProtocol {
51
52
  * 自定义事件 处理流程编排任务更新
52
53
  */
53
54
  handleFlowAgentUpdateCustomEvent(event: ICustomEvent): void;
55
+ handleInfoCustomEvent(event: ICustomEvent): void;
54
56
  /**
55
57
  * 自定义事件 处理意图识别结束
56
58
  */
@@ -35,7 +35,6 @@
35
35
  }
36
36
  return obj;
37
37
  }
38
- import { transferMessageApi2Message } from '../http/transform/index.ts.js';
39
38
  import { ActivityType, MessageRole, MessageStatus, MessageType } from '../message/index.ts.js';
40
39
  import { CustomEventName, EventType, FlowTaskState, RunFinishedOutcomeType } from './type.ts.js';
41
40
  /**
@@ -50,18 +49,38 @@ import { CustomEventName, EventType, FlowTaskState, RunFinishedOutcomeType } fro
50
49
  * 处理活动快照事件
51
50
  * 记录活动的完整状态
52
51
  */ handleActivitySnapshotEvent(event) {
53
- const message = this.messageModule.getCurrentLoadingMessage();
52
+ if (event.activityType === ActivityType.Info) {
53
+ const message = this.messageModule.getMessageByMessageId(event.messageId);
54
+ if ((message === null || message === void 0 ? void 0 : message.role) === MessageRole.Info) {
55
+ message.content = event.content;
56
+ }
57
+ return;
58
+ }
54
59
  if (event.activityType === ActivityType.Interrupt) {
60
+ const message = this.messageModule.getCurrentLoadingMessage();
55
61
  if ((message === null || message === void 0 ? void 0 : message.role) === MessageRole.Interrupt) {
56
62
  message.content = event.content;
57
63
  message.status = MessageStatus.Complete;
58
64
  }
59
65
  }
60
66
  }
67
+ handleArtifactsGeneratedCustomEvent(event) {
68
+ const message = this.messageModule.list.value.findLast((item)=>item.role === MessageRole.Assistant);
69
+ if (message) {
70
+ var _message;
71
+ const value = event.value;
72
+ var _property;
73
+ (_property = (_message = message).property) !== null && _property !== void 0 ? _property : _message.property = {};
74
+ message.property.artifacts = value.artifacts;
75
+ }
76
+ }
61
77
  /**
62
78
  * 处理自定义事件
63
79
  */ handleCustomEvent(event) {
64
80
  switch(event.name){
81
+ case CustomEventName.ArtifactsGenerated:
82
+ this.handleArtifactsGeneratedCustomEvent(event);
83
+ break;
65
84
  case CustomEventName.FlowAgentStart:
66
85
  this.handleFlowAgentStartCustomEvent(event);
67
86
  break;
@@ -98,6 +117,9 @@ import { CustomEventName, EventType, FlowTaskState, RunFinishedOutcomeType } fro
98
117
  case CustomEventName.FlowAgentUpdate:
99
118
  this.handleFlowAgentUpdateCustomEvent(event);
100
119
  break;
120
+ case CustomEventName.Info:
121
+ this.handleInfoCustomEvent(event);
122
+ break;
101
123
  default:
102
124
  break;
103
125
  }
@@ -171,6 +193,15 @@ import { CustomEventName, EventType, FlowTaskState, RunFinishedOutcomeType } fro
171
193
  }
172
194
  });
173
195
  }
196
+ handleInfoCustomEvent(event) {
197
+ const value = event.value;
198
+ this.messageModule.plusMessage({
199
+ role: MessageRole.Info,
200
+ messageId: value.messageId,
201
+ content: value.content,
202
+ status: MessageStatus.Complete
203
+ });
204
+ }
174
205
  /**
175
206
  * 自定义事件 处理意图识别结束
176
207
  */ handleKnowledgeRagEndCustomEvent(_event) {
@@ -214,7 +245,7 @@ import { CustomEventName, EventType, FlowTaskState, RunFinishedOutcomeType } fro
214
245
  * 用于同步多端消息状态
215
246
  */ handleMessagesSnapshotEvent(event) {
216
247
  if (event.messages && event.messages.length > 0) {
217
- this.messageModule.list.value = event.messages.map(transferMessageApi2Message);
248
+ this.messageModule.list.value = event.messages;
218
249
  }
219
250
  }
220
251
  /**
@@ -1,11 +1,13 @@
1
- import { type IMessageApi, type MessageRole, type MessageStatus } from '../message/type';
1
+ import { type IMessage, type IMessageArtifact, type MessageRole, type MessageStatus } from '../message/type';
2
2
  import type { JSONSchema4 } from 'json-schema';
3
3
  export declare enum CustomEventName {
4
+ ArtifactsGenerated = "artifacts_generated",
4
5
  FlowAgentEnd = "flow_agent_end",
5
6
  FlowAgentResult = "flow_agent_result",
6
7
  FlowAgentStart = "flow_agent_start",
7
8
  FlowAgentUpdate = "flow_agent_update",
8
9
  FlowAgentRestart = "flow_agent_restart",
10
+ Info = "info",
9
11
  KnowledgeRagEnd = "knowledge_rag_end",
10
12
  KnowledgeRagResult = "knowledge_rag_result",
11
13
  KnowledgeRagStart = "knowledge_rag_start",
@@ -114,6 +116,11 @@ export interface IActivitySnapshotEvent extends IBaseEvent {
114
116
  replace?: boolean;
115
117
  type: EventType.ActivitySnapshot;
116
118
  }
119
+ export interface IArtifactsGeneratedCustomValue {
120
+ artifacts: IMessageArtifact[];
121
+ runId: string;
122
+ status: 'complete' | 'empty';
123
+ }
117
124
  export interface IBaseEvent {
118
125
  timestamp?: number;
119
126
  type: EventType;
@@ -125,7 +132,7 @@ export interface IBaseEvent {
125
132
  export interface ICustomEvent extends IBaseEvent {
126
133
  name: CustomEventName;
127
134
  type: EventType.Custom;
128
- value: IFlowAgentEndCustomValue | IFlowAgentResultCustomValue | IFlowAgentStartCustomValue | IFlowAgentRestartCustomValue | IKnowledgeRagResultCustomValue | IKnowledgeRagTextContentCustomValue | IReferenceDocumentCustomValue | ITempMessageCustomValue | IApprovalResultCustomValue;
135
+ value: IArtifactsGeneratedCustomValue | IFlowAgentEndCustomValue | IFlowAgentResultCustomValue | IFlowAgentStartCustomValue | IFlowAgentRestartCustomValue | IInfoCustomValue | IKnowledgeRagResultCustomValue | IKnowledgeRagTextContentCustomValue | IReferenceDocumentCustomValue | ITempMessageCustomValue | IApprovalResultCustomValue;
129
136
  }
130
137
  export type IEvent = IActivityDeltaEvent | IActivitySnapshotEvent | ICustomEvent | IMessagesSnapshotEvent | IRawEvent | IRunErrorEvent | IRunFinishedEvent | IRunStartedEvent | IStateDeltaEvent | IStateSnapshotEvent | IStepFinishedEvent | IStepStartedEvent | ITextMessageChunkEvent | ITextMessageContentEvent | ITextMessageEndEvent | ITextMessageStartEvent | IThinkingEndEvent | IThinkingStartEvent | IThinkingTextMessageContentEvent | IThinkingTextMessageEndEvent | IThinkingTextMessageStartEvent | IToolCallArgsEvent | IToolCallChunkEvent | IToolCallEndEvent | IToolCallResultEvent | IToolCallStartEvent;
131
138
  export type IFlowAgentEndCustomValue = {
@@ -152,6 +159,10 @@ export type IFlowAgentStartCustomValue = {
152
159
  task_id: string;
153
160
  }[];
154
161
  export type IFlowAgentRestartCustomValue = IFlowAgentStartCustomValue;
162
+ export interface IInfoCustomValue {
163
+ content: string;
164
+ messageId: string;
165
+ }
155
166
  export type IKnowledgeRagResultCustomValue = IReferenceDocumentCustomValue;
156
167
  export interface IKnowledgeRagTextContentCustomValue {
157
168
  cover: boolean;
@@ -165,7 +176,7 @@ export interface IKnowledgeRagTextContentCustomValue {
165
176
  * 同步多端消息状态
166
177
  */
167
178
  export interface IMessagesSnapshotEvent extends IBaseEvent {
168
- messages: IMessageApi[];
179
+ messages: IMessage[];
169
180
  type: EventType.MessagesSnapshot;
170
181
  }
171
182
  /**
@@ -24,11 +24,13 @@
24
24
  * IN THE SOFTWARE.
25
25
  */ export var CustomEventName;
26
26
  (function(CustomEventName) {
27
+ CustomEventName["ArtifactsGenerated"] = "artifacts_generated";
27
28
  CustomEventName["FlowAgentEnd"] = "flow_agent_end";
28
29
  CustomEventName["FlowAgentResult"] = "flow_agent_result";
29
30
  CustomEventName["FlowAgentStart"] = "flow_agent_start";
30
31
  CustomEventName["FlowAgentUpdate"] = "flow_agent_update";
31
32
  CustomEventName["FlowAgentRestart"] = "flow_agent_restart";
33
+ CustomEventName["Info"] = "info";
32
34
  CustomEventName["KnowledgeRagEnd"] = "knowledge_rag_end";
33
35
  CustomEventName["KnowledgeRagResult"] = "knowledge_rag_result";
34
36
  CustomEventName["KnowledgeRagStart"] = "knowledge_rag_start";
@@ -276,7 +276,12 @@ export class FetchClient {
276
276
  var _this = this;
277
277
  return _async_to_generator(function*() {
278
278
  const { url, fetchConfig, requestConfig, controller } = _this.prepareRequest(config);
279
- const timeoutId = requestConfig.timeout && requestConfig.timeout > 0 ? setTimeout(()=>controller.abort(), requestConfig.timeout) : undefined;
279
+ // 超时与用户主动取消共用同一个 AbortController,需靠此标记区分
280
+ let timedOut = false;
281
+ const timeoutId = requestConfig.timeout && requestConfig.timeout > 0 ? setTimeout(()=>{
282
+ timedOut = true;
283
+ controller.abort();
284
+ }, requestConfig.timeout) : undefined;
280
285
  try {
281
286
  const fetchResponse = yield fetch(url, fetchConfig);
282
287
  if (timeoutId) {
@@ -319,9 +324,8 @@ export class FetchClient {
319
324
  };
320
325
  const validateStatus = requestConfig.validateStatus || _this.defaults.validateStatus;
321
326
  if (!validateStatus(fetchResponse.status)) {
322
- var _response_data_error, _response_data;
323
- const message = ((_response_data = response.data) === null || _response_data === void 0 ? void 0 : (_response_data_error = _response_data.error) === null || _response_data_error === void 0 ? void 0 : _response_data_error.message) || `Request failed with status code ${fetchResponse.status}`;
324
- throw createError(message, requestConfig, `ERR_BAD_RESPONSE`, response);
327
+ const { code, message } = resolveErrorPayload(response.data, `Request failed with status code ${fetchResponse.status}`);
328
+ throw createError(message, requestConfig, code, response);
325
329
  }
326
330
  let finalResponse = response;
327
331
  _this.interceptors.response.forEach((interceptor)=>{
@@ -341,23 +345,28 @@ export class FetchClient {
341
345
  }
342
346
  // 检查业务状态码(区别于 HTTP 状态码)
343
347
  const apiResponse = finalResponse.data;
348
+ // 无响应体(如 204 或空 body)时没有业务码可校验,直接放行
349
+ if (!apiResponse) {
350
+ return undefined;
351
+ }
344
352
  if (![
345
353
  0,
346
354
  'success'
347
355
  ].includes(apiResponse.code)) {
348
- throw createError(apiResponse.message, requestConfig, apiResponse.code, finalResponse);
356
+ const { code, message } = resolveErrorPayload(apiResponse, `Request failed with code ${apiResponse.code}`);
357
+ throw createError(message, requestConfig, code, finalResponse);
349
358
  }
350
359
  return apiResponse.data;
351
360
  } catch (error) {
352
361
  if (timeoutId) {
353
362
  clearTimeout(timeoutId);
354
363
  }
355
- // 用户手动取消请求
356
- if (error instanceof Error && error.name === 'AbortError') {
364
+ // 用户手动取消请求;超时同样表现为 AbortError,需作为异常上报
365
+ if (error instanceof Error && error.name === 'AbortError' && !timedOut) {
357
366
  console.warn('User canceled request', error.message);
358
367
  return;
359
368
  }
360
- const requestError = error.isAxiosError === true ? error : createError(error.message, requestConfig, error.code, undefined);
369
+ const requestError = timedOut ? createError(`timeout of ${requestConfig.timeout}ms exceeded`, requestConfig, 'ECONNABORTED', undefined) : error.isAxiosError === true ? error : createError(error.message, requestConfig, error.code, undefined);
361
370
  _this.dispatchError(requestError);
362
371
  throw _this.applyResponseErrorInterceptors(requestError);
363
372
  }
@@ -396,17 +405,14 @@ export class FetchClient {
396
405
  const fetchResponse = yield fetch(url, fetchConfig);
397
406
  const validateStatus = requestConfig.validateStatus || _this.defaults.validateStatus;
398
407
  if (!validateStatus(fetchResponse.status)) {
399
- let message = `Request failed with status code ${fetchResponse.status}`;
408
+ let errorData = null;
400
409
  try {
401
- var _errorData_error;
402
- const errorData = yield fetchResponse.json();
403
- if (errorData === null || errorData === void 0 ? void 0 : (_errorData_error = errorData.error) === null || _errorData_error === void 0 ? void 0 : _errorData_error.message) {
404
- message = errorData.error.message;
405
- }
410
+ errorData = yield fetchResponse.json();
406
411
  } catch (_error) {
407
- message = `Request failed with status code ${fetchResponse.status}`;
412
+ errorData = null;
408
413
  }
409
- const error = createError(message, requestConfig, `ERR_BAD_RESPONSE`, undefined);
414
+ const { code, message } = resolveErrorPayload(errorData, `Request failed with status code ${fetchResponse.status}`);
415
+ const error = createError(message, requestConfig, code, undefined);
410
416
  wrappedOnError(error);
411
417
  return;
412
418
  }
@@ -503,6 +509,64 @@ function buildURL(url, params) {
503
509
  }
504
510
  return url;
505
511
  }
512
+ /**
513
+ * 从错误响应体中解析业务错误信息
514
+ *
515
+ * 后端错误体存在多种形态,需逐一兼容:
516
+ * - 新版网关 / aidev 插件:`{ error: { code, message, data } }`
517
+ * - 旧版蓝鲸标准(如 blueapps 登录态失效):`{ result, code, message, data }`
518
+ * - DRF 原生异常:`{ detail }`
519
+ */ function resolveErrorPayload(body, fallbackMessage) {
520
+ var _record_error;
521
+ const fallbackCode = 'ERR_BAD_RESPONSE';
522
+ if (!body || typeof body !== 'object') {
523
+ return {
524
+ code: fallbackCode,
525
+ message: fallbackMessage
526
+ };
527
+ }
528
+ const record = body;
529
+ if ((_record_error = record.error) === null || _record_error === void 0 ? void 0 : _record_error.message) {
530
+ var _record_error_code;
531
+ return {
532
+ code: (_record_error_code = record.error.code) !== null && _record_error_code !== void 0 ? _record_error_code : fallbackCode,
533
+ data: record.error.data,
534
+ message: stringifyErrorMessage(record.error.message, fallbackMessage)
535
+ };
536
+ }
537
+ if (record.message) {
538
+ var _record_code;
539
+ return {
540
+ code: (_record_code = record.code) !== null && _record_code !== void 0 ? _record_code : fallbackCode,
541
+ data: record.data,
542
+ message: stringifyErrorMessage(record.message, fallbackMessage)
543
+ };
544
+ }
545
+ if (record.detail) {
546
+ var _record_code1;
547
+ return {
548
+ code: (_record_code1 = record.code) !== null && _record_code1 !== void 0 ? _record_code1 : fallbackCode,
549
+ data: record.data,
550
+ message: stringifyErrorMessage(record.detail, fallbackMessage)
551
+ };
552
+ }
553
+ var _record_code2;
554
+ return {
555
+ code: (_record_code2 = record.code) !== null && _record_code2 !== void 0 ? _record_code2 : fallbackCode,
556
+ data: record.data,
557
+ message: fallbackMessage
558
+ };
559
+ }
560
+ /** 错误 message 可能是字符串以外的结构(如字段校验字典),统一转成可读文案 */ function stringifyErrorMessage(message, fallbackMessage) {
561
+ if (typeof message === 'string') {
562
+ return message || fallbackMessage;
563
+ }
564
+ try {
565
+ return JSON.stringify(message) || fallbackMessage;
566
+ } catch (_error) {
567
+ return fallbackMessage;
568
+ }
569
+ }
506
570
  function createError(message, config, code, response) {
507
571
  const error = new Error(message);
508
572
  error.config = config;
@@ -12,6 +12,7 @@ export declare const useHttp: (options: IUseChatHelperOptions) => {
12
12
  onError: (handler: import("./fetch").GlobalErrorHandler, options?: import("./fetch").ErrorHandlerOptions) => void;
13
13
  agent: {
14
14
  getAgentInfo: (config?: import("./fetch").IRequestConfig) => Promise<import("..").IAgentInfo>;
15
+ getLlms: (params?: import("..").ILlmListQuery, config?: import("./fetch").IRequestConfig) => Promise<import("..").ILlmItem[]>;
15
16
  };
16
17
  session: {
17
18
  clearSession: (sessionCode: string, config?: import("./fetch").IRequestConfig) => Promise<unknown>;
@@ -38,12 +39,13 @@ export declare const useHttp: (options: IUseChatHelperOptions) => {
38
39
  uploadFile: (sessionCode: string, file: File, config?: import("./fetch").IRequestConfig) => Promise<{
39
40
  download_url?: string;
40
41
  }>;
42
+ getPvFileDownloadUrl: (sessionCode: string, path: string, options?: import("..").GetPvFileDownloadUrlOptions, config?: import("./fetch").IRequestConfig) => Promise<import("..").IPvFileDownloadUrlResult>;
41
43
  isResumeSession: (sessionCode: string, config?: import("./fetch").IRequestConfig) => Promise<boolean>;
42
44
  };
43
45
  message: {
44
46
  getMessages: (sessionCode: string, limit?: number, config?: import("./fetch").IRequestConfig) => Promise<import("..").IMessage[]>;
45
- plusMessage: (data: import("..").IMessage, config?: import("./fetch").IRequestConfig) => Promise<import("..").IActivityMessage | import("..").IAssistantMessage | import("..").IDeveloperMessage | import("..").IInterruptMessage | import("..").IGuideMessage | import("..").IHiddenAssistantMessage | import("..").IHiddenGuideMessage | import("..").IHiddenMessage | import("..").IHiddenSystemMessage | import("..").IHiddenUserMessage | import("..").IInfoMessage | import("..").IPauseMessage | import("..").IPlaceholderMessage | import("..").IReasoningMessage | import("..").ISystemMessage | import("..").ITemplateAssistantMessage | import("..").ITemplateGuideMessage | import("..").ITemplateHiddenMessage | import("..").ITemplateSystemMessage | import("..").ITemplateUserMessage | import("..").IToolMessage | import("..").IUserMessage>;
46
- modifyMessage: (data: import("..").IMessage, config?: import("./fetch").IRequestConfig) => Promise<import("..").IActivityMessage | import("..").IAssistantMessage | import("..").IDeveloperMessage | import("..").IInterruptMessage | import("..").IGuideMessage | import("..").IHiddenAssistantMessage | import("..").IHiddenGuideMessage | import("..").IHiddenMessage | import("..").IHiddenSystemMessage | import("..").IHiddenUserMessage | import("..").IInfoMessage | import("..").IPauseMessage | import("..").IPlaceholderMessage | import("..").IReasoningMessage | import("..").ISystemMessage | import("..").ITemplateAssistantMessage | import("..").ITemplateGuideMessage | import("..").ITemplateHiddenMessage | import("..").ITemplateSystemMessage | import("..").ITemplateUserMessage | import("..").IToolMessage | import("..").IUserMessage>;
47
+ plusMessage: (data: import("..").IMessage, config?: import("./fetch").IRequestConfig) => Promise<import("..").IActivityMessage | import("..").IAssistantMessage | import("..").IDeveloperMessage | import("..").IGuideMessage | import("..").IHiddenAssistantMessage | import("..").IHiddenGuideMessage | import("..").IHiddenMessage | import("..").IHiddenSystemMessage | import("..").IHiddenUserMessage | import("..").IInfoMessage | import("..").IPauseMessage | import("..").IPlaceholderMessage | import("..").IReasoningMessage | import("..").ISystemMessage | import("..").ITemplateAssistantMessage | import("..").ITemplateGuideMessage | import("..").ITemplateHiddenMessage | import("..").ITemplateSystemMessage | import("..").ITemplateUserMessage | import("..").IToolMessage | import("..").IUserMessage | import("..").IInterruptMessage>;
48
+ modifyMessage: (data: import("..").IMessage, config?: import("./fetch").IRequestConfig) => Promise<import("..").IActivityMessage | import("..").IAssistantMessage | import("..").IDeveloperMessage | import("..").IGuideMessage | import("..").IHiddenAssistantMessage | import("..").IHiddenGuideMessage | import("..").IHiddenMessage | import("..").IHiddenSystemMessage | import("..").IHiddenUserMessage | import("..").IInfoMessage | import("..").IPauseMessage | import("..").IPlaceholderMessage | import("..").IReasoningMessage | import("..").ISystemMessage | import("..").ITemplateAssistantMessage | import("..").ITemplateGuideMessage | import("..").ITemplateHiddenMessage | import("..").ITemplateSystemMessage | import("..").ITemplateUserMessage | import("..").IToolMessage | import("..").IUserMessage | import("..").IInterruptMessage>;
47
49
  deleteMessage: (id: string, config?: import("./fetch").IRequestConfig) => Promise<import("..").IMessage>;
48
50
  batchDeleteMessages: (ids: string[], config?: import("./fetch").IRequestConfig) => Promise<number>;
49
51
  shareMessages: (sessionCode: string, contentIds: string[], expiredAt?: number, config?: import("./fetch").IRequestConfig) => Promise<import("./module/message").IShareMessagesResponse>;
@@ -1,3 +1,4 @@
1
+ import type { ILlmItem, ILlmListQuery } from '../../agent/type';
1
2
  import type { FetchClient, IRequestConfig } from '../fetch';
2
3
  /**
3
4
  * agent 相关 http 接口
@@ -6,4 +7,5 @@ import type { FetchClient, IRequestConfig } from '../fetch';
6
7
  */
7
8
  export declare const useAgent: (fetchClient: FetchClient) => {
8
9
  getAgentInfo: (config?: IRequestConfig) => Promise<import("../../agent/type").IAgentInfo>;
10
+ getLlms: (params?: ILlmListQuery, config?: IRequestConfig) => Promise<ILlmItem[]>;
9
11
  };
@@ -22,7 +22,7 @@
22
22
  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
23
23
  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24
24
  * IN THE SOFTWARE.
25
- */ import { transferAgentInfoApi2AgentInfo } from '../transform/agent.ts.js';
25
+ */ import { transferAgentInfoApi2AgentInfo, transferLlmListApi2LlmItems } from '../transform/agent.ts.js';
26
26
  /**
27
27
  * agent 相关 http 接口
28
28
  * @param fetchClient - 请求客户端
@@ -30,7 +30,24 @@
30
30
  */ export const useAgent = (fetchClient)=>{
31
31
  // 获取 agent 信息
32
32
  const getAgentInfo = (config)=>fetchClient.get('agent/info/', undefined, config).then(transferAgentInfoApi2AgentInfo);
33
+ /**
34
+ * 获取当前空间可用模型列表(公开 + 空间授权 + 用户权限交集)
35
+ * @param params 查询参数;未传 llm_type 时默认 chat.completion
36
+ */ const getLlms = (params, config)=>{
37
+ var _params_llm_type;
38
+ const query = {
39
+ llm_type: (_params_llm_type = params === null || params === void 0 ? void 0 : params.llm_type) !== null && _params_llm_type !== void 0 ? _params_llm_type : 'chat.completion'
40
+ };
41
+ if (params === null || params === void 0 ? void 0 : params.fuzzy) {
42
+ query.fuzzy = params.fuzzy;
43
+ }
44
+ if (params === null || params === void 0 ? void 0 : params.supports) {
45
+ query.supports = params.supports;
46
+ }
47
+ return fetchClient.get('llms/', query, config).then(transferLlmListApi2LlmItems);
48
+ };
33
49
  return {
34
- getAgentInfo
50
+ getAgentInfo,
51
+ getLlms
35
52
  };
36
53
  };
@@ -7,6 +7,7 @@ import type { FetchClient } from '../fetch';
7
7
  export declare const useModule: (fetchClient: FetchClient) => {
8
8
  agent: {
9
9
  getAgentInfo: (config?: import("../fetch").IRequestConfig) => Promise<import("../..").IAgentInfo>;
10
+ getLlms: (params?: import("../..").ILlmListQuery, config?: import("../fetch").IRequestConfig) => Promise<import("../..").ILlmItem[]>;
10
11
  };
11
12
  session: {
12
13
  clearSession: (sessionCode: string, config?: import("../fetch").IRequestConfig) => Promise<unknown>;
@@ -33,12 +34,13 @@ export declare const useModule: (fetchClient: FetchClient) => {
33
34
  uploadFile: (sessionCode: string, file: File, config?: import("../fetch").IRequestConfig) => Promise<{
34
35
  download_url?: string;
35
36
  }>;
37
+ getPvFileDownloadUrl: (sessionCode: string, path: string, options?: import("../..").GetPvFileDownloadUrlOptions, config?: import("../fetch").IRequestConfig) => Promise<import("../..").IPvFileDownloadUrlResult>;
36
38
  isResumeSession: (sessionCode: string, config?: import("../fetch").IRequestConfig) => Promise<boolean>;
37
39
  };
38
40
  message: {
39
41
  getMessages: (sessionCode: string, limit?: number, config?: import("../fetch").IRequestConfig) => Promise<import("../..").IMessage[]>;
40
- plusMessage: (data: import("../..").IMessage, config?: import("../fetch").IRequestConfig) => Promise<import("../..").IActivityMessage | import("../..").IAssistantMessage | import("../..").IDeveloperMessage | import("../..").IInterruptMessage | import("../..").IGuideMessage | import("../..").IHiddenAssistantMessage | import("../..").IHiddenGuideMessage | import("../..").IHiddenMessage | import("../..").IHiddenSystemMessage | import("../..").IHiddenUserMessage | import("../..").IInfoMessage | import("../..").IPauseMessage | import("../..").IPlaceholderMessage | import("../..").IReasoningMessage | import("../..").ISystemMessage | import("../..").ITemplateAssistantMessage | import("../..").ITemplateGuideMessage | import("../..").ITemplateHiddenMessage | import("../..").ITemplateSystemMessage | import("../..").ITemplateUserMessage | import("../..").IToolMessage | import("../..").IUserMessage>;
41
- modifyMessage: (data: import("../..").IMessage, config?: import("../fetch").IRequestConfig) => Promise<import("../..").IActivityMessage | import("../..").IAssistantMessage | import("../..").IDeveloperMessage | import("../..").IInterruptMessage | import("../..").IGuideMessage | import("../..").IHiddenAssistantMessage | import("../..").IHiddenGuideMessage | import("../..").IHiddenMessage | import("../..").IHiddenSystemMessage | import("../..").IHiddenUserMessage | import("../..").IInfoMessage | import("../..").IPauseMessage | import("../..").IPlaceholderMessage | import("../..").IReasoningMessage | import("../..").ISystemMessage | import("../..").ITemplateAssistantMessage | import("../..").ITemplateGuideMessage | import("../..").ITemplateHiddenMessage | import("../..").ITemplateSystemMessage | import("../..").ITemplateUserMessage | import("../..").IToolMessage | import("../..").IUserMessage>;
42
+ plusMessage: (data: import("../..").IMessage, config?: import("../fetch").IRequestConfig) => Promise<import("../..").IActivityMessage | import("../..").IAssistantMessage | import("../..").IDeveloperMessage | import("../..").IGuideMessage | import("../..").IHiddenAssistantMessage | import("../..").IHiddenGuideMessage | import("../..").IHiddenMessage | import("../..").IHiddenSystemMessage | import("../..").IHiddenUserMessage | import("../..").IInfoMessage | import("../..").IPauseMessage | import("../..").IPlaceholderMessage | import("../..").IReasoningMessage | import("../..").ISystemMessage | import("../..").ITemplateAssistantMessage | import("../..").ITemplateGuideMessage | import("../..").ITemplateHiddenMessage | import("../..").ITemplateSystemMessage | import("../..").ITemplateUserMessage | import("../..").IToolMessage | import("../..").IUserMessage | import("../..").IInterruptMessage>;
43
+ modifyMessage: (data: import("../..").IMessage, config?: import("../fetch").IRequestConfig) => Promise<import("../..").IActivityMessage | import("../..").IAssistantMessage | import("../..").IDeveloperMessage | import("../..").IGuideMessage | import("../..").IHiddenAssistantMessage | import("../..").IHiddenGuideMessage | import("../..").IHiddenMessage | import("../..").IHiddenSystemMessage | import("../..").IHiddenUserMessage | import("../..").IInfoMessage | import("../..").IPauseMessage | import("../..").IPlaceholderMessage | import("../..").IReasoningMessage | import("../..").ISystemMessage | import("../..").ITemplateAssistantMessage | import("../..").ITemplateGuideMessage | import("../..").ITemplateHiddenMessage | import("../..").ITemplateSystemMessage | import("../..").ITemplateUserMessage | import("../..").IToolMessage | import("../..").IUserMessage | import("../..").IInterruptMessage>;
42
44
  deleteMessage: (id: string, config?: import("../fetch").IRequestConfig) => Promise<import("../..").IMessage>;
43
45
  batchDeleteMessages: (ids: string[], config?: import("../fetch").IRequestConfig) => Promise<number>;
44
46
  shareMessages: (sessionCode: string, contentIds: string[], expiredAt?: number, config?: import("../fetch").IRequestConfig) => Promise<import("./message").IShareMessagesResponse>;