@ynhcj/xiaoyi 2.5.4 → 2.5.5

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.
@@ -1,9 +1,9 @@
1
- {
2
- "id": "xiaoyi",
3
- "channels": ["xiaoyi"],
4
- "configSchema": {
5
- "type": "object",
6
- "additionalProperties": true,
7
- "properties": {}
8
- }
9
- }
1
+ {
2
+ "id": "xiaoyi",
3
+ "channels": ["xiaoyi"],
4
+ "configSchema": {
5
+ "type": "object",
6
+ "additionalProperties": true,
7
+ "properties": {}
8
+ }
9
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ynhcj/xiaoyi",
3
- "version": "2.5.4",
3
+ "version": "2.5.5",
4
4
  "description": "XiaoYi channel plugin for OpenClaw",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/xiaoyi.js CHANGED
@@ -1 +1 @@
1
- module.exports = require('./dist/index.js');
1
+ module.exports = require('./dist/index.js');
@@ -1,78 +0,0 @@
1
- /**
2
- * SessionManager - 统一的会话状态管理
3
- *
4
- * 职责:
5
- * 1. 管理会话的生命周期和状态
6
- * 2. 追踪异步任务(SubAgent)状态
7
- * 3. 提供清晰的状态查询接口
8
- * 4. 管理超时和定时器
9
- */
10
- export interface FinalMessageOptions {
11
- text?: string;
12
- isFinal?: boolean;
13
- }
14
- export interface SessionState {
15
- sessionId: string;
16
- taskId: string;
17
- startTime: number;
18
- accumulatedText: string;
19
- hasSentFinal: boolean;
20
- hasAsyncActivity: boolean;
21
- lastDeliverTime: number;
22
- gracePeriodTimeout: NodeJS.Timeout | null;
23
- maxTimeoutId: NodeJS.Timeout | null;
24
- }
25
- export declare class SessionManager {
26
- private sessions;
27
- private runtime;
28
- /**
29
- * 初始化会话
30
- */
31
- initSession(sessionId: string, taskId: string): void;
32
- /**
33
- * 更新会话活动时间
34
- * 每次调用 deliver 时都应调用此方法
35
- */
36
- updateActivity(sessionId: string, text: string): void;
37
- /**
38
- * 检测是否有异步活动
39
- * 基于 queuedFinal 和 tool 调用
40
- */
41
- detectAsyncActivity(queuedFinal: boolean, counts: any): boolean;
42
- /**
43
- * 判断是否为 final 响应
44
- */
45
- isFinalResponse(info: any, payload: any): boolean;
46
- /**
47
- * 发送 final 消息并标记会话完成
48
- */
49
- sendFinal(sessionId: string, conn: any, taskId: string, options: FinalMessageOptions, runtime: any): Promise<void>;
50
- /**
51
- * 启动 grace period(宽限期)
52
- */
53
- startGracePeriod(sessionId: string, config: {
54
- onSubAgentOutput: () => void;
55
- onTimeout: () => void;
56
- }): void;
57
- /**
58
- * 处理 SubAgent 输出(延长宽限期)
59
- */
60
- handleSubAgentOutput(sessionId: string): void;
61
- /**
62
- * 清除该会话的所有定时器
63
- */
64
- clearTimeouts(sessionId: string): void;
65
- /**
66
- * 标记会话为完成(不发送 final)
67
- * 用于简单对话场景,无需 grace period
68
- */
69
- markCompleted(sessionId: string): void;
70
- /**
71
- * 获取会话状态
72
- */
73
- getSessionState(sessionId: string): SessionState | undefined;
74
- /**
75
- * 清理会话(移除)
76
- */
77
- cleanup(sessionId: string): void;
78
- }
@@ -1,258 +0,0 @@
1
- "use strict";
2
- /**
3
- * SessionManager - 统一的会话状态管理
4
- *
5
- * 职责:
6
- * 1. 管理会话的生命周期和状态
7
- * 2. 追踪异步任务(SubAgent)状态
8
- * 3. 提供清晰的状态查询接口
9
- * 4. 管理超时和定时器
10
- */
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.SessionManager = void 0;
13
- const runtime_1 = require("./runtime");
14
- // Constants for timeout configuration
15
- const SUBAGENT_GRACE_PERIOD_MS = 30000; // 30秒初始宽限期
16
- const SUBAGENT_MAX_WAIT_MS = 120000; // 最大2分钟
17
- const SUBACTIVITY_TIMEOUT_MS = 5000; // 5秒无活动=空闲
18
- class SessionManager {
19
- constructor() {
20
- this.sessions = new Map();
21
- this.runtime = (0, runtime_1.getXiaoYiRuntime)();
22
- }
23
- /**
24
- * 初始化会话
25
- */
26
- initSession(sessionId, taskId) {
27
- const now = Date.now();
28
- const session = {
29
- sessionId,
30
- taskId,
31
- startTime: now,
32
- accumulatedText: "",
33
- hasSentFinal: false,
34
- hasAsyncActivity: false,
35
- lastDeliverTime: now,
36
- gracePeriodTimeout: null,
37
- maxTimeoutId: null,
38
- };
39
- this.sessions.set(sessionId, session);
40
- console.log(`\n[SESSION] Initialized session ${sessionId}`);
41
- console.log(` Task ID: ${taskId}`);
42
- console.log(` Start time: ${now}`);
43
- }
44
- /**
45
- * 更新会话活动时间
46
- * 每次调用 deliver 时都应调用此方法
47
- */
48
- updateActivity(sessionId, text) {
49
- const session = this.sessions.get(sessionId);
50
- if (!session) {
51
- console.warn(`[SESSION] Session ${sessionId} not found for activity update`);
52
- return;
53
- }
54
- const previousLength = session.accumulatedText.length;
55
- session.accumulatedText = text;
56
- session.lastDeliverTime = Date.now();
57
- console.log(`\n[ACTIVITY] Session ${sessionId}`);
58
- console.log(` Text length: ${text.length} (added ${text.length - previousLength})`);
59
- console.log(` Elapsed: ${Date.now() - session.startTime}ms`);
60
- }
61
- /**
62
- * 检测是否有异步活动
63
- * 基于 queuedFinal 和 tool 调用
64
- */
65
- detectAsyncActivity(queuedFinal, counts) {
66
- return queuedFinal === true || (counts?.tool || 0) > 0;
67
- }
68
- /**
69
- * 判断是否为 final 响应
70
- */
71
- isFinalResponse(info, payload) {
72
- const kindFinal = info?.kind === "final";
73
- const statusFinal = payload?.status === "final";
74
- const payloadQueuedFinal = payload?.queuedFinal === true;
75
- return kindFinal || statusFinal || payloadQueuedFinal;
76
- }
77
- /**
78
- * 发送 final 消息并标记会话完成
79
- */
80
- async sendFinal(sessionId, conn, taskId, options, runtime) {
81
- const session = this.sessions.get(sessionId);
82
- if (!session) {
83
- console.error(`[SESSION] Cannot send final for session ${sessionId}: session not found`);
84
- return;
85
- }
86
- // 检查是否已发送
87
- if (session.hasSentFinal) {
88
- console.log(`[SESSION] Final already sent for session ${sessionId}, skipping`);
89
- return;
90
- }
91
- // 标记为已发送
92
- session.hasSentFinal = true;
93
- // 清除所有定时器
94
- this.clearTimeouts(sessionId);
95
- const response = {
96
- sessionId,
97
- messageId: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
98
- timestamp: Date.now(),
99
- agentId: this.runtime.getConfig()?.agentId || "",
100
- sender: {
101
- id: this.runtime.getConfig()?.agentId || "",
102
- name: "OpenClaw Agent",
103
- type: "agent",
104
- },
105
- content: {
106
- type: "text",
107
- text: options.text || session.accumulatedText,
108
- },
109
- status: "success",
110
- };
111
- try {
112
- // 发送 isFinal=true
113
- await conn.sendResponse(response, taskId, sessionId, options.isFinal !== false, false);
114
- const elapsed = Date.now() - session.startTime;
115
- console.log(`\n[SESSION] Final message sent for session ${sessionId}`);
116
- console.log(` Total elapsed: ${elapsed}ms`);
117
- console.log(` Text length: ${session.accumulatedText.length} chars`);
118
- console.log(` isFinal: ${options.isFinal !== false ? options.isFinal : true}`);
119
- }
120
- catch (error) {
121
- console.error(`[SESSION] Failed to send final for session ${sessionId}:`, error);
122
- }
123
- }
124
- /**
125
- * 启动 grace period(宽限期)
126
- */
127
- startGracePeriod(sessionId, config) {
128
- const session = this.sessions.get(sessionId);
129
- if (!session) {
130
- console.warn(`[SESSION] Cannot start grace period for session ${sessionId}: session not found`);
131
- return;
132
- }
133
- if (session.hasSentFinal) {
134
- console.log(`[SESSION] Final already sent for session ${sessionId}, skipping grace period`);
135
- return;
136
- }
137
- // 清除旧的定时器
138
- this.clearTimeouts(sessionId);
139
- console.log(`\n[GRACE-PERIOD] Starting grace period for session ${sessionId}`);
140
- console.log(` Grace period: ${SUBAGENT_GRACE_PERIOD_MS}ms`);
141
- console.log(` Max wait: ${SUBAGENT_MAX_WAIT_MS}ms`);
142
- console.log(` Inactivity timeout: ${SUBACTIVITY_TIMEOUT_MS}ms`);
143
- // 初始宽限期超时
144
- session.gracePeriodTimeout = setTimeout(async () => {
145
- const timeSinceLastDeliver = Date.now() - session.lastDeliverTime;
146
- if (timeSinceLastDeliver < SUBACTIVITY_TIMEOUT_MS) {
147
- // 有活动,延长宽限期
148
- console.log(`\n[GRACE-PERIOD] Activity detected, extending grace period for session ${sessionId}`);
149
- console.log(` Time since last deliver: ${timeSinceLastDeliver}ms`);
150
- session.gracePeriodTimeout = setTimeout(async () => {
151
- await config.onTimeout();
152
- }, SUBACTIVITY_TIMEOUT_MS);
153
- }
154
- else {
155
- // 无活动,发送 final
156
- console.log(`\n[GRACE-PERIOD] No activity for ${SUBACTIVITY_TIMEOUT_MS}ms, sending final for session ${sessionId}`);
157
- console.log(` Time since last deliver: ${timeSinceLastDeliver}ms}`);
158
- await this.sendFinal(sessionId, this.runtime.getConnection(), session.taskId, {
159
- text: session.accumulatedText,
160
- isFinal: true,
161
- }, this.runtime);
162
- // 标记为已发送
163
- session.hasSentFinal = true;
164
- session.gracePeriodTimeout = null;
165
- }
166
- }, SUBAGENT_GRACE_PERIOD_MS);
167
- // 最大超时保护
168
- session.maxTimeoutId = setTimeout(async () => {
169
- if (session.gracePeriodTimeout !== null && !session.hasSentFinal) {
170
- console.log(`\n[GRACE-PERIOD] Max timeout (${SUBAGENT_MAX_WAIT_MS}ms) reached for session ${sessionId}`);
171
- this.clearTimeouts(sessionId);
172
- await this.sendFinal(sessionId, this.runtime.getConnection(), session.taskId, {
173
- text: session.accumulatedText,
174
- isFinal: true,
175
- }, this.runtime);
176
- session.hasSentFinal = true;
177
- session.gracePeriodTimeout = null;
178
- }
179
- }, SUBAGENT_MAX_WAIT_MS);
180
- }
181
- /**
182
- * 处理 SubAgent 输出(延长宽限期)
183
- */
184
- handleSubAgentOutput(sessionId) {
185
- const session = this.sessions.get(sessionId);
186
- if (!session || session.hasSentFinal) {
187
- return;
188
- }
189
- console.log(`\n[SUBAGENT] Output detected for session ${sessionId}`);
190
- console.log(` Time since last deliver: ${Date.now() - session.lastDeliverTime}ms`);
191
- // 清除现有宽限期,重新启动
192
- if (session.gracePeriodTimeout) {
193
- clearTimeout(session.gracePeriodTimeout);
194
- console.log(`[SUBAGENT] Cleared existing grace period timeout`);
195
- }
196
- // 启动新的宽限期
197
- session.gracePeriodTimeout = setTimeout(async () => {
198
- console.log(`\n[GRACE-PERIOD] Grace period expired, sending final for session ${sessionId}`);
199
- await this.sendFinal(sessionId, this.runtime.getConnection(), session.taskId, {
200
- text: session.accumulatedText,
201
- isFinal: true,
202
- }, this.runtime);
203
- }, SUBACTIVITY_TIMEOUT_MS);
204
- }
205
- /**
206
- * 清除该会话的所有定时器
207
- */
208
- clearTimeouts(sessionId) {
209
- const session = this.sessions.get(sessionId);
210
- if (!session) {
211
- return;
212
- }
213
- if (session.gracePeriodTimeout) {
214
- clearTimeout(session.gracePeriodTimeout);
215
- session.gracePeriodTimeout = null;
216
- console.log(`[CLEANUP] Cleared grace period timeout for session ${sessionId}`);
217
- }
218
- if (session.maxTimeoutId) {
219
- clearTimeout(session.maxTimeoutId);
220
- session.maxTimeoutId = null;
221
- console.log(`[CLEANUP] Cleared max timeout for session ${sessionId}`);
222
- }
223
- }
224
- /**
225
- * 标记会话为完成(不发送 final)
226
- * 用于简单对话场景,无需 grace period
227
- */
228
- markCompleted(sessionId) {
229
- const session = this.sessions.get(sessionId);
230
- if (!session) {
231
- console.warn(`[SESSION] Session ${sessionId} not found for completion`);
232
- return;
233
- }
234
- console.log(`\n[SESSION] Marked session ${sessionId} as completed (no grace period needed)`);
235
- console.log(` Total elapsed: ${Date.now() - session.startTime}ms`);
236
- console.log(` Final text: ${session.accumulatedText.length} chars`);
237
- }
238
- /**
239
- * 获取会话状态
240
- */
241
- getSessionState(sessionId) {
242
- return this.sessions.get(sessionId);
243
- }
244
- /**
245
- * 清理会话(移除)
246
- */
247
- cleanup(sessionId) {
248
- const session = this.sessions.get(sessionId);
249
- if (session) {
250
- this.clearTimeouts(sessionId);
251
- this.sessions.delete(sessionId);
252
- console.log(`\n[SESSION] Cleaned up session ${sessionId}`);
253
- console.log(` Total elapsed: ${Date.now() - session.startTime}ms`);
254
- console.log(` Final text: ${session.accumulatedText.length} chars`);
255
- }
256
- }
257
- }
258
- exports.SessionManager = SessionManager;