@ray-js/t-agent-plugin-aistream 0.2.0-beta-2 → 0.2.0-beta-4
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.
- package/dist/ChatHistoryStore.d.ts +31 -29
- package/dist/ChatHistoryStore.js +132 -101
- package/dist/utils/AIStream.d.ts +4 -4
- package/dist/utils/AIStream.js +15 -7
- package/dist/utils/apis.d.ts +2 -2
- package/dist/utils/apis.js +1 -1
- package/dist/utils/createAsrAgent.d.ts +79 -0
- package/dist/utils/createAsrAgent.js +197 -0
- package/dist/utils/defaultMock.js +81 -16
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +3 -1
- package/dist/utils/mock.d.ts +1 -0
- package/dist/utils/mock.js +8 -0
- package/dist/utils/promisify.d.ts +6 -0
- package/dist/utils/promisify.js +24 -4
- package/dist/utils/ttt.js +1 -1
- package/dist/withAIStream.d.ts +17 -17
- package/dist/withAIStream.js +129 -84
- package/package.json +2 -2
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
2
|
+
import "core-js/modules/es.json.stringify.js";
|
|
3
|
+
import { authorize } from './ttt';
|
|
4
|
+
import { DEFAULT_TOKEN_API, DEFAULT_TOKEN_API_VERSION, globalAIStreamClient } from '../global';
|
|
5
|
+
import { ConnectClientType, AIStreamAttributePayloadType, AIStreamAttributeType, AIStreamChatSysWorkflow } from '../AIStreamTypes';
|
|
6
|
+
import logger from './logger';
|
|
7
|
+
class AsrAgent {
|
|
8
|
+
constructor(options) {
|
|
9
|
+
/** 数据链接,一个agent保持一个链接就可以 */
|
|
10
|
+
/** 当前请求的session,每次请求都需要是一个新的session */
|
|
11
|
+
/** 音频流监听 */
|
|
12
|
+
/** 录音时长定时器 */
|
|
13
|
+
_defineProperty(this, "recordDurationTimer", null);
|
|
14
|
+
this.options = options;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** 获取录音权限 */
|
|
18
|
+
getRecordScope() {
|
|
19
|
+
return authorize({
|
|
20
|
+
scope: 'scope.record'
|
|
21
|
+
}).then(() => true, () => false);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** 获取数据链接,一般只有一个链接就可以 */
|
|
25
|
+
getConnection(clientType, deviceId) {
|
|
26
|
+
if (this.streamConn) {
|
|
27
|
+
return this.streamConn;
|
|
28
|
+
}
|
|
29
|
+
// 创建 activeSession
|
|
30
|
+
this.streamConn = globalAIStreamClient.getConnection({
|
|
31
|
+
clientType: clientType || ConnectClientType.APP,
|
|
32
|
+
deviceId: deviceId
|
|
33
|
+
});
|
|
34
|
+
return this.streamConn;
|
|
35
|
+
}
|
|
36
|
+
createSession() {
|
|
37
|
+
var _this$activeSession;
|
|
38
|
+
// 每次新的请求,都需要重新创建一个Session
|
|
39
|
+
const {
|
|
40
|
+
clientType,
|
|
41
|
+
deviceId,
|
|
42
|
+
tokenApi,
|
|
43
|
+
tokenApiVersion,
|
|
44
|
+
agentId
|
|
45
|
+
} = this.options;
|
|
46
|
+
const streamConn = this.getConnection(clientType, deviceId);
|
|
47
|
+
// 如果有激活的,需要释放
|
|
48
|
+
if ((_this$activeSession = this.activeSession) !== null && _this$activeSession !== void 0 && _this$activeSession.sessionId) {
|
|
49
|
+
this.activeSession.close();
|
|
50
|
+
}
|
|
51
|
+
const activeSession = streamConn.createSession({
|
|
52
|
+
api: tokenApi || DEFAULT_TOKEN_API,
|
|
53
|
+
apiVersion: tokenApiVersion || DEFAULT_TOKEN_API_VERSION,
|
|
54
|
+
solutionCode: agentId
|
|
55
|
+
});
|
|
56
|
+
this.activeSession = activeSession;
|
|
57
|
+
return this.activeSession;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** 开始录音时长监听 */
|
|
61
|
+
startRecordTimer() {
|
|
62
|
+
const {
|
|
63
|
+
maxDuration
|
|
64
|
+
} = this.options;
|
|
65
|
+
if (maxDuration) {
|
|
66
|
+
if (this.recordDurationTimer) {
|
|
67
|
+
clearTimeout(this.recordDurationTimer);
|
|
68
|
+
}
|
|
69
|
+
this.recordDurationTimer = setTimeout(() => {
|
|
70
|
+
this.stop(true);
|
|
71
|
+
}, maxDuration * 1000);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async start() {
|
|
75
|
+
const hasScope = await this.getRecordScope();
|
|
76
|
+
if (!hasScope) {
|
|
77
|
+
throw new Error('authorize failed');
|
|
78
|
+
}
|
|
79
|
+
const {
|
|
80
|
+
onMessage,
|
|
81
|
+
onFinish,
|
|
82
|
+
onError
|
|
83
|
+
} = this.options || {};
|
|
84
|
+
const activeSession = await this.createSession();
|
|
85
|
+
const attribute = {
|
|
86
|
+
'processing.interrupt': 'false',
|
|
87
|
+
'asr.enableVad': 'false',
|
|
88
|
+
'sys.workflow': AIStreamChatSysWorkflow.ASR
|
|
89
|
+
};
|
|
90
|
+
const activeEvent = await activeSession.startEvent({
|
|
91
|
+
userData: [{
|
|
92
|
+
type: AIStreamAttributeType.AI_CHAT,
|
|
93
|
+
payloadType: AIStreamAttributePayloadType.STRING,
|
|
94
|
+
value: JSON.stringify(attribute)
|
|
95
|
+
}]
|
|
96
|
+
});
|
|
97
|
+
this.activeEvent = activeEvent;
|
|
98
|
+
const audioStream = activeEvent.stream({
|
|
99
|
+
type: 'audio'
|
|
100
|
+
});
|
|
101
|
+
this.audioStream = audioStream;
|
|
102
|
+
await audioStream.start();
|
|
103
|
+
this.startRecordTimer();
|
|
104
|
+
activeEvent.on('data', entry => {
|
|
105
|
+
if (entry.type === 'text') {
|
|
106
|
+
console.log('text', entry, JSON.parse(entry.body.text));
|
|
107
|
+
let data = {
|
|
108
|
+
text: ''
|
|
109
|
+
};
|
|
110
|
+
try {
|
|
111
|
+
data = JSON.parse(entry.body.text) || {};
|
|
112
|
+
} catch (error) {
|
|
113
|
+
logger.error('JSON.parse error', error);
|
|
114
|
+
}
|
|
115
|
+
typeof onMessage === 'function' && onMessage(data);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
activeEvent.on('finish', () => {
|
|
119
|
+
this.stop();
|
|
120
|
+
typeof onFinish === 'function' && onFinish();
|
|
121
|
+
});
|
|
122
|
+
activeEvent.on('error', error => {
|
|
123
|
+
typeof onError === 'function' && onError(error);
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
async stop(isAbort) {
|
|
127
|
+
var _this$activeSession2;
|
|
128
|
+
if (this.recordDurationTimer) {
|
|
129
|
+
clearTimeout(this.recordDurationTimer);
|
|
130
|
+
this.recordDurationTimer = null;
|
|
131
|
+
}
|
|
132
|
+
if (this.audioStream) {
|
|
133
|
+
await this.audioStream.stop();
|
|
134
|
+
this.audioStream = null;
|
|
135
|
+
}
|
|
136
|
+
if (this.activeEvent) {
|
|
137
|
+
if (isAbort) {
|
|
138
|
+
await this.activeEvent.abort();
|
|
139
|
+
} else {
|
|
140
|
+
await this.activeEvent.end();
|
|
141
|
+
}
|
|
142
|
+
this.activeEvent = null;
|
|
143
|
+
}
|
|
144
|
+
if (isAbort) {
|
|
145
|
+
const {
|
|
146
|
+
onAbort
|
|
147
|
+
} = this.options || {};
|
|
148
|
+
typeof onAbort === 'function' && onAbort();
|
|
149
|
+
}
|
|
150
|
+
await ((_this$activeSession2 = this.activeSession) === null || _this$activeSession2 === void 0 ? void 0 : _this$activeSession2.close());
|
|
151
|
+
}
|
|
152
|
+
async abort() {
|
|
153
|
+
await this.stop(true);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* 创建一个AsrAgent实例,用于语音转文本
|
|
159
|
+
* @param options AsrAgentOptions
|
|
160
|
+
* @param options.agentId 必填 语音转文本的agentId
|
|
161
|
+
* @param options.tokenApi 语音转文本的tokenApi
|
|
162
|
+
* @param options.tokenApiVersion 语音转文本的tokenApiVersion
|
|
163
|
+
* @param options.clientType 语音转文本的clientType
|
|
164
|
+
* @param options.deviceId 语音转文本的deviceId
|
|
165
|
+
* @example
|
|
166
|
+
* const asrAgent = createAsrAgent({
|
|
167
|
+
* agentId: 'asr-agent',
|
|
168
|
+
* tokenApi: 'm.thing.aigc.basic.server.token',
|
|
169
|
+
* tokenApiVersion: '1.0',
|
|
170
|
+
* clientType: ConnectClientType.APP,
|
|
171
|
+
* deviceId: 'deviceId',
|
|
172
|
+
* maxDuration: 60,
|
|
173
|
+
* onMessage: (message) => {
|
|
174
|
+
* console.log('onMessage', message);
|
|
175
|
+
* },
|
|
176
|
+
* onFinish: () => {
|
|
177
|
+
* console.log('onFinish');
|
|
178
|
+
* },
|
|
179
|
+
* onError: (error) => {
|
|
180
|
+
* console.log('onError', error);
|
|
181
|
+
* },
|
|
182
|
+
* onAbort: () => {
|
|
183
|
+
* console.log('onAbort');
|
|
184
|
+
* },
|
|
185
|
+
* });
|
|
186
|
+
* // 开始录音
|
|
187
|
+
* asrAgent.start()
|
|
188
|
+
* // 停止录音
|
|
189
|
+
* asrAgent.stop()
|
|
190
|
+
* // 中断录音
|
|
191
|
+
* asrAgent.abort()
|
|
192
|
+
* @returns
|
|
193
|
+
*/
|
|
194
|
+
export function createAsrAgent(options) {
|
|
195
|
+
const asrAgent = new AsrAgent(options);
|
|
196
|
+
return asrAgent;
|
|
197
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
1
2
|
import "core-js/modules/es.array.sort.js";
|
|
2
3
|
import "core-js/modules/es.json.stringify.js";
|
|
3
4
|
import "core-js/modules/es.regexp.exec.js";
|
|
@@ -34,19 +35,20 @@ mock.hooks.hook('getMiniAppConfig', context => {
|
|
|
34
35
|
config: {}
|
|
35
36
|
};
|
|
36
37
|
});
|
|
38
|
+
const getCurrentConnection = () => {
|
|
39
|
+
return mock.data.get('currentConnection');
|
|
40
|
+
};
|
|
37
41
|
mock.hooks.hook('connect', context => {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
});
|
|
47
|
-
mock.data.set("connection-".concat(connectionId), key);
|
|
42
|
+
let connection = getCurrentConnection();
|
|
43
|
+
if (connection) {
|
|
44
|
+
throw new Error('already connected');
|
|
45
|
+
} else {
|
|
46
|
+
connection = {
|
|
47
|
+
connectionId: generateId()
|
|
48
|
+
};
|
|
49
|
+
mock.data.set('currentConnection', connection);
|
|
48
50
|
}
|
|
49
|
-
context.result =
|
|
51
|
+
context.result = connection;
|
|
50
52
|
});
|
|
51
53
|
mock.hooks.hook('disconnect', context => {
|
|
52
54
|
const {
|
|
@@ -54,9 +56,15 @@ mock.hooks.hook('disconnect', context => {
|
|
|
54
56
|
connectionId
|
|
55
57
|
}
|
|
56
58
|
} = context;
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
const connection = getCurrentConnection();
|
|
60
|
+
if (!connection) {
|
|
61
|
+
throw new Error('not connected');
|
|
62
|
+
}
|
|
63
|
+
if (connection.connectionId !== connectionId) {
|
|
64
|
+
throw new Error('connectionId mismatch');
|
|
65
|
+
}
|
|
66
|
+
mock.data.set('currentConnection', null);
|
|
67
|
+
mock.data.set('sessionMap', new Map());
|
|
60
68
|
});
|
|
61
69
|
mock.hooks.hook('queryAgentToken', context => {
|
|
62
70
|
context.result = {
|
|
@@ -106,6 +114,14 @@ mock.hooks.hook('createSession', context => {
|
|
|
106
114
|
sendDataChannels: session.sendDataChannels,
|
|
107
115
|
revDataChannels: session.revDataChannels
|
|
108
116
|
};
|
|
117
|
+
|
|
118
|
+
// setTimeout(() => {
|
|
119
|
+
// dispatch('onConnectStateChanged', {
|
|
120
|
+
// connectionId: getCurrentConnection().connectionId,
|
|
121
|
+
// connectState: ConnectState.DISCONNECTED,
|
|
122
|
+
// code: 200,
|
|
123
|
+
// });
|
|
124
|
+
// }, 1000);
|
|
109
125
|
});
|
|
110
126
|
mock.hooks.hook('closeSession', context => {
|
|
111
127
|
const map = mock.data.get('sessionMap');
|
|
@@ -149,21 +165,31 @@ mock.hooks.hook('unregisterVoiceAmplitudes', context => {
|
|
|
149
165
|
mock.hooks.hook('sendEventEnd', context => {
|
|
150
166
|
const session = getSession(context.options.sessionId, context.options.eventId);
|
|
151
167
|
context.result = true;
|
|
168
|
+
const event = session.currentEvent;
|
|
152
169
|
(async () => {
|
|
170
|
+
await event.asrStatus.promise;
|
|
153
171
|
const ctx = {
|
|
154
|
-
data:
|
|
172
|
+
data: event.data,
|
|
155
173
|
responseText: ''
|
|
156
174
|
};
|
|
157
|
-
await session.currentEvent.asrStatus.promise;
|
|
158
175
|
await mock.hooks.callHook('sendToAIStream', ctx);
|
|
159
176
|
const text = ctx.responseText || '⚠️ No mock text response matched!';
|
|
160
177
|
const words = splitString(text);
|
|
178
|
+
if (event.controller.signal.aborted) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
161
181
|
session.replyEvent(EventType.EVENT_START);
|
|
162
182
|
await mock.sleep(500);
|
|
183
|
+
if (event.controller.signal.aborted) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
163
186
|
const bizId = generateId();
|
|
164
187
|
session.replyText(StreamFlag.START);
|
|
165
188
|
for (const word of words) {
|
|
166
189
|
await mock.sleep(100);
|
|
190
|
+
if (event.controller.signal.aborted) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
167
193
|
session.replyText(StreamFlag.IN_PROGRESS, {
|
|
168
194
|
bizType: ReceivedTextPacketType.NLG,
|
|
169
195
|
eof: ReceivedTextPacketEof.CONTINUE,
|
|
@@ -175,6 +201,10 @@ mock.hooks.hook('sendEventEnd', context => {
|
|
|
175
201
|
}
|
|
176
202
|
});
|
|
177
203
|
}
|
|
204
|
+
await mock.sleep(100);
|
|
205
|
+
if (event.controller.signal.aborted) {
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
178
208
|
session.replyText(StreamFlag.IN_PROGRESS, {
|
|
179
209
|
bizType: ReceivedTextPacketType.NLG,
|
|
180
210
|
eof: ReceivedTextPacketEof.END,
|
|
@@ -186,8 +216,14 @@ mock.hooks.hook('sendEventEnd', context => {
|
|
|
186
216
|
}
|
|
187
217
|
});
|
|
188
218
|
await mock.sleep(10);
|
|
219
|
+
if (event.controller.signal.aborted) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
189
222
|
session.replyText(StreamFlag.END);
|
|
190
223
|
await mock.sleep(500);
|
|
224
|
+
if (event.controller.signal.aborted) {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
191
227
|
session.replyEvent(EventType.EVENT_END);
|
|
192
228
|
session.currentEvent = null;
|
|
193
229
|
})();
|
|
@@ -238,6 +274,7 @@ mock.hooks.hook('startRecordAndSendAudioData', context => {
|
|
|
238
274
|
let text = '';
|
|
239
275
|
controller.signal.addEventListener('abort', async () => {
|
|
240
276
|
var _finishResolve;
|
|
277
|
+
// 终止识别到出完整结果的延迟
|
|
241
278
|
await mock.sleep(300);
|
|
242
279
|
session.replyText(StreamFlag.IN_PROGRESS, {
|
|
243
280
|
bizType: ReceivedTextPacketType.ASR,
|
|
@@ -249,8 +286,16 @@ mock.hooks.hook('startRecordAndSendAudioData', context => {
|
|
|
249
286
|
});
|
|
250
287
|
await mock.sleep(100);
|
|
251
288
|
session.replyText(StreamFlag.END);
|
|
289
|
+
if (session.currentEvent) {
|
|
290
|
+
session.currentEvent.data.push({
|
|
291
|
+
type: 'text',
|
|
292
|
+
text
|
|
293
|
+
});
|
|
294
|
+
}
|
|
252
295
|
(_finishResolve = finishResolve) === null || _finishResolve === void 0 || _finishResolve();
|
|
253
296
|
});
|
|
297
|
+
|
|
298
|
+
// 识别 ASR 的延迟
|
|
254
299
|
await mock.sleep(100);
|
|
255
300
|
if (controller.signal.aborted) {
|
|
256
301
|
return;
|
|
@@ -426,4 +471,24 @@ mock.hooks.hook('insertRecord', context => {
|
|
|
426
471
|
context.result = {
|
|
427
472
|
id
|
|
428
473
|
};
|
|
474
|
+
});
|
|
475
|
+
mock.hooks.hook('updateRecord', context => {
|
|
476
|
+
const options = context.options;
|
|
477
|
+
const id = options.id;
|
|
478
|
+
|
|
479
|
+
// 默认倒序
|
|
480
|
+
const records = filterRecords({
|
|
481
|
+
id: [id]
|
|
482
|
+
});
|
|
483
|
+
if (!records.length) {
|
|
484
|
+
throw new Error('record not exists');
|
|
485
|
+
}
|
|
486
|
+
const newRecord = _objectSpread(_objectSpread({}, records[0]), options);
|
|
487
|
+
mock.setRecord({
|
|
488
|
+
id,
|
|
489
|
+
record: newRecord
|
|
490
|
+
});
|
|
491
|
+
context.result = {
|
|
492
|
+
newRecord
|
|
493
|
+
};
|
|
429
494
|
});
|
package/dist/utils/index.d.ts
CHANGED
package/dist/utils/index.js
CHANGED
package/dist/utils/mock.d.ts
CHANGED
|
@@ -41,6 +41,7 @@ declare const mock: {
|
|
|
41
41
|
getRecords: <T = any>() => Row<T>[];
|
|
42
42
|
getRecord: <T_1 = any>(id: number) => Row<T_1> | undefined;
|
|
43
43
|
setRecord: <T_2 = any>(entry: Row<T_2>) => void;
|
|
44
|
+
updateRecord: <T_3 = any>(entry: Row<T_3>) => void;
|
|
44
45
|
deleteRecord: (id: number) => void;
|
|
45
46
|
clearRecords: () => void;
|
|
46
47
|
getId: () => number;
|
package/dist/utils/mock.js
CHANGED
|
@@ -52,6 +52,14 @@ const mock = {
|
|
|
52
52
|
data: JSON.stringify(mock.getRecords())
|
|
53
53
|
});
|
|
54
54
|
},
|
|
55
|
+
updateRecord: entry => {
|
|
56
|
+
mock.getRecords();
|
|
57
|
+
mock.database.set(entry.id, entry);
|
|
58
|
+
ty.setStorageSync({
|
|
59
|
+
key: 'AIStreamMockDatabase',
|
|
60
|
+
data: JSON.stringify(mock.getRecords())
|
|
61
|
+
});
|
|
62
|
+
},
|
|
55
63
|
deleteRecord: id => {
|
|
56
64
|
mock.getRecords();
|
|
57
65
|
mock.database.delete(id);
|
|
@@ -11,6 +11,12 @@ 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
|
+
}
|
|
14
20
|
export declare const getEnableMock: () => boolean;
|
|
15
21
|
export declare const setEnableMock: (enable: boolean) => boolean;
|
|
16
22
|
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]>;
|
package/dist/utils/promisify.js
CHANGED
|
@@ -2,30 +2,40 @@ 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
15
|
let callId = 100000;
|
|
6
16
|
export const getEnableMock = () => {
|
|
7
17
|
try {
|
|
8
18
|
const result = ty.getStorageSync({
|
|
9
|
-
key: '
|
|
19
|
+
key: 'AIStreamEnableMock'
|
|
10
20
|
});
|
|
11
21
|
// @ts-ignore
|
|
12
22
|
if (result && (result === 'true' || result.data === 'true')) {
|
|
13
23
|
return true;
|
|
14
24
|
}
|
|
15
25
|
} catch (e) {
|
|
16
|
-
console.error('获取
|
|
26
|
+
console.error('获取AIStreamEnableMock配置失败', e);
|
|
17
27
|
}
|
|
18
28
|
return isDevTools();
|
|
19
29
|
};
|
|
20
30
|
export const setEnableMock = enable => {
|
|
21
31
|
try {
|
|
22
32
|
ty.setStorageSync({
|
|
23
|
-
key: '
|
|
33
|
+
key: 'AIStreamEnableMock',
|
|
24
34
|
data: String(enable)
|
|
25
35
|
});
|
|
26
36
|
return true;
|
|
27
37
|
} catch (e) {
|
|
28
|
-
console.error('设置
|
|
38
|
+
console.error('设置AIStreamEnableMock配置失败', e);
|
|
29
39
|
return false;
|
|
30
40
|
}
|
|
31
41
|
};
|
|
@@ -44,6 +54,16 @@ export function promisify(fn) {
|
|
|
44
54
|
};
|
|
45
55
|
const reject = error => {
|
|
46
56
|
logger.debug("TTT error #".concat(id, " %c").concat(fn.name), 'background: red; color: white', error);
|
|
57
|
+
|
|
58
|
+
// 这是 TTT 的错误
|
|
59
|
+
if (error.errorCode != null && error.errorMsg != null) {
|
|
60
|
+
var _error$innerError;
|
|
61
|
+
if (((_error$innerError = error.innerError) === null || _error$innerError === void 0 ? void 0 : _error$innerError.errorCode) != null && error.innerError.errorMsg != null) {
|
|
62
|
+
error = new TTTError(error.innerError.errorMsg, error.innerError.errorCode);
|
|
63
|
+
} else {
|
|
64
|
+
error = new TTTError(error.errorMsg, error.errorCode);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
47
67
|
_reject(error);
|
|
48
68
|
};
|
|
49
69
|
const context = {
|
package/dist/utils/ttt.js
CHANGED
|
@@ -2,7 +2,7 @@ import { listening, promisify } from './promisify';
|
|
|
2
2
|
import { ConnectClientType, ConnectState } from '../AIStreamTypes';
|
|
3
3
|
import { generateId } from '@ray-js/t-agent';
|
|
4
4
|
export const getMiniAppConfig = promisify(ty.getMiniAppConfig, true);
|
|
5
|
-
export const getAccountInfo = promisify(ty.getAccountInfo
|
|
5
|
+
export const getAccountInfo = promisify(ty.getAccountInfo);
|
|
6
6
|
export const isDevTools = () => {
|
|
7
7
|
return ty.getSystemInfoSync().brand === 'devtools';
|
|
8
8
|
};
|
package/dist/withAIStream.d.ts
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
import { ChatAgent, ChatMessage, ComposeHandler, InputBlock } from '@ray-js/t-agent';
|
|
2
2
|
import { ConnectClientType } from './AIStreamTypes';
|
|
3
|
-
import {
|
|
3
|
+
import { ChatHistoryLocalStore, StoredMessageObject } from './ChatHistoryStore';
|
|
4
4
|
export interface AIStreamOptions {
|
|
5
5
|
/** client 类型: 1-作为设备代理, 2-作为 App */
|
|
6
6
|
clientType?: ConnectClientType;
|
|
7
7
|
/** 代理的设备ID, clientType == 1 时必传 */
|
|
8
8
|
deviceId?: string;
|
|
9
|
+
/** Agent ID */
|
|
9
10
|
agentId?: string;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
/** 获取 agent token 的参数 */
|
|
12
|
+
tokenOptions?: {
|
|
13
|
+
api: string;
|
|
14
|
+
version: string;
|
|
15
|
+
extParams?: Record<string, any>;
|
|
16
|
+
};
|
|
16
17
|
/** 历史消息数量,默认1000,为0的话,则已分页的方式取全部数据 */
|
|
17
18
|
historySize?: number;
|
|
18
19
|
/** 是否支持多模态 */
|
|
19
20
|
multiModal?: boolean;
|
|
21
|
+
/** 是否将输入块传递给智能体,默认为 true,设置为 false 时,需要你自己编写 onInputBlocksPush Hook 来处理输入块 */
|
|
20
22
|
wireInput?: boolean;
|
|
21
23
|
/** 索引ID,如果传了 createChatHistoryStore,则会覆盖 */
|
|
22
24
|
indexId?: string;
|
|
23
25
|
/** 家庭id,不填默认当前家庭 */
|
|
24
26
|
homeId?: number;
|
|
25
|
-
/**
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
[key: string]: string;
|
|
30
|
-
};
|
|
27
|
+
/** 是否在 onAgentStart 阶段就建立连接 */
|
|
28
|
+
earlyStart?: boolean;
|
|
29
|
+
/** 自定义消息存储, 返回的实例需要实现 ChatHistoryLocalStore 接口, 返回null则不存储历史聊天记录 */
|
|
30
|
+
createChatHistoryStore?: (agent: ChatAgent) => ChatHistoryLocalStore | null;
|
|
31
31
|
}
|
|
32
32
|
export interface AIStreamHooks {
|
|
33
33
|
onMessageParse: (msgItem: StoredMessageObject, result: {
|
|
@@ -39,7 +39,7 @@ export interface AIStreamHooks {
|
|
|
39
39
|
}
|
|
40
40
|
export declare function withAIStream(options?: AIStreamOptions): (agent: ChatAgent) => {
|
|
41
41
|
hooks: import("hookable").Hookable<any, string>;
|
|
42
|
-
|
|
42
|
+
aiStream: {
|
|
43
43
|
send: (blocks: InputBlock[], signal?: AbortSignal, extraOptions?: Record<string, any>) => {
|
|
44
44
|
response: import("@ray-js/t-agent").StreamResponse;
|
|
45
45
|
metaPromise: Promise<Record<string, any>>;
|
|
@@ -53,12 +53,12 @@ export declare function withAIStream(options?: AIStreamOptions): (agent: ChatAge
|
|
|
53
53
|
options: AIStreamOptions;
|
|
54
54
|
removeMessage: (message: ChatMessage) => Promise<void>;
|
|
55
55
|
clearAllMessages: () => Promise<void>;
|
|
56
|
-
feedback: ({ requestId, type
|
|
56
|
+
feedback: ({ requestId, type }: {
|
|
57
57
|
requestId: string;
|
|
58
|
-
type:
|
|
58
|
+
type: string;
|
|
59
59
|
}) => Promise<{
|
|
60
60
|
thingjson?: any;
|
|
61
61
|
data: string;
|
|
62
|
-
}
|
|
62
|
+
}>;
|
|
63
63
|
};
|
|
64
64
|
};
|