@blueking/chat-helper 0.0.12-beta.9 → 0.0.12

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 (37) hide show
  1. package/README.md +21 -7
  2. package/dist/agent/type.d.ts +84 -0
  3. package/dist/agent/type.ts.js +5 -1
  4. package/dist/agent/use-agent.d.ts +573 -360
  5. package/dist/agent/use-agent.ts.js +365 -25
  6. package/dist/event/ag-ui.d.ts +4 -1
  7. package/dist/event/ag-ui.ts.js +106 -7
  8. package/dist/event/type.d.ts +15 -3
  9. package/dist/event/type.ts.js +2 -0
  10. package/dist/http/fetch/fetch.spec.d.ts +1 -0
  11. package/dist/http/fetch/fetch.ts.js +106 -22
  12. package/dist/http/index.d.ts +13 -7
  13. package/dist/http/module/agent.d.ts +2 -0
  14. package/dist/http/module/agent.ts.js +19 -2
  15. package/dist/http/module/index.d.ts +13 -7
  16. package/dist/http/module/message.d.ts +3 -3
  17. package/dist/http/module/message.ts.js +4 -3
  18. package/dist/http/module/session.d.ts +10 -5
  19. package/dist/http/module/session.ts.js +60 -3
  20. package/dist/http/transform/agent.d.ts +9 -1
  21. package/dist/http/transform/agent.spec.d.ts +1 -0
  22. package/dist/http/transform/agent.ts.js +32 -2
  23. package/dist/http/transform/message.ts.js +17 -5
  24. package/dist/index.d.ts +3844 -2720
  25. package/dist/message/type.d.ts +30 -3
  26. package/dist/message/type.ts.js +16 -0
  27. package/dist/message/use-message.d.ts +685 -385
  28. package/dist/session/index.d.ts +1 -0
  29. package/dist/session/index.ts.js +2 -1
  30. package/dist/session/pv-file-upload.d.ts +7 -0
  31. package/dist/session/pv-file-upload.spec.d.ts +1 -0
  32. package/dist/session/pv-file-upload.ts.js +64 -0
  33. package/dist/session/type.d.ts +57 -0
  34. package/dist/session/use-session.d.ts +2539 -1933
  35. package/dist/session/use-session.spec.d.ts +1 -0
  36. package/dist/session/use-session.ts.js +117 -10
  37. package/package.json +4 -2
@@ -35,8 +35,46 @@
35
35
  }
36
36
  return obj;
37
37
  }
38
- import { transferMessageApi2Message } from '../http/transform/index.ts.js';
39
- import { ActivityType, MessageRole, MessageStatus, MessageType } from '../message/index.ts.js';
38
+ function _object_spread(target) {
39
+ for(var i = 1; i < arguments.length; i++){
40
+ var source = arguments[i] != null ? arguments[i] : {};
41
+ var ownKeys = Object.keys(source);
42
+ if (typeof Object.getOwnPropertySymbols === "function") {
43
+ ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
44
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
45
+ }));
46
+ }
47
+ ownKeys.forEach(function(key) {
48
+ _define_property(target, key, source[key]);
49
+ });
50
+ }
51
+ return target;
52
+ }
53
+ function ownKeys(object, enumerableOnly) {
54
+ var keys = Object.keys(object);
55
+ if (Object.getOwnPropertySymbols) {
56
+ var symbols = Object.getOwnPropertySymbols(object);
57
+ if (enumerableOnly) {
58
+ symbols = symbols.filter(function(sym) {
59
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
60
+ });
61
+ }
62
+ keys.push.apply(keys, symbols);
63
+ }
64
+ return keys;
65
+ }
66
+ function _object_spread_props(target, source) {
67
+ source = source != null ? source : {};
68
+ if (Object.getOwnPropertyDescriptors) {
69
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
70
+ } else {
71
+ ownKeys(Object(source)).forEach(function(key) {
72
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
73
+ });
74
+ }
75
+ return target;
76
+ }
77
+ import { ActivityType, MessageRole, MessageStatus, MessageType, formatEventTimestampToCreatedAt, resolveMessageCreatedAt } from '../message/index.ts.js';
40
78
  import { CustomEventName, EventType, FlowTaskState, RunFinishedOutcomeType } from './type.ts.js';
41
79
  /**
42
80
  * AGUI 协议
@@ -50,18 +88,38 @@ import { CustomEventName, EventType, FlowTaskState, RunFinishedOutcomeType } fro
50
88
  * 处理活动快照事件
51
89
  * 记录活动的完整状态
52
90
  */ handleActivitySnapshotEvent(event) {
53
- const message = this.messageModule.getCurrentLoadingMessage();
91
+ if (event.activityType === ActivityType.Info) {
92
+ const message = this.messageModule.getMessageByMessageId(event.messageId);
93
+ if ((message === null || message === void 0 ? void 0 : message.role) === MessageRole.Info) {
94
+ message.content = event.content;
95
+ }
96
+ return;
97
+ }
54
98
  if (event.activityType === ActivityType.Interrupt) {
99
+ const message = this.messageModule.getCurrentLoadingMessage();
55
100
  if ((message === null || message === void 0 ? void 0 : message.role) === MessageRole.Interrupt) {
56
101
  message.content = event.content;
57
102
  message.status = MessageStatus.Complete;
58
103
  }
59
104
  }
60
105
  }
106
+ handleArtifactsGeneratedCustomEvent(event) {
107
+ const message = this.messageModule.list.value.findLast((item)=>item.role === MessageRole.Assistant);
108
+ if (message) {
109
+ var _message;
110
+ const value = event.value;
111
+ var _property;
112
+ (_property = (_message = message).property) !== null && _property !== void 0 ? _property : _message.property = {};
113
+ message.property.artifacts = value.artifacts;
114
+ }
115
+ }
61
116
  /**
62
117
  * 处理自定义事件
63
118
  */ handleCustomEvent(event) {
64
119
  switch(event.name){
120
+ case CustomEventName.ArtifactsGenerated:
121
+ this.handleArtifactsGeneratedCustomEvent(event);
122
+ break;
65
123
  case CustomEventName.FlowAgentStart:
66
124
  this.handleFlowAgentStartCustomEvent(event);
67
125
  break;
@@ -98,6 +156,9 @@ import { CustomEventName, EventType, FlowTaskState, RunFinishedOutcomeType } fro
98
156
  case CustomEventName.FlowAgentUpdate:
99
157
  this.handleFlowAgentUpdateCustomEvent(event);
100
158
  break;
159
+ case CustomEventName.Info:
160
+ this.handleInfoCustomEvent(event);
161
+ break;
101
162
  default:
102
163
  break;
103
164
  }
@@ -171,6 +232,15 @@ import { CustomEventName, EventType, FlowTaskState, RunFinishedOutcomeType } fro
171
232
  }
172
233
  });
173
234
  }
235
+ handleInfoCustomEvent(event) {
236
+ const value = event.value;
237
+ this.messageModule.plusMessage({
238
+ role: MessageRole.Info,
239
+ messageId: value.messageId,
240
+ content: value.content,
241
+ status: MessageStatus.Complete
242
+ });
243
+ }
174
244
  /**
175
245
  * 自定义事件 处理意图识别结束
176
246
  */ handleKnowledgeRagEndCustomEvent(_event) {
@@ -211,10 +281,10 @@ import { CustomEventName, EventType, FlowTaskState, RunFinishedOutcomeType } fro
211
281
  }
212
282
  /**
213
283
  * 处理消息快照事件
214
- * 用于同步多端消息状态
284
+ * 用于同步多端消息状态;chat_completion 首帧会全量返回历史消息(含 created_at)
215
285
  */ handleMessagesSnapshotEvent(event) {
216
286
  if (event.messages && event.messages.length > 0) {
217
- this.messageModule.list.value = event.messages.map(transferMessageApi2Message);
287
+ this.messageModule.list.value = event.messages.map(normalizeSnapshotMessage);
218
288
  }
219
289
  }
220
290
  /**
@@ -253,17 +323,24 @@ import { CustomEventName, EventType, FlowTaskState, RunFinishedOutcomeType } fro
253
323
  * 处理运行完成事件
254
324
  */ handleRunFinishedEvent(event) {
255
325
  var _event_outcome, _event_outcome1;
326
+ const createdAt = formatEventTimestampToCreatedAt(event.timestamp);
256
327
  const message = this.messageModule.getCurrentLoadingMessage();
257
328
  if (message) {
258
329
  message.status = MessageStatus.Complete;
259
330
  }
331
+ // 本轮流式消息在落库前没有 createdAt,用 RUN_FINISHED.timestamp 转成 ISO 后补上;已有时间的历史消息不覆盖
332
+ if (createdAt) {
333
+ applyCreatedAtToCurrentRun(this.messageModule.list.value, createdAt);
334
+ }
260
335
  // 如果是中断消息,则创建一个中断消息
261
336
  if (((_event_outcome = event.outcome) === null || _event_outcome === void 0 ? void 0 : _event_outcome.type) === RunFinishedOutcomeType.Interrupt) {
262
- this.messageModule.plusMessage({
337
+ this.messageModule.plusMessage(_object_spread({
263
338
  role: MessageRole.Interrupt,
264
339
  content: event,
265
340
  status: MessageStatus.Pending
266
- });
341
+ }, createdAt ? {
342
+ createdAt
343
+ } : {}));
267
344
  }
268
345
  // 二次返回,直接更新消息内容
269
346
  if (((_event_outcome1 = event.outcome) === null || _event_outcome1 === void 0 ? void 0 : _event_outcome1.type) === RunFinishedOutcomeType.Success && (message === null || message === void 0 ? void 0 : message.role) === MessageRole.Interrupt) {
@@ -349,7 +426,14 @@ import { CustomEventName, EventType, FlowTaskState, RunFinishedOutcomeType } fro
349
426
  }
350
427
  /**
351
428
  * 处理文本消息开始事件
429
+ * 断线续传时会重放缓存事件:同 messageId 已存在则重置内容,避免重复气泡/文本翻倍
352
430
  */ handleTextMessageStartEvent(event) {
431
+ const existing = this.messageModule.getMessageByMessageId(event.messageId);
432
+ if (existing) {
433
+ existing.content = '';
434
+ existing.status = MessageStatus.Streaming;
435
+ return;
436
+ }
353
437
  this.messageModule.plusMessage({
354
438
  role: event.role,
355
439
  content: '',
@@ -580,3 +664,18 @@ import { CustomEventName, EventType, FlowTaskState, RunFinishedOutcomeType } fro
580
664
  this.onStartCallback = params === null || params === void 0 ? void 0 : params.onStart;
581
665
  }
582
666
  }
667
+ /** chat_completion 快照可能是 camelCase 或 REST snake_case,统一落到 createdAt */ function normalizeSnapshotMessage(message) {
668
+ const createdAt = resolveMessageCreatedAt(message);
669
+ return createdAt ? _object_spread_props(_object_spread({}, message), {
670
+ createdAt
671
+ }) : message;
672
+ }
673
+ /** 从列表尾部向前,给本轮尚未带时间的消息补 createdAt,遇到已有时间的历史消息即停 */ function applyCreatedAtToCurrentRun(messages, createdAt) {
674
+ for(let index = messages.length - 1; index >= 0; index--){
675
+ const item = messages[index];
676
+ if (item.createdAt) {
677
+ break;
678
+ }
679
+ item.createdAt = createdAt;
680
+ }
681
+ }
@@ -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,7 +116,13 @@ 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 {
125
+ /** 事件时间,毫秒时间戳;RUN_FINISHED 会转成 ISO 字符串写入消息 createdAt */
118
126
  timestamp?: number;
119
127
  type: EventType;
120
128
  }
@@ -125,7 +133,7 @@ export interface IBaseEvent {
125
133
  export interface ICustomEvent extends IBaseEvent {
126
134
  name: CustomEventName;
127
135
  type: EventType.Custom;
128
- value: IFlowAgentEndCustomValue | IFlowAgentResultCustomValue | IFlowAgentStartCustomValue | IFlowAgentRestartCustomValue | IKnowledgeRagResultCustomValue | IKnowledgeRagTextContentCustomValue | IReferenceDocumentCustomValue | ITempMessageCustomValue | IApprovalResultCustomValue;
136
+ value: IArtifactsGeneratedCustomValue | IFlowAgentEndCustomValue | IFlowAgentResultCustomValue | IFlowAgentStartCustomValue | IFlowAgentRestartCustomValue | IInfoCustomValue | IKnowledgeRagResultCustomValue | IKnowledgeRagTextContentCustomValue | IReferenceDocumentCustomValue | ITempMessageCustomValue | IApprovalResultCustomValue;
129
137
  }
130
138
  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
139
  export type IFlowAgentEndCustomValue = {
@@ -152,6 +160,10 @@ export type IFlowAgentStartCustomValue = {
152
160
  task_id: string;
153
161
  }[];
154
162
  export type IFlowAgentRestartCustomValue = IFlowAgentStartCustomValue;
163
+ export interface IInfoCustomValue {
164
+ content: string;
165
+ messageId: string;
166
+ }
155
167
  export type IKnowledgeRagResultCustomValue = IReferenceDocumentCustomValue;
156
168
  export interface IKnowledgeRagTextContentCustomValue {
157
169
  cover: boolean;
@@ -165,7 +177,7 @@ export interface IKnowledgeRagTextContentCustomValue {
165
177
  * 同步多端消息状态
166
178
  */
167
179
  export interface IMessagesSnapshotEvent extends IBaseEvent {
168
- messages: IMessageApi[];
180
+ messages: IMessage[];
169
181
  type: EventType.MessagesSnapshot;
170
182
  }
171
183
  /**
@@ -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";
@@ -0,0 +1 @@
1
+ export {};
@@ -240,6 +240,10 @@ export class FetchClient {
240
240
  if (isStream && !headers.has('Accept')) {
241
241
  headers.set('Accept', 'text/event-stream');
242
242
  }
243
+ // multipart 必须由浏览器带 boundary;默认 application/json 会破坏 FormData
244
+ if (body instanceof FormData) {
245
+ headers.delete('Content-Type');
246
+ }
243
247
  if (body !== undefined && body !== null) {
244
248
  var _headers_get;
245
249
  if (requestConfig.transformRequest) {
@@ -276,7 +280,12 @@ export class FetchClient {
276
280
  var _this = this;
277
281
  return _async_to_generator(function*() {
278
282
  const { url, fetchConfig, requestConfig, controller } = _this.prepareRequest(config);
279
- const timeoutId = requestConfig.timeout && requestConfig.timeout > 0 ? setTimeout(()=>controller.abort(), requestConfig.timeout) : undefined;
283
+ // 超时与用户主动取消共用同一个 AbortController,需靠此标记区分
284
+ let timedOut = false;
285
+ const timeoutId = requestConfig.timeout && requestConfig.timeout > 0 ? setTimeout(()=>{
286
+ timedOut = true;
287
+ controller.abort();
288
+ }, requestConfig.timeout) : undefined;
280
289
  try {
281
290
  const fetchResponse = yield fetch(url, fetchConfig);
282
291
  if (timeoutId) {
@@ -319,9 +328,8 @@ export class FetchClient {
319
328
  };
320
329
  const validateStatus = requestConfig.validateStatus || _this.defaults.validateStatus;
321
330
  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);
331
+ const { code, message } = resolveErrorPayload(response.data, `Request failed with status code ${fetchResponse.status}`);
332
+ throw createError(message, requestConfig, code, response);
325
333
  }
326
334
  let finalResponse = response;
327
335
  _this.interceptors.response.forEach((interceptor)=>{
@@ -341,23 +349,28 @@ export class FetchClient {
341
349
  }
342
350
  // 检查业务状态码(区别于 HTTP 状态码)
343
351
  const apiResponse = finalResponse.data;
352
+ // 无响应体(如 204 或空 body)时没有业务码可校验,直接放行
353
+ if (!apiResponse) {
354
+ return undefined;
355
+ }
344
356
  if (![
345
357
  0,
346
358
  'success'
347
359
  ].includes(apiResponse.code)) {
348
- throw createError(apiResponse.message, requestConfig, apiResponse.code, finalResponse);
360
+ const { code, message } = resolveErrorPayload(apiResponse, `Request failed with code ${apiResponse.code}`);
361
+ throw createError(message, requestConfig, code, finalResponse);
349
362
  }
350
363
  return apiResponse.data;
351
364
  } catch (error) {
352
365
  if (timeoutId) {
353
366
  clearTimeout(timeoutId);
354
367
  }
355
- // 用户手动取消请求
356
- if (error instanceof Error && error.name === 'AbortError') {
368
+ // 用户手动取消请求;超时同样表现为 AbortError,需作为异常上报
369
+ if (error instanceof Error && error.name === 'AbortError' && !timedOut) {
357
370
  console.warn('User canceled request', error.message);
358
371
  return;
359
372
  }
360
- const requestError = error.isAxiosError === true ? error : createError(error.message, requestConfig, error.code, undefined);
373
+ 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
374
  _this.dispatchError(requestError);
362
375
  throw _this.applyResponseErrorInterceptors(requestError);
363
376
  }
@@ -390,33 +403,44 @@ export class FetchClient {
390
403
  const wrappedConfig = _object_spread_props(_object_spread({}, config), {
391
404
  onError: wrappedOnError
392
405
  });
393
- const { url, fetchConfig, requestConfig } = _this.prepareRequest(wrappedConfig, true);
406
+ const { url, fetchConfig, requestConfig, controller } = _this.prepareRequest(wrappedConfig, true);
407
+ let reader;
408
+ const cancelReaderOnAbort = ()=>{
409
+ // pipeThrough(TextDecoderStream) 后,仅 abort fetch signal 在部分环境下不会立刻打断 reader.read()
410
+ void (reader === null || reader === void 0 ? void 0 : reader.cancel().catch(()=>{}));
411
+ };
394
412
  try {
395
413
  var _wrappedConfig_onStart, _fetchResponse_body;
396
414
  const fetchResponse = yield fetch(url, fetchConfig);
397
415
  const validateStatus = requestConfig.validateStatus || _this.defaults.validateStatus;
398
416
  if (!validateStatus(fetchResponse.status)) {
399
- let message = `Request failed with status code ${fetchResponse.status}`;
417
+ let errorData = null;
400
418
  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
- }
419
+ errorData = yield fetchResponse.json();
406
420
  } catch (_error) {
407
- message = `Request failed with status code ${fetchResponse.status}`;
421
+ errorData = null;
408
422
  }
409
- const error = createError(message, requestConfig, `ERR_BAD_RESPONSE`, undefined);
423
+ const { code, message } = resolveErrorPayload(errorData, `Request failed with status code ${fetchResponse.status}`);
424
+ const error = createError(message, requestConfig, code, undefined);
410
425
  wrappedOnError(error);
411
426
  return;
412
427
  }
413
428
  (_wrappedConfig_onStart = wrappedConfig.onStart) === null || _wrappedConfig_onStart === void 0 ? void 0 : _wrappedConfig_onStart.call(wrappedConfig);
414
- const reader = (_fetchResponse_body = fetchResponse.body) === null || _fetchResponse_body === void 0 ? void 0 : _fetchResponse_body.pipeThrough(new window.TextDecoderStream()).getReader();
429
+ reader = (_fetchResponse_body = fetchResponse.body) === null || _fetchResponse_body === void 0 ? void 0 : _fetchResponse_body.pipeThrough(new window.TextDecoderStream()).getReader();
415
430
  if (!reader) {
416
431
  const error = new Error('IResponse body is not readable');
417
432
  wrappedOnError(error);
418
433
  return;
419
434
  }
435
+ controller.signal.addEventListener('abort', cancelReaderOnAbort, {
436
+ once: true
437
+ });
438
+ if (controller.signal.aborted) {
439
+ var _wrappedConfig_onDone;
440
+ cancelReaderOnAbort();
441
+ (_wrappedConfig_onDone = wrappedConfig.onDone) === null || _wrappedConfig_onDone === void 0 ? void 0 : _wrappedConfig_onDone.call(wrappedConfig);
442
+ return;
443
+ }
420
444
  // 缓存跨行分片数据
421
445
  let temp = '';
422
446
  const isJson = (str)=>{
@@ -431,8 +455,8 @@ export class FetchClient {
431
455
  while(true){
432
456
  const { value, done } = yield reader.read();
433
457
  if (done) {
434
- var _wrappedConfig_onDone;
435
- (_wrappedConfig_onDone = wrappedConfig.onDone) === null || _wrappedConfig_onDone === void 0 ? void 0 : _wrappedConfig_onDone.call(wrappedConfig);
458
+ var _wrappedConfig_onDone1;
459
+ (_wrappedConfig_onDone1 = wrappedConfig.onDone) === null || _wrappedConfig_onDone1 === void 0 ? void 0 : _wrappedConfig_onDone1.call(wrappedConfig);
436
460
  break;
437
461
  }
438
462
  const values = (temp + value.toString()).split('\n');
@@ -451,13 +475,15 @@ export class FetchClient {
451
475
  } catch (error) {
452
476
  if (error instanceof Error) {
453
477
  if (error.name === 'AbortError') {
454
- var _wrappedConfig_onDone1;
455
- (_wrappedConfig_onDone1 = wrappedConfig.onDone) === null || _wrappedConfig_onDone1 === void 0 ? void 0 : _wrappedConfig_onDone1.call(wrappedConfig);
478
+ var _wrappedConfig_onDone2;
479
+ (_wrappedConfig_onDone2 = wrappedConfig.onDone) === null || _wrappedConfig_onDone2 === void 0 ? void 0 : _wrappedConfig_onDone2.call(wrappedConfig);
456
480
  return;
457
481
  }
458
482
  wrappedOnError(error);
459
483
  }
460
484
  throw error;
485
+ } finally{
486
+ controller.signal.removeEventListener('abort', cancelReaderOnAbort);
461
487
  }
462
488
  })();
463
489
  }
@@ -503,6 +529,64 @@ function buildURL(url, params) {
503
529
  }
504
530
  return url;
505
531
  }
532
+ /**
533
+ * 从错误响应体中解析业务错误信息
534
+ *
535
+ * 后端错误体存在多种形态,需逐一兼容:
536
+ * - 新版网关 / aidev 插件:`{ error: { code, message, data } }`
537
+ * - 旧版蓝鲸标准(如 blueapps 登录态失效):`{ result, code, message, data }`
538
+ * - DRF 原生异常:`{ detail }`
539
+ */ function resolveErrorPayload(body, fallbackMessage) {
540
+ var _record_error;
541
+ const fallbackCode = 'ERR_BAD_RESPONSE';
542
+ if (!body || typeof body !== 'object') {
543
+ return {
544
+ code: fallbackCode,
545
+ message: fallbackMessage
546
+ };
547
+ }
548
+ const record = body;
549
+ if ((_record_error = record.error) === null || _record_error === void 0 ? void 0 : _record_error.message) {
550
+ var _record_error_code;
551
+ return {
552
+ code: (_record_error_code = record.error.code) !== null && _record_error_code !== void 0 ? _record_error_code : fallbackCode,
553
+ data: record.error.data,
554
+ message: stringifyErrorMessage(record.error.message, fallbackMessage)
555
+ };
556
+ }
557
+ if (record.message) {
558
+ var _record_code;
559
+ return {
560
+ code: (_record_code = record.code) !== null && _record_code !== void 0 ? _record_code : fallbackCode,
561
+ data: record.data,
562
+ message: stringifyErrorMessage(record.message, fallbackMessage)
563
+ };
564
+ }
565
+ if (record.detail) {
566
+ var _record_code1;
567
+ return {
568
+ code: (_record_code1 = record.code) !== null && _record_code1 !== void 0 ? _record_code1 : fallbackCode,
569
+ data: record.data,
570
+ message: stringifyErrorMessage(record.detail, fallbackMessage)
571
+ };
572
+ }
573
+ var _record_code2;
574
+ return {
575
+ code: (_record_code2 = record.code) !== null && _record_code2 !== void 0 ? _record_code2 : fallbackCode,
576
+ data: record.data,
577
+ message: fallbackMessage
578
+ };
579
+ }
580
+ /** 错误 message 可能是字符串以外的结构(如字段校验字典),统一转成可读文案 */ function stringifyErrorMessage(message, fallbackMessage) {
581
+ if (typeof message === 'string') {
582
+ return message || fallbackMessage;
583
+ }
584
+ try {
585
+ return JSON.stringify(message) || fallbackMessage;
586
+ } catch (_error) {
587
+ return fallbackMessage;
588
+ }
589
+ }
506
590
  function createError(message, config, code, response) {
507
591
  const error = new Error(message);
508
592
  error.config = config;
@@ -12,10 +12,16 @@ 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>;
18
- getSessions: (config?: import("./fetch").IRequestConfig) => Promise<import("..").ISession<unknown, unknown>[]>;
19
+ getSessions: (params?: import("..").ISessionListParams, config?: import("./fetch").IRequestConfig) => Promise<{
20
+ page: number;
21
+ numPages: number;
22
+ count: number;
23
+ results: import("..").ISession<unknown, unknown>[];
24
+ }>;
19
25
  plusSession: (data: import("..").ISession, config?: import("./fetch").IRequestConfig) => Promise<import("..").ISession<unknown, unknown>>;
20
26
  modifySession: (data: import("..").ISession, config?: import("./fetch").IRequestConfig) => Promise<import("..").ISession<unknown, unknown>>;
21
27
  deleteSession: (sessionCode: string, config?: import("./fetch").IRequestConfig) => Promise<unknown>;
@@ -30,15 +36,15 @@ export declare const useHttp: (options: IUseChatHelperOptions) => {
30
36
  }>;
31
37
  getSessionFeedbackReasons: (rate: number, config?: import("./fetch").IRequestConfig) => Promise<string[]>;
32
38
  renameSession: (sessionCode: string, config?: import("./fetch").IRequestConfig) => Promise<import("..").ISession<unknown, unknown>>;
33
- uploadFile: (sessionCode: string, file: File, config?: import("./fetch").IRequestConfig) => Promise<{
34
- download_url?: string;
35
- }>;
39
+ uploadFile: (sessionCode: string, file: File, config?: import("./fetch").IRequestConfig) => Promise<import("..").ILegacyUploadFileResult>;
40
+ uploadPvFiles: (sessionCode: string, files: File[], config?: import("./fetch").IRequestConfig) => Promise<import("..").IPvFileUploadResult>;
41
+ getPvFileDownloadUrl: (sessionCode: string, path: string, options?: import("..").GetPvFileDownloadUrlOptions, config?: import("./fetch").IRequestConfig) => Promise<import("..").IPvFileDownloadUrlResult>;
36
42
  isResumeSession: (sessionCode: string, config?: import("./fetch").IRequestConfig) => Promise<boolean>;
37
43
  };
38
44
  message: {
39
- 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>;
45
+ getMessages: (sessionCode: string, limit?: number, config?: import("./fetch").IRequestConfig, fuzzy?: string) => Promise<import("..").IMessage[]>;
46
+ 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>;
47
+ 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
48
  deleteMessage: (id: string, config?: import("./fetch").IRequestConfig) => Promise<import("..").IMessage>;
43
49
  batchDeleteMessages: (ids: string[], config?: import("./fetch").IRequestConfig) => Promise<number>;
44
50
  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,10 +7,16 @@ 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>;
13
- getSessions: (config?: import("../fetch").IRequestConfig) => Promise<import("../..").ISession<unknown, unknown>[]>;
14
+ getSessions: (params?: import("../..").ISessionListParams, config?: import("../fetch").IRequestConfig) => Promise<{
15
+ page: number;
16
+ numPages: number;
17
+ count: number;
18
+ results: import("../..").ISession<unknown, unknown>[];
19
+ }>;
14
20
  plusSession: (data: import("../..").ISession, config?: import("../fetch").IRequestConfig) => Promise<import("../..").ISession<unknown, unknown>>;
15
21
  modifySession: (data: import("../..").ISession, config?: import("../fetch").IRequestConfig) => Promise<import("../..").ISession<unknown, unknown>>;
16
22
  deleteSession: (sessionCode: string, config?: import("../fetch").IRequestConfig) => Promise<unknown>;
@@ -25,15 +31,15 @@ export declare const useModule: (fetchClient: FetchClient) => {
25
31
  }>;
26
32
  getSessionFeedbackReasons: (rate: number, config?: import("../fetch").IRequestConfig) => Promise<string[]>;
27
33
  renameSession: (sessionCode: string, config?: import("../fetch").IRequestConfig) => Promise<import("../..").ISession<unknown, unknown>>;
28
- uploadFile: (sessionCode: string, file: File, config?: import("../fetch").IRequestConfig) => Promise<{
29
- download_url?: string;
30
- }>;
34
+ uploadFile: (sessionCode: string, file: File, config?: import("../fetch").IRequestConfig) => Promise<import("../..").ILegacyUploadFileResult>;
35
+ uploadPvFiles: (sessionCode: string, files: File[], config?: import("../fetch").IRequestConfig) => Promise<import("../..").IPvFileUploadResult>;
36
+ getPvFileDownloadUrl: (sessionCode: string, path: string, options?: import("../..").GetPvFileDownloadUrlOptions, config?: import("../fetch").IRequestConfig) => Promise<import("../..").IPvFileDownloadUrlResult>;
31
37
  isResumeSession: (sessionCode: string, config?: import("../fetch").IRequestConfig) => Promise<boolean>;
32
38
  };
33
39
  message: {
34
- getMessages: (sessionCode: string, limit?: number, config?: import("../fetch").IRequestConfig) => Promise<import("../..").IMessage[]>;
35
- 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>;
36
- 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>;
40
+ getMessages: (sessionCode: string, limit?: number, config?: import("../fetch").IRequestConfig, fuzzy?: string) => Promise<import("../..").IMessage[]>;
41
+ 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>;
42
+ 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>;
37
43
  deleteMessage: (id: string, config?: import("../fetch").IRequestConfig) => Promise<import("../..").IMessage>;
38
44
  batchDeleteMessages: (ids: string[], config?: import("../fetch").IRequestConfig) => Promise<number>;
39
45
  shareMessages: (sessionCode: string, contentIds: string[], expiredAt?: number, config?: import("../fetch").IRequestConfig) => Promise<import("./message").IShareMessagesResponse>;