@ray-js/t-agent-plugin-aistream 0.2.8-beta.2 → 0.2.8-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/README-zh_CN.md +70 -11
- package/README.md +916 -706
- package/dist/AIStreamTypes.d.ts +20 -1
- package/dist/asr/AsrAgent.d.ts +1 -1
- package/dist/asr/AsrAgent.js +7 -5
- package/dist/buildIn/withBuildIn.d.ts +1 -0
- package/dist/buildIn/withBuildIn.js +149 -25
- package/dist/utils/AIStream.d.ts +15 -2
- package/dist/utils/AIStream.js +82 -40
- package/dist/utils/defaultMock.js +90 -3
- package/dist/utils/mock.d.ts +15 -0
- package/dist/utils/observer.d.ts +6 -0
- package/dist/utils/observer.js +100 -32
- package/dist/utils/sendMessage.d.ts +0 -1
- package/dist/utils/sendMessage.js +19 -8
- package/dist/utils/ttt.d.ts +1 -0
- package/dist/utils/ttt.js +2 -0
- package/dist/withAIStream.d.ts +10 -2
- package/dist/withAIStream.js +93 -57
- package/package.json +2 -3
package/dist/utils/observer.d.ts
CHANGED
|
@@ -45,6 +45,12 @@ export declare class AIStreamObserverPool {
|
|
|
45
45
|
private observerMap;
|
|
46
46
|
constructor();
|
|
47
47
|
private cancels;
|
|
48
|
+
private createObserverMap;
|
|
49
|
+
private isSessionAwareType;
|
|
50
|
+
private getEntrySessionIds;
|
|
51
|
+
private collectObservers;
|
|
52
|
+
private addObserver;
|
|
53
|
+
private removeObserver;
|
|
48
54
|
start(): void;
|
|
49
55
|
dispose(): void;
|
|
50
56
|
connect(observer: AIStreamObserver): void;
|
package/dist/utils/observer.js
CHANGED
|
@@ -10,25 +10,102 @@ export class AIStreamObserverPool {
|
|
|
10
10
|
constructor() {
|
|
11
11
|
_defineProperty(this, "isStarted", false);
|
|
12
12
|
_defineProperty(this, "cancels", []);
|
|
13
|
-
this.observerMap =
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
13
|
+
this.observerMap = this.createObserverMap();
|
|
14
|
+
}
|
|
15
|
+
createObserverMap() {
|
|
16
|
+
return {
|
|
17
|
+
connectionState: {
|
|
18
|
+
all: new Set(),
|
|
19
|
+
bySessionId: new Map()
|
|
20
|
+
},
|
|
21
|
+
sessionState: {
|
|
22
|
+
all: new Set(),
|
|
23
|
+
bySessionId: new Map()
|
|
24
|
+
},
|
|
25
|
+
sessionEvent: {
|
|
26
|
+
all: new Set(),
|
|
27
|
+
bySessionId: new Map()
|
|
28
|
+
},
|
|
29
|
+
event: {
|
|
30
|
+
all: new Set(),
|
|
31
|
+
bySessionId: new Map()
|
|
32
|
+
},
|
|
33
|
+
text: {
|
|
34
|
+
all: new Set(),
|
|
35
|
+
bySessionId: new Map()
|
|
36
|
+
},
|
|
37
|
+
audio: {
|
|
38
|
+
all: new Set(),
|
|
39
|
+
bySessionId: new Map()
|
|
40
|
+
},
|
|
41
|
+
video: {
|
|
42
|
+
all: new Set(),
|
|
43
|
+
bySessionId: new Map()
|
|
44
|
+
},
|
|
45
|
+
file: {
|
|
46
|
+
all: new Set(),
|
|
47
|
+
bySessionId: new Map()
|
|
48
|
+
},
|
|
49
|
+
image: {
|
|
50
|
+
all: new Set(),
|
|
51
|
+
bySessionId: new Map()
|
|
52
|
+
}
|
|
23
53
|
};
|
|
24
54
|
}
|
|
55
|
+
isSessionAwareType(type) {
|
|
56
|
+
return type !== 'connectionState';
|
|
57
|
+
}
|
|
58
|
+
getEntrySessionIds(entry) {
|
|
59
|
+
if (entry.type === 'event' || entry.type === 'sessionEvent' || entry.type === 'sessionState') {
|
|
60
|
+
return entry.body.sessionId ? [entry.body.sessionId] : [];
|
|
61
|
+
}
|
|
62
|
+
if (entry.type === 'text' || entry.type === 'audio' || entry.type === 'video' || entry.type === 'file' || entry.type === 'image') {
|
|
63
|
+
return entry.body.sessionIdList || [];
|
|
64
|
+
}
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
collectObservers(entry) {
|
|
68
|
+
const bucket = this.observerMap[entry.type];
|
|
69
|
+
const observers = new Set(bucket.all);
|
|
70
|
+
this.getEntrySessionIds(entry).forEach(sessionId => {
|
|
71
|
+
const sessionObservers = bucket.bySessionId.get(sessionId);
|
|
72
|
+
sessionObservers === null || sessionObservers === void 0 || sessionObservers.forEach(observer => {
|
|
73
|
+
observers.add(observer);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
return observers;
|
|
77
|
+
}
|
|
78
|
+
addObserver(type, observer) {
|
|
79
|
+
const sessionId = observer.options.sessionId;
|
|
80
|
+
const bucket = this.observerMap[type];
|
|
81
|
+
if (!sessionId || !this.isSessionAwareType(type)) {
|
|
82
|
+
bucket.all.add(observer);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
let sessionObservers = bucket.bySessionId.get(sessionId);
|
|
86
|
+
if (!sessionObservers) {
|
|
87
|
+
sessionObservers = new Set();
|
|
88
|
+
bucket.bySessionId.set(sessionId, sessionObservers);
|
|
89
|
+
}
|
|
90
|
+
sessionObservers.add(observer);
|
|
91
|
+
}
|
|
92
|
+
removeObserver(type, observer) {
|
|
93
|
+
const bucket = this.observerMap[type];
|
|
94
|
+
bucket.all.delete(observer);
|
|
95
|
+
bucket.bySessionId.forEach((sessionObservers, sessionId) => {
|
|
96
|
+
sessionObservers.delete(observer);
|
|
97
|
+
if (sessionObservers.size === 0) {
|
|
98
|
+
bucket.bySessionId.delete(sessionId);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
25
102
|
start() {
|
|
26
103
|
if (this.isStarted) {
|
|
27
104
|
return;
|
|
28
105
|
}
|
|
29
106
|
const handle = entry => {
|
|
30
107
|
var _entry$body;
|
|
31
|
-
const observers = this.
|
|
108
|
+
const observers = this.collectObservers(entry);
|
|
32
109
|
let state = '';
|
|
33
110
|
if (entry.type === 'connectionState') {
|
|
34
111
|
state = "".concat(ConnectState[entry.body.connectState], " ").concat(entry.body.code || '');
|
|
@@ -47,18 +124,19 @@ export class AIStreamObserverPool {
|
|
|
47
124
|
sessionId
|
|
48
125
|
} = observer.options;
|
|
49
126
|
let matched = true;
|
|
127
|
+
const sessionIdList = entry.body.sessionIdList || [];
|
|
50
128
|
if (dataChannels !== null && dataChannels !== void 0 && dataChannels.length && !dataChannels.includes(entry.body.dataChannel)) {
|
|
51
129
|
matched = false;
|
|
52
130
|
}
|
|
53
|
-
if (sessionId && !
|
|
131
|
+
if (sessionId && !sessionIdList.includes(sessionId)) {
|
|
54
132
|
matched = false;
|
|
55
133
|
}
|
|
56
134
|
if (matched) {
|
|
57
135
|
observer.callback(entry, observer);
|
|
58
136
|
}
|
|
59
|
-
} else {
|
|
137
|
+
} else if (!((entry.type === 'event' || entry.type === 'sessionEvent' || entry.type === 'sessionState') && observer.options.sessionId && observer.options.sessionId !== entry.body.sessionId)) {
|
|
60
138
|
observer.callback(entry, observer);
|
|
61
|
-
}
|
|
139
|
+
} // noop
|
|
62
140
|
});
|
|
63
141
|
};
|
|
64
142
|
this.cancels = [listenConnectStateChanged(body => handle({
|
|
@@ -98,36 +176,26 @@ export class AIStreamObserverPool {
|
|
|
98
176
|
this.isStarted = false;
|
|
99
177
|
this.cancels.forEach(cancel => cancel());
|
|
100
178
|
this.cancels = [];
|
|
101
|
-
this.observerMap =
|
|
102
|
-
connectionState: new Set(),
|
|
103
|
-
sessionState: new Set(),
|
|
104
|
-
sessionEvent: new Set(),
|
|
105
|
-
event: new Set(),
|
|
106
|
-
text: new Set(),
|
|
107
|
-
audio: new Set(),
|
|
108
|
-
video: new Set(),
|
|
109
|
-
file: new Set(),
|
|
110
|
-
image: new Set()
|
|
111
|
-
};
|
|
179
|
+
this.observerMap = this.createObserverMap();
|
|
112
180
|
}
|
|
113
181
|
connect(observer) {
|
|
114
182
|
if (!this.isStarted) {
|
|
115
183
|
this.start();
|
|
116
184
|
}
|
|
117
|
-
types.forEach(
|
|
118
|
-
const type = key;
|
|
185
|
+
types.forEach(type => {
|
|
119
186
|
if (observer.options[type]) {
|
|
120
|
-
this.
|
|
187
|
+
this.addObserver(type, observer);
|
|
121
188
|
}
|
|
122
189
|
});
|
|
123
190
|
}
|
|
124
191
|
disconnect(observer) {
|
|
125
|
-
types.forEach(
|
|
126
|
-
this.
|
|
192
|
+
types.forEach(type => {
|
|
193
|
+
this.removeObserver(type, observer);
|
|
127
194
|
});
|
|
128
195
|
let empty = true;
|
|
129
|
-
types.forEach(
|
|
130
|
-
|
|
196
|
+
types.forEach(type => {
|
|
197
|
+
const bucket = this.observerMap[type];
|
|
198
|
+
if (bucket.all.size > 0 || bucket.bySessionId.size > 0) {
|
|
131
199
|
empty = false;
|
|
132
200
|
}
|
|
133
201
|
});
|
|
@@ -219,15 +219,17 @@ export function sendBlocksToAIStream(params) {
|
|
|
219
219
|
if (!imageId) {
|
|
220
220
|
imageId = generateId();
|
|
221
221
|
}
|
|
222
|
+
const attachment = {
|
|
223
|
+
streamFlag: data.body.streamFlag,
|
|
224
|
+
path: data.body.path,
|
|
225
|
+
width: data.body.width,
|
|
226
|
+
height: data.body.height
|
|
227
|
+
};
|
|
222
228
|
enqueue({
|
|
223
229
|
id: imageId,
|
|
224
230
|
type: 'attachment',
|
|
225
231
|
attachmentType: 'image',
|
|
226
|
-
attachment:
|
|
227
|
-
path: data.body.path || null,
|
|
228
|
-
width: data.body.width || null,
|
|
229
|
-
height: data.body.height || null
|
|
230
|
-
},
|
|
232
|
+
attachment: attachment,
|
|
231
233
|
meta
|
|
232
234
|
});
|
|
233
235
|
if (data.body.streamFlag === StreamFlag.END) {
|
|
@@ -237,13 +239,20 @@ export function sendBlocksToAIStream(params) {
|
|
|
237
239
|
if (!audioId) {
|
|
238
240
|
audioId = generateId();
|
|
239
241
|
}
|
|
242
|
+
const attachment = {
|
|
243
|
+
streamFlag: data.body.streamFlag,
|
|
244
|
+
path: data.body.path,
|
|
245
|
+
pts: data.body.pts,
|
|
246
|
+
codecType: data.body.codecType,
|
|
247
|
+
sampleRate: data.body.sampleRate,
|
|
248
|
+
channels: data.body.channels,
|
|
249
|
+
bitDepth: data.body.bitDepth
|
|
250
|
+
};
|
|
240
251
|
enqueue({
|
|
241
252
|
id: audioId,
|
|
242
253
|
type: 'attachment',
|
|
243
254
|
attachmentType: 'audio',
|
|
244
|
-
attachment
|
|
245
|
-
path: data.body.path || null
|
|
246
|
-
},
|
|
255
|
+
attachment,
|
|
247
256
|
meta
|
|
248
257
|
});
|
|
249
258
|
if (data.body.streamFlag === StreamFlag.END) {
|
|
@@ -380,6 +389,8 @@ export function sendBlocksToAIStream(params) {
|
|
|
380
389
|
}
|
|
381
390
|
});
|
|
382
391
|
return {
|
|
392
|
+
// web-streams-polyfill's ReadableStream is runtime-compatible but its
|
|
393
|
+
// getReader() overloads differ from lib.dom's, so cast to satisfy the type.
|
|
383
394
|
response: new StreamResponse(stream),
|
|
384
395
|
metaPromise
|
|
385
396
|
};
|
package/dist/utils/ttt.d.ts
CHANGED
|
@@ -72,6 +72,7 @@ export declare const createSession: (options?: Omit<CreateSessionParams, "succes
|
|
|
72
72
|
sessionId: string;
|
|
73
73
|
sendDataChannels: string[];
|
|
74
74
|
revDataChannels: string[];
|
|
75
|
+
baseCacheDir: string;
|
|
75
76
|
}>;
|
|
76
77
|
export declare const closeSession: (options?: Omit<CloseSessionParams, "success" | "fail"> | undefined) => Promise<null>;
|
|
77
78
|
export declare const sendEventStart: (options?: Omit<SendEventStartParams, "success" | "fail"> | undefined) => Promise<{
|
package/dist/utils/ttt.js
CHANGED
|
@@ -42,6 +42,8 @@ export const sendEventStart = promisify(ty.aistream.sendEventStart, true);
|
|
|
42
42
|
export const sendEventPayloadEnd = promisify(ty.aistream.sendEventPayloadEnd, true);
|
|
43
43
|
export const sendEventEnd = promisify(ty.aistream.sendEventEnd, true);
|
|
44
44
|
export const sendEventChatBreak = promisify(ty.aistream.sendEventChatBreak, true);
|
|
45
|
+
|
|
46
|
+
// @ts-ignore
|
|
45
47
|
export const sendEventToAIStream = promisify(ty.aistream.sendEvent, true);
|
|
46
48
|
export const startRecordAndSendAudioData = promisify(ty.aistream.startRecordAndSendAudioData, true);
|
|
47
49
|
export const stopRecordAndSendAudioData = promisify(ty.aistream.stopRecordAndSendAudioData, true);
|
package/dist/withAIStream.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AbortSignalObject, ChatAgent, ChatCardObject, ChatMessage, ChatMessageStatus, ChatTile, GetChatPluginHandler, InputBlock } from '@ray-js/t-agent';
|
|
1
|
+
import { AbortSignalObject, AttachmentPart, ChatAgent, ChatCardObject, ChatMessage, ChatMessageStatus, ChatTile, GetChatPluginHandler, InputBlock } from '@ray-js/t-agent';
|
|
2
2
|
import { TTTAction } from './utils';
|
|
3
3
|
import { AIStreamUserData, ConnectClientType, ReceivedTextSkillPacketBody, SendAIStreamEventParams, SessionEventBody } from './AIStreamTypes';
|
|
4
4
|
import { ChatHistoryStore, StoredMessageObject } from './ChatHistoryStore';
|
|
@@ -46,7 +46,13 @@ export interface AIStreamHooks {
|
|
|
46
46
|
onTextCompose: (respMsg: ChatMessage, status: ChatMessageStatus, result: {
|
|
47
47
|
text: string;
|
|
48
48
|
}) => void;
|
|
49
|
-
onSkillCompose: (skill: ReceivedTextSkillPacketBody
|
|
49
|
+
onSkillCompose: (skill: ReceivedTextSkillPacketBody, respMsg: ChatMessage, result: {
|
|
50
|
+
messages: ChatMessage[];
|
|
51
|
+
}) => void;
|
|
52
|
+
onAttachmentCompose: (part: AttachmentPart, respMsg: ChatMessage, result: {
|
|
53
|
+
messages: ChatMessage[];
|
|
54
|
+
}) => void;
|
|
55
|
+
onAttachmentsEnd: (parts: AttachmentPart[], respMsg: ChatMessage, result: {
|
|
50
56
|
messages: ChatMessage[];
|
|
51
57
|
}) => void;
|
|
52
58
|
onSkillsEnd: (skills: ReceivedTextSkillPacketBody[], respMsg: ChatMessage, result: {
|
|
@@ -94,6 +100,8 @@ export declare function withAIStream(options?: AIStreamOptions): (agent: ChatAge
|
|
|
94
100
|
onCardsReceived: (fn: AIStreamHooks["onCardsReceived"]) => () => void;
|
|
95
101
|
onUserDataRead: (fn: AIStreamHooks["onUserDataRead"]) => () => void;
|
|
96
102
|
onSessionEventReceived: (fn: AIStreamHooks["onSessionEventReceived"]) => () => void;
|
|
103
|
+
onAttachmentCompose: (fn: AIStreamHooks["onAttachmentCompose"]) => () => void;
|
|
104
|
+
onAttachmentsEnd: (fn: AIStreamHooks["onAttachmentsEnd"]) => () => void;
|
|
97
105
|
sendEvent: (params: SendAIStreamEventParams) => Promise<null>;
|
|
98
106
|
onTTTAction: (fn: AIStreamHooks["onTTTAction"]) => () => void;
|
|
99
107
|
getChatId: () => Promise<string>;
|
package/dist/withAIStream.js
CHANGED
|
@@ -93,65 +93,79 @@ export function withAIStream() {
|
|
|
93
93
|
clientType,
|
|
94
94
|
deviceId
|
|
95
95
|
});
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
hooks.callHook('onSessionEventReceived', event);
|
|
115
|
-
});
|
|
116
|
-
await session.set('AIStream.streamSession', streamSession);
|
|
117
|
-
if (options.earlyStart) {
|
|
118
|
-
// 故意异步,不阻塞消息列表加载
|
|
119
|
-
streamSession.ensureSession().catch(error => {
|
|
120
|
-
logger.error('earlyStart failed', error);
|
|
96
|
+
let streamSession = null;
|
|
97
|
+
try {
|
|
98
|
+
streamSession = connection.createSession({
|
|
99
|
+
ownerId: clientType === ConnectClientType.DEVICE ? deviceId : "".concat(homeId),
|
|
100
|
+
api: tokenOptions.api,
|
|
101
|
+
apiVersion: tokenOptions.version,
|
|
102
|
+
solutionCode: agentId,
|
|
103
|
+
extParams: _objectSpread({
|
|
104
|
+
needTts: !!options.enableTts,
|
|
105
|
+
deviceId
|
|
106
|
+
}, tokenOptions.extParams),
|
|
107
|
+
getSessionUserData: async () => {
|
|
108
|
+
const result = {
|
|
109
|
+
userData: {}
|
|
110
|
+
};
|
|
111
|
+
await hooks.callHook('onUserDataRead', 'create-session', {}, result);
|
|
112
|
+
return result.userData;
|
|
113
|
+
}
|
|
121
114
|
});
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
/*
|
|
125
|
-
* 2. 获取历史消息
|
|
126
|
-
*/
|
|
127
|
-
let historyStore;
|
|
128
|
-
if (typeof options.createChatHistoryStore === 'function') {
|
|
129
|
-
historyStore = options.createChatHistoryStore(agent);
|
|
130
|
-
} else {
|
|
131
|
-
historyStore = new ChatHistoryLocalStore({
|
|
132
|
-
bizCode: BizCode.CHAT,
|
|
133
|
-
agentId,
|
|
134
|
-
deviceId,
|
|
135
|
-
homeId,
|
|
136
|
-
indexId
|
|
115
|
+
streamSession.on('sessionEvent', event => {
|
|
116
|
+
hooks.callHook('onSessionEventReceived', event);
|
|
137
117
|
});
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
118
|
+
await session.set('AIStream.connection', connection);
|
|
119
|
+
await session.set('AIStream.streamSession', streamSession);
|
|
120
|
+
if (options.earlyStart) {
|
|
121
|
+
// 故意异步,不阻塞消息列表加载
|
|
122
|
+
streamSession.ensureSession().catch(error => {
|
|
123
|
+
logger.error('earlyStart failed', error);
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/*
|
|
128
|
+
* 2. 获取历史消息
|
|
129
|
+
*/
|
|
130
|
+
let historyStore;
|
|
131
|
+
if (typeof options.createChatHistoryStore === 'function') {
|
|
132
|
+
historyStore = options.createChatHistoryStore(agent);
|
|
133
|
+
} else {
|
|
134
|
+
historyStore = new ChatHistoryLocalStore({
|
|
135
|
+
bizCode: BizCode.CHAT,
|
|
136
|
+
agentId,
|
|
137
|
+
deviceId,
|
|
138
|
+
homeId,
|
|
139
|
+
indexId
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
if (historyStore) {
|
|
143
|
+
await agent.session.set('AIStream.historyStore', historyStore);
|
|
144
|
+
const {
|
|
145
|
+
records
|
|
146
|
+
} = await historyStore.queryAll({
|
|
147
|
+
sort: 'desc',
|
|
148
|
+
// id 倒序去获取最新的消息list,然后再reverse,保证最新的消息在最前面
|
|
149
|
+
limit: options.historySize || 1000,
|
|
150
|
+
offset: 0
|
|
151
|
+
});
|
|
152
|
+
await session.set('AIStream.rawMessages', records.reverse());
|
|
153
|
+
session.isNewChat = records.length === 0;
|
|
154
|
+
} else {
|
|
155
|
+
session.isNewChat = true;
|
|
156
|
+
}
|
|
157
|
+
session.sessionId = indexId;
|
|
158
|
+
} catch (error) {
|
|
159
|
+
if (streamSession) {
|
|
160
|
+
await streamSession.close().catch(closeError => {
|
|
161
|
+
logger.error('withAIStream cleanup streamSession failed', closeError);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
await connection.close().catch(closeError => {
|
|
165
|
+
logger.error('withAIStream cleanup connection failed', closeError);
|
|
148
166
|
});
|
|
149
|
-
|
|
150
|
-
session.isNewChat = records.length === 0;
|
|
151
|
-
} else {
|
|
152
|
-
session.isNewChat = true;
|
|
167
|
+
throw error;
|
|
153
168
|
}
|
|
154
|
-
session.sessionId = indexId;
|
|
155
169
|
});
|
|
156
170
|
const getHistoryStore = () => {
|
|
157
171
|
const historyStore = session.get('AIStream.historyStore');
|
|
@@ -431,6 +445,7 @@ export function withAIStream() {
|
|
|
431
445
|
});
|
|
432
446
|
await hooks.callHook('onChatMessageSent', userMsg, message);
|
|
433
447
|
const skills = [];
|
|
448
|
+
const attachments = [];
|
|
434
449
|
logger.debug('withAIStream chat agent.flushStreamToShow');
|
|
435
450
|
const result = {
|
|
436
451
|
messages: await agent.flushStreamToShow(message, response, {
|
|
@@ -445,17 +460,28 @@ export function withAIStream() {
|
|
|
445
460
|
const result = {
|
|
446
461
|
messages: []
|
|
447
462
|
};
|
|
463
|
+
await hooks.callHook('onAttachmentCompose', part, respMsg, result);
|
|
464
|
+
attachments.push(part);
|
|
448
465
|
if (part.attachmentType === 'skill') {
|
|
449
|
-
|
|
450
|
-
|
|
466
|
+
const skill = part.attachment;
|
|
467
|
+
skills.push(skill);
|
|
468
|
+
await hooks.callHook('onSkillCompose', skill, respMsg, result);
|
|
451
469
|
}
|
|
452
470
|
return result.messages;
|
|
453
471
|
}
|
|
454
472
|
})
|
|
455
473
|
};
|
|
456
474
|
logger.debug('withAIStream chat agent.flushStreamToShow end');
|
|
475
|
+
let changed = false;
|
|
457
476
|
if (skills.length) {
|
|
477
|
+
changed = true;
|
|
458
478
|
await hooks.callHook('onSkillsEnd', skills, message, result);
|
|
479
|
+
}
|
|
480
|
+
if (attachments.length) {
|
|
481
|
+
changed = true;
|
|
482
|
+
await hooks.callHook('onAttachmentsEnd', attachments, message, result);
|
|
483
|
+
}
|
|
484
|
+
if (changed) {
|
|
459
485
|
await message.update();
|
|
460
486
|
}
|
|
461
487
|
let valid = false;
|
|
@@ -533,6 +559,7 @@ export function withAIStream() {
|
|
|
533
559
|
});
|
|
534
560
|
onAgentDispose(async () => {
|
|
535
561
|
const streamSession = session.get('AIStream.streamSession');
|
|
562
|
+
const connection = session.get('AIStream.connection');
|
|
536
563
|
|
|
537
564
|
// 比较低的概率 onAgentStart 还没跑完(卡在获取获取家庭信息)就调用了 dispose
|
|
538
565
|
if (streamSession) {
|
|
@@ -541,6 +568,9 @@ export function withAIStream() {
|
|
|
541
568
|
*/
|
|
542
569
|
await streamSession.close();
|
|
543
570
|
}
|
|
571
|
+
if (connection) {
|
|
572
|
+
await connection.close();
|
|
573
|
+
}
|
|
544
574
|
});
|
|
545
575
|
const handleTTTAction = async (tile, tttAction) => {
|
|
546
576
|
const result = {
|
|
@@ -664,6 +694,12 @@ export function withAIStream() {
|
|
|
664
694
|
onSessionEventReceived: fn => {
|
|
665
695
|
return hooks.hook('onSessionEventReceived', fn);
|
|
666
696
|
},
|
|
697
|
+
onAttachmentCompose: fn => {
|
|
698
|
+
return hooks.hook('onAttachmentCompose', fn);
|
|
699
|
+
},
|
|
700
|
+
onAttachmentsEnd: fn => {
|
|
701
|
+
return hooks.hook('onAttachmentsEnd', fn);
|
|
702
|
+
},
|
|
667
703
|
sendEvent: params => sendEventToAIStream(params),
|
|
668
704
|
onTTTAction: fn => {
|
|
669
705
|
return hooks.hook('onTTTAction', fn);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ray-js/t-agent-plugin-aistream",
|
|
3
|
-
"version": "0.2.8-beta.
|
|
3
|
+
"version": "0.2.8-beta.4",
|
|
4
4
|
"author": "Tuya.inc",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": false,
|
|
@@ -26,7 +26,6 @@
|
|
|
26
26
|
"test:coverage": "jest --runInBand --coverage"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"dayjs": "^1.10.4",
|
|
30
29
|
"url-parse": "^1.5.10",
|
|
31
30
|
"web-streams-polyfill": "^4.0.0"
|
|
32
31
|
},
|
|
@@ -37,5 +36,5 @@
|
|
|
37
36
|
"devDependencies": {
|
|
38
37
|
"@types/url-parse": "^1.4.11"
|
|
39
38
|
},
|
|
40
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "556407c77bdeb9f879a8bb9e89184fc62e4c8bd0"
|
|
41
40
|
}
|