chatccc 0.2.258 → 0.2.260
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/README.md +20 -11
- package/config.sample.json +23 -8
- package/deepccc-agent/package.json +1 -1
- package/dist/deepccc-agent/src/context.js +12 -3
- package/dist/deepccc-agent/src/index.js +116 -73
- package/dist/deepccc-agent/src/progress/reducer.js +4 -0
- package/dist/deepccc-agent/src/tool-protocol.js +17 -0
- package/dist/src/adapters/ccc-adapter.js +12 -0
- package/dist/src/adapters/claude-adapter.js +3 -2
- package/dist/src/adapters/dsh-adapter.js +230 -0
- package/dist/src/agent-activity.js +4 -0
- package/dist/src/agent-tool.js +2 -1
- package/dist/src/card-action-parser.js +1 -0
- package/dist/src/cards.js +11 -3
- package/dist/src/config.js +34 -2
- package/dist/src/engines/engine-manager.js +408 -0
- package/dist/src/engines/engine-specs.js +157 -0
- package/dist/src/feishu-api.js +2 -1
- package/dist/src/orchestrator.js +21 -10
- package/dist/src/progress/reducer.js +4 -0
- package/dist/src/response-stall.js +2 -2
- package/dist/src/session.js +43 -4
- package/dist/src/web-ui.js +286 -200
- package/package.json +1 -1
- package/dist/src/claude-sdk-installer.js +0 -249
|
@@ -57,6 +57,10 @@ export function reduceProgress(prev, event) {
|
|
|
57
57
|
case "text":
|
|
58
58
|
// accumulated 是全文累积,直接全量替换,天然幂等
|
|
59
59
|
return withProgressView(prev, { text: event.accumulated });
|
|
60
|
+
case "progress":
|
|
61
|
+
return withProgressView(prev, { headerTitle: "思考中..." });
|
|
62
|
+
case "text_reset":
|
|
63
|
+
return withProgressView(prev, { text: "", tools: [] });
|
|
60
64
|
case "tool_use": {
|
|
61
65
|
const tool = {
|
|
62
66
|
id: event.id ?? `tool-${prev.tools.length + 1}`,
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* Tracks how long the displayed output character count has remained unchanged.
|
|
3
3
|
* Leaving a monitored phase clears the window; returning starts a fresh one.
|
|
4
4
|
*/
|
|
5
|
-
export function observeResponseProgress(previous, isMonitoredPhase, totalChars, now = Date.now()) {
|
|
5
|
+
export function observeResponseProgress(previous, isMonitoredPhase, totalChars, now = Date.now(), heartbeat = false) {
|
|
6
6
|
if (!isMonitoredPhase)
|
|
7
7
|
return undefined;
|
|
8
|
-
if (previous?.totalChars === totalChars)
|
|
8
|
+
if (!heartbeat && previous?.totalChars === totalChars)
|
|
9
9
|
return previous;
|
|
10
10
|
return { totalChars, unchangedSince: now };
|
|
11
11
|
}
|
package/dist/src/session.js
CHANGED
|
@@ -10,6 +10,7 @@ import { createClaudeAdapter } from "./adapters/claude-adapter.js";
|
|
|
10
10
|
import { createCursorAdapter } from "./adapters/cursor-adapter.js";
|
|
11
11
|
import { createCodexAdapter } from "./adapters/codex-adapter.js";
|
|
12
12
|
import { createCccAdapter } from "./adapters/ccc-adapter.js";
|
|
13
|
+
import { createDshAdapter } from "./adapters/dsh-adapter.js";
|
|
13
14
|
import { killProcessTree } from "./adapters/proc-tree-kill.js";
|
|
14
15
|
import { resourceMonitor, registerProcess, unregisterProcess } from "./adapters/resource-monitor.js";
|
|
15
16
|
import { buildImSkillsPromptCached, exportSkillSubDocs } from "./im-skills.js";
|
|
@@ -233,7 +234,7 @@ function formatAutoEndedReply(finalReply) {
|
|
|
233
234
|
* 状态或资源保护,不能把它们消耗的时间算入回复停滞窗口。
|
|
234
235
|
*/
|
|
235
236
|
function monitorsOutputProgress(kind) {
|
|
236
|
-
return kind === "responding";
|
|
237
|
+
return kind === "responding" || kind === "thinking";
|
|
237
238
|
}
|
|
238
239
|
function formatTerminalReply(status, finalReply, terminalError) {
|
|
239
240
|
if (status === "auto_ended")
|
|
@@ -418,6 +419,8 @@ export function getEffectiveModelForTool(tool, sessionId) {
|
|
|
418
419
|
return config.codex.model;
|
|
419
420
|
if (tool === "ccc")
|
|
420
421
|
return config.ccc.model;
|
|
422
|
+
if (tool === "dsh")
|
|
423
|
+
return config.dsh.model;
|
|
421
424
|
return CLAUDE_MODEL;
|
|
422
425
|
}
|
|
423
426
|
export function getEffectiveEffortForTool(tool, sessionId) {
|
|
@@ -528,14 +531,23 @@ export function getAdapterForTool(tool, sessionId) {
|
|
|
528
531
|
apiKey: config.ccc.DEEPSEEK_API_KEY,
|
|
529
532
|
baseURL: config.ccc.DEEPSEEK_BASE_URL,
|
|
530
533
|
model: effectiveModel || undefined,
|
|
531
|
-
effort: effectiveEffort || undefined,
|
|
532
534
|
compactionTimeoutMs: config.ccc.compactionTimeoutMs,
|
|
533
535
|
contextWindow: config.ccc.contextWindow,
|
|
536
|
+
...(effectiveEffort ? { effort: effectiveEffort } : {}),
|
|
534
537
|
// 留空("")不传 → ChatSession 跟随 DeepCCC 内核配置(~/.deepccc/config.json 或 DEEPCCC_PROVIDER)
|
|
535
538
|
...(config.ccc.provider ? { provider: config.ccc.provider } : {}),
|
|
536
539
|
...(config.ccc.subModel ? { subModel: config.ccc.subModel } : {}),
|
|
537
540
|
});
|
|
538
541
|
}
|
|
542
|
+
else if (tool === "dsh") {
|
|
543
|
+
adapter = createDshAdapter({
|
|
544
|
+
apiKey: config.dsh.apiKey,
|
|
545
|
+
baseUrl: config.dsh.baseUrl,
|
|
546
|
+
model: effectiveModel || config.dsh.model,
|
|
547
|
+
provider: config.dsh.provider,
|
|
548
|
+
maxTokens: config.dsh.maxTokens,
|
|
549
|
+
});
|
|
550
|
+
}
|
|
539
551
|
else {
|
|
540
552
|
adapter = createClaudeAdapter({
|
|
541
553
|
model: effectiveModel,
|
|
@@ -761,6 +773,14 @@ export function accumulateBlockContent(block, state, toolCallMap) {
|
|
|
761
773
|
// 覆盖而非追加:适配器已保证这是一段完整最终文本(如 Cursor 流末快照)
|
|
762
774
|
state.finalCompleteText = block.text;
|
|
763
775
|
break;
|
|
776
|
+
case "text_reset":
|
|
777
|
+
state.accumulatedContent = "";
|
|
778
|
+
state.finalText = "";
|
|
779
|
+
state.finalCompleteText = "";
|
|
780
|
+
state.chunkCount = 0;
|
|
781
|
+
break;
|
|
782
|
+
case "agent_progress":
|
|
783
|
+
break;
|
|
764
784
|
case "compact_boundary": {
|
|
765
785
|
const triggerLabel = block.trigger === "manual" ? "手动" : "自动"; // 手动 / 自动
|
|
766
786
|
state.accumulatedContent +=
|
|
@@ -844,6 +864,10 @@ function formatToolConfigForLog(tool, sessionModel, sessionId) {
|
|
|
844
864
|
const modelStr = m.trim() !== "" ? m : "(not configured)";
|
|
845
865
|
return `model=${modelStr}, baseURL=${config.ccc.DEEPSEEK_BASE_URL}`;
|
|
846
866
|
}
|
|
867
|
+
if (tool === "dsh") {
|
|
868
|
+
const model = getEffectiveModelForTool(tool, sessionId);
|
|
869
|
+
return `model=${model || "(not configured)"}, baseURL=${config.dsh.baseUrl}`;
|
|
870
|
+
}
|
|
847
871
|
return `model=${anthropicConfigDisplay(getModelForSession(sessionId))}, subagentModel=${anthropicConfigDisplay(CLAUDE_SUBAGENT_MODEL)}, effort=${anthropicConfigDisplay(getEffectiveEffortForTool(tool, sessionId))}`;
|
|
848
872
|
}
|
|
849
873
|
export async function initClaudeSession(tool, overrideCwd, chatId) {
|
|
@@ -1238,7 +1262,15 @@ export async function runAgentSession(sessionId, userText, platform, _chatId, ms
|
|
|
1238
1262
|
}
|
|
1239
1263
|
}
|
|
1240
1264
|
let activityChanged = false;
|
|
1265
|
+
let progressHeartbeat = false;
|
|
1266
|
+
let outputReset = false;
|
|
1241
1267
|
for (const block of unifiedMsg.blocks) {
|
|
1268
|
+
if (block.type === "agent_progress")
|
|
1269
|
+
progressHeartbeat = true;
|
|
1270
|
+
if (block.type === "text_reset") {
|
|
1271
|
+
outputReset = true;
|
|
1272
|
+
toolCallMap.clear();
|
|
1273
|
+
}
|
|
1242
1274
|
if (updateAgentActivity(activityTracker, block))
|
|
1243
1275
|
activityChanged = true;
|
|
1244
1276
|
accumulateBlockContent(block, state, toolCallMap);
|
|
@@ -1263,11 +1295,11 @@ export async function runAgentSession(sessionId, userText, platform, _chatId, ms
|
|
|
1263
1295
|
prompt.responseProgress = observeResponseProgress(
|
|
1264
1296
|
// starting → responding 本身是一次有效进展,即便首个文本块仍为空也应
|
|
1265
1297
|
// 重新计时;其它活动阶段会清空观察窗口。
|
|
1266
|
-
activityChanged ? undefined : prompt.responseProgress, monitorsOutputProgress(activityTracker.activity.kind), totalChars, Date.now());
|
|
1298
|
+
activityChanged ? undefined : prompt.responseProgress, monitorsOutputProgress(activityTracker.activity.kind), totalChars, Date.now(), progressHeartbeat);
|
|
1267
1299
|
}
|
|
1268
1300
|
// 定时写入文件
|
|
1269
1301
|
const now2 = Date.now();
|
|
1270
|
-
if (activityChanged || now2 - lastFileWrite >= FILE_WRITE_INTERVAL_MS) {
|
|
1302
|
+
if (activityChanged || outputReset || now2 - lastFileWrite >= FILE_WRITE_INTERVAL_MS) {
|
|
1271
1303
|
lastFileWrite = now2;
|
|
1272
1304
|
await writeStreamState({
|
|
1273
1305
|
sessionId,
|
|
@@ -2045,6 +2077,13 @@ async function resolveModelEffort(tool, sessionId) {
|
|
|
2045
2077
|
effort: null,
|
|
2046
2078
|
};
|
|
2047
2079
|
}
|
|
2080
|
+
if (tool === "dsh") {
|
|
2081
|
+
const model = getEffectiveModelForTool(tool, sessionId);
|
|
2082
|
+
return {
|
|
2083
|
+
model: model.trim() !== "" ? model : UNKNOWN_MODEL_PLACEHOLDER,
|
|
2084
|
+
effort: null,
|
|
2085
|
+
};
|
|
2086
|
+
}
|
|
2048
2087
|
return {
|
|
2049
2088
|
model: anthropicConfigDisplay(getModelForSession(sessionId)),
|
|
2050
2089
|
effort: anthropicConfigDisplay(getEffectiveEffortForTool(tool, sessionId)),
|