@corbat-tech/coco 2.22.1 → 2.23.0
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/index.js +149 -12
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -1016,6 +1016,7 @@ var init_anthropic = __esm({
|
|
|
1016
1016
|
*/
|
|
1017
1017
|
async *stream(messages, options) {
|
|
1018
1018
|
this.ensureInitialized();
|
|
1019
|
+
let timeoutTriggered = false;
|
|
1019
1020
|
try {
|
|
1020
1021
|
const stream = await this.client.messages.stream(
|
|
1021
1022
|
{
|
|
@@ -1033,6 +1034,7 @@ var init_anthropic = __esm({
|
|
|
1033
1034
|
const timeoutInterval = setInterval(() => {
|
|
1034
1035
|
if (Date.now() - lastActivityTime > streamTimeout) {
|
|
1035
1036
|
clearInterval(timeoutInterval);
|
|
1037
|
+
timeoutTriggered = true;
|
|
1036
1038
|
timeoutController.abort();
|
|
1037
1039
|
}
|
|
1038
1040
|
}, 5e3);
|
|
@@ -1063,6 +1065,11 @@ var init_anthropic = __esm({
|
|
|
1063
1065
|
throw new Error(`Stream timeout: No response from LLM for ${streamTimeout / 1e3}s`);
|
|
1064
1066
|
}
|
|
1065
1067
|
} catch (error) {
|
|
1068
|
+
if (timeoutTriggered) {
|
|
1069
|
+
throw new Error(
|
|
1070
|
+
`Stream timeout: No response from LLM for ${(this.config.timeout ?? 12e4) / 1e3}s`
|
|
1071
|
+
);
|
|
1072
|
+
}
|
|
1066
1073
|
throw this.handleError(error);
|
|
1067
1074
|
}
|
|
1068
1075
|
}
|
|
@@ -1071,6 +1078,7 @@ var init_anthropic = __esm({
|
|
|
1071
1078
|
*/
|
|
1072
1079
|
async *streamWithTools(messages, options) {
|
|
1073
1080
|
this.ensureInitialized();
|
|
1081
|
+
let timeoutTriggered = false;
|
|
1074
1082
|
try {
|
|
1075
1083
|
const stream = await this.client.messages.stream(
|
|
1076
1084
|
{
|
|
@@ -1092,6 +1100,7 @@ var init_anthropic = __esm({
|
|
|
1092
1100
|
const timeoutInterval = setInterval(() => {
|
|
1093
1101
|
if (Date.now() - lastActivityTime > streamTimeout) {
|
|
1094
1102
|
clearInterval(timeoutInterval);
|
|
1103
|
+
timeoutTriggered = true;
|
|
1095
1104
|
timeoutController.abort();
|
|
1096
1105
|
}
|
|
1097
1106
|
}, 5e3);
|
|
@@ -1186,6 +1195,11 @@ var init_anthropic = __esm({
|
|
|
1186
1195
|
throw new Error(`Stream timeout: No response from LLM for ${streamTimeout / 1e3}s`);
|
|
1187
1196
|
}
|
|
1188
1197
|
} catch (error) {
|
|
1198
|
+
if (timeoutTriggered) {
|
|
1199
|
+
throw new Error(
|
|
1200
|
+
`Stream timeout: No response from LLM for ${(this.config.timeout ?? 12e4) / 1e3}s`
|
|
1201
|
+
);
|
|
1202
|
+
}
|
|
1189
1203
|
throw this.handleError(error);
|
|
1190
1204
|
}
|
|
1191
1205
|
}
|
|
@@ -1755,6 +1769,7 @@ var init_openai = __esm({
|
|
|
1755
1769
|
yield* this.streamWithToolsViaResponses(messages, options);
|
|
1756
1770
|
return;
|
|
1757
1771
|
}
|
|
1772
|
+
let timeoutTriggered = false;
|
|
1758
1773
|
try {
|
|
1759
1774
|
const supportsTemp = this.supportsTemperature(model);
|
|
1760
1775
|
const extraBody = this.getExtraBody(model);
|
|
@@ -1783,6 +1798,7 @@ var init_openai = __esm({
|
|
|
1783
1798
|
const timeoutInterval = setInterval(() => {
|
|
1784
1799
|
if (Date.now() - lastActivityTime > streamTimeout) {
|
|
1785
1800
|
clearInterval(timeoutInterval);
|
|
1801
|
+
timeoutTriggered = true;
|
|
1786
1802
|
timeoutController.abort();
|
|
1787
1803
|
}
|
|
1788
1804
|
}, 5e3);
|
|
@@ -1896,6 +1912,11 @@ var init_openai = __esm({
|
|
|
1896
1912
|
throw new Error(`Stream timeout: No response from LLM for ${streamTimeout / 1e3}s`);
|
|
1897
1913
|
}
|
|
1898
1914
|
} catch (error) {
|
|
1915
|
+
if (timeoutTriggered) {
|
|
1916
|
+
throw new Error(
|
|
1917
|
+
`Stream timeout: No response from LLM for ${(this.config.timeout ?? 12e4) / 1e3}s`
|
|
1918
|
+
);
|
|
1919
|
+
}
|
|
1899
1920
|
throw this.handleError(error);
|
|
1900
1921
|
}
|
|
1901
1922
|
}
|
|
@@ -2341,6 +2362,7 @@ var init_openai = __esm({
|
|
|
2341
2362
|
*/
|
|
2342
2363
|
async *streamViaResponses(messages, options) {
|
|
2343
2364
|
this.ensureInitialized();
|
|
2365
|
+
let timeoutTriggered = false;
|
|
2344
2366
|
try {
|
|
2345
2367
|
const model = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
|
|
2346
2368
|
const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
|
|
@@ -2359,6 +2381,7 @@ var init_openai = __esm({
|
|
|
2359
2381
|
const timeoutInterval = setInterval(() => {
|
|
2360
2382
|
if (Date.now() - lastActivityTime > streamTimeout) {
|
|
2361
2383
|
clearInterval(timeoutInterval);
|
|
2384
|
+
timeoutTriggered = true;
|
|
2362
2385
|
timeoutController.abort();
|
|
2363
2386
|
}
|
|
2364
2387
|
}, 5e3);
|
|
@@ -2383,6 +2406,11 @@ var init_openai = __esm({
|
|
|
2383
2406
|
throw new Error(`Stream timeout: No response from LLM for ${streamTimeout / 1e3}s`);
|
|
2384
2407
|
}
|
|
2385
2408
|
} catch (error) {
|
|
2409
|
+
if (timeoutTriggered) {
|
|
2410
|
+
throw new Error(
|
|
2411
|
+
`Stream timeout: No response from LLM for ${(this.config.timeout ?? 12e4) / 1e3}s`
|
|
2412
|
+
);
|
|
2413
|
+
}
|
|
2386
2414
|
throw this.handleError(error);
|
|
2387
2415
|
}
|
|
2388
2416
|
}
|
|
@@ -2395,6 +2423,7 @@ var init_openai = __esm({
|
|
|
2395
2423
|
*/
|
|
2396
2424
|
async *streamWithToolsViaResponses(messages, options) {
|
|
2397
2425
|
this.ensureInitialized();
|
|
2426
|
+
let timeoutTriggered = false;
|
|
2398
2427
|
try {
|
|
2399
2428
|
const model = options?.model ?? this.config.model ?? DEFAULT_MODEL2;
|
|
2400
2429
|
const { input, instructions } = this.convertToResponsesInput(messages, options?.system);
|
|
@@ -2421,6 +2450,7 @@ var init_openai = __esm({
|
|
|
2421
2450
|
const timeoutInterval = setInterval(() => {
|
|
2422
2451
|
if (Date.now() - lastActivityTime > streamTimeout) {
|
|
2423
2452
|
clearInterval(timeoutInterval);
|
|
2453
|
+
timeoutTriggered = true;
|
|
2424
2454
|
timeoutController.abort();
|
|
2425
2455
|
}
|
|
2426
2456
|
}, 5e3);
|
|
@@ -2506,6 +2536,11 @@ var init_openai = __esm({
|
|
|
2506
2536
|
throw new Error(`Stream timeout: No response from LLM for ${streamTimeout / 1e3}s`);
|
|
2507
2537
|
}
|
|
2508
2538
|
} catch (error) {
|
|
2539
|
+
if (timeoutTriggered) {
|
|
2540
|
+
throw new Error(
|
|
2541
|
+
`Stream timeout: No response from LLM for ${(this.config.timeout ?? 12e4) / 1e3}s`
|
|
2542
|
+
);
|
|
2543
|
+
}
|
|
2509
2544
|
throw this.handleError(error);
|
|
2510
2545
|
}
|
|
2511
2546
|
}
|
|
@@ -9582,7 +9617,15 @@ Responses are short and direct by default. Lead with the answer or action, not r
|
|
|
9582
9617
|
|
|
9583
9618
|
## File Changes
|
|
9584
9619
|
|
|
9585
|
-
**Never output raw diff or unified diff format in your responses.** Use edit_file and write_file to make changes \u2014 Coco renders a visual diff automatically.
|
|
9620
|
+
**Never output raw diff or unified diff format in your responses.** Use edit_file and write_file to make changes \u2014 Coco renders a visual diff automatically.
|
|
9621
|
+
|
|
9622
|
+
## Output Discipline
|
|
9623
|
+
|
|
9624
|
+
**NEVER echo file contents in your responses.** When you read a file, extract only the specific information needed \u2014 do NOT reprint whole files, functions, or large excerpts. The terminal shows which files you read and their line counts \u2014 the user does not need to see the content again.
|
|
9625
|
+
|
|
9626
|
+
**During tool-calling iterations, keep text minimal.** A single short orienting line before tool calls is acceptable. Do NOT explain every step, narrate what you are about to do, or produce paragraphs between tool calls. Reserve explanatory text for your final response after all tools have completed.
|
|
9627
|
+
|
|
9628
|
+
**Code blocks in responses are expensive.** Only include a code block when the user explicitly asks to see code, or when the code IS the deliverable (e.g., a script to paste in a terminal). Never include a code block to "show your work" when you can write the file directly instead.`;
|
|
9586
9629
|
SHELL_METACHARACTERS = /[;|&`$(){}<>!\n\\'"]/;
|
|
9587
9630
|
SAFE_COMMAND_VALIDATORS = {
|
|
9588
9631
|
git: (args) => {
|
|
@@ -47017,6 +47060,8 @@ var streamingIndicatorInterval = null;
|
|
|
47017
47060
|
var streamingIndicatorFrame = 0;
|
|
47018
47061
|
var STREAMING_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
47019
47062
|
var getTerminalWidth2 = () => process.stdout.columns || 80;
|
|
47063
|
+
var MAX_STREAMING_CODE_LINES = 50;
|
|
47064
|
+
var STREAMING_CODE_HEAD_LINES = 40;
|
|
47020
47065
|
function startStreamingIndicator() {
|
|
47021
47066
|
if (streamingIndicatorActive) return;
|
|
47022
47067
|
streamingIndicatorActive = true;
|
|
@@ -47340,11 +47385,17 @@ function renderSimpleCodeBlock(lang, lines, blockId) {
|
|
|
47340
47385
|
const isDiff = lang === "diff" || !lang && looksLikeDiff(lines);
|
|
47341
47386
|
const title = lang || "Code";
|
|
47342
47387
|
console.log(chalk2.dim(`${title} \xB7 #${blockId}`));
|
|
47388
|
+
let displayLines = lines;
|
|
47389
|
+
let truncatedCount = 0;
|
|
47390
|
+
if (!isDiff && lines.length > MAX_STREAMING_CODE_LINES) {
|
|
47391
|
+
displayLines = lines.slice(0, STREAMING_CODE_HEAD_LINES);
|
|
47392
|
+
truncatedCount = lines.length - STREAMING_CODE_HEAD_LINES;
|
|
47393
|
+
}
|
|
47343
47394
|
const bgDel = chalk2.bgRgb(80, 20, 20);
|
|
47344
47395
|
const bgAdd = chalk2.bgRgb(20, 60, 20);
|
|
47345
47396
|
let oldLineNo = 0;
|
|
47346
47397
|
let newLineNo = 0;
|
|
47347
|
-
for (const line of
|
|
47398
|
+
for (const line of displayLines) {
|
|
47348
47399
|
if (isDiff) {
|
|
47349
47400
|
const hunkMatch = line.match(/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/);
|
|
47350
47401
|
if (hunkMatch) {
|
|
@@ -47372,6 +47423,9 @@ function renderSimpleCodeBlock(lang, lines, blockId) {
|
|
|
47372
47423
|
}
|
|
47373
47424
|
}
|
|
47374
47425
|
}
|
|
47426
|
+
if (truncatedCount > 0) {
|
|
47427
|
+
console.log(chalk2.dim(` \u2026 ${truncatedCount} more lines \xB7 /copy ${blockId} for full content`));
|
|
47428
|
+
}
|
|
47375
47429
|
console.log(chalk2.dim(` #${blockId} \xB7 /copy ${blockId}`));
|
|
47376
47430
|
}
|
|
47377
47431
|
function formatDiffLineNo(line, oldLineNo, newLineNo) {
|
|
@@ -50023,6 +50077,8 @@ async function executeAgentTurn(session, userMessage, provider, toolRegistry, op
|
|
|
50023
50077
|
const maxIterations = session.config.agent.maxToolIterations;
|
|
50024
50078
|
const toolErrorCounts = /* @__PURE__ */ new Map();
|
|
50025
50079
|
const MAX_CONSECUTIVE_TOOL_ERRORS = 3;
|
|
50080
|
+
const ITERATION_LIMIT_WARNING_RATIO = 0.75;
|
|
50081
|
+
const ITERATION_LIMIT_SUMMARY_PROMPT = `[System: You have now used all allowed iterations and tool calls are no longer available. Write your final response immediately: (1) briefly state what was completed, (2) describe what still needs to be done, (3) give specific next steps so the user can continue. Be concise and direct.]`;
|
|
50026
50082
|
const INLINE_RESULT_MAX_CHARS = 8e3;
|
|
50027
50083
|
const INLINE_RESULT_HEAD_CHARS = 6500;
|
|
50028
50084
|
const INLINE_RESULT_TAIL_CHARS = 1e3;
|
|
@@ -50037,6 +50093,8 @@ ${tail}`;
|
|
|
50037
50093
|
}
|
|
50038
50094
|
while (iteration < maxIterations) {
|
|
50039
50095
|
iteration++;
|
|
50096
|
+
const isLastIteration = iteration === maxIterations;
|
|
50097
|
+
const iterationTextChunks = [];
|
|
50040
50098
|
if (options.signal?.aborted) {
|
|
50041
50099
|
return abortReturn();
|
|
50042
50100
|
}
|
|
@@ -50064,7 +50122,7 @@ ${tail}`;
|
|
|
50064
50122
|
}
|
|
50065
50123
|
responseContent += chunk.text;
|
|
50066
50124
|
finalContent += chunk.text;
|
|
50067
|
-
|
|
50125
|
+
iterationTextChunks.push(chunk);
|
|
50068
50126
|
}
|
|
50069
50127
|
if (chunk.type === "tool_use_start" && chunk.toolCall) {
|
|
50070
50128
|
flushLineBuffer();
|
|
@@ -50141,6 +50199,11 @@ ${tail}`;
|
|
|
50141
50199
|
error: errorMsg
|
|
50142
50200
|
};
|
|
50143
50201
|
}
|
|
50202
|
+
if (collectedToolCalls.length === 0) {
|
|
50203
|
+
for (const bufferedChunk of iterationTextChunks) {
|
|
50204
|
+
options.onStream?.(bufferedChunk);
|
|
50205
|
+
}
|
|
50206
|
+
}
|
|
50144
50207
|
const inputText = messages.map((m) => {
|
|
50145
50208
|
if (typeof m.content === "string") return m.content;
|
|
50146
50209
|
try {
|
|
@@ -50316,10 +50379,20 @@ ${tail}`;
|
|
|
50316
50379
|
});
|
|
50317
50380
|
const declineReason = declinedTools.get(toolCall.id);
|
|
50318
50381
|
if (declineReason) {
|
|
50382
|
+
let skipContent;
|
|
50383
|
+
if (declineReason === "User declined") {
|
|
50384
|
+
skipContent = "The user explicitly declined this tool call. You MUST find a different approach \u2014 do not retry the same action or parameters.";
|
|
50385
|
+
} else if (declineReason.toLowerCase().includes("timeout") || declineReason.toLowerCase().includes("timed out")) {
|
|
50386
|
+
skipContent = `Tool execution timed out: ${declineReason}. Try a simpler or faster alternative, or break the task into smaller steps.`;
|
|
50387
|
+
} else if (declineReason.toLowerCase().includes("abort")) {
|
|
50388
|
+
skipContent = "Tool execution was cancelled.";
|
|
50389
|
+
} else {
|
|
50390
|
+
skipContent = `Tool execution was skipped: ${declineReason}`;
|
|
50391
|
+
}
|
|
50319
50392
|
toolResults.push({
|
|
50320
50393
|
type: "tool_result",
|
|
50321
50394
|
tool_use_id: toolCall.id,
|
|
50322
|
-
content:
|
|
50395
|
+
content: skipContent,
|
|
50323
50396
|
is_error: true
|
|
50324
50397
|
});
|
|
50325
50398
|
continue;
|
|
@@ -50373,6 +50446,28 @@ ${tail}`;
|
|
|
50373
50446
|
}
|
|
50374
50447
|
}
|
|
50375
50448
|
}
|
|
50449
|
+
if (toolResults.length > 0) {
|
|
50450
|
+
const warningThreshold = Math.ceil(maxIterations * ITERATION_LIMIT_WARNING_RATIO);
|
|
50451
|
+
const lastIdx = toolResults.length - 1;
|
|
50452
|
+
const last = toolResults[lastIdx];
|
|
50453
|
+
if (isLastIteration && !stuckInErrorLoop) {
|
|
50454
|
+
toolResults[lastIdx] = {
|
|
50455
|
+
...last,
|
|
50456
|
+
content: typeof last.content === "string" ? last.content + `
|
|
50457
|
+
|
|
50458
|
+
${ITERATION_LIMIT_SUMMARY_PROMPT}` : ITERATION_LIMIT_SUMMARY_PROMPT
|
|
50459
|
+
};
|
|
50460
|
+
} else if (iteration === warningThreshold) {
|
|
50461
|
+
const remaining = maxIterations - iteration;
|
|
50462
|
+
const warning = `
|
|
50463
|
+
|
|
50464
|
+
[System: Iteration budget warning \u2014 ${iteration} of ${maxIterations} iterations used, ${remaining} remaining. Begin wrapping up your task. Prioritize the most critical remaining steps.]`;
|
|
50465
|
+
toolResults[lastIdx] = {
|
|
50466
|
+
...last,
|
|
50467
|
+
content: typeof last.content === "string" ? last.content + warning : warning
|
|
50468
|
+
};
|
|
50469
|
+
}
|
|
50470
|
+
}
|
|
50376
50471
|
const assistantContent = response.content ? [{ type: "text", text: response.content }, ...toolUses] : toolUses;
|
|
50377
50472
|
addMessage(session, {
|
|
50378
50473
|
role: "assistant",
|
|
@@ -50417,14 +50512,38 @@ ${tail}`;
|
|
|
50417
50512
|
}
|
|
50418
50513
|
break;
|
|
50419
50514
|
}
|
|
50420
|
-
|
|
50421
|
-
|
|
50422
|
-
|
|
50515
|
+
if (isLastIteration && toolResults.length > 0) {
|
|
50516
|
+
let summaryThinkingEnded = false;
|
|
50517
|
+
options.onThinkingStart?.();
|
|
50518
|
+
try {
|
|
50519
|
+
const finalMessages = getConversationContext(session, toolRegistry);
|
|
50520
|
+
for await (const chunk of provider.streamWithTools(finalMessages, {
|
|
50521
|
+
tools: [],
|
|
50522
|
+
maxTokens: session.config.provider.maxTokens,
|
|
50523
|
+
signal: options.signal
|
|
50524
|
+
})) {
|
|
50525
|
+
if (options.signal?.aborted) break;
|
|
50526
|
+
if (chunk.type === "text" && chunk.text) {
|
|
50527
|
+
if (!summaryThinkingEnded) {
|
|
50528
|
+
options.onThinkingEnd?.();
|
|
50529
|
+
summaryThinkingEnded = true;
|
|
50530
|
+
}
|
|
50531
|
+
finalContent += chunk.text;
|
|
50532
|
+
options.onStream?.(chunk);
|
|
50533
|
+
}
|
|
50534
|
+
if (chunk.type === "done") break;
|
|
50535
|
+
}
|
|
50536
|
+
} catch {
|
|
50537
|
+
const notice = `
|
|
50423
50538
|
|
|
50424
|
-
|
|
50425
|
-
|
|
50426
|
-
|
|
50427
|
-
|
|
50539
|
+
I have reached the maximum iteration limit (${maxIterations}). The task may be incomplete. Type "continue" to give me more iterations, or describe what you'd like me to focus on next.`;
|
|
50540
|
+
finalContent += notice;
|
|
50541
|
+
options.onStream?.({ type: "text", text: notice });
|
|
50542
|
+
} finally {
|
|
50543
|
+
if (!summaryThinkingEnded) options.onThinkingEnd?.();
|
|
50544
|
+
}
|
|
50545
|
+
break;
|
|
50546
|
+
}
|
|
50428
50547
|
}
|
|
50429
50548
|
options.onStream?.({ type: "done" });
|
|
50430
50549
|
return {
|
|
@@ -51623,6 +51742,9 @@ ${imagePrompts}`.trim() : imagePrompts;
|
|
|
51623
51742
|
result.toolCalls.length
|
|
51624
51743
|
);
|
|
51625
51744
|
}
|
|
51745
|
+
if (result.toolCalls.length > 0) {
|
|
51746
|
+
console.log(chalk2.dim(" Type your request again to resume where you left off."));
|
|
51747
|
+
}
|
|
51626
51748
|
console.log();
|
|
51627
51749
|
continue;
|
|
51628
51750
|
}
|
|
@@ -51646,6 +51768,9 @@ ${imagePrompts}`.trim() : imagePrompts;
|
|
|
51646
51768
|
console.log(
|
|
51647
51769
|
chalk2.dim(" Recovery failed or error is non-retryable. Returning to prompt.")
|
|
51648
51770
|
);
|
|
51771
|
+
console.log(
|
|
51772
|
+
chalk2.dim(" Tip: Try /provider or /model to switch, then rephrase and retry.")
|
|
51773
|
+
);
|
|
51649
51774
|
consecutiveErrors = 0;
|
|
51650
51775
|
}
|
|
51651
51776
|
console.log();
|
|
@@ -51713,12 +51838,20 @@ ${imagePrompts}`.trim() : imagePrompts;
|
|
|
51713
51838
|
compactSpinner.clear();
|
|
51714
51839
|
}
|
|
51715
51840
|
} catch {
|
|
51716
|
-
compactSpinner.
|
|
51841
|
+
compactSpinner.stop("\u26A0 Context compaction failed");
|
|
51842
|
+
console.log(
|
|
51843
|
+
chalk2.yellow(
|
|
51844
|
+
" \u26A0 Context compaction failed \u2014 context unchanged. Use /clear if needed."
|
|
51845
|
+
)
|
|
51846
|
+
);
|
|
51717
51847
|
} finally {
|
|
51718
51848
|
clearTimeout(compactTimeout);
|
|
51719
51849
|
process.off("SIGINT", compactSigint);
|
|
51720
51850
|
}
|
|
51721
51851
|
} catch {
|
|
51852
|
+
console.log(
|
|
51853
|
+
chalk2.yellow(" \u26A0 Context compaction failed \u2014 context unchanged. Use /clear if needed.")
|
|
51854
|
+
);
|
|
51722
51855
|
}
|
|
51723
51856
|
renderStatusBar(session.projectPath, session.config, gitContext, usageForDisplay);
|
|
51724
51857
|
if (usageForDisplay >= 90 && !warned90) {
|
|
@@ -51825,11 +51958,15 @@ ${imagePrompts}`.trim() : imagePrompts;
|
|
|
51825
51958
|
session.messages.length = preCallMessageLength;
|
|
51826
51959
|
renderError(errorMsg);
|
|
51827
51960
|
console.log(chalk2.dim(" Recovery failed after multiple attempts. Returning to prompt."));
|
|
51961
|
+
console.log(
|
|
51962
|
+
chalk2.dim(" Tip: Try /provider or /model to switch, then rephrase and retry.")
|
|
51963
|
+
);
|
|
51828
51964
|
continue;
|
|
51829
51965
|
}
|
|
51830
51966
|
session.messages.length = preCallMessageLength;
|
|
51831
51967
|
consecutiveErrors = 0;
|
|
51832
51968
|
renderError(errorMsg);
|
|
51969
|
+
console.log(chalk2.dim(" Tip: Try /provider or /model to switch, then rephrase and retry."));
|
|
51833
51970
|
} finally {
|
|
51834
51971
|
clearSpinner();
|
|
51835
51972
|
if (originalSystemPrompt !== void 0) {
|