@ynhcj/xiaoyi 2.3.4 → 2.3.6
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/channel.js +53 -25
- package/dist/runtime.d.ts +31 -0
- package/dist/runtime.js +60 -0
- package/dist/types.d.ts +1 -2
- package/dist/websocket.js +9 -11
- package/package.json +1 -1
package/dist/channel.js
CHANGED
|
@@ -215,7 +215,7 @@ exports.xiaoyiPlugin = {
|
|
|
215
215
|
const runtime = getXiaoYiRuntime();
|
|
216
216
|
console.log(`XiaoYi: [Message Handler] Using runtime instance: ${runtime.getInstanceId()}`);
|
|
217
217
|
// Store sessionId -> taskId mapping in runtime (use params.id as taskId)
|
|
218
|
-
runtime.setTaskIdForSession(message.sessionId, message.params.id);
|
|
218
|
+
runtime.setTaskIdForSession(message.params.sessionId, message.params.id);
|
|
219
219
|
// Get PluginRuntime from our runtime wrapper
|
|
220
220
|
const pluginRuntime = runtime.getPluginRuntime();
|
|
221
221
|
if (!pluginRuntime) {
|
|
@@ -291,8 +291,8 @@ exports.xiaoyiPlugin = {
|
|
|
291
291
|
const msgContext = {
|
|
292
292
|
Body: bodyText,
|
|
293
293
|
From: senderId,
|
|
294
|
-
To: message.sessionId,
|
|
295
|
-
SessionKey: `xiaoyi:${resolvedAccount.accountId}:${message.sessionId}`,
|
|
294
|
+
To: message.params.sessionId,
|
|
295
|
+
SessionKey: `xiaoyi:${resolvedAccount.accountId}:${message.params.sessionId}`,
|
|
296
296
|
AccountId: resolvedAccount.accountId,
|
|
297
297
|
MessageSid: message.id, // Use top-level id as message sequence number
|
|
298
298
|
Timestamp: Date.now(), // Generate timestamp since new format doesn't include it
|
|
@@ -307,30 +307,34 @@ exports.xiaoyiPlugin = {
|
|
|
307
307
|
try {
|
|
308
308
|
console.log("\n" + "=".repeat(60));
|
|
309
309
|
console.log(`XiaoYi: [MESSAGE] Processing user message`);
|
|
310
|
-
console.log(` Session: ${message.sessionId}`);
|
|
310
|
+
console.log(` Session: ${message.params.sessionId}`);
|
|
311
311
|
console.log(` Task ID: ${message.params.id}`);
|
|
312
312
|
console.log(` User input: ${bodyText.substring(0, 50)}${bodyText.length > 50 ? "..." : ""}`);
|
|
313
313
|
console.log(` Images: ${images.length}`);
|
|
314
314
|
console.log("=".repeat(60) + "\n");
|
|
315
|
-
const taskId = runtime.getTaskIdForSession(message.sessionId) || `task_${Date.now()}`;
|
|
315
|
+
const taskId = runtime.getTaskIdForSession(message.params.sessionId) || `task_${Date.now()}`;
|
|
316
316
|
const startTime = Date.now();
|
|
317
317
|
let accumulatedText = "";
|
|
318
|
+
// ==================== CREATE ABORT CONTROLLER ====================
|
|
319
|
+
// Create AbortController for this session to allow cancelation
|
|
320
|
+
const { controller: abortController, signal: abortSignal } = runtime.createAbortControllerForSession(message.params.sessionId);
|
|
321
|
+
// ================================================================
|
|
318
322
|
// ==================== START TIMEOUT PROTECTION ====================
|
|
319
323
|
// Start 60-second timeout timer
|
|
320
324
|
const timeoutConfig = runtime.getTimeoutConfig();
|
|
321
|
-
console.log(`[TIMEOUT] Starting ${timeoutConfig.duration}ms timeout protection for session ${message.sessionId}`);
|
|
322
|
-
runtime.setTimeoutForSession(message.sessionId, async () => {
|
|
325
|
+
console.log(`[TIMEOUT] Starting ${timeoutConfig.duration}ms timeout protection for session ${message.params.sessionId}`);
|
|
326
|
+
runtime.setTimeoutForSession(message.params.sessionId, async () => {
|
|
323
327
|
// Timeout callback - send timeout message to user
|
|
324
328
|
const elapsed = Date.now() - startTime;
|
|
325
329
|
console.log("\n" + "=".repeat(60));
|
|
326
|
-
console.log(`[TIMEOUT] Timeout triggered for session ${message.sessionId}`);
|
|
330
|
+
console.log(`[TIMEOUT] Timeout triggered for session ${message.params.sessionId}`);
|
|
327
331
|
console.log(` Elapsed: ${elapsed}ms`);
|
|
328
332
|
console.log(` Task ID: ${taskId}`);
|
|
329
333
|
console.log("=".repeat(60) + "\n");
|
|
330
334
|
const conn = runtime.getConnection();
|
|
331
335
|
if (conn) {
|
|
332
336
|
const timeoutResponse = {
|
|
333
|
-
sessionId: message.sessionId,
|
|
337
|
+
sessionId: message.params.sessionId,
|
|
334
338
|
messageId: `timeout_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
335
339
|
timestamp: Date.now(),
|
|
336
340
|
agentId: resolvedAccount.config.agentId,
|
|
@@ -346,8 +350,8 @@ exports.xiaoyiPlugin = {
|
|
|
346
350
|
status: "success",
|
|
347
351
|
};
|
|
348
352
|
try {
|
|
349
|
-
await conn.sendResponse(timeoutResponse, taskId, message.sessionId, true, false);
|
|
350
|
-
console.log(`[TIMEOUT] Timeout message sent successfully to session ${message.sessionId}\n`);
|
|
353
|
+
await conn.sendResponse(timeoutResponse, taskId, message.params.sessionId, true, false);
|
|
354
|
+
console.log(`[TIMEOUT] Timeout message sent successfully to session ${message.params.sessionId}\n`);
|
|
351
355
|
}
|
|
352
356
|
catch (error) {
|
|
353
357
|
console.error(`[TIMEOUT] Failed to send timeout message:`, error);
|
|
@@ -366,12 +370,22 @@ exports.xiaoyiPlugin = {
|
|
|
366
370
|
const elapsed = Date.now() - startTime;
|
|
367
371
|
const completeText = payload.text || "";
|
|
368
372
|
accumulatedText = completeText;
|
|
373
|
+
// Check if session was aborted
|
|
374
|
+
if (runtime.isSessionAborted(message.params.sessionId)) {
|
|
375
|
+
console.log("\n" + "=".repeat(60));
|
|
376
|
+
console.log(`[ABORT] Response received AFTER abort`);
|
|
377
|
+
console.log(` Session: ${message.params.sessionId}`);
|
|
378
|
+
console.log(` Elapsed: ${elapsed}ms`);
|
|
379
|
+
console.log(` Action: DISCARDING (session was canceled)`);
|
|
380
|
+
console.log("=".repeat(60) + "\n");
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
369
383
|
// ==================== CHECK TIMEOUT ====================
|
|
370
384
|
// If timeout already sent, discard this response
|
|
371
|
-
if (runtime.isSessionTimeout(message.sessionId)) {
|
|
385
|
+
if (runtime.isSessionTimeout(message.params.sessionId)) {
|
|
372
386
|
console.log("\n" + "=".repeat(60));
|
|
373
387
|
console.log(`[TIMEOUT] Response received AFTER timeout`);
|
|
374
|
-
console.log(` Session: ${message.sessionId}`);
|
|
388
|
+
console.log(` Session: ${message.params.sessionId}`);
|
|
375
389
|
console.log(` Elapsed: ${elapsed}ms`);
|
|
376
390
|
console.log(` Action: DISCARDING (timeout message already sent)`);
|
|
377
391
|
console.log("=".repeat(60) + "\n");
|
|
@@ -382,7 +396,7 @@ exports.xiaoyiPlugin = {
|
|
|
382
396
|
if (!completeText || completeText.length === 0) {
|
|
383
397
|
console.log("\n" + "=".repeat(60));
|
|
384
398
|
console.log(`[TIMEOUT] Empty response detected`);
|
|
385
|
-
console.log(` Session: ${message.sessionId}`);
|
|
399
|
+
console.log(` Session: ${message.params.sessionId}`);
|
|
386
400
|
console.log(` Elapsed: ${elapsed}ms`);
|
|
387
401
|
console.log(` Action: KEEPING TIMEOUT (session conflict detected)`);
|
|
388
402
|
console.log("=".repeat(60) + "\n");
|
|
@@ -397,7 +411,7 @@ exports.xiaoyiPlugin = {
|
|
|
397
411
|
console.log("-".repeat(60) + "\n");
|
|
398
412
|
// Send final response to XiaoYi
|
|
399
413
|
const response = {
|
|
400
|
-
sessionId: message.sessionId,
|
|
414
|
+
sessionId: message.params.sessionId,
|
|
401
415
|
messageId: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
402
416
|
timestamp: Date.now(),
|
|
403
417
|
agentId: resolvedAccount.config.agentId,
|
|
@@ -414,14 +428,14 @@ exports.xiaoyiPlugin = {
|
|
|
414
428
|
};
|
|
415
429
|
const conn = runtime.getConnection();
|
|
416
430
|
if (conn) {
|
|
417
|
-
await conn.sendResponse(response, taskId, message.sessionId, true, false);
|
|
431
|
+
await conn.sendResponse(response, taskId, message.params.sessionId, true, false);
|
|
418
432
|
console.log(`✓ XiaoYi: Response sent successfully\n`);
|
|
419
433
|
}
|
|
420
434
|
else {
|
|
421
435
|
console.error(`✗ XiaoYi: Connection not available\n`);
|
|
422
436
|
}
|
|
423
437
|
// Clear timeout as response was sent successfully
|
|
424
|
-
runtime.markSessionCompleted(message.sessionId);
|
|
438
|
+
runtime.markSessionCompleted(message.params.sessionId);
|
|
425
439
|
},
|
|
426
440
|
onIdle: async () => {
|
|
427
441
|
const elapsed = Date.now() - startTime;
|
|
@@ -432,7 +446,8 @@ exports.xiaoyiPlugin = {
|
|
|
432
446
|
// Only clear timeout if we have a valid response
|
|
433
447
|
// If empty, keep timeout running to handle session conflict
|
|
434
448
|
if (accumulatedText.length > 0) {
|
|
435
|
-
runtime.markSessionCompleted(message.sessionId);
|
|
449
|
+
runtime.markSessionCompleted(message.params.sessionId);
|
|
450
|
+
runtime.clearAbortControllerForSession(message.params.sessionId);
|
|
436
451
|
console.log(`[TIMEOUT] Timeout cleared (valid response)\n`);
|
|
437
452
|
}
|
|
438
453
|
else {
|
|
@@ -441,26 +456,39 @@ exports.xiaoyiPlugin = {
|
|
|
441
456
|
console.log("=".repeat(60) + "\n");
|
|
442
457
|
},
|
|
443
458
|
},
|
|
444
|
-
replyOptions:
|
|
459
|
+
replyOptions: {
|
|
460
|
+
abortSignal: abortSignal, // Pass abort signal to allow cancellation
|
|
461
|
+
},
|
|
445
462
|
images: images.length > 0 ? images : undefined,
|
|
446
463
|
});
|
|
447
464
|
}
|
|
448
465
|
catch (error) {
|
|
449
466
|
console.error("XiaoYi: [ERROR] Error dispatching message:", error);
|
|
450
467
|
// Clear timeout on error
|
|
451
|
-
runtime.clearSessionTimeout(message.sessionId);
|
|
468
|
+
runtime.clearSessionTimeout(message.params.sessionId);
|
|
469
|
+
// Clear abort controller on error
|
|
470
|
+
runtime.clearAbortControllerForSession(message.params.sessionId);
|
|
452
471
|
}
|
|
453
472
|
});
|
|
454
473
|
// Setup cancel handler
|
|
455
|
-
//
|
|
474
|
+
// When tasks/cancel is received, abort the current session's agent run
|
|
456
475
|
connection.on("cancel", async (data) => {
|
|
476
|
+
const { sessionId } = data;
|
|
457
477
|
console.log("\n" + "=".repeat(60));
|
|
458
|
-
console.log(`XiaoYi: [CANCEL] Cancel event received
|
|
459
|
-
console.log(` Session: ${
|
|
478
|
+
console.log(`XiaoYi: [CANCEL] Cancel event received`);
|
|
479
|
+
console.log(` Session: ${sessionId}`);
|
|
460
480
|
console.log(` Task ID: ${data.taskId || "N/A"}`);
|
|
461
481
|
console.log("=".repeat(60) + "\n");
|
|
462
|
-
//
|
|
463
|
-
|
|
482
|
+
// Abort the session's agent run
|
|
483
|
+
const aborted = runtime.abortSession(sessionId);
|
|
484
|
+
if (aborted) {
|
|
485
|
+
console.log(`[CANCEL] Successfully triggered abort for session ${sessionId}`);
|
|
486
|
+
}
|
|
487
|
+
else {
|
|
488
|
+
console.log(`[CANCEL] No active agent run found for session ${sessionId}`);
|
|
489
|
+
}
|
|
490
|
+
// Clear timeout as the session is being canceled
|
|
491
|
+
runtime.markSessionCompleted(sessionId);
|
|
464
492
|
});
|
|
465
493
|
console.log("XiaoYi: Event handlers registered");
|
|
466
494
|
console.log("XiaoYi: startAccount() completed - END");
|
package/dist/runtime.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export declare class XiaoYiRuntime {
|
|
|
21
21
|
private sessionTimeoutMap;
|
|
22
22
|
private sessionTimeoutSent;
|
|
23
23
|
private timeoutConfig;
|
|
24
|
+
private sessionAbortControllerMap;
|
|
24
25
|
constructor();
|
|
25
26
|
getInstanceId(): string;
|
|
26
27
|
/**
|
|
@@ -97,6 +98,36 @@ export declare class XiaoYiRuntime {
|
|
|
97
98
|
* Clear taskId for a session
|
|
98
99
|
*/
|
|
99
100
|
clearTaskIdForSession(sessionId: string): void;
|
|
101
|
+
/**
|
|
102
|
+
* Create and register an AbortController for a session
|
|
103
|
+
* @param sessionId - Session ID
|
|
104
|
+
* @returns The AbortController and its signal
|
|
105
|
+
*/
|
|
106
|
+
createAbortControllerForSession(sessionId: string): {
|
|
107
|
+
controller: AbortController;
|
|
108
|
+
signal: AbortSignal;
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* Abort a session's agent run
|
|
112
|
+
* @param sessionId - Session ID
|
|
113
|
+
* @returns true if a controller was found and aborted, false otherwise
|
|
114
|
+
*/
|
|
115
|
+
abortSession(sessionId: string): boolean;
|
|
116
|
+
/**
|
|
117
|
+
* Check if a session has been aborted
|
|
118
|
+
* @param sessionId - Session ID
|
|
119
|
+
* @returns true if the session's abort signal was triggered
|
|
120
|
+
*/
|
|
121
|
+
isSessionAborted(sessionId: string): boolean;
|
|
122
|
+
/**
|
|
123
|
+
* Clear the AbortController for a session (call when agent completes successfully)
|
|
124
|
+
* @param sessionId - Session ID
|
|
125
|
+
*/
|
|
126
|
+
clearAbortControllerForSession(sessionId: string): void;
|
|
127
|
+
/**
|
|
128
|
+
* Clear all AbortControllers
|
|
129
|
+
*/
|
|
130
|
+
clearAllAbortControllers(): void;
|
|
100
131
|
}
|
|
101
132
|
export declare function getXiaoYiRuntime(): XiaoYiRuntime;
|
|
102
133
|
export declare function setXiaoYiRuntime(runtime: any): void;
|
package/dist/runtime.js
CHANGED
|
@@ -26,6 +26,8 @@ class XiaoYiRuntime {
|
|
|
26
26
|
this.sessionTimeoutMap = new Map();
|
|
27
27
|
this.sessionTimeoutSent = new Set();
|
|
28
28
|
this.timeoutConfig = DEFAULT_TIMEOUT_CONFIG;
|
|
29
|
+
// AbortController management for canceling agent runs
|
|
30
|
+
this.sessionAbortControllerMap = new Map();
|
|
29
31
|
this.instanceId = `runtime_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
30
32
|
console.log(`XiaoYi: Created new runtime instance: ${this.instanceId}`);
|
|
31
33
|
}
|
|
@@ -100,6 +102,8 @@ class XiaoYiRuntime {
|
|
|
100
102
|
this.sessionToTaskIdMap.clear();
|
|
101
103
|
// Clear all timeouts
|
|
102
104
|
this.clearAllTimeouts();
|
|
105
|
+
// Clear all abort controllers
|
|
106
|
+
this.clearAllAbortControllers();
|
|
103
107
|
}
|
|
104
108
|
/**
|
|
105
109
|
* Set timeout configuration
|
|
@@ -220,6 +224,62 @@ class XiaoYiRuntime {
|
|
|
220
224
|
clearTaskIdForSession(sessionId) {
|
|
221
225
|
this.sessionToTaskIdMap.delete(sessionId);
|
|
222
226
|
}
|
|
227
|
+
/**
|
|
228
|
+
* Create and register an AbortController for a session
|
|
229
|
+
* @param sessionId - Session ID
|
|
230
|
+
* @returns The AbortController and its signal
|
|
231
|
+
*/
|
|
232
|
+
createAbortControllerForSession(sessionId) {
|
|
233
|
+
// Abort any existing controller for this session
|
|
234
|
+
this.abortSession(sessionId);
|
|
235
|
+
const controller = new AbortController();
|
|
236
|
+
this.sessionAbortControllerMap.set(sessionId, controller);
|
|
237
|
+
console.log(`[ABORT] Created AbortController for session ${sessionId}`);
|
|
238
|
+
return { controller, signal: controller.signal };
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Abort a session's agent run
|
|
242
|
+
* @param sessionId - Session ID
|
|
243
|
+
* @returns true if a controller was found and aborted, false otherwise
|
|
244
|
+
*/
|
|
245
|
+
abortSession(sessionId) {
|
|
246
|
+
const controller = this.sessionAbortControllerMap.get(sessionId);
|
|
247
|
+
if (controller) {
|
|
248
|
+
console.log(`[ABORT] Aborting session ${sessionId}`);
|
|
249
|
+
controller.abort();
|
|
250
|
+
this.sessionAbortControllerMap.delete(sessionId);
|
|
251
|
+
return true;
|
|
252
|
+
}
|
|
253
|
+
console.log(`[ABORT] No AbortController found for session ${sessionId}`);
|
|
254
|
+
return false;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Check if a session has been aborted
|
|
258
|
+
* @param sessionId - Session ID
|
|
259
|
+
* @returns true if the session's abort signal was triggered
|
|
260
|
+
*/
|
|
261
|
+
isSessionAborted(sessionId) {
|
|
262
|
+
const controller = this.sessionAbortControllerMap.get(sessionId);
|
|
263
|
+
return controller ? controller.signal.aborted : false;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Clear the AbortController for a session (call when agent completes successfully)
|
|
267
|
+
* @param sessionId - Session ID
|
|
268
|
+
*/
|
|
269
|
+
clearAbortControllerForSession(sessionId) {
|
|
270
|
+
const controller = this.sessionAbortControllerMap.get(sessionId);
|
|
271
|
+
if (controller) {
|
|
272
|
+
this.sessionAbortControllerMap.delete(sessionId);
|
|
273
|
+
console.log(`[ABORT] Cleared AbortController for session ${sessionId}`);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Clear all AbortControllers
|
|
278
|
+
*/
|
|
279
|
+
clearAllAbortControllers() {
|
|
280
|
+
this.sessionAbortControllerMap.clear();
|
|
281
|
+
console.log("[ABORT] All AbortControllers cleared");
|
|
282
|
+
}
|
|
223
283
|
}
|
|
224
284
|
exports.XiaoYiRuntime = XiaoYiRuntime;
|
|
225
285
|
// Global runtime instance - use global object to survive module reloads
|
package/dist/types.d.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
export interface A2ARequestMessage {
|
|
2
2
|
agentId: string;
|
|
3
|
-
sessionId: string;
|
|
4
3
|
jsonrpc: "2.0";
|
|
5
4
|
id: string;
|
|
6
5
|
method: "message/stream";
|
|
7
6
|
params: {
|
|
8
7
|
id: string;
|
|
9
|
-
sessionId
|
|
8
|
+
sessionId: string;
|
|
10
9
|
agentLoginSessionId?: string;
|
|
11
10
|
message: {
|
|
12
11
|
role: "user" | "agent";
|
package/dist/websocket.js
CHANGED
|
@@ -320,9 +320,9 @@ class XiaoYiWebSocketManager extends events_1.EventEmitter {
|
|
|
320
320
|
return;
|
|
321
321
|
}
|
|
322
322
|
// Record session → server mapping
|
|
323
|
-
if (message.sessionId) {
|
|
324
|
-
this.sessionServerMap.set(message.sessionId, sourceServer);
|
|
325
|
-
console.log(`[MAP] Session ${message.sessionId} -> ${sourceServer}`);
|
|
323
|
+
if (message.params.sessionId) {
|
|
324
|
+
this.sessionServerMap.set(message.params.sessionId, sourceServer);
|
|
325
|
+
console.log(`[MAP] Session ${message.params.sessionId} -> ${sourceServer}`);
|
|
326
326
|
}
|
|
327
327
|
// Handle special messages (clearContext, tasks/cancel)
|
|
328
328
|
if (message.method === "clearContext") {
|
|
@@ -341,7 +341,7 @@ class XiaoYiWebSocketManager extends events_1.EventEmitter {
|
|
|
341
341
|
if (this.isA2ARequestMessage(message)) {
|
|
342
342
|
// Store task for potential cancellation
|
|
343
343
|
this.activeTasks.set(message.id, {
|
|
344
|
-
sessionId: message.sessionId,
|
|
344
|
+
sessionId: message.params.sessionId,
|
|
345
345
|
timestamp: Date.now(),
|
|
346
346
|
});
|
|
347
347
|
// Emit with server info
|
|
@@ -476,16 +476,16 @@ class XiaoYiWebSocketManager extends events_1.EventEmitter {
|
|
|
476
476
|
* Handle clearContext method
|
|
477
477
|
*/
|
|
478
478
|
handleClearContext(message, sourceServer) {
|
|
479
|
-
console.log(`[${sourceServer}] Received clearContext for session: ${message.sessionId}`);
|
|
480
|
-
this.sendClearContextResponse(message.id, message.sessionId, true, sourceServer)
|
|
479
|
+
console.log(`[${sourceServer}] Received clearContext for session: ${message.params.sessionId}`);
|
|
480
|
+
this.sendClearContextResponse(message.id, message.params.sessionId, true, sourceServer)
|
|
481
481
|
.catch(error => console.error(`[${sourceServer}] Failed to send clearContext response:`, error));
|
|
482
482
|
this.emit("clear", {
|
|
483
|
-
sessionId: message.sessionId,
|
|
483
|
+
sessionId: message.params.sessionId,
|
|
484
484
|
id: message.id,
|
|
485
485
|
serverId: sourceServer,
|
|
486
486
|
});
|
|
487
487
|
// Remove session mapping
|
|
488
|
-
this.sessionServerMap.delete(message.sessionId);
|
|
488
|
+
this.sessionServerMap.delete(message.params.sessionId);
|
|
489
489
|
}
|
|
490
490
|
/**
|
|
491
491
|
* Handle clear message (legacy format)
|
|
@@ -770,14 +770,12 @@ class XiaoYiWebSocketManager extends events_1.EventEmitter {
|
|
|
770
770
|
isA2ARequestMessage(data) {
|
|
771
771
|
return data &&
|
|
772
772
|
typeof data.agentId === "string" &&
|
|
773
|
-
typeof data.sessionId === "string" &&
|
|
774
773
|
data.jsonrpc === "2.0" &&
|
|
775
774
|
typeof data.id === "string" &&
|
|
776
775
|
data.method === "message/stream" &&
|
|
777
776
|
data.params &&
|
|
778
777
|
typeof data.params.id === "string" &&
|
|
779
|
-
|
|
780
|
-
(data.params.sessionId === undefined || typeof data.params.sessionId === "string") &&
|
|
778
|
+
typeof data.params.sessionId === "string" &&
|
|
781
779
|
data.params.message &&
|
|
782
780
|
typeof data.params.message.role === "string" &&
|
|
783
781
|
Array.isArray(data.params.message.parts);
|