@cydm/pie 1.0.45 → 1.0.47
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-PKR3PO73.js → chunk-IJMP3JTX.js} +195 -34
- package/dist/chunks/{chunk-75JWZPRK.js → chunk-U4B6RJ6Z.js} +1 -1
- package/dist/chunks/{test-stream-XCE2KXJU.js → test-stream-5T7E7C25.js} +9 -2
- package/dist/cli.js +1989 -790
- package/package.json +2 -2
|
@@ -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-IJMP3JTX.js";
|
|
5
5
|
import "../../../chunks/chunk-FKAO25XH.js";
|
|
6
6
|
import "../../../chunks/chunk-K6ZOCJ4V.js";
|
|
7
7
|
import "../../../chunks/chunk-LZQXQOPJ.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-U4B6RJ6Z.js";
|
|
5
5
|
import {
|
|
6
6
|
createSharedFileSystemTools,
|
|
7
7
|
createSubagentCapability
|
|
8
|
-
} from "../../../chunks/chunk-
|
|
8
|
+
} from "../../../chunks/chunk-IJMP3JTX.js";
|
|
9
9
|
import "../../../chunks/chunk-FKAO25XH.js";
|
|
10
10
|
import "../../../chunks/chunk-K6ZOCJ4V.js";
|
|
11
11
|
import "../../../chunks/chunk-LZQXQOPJ.js";
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
executeManageTodoList,
|
|
8
8
|
executionStateToTodos,
|
|
9
9
|
restoreExecutionState
|
|
10
|
-
} from "../../../chunks/chunk-
|
|
10
|
+
} from "../../../chunks/chunk-IJMP3JTX.js";
|
|
11
11
|
import "../../../chunks/chunk-FKAO25XH.js";
|
|
12
12
|
import "../../../chunks/chunk-K6ZOCJ4V.js";
|
|
13
13
|
import "../../../chunks/chunk-LZQXQOPJ.js";
|
|
@@ -3524,9 +3524,6 @@ var SessionManager = class {
|
|
|
3524
3524
|
(e) => e.type === "message" && e.message
|
|
3525
3525
|
).length;
|
|
3526
3526
|
if (this.activeSession.metadata.messageCount === 0) {
|
|
3527
|
-
if (await this.store.exists(this.activeSession.id)) {
|
|
3528
|
-
await this.store.delete(this.activeSession.id);
|
|
3529
|
-
}
|
|
3530
3527
|
this.activeSession.isDirty = false;
|
|
3531
3528
|
return;
|
|
3532
3529
|
}
|
|
@@ -4692,6 +4689,31 @@ function asTerminalFailure(failure, message = failure.message) {
|
|
|
4692
4689
|
message
|
|
4693
4690
|
};
|
|
4694
4691
|
}
|
|
4692
|
+
function emitTurnEndPolicyFailure(emit, error) {
|
|
4693
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
4694
|
+
emit({
|
|
4695
|
+
type: "turn_failed_terminal",
|
|
4696
|
+
failure: {
|
|
4697
|
+
kind: "internal_error",
|
|
4698
|
+
message: `Turn-end policy failed: ${message}`,
|
|
4699
|
+
retryable: false,
|
|
4700
|
+
compactable: false,
|
|
4701
|
+
userAbort: false,
|
|
4702
|
+
terminal: true
|
|
4703
|
+
}
|
|
4704
|
+
});
|
|
4705
|
+
emit({ type: "turn_settled" });
|
|
4706
|
+
}
|
|
4707
|
+
function handleTurnEndPolicyThrow(emit, error, context) {
|
|
4708
|
+
context.cancelPendingRecovery();
|
|
4709
|
+
if (context.recoveryWasActive) {
|
|
4710
|
+
context.markRecoveryTerminal();
|
|
4711
|
+
emitTurnEndPolicyFailure(emit, error);
|
|
4712
|
+
return;
|
|
4713
|
+
}
|
|
4714
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
4715
|
+
emit({ type: "turn_policy_error", message: `Turn-end policy failed after settle: ${message}` });
|
|
4716
|
+
}
|
|
4695
4717
|
|
|
4696
4718
|
// ../../packages/agent-framework/src/session/controller/retry-policy.ts
|
|
4697
4719
|
function defaultSetTimeout4(callback, delay) {
|
|
@@ -4728,6 +4750,7 @@ var AgentSessionRetryController = class {
|
|
|
4728
4750
|
}
|
|
4729
4751
|
async handleTurnEnd(message, failure) {
|
|
4730
4752
|
if (!this.retry || !message || message.role !== "assistant") {
|
|
4753
|
+
this.settleStrandedRetry(failure);
|
|
4731
4754
|
return;
|
|
4732
4755
|
}
|
|
4733
4756
|
if (!failure) {
|
|
@@ -4790,6 +4813,33 @@ var AgentSessionRetryController = class {
|
|
|
4790
4813
|
});
|
|
4791
4814
|
}, delayMs);
|
|
4792
4815
|
}
|
|
4816
|
+
/**
|
|
4817
|
+
* A retried turn can end without an assistant failure message (for example
|
|
4818
|
+
* the request dies before any content arrives, or a host classifier throws).
|
|
4819
|
+
* Without this net the pending recovery promise never resolves:
|
|
4820
|
+
* waitForRetry()/waitForSettled() hang forever, queued input never
|
|
4821
|
+
* dispatches, and the whole task freezes with no turn_settled.
|
|
4822
|
+
*/
|
|
4823
|
+
settleStrandedRetry(failure) {
|
|
4824
|
+
if (this.retryTimer !== void 0 || this.pendingRetry === void 0) {
|
|
4825
|
+
return;
|
|
4826
|
+
}
|
|
4827
|
+
const terminalFailure = asTerminalFailure(failure ?? {
|
|
4828
|
+
kind: "internal_error",
|
|
4829
|
+
message: "Retried turn ended without an assistant message; recovery settled to avoid a hang",
|
|
4830
|
+
retryable: false,
|
|
4831
|
+
compactable: false,
|
|
4832
|
+
userAbort: false,
|
|
4833
|
+
terminal: true
|
|
4834
|
+
});
|
|
4835
|
+
const maxRetries = this.retry?.maxRetries ?? 3;
|
|
4836
|
+
this.emit({ type: "retry_exhausted", errorMessage: terminalFailure.message, maxRetries });
|
|
4837
|
+
this.emit({ type: "turn_failed_terminal", failure: terminalFailure });
|
|
4838
|
+
this.emit({ type: "turn_settled" });
|
|
4839
|
+
this.retryAttempt = 0;
|
|
4840
|
+
this.setRecoveryState("terminal");
|
|
4841
|
+
this.resolvePending();
|
|
4842
|
+
}
|
|
4793
4843
|
cancel() {
|
|
4794
4844
|
this.cancelTimerOnly();
|
|
4795
4845
|
this.retryAttempt = 0;
|
|
@@ -4822,6 +4872,8 @@ var AgentSessionRetryController = class {
|
|
|
4822
4872
|
// ../../packages/agent-framework/src/session/controller/runtime-guard.ts
|
|
4823
4873
|
var RUNAWAY_TOOLCALL_WHITESPACE_DELTA_CHARS = 16384;
|
|
4824
4874
|
var RUNAWAY_TOOLCALL_WHITESPACE_DELTA_EVENTS = 40;
|
|
4875
|
+
var TOOL_FAILURE_ABORT_THRESHOLD = 4;
|
|
4876
|
+
var TOOL_FAILURE_ADVISORY_THRESHOLD = 2;
|
|
4825
4877
|
var TOOL_FAILURE_SIGNATURE_CHARS = 1e3;
|
|
4826
4878
|
var TOOL_FAILURE_SIGNATURE_CONTEXT_LINES = 5;
|
|
4827
4879
|
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;
|
|
@@ -4874,10 +4926,12 @@ function isStateChangingSuccess(event) {
|
|
|
4874
4926
|
return event.toolName === "bash" && details?.commandClass === "filesystem_write";
|
|
4875
4927
|
}
|
|
4876
4928
|
var AgentSessionRuntimeGuard = class {
|
|
4877
|
-
constructor(trigger) {
|
|
4929
|
+
constructor(trigger, advise) {
|
|
4878
4930
|
this.trigger = trigger;
|
|
4931
|
+
this.advise = advise;
|
|
4879
4932
|
}
|
|
4880
4933
|
trigger;
|
|
4934
|
+
advise;
|
|
4881
4935
|
repeatedToolFailures = /* @__PURE__ */ new Map();
|
|
4882
4936
|
streamGuard = {
|
|
4883
4937
|
whitespaceToolCallDeltaChars: 0,
|
|
@@ -4947,7 +5001,18 @@ var AgentSessionRuntimeGuard = class {
|
|
|
4947
5001
|
const key = `${event.toolName}:${reason}:${stableStringify(event.args)}:${resultSummary}`;
|
|
4948
5002
|
const repeatCount = (this.repeatedToolFailures.get(key) ?? 0) + 1;
|
|
4949
5003
|
this.repeatedToolFailures.set(key, repeatCount);
|
|
4950
|
-
if (
|
|
5004
|
+
if (this.isTriggered) {
|
|
5005
|
+
return;
|
|
5006
|
+
}
|
|
5007
|
+
if (repeatCount >= TOOL_FAILURE_ADVISORY_THRESHOLD && repeatCount < TOOL_FAILURE_ABORT_THRESHOLD && this.advise) {
|
|
5008
|
+
this.advise(
|
|
5009
|
+
event.toolName,
|
|
5010
|
+
repeatCount,
|
|
5011
|
+
reason,
|
|
5012
|
+
`Tool ${event.toolName} failed ${repeatCount} times in a row with the identical error and identical arguments. Re-read the tool error above: it usually names the exact recovery step or alternative tool. Retrying the same call unchanged will fail again; change the approach.`
|
|
5013
|
+
);
|
|
5014
|
+
}
|
|
5015
|
+
if (repeatCount < TOOL_FAILURE_ABORT_THRESHOLD) {
|
|
4951
5016
|
return;
|
|
4952
5017
|
}
|
|
4953
5018
|
this.isTriggered = true;
|
|
@@ -5281,9 +5346,14 @@ var AgentSessionController = class {
|
|
|
5281
5346
|
if (options.onEvent) {
|
|
5282
5347
|
this.listeners.add(options.onEvent);
|
|
5283
5348
|
}
|
|
5284
|
-
this.runtimeGuard = new AgentSessionRuntimeGuard(
|
|
5285
|
-
|
|
5286
|
-
|
|
5349
|
+
this.runtimeGuard = new AgentSessionRuntimeGuard(
|
|
5350
|
+
(toolName, repeatCount, reason) => {
|
|
5351
|
+
this.triggerRuntimeGuard(toolName, repeatCount, reason);
|
|
5352
|
+
},
|
|
5353
|
+
(toolName, repeatCount, reason, guidance) => {
|
|
5354
|
+
this.emit({ type: "runtime_guard_advisory", toolName, repeatCount, reason, guidance });
|
|
5355
|
+
}
|
|
5356
|
+
);
|
|
5287
5357
|
this.queue = new AgentSessionQueue({
|
|
5288
5358
|
agent: this.agent,
|
|
5289
5359
|
getIsStreaming: () => this.isStreaming,
|
|
@@ -5569,7 +5639,16 @@ var AgentSessionController = class {
|
|
|
5569
5639
|
if (event.type === "turn_end") {
|
|
5570
5640
|
void this.syncNewAgentMessages();
|
|
5571
5641
|
this.recordLifecycle({ type: "turn_end_success" });
|
|
5572
|
-
void this.handleTurnEndRuntimePolicies(event.message, event.toolResults)
|
|
5642
|
+
void this.handleTurnEndRuntimePolicies(event.message, event.toolResults).catch((error) => handleTurnEndPolicyThrow((event2) => this.emit(event2), error, {
|
|
5643
|
+
recoveryWasActive: this.isRecoveryActive(),
|
|
5644
|
+
cancelPendingRecovery: () => {
|
|
5645
|
+
this.retryController.cancel();
|
|
5646
|
+
this.autoCompact.cancel();
|
|
5647
|
+
},
|
|
5648
|
+
markRecoveryTerminal: () => {
|
|
5649
|
+
this.recoveryState = "terminal";
|
|
5650
|
+
}
|
|
5651
|
+
}));
|
|
5573
5652
|
}
|
|
5574
5653
|
if (event.type === "agent_end") {
|
|
5575
5654
|
this.recordLifecycle({ type: "agent_end" });
|
|
@@ -5789,46 +5868,52 @@ function isExtensionEnabled(identity, ...layers) {
|
|
|
5789
5868
|
}
|
|
5790
5869
|
return true;
|
|
5791
5870
|
}
|
|
5792
|
-
function
|
|
5871
|
+
function extractEnablementMap(parsed, key) {
|
|
5793
5872
|
if (!parsed || typeof parsed !== "object") {
|
|
5794
5873
|
return {};
|
|
5795
5874
|
}
|
|
5796
|
-
if (!hasOwn(parsed,
|
|
5875
|
+
if (!hasOwn(parsed, key)) {
|
|
5797
5876
|
return {};
|
|
5798
5877
|
}
|
|
5799
|
-
const
|
|
5800
|
-
if (!
|
|
5878
|
+
const map = parsed[key];
|
|
5879
|
+
if (!map || typeof map !== "object" || Array.isArray(map)) {
|
|
5801
5880
|
return {};
|
|
5802
5881
|
}
|
|
5803
|
-
return
|
|
5882
|
+
return map;
|
|
5804
5883
|
}
|
|
5805
|
-
function
|
|
5806
|
-
|
|
5807
|
-
|
|
5884
|
+
function extractExtensionSettings(parsed) {
|
|
5885
|
+
return extractEnablementMap(parsed, "extensions");
|
|
5886
|
+
}
|
|
5887
|
+
function setEnablementInMap(settingsObject, key, identity, enabled) {
|
|
5888
|
+
const map = cloneOwnProperties(extractEnablementMap(settingsObject, key));
|
|
5889
|
+
const current = hasOwn(map, identity) ? map[identity] : void 0;
|
|
5808
5890
|
if (enabled === void 0) {
|
|
5809
5891
|
if (current && typeof current === "object" && !Array.isArray(current)) {
|
|
5810
5892
|
const next = cloneOwnProperties(current);
|
|
5811
5893
|
delete next.enabled;
|
|
5812
5894
|
if (Object.keys(next).length === 0) {
|
|
5813
|
-
delete
|
|
5895
|
+
delete map[identity];
|
|
5814
5896
|
} else {
|
|
5815
|
-
defineOwnDataProperty(
|
|
5897
|
+
defineOwnDataProperty(map, identity, next);
|
|
5816
5898
|
}
|
|
5817
5899
|
} else {
|
|
5818
|
-
delete
|
|
5900
|
+
delete map[identity];
|
|
5819
5901
|
}
|
|
5820
5902
|
} else {
|
|
5821
5903
|
const next = current && typeof current === "object" && !Array.isArray(current) ? cloneOwnProperties(current) : {};
|
|
5822
5904
|
defineOwnDataProperty(next, "enabled", enabled);
|
|
5823
|
-
defineOwnDataProperty(
|
|
5905
|
+
defineOwnDataProperty(map, identity, next);
|
|
5824
5906
|
}
|
|
5825
|
-
if (Object.keys(
|
|
5826
|
-
delete settingsObject
|
|
5907
|
+
if (Object.keys(map).length === 0) {
|
|
5908
|
+
delete settingsObject[key];
|
|
5827
5909
|
} else {
|
|
5828
|
-
defineOwnDataProperty(settingsObject,
|
|
5910
|
+
defineOwnDataProperty(settingsObject, key, map);
|
|
5829
5911
|
}
|
|
5830
5912
|
return settingsObject;
|
|
5831
5913
|
}
|
|
5914
|
+
function setExtensionEnabledInSettings(settingsObject, identity, enabled) {
|
|
5915
|
+
return setEnablementInMap(settingsObject, "extensions", identity, enabled);
|
|
5916
|
+
}
|
|
5832
5917
|
|
|
5833
5918
|
// ../../packages/agent-framework/src/interaction.ts
|
|
5834
5919
|
var InteractionUnavailableError = class extends Error {
|
|
@@ -6807,6 +6892,19 @@ function snapshotFromStatAndContent(stat, content) {
|
|
|
6807
6892
|
contentHash: hashText(content)
|
|
6808
6893
|
};
|
|
6809
6894
|
}
|
|
6895
|
+
function mergeLineRanges(ranges) {
|
|
6896
|
+
const sorted = [...ranges].sort((left, right) => left.startLine - right.startLine || left.endLine - right.endLine);
|
|
6897
|
+
const merged = [];
|
|
6898
|
+
for (const range2 of sorted) {
|
|
6899
|
+
const last = merged[merged.length - 1];
|
|
6900
|
+
if (last && range2.startLine <= last.endLine + 1) {
|
|
6901
|
+
last.endLine = Math.max(last.endLine, range2.endLine);
|
|
6902
|
+
} else {
|
|
6903
|
+
merged.push({ startLine: range2.startLine, endLine: range2.endLine });
|
|
6904
|
+
}
|
|
6905
|
+
}
|
|
6906
|
+
return merged;
|
|
6907
|
+
}
|
|
6810
6908
|
function createFileObservationState(options = {}) {
|
|
6811
6909
|
const files = /* @__PURE__ */ new Map();
|
|
6812
6910
|
const maxFiles = Math.max(1, Math.floor(options.maxFiles ?? 100));
|
|
@@ -6833,6 +6931,33 @@ function createFileObservationState(options = {}) {
|
|
|
6833
6931
|
readRanges.delete(oldest);
|
|
6834
6932
|
}
|
|
6835
6933
|
}
|
|
6934
|
+
function coverageSpansFile(coveredRanges, totalLines) {
|
|
6935
|
+
if (totalLines <= 0) return true;
|
|
6936
|
+
const merged = mergeLineRanges(coveredRanges);
|
|
6937
|
+
return merged.length > 0 && merged[0].startLine <= 1 && merged[merged.length - 1].endLine >= totalLines;
|
|
6938
|
+
}
|
|
6939
|
+
function summarize(observed) {
|
|
6940
|
+
const merged = mergeLineRanges(observed.coveredRanges);
|
|
6941
|
+
const coveredLines = merged.reduce((total, range2) => total + (range2.endLine - range2.startLine + 1), 0);
|
|
6942
|
+
let firstUnseenLine;
|
|
6943
|
+
if (observed.coveredTotalLines > 0 && coveredLines < observed.coveredTotalLines) {
|
|
6944
|
+
firstUnseenLine = merged.length > 0 && merged[0].startLine <= 1 ? merged[merged.length - 1].endLine + 1 : 1;
|
|
6945
|
+
}
|
|
6946
|
+
let lastRange;
|
|
6947
|
+
for (const range2 of observed.readRanges.values()) {
|
|
6948
|
+
if (range2.coverage) {
|
|
6949
|
+
lastRange = range2.coverage;
|
|
6950
|
+
}
|
|
6951
|
+
}
|
|
6952
|
+
return {
|
|
6953
|
+
readCount: observed.readRanges.size,
|
|
6954
|
+
coveredLines,
|
|
6955
|
+
totalLines: observed.coveredTotalLines,
|
|
6956
|
+
completeTextKnown: observed.completeTextKnown,
|
|
6957
|
+
...lastRange ? { lastRange } : {},
|
|
6958
|
+
...firstUnseenLine ? { firstUnseenLine } : {}
|
|
6959
|
+
};
|
|
6960
|
+
}
|
|
6836
6961
|
return {
|
|
6837
6962
|
isUnchangedReadRange(absolutePath, rangeKey, snapshot, selectedContentHash) {
|
|
6838
6963
|
const observed = files.get(absolutePath);
|
|
@@ -6845,16 +6970,32 @@ function createFileObservationState(options = {}) {
|
|
|
6845
6970
|
touchFile(absolutePath, observed);
|
|
6846
6971
|
return unchanged;
|
|
6847
6972
|
},
|
|
6848
|
-
recordTextRead(absolutePath, rangeKey, snapshot, selectedContentHash, completeTextKnown) {
|
|
6849
|
-
const
|
|
6973
|
+
recordTextRead(absolutePath, rangeKey, snapshot, selectedContentHash, completeTextKnown, coverage) {
|
|
6974
|
+
const existing = files.get(absolutePath);
|
|
6975
|
+
const contentMatches = !!existing && snapshotsHaveSameContent(existing.snapshot, snapshot);
|
|
6976
|
+
const observed = existing ?? {
|
|
6850
6977
|
snapshot,
|
|
6851
6978
|
completeTextKnown: false,
|
|
6852
|
-
readRanges: /* @__PURE__ */ new Map()
|
|
6979
|
+
readRanges: /* @__PURE__ */ new Map(),
|
|
6980
|
+
coveredRanges: [],
|
|
6981
|
+
coveredTotalLines: 0
|
|
6853
6982
|
};
|
|
6854
|
-
const preservesFreshCompleteRead = observed.completeTextKnown &&
|
|
6983
|
+
const preservesFreshCompleteRead = observed.completeTextKnown && contentMatches;
|
|
6984
|
+
if (!contentMatches || coverage && observed.coveredTotalLines !== coverage.totalLines) {
|
|
6985
|
+
observed.coveredRanges = [];
|
|
6986
|
+
observed.coveredTotalLines = coverage?.totalLines ?? observed.coveredTotalLines;
|
|
6987
|
+
}
|
|
6855
6988
|
observed.snapshot = snapshot;
|
|
6856
|
-
|
|
6857
|
-
|
|
6989
|
+
if (coverage) {
|
|
6990
|
+
observed.coveredRanges = mergeLineRanges([...observed.coveredRanges, { startLine: coverage.startLine, endLine: coverage.endLine }]);
|
|
6991
|
+
observed.coveredTotalLines = coverage.totalLines;
|
|
6992
|
+
}
|
|
6993
|
+
observed.completeTextKnown = completeTextKnown || preservesFreshCompleteRead || observed.coveredTotalLines > 0 && coverageSpansFile(observed.coveredRanges, observed.coveredTotalLines);
|
|
6994
|
+
touchRange(observed.readRanges, rangeKey, {
|
|
6995
|
+
snapshot,
|
|
6996
|
+
selectedContentHash,
|
|
6997
|
+
...coverage ? { coverage: { startLine: coverage.startLine, endLine: coverage.endLine } } : {}
|
|
6998
|
+
});
|
|
6858
6999
|
touchFile(absolutePath, observed);
|
|
6859
7000
|
},
|
|
6860
7001
|
getCompleteTextSnapshot(absolutePath) {
|
|
@@ -6865,11 +7006,20 @@ function createFileObservationState(options = {}) {
|
|
|
6865
7006
|
touchFile(absolutePath, observed);
|
|
6866
7007
|
return observed.snapshot;
|
|
6867
7008
|
},
|
|
7009
|
+
describeObservation(absolutePath) {
|
|
7010
|
+
const observed = files.get(absolutePath);
|
|
7011
|
+
if (!observed) {
|
|
7012
|
+
return void 0;
|
|
7013
|
+
}
|
|
7014
|
+
return summarize(observed);
|
|
7015
|
+
},
|
|
6868
7016
|
recordCompleteTextWrite(absolutePath, snapshot) {
|
|
6869
7017
|
touchFile(absolutePath, {
|
|
6870
7018
|
snapshot,
|
|
6871
7019
|
completeTextKnown: true,
|
|
6872
|
-
readRanges: /* @__PURE__ */ new Map()
|
|
7020
|
+
readRanges: /* @__PURE__ */ new Map(),
|
|
7021
|
+
coveredRanges: [],
|
|
7022
|
+
coveredTotalLines: 0
|
|
6873
7023
|
});
|
|
6874
7024
|
},
|
|
6875
7025
|
invalidate(absolutePath) {
|
|
@@ -7137,7 +7287,7 @@ function createReadTool(cwd, options) {
|
|
|
7137
7287
|
resolve3({
|
|
7138
7288
|
content: [{
|
|
7139
7289
|
type: "text",
|
|
7140
|
-
text:
|
|
7290
|
+
text: `File unchanged since previous read of this range (offset=${startLineDisplay}${limit === void 0 ? ", no limit" : `, limit=${limit}`}). Earlier reads still count toward write_file coverage of this file. Use a different offset/limit if you need another section.`
|
|
7141
7291
|
}],
|
|
7142
7292
|
details: {
|
|
7143
7293
|
unchangedSincePreviousRead: true,
|
|
@@ -7187,7 +7337,15 @@ Base directory: ${nodePath.dirname(absolutePath)}
|
|
|
7187
7337
|
rangeKey,
|
|
7188
7338
|
snapshot,
|
|
7189
7339
|
range2.selectedContentHash,
|
|
7190
|
-
isCompleteTextKnown
|
|
7340
|
+
isCompleteTextKnown,
|
|
7341
|
+
{
|
|
7342
|
+
// firstLineExceedsLimit yields an intentionally empty range
|
|
7343
|
+
// (start - 1): zero lines were actually shown, so it must
|
|
7344
|
+
// contribute nothing to write coverage.
|
|
7345
|
+
startLine: startLineDisplay,
|
|
7346
|
+
endLine: startLineDisplay + (truncation.firstLineExceedsLimit ? 0 : truncation.truncated ? truncation.outputLines : range2.selectedLines) - 1,
|
|
7347
|
+
totalLines: range2.totalLines
|
|
7348
|
+
}
|
|
7191
7349
|
);
|
|
7192
7350
|
outputText = sourceHeader + outputText;
|
|
7193
7351
|
const textContent = [{ type: "text", text: outputText }];
|
|
@@ -7548,8 +7706,10 @@ function createWriteTool(cwd, options) {
|
|
|
7548
7706
|
const currentSnapshot = snapshotFromStatAndContent(currentStat, currentContent);
|
|
7549
7707
|
const observedSnapshot = fileObservationState.getCompleteTextSnapshot(absolutePath);
|
|
7550
7708
|
if (!observedSnapshot) {
|
|
7709
|
+
const summary = fileObservationState.describeObservation(absolutePath);
|
|
7710
|
+
const coverageHint = summary && summary.totalLines > 0 ? ` Previous reads cover ${summary.coveredLines}/${summary.totalLines} lines${summary.lastRange ? ` (last read: lines ${summary.lastRange.startLine}-${summary.lastRange.endLine})` : ""}${summary.firstUnseenLine ? `; read the rest with read_file offset=${summary.firstUnseenLine}` : "; read the full file with read_file (no offset/limit)"}.` : " Read the current full file with read_file (no offset/limit) first.";
|
|
7551
7711
|
throw new Error(
|
|
7552
|
-
usesExternalFileObservationState ?
|
|
7712
|
+
usesExternalFileObservationState ? `write_file blocked: overwriting requires the file to be fully observed by read_file.${coverageHint} Alternatively, use edit_file for targeted changes.` : "Existing-file overwrite requires write_file to share a fileObservationState with read_file; use createSharedFileSystemTools or pass the same fileObservationState to both tools."
|
|
7553
7713
|
);
|
|
7554
7714
|
}
|
|
7555
7715
|
if (!snapshotsHaveSameContent(observedSnapshot, currentSnapshot)) {
|
|
@@ -14799,6 +14959,7 @@ export {
|
|
|
14799
14959
|
getExtensionEnablementEntry,
|
|
14800
14960
|
isExtensionEnabled,
|
|
14801
14961
|
extractExtensionSettings,
|
|
14962
|
+
setEnablementInMap,
|
|
14802
14963
|
setExtensionEnabledInSettings,
|
|
14803
14964
|
registerInteractionHandler,
|
|
14804
14965
|
hasInteractionHandler,
|
|
@@ -90,7 +90,7 @@ function createTestStreamFnFromSequenceEnv(value = process.env.PIE_TEST_MOCK_STR
|
|
|
90
90
|
}
|
|
91
91
|
const steps = parseMockStreamSequence(value);
|
|
92
92
|
let callIndex = 0;
|
|
93
|
-
return async (model, context) => {
|
|
93
|
+
return async (model, context, options) => {
|
|
94
94
|
const step = steps[Math.min(callIndex, steps.length - 1)];
|
|
95
95
|
assertSystemPromptIncludes(context.systemPrompt, callIndex);
|
|
96
96
|
callIndex += 1;
|
|
@@ -143,7 +143,14 @@ function createTestStreamFnFromSequenceEnv(value = process.env.PIE_TEST_MOCK_STR
|
|
|
143
143
|
stream.push({ type: "done", reason: "stop", message });
|
|
144
144
|
};
|
|
145
145
|
if (step?.delayMs) {
|
|
146
|
-
setTimeout(emit, step.delayMs);
|
|
146
|
+
const timer = setTimeout(emit, step.delayMs);
|
|
147
|
+
options?.signal?.addEventListener("abort", () => {
|
|
148
|
+
clearTimeout(timer);
|
|
149
|
+
const reason = options.signal?.reason;
|
|
150
|
+
const message = reason instanceof Error ? reason.message : String(reason ?? "aborted");
|
|
151
|
+
const error = createAssistantMessage(model, "", "error", message);
|
|
152
|
+
stream.push({ type: "error", reason: "error", error });
|
|
153
|
+
}, { once: true });
|
|
147
154
|
} else {
|
|
148
155
|
queueMicrotask(emit);
|
|
149
156
|
}
|