cc-claw 0.13.0 → 0.13.2
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/cli.js +67 -23
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -72,7 +72,7 @@ var VERSION;
|
|
|
72
72
|
var init_version = __esm({
|
|
73
73
|
"src/version.ts"() {
|
|
74
74
|
"use strict";
|
|
75
|
-
VERSION = true ? "0.13.
|
|
75
|
+
VERSION = true ? "0.13.2" : (() => {
|
|
76
76
|
try {
|
|
77
77
|
return JSON.parse(readFileSync(join2(process.cwd(), "package.json"), "utf-8")).version ?? "unknown";
|
|
78
78
|
} catch {
|
|
@@ -9684,6 +9684,9 @@ function stopAgent(chatId) {
|
|
|
9684
9684
|
}
|
|
9685
9685
|
return true;
|
|
9686
9686
|
}
|
|
9687
|
+
function getGeminiFallback(model2) {
|
|
9688
|
+
return GEMINI_FALLBACK_CHAIN[model2] ?? null;
|
|
9689
|
+
}
|
|
9687
9690
|
function spawnQuery(adapter, config2, model2, cancelState, thinkingLevel, timeoutMs, maxTurns, opts) {
|
|
9688
9691
|
const effectiveTimeout = timeoutMs ?? SPAWN_TIMEOUT_MS;
|
|
9689
9692
|
return new Promise((resolve, reject) => {
|
|
@@ -9727,10 +9730,11 @@ function spawnQuery(adapter, config2, model2, cancelState, thinkingLevel, timeou
|
|
|
9727
9730
|
let firstLine = true;
|
|
9728
9731
|
const frTimeoutMs = opts?.firstResponseTimeoutMs ?? FIRST_RESPONSE_TIMEOUT_MS;
|
|
9729
9732
|
let firstResponseTimer;
|
|
9733
|
+
let gotModelContent = false;
|
|
9730
9734
|
if (frTimeoutMs > 0) {
|
|
9731
9735
|
firstResponseTimer = setTimeout(() => {
|
|
9732
|
-
if (
|
|
9733
|
-
warn(`[agent] First-response timeout after ${frTimeoutMs}ms for ${adapter.id} \u2014 no
|
|
9736
|
+
if (!gotModelContent) {
|
|
9737
|
+
warn(`[agent] First-response timeout after ${frTimeoutMs}ms for ${adapter.id} \u2014 no model content received (init may have arrived), killing`);
|
|
9734
9738
|
killProcessGroup(proc, "SIGTERM");
|
|
9735
9739
|
timedOut = true;
|
|
9736
9740
|
cancelState.__firstResponseTimeout = true;
|
|
@@ -9743,10 +9747,6 @@ function spawnQuery(adapter, config2, model2, cancelState, thinkingLevel, timeou
|
|
|
9743
9747
|
if (firstLine) {
|
|
9744
9748
|
log(`[agent] First CLI message after ${elapsed()}`);
|
|
9745
9749
|
firstLine = false;
|
|
9746
|
-
if (firstResponseTimer) {
|
|
9747
|
-
clearTimeout(firstResponseTimer);
|
|
9748
|
-
firstResponseTimer = void 0;
|
|
9749
|
-
}
|
|
9750
9750
|
}
|
|
9751
9751
|
let msg;
|
|
9752
9752
|
try {
|
|
@@ -9766,12 +9766,26 @@ function spawnQuery(adapter, config2, model2, cancelState, thinkingLevel, timeou
|
|
|
9766
9766
|
if (ev.sessionId) sessionId = ev.sessionId;
|
|
9767
9767
|
break;
|
|
9768
9768
|
case "text":
|
|
9769
|
+
if (!gotModelContent) {
|
|
9770
|
+
gotModelContent = true;
|
|
9771
|
+
if (firstResponseTimer) {
|
|
9772
|
+
clearTimeout(firstResponseTimer);
|
|
9773
|
+
firstResponseTimer = void 0;
|
|
9774
|
+
}
|
|
9775
|
+
}
|
|
9769
9776
|
if (ev.text) {
|
|
9770
9777
|
accumulatedText = appendTextChunk(accumulatedText, ev.text);
|
|
9771
9778
|
if (opts?.onStream) opts.onStream(ev.text);
|
|
9772
9779
|
}
|
|
9773
9780
|
break;
|
|
9774
9781
|
case "tool_start":
|
|
9782
|
+
if (!gotModelContent) {
|
|
9783
|
+
gotModelContent = true;
|
|
9784
|
+
if (firstResponseTimer) {
|
|
9785
|
+
clearTimeout(firstResponseTimer);
|
|
9786
|
+
firstResponseTimer = void 0;
|
|
9787
|
+
}
|
|
9788
|
+
}
|
|
9775
9789
|
sawToolEvents = true;
|
|
9776
9790
|
if (opts?.onToolAction && ev.toolName) {
|
|
9777
9791
|
const toolInput = ev.toolInput ?? {};
|
|
@@ -9821,6 +9835,13 @@ function spawnQuery(adapter, config2, model2, cancelState, thinkingLevel, timeou
|
|
|
9821
9835
|
}
|
|
9822
9836
|
break;
|
|
9823
9837
|
case "result":
|
|
9838
|
+
if (!gotModelContent) {
|
|
9839
|
+
gotModelContent = true;
|
|
9840
|
+
if (firstResponseTimer) {
|
|
9841
|
+
clearTimeout(firstResponseTimer);
|
|
9842
|
+
firstResponseTimer = void 0;
|
|
9843
|
+
}
|
|
9844
|
+
}
|
|
9824
9845
|
sawResultEvent = true;
|
|
9825
9846
|
log(`[agent] Result received at ${elapsed()}`);
|
|
9826
9847
|
resultText = ev.resultText || accumulatedText;
|
|
@@ -9934,12 +9955,14 @@ async function spawnGeminiWithRotation(chatId, adapter, baseConfig, configWithSe
|
|
|
9934
9955
|
const isTimeout = errMsg.startsWith(FIRST_RESPONSE_TIMEOUT_ERROR);
|
|
9935
9956
|
const isExhausted = /RESOURCE.?EXHAUSTED|resource has been exhausted/i.test(errMsg);
|
|
9936
9957
|
if ((isTimeout || isExhausted) && GEMINI_DOWNGRADE_MODELS.has(model2)) {
|
|
9958
|
+
const fallbackModel = getGeminiFallback(model2);
|
|
9937
9959
|
const reason = isTimeout ? "No response within timeout" : "Resource exhausted";
|
|
9938
|
-
warn(`[agent:gemini-rotation] ${reason} on ${model2} (${slotLabel}) \u2014 downgrading to ${
|
|
9939
|
-
onModelDowngrade?.(model2,
|
|
9960
|
+
warn(`[agent:gemini-rotation] ${reason} on ${model2} (${slotLabel}) \u2014 downgrading to ${fallbackModel}`);
|
|
9961
|
+
onModelDowngrade?.(model2, fallbackModel, `${reason} \u2014 model likely overloaded`);
|
|
9962
|
+
setModel(chatId, fallbackModel);
|
|
9940
9963
|
const fallbackConfig = adapter.buildSpawnConfig({
|
|
9941
9964
|
prompt: effectiveConfig.args[effectiveConfig.args.indexOf("-p") + 1],
|
|
9942
|
-
model:
|
|
9965
|
+
model: fallbackModel,
|
|
9943
9966
|
permMode: "yolo",
|
|
9944
9967
|
allowedTools: [],
|
|
9945
9968
|
cwd: effectiveConfig.cwd,
|
|
@@ -9956,7 +9979,9 @@ async function spawnGeminiWithRotation(chatId, adapter, baseConfig, configWithSe
|
|
|
9956
9979
|
}
|
|
9957
9980
|
}
|
|
9958
9981
|
}
|
|
9959
|
-
|
|
9982
|
+
const fallbackResult = await spawnQuery(adapter, fallbackConfig, fallbackModel, cancelState, thinkingLevel, timeoutMs, maxTurns, { ...opts, envOverride: env });
|
|
9983
|
+
fallbackResult.resolvedModel = fallbackModel;
|
|
9984
|
+
return fallbackResult;
|
|
9960
9985
|
}
|
|
9961
9986
|
const quotaClass = classifyGeminiQuota(errMsg);
|
|
9962
9987
|
if (quotaClass === "rate_limited") {
|
|
@@ -10068,12 +10093,14 @@ async function askAgentImpl(chatId, userMessage, opts) {
|
|
|
10068
10093
|
const isTimeout = errMsg.startsWith(FIRST_RESPONSE_TIMEOUT_ERROR);
|
|
10069
10094
|
const isExhausted = /RESOURCE.?EXHAUSTED|resource has been exhausted/i.test(errMsg);
|
|
10070
10095
|
if (adapter.id === "gemini" && (isTimeout || isExhausted) && GEMINI_DOWNGRADE_MODELS.has(resolvedModel)) {
|
|
10096
|
+
const fallbackModel = getGeminiFallback(resolvedModel);
|
|
10071
10097
|
const reason = isTimeout ? "No response within timeout" : "Resource exhausted";
|
|
10072
|
-
warn(`[agent] ${reason} on ${resolvedModel} (no rotation) \u2014 downgrading to ${
|
|
10073
|
-
onModelDowngrade?.(chatId, resolvedModel,
|
|
10098
|
+
warn(`[agent] ${reason} on ${resolvedModel} (no rotation) \u2014 downgrading to ${fallbackModel}`);
|
|
10099
|
+
onModelDowngrade?.(chatId, resolvedModel, fallbackModel, `${reason} \u2014 model likely overloaded`);
|
|
10100
|
+
setModel(chatId, fallbackModel);
|
|
10074
10101
|
const fallbackConfig = adapter.buildSpawnConfig({
|
|
10075
10102
|
prompt: configWithSession.args[configWithSession.args.indexOf("-p") + 1],
|
|
10076
|
-
model:
|
|
10103
|
+
model: fallbackModel,
|
|
10077
10104
|
permMode: mode,
|
|
10078
10105
|
allowedTools,
|
|
10079
10106
|
cwd: resolvedCwd,
|
|
@@ -10083,7 +10110,8 @@ async function askAgentImpl(chatId, userMessage, opts) {
|
|
|
10083
10110
|
if (mcpConfigPath) {
|
|
10084
10111
|
fallbackConfig.args = injectMcpConfig(adapter.id, fallbackConfig.args, mcpConfigPath);
|
|
10085
10112
|
}
|
|
10086
|
-
result = await spawnQuery(adapter, fallbackConfig,
|
|
10113
|
+
result = await spawnQuery(adapter, fallbackConfig, fallbackModel, cancelState, thinkingLevel, timeoutMs, maxTurns, spawnOpts);
|
|
10114
|
+
result.resolvedModel = fallbackModel;
|
|
10087
10115
|
} else {
|
|
10088
10116
|
throw err;
|
|
10089
10117
|
}
|
|
@@ -10154,7 +10182,8 @@ async function askAgentImpl(chatId, userMessage, opts) {
|
|
|
10154
10182
|
return {
|
|
10155
10183
|
text: result.resultText || `(No response from ${adapter.displayName})`,
|
|
10156
10184
|
sessionId: result.sessionId,
|
|
10157
|
-
usage: { input: result.input, output: result.output, cacheRead: result.cacheRead, contextSize: result.contextSize }
|
|
10185
|
+
usage: { input: result.input, output: result.output, cacheRead: result.cacheRead, contextSize: result.contextSize },
|
|
10186
|
+
resolvedModel: result.resolvedModel
|
|
10158
10187
|
};
|
|
10159
10188
|
}
|
|
10160
10189
|
function getMcpConfigPath(chatId) {
|
|
@@ -10168,7 +10197,7 @@ function injectMcpConfig(adapterId, args, mcpConfigPath) {
|
|
|
10168
10197
|
if (!flag) return args;
|
|
10169
10198
|
return [...args, ...flag, mcpConfigPath];
|
|
10170
10199
|
}
|
|
10171
|
-
var activeChats, chatLocks, SPAWN_TIMEOUT_MS, FIRST_RESPONSE_TIMEOUT_MS, FIRST_RESPONSE_TIMEOUT_ERROR,
|
|
10200
|
+
var activeChats, chatLocks, SPAWN_TIMEOUT_MS, FIRST_RESPONSE_TIMEOUT_MS, FIRST_RESPONSE_TIMEOUT_ERROR, GEMINI_FALLBACK_CHAIN, GEMINI_DOWNGRADE_MODELS, MCP_CONFIG_FLAG;
|
|
10172
10201
|
var init_agent = __esm({
|
|
10173
10202
|
"src/agent.ts"() {
|
|
10174
10203
|
"use strict";
|
|
@@ -10191,10 +10220,13 @@ var init_agent = __esm({
|
|
|
10191
10220
|
activeChats = /* @__PURE__ */ new Map();
|
|
10192
10221
|
chatLocks = /* @__PURE__ */ new Map();
|
|
10193
10222
|
SPAWN_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
10194
|
-
FIRST_RESPONSE_TIMEOUT_MS = parseInt(process.env.GEMINI_FIRST_RESPONSE_TIMEOUT_MS ?? "
|
|
10223
|
+
FIRST_RESPONSE_TIMEOUT_MS = parseInt(process.env.GEMINI_FIRST_RESPONSE_TIMEOUT_MS ?? "30000", 10);
|
|
10195
10224
|
FIRST_RESPONSE_TIMEOUT_ERROR = "FIRST_RESPONSE_TIMEOUT";
|
|
10196
|
-
|
|
10197
|
-
|
|
10225
|
+
GEMINI_FALLBACK_CHAIN = {
|
|
10226
|
+
"gemini-3.1-pro-preview": "gemini-2.5-pro",
|
|
10227
|
+
"gemini-2.5-pro": "gemini-3.1-flash-preview"
|
|
10228
|
+
};
|
|
10229
|
+
GEMINI_DOWNGRADE_MODELS = new Set(Object.keys(GEMINI_FALLBACK_CHAIN));
|
|
10198
10230
|
MCP_CONFIG_FLAG = {
|
|
10199
10231
|
claude: ["--mcp-config"]
|
|
10200
10232
|
};
|
|
@@ -15202,12 +15234,20 @@ You're still in discussion mode \u2014 try again or click a button to exit.`, {
|
|
|
15202
15234
|
const sigEnabled = getModelSignature(chatId);
|
|
15203
15235
|
if (sigEnabled === "on" && responseText && !responseText.startsWith("(No response")) {
|
|
15204
15236
|
const adapter = getAdapterForChat(chatId);
|
|
15205
|
-
const modelId = model2 ?? adapter.defaultModel;
|
|
15237
|
+
const modelId = response.resolvedModel ?? model2 ?? adapter.defaultModel;
|
|
15206
15238
|
const thinking2 = getThinkingLevel(chatId) || "auto";
|
|
15207
15239
|
const shortModel = formatModelShort(modelId);
|
|
15240
|
+
let slotTag = "";
|
|
15241
|
+
if (adapter.id === "gemini") {
|
|
15242
|
+
const slotId = getChatGeminiSlotId(chatId);
|
|
15243
|
+
if (slotId) {
|
|
15244
|
+
const slot = getGeminiSlots().find((s) => s.id === slotId);
|
|
15245
|
+
if (slot) slotTag = ` \xB7 ${slot.label || `slot-${slot.id}`}`;
|
|
15246
|
+
}
|
|
15247
|
+
}
|
|
15208
15248
|
responseText += `
|
|
15209
15249
|
|
|
15210
|
-
\u{1F9E0} [${shortModel} | ${capitalize(thinking2)}] \u23F1\uFE0F ${elapsedSec}s`;
|
|
15250
|
+
\u{1F9E0} [${shortModel} | ${capitalize(thinking2)}${slotTag}] \u23F1\uFE0F ${elapsedSec}s`;
|
|
15211
15251
|
}
|
|
15212
15252
|
if (observedSubagents.size > 0) {
|
|
15213
15253
|
const names = [...observedSubagents].join(", ");
|
|
@@ -16474,7 +16514,11 @@ Result: ${task.result.slice(0, 500)}` : ""
|
|
|
16474
16514
|
pinChatGeminiSlot(chatId, slotId);
|
|
16475
16515
|
const label2 = slot.label || `slot-${slot.id}`;
|
|
16476
16516
|
const icon = slot.slotType === "oauth" ? "\u{1F468}\u{1F3FD}\u200D\u{1F4BB}" : "\u{1F511}";
|
|
16477
|
-
|
|
16517
|
+
const rotationMode = getGeminiRotationMode();
|
|
16518
|
+
const rotationLabels = { off: "off", all: "all slots", accounts: "accounts only", keys: "keys only" };
|
|
16519
|
+
const rotationNote = rotationMode === "off" ? "Rotation is off \u2014 only this account will be used." : `Rotation: ${rotationLabels[rotationMode]} (this is the starting slot).`;
|
|
16520
|
+
await channel.sendText(chatId, `${icon} Account set to <b>${label2}</b>
|
|
16521
|
+
${rotationNote}`, { parseMode: "html" });
|
|
16478
16522
|
}
|
|
16479
16523
|
}
|
|
16480
16524
|
return;
|
package/package.json
CHANGED