@ynhcj/xiaoyi 2.5.5 → 2.5.7
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/auth.d.ts +1 -1
- package/dist/channel.d.ts +116 -14
- package/dist/channel.js +199 -665
- package/dist/config-schema.d.ts +8 -8
- package/dist/config-schema.js +5 -5
- package/dist/file-download.d.ts +17 -0
- package/dist/file-download.js +69 -0
- package/dist/heartbeat.d.ts +39 -0
- package/dist/heartbeat.js +102 -0
- package/dist/index.d.ts +1 -4
- package/dist/index.js +7 -11
- package/dist/push.d.ts +28 -0
- package/dist/push.js +135 -0
- package/dist/runtime.d.ts +48 -2
- package/dist/runtime.js +117 -3
- package/dist/types.d.ts +95 -1
- package/dist/websocket.d.ts +49 -1
- package/dist/websocket.js +279 -20
- package/dist/xy-bot.d.ts +19 -0
- package/dist/xy-bot.js +277 -0
- package/dist/xy-client.d.ts +26 -0
- package/dist/xy-client.js +78 -0
- package/dist/xy-config.d.ts +18 -0
- package/dist/xy-config.js +37 -0
- package/dist/xy-formatter.d.ts +94 -0
- package/dist/xy-formatter.js +303 -0
- package/dist/xy-monitor.d.ts +17 -0
- package/dist/xy-monitor.js +187 -0
- package/dist/xy-parser.d.ts +49 -0
- package/dist/xy-parser.js +109 -0
- package/dist/xy-reply-dispatcher.d.ts +17 -0
- package/dist/xy-reply-dispatcher.js +308 -0
- package/dist/xy-tools/session-manager.d.ts +29 -0
- package/dist/xy-tools/session-manager.js +80 -0
- package/dist/xy-utils/config-manager.d.ts +26 -0
- package/dist/xy-utils/config-manager.js +61 -0
- package/dist/xy-utils/crypto.d.ts +8 -0
- package/dist/xy-utils/crypto.js +21 -0
- package/dist/xy-utils/logger.d.ts +6 -0
- package/dist/xy-utils/logger.js +37 -0
- package/dist/xy-utils/session.d.ts +34 -0
- package/dist/xy-utils/session.js +55 -0
- package/package.json +32 -16
package/dist/runtime.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.XiaoYiRuntime = void 0;
|
|
4
4
|
exports.getXiaoYiRuntime = getXiaoYiRuntime;
|
|
5
5
|
exports.setXiaoYiRuntime = setXiaoYiRuntime;
|
|
6
|
-
const
|
|
6
|
+
const websocket_js_1 = require("./websocket.js");
|
|
7
7
|
/**
|
|
8
8
|
* Default timeout configuration
|
|
9
9
|
*/
|
|
@@ -30,6 +30,12 @@ class XiaoYiRuntime {
|
|
|
30
30
|
this.sessionAbortControllerMap = new Map();
|
|
31
31
|
// Track if a session has an active agent run (for concurrent request detection)
|
|
32
32
|
this.sessionActiveRunMap = new Map();
|
|
33
|
+
// Track session start time for timeout detection
|
|
34
|
+
this.sessionStartTimeMap = new Map();
|
|
35
|
+
// 1-hour task timeout mechanism
|
|
36
|
+
this.sessionTaskTimeoutMap = new Map();
|
|
37
|
+
this.sessionPushPendingMap = new Map();
|
|
38
|
+
this.taskTimeoutMs = 3600000; // Default 1 hour
|
|
33
39
|
this.instanceId = `runtime_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
34
40
|
console.log(`XiaoYi: Created new runtime instance: ${this.instanceId}`);
|
|
35
41
|
}
|
|
@@ -58,7 +64,7 @@ class XiaoYiRuntime {
|
|
|
58
64
|
return;
|
|
59
65
|
}
|
|
60
66
|
this.config = config;
|
|
61
|
-
const manager = new
|
|
67
|
+
const manager = new websocket_js_1.XiaoYiWebSocketManager(config);
|
|
62
68
|
// Setup basic event handlers (message handling is done in channel.ts)
|
|
63
69
|
manager.on("error", (error) => {
|
|
64
70
|
console.error("XiaoYi channel error:", error);
|
|
@@ -106,6 +112,10 @@ class XiaoYiRuntime {
|
|
|
106
112
|
this.clearAllTimeouts();
|
|
107
113
|
// Clear all abort controllers
|
|
108
114
|
this.clearAllAbortControllers();
|
|
115
|
+
// Clear all task timeout state
|
|
116
|
+
for (const sessionId of this.sessionTaskTimeoutMap.keys()) {
|
|
117
|
+
this.clearTaskTimeoutState(sessionId);
|
|
118
|
+
}
|
|
109
119
|
}
|
|
110
120
|
/**
|
|
111
121
|
* Set timeout configuration
|
|
@@ -246,16 +256,35 @@ class XiaoYiRuntime {
|
|
|
246
256
|
const controller = new AbortController();
|
|
247
257
|
this.sessionAbortControllerMap.set(sessionId, controller);
|
|
248
258
|
this.sessionActiveRunMap.set(sessionId, true);
|
|
259
|
+
this.sessionStartTimeMap.set(sessionId, Date.now());
|
|
249
260
|
console.log(`[ABORT] Created AbortController for session ${sessionId}`);
|
|
250
261
|
return { controller, signal: controller.signal };
|
|
251
262
|
}
|
|
252
263
|
/**
|
|
253
264
|
* Check if a session has an active agent run
|
|
265
|
+
* If session is active but stale (超过 SESSION_STALE_TIMEOUT_MS), automatically clean up
|
|
254
266
|
* @param sessionId - Session ID
|
|
255
267
|
* @returns true if session is busy
|
|
256
268
|
*/
|
|
257
269
|
isSessionActive(sessionId) {
|
|
258
|
-
|
|
270
|
+
const isActive = this.sessionActiveRunMap.get(sessionId) || false;
|
|
271
|
+
if (isActive) {
|
|
272
|
+
// Check if the session has been active for too long
|
|
273
|
+
const startTime = this.sessionStartTimeMap.get(sessionId);
|
|
274
|
+
if (startTime) {
|
|
275
|
+
const elapsed = Date.now() - startTime;
|
|
276
|
+
if (elapsed > XiaoYiRuntime.SESSION_STALE_TIMEOUT_MS) {
|
|
277
|
+
// Session is stale, auto-cleanup and return false
|
|
278
|
+
console.log(`[CONCURRENT] Session ${sessionId} is stale (active for ${elapsed}ms), auto-cleaning`);
|
|
279
|
+
this.clearAbortControllerForSession(sessionId);
|
|
280
|
+
this.clearTaskIdForSession(sessionId);
|
|
281
|
+
this.clearSessionTimeout(sessionId);
|
|
282
|
+
this.sessionStartTimeMap.delete(sessionId);
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return isActive;
|
|
259
288
|
}
|
|
260
289
|
/**
|
|
261
290
|
* Abort a session's agent run
|
|
@@ -294,6 +323,8 @@ class XiaoYiRuntime {
|
|
|
294
323
|
}
|
|
295
324
|
// Also clear the active run flag
|
|
296
325
|
this.sessionActiveRunMap.delete(sessionId);
|
|
326
|
+
// Clear the session start time
|
|
327
|
+
this.sessionStartTimeMap.delete(sessionId);
|
|
297
328
|
console.log(`[CONCURRENT] Session ${sessionId} marked as inactive`);
|
|
298
329
|
}
|
|
299
330
|
/**
|
|
@@ -303,8 +334,91 @@ class XiaoYiRuntime {
|
|
|
303
334
|
this.sessionAbortControllerMap.clear();
|
|
304
335
|
console.log("[ABORT] All AbortControllers cleared");
|
|
305
336
|
}
|
|
337
|
+
// ==================== PUSH STATE MANAGEMENT HELPERS ====================
|
|
338
|
+
/**
|
|
339
|
+
* Generate a composite key for session+task combination
|
|
340
|
+
* This ensures each task has its own push state, even within the same session
|
|
341
|
+
*/
|
|
342
|
+
getPushStateKey(sessionId, taskId) {
|
|
343
|
+
return `${sessionId}:${taskId}`;
|
|
344
|
+
}
|
|
345
|
+
// ==================== END PUSH STATE MANAGEMENT HELPERS ====================
|
|
346
|
+
// ==================== 1-HOUR TASK TIMEOUT METHODS ====================
|
|
347
|
+
/**
|
|
348
|
+
* Set task timeout time (from configuration)
|
|
349
|
+
*/
|
|
350
|
+
setTaskTimeout(timeoutMs) {
|
|
351
|
+
this.taskTimeoutMs = timeoutMs;
|
|
352
|
+
console.log(`[TASK TIMEOUT] Task timeout set to ${timeoutMs}ms`);
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Set a 1-hour task timeout timer for a session
|
|
356
|
+
* @returns timeout ID
|
|
357
|
+
*/
|
|
358
|
+
setTaskTimeoutForSession(sessionId, taskId, callback) {
|
|
359
|
+
this.clearTaskTimeoutForSession(sessionId);
|
|
360
|
+
const timeoutId = setTimeout(() => {
|
|
361
|
+
console.log(`[TASK TIMEOUT] ${this.taskTimeoutMs}ms timeout triggered for session ${sessionId}, task ${taskId}`);
|
|
362
|
+
callback(sessionId, taskId);
|
|
363
|
+
}, this.taskTimeoutMs);
|
|
364
|
+
this.sessionTaskTimeoutMap.set(sessionId, timeoutId);
|
|
365
|
+
console.log(`[TASK TIMEOUT] ${this.taskTimeoutMs}ms task timeout started for session ${sessionId}`);
|
|
366
|
+
return timeoutId;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Clear the task timeout timer for a session
|
|
370
|
+
*/
|
|
371
|
+
clearTaskTimeoutForSession(sessionId) {
|
|
372
|
+
const timeoutId = this.sessionTaskTimeoutMap.get(sessionId);
|
|
373
|
+
if (timeoutId) {
|
|
374
|
+
clearTimeout(timeoutId);
|
|
375
|
+
this.sessionTaskTimeoutMap.delete(sessionId);
|
|
376
|
+
console.log(`[TASK TIMEOUT] Timeout cleared for session ${sessionId}`);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Check if session+task is waiting for push notification
|
|
381
|
+
* @param sessionId - Session ID
|
|
382
|
+
* @param taskId - Task ID (optional, for per-task tracking)
|
|
383
|
+
*/
|
|
384
|
+
isSessionWaitingForPush(sessionId, taskId) {
|
|
385
|
+
const key = taskId ? this.getPushStateKey(sessionId, taskId) : sessionId;
|
|
386
|
+
return this.sessionPushPendingMap.get(key) === true;
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Mark session+task as waiting for push notification
|
|
390
|
+
* @param sessionId - Session ID
|
|
391
|
+
* @param taskId - Task ID (optional, for per-task tracking)
|
|
392
|
+
*/
|
|
393
|
+
markSessionWaitingForPush(sessionId, taskId) {
|
|
394
|
+
const key = taskId ? this.getPushStateKey(sessionId, taskId) : sessionId;
|
|
395
|
+
this.sessionPushPendingMap.set(key, true);
|
|
396
|
+
const taskInfo = taskId ? `, task ${taskId}` : '';
|
|
397
|
+
console.log(`[PUSH] Session ${sessionId}${taskInfo} marked as waiting for push`);
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Clear the waiting push state for a session+task
|
|
401
|
+
* @param sessionId - Session ID
|
|
402
|
+
* @param taskId - Task ID (optional, for per-task tracking)
|
|
403
|
+
*/
|
|
404
|
+
clearSessionWaitingForPush(sessionId, taskId) {
|
|
405
|
+
const key = taskId ? this.getPushStateKey(sessionId, taskId) : sessionId;
|
|
406
|
+
this.sessionPushPendingMap.delete(key);
|
|
407
|
+
const taskInfo = taskId ? `, task ${taskId}` : '';
|
|
408
|
+
console.log(`[PUSH] Session ${sessionId}${taskInfo} cleared from waiting for push`);
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Clear all task timeout related state for a session
|
|
412
|
+
*/
|
|
413
|
+
clearTaskTimeoutState(sessionId) {
|
|
414
|
+
this.clearTaskTimeoutForSession(sessionId);
|
|
415
|
+
this.clearSessionWaitingForPush(sessionId);
|
|
416
|
+
console.log(`[TASK TIMEOUT] All timeout state cleared for session ${sessionId}`);
|
|
417
|
+
}
|
|
306
418
|
}
|
|
307
419
|
exports.XiaoYiRuntime = XiaoYiRuntime;
|
|
420
|
+
// Maximum time a session can be active before we consider it stale (5 minutes)
|
|
421
|
+
XiaoYiRuntime.SESSION_STALE_TIMEOUT_MS = 5 * 60 * 1000;
|
|
308
422
|
// Global runtime instance - use global object to survive module reloads
|
|
309
423
|
// CRITICAL: Use string key instead of Symbol to ensure consistency across module reloads
|
|
310
424
|
const GLOBAL_KEY = '__xiaoyi_runtime_instance__';
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,69 @@
|
|
|
1
|
+
export interface A2AJsonRpcRequest {
|
|
2
|
+
jsonrpc: "2.0";
|
|
3
|
+
method: string;
|
|
4
|
+
params: A2ARequestParams;
|
|
5
|
+
id: string;
|
|
6
|
+
}
|
|
7
|
+
export interface A2ARequestParams {
|
|
8
|
+
id: string;
|
|
9
|
+
sessionId: string;
|
|
10
|
+
agentLoginSessionId?: string;
|
|
11
|
+
message: A2AMessage;
|
|
12
|
+
}
|
|
13
|
+
export interface A2AMessage {
|
|
14
|
+
role: "user" | "assistant" | "system";
|
|
15
|
+
parts: A2AMessagePart[];
|
|
16
|
+
}
|
|
17
|
+
export type A2AMessagePart = A2ATextPart | A2AFilePart | A2ADataPart;
|
|
18
|
+
export interface A2ATextPart {
|
|
19
|
+
kind: "text";
|
|
20
|
+
text: string;
|
|
21
|
+
}
|
|
22
|
+
export interface A2AFilePart {
|
|
23
|
+
kind: "file";
|
|
24
|
+
file: {
|
|
25
|
+
name: string;
|
|
26
|
+
mimeType: string;
|
|
27
|
+
uri: string;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export interface A2ADataPart {
|
|
31
|
+
kind: "data";
|
|
32
|
+
data: {
|
|
33
|
+
event?: A2ADataEvent;
|
|
34
|
+
variables?: {
|
|
35
|
+
systemVariables?: {
|
|
36
|
+
push_id?: string;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
[key: string]: any;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export interface A2ADataEvent {
|
|
43
|
+
intentName: string;
|
|
44
|
+
outputs: Record<string, any>;
|
|
45
|
+
status: "success" | "failed";
|
|
46
|
+
}
|
|
47
|
+
export interface A2AReasoningTextPart {
|
|
48
|
+
kind: "reasoningText";
|
|
49
|
+
reasoningText: string;
|
|
50
|
+
}
|
|
51
|
+
export interface A2ACommandPart {
|
|
52
|
+
kind: "command";
|
|
53
|
+
command: A2ACommand;
|
|
54
|
+
}
|
|
55
|
+
export interface A2ACommand {
|
|
56
|
+
header: {
|
|
57
|
+
namespace: string;
|
|
58
|
+
name: string;
|
|
59
|
+
};
|
|
60
|
+
payload: Record<string, any>;
|
|
61
|
+
}
|
|
62
|
+
export type A2AArtifactPart = A2ATextPart | A2ADataPart | A2ACommandPart | A2AReasoningTextPart;
|
|
63
|
+
export interface A2AArtifact {
|
|
64
|
+
artifactId: string;
|
|
65
|
+
parts: A2AArtifactPart[];
|
|
66
|
+
}
|
|
1
67
|
export interface A2ARequestMessage {
|
|
2
68
|
agentId: string;
|
|
3
69
|
jsonrpc: "2.0";
|
|
@@ -75,8 +141,9 @@ export interface A2ATaskArtifactUpdateEvent {
|
|
|
75
141
|
artifact: {
|
|
76
142
|
artifactId: string;
|
|
77
143
|
parts: Array<{
|
|
78
|
-
kind: "text" | "file" | "data";
|
|
144
|
+
kind: "text" | "file" | "data" | "reasoningText";
|
|
79
145
|
text?: string;
|
|
146
|
+
reasoningText?: string;
|
|
80
147
|
file?: {
|
|
81
148
|
name: string;
|
|
82
149
|
mimeType: string;
|
|
@@ -152,6 +219,15 @@ export interface XiaoYiChannelConfig {
|
|
|
152
219
|
sk: string;
|
|
153
220
|
agentId: string;
|
|
154
221
|
enableStreaming?: boolean;
|
|
222
|
+
apiId?: string;
|
|
223
|
+
pushId?: string;
|
|
224
|
+
taskTimeoutMs?: number;
|
|
225
|
+
/**
|
|
226
|
+
* Session cleanup timeout in milliseconds
|
|
227
|
+
* When user clears context, old sessions are cleaned up after this timeout
|
|
228
|
+
* Default: 1 hour (60 * 60 * 1000)
|
|
229
|
+
*/
|
|
230
|
+
sessionCleanupTimeoutMs?: number;
|
|
155
231
|
}
|
|
156
232
|
export interface AuthCredentials {
|
|
157
233
|
ak: string;
|
|
@@ -176,6 +252,7 @@ export interface InternalWebSocketConfig {
|
|
|
176
252
|
ak: string;
|
|
177
253
|
sk: string;
|
|
178
254
|
enableStreaming?: boolean;
|
|
255
|
+
sessionCleanupTimeoutMs?: number;
|
|
179
256
|
}
|
|
180
257
|
export type ServerId = 'server1' | 'server2';
|
|
181
258
|
export interface ServerConnectionState {
|
|
@@ -184,3 +261,20 @@ export interface ServerConnectionState {
|
|
|
184
261
|
lastHeartbeat: number;
|
|
185
262
|
reconnectAttempts: number;
|
|
186
263
|
}
|
|
264
|
+
/**
|
|
265
|
+
* Session cleanup state for delayed cleanup
|
|
266
|
+
*/
|
|
267
|
+
export interface SessionCleanupState {
|
|
268
|
+
sessionId: string;
|
|
269
|
+
serverId: ServerId;
|
|
270
|
+
markedForCleanupAt: number;
|
|
271
|
+
cleanupTimeoutId?: NodeJS.Timeout;
|
|
272
|
+
reason: 'user_cleared' | 'timeout' | 'error';
|
|
273
|
+
accumulatedText?: string;
|
|
274
|
+
}
|
|
275
|
+
export interface SessionBinding {
|
|
276
|
+
sessionId: string;
|
|
277
|
+
server: ServerIdentifier;
|
|
278
|
+
boundAt: number;
|
|
279
|
+
}
|
|
280
|
+
export type ServerIdentifier = 'server1' | 'server2';
|
package/dist/websocket.d.ts
CHANGED
|
@@ -1,23 +1,33 @@
|
|
|
1
1
|
import { EventEmitter } from "events";
|
|
2
|
-
import { A2AResponseMessage, WebSocketConnectionState, XiaoYiChannelConfig, ServerId, ServerConnectionState } from "./types";
|
|
2
|
+
import { A2AResponseMessage, OutboundWebSocketMessage, WebSocketConnectionState, XiaoYiChannelConfig, ServerId, ServerConnectionState, SessionCleanupState } from "./types.js";
|
|
3
3
|
export declare class XiaoYiWebSocketManager extends EventEmitter {
|
|
4
4
|
private ws1;
|
|
5
5
|
private ws2;
|
|
6
6
|
private state1;
|
|
7
7
|
private state2;
|
|
8
8
|
private sessionServerMap;
|
|
9
|
+
private sessionCleanupStateMap;
|
|
10
|
+
private static readonly DEFAULT_CLEANUP_TIMEOUT_MS;
|
|
9
11
|
private auth;
|
|
10
12
|
private config;
|
|
11
13
|
private heartbeatTimeout1?;
|
|
12
14
|
private heartbeatTimeout2?;
|
|
13
15
|
private appHeartbeatInterval?;
|
|
16
|
+
private heartbeat1?;
|
|
17
|
+
private heartbeat2?;
|
|
14
18
|
private reconnectTimeout1?;
|
|
15
19
|
private reconnectTimeout2?;
|
|
16
20
|
private stableConnectionTimer1?;
|
|
17
21
|
private stableConnectionTimer2?;
|
|
18
22
|
private static readonly STABLE_CONNECTION_THRESHOLD;
|
|
19
23
|
private activeTasks;
|
|
24
|
+
private onHealthEvent?;
|
|
20
25
|
constructor(config: XiaoYiChannelConfig);
|
|
26
|
+
/**
|
|
27
|
+
* Set health event callback to report activity to OpenClaw framework.
|
|
28
|
+
* This callback is invoked on heartbeat success to update lastEventAt.
|
|
29
|
+
*/
|
|
30
|
+
setHealthEventCallback(callback: () => void): void;
|
|
21
31
|
/**
|
|
22
32
|
* Check if URL is wss + IP format (skip certificate verification)
|
|
23
33
|
*/
|
|
@@ -91,6 +101,14 @@ export declare class XiaoYiWebSocketManager extends EventEmitter {
|
|
|
91
101
|
* TODO: 实现实际的推送消息发送逻辑
|
|
92
102
|
*/
|
|
93
103
|
sendPushMessage(sessionId: string, message: string): Promise<void>;
|
|
104
|
+
/**
|
|
105
|
+
* Send an outbound WebSocket message directly.
|
|
106
|
+
* This is a low-level method that sends a pre-formatted OutboundWebSocketMessage.
|
|
107
|
+
*
|
|
108
|
+
* @param sessionId - Session ID for routing
|
|
109
|
+
* @param message - Pre-formatted outbound message
|
|
110
|
+
*/
|
|
111
|
+
sendMessage(sessionId: string, message: OutboundWebSocketMessage): Promise<void>;
|
|
94
112
|
/**
|
|
95
113
|
* Send tasks cancel response to specific server
|
|
96
114
|
*/
|
|
@@ -176,4 +194,34 @@ export declare class XiaoYiWebSocketManager extends EventEmitter {
|
|
|
176
194
|
* Remove session mapping
|
|
177
195
|
*/
|
|
178
196
|
removeSession(sessionId: string): void;
|
|
197
|
+
/**
|
|
198
|
+
* Mark a session for delayed cleanup
|
|
199
|
+
* @param sessionId The session ID to mark for cleanup
|
|
200
|
+
* @param serverId The server ID associated with this session
|
|
201
|
+
* @param timeoutMs Timeout in milliseconds before forcing cleanup
|
|
202
|
+
*/
|
|
203
|
+
private markSessionForCleanup;
|
|
204
|
+
/**
|
|
205
|
+
* Force cleanup a session immediately
|
|
206
|
+
* @param sessionId The session ID to cleanup
|
|
207
|
+
*/
|
|
208
|
+
forceCleanupSession(sessionId: string): void;
|
|
209
|
+
/**
|
|
210
|
+
* Check if a session is pending cleanup
|
|
211
|
+
* @param sessionId The session ID to check
|
|
212
|
+
* @returns True if session is pending cleanup
|
|
213
|
+
*/
|
|
214
|
+
isSessionPendingCleanup(sessionId: string): boolean;
|
|
215
|
+
/**
|
|
216
|
+
* Get cleanup state for a session
|
|
217
|
+
* @param sessionId The session ID to check
|
|
218
|
+
* @returns Cleanup state if exists, undefined otherwise
|
|
219
|
+
*/
|
|
220
|
+
getSessionCleanupState(sessionId: string): SessionCleanupState | undefined;
|
|
221
|
+
/**
|
|
222
|
+
* Update accumulated text for a pending cleanup session
|
|
223
|
+
* @param sessionId The session ID
|
|
224
|
+
* @param text The accumulated text
|
|
225
|
+
*/
|
|
226
|
+
updateAccumulatedTextForCleanup(sessionId: string, text: string): void;
|
|
179
227
|
}
|