@ray-js/t-agent-plugin-aistream 0.2.6-beta-1 → 0.2.6-beta-3

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.
@@ -1117,6 +1117,8 @@ export type QueryAgentTokenParams = {
1117
1117
  agentToken: string;
1118
1118
  /** 业务配置 */
1119
1119
  bizConfig: BizConfig;
1120
+ /** 额外字段, JSON 字符串 */
1121
+ extParams?: string;
1120
1122
  }) => void;
1121
1123
  fail?: (params: {
1122
1124
  errorMsg: string;
@@ -1208,6 +1210,7 @@ export type DisconnectParams = {
1208
1210
  export type SendEventStartParams = {
1209
1211
  /** 会话 id */
1210
1212
  sessionId: string;
1213
+ eventIdPrefix?: string;
1211
1214
  /** 扩展属性 */
1212
1215
  userData?: Attribute[];
1213
1216
  success?: (params: {
@@ -33,6 +33,7 @@ export interface AsrAgentOptions {
33
33
  maxDuration?: number;
34
34
  };
35
35
  enableLog?: boolean;
36
+ eventIdPrefix?: string;
36
37
  }
37
38
  export declare enum AsrAgentStatus {
38
39
  PENDING = "pending",
@@ -182,6 +182,7 @@ export class AsrAgent {
182
182
  'asr.enableVad': 'false'
183
183
  };
184
184
  const [startEventError, activeEvent] = await tryCatch(() => activeSession.startEvent({
185
+ eventIdPrefix: this.options.eventIdPrefix,
185
186
  userData: [{
186
187
  type: AIStreamAttributeType.AI_CHAT,
187
188
  payloadType: AIStreamAttributePayloadType.STRING,
@@ -45,6 +45,7 @@ interface AIStreamSessionOptions {
45
45
  interface AIStreamEventOptions {
46
46
  signal?: AbortSignal;
47
47
  userData?: Attribute[];
48
+ eventIdPrefix?: string;
48
49
  }
49
50
  export declare class AIStreamSession {
50
51
  private connection;
@@ -57,6 +58,10 @@ export declare class AIStreamSession {
57
58
  private activeEvent?;
58
59
  private activeObserver?;
59
60
  private promise;
61
+ tokenExtParamsResolvable: import("./object").Resolvable<{
62
+ [key: string]: any;
63
+ chatId?: string | undefined;
64
+ }>;
60
65
  constructor(connection: AIStreamConnection, pool: AIStreamObserverPool, options: AIStreamSessionOptions);
61
66
  ensureSession(): Promise<void>;
62
67
  _onStateChanged: (entry: AIStreamDataEntry) => void;
@@ -10,9 +10,10 @@ import "core-js/modules/web.dom-collections.iterator.js";
10
10
  import { AIStreamAttributeType, AIStreamErrorCode, AIStreamServerErrorCode, BizTag, ConnectClientType, ConnectState, EventType, NetworkType, SessionState } from '../AIStreamTypes';
11
11
  import { closeSession, connect, createSession, disconnect, getCurrentHomeInfo, getNetworkType, isConnected, queryAgentToken, sendEventChatBreak, sendEventEnd, sendEventPayloadEnd, sendEventStart, sendImageData, sendTextData, startRecordAndSendAudioData, stopRecordAndSendAudioData } from './ttt';
12
12
  import { AIStreamObserver, AIStreamObserverPool } from './observer';
13
- import { isAbortError } from '@ray-js/t-agent';
13
+ import { isAbortError, safeParseJSON } from '@ray-js/t-agent';
14
14
  import logger from './logger';
15
15
  import { AIStreamError, tryCatchTTT } from './errors';
16
+ import { createResolvable } from './object';
16
17
  export class AIStreamClient {
17
18
  constructor() {
18
19
  _defineProperty(this, "pool", new AIStreamObserverPool());
@@ -163,6 +164,7 @@ export class AIStreamSession {
163
164
  _defineProperty(this, "revDataChannels", []);
164
165
  _defineProperty(this, "disposed", false);
165
166
  _defineProperty(this, "promise", null);
167
+ _defineProperty(this, "tokenExtParamsResolvable", createResolvable());
166
168
  _defineProperty(this, "_onStateChanged", entry => {
167
169
  var _this$activeEvent;
168
170
  (_this$activeEvent = this.activeEvent) === null || _this$activeEvent === void 0 || _this$activeEvent.emit('data', entry);
@@ -213,7 +215,7 @@ export class AIStreamSession {
213
215
  if (this.sessionId) {
214
216
  return Promise.resolve();
215
217
  }
216
- this.promise = (async () => {
218
+ this.promise = (async _this$options => {
217
219
  try {
218
220
  await this.connection._ensureConnected();
219
221
  } catch (e) {
@@ -240,11 +242,22 @@ export class AIStreamSession {
240
242
  }
241
243
  this.options.ownerId = ownerId;
242
244
  }
243
- const options = _objectSpread({
245
+
246
+ // 如果之前有 chatId,带上
247
+ let chatId = (_this$options = this.options) === null || _this$options === void 0 || (_this$options = _this$options.extParams) === null || _this$options === void 0 ? void 0 : _this$options.chatId;
248
+ if (!chatId && this.tokenExtParamsResolvable.state === 'fulfilled') {
249
+ var _await$this$tokenExtP;
250
+ chatId = (_await$this$tokenExtP = await this.tokenExtParamsResolvable.promise) === null || _await$this$tokenExtP === void 0 ? void 0 : _await$this$tokenExtP.chatId;
251
+ }
252
+ const options = _objectSpread(_objectSpread({
244
253
  bizTag: BizTag.DEFAULT,
245
- ownerId,
246
- extParams: {}
247
- }, this.options);
254
+ ownerId
255
+ }, this.options), {}, {
256
+ extParams: _objectSpread(_objectSpread({}, this.options.extParams), {}, {
257
+ // chatId 之前可能是 undefined,这里要覆盖掉
258
+ chatId
259
+ })
260
+ });
248
261
  const [error, result] = await tryCatchTTT(() => queryAgentToken(options));
249
262
  if (error) {
250
263
  this.promise = null;
@@ -252,8 +265,15 @@ export class AIStreamSession {
252
265
  }
253
266
  const {
254
267
  agentToken,
255
- bizConfig
268
+ bizConfig,
269
+ extParams
256
270
  } = result;
271
+ if (extParams) {
272
+ const ext = safeParseJSON(extParams) || {};
273
+ this.tokenExtParamsResolvable.resolve(ext);
274
+ } else {
275
+ this.tokenExtParamsResolvable.resolve({});
276
+ }
257
277
  {
258
278
  const [err, res] = await tryCatchTTT(() => createSession({
259
279
  bizTag: options.bizTag,
@@ -95,20 +95,34 @@ mock.hooks.hook('disconnect', context => {
95
95
  mock.data.set('sessionMap', new Map());
96
96
  });
97
97
  mock.hooks.hook('queryAgentToken', context => {
98
- var _context$options$extP, _context$options$extP2;
98
+ var _context$options$extP, _context$options$extP2, _context$options$extP3;
99
99
  const agentToken = generateId();
100
100
  const map = mock.data.get('tokenMap');
101
101
  map.set(agentToken, {
102
102
  onlyAsr: ((_context$options$extP = context.options.extParams) === null || _context$options$extP === void 0 ? void 0 : _context$options$extP.onlyAsr) || false,
103
103
  needTts: ((_context$options$extP2 = context.options.extParams) === null || _context$options$extP2 === void 0 ? void 0 : _context$options$extP2.needTts) || false
104
104
  });
105
+ let chatId;
106
+ if (((_context$options$extP3 = context.options.extParams) === null || _context$options$extP3 === void 0 ? void 0 : _context$options$extP3.dialogueMode) === 1) {
107
+ var _context$options$extP4;
108
+ if ((_context$options$extP4 = context.options.extParams) !== null && _context$options$extP4 !== void 0 && _context$options$extP4.chatId) {
109
+ // 如果参数有传吗,则使用传入的 chatId
110
+ chatId = context.options.extParams.chatId;
111
+ } else {
112
+ // 使用生成的 id
113
+ chatId = "chatId-".concat(generateId());
114
+ }
115
+ }
105
116
  context.result = {
106
117
  agentToken,
107
118
  bizConfig: {
108
119
  bizCode: BizCode.CHAT,
109
120
  sendData: ['audio', 'video', 'text', 'image'],
110
121
  revData: ['text', 'audio']
111
- }
122
+ },
123
+ extParams: JSON.stringify({
124
+ chatId
125
+ })
112
126
  };
113
127
  });
114
128
  const dispatch = (type, detail) => {
@@ -0,0 +1,7 @@
1
+ export interface Resolvable<T = void> {
2
+ resolve: (value?: T) => void;
3
+ reject: (reason?: any) => void;
4
+ promise: Promise<T>;
5
+ state: 'pending' | 'fulfilled' | 'rejected';
6
+ }
7
+ export declare const createResolvable: <T = void>() => Resolvable<T>;
@@ -0,0 +1,25 @@
1
+ export const createResolvable = () => {
2
+ const ret = {
3
+ resolve: null,
4
+ reject: null,
5
+ promise: null,
6
+ state: 'pending'
7
+ };
8
+ ret.promise = new Promise((resolve, reject) => {
9
+ ret.resolve = value => {
10
+ if (ret.state !== 'pending') {
11
+ return;
12
+ }
13
+ ret.state = 'fulfilled';
14
+ resolve(value);
15
+ };
16
+ ret.reject = reason => {
17
+ if (ret.state !== 'pending') {
18
+ return;
19
+ }
20
+ ret.state = 'rejected';
21
+ reject(reason);
22
+ };
23
+ });
24
+ return ret;
25
+ };
@@ -1,4 +1,5 @@
1
1
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
+ import "core-js/modules/es.global-this.js";
2
3
  import { isDevTools } from './ttt';
3
4
  import logger from './logger';
4
5
  import { mock } from './mock';
@@ -6,6 +7,9 @@ import { TTTError } from './errors';
6
7
  let callId = 100000;
7
8
  export const getEnableMock = () => {
8
9
  try {
10
+ if ((globalThis === null || globalThis === void 0 ? void 0 : globalThis.__AIStreamEnableMock) != null) {
11
+ return globalThis.__AIStreamEnableMock;
12
+ }
9
13
  const result = ty.getStorageSync({
10
14
  key: 'AIStreamEnableMock'
11
15
  });
@@ -8,6 +8,7 @@ export interface SendBlocksToAIStreamParams {
8
8
  attribute?: AIStreamChatAttribute;
9
9
  signal?: AbortSignal;
10
10
  enableTts?: boolean;
11
+ eventIdPrefix?: string;
11
12
  }
12
13
  export declare function sendBlocksToAIStream(params: SendBlocksToAIStreamParams): {
13
14
  response: StreamResponse;
@@ -19,7 +19,8 @@ export function sendBlocksToAIStream(params) {
19
19
  const {
20
20
  session,
21
21
  blocks,
22
- signal
22
+ signal,
23
+ eventIdPrefix
23
24
  } = params;
24
25
  let audioEmitter = null;
25
26
  for (const block of blocks) {
@@ -105,6 +106,7 @@ export function sendBlocksToAIStream(params) {
105
106
  let error;
106
107
  [error, event] = await tryCatch(() => session.startEvent({
107
108
  signal,
109
+ eventIdPrefix,
108
110
  userData: [{
109
111
  type: AIStreamAttributeType.AI_CHAT,
110
112
  payloadType: AIStreamAttributePayloadType.STRING,
@@ -66,6 +66,7 @@ export declare const disconnect: (options?: Omit<DisconnectParams, "success" | "
66
66
  export declare const queryAgentToken: (options?: Omit<QueryAgentTokenParams, "success" | "fail"> | undefined) => Promise<{
67
67
  agentToken: string;
68
68
  bizConfig: import("../AIStreamTypes").BizConfig;
69
+ extParams?: string | undefined;
69
70
  }>;
70
71
  export declare const createSession: (options?: Omit<CreateSessionParams, "success" | "fail"> | undefined) => Promise<{
71
72
  sessionId: string;
@@ -14,7 +14,11 @@ export interface AIStreamOptions {
14
14
  api: string;
15
15
  /** 如果是 clientType == 3,则是 highway 接口,可以不传 */
16
16
  version?: string;
17
- extParams?: Record<string, any>;
17
+ extParams?: {
18
+ deviceId?: string;
19
+ chatId?: string;
20
+ [key: string]: any;
21
+ };
18
22
  };
19
23
  /** 历史消息数量,默认1000,为0的话,则已分页的方式取全部数据 */
20
24
  historySize?: number;
@@ -30,6 +34,8 @@ export interface AIStreamOptions {
30
34
  createChatHistoryStore?: (agent: ChatAgent) => ChatHistoryStore | null;
31
35
  /** 是否开启音频合成 */
32
36
  enableTts?: boolean;
37
+ /** eventId 前缀,用于方便云端调试 */
38
+ eventIdPrefix?: string;
33
39
  }
34
40
  export type AIStreamPlugin = GetChatPluginHandler<typeof withAIStream>;
35
41
  export interface AIStreamHooks {
@@ -75,5 +81,6 @@ export declare function withAIStream(options?: AIStreamOptions): (agent: ChatAge
75
81
  onSkillsEnd: (fn: AIStreamHooks['onSkillsEnd']) => () => void;
76
82
  onCardsReceived: (fn: AIStreamHooks['onCardsReceived']) => () => void;
77
83
  onTTTAction: (fn: AIStreamHooks['onTTTAction']) => () => void;
84
+ getChatId: () => Promise<string>;
78
85
  };
79
86
  };
@@ -225,6 +225,7 @@ export function withAIStream() {
225
225
  blocks,
226
226
  session: streamSession,
227
227
  signal,
228
+ eventIdPrefix: options.eventIdPrefix,
228
229
  attribute: _objectSpread({}, extraOptions)
229
230
  });
230
231
  signal === null || signal === void 0 || signal.addEventListener('abort', event => {
@@ -560,6 +561,21 @@ export function withAIStream() {
560
561
  },
561
562
  onTTTAction: fn => {
562
563
  return hooks.hook('onTTTAction', fn);
564
+ },
565
+ getChatId: async () => {
566
+ var _options$tokenOptions;
567
+ if ((_options$tokenOptions = options.tokenOptions) !== null && _options$tokenOptions !== void 0 && (_options$tokenOptions = _options$tokenOptions.extParams) !== null && _options$tokenOptions !== void 0 && _options$tokenOptions.chatId) {
568
+ return options.tokenOptions.extParams.chatId;
569
+ }
570
+ const streamSession = session.get('AIStream.streamSession');
571
+ if (!streamSession) {
572
+ throw new Error('Stream session is not started');
573
+ }
574
+ const data = await streamSession.tokenExtParamsResolvable.promise;
575
+ if (data) {
576
+ return data.chatId;
577
+ }
578
+ return null;
563
579
  }
564
580
  }
565
581
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ray-js/t-agent-plugin-aistream",
3
- "version": "0.2.6-beta-1",
3
+ "version": "0.2.6-beta-3",
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": "7c5c58dfe2f598e502f3a9a09ed2439660336ce3"
38
+ "gitHead": "e478ba7ce360563e061efc24d6a8dfb495c5f9e9"
39
39
  }