@yeaft/webchat-agent 0.0.61 → 0.0.62
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 +13 -1
- package/conversation.js +1 -3
- package/crew.js +14 -2
- package/package.json +1 -1
package/claude.js
CHANGED
|
@@ -354,7 +354,19 @@ async function processClaudeOutput(conversationId, claudeQuery, state) {
|
|
|
354
354
|
state.usage.cacheCreation += message.usage.cache_creation_input_tokens || 0;
|
|
355
355
|
}
|
|
356
356
|
state.usage.totalCostUsd += message.total_cost_usd || 0;
|
|
357
|
-
|
|
357
|
+
|
|
358
|
+
// 计算上下文使用百分比并注入到消息中
|
|
359
|
+
const inputTokens = message.usage?.input_tokens || 0;
|
|
360
|
+
const maxContextTokens = 200000; // Claude 模型 context window
|
|
361
|
+
if (inputTokens > 0) {
|
|
362
|
+
message._contextUsage = {
|
|
363
|
+
inputTokens,
|
|
364
|
+
maxTokens: maxContextTokens,
|
|
365
|
+
percentage: Math.min(100, Math.round((inputTokens / maxContextTokens) * 100))
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
console.log(`[SDK] Query completed for ${conversationId}, cost: $${state.usage.totalCostUsd.toFixed(4)}, context: ${inputTokens}/${maxContextTokens} tokens`);
|
|
358
370
|
|
|
359
371
|
// ★ Guard:当前 turn 已收到过 result,抑制 SDK 发出的重复 result
|
|
360
372
|
// (长任务场景下 SDK 可能先发 result/success 再发 result/error_during_execution)
|
package/conversation.js
CHANGED
|
@@ -375,9 +375,6 @@ export async function handleUserInput(msg) {
|
|
|
375
375
|
|
|
376
376
|
let state = ctx.conversations.get(conversationId);
|
|
377
377
|
|
|
378
|
-
// ★ Phase 3.6: 排队逻辑已移至 server 端,agent 不再本地排队
|
|
379
|
-
// Server 保证 conversation busy 时不会发新的 execute 过来
|
|
380
|
-
|
|
381
378
|
// 如果没有活跃的查询,启动新的
|
|
382
379
|
if (!state || !state.query || !state.inputStream) {
|
|
383
380
|
const resumeSessionId = claudeSessionId || state?.claudeSessionId || null;
|
|
@@ -388,6 +385,7 @@ export async function handleUserInput(msg) {
|
|
|
388
385
|
}
|
|
389
386
|
|
|
390
387
|
// 发送用户消息到输入流
|
|
388
|
+
// Claude stream-json 模式支持在回复过程中接收新消息(写入 stdin)
|
|
391
389
|
const userMessage = {
|
|
392
390
|
type: 'user',
|
|
393
391
|
message: { role: 'user', content: prompt }
|
package/crew.js
CHANGED
|
@@ -34,14 +34,26 @@ export { crewSessions };
|
|
|
34
34
|
|
|
35
35
|
const CREW_INDEX_PATH = join(homedir(), '.claude', 'crew-sessions.json');
|
|
36
36
|
|
|
37
|
+
// 写入锁:防止并发写入导致文件损坏
|
|
38
|
+
let _indexWriteLock = Promise.resolve();
|
|
39
|
+
|
|
37
40
|
export async function loadCrewIndex() {
|
|
38
41
|
try { return JSON.parse(await fs.readFile(CREW_INDEX_PATH, 'utf-8')); }
|
|
39
42
|
catch { return []; }
|
|
40
43
|
}
|
|
41
44
|
|
|
42
45
|
async function saveCrewIndex(index) {
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
const doWrite = async () => {
|
|
47
|
+
await fs.mkdir(join(homedir(), '.claude'), { recursive: true });
|
|
48
|
+
const data = JSON.stringify(index, null, 2);
|
|
49
|
+
// 先写临时文件再 rename,保证原子性
|
|
50
|
+
const tmpPath = CREW_INDEX_PATH + '.tmp';
|
|
51
|
+
await fs.writeFile(tmpPath, data);
|
|
52
|
+
await fs.rename(tmpPath, CREW_INDEX_PATH);
|
|
53
|
+
};
|
|
54
|
+
// 串行化写入
|
|
55
|
+
_indexWriteLock = _indexWriteLock.then(doWrite, doWrite);
|
|
56
|
+
return _indexWriteLock;
|
|
45
57
|
}
|
|
46
58
|
|
|
47
59
|
function sessionToIndexEntry(session) {
|