@yeaft/webchat-agent 0.0.12 → 0.0.13

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/claude.js CHANGED
@@ -34,6 +34,7 @@ export async function startClaudeQuery(conversationId, workDir, resumeSessionId)
34
34
  createdAt: Date.now(),
35
35
  abortController,
36
36
  turnActive: false, // 是否有 turn 正在处理中
37
+ turnResultReceived: false, // 当前 turn 是否已收到 result(用于抑制重复 result)
37
38
  // Metadata from system init message
38
39
  tools: [],
39
40
  slashCommands: [],
@@ -324,6 +325,7 @@ async function processClaudeOutput(conversationId, claudeQuery, state) {
324
325
 
325
326
  // 捕获 result 消息中的 usage 信息
326
327
  if (message.type === 'result') {
328
+ // 累计 usage(无论是否重复,始终统计)
327
329
  if (message.usage) {
328
330
  state.usage.inputTokens += message.usage.input_tokens || 0;
329
331
  state.usage.outputTokens += message.usage.output_tokens || 0;
@@ -333,9 +335,17 @@ async function processClaudeOutput(conversationId, claudeQuery, state) {
333
335
  state.usage.totalCostUsd += message.total_cost_usd || 0;
334
336
  console.log(`[SDK] Query completed for ${conversationId}, cost: $${state.usage.totalCostUsd.toFixed(4)}`);
335
337
 
338
+ // ★ Guard:当前 turn 已收到过 result,抑制 SDK 发出的重复 result
339
+ // (长任务场景下 SDK 可能先发 result/success 再发 result/error_during_execution)
340
+ if (state.turnResultReceived) {
341
+ console.warn(`[SDK] Suppressing duplicate result for ${conversationId} (subtype: ${message.subtype || 'unknown'})`);
342
+ continue;
343
+ }
344
+
336
345
  // ★ Turn 完成:发送 turn_completed,进程继续运行等待下一条消息
337
346
  // stream-json 模式下 Claude 进程是持久运行的,for-await 在 result 后继续等待
338
347
  // 不清空 state.query 和 state.inputStream,下次用户消息直接通过同一个 inputStream 发送
348
+ state.turnResultReceived = true;
339
349
  sendOutput(conversationId, message);
340
350
 
341
351
  resultHandled = true;
package/conversation.js CHANGED
@@ -360,6 +360,7 @@ export async function handleUserInput(msg) {
360
360
 
361
361
  console.log(`[${conversationId}] Sending: ${prompt.substring(0, 100)}...`);
362
362
  state.turnActive = true;
363
+ state.turnResultReceived = false; // 重置 per-turn 去重标志
363
364
  sendConversationList(); // 在 turnActive=true 后通知 server,确保 processing 状态正确
364
365
  state.inputStream.enqueue(userMessage);
365
366
  }
package/history.js CHANGED
@@ -168,7 +168,7 @@ export function loadSessionHistory(workDir, claudeSessionId, limit = 500) {
168
168
  }
169
169
 
170
170
  export async function handleListHistorySessions(msg) {
171
- const { workDir, requestId } = msg;
171
+ const { workDir, requestId, _requestClientId } = msg;
172
172
  const effectiveWorkDir = workDir || ctx.CONFIG.workDir;
173
173
 
174
174
  console.log(`Listing history sessions for: ${effectiveWorkDir}`);
@@ -178,6 +178,7 @@ export async function handleListHistorySessions(msg) {
178
178
  ctx.sendToServer({
179
179
  type: 'history_sessions_list',
180
180
  requestId,
181
+ _requestClientId,
181
182
  workDir: effectiveWorkDir,
182
183
  sessions
183
184
  });
@@ -186,6 +187,7 @@ export async function handleListHistorySessions(msg) {
186
187
  ctx.sendToServer({
187
188
  type: 'history_sessions_list',
188
189
  requestId,
190
+ _requestClientId,
189
191
  workDir: effectiveWorkDir,
190
192
  sessions: [],
191
193
  error: e.message
@@ -195,7 +197,7 @@ export async function handleListHistorySessions(msg) {
195
197
 
196
198
  // 列出 Claude projects 目录下的所有 folder (工作目录)
197
199
  export async function handleListFolders(msg) {
198
- const { requestId } = msg;
200
+ const { requestId, _requestClientId } = msg;
199
201
  const projectsDir = getClaudeProjectsDir();
200
202
 
201
203
  console.log(`Listing folders from: ${projectsDir}`);
@@ -268,6 +270,7 @@ export async function handleListFolders(msg) {
268
270
  ctx.sendToServer({
269
271
  type: 'folders_list',
270
272
  requestId,
273
+ _requestClientId,
271
274
  folders
272
275
  });
273
276
  console.log(`folders_list sent with ${folders.length} folders`);
@@ -276,6 +279,7 @@ export async function handleListFolders(msg) {
276
279
  ctx.sendToServer({
277
280
  type: 'folders_list',
278
281
  requestId,
282
+ _requestClientId,
279
283
  folders: [],
280
284
  error: e.message
281
285
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yeaft/webchat-agent",
3
- "version": "0.0.12",
3
+ "version": "0.0.13",
4
4
  "description": "Remote agent for Yeaft WebChat — connects worker machines to the central server",
5
5
  "main": "index.js",
6
6
  "type": "module",