@ray-js/t-agent-plugin-aistream 0.2.0-beta-4 → 0.2.0-beta-5

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.
@@ -651,6 +651,7 @@ export declare enum FileFormat {
651
651
  SWEEPER_MAP = 6
652
652
  }
653
653
  export declare enum AIStreamErrorCode {
654
+ AIStreamError = -1,
654
655
  OK = 200,
655
656
  BadRequest = 400,
656
657
  Unauthenticated = 401,
@@ -828,6 +829,29 @@ export type CheckConnectResult = {
828
829
  /** 连接的唯一标识 */
829
830
  connectionId?: string;
830
831
  };
832
+ export type IsConnectedParams = {
833
+ /** client 类型: 1-作为设备代理, 2-作为 App */
834
+ clientType: number;
835
+ /** 代理的设备ID, clientType == 1 时必传 */
836
+ deviceId?: string;
837
+ success?: (params: {
838
+ /** 是否已连接 */
839
+ connected: boolean;
840
+ /** 通道连接状态: 0-初始化,1-连接中,2-鉴权中,3-已连接,4-被云端断开,5-主动关闭 */
841
+ state: number;
842
+ /** 连接的唯一标识 */
843
+ connectionId?: string;
844
+ }) => void;
845
+ fail?: (params: {
846
+ errorMsg: string;
847
+ errorCode: string | number;
848
+ innerError: {
849
+ errorCode: string | number;
850
+ errorMsg: string;
851
+ };
852
+ }) => void;
853
+ complete?: () => void;
854
+ };
831
855
  /**
832
856
  *@description 发起通道连接,若此前已连接会直接回调成功
833
857
  */
@@ -118,6 +118,7 @@ export let FileFormat = /*#__PURE__*/function (FileFormat) {
118
118
  return FileFormat;
119
119
  }({});
120
120
  export let AIStreamErrorCode = /*#__PURE__*/function (AIStreamErrorCode) {
121
+ AIStreamErrorCode[AIStreamErrorCode["AIStreamError"] = -1] = "AIStreamError";
121
122
  AIStreamErrorCode[AIStreamErrorCode["OK"] = 200] = "OK";
122
123
  AIStreamErrorCode[AIStreamErrorCode["BadRequest"] = 400] = "BadRequest";
123
124
  AIStreamErrorCode[AIStreamErrorCode["Unauthenticated"] = 401] = "Unauthenticated";
@@ -51,6 +51,7 @@ export declare class AIStreamSession {
51
51
  sessionId: string | null;
52
52
  sendDataChannels: string[];
53
53
  revDataChannels: string[];
54
+ disposed: boolean;
54
55
  private activeEvent?;
55
56
  private activeObserver?;
56
57
  private promise;
@@ -6,9 +6,12 @@ import "core-js/modules/esnext.iterator.for-each.js";
6
6
  import "core-js/modules/esnext.iterator.map.js";
7
7
  import "core-js/modules/web.dom-collections.iterator.js";
8
8
  import { AIStreamErrorCode, BizTag, ConnectClientType, ConnectState, EventType, SessionState } from '../AIStreamTypes';
9
- import { closeSession, connect, createSession, disconnect, getCurrentHomeInfo, isConnectSync, queryAgentToken, registerRecordAmplitudes, sendEventChatBreak, sendEventEnd, sendEventPayloadEnd, sendEventStart, sendImageData, sendTextData, startRecordAndSendAudioData, stopRecordAndSendAudioData, unregisterVoiceAmplitudes } from './ttt';
9
+ import { closeSession, connect, createSession, disconnect, getCurrentHomeInfo, isConnected, queryAgentToken, registerRecordAmplitudes, sendEventChatBreak, sendEventEnd, sendEventPayloadEnd, sendEventStart, sendImageData, sendTextData, startRecordAndSendAudioData, stopRecordAndSendAudioData, unregisterVoiceAmplitudes } from './ttt';
10
10
  import { AIStreamObserver, AIStreamObserverPool } from './observer';
11
11
  import { isAbortError } from '@ray-js/t-agent';
12
+ import logger from './logger';
13
+ import { AIStreamConnectionError, AIStreamEventError } from './errors';
14
+ import { tryCatch } from './misc';
12
15
  export class AIStreamClient {
13
16
  constructor() {
14
17
  _defineProperty(this, "pool", new AIStreamObserverPool());
@@ -38,8 +41,8 @@ export class AIStreamConnection {
38
41
  session._onStateChanged(entry);
39
42
  }
40
43
  });
41
- if (entry.body.connectState === ConnectState.DISCONNECTED || entry.body.connectState === ConnectState.CLOSED) {
42
- // 事件触发的时候,只做清理
44
+ if (entry.body.connectState === ConnectState.DISCONNECTED || entry.body.connectState === ConnectState.CLOSED || entry.body.connectState === ConnectState.CONNECTING || entry.body.connectState === ConnectState.AUTHORIZING) {
45
+ // 断开事件触发时只做清理,因为连接已经关掉了
43
46
  this.cleanup();
44
47
  }
45
48
  }
@@ -47,9 +50,6 @@ export class AIStreamConnection {
47
50
  this.activeSessions.forEach(session => {
48
51
  if (session.sessionId && session.sessionId === entry.body.sessionId) {
49
52
  session._onStateChanged(entry);
50
- if (entry.body.sessionState === SessionState.CLOSED || entry.body.sessionState === SessionState.CREATE_FAILED) {
51
- this.activeSessions.delete(session);
52
- }
53
53
  }
54
54
  });
55
55
  }
@@ -61,39 +61,52 @@ export class AIStreamConnection {
61
61
  if (this.promise) {
62
62
  return this.promise;
63
63
  }
64
- const result = isConnectSync(this.options);
65
-
66
- // 监听断开事件,重置 state & 清理
67
- if (!this.observer) {
68
- this.observer = new AIStreamObserver(this.onStateChanged, this.pool);
69
- this.observer.observe({
70
- connectionState: true,
71
- sessionState: true
72
- });
73
- }
74
- if (result.connected) {
75
- this.state = result.state;
76
- this.connectionId = result.connectionId;
77
- return Promise.resolve();
78
- }
64
+ const observe = () => {
65
+ if (!this.observer) {
66
+ this.observer = new AIStreamObserver(this.onStateChanged, this.pool);
67
+ this.observer.observe({
68
+ connectionState: true,
69
+ sessionState: true
70
+ });
71
+ }
72
+ };
79
73
  this.promise = (async () => {
80
- // 调用 SDK connect
81
- const res = await connect(this.options);
82
- this.connectionId = res.connectionId;
83
- this.state = ConnectState.CONNECTED;
84
- this.promise = null;
74
+ {
75
+ const [error, result] = await tryCatch(() => isConnected(this.options));
76
+ if (error) {
77
+ throw new AIStreamConnectionError(error.message, error.code || AIStreamErrorCode.AIStreamError);
78
+ }
79
+ if (result.connected) {
80
+ this.state = result.state;
81
+ this.connectionId = result.connectionId;
82
+ observe();
83
+ return;
84
+ }
85
+ }
86
+ {
87
+ // 调用 SDK connect
88
+ const [error, result] = await tryCatch(() => connect(this.options));
89
+ if (error) {
90
+ throw new AIStreamConnectionError(error.message, error.code || AIStreamErrorCode.AIStreamError);
91
+ }
92
+ this.connectionId = result.connectionId;
93
+ this.state = ConnectState.CONNECTED;
94
+ this.promise = null;
95
+ observe();
96
+ }
85
97
  })();
86
98
  return this.promise;
87
99
  }
88
100
  cleanup() {
89
101
  var _this$observer;
102
+ logger.debug('AIStreamConnection cleanup');
90
103
  (_this$observer = this.observer) === null || _this$observer === void 0 || _this$observer.disconnect();
91
104
  this.observer = null;
92
105
  this.state = ConnectState.CLOSED;
93
106
  this.connectionId = null;
94
107
  this.promise = null;
95
108
  this.activeSessions.forEach(s => s.cleanup());
96
- this.activeSessions.clear();
109
+ // session 不清空,closeSession 被调用时才清空
97
110
  }
98
111
  createSession(options) {
99
112
  const session = new AIStreamSession(this, this.pool, options);
@@ -129,6 +142,7 @@ export class AIStreamSession {
129
142
  _defineProperty(this, "sessionId", null);
130
143
  _defineProperty(this, "sendDataChannels", []);
131
144
  _defineProperty(this, "revDataChannels", []);
145
+ _defineProperty(this, "disposed", false);
132
146
  _defineProperty(this, "promise", null);
133
147
  _defineProperty(this, "_onStateChanged", entry => {
134
148
  var _this$activeEvent;
@@ -203,8 +217,11 @@ export class AIStreamSession {
203
217
  }
204
218
  async startEvent() {
205
219
  let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
220
+ if (this.disposed) {
221
+ throw new AIStreamEventError('Event has been disposed', AIStreamErrorCode.AIStreamError);
222
+ }
206
223
  if (this.activeEvent) {
207
- throw new Error('Cannot start a new event while another is active');
224
+ throw new AIStreamEventError('Cannot start a new event while another is active', AIStreamErrorCode.AIStreamError);
208
225
  }
209
226
  await this.ensureSession();
210
227
  const {
@@ -251,12 +268,14 @@ export class AIStreamSession {
251
268
  }
252
269
  cleanupEvent() {
253
270
  var _this$activeObserver, _this$activeEvent4;
271
+ logger.debug('AIStreamSession cleanupEvent');
254
272
  (_this$activeObserver = this.activeObserver) === null || _this$activeObserver === void 0 || _this$activeObserver.disconnect();
255
273
  this.activeObserver = null;
256
274
  (_this$activeEvent4 = this.activeEvent) === null || _this$activeEvent4 === void 0 || _this$activeEvent4.emit('close');
257
275
  this.activeEvent = null;
258
276
  }
259
277
  cleanup() {
278
+ logger.debug('AIStreamSession cleanup');
260
279
  this.cleanupEvent();
261
280
  this.sessionId = null;
262
281
  this.sendDataChannels = [];
@@ -265,10 +284,10 @@ export class AIStreamSession {
265
284
 
266
285
  // 会话关闭清理
267
286
  async close() {
287
+ logger.debug('AIStreamSession close');
288
+ this.disposed = true;
268
289
  await this.connection.closeSession(this);
269
- if (this.sessionId) {
270
- this.cleanup();
271
- }
290
+ this.cleanup();
272
291
  }
273
292
  }
274
293
  export class AIStreamEvent {
@@ -289,13 +308,13 @@ export class AIStreamEvent {
289
308
  findFirstCode(type) {
290
309
  const code = this.sendDataChannels.find(code => code.startsWith(type));
291
310
  if (!code) {
292
- throw new Error("No available data code for type: ".concat(type));
311
+ throw new AIStreamEventError("No available data code for type: ".concat(type), AIStreamErrorCode.AIStreamError);
293
312
  }
294
313
  return code;
295
314
  }
296
315
  write(chunk) {
297
316
  if (this.closed) {
298
- throw new Error('Cannot write to a closed event');
317
+ throw new AIStreamEventError('Cannot write to a closed event', AIStreamErrorCode.AIStreamError);
299
318
  }
300
319
  const dataChannel = chunk.dataChannel || this.findFirstCode(chunk.type);
301
320
  let promise = this.chains[dataChannel];
@@ -341,11 +360,11 @@ export class AIStreamEvent {
341
360
  }
342
361
  stream(source) {
343
362
  if (this.closed) {
344
- throw new Error('Cannot stream to a closed event');
363
+ throw new AIStreamEventError('Cannot stream to a closed event', AIStreamErrorCode.AIStreamError);
345
364
  }
346
365
  const dataChannel = source.dataChannel || this.findFirstCode(source.type);
347
366
  if (this.streams[dataChannel]) {
348
- throw new Error("".concat(dataChannel, " stream already exists"));
367
+ throw new AIStreamEventError("".concat(dataChannel, " stream already exists"), AIStreamErrorCode.AIStreamError);
349
368
  }
350
369
  const stream = {
351
370
  dataChannel,
@@ -353,7 +372,7 @@ export class AIStreamEvent {
353
372
  started: false,
354
373
  start: async () => {
355
374
  if (this.closed) {
356
- throw new Error('Cannot stream to a closed event');
375
+ throw new AIStreamEventError('Cannot stream to a closed event', AIStreamErrorCode.AIStreamError);
357
376
  }
358
377
  if (stream.started) {
359
378
  return;
@@ -8,13 +8,17 @@ import "core-js/modules/esnext.iterator.map.js";
8
8
  import "core-js/modules/web.dom-collections.iterator.js";
9
9
  import { mock } from './mock';
10
10
  import { EmitterEvent, generateId } from '@ray-js/t-agent';
11
- import { BizCode, EventType, ReceivedTextPacketEof, ReceivedTextPacketType, StreamFlag } from '../AIStreamTypes';
11
+ import { BizCode, ConnectState, EventType, ReceivedTextPacketEof, ReceivedTextPacketType, StreamFlag } from '../AIStreamTypes';
12
12
  import AbortController from './abort';
13
13
  function splitString(input) {
14
14
  return input.match(/[a-zA-Z0-9]+\s*|[\u4e00-\u9fff]+\s*|[^\w\s\u4e00-\u9fff]+\s*|[\s]+/g) || [];
15
15
  }
16
16
  mock.data.set('sessionMap', new Map());
17
17
  const getSession = (sessionId, eventId) => {
18
+ const connection = getCurrentConnection();
19
+ if (!connection) {
20
+ throw new Error('not connected');
21
+ }
18
22
  const map = mock.data.get('sessionMap');
19
23
  const session = map.get(sessionId);
20
24
  if (!session) {
@@ -38,6 +42,21 @@ mock.hooks.hook('getMiniAppConfig', context => {
38
42
  const getCurrentConnection = () => {
39
43
  return mock.data.get('currentConnection');
40
44
  };
45
+ mock.hooks.hook('isConnected', context => {
46
+ const connection = getCurrentConnection();
47
+ if (connection) {
48
+ context.result = {
49
+ connected: true,
50
+ state: ConnectState.CONNECTED,
51
+ connectionId: connection.connectionId
52
+ };
53
+ } else {
54
+ context.result = {
55
+ connected: false,
56
+ state: ConnectState.DISCONNECTED
57
+ };
58
+ }
59
+ });
41
60
  mock.hooks.hook('connect', context => {
42
61
  let connection = getCurrentConnection();
43
62
  if (connection) {
@@ -82,14 +101,25 @@ const dispatch = (type, detail) => {
82
101
  }));
83
102
  };
84
103
  mock.hooks.hook('createSession', context => {
104
+ const connection = getCurrentConnection();
105
+ if (!connection) {
106
+ throw new Error('not connected');
107
+ }
85
108
  const map = mock.data.get('sessionMap');
86
109
  const session = {
110
+ closed: false,
87
111
  sessionId: generateId(),
88
112
  sendDataChannels: ['audio', 'video', 'text', 'image'],
89
113
  revDataChannels: ['text', 'audio'],
90
114
  currentEvent: null,
91
115
  replyText: function (streamFlag) {
92
116
  let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
117
+ if (session.closed) {
118
+ return;
119
+ }
120
+ if (!session.currentEvent) {
121
+ throw new Error('replyText event not exists');
122
+ }
93
123
  dispatch('onTextReceived', {
94
124
  dataChannel: 'text',
95
125
  sessionIdList: [session.sessionId],
@@ -98,6 +128,9 @@ mock.hooks.hook('createSession', context => {
98
128
  });
99
129
  },
100
130
  replyEvent: eventType => {
131
+ if (session.closed) {
132
+ return;
133
+ }
101
134
  if (!session.currentEvent) {
102
135
  throw new Error('replyEvent event not exists');
103
136
  }
@@ -115,13 +148,31 @@ mock.hooks.hook('createSession', context => {
115
148
  revDataChannels: session.revDataChannels
116
149
  };
117
150
 
151
+ // 用于测试断开连接;
118
152
  // setTimeout(() => {
119
153
  // dispatch('onConnectStateChanged', {
120
154
  // connectionId: getCurrentConnection().connectionId,
121
155
  // connectState: ConnectState.DISCONNECTED,
122
156
  // code: 200,
123
157
  // });
124
- // }, 1000);
158
+ // mock.data.set('currentConnection', null);
159
+ // const map: Map<string, MockSession> = mock.data.get('sessionMap');
160
+ // map.forEach(s => {
161
+ // s.closed = true;
162
+ // });
163
+ // mock.data.set('sessionMap', new Map());
164
+ // }, 3000);
165
+
166
+ // 用于测试断开会话
167
+ // setTimeout(() => {
168
+ // dispatch('onSessionStateChanged', {
169
+ // sessionId: session.sessionId,
170
+ // sessionState: SessionState.CREATE_FAILED,
171
+ // code: 200,
172
+ // });
173
+ // session.closed = true;
174
+ // map.delete(session.sessionId);
175
+ // }, 3000);
125
176
  });
126
177
  mock.hooks.hook('closeSession', context => {
127
178
  const map = mock.data.get('sessionMap');
@@ -0,0 +1,26 @@
1
+ export declare class BaseError extends Error {
2
+ message: string;
3
+ code: string | number;
4
+ constructor(message: string, code: string | number);
5
+ toString(): string;
6
+ }
7
+ export declare class TTTError extends BaseError {
8
+ message: string;
9
+ code: string | number;
10
+ constructor(message: string, code: string | number);
11
+ }
12
+ export declare class AIStreamConnectionError extends BaseError {
13
+ message: string;
14
+ code: string | number;
15
+ constructor(message: string, code: string | number);
16
+ }
17
+ export declare class AIStreamSessionError extends BaseError {
18
+ message: string;
19
+ code: string | number;
20
+ constructor(message: string, code: string | number);
21
+ }
22
+ export declare class AIStreamEventError extends BaseError {
23
+ message: string;
24
+ code: string | number;
25
+ constructor(message: string, code: string | number);
26
+ }
@@ -0,0 +1,42 @@
1
+ export class BaseError extends Error {
2
+ constructor(message, code) {
3
+ super(message);
4
+ this.message = message;
5
+ this.code = code;
6
+ }
7
+ toString() {
8
+ return "".concat(this.name, "(").concat(this.code, "): ").concat(this.message);
9
+ }
10
+ }
11
+ export class TTTError extends BaseError {
12
+ constructor(message, code) {
13
+ super(message, code);
14
+ this.message = message;
15
+ this.code = code;
16
+ this.name = 'TTTError';
17
+ }
18
+ }
19
+ export class AIStreamConnectionError extends BaseError {
20
+ constructor(message, code) {
21
+ super(message, code);
22
+ this.message = message;
23
+ this.code = code;
24
+ this.name = 'AIStreamConnectionError';
25
+ }
26
+ }
27
+ export class AIStreamSessionError extends BaseError {
28
+ constructor(message, code) {
29
+ super(message, code);
30
+ this.message = message;
31
+ this.code = code;
32
+ this.name = 'AIStreamSessionError';
33
+ }
34
+ }
35
+ export class AIStreamEventError extends BaseError {
36
+ constructor(message, code) {
37
+ super(message, code);
38
+ this.message = message;
39
+ this.code = code;
40
+ this.name = 'AIStreamEventError';
41
+ }
42
+ }
@@ -11,12 +11,6 @@ interface AsyncTTTFnParams<P> {
11
11
  }) => void;
12
12
  [key: string]: any;
13
13
  }
14
- export declare class TTTError extends Error {
15
- message: string;
16
- errorCode: string | number;
17
- constructor(message: string, errorCode: string | number);
18
- toString(): string;
19
- }
20
14
  export declare const getEnableMock: () => boolean;
21
15
  export declare const setEnableMock: (enable: boolean) => boolean;
22
16
  export declare function promisify<T extends AsyncTTTFnParams<any>>(fn: (options: any) => void, enableMock?: boolean): (options?: Omit<T, 'success' | 'fail'>) => Promise<Parameters<NonNullable<T["success"]>>[0]>;
@@ -2,16 +2,7 @@ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
2
  import { isDevTools } from './ttt';
3
3
  import logger from './logger';
4
4
  import { mock } from './mock';
5
- export class TTTError extends Error {
6
- constructor(message, errorCode) {
7
- super(message);
8
- this.message = message;
9
- this.errorCode = errorCode;
10
- }
11
- toString() {
12
- return "TTTError: ".concat(this.message, ", errorCode: ").concat(this.errorCode);
13
- }
14
- }
5
+ import { TTTError } from './errors';
15
6
  let callId = 100000;
16
7
  export const getEnableMock = () => {
17
8
  try {
@@ -44,7 +35,7 @@ export function promisify(fn) {
44
35
  return options => {
45
36
  return new Promise((_resolve, _reject) => {
46
37
  if (!fn) {
47
- _reject(new Error('fn is not a function'));
38
+ _reject(new Error('promisify: fn is not a function'));
48
39
  }
49
40
  const id = callId++;
50
41
  logger.debug("TTT call #".concat(id, " %c").concat(fn.name), 'background: blue; color: white', options);
@@ -11,10 +11,6 @@ export declare class AIStreamSessionError extends Error {
11
11
  readonly code: number;
12
12
  constructor(message: string, code: number);
13
13
  }
14
- export declare class AIStreamConnectionError extends Error {
15
- readonly code: number;
16
- constructor(message: string, code: number);
17
- }
18
14
  export declare function sendBlocksToAIStream(params: SendBlocksToAIStreamParams): {
19
15
  response: StreamResponse;
20
16
  metaPromise: Promise<Record<string, any>>;
@@ -6,6 +6,7 @@ import { ReadableStream } from 'web-streams-polyfill';
6
6
  import { AIStreamAttributePayloadType, AIStreamAttributeType, AIStreamChatSysWorkflow, ConnectState, FileFormat, ReceivedTextPacketEof, ReceivedTextPacketType, SessionState, StreamFlag } from '../AIStreamTypes';
7
7
  import { EmitterEvent, generateId, safeParseJSON, StreamResponse } from '@ray-js/t-agent';
8
8
  import { tryCatch } from './misc';
9
+ import { AIStreamConnectionError } from './errors';
9
10
  const mimeTypeToFormatMap = {
10
11
  'video/mp4': FileFormat.MP4,
11
12
  'text/json': FileFormat.JSON,
@@ -19,13 +20,6 @@ export class AIStreamSessionError extends Error {
19
20
  this.code = code;
20
21
  }
21
22
  }
22
- export class AIStreamConnectionError extends Error {
23
- constructor(message, code) {
24
- super(message);
25
- this.name = 'AIStreamConnectionError';
26
- this.code = code;
27
- }
28
- }
29
23
  export function sendBlocksToAIStream(params) {
30
24
  const {
31
25
  session,
@@ -48,6 +42,7 @@ export function sendBlocksToAIStream(params) {
48
42
  'sys.workflow': audioEmitter ? AIStreamChatSysWorkflow.ASR_LLM : AIStreamChatSysWorkflow.LLM
49
43
  }, params.attribute);
50
44
  let canceled = false;
45
+ let closed = false;
51
46
  let event = null;
52
47
  let metaResolve;
53
48
  const metaPromise = new Promise(resolve => {
@@ -56,7 +51,7 @@ export function sendBlocksToAIStream(params) {
56
51
  const stream = new ReadableStream({
57
52
  async start(controller) {
58
53
  const enqueue = part => {
59
- if (canceled) {
54
+ if (canceled || closed) {
60
55
  return;
61
56
  }
62
57
  controller.enqueue(part);
@@ -71,6 +66,7 @@ export function sendBlocksToAIStream(params) {
71
66
  }));
72
67
  if (error) {
73
68
  controller.error(error);
69
+ closed = true;
74
70
  controller.close();
75
71
  return;
76
72
  }
@@ -155,7 +151,7 @@ export function sendBlocksToAIStream(params) {
155
151
  audioId = null;
156
152
  }
157
153
  } else if (data.type === 'sessionState') {
158
- if (data.body.sessionState === SessionState.CLOSED) {
154
+ if (data.body.sessionState === SessionState.CLOSED || data.body.sessionState === SessionState.CREATE_FAILED) {
159
155
  enqueue({
160
156
  type: 'error',
161
157
  error: new AIStreamSessionError('Session closed', data.body.code),
@@ -164,7 +160,7 @@ export function sendBlocksToAIStream(params) {
164
160
  });
165
161
  }
166
162
  } else if (data.type === 'connectionState') {
167
- if (data.body.connectState === ConnectState.DISCONNECTED) {
163
+ if (data.body.connectState === ConnectState.DISCONNECTED || data.body.connectState === ConnectState.CLOSED) {
168
164
  enqueue({
169
165
  type: 'error',
170
166
  error: new AIStreamConnectionError('Connection disconnected', data.body.code),
@@ -174,8 +170,15 @@ export function sendBlocksToAIStream(params) {
174
170
  }
175
171
  }
176
172
  });
173
+ event.on('close', () => {
174
+ if (!canceled && !closed) {
175
+ // 当取消后,不需要关闭控制器
176
+ controller.close();
177
+ }
178
+ });
177
179
  event.on('finish', () => {
178
180
  if (!canceled) {
181
+ closed = true;
179
182
  // 当取消后,不需要关闭控制器
180
183
  controller.close();
181
184
  }
@@ -1,4 +1,4 @@
1
- import { ApiRequestByAtopParams, ApiRequestByHighwayParams, AudioBody, AuthorizeParams, AuthorizePolicyStatusParams, CanIUseRouterParams, CheckConnectParams, CheckConnectResult, CloseSessionParams, ConnectParams, ConnectStateBody, CreateSessionParams, DeleteRecordListParams, DisconnectParams, EventBody, EventChannelMessageParams, GetAppInfoParams, GetCurrentHomeInfoParams, GetMiniAppConfigParams, GetAccountInfoParams, ImageBody, InsertRecordParams, NavigateToMiniProgramParams, OpenInnerH5Params, OpenMiniWidgetParams, QueryAgentTokenParams, QueryRecordListParams, RecordAmplitudesBody, RegisterChannelParams, RouterParams, SendEventChatBreakParams, SendEventEndParams, SendEventPayloadEndParams, SendEventStartParams, SendImageDataParams, SendTextDataParams, SessionStateBody, StartRecordAndSendAudioDataParams, StopRecordAndSendAudioDataParams, TextBody, UpdateRecordParams } from '../AIStreamTypes';
1
+ import { ApiRequestByAtopParams, ApiRequestByHighwayParams, AudioBody, AuthorizeParams, AuthorizePolicyStatusParams, CanIUseRouterParams, CloseSessionParams, ConnectParams, ConnectStateBody, CreateSessionParams, DeleteRecordListParams, DisconnectParams, EventBody, EventChannelMessageParams, GetAppInfoParams, GetCurrentHomeInfoParams, GetMiniAppConfigParams, GetAccountInfoParams, ImageBody, InsertRecordParams, NavigateToMiniProgramParams, OpenInnerH5Params, OpenMiniWidgetParams, QueryAgentTokenParams, QueryRecordListParams, RecordAmplitudesBody, RegisterChannelParams, RouterParams, SendEventChatBreakParams, SendEventEndParams, SendEventPayloadEndParams, SendEventStartParams, SendImageDataParams, SendTextDataParams, SessionStateBody, StartRecordAndSendAudioDataParams, StopRecordAndSendAudioDataParams, TextBody, UpdateRecordParams, IsConnectedParams } from '../AIStreamTypes';
2
2
  export declare const getMiniAppConfig: (options?: Omit<GetMiniAppConfigParams, "success" | "fail"> | undefined) => Promise<{
3
3
  config: any;
4
4
  }>;
@@ -52,7 +52,11 @@ export declare const authorizePolicyStatus: (options?: Omit<AuthorizePolicyStatu
52
52
  export declare const registerChannel: (options?: Omit<RegisterChannelParams, "success" | "fail"> | undefined) => Promise<null>;
53
53
  export declare const listenReceiveMessage: (listener: (params: EventChannelMessageParams) => void) => () => void;
54
54
  export declare const openMiniWidget: (options?: Omit<OpenMiniWidgetParams, "success" | "fail"> | undefined) => Promise<null>;
55
- export declare const isConnectSync: (params: CheckConnectParams) => CheckConnectResult;
55
+ export declare const isConnected: (options?: Omit<IsConnectedParams, "success" | "fail"> | undefined) => Promise<{
56
+ connected: boolean;
57
+ state: number;
58
+ connectionId?: string | undefined;
59
+ }>;
56
60
  export declare const connect: (options?: Omit<ConnectParams, "success" | "fail"> | undefined) => Promise<{
57
61
  connectionId: string;
58
62
  }>;
package/dist/utils/ttt.js CHANGED
@@ -1,6 +1,4 @@
1
1
  import { listening, promisify } from './promisify';
2
- import { ConnectClientType, ConnectState } from '../AIStreamTypes';
3
- import { generateId } from '@ray-js/t-agent';
4
2
  export const getMiniAppConfig = promisify(ty.getMiniAppConfig, true);
5
3
  export const getAccountInfo = promisify(ty.getAccountInfo);
6
4
  export const isDevTools = () => {
@@ -30,17 +28,7 @@ ty.authorizePolicyStatus);
30
28
  export const registerChannel = promisify(ty.registerChannel);
31
29
  export const listenReceiveMessage = listening(ty.onReceiveMessage, ty.offReceiveMessage);
32
30
  export const openMiniWidget = promisify(ty.openMiniWidget);
33
- export const isConnectSync = params => {
34
- if (isDevTools()) {
35
- return {
36
- connected: true,
37
- state: ConnectState.CONNECTED,
38
- connectionId: generateId(),
39
- clientType: ConnectClientType.APP
40
- };
41
- }
42
- return ty.aistream.isConnectedSync(params);
43
- };
31
+ export const isConnected = promisify(ty.aistream.isConnected, true);
44
32
  export const connect = promisify(ty.aistream.connect, true);
45
33
  export const disconnect = promisify(ty.aistream.disconnect, true);
46
34
  export const queryAgentToken = promisify(ty.aistream.queryAgentToken, true);
@@ -5,7 +5,6 @@ import "core-js/modules/es.array.flat.js";
5
5
  import "core-js/modules/es.array.reverse.js";
6
6
  import "core-js/modules/es.array.unscopables.flat.js";
7
7
  import "core-js/modules/esnext.iterator.constructor.js";
8
- import "core-js/modules/esnext.iterator.for-each.js";
9
8
  import "core-js/modules/esnext.iterator.map.js";
10
9
  import "core-js/modules/web.dom-collections.iterator.js";
11
10
  import { BubbleTileStatus, ChatMessageStatus, createHooks } from '@ray-js/t-agent';
@@ -449,9 +448,7 @@ export function withAIStream() {
449
448
  clearAllMessages: async () => {
450
449
  // 删除内存中的消息
451
450
  const messages = agent.session.messages.values();
452
- Array.from(messages).forEach(message => {
453
- message.remove();
454
- });
451
+ await Promise.all(Array.from(messages).map(message => message.remove()));
455
452
  // 清空缓存的数据
456
453
  const historyStore = getHistoryStore();
457
454
  if (historyStore) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ray-js/t-agent-plugin-aistream",
3
- "version": "0.2.0-beta-4",
3
+ "version": "0.2.0-beta-5",
4
4
  "author": "Tuya.inc",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -35,5 +35,5 @@
35
35
  "devDependencies": {
36
36
  "@types/url-parse": "^1.4.11"
37
37
  },
38
- "gitHead": "1728f8a1cac6b2ca53e506e06171808fbf38efdc"
38
+ "gitHead": "a0beda17c8e1c3ef81c718300c02a23d88a3ee4a"
39
39
  }