@ponythewhite/base-context 1.0.7 → 1.0.9
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/CHANGELOG.md +24 -0
- package/dist/base-context-runtime/pyproject.toml +1 -1
- package/dist/base-context-runtime/src/rlm/__init__.py +3 -0
- package/dist/base-context-runtime/src/rlm/harness.py +86 -48
- package/dist/base-context-runtime/test/test_harness.py +215 -140
- package/dist/base-context-runtime/uv.lock +1 -1
- package/dist/build-info.json +1 -1
- package/dist/bundle/amazon-bedrock.js +3 -3
- package/dist/bundle/{anthropic-UV5GZDGU.js → anthropic-5PSCZEER.js} +2 -7
- package/dist/bundle/{azure-openai-responses-WSNPXLYC.js → azure-openai-responses-AYTLJR33.js} +2 -2
- package/dist/bundle/{bundled-modules-PS66L3IT.js → bundled-modules-5JRM6P4T.js} +5 -5
- package/dist/bundle/{chunk-UPVDERMD.js → chunk-2IPDSTDR.js} +11 -9
- package/dist/bundle/chunk-D3KOF57W.js +22040 -0
- package/dist/bundle/{chunk-VSIYFWYI.js → chunk-KT2BNEPE.js} +21 -8
- package/dist/bundle/{chunk-VCW3YDFF.js → chunk-NEHLB7JV.js} +1548 -574
- package/dist/bundle/{chunk-KTNETTHI.js → chunk-Q3MBSBEB.js} +3 -101
- package/dist/bundle/{chunk-LFPWHI42.js → chunk-QKIFBA7N.js} +2 -2
- package/dist/bundle/{chunk-PFROC4EV.js → chunk-VVI3UKGR.js} +12 -9
- package/dist/bundle/{cli-main-MMHTK7EB.js → cli-main-YUDBEYE2.js} +4 -4
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/{google-T32FMD4G.js → google-HTMCUJ7X.js} +2 -2
- package/dist/bundle/{google-vertex-56KP6I3B.js → google-vertex-ZQO65AXF.js} +2 -2
- package/dist/bundle/{main-XAIVH4Y7.js → main-ZLGGAAGU.js} +5 -5
- package/dist/bundle/{mistral-WGBMYIVU.js → mistral-SB7LU56G.js} +1 -1
- package/dist/bundle/{openai-codex-responses-PIV2RQ3G.js → openai-codex-responses-5CEW4VN3.js} +53 -27
- package/dist/bundle/{openai-completions-64C3JPR4.js → openai-completions-BAZJQSS2.js} +1 -1
- package/dist/bundle/{openai-responses-UI7RSTDV.js → openai-responses-VHOE427P.js} +48 -5
- package/dist/core/agent-session.d.ts +9 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +225 -29
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/canonical-context.d.ts +8 -0
- package/dist/core/canonical-context.d.ts.map +1 -1
- package/dist/core/canonical-context.js +37 -5
- package/dist/core/canonical-context.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +2 -2
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +31 -13
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/context-epoch.d.ts +1 -1
- package/dist/core/context-epoch.d.ts.map +1 -1
- package/dist/core/context-epoch.js +2 -1
- package/dist/core/context-epoch.js.map +1 -1
- package/dist/core/extensions/types.d.ts +2 -2
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/history-index-worker.d.ts.map +1 -1
- package/dist/core/history-index-worker.js +29 -8
- package/dist/core/history-index-worker.js.map +1 -1
- package/dist/core/history-index.d.ts +11 -1
- package/dist/core/history-index.d.ts.map +1 -1
- package/dist/core/history-index.js +2 -1
- package/dist/core/history-index.js.map +1 -1
- package/dist/core/inference-coordinator.d.ts +1 -1
- package/dist/core/inference-coordinator.d.ts.map +1 -1
- package/dist/core/inference-coordinator.js +110 -15
- package/dist/core/inference-coordinator.js.map +1 -1
- package/dist/core/kernel/bootstrap.d.ts.map +1 -1
- package/dist/core/kernel/bootstrap.js +97 -107
- package/dist/core/kernel/bootstrap.js.map +1 -1
- package/dist/core/kernel/repl-manager.d.ts.map +1 -1
- package/dist/core/kernel/repl-manager.js +11 -0
- package/dist/core/kernel/repl-manager.js.map +1 -1
- package/dist/core/kernel/shared.d.ts +2 -0
- package/dist/core/kernel/shared.d.ts.map +1 -1
- package/dist/core/kernel/shared.js.map +1 -1
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +4 -1
- package/dist/core/messages.js.map +1 -1
- package/dist/core/prompts/rlm.d.ts.map +1 -1
- package/dist/core/prompts/rlm.js +4 -2
- package/dist/core/prompts/rlm.js.map +1 -1
- package/dist/core/public-context.d.ts.map +1 -1
- package/dist/core/public-context.js +16 -0
- package/dist/core/public-context.js.map +1 -1
- package/dist/core/refinement/refinement.d.ts +19 -5
- package/dist/core/refinement/refinement.d.ts.map +1 -1
- package/dist/core/refinement/refinement.js +90 -35
- package/dist/core/refinement/refinement.js.map +1 -1
- package/dist/core/request-view-selection.d.ts +13 -3
- package/dist/core/request-view-selection.d.ts.map +1 -1
- package/dist/core/request-view-selection.js +239 -101
- package/dist/core/request-view-selection.js.map +1 -1
- package/dist/core/retained-tool-output.d.ts +28 -0
- package/dist/core/retained-tool-output.d.ts.map +1 -0
- package/dist/core/retained-tool-output.js +102 -0
- package/dist/core/retained-tool-output.js.map +1 -0
- package/dist/core/selective-recovery.d.ts +47 -3
- package/dist/core/selective-recovery.d.ts.map +1 -1
- package/dist/core/selective-recovery.js +428 -109
- package/dist/core/selective-recovery.js.map +1 -1
- package/dist/core/session-history-index.d.ts +3 -1
- package/dist/core/session-history-index.d.ts.map +1 -1
- package/dist/core/session-history-index.js +1 -1
- package/dist/core/session-history-index.js.map +1 -1
- package/dist/core/session-manager.d.ts +2 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +38 -13
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +5 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +3 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/system-prompt.d.ts +3 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +3 -3
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/task-frame.d.ts +1 -1
- package/dist/core/task-frame.d.ts.map +1 -1
- package/dist/core/task-frame.js +21 -1
- package/dist/core/task-frame.js.map +1 -1
- package/dist/core/task-state-reader.d.ts +10 -2
- package/dist/core/task-state-reader.d.ts.map +1 -1
- package/dist/core/task-state-reader.js +75 -9
- package/dist/core/task-state-reader.js.map +1 -1
- package/dist/core/tools/ipython.d.ts +5 -0
- package/dist/core/tools/ipython.d.ts.map +1 -1
- package/dist/core/tools/ipython.js +59 -17
- package/dist/core/tools/ipython.js.map +1 -1
- package/dist/core/tools/prime-context.d.ts.map +1 -1
- package/dist/core/tools/prime-context.js +1 -1
- package/dist/core/tools/prime-context.js.map +1 -1
- package/dist/core/view-units.d.ts +4 -0
- package/dist/core/view-units.d.ts.map +1 -1
- package/dist/core/view-units.js +28 -19
- package/dist/core/view-units.js.map +1 -1
- package/dist/installer.mjs +98 -77
- package/dist/modes/interactive/components/refinement-outcome-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/refinement-outcome-message.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +5 -5
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/skills/skill-creator/SKILL.md +18 -1
- package/docs/settings.md +45 -0
- package/docs/skills.md +77 -2
- package/package.json +4 -4
- package/skills/skill-creator/SKILL.md +18 -1
- package/dist/bundle/chunk-W46VZFI6.js +0 -21681
|
@@ -5,7 +5,7 @@ import { tmpdir } from "node:os";
|
|
|
5
5
|
import { basename, dirname, join, resolve } from "node:path";
|
|
6
6
|
import { isDeepStrictEqual } from "node:util";
|
|
7
7
|
import { Agent, AgentContinueError, AgentOutputLimitError, } from "@ponythewhite/base-context-agent";
|
|
8
|
-
import { clampThinkingLevel, cleanupSessionResources, getSupportedThinkingLevels, isContextOverflow, isTransientProviderFailure, modelsAreEqual, resetApiProviders, supportsFastMode, } from "@ponythewhite/base-context-ai";
|
|
8
|
+
import { clampThinkingLevel, cleanupSessionResources, conservativeTextTokenCost, getSupportedThinkingLevels, isContextOverflow, isTransientProviderFailure, modelsAreEqual, resetApiProviders, supportsFastMode, } from "@ponythewhite/base-context-ai";
|
|
9
9
|
import { theme } from "../modes/interactive/theme/theme.js";
|
|
10
10
|
import { PRODUCT } from "../product-identity.js";
|
|
11
11
|
import { sleep } from "../utils/sleep.js";
|
|
@@ -31,13 +31,13 @@ import { snapshotPathIn } from "./kernel/state-snapshot.js";
|
|
|
31
31
|
import { convertToLlm, createCompactionOutcomeMessage, createHeartbeatPromptMessage, createRefinementOutcomeMessage, createRlmChildFailureMessage, createRlmChildTerminalNoticeMessage, createSessionSlashCommandMessage, createSessionSlashCommandResultMessage, HEARTBEAT_PROMPT_CUSTOM_TYPE, HEARTBEAT_PROMPT_PREVIEW_LABEL, IPYTHON_STATE_RESTORED_CUSTOM_TYPE, isSessionSlashCommandMessage, RLM_CHILD_FAILURE_CUSTOM_TYPE, RLM_CHILD_TERMINAL_NOTICE_CUSTOM_TYPE, } from "./messages.js";
|
|
32
32
|
import { throwIfPromptAdmissionCancelled } from "./prompt-admission.js";
|
|
33
33
|
import { expandPromptTemplate } from "./prompt-templates.js";
|
|
34
|
-
import { appendGlobalRefinement, applyRefinementProposal, generateRefinementId, getGlobalHarnessStateDir, getLocalHarnessStateDir, getRefinementHistory, inferRefinementResultScope, loadGlobalRefinementHistory, loadHarnessState, mergeHarnessStates, mergeRefinementHistory, normalizeRefinementProposal, planRefinement, prepareRefinementApplication, REFINE_SKILL_NAME, reviewAutoRefine, saveHarnessState, takeNativePlannerRequestWrite, withRefinementBaseline, } from "./refinement/index.js";
|
|
34
|
+
import { appendGlobalRefinement, applyRefinementProposal, generateRefinementId, getGlobalHarnessStateDir, getLocalHarnessStateDir, getRefinementHistory, getWorkspaceHarnessStateDir, inferRefinementResultScope, loadGlobalRefinementHistory, loadHarnessState, mergeHarnessStates, mergeRefinementHistory, normalizeRefinementProposal, planRefinement, prepareRefinementApplication, REFINE_SKILL_NAME, reviewAutoRefine, saveHarnessState, takeNativePlannerRequestWrite, withRefinementBaseline, } from "./refinement/index.js";
|
|
35
35
|
import { PublicContextBudgetError } from "./request-view-selection.js";
|
|
36
36
|
import { resolveConfigValue } from "./resolve-config-value.js";
|
|
37
37
|
import { assertResourceCurrent } from "./resource-view.js";
|
|
38
38
|
import { createDefaultRlmSubagentSessionName, createRlmDeleteSubagentHostHandler, createRlmFindModelsHostHandler, createRlmListSubagentsHostHandler, createRlmRunHostHandler, findRlmModelMatches, normalizeRequestedRlmSubagentModel, normalizeRequestedRlmSubagentSessionName, normalizeRequestedRlmSubagentThinkingLevel, } from "./rlm-runtime.js";
|
|
39
39
|
import { captureSelectedSkill, captureSkillDescriptor, readSkillSelection, sameSelectedSkills, selectedSkillBlock, selectedSkillIdentity, } from "./selected-skills.js";
|
|
40
|
-
import { createNativeRecoveryRefusal, DEFAULT_NATIVE_RECOVERY_LIMITS, NativeRecoveryBudgetRefusal, parseNativeRecoveryInput, recoverCapturedHistory, } from "./selective-recovery.js";
|
|
40
|
+
import { createNativeRecoveryRefusal, DEFAULT_NATIVE_RECOVERY_LIMITS, NativeRecoveryBudgetRefusal, NativeRecoveryCursorStore, parseNativeRecoveryInput, recoverCapturedHistory, } from "./selective-recovery.js";
|
|
41
41
|
import { modelRequestHeaders, SemanticEdgeRecorder, semanticEdgeLedgerPath, wrapStreamFnWithSemanticEdges, } from "./semantic-edges.js";
|
|
42
42
|
import { ActionStore, canSelectSessionAction, queuedMessageLaneDeliveryPolicy, transitionSessionAction, } from "./session-action-store.js";
|
|
43
43
|
import { readSessionBootstrap } from "./session-bootstrap.js";
|
|
@@ -281,6 +281,8 @@ export class AgentSession {
|
|
|
281
281
|
requests;
|
|
282
282
|
runtimeServices;
|
|
283
283
|
_contextCompiler = new CanonicalContextCompiler();
|
|
284
|
+
_failedAutomaticCompaction;
|
|
285
|
+
_failedThresholdCompaction;
|
|
284
286
|
_contextEpochsEnabled;
|
|
285
287
|
_initialContextMode;
|
|
286
288
|
_contextMode;
|
|
@@ -444,6 +446,8 @@ export class AgentSession {
|
|
|
444
446
|
_modelRegistry;
|
|
445
447
|
_toolRegistry = new Map();
|
|
446
448
|
_nativeRecoveryTools = new WeakMap();
|
|
449
|
+
_nativeRecoveryCursors = new NativeRecoveryCursorStore();
|
|
450
|
+
_nativeRecoveryCursorSource;
|
|
447
451
|
_nativeRecoveryProducer = new AsyncLocalStorage();
|
|
448
452
|
_toolDefinitions = new Map();
|
|
449
453
|
_toolPromptSnippets = new Map();
|
|
@@ -452,6 +456,7 @@ export class AgentSession {
|
|
|
452
456
|
_baseSystemPromptOptions;
|
|
453
457
|
_assistantTurnsSinceAutoRefine = 0;
|
|
454
458
|
_lastAutoRefineReviewAt = 0;
|
|
459
|
+
_lastAutoRefineEvidence;
|
|
455
460
|
_autoRefineInProgress = false;
|
|
456
461
|
_autoRefineAdmissionClosed = false;
|
|
457
462
|
_autoRefineOperations = new Set();
|
|
@@ -610,7 +615,8 @@ export class AgentSession {
|
|
|
610
615
|
const epochContext = getCanonicalEpochContext(messages);
|
|
611
616
|
if (epochContext)
|
|
612
617
|
this._contextMode = epochContext.mode;
|
|
613
|
-
const unbudgetedPublic = !contextEpochsEnabled &&
|
|
618
|
+
const unbudgetedPublic = !contextEpochsEnabled &&
|
|
619
|
+
Boolean(epochContext?.toolContinuations?.length || epochContext?.taskFrameRebased || epochContext?.checkpoint);
|
|
614
620
|
const nativeSkills = Boolean(contextEpochsEnabled || epochContext?.checkpoint || unbudgetedPublic);
|
|
615
621
|
const skillPolicy = nativeSkills ? (this._nativeRecoveryEnabled() ? "enabled" : "unavailable") : undefined;
|
|
616
622
|
if (this._baseSystemPromptOptions.nativeSkillSelection !== skillPolicy) {
|
|
@@ -637,6 +643,7 @@ export class AgentSession {
|
|
|
637
643
|
message.content.some((part) => part.type !== "text" || part.textSignature !== undefined)));
|
|
638
644
|
let accepted;
|
|
639
645
|
let acceptedBody;
|
|
646
|
+
let acceptedResponseIdentity;
|
|
640
647
|
let acceptedReplayContract;
|
|
641
648
|
let acknowledged;
|
|
642
649
|
const commitFailure = (cause) => {
|
|
@@ -656,7 +663,7 @@ export class AgentSession {
|
|
|
656
663
|
candidate.projection.pendingPublicMessageGroups?.length))
|
|
657
664
|
throw new Error("Tool continuation requires its exact public candidate before epoch ACK");
|
|
658
665
|
assertResourceCurrent(resource);
|
|
659
|
-
const representation = contextEpochRepresentation(candidate.request, candidate.assessment, limits.maxSourceBytes, unbudgetedPublic);
|
|
666
|
+
const representation = contextEpochRepresentation(candidate.request, candidate.assessment, limits.maxSourceBytes, unbudgetedPublic, candidate.responseItemIdentity);
|
|
660
667
|
const replayContract = "replayContract" in candidate.projection &&
|
|
661
668
|
candidate.projection.replayContract === "message-groups"
|
|
662
669
|
? "message-groups"
|
|
@@ -669,6 +676,7 @@ export class AgentSession {
|
|
|
669
676
|
candidate.publicMessages !== undefined,
|
|
670
677
|
candidate.selectedUnitIds,
|
|
671
678
|
]);
|
|
679
|
+
acceptedResponseIdentity = candidate.responseItemIdentity;
|
|
672
680
|
if (accepted !== undefined) {
|
|
673
681
|
if (accepted !== selection)
|
|
674
682
|
throw new Error("Captured epoch request selection changed after acceptance");
|
|
@@ -707,7 +715,7 @@ export class AgentSession {
|
|
|
707
715
|
acknowledged = { entryId, result };
|
|
708
716
|
try {
|
|
709
717
|
assertResourceCurrent(resource);
|
|
710
|
-
if (this.sessionManager !== epochManager ||
|
|
718
|
+
if (this.sessionManager !== epochManager || !compaction.isCurrent())
|
|
711
719
|
throw new Error("Context epoch source changed before adoption");
|
|
712
720
|
this.agent.state.messages = prepared.messages;
|
|
713
721
|
committed = prepared.checkpoint;
|
|
@@ -738,12 +746,13 @@ export class AgentSession {
|
|
|
738
746
|
}
|
|
739
747
|
return;
|
|
740
748
|
}
|
|
749
|
+
if (epochContext.taskFrameRebased && acceptedBody === undefined)
|
|
750
|
+
throw new Error("Task frame rebase requires a committed epoch boundary");
|
|
741
751
|
if (!committed)
|
|
742
752
|
return;
|
|
743
753
|
if (acceptedBody === undefined || request.body !== acceptedBody)
|
|
744
754
|
throw new Error("Committed context epoch requires a compatible final provider projection");
|
|
745
|
-
if (contextEpochRepresentation(request, assessment, limits.maxSourceBytes, unbudgetedPublic) !==
|
|
746
|
-
committed.representation)
|
|
755
|
+
if (contextEpochRepresentation(request, assessment, limits.maxSourceBytes, unbudgetedPublic, acceptedResponseIdentity) !== committed.representation)
|
|
747
756
|
throw new Error("Context epoch representation changed without a committed boundary");
|
|
748
757
|
if (committed.resourceRevision !== epochContext.resourceRevision)
|
|
749
758
|
throw new Error("Context epoch resource revision requires a committed boundary");
|
|
@@ -797,7 +806,7 @@ export class AgentSession {
|
|
|
797
806
|
committedEntry = { sessionId: epochContext.source.sessionId, entryId };
|
|
798
807
|
requestContract = nextContract;
|
|
799
808
|
assertResourceCurrent(resource);
|
|
800
|
-
if (this.sessionManager !== epochManager ||
|
|
809
|
+
if (this.sessionManager !== epochManager || !compaction.isCurrent())
|
|
801
810
|
throw new Error("Context contract source changed before acceptance");
|
|
802
811
|
}
|
|
803
812
|
if (!sameSelectedSkills(committed?.selectedSkills, epochContext.selectedSkills))
|
|
@@ -814,7 +823,7 @@ export class AgentSession {
|
|
|
814
823
|
throw commitFailure(cause);
|
|
815
824
|
}
|
|
816
825
|
}
|
|
817
|
-
: undefined);
|
|
826
|
+
: undefined, compaction.isCurrent);
|
|
818
827
|
}
|
|
819
828
|
this._compactionSetupFailure = undefined;
|
|
820
829
|
return { messages, adoptMessages: true, streamContext: captured, release: () => captured.dispose() };
|
|
@@ -842,11 +851,43 @@ export class AgentSession {
|
|
|
842
851
|
!error.source.persistent ||
|
|
843
852
|
error.source.sessionId !== owner.sessionId ||
|
|
844
853
|
error.source.sessionFile !== owner.sessionFile ||
|
|
845
|
-
error.source.leafId
|
|
854
|
+
!(error.isSourceCurrent?.() ?? error.source.leafId === owner.manager.getLeafId()))
|
|
855
|
+
return false;
|
|
856
|
+
// Rebase this captured frame before paying for a summary. The replacement still
|
|
857
|
+
// needs the normal full provider projection and epoch ACK before MAIN can send.
|
|
858
|
+
if (error.taskFrameRebaseAvailable) {
|
|
859
|
+
this._contextCompiler.requestTaskFrameRebase();
|
|
860
|
+
return "reprepare";
|
|
861
|
+
}
|
|
862
|
+
if (error.mandatoryAssessment?.status === "over-budget")
|
|
846
863
|
return false;
|
|
847
864
|
// The loop released its unsent inference and captured projection before this handoff.
|
|
848
865
|
// Continue in-place only after the real summary ACK and canonical owner adoption.
|
|
849
|
-
|
|
866
|
+
const key = error.getCompactionKey();
|
|
867
|
+
const current = {
|
|
868
|
+
key: key ?? "",
|
|
869
|
+
systemPrompt: this.agent.state.systemPrompt,
|
|
870
|
+
tools: this.agent.state.tools,
|
|
871
|
+
settings: JSON.stringify(this.settingsManager.getCompactionSettings()),
|
|
872
|
+
};
|
|
873
|
+
const failed = this._failedAutomaticCompaction;
|
|
874
|
+
if (key &&
|
|
875
|
+
failed &&
|
|
876
|
+
failed.key === key &&
|
|
877
|
+
failed.systemPrompt === current.systemPrompt &&
|
|
878
|
+
failed.tools === current.tools &&
|
|
879
|
+
failed.settings === current.settings)
|
|
880
|
+
return false;
|
|
881
|
+
this._failedAutomaticCompaction = undefined;
|
|
882
|
+
let succeeded = false;
|
|
883
|
+
try {
|
|
884
|
+
succeeded = await this._runAutoCompaction("threshold", false, owner, true, error);
|
|
885
|
+
return succeeded;
|
|
886
|
+
}
|
|
887
|
+
finally {
|
|
888
|
+
if (!succeeded && key && this._isCompactionSourceOwnerCurrent(owner))
|
|
889
|
+
this._failedAutomaticCompaction = current;
|
|
890
|
+
}
|
|
850
891
|
});
|
|
851
892
|
this.agent.bindProviderFailureRecoveryOwner({
|
|
852
893
|
recover: (message, signal) => this._handleRetryableError(message, signal),
|
|
@@ -1138,7 +1179,7 @@ export class AgentSession {
|
|
|
1138
1179
|
};
|
|
1139
1180
|
// ACK is authoritative even if later setup or release fails.
|
|
1140
1181
|
this._contextMode = mode;
|
|
1141
|
-
if (this.sessionManager !== manager ||
|
|
1182
|
+
if (this.sessionManager !== manager || !compaction.isCurrent())
|
|
1142
1183
|
throw new Error("Context mode source changed before adoption");
|
|
1143
1184
|
assertResourceCurrent(resource);
|
|
1144
1185
|
this.agent.state.messages = prepared.messages;
|
|
@@ -2840,6 +2881,25 @@ export class AgentSession {
|
|
|
2840
2881
|
return timestamp;
|
|
2841
2882
|
});
|
|
2842
2883
|
}
|
|
2884
|
+
_thresholdCompactionConfiguration() {
|
|
2885
|
+
return JSON.stringify({
|
|
2886
|
+
model: this.model,
|
|
2887
|
+
thinkingLevel: this.thinkingLevel,
|
|
2888
|
+
settings: this.settingsManager.getCompactionSettings(),
|
|
2889
|
+
});
|
|
2890
|
+
}
|
|
2891
|
+
_hasFailedThresholdCompaction() {
|
|
2892
|
+
const failed = this._failedThresholdCompaction;
|
|
2893
|
+
if (!failed)
|
|
2894
|
+
return false;
|
|
2895
|
+
if (failed.isCurrent() &&
|
|
2896
|
+
failed.configuration === this._thresholdCompactionConfiguration() &&
|
|
2897
|
+
failed.systemPrompt === this.agent.state.systemPrompt &&
|
|
2898
|
+
failed.tools === this.agent.state.tools)
|
|
2899
|
+
return true;
|
|
2900
|
+
this._failedThresholdCompaction = undefined;
|
|
2901
|
+
return false;
|
|
2902
|
+
}
|
|
2843
2903
|
async _thresholdCompactionNeeded(context, owner = this._captureCompactionOwner(), goalOwner = {
|
|
2844
2904
|
...this._captureGoalContinuationOwner(owner.signal),
|
|
2845
2905
|
checkpointOwner: owner,
|
|
@@ -2858,6 +2918,8 @@ export class AgentSession {
|
|
|
2858
2918
|
const contextTokens = this._getThresholdContextTokens(context.message, compactionTimestamp);
|
|
2859
2919
|
if (contextTokens === undefined || !shouldCompact(contextTokens, contextWindow, settings))
|
|
2860
2920
|
return false;
|
|
2921
|
+
if (this._hasFailedThresholdCompaction())
|
|
2922
|
+
return false;
|
|
2861
2923
|
// Keep the existing threshold-specific goal winner; do not import W74's natural wait policy here.
|
|
2862
2924
|
if (!this._isGoalContinuationOwnerCurrent(goalOwner))
|
|
2863
2925
|
return true;
|
|
@@ -4107,6 +4169,10 @@ export class AgentSession {
|
|
|
4107
4169
|
* the latest state reaches disk instead of racing process exit.
|
|
4108
4170
|
*/
|
|
4109
4171
|
async disposeAsync(options) {
|
|
4172
|
+
this._failedAutomaticCompaction = undefined;
|
|
4173
|
+
this._failedThresholdCompaction = undefined;
|
|
4174
|
+
this._contextCompiler.clear();
|
|
4175
|
+
this._nativeRecoveryCursors.clear();
|
|
4110
4176
|
for (const admission of this._rlmChildAdmissions)
|
|
4111
4177
|
admission.cancel("Parent session disposed");
|
|
4112
4178
|
if (this._disposeAsyncPromise)
|
|
@@ -4340,6 +4406,10 @@ export class AgentSession {
|
|
|
4340
4406
|
return this._disposeCallbacksPromise;
|
|
4341
4407
|
}
|
|
4342
4408
|
dispose() {
|
|
4409
|
+
this._failedAutomaticCompaction = undefined;
|
|
4410
|
+
this._failedThresholdCompaction = undefined;
|
|
4411
|
+
this._contextCompiler.clear();
|
|
4412
|
+
this._nativeRecoveryCursors.clear();
|
|
4343
4413
|
if (this._disposed) {
|
|
4344
4414
|
return;
|
|
4345
4415
|
}
|
|
@@ -4583,7 +4653,7 @@ export class AgentSession {
|
|
|
4583
4653
|
}
|
|
4584
4654
|
return Array.from(unique);
|
|
4585
4655
|
}
|
|
4586
|
-
_rebuildSystemPrompt(toolNames, nativeEpoch = this.sessionManager.isPersisted() && this._contextEpochsEnabled) {
|
|
4656
|
+
_rebuildSystemPrompt(toolNames, nativeEpoch = this.sessionManager.isPersisted() && this._contextEpochsEnabled, operation = this._baseSystemPromptOptions?.errorFixSelection?.operation) {
|
|
4587
4657
|
const validToolNames = toolNames.filter((name) => this._toolRegistry.has(name));
|
|
4588
4658
|
const toolSnippets = {};
|
|
4589
4659
|
const promptGuidelines = [];
|
|
@@ -4617,6 +4687,14 @@ export class AgentSession {
|
|
|
4617
4687
|
rlmDepth: this._rlmDepth,
|
|
4618
4688
|
rlmParentAgent: this._rlmParentAgent,
|
|
4619
4689
|
harnessState: this._loadMergedHarnessState(),
|
|
4690
|
+
errorFixSelection: {
|
|
4691
|
+
enabled: this.settingsManager.getLearningEnabled(),
|
|
4692
|
+
tools: validToolNames,
|
|
4693
|
+
operation,
|
|
4694
|
+
goal: this._goalState.objective,
|
|
4695
|
+
environment: { cwd: this._cwd, platform: process.platform },
|
|
4696
|
+
countTokens: conservativeTextTokenCost,
|
|
4697
|
+
},
|
|
4620
4698
|
genericMcpServers: this._mcpManager?.getEnabledPersistentGenericServers(),
|
|
4621
4699
|
};
|
|
4622
4700
|
return buildSystemPrompt(this._baseSystemPromptOptions);
|
|
@@ -6099,6 +6177,12 @@ export class AgentSession {
|
|
|
6099
6177
|
const preparationAction = activeTurns().at(-1);
|
|
6100
6178
|
if (!preparationAction)
|
|
6101
6179
|
return undefined;
|
|
6180
|
+
if (this.settingsManager.getLearningEnabled() ||
|
|
6181
|
+
this._baseSystemPromptOptions.errorFixSelection?.enabled) {
|
|
6182
|
+
// Capture advice for this task before extensions and provider preparation.
|
|
6183
|
+
// Tool continuations keep the same prompt until the next task boundary.
|
|
6184
|
+
this._baseSystemPrompt = this._rebuildSystemPrompt(this.getActiveToolNames(), this._baseSystemPromptOptions.nativeSkillSelection !== undefined, preparationAction.payload.text);
|
|
6185
|
+
}
|
|
6102
6186
|
const basePromptSnapshot = this._baseSystemPrompt;
|
|
6103
6187
|
const result = await this._extensionRunner.emitBeforeAgentStart(preparationAction.payload.text, preparationAction.payload.images, basePromptSnapshot, this._baseSystemPromptOptions);
|
|
6104
6188
|
if (activeTurns().at(-1) !== preparationAction)
|
|
@@ -7759,7 +7843,11 @@ export class AgentSession {
|
|
|
7759
7843
|
const summaryRequests = requests[captureNativeCompactionRequests]();
|
|
7760
7844
|
let summaryFailure;
|
|
7761
7845
|
try {
|
|
7762
|
-
nativeCompaction = await compact(preparation, model, apiKey, headers, customInstructions, signal, thinkingLevel, summaryCall, summaryRequests
|
|
7846
|
+
nativeCompaction = await compact(preparation, model, apiKey, headers, customInstructions, signal, thinkingLevel, summaryCall, summaryRequests, options.capacity
|
|
7847
|
+
? (wrapper) => options.capacity.remainingSummaryTokens(new Set(pathEntries
|
|
7848
|
+
.slice(pathEntries.findIndex((entry) => entry.id === preparation.firstKeptEntryId))
|
|
7849
|
+
.map((entry) => entry.id)), wrapper)
|
|
7850
|
+
: undefined);
|
|
7763
7851
|
({ summary, firstKeptEntryId, tokensBefore, details, usage } = nativeCompaction);
|
|
7764
7852
|
}
|
|
7765
7853
|
catch (error) {
|
|
@@ -8320,9 +8408,9 @@ export class AgentSession {
|
|
|
8320
8408
|
}
|
|
8321
8409
|
}
|
|
8322
8410
|
catch (error) {
|
|
8323
|
-
//
|
|
8324
|
-
//
|
|
8325
|
-
|
|
8411
|
+
// Consume this exact automatic proposal after failure. New evidence can
|
|
8412
|
+
// request a new review; manual /refine remains independent.
|
|
8413
|
+
this._pendingAutoRefineReview = undefined;
|
|
8326
8414
|
this._lastAutoRefineReviewAt = Date.now();
|
|
8327
8415
|
if (error instanceof RefineSkippedError) {
|
|
8328
8416
|
// A skipped round is consumed like a reviewer decline, not retained for retry.
|
|
@@ -8362,7 +8450,78 @@ export class AgentSession {
|
|
|
8362
8450
|
throw new Error(`autoRefine.model thinkingLevel ${selection.thinkingLevel} is not supported by ${selection.provider}/${selection.modelId}`);
|
|
8363
8451
|
return { model: { ...model, cost: { ...model.cost } }, thinkingLevel: selection.thinkingLevel, explicit: true };
|
|
8364
8452
|
}
|
|
8453
|
+
async _autoRefineEvidence(harnessState) {
|
|
8454
|
+
const manager = this.sessionManager;
|
|
8455
|
+
const goalEvidence = ({ active, status, goalId, objective, tokenBudget, lastError }) => ({
|
|
8456
|
+
active,
|
|
8457
|
+
status,
|
|
8458
|
+
goalId,
|
|
8459
|
+
objective,
|
|
8460
|
+
tokenBudget,
|
|
8461
|
+
lastError,
|
|
8462
|
+
});
|
|
8463
|
+
const frontier = manager.supportsCapturedHistoryReads()
|
|
8464
|
+
? await manager.readBranchHistory(async (history) => {
|
|
8465
|
+
const goal = (await history.branchBootstrap()).goalState;
|
|
8466
|
+
const limits = this.settingsManager.getCanonicalContextLimits();
|
|
8467
|
+
let goalState = emptyGoalState();
|
|
8468
|
+
if (goal) {
|
|
8469
|
+
const hydrated = await history.hydrateEntry(goal.id, limits.maxSourceBytes);
|
|
8470
|
+
if (!hydrated ||
|
|
8471
|
+
hydrated.source.retention === "retained-import" ||
|
|
8472
|
+
hydrated.entry.type !== "custom" ||
|
|
8473
|
+
hydrated.entry.customType !== GOAL_STATE_CUSTOM_TYPE ||
|
|
8474
|
+
!isPersistedGoalState(hydrated.entry.data))
|
|
8475
|
+
throw new RefineSkippedError("Automatic refinement goal source is unavailable or ineligible");
|
|
8476
|
+
goalState = normalizeGoalState(hydrated.entry.data);
|
|
8477
|
+
}
|
|
8478
|
+
let id = history.source.leafId;
|
|
8479
|
+
const maxEntries = limits.maxMessages;
|
|
8480
|
+
for (let scanned = 0; scanned < maxEntries; scanned++) {
|
|
8481
|
+
const entry = id ? await history.get(id) : undefined;
|
|
8482
|
+
if (id && !entry)
|
|
8483
|
+
throw new RefineSkippedError("Automatic refinement task frontier is unavailable");
|
|
8484
|
+
const message = entry?.kind === "message" ? entry : undefined;
|
|
8485
|
+
if (message || !entry)
|
|
8486
|
+
return {
|
|
8487
|
+
sessionId: history.source.sessionId,
|
|
8488
|
+
sessionFile: history.source.sessionFile,
|
|
8489
|
+
message: message ? [message.id, message.revision] : undefined,
|
|
8490
|
+
goal: goalEvidence(goalState),
|
|
8491
|
+
};
|
|
8492
|
+
id = entry.parentId;
|
|
8493
|
+
}
|
|
8494
|
+
throw new RefineSkippedError("Automatic refinement task frontier exceeds the context read limit");
|
|
8495
|
+
})
|
|
8496
|
+
: (() => {
|
|
8497
|
+
const branch = manager.getBranch().slice().reverse();
|
|
8498
|
+
const message = branch.find((entry) => entry.type === "message");
|
|
8499
|
+
return {
|
|
8500
|
+
sessionId: manager.getSessionId(),
|
|
8501
|
+
sessionFile: manager.getSessionFile(),
|
|
8502
|
+
message: message ? [message.id, message.timestamp] : undefined,
|
|
8503
|
+
goal: goalEvidence(this._loadPersistedGoalState()),
|
|
8504
|
+
};
|
|
8505
|
+
})();
|
|
8506
|
+
return {
|
|
8507
|
+
...frontier,
|
|
8508
|
+
systemPrompt: this.agent.state.systemPrompt,
|
|
8509
|
+
model: JSON.stringify([this.model?.provider, this.model?.id, this.settingsManager.getAutoRefineModel()]),
|
|
8510
|
+
harnessEntries: Object.fromEntries(Object.entries(harnessState.entries).map(([kind, entries]) => [
|
|
8511
|
+
kind,
|
|
8512
|
+
Object.fromEntries(Object.entries(entries).map(([id, { version: _version, created_at: _created, updated_at: _updated, ...entry }]) => [id, entry])),
|
|
8513
|
+
])),
|
|
8514
|
+
};
|
|
8515
|
+
}
|
|
8365
8516
|
async _reviewAutoRefine(context, signal) {
|
|
8517
|
+
const harnessState = this._loadMergedHarnessState();
|
|
8518
|
+
const evidence = await this._autoRefineEvidence(harnessState);
|
|
8519
|
+
signal?.throwIfAborted();
|
|
8520
|
+
if (isDeepStrictEqual(evidence, this._lastAutoRefineEvidence))
|
|
8521
|
+
return { shouldRefine: false, rationale: "No new task evidence since the previous automatic review." };
|
|
8522
|
+
// Reserve before any inference wait. Equivalent running, declined or failed
|
|
8523
|
+
// automatic reviews do not buy another call; explicit /refine stays independent.
|
|
8524
|
+
this._lastAutoRefineEvidence = evidence;
|
|
8366
8525
|
if (this._autoRefineReviewer)
|
|
8367
8526
|
return this._autoRefineReviewer(context, signal);
|
|
8368
8527
|
const selected = this._resolveRefinementModel();
|
|
@@ -8370,7 +8529,6 @@ export class AgentSession {
|
|
|
8370
8529
|
return { shouldRefine: false, rationale: "No model selected." };
|
|
8371
8530
|
const { model, thinkingLevel, explicit } = selected;
|
|
8372
8531
|
const messages = structuredClone(this.agent.state.messages);
|
|
8373
|
-
const harnessState = this._loadMergedHarnessState();
|
|
8374
8532
|
const reviewContext = { ...context };
|
|
8375
8533
|
const requests = this.requests[captureNativeReviewerRequests]();
|
|
8376
8534
|
try {
|
|
@@ -8382,10 +8540,10 @@ export class AgentSession {
|
|
|
8382
8540
|
await requests.dispose();
|
|
8383
8541
|
}
|
|
8384
8542
|
}
|
|
8385
|
-
/**
|
|
8543
|
+
/** Merge existing session/global memory with the selected project's workspace memory. */
|
|
8386
8544
|
_loadMergedHarnessState() {
|
|
8387
8545
|
const localHarnessStateDir = this._localHarnessStateDir();
|
|
8388
|
-
return mergeHarnessStates(loadHarnessState(getGlobalHarnessStateDir(), "global"), localHarnessStateDir ? loadHarnessState(localHarnessStateDir, "local") : undefined);
|
|
8546
|
+
return mergeHarnessStates(loadHarnessState(getGlobalHarnessStateDir(), "global"), localHarnessStateDir ? loadHarnessState(localHarnessStateDir, "local") : undefined, loadHarnessState(getWorkspaceHarnessStateDir(this._cwd), "workspace"));
|
|
8389
8547
|
}
|
|
8390
8548
|
async _loadRefinementHistory() {
|
|
8391
8549
|
const limits = {
|
|
@@ -8843,7 +9001,21 @@ export class AgentSession {
|
|
|
8843
9001
|
}
|
|
8844
9002
|
if (!this._isCompactionOwnerCurrent(owner))
|
|
8845
9003
|
return false;
|
|
8846
|
-
|
|
9004
|
+
let assistantIsFromBeforeCompaction = compactionTimestamp !== undefined && assistantMessage.timestamp <= compactionTimestamp;
|
|
9005
|
+
const assistantEntryId = this._findAssistantEntryIdForMessage(assistantMessage);
|
|
9006
|
+
if (assistantEntryId && owner.manager.supportsCapturedHistoryReads()) {
|
|
9007
|
+
const ordered = await owner.manager.readBranchHistory(async (history) => {
|
|
9008
|
+
const assistant = await history.get(assistantEntryId);
|
|
9009
|
+
const boundary = (await history.branchBootstrap()).latestCompaction;
|
|
9010
|
+
return assistant && boundary ? assistant.sequence <= boundary.sequence : undefined;
|
|
9011
|
+
});
|
|
9012
|
+
if (!this._isCompactionOwnerCurrent(owner))
|
|
9013
|
+
return false;
|
|
9014
|
+
// Provider messages are timestamped before request preparation, which may
|
|
9015
|
+
// commit an epoch. Canonical append order, not that start time, owns staleness.
|
|
9016
|
+
if (ordered !== undefined)
|
|
9017
|
+
assistantIsFromBeforeCompaction = ordered;
|
|
9018
|
+
}
|
|
8847
9019
|
// Case 1: Overflow - takes priority over a pending model request so the error
|
|
8848
9020
|
// strip + retry still happen; the compaction it runs consumes the request.
|
|
8849
9021
|
if (!assistantIsFromBeforeCompaction &&
|
|
@@ -8881,6 +9053,8 @@ export class AgentSession {
|
|
|
8881
9053
|
if (contextTokens === undefined)
|
|
8882
9054
|
return false;
|
|
8883
9055
|
if (shouldCompact(contextTokens, contextWindow, settings)) {
|
|
9056
|
+
if (this._hasFailedThresholdCompaction())
|
|
9057
|
+
return false;
|
|
8884
9058
|
if (!this._pendingCheckpoint && queueAutonomousContinuation) {
|
|
8885
9059
|
if (!(await this._queueGoalContinuationForThresholdCompaction(assistantMessage, goalOwner)) &&
|
|
8886
9060
|
this._isGoalContinuationOwnerCurrent(goalOwner)) {
|
|
@@ -8935,7 +9109,7 @@ export class AgentSession {
|
|
|
8935
9109
|
this._emit({ type: "message_start", message: outcomeMessage });
|
|
8936
9110
|
this._emit({ type: "message_end", message: outcomeMessage });
|
|
8937
9111
|
}
|
|
8938
|
-
async _runAutoCompaction(reason, willRetry, capturedOwner, resumeInPlace = false) {
|
|
9112
|
+
async _runAutoCompaction(reason, willRetry, capturedOwner, resumeInPlace = false, capacity) {
|
|
8939
9113
|
const checkpoint = this._pendingCheckpoint;
|
|
8940
9114
|
const pending = this._pendingRequestedCompaction;
|
|
8941
9115
|
const owner = checkpoint?.owner ?? pending?.owner ?? capturedOwner ?? this._captureCompactionOwner();
|
|
@@ -8980,6 +9154,21 @@ export class AgentSession {
|
|
|
8980
9154
|
let compaction;
|
|
8981
9155
|
let committed;
|
|
8982
9156
|
let failure;
|
|
9157
|
+
const thresholdConfiguration = reason === "threshold" && !resumeInPlace
|
|
9158
|
+
? {
|
|
9159
|
+
configuration: this._thresholdCompactionConfiguration(),
|
|
9160
|
+
systemPrompt: this.agent.state.systemPrompt,
|
|
9161
|
+
tools: this.agent.state.tools,
|
|
9162
|
+
}
|
|
9163
|
+
: undefined;
|
|
9164
|
+
const rememberThresholdFailure = () => {
|
|
9165
|
+
if (thresholdConfiguration &&
|
|
9166
|
+
!abort.signal.aborted &&
|
|
9167
|
+
this._isCompactionOwnerCurrent(owner) &&
|
|
9168
|
+
compaction?.isCurrent()) {
|
|
9169
|
+
this._failedThresholdCompaction = { ...thresholdConfiguration, isCurrent: compaction.isCurrent };
|
|
9170
|
+
}
|
|
9171
|
+
};
|
|
8983
9172
|
try {
|
|
8984
9173
|
const selected = this._resolveCompactionModel();
|
|
8985
9174
|
const model = selected?.model;
|
|
@@ -9000,6 +9189,7 @@ export class AgentSession {
|
|
|
9000
9189
|
: authResult.error;
|
|
9001
9190
|
await this._endCompactionUnsuccessfully(reason, "failed", `Compaction failed: ${detail}`, { owner });
|
|
9002
9191
|
this._clearQueuedAutonomousContinuationsAfterSkippedThresholdCompaction(reason === "threshold" && shouldContinueAfterCompaction, queuedAutonomousContinuationsForThisCompaction);
|
|
9192
|
+
rememberThresholdFailure();
|
|
9003
9193
|
resumeAfterFailure();
|
|
9004
9194
|
return false;
|
|
9005
9195
|
}
|
|
@@ -9018,6 +9208,7 @@ export class AgentSession {
|
|
|
9018
9208
|
signal: abort.signal,
|
|
9019
9209
|
// Only confirmed public-budget recovery resumes within the same invocation.
|
|
9020
9210
|
budgetPressure: resumeInPlace,
|
|
9211
|
+
capacity,
|
|
9021
9212
|
});
|
|
9022
9213
|
const result = committed.result;
|
|
9023
9214
|
// Release this captured source before arming success. A later release failure still carries the ACK.
|
|
@@ -9075,6 +9266,7 @@ export class AgentSession {
|
|
|
9075
9266
|
? `Requested compaction failed: ${errorMessage}`
|
|
9076
9267
|
: `Auto-compaction failed: ${errorMessage}`, { customInstructions, owner });
|
|
9077
9268
|
}
|
|
9269
|
+
rememberThresholdFailure();
|
|
9078
9270
|
resumeAfterFailure();
|
|
9079
9271
|
return false;
|
|
9080
9272
|
}
|
|
@@ -9613,7 +9805,12 @@ export class AgentSession {
|
|
|
9613
9805
|
producer?.skillOwner?.writer.assertCurrent();
|
|
9614
9806
|
if (this.sessionManager !== manager)
|
|
9615
9807
|
throw new Error("Native recovery source changed");
|
|
9616
|
-
|
|
9808
|
+
const cursorSource = JSON.stringify([manager.getSessionId(), manager.getSessionFile()]);
|
|
9809
|
+
if (this._nativeRecoveryCursorSource !== cursorSource) {
|
|
9810
|
+
this._nativeRecoveryCursors.clear();
|
|
9811
|
+
this._nativeRecoveryCursorSource = cursorSource;
|
|
9812
|
+
}
|
|
9813
|
+
return await manager.readBranchHistory((history) => recoverCapturedHistory(history.branchContext, request, { ...DEFAULT_NATIVE_RECOVERY_LIMITS, maxBytes: responseBytes }, signal, this._nativeRecoveryCursors));
|
|
9617
9814
|
}
|
|
9618
9815
|
catch (error) {
|
|
9619
9816
|
signal?.throwIfAborted();
|
|
@@ -9762,6 +9959,7 @@ export class AgentSession {
|
|
|
9762
9959
|
BASE_CONTEXT_RLM_DEPTH: String(this._rlmDepth),
|
|
9763
9960
|
BASE_CONTEXT_RLM_MAX_DEPTH: String(this._rlmMaxDepth),
|
|
9764
9961
|
BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR: getGlobalHarnessStateDir(),
|
|
9962
|
+
BASE_CONTEXT_WORKSPACE_HARNESS_STATE_DIR: getWorkspaceHarnessStateDir(this._cwd),
|
|
9765
9963
|
};
|
|
9766
9964
|
const rlmSessionDir = this._ensureRlmSessionDir();
|
|
9767
9965
|
if (rlmSessionDir) {
|
|
@@ -9854,15 +10052,13 @@ export class AgentSession {
|
|
|
9854
10052
|
if (message?.role !== "assistant")
|
|
9855
10053
|
return;
|
|
9856
10054
|
if (this.sessionManager.isPersisted()) {
|
|
9857
|
-
const
|
|
9858
|
-
if (!
|
|
9859
|
-
acknowledged.sessionId !== this.sessionId ||
|
|
9860
|
-
acknowledged.sessionFile !== this.sessionFile)
|
|
10055
|
+
const entryId = this._findAssistantEntryIdForMessage(message);
|
|
10056
|
+
if (!entryId)
|
|
9861
10057
|
throw new Error("Cannot identify the acknowledged assistant response removed by retry control");
|
|
9862
10058
|
if (this._contextOmissions?.sessionId !== this.sessionId ||
|
|
9863
10059
|
this._contextOmissions?.sessionFile !== this.sessionFile)
|
|
9864
10060
|
this._contextOmissions = { sessionId: this.sessionId, sessionFile: this.sessionFile, ids: new Set() };
|
|
9865
|
-
this._contextOmissions.ids.add(
|
|
10061
|
+
this._contextOmissions.ids.add(entryId);
|
|
9866
10062
|
}
|
|
9867
10063
|
this.agent.state.messages = messages.slice(0, -1);
|
|
9868
10064
|
}
|