maka-agent 0.2.0-dev.30.20260912 → 0.2.0-dev.31.20260913
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/THIRD_PARTY_NOTICES.txt +392 -0
- package/dist/acp/maka-acp-agent.js +8 -2
- package/dist/acp/prompt-content.js +225 -0
- package/dist/acp/session-event-mapper.js +103 -0
- package/dist/acp/session-registry.js +654 -17
- package/dist/acp/stdio-server.js +10 -1
- package/dist/cli-core.js +1 -1
- package/dist/pi-transcript-tools.js +3 -2
- package/dist/pi-transcript.js +12 -2
- package/dist/runtime-host-session-channel.js +63 -9
- package/native/runtime-host-windows-task-launcher/prebuilds/win32-x64/maka-runtime-host-task-launcher.exe +0 -0
- package/node_modules/@maka/core/dist/artifacts.js +6 -0
- package/node_modules/@maka/core/dist/attachments.js +7 -2
- package/node_modules/@maka/core/dist/durable-tool-result-projection.js +3 -1
- package/node_modules/@maka/core/dist/events.js +21 -0
- package/node_modules/@maka/core/dist/goal.js +44 -2
- package/node_modules/@maka/core/dist/permission.js +0 -1
- package/node_modules/@maka/core/dist/runtime-boundary.js +73 -29
- package/node_modules/@maka/core/dist/runtime-event.js +6 -3
- package/node_modules/@maka/core/dist/runtime-handoff.js +10 -2
- package/node_modules/@maka/core/dist/runtime-logical-execution.js +39 -14
- package/node_modules/@maka/core/dist/tool-result-archive-evidence.js +3 -1
- package/node_modules/@maka/core/dist/tool-result-record-schema.js +2 -1
- package/node_modules/@maka/core/dist/unified-diff.js +33 -26
- package/node_modules/@maka/runtime/dist/ai-sdk-compaction.js +49 -178
- package/node_modules/@maka/runtime/dist/ai-sdk-message-projection.js +7 -2
- package/node_modules/@maka/runtime/dist/ai-sdk-turn.js +15 -53
- package/node_modules/@maka/runtime/dist/bash-model-output.js +7 -1
- package/node_modules/@maka/runtime/dist/bash-tail-buffer.js +13 -52
- package/node_modules/@maka/runtime/dist/builtin-tools.js +59 -111
- package/node_modules/@maka/runtime/dist/child-fd-input.js +3 -2
- package/node_modules/@maka/runtime/dist/context-budget-policy.js +1 -11
- package/node_modules/@maka/runtime/dist/context-budget.js +12 -1
- package/node_modules/@maka/runtime/dist/conversation-copy.js +104 -9
- package/node_modules/@maka/runtime/dist/filesystem-executor.js +10 -6
- package/node_modules/@maka/runtime/dist/filesystem-worker/client.js +77 -19
- package/node_modules/@maka/runtime/dist/filesystem-worker/launch-spec.js +66 -55
- package/node_modules/@maka/runtime/dist/filesystem-worker/operations.js +34 -97
- package/node_modules/@maka/runtime/dist/filesystem-worker/protocol.js +25 -10
- package/node_modules/@maka/runtime/dist/filesystem-worker/worker-entry.js +2 -0
- package/node_modules/@maka/runtime/dist/glob-search.js +74 -0
- package/node_modules/@maka/runtime/dist/goal-continuation.js +78 -8
- package/node_modules/@maka/runtime/dist/goal-state.js +7 -0
- package/node_modules/@maka/runtime/dist/grep-search.js +155 -0
- package/node_modules/@maka/runtime/dist/ledger-tool-result-archive-reader.js +84 -94
- package/node_modules/@maka/runtime/dist/model-history.js +25 -3
- package/node_modules/@maka/runtime/dist/pipe-tail-collector.js +6 -9
- package/node_modules/@maka/runtime/dist/read-page.js +231 -0
- package/node_modules/@maka/runtime/dist/request-projection.js +2 -15
- package/node_modules/@maka/runtime/dist/ripgrep-executable.js +62 -0
- package/node_modules/@maka/runtime/dist/ripgrep-guidance.js +81 -0
- package/node_modules/@maka/runtime/dist/runtime-event-read-model.js +187 -20
- package/node_modules/@maka/runtime/dist/runtime-read-model.js +2 -1
- package/node_modules/@maka/runtime/dist/sandbox/linux-profile-path.js +7 -1
- package/node_modules/@maka/runtime/dist/sandbox/linux-sandbox.js +20 -5
- package/node_modules/@maka/runtime/dist/session-manager.js +6 -6
- package/node_modules/@maka/runtime/dist/session-recap.js +9 -5
- package/node_modules/@maka/runtime/dist/shell-exec.js +7 -25
- package/node_modules/@maka/runtime/dist/shell-run-manager.js +1 -1
- package/node_modules/@maka/runtime/dist/shell-run-tool-result.js +1 -1
- package/node_modules/@maka/runtime/dist/shell-tools.js +6 -12
- package/node_modules/@maka/runtime/dist/tool-availability.js +0 -1
- package/node_modules/@maka/runtime/dist/tool-output.js +1 -1
- package/node_modules/@maka/runtime/dist/tool-result-archive-capability.js +24 -36
- package/node_modules/@maka/runtime/dist/tool-result-archive-resource.js +32 -527
- package/node_modules/@maka/runtime/dist/tool-result-archive-transition.js +17 -119
- package/node_modules/@maka/runtime/dist/tool-result-archive.js +7 -25
- package/node_modules/@maka/runtime/dist/tool-runtime.js +7 -5
- package/node_modules/@maka/runtime/dist/workers/filesystem-worker.js +6933 -3681
- package/node_modules/@maka/runtime/dist/workspace-executor.js +20 -24
- package/node_modules/@maka/runtime/package.json +2 -0
- package/node_modules/@maka/runtime-host/dist/client/host-handoff-copy.js +185 -191
- package/node_modules/@maka/runtime-host/dist/client/reconnecting-connection.js +3 -0
- package/node_modules/@maka/runtime-host/dist/protocol/index.js +5 -1
- package/node_modules/@maka/runtime-host/dist/protocol/message.js +2 -2
- package/node_modules/@maka/runtime-host/dist/protocol/operations.js +1 -0
- package/node_modules/@maka/runtime-host/dist/protocol/session-continuity.js +2 -2
- package/node_modules/@maka/runtime-host/dist/protocol/turn.js +10 -2
- package/node_modules/@maka/runtime-host/dist/protocol/workhub-coordination.js +38 -0
- package/node_modules/@maka/runtime-host/dist/server/execution-artifacts.js +2 -8
- package/node_modules/@maka/runtime-host/dist/server/execution-composition.js +2 -0
- package/node_modules/@maka/runtime-host/dist/server/goal-coordinator.js +81 -7
- package/node_modules/@maka/runtime-host/dist/server/hosted-execution-tool-profile.js +13 -13
- package/node_modules/@maka/runtime-host/dist/server/interaction-coordinator.js +65 -0
- package/node_modules/@maka/runtime-host/dist/server/root-turn-coordinator.js +1 -0
- package/node_modules/@maka/runtime-host/dist/server/session-continuity-coordinator.js +5 -2
- package/node_modules/@maka/runtime-host/dist/server/session-transcript-reader.js +88 -72
- package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-action-gate.js +21 -4
- package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-coordinator.js +145 -1
- package/node_modules/@maka/storage/dist/agent-run-store.js +5 -2
- package/node_modules/@maka/storage/dist/execution-stores.js +2 -1
- package/node_modules/@maka/storage/dist/runtime-transcript-query.js +27 -14
- package/node_modules/@maka/storage/dist/sqlite-runtime-store.js +69 -3
- package/node_modules/balanced-match/LICENSE.md +23 -0
- package/node_modules/balanced-match/README.md +57 -0
- package/node_modules/balanced-match/dist/commonjs/index.js +59 -0
- package/node_modules/balanced-match/dist/commonjs/package.json +3 -0
- package/node_modules/balanced-match/dist/esm/index.js +54 -0
- package/node_modules/balanced-match/dist/esm/package.json +3 -0
- package/node_modules/balanced-match/package.json +68 -0
- package/node_modules/brace-expansion/LICENSE +23 -0
- package/node_modules/brace-expansion/README.md +105 -0
- package/node_modules/brace-expansion/dist/commonjs/index.js +289 -0
- package/node_modules/brace-expansion/dist/commonjs/package.json +3 -0
- package/node_modules/brace-expansion/dist/esm/index.js +285 -0
- package/node_modules/brace-expansion/dist/esm/package.json +3 -0
- package/node_modules/brace-expansion/package.json +64 -0
- package/node_modules/glob/LICENSE.md +63 -0
- package/node_modules/glob/README.md +1203 -0
- package/node_modules/glob/dist/commonjs/glob.js +248 -0
- package/node_modules/glob/dist/commonjs/has-magic.js +27 -0
- package/node_modules/glob/dist/commonjs/ignore.js +119 -0
- package/node_modules/glob/dist/commonjs/index.js +68 -0
- package/node_modules/glob/dist/commonjs/index.min.js +4 -0
- package/node_modules/glob/dist/commonjs/package.json +3 -0
- package/node_modules/glob/dist/commonjs/pattern.js +223 -0
- package/node_modules/glob/dist/commonjs/processor.js +301 -0
- package/node_modules/glob/dist/commonjs/walker.js +387 -0
- package/node_modules/glob/dist/esm/glob.js +244 -0
- package/node_modules/glob/dist/esm/has-magic.js +23 -0
- package/node_modules/glob/dist/esm/ignore.js +115 -0
- package/node_modules/glob/dist/esm/index.js +55 -0
- package/node_modules/glob/dist/esm/index.min.js +4 -0
- package/node_modules/glob/dist/esm/package.json +3 -0
- package/node_modules/glob/dist/esm/pattern.js +219 -0
- package/node_modules/glob/dist/esm/processor.js +294 -0
- package/node_modules/glob/dist/esm/walker.js +381 -0
- package/node_modules/glob/package.json +98 -0
- package/node_modules/minimatch/LICENSE.md +55 -0
- package/node_modules/minimatch/README.md +528 -0
- package/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js +14 -0
- package/node_modules/minimatch/dist/commonjs/ast.js +845 -0
- package/node_modules/minimatch/dist/commonjs/brace-expressions.js +150 -0
- package/node_modules/minimatch/dist/commonjs/escape.js +30 -0
- package/node_modules/minimatch/dist/commonjs/index.js +1127 -0
- package/node_modules/minimatch/dist/commonjs/package.json +3 -0
- package/node_modules/minimatch/dist/commonjs/unescape.js +38 -0
- package/node_modules/minimatch/dist/esm/assert-valid-pattern.js +10 -0
- package/node_modules/minimatch/dist/esm/ast.js +841 -0
- package/node_modules/minimatch/dist/esm/brace-expressions.js +146 -0
- package/node_modules/minimatch/dist/esm/escape.js +26 -0
- package/node_modules/minimatch/dist/esm/index.js +1114 -0
- package/node_modules/minimatch/dist/esm/package.json +3 -0
- package/node_modules/minimatch/dist/esm/unescape.js +34 -0
- package/node_modules/minimatch/package.json +73 -0
- package/node_modules/minipass/LICENSE.md +55 -0
- package/node_modules/minipass/README.md +825 -0
- package/node_modules/minipass/dist/commonjs/index.js +1038 -0
- package/node_modules/minipass/dist/commonjs/package.json +3 -0
- package/node_modules/minipass/dist/esm/index.js +1020 -0
- package/node_modules/minipass/dist/esm/package.json +3 -0
- package/node_modules/minipass/package.json +77 -0
- package/node_modules/path-scurry/LICENSE.md +55 -0
- package/node_modules/path-scurry/README.md +636 -0
- package/node_modules/path-scurry/dist/commonjs/index.js +2018 -0
- package/node_modules/path-scurry/dist/commonjs/package.json +3 -0
- package/node_modules/path-scurry/dist/esm/index.js +1983 -0
- package/node_modules/path-scurry/dist/esm/package.json +3 -0
- package/node_modules/path-scurry/node_modules/lru-cache/LICENSE.md +55 -0
- package/node_modules/path-scurry/node_modules/lru-cache/README.md +469 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel.js +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.js +1726 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.min.js +2 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/perf.js +10 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/diagnostics-channel-cjs.d.cts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/diagnostics-channel.js +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.js +1726 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.min.js +2 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel.js +9 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.js +1726 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.min.js +2 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/perf.js +10 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/package.json +3 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/perf.js +10 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/diagnostics-channel.js +4 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.js +1722 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.min.js +2 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/perf.js +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/diagnostics-channel-esm.d.mts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/diagnostics-channel.js +19 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.js +1722 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.min.js +2 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/diagnostics-channel.js +6 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.js +1722 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.min.js +2 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/perf.js +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/package.json +3 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/perf.js +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/package.json +154 -0
- package/node_modules/path-scurry/package.json +72 -0
- package/package.json +1 -1
- package/node_modules/@maka/runtime/dist/active-tool-result-prune.js +0 -248
- package/node_modules/@maka/runtime/dist/active-tool-result-working-set.js +0 -218
- package/node_modules/@maka/runtime/dist/archive-read-tool.js +0 -115
|
@@ -20,7 +20,8 @@ import { continuationStartEventMatchesClaim, createRuntimeBoundaryCursor, invoca
|
|
|
20
20
|
import { readRunInvocation, } from './runtime-event-store.js';
|
|
21
21
|
import { assertHandoffClaimSource, runtimeHandoffPause, } from './runtime-handoff.js';
|
|
22
22
|
/** All logical snapshot and command routing paths share these edge checks. */
|
|
23
|
-
export async function readLogicalRuntimeExecution(store, identity, knownRoot) {
|
|
23
|
+
export async function readLogicalRuntimeExecution(store, identity, knownRoot, options) {
|
|
24
|
+
const membership = options?.mode === 'membership';
|
|
24
25
|
const root = knownRoot ?? (await readRunInvocation(store, identity.sessionId, identity.runId));
|
|
25
26
|
if (!root)
|
|
26
27
|
return undefined;
|
|
@@ -37,17 +38,25 @@ export async function readLogicalRuntimeExecution(store, identity, knownRoot) {
|
|
|
37
38
|
if (seen.has(tip.runId) || seen.size >= 64)
|
|
38
39
|
throw new Error('Invalid logical execution handoff lineage');
|
|
39
40
|
seen.add(tip.runId);
|
|
40
|
-
const events =
|
|
41
|
-
|
|
41
|
+
const events = membership
|
|
42
|
+
? undefined
|
|
43
|
+
: await store.readImmutableRuntimeEvents(identity.sessionId, tip.runId);
|
|
44
|
+
const last = membership ? tip.terminalEvent : events?.at(-1);
|
|
42
45
|
const pause = last && runtimeHandoffPause(last);
|
|
43
46
|
if (!pause)
|
|
44
|
-
return
|
|
47
|
+
return logicalExecutionResult(root, tip, [...seen], events);
|
|
45
48
|
if (pause.rootRunId !== root.runId)
|
|
46
49
|
throw new Error('Handoff seal changes the logical root');
|
|
47
|
-
const prefix =
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
const prefix = membership
|
|
51
|
+
? await store.readImmutableRuntimePrefixProof({
|
|
52
|
+
sessionId: identity.sessionId,
|
|
53
|
+
runId: tip.runId,
|
|
54
|
+
})
|
|
55
|
+
: await store.readImmutableRuntimePrefix({
|
|
56
|
+
sessionId: identity.sessionId,
|
|
57
|
+
runId: tip.runId,
|
|
58
|
+
});
|
|
59
|
+
const segment = runtimePrefixSegment(prefix);
|
|
51
60
|
if (prefix.position.lastEventId !== last.id)
|
|
52
61
|
throw new Error('Handoff source changed after its seal');
|
|
53
62
|
if (!segments) {
|
|
@@ -59,9 +68,9 @@ export async function readLogicalRuntimeExecution(store, identity, knownRoot) {
|
|
|
59
68
|
throw new Error('Handoff requires authenticated source lineage');
|
|
60
69
|
const initial = await store.readContinuationClaimStateByBoundary(source.boundaryDigest);
|
|
61
70
|
if (!initial ||
|
|
62
|
-
initial.startEventId !== prefix.
|
|
71
|
+
initial.startEventId !== prefixFirstEvent(prefix).id ||
|
|
63
72
|
!invocationMatchesClaimTarget(root, initial.claim) ||
|
|
64
|
-
!continuationStartEventMatchesClaim(prefix
|
|
73
|
+
!continuationStartEventMatchesClaim(prefixFirstEvent(prefix), initial.claim, initial.startKind)) {
|
|
65
74
|
throw new Error('Handoff root continuation is not authenticated');
|
|
66
75
|
}
|
|
67
76
|
segments = [...initial.claim.boundary.segments];
|
|
@@ -69,7 +78,7 @@ export async function readLogicalRuntimeExecution(store, identity, knownRoot) {
|
|
|
69
78
|
else
|
|
70
79
|
segments = [];
|
|
71
80
|
}
|
|
72
|
-
segments.push(
|
|
81
|
+
segments.push(segment);
|
|
73
82
|
const boundary = createRuntimeBoundaryCursor(segments);
|
|
74
83
|
let state = await store.readContinuationClaimStateByBoundary(boundary.manifestDigest);
|
|
75
84
|
const next = await readRunInvocation(store, identity.sessionId, pause.successorRunId);
|
|
@@ -81,15 +90,21 @@ export async function readLogicalRuntimeExecution(store, identity, knownRoot) {
|
|
|
81
90
|
if (!state) {
|
|
82
91
|
if (next)
|
|
83
92
|
throw new Error('Handoff successor opened without its continuation claim');
|
|
84
|
-
return
|
|
93
|
+
return logicalExecutionResult(root, tip, [...seen], events, pause);
|
|
85
94
|
}
|
|
86
95
|
assertHandoffClaimSource(state.claim, prefix);
|
|
87
96
|
if (!next) {
|
|
88
97
|
if (state.startEventId)
|
|
89
98
|
throw new Error('Handoff successor opening is missing');
|
|
90
|
-
return
|
|
99
|
+
return logicalExecutionResult(root, tip, [...seen], events, pause);
|
|
91
100
|
}
|
|
92
|
-
const first =
|
|
101
|
+
const first = membership
|
|
102
|
+
? prefixFirstEvent(await store.readImmutableRuntimePrefixProof({
|
|
103
|
+
sessionId: identity.sessionId,
|
|
104
|
+
runId: next.runId,
|
|
105
|
+
upToEventSeq: 1,
|
|
106
|
+
}))
|
|
107
|
+
: (await store.readImmutableRuntimeEvents(identity.sessionId, next.runId))[0];
|
|
93
108
|
if (state.startEventId !== first?.id ||
|
|
94
109
|
!invocationMatchesClaimTarget(next, state.claim) ||
|
|
95
110
|
!continuationStartEventMatchesClaim(first, state.claim, state.startKind)) {
|
|
@@ -98,6 +113,16 @@ export async function readLogicalRuntimeExecution(store, identity, knownRoot) {
|
|
|
98
113
|
tip = next;
|
|
99
114
|
}
|
|
100
115
|
}
|
|
116
|
+
function prefixFirstEvent(prefix) {
|
|
117
|
+
const first = prefix.protocol === 'immutable_runtime_prefix_v1' ? prefix.events[0] : prefix.firstEvent;
|
|
118
|
+
if (!first)
|
|
119
|
+
throw new Error('immutable RuntimeEvent prefix is empty');
|
|
120
|
+
return first;
|
|
121
|
+
}
|
|
122
|
+
function logicalExecutionResult(root, tip, runIds, events, pendingHandoff) {
|
|
123
|
+
const result = { root, tip, runIds, ...(pendingHandoff ? { pendingHandoff } : {}) };
|
|
124
|
+
return events ? { ...result, events } : result;
|
|
125
|
+
}
|
|
101
126
|
/** Resolve a durable physical proof back to its root, then authenticate membership. */
|
|
102
127
|
export async function readLogicalRuntimeExecutionForRun(store, identity) {
|
|
103
128
|
const run = await readRunInvocation(store, identity.sessionId, identity.runId);
|
|
@@ -16,5 +16,7 @@
|
|
|
16
16
|
* specific language governing permissions and limitations
|
|
17
17
|
* under the License.
|
|
18
18
|
*/
|
|
19
|
+
import { DURABLE_TOOL_RESULT_PROJECTION_MAX_BYTES } from './durable-tool-result-projection.js';
|
|
19
20
|
export const TOOL_RESULT_ARCHIVE_EVIDENCE_MAX_TRANSITIONS = 64;
|
|
20
|
-
|
|
21
|
+
// Include event identity and transition overhead around the stored projection.
|
|
22
|
+
export const TOOL_RESULT_ARCHIVE_EVIDENCE_MAX_BYTES = DURABLE_TOOL_RESULT_PROJECTION_MAX_BYTES + 128 * 1024;
|
|
@@ -162,7 +162,8 @@ function isNonShellToolResultContent(value) {
|
|
|
162
162
|
isFiniteNumber(value.originalEstimatedTokens) &&
|
|
163
163
|
isFiniteNumber(value.originalBytes) &&
|
|
164
164
|
isFiniteNumber(value.rewriteVersion) &&
|
|
165
|
-
(value.reason === '
|
|
165
|
+
(value.reason === 'tool_result_pruned' ||
|
|
166
|
+
value.reason === 'stale_tool_result_pruned_before_compact' ||
|
|
166
167
|
value.reason === 'active_current_turn_tool_result_pruned_before_next_step'));
|
|
167
168
|
case 'image':
|
|
168
169
|
return (hasExactShape(value, IMAGE_SHAPE) &&
|
|
@@ -26,39 +26,57 @@ const HUNK_HEADER = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/;
|
|
|
26
26
|
* structure — degrades to unnumbered meta rows.
|
|
27
27
|
*/
|
|
28
28
|
export function parseUnifiedDiffRows(diff) {
|
|
29
|
-
const lines = diff.split('\n');
|
|
30
|
-
// A trailing newline terminates the diff rather than starting an empty row.
|
|
31
|
-
if (lines.length > 1 && lines[lines.length - 1] === '')
|
|
32
|
-
lines.pop();
|
|
33
29
|
const rows = [];
|
|
30
|
+
scanUnifiedDiff(diff, rows);
|
|
31
|
+
return rows;
|
|
32
|
+
}
|
|
33
|
+
/** Green `+N` / red `-N` counts, without materializing display rows or body text. */
|
|
34
|
+
export function countDiffLineStats(diff) {
|
|
35
|
+
return scanUnifiedDiff(diff);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* One structural scan for both consumers. The optional output array keeps
|
|
39
|
+
* display objects and body substrings out of the count-only path.
|
|
40
|
+
*/
|
|
41
|
+
function scanUnifiedDiff(diff, rows) {
|
|
42
|
+
let additions = 0;
|
|
43
|
+
let deletions = 0;
|
|
34
44
|
let oldLine = 0;
|
|
35
45
|
let newLine = 0;
|
|
36
46
|
let remainingOld = 0;
|
|
37
47
|
let remainingNew = 0;
|
|
38
48
|
let inHunk = false;
|
|
39
|
-
|
|
49
|
+
let offset = 0;
|
|
50
|
+
// Visit an empty input once, but do not invent a row after a trailing newline.
|
|
51
|
+
do {
|
|
52
|
+
const start = offset;
|
|
53
|
+
const newline = diff.indexOf('\n', start);
|
|
54
|
+
const end = newline === -1 ? diff.length : newline;
|
|
55
|
+
offset = end + 1;
|
|
40
56
|
if (inHunk && remainingOld + remainingNew > 0) {
|
|
41
|
-
const marker =
|
|
57
|
+
const marker = diff.charAt(start);
|
|
42
58
|
if (marker === '\\') {
|
|
43
59
|
// `` annotates the previous row without
|
|
44
60
|
// consuming a line on either side.
|
|
45
|
-
rows
|
|
61
|
+
rows?.push({ kind: 'meta', text: diff.slice(start, end) });
|
|
46
62
|
continue;
|
|
47
63
|
}
|
|
48
64
|
if (marker === '-') {
|
|
49
|
-
rows
|
|
65
|
+
rows?.push({ kind: 'del', text: diff.slice(start, end), oldLine });
|
|
66
|
+
deletions += 1;
|
|
50
67
|
oldLine += 1;
|
|
51
68
|
remainingOld -= 1;
|
|
52
69
|
continue;
|
|
53
70
|
}
|
|
54
71
|
if (marker === '+') {
|
|
55
|
-
rows
|
|
72
|
+
rows?.push({ kind: 'add', text: diff.slice(start, end), newLine });
|
|
73
|
+
additions += 1;
|
|
56
74
|
newLine += 1;
|
|
57
75
|
remainingNew -= 1;
|
|
58
76
|
continue;
|
|
59
77
|
}
|
|
60
78
|
// ' ' context, and the bare empty line some generators emit for one.
|
|
61
|
-
rows
|
|
79
|
+
rows?.push({ kind: 'ctx', text: diff.slice(start, end), oldLine, newLine });
|
|
62
80
|
oldLine += 1;
|
|
63
81
|
newLine += 1;
|
|
64
82
|
remainingOld -= 1;
|
|
@@ -66,6 +84,7 @@ export function parseUnifiedDiffRows(diff) {
|
|
|
66
84
|
continue;
|
|
67
85
|
}
|
|
68
86
|
inHunk = false;
|
|
87
|
+
const line = diff.slice(start, end);
|
|
69
88
|
const hunk = HUNK_HEADER.exec(line);
|
|
70
89
|
if (hunk) {
|
|
71
90
|
oldLine = Number(hunk[1]);
|
|
@@ -73,29 +92,17 @@ export function parseUnifiedDiffRows(diff) {
|
|
|
73
92
|
remainingOld = hunk[2] === undefined ? 1 : Number(hunk[2]);
|
|
74
93
|
remainingNew = hunk[4] === undefined ? 1 : Number(hunk[4]);
|
|
75
94
|
inHunk = true;
|
|
76
|
-
rows
|
|
95
|
+
rows?.push({ kind: 'hunk', text: line });
|
|
77
96
|
continue;
|
|
78
97
|
}
|
|
79
98
|
if (line.startsWith('diff ')) {
|
|
80
|
-
rows
|
|
99
|
+
rows?.push({ kind: 'meta', text: line });
|
|
81
100
|
continue;
|
|
82
101
|
}
|
|
83
102
|
if (line.startsWith('--- ') || line.startsWith('+++ ') || line.startsWith('index ')) {
|
|
84
103
|
continue;
|
|
85
104
|
}
|
|
86
|
-
rows
|
|
87
|
-
}
|
|
88
|
-
return rows;
|
|
89
|
-
}
|
|
90
|
-
/** Green `+N` / red `-N` counts, from the structural parse. */
|
|
91
|
-
export function countDiffLineStats(diff) {
|
|
92
|
-
let additions = 0;
|
|
93
|
-
let deletions = 0;
|
|
94
|
-
for (const row of parseUnifiedDiffRows(diff)) {
|
|
95
|
-
if (row.kind === 'add')
|
|
96
|
-
additions += 1;
|
|
97
|
-
else if (row.kind === 'del')
|
|
98
|
-
deletions += 1;
|
|
99
|
-
}
|
|
105
|
+
rows?.push({ kind: 'meta', text: line });
|
|
106
|
+
} while (offset < diff.length);
|
|
100
107
|
return { additions, deletions };
|
|
101
108
|
}
|
|
@@ -22,10 +22,9 @@ import { isHistoryCompactContentEvent } from './history-compaction.js';
|
|
|
22
22
|
import { canContinueHistoryCompactCheckpointForModel, canReplayHistoryCompactCheckpointForModel, historyCompactSourceDigest, matchHistoryCompactCheckpointPrefix, projectHistoryCompactCheckpointReplay, } from './history-compact-checkpoint.js';
|
|
23
23
|
import { HistoryCompactSummarizerError, isMalformedHistoryCompactSummaryReason, } from './history-compact-error.js';
|
|
24
24
|
import { createHash } from 'node:crypto';
|
|
25
|
-
import {
|
|
26
|
-
import { archiveToolResultAsTransition, collectStaleToolResultArchiveCandidates, serializedToolResultProjection, } from './tool-result-archive-transition.js';
|
|
25
|
+
import { archiveToolResultAsTransition, collectToolResultArchiveCandidates, serializedToolResultProjection, } from './tool-result-archive-transition.js';
|
|
27
26
|
import { estimateTokens } from './context-budget-helpers.js';
|
|
28
|
-
import {
|
|
27
|
+
import { reduceEffectiveModelProjections, } from './model-projection-transition-ledger.js';
|
|
29
28
|
import { buildRuntimeEventModelReplayPlan, collectToolActivityTurnIds, compatibleProviderReasoningReplayEventIds, } from './model-history.js';
|
|
30
29
|
import { planHistoryCompaction } from './history-compaction.js';
|
|
31
30
|
import { resolveDeclaredContextWindow } from './context-budget-policy.js';
|
|
@@ -98,7 +97,6 @@ export class AiSdkCompaction {
|
|
|
98
97
|
sessionId: this.sessionId,
|
|
99
98
|
archiveToolResult: (candidate) => archive(candidate),
|
|
100
99
|
recordTransition: (transition) => record(transition, turnId),
|
|
101
|
-
loadTransitions: () => this.loadModelProjectionTransitions(),
|
|
102
100
|
now: this.now,
|
|
103
101
|
};
|
|
104
102
|
}
|
|
@@ -335,11 +333,11 @@ export class AiSdkCompaction {
|
|
|
335
333
|
*
|
|
336
334
|
* The current Turn's own events go through here on every provider step, for
|
|
337
335
|
* the same reason prior Turns do: what the model sees is the folded ledger,
|
|
338
|
-
* not the raw one.
|
|
339
|
-
*
|
|
336
|
+
* not the raw one. Checkpoint validation and replay pass the same snapshot;
|
|
337
|
+
* standalone callers read one here. Unreadable targets remain withheld.
|
|
340
338
|
*/
|
|
341
|
-
async foldEffectiveModelHistory(events) {
|
|
342
|
-
const loaded = await this.loadModelProjectionTransitions();
|
|
339
|
+
async foldEffectiveModelHistory(events, snapshot) {
|
|
340
|
+
const loaded = snapshot ?? (await this.loadModelProjectionTransitions());
|
|
343
341
|
if (loaded.transitions.length === 0 && loaded.unreadableTargets.size === 0) {
|
|
344
342
|
return [...events];
|
|
345
343
|
}
|
|
@@ -371,39 +369,32 @@ export class AiSdkCompaction {
|
|
|
371
369
|
return historyCompactSourceDigest(covered) === pinned;
|
|
372
370
|
}
|
|
373
371
|
/**
|
|
374
|
-
*
|
|
375
|
-
* commit any new stale-result transition the prune policy calls for.
|
|
372
|
+
* Apply the same bounded-result rule to current and prior events.
|
|
376
373
|
*
|
|
377
374
|
* This is the one seam where raw RuntimeEvents become effective model
|
|
378
375
|
* history: the caller uses the returned events for replay, budgeting and
|
|
379
376
|
* compaction alike, so no later stage can read content a transition removed.
|
|
380
377
|
*/
|
|
381
|
-
async
|
|
378
|
+
async pruneToolResults(runtimeContext, turnId) {
|
|
382
379
|
const policy = this.input.contextBudget;
|
|
383
|
-
|
|
384
|
-
let
|
|
385
|
-
let effective = reduceEffectiveModelProjections(runtimeContext, transitions, loaded.unreadableTargets);
|
|
380
|
+
let loaded = await this.loadModelProjectionTransitions();
|
|
381
|
+
let effective = reduceEffectiveModelProjections(runtimeContext, loaded.transitions, loaded.unreadableTargets);
|
|
386
382
|
if (!policy)
|
|
387
|
-
return {
|
|
388
|
-
let
|
|
389
|
-
let diagnosticPatch;
|
|
383
|
+
return { events: effective.events, projectionSnapshot: loaded };
|
|
384
|
+
let stats;
|
|
390
385
|
// A chain this reader cannot see in full is a chain it must not extend: a
|
|
391
386
|
// successor built on a partly known state would name the wrong predecessor
|
|
392
387
|
// and be permanently inert, losing the content it archived.
|
|
393
388
|
const services = loaded.unreadableTargets.size === 0
|
|
394
389
|
? this.toolResultArchiveTransitionServices(turnId)
|
|
395
390
|
: undefined;
|
|
396
|
-
if (policy.
|
|
391
|
+
if (policy.toolResultPrune?.enabled === true && services) {
|
|
397
392
|
// The decision is taken over EFFECTIVE history, so a result an earlier
|
|
398
393
|
// Turn already replaced is never re-measured — or re-archived — at the
|
|
399
394
|
// size it used to have.
|
|
400
|
-
const candidates =
|
|
401
|
-
const committed = [];
|
|
402
|
-
let archiveFailures = 0;
|
|
403
|
-
let estimatedTokensBefore = 0;
|
|
404
|
-
let estimatedTokensAfter = 0;
|
|
395
|
+
const candidates = collectToolResultArchiveCandidates(effective.events, policy.toolResultPrune, policy.charsPerToken ?? 4);
|
|
405
396
|
for (const candidate of candidates) {
|
|
406
|
-
|
|
397
|
+
await archiveToolResultAsTransition(services, {
|
|
407
398
|
runtimeEventId: candidate.runtimeEventId,
|
|
408
399
|
turnId: candidate.turnId,
|
|
409
400
|
toolCallId: candidate.toolCallId,
|
|
@@ -415,37 +406,41 @@ export class AiSdkCompaction {
|
|
|
415
406
|
reason: candidate.reason,
|
|
416
407
|
result: candidate.result,
|
|
417
408
|
});
|
|
418
|
-
if (!outcome) {
|
|
419
|
-
archiveFailures += 1;
|
|
420
|
-
continue;
|
|
421
|
-
}
|
|
422
|
-
committed.push(outcome.transition);
|
|
423
|
-
estimatedTokensBefore += candidate.originalEstimatedTokens;
|
|
424
|
-
estimatedTokensAfter += estimateTokens(serializedToolResultProjection(outcome.transition.replacement).length, policy.charsPerToken ?? 4);
|
|
425
409
|
}
|
|
426
|
-
if (
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
archivePlaceholders: committed.length,
|
|
438
|
-
archivePlaceholderReasonCounts: {
|
|
439
|
-
stale_tool_result_pruned_before_compact: committed.length,
|
|
440
|
-
},
|
|
441
|
-
}
|
|
442
|
-
: {}),
|
|
443
|
-
...(archiveFailures > 0
|
|
444
|
-
? { archiveWriteFailures: archiveFailures, unarchivedToolResults: archiveFailures }
|
|
445
|
-
: {}),
|
|
410
|
+
if (candidates.length > 0) {
|
|
411
|
+
// Writes (including a rival winner or an uncertain commit) cannot tell
|
|
412
|
+
// us what the model sees. Read once after the batch and use this same
|
|
413
|
+
// snapshot for checkpoint validation, replay, and diagnostics.
|
|
414
|
+
loaded = await this.loadModelProjectionTransitions();
|
|
415
|
+
effective = reduceEffectiveModelProjections(runtimeContext, loaded.transitions, loaded.unreadableTargets);
|
|
416
|
+
stats = {
|
|
417
|
+
prunedToolResults: 0,
|
|
418
|
+
prunedToolResultEstimatedTokensBefore: 0,
|
|
419
|
+
prunedToolResultEstimatedTokensAfter: 0,
|
|
420
|
+
archiveWriteFailures: 0,
|
|
446
421
|
};
|
|
422
|
+
for (const candidate of candidates) {
|
|
423
|
+
const applied = effective.applied.find((transition) => transition.target.runtimeEventId === candidate.runtimeEventId);
|
|
424
|
+
if (!applied) {
|
|
425
|
+
stats.archiveWriteFailures++;
|
|
426
|
+
continue;
|
|
427
|
+
}
|
|
428
|
+
stats.prunedToolResults++;
|
|
429
|
+
stats.prunedToolResultEstimatedTokensBefore += candidate.originalEstimatedTokens;
|
|
430
|
+
stats.prunedToolResultEstimatedTokensAfter += estimateTokens(serializedToolResultProjection(applied.replacement).length, policy.charsPerToken ?? 4);
|
|
431
|
+
}
|
|
447
432
|
}
|
|
448
433
|
}
|
|
434
|
+
return { events: effective.events, projectionSnapshot: loaded, ...(stats ? { stats } : {}) };
|
|
435
|
+
}
|
|
436
|
+
async prepareContextBudgetPolicy(runtimeContext, turnId) {
|
|
437
|
+
const policy = this.input.contextBudget;
|
|
438
|
+
const prepared = await this.pruneToolResults(runtimeContext, turnId);
|
|
439
|
+
const effective = { events: prepared.events };
|
|
440
|
+
if (!policy)
|
|
441
|
+
return { policy, events: effective.events, projectionSnapshot: prepared.projectionSnapshot };
|
|
442
|
+
let nextPolicy = policy;
|
|
443
|
+
let diagnosticPatch = prepared.stats;
|
|
449
444
|
let loadedCheckpoint;
|
|
450
445
|
try {
|
|
451
446
|
loadedCheckpoint = await Promise.resolve(this.input.loadHistoryCompactCheckpoint?.());
|
|
@@ -492,93 +487,10 @@ export class AiSdkCompaction {
|
|
|
492
487
|
return {
|
|
493
488
|
policy: nextPolicy,
|
|
494
489
|
events: effective.events,
|
|
490
|
+
projectionSnapshot: prepared.projectionSnapshot,
|
|
495
491
|
...(diagnosticPatch ? { diagnosticPatch } : {}),
|
|
496
492
|
};
|
|
497
493
|
}
|
|
498
|
-
buildActiveToolResultPruneProjection(turnId, includeNewestStep, onDiagnosticPatch) {
|
|
499
|
-
const policy = this.input.contextBudget?.activeToolResultPrune;
|
|
500
|
-
if (policy?.enabled !== true)
|
|
501
|
-
return undefined;
|
|
502
|
-
const services = this.toolResultArchiveTransitionServices(turnId);
|
|
503
|
-
// No durable ledger, no lossy rewrite. The old per-Turn placeholder map let
|
|
504
|
-
// this run prune content that the NEXT request would have shown again.
|
|
505
|
-
if (!services || !this.input.loadTurnRuntimeEvents)
|
|
506
|
-
return undefined;
|
|
507
|
-
// The current Turn reads the same folded history as every other consumer.
|
|
508
|
-
// Nothing here remembers what this run already archived: the ledger says it,
|
|
509
|
-
// and a step that measures the raw body again would archive it again.
|
|
510
|
-
let effective;
|
|
511
|
-
const loadEffectiveTurnEvents = async () => {
|
|
512
|
-
if (effective)
|
|
513
|
-
return effective;
|
|
514
|
-
const loaded = await this.loadModelProjectionTransitions();
|
|
515
|
-
if (loaded.unreadableTargets.size > 0)
|
|
516
|
-
return undefined;
|
|
517
|
-
let turnEvents;
|
|
518
|
-
try {
|
|
519
|
-
turnEvents = await this.input.loadTurnRuntimeEvents(turnId);
|
|
520
|
-
}
|
|
521
|
-
catch {
|
|
522
|
-
return undefined;
|
|
523
|
-
}
|
|
524
|
-
const reduction = reduceEffectiveModelProjections(turnEvents, loaded.transitions);
|
|
525
|
-
const lastApplied = new Map();
|
|
526
|
-
for (const transition of reduction.applied) {
|
|
527
|
-
lastApplied.set(transition.target.runtimeEventId, transition.transitionId);
|
|
528
|
-
}
|
|
529
|
-
effective = { events: reduction.events, lastApplied };
|
|
530
|
-
return effective;
|
|
531
|
-
};
|
|
532
|
-
const resolveProjection = async (toolCallId) => {
|
|
533
|
-
const current = await loadEffectiveTurnEvents();
|
|
534
|
-
if (!current)
|
|
535
|
-
return undefined;
|
|
536
|
-
const event = current.events.find((candidate) => candidate.partial !== true &&
|
|
537
|
-
candidate.content?.kind === 'function_response' &&
|
|
538
|
-
candidate.content.id === toolCallId);
|
|
539
|
-
if (!event || event.content?.kind !== 'function_response')
|
|
540
|
-
return undefined;
|
|
541
|
-
const projection = baseToolResultProjection(event);
|
|
542
|
-
if (!projection)
|
|
543
|
-
return undefined;
|
|
544
|
-
const previousTransitionId = current.lastApplied.get(event.id);
|
|
545
|
-
return {
|
|
546
|
-
runtimeEventId: event.id,
|
|
547
|
-
turnId: event.turnId,
|
|
548
|
-
toolName: event.content.name,
|
|
549
|
-
projection,
|
|
550
|
-
...(previousTransitionId ? { previousTransitionId } : {}),
|
|
551
|
-
};
|
|
552
|
-
};
|
|
553
|
-
return async (options) => {
|
|
554
|
-
const eligibleToolCallIds = collectPrunableCompletedStepToolCallIds(options.completedSteps, includeNewestStep);
|
|
555
|
-
if (eligibleToolCallIds.size === 0)
|
|
556
|
-
return undefined;
|
|
557
|
-
// Each provider step rebuilds its messages from the durable Turn ledger,
|
|
558
|
-
// so each step must re-fold it too.
|
|
559
|
-
effective = undefined;
|
|
560
|
-
const rewritten = await rewriteActiveToolResultsInMessages({
|
|
561
|
-
messages: options.messages,
|
|
562
|
-
policy,
|
|
563
|
-
stepNumber: options.stepNumber,
|
|
564
|
-
turnId,
|
|
565
|
-
charsPerToken: this.input.contextBudget?.charsPerToken,
|
|
566
|
-
eligibleToolCallIds,
|
|
567
|
-
completedToolCalls: options.completedSteps.flatMap((step, stepNumber) => (step.toolCalls ?? []).map((call) => ({
|
|
568
|
-
toolCallId: call.toolCallId,
|
|
569
|
-
toolName: call.toolName,
|
|
570
|
-
input: call.input,
|
|
571
|
-
stepNumber,
|
|
572
|
-
}))),
|
|
573
|
-
resolveProjection,
|
|
574
|
-
transitions: services,
|
|
575
|
-
});
|
|
576
|
-
if (hasActiveToolResultPruneDiagnosticPatch(rewritten.diagnosticPatch)) {
|
|
577
|
-
onDiagnosticPatch?.(rewritten.diagnosticPatch);
|
|
578
|
-
}
|
|
579
|
-
return rewritten.rewritten > 0 ? { messages: rewritten.messages } : undefined;
|
|
580
|
-
};
|
|
581
|
-
}
|
|
582
494
|
/**
|
|
583
495
|
* Mid-turn capacity compaction eligibility (issue #882 PR 1). Explicit
|
|
584
496
|
* opt-in via `historyCompact.midTurn.enabled`; requires the checkpoint
|
|
@@ -907,7 +819,8 @@ export class AiSdkCompaction {
|
|
|
907
819
|
// materializable and replay-admissible. A checkpoint that fails either
|
|
908
820
|
// check must never be persisted because it would poison every later
|
|
909
821
|
// projection.
|
|
910
|
-
const
|
|
822
|
+
const effectiveReplacement = await this.foldEffectiveModelHistory(plan.replacementEvents);
|
|
823
|
+
const replayPlan = buildRuntimeEventModelReplayPlan(effectiveReplacement, {
|
|
911
824
|
toolActivityTurnIds: collectToolActivityTurnIds(orderedEvents),
|
|
912
825
|
});
|
|
913
826
|
if (replayPlan.items.length === 0 ||
|
|
@@ -1035,41 +948,6 @@ export class AiSdkCompaction {
|
|
|
1035
948
|
return { messages: outcome.replacementMessages };
|
|
1036
949
|
}
|
|
1037
950
|
}
|
|
1038
|
-
// -- moved helpers (defined in ai-sdk-backend, used only by cache write) -------
|
|
1039
|
-
function incrementRecord(counts, key) {
|
|
1040
|
-
counts[key] = (counts[key] ?? 0) + 1;
|
|
1041
|
-
}
|
|
1042
|
-
function mergeCountsInto(target, source) {
|
|
1043
|
-
for (const [key, value] of Object.entries(source ?? {})) {
|
|
1044
|
-
target[key] = (target[key] ?? 0) + value;
|
|
1045
|
-
}
|
|
1046
|
-
}
|
|
1047
|
-
// -- moved helpers (prepare-step / signature / prune) ------------------------
|
|
1048
|
-
/**
|
|
1049
|
-
* Tool results from the newest completed step have not crossed the provider
|
|
1050
|
-
* boundary yet: projection is invoked immediately before the first request
|
|
1051
|
-
* that could show those results to the model. By default active pruning defers
|
|
1052
|
-
* the newest step and archives only older completed steps, after the model has
|
|
1053
|
-
* had one request in which to consume their exact output.
|
|
1054
|
-
*
|
|
1055
|
-
* `includeNewestStep` widens eligibility to every completed step, including the
|
|
1056
|
-
* newest. The caller sets it when mid-turn capacity compaction is active: the
|
|
1057
|
-
* final-payload verdict may need an oversized newest result pruned to a
|
|
1058
|
-
* placeholder before declaring exhaustion, and capacity/recovery rebuilds
|
|
1059
|
-
* re-materialize raw bodies from the ledger that must be re-archived.
|
|
1060
|
-
*/
|
|
1061
|
-
function collectPrunableCompletedStepToolCallIds(steps, includeNewestStep) {
|
|
1062
|
-
const out = new Set();
|
|
1063
|
-
const prunableSteps = includeNewestStep ? steps : steps.slice(0, -1);
|
|
1064
|
-
for (const step of prunableSteps) {
|
|
1065
|
-
for (const call of step.toolCalls ?? []) {
|
|
1066
|
-
if (typeof call.toolCallId === 'string' && call.toolCallId.length > 0) {
|
|
1067
|
-
out.add(call.toolCallId);
|
|
1068
|
-
}
|
|
1069
|
-
}
|
|
1070
|
-
}
|
|
1071
|
-
return out;
|
|
1072
|
-
}
|
|
1073
951
|
function projectHistoricalImageOmissions(messages, omittedImageToolResults) {
|
|
1074
952
|
if (omittedImageToolResults.size === 0)
|
|
1075
953
|
return undefined;
|
|
@@ -1110,13 +988,6 @@ function stableStringifyForSignature(value) {
|
|
|
1110
988
|
.map((key) => `${JSON.stringify(key)}:${stableStringifyForSignature(object[key])}`)
|
|
1111
989
|
.join(',')}}`;
|
|
1112
990
|
}
|
|
1113
|
-
export function hasActiveToolResultPruneDiagnosticPatch(patch) {
|
|
1114
|
-
return ((patch.activePrunedToolResults ?? 0) > 0 ||
|
|
1115
|
-
(patch.activeSupersededToolResults ?? 0) > 0 ||
|
|
1116
|
-
(patch.activeDuplicateToolResults ?? 0) > 0 ||
|
|
1117
|
-
(patch.activeArchiveFailures ?? 0) > 0 ||
|
|
1118
|
-
(patch.activeEstimatedTokensSaved ?? 0) > 0);
|
|
1119
|
-
}
|
|
1120
991
|
/**
|
|
1121
992
|
* Per-send() state for the mid-turn capacity invariant. The coverage pool is
|
|
1122
993
|
* NOT mirrored here: every trigger reads the current turn's persisted
|
|
@@ -444,18 +444,23 @@ export class AiSdkMessageProjection {
|
|
|
444
444
|
}
|
|
445
445
|
async materializeRuntimeReplayItem(budget, item) {
|
|
446
446
|
if (item.role === 'user') {
|
|
447
|
+
// Both ordinary and steered replay materialize image attachments through
|
|
448
|
+
// the same path the original request used — a steering replay that kept
|
|
449
|
+
// only the envelope text would hand a recovery turn references without
|
|
450
|
+
// the native images the first request received.
|
|
451
|
+
const content = await this.appendImageParts(budget, item.content, item.attachments, item.steering ? `steering:${item.steering.eventId}` : `runtime-event:${item.eventId}`);
|
|
447
452
|
if (item.steering) {
|
|
448
453
|
// Already envelope-wrapped by the plan; carry the structured identity
|
|
449
454
|
// so injection dedupe recognizes the replayed message.
|
|
450
455
|
return {
|
|
451
456
|
role: 'user',
|
|
452
|
-
content
|
|
457
|
+
content,
|
|
453
458
|
providerOptions: steeringProviderOptions(item.steering.eventId),
|
|
454
459
|
};
|
|
455
460
|
}
|
|
456
461
|
return {
|
|
457
462
|
role: 'user',
|
|
458
|
-
content
|
|
463
|
+
content,
|
|
459
464
|
};
|
|
460
465
|
}
|
|
461
466
|
return {
|