@cydm/pie 1.0.16 → 1.0.17
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/builtin/extensions/ask-user/index.js +1 -1
- package/dist/builtin/extensions/plan-mode/index.js +1 -1
- package/dist/builtin/extensions/subagent/index.js +2 -2
- package/dist/builtin/extensions/todo/index.js +1 -1
- package/dist/chunks/{chunk-62XU6P2H.js → chunk-4MIOCDBV.js} +1 -1
- package/dist/chunks/{chunk-7GAYJ6AF.js → chunk-B4VUX6SD.js} +352 -69
- package/dist/cli.js +52 -7
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
createAskUserCapability
|
|
4
|
-
} from "../../../chunks/chunk-
|
|
4
|
+
} from "../../../chunks/chunk-B4VUX6SD.js";
|
|
5
5
|
import "../../../chunks/chunk-VE2HDCNB.js";
|
|
6
6
|
import "../../../chunks/chunk-5DA2D3K2.js";
|
|
7
7
|
import "../../../chunks/chunk-TG2EQLX2.js";
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
isPlanModeSafeCommand,
|
|
8
8
|
markCompletedPlanSteps,
|
|
9
9
|
restoreExecutionState
|
|
10
|
-
} from "../../../chunks/chunk-
|
|
10
|
+
} from "../../../chunks/chunk-B4VUX6SD.js";
|
|
11
11
|
import "../../../chunks/chunk-VE2HDCNB.js";
|
|
12
12
|
import "../../../chunks/chunk-5DA2D3K2.js";
|
|
13
13
|
import "../../../chunks/chunk-TG2EQLX2.js";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
createCliHostCapabilities
|
|
4
|
-
} from "../../../chunks/chunk-
|
|
4
|
+
} from "../../../chunks/chunk-4MIOCDBV.js";
|
|
5
5
|
import {
|
|
6
6
|
createSharedFileSystemTools,
|
|
7
7
|
createSubagentCapability
|
|
8
|
-
} from "../../../chunks/chunk-
|
|
8
|
+
} from "../../../chunks/chunk-B4VUX6SD.js";
|
|
9
9
|
import "../../../chunks/chunk-VE2HDCNB.js";
|
|
10
10
|
import "../../../chunks/chunk-5DA2D3K2.js";
|
|
11
11
|
import "../../../chunks/chunk-TG2EQLX2.js";
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
executeManageTodoList,
|
|
8
8
|
executionStateToTodos,
|
|
9
9
|
restoreExecutionState
|
|
10
|
-
} from "../../../chunks/chunk-
|
|
10
|
+
} from "../../../chunks/chunk-B4VUX6SD.js";
|
|
11
11
|
import "../../../chunks/chunk-VE2HDCNB.js";
|
|
12
12
|
import "../../../chunks/chunk-5DA2D3K2.js";
|
|
13
13
|
import "../../../chunks/chunk-TG2EQLX2.js";
|
|
@@ -1633,10 +1633,17 @@ ${sections.join("\n\n")}` : "";
|
|
|
1633
1633
|
}
|
|
1634
1634
|
async function createCompactionSummary(messages, options = {}) {
|
|
1635
1635
|
const { model, apiKey, systemPrompt, compactPrompt, signal } = options;
|
|
1636
|
+
const throwIfAborted = () => {
|
|
1637
|
+
if (signal?.aborted) {
|
|
1638
|
+
throw new Error("Compaction aborted");
|
|
1639
|
+
}
|
|
1640
|
+
};
|
|
1636
1641
|
if (!model) {
|
|
1642
|
+
throwIfAborted();
|
|
1637
1643
|
return appendFileOperationsToSummary(createSimpleSummary(messages), messages);
|
|
1638
1644
|
}
|
|
1639
1645
|
try {
|
|
1646
|
+
throwIfAborted();
|
|
1640
1647
|
const response = await streamSimple(
|
|
1641
1648
|
model,
|
|
1642
1649
|
{
|
|
@@ -1655,8 +1662,10 @@ async function createCompactionSummary(messages, options = {}) {
|
|
|
1655
1662
|
signal
|
|
1656
1663
|
}
|
|
1657
1664
|
).result();
|
|
1665
|
+
throwIfAborted();
|
|
1658
1666
|
return appendFileOperationsToSummary(getAssistantText(response) || createSimpleSummary(messages), messages);
|
|
1659
1667
|
} catch (error) {
|
|
1668
|
+
throwIfAborted();
|
|
1660
1669
|
console.warn("[Compaction] Failed to create Codex-style summary:", error);
|
|
1661
1670
|
return appendFileOperationsToSummary(createSimpleSummary(messages), messages);
|
|
1662
1671
|
}
|
|
@@ -2970,6 +2979,7 @@ var AgentSessionAutoCompactScheduler = class {
|
|
|
2970
2979
|
autoCompactTimer;
|
|
2971
2980
|
pendingAutoCompact;
|
|
2972
2981
|
runningAutoCompact;
|
|
2982
|
+
runningAbortController;
|
|
2973
2983
|
pendingWait;
|
|
2974
2984
|
resolvePendingWait;
|
|
2975
2985
|
get hasPendingAutoCompact() {
|
|
@@ -3001,11 +3011,17 @@ var AgentSessionAutoCompactScheduler = class {
|
|
|
3001
3011
|
this.schedule(pending, 100);
|
|
3002
3012
|
return;
|
|
3003
3013
|
}
|
|
3004
|
-
|
|
3014
|
+
const abortController = new AbortController();
|
|
3015
|
+
this.runningAbortController = abortController;
|
|
3016
|
+
const running = this.options.runAutoCompact(pending, abortController.signal).catch(() => {
|
|
3005
3017
|
}).finally(() => {
|
|
3006
|
-
this.runningAutoCompact
|
|
3007
|
-
|
|
3018
|
+
if (this.runningAutoCompact === running) {
|
|
3019
|
+
this.runningAutoCompact = void 0;
|
|
3020
|
+
this.runningAbortController = void 0;
|
|
3021
|
+
this.resolvePending();
|
|
3022
|
+
}
|
|
3008
3023
|
});
|
|
3024
|
+
this.runningAutoCompact = running;
|
|
3009
3025
|
}, delayMs);
|
|
3010
3026
|
}
|
|
3011
3027
|
cancel() {
|
|
@@ -3015,6 +3031,9 @@ var AgentSessionAutoCompactScheduler = class {
|
|
|
3015
3031
|
this.autoCompactTimer = void 0;
|
|
3016
3032
|
}
|
|
3017
3033
|
this.pendingAutoCompact = void 0;
|
|
3034
|
+
this.runningAbortController?.abort();
|
|
3035
|
+
this.runningAbortController = void 0;
|
|
3036
|
+
this.runningAutoCompact = void 0;
|
|
3018
3037
|
this.resolvePending();
|
|
3019
3038
|
}
|
|
3020
3039
|
ensurePendingWait() {
|
|
@@ -3143,8 +3162,15 @@ async function runAgentSessionCompaction(params) {
|
|
|
3143
3162
|
if (!params.compaction) {
|
|
3144
3163
|
throw new Error("No compaction handler configured");
|
|
3145
3164
|
}
|
|
3165
|
+
const abortedResult = () => ({ aborted: true });
|
|
3166
|
+
const isAborted = () => params.signal?.aborted === true;
|
|
3146
3167
|
params.emit({ type: "auto_compaction_start", reason: params.reason, willRetry: params.willRetry });
|
|
3147
3168
|
try {
|
|
3169
|
+
if (isAborted()) {
|
|
3170
|
+
const result2 = abortedResult();
|
|
3171
|
+
params.emit({ type: "auto_compaction_end", reason: params.reason, willRetry: params.willRetry, result: result2 });
|
|
3172
|
+
return result2;
|
|
3173
|
+
}
|
|
3148
3174
|
if (params.willRetry) {
|
|
3149
3175
|
params.removeTrailingAssistantError();
|
|
3150
3176
|
}
|
|
@@ -3154,22 +3180,43 @@ async function runAgentSessionCompaction(params) {
|
|
|
3154
3180
|
agent: params.agent,
|
|
3155
3181
|
sessionManager: params.sessionManager,
|
|
3156
3182
|
messages: params.agent.state.messages.slice(),
|
|
3157
|
-
cwd: params.cwd
|
|
3183
|
+
cwd: params.cwd,
|
|
3184
|
+
signal: params.signal
|
|
3158
3185
|
});
|
|
3186
|
+
if (isAborted() || result?.aborted) {
|
|
3187
|
+
const aborted = { ...result, aborted: true };
|
|
3188
|
+
params.emit({ type: "auto_compaction_end", reason: params.reason, willRetry: params.willRetry, result: aborted });
|
|
3189
|
+
return aborted;
|
|
3190
|
+
}
|
|
3159
3191
|
if (result?.summary && result.firstKeptEntryId) {
|
|
3160
3192
|
params.sessionManager.appendCompaction(result.summary, result.firstKeptEntryId, result.tokensBefore);
|
|
3161
3193
|
params.replaceMessagesAndMarkSynced(params.sessionManager.getMessages());
|
|
3162
3194
|
} else if (result?.messages) {
|
|
3163
3195
|
params.replaceMessagesAndMarkSynced(result.messages, { updateSession: true });
|
|
3164
3196
|
}
|
|
3197
|
+
if (isAborted()) {
|
|
3198
|
+
const aborted = { ...result, aborted: true };
|
|
3199
|
+
params.emit({ type: "auto_compaction_end", reason: params.reason, willRetry: params.willRetry, result: aborted });
|
|
3200
|
+
return aborted;
|
|
3201
|
+
}
|
|
3165
3202
|
params.markSyncedToAgentState();
|
|
3166
3203
|
await params.sessionManager.save();
|
|
3204
|
+
if (isAborted()) {
|
|
3205
|
+
const aborted = { ...result, aborted: true };
|
|
3206
|
+
params.emit({ type: "auto_compaction_end", reason: params.reason, willRetry: params.willRetry, result: aborted });
|
|
3207
|
+
return aborted;
|
|
3208
|
+
}
|
|
3167
3209
|
if (params.willRetry && !result?.aborted) {
|
|
3168
3210
|
await params.continueTurn();
|
|
3169
3211
|
}
|
|
3170
3212
|
params.emit({ type: "auto_compaction_end", reason: params.reason, willRetry: params.willRetry, result });
|
|
3171
3213
|
return result;
|
|
3172
3214
|
} catch (error) {
|
|
3215
|
+
if (isAborted()) {
|
|
3216
|
+
const result = abortedResult();
|
|
3217
|
+
params.emit({ type: "auto_compaction_end", reason: params.reason, willRetry: params.willRetry, result });
|
|
3218
|
+
return result;
|
|
3219
|
+
}
|
|
3173
3220
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
3174
3221
|
params.emit({ type: "auto_compaction_end", reason: params.reason, willRetry: params.willRetry, errorMessage });
|
|
3175
3222
|
throw error;
|
|
@@ -3685,6 +3732,9 @@ var AgentSessionRetryController = class {
|
|
|
3685
3732
|
// ../../packages/agent-framework/src/session/controller/runtime-guard.ts
|
|
3686
3733
|
var RUNAWAY_TOOLCALL_WHITESPACE_DELTA_CHARS = 16384;
|
|
3687
3734
|
var RUNAWAY_TOOLCALL_WHITESPACE_DELTA_EVENTS = 40;
|
|
3735
|
+
var TOOL_FAILURE_SIGNATURE_CHARS = 1e3;
|
|
3736
|
+
var TOOL_FAILURE_SIGNATURE_CONTEXT_LINES = 5;
|
|
3737
|
+
var FAILURE_DIAGNOSTIC_LINE_PATTERN = /\b(E2E_FAILED|AssertionError|TimeoutError|SyntaxError|ReferenceError|TypeError|Error):|(^|\b)(failed|failure|timed out|timeout|exit code|command failed|npm ERR!)/i;
|
|
3688
3738
|
function stableStringify(value) {
|
|
3689
3739
|
if (value === null || typeof value !== "object") {
|
|
3690
3740
|
return JSON.stringify(value) ?? String(value);
|
|
@@ -3703,6 +3753,20 @@ function summarizeToolResultForGuard(result) {
|
|
|
3703
3753
|
const text = content.filter((block) => !!block && typeof block === "object" && "type" in block).filter((block) => block.type === "text").map((block) => block.text || "").join("\n").trim();
|
|
3704
3754
|
return text || stableStringify(result);
|
|
3705
3755
|
}
|
|
3756
|
+
function summarizeToolFailureSignature(result) {
|
|
3757
|
+
const summary = summarizeToolResultForGuard(result).replace(/\r\n/g, "\n").replace(/\r/g, "\n").trim();
|
|
3758
|
+
if (!summary) {
|
|
3759
|
+
return "";
|
|
3760
|
+
}
|
|
3761
|
+
const lines = summary.split("\n");
|
|
3762
|
+
for (let index = lines.length - 1; index >= 0; index--) {
|
|
3763
|
+
if (!FAILURE_DIAGNOSTIC_LINE_PATTERN.test(lines[index] ?? "")) {
|
|
3764
|
+
continue;
|
|
3765
|
+
}
|
|
3766
|
+
return lines.slice(index, Math.min(lines.length, index + TOOL_FAILURE_SIGNATURE_CONTEXT_LINES)).join("\n").slice(0, TOOL_FAILURE_SIGNATURE_CHARS);
|
|
3767
|
+
}
|
|
3768
|
+
return summary.slice(-TOOL_FAILURE_SIGNATURE_CHARS);
|
|
3769
|
+
}
|
|
3706
3770
|
var AgentSessionRuntimeGuard = class {
|
|
3707
3771
|
constructor(trigger) {
|
|
3708
3772
|
this.trigger = trigger;
|
|
@@ -3767,7 +3831,7 @@ var AgentSessionRuntimeGuard = class {
|
|
|
3767
3831
|
}
|
|
3768
3832
|
return;
|
|
3769
3833
|
}
|
|
3770
|
-
const resultSummary =
|
|
3834
|
+
const resultSummary = summarizeToolFailureSignature(event.result);
|
|
3771
3835
|
const key = `${event.toolName}:${stableStringify(event.args)}:${resultSummary}`;
|
|
3772
3836
|
const repeatCount = (this.repeatedToolFailures.get(key) ?? 0) + 1;
|
|
3773
3837
|
this.repeatedToolFailures.set(key, repeatCount);
|
|
@@ -4009,6 +4073,7 @@ async function runAgentSessionControllerAutoCompact(params) {
|
|
|
4009
4073
|
const result = await runAgentSessionCompaction({
|
|
4010
4074
|
reason: params.reason,
|
|
4011
4075
|
willRetry: params.willRetry,
|
|
4076
|
+
signal: params.signal,
|
|
4012
4077
|
compaction: params.compaction,
|
|
4013
4078
|
agent: params.agent,
|
|
4014
4079
|
sessionManager: params.sessionManager,
|
|
@@ -4020,14 +4085,15 @@ async function runAgentSessionControllerAutoCompact(params) {
|
|
|
4020
4085
|
continueTurn: params.continueTurn
|
|
4021
4086
|
});
|
|
4022
4087
|
if (!params.willRetry || result?.aborted) {
|
|
4088
|
+
const alreadyCancelled = params.getRecoveryState?.() === "cancelled" || params.getDisposed?.() === true;
|
|
4023
4089
|
params.setRecoveryState(result?.aborted && cancelOnAbort ? "cancelled" : "none");
|
|
4024
4090
|
if (result?.aborted) {
|
|
4025
4091
|
params.cancelRetry();
|
|
4026
|
-
if (cancelOnAbort) {
|
|
4092
|
+
if (cancelOnAbort && !alreadyCancelled) {
|
|
4027
4093
|
params.emit({ type: "turn_cancelled", reason: "compaction_aborted" });
|
|
4028
4094
|
}
|
|
4029
4095
|
}
|
|
4030
|
-
if (emitSettled) {
|
|
4096
|
+
if (emitSettled && !alreadyCancelled) {
|
|
4031
4097
|
params.emit({ type: "turn_settled" });
|
|
4032
4098
|
}
|
|
4033
4099
|
if (!result?.aborted && runAfterAgentEndHook) {
|
|
@@ -4125,8 +4191,8 @@ var AgentSessionController = class {
|
|
|
4125
4191
|
getDisposed: () => this.disposed,
|
|
4126
4192
|
getRuntimeGuardTriggered: () => this.runtimeGuard.triggered,
|
|
4127
4193
|
isStreaming: () => this.isStreaming,
|
|
4128
|
-
runAutoCompact: async (decision) => {
|
|
4129
|
-
await this.runAutoCompact(decision.reason, decision.willRetry);
|
|
4194
|
+
runAutoCompact: async (decision, signal) => {
|
|
4195
|
+
await this.runAutoCompact(decision.reason, decision.willRetry, { signal });
|
|
4130
4196
|
}
|
|
4131
4197
|
});
|
|
4132
4198
|
this.autoContinue = new AgentSessionAutoContinueController({
|
|
@@ -4309,6 +4375,7 @@ var AgentSessionController = class {
|
|
|
4309
4375
|
return runAgentSessionControllerAutoCompact({
|
|
4310
4376
|
reason,
|
|
4311
4377
|
willRetry,
|
|
4378
|
+
signal: options?.signal,
|
|
4312
4379
|
compaction: this.compaction,
|
|
4313
4380
|
agent: this.agent,
|
|
4314
4381
|
sessionManager: this.sessionManager,
|
|
@@ -4318,6 +4385,8 @@ var AgentSessionController = class {
|
|
|
4318
4385
|
setRecoveryState: (state) => {
|
|
4319
4386
|
this.recoveryState = state;
|
|
4320
4387
|
},
|
|
4388
|
+
getRecoveryState: () => this.recoveryState,
|
|
4389
|
+
getDisposed: () => this.disposed,
|
|
4321
4390
|
cancelRetry: () => this.retryController.cancel(),
|
|
4322
4391
|
clearPendingFailure: () => {
|
|
4323
4392
|
this.pendingCompactionFailure = void 0;
|
|
@@ -5738,7 +5807,49 @@ function restoreLineEndings(text, ending) {
|
|
|
5738
5807
|
return ending === "\r\n" ? text.replace(/\n/g, "\r\n") : text;
|
|
5739
5808
|
}
|
|
5740
5809
|
function normalizeForFuzzyMatch(text) {
|
|
5741
|
-
return text
|
|
5810
|
+
return buildFuzzyIndexMap(text).normalized;
|
|
5811
|
+
}
|
|
5812
|
+
function normalizeCharForFuzzyMatch(char) {
|
|
5813
|
+
if (/[\u2018\u2019\u201A\u201B]/.test(char)) return "'";
|
|
5814
|
+
if (/[\u201C\u201D\u201E\u201F]/.test(char)) return '"';
|
|
5815
|
+
if (/[\u2010\u2011\u2012\u2013\u2014\u2015\u2212]/.test(char)) return "-";
|
|
5816
|
+
if (/[\u00A0\u2002-\u200A\u202F\u205F\u3000]/.test(char)) return " ";
|
|
5817
|
+
return char;
|
|
5818
|
+
}
|
|
5819
|
+
function buildFuzzyIndexMap(text) {
|
|
5820
|
+
const lines = text.split("\n");
|
|
5821
|
+
let normalized = "";
|
|
5822
|
+
const originalStartByNormalizedIndex = [];
|
|
5823
|
+
const originalEndByNormalizedIndex = [];
|
|
5824
|
+
let originalLineStart = 0;
|
|
5825
|
+
for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
|
|
5826
|
+
const line = lines[lineIndex] ?? "";
|
|
5827
|
+
const trimmedLine = line.trimEnd();
|
|
5828
|
+
for (let index = 0; index < trimmedLine.length; index++) {
|
|
5829
|
+
normalized += normalizeCharForFuzzyMatch(trimmedLine[index]);
|
|
5830
|
+
originalStartByNormalizedIndex.push(originalLineStart + index);
|
|
5831
|
+
originalEndByNormalizedIndex.push(originalLineStart + index + 1);
|
|
5832
|
+
}
|
|
5833
|
+
if (lineIndex < lines.length - 1) {
|
|
5834
|
+
normalized += "\n";
|
|
5835
|
+
originalStartByNormalizedIndex.push(originalLineStart + line.length);
|
|
5836
|
+
originalEndByNormalizedIndex.push(originalLineStart + line.length + 1);
|
|
5837
|
+
}
|
|
5838
|
+
originalLineStart += line.length + (lineIndex < lines.length - 1 ? 1 : 0);
|
|
5839
|
+
}
|
|
5840
|
+
return { normalized, originalStartByNormalizedIndex, originalEndByNormalizedIndex };
|
|
5841
|
+
}
|
|
5842
|
+
function countOccurrences(content, needle) {
|
|
5843
|
+
if (needle.length === 0) return 0;
|
|
5844
|
+
let count = 0;
|
|
5845
|
+
let index = 0;
|
|
5846
|
+
while (true) {
|
|
5847
|
+
const nextIndex = content.indexOf(needle, index);
|
|
5848
|
+
if (nextIndex === -1) break;
|
|
5849
|
+
count++;
|
|
5850
|
+
index = nextIndex + needle.length;
|
|
5851
|
+
}
|
|
5852
|
+
return count;
|
|
5742
5853
|
}
|
|
5743
5854
|
function fuzzyFindText(content, oldText) {
|
|
5744
5855
|
const exactIndex = content.indexOf(oldText);
|
|
@@ -5748,11 +5859,25 @@ function fuzzyFindText(content, oldText) {
|
|
|
5748
5859
|
index: exactIndex,
|
|
5749
5860
|
matchLength: oldText.length,
|
|
5750
5861
|
usedFuzzyMatch: false,
|
|
5751
|
-
contentForReplacement: content
|
|
5862
|
+
contentForReplacement: content,
|
|
5863
|
+
occurrences: countOccurrences(content, oldText),
|
|
5864
|
+
matchKind: "exact"
|
|
5752
5865
|
};
|
|
5753
5866
|
}
|
|
5754
|
-
const
|
|
5867
|
+
const fuzzyMap = buildFuzzyIndexMap(content);
|
|
5868
|
+
const fuzzyContent = fuzzyMap.normalized;
|
|
5755
5869
|
const fuzzyOldText = normalizeForFuzzyMatch(oldText);
|
|
5870
|
+
if (fuzzyOldText.length === 0) {
|
|
5871
|
+
return {
|
|
5872
|
+
found: false,
|
|
5873
|
+
index: -1,
|
|
5874
|
+
matchLength: 0,
|
|
5875
|
+
usedFuzzyMatch: false,
|
|
5876
|
+
contentForReplacement: content,
|
|
5877
|
+
occurrences: 0,
|
|
5878
|
+
matchKind: "none"
|
|
5879
|
+
};
|
|
5880
|
+
}
|
|
5756
5881
|
const fuzzyIndex = fuzzyContent.indexOf(fuzzyOldText);
|
|
5757
5882
|
if (fuzzyIndex === -1) {
|
|
5758
5883
|
return {
|
|
@@ -5760,35 +5885,65 @@ function fuzzyFindText(content, oldText) {
|
|
|
5760
5885
|
index: -1,
|
|
5761
5886
|
matchLength: 0,
|
|
5762
5887
|
usedFuzzyMatch: false,
|
|
5763
|
-
contentForReplacement: content
|
|
5888
|
+
contentForReplacement: content,
|
|
5889
|
+
occurrences: 0,
|
|
5890
|
+
matchKind: "none"
|
|
5764
5891
|
};
|
|
5765
5892
|
}
|
|
5893
|
+
const endFuzzyIndex = fuzzyIndex + fuzzyOldText.length - 1;
|
|
5894
|
+
const originalStart = fuzzyMap.originalStartByNormalizedIndex[fuzzyIndex];
|
|
5895
|
+
const originalEnd = fuzzyMap.originalEndByNormalizedIndex[endFuzzyIndex];
|
|
5766
5896
|
return {
|
|
5767
5897
|
found: true,
|
|
5768
|
-
index:
|
|
5769
|
-
matchLength:
|
|
5898
|
+
index: originalStart,
|
|
5899
|
+
matchLength: originalEnd - originalStart,
|
|
5770
5900
|
usedFuzzyMatch: true,
|
|
5771
|
-
contentForReplacement:
|
|
5901
|
+
contentForReplacement: content,
|
|
5902
|
+
occurrences: countOccurrences(fuzzyContent, fuzzyOldText),
|
|
5903
|
+
matchKind: "fuzzy"
|
|
5772
5904
|
};
|
|
5773
5905
|
}
|
|
5774
5906
|
function stripBom(content) {
|
|
5775
5907
|
return content.startsWith("\uFEFF") ? { bom: "\uFEFF", text: content.slice(1) } : { bom: "", text: content };
|
|
5776
5908
|
}
|
|
5777
|
-
function generateDiffString(oldContent, newContent,
|
|
5778
|
-
const oldLines = oldContent.split("\n");
|
|
5779
|
-
const newLines = newContent.split("\n");
|
|
5780
|
-
let
|
|
5781
|
-
|
|
5782
|
-
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
}
|
|
5786
|
-
}
|
|
5787
|
-
|
|
5788
|
-
|
|
5789
|
-
|
|
5790
|
-
|
|
5791
|
-
|
|
5909
|
+
function generateDiffString(oldContent, newContent, contextLines = 4) {
|
|
5910
|
+
const oldLines = normalizeToLF(stripBom(oldContent).text).split("\n");
|
|
5911
|
+
const newLines = normalizeToLF(stripBom(newContent).text).split("\n");
|
|
5912
|
+
let prefixLength = 0;
|
|
5913
|
+
while (prefixLength < oldLines.length && prefixLength < newLines.length && oldLines[prefixLength] === newLines[prefixLength]) {
|
|
5914
|
+
prefixLength++;
|
|
5915
|
+
}
|
|
5916
|
+
if (prefixLength === oldLines.length && prefixLength === newLines.length) {
|
|
5917
|
+
return { diff: "--- old\n+++ new\n", firstChangedLine: void 0 };
|
|
5918
|
+
}
|
|
5919
|
+
let oldSuffixIndex = oldLines.length - 1;
|
|
5920
|
+
let newSuffixIndex = newLines.length - 1;
|
|
5921
|
+
while (oldSuffixIndex >= prefixLength && newSuffixIndex >= prefixLength && oldLines[oldSuffixIndex] === newLines[newSuffixIndex]) {
|
|
5922
|
+
oldSuffixIndex--;
|
|
5923
|
+
newSuffixIndex--;
|
|
5924
|
+
}
|
|
5925
|
+
const beforeContext = Math.min(contextLines, prefixLength);
|
|
5926
|
+
const removedCount = Math.max(0, oldSuffixIndex - prefixLength + 1);
|
|
5927
|
+
const addedCount = Math.max(0, newSuffixIndex - prefixLength + 1);
|
|
5928
|
+
const afterContext = Math.min(contextLines, oldLines.length - oldSuffixIndex - 1, newLines.length - newSuffixIndex - 1);
|
|
5929
|
+
const hunkOldStart = Math.max(0, prefixLength - beforeContext);
|
|
5930
|
+
const hunkNewStart = Math.max(0, prefixLength - beforeContext);
|
|
5931
|
+
const hunkOldCount = beforeContext + removedCount + afterContext;
|
|
5932
|
+
const hunkNewCount = beforeContext + addedCount + afterContext;
|
|
5933
|
+
const lines = ["--- old", "+++ new", `@@ -${hunkOldStart + 1},${hunkOldCount} +${hunkNewStart + 1},${hunkNewCount} @@`];
|
|
5934
|
+
for (let index = prefixLength - beforeContext; index < prefixLength; index++) {
|
|
5935
|
+
lines.push(` ${oldLines[index] ?? ""}`);
|
|
5936
|
+
}
|
|
5937
|
+
for (let index = prefixLength; index <= oldSuffixIndex; index++) {
|
|
5938
|
+
lines.push(`-${oldLines[index] ?? ""}`);
|
|
5939
|
+
}
|
|
5940
|
+
for (let index = prefixLength; index <= newSuffixIndex; index++) {
|
|
5941
|
+
lines.push(`+${newLines[index] ?? ""}`);
|
|
5942
|
+
}
|
|
5943
|
+
for (let offset = 1; offset <= afterContext; offset++) {
|
|
5944
|
+
lines.push(` ${oldLines[oldSuffixIndex + offset] ?? ""}`);
|
|
5945
|
+
}
|
|
5946
|
+
return { diff: lines.join("\n"), firstChangedLine: prefixLength + 1 };
|
|
5792
5947
|
}
|
|
5793
5948
|
|
|
5794
5949
|
// ../../packages/shared-headless-capabilities/src/builtin/fs/edit.ts
|
|
@@ -5810,7 +5965,7 @@ function validateEditArgs(path3, oldText, newText) {
|
|
|
5810
5965
|
throw new Error("Invalid edit_file arguments: path, oldText, and newText must be real edit values, not tool-call markup.");
|
|
5811
5966
|
}
|
|
5812
5967
|
}
|
|
5813
|
-
function
|
|
5968
|
+
function countOccurrences2(content, needle) {
|
|
5814
5969
|
if (needle.length === 0) return 0;
|
|
5815
5970
|
let count = 0;
|
|
5816
5971
|
let index = 0;
|
|
@@ -5822,6 +5977,29 @@ function countOccurrences(content, needle) {
|
|
|
5822
5977
|
}
|
|
5823
5978
|
return count;
|
|
5824
5979
|
}
|
|
5980
|
+
function createEditErrorResult(params) {
|
|
5981
|
+
const detailLines = [
|
|
5982
|
+
params.message,
|
|
5983
|
+
params.recoveryHint,
|
|
5984
|
+
params.alreadyAppliedCandidate ? "Diagnostic: newText already appears in the current file, but edit_file did not treat that as success because it may be an unrelated occurrence." : ""
|
|
5985
|
+
].filter(Boolean);
|
|
5986
|
+
return {
|
|
5987
|
+
content: [{ type: "text", text: detailLines.join("\n") }],
|
|
5988
|
+
details: {
|
|
5989
|
+
status: "error",
|
|
5990
|
+
matchKind: params.matchKind,
|
|
5991
|
+
changed: false,
|
|
5992
|
+
diff: "",
|
|
5993
|
+
oldTextOccurrences: params.oldTextOccurrences,
|
|
5994
|
+
newTextOccurrences: params.newTextOccurrences,
|
|
5995
|
+
errorReason: params.errorReason,
|
|
5996
|
+
recoveryHint: params.recoveryHint,
|
|
5997
|
+
staleBaseLikely: params.staleBaseLikely,
|
|
5998
|
+
alreadyAppliedCandidate: params.alreadyAppliedCandidate
|
|
5999
|
+
},
|
|
6000
|
+
isError: true
|
|
6001
|
+
};
|
|
6002
|
+
}
|
|
5825
6003
|
function createEditTool(cwd, options) {
|
|
5826
6004
|
const fs2 = getFileSystem();
|
|
5827
6005
|
const rootSchema = buildRootParameterSchema(cwd, options);
|
|
@@ -5871,37 +6049,53 @@ function createEditTool(cwd, options) {
|
|
|
5871
6049
|
const normalizedContent = normalizeToLF(content);
|
|
5872
6050
|
const normalizedOldText = normalizeToLF(oldText);
|
|
5873
6051
|
const normalizedNewText = normalizeToLF(newText);
|
|
6052
|
+
const newTextOccurrences = countOccurrences2(normalizedContent, normalizedNewText);
|
|
5874
6053
|
const matchResult = fuzzyFindText(normalizedContent, normalizedOldText);
|
|
5875
6054
|
if (!matchResult.found) {
|
|
5876
6055
|
if (signal) signal.removeEventListener("abort", onAbort);
|
|
5877
|
-
|
|
5878
|
-
|
|
5879
|
-
`Could not find
|
|
5880
|
-
|
|
6056
|
+
resolve2(
|
|
6057
|
+
createEditErrorResult({
|
|
6058
|
+
message: `Could not find oldText in ${path3}.`,
|
|
6059
|
+
matchKind: "none",
|
|
6060
|
+
errorReason: "old_text_not_found",
|
|
6061
|
+
oldTextOccurrences: 0,
|
|
6062
|
+
newTextOccurrences,
|
|
6063
|
+
staleBaseLikely: newTextOccurrences > 0,
|
|
6064
|
+
alreadyAppliedCandidate: newTextOccurrences > 0,
|
|
6065
|
+
recoveryHint: newTextOccurrences > 0 ? "The replacement text already appears in the current file. Read the current file before retrying; this may be a stale oldText from an earlier edit in the same turn." : "Read the current file and retry with a larger exact block copied from the latest file contents."
|
|
6066
|
+
})
|
|
5881
6067
|
);
|
|
5882
6068
|
return;
|
|
5883
6069
|
}
|
|
5884
|
-
|
|
5885
|
-
const fuzzyOldText = normalizeForFuzzyMatch(normalizedOldText);
|
|
5886
|
-
const occurrences = countOccurrences(fuzzyContent, fuzzyOldText);
|
|
5887
|
-
if (occurrences > 1) {
|
|
6070
|
+
if (matchResult.occurrences > 1) {
|
|
5888
6071
|
if (signal) signal.removeEventListener("abort", onAbort);
|
|
5889
|
-
|
|
5890
|
-
|
|
5891
|
-
`Found ${occurrences} occurrences of
|
|
5892
|
-
|
|
6072
|
+
resolve2(
|
|
6073
|
+
createEditErrorResult({
|
|
6074
|
+
message: `Found ${matchResult.occurrences} occurrences of oldText in ${path3}. The text must be unique.`,
|
|
6075
|
+
matchKind: matchResult.matchKind,
|
|
6076
|
+
errorReason: "old_text_not_unique",
|
|
6077
|
+
oldTextOccurrences: matchResult.occurrences,
|
|
6078
|
+
newTextOccurrences,
|
|
6079
|
+
recoveryHint: "Read the current file and retry with a larger exact block that uniquely identifies the intended location."
|
|
6080
|
+
})
|
|
5893
6081
|
);
|
|
5894
6082
|
return;
|
|
5895
6083
|
}
|
|
5896
6084
|
if (aborted) return;
|
|
5897
|
-
const baseContent =
|
|
6085
|
+
const baseContent = normalizedContent;
|
|
5898
6086
|
const newContent = baseContent.substring(0, matchResult.index) + normalizedNewText + baseContent.substring(matchResult.index + matchResult.matchLength);
|
|
5899
6087
|
if (baseContent === newContent) {
|
|
5900
6088
|
if (signal) signal.removeEventListener("abort", onAbort);
|
|
5901
|
-
|
|
5902
|
-
|
|
5903
|
-
`No changes made to ${path3}. The replacement produced identical content
|
|
5904
|
-
|
|
6089
|
+
resolve2(
|
|
6090
|
+
createEditErrorResult({
|
|
6091
|
+
message: `No changes made to ${path3}. The replacement produced identical content.`,
|
|
6092
|
+
matchKind: matchResult.matchKind,
|
|
6093
|
+
errorReason: "replacement_no_change",
|
|
6094
|
+
oldTextOccurrences: matchResult.occurrences,
|
|
6095
|
+
newTextOccurrences,
|
|
6096
|
+
recoveryHint: "Read the current file and verify whether the intended edit is already present or whether oldText/newText need a larger exact block.",
|
|
6097
|
+
alreadyAppliedCandidate: newTextOccurrences > 0
|
|
6098
|
+
})
|
|
5905
6099
|
);
|
|
5906
6100
|
return;
|
|
5907
6101
|
}
|
|
@@ -5911,16 +6105,24 @@ function createEditTool(cwd, options) {
|
|
|
5911
6105
|
if (signal) {
|
|
5912
6106
|
signal.removeEventListener("abort", onAbort);
|
|
5913
6107
|
}
|
|
5914
|
-
const diffResult = generateDiffString(content,
|
|
6108
|
+
const diffResult = generateDiffString(content, restoreLineEndings(newContent, originalEnding));
|
|
5915
6109
|
resolve2({
|
|
5916
6110
|
content: [
|
|
5917
6111
|
{
|
|
5918
6112
|
type: "text",
|
|
5919
|
-
text: `Successfully replaced text in ${path3}.`
|
|
6113
|
+
text: `Successfully replaced text in ${path3} using ${matchResult.matchKind} match.`
|
|
5920
6114
|
},
|
|
5921
6115
|
{ type: "text", text: diffResult.diff }
|
|
5922
6116
|
],
|
|
5923
|
-
details: {
|
|
6117
|
+
details: {
|
|
6118
|
+
status: "success",
|
|
6119
|
+
matchKind: matchResult.matchKind,
|
|
6120
|
+
changed: true,
|
|
6121
|
+
diff: diffResult.diff,
|
|
6122
|
+
firstChangedLine: diffResult.firstChangedLine,
|
|
6123
|
+
oldTextOccurrences: matchResult.occurrences,
|
|
6124
|
+
newTextOccurrences
|
|
6125
|
+
}
|
|
5924
6126
|
});
|
|
5925
6127
|
} catch (error) {
|
|
5926
6128
|
if (signal) {
|
|
@@ -6974,6 +7176,81 @@ function createEmptyRuntimeSummary() {
|
|
|
6974
7176
|
toolErrors: 0
|
|
6975
7177
|
};
|
|
6976
7178
|
}
|
|
7179
|
+
function summarizeString(value, maxLength = 300) {
|
|
7180
|
+
return value.length > maxLength ? `${value.slice(0, maxLength)}...` : value;
|
|
7181
|
+
}
|
|
7182
|
+
function summarizeMessage(message) {
|
|
7183
|
+
if (!isRecord(message)) return typeof message;
|
|
7184
|
+
if ("contentBlocks" in message && !("content" in message)) return message;
|
|
7185
|
+
const content = Array.isArray(message.content) ? message.content : [];
|
|
7186
|
+
const blockTypes = content.filter(isRecord).map((block) => String(block.type || "unknown")).slice(0, 10);
|
|
7187
|
+
const text = getTextFromMessageContent(content);
|
|
7188
|
+
return {
|
|
7189
|
+
role: message.role,
|
|
7190
|
+
stopReason: message.stopReason,
|
|
7191
|
+
errorMessage: typeof message.errorMessage === "string" ? summarizeString(message.errorMessage) : void 0,
|
|
7192
|
+
contentBlocks: content.length,
|
|
7193
|
+
blockTypes,
|
|
7194
|
+
textLength: text.length
|
|
7195
|
+
};
|
|
7196
|
+
}
|
|
7197
|
+
function summarizeToolResults(value) {
|
|
7198
|
+
if (isRecord(value) && typeof value.count === "number" && !Array.isArray(value)) return value;
|
|
7199
|
+
if (!Array.isArray(value)) return typeof value;
|
|
7200
|
+
let errors = 0;
|
|
7201
|
+
const toolNames = [];
|
|
7202
|
+
for (const result of value) {
|
|
7203
|
+
if (!isRecord(result)) continue;
|
|
7204
|
+
if (result.isError === true) errors++;
|
|
7205
|
+
const toolName = typeof result.toolName === "string" ? result.toolName : typeof result.name === "string" ? result.name : void 0;
|
|
7206
|
+
if (toolName && toolNames.length < 10) toolNames.push(toolName);
|
|
7207
|
+
}
|
|
7208
|
+
return { count: value.length, errors, toolNames };
|
|
7209
|
+
}
|
|
7210
|
+
function summarizeFailure(value) {
|
|
7211
|
+
if (!isRecord(value)) return typeof value;
|
|
7212
|
+
return {
|
|
7213
|
+
kind: value.kind,
|
|
7214
|
+
retryable: value.retryable,
|
|
7215
|
+
compactable: value.compactable,
|
|
7216
|
+
userAbort: value.userAbort,
|
|
7217
|
+
terminal: value.terminal,
|
|
7218
|
+
message: typeof value.message === "string" ? summarizeString(value.message) : void 0
|
|
7219
|
+
};
|
|
7220
|
+
}
|
|
7221
|
+
function summarizeRuntimeEvent(value) {
|
|
7222
|
+
if (!isRecord(value)) return typeof value;
|
|
7223
|
+
const summary = {
|
|
7224
|
+
type: value.type
|
|
7225
|
+
};
|
|
7226
|
+
if ("toolCallId" in value) summary.toolCallId = value.toolCallId;
|
|
7227
|
+
if ("toolName" in value) summary.toolName = value.toolName;
|
|
7228
|
+
if ("turnIndex" in value) summary.turnIndex = value.turnIndex;
|
|
7229
|
+
if ("isError" in value) summary.isError = value.isError;
|
|
7230
|
+
if ("errorMessage" in value && typeof value.errorMessage === "string") {
|
|
7231
|
+
summary.errorMessage = summarizeString(value.errorMessage);
|
|
7232
|
+
}
|
|
7233
|
+
if ("message" in value) summary.message = summarizeMessage(value.message);
|
|
7234
|
+
if ("toolResults" in value) summary.toolResults = summarizeToolResults(value.toolResults);
|
|
7235
|
+
return summary;
|
|
7236
|
+
}
|
|
7237
|
+
function shouldRecordRuntimeEvent(type) {
|
|
7238
|
+
const normalizedType = type.startsWith("runtime:") ? type.slice("runtime:".length) : type;
|
|
7239
|
+
return normalizedType !== "agent_event" && normalizedType !== "semantic_event";
|
|
7240
|
+
}
|
|
7241
|
+
function recomputeRuntimeSummaryFromTimeline(events) {
|
|
7242
|
+
const summary = createEmptyRuntimeSummary();
|
|
7243
|
+
for (const event of events ?? []) {
|
|
7244
|
+
if (/queue|queued_turn/.test(event.type)) summary.queuedTurnEvents++;
|
|
7245
|
+
if (/retry/.test(event.type)) summary.retryEvents++;
|
|
7246
|
+
if (/auto_compaction|auto_compact|compaction/.test(event.type)) summary.autoCompactionEvents++;
|
|
7247
|
+
if (/runtime_guard|repeated_tool_error/.test(event.type)) summary.runtimeGuardEvents++;
|
|
7248
|
+
if (/subagent/.test(event.type)) summary.subagentEvents++;
|
|
7249
|
+
if (event.type === "tool_end" || event.type === "tool_error") summary.toolResults++;
|
|
7250
|
+
if (event.type === "tool_error") summary.toolErrors++;
|
|
7251
|
+
}
|
|
7252
|
+
return summary;
|
|
7253
|
+
}
|
|
6977
7254
|
function summarizeMeta(meta) {
|
|
6978
7255
|
if (!isRecord(meta)) return meta;
|
|
6979
7256
|
const summary = {};
|
|
@@ -6982,6 +7259,22 @@ function summarizeMeta(meta) {
|
|
|
6982
7259
|
summary[key] = Array.isArray(value) ? { count: value.length } : typeof value;
|
|
6983
7260
|
continue;
|
|
6984
7261
|
}
|
|
7262
|
+
if (key === "message") {
|
|
7263
|
+
summary[key] = summarizeMessage(value);
|
|
7264
|
+
continue;
|
|
7265
|
+
}
|
|
7266
|
+
if (key === "toolResults") {
|
|
7267
|
+
summary[key] = summarizeToolResults(value);
|
|
7268
|
+
continue;
|
|
7269
|
+
}
|
|
7270
|
+
if (key === "failure") {
|
|
7271
|
+
summary[key] = summarizeFailure(value);
|
|
7272
|
+
continue;
|
|
7273
|
+
}
|
|
7274
|
+
if (key === "event") {
|
|
7275
|
+
summary[key] = summarizeRuntimeEvent(value);
|
|
7276
|
+
continue;
|
|
7277
|
+
}
|
|
6985
7278
|
if (key === "queuedInput" && isRecord(value)) {
|
|
6986
7279
|
summary[key] = {
|
|
6987
7280
|
mode: value.mode,
|
|
@@ -6991,7 +7284,7 @@ function summarizeMeta(meta) {
|
|
|
6991
7284
|
};
|
|
6992
7285
|
continue;
|
|
6993
7286
|
}
|
|
6994
|
-
summary[key] = typeof value === "string"
|
|
7287
|
+
summary[key] = typeof value === "string" ? summarizeString(value) : value;
|
|
6995
7288
|
}
|
|
6996
7289
|
return summary;
|
|
6997
7290
|
}
|
|
@@ -7105,9 +7398,7 @@ function timelineEventFromTraceEvent(type, meta) {
|
|
|
7105
7398
|
failure: typeof data.failureCategory === "string" && data.failureCategory.length > 0
|
|
7106
7399
|
};
|
|
7107
7400
|
}
|
|
7108
|
-
if (normalizedType === "subagent_summary")
|
|
7109
|
-
return { type: "subagent_child_end", summary: `subagent summary count=${String(data.count ?? "?")}`, details: detail };
|
|
7110
|
-
}
|
|
7401
|
+
if (normalizedType === "subagent_summary") return null;
|
|
7111
7402
|
return null;
|
|
7112
7403
|
}
|
|
7113
7404
|
function cloneTurn(turn) {
|
|
@@ -7148,6 +7439,9 @@ var SessionTraceController = class {
|
|
|
7148
7439
|
if (!Array.isArray(this.trace.recentTimeline)) {
|
|
7149
7440
|
this.trace.recentTimeline = [];
|
|
7150
7441
|
}
|
|
7442
|
+
this.trace.recentEvents = this.trace.recentEvents.slice(-this.recentEventsLimit);
|
|
7443
|
+
this.trace.recentTimeline = this.trace.recentTimeline.slice(-this.recentEventsLimit);
|
|
7444
|
+
this.trace.runtimeSummary = recomputeRuntimeSummaryFromTimeline(this.trace.recentTimeline);
|
|
7151
7445
|
}
|
|
7152
7446
|
trace;
|
|
7153
7447
|
recentTurnsLimit;
|
|
@@ -7162,7 +7456,6 @@ var SessionTraceController = class {
|
|
|
7162
7456
|
if (this.trace.recentEvents.length > this.recentEventsLimit) {
|
|
7163
7457
|
this.trace.recentEvents = this.trace.recentEvents.slice(-this.recentEventsLimit);
|
|
7164
7458
|
}
|
|
7165
|
-
this.updateRuntimeSummary(type, meta);
|
|
7166
7459
|
const timelineEvent = timelineEventFromTraceEvent(type, meta);
|
|
7167
7460
|
if (timelineEvent) {
|
|
7168
7461
|
this.pushTimeline(timelineEvent);
|
|
@@ -7177,17 +7470,7 @@ var SessionTraceController = class {
|
|
|
7177
7470
|
if (this.trace.recentTimeline.length > this.recentEventsLimit) {
|
|
7178
7471
|
this.trace.recentTimeline = this.trace.recentTimeline.slice(-this.recentEventsLimit);
|
|
7179
7472
|
}
|
|
7180
|
-
|
|
7181
|
-
updateRuntimeSummary(type, meta) {
|
|
7182
|
-
const summary = this.trace.runtimeSummary ?? createEmptyRuntimeSummary();
|
|
7183
|
-
if (/queue|queued_turn/.test(type)) summary.queuedTurnEvents++;
|
|
7184
|
-
if (/retry/.test(type)) summary.retryEvents++;
|
|
7185
|
-
if (/auto_compaction|auto_compact|compaction/.test(type)) summary.autoCompactionEvents++;
|
|
7186
|
-
if (/runtime_guard|repeated_tool_error/.test(type)) summary.runtimeGuardEvents++;
|
|
7187
|
-
if (/subagent/.test(type)) summary.subagentEvents++;
|
|
7188
|
-
if (type === "tool_end") summary.toolResults++;
|
|
7189
|
-
if (type === "tool_end" && isRecord(meta) && meta.isError) summary.toolErrors++;
|
|
7190
|
-
this.trace.runtimeSummary = summary;
|
|
7473
|
+
this.trace.runtimeSummary = recomputeRuntimeSummaryFromTimeline(this.trace.recentTimeline);
|
|
7191
7474
|
}
|
|
7192
7475
|
nextTurnIndex() {
|
|
7193
7476
|
if (this.trace.activeTurn) {
|
|
@@ -7259,6 +7542,7 @@ var SessionTraceController = class {
|
|
|
7259
7542
|
this.touch();
|
|
7260
7543
|
}
|
|
7261
7544
|
noteRuntimeEvent(type, meta) {
|
|
7545
|
+
if (!shouldRecordRuntimeEvent(type)) return;
|
|
7262
7546
|
this.pushEvent(`runtime:${type}`, summarizeMeta(meta));
|
|
7263
7547
|
this.touch();
|
|
7264
7548
|
}
|
|
@@ -7283,7 +7567,6 @@ var SessionTraceController = class {
|
|
|
7283
7567
|
if (!message || message.role !== "assistant" || !this.trace.activeTurn) return;
|
|
7284
7568
|
this.trace.activeTurn.state = this.trace.activeTurn.toolCalls.some((tool) => tool.status === "running") ? "tool_running" : "streaming";
|
|
7285
7569
|
this.trace.activeTurn.assistantText = getTextFromMessageContent(message.content);
|
|
7286
|
-
this.pushEvent("assistant_update");
|
|
7287
7570
|
this.touch();
|
|
7288
7571
|
}
|
|
7289
7572
|
startTool(toolCallId, toolName, args) {
|
package/dist/cli.js
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
getSettingsPath,
|
|
15
15
|
getThemesDir,
|
|
16
16
|
migrateConfigFromAgentDir
|
|
17
|
-
} from "./chunks/chunk-
|
|
17
|
+
} from "./chunks/chunk-4MIOCDBV.js";
|
|
18
18
|
import {
|
|
19
19
|
AGENTS_CONTEXT_FILE_NAME,
|
|
20
20
|
AgentSessionController,
|
|
@@ -55,7 +55,7 @@ import {
|
|
|
55
55
|
selectToolsForRuntimePolicy,
|
|
56
56
|
shouldPreserveExecutionStateForUserText,
|
|
57
57
|
supersedeExecutionState
|
|
58
|
-
} from "./chunks/chunk-
|
|
58
|
+
} from "./chunks/chunk-B4VUX6SD.js";
|
|
59
59
|
import "./chunks/chunk-VE2HDCNB.js";
|
|
60
60
|
import {
|
|
61
61
|
Deref,
|
|
@@ -59550,6 +59550,26 @@ ${theme.fg("muted", "Receiving edit parameters...")}`;
|
|
|
59550
59550
|
|
|
59551
59551
|
${theme.fg("error", errorText)}`;
|
|
59552
59552
|
}
|
|
59553
|
+
} else if (this.result?.details?.diff && rawPath) {
|
|
59554
|
+
const diff = this.result.details.diff;
|
|
59555
|
+
const firstChangedLine = this.result.details.firstChangedLine;
|
|
59556
|
+
if (firstChangedLine) {
|
|
59557
|
+
text = `${theme.fg("toolTitle", theme.bold("edit_file"))} ${theme.fg("accent", path27 || rawPath)}${theme.fg("warning", `:${firstChangedLine}`)}`;
|
|
59558
|
+
}
|
|
59559
|
+
const lines = diff.split("\n");
|
|
59560
|
+
const maxLines = this.expanded ? lines.length : 15;
|
|
59561
|
+
const displayLines = lines.slice(0, maxLines);
|
|
59562
|
+
const remaining = lines.length - maxLines;
|
|
59563
|
+
text += "\n\n" + displayLines.map((line) => {
|
|
59564
|
+
if (line.startsWith("+")) return theme.fg("success", line);
|
|
59565
|
+
if (line.startsWith("-")) return theme.fg("error", line);
|
|
59566
|
+
if (line.startsWith("@@")) return theme.fg("warning", line);
|
|
59567
|
+
return theme.fg("toolOutput", line);
|
|
59568
|
+
}).join("\n");
|
|
59569
|
+
if (remaining > 0) {
|
|
59570
|
+
text += theme.fg("muted", `
|
|
59571
|
+
... (${remaining} more lines, press Ctrl+O to expand)`);
|
|
59572
|
+
}
|
|
59553
59573
|
} else if (hasOldText && hasNewText && rawPath) {
|
|
59554
59574
|
const diff = generateEditDiff(oldText, newText, rawPath);
|
|
59555
59575
|
const firstChangedLine = findFirstChangedLine(oldText, newText);
|
|
@@ -64117,6 +64137,9 @@ function shouldCliAutoCompactTokens(params) {
|
|
|
64117
64137
|
return tokenLimit !== void 0 && params.tokens > tokenLimit;
|
|
64118
64138
|
}
|
|
64119
64139
|
async function createCliAutoCompactionResult(params) {
|
|
64140
|
+
if (params.context.signal?.aborted) {
|
|
64141
|
+
return { aborted: true };
|
|
64142
|
+
}
|
|
64120
64143
|
const activeEntryId = params.context.sessionManager.getActiveEntryId();
|
|
64121
64144
|
if (!activeEntryId) {
|
|
64122
64145
|
return { aborted: true };
|
|
@@ -64129,9 +64152,13 @@ async function createCliAutoCompactionResult(params) {
|
|
|
64129
64152
|
const compactOptions = {
|
|
64130
64153
|
model: params.model,
|
|
64131
64154
|
apiKey: params.apiKey,
|
|
64132
|
-
systemPrompt: params.systemPrompt
|
|
64155
|
+
systemPrompt: params.systemPrompt,
|
|
64156
|
+
signal: params.context.signal
|
|
64133
64157
|
};
|
|
64134
64158
|
const summary = await createCompactionSummary(params.context.messages, compactOptions);
|
|
64159
|
+
if (params.context.signal?.aborted) {
|
|
64160
|
+
return { aborted: true };
|
|
64161
|
+
}
|
|
64135
64162
|
return {
|
|
64136
64163
|
summary,
|
|
64137
64164
|
firstKeptEntryId,
|
|
@@ -68035,6 +68062,18 @@ async function runJsonEventsMode(params) {
|
|
|
68035
68062
|
break;
|
|
68036
68063
|
}
|
|
68037
68064
|
}
|
|
68065
|
+
function rememberTerminal(kind, detail, options) {
|
|
68066
|
+
if (!activeTurn || activeTurn.finalized) return;
|
|
68067
|
+
if (activeTurn.pendingTerminal && options?.overwrite === false) return;
|
|
68068
|
+
activeTurn.pendingTerminal = { kind, detail };
|
|
68069
|
+
touch();
|
|
68070
|
+
}
|
|
68071
|
+
function finalizePendingTerminal() {
|
|
68072
|
+
if (!activeTurn || activeTurn.finalized) return;
|
|
68073
|
+
const pending = activeTurn.pendingTerminal;
|
|
68074
|
+
if (!pending) return;
|
|
68075
|
+
finalize(pending.kind, pending.detail);
|
|
68076
|
+
}
|
|
68038
68077
|
function handleSemanticEvent(event) {
|
|
68039
68078
|
if (!activeTurn || activeTurn.finalized) return;
|
|
68040
68079
|
switch (event.type) {
|
|
@@ -68082,6 +68121,7 @@ async function runJsonEventsMode(params) {
|
|
|
68082
68121
|
function handleControllerEvent(event) {
|
|
68083
68122
|
trace?.noteRuntimeEvent(event.type, event);
|
|
68084
68123
|
if (event.type === "turn_settled" && activeTurn) {
|
|
68124
|
+
finalizePendingTerminal();
|
|
68085
68125
|
writeEvent({
|
|
68086
68126
|
type: "turn.settled",
|
|
68087
68127
|
sessionId: activeTurn.sessionId,
|
|
@@ -68166,7 +68206,7 @@ async function runJsonEventsMode(params) {
|
|
|
68166
68206
|
} else if (event.type === "turn_completed") {
|
|
68167
68207
|
const text = assistantTextFromMessage(event.message);
|
|
68168
68208
|
flushAssistantOutput(text);
|
|
68169
|
-
|
|
68209
|
+
rememberTerminal("completed", text || activeTurn.summary.trim());
|
|
68170
68210
|
} else if (event.type === "turn_failed_terminal") {
|
|
68171
68211
|
touch();
|
|
68172
68212
|
if (lastRetryEvent) {
|
|
@@ -68181,9 +68221,9 @@ async function runJsonEventsMode(params) {
|
|
|
68181
68221
|
});
|
|
68182
68222
|
lastRetryEvent = void 0;
|
|
68183
68223
|
}
|
|
68184
|
-
|
|
68224
|
+
rememberTerminal("failed", event.failure.message);
|
|
68185
68225
|
} else if (event.type === "turn_cancelled") {
|
|
68186
|
-
|
|
68226
|
+
rememberTerminal("cancelled", event.reason, { overwrite: false });
|
|
68187
68227
|
}
|
|
68188
68228
|
}
|
|
68189
68229
|
async function ensureRuntime() {
|
|
@@ -68359,6 +68399,7 @@ async function runJsonEventsMode(params) {
|
|
|
68359
68399
|
trace?.noteWaitForIdleStart({ mode: "json-events" });
|
|
68360
68400
|
await controller.waitForSettled();
|
|
68361
68401
|
trace?.noteWaitForIdleSettled({ mode: "json-events" });
|
|
68402
|
+
finalizePendingTerminal();
|
|
68362
68403
|
if (!activeTurn?.finalized) {
|
|
68363
68404
|
const finalError = assistantErrorFromAgent(agent);
|
|
68364
68405
|
if (activeTurn?.interrupted) {
|
|
@@ -68434,7 +68475,11 @@ async function runJsonEventsMode(params) {
|
|
|
68434
68475
|
if (activeTurn && !activeTurn.finalized) {
|
|
68435
68476
|
activeTurn.interrupted = true;
|
|
68436
68477
|
controller?.abort();
|
|
68437
|
-
|
|
68478
|
+
if (!controller) {
|
|
68479
|
+
finalize("cancelled", message.reason || "shutdown");
|
|
68480
|
+
} else {
|
|
68481
|
+
rememberTerminal("cancelled", message.reason || "shutdown");
|
|
68482
|
+
}
|
|
68438
68483
|
}
|
|
68439
68484
|
break;
|
|
68440
68485
|
}
|