@ray-js/t-agent-plugin-aistream 0.2.5 → 0.2.6-beta-2

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.
@@ -614,7 +614,9 @@ export declare enum ConnectClientType {
614
614
  /** 作为设备代理 */
615
615
  DEVICE = 1,
616
616
  /** 作为 App */
617
- APP = 2
617
+ APP = 2,
618
+ /** 作为开发者(行业 APP) */
619
+ DEVELOPER = 3
618
620
  }
619
621
  export declare enum EventType {
620
622
  /** 事件开始 */
@@ -1101,13 +1103,13 @@ export type ConnectParams = {
1101
1103
  */
1102
1104
  export type QueryAgentTokenParams = {
1103
1105
  /** Owner ID: HomeID 或 设备id */
1104
- ownerId: string;
1106
+ ownerId?: string;
1105
1107
  /** 智能解决方案 code */
1106
1108
  solutionCode: string;
1107
1109
  /** 业务接口 */
1108
1110
  api: string;
1109
1111
  /** 接口版本 */
1110
- apiVersion: string;
1112
+ apiVersion?: string;
1111
1113
  /** 业务额外参数 */
1112
1114
  extParams: any;
1113
1115
  success?: (params: {
@@ -1115,6 +1117,8 @@ export type QueryAgentTokenParams = {
1115
1117
  agentToken: string;
1116
1118
  /** 业务配置 */
1117
1119
  bizConfig: BizConfig;
1120
+ /** 额外字段, JSON 字符串 */
1121
+ extParams?: string;
1118
1122
  }) => void;
1119
1123
  fail?: (params: {
1120
1124
  errorMsg: string;
@@ -1206,6 +1210,7 @@ export type DisconnectParams = {
1206
1210
  export type SendEventStartParams = {
1207
1211
  /** 会话 id */
1208
1212
  sessionId: string;
1213
+ eventIdPrefix?: string;
1209
1214
  /** 扩展属性 */
1210
1215
  userData?: Attribute[];
1211
1216
  success?: (params: {
@@ -90,6 +90,7 @@ export let SessionState = /*#__PURE__*/function (SessionState) {
90
90
  export let ConnectClientType = /*#__PURE__*/function (ConnectClientType) {
91
91
  ConnectClientType[ConnectClientType["DEVICE"] = 1] = "DEVICE";
92
92
  ConnectClientType[ConnectClientType["APP"] = 2] = "APP";
93
+ ConnectClientType[ConnectClientType["DEVELOPER"] = 3] = "DEVELOPER";
93
94
  return ConnectClientType;
94
95
  }({});
95
96
  export let EventType = /*#__PURE__*/function (EventType) {
@@ -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,
@@ -37,7 +37,7 @@ interface AIStreamSessionOptions {
37
37
  /** 业务接口 */
38
38
  api: string;
39
39
  /** 接口版本 */
40
- apiVersion: string;
40
+ apiVersion?: string;
41
41
  /** 业务额外参数 */
42
42
  extParams?: any;
43
43
  userData?: Attribute[];
@@ -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) {
@@ -221,7 +223,10 @@ export class AIStreamSession {
221
223
  throw e;
222
224
  }
223
225
  let ownerId = this.options.ownerId;
224
- if (!ownerId) {
226
+ if (this.connection.options.clientType === ConnectClientType.DEVELOPER) {
227
+ ownerId = undefined;
228
+ this.options.ownerId = undefined;
229
+ } else if (!ownerId) {
225
230
  if (this.connection.options.clientType === ConnectClientType.APP) {
226
231
  try {
227
232
  const {
@@ -237,11 +242,21 @@ export class AIStreamSession {
237
242
  }
238
243
  this.options.ownerId = ownerId;
239
244
  }
240
- 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({
241
253
  bizTag: BizTag.DEFAULT,
242
- ownerId,
243
- extParams: {}
244
- }, this.options);
254
+ ownerId
255
+ }, this.options), {}, {
256
+ extParams: _objectSpread({
257
+ chatId
258
+ }, this.options.extParams)
259
+ });
245
260
  const [error, result] = await tryCatchTTT(() => queryAgentToken(options));
246
261
  if (error) {
247
262
  this.promise = null;
@@ -249,8 +264,15 @@ export class AIStreamSession {
249
264
  }
250
265
  const {
251
266
  agentToken,
252
- bizConfig
267
+ bizConfig,
268
+ extParams
253
269
  } = result;
270
+ if (extParams) {
271
+ const ext = safeParseJSON(extParams) || {};
272
+ this.tokenExtParamsResolvable.resolve(ext);
273
+ } else {
274
+ this.tokenExtParamsResolvable.resolve({});
275
+ }
254
276
  {
255
277
  const [err, res] = await tryCatchTTT(() => createSession({
256
278
  bizTag: options.bizTag,
@@ -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
+ };
@@ -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;
@@ -3,7 +3,7 @@ import { TTTAction } from './utils';
3
3
  import { ConnectClientType, ReceivedTextSkillPacketBody } from './AIStreamTypes';
4
4
  import { ChatHistoryStore, StoredMessageObject } from './ChatHistoryStore';
5
5
  export interface AIStreamOptions {
6
- /** client 类型: 1-作为设备代理, 2-作为 App */
6
+ /** client 类型: 1-作为设备代理, 2-作为 App,3-作为开发者(行业 App) */
7
7
  clientType?: ConnectClientType;
8
8
  /** 代理的设备ID, clientType == 1 时必传 */
9
9
  deviceId?: string;
@@ -12,8 +12,13 @@ export interface AIStreamOptions {
12
12
  /** 获取 agent token 的参数 */
13
13
  tokenOptions?: {
14
14
  api: string;
15
- version: string;
16
- extParams?: Record<string, any>;
15
+ /** 如果是 clientType == 3,则是 highway 接口,可以不传 */
16
+ version?: string;
17
+ extParams?: {
18
+ deviceId?: string;
19
+ chatId?: string;
20
+ [key: string]: any;
21
+ };
17
22
  };
18
23
  /** 历史消息数量,默认1000,为0的话,则已分页的方式取全部数据 */
19
24
  historySize?: number;
@@ -29,6 +34,8 @@ export interface AIStreamOptions {
29
34
  createChatHistoryStore?: (agent: ChatAgent) => ChatHistoryStore | null;
30
35
  /** 是否开启音频合成 */
31
36
  enableTts?: boolean;
37
+ /** eventId 前缀,用于方便云端调试 */
38
+ eventIdPrefix?: string;
32
39
  }
33
40
  export type AIStreamPlugin = GetChatPluginHandler<typeof withAIStream>;
34
41
  export interface AIStreamHooks {
@@ -74,5 +81,6 @@ export declare function withAIStream(options?: AIStreamOptions): (agent: ChatAge
74
81
  onSkillsEnd: (fn: AIStreamHooks['onSkillsEnd']) => () => void;
75
82
  onCardsReceived: (fn: AIStreamHooks['onCardsReceived']) => () => void;
76
83
  onTTTAction: (fn: AIStreamHooks['onTTTAction']) => () => void;
84
+ getChatId: () => Promise<string>;
77
85
  };
78
86
  };
@@ -47,7 +47,11 @@ export function withAIStream() {
47
47
  if (!agentId) {
48
48
  throw new Error('agentId is required');
49
49
  }
50
- if (!tokenOptions.api || !tokenOptions.version) {
50
+ if (clientType === ConnectClientType.DEVELOPER) {
51
+ if (!tokenOptions.api) {
52
+ throw new Error('tokenOptions.api is required');
53
+ }
54
+ } else if (!tokenOptions.api || !tokenOptions.version) {
51
55
  throw new Error('tokenOptions.api and tokenOptions.version are required');
52
56
  }
53
57
  if (clientType === ConnectClientType.DEVICE && !deviceId) {
@@ -57,6 +61,9 @@ export function withAIStream() {
57
61
  throw new Error('deviceId is not allowed when clientType is app');
58
62
  }
59
63
  let homeId = options.homeId;
64
+ if (clientType === ConnectClientType.DEVELOPER) {
65
+ homeId = 1;
66
+ }
60
67
  if (!homeId) {
61
68
  const info = await getCurrentHomeInfo();
62
69
  homeId = +info.homeId;
@@ -218,6 +225,7 @@ export function withAIStream() {
218
225
  blocks,
219
226
  session: streamSession,
220
227
  signal,
228
+ eventIdPrefix: options.eventIdPrefix,
221
229
  attribute: _objectSpread({}, extraOptions)
222
230
  });
223
231
  signal === null || signal === void 0 || signal.addEventListener('abort', event => {
@@ -553,6 +561,21 @@ export function withAIStream() {
553
561
  },
554
562
  onTTTAction: fn => {
555
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;
556
579
  }
557
580
  }
558
581
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ray-js/t-agent-plugin-aistream",
3
- "version": "0.2.5",
3
+ "version": "0.2.6-beta-2",
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": "5c2ee8c15695fa858e00d9f58147487479ca0121"
38
+ "gitHead": "fa6602d3d1a9c14187a8f524302317ed22fec7c3"
39
39
  }