@ponythewhite/base-context 1.0.10 → 1.0.12
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 +22 -0
- package/dist/base-context-runtime/pyproject.toml +1 -1
- 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-5PSCZEER.js → anthropic-BJVPUMPB.js} +2 -2
- package/dist/bundle/{azure-openai-responses-AYTLJR33.js → azure-openai-responses-ERRMAXK6.js} +4 -5
- package/dist/bundle/{bundled-modules-MX6YNAM2.js → bundled-modules-WCGPZI2H.js} +5 -5
- package/dist/bundle/{chunk-D3KOF57W.js → chunk-25VYRAC6.js} +14 -1
- package/dist/bundle/{chunk-2IPDSTDR.js → chunk-AEMRBMI2.js} +9 -9
- package/dist/bundle/{chunk-Q3MBSBEB.js → chunk-FOGKLC7V.js} +1 -1
- package/dist/bundle/{chunk-UHLGPYMI.js → chunk-IAKHCQA2.js} +185 -39
- package/dist/bundle/{chunk-KT2BNEPE.js → chunk-MUFZODP5.js} +1 -1
- package/dist/bundle/{chunk-QKIFBA7N.js → chunk-Q6UAHLII.js} +2 -2
- package/dist/bundle/{chunk-CDXQNS5P.js → chunk-YGV3Y4AD.js} +1009 -185
- package/dist/bundle/{cli-main-D7W3WWCV.js → cli-main-CTYDQHFE.js} +4 -4
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/{google-HTMCUJ7X.js → google-4GA4YMUX.js} +2 -2
- package/dist/bundle/{google-vertex-ZQO65AXF.js → google-vertex-7AMALD7D.js} +2 -2
- package/dist/bundle/{main-5J3QBZ5Y.js → main-GVGK354K.js} +5 -5
- package/dist/bundle/{mistral-SB7LU56G.js → mistral-74BXMNRM.js} +1 -1
- package/dist/bundle/{openai-codex-responses-5CEW4VN3.js → openai-codex-responses-COXNC4IH.js} +2 -2
- package/dist/bundle/{openai-completions-BAZJQSS2.js → openai-completions-BCSA5Q6S.js} +2 -2
- package/dist/bundle/{openai-responses-VHOE427P.js → openai-responses-ONCIZSJS.js} +3 -3
- package/dist/core/agent-session.d.ts +6 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +445 -146
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/canonical-context.d.ts +19 -3
- package/dist/core/canonical-context.d.ts.map +1 -1
- package/dist/core/canonical-context.js +130 -9
- package/dist/core/canonical-context.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +9 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +29 -3
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/context-epoch-copy.d.ts +1 -1
- package/dist/core/context-epoch-copy.d.ts.map +1 -1
- package/dist/core/context-epoch-copy.js +18 -7
- package/dist/core/context-epoch-copy.js.map +1 -1
- package/dist/core/context-epoch.d.ts +4 -0
- package/dist/core/context-epoch.d.ts.map +1 -1
- package/dist/core/context-epoch.js +8 -1
- package/dist/core/context-epoch.js.map +1 -1
- package/dist/core/context-tree.d.ts +14 -11
- package/dist/core/context-tree.d.ts.map +1 -1
- package/dist/core/context-tree.js +145 -9
- package/dist/core/context-tree.js.map +1 -1
- package/dist/core/history-index-worker.d.ts.map +1 -1
- package/dist/core/history-index-worker.js +59 -6
- package/dist/core/history-index-worker.js.map +1 -1
- package/dist/core/history-index.d.ts +17 -0
- package/dist/core/history-index.d.ts.map +1 -1
- package/dist/core/history-index.js +22 -0
- 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 +23 -6
- package/dist/core/inference-coordinator.js.map +1 -1
- package/dist/core/messages.d.ts +2 -0
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +2 -0
- package/dist/core/messages.js.map +1 -1
- package/dist/core/refinement/refinement.d.ts +2 -0
- package/dist/core/refinement/refinement.d.ts.map +1 -1
- package/dist/core/refinement/refinement.js +10 -1
- package/dist/core/refinement/refinement.js.map +1 -1
- package/dist/core/request-usage.d.ts +34 -0
- package/dist/core/request-usage.d.ts.map +1 -0
- package/dist/core/request-usage.js +111 -0
- package/dist/core/request-usage.js.map +1 -0
- package/dist/core/request-view-selection.d.ts +2 -1
- package/dist/core/request-view-selection.d.ts.map +1 -1
- package/dist/core/request-view-selection.js +29 -2
- package/dist/core/request-view-selection.js.map +1 -1
- package/dist/core/session-fork-messages.d.ts +5 -0
- package/dist/core/session-fork-messages.d.ts.map +1 -1
- package/dist/core/session-fork-messages.js +44 -0
- package/dist/core/session-fork-messages.js.map +1 -1
- package/dist/core/session-history-index.d.ts +5 -0
- package/dist/core/session-history-index.d.ts.map +1 -1
- package/dist/core/session-history-index.js +7 -0
- 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 +155 -13
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-tree.d.ts +9 -0
- package/dist/core/session-tree.d.ts.map +1 -1
- package/dist/core/session-tree.js +71 -11
- package/dist/core/session-tree.js.map +1 -1
- package/dist/core/settings-manager.d.ts +3 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +7 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/system-prompt.d.ts +2 -0
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +4 -2
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/modes/agent-connection/daemon-agent-connection.d.ts.map +1 -1
- package/dist/modes/agent-connection/daemon-agent-connection.js +8 -1
- package/dist/modes/agent-connection/daemon-agent-connection.js.map +1 -1
- package/dist/modes/agent-connection/in-process-agent-connection.d.ts.map +1 -1
- package/dist/modes/agent-connection/in-process-agent-connection.js +4 -4
- package/dist/modes/agent-connection/in-process-agent-connection.js.map +1 -1
- package/dist/modes/daemon/daemon-mode.d.ts.map +1 -1
- package/dist/modes/daemon/daemon-mode.js +4 -4
- package/dist/modes/daemon/daemon-mode.js.map +1 -1
- package/dist/modes/daemon/daemon-protocol.d.ts +13 -3
- package/dist/modes/daemon/daemon-protocol.d.ts.map +1 -1
- package/dist/modes/daemon/daemon-protocol.js +10 -2
- package/dist/modes/daemon/daemon-protocol.js.map +1 -1
- package/dist/modes/daemon/daemon-session-summarizer.d.ts +3 -0
- package/dist/modes/daemon/daemon-session-summarizer.d.ts.map +1 -1
- package/dist/modes/daemon/daemon-session-summarizer.js +71 -32
- package/dist/modes/daemon/daemon-session-summarizer.js.map +1 -1
- package/dist/modes/interactive/components/context-tree-format.d.ts.map +1 -1
- package/dist/modes/interactive/components/context-tree-format.js +49 -0
- package/dist/modes/interactive/components/context-tree-format.js.map +1 -1
- package/docs/compaction.md +27 -3
- package/docs/context-management.md +17 -1
- package/docs/rlm.md +1 -1
- package/docs/settings.md +12 -0
- package/docs/usage.md +24 -1
- package/package.json +4 -4
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
typebox_exports,
|
|
33
33
|
validateToolArguments,
|
|
34
34
|
waitForChildProcess
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-AEMRBMI2.js";
|
|
36
36
|
import {
|
|
37
37
|
cleanupSessionResources,
|
|
38
38
|
registerSessionResourceCleanup
|
|
@@ -67,7 +67,7 @@ import {
|
|
|
67
67
|
requestTokenRouteIdentity,
|
|
68
68
|
supportsFastMode,
|
|
69
69
|
withRequestBody
|
|
70
|
-
} from "./chunk-
|
|
70
|
+
} from "./chunk-25VYRAC6.js";
|
|
71
71
|
import {
|
|
72
72
|
__commonJS,
|
|
73
73
|
__export,
|
|
@@ -10887,8 +10887,8 @@ var DAEMON_PROTOCOL_NAME = PRODUCT.daemonService;
|
|
|
10887
10887
|
var DAEMON_PROTOCOL_VERSION = 13;
|
|
10888
10888
|
var DAEMON_LEGACY_INSPECTION_PROTOCOL_VERSIONS = [8, 9, 10];
|
|
10889
10889
|
var DAEMON_COMMAND_ENVELOPE_MIN_PROTOCOL_VERSION = 8;
|
|
10890
|
-
var DAEMON_SCHEMA_REVISION =
|
|
10891
|
-
var DAEMON_SCHEMA_ID = "protocol-13-schema-
|
|
10890
|
+
var DAEMON_SCHEMA_REVISION = 50;
|
|
10891
|
+
var DAEMON_SCHEMA_ID = "protocol-13-schema-50-context-request-usage";
|
|
10892
10892
|
var DAEMON_PROTOCOL_INFO = {
|
|
10893
10893
|
name: DAEMON_PROTOCOL_NAME,
|
|
10894
10894
|
version: DAEMON_PROTOCOL_VERSION
|
|
@@ -10913,6 +10913,7 @@ var DAEMON_DEFAULT_SERVER_CAPABILITIES = [
|
|
|
10913
10913
|
"cron_resume",
|
|
10914
10914
|
"agent_results",
|
|
10915
10915
|
"model_catalog",
|
|
10916
|
+
"context_request_usage",
|
|
10916
10917
|
"side_question_transcript",
|
|
10917
10918
|
"transient_bash",
|
|
10918
10919
|
"session_input_admission",
|
|
@@ -27790,6 +27791,12 @@ function readContextEpoch(details, maxBytes) {
|
|
|
27790
27791
|
throw new Error("Invalid committed context epoch");
|
|
27791
27792
|
return snapshotContextEpoch(value, maxBytes);
|
|
27792
27793
|
}
|
|
27794
|
+
var UnsupportedContextEpochConfigurationError = class extends Error {
|
|
27795
|
+
constructor() {
|
|
27796
|
+
super("Unsupported context epoch request configuration");
|
|
27797
|
+
this.name = "UnsupportedContextEpochConfigurationError";
|
|
27798
|
+
}
|
|
27799
|
+
};
|
|
27793
27800
|
function contextEpochRepresentation(request, assessment, maxBytes, unbudgetedPublic = false, responseItemIdentity) {
|
|
27794
27801
|
if (!assessment && !unbudgetedPublic || assessment && (!assessment.profile || assessment.limitSource !== "explicit-profile" || !assessment.route || !assessment.model) || request.body === void 0)
|
|
27795
27802
|
throw new Error("Committed context epoch requires its explicit request profile");
|
|
@@ -27827,7 +27834,7 @@ function contextEpochRepresentation(request, assessment, maxBytes, unbudgetedPub
|
|
|
27827
27834
|
if (["input", "messages", "previous_response_id", "prompt_cache_key"].includes(key2))
|
|
27828
27835
|
continue;
|
|
27829
27836
|
if (!fields.has(key2))
|
|
27830
|
-
throw new
|
|
27837
|
+
throw new UnsupportedContextEpochConfigurationError();
|
|
27831
27838
|
configuration[key2] = value;
|
|
27832
27839
|
}
|
|
27833
27840
|
const input = "input" in body ? body.input : "messages" in body ? body.messages : void 0;
|
|
@@ -28079,6 +28086,7 @@ var SESSION_SLASH_COMMAND_CUSTOM_TYPE = "session_slash_command";
|
|
|
28079
28086
|
var SESSION_SLASH_COMMAND_RESULT_CUSTOM_TYPE = "session_slash_command_result";
|
|
28080
28087
|
var COMPACTION_OUTCOME_CUSTOM_TYPE = "compaction_outcome";
|
|
28081
28088
|
var REFINEMENT_OUTCOME_CUSTOM_TYPE = "refinement_outcome";
|
|
28089
|
+
var HARNESS_SNAPSHOT_CUSTOM_TYPE = "harness_snapshot";
|
|
28082
28090
|
var RLM_CHILD_FAILURE_CUSTOM_TYPE = "rlm_child_failure";
|
|
28083
28091
|
var RLM_CHILD_TERMINAL_NOTICE_CUSTOM_TYPE = "rlm_child_terminal_notice";
|
|
28084
28092
|
function createRlmChildFailureMessage(details, timestamp = Date.now()) {
|
|
@@ -29066,6 +29074,15 @@ var HistoryIndex = class _HistoryIndex {
|
|
|
29066
29074
|
snapshot: target
|
|
29067
29075
|
});
|
|
29068
29076
|
}
|
|
29077
|
+
/** Whole-source own usage for exactly the current acknowledged owner snapshot. */
|
|
29078
|
+
async currentSourceUsage(sessionId, snapshot) {
|
|
29079
|
+
return await this.request({
|
|
29080
|
+
id: this.nextId++,
|
|
29081
|
+
action: "current_source_usage",
|
|
29082
|
+
sessionId,
|
|
29083
|
+
snapshot
|
|
29084
|
+
});
|
|
29085
|
+
}
|
|
29069
29086
|
/** Latest label control for this source target, including a clear. */
|
|
29070
29087
|
async sourceLabel(sessionId, targetId, through) {
|
|
29071
29088
|
return await this.request({ id: this.nextId++, action: "source_label", sessionId, targetId, through });
|
|
@@ -29080,6 +29097,17 @@ var HistoryIndex = class _HistoryIndex {
|
|
|
29080
29097
|
through
|
|
29081
29098
|
});
|
|
29082
29099
|
}
|
|
29100
|
+
/** All matching source update refs, including off-branch and older revisions. */
|
|
29101
|
+
async sourceContextUpdates(sessionId, target, through, after = 0) {
|
|
29102
|
+
return await this.request({
|
|
29103
|
+
id: this.nextId++,
|
|
29104
|
+
action: "source_context_updates",
|
|
29105
|
+
sessionId,
|
|
29106
|
+
target: target.kind === "assistant-usage" ? { kind: target.kind, targetId: target.targetId } : { kind: target.kind, toolCallId: target.toolCallId },
|
|
29107
|
+
through,
|
|
29108
|
+
after
|
|
29109
|
+
});
|
|
29110
|
+
}
|
|
29083
29111
|
async get(sessionId, eventId, scope) {
|
|
29084
29112
|
return await this.request({
|
|
29085
29113
|
id: this.nextId++,
|
|
@@ -29402,6 +29430,7 @@ function createSessionHistoryReadScope(index, source, query, scope) {
|
|
|
29402
29430
|
}),
|
|
29403
29431
|
sourceLabel: (targetId) => query(() => index.sourceLabel(sessionId, targetId, source.sourceSequence)),
|
|
29404
29432
|
sourceAssistantUsage: (targetId) => query(() => index.sourceAssistantUsage(sessionId, targetId, source.sourceSequence)),
|
|
29433
|
+
sourceContextUpdates: (target, after = 0) => query(() => index.sourceContextUpdates(sessionId, target, source.sourceSequence, after)),
|
|
29405
29434
|
ipythonSentMessages: (toolCallId, options = {}) => query(() => index.ipythonSentMessages(sessionId, branch, toolCallId, options)),
|
|
29406
29435
|
get,
|
|
29407
29436
|
page,
|
|
@@ -29495,6 +29524,12 @@ var SessionHistoryIndex = class {
|
|
|
29495
29524
|
const index = await this.synchronize(captured);
|
|
29496
29525
|
return index.currentSourceBootstrap(this.sessionId, captured);
|
|
29497
29526
|
}
|
|
29527
|
+
/** Caller holds the owner queue until the exact current projection is read. */
|
|
29528
|
+
async currentSourceUsage(snapshot) {
|
|
29529
|
+
const captured = { ...snapshot };
|
|
29530
|
+
const index = await this.synchronize(captured);
|
|
29531
|
+
return index.currentSourceUsage(this.sessionId, captured);
|
|
29532
|
+
}
|
|
29498
29533
|
/** Finish accepted indexing, then wait for the external worker to close. */
|
|
29499
29534
|
close() {
|
|
29500
29535
|
this.closing ??= (async () => {
|
|
@@ -31574,7 +31609,19 @@ function prepareCanonicalEpoch(messages, selectedUnitIds, representation, maxByt
|
|
|
31574
31609
|
messages: chosen
|
|
31575
31610
|
};
|
|
31576
31611
|
}
|
|
31577
|
-
|
|
31612
|
+
var MissingRecoveryReplayContractError = class extends Error {
|
|
31613
|
+
constructor() {
|
|
31614
|
+
super("Recovery compaction requires an accepted replay contract for its selected results");
|
|
31615
|
+
this.name = "MissingRecoveryReplayContractError";
|
|
31616
|
+
}
|
|
31617
|
+
};
|
|
31618
|
+
function sameRecoverySource(left, right, ownerStillCurrent = false) {
|
|
31619
|
+
return JSON.stringify(left) === JSON.stringify(right) || ownerStillCurrent && left.sessionId === right.sessionId && left.sessionFile === right.sessionFile && left.persistent === right.persistent;
|
|
31620
|
+
}
|
|
31621
|
+
function sameRecoveryReference(left, right, ownerStillCurrent = false) {
|
|
31622
|
+
return sameRecoverySource(left.source, right.source, ownerStillCurrent) && JSON.stringify(left.ref) === JSON.stringify(right.ref) && left.sourceRevision === right.sourceRevision;
|
|
31623
|
+
}
|
|
31624
|
+
function canonicalRecoveryBoundary(messages, authorization) {
|
|
31578
31625
|
const context = compiledEpochContexts.get(messages);
|
|
31579
31626
|
const units = getCanonicalViewUnits(messages);
|
|
31580
31627
|
if (!context || !units)
|
|
@@ -31584,15 +31631,22 @@ function canonicalRecoveryBoundary(messages) {
|
|
|
31584
31631
|
const recoveries = units.flatMap((unit, index) => unit.kind === "recovery" ? [context.references[index]] : []);
|
|
31585
31632
|
if (!recoveries.length)
|
|
31586
31633
|
return;
|
|
31634
|
+
if (authorization) {
|
|
31635
|
+
const ownerStillCurrent = authorization.isSourceCurrent?.();
|
|
31636
|
+
if (ownerStillCurrent === false || !sameRecoverySource(context.source, authorization.source, ownerStillCurrent === true) || context.resourceRevision !== authorization.resourceRevision || recoveries.length !== authorization.recoveries.length || recoveries.some((reference) => !reference || !authorization.recoveries.some((covered) => sameRecoveryReference(reference, covered, ownerStillCurrent === true))))
|
|
31637
|
+
throw new Error("Recovery compaction authorization no longer matches its captured source");
|
|
31638
|
+
return latestLiteralReference(context.references)?.ref.entryId;
|
|
31639
|
+
}
|
|
31587
31640
|
const checkpoint = context.checkpoint;
|
|
31588
|
-
|
|
31589
|
-
|
|
31641
|
+
const inherited = checkpoint?.includeSummary === true && checkpoint.replayContract === "message-groups";
|
|
31642
|
+
if (checkpoint?.replayContract !== "message-groups" || recoveries.some((reference) => !reference || (checkpoint.representation ? reference.ref.sequence > checkpoint.source.sourceSequence : !inherited || !context.inheritedRecoveryCoverage?.some((covered) => sameRecoveryReference(reference, covered)))))
|
|
31643
|
+
throw new MissingRecoveryReplayContractError();
|
|
31590
31644
|
return checkpoint.literalTailId;
|
|
31591
31645
|
}
|
|
31592
|
-
function prepareRecoveryCompaction(messages, firstKeptEntryId, maxBytes) {
|
|
31593
|
-
const boundary = canonicalRecoveryBoundary(messages);
|
|
31646
|
+
function prepareRecoveryCompaction(messages, firstKeptEntryId, maxBytes, authorization) {
|
|
31647
|
+
const boundary = canonicalRecoveryBoundary(messages, authorization);
|
|
31594
31648
|
const context = compiledEpochContexts.get(messages);
|
|
31595
|
-
const publicWindow = context?.checkpoint?.publicWindow === true && context.checkpoint.replayContract === "message-groups";
|
|
31649
|
+
const publicWindow = authorization ? authorization.publicWindow : context?.checkpoint?.publicWindow === true && context.checkpoint.replayContract === "message-groups";
|
|
31596
31650
|
if (!boundary && !publicWindow && !context?.selectedSkills?.length && !context?.toolContinuations?.length)
|
|
31597
31651
|
return;
|
|
31598
31652
|
if (!context)
|
|
@@ -31676,7 +31730,7 @@ var CanonicalContextCompiler = class {
|
|
|
31676
31730
|
hasActiveEntry(entryId) {
|
|
31677
31731
|
return this.entries.has(entryId);
|
|
31678
31732
|
}
|
|
31679
|
-
async compile(view, limits, omittedAssistantIds = /* @__PURE__ */ new Set(), frameOptions = {}, resourceCapture, initialContextMode = "on", allowPendingToolPublic = false,
|
|
31733
|
+
async compile(view, limits, omittedAssistantIds = /* @__PURE__ */ new Set(), frameOptions = {}, resourceCapture, initialContextMode = "on", allowPendingToolPublic = false, purpose2 = "request") {
|
|
31680
31734
|
const generation = this.generation;
|
|
31681
31735
|
const frameLimits = taskFrameLimits(frameOptions);
|
|
31682
31736
|
const previousSource = this.source;
|
|
@@ -31814,7 +31868,7 @@ var CanonicalContextCompiler = class {
|
|
|
31814
31868
|
const referenceFrame = resetFrame ? checkpoint?.taskFrame : previousFrame;
|
|
31815
31869
|
if (resetFrame || referenceFrame && referenceFrame.messages.length <= 1)
|
|
31816
31870
|
this.forceTaskFrameRebase = false;
|
|
31817
|
-
const forceRebase =
|
|
31871
|
+
const forceRebase = purpose2 === "request" && this.forceTaskFrameRebase;
|
|
31818
31872
|
let taskFrame = tasks ? compileTaskFrame(tasks, frameLimits, forceRebase ? void 0 : referenceFrame) : void 0;
|
|
31819
31873
|
const taskFrameRebased = Boolean(mode === "on" && referenceFrame && taskFrame !== referenceFrame && (!taskFrame || taskFrame.messages.length === 1));
|
|
31820
31874
|
const resource = mode === "on" && resourceCapture && (resourceCapture.enabled || checkpoint) ? renderResourceView(resourceCapture) : void 0;
|
|
@@ -32146,7 +32200,7 @@ ${JSON.stringify(selections.map((skill) => ({
|
|
|
32146
32200
|
});
|
|
32147
32201
|
if (frozenGroups.length !== candidates.filter((candidate) => candidate.prior).length)
|
|
32148
32202
|
throw new Error("Committed tool continuation lost its original group");
|
|
32149
|
-
if (
|
|
32203
|
+
if (purpose2 === "request" && candidates.length && (!allowPendingToolPublic || mode === "off"))
|
|
32150
32204
|
throw new Error("Tool continuation requires an enabled native public request boundary");
|
|
32151
32205
|
const readToolEvidence = async (metadata) => {
|
|
32152
32206
|
const cached = next.get(metadata.id);
|
|
@@ -32324,11 +32378,84 @@ ${JSON.stringify(selections.map((skill) => ({
|
|
|
32324
32378
|
units: selectionUnits,
|
|
32325
32379
|
limits: unitLimits,
|
|
32326
32380
|
...mode === "on" && (taskFrameRebased || checkpoint) ? { requiresEpoch: true } : {},
|
|
32381
|
+
...mode === "on" && sourceUnits.some((unit) => unit.kind === "recovery") ? { recoveryContractRequested: true } : {},
|
|
32327
32382
|
...pendingPublicMessageGroups.length ? { pendingPublicMessageGroups } : {}
|
|
32328
32383
|
}
|
|
32329
32384
|
});
|
|
32385
|
+
const inheritedRecoveryCoverage = [];
|
|
32386
|
+
if (checkpoint?.includeSummary && checkpoint.replayContract === "message-groups" && closedUnits.some((unit) => unit.kind === "recovery")) {
|
|
32387
|
+
const prefix = await view.atSnapshot(checkpoint.source);
|
|
32388
|
+
const suffix = /* @__PURE__ */ new Map();
|
|
32389
|
+
const frozenViews = /* @__PURE__ */ new Map();
|
|
32390
|
+
let capturedMessages = 0;
|
|
32391
|
+
let retained = false;
|
|
32392
|
+
let cursor2;
|
|
32393
|
+
for (; ; ) {
|
|
32394
|
+
const page = await prefix.contextManifest({ cursor: cursor2, limit: 128 });
|
|
32395
|
+
if (page.selection !== "known")
|
|
32396
|
+
throw new Error("Summary recovery source is unavailable");
|
|
32397
|
+
if (!cursor2 && page.summaryRef) {
|
|
32398
|
+
const entry = await hydrate(page.summaryRef, void 0, prefix);
|
|
32399
|
+
const metadata = await prefix.get(page.summaryRef.entryId);
|
|
32400
|
+
const prior = entry.type === "compaction" && metadata?.qualification === "native-context-epoch" && metadata.retention !== "retained-import" ? readContextEpoch(entry.details, maxSourceBytes) : void 0;
|
|
32401
|
+
if ((!prior || prior.includeSummary) && page.summaryRef.entryId === checkpoint.literalTailId)
|
|
32402
|
+
retained = true;
|
|
32403
|
+
capturedMessages += prior?.views.length ?? 0;
|
|
32404
|
+
for (const pinned of prior?.views ?? []) {
|
|
32405
|
+
if (pinned.ref.entryId === checkpoint.literalTailId)
|
|
32406
|
+
retained = true;
|
|
32407
|
+
if (retained) {
|
|
32408
|
+
suffix.set(pinned.ref.entryId, pinned.ref);
|
|
32409
|
+
frozenViews.set(pinned.ref.entryId, pinned);
|
|
32410
|
+
}
|
|
32411
|
+
}
|
|
32412
|
+
}
|
|
32413
|
+
for (const ref of page.refs) {
|
|
32414
|
+
if (ref.entryId === checkpoint.literalTailId)
|
|
32415
|
+
retained = true;
|
|
32416
|
+
if (retained)
|
|
32417
|
+
suffix.set(ref.entryId, ref);
|
|
32418
|
+
}
|
|
32419
|
+
capturedMessages += page.refs.length;
|
|
32420
|
+
if (capturedMessages > maxMessages)
|
|
32421
|
+
throw new Error("Summary recovery source exceeds its message budget");
|
|
32422
|
+
if (!page.nextCursor)
|
|
32423
|
+
break;
|
|
32424
|
+
cursor2 = page.nextCursor;
|
|
32425
|
+
}
|
|
32426
|
+
for (const [index, message2] of closedMessages.entries()) {
|
|
32427
|
+
if (closedUnits[index].kind !== "recovery")
|
|
32428
|
+
continue;
|
|
32429
|
+
const reference = epochReferences.get(message2);
|
|
32430
|
+
if (checkpoint.views.some((covered) => sameRecoveryReference(reference, covered))) {
|
|
32431
|
+
inheritedRecoveryCoverage.push(reference);
|
|
32432
|
+
continue;
|
|
32433
|
+
}
|
|
32434
|
+
const frozen = suffix.get(reference.ref.entryId);
|
|
32435
|
+
if (!frozen || JSON.stringify(frozen) !== JSON.stringify(reference.ref))
|
|
32436
|
+
continue;
|
|
32437
|
+
const pinned = frozenViews.get(frozen.entryId);
|
|
32438
|
+
if (pinned) {
|
|
32439
|
+
if (reference.sourceRevision === pinned.sourceRevision)
|
|
32440
|
+
inheritedRecoveryCoverage.push(reference);
|
|
32441
|
+
continue;
|
|
32442
|
+
}
|
|
32443
|
+
const revisions = [frozen.revision];
|
|
32444
|
+
const entry = next.get(frozen.entryId)?.entry;
|
|
32445
|
+
if (entry?.type === "message" && entry.message.role === "toolResult" && entry.message.toolName === "ipython") {
|
|
32446
|
+
const updates = await prefix.contextUpdates({
|
|
32447
|
+
kind: "ipython-sent-message",
|
|
32448
|
+
toolCallId: entry.message.toolCallId
|
|
32449
|
+
});
|
|
32450
|
+
revisions.push(...updates.refs.map((update) => update.revision));
|
|
32451
|
+
}
|
|
32452
|
+
if (reference.sourceRevision === JSON.stringify(revisions))
|
|
32453
|
+
inheritedRecoveryCoverage.push(reference);
|
|
32454
|
+
}
|
|
32455
|
+
}
|
|
32330
32456
|
compiledEpochContexts.set(closedMessages, {
|
|
32331
|
-
...
|
|
32457
|
+
...inheritedRecoveryCoverage.length ? { inheritedRecoveryCoverage } : {},
|
|
32458
|
+
...purpose2 === "read" ? { readOnly: true } : {},
|
|
32332
32459
|
mode,
|
|
32333
32460
|
source: { ...view.source },
|
|
32334
32461
|
checkpoint,
|
|
@@ -32348,7 +32475,7 @@ ${JSON.stringify(selections.map((skill) => ({
|
|
|
32348
32475
|
this.source = view.source;
|
|
32349
32476
|
this.sourceBytes = sourceBytes;
|
|
32350
32477
|
this.messageCount = messageCount;
|
|
32351
|
-
return
|
|
32478
|
+
return purpose2 === "read" && pendingPublicMessageGroups.length ? renderToolContinuationWindow(closedMessages).messages : closedMessages;
|
|
32352
32479
|
}
|
|
32353
32480
|
};
|
|
32354
32481
|
|
|
@@ -32381,6 +32508,10 @@ var PublicContextBudgetError = class extends RequestTokenBudgetError {
|
|
|
32381
32508
|
this.#summaryCapacity = summaryCapacity;
|
|
32382
32509
|
}
|
|
32383
32510
|
};
|
|
32511
|
+
var recoveryCompactionAuthorizations = /* @__PURE__ */ new WeakMap();
|
|
32512
|
+
function getRecoveryCompactionAuthorization(error) {
|
|
32513
|
+
return error ? recoveryCompactionAuthorizations.get(error) : void 0;
|
|
32514
|
+
}
|
|
32384
32515
|
function captureRequestViewBoundary(messages, commit, validate2, fixedPrepare, isSourceCurrent) {
|
|
32385
32516
|
const source = getCanonicalViewSelectionSource(messages);
|
|
32386
32517
|
if (!source)
|
|
@@ -32479,7 +32610,7 @@ function publicBudgetFailure(boundary, messages, request, projection, budget, as
|
|
|
32479
32610
|
});
|
|
32480
32611
|
};
|
|
32481
32612
|
const minimum = withRequestBody(request, JSON.stringify({ ...body, [inputKey]: retainedInput(/* @__PURE__ */ new Set()) }));
|
|
32482
|
-
|
|
32613
|
+
const error = new PublicContextBudgetError(boundary.source, assessment, original, budget.measure(minimum), (context.taskFrame?.messages.length ?? 0) > 1, JSON.stringify([
|
|
32483
32614
|
boundary.source.sessionId,
|
|
32484
32615
|
boundary.source.sessionFile,
|
|
32485
32616
|
source.units.map((unit) => [unit.id, unit.sourceRevision]),
|
|
@@ -32498,6 +32629,21 @@ function publicBudgetFailure(boundary, messages, request, projection, budget, as
|
|
|
32498
32629
|
const measured = budget.measure(withRequestBody(request, JSON.stringify({ ...body, [inputKey]: kept })));
|
|
32499
32630
|
return measured.status === "unknown" || measured.availableInputTokens === null || measured.estimatedInputTokens === null ? void 0 : Math.floor(measured.availableInputTokens - measured.estimatedInputTokens);
|
|
32500
32631
|
}, boundary.isSourceCurrent);
|
|
32632
|
+
if (projection.replayContract === "message-groups") {
|
|
32633
|
+
const originalContext = getCanonicalEpochContext(boundary.messages);
|
|
32634
|
+
const recoveries = boundary.units.flatMap((unit, index) => unit.kind === "recovery" && originalContext.references[index] ? [originalContext.references[index]] : []);
|
|
32635
|
+
if (recoveries.length) {
|
|
32636
|
+
recoveryCompactionAuthorizations.set(error, {
|
|
32637
|
+
source: originalContext.source,
|
|
32638
|
+
recoveries,
|
|
32639
|
+
resourceRevision: originalContext.resourceRevision,
|
|
32640
|
+
// Do not extend a partial public conversion to native groups the encoder did not replace.
|
|
32641
|
+
publicWindow: messages !== boundary.messages && projection.publicWindow === true && boundary.units.every((unit, index) => !["recovery", "replay-group"].includes(unit.kind) || context.references[index]?.rendering !== void 0),
|
|
32642
|
+
isSourceCurrent: boundary.isSourceCurrent
|
|
32643
|
+
});
|
|
32644
|
+
}
|
|
32645
|
+
}
|
|
32646
|
+
return error;
|
|
32501
32647
|
}
|
|
32502
32648
|
async function prepareFixedRequestView(boundary, request, projection, assessment) {
|
|
32503
32649
|
projection = canonicalRequestProjection(boundary, projection);
|
|
@@ -32570,7 +32716,7 @@ async function selectRequestView(boundary, request, projection, budget, allowShr
|
|
|
32570
32716
|
const inputKey = requestInputKey(request, projection);
|
|
32571
32717
|
if (budget && full?.limitSource !== "explicit-profile" || !inputKey)
|
|
32572
32718
|
return;
|
|
32573
|
-
if (!budget && !boundary.requiresEpoch && !boundary.pendingPublicMessageGroups?.length)
|
|
32719
|
+
if (!budget && !boundary.requiresEpoch && !boundary.recoveryContractRequested && !boundary.pendingPublicMessageGroups?.length)
|
|
32574
32720
|
return;
|
|
32575
32721
|
const payload = JSON.parse(request.body);
|
|
32576
32722
|
const input = payload[inputKey];
|
|
@@ -32999,6 +33145,9 @@ function wrapStreamFnWithSemanticEdges(streamFn, recorder) {
|
|
|
32999
33145
|
}
|
|
33000
33146
|
|
|
33001
33147
|
// dist/core/inference-coordinator.js
|
|
33148
|
+
function isPrimaryRequest(purpose2) {
|
|
33149
|
+
return purpose2 === "main" || purpose2 === "child";
|
|
33150
|
+
}
|
|
33002
33151
|
var REQUEST_STREAM_BINDING = /* @__PURE__ */ Symbol("base-context.request-stream-binding");
|
|
33003
33152
|
var captureNativeCompactionRequests = /* @__PURE__ */ Symbol("base-context.native-compaction-requests");
|
|
33004
33153
|
var captureNativeBranchRequests = /* @__PURE__ */ Symbol("base-context.native-branch-requests");
|
|
@@ -33230,7 +33379,7 @@ var InferenceCoordinator = class _InferenceCoordinator {
|
|
|
33230
33379
|
this.notifyActivity();
|
|
33231
33380
|
return captured;
|
|
33232
33381
|
}
|
|
33233
|
-
/** Explicit
|
|
33382
|
+
/** Explicit session-owned epoch boundary, on this same captured primary source only. */
|
|
33234
33383
|
bindRequestViewBoundary(messages, commit, validate2, fixedPrepare, isSourceCurrent) {
|
|
33235
33384
|
this.assertAdmission();
|
|
33236
33385
|
if (!this.capturedSink)
|
|
@@ -33448,7 +33597,7 @@ var InferenceCoordinator = class _InferenceCoordinator {
|
|
|
33448
33597
|
activeUser = true;
|
|
33449
33598
|
this.releaseCapture();
|
|
33450
33599
|
this.finishCapturePending?.();
|
|
33451
|
-
if (this.work.budget || this.requestViewBoundary && operation.metadata.purpose
|
|
33600
|
+
if (this.work.budget || this.requestViewBoundary && isPrimaryRequest(operation.metadata.purpose)) {
|
|
33452
33601
|
model = structuredClone(model);
|
|
33453
33602
|
context = structuredClone({
|
|
33454
33603
|
...context,
|
|
@@ -33481,7 +33630,7 @@ var InferenceCoordinator = class _InferenceCoordinator {
|
|
|
33481
33630
|
if (!this.work.admissionOpen)
|
|
33482
33631
|
throw new Error("Inference owner is closing");
|
|
33483
33632
|
const parentBudget = this.work.budget;
|
|
33484
|
-
const boundary = operation.metadata.purpose
|
|
33633
|
+
const boundary = isPrimaryRequest(operation.metadata.purpose) ? this.requestViewBoundary : void 0;
|
|
33485
33634
|
const budget = boundary ? parentBudget?.capture() : parentBudget;
|
|
33486
33635
|
let measuredForAdmission = false;
|
|
33487
33636
|
let countingInput = false;
|
|
@@ -33527,7 +33676,7 @@ var InferenceCoordinator = class _InferenceCoordinator {
|
|
|
33527
33676
|
} : void 0;
|
|
33528
33677
|
const requiredPublic = Boolean(boundary?.pendingPublicMessageGroups?.length);
|
|
33529
33678
|
const requiredEpoch = boundary?.requiresEpoch === true;
|
|
33530
|
-
const canSelect = (budget || boundary?.fixedPrepare || requiredPublic || requiredEpoch) && boundary && matchesRequestView(boundary, source, context);
|
|
33679
|
+
const canSelect = (budget || boundary?.fixedPrepare || requiredPublic || requiredEpoch || boundary?.recoveryContractRequested) && boundary && matchesRequestView(boundary, source, context);
|
|
33531
33680
|
if (requiredPublic && (!canSelect || boundary?.fixedPrepare))
|
|
33532
33681
|
throw new Error("Tool continuation requires a selectable native public request boundary");
|
|
33533
33682
|
const responsesMessageIds = canSelect && !boundary.fixedPrepare && (model.api === "openai-responses" || model.api === "openai-codex-responses") ? boundary.providerMessageIndices.map((index) => {
|
|
@@ -33663,7 +33812,14 @@ var InferenceCoordinator = class _InferenceCoordinator {
|
|
|
33663
33812
|
}
|
|
33664
33813
|
};
|
|
33665
33814
|
const signal = options?.signal ? AbortSignal.any([options.signal, this.work.cancellation.signal]) : this.work.cancellation.signal;
|
|
33666
|
-
const
|
|
33815
|
+
const sessionId = options?.sessionId ?? (isPrimaryRequest(operation.metadata.purpose) ? source.sessionId : `${operation.metadata.purpose}:${source.sessionId}`);
|
|
33816
|
+
const events = await send(model, context, {
|
|
33817
|
+
...options,
|
|
33818
|
+
sessionId,
|
|
33819
|
+
signal,
|
|
33820
|
+
attempts,
|
|
33821
|
+
requireProviderAttempts: true
|
|
33822
|
+
});
|
|
33667
33823
|
localSimulation = isLocalFauxStream(events);
|
|
33668
33824
|
const settled = settle(events.result());
|
|
33669
33825
|
events.result = async () => (await settled).message;
|
|
@@ -33782,7 +33938,7 @@ var InferenceCoordinator = class _InferenceCoordinator {
|
|
|
33782
33938
|
if (captured || previous?.metadata.operationId !== operationId) {
|
|
33783
33939
|
previous = executor.bindOperation(model, { ...request, semanticEdgeId }, operationId);
|
|
33784
33940
|
}
|
|
33785
|
-
return (await executor.execute(previous, model, context, options, inner, captured !== void 0 && request.purpose
|
|
33941
|
+
return (await executor.execute(previous, model, context, options, inner, captured !== void 0 && isPrimaryRequest(request.purpose))).events;
|
|
33786
33942
|
};
|
|
33787
33943
|
wrapped[REQUEST_STREAM_BINDING] = { coordinator: this, inner };
|
|
33788
33944
|
return wrapped;
|
|
@@ -34034,12 +34190,31 @@ function estimateContextTokens(messages) {
|
|
|
34034
34190
|
lastUsageIndex: usageInfo.index
|
|
34035
34191
|
};
|
|
34036
34192
|
}
|
|
34037
|
-
function shouldCompact(contextTokens, contextWindow, settings) {
|
|
34193
|
+
function shouldCompact(contextTokens, contextWindow, settings, fixedContextTokens = 0) {
|
|
34038
34194
|
if (!settings.enabled)
|
|
34039
34195
|
return false;
|
|
34040
34196
|
if (contextWindow <= 0)
|
|
34041
34197
|
return false;
|
|
34042
|
-
|
|
34198
|
+
const modelLimit = contextWindow - settings.reserveTokens;
|
|
34199
|
+
const target = settings.targetTokens === "model-limit" ? modelLimit : Math.max(settings.targetTokens ?? Math.min(96e3, contextWindow / 2), fixedContextTokens + 4 * settings.keepRecentTokens);
|
|
34200
|
+
return contextTokens > Math.min(target, modelLimit);
|
|
34201
|
+
}
|
|
34202
|
+
function estimateFixedCompactionTokens(systemPrompt, tools, messages) {
|
|
34203
|
+
const toolSchemas = tools.map(({ name, description, parameters }) => ({ name, description, parameters }));
|
|
34204
|
+
let tokens = Math.ceil((systemPrompt.length + (tools.length ? JSON.stringify(toolSchemas).length : 0)) / 4);
|
|
34205
|
+
let hasHarnessSnapshot = false;
|
|
34206
|
+
for (let index = messages.length - 1; index >= 0; index--) {
|
|
34207
|
+
const message2 = messages[index];
|
|
34208
|
+
if (message2.role !== "custom")
|
|
34209
|
+
continue;
|
|
34210
|
+
if (message2.customType === TASK_FRAME_CUSTOM_TYPE)
|
|
34211
|
+
tokens += estimateTokens(message2);
|
|
34212
|
+
else if (message2.customType === HARNESS_SNAPSHOT_CUSTOM_TYPE && !hasHarnessSnapshot) {
|
|
34213
|
+
tokens += estimateTokens(message2);
|
|
34214
|
+
hasHarnessSnapshot = true;
|
|
34215
|
+
}
|
|
34216
|
+
}
|
|
34217
|
+
return tokens;
|
|
34043
34218
|
}
|
|
34044
34219
|
function compactionTokenScale(messages) {
|
|
34045
34220
|
const usageInfo = getLastAssistantUsageInfo(messages);
|
|
@@ -34627,7 +34802,7 @@ function captureEpochCopyEntry(entry, source) {
|
|
|
34627
34802
|
...updateTarget ? { updateTarget } : {}
|
|
34628
34803
|
};
|
|
34629
34804
|
}
|
|
34630
|
-
async function rebuildCopiedContextEpoch(history, copied, limits) {
|
|
34805
|
+
async function rebuildCopiedContextEpoch(history, copied, limits, metadataMaxBytes = limits.maxSourceBytes) {
|
|
34631
34806
|
const view = history.branchContext;
|
|
34632
34807
|
const manifest = await view.contextManifest({ limit: 1 });
|
|
34633
34808
|
if (manifest.selection !== "known")
|
|
@@ -34656,15 +34831,26 @@ async function rebuildCopiedContextEpoch(history, copied, limits) {
|
|
|
34656
34831
|
throw new Error("Tool continuation recipes require their original native execution source");
|
|
34657
34832
|
if (!checkpoint || checkpoint.literalTailId !== entry.firstKeptEntryId || !view.atSnapshot)
|
|
34658
34833
|
throw new Error("Copied context epoch boundary is unavailable");
|
|
34659
|
-
if (
|
|
34834
|
+
if (checkpoint.views.length > limits.maxEntries)
|
|
34660
34835
|
throw new Error("Copied context epoch item budget exceeded");
|
|
34661
|
-
stringifyBoundedJson(copied,
|
|
34836
|
+
stringifyBoundedJson(copied, metadataMaxBytes);
|
|
34662
34837
|
const oldByRevision = new Map([...oldById.values()].map((source) => [source.revision, source]));
|
|
34663
34838
|
const destination = /* @__PURE__ */ new Map();
|
|
34664
|
-
|
|
34665
|
-
|
|
34666
|
-
|
|
34667
|
-
|
|
34839
|
+
let after = 0;
|
|
34840
|
+
for (; ; ) {
|
|
34841
|
+
const page = await history.page(after, 128);
|
|
34842
|
+
if (page.indexedThrough < history.source.sourceSequence)
|
|
34843
|
+
throw new Error("Copied context destination has incomplete index coverage");
|
|
34844
|
+
for (const actual of page.events) {
|
|
34845
|
+
if (!oldById.has(actual.id))
|
|
34846
|
+
continue;
|
|
34847
|
+
if (destination.size >= limits.maxEntries)
|
|
34848
|
+
throw new Error("Copied context epoch item budget exceeded");
|
|
34849
|
+
destination.set(actual.id, actual);
|
|
34850
|
+
}
|
|
34851
|
+
if (page.nextAfter === null)
|
|
34852
|
+
break;
|
|
34853
|
+
after = page.nextAfter;
|
|
34668
34854
|
}
|
|
34669
34855
|
const prefixViews = /* @__PURE__ */ new Map();
|
|
34670
34856
|
const prefix = async (source) => {
|
|
@@ -36655,6 +36841,7 @@ var DEFAULT_MANAGER_HISTORY_LIMITS = {
|
|
|
36655
36841
|
maxEntries: 16384,
|
|
36656
36842
|
maxSourceBytes: 64 * 1024 * 1024
|
|
36657
36843
|
};
|
|
36844
|
+
var FORK_SOURCE_METADATA_MAX_BYTES = 64 * 1024 * 1024;
|
|
36658
36845
|
async function readOwnedSessionHeader(snapshot) {
|
|
36659
36846
|
const handle = await openFile(snapshot.journalPath, "r");
|
|
36660
36847
|
let capturedHeader;
|
|
@@ -37182,6 +37369,19 @@ var SessionManager = class _SessionManager {
|
|
|
37182
37369
|
readSourceHistory(read2) {
|
|
37183
37370
|
return this._runHistoryRead(this._bindHistorySource((index, source, query) => createSessionHistoryReadScope(index, source, query, "source")), read2);
|
|
37184
37371
|
}
|
|
37372
|
+
/** Read the owner-maintained own-spend projection without hydrating the source. */
|
|
37373
|
+
async readOwnUsageSummary() {
|
|
37374
|
+
this._assertMutable();
|
|
37375
|
+
if (!this.supportsCapturedHistoryReads())
|
|
37376
|
+
throw new Error("Own usage projection requires an owned native source");
|
|
37377
|
+
const state = this.writeState;
|
|
37378
|
+
return this._enqueue(state, 0, async () => {
|
|
37379
|
+
await state.owner.flush();
|
|
37380
|
+
const snapshot = state.owner.getSnapshot();
|
|
37381
|
+
await this._acknowledgedHistory(state, snapshot);
|
|
37382
|
+
return state.history.currentSourceUsage(snapshot);
|
|
37383
|
+
});
|
|
37384
|
+
}
|
|
37185
37385
|
/** Complete bounded structured task reduction on one captured native branch. */
|
|
37186
37386
|
async readTaskState(limits = {}) {
|
|
37187
37387
|
const captured = taskStateReadLimits(limits);
|
|
@@ -38921,6 +39121,8 @@ var SessionManager = class _SessionManager {
|
|
|
38921
39121
|
}
|
|
38922
39122
|
async _captureForkInput(target, options) {
|
|
38923
39123
|
const limits = { ...options.limits ?? DEFAULT_MANAGER_HISTORY_LIMITS };
|
|
39124
|
+
if (!Number.isSafeInteger(limits.maxEntries) || limits.maxEntries <= 0 || !Number.isSafeInteger(limits.maxSourceBytes) || limits.maxSourceBytes <= 0)
|
|
39125
|
+
throw new Error("Invalid fork source limits");
|
|
38924
39126
|
const sourceFile = this.sessionFile;
|
|
38925
39127
|
const header = JSON.parse(stringifyBoundedJson(this.getHeader(), limits.maxSourceBytes));
|
|
38926
39128
|
const settings = {
|
|
@@ -39032,32 +39234,143 @@ var SessionManager = class _SessionManager {
|
|
|
39032
39234
|
if (headerBytes >= limits.maxSourceBytes)
|
|
39033
39235
|
throw new Error("Fork source byte budget exceeded");
|
|
39034
39236
|
return this.readSourceHistory(async (history) => {
|
|
39035
|
-
const
|
|
39036
|
-
|
|
39037
|
-
|
|
39038
|
-
|
|
39039
|
-
|
|
39040
|
-
|
|
39041
|
-
|
|
39237
|
+
const metadata = /* @__PURE__ */ new Map();
|
|
39238
|
+
let metadataBytes = 0;
|
|
39239
|
+
let after = 0;
|
|
39240
|
+
for (; ; ) {
|
|
39241
|
+
const page2 = await history.page(after, 128);
|
|
39242
|
+
if (page2.indexedThrough < history.source.sourceSequence)
|
|
39243
|
+
throw new Error("Captured fork history has incomplete index coverage");
|
|
39244
|
+
for (const reference of page2.events) {
|
|
39245
|
+
const source = {
|
|
39246
|
+
id: reference.id,
|
|
39247
|
+
parentId: reference.parentId,
|
|
39248
|
+
kind: reference.kind,
|
|
39249
|
+
sequence: reference.sequence,
|
|
39250
|
+
revision: reference.revision,
|
|
39251
|
+
locator: { ...reference.locator },
|
|
39252
|
+
retention: reference.retention,
|
|
39253
|
+
qualification: reference.qualification
|
|
39254
|
+
};
|
|
39255
|
+
metadataBytes += Buffer.byteLength(JSON.stringify(source)) + 1;
|
|
39256
|
+
if (metadataBytes > FORK_SOURCE_METADATA_MAX_BYTES)
|
|
39257
|
+
throw new Error("Fork source metadata byte budget exceeded");
|
|
39258
|
+
metadata.set(source.id, source);
|
|
39259
|
+
}
|
|
39260
|
+
if (page2.nextAfter === null)
|
|
39261
|
+
break;
|
|
39262
|
+
after = page2.nextAfter;
|
|
39263
|
+
}
|
|
39264
|
+
const hasEpoch = [...metadata.values()].some((entry) => entry.kind === "compaction" && entry.qualification === "native-context-epoch");
|
|
39265
|
+
const loaded = /* @__PURE__ */ new Map();
|
|
39266
|
+
let sourceBytes = headerBytes;
|
|
39267
|
+
const load = async (id) => {
|
|
39268
|
+
const existing = loaded.get(id);
|
|
39269
|
+
if (existing)
|
|
39270
|
+
return existing;
|
|
39271
|
+
const reference = metadata.get(id);
|
|
39272
|
+
if (!reference)
|
|
39273
|
+
throw new Error("Fork selected source is unavailable");
|
|
39274
|
+
if (loaded.size >= limits.maxEntries)
|
|
39275
|
+
throw new Error("Fork entry budget exceeded");
|
|
39276
|
+
const remaining = limits.maxSourceBytes - sourceBytes;
|
|
39277
|
+
if (reference.locator.length > remaining)
|
|
39278
|
+
throw new Error("Fork source byte budget exceeded");
|
|
39279
|
+
const hydrated = await history.hydrateEntry(id, remaining);
|
|
39280
|
+
if (!hydrated)
|
|
39281
|
+
throw new Error("Fork selected source is unavailable");
|
|
39282
|
+
const entry = withEntryRetention(hydrated.entry, hydrated.source.retention, hydrated.source.qualification);
|
|
39283
|
+
loaded.set(id, entry);
|
|
39284
|
+
metadata.set(id, captureEpochCopyEntry(entry, hydrated.source));
|
|
39285
|
+
sourceBytes += reference.locator.length;
|
|
39286
|
+
return entry;
|
|
39287
|
+
};
|
|
39288
|
+
if ("entryId" in target && !metadata.has(target.entryId))
|
|
39289
|
+
throw new Error("Invalid entry ID for forking");
|
|
39290
|
+
const selected = "entryId" in target ? await load(target.entryId) : void 0;
|
|
39291
|
+
if ("entryId" in target && target.position === "before" && (selected?.type !== "message" || selected.message.role !== "user"))
|
|
39292
|
+
throw new Error("Invalid entry ID for forking");
|
|
39293
|
+
const leafId = "entryId" in target ? target.position === "at" ? selected.id : selected.parentId : target.leafId;
|
|
39294
|
+
const path6 = [];
|
|
39295
|
+
let page = await history.parentPathFrom(leafId);
|
|
39296
|
+
for (; ; ) {
|
|
39297
|
+
if (page.totalEntries > limits.maxEntries)
|
|
39298
|
+
throw new Error("Fork entry budget exceeded");
|
|
39299
|
+
for (const reference of page.events)
|
|
39300
|
+
path6.push(await load(reference.id));
|
|
39301
|
+
if (!page.nextCursor)
|
|
39302
|
+
break;
|
|
39303
|
+
page = await history.parentPathFrom(leafId, { cursor: page.nextCursor });
|
|
39304
|
+
}
|
|
39305
|
+
const copied = path6.filter((entry) => entry.type !== "label");
|
|
39306
|
+
const ids = new Set(copied.map((entry) => entry.id));
|
|
39307
|
+
if (hasEpoch) {
|
|
39308
|
+
for (const entry of copied) {
|
|
39309
|
+
if (entry.type !== "message")
|
|
39310
|
+
continue;
|
|
39311
|
+
if (entry.execution && "invocationId" in entry.execution)
|
|
39312
|
+
ids.add(entry.execution.invocationId);
|
|
39313
|
+
const updateTarget = entry.message.role === "assistant" ? { kind: "assistant-usage", targetId: entry.id } : entry.message.role === "toolResult" ? { kind: "ipython-sent-message", toolCallId: entry.message.toolCallId } : void 0;
|
|
39314
|
+
if (!updateTarget)
|
|
39315
|
+
continue;
|
|
39316
|
+
let after2 = 0;
|
|
39317
|
+
for (; ; ) {
|
|
39318
|
+
const updates = await history.sourceContextUpdates(updateTarget, after2);
|
|
39319
|
+
if (updates.indexedThrough < history.source.sourceSequence)
|
|
39320
|
+
throw new Error("Captured fork updates have incomplete index coverage");
|
|
39321
|
+
for (const reference of updates.events)
|
|
39322
|
+
ids.add(reference.id);
|
|
39323
|
+
if (updates.nextAfter === null)
|
|
39324
|
+
break;
|
|
39325
|
+
after2 = updates.nextAfter;
|
|
39326
|
+
}
|
|
39327
|
+
}
|
|
39328
|
+
for (const id of ids) {
|
|
39329
|
+
const reference = metadata.get(id);
|
|
39330
|
+
if (!reference)
|
|
39331
|
+
throw new Error("Fork related source is unavailable");
|
|
39332
|
+
if (reference.parentId !== null)
|
|
39333
|
+
ids.add(reference.parentId);
|
|
39334
|
+
}
|
|
39335
|
+
for (const id of ids)
|
|
39336
|
+
await load(id);
|
|
39337
|
+
} else {
|
|
39338
|
+
for (const entry of copied) {
|
|
39339
|
+
if (entry.type !== "message" || entry.message.role !== "assistant")
|
|
39340
|
+
continue;
|
|
39341
|
+
const latest = await history.sourceAssistantUsage(entry.id);
|
|
39342
|
+
if (latest)
|
|
39343
|
+
await load(latest.id);
|
|
39344
|
+
}
|
|
39345
|
+
}
|
|
39346
|
+
for (const id of ids) {
|
|
39347
|
+
const label = await history.sourceLabel(id);
|
|
39348
|
+
if (label)
|
|
39349
|
+
await load(label.id);
|
|
39350
|
+
}
|
|
39351
|
+
const entries = [...loaded.values()].sort((left, right) => metadata.get(left.id).sequence - metadata.get(right.id).sequence);
|
|
39042
39352
|
if (!hasEpoch)
|
|
39043
39353
|
applyChildUsageAttributions(entries);
|
|
39044
|
-
|
|
39354
|
+
const epochCopy = hasEpoch ? {
|
|
39045
39355
|
sessionId: history.source.sessionId,
|
|
39046
39356
|
sessionFile: history.source.sessionFile,
|
|
39047
39357
|
through: history.source.sourceSequence,
|
|
39048
|
-
entries:
|
|
39358
|
+
entries: [...metadata.values()],
|
|
39049
39359
|
retained: false
|
|
39050
|
-
} : void 0
|
|
39360
|
+
} : void 0;
|
|
39361
|
+
if (epochCopy)
|
|
39362
|
+
stringifyBoundedJson(epochCopy, FORK_SOURCE_METADATA_MAX_BYTES);
|
|
39363
|
+
return finish(entries, history, epochCopy);
|
|
39051
39364
|
});
|
|
39052
39365
|
}
|
|
39053
|
-
async _rebuildCopiedEpoch(copied, limits) {
|
|
39366
|
+
async _rebuildCopiedEpoch(copied, limits, metadataMaxBytes = limits.maxSourceBytes) {
|
|
39054
39367
|
if (!copied.entries.some((entry) => entry.kind === "compaction" && entry.qualification === "native-context-epoch"))
|
|
39055
39368
|
return;
|
|
39056
39369
|
if (!this.supportsCapturedHistoryReads())
|
|
39057
39370
|
throw new Error("Copied context epochs require an owned persistent source");
|
|
39058
39371
|
const sink = this.bindCompactionSink(limits);
|
|
39059
39372
|
await this._runHistoryRead({ ...sink, readHistory: (read2) => sink[readCopiedEpochSource](read2) }, async (history) => {
|
|
39060
|
-
const rebuilt = await rebuildCopiedContextEpoch(history, copied, limits);
|
|
39373
|
+
const rebuilt = await rebuildCopiedContextEpoch(history, copied, limits, metadataMaxBytes);
|
|
39061
39374
|
if (rebuilt)
|
|
39062
39375
|
await sink[appendContextEpoch](rebuilt.checkpoint, rebuilt.tokensBefore, rebuilt.summary);
|
|
39063
39376
|
});
|
|
@@ -39094,7 +39407,7 @@ var SessionManager = class _SessionManager {
|
|
|
39094
39407
|
if (input.epochCopy) {
|
|
39095
39408
|
try {
|
|
39096
39409
|
await next.branchTo(input.leafId ?? null);
|
|
39097
|
-
await next._rebuildCopiedEpoch(input.epochCopy, input.limits);
|
|
39410
|
+
await next._rebuildCopiedEpoch(input.epochCopy, input.limits, FORK_SOURCE_METADATA_MAX_BYTES);
|
|
39098
39411
|
} catch (error) {
|
|
39099
39412
|
try {
|
|
39100
39413
|
await next.close();
|
|
@@ -39487,13 +39800,6 @@ function parseBoundedSessionEntries(text2, maxEntries) {
|
|
|
39487
39800
|
}
|
|
39488
39801
|
return parseSessionEntries(text2);
|
|
39489
39802
|
}
|
|
39490
|
-
async function readSessionHistoryFile(inputPath, limits) {
|
|
39491
|
-
limits = { ...limits };
|
|
39492
|
-
const captured = await readSessionHistoryImage(inputPath, limits.maxSourceBytes);
|
|
39493
|
-
const complete = captured.subarray(0, captured.lastIndexOf(10) + 1);
|
|
39494
|
-
const text2 = new TextDecoder3("utf-8", { fatal: true, ignoreBOM: true }).decode(complete);
|
|
39495
|
-
return parseBoundedSessionEntries(text2, limits.maxEntries);
|
|
39496
|
-
}
|
|
39497
39803
|
async function readExportHistory(inputPath, limits) {
|
|
39498
39804
|
limits = { ...limits };
|
|
39499
39805
|
const captured = await readSessionHistoryImage(inputPath, limits.maxSourceBytes);
|
|
@@ -42810,6 +43116,99 @@ ${instructions}`;
|
|
|
42810
43116
|
// dist/core/context-tree.js
|
|
42811
43117
|
import { existsSync as existsSync14, opendirSync, statSync as statSync6 } from "node:fs";
|
|
42812
43118
|
import { basename as basename6, join as join20 } from "node:path";
|
|
43119
|
+
|
|
43120
|
+
// dist/core/request-usage.js
|
|
43121
|
+
function emptyRequestUsageTotals() {
|
|
43122
|
+
return {
|
|
43123
|
+
attempts: 0,
|
|
43124
|
+
settledAttempts: 0,
|
|
43125
|
+
partialUsageAttempts: 0,
|
|
43126
|
+
missingUsageAttempts: 0,
|
|
43127
|
+
unsettledAttempts: 0,
|
|
43128
|
+
unpricedAttempts: 0,
|
|
43129
|
+
input: 0,
|
|
43130
|
+
inputTotal: 0,
|
|
43131
|
+
output: 0,
|
|
43132
|
+
cacheRead: 0,
|
|
43133
|
+
cacheWrite: 0,
|
|
43134
|
+
processedTokens: 0,
|
|
43135
|
+
catalogEstimateUsd: 0
|
|
43136
|
+
};
|
|
43137
|
+
}
|
|
43138
|
+
function addRequestUsageTotals(total, usage) {
|
|
43139
|
+
for (const field of Object.keys(total))
|
|
43140
|
+
total[field] += usage[field];
|
|
43141
|
+
}
|
|
43142
|
+
function purpose(event) {
|
|
43143
|
+
if (event.purpose === "native-control" && event.purposeDetail === "daemon-status")
|
|
43144
|
+
return "status";
|
|
43145
|
+
if (event.purpose === "summary" && (event.purposeDetail === "compaction" || event.purposeDetail === "compaction-turn-prefix"))
|
|
43146
|
+
return "compaction";
|
|
43147
|
+
return event.purpose;
|
|
43148
|
+
}
|
|
43149
|
+
function inputTotal(usage) {
|
|
43150
|
+
if (usage.inputTotal !== void 0)
|
|
43151
|
+
return usage.inputTotal;
|
|
43152
|
+
if (usage.input !== void 0 && usage.cacheRead !== void 0 && usage.cacheWrite !== void 0)
|
|
43153
|
+
return usage.input + usage.cacheRead + usage.cacheWrite;
|
|
43154
|
+
if (usage.totalTokens !== void 0 && usage.output !== void 0)
|
|
43155
|
+
return usage.totalTokens - usage.output;
|
|
43156
|
+
return void 0;
|
|
43157
|
+
}
|
|
43158
|
+
var RequestUsageAccumulator = class {
|
|
43159
|
+
sessionId;
|
|
43160
|
+
attempts = /* @__PURE__ */ new Map();
|
|
43161
|
+
constructor(sessionId) {
|
|
43162
|
+
this.sessionId = sessionId;
|
|
43163
|
+
}
|
|
43164
|
+
add(event) {
|
|
43165
|
+
if (event.source.sessionId !== this.sessionId || event.purpose === "native-control" && event.purposeDetail === "input-token-count")
|
|
43166
|
+
return;
|
|
43167
|
+
const previous = this.attempts.get(event.attemptId);
|
|
43168
|
+
if (event.type === "attempt_admitted" && previous)
|
|
43169
|
+
return;
|
|
43170
|
+
const totals = emptyRequestUsageTotals();
|
|
43171
|
+
totals.attempts = 1;
|
|
43172
|
+
if (event.type === "attempt_admitted") {
|
|
43173
|
+
totals.unsettledAttempts = 1;
|
|
43174
|
+
} else {
|
|
43175
|
+
totals.settledAttempts = 1;
|
|
43176
|
+
const { usage, usageCompleteness } = event.receipt;
|
|
43177
|
+
const incompleteBuckets = [usage.input, usage.output, usage.cacheRead, usage.cacheWrite].some((value) => value === void 0);
|
|
43178
|
+
totals.partialUsageAttempts = usageCompleteness === "partial" || usageCompleteness !== "none" && incompleteBuckets ? 1 : 0;
|
|
43179
|
+
totals.missingUsageAttempts = usageCompleteness === "none" ? 1 : 0;
|
|
43180
|
+
totals.input = usage.input ?? 0;
|
|
43181
|
+
totals.inputTotal = inputTotal(usage) ?? (usage.input ?? 0) + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);
|
|
43182
|
+
totals.output = usage.output ?? 0;
|
|
43183
|
+
totals.cacheRead = usage.cacheRead ?? 0;
|
|
43184
|
+
totals.cacheWrite = usage.cacheWrite ?? 0;
|
|
43185
|
+
const input = inputTotal(usage);
|
|
43186
|
+
totals.processedTokens = input !== void 0 && usage.output !== void 0 ? input + usage.output : usage.totalTokens ?? totals.inputTotal + totals.output;
|
|
43187
|
+
const pricing = event.modelContract.pricing;
|
|
43188
|
+
const rates = pricing.status !== "unavailable" && pricing.currency === "USD" && pricing.unit === "million-tokens" ? pricing.catalogRates : void 0;
|
|
43189
|
+
if (rates && usage.input !== void 0 && usage.output !== void 0 && usage.cacheRead !== void 0 && usage.cacheWrite !== void 0) {
|
|
43190
|
+
totals.catalogEstimateUsd = (usage.input * rates.input + usage.output * rates.output + usage.cacheRead * rates.cacheRead + usage.cacheWrite * rates.cacheWrite) / 1e6;
|
|
43191
|
+
} else {
|
|
43192
|
+
totals.unpricedAttempts = 1;
|
|
43193
|
+
}
|
|
43194
|
+
}
|
|
43195
|
+
this.attempts.set(event.attemptId, { purpose: purpose(event), totals });
|
|
43196
|
+
}
|
|
43197
|
+
finish() {
|
|
43198
|
+
if (this.attempts.size === 0)
|
|
43199
|
+
return void 0;
|
|
43200
|
+
const result = { sessionId: this.sessionId, byPurpose: {}, total: emptyRequestUsageTotals() };
|
|
43201
|
+
for (const attempt of this.attempts.values()) {
|
|
43202
|
+
const bucket = result.byPurpose[attempt.purpose] ?? emptyRequestUsageTotals();
|
|
43203
|
+
result.byPurpose[attempt.purpose] = bucket;
|
|
43204
|
+
addRequestUsageTotals(bucket, attempt.totals);
|
|
43205
|
+
addRequestUsageTotals(result.total, attempt.totals);
|
|
43206
|
+
}
|
|
43207
|
+
return result;
|
|
43208
|
+
}
|
|
43209
|
+
};
|
|
43210
|
+
|
|
43211
|
+
// dist/core/context-tree.js
|
|
42813
43212
|
var ContextTreeLimitError = class extends Error {
|
|
42814
43213
|
};
|
|
42815
43214
|
var ContextTreeRequest = class {
|
|
@@ -42903,6 +43302,11 @@ function computeOwnAndTotalUsage(branch, allEntries) {
|
|
|
42903
43302
|
}
|
|
42904
43303
|
function readResidentContextTreeUsage(manager, limits = { maxEntries: 16384, maxSourceBytes: 64 * 1024 * 1024 }, availabilityMaxSourceBytes) {
|
|
42905
43304
|
const snapshot = manager.materializeResidentHistory(limits);
|
|
43305
|
+
const receipts = new RequestUsageAccumulator(manager.getSessionId());
|
|
43306
|
+
for (const entry of snapshot.entries)
|
|
43307
|
+
if (entry.type === "request")
|
|
43308
|
+
receipts.add(entry.request);
|
|
43309
|
+
const ownRequestUsage = receipts.finish();
|
|
42906
43310
|
const branch = branchEntries(snapshot.entries, snapshot.leafId, availabilityMaxSourceBytes !== void 0);
|
|
42907
43311
|
if (availabilityMaxSourceBytes !== void 0) {
|
|
42908
43312
|
if (!Number.isSafeInteger(availabilityMaxSourceBytes) || availabilityMaxSourceBytes <= 0)
|
|
@@ -42916,19 +43320,67 @@ function readResidentContextTreeUsage(manager, limits = { maxEntries: 16384, max
|
|
|
42916
43320
|
}
|
|
42917
43321
|
return {
|
|
42918
43322
|
...computeOwnAndTotalUsage(branch, snapshot.entries),
|
|
43323
|
+
...ownRequestUsage ? { ownRequestUsage } : {},
|
|
42919
43324
|
...availabilityMaxSourceBytes === void 0 ? {} : { hasPostCompactionUsage: hasPostCompactionUsage(branch) }
|
|
42920
43325
|
};
|
|
42921
43326
|
}
|
|
43327
|
+
function isContextTreeUsageReference(reference) {
|
|
43328
|
+
return reference.kind === "message" && reference.authority === "assistant" || reference.kind === "compaction" || reference.kind === "branch_summary" || reference.kind === "child_usage_attributed";
|
|
43329
|
+
}
|
|
42922
43330
|
async function readContextTreeUsage(manager, limits = { maxEntries: 16384, maxSourceBytes: 64 * 1024 * 1024 }, request, availabilityMaxSourceBytes) {
|
|
42923
43331
|
if (!manager.supportsCapturedHistoryReads())
|
|
42924
43332
|
return void 0;
|
|
42925
43333
|
const sourceLimits = request?.limits ?? limits;
|
|
42926
43334
|
const capturedLimits = { maxEntries: sourceLimits.maxEntries, maxSourceBytes: sourceLimits.maxSourceBytes };
|
|
43335
|
+
if (!Object.values(capturedLimits).every((value) => Number.isSafeInteger(value) && value > 0))
|
|
43336
|
+
throw new Error("Invalid history materialization limits");
|
|
42927
43337
|
return manager.readSourceHistory((history) => {
|
|
42928
43338
|
request?.retainMetadata(history.source);
|
|
42929
43339
|
const reduce = async () => {
|
|
42930
|
-
const
|
|
42931
|
-
|
|
43340
|
+
const allEntries = [];
|
|
43341
|
+
let receipts = new RequestUsageAccumulator(history.source.sessionId);
|
|
43342
|
+
let requestEntries = 0;
|
|
43343
|
+
let requestBytes = 0;
|
|
43344
|
+
let sourceBytes = 0;
|
|
43345
|
+
let after = 0;
|
|
43346
|
+
for (; ; ) {
|
|
43347
|
+
const page = await history.page(after);
|
|
43348
|
+
if (page.indexedThrough < history.source.sourceSequence)
|
|
43349
|
+
throw new Error("Captured history has incomplete index coverage");
|
|
43350
|
+
for (const reference of page.events) {
|
|
43351
|
+
if (reference.kind === "request" && receipts) {
|
|
43352
|
+
requestEntries++;
|
|
43353
|
+
requestBytes += reference.locator.length;
|
|
43354
|
+
if (requestEntries > capturedLimits.maxEntries || requestBytes > capturedLimits.maxSourceBytes) {
|
|
43355
|
+
receipts = void 0;
|
|
43356
|
+
} else {
|
|
43357
|
+
try {
|
|
43358
|
+
const hydrated2 = await history.hydrateEntry(reference.id, reference.locator.length);
|
|
43359
|
+
if (hydrated2?.entry.type !== "request")
|
|
43360
|
+
receipts = void 0;
|
|
43361
|
+
else
|
|
43362
|
+
receipts.add(hydrated2.entry.request);
|
|
43363
|
+
} catch {
|
|
43364
|
+
receipts = void 0;
|
|
43365
|
+
}
|
|
43366
|
+
}
|
|
43367
|
+
}
|
|
43368
|
+
if (!isContextTreeUsageReference(reference))
|
|
43369
|
+
continue;
|
|
43370
|
+
if (allEntries.length >= capturedLimits.maxEntries)
|
|
43371
|
+
throw new Error("History entry budget exceeded");
|
|
43372
|
+
if (sourceBytes + reference.locator.length > capturedLimits.maxSourceBytes)
|
|
43373
|
+
throw new Error("History source byte budget exceeded");
|
|
43374
|
+
const hydrated = await history.hydrateEntry(reference.id, capturedLimits.maxSourceBytes - sourceBytes);
|
|
43375
|
+
if (!hydrated)
|
|
43376
|
+
throw new Error("Context-tree usage entry source is unavailable");
|
|
43377
|
+
allEntries.push(hydrated.entry);
|
|
43378
|
+
sourceBytes += reference.locator.length;
|
|
43379
|
+
}
|
|
43380
|
+
if (page.nextAfter === null)
|
|
43381
|
+
break;
|
|
43382
|
+
after = page.nextAfter;
|
|
43383
|
+
}
|
|
42932
43384
|
applyChildUsageAttributions(allEntries);
|
|
42933
43385
|
const byId = new Map(allEntries.map((entry) => [entry.id, entry]));
|
|
42934
43386
|
const branch = [];
|
|
@@ -42936,6 +43388,8 @@ async function readContextTreeUsage(manager, limits = { maxEntries: 16384, maxSo
|
|
|
42936
43388
|
do {
|
|
42937
43389
|
const page = await history.parentPath({ cursor });
|
|
42938
43390
|
for (const reference of page.events) {
|
|
43391
|
+
if (!isContextTreeUsageReference(reference))
|
|
43392
|
+
continue;
|
|
42939
43393
|
const entry = byId.get(reference.id);
|
|
42940
43394
|
if (!entry)
|
|
42941
43395
|
throw new Error("Context-tree parent-path entry source is unavailable");
|
|
@@ -42962,8 +43416,10 @@ async function readContextTreeUsage(manager, limits = { maxEntries: 16384, maxSo
|
|
|
42962
43416
|
available = calculateContextTokens(assistant.message.usage) > 0;
|
|
42963
43417
|
}
|
|
42964
43418
|
}
|
|
43419
|
+
const ownRequestUsage = receipts?.finish();
|
|
42965
43420
|
const usage = {
|
|
42966
43421
|
...computeOwnAndTotalUsage(branch, allEntries),
|
|
43422
|
+
...ownRequestUsage ? { ownRequestUsage } : {},
|
|
42967
43423
|
...available === void 0 ? {} : { hasPostCompactionUsage: available }
|
|
42968
43424
|
};
|
|
42969
43425
|
request?.retainMetadata(usage);
|
|
@@ -42998,7 +43454,7 @@ function computeContextUsageFromEntries(allEntries, branch, contextWindow) {
|
|
|
42998
43454
|
if (!hasPostCompactionUsage(branch)) {
|
|
42999
43455
|
return { tokens: null, contextWindow, percent: null };
|
|
43000
43456
|
}
|
|
43001
|
-
const estimate = estimateContextTokens(buildSessionContext(allEntries).messages);
|
|
43457
|
+
const estimate = estimateContextTokens(buildSessionContext(allEntries, branch.at(-1)?.id ?? null).messages);
|
|
43002
43458
|
if (estimate.tokens <= 0) {
|
|
43003
43459
|
return void 0;
|
|
43004
43460
|
}
|
|
@@ -43125,10 +43581,77 @@ function listChildSessionDirs(rlmSessionDir, request) {
|
|
|
43125
43581
|
});
|
|
43126
43582
|
return { paths, bytes };
|
|
43127
43583
|
}
|
|
43584
|
+
async function readContextTreeProjectionFromDisk(sessionFile, request) {
|
|
43585
|
+
const entries = [];
|
|
43586
|
+
const hiddenParents = /* @__PURE__ */ new Map();
|
|
43587
|
+
let leafId = null;
|
|
43588
|
+
let hasHeader = false;
|
|
43589
|
+
let receipts;
|
|
43590
|
+
let requestEntries = 0;
|
|
43591
|
+
let requestBytes = 0;
|
|
43592
|
+
let sourceBytes = 0;
|
|
43593
|
+
let metadataBytes = 0;
|
|
43594
|
+
try {
|
|
43595
|
+
await readCapturedSessionJournal(sessionFile, (record2) => {
|
|
43596
|
+
const value = record2.entry;
|
|
43597
|
+
if (!value || typeof value !== "object" || !("type" in value) || typeof value.type !== "string")
|
|
43598
|
+
throw new Error("Invalid session journal entry");
|
|
43599
|
+
const entry = value;
|
|
43600
|
+
if (!hasHeader) {
|
|
43601
|
+
if (entry.type !== "session" || typeof entry.id !== "string")
|
|
43602
|
+
throw new Error("Session source has no valid header");
|
|
43603
|
+
hasHeader = true;
|
|
43604
|
+
receipts = new RequestUsageAccumulator(entry.id);
|
|
43605
|
+
}
|
|
43606
|
+
if (entry.type === "request" && receipts) {
|
|
43607
|
+
requestEntries++;
|
|
43608
|
+
requestBytes += record2.source?.locator.length ?? Buffer.byteLength(record2.json) + 1;
|
|
43609
|
+
if (requestEntries > request.limits.maxEntries || requestBytes > request.limits.maxSourceBytes)
|
|
43610
|
+
receipts = void 0;
|
|
43611
|
+
else
|
|
43612
|
+
receipts.add(entry.request);
|
|
43613
|
+
}
|
|
43614
|
+
if (entry.type !== "session")
|
|
43615
|
+
leafId = entry.id;
|
|
43616
|
+
if (entry.type === "request" || entry.type === "tool_intent") {
|
|
43617
|
+
metadataBytes += request.retainMetadata([entry.id, entry.parentId]);
|
|
43618
|
+
hiddenParents.set(entry.id, entry.parentId);
|
|
43619
|
+
return;
|
|
43620
|
+
}
|
|
43621
|
+
const bytes = record2.source?.locator.length ?? Buffer.byteLength(record2.json) + 1;
|
|
43622
|
+
if (sourceBytes + bytes > request.limits.maxSourceBytes)
|
|
43623
|
+
throw new ContextTreeLimitError("Context tree source byte budget exceeded");
|
|
43624
|
+
sourceBytes += bytes;
|
|
43625
|
+
if (entry.type === "session")
|
|
43626
|
+
return;
|
|
43627
|
+
if (entries.length >= request.limits.maxEntries)
|
|
43628
|
+
throw new ContextTreeLimitError("Context tree entry budget exceeded");
|
|
43629
|
+
entries.push(entry);
|
|
43630
|
+
});
|
|
43631
|
+
const visibleParent = (id) => {
|
|
43632
|
+
let remaining = hiddenParents.size;
|
|
43633
|
+
while (id !== null && hiddenParents.has(id)) {
|
|
43634
|
+
if (remaining-- === 0)
|
|
43635
|
+
throw new Error("Parent path lineage is unresolved");
|
|
43636
|
+
id = hiddenParents.get(id);
|
|
43637
|
+
}
|
|
43638
|
+
return id;
|
|
43639
|
+
};
|
|
43640
|
+
for (const entry of entries)
|
|
43641
|
+
entry.parentId = visibleParent(entry.parentId);
|
|
43642
|
+
const hasSourceLeaf = leafId !== null;
|
|
43643
|
+
leafId = visibleParent(leafId);
|
|
43644
|
+
applyChildUsageAttributions(entries);
|
|
43645
|
+
const ownRequestUsage = receipts?.finish();
|
|
43646
|
+
return { entries, leafId, hasSourceLeaf, ...ownRequestUsage ? { ownRequestUsage } : {} };
|
|
43647
|
+
} finally {
|
|
43648
|
+
request.releaseMetadata(metadataBytes);
|
|
43649
|
+
}
|
|
43650
|
+
}
|
|
43128
43651
|
async function readContextTreeChildNodeFromDisk(childSessionDir, sessionFile, resolveContextWindow, request, identity) {
|
|
43129
|
-
const allEntries =
|
|
43130
|
-
const branch = branchEntries(allEntries);
|
|
43131
|
-
if (branch.length === 0) {
|
|
43652
|
+
const { entries: allEntries, leafId, hasSourceLeaf, ownRequestUsage } = await readContextTreeProjectionFromDisk(sessionFile, request);
|
|
43653
|
+
const branch = branchEntries(allEntries, leafId);
|
|
43654
|
+
if (branch.length === 0 && !hasSourceLeaf) {
|
|
43132
43655
|
return void 0;
|
|
43133
43656
|
}
|
|
43134
43657
|
const { ownUsage, totalUsage } = computeOwnAndTotalUsage(branch, allEntries);
|
|
@@ -43157,9 +43680,10 @@ async function readContextTreeChildNodeFromDisk(childSessionDir, sessionFile, re
|
|
|
43157
43680
|
model,
|
|
43158
43681
|
ownUsage,
|
|
43159
43682
|
totalUsage,
|
|
43683
|
+
...ownRequestUsage ? { ownRequestUsage } : {},
|
|
43160
43684
|
contextUsage: computeContextUsageFromEntries(allEntries, branch, contextWindow)
|
|
43161
43685
|
};
|
|
43162
|
-
request.retainMetadata(identity ? { model, ownUsage, totalUsage, contextUsage: metadata.contextUsage } : metadata);
|
|
43686
|
+
request.retainMetadata(identity ? { model, ownUsage, totalUsage, ownRequestUsage, contextUsage: metadata.contextUsage } : metadata);
|
|
43163
43687
|
return { ...metadata, children: [] };
|
|
43164
43688
|
}
|
|
43165
43689
|
async function loadContextTreeChildFromDisk(childSessionDir, resolveContextWindow, limits = {}, identity) {
|
|
@@ -45559,7 +46083,7 @@ async function loadExtensionModule(extensionPath) {
|
|
|
45559
46083
|
// (file-path aliases would load a second, divergent copy of each package).
|
|
45560
46084
|
// Also disable tryNative so jiti handles ALL imports (not just the entry point)
|
|
45561
46085
|
// Node/dev must also share the native AI registry and implementation identities.
|
|
45562
|
-
...isBunBinary || isBundledCli ? { virtualModules: (await import("./bundled-modules-
|
|
46086
|
+
...isBunBinary || isBundledCli ? { virtualModules: (await import("./bundled-modules-WCGPZI2H.js")).VIRTUAL_MODULES, tryNative: false } : {
|
|
45563
46087
|
alias: getAliases(),
|
|
45564
46088
|
virtualModules: {
|
|
45565
46089
|
"@ponythewhite/base-context-ai": src_exports,
|
|
@@ -47298,6 +47822,15 @@ function formatHarnessStateForPrompt(state, options = {}) {
|
|
|
47298
47822
|
includeIpythonExamples ? "Call contract: read each installed Python skill's SKILL.md and call its documented module function in the Python REPL; do not assume a `.run` entrypoint. Use `<skill_import> ...` in shell when a CLI exists. Continual harness skill entries are Python REPL skills with an explicit Python `reference` and `arguments` contract. Spawn a continual harness subagent spec by composing a concise task prompt and calling `handle = await rlm('sub-task')`; admission returns immediately with `rlm_child_id`, `name`, `session_dir`, and `model`, never the child's answer. Results arrive only through explicit `agent_message` replies or files; children reply with `await agent_message.send(message, receiver_role='parent')`. Use `await rlm.list_subagents()` to recover direct child handles and `await agent_message.send(..., receiver_role='child', receiver_name=handle.name)` for follow-ups. Do not invent wrappers such as `call_skill(...)`, `run_subagent(...)`, or named subagent registries." : options.includeShellExamples ? "Call contract: use installed skills as shell commands when available (for example `<skill_import> ...`). Continual harness entries are routing/context hints only in sessions without the Python REPL; do not use Python `await`, `asyncio`, or `rlm` examples unless the prompt also documents a Python kernel." : "Call contract: continual harness entries are routing/context hints only in sessions without the Python REPL or shell access; do not use Python `await`, `asyncio`, `rlm`, or shell skill commands unless the prompt also documents those interfaces.",
|
|
47299
47823
|
""
|
|
47300
47824
|
];
|
|
47825
|
+
if (options.section === "instructions") {
|
|
47826
|
+
lines.push("The latest Continual Harness Snapshot in the conversation is the current compact state. It supersedes all earlier snapshots, including removed entries and advice. Do not revive deleted or rolled-back instructions from older snapshots or summaries.");
|
|
47827
|
+
if (options.errorFixSelection?.enabled && includeIpythonExamples)
|
|
47828
|
+
lines.push("", ERROR_FIX_CREATION_GUIDANCE);
|
|
47829
|
+
return lines.join("\n").trim();
|
|
47830
|
+
}
|
|
47831
|
+
if (options.section === "entries") {
|
|
47832
|
+
lines.splice(0, lines.length, "# Continual Harness Snapshot", "This is the complete current compact harness overview and selected error-fix advice. It supersedes all earlier snapshots, including deletions, rollbacks, and empty state. Treat entries as routing/context advice; system instructions and the current task take precedence. Earlier snapshots and summaries are not current harness advice.", "");
|
|
47833
|
+
}
|
|
47301
47834
|
let totalEntries = 0;
|
|
47302
47835
|
for (const kind of Object.keys(state.entries)) {
|
|
47303
47836
|
const entries = Object.values(state.entries[kind]).filter((entry) => !isErrorFixMemory(entry)).sort((a, b2) => [a.path, a.title, a.id].join("\0").localeCompare([b2.path, b2.title, b2.id].join("\0")));
|
|
@@ -47322,7 +47855,7 @@ function formatHarnessStateForPrompt(state, options = {}) {
|
|
|
47322
47855
|
lines.push("No saved harness entries yet.", "");
|
|
47323
47856
|
}
|
|
47324
47857
|
if (options.errorFixSelection?.enabled) {
|
|
47325
|
-
if (includeIpythonExamples)
|
|
47858
|
+
if (includeIpythonExamples && options.section !== "entries")
|
|
47326
47859
|
lines.push("", ERROR_FIX_CREATION_GUIDANCE);
|
|
47327
47860
|
const advice = selectErrorFixAdvice(state, options.errorFixSelection);
|
|
47328
47861
|
if (advice)
|
|
@@ -48316,6 +48849,9 @@ var DEFAULT_FORK_MESSAGE_LIMITS = Object.freeze({
|
|
|
48316
48849
|
async function readUserMessagesForForking(manager, limits = DEFAULT_FORK_MESSAGE_LIMITS) {
|
|
48317
48850
|
const capturedLimits = { ...limits };
|
|
48318
48851
|
const entries = manager.supportsCapturedHistoryReads() ? (await manager.materializeSourceHistory(capturedLimits)).entries.map(({ entry }) => entry) : manager.materializeResidentHistory(capturedLimits).entries;
|
|
48852
|
+
return projectUserMessages(entries);
|
|
48853
|
+
}
|
|
48854
|
+
function projectUserMessages(entries) {
|
|
48319
48855
|
const result = [];
|
|
48320
48856
|
for (const entry of entries) {
|
|
48321
48857
|
if (entry.type !== "message" || entry.message.role !== "user")
|
|
@@ -48332,6 +48868,40 @@ async function readUserMessagesForForking(manager, limits = DEFAULT_FORK_MESSAGE
|
|
|
48332
48868
|
}
|
|
48333
48869
|
return result;
|
|
48334
48870
|
}
|
|
48871
|
+
async function readVisibleUserMessagesForForking(manager, limits = DEFAULT_FORK_MESSAGE_LIMITS) {
|
|
48872
|
+
const { maxEntries, maxSourceBytes } = limits;
|
|
48873
|
+
if (!Number.isSafeInteger(maxEntries) || maxEntries <= 0 || !Number.isSafeInteger(maxSourceBytes) || maxSourceBytes <= 0)
|
|
48874
|
+
throw new Error("Invalid history materialization limits");
|
|
48875
|
+
if (!manager.supportsCapturedHistoryReads())
|
|
48876
|
+
return readUserMessagesForForking(manager, { maxEntries, maxSourceBytes });
|
|
48877
|
+
return manager.readSourceHistory(async (history) => {
|
|
48878
|
+
const entries = [];
|
|
48879
|
+
let sourceBytes = 0;
|
|
48880
|
+
let after = 0;
|
|
48881
|
+
for (; ; ) {
|
|
48882
|
+
const page = await history.page(after);
|
|
48883
|
+
if (page.indexedThrough < history.source.sourceSequence)
|
|
48884
|
+
throw new Error("Captured history has incomplete index coverage");
|
|
48885
|
+
for (const reference of page.events) {
|
|
48886
|
+
if (reference.kind !== "message" || reference.authority === "assistant" || reference.authority === "runtime")
|
|
48887
|
+
continue;
|
|
48888
|
+
if (entries.length >= maxEntries)
|
|
48889
|
+
throw new Error("History entry budget exceeded");
|
|
48890
|
+
if (sourceBytes + reference.locator.length > maxSourceBytes)
|
|
48891
|
+
throw new Error("History source byte budget exceeded");
|
|
48892
|
+
const hydrated = await history.hydrateEntry(reference.id, maxSourceBytes - sourceBytes);
|
|
48893
|
+
if (!hydrated)
|
|
48894
|
+
throw new Error("Fork message source is unavailable");
|
|
48895
|
+
sourceBytes += reference.locator.length;
|
|
48896
|
+
entries.push(hydrated.entry);
|
|
48897
|
+
}
|
|
48898
|
+
if (page.nextAfter === null)
|
|
48899
|
+
break;
|
|
48900
|
+
after = page.nextAfter;
|
|
48901
|
+
}
|
|
48902
|
+
return projectUserMessages(entries);
|
|
48903
|
+
});
|
|
48904
|
+
}
|
|
48335
48905
|
|
|
48336
48906
|
// dist/core/session-jsonl-export.js
|
|
48337
48907
|
import { mkdir as mkdir3, open as open4, unlink } from "node:fs/promises";
|
|
@@ -49394,6 +49964,8 @@ var IMPLEMENTATION_CONTRACT = [
|
|
|
49394
49964
|
"Preserve earlier requirements unless later instructions replace them. Apply stated eligibility, priorities, and decision order literally, even when a different policy seems simpler or more sensible; reevaluate later decisions when earlier actions change their inputs.",
|
|
49395
49965
|
"The required commands must implement the stated workflow from its stated starting state, without development-only state or extra steps.",
|
|
49396
49966
|
"During tool-based inspection of large datasets, request schemas or small samples. Process full inputs in local code instead of printing entire datasets into the conversation.",
|
|
49967
|
+
"Read long text in bounded pages; use a character limit as well as a line limit when lines are long. If output is truncated, page the retained result instead of repeating the original command or printing the whole file again.",
|
|
49968
|
+
"Batch nonurgent child updates. Send results, blockers, or decisions that need action rather than acknowledgements and repeated status requests. Continue independent work while children run, and report meaningful milestones to the user.",
|
|
49397
49969
|
"Do not repeat a successful check without a concrete reason, such as changed input, an edit, or an observed failure.",
|
|
49398
49970
|
"Choose algorithms whose time and memory costs fit the stated input limits.",
|
|
49399
49971
|
"For constrained search, prune known-impossible partial states before expanding them; do not postpone all feasibility checks until completed candidates.",
|
|
@@ -49457,7 +50029,7 @@ ${childDoctrine}`;
|
|
|
49457
50029
|
if (harnessState) {
|
|
49458
50030
|
prompt2 += `
|
|
49459
50031
|
|
|
49460
|
-
${formatHarnessStateForPrompt(harnessState, { includeIpythonExamples: hasIpython, includeShellExamples: hasBash, includeRefineExamples: hasIpython && hasRefineSkill, errorFixSelection: options.errorFixSelection })}`;
|
|
50032
|
+
${formatHarnessStateForPrompt(harnessState, { includeIpythonExamples: hasIpython, includeShellExamples: hasBash, includeRefineExamples: hasIpython && hasRefineSkill, errorFixSelection: options.errorFixSelection, section: options.harnessSection })}`;
|
|
49461
50033
|
}
|
|
49462
50034
|
if (genericMcpSection) {
|
|
49463
50035
|
prompt2 += `
|
|
@@ -49496,7 +50068,7 @@ ${buildSubagentGuidance({
|
|
|
49496
50068
|
if (harnessState) {
|
|
49497
50069
|
prompt += `
|
|
49498
50070
|
|
|
49499
|
-
${formatHarnessStateForPrompt(harnessState, { includeIpythonExamples: hasIpython, includeShellExamples: hasBash, includeRefineExamples: hasIpython && hasRefineSkill, errorFixSelection: options.errorFixSelection })}`;
|
|
50071
|
+
${formatHarnessStateForPrompt(harnessState, { includeIpythonExamples: hasIpython, includeShellExamples: hasBash, includeRefineExamples: hasIpython && hasRefineSkill, errorFixSelection: options.errorFixSelection, section: options.harnessSection })}`;
|
|
49500
50072
|
}
|
|
49501
50073
|
if (genericMcpSection) {
|
|
49502
50074
|
prompt += `
|
|
@@ -58610,6 +59182,7 @@ var StaleCompactionOwnerError = class extends Error {
|
|
|
58610
59182
|
function createPostCompactionContinuationSettlement(resume) {
|
|
58611
59183
|
return { ...createAgentMessageDeferred(), resume, settled: false };
|
|
58612
59184
|
}
|
|
59185
|
+
var RLM_PARENT_USAGE_CUSTOM_TYPE = "rlm_parent_usage";
|
|
58613
59186
|
var KERNEL_STATE_LISTING_TIMEOUT_MS = 5e3;
|
|
58614
59187
|
var RLM_MAX_DEPTH_STATE_CUSTOM_TYPE = "rlm_max_depth_state";
|
|
58615
59188
|
function noopRlmChildAbort() {
|
|
@@ -58847,6 +59420,8 @@ var AgentSession = class _AgentSession {
|
|
|
58847
59420
|
// Kept alive for retained children so nested updates (e.g. a grandchild cancel)
|
|
58848
59421
|
// still forward to root; torn down when the retained child is disposed.
|
|
58849
59422
|
_rlmChildUnsubscribes = /* @__PURE__ */ new Map();
|
|
59423
|
+
_rlmChildUsageSources = /* @__PURE__ */ new Map();
|
|
59424
|
+
_rlmParentUsageAttribution;
|
|
58850
59425
|
/** Latest recap for this session, written by the daemon summarizer; read by a parent to label its child snapshots. */
|
|
58851
59426
|
_currentRecap;
|
|
58852
59427
|
_initialGoal;
|
|
@@ -58962,10 +59537,12 @@ var AgentSession = class _AgentSession {
|
|
|
58962
59537
|
await this._goalResumeOperation;
|
|
58963
59538
|
await this._waitForAgentEventsBeforeContext();
|
|
58964
59539
|
await this._waitForChildUsageWrites();
|
|
59540
|
+
const assertHarnessSourceCurrent = await this._appendHarnessSnapshotIfChanged();
|
|
58965
59541
|
await this.sessionManager.flushNow();
|
|
59542
|
+
assertHarnessSourceCurrent();
|
|
58966
59543
|
if (!this.sessionManager.isPersisted()) {
|
|
58967
59544
|
if (!this._compactionSetupFailure)
|
|
58968
|
-
return;
|
|
59545
|
+
return { messages: this.agent.state.messages, adoptMessages: true };
|
|
58969
59546
|
const rebuilt = await readSessionBootstrap(this.sessionManager, this.settingsManager.getCanonicalContextLimits());
|
|
58970
59547
|
this._compactionSetupFailure = void 0;
|
|
58971
59548
|
return { messages: rebuilt.context.messages, adoptMessages: true };
|
|
@@ -59019,7 +59596,7 @@ var AgentSession = class _AgentSession {
|
|
|
59019
59596
|
const epochContext = getCanonicalEpochContext(messages);
|
|
59020
59597
|
if (epochContext)
|
|
59021
59598
|
this._contextMode = epochContext.mode;
|
|
59022
|
-
const unbudgetedPublic = !contextEpochsEnabled && Boolean(epochContext?.toolContinuations?.length || epochContext?.taskFrameRebased || epochContext?.checkpoint);
|
|
59599
|
+
const unbudgetedPublic = !contextEpochsEnabled && Boolean(epochContext?.toolContinuations?.length || epochContext?.taskFrameRebased || epochContext?.checkpoint || getCanonicalViewSelectionSource(messages)?.recoveryContractRequested);
|
|
59023
59600
|
const nativeSkills = Boolean(contextEpochsEnabled || epochContext?.checkpoint || unbudgetedPublic);
|
|
59024
59601
|
const skillPolicy = nativeSkills ? this._nativeRecoveryEnabled() ? "enabled" : "unavailable" : void 0;
|
|
59025
59602
|
if (this._baseSystemPromptOptions.nativeSkillSelection !== skillPolicy) {
|
|
@@ -59055,7 +59632,19 @@ var AgentSession = class _AgentSession {
|
|
|
59055
59632
|
if (epochContext.toolContinuations?.length && (!candidate.publicMessages || JSON.stringify(getCanonicalEpochContext(candidate.publicMessages)?.toolContinuations) !== JSON.stringify(epochContext.toolContinuations) || candidate.projection.pendingPublicMessageGroups?.length))
|
|
59056
59633
|
throw new Error("Tool continuation requires its exact public candidate before epoch ACK");
|
|
59057
59634
|
assertResourceCurrent(resource);
|
|
59058
|
-
|
|
59635
|
+
let representation;
|
|
59636
|
+
try {
|
|
59637
|
+
representation = contextEpochRepresentation(candidate.request, candidate.assessment, limits.maxSourceBytes, unbudgetedPublic, candidate.responseItemIdentity);
|
|
59638
|
+
} catch (error) {
|
|
59639
|
+
if (error instanceof UnsupportedContextEpochConfigurationError && !contextEpochsEnabled && !candidate.assessment && !committed && !acknowledged && !epochContext.taskFrameRebased && !epochContext.selectedSkills?.length && !epochContext.toolContinuations?.length && !candidate.publicMessages) {
|
|
59640
|
+
const source = getCanonicalViewSelectionSource(messages);
|
|
59641
|
+
const selected = new Set(candidate.selectedUnitIds);
|
|
59642
|
+
if (source.recoveryContractRequested && !source.requiresEpoch && !source.pendingPublicMessageGroups?.length && this.sessionManager === epochManager && compaction.isCurrent() && JSON.stringify(candidate.source) === JSON.stringify(source.source) && candidate.selectedUnitIds.length === source.units.length && selected.size === source.units.length && source.units.every((unit) => selected.has(unit.id))) {
|
|
59643
|
+
return;
|
|
59644
|
+
}
|
|
59645
|
+
}
|
|
59646
|
+
throw error;
|
|
59647
|
+
}
|
|
59059
59648
|
const replayContract = "replayContract" in candidate.projection && candidate.projection.replayContract === "message-groups" ? "message-groups" : "complete-context";
|
|
59060
59649
|
const publicWindow = "publicWindow" in candidate.projection && candidate.projection.publicWindow === true;
|
|
59061
59650
|
const selection = JSON.stringify([
|
|
@@ -61040,7 +61629,7 @@ var AgentSession = class _AgentSession {
|
|
|
61040
61629
|
if (compactionTimestamp !== void 0 && context.message.timestamp <= compactionTimestamp)
|
|
61041
61630
|
return false;
|
|
61042
61631
|
const contextTokens = this._getThresholdContextTokens(context.message, compactionTimestamp);
|
|
61043
|
-
if (contextTokens === void 0 || !shouldCompact(contextTokens, contextWindow, settings))
|
|
61632
|
+
if (contextTokens === void 0 || !shouldCompact(contextTokens, contextWindow, settings, estimateFixedCompactionTokens(this.systemPrompt, this.agent.state.tools, this.messages)))
|
|
61044
61633
|
return false;
|
|
61045
61634
|
if (this._hasFailedThresholdCompaction())
|
|
61046
61635
|
return false;
|
|
@@ -61373,7 +61962,7 @@ var AgentSession = class _AgentSession {
|
|
|
61373
61962
|
}
|
|
61374
61963
|
return {
|
|
61375
61964
|
scheduled: true,
|
|
61376
|
-
note: "Refinement runs when the current turn ends;
|
|
61965
|
+
note: "Refinement runs when the current turn ends; fresh harness advice is added to the next request and you resume automatically. Continue working normally."
|
|
61377
61966
|
};
|
|
61378
61967
|
}
|
|
61379
61968
|
default:
|
|
@@ -62316,6 +62905,7 @@ var AgentSession = class _AgentSession {
|
|
|
62316
62905
|
for (const { session } of this._rlmChildSessions.values())
|
|
62317
62906
|
await drain(() => session.disposeAsync());
|
|
62318
62907
|
this._rlmChildSessions.clear();
|
|
62908
|
+
this._rlmChildUsageSources.clear();
|
|
62319
62909
|
this._rlmChildCleanupFailures.clear();
|
|
62320
62910
|
this._deletedRlmChildIds.clear();
|
|
62321
62911
|
await drain(() => this._ipythonKernelProvisioner?.dispose({ snapshot: kernelSnapshot }));
|
|
@@ -62405,6 +62995,7 @@ var AgentSession = class _AgentSession {
|
|
|
62405
62995
|
session.dispose();
|
|
62406
62996
|
}
|
|
62407
62997
|
this._rlmChildSessions.clear();
|
|
62998
|
+
this._rlmChildUsageSources.clear();
|
|
62408
62999
|
this._rlmChildCleanupFailures.clear();
|
|
62409
63000
|
this._deletedRlmChildIds.clear();
|
|
62410
63001
|
this._pendingNextTurnMessages = [];
|
|
@@ -62639,6 +63230,7 @@ var AgentSession = class _AgentSession {
|
|
|
62639
63230
|
rlmDepth: this._rlmDepth,
|
|
62640
63231
|
rlmParentAgent: this._rlmParentAgent,
|
|
62641
63232
|
harnessState: this._loadMergedHarnessState(),
|
|
63233
|
+
harnessSection: "instructions",
|
|
62642
63234
|
errorFixSelection: {
|
|
62643
63235
|
enabled: this.settingsManager.getLearningEnabled(),
|
|
62644
63236
|
tools: validToolNames,
|
|
@@ -62651,6 +63243,106 @@ var AgentSession = class _AgentSession {
|
|
|
62651
63243
|
};
|
|
62652
63244
|
return buildSystemPrompt(this._baseSystemPromptOptions);
|
|
62653
63245
|
}
|
|
63246
|
+
/** Read only snapshot candidates in the active literal tail and accepted epoch recipes. */
|
|
63247
|
+
async _readHarnessSnapshot(view) {
|
|
63248
|
+
const { maxMessages, maxSourceBytes } = this.settingsManager.getCanonicalContextLimits();
|
|
63249
|
+
const refs = [];
|
|
63250
|
+
let summary = null;
|
|
63251
|
+
let cursor;
|
|
63252
|
+
let count = 0;
|
|
63253
|
+
let bytes = 0;
|
|
63254
|
+
do {
|
|
63255
|
+
const page = await view.contextManifest({ cursor, limit: 128 });
|
|
63256
|
+
if (page.selection !== "known")
|
|
63257
|
+
throw new Error(`Harness snapshot context selection is ${page.selection}`);
|
|
63258
|
+
summary = page.summaryRef;
|
|
63259
|
+
count += page.refs.length;
|
|
63260
|
+
if (count + (summary ? 1 : 0) > maxMessages)
|
|
63261
|
+
throw new Error("Harness snapshot context message budget exceeded");
|
|
63262
|
+
refs.push(...page.refs.filter((ref) => ref.kind === "custom_message"));
|
|
63263
|
+
cursor = page.nextCursor ?? void 0;
|
|
63264
|
+
} while (cursor);
|
|
63265
|
+
const read2 = async (ref, source = view) => {
|
|
63266
|
+
bytes += ref.locator.length;
|
|
63267
|
+
if (bytes > maxSourceBytes)
|
|
63268
|
+
throw new Error("Harness snapshot source byte budget exceeded");
|
|
63269
|
+
const metadata = await source.get(ref.entryId);
|
|
63270
|
+
if (!metadata || metadata.revision !== ref.revision)
|
|
63271
|
+
throw new Error("Harness snapshot source is unavailable");
|
|
63272
|
+
const hydrated = await hydrateCapturedHistoryEntry(metadata, ref.locator.length, source.readPayload);
|
|
63273
|
+
if (!hydrated)
|
|
63274
|
+
throw new Error("Harness snapshot payload is unavailable");
|
|
63275
|
+
return hydrated.entry;
|
|
63276
|
+
};
|
|
63277
|
+
const content = (entry2) => entry2.type === "custom_message" && entry2.customType === HARNESS_SNAPSHOT_CUSTOM_TYPE && typeof entry2.content === "string" ? entry2.content : void 0;
|
|
63278
|
+
for (const ref of refs.reverse()) {
|
|
63279
|
+
const snapshot = content(await read2(ref));
|
|
63280
|
+
if (snapshot !== void 0)
|
|
63281
|
+
return snapshot;
|
|
63282
|
+
}
|
|
63283
|
+
if (!summary)
|
|
63284
|
+
return;
|
|
63285
|
+
const entry = await read2(summary);
|
|
63286
|
+
if (entry.type !== "compaction" || summary.qualification !== "native-context-epoch" || summary.retention === "retained-import")
|
|
63287
|
+
return;
|
|
63288
|
+
const checkpoint = readContextEpoch(entry.details, maxSourceBytes);
|
|
63289
|
+
if (!checkpoint)
|
|
63290
|
+
return;
|
|
63291
|
+
if (count + checkpoint.views.length > maxMessages)
|
|
63292
|
+
throw new Error("Harness snapshot context message budget exceeded");
|
|
63293
|
+
for (const pinned of [...checkpoint.views].reverse()) {
|
|
63294
|
+
if (pinned.ref.kind !== "custom_message")
|
|
63295
|
+
continue;
|
|
63296
|
+
if (!view.atSnapshot)
|
|
63297
|
+
throw new Error("Harness snapshot epoch requires its captured source");
|
|
63298
|
+
const snapshot = content(await read2(pinned.ref, await view.atSnapshot(pinned.source)));
|
|
63299
|
+
if (snapshot !== void 0)
|
|
63300
|
+
return snapshot;
|
|
63301
|
+
}
|
|
63302
|
+
}
|
|
63303
|
+
/** Persist mutable advice before the request owner captures its source and epoch ACK boundary. */
|
|
63304
|
+
async _appendHarnessSnapshotIfChanged() {
|
|
63305
|
+
const manager = this.sessionManager;
|
|
63306
|
+
let leafId = manager.getLeafId();
|
|
63307
|
+
const sourceIsCurrent = manager.captureCompactionSourceOwner();
|
|
63308
|
+
const assertCurrent = () => {
|
|
63309
|
+
if (this._disposed || this.sessionManager !== manager || !sourceIsCurrent() || manager.getLeafId() !== leafId)
|
|
63310
|
+
throw new Error("Harness snapshot source changed before request ownership");
|
|
63311
|
+
};
|
|
63312
|
+
let previous;
|
|
63313
|
+
if (manager.isPersisted()) {
|
|
63314
|
+
previous = await manager.readBranchHistory((view) => this._readHarnessSnapshot(view.branchContext));
|
|
63315
|
+
} else {
|
|
63316
|
+
const snapshot = manager.buildSessionContext().messages.reverse().find((message2) => message2.role === "custom" && message2.customType === HARNESS_SNAPSHOT_CUSTOM_TYPE);
|
|
63317
|
+
if (snapshot?.role === "custom")
|
|
63318
|
+
previous = snapshot.content;
|
|
63319
|
+
}
|
|
63320
|
+
assertCurrent();
|
|
63321
|
+
const options = this._baseSystemPromptOptions;
|
|
63322
|
+
const tools = options.selectedTools ?? [];
|
|
63323
|
+
const hasIpython = tools.includes("ipython");
|
|
63324
|
+
const content = formatHarnessStateForPrompt(this._loadMergedHarnessState(), {
|
|
63325
|
+
section: "entries",
|
|
63326
|
+
includeIpythonExamples: hasIpython,
|
|
63327
|
+
includeShellExamples: tools.includes("bash"),
|
|
63328
|
+
errorFixSelection: options.errorFixSelection ? { ...options.errorFixSelection, enabled: this.settingsManager.getLearningEnabled() } : void 0
|
|
63329
|
+
});
|
|
63330
|
+
if (previous === content)
|
|
63331
|
+
return assertCurrent;
|
|
63332
|
+
const entryId = await manager.appendCustomMessageEntryWithRollback(HARNESS_SNAPSHOT_CUSTOM_TYPE, content, false);
|
|
63333
|
+
if (this._disposed || this.sessionManager !== manager || !sourceIsCurrent() || manager.getLeafId() !== entryId)
|
|
63334
|
+
throw new Error("Harness snapshot source changed during append");
|
|
63335
|
+
if (!manager.isPersisted())
|
|
63336
|
+
this.agent.state.messages.push({
|
|
63337
|
+
role: "custom",
|
|
63338
|
+
customType: HARNESS_SNAPSHOT_CUSTOM_TYPE,
|
|
63339
|
+
content,
|
|
63340
|
+
display: false,
|
|
63341
|
+
timestamp: Date.now()
|
|
63342
|
+
});
|
|
63343
|
+
leafId = entryId;
|
|
63344
|
+
return assertCurrent;
|
|
63345
|
+
}
|
|
62654
63346
|
_refreshExtensionSystemPrompt(extensionPrompt, baseSnapshot) {
|
|
62655
63347
|
if (this._baseSystemPrompt === baseSnapshot) {
|
|
62656
63348
|
return extensionPrompt;
|
|
@@ -62704,7 +63396,7 @@ var AgentSession = class _AgentSession {
|
|
|
62704
63396
|
async _runPreTurnCompaction() {
|
|
62705
63397
|
const lastAssistant = this._findLastAssistantMessage();
|
|
62706
63398
|
if (lastAssistant)
|
|
62707
|
-
await this._checkCompaction(lastAssistant, false, false);
|
|
63399
|
+
await this._checkCompaction(lastAssistant, false, false, void 0, true);
|
|
62708
63400
|
}
|
|
62709
63401
|
async _prepareForCommit(policy, steps) {
|
|
62710
63402
|
if (policy.initialRefineBarrier === "always" || policy.initialRefineBarrier === "ifInFlight" && this._refineInFlight) {
|
|
@@ -65384,7 +66076,7 @@ ${parsed.args}` : block;
|
|
|
65384
66076
|
}
|
|
65385
66077
|
}
|
|
65386
66078
|
/** A private compiled context keeps extension summary edits separate from retained source recipes. */
|
|
65387
|
-
async _prepareCapturedCompaction(pathEntries, settings, requests, compaction, owner = this._captureCompactionOwner(), allowShortSession = false, budgetPressure = false) {
|
|
66079
|
+
async _prepareCapturedCompaction(pathEntries, settings, requests, compaction, owner = this._captureCompactionOwner(), allowShortSession = false, budgetPressure = false, capacity) {
|
|
65388
66080
|
this._assertCompactionOwner(owner);
|
|
65389
66081
|
const limits = this.settingsManager.getCanonicalContextLimits();
|
|
65390
66082
|
const resource = this._captureKernelResource();
|
|
@@ -65401,10 +66093,11 @@ ${parsed.args}` : block;
|
|
|
65401
66093
|
const context = getCanonicalEpochContext(messages);
|
|
65402
66094
|
if (context.checkpoint?.includeSummary && pathEntries.at(-1)?.type === "compaction")
|
|
65403
66095
|
return { preparation: void 0, maxSourceBytes: limits.maxSourceBytes };
|
|
65404
|
-
const
|
|
66096
|
+
const authorization = getRecoveryCompactionAuthorization(capacity);
|
|
66097
|
+
const boundary = canonicalRecoveryBoundary(messages, authorization);
|
|
65405
66098
|
const preparation = budgetPressure || context.checkpoint || boundary ? prepareViewCompaction(messages, context.references.map((ref) => ref?.ref.entryId), pathEntries, settings, boundary, allowShortSession, budgetPressure) : prepareCompaction(pathEntries, settings, allowShortSession);
|
|
65406
66099
|
if (preparation)
|
|
65407
|
-
prepareRecoveryCompaction(messages, preparation.firstKeptEntryId, limits.maxSourceBytes);
|
|
66100
|
+
prepareRecoveryCompaction(messages, preparation.firstKeptEntryId, limits.maxSourceBytes, authorization);
|
|
65408
66101
|
return {
|
|
65409
66102
|
preparation,
|
|
65410
66103
|
messages,
|
|
@@ -65420,7 +66113,7 @@ ${parsed.args}` : block;
|
|
|
65420
66113
|
*/
|
|
65421
66114
|
async _performCompaction(options) {
|
|
65422
66115
|
const { model, apiKey, headers, customInstructions, signal, thinkingLevel, requests, compaction, semanticEdges, pathEntries, settings, owner = this._captureCompactionOwner(), allowShortSession = false, budgetPressure = false } = options;
|
|
65423
|
-
const prepared = await this._prepareCapturedCompaction(pathEntries, settings, requests, compaction, owner, allowShortSession, budgetPressure);
|
|
66116
|
+
const prepared = await this._prepareCapturedCompaction(pathEntries, settings, requests, compaction, owner, allowShortSession, budgetPressure, options.capacity);
|
|
65424
66117
|
this._assertCompactionOwner(owner);
|
|
65425
66118
|
if (prepared.resource)
|
|
65426
66119
|
assertResourceCurrent(prepared.resource);
|
|
@@ -65501,7 +66194,7 @@ ${parsed.args}` : block;
|
|
|
65501
66194
|
}
|
|
65502
66195
|
this._assertCompactionOwner(owner);
|
|
65503
66196
|
const result = JSON.parse(JSON.stringify({ summary, firstKeptEntryId, tokensBefore, details }));
|
|
65504
|
-
const recovery = prepared.messages ? prepareRecoveryCompaction(prepared.messages, firstKeptEntryId, prepared.maxSourceBytes) : void 0;
|
|
66197
|
+
const recovery = prepared.messages ? prepareRecoveryCompaction(prepared.messages, firstKeptEntryId, prepared.maxSourceBytes, getRecoveryCompactionAuthorization(options.capacity)) : void 0;
|
|
65505
66198
|
if (prepared.resource)
|
|
65506
66199
|
assertResourceCurrent(prepared.resource);
|
|
65507
66200
|
if (recovery) {
|
|
@@ -66124,7 +66817,30 @@ ${parsed.args}` : block;
|
|
|
66124
66817
|
const sessionHistory = (async () => {
|
|
66125
66818
|
if (residentEntries !== void 0)
|
|
66126
66819
|
return residentEntries;
|
|
66127
|
-
return
|
|
66820
|
+
return this.sessionManager.readSourceHistory(async (history) => {
|
|
66821
|
+
const entries = [];
|
|
66822
|
+
let sourceBytes = 0;
|
|
66823
|
+
let after = 0;
|
|
66824
|
+
for (; ; ) {
|
|
66825
|
+
const page = await history.page(after, 128);
|
|
66826
|
+
if (page.indexedThrough < history.source.sourceSequence)
|
|
66827
|
+
throw new Error("Captured refinement history has incomplete index coverage");
|
|
66828
|
+
for (const reference of page.events) {
|
|
66829
|
+
if (reference.kind !== "custom")
|
|
66830
|
+
continue;
|
|
66831
|
+
if (entries.length >= limits.maxEntries)
|
|
66832
|
+
throw new Error("Refinement history entry budget exceeded");
|
|
66833
|
+
if (sourceBytes + reference.locator.length > limits.maxSourceBytes)
|
|
66834
|
+
throw new Error("Refinement history source byte budget exceeded");
|
|
66835
|
+
const hydrated = await hydrateCapturedHistoryEntry(reference, limits.maxSourceBytes - sourceBytes, history.readPayload);
|
|
66836
|
+
entries.push(hydrated.entry);
|
|
66837
|
+
sourceBytes += reference.locator.length;
|
|
66838
|
+
}
|
|
66839
|
+
if (page.nextAfter === null)
|
|
66840
|
+
return entries;
|
|
66841
|
+
after = page.nextAfter;
|
|
66842
|
+
}
|
|
66843
|
+
});
|
|
66128
66844
|
})();
|
|
66129
66845
|
const [globalResult, sessionResult] = await Promise.allSettled([globalHistory, sessionHistory]);
|
|
66130
66846
|
if (globalResult.status === "rejected") {
|
|
@@ -66391,8 +67107,10 @@ ${parsed.args}` : block;
|
|
|
66391
67107
|
}
|
|
66392
67108
|
if (refinementAuditAppendError)
|
|
66393
67109
|
throw refinementAuditAppendError.error;
|
|
66394
|
-
this.
|
|
66395
|
-
|
|
67110
|
+
this._baseSystemPromptOptions = {
|
|
67111
|
+
...this._baseSystemPromptOptions,
|
|
67112
|
+
harnessState: this._loadMergedHarnessState()
|
|
67113
|
+
};
|
|
66396
67114
|
try {
|
|
66397
67115
|
this._emit({ type: "refine_complete", result });
|
|
66398
67116
|
} catch {
|
|
@@ -66445,7 +67163,7 @@ ${parsed.args}` : block;
|
|
|
66445
67163
|
return void 0;
|
|
66446
67164
|
return calculateContextTokens(assistantMessage.usage);
|
|
66447
67165
|
}
|
|
66448
|
-
async _checkCompaction(assistantMessage, skipAbortedCheck = true, queueAutonomousContinuation = true, invocationOwner) {
|
|
67166
|
+
async _checkCompaction(assistantMessage, skipAbortedCheck = true, queueAutonomousContinuation = true, invocationOwner, beforeNextTurn = false) {
|
|
66449
67167
|
if (this._compactionSetupFailure)
|
|
66450
67168
|
return false;
|
|
66451
67169
|
if (invocationOwner && !this._isCompactionSourceOwnerCurrent(invocationOwner))
|
|
@@ -66518,7 +67236,7 @@ ${parsed.args}` : block;
|
|
|
66518
67236
|
if (messages.length > 0 && messages[messages.length - 1].role === "assistant") {
|
|
66519
67237
|
this._removeLastAssistantFromContext();
|
|
66520
67238
|
}
|
|
66521
|
-
return await this._runAutoCompaction("overflow", true, owner);
|
|
67239
|
+
return await this._runAutoCompaction("overflow", true, owner, false, void 0, beforeNextTurn);
|
|
66522
67240
|
}
|
|
66523
67241
|
if (this._pendingRequestedCompaction !== void 0) {
|
|
66524
67242
|
return await this._runAutoCompaction("requested", false, owner);
|
|
@@ -66530,7 +67248,7 @@ ${parsed.args}` : block;
|
|
|
66530
67248
|
const contextTokens = this._getThresholdContextTokens(assistantMessage, compactionTimestamp);
|
|
66531
67249
|
if (contextTokens === void 0)
|
|
66532
67250
|
return false;
|
|
66533
|
-
if (shouldCompact(contextTokens, contextWindow, settings)) {
|
|
67251
|
+
if (shouldCompact(contextTokens, contextWindow, settings, estimateFixedCompactionTokens(this.systemPrompt, this.agent.state.tools, this.messages))) {
|
|
66534
67252
|
if (this._hasFailedThresholdCompaction())
|
|
66535
67253
|
return false;
|
|
66536
67254
|
if (!this._pendingCheckpoint && queueAutonomousContinuation) {
|
|
@@ -66540,7 +67258,7 @@ ${parsed.args}` : block;
|
|
|
66540
67258
|
}
|
|
66541
67259
|
if (!this._isCompactionOwnerCurrent(owner) || !this._contextOptimizationAllowed())
|
|
66542
67260
|
return false;
|
|
66543
|
-
return await this._runAutoCompaction("threshold", false, owner);
|
|
67261
|
+
return await this._runAutoCompaction("threshold", false, owner, false, void 0, beforeNextTurn);
|
|
66544
67262
|
}
|
|
66545
67263
|
return false;
|
|
66546
67264
|
}
|
|
@@ -66586,7 +67304,7 @@ This compaction outcome could not be saved to session history: ${persistenceErro
|
|
|
66586
67304
|
this._emit({ type: "message_start", message: outcomeMessage });
|
|
66587
67305
|
this._emit({ type: "message_end", message: outcomeMessage });
|
|
66588
67306
|
}
|
|
66589
|
-
async _runAutoCompaction(reason, willRetry, capturedOwner, resumeInPlace = false, capacity) {
|
|
67307
|
+
async _runAutoCompaction(reason, willRetry, capturedOwner, resumeInPlace = false, capacity, beforeNextTurn = false) {
|
|
66590
67308
|
const checkpoint = this._pendingCheckpoint;
|
|
66591
67309
|
const pending = this._pendingRequestedCompaction;
|
|
66592
67310
|
const owner = checkpoint?.owner ?? pending?.owner ?? capturedOwner ?? this._captureCompactionOwner();
|
|
@@ -66699,6 +67417,12 @@ This compaction outcome could not be saved to session history: ${persistenceErro
|
|
|
66699
67417
|
if (!this._isCompactionSourceOwnerCurrent(owner))
|
|
66700
67418
|
throw failure2;
|
|
66701
67419
|
this._clearQueuedAutonomousContinuationsAfterSkippedThresholdCompaction(reason === "threshold" && shouldContinueAfterCompaction, queuedAutonomousContinuationsForThisCompaction);
|
|
67420
|
+
if (beforeNextTurn && error instanceof MissingRecoveryReplayContractError) {
|
|
67421
|
+
if (reason === "overflow")
|
|
67422
|
+
this._overflowRecovery = "idle";
|
|
67423
|
+
await this._endCompactionUnsuccessfully(reason, "skipped", "Compaction deferred until the next native request establishes recovery replay coverage.", { errorSeverity: "warning", customInstructions, owner });
|
|
67424
|
+
return false;
|
|
67425
|
+
}
|
|
66702
67426
|
const errorMessage4 = error instanceof Error ? error.message : "compaction failed";
|
|
66703
67427
|
const aborted = errorMessage4 === "Compaction cancelled" || error instanceof Error && error.name === "AbortError" || abort.signal.aborted;
|
|
66704
67428
|
if (aborted) {
|
|
@@ -67947,6 +68671,7 @@ This compaction outcome could not be saved to session history: ${persistenceErro
|
|
|
67947
68671
|
this._rlmChildUnsubscribes.get(childId)?.();
|
|
67948
68672
|
this._rlmChildUnsubscribes.delete(childId);
|
|
67949
68673
|
this._rlmChildSessions.delete(childId);
|
|
68674
|
+
this._rlmChildUsageSources.delete(childId);
|
|
67950
68675
|
this._rlmChildCleanupFailures.delete(childId);
|
|
67951
68676
|
this._abandonedRlmQuiescenceChildIds.delete(childId);
|
|
67952
68677
|
if (!run2 || this._activeRlmChildRuns.get(childId) === run2) {
|
|
@@ -68021,6 +68746,145 @@ This compaction outcome could not be saved to session history: ${persistenceErro
|
|
|
68021
68746
|
this._removeRlmSubagentTracking(childId);
|
|
68022
68747
|
return { subagent };
|
|
68023
68748
|
}
|
|
68749
|
+
async _restoreRlmChildUsageSource(childId, child) {
|
|
68750
|
+
if (this._rlmChildUsageSources.has(childId))
|
|
68751
|
+
return;
|
|
68752
|
+
const readSource = (entry) => {
|
|
68753
|
+
if (entry.type !== "custom" || entry.customType !== RLM_PARENT_USAGE_CUSTOM_TYPE)
|
|
68754
|
+
return;
|
|
68755
|
+
const data = entry.data;
|
|
68756
|
+
if (!data || data.sessionId !== this.sessionId || data.sessionFile !== this.sessionFile || typeof data.entryId !== "string")
|
|
68757
|
+
return;
|
|
68758
|
+
return { sessionId: data.sessionId, sessionFile: data.sessionFile, entryId: data.entryId };
|
|
68759
|
+
};
|
|
68760
|
+
const source = child.sessionManager.supportsCapturedHistoryReads() ? await child.sessionManager.readBranchHistory(async (history) => {
|
|
68761
|
+
let after = 0;
|
|
68762
|
+
while (true) {
|
|
68763
|
+
const page = await history.page(after, 64);
|
|
68764
|
+
for (const ref of page.events) {
|
|
68765
|
+
if (ref.kind !== "custom" || ref.locator.length > 16 * 1024)
|
|
68766
|
+
continue;
|
|
68767
|
+
const record2 = await history.hydrateEntry(ref.id, 16 * 1024);
|
|
68768
|
+
const source2 = record2 && readSource(record2.entry);
|
|
68769
|
+
if (source2)
|
|
68770
|
+
return source2;
|
|
68771
|
+
}
|
|
68772
|
+
if (page.nextAfter === null)
|
|
68773
|
+
return;
|
|
68774
|
+
after = page.nextAfter;
|
|
68775
|
+
}
|
|
68776
|
+
}) : child.sessionManager.getBranch().map(readSource).find((source2) => source2 !== void 0);
|
|
68777
|
+
if (!source || source.sessionId !== this.sessionId || source.sessionFile !== this.sessionFile)
|
|
68778
|
+
return;
|
|
68779
|
+
const target = await this.sessionManager.readEntry(source.entryId);
|
|
68780
|
+
if (target?.type !== "message" || target.message.role !== "assistant")
|
|
68781
|
+
return;
|
|
68782
|
+
if (source.sessionId !== this.sessionId || source.sessionFile !== this.sessionFile)
|
|
68783
|
+
return;
|
|
68784
|
+
this._rlmChildUsageSources.set(childId, source);
|
|
68785
|
+
}
|
|
68786
|
+
_subscribeRlmChildEvents(childId, child, run2, onUsageWrite) {
|
|
68787
|
+
let runningToolCount = 0;
|
|
68788
|
+
const emitChildUpdate = () => {
|
|
68789
|
+
if (run2)
|
|
68790
|
+
run2.emitUpdate?.();
|
|
68791
|
+
else
|
|
68792
|
+
this._emit({ type: "rlm_child_update", child: this._rlmChildSnapshotForSession(childId, child) });
|
|
68793
|
+
};
|
|
68794
|
+
const attributeUsage = (usage, origin) => {
|
|
68795
|
+
const source = this._rlmChildUsageSources.get(childId);
|
|
68796
|
+
if (!source || source.sessionId !== this.sessionId || source.sessionFile !== this.sessionFile)
|
|
68797
|
+
return Promise.resolve();
|
|
68798
|
+
const delta = structuredClone(usage);
|
|
68799
|
+
const target = this.messages.find((message2) => message2.role === "assistant" && this._findAssistantEntryIdForMessage(message2) === source.entryId);
|
|
68800
|
+
const refreshOutput = this._refreshInvocationOutput;
|
|
68801
|
+
const forwardUsage = this._rlmParentUsageAttribution;
|
|
68802
|
+
const write2 = this.sessionManager.appendChildUsageAttributionWithAggregate(source.entryId, delta, void 0, origin).then(async ({ aggregateUsage }) => {
|
|
68803
|
+
if (target) {
|
|
68804
|
+
target.usage = structuredClone(aggregateUsage);
|
|
68805
|
+
refreshOutput?.(target);
|
|
68806
|
+
}
|
|
68807
|
+
await forwardUsage?.(delta, origin);
|
|
68808
|
+
});
|
|
68809
|
+
this._childUsageWrites.add(write2);
|
|
68810
|
+
onUsageWrite?.(write2);
|
|
68811
|
+
void write2.then(() => this._childUsageWrites.delete(write2), (error) => {
|
|
68812
|
+
this._childUsageWrites.delete(write2);
|
|
68813
|
+
if (run2)
|
|
68814
|
+
run2.error = `Child usage attribution was not acknowledged: ${this._asError(error).message}`;
|
|
68815
|
+
this._surfaceSessionInputError(error);
|
|
68816
|
+
});
|
|
68817
|
+
return write2;
|
|
68818
|
+
};
|
|
68819
|
+
child._rlmParentUsageAttribution = attributeUsage;
|
|
68820
|
+
const unsubscribe = child.subscribe((event) => {
|
|
68821
|
+
if (event.type === "rlm_child_update") {
|
|
68822
|
+
this._emit(event);
|
|
68823
|
+
return;
|
|
68824
|
+
}
|
|
68825
|
+
if (event.type === "agent_start") {
|
|
68826
|
+
if (run2)
|
|
68827
|
+
run2.activity = { kind: "waiting" };
|
|
68828
|
+
emitChildUpdate();
|
|
68829
|
+
} else if (event.type === "agent_end") {
|
|
68830
|
+
if (run2)
|
|
68831
|
+
run2.activity = void 0;
|
|
68832
|
+
emitChildUpdate();
|
|
68833
|
+
} else if (event.type === "message_end" && event.message.role === "assistant") {
|
|
68834
|
+
const assistant = event.message;
|
|
68835
|
+
if (run2) {
|
|
68836
|
+
run2.terminalAssistantOutcome = {
|
|
68837
|
+
stopReason: assistant.stopReason,
|
|
68838
|
+
errorMessage: assistant.errorMessage
|
|
68839
|
+
};
|
|
68840
|
+
}
|
|
68841
|
+
const update = () => {
|
|
68842
|
+
const text2 = compactRlmText(readAssistantText(assistant));
|
|
68843
|
+
if (run2 && text2)
|
|
68844
|
+
run2.answerPreview = text2;
|
|
68845
|
+
emitChildUpdate();
|
|
68846
|
+
};
|
|
68847
|
+
if (assistant.stopReason !== "error" && assistant.stopReason !== "aborted") {
|
|
68848
|
+
const messages = child.messages;
|
|
68849
|
+
const precedingPrompt = messages.slice(0, messages.lastIndexOf(assistant)).reverse().find((message2) => message2.role === "user" || message2.role === "custom" && message2.customType !== HARNESS_SNAPSHOT_CUSTOM_TYPE);
|
|
68850
|
+
const origin = precedingPrompt?.role === "custom" && isAgentSessionMessage(precedingPrompt) ? precedingPrompt.details.id.startsWith("spawn:") ? "spawn_task" : "agent_message" : "direct_user";
|
|
68851
|
+
void attributeUsage(assistant.usage, origin).then(update, () => {
|
|
68852
|
+
});
|
|
68853
|
+
} else
|
|
68854
|
+
update();
|
|
68855
|
+
} else if (event.type === "message_start" || event.type === "message_update") {
|
|
68856
|
+
if (event.message.role === "assistant") {
|
|
68857
|
+
if (run2) {
|
|
68858
|
+
const text2 = compactRlmText(readAssistantText(event.message));
|
|
68859
|
+
if (text2)
|
|
68860
|
+
run2.answerPreview = text2;
|
|
68861
|
+
run2.activity = { kind: "writing" };
|
|
68862
|
+
}
|
|
68863
|
+
emitChildUpdate();
|
|
68864
|
+
}
|
|
68865
|
+
} else if (event.type === "tool_execution_start") {
|
|
68866
|
+
if (run2) {
|
|
68867
|
+
run2.toolUseCount++;
|
|
68868
|
+
runningToolCount++;
|
|
68869
|
+
run2.activity = { kind: "executing", toolName: event.toolName };
|
|
68870
|
+
}
|
|
68871
|
+
emitChildUpdate();
|
|
68872
|
+
} else if (event.type === "tool_execution_end") {
|
|
68873
|
+
if (run2) {
|
|
68874
|
+
runningToolCount = Math.max(0, runningToolCount - 1);
|
|
68875
|
+
if (runningToolCount === 0)
|
|
68876
|
+
run2.activity = { kind: "waiting" };
|
|
68877
|
+
}
|
|
68878
|
+
emitChildUpdate();
|
|
68879
|
+
} else if (event.type === "session_info_changed" || event.type === "recap_update")
|
|
68880
|
+
emitChildUpdate();
|
|
68881
|
+
});
|
|
68882
|
+
return () => {
|
|
68883
|
+
unsubscribe();
|
|
68884
|
+
if (child._rlmParentUsageAttribution === attributeUsage)
|
|
68885
|
+
child._rlmParentUsageAttribution = void 0;
|
|
68886
|
+
};
|
|
68887
|
+
}
|
|
68024
68888
|
/**
|
|
68025
68889
|
* Retain a finished child session for the parent lifetime so inspectors and
|
|
68026
68890
|
* daemon-hosted agent messaging can keep addressing it. Returns false (and disposes
|
|
@@ -68050,10 +68914,24 @@ This compaction outcome could not be saved to session history: ${persistenceErro
|
|
|
68050
68914
|
}
|
|
68051
68915
|
}
|
|
68052
68916
|
}
|
|
68053
|
-
this.
|
|
68054
|
-
if (
|
|
68055
|
-
|
|
68917
|
+
await this._restoreRlmChildUsageSource(childId, session);
|
|
68918
|
+
if (this._disposed || this._disposing) {
|
|
68919
|
+
await session.disposeAsync();
|
|
68920
|
+
return false;
|
|
68056
68921
|
}
|
|
68922
|
+
if (this._deletingRlmChildren.has(childId) || this._deletedRlmChildIds.has(childId))
|
|
68923
|
+
return false;
|
|
68924
|
+
const retained = this._rlmChildSessions.get(childId);
|
|
68925
|
+
const run2 = this._activeRlmChildRuns.get(childId);
|
|
68926
|
+
if (!run2?.unsubscribe && (retained?.session !== session || !this._rlmChildUnsubscribes.has(childId))) {
|
|
68927
|
+
this._rlmChildUnsubscribes.get(childId)?.();
|
|
68928
|
+
const ownedUnsubscribe = this._subscribeRlmChildEvents(childId, session);
|
|
68929
|
+
this._rlmChildUnsubscribes.set(childId, () => {
|
|
68930
|
+
ownedUnsubscribe();
|
|
68931
|
+
unsubscribe?.();
|
|
68932
|
+
});
|
|
68933
|
+
}
|
|
68934
|
+
this._rlmChildSessions.set(childId, { session, run: run2 });
|
|
68057
68935
|
return true;
|
|
68058
68936
|
}
|
|
68059
68937
|
releaseRlmChildSession(childId, session) {
|
|
@@ -68061,8 +68939,10 @@ This compaction outcome could not be saved to session history: ${persistenceErro
|
|
|
68061
68939
|
if (run2?.session === session && run2.status === "done") {
|
|
68062
68940
|
const unsubscribe2 = run2.unsubscribe ?? noopRlmChildEventUnsubscribe;
|
|
68063
68941
|
return () => {
|
|
68064
|
-
run2.unsubscribe
|
|
68065
|
-
|
|
68942
|
+
if (run2.unsubscribe === unsubscribe2)
|
|
68943
|
+
run2.unsubscribe = void 0;
|
|
68944
|
+
if (this._activeRlmChildRuns.get(childId) === run2)
|
|
68945
|
+
this._activeRlmChildRuns.delete(childId);
|
|
68066
68946
|
unsubscribe2();
|
|
68067
68947
|
};
|
|
68068
68948
|
}
|
|
@@ -68070,8 +68950,10 @@ This compaction outcome could not be saved to session history: ${persistenceErro
|
|
|
68070
68950
|
return false;
|
|
68071
68951
|
const unsubscribe = this._rlmChildUnsubscribes.get(childId) ?? noopRlmChildEventUnsubscribe;
|
|
68072
68952
|
return () => {
|
|
68073
|
-
this._rlmChildUnsubscribes.
|
|
68074
|
-
|
|
68953
|
+
if (this._rlmChildSessions.get(childId)?.session === session && this._rlmChildUnsubscribes.get(childId) === unsubscribe) {
|
|
68954
|
+
this._rlmChildUnsubscribes.delete(childId);
|
|
68955
|
+
this._rlmChildSessions.delete(childId);
|
|
68956
|
+
}
|
|
68075
68957
|
unsubscribe();
|
|
68076
68958
|
};
|
|
68077
68959
|
}
|
|
@@ -68191,7 +69073,7 @@ This compaction outcome could not be saved to session history: ${persistenceErro
|
|
|
68191
69073
|
return [...sessions];
|
|
68192
69074
|
}
|
|
68193
69075
|
_hasUnsettledRlmQuiescenceWork() {
|
|
68194
|
-
if (this.requests.hasPending)
|
|
69076
|
+
if (this.requests.hasPending || this._childUsageWrites.size > 0)
|
|
68195
69077
|
return true;
|
|
68196
69078
|
if (this._hasDeferredRlmTerminalNotices())
|
|
68197
69079
|
return true;
|
|
@@ -68235,6 +69117,7 @@ This compaction outcome could not be saved to session history: ${persistenceErro
|
|
|
68235
69117
|
return;
|
|
68236
69118
|
await wait(Promise.all([
|
|
68237
69119
|
...unsettledRuns.map((run2) => run2.settlement.promise),
|
|
69120
|
+
...this._childUsageWrites,
|
|
68238
69121
|
...childSessions.map((child) => child.waitForRlmQuiescence(cancellation.signal))
|
|
68239
69122
|
]));
|
|
68240
69123
|
}
|
|
@@ -68389,6 +69272,12 @@ This compaction outcome could not be saved to session history: ${persistenceErro
|
|
|
68389
69272
|
async _startRlmChildRun(prompt, admission, kwargs = {}, spawnCode) {
|
|
68390
69273
|
const spawnedByRequestId = this.isStreaming ? this._semanticEdges.lastTurnRequestId : void 0;
|
|
68391
69274
|
const parentAssistantForUsage = this._findLastAssistantMessage();
|
|
69275
|
+
const parentEntryId = parentAssistantForUsage && this._findAssistantEntryIdForMessage(parentAssistantForUsage);
|
|
69276
|
+
const usageSource = parentEntryId ? {
|
|
69277
|
+
sessionId: this.sessionId,
|
|
69278
|
+
sessionFile: this.sessionFile,
|
|
69279
|
+
entryId: parentEntryId
|
|
69280
|
+
} : void 0;
|
|
68392
69281
|
const { name: rawName, model: rawModel, thinking: rawThinking, ...unsupported } = kwargs;
|
|
68393
69282
|
const unsupportedKwargs = Object.keys(unsupported);
|
|
68394
69283
|
if (unsupportedKwargs.length > 0) {
|
|
@@ -68433,7 +69322,6 @@ This compaction outcome could not be saved to session history: ${persistenceErro
|
|
|
68433
69322
|
await this._assertRlmSubagentSessionNameAvailable(sessionName);
|
|
68434
69323
|
admission.assertCurrent();
|
|
68435
69324
|
const startedAt = Date.now();
|
|
68436
|
-
let runningToolCount = 0;
|
|
68437
69325
|
let childSession;
|
|
68438
69326
|
let usageSettlement = Promise.resolve();
|
|
68439
69327
|
const run2 = {
|
|
@@ -68455,6 +69343,8 @@ This compaction outcome could not be saved to session history: ${persistenceErro
|
|
|
68455
69343
|
throw new Error(run2.error ?? "RLM child cancelled");
|
|
68456
69344
|
};
|
|
68457
69345
|
this._activeRlmChildRuns.set(run2.id, run2);
|
|
69346
|
+
if (usageSource)
|
|
69347
|
+
this._rlmChildUsageSources.set(run2.id, usageSource);
|
|
68458
69348
|
this._unsettledRlmChildRuns.add(run2);
|
|
68459
69349
|
const emitChildUpdate = () => {
|
|
68460
69350
|
const child = this._rlmChildSnapshotForRun(run2);
|
|
@@ -68537,73 +69427,12 @@ This compaction outcome could not be saved to session history: ${persistenceErro
|
|
|
68537
69427
|
throwIfCancelled();
|
|
68538
69428
|
run2.status = "running";
|
|
68539
69429
|
emitChildUpdate();
|
|
68540
|
-
|
|
68541
|
-
|
|
68542
|
-
|
|
68543
|
-
|
|
68544
|
-
|
|
68545
|
-
|
|
68546
|
-
run2.activity = { kind: "waiting" };
|
|
68547
|
-
emitChildUpdate();
|
|
68548
|
-
} else if (event.type === "agent_end") {
|
|
68549
|
-
run2.activity = void 0;
|
|
68550
|
-
emitChildUpdate();
|
|
68551
|
-
} else if (event.type === "message_end" && event.message.role === "assistant") {
|
|
68552
|
-
const assistant = event.message;
|
|
68553
|
-
if (assistant.stopReason !== "error" && assistant.stopReason !== "aborted") {
|
|
68554
|
-
if (parentAssistantForUsage) {
|
|
68555
|
-
const parentEntryId = this._findAssistantEntryIdForMessage(parentAssistantForUsage);
|
|
68556
|
-
if (parentEntryId) {
|
|
68557
|
-
const messages = child.messages;
|
|
68558
|
-
const assistantIndex = messages.lastIndexOf(assistant);
|
|
68559
|
-
const precedingPrompt = messages.slice(0, assistantIndex).reverse().find((message2) => message2.role === "user" || message2.role === "custom");
|
|
68560
|
-
const origin = precedingPrompt?.role === "custom" && isAgentSessionMessage(precedingPrompt) ? precedingPrompt.details.id.startsWith("spawn:") ? "spawn_task" : "agent_message" : "direct_user";
|
|
68561
|
-
const text3 = compactRlmText(readAssistantText(assistant));
|
|
68562
|
-
const refreshOutput = this._refreshInvocationOutput;
|
|
68563
|
-
const write2 = this.sessionManager.appendChildUsageAttributionWithAggregate(parentEntryId, assistant.usage, void 0, origin).then(({ aggregateUsage }) => {
|
|
68564
|
-
parentAssistantForUsage.usage = structuredClone(aggregateUsage);
|
|
68565
|
-
refreshOutput?.(parentAssistantForUsage);
|
|
68566
|
-
if (text3)
|
|
68567
|
-
run2.answerPreview = text3;
|
|
68568
|
-
emitChildUpdate();
|
|
68569
|
-
});
|
|
68570
|
-
this._childUsageWrites.add(write2);
|
|
68571
|
-
usageSettlement = Promise.all([usageSettlement, write2]).then(() => void 0);
|
|
68572
|
-
void usageSettlement.catch(() => void 0);
|
|
68573
|
-
void write2.then(() => this._childUsageWrites.delete(write2), (error) => {
|
|
68574
|
-
this._childUsageWrites.delete(write2);
|
|
68575
|
-
run2.error = `Child usage attribution was not acknowledged: ${this._asError(error).message}`;
|
|
68576
|
-
this._surfaceSessionInputError(error);
|
|
68577
|
-
});
|
|
68578
|
-
return;
|
|
68579
|
-
}
|
|
68580
|
-
}
|
|
68581
|
-
}
|
|
68582
|
-
const text2 = compactRlmText(readAssistantText(assistant));
|
|
68583
|
-
if (text2)
|
|
68584
|
-
run2.answerPreview = text2;
|
|
68585
|
-
emitChildUpdate();
|
|
68586
|
-
} else if (event.type === "message_start" || event.type === "message_update") {
|
|
68587
|
-
if (event.message.role === "assistant") {
|
|
68588
|
-
const text2 = compactRlmText(readAssistantText(event.message));
|
|
68589
|
-
if (text2)
|
|
68590
|
-
run2.answerPreview = text2;
|
|
68591
|
-
run2.activity = { kind: "writing" };
|
|
68592
|
-
emitChildUpdate();
|
|
68593
|
-
}
|
|
68594
|
-
} else if (event.type === "tool_execution_start") {
|
|
68595
|
-
run2.toolUseCount += 1;
|
|
68596
|
-
runningToolCount += 1;
|
|
68597
|
-
run2.activity = { kind: "executing", toolName: event.toolName };
|
|
68598
|
-
emitChildUpdate();
|
|
68599
|
-
} else if (event.type === "tool_execution_end") {
|
|
68600
|
-
runningToolCount = Math.max(0, runningToolCount - 1);
|
|
68601
|
-
if (runningToolCount === 0)
|
|
68602
|
-
run2.activity = { kind: "waiting" };
|
|
68603
|
-
emitChildUpdate();
|
|
68604
|
-
} else if (event.type === "session_info_changed" || event.type === "recap_update") {
|
|
68605
|
-
emitChildUpdate();
|
|
68606
|
-
}
|
|
69430
|
+
if (usageSource) {
|
|
69431
|
+
await child.sessionManager.appendCustomEntry(RLM_PARENT_USAGE_CUSTOM_TYPE, usageSource);
|
|
69432
|
+
}
|
|
69433
|
+
const unsubscribeChildEvents = this._subscribeRlmChildEvents(run2.id, child, run2, (write2) => {
|
|
69434
|
+
usageSettlement = Promise.all([usageSettlement, write2]).then(() => void 0);
|
|
69435
|
+
void usageSettlement.catch(() => void 0);
|
|
68607
69436
|
});
|
|
68608
69437
|
run2.unsubscribe = unsubscribeChildEvents;
|
|
68609
69438
|
const content = `[task from parent]
|
|
@@ -68633,8 +69462,17 @@ ${prompt}`;
|
|
|
68633
69462
|
source: "extension",
|
|
68634
69463
|
customMessage: spawnMessage
|
|
68635
69464
|
});
|
|
69465
|
+
const terminal = run2.terminalAssistantOutcome;
|
|
69466
|
+
if (terminal?.stopReason === "aborted") {
|
|
69467
|
+
run2.status = "cancelled";
|
|
69468
|
+
run2.error ??= terminal.errorMessage || "RLM child aborted";
|
|
69469
|
+
}
|
|
69470
|
+
throwIfCancelled();
|
|
69471
|
+
if (terminal?.stopReason === "error")
|
|
69472
|
+
throw new Error(terminal.errorMessage || "RLM child inference failed");
|
|
68636
69473
|
await child.waitForRlmQuiescence();
|
|
68637
69474
|
await usageSettlement;
|
|
69475
|
+
throwIfCancelled();
|
|
68638
69476
|
if (run2.error)
|
|
68639
69477
|
throw new Error(run2.error);
|
|
68640
69478
|
run2.status = "done";
|
|
@@ -69462,34 +70300,13 @@ ${command}` : command;
|
|
|
69462
70300
|
_contextWindowResolver() {
|
|
69463
70301
|
return (provider, modelId) => this._modelRegistry.find(provider, modelId)?.contextWindow;
|
|
69464
70302
|
}
|
|
69465
|
-
_ownUsageMemo;
|
|
69466
70303
|
// Whole-source own spend, identical to the catalog reduction at passivation.
|
|
69467
70304
|
async getOwnUsageSummary() {
|
|
69468
70305
|
if (!this.sessionManager.supportsCapturedHistoryReads()) {
|
|
69469
|
-
const entries =
|
|
70306
|
+
const entries = this.sessionManager.getEntries();
|
|
69470
70307
|
return sessionUsageSummaryFrom(computeOwnAndTotalUsage(entries, entries).ownUsage);
|
|
69471
70308
|
}
|
|
69472
|
-
|
|
69473
|
-
return this.sessionManager.readSourceHistory(async (history) => {
|
|
69474
|
-
const { sessionId, sessionFile, sourceSequence } = history.source;
|
|
69475
|
-
const memo = this._ownUsageMemo;
|
|
69476
|
-
if (memo && memo.sessionId === sessionId && memo.sessionFile === sessionFile && memo.sourceSequence === sourceSequence && memo.count <= limits.maxEntries && memo.sourceBytes <= limits.maxSourceBytes) {
|
|
69477
|
-
return memo.usage ? { ...memo.usage } : void 0;
|
|
69478
|
-
}
|
|
69479
|
-
const materialized = await history.materialize(limits);
|
|
69480
|
-
const entries = materialized.entries.map(({ entry }) => entry);
|
|
69481
|
-
applyChildUsageAttributions(entries);
|
|
69482
|
-
const usage = sessionUsageSummaryFrom(computeOwnAndTotalUsage(entries, entries).ownUsage);
|
|
69483
|
-
this._ownUsageMemo = {
|
|
69484
|
-
sessionId,
|
|
69485
|
-
sessionFile,
|
|
69486
|
-
sourceSequence,
|
|
69487
|
-
count: entries.length,
|
|
69488
|
-
sourceBytes: materialized.sourceBytes,
|
|
69489
|
-
usage
|
|
69490
|
-
};
|
|
69491
|
-
return usage ? { ...usage } : void 0;
|
|
69492
|
-
});
|
|
70309
|
+
return this.sessionManager.readOwnUsageSummary();
|
|
69493
70310
|
}
|
|
69494
70311
|
/**
|
|
69495
70312
|
* Build the agent context overview for /context: this session as the root
|
|
@@ -69544,7 +70361,12 @@ ${command}` : command;
|
|
|
69544
70361
|
if (!usage)
|
|
69545
70362
|
throw new Error("Context tree usage source is unavailable");
|
|
69546
70363
|
const contextUsage = estimate ? usage.hasPostCompactionUsage ? { tokens: estimate.tokens, contextWindow, percent: estimate.tokens / contextWindow * 100 } : { tokens: null, contextWindow, percent: null } : void 0;
|
|
69547
|
-
const usageMetadata = {
|
|
70364
|
+
const usageMetadata = {
|
|
70365
|
+
ownUsage: usage.ownUsage,
|
|
70366
|
+
totalUsage: usage.totalUsage,
|
|
70367
|
+
...usage.ownRequestUsage ? { ownRequestUsage: usage.ownRequestUsage } : {},
|
|
70368
|
+
contextUsage
|
|
70369
|
+
};
|
|
69548
70370
|
request.retainMetadata({ contextUsage });
|
|
69549
70371
|
return {
|
|
69550
70372
|
...rootNode,
|
|
@@ -70090,7 +70912,7 @@ import { resolve as resolve15 } from "node:path";
|
|
|
70090
70912
|
var BASE_CONTEXT_BUILD_ID_ENV = "BASE_CONTEXT_BUILD_ID";
|
|
70091
70913
|
var BASE_CONTEXT_LAUNCHER_PATH_ENV = "BASE_CONTEXT_LAUNCHER_PATH";
|
|
70092
70914
|
function bundledBuildId() {
|
|
70093
|
-
return false ? void 0 : "v1.0.
|
|
70915
|
+
return false ? void 0 : "v1.0.11-2-g8a0001383";
|
|
70094
70916
|
}
|
|
70095
70917
|
function getDaemonRuntimeIdentity(environment = process.env) {
|
|
70096
70918
|
const entrypoint = process.argv[1];
|
|
@@ -70795,6 +71617,8 @@ export {
|
|
|
70795
71617
|
collectEntriesForBranchSummary,
|
|
70796
71618
|
prepareBranchEntries,
|
|
70797
71619
|
generateBranchSummary,
|
|
71620
|
+
emptyRequestUsageTotals,
|
|
71621
|
+
addRequestUsageTotals,
|
|
70798
71622
|
SESSION_SCHEDULED_JOBS_FILENAME,
|
|
70799
71623
|
DEFAULT_HEARTBEAT_SCHEDULE,
|
|
70800
71624
|
DEFAULT_HEARTBEAT_DELIVERY_MODE,
|
|
@@ -70917,7 +71741,7 @@ export {
|
|
|
70917
71741
|
passivatedWorkerRosterEntry,
|
|
70918
71742
|
sessionSummaryFromRosterEntry,
|
|
70919
71743
|
AgentRoster,
|
|
70920
|
-
|
|
71744
|
+
readVisibleUserMessagesForForking,
|
|
70921
71745
|
SERPER_CREDENTIAL_ID,
|
|
70922
71746
|
SERPER_CREDENTIAL_NAME,
|
|
70923
71747
|
PromptAdmissionCancelledError,
|