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.
Files changed (194) hide show
  1. package/THIRD_PARTY_NOTICES.txt +392 -0
  2. package/dist/acp/maka-acp-agent.js +8 -2
  3. package/dist/acp/prompt-content.js +225 -0
  4. package/dist/acp/session-event-mapper.js +103 -0
  5. package/dist/acp/session-registry.js +654 -17
  6. package/dist/acp/stdio-server.js +10 -1
  7. package/dist/cli-core.js +1 -1
  8. package/dist/pi-transcript-tools.js +3 -2
  9. package/dist/pi-transcript.js +12 -2
  10. package/dist/runtime-host-session-channel.js +63 -9
  11. package/native/runtime-host-windows-task-launcher/prebuilds/win32-x64/maka-runtime-host-task-launcher.exe +0 -0
  12. package/node_modules/@maka/core/dist/artifacts.js +6 -0
  13. package/node_modules/@maka/core/dist/attachments.js +7 -2
  14. package/node_modules/@maka/core/dist/durable-tool-result-projection.js +3 -1
  15. package/node_modules/@maka/core/dist/events.js +21 -0
  16. package/node_modules/@maka/core/dist/goal.js +44 -2
  17. package/node_modules/@maka/core/dist/permission.js +0 -1
  18. package/node_modules/@maka/core/dist/runtime-boundary.js +73 -29
  19. package/node_modules/@maka/core/dist/runtime-event.js +6 -3
  20. package/node_modules/@maka/core/dist/runtime-handoff.js +10 -2
  21. package/node_modules/@maka/core/dist/runtime-logical-execution.js +39 -14
  22. package/node_modules/@maka/core/dist/tool-result-archive-evidence.js +3 -1
  23. package/node_modules/@maka/core/dist/tool-result-record-schema.js +2 -1
  24. package/node_modules/@maka/core/dist/unified-diff.js +33 -26
  25. package/node_modules/@maka/runtime/dist/ai-sdk-compaction.js +49 -178
  26. package/node_modules/@maka/runtime/dist/ai-sdk-message-projection.js +7 -2
  27. package/node_modules/@maka/runtime/dist/ai-sdk-turn.js +15 -53
  28. package/node_modules/@maka/runtime/dist/bash-model-output.js +7 -1
  29. package/node_modules/@maka/runtime/dist/bash-tail-buffer.js +13 -52
  30. package/node_modules/@maka/runtime/dist/builtin-tools.js +59 -111
  31. package/node_modules/@maka/runtime/dist/child-fd-input.js +3 -2
  32. package/node_modules/@maka/runtime/dist/context-budget-policy.js +1 -11
  33. package/node_modules/@maka/runtime/dist/context-budget.js +12 -1
  34. package/node_modules/@maka/runtime/dist/conversation-copy.js +104 -9
  35. package/node_modules/@maka/runtime/dist/filesystem-executor.js +10 -6
  36. package/node_modules/@maka/runtime/dist/filesystem-worker/client.js +77 -19
  37. package/node_modules/@maka/runtime/dist/filesystem-worker/launch-spec.js +66 -55
  38. package/node_modules/@maka/runtime/dist/filesystem-worker/operations.js +34 -97
  39. package/node_modules/@maka/runtime/dist/filesystem-worker/protocol.js +25 -10
  40. package/node_modules/@maka/runtime/dist/filesystem-worker/worker-entry.js +2 -0
  41. package/node_modules/@maka/runtime/dist/glob-search.js +74 -0
  42. package/node_modules/@maka/runtime/dist/goal-continuation.js +78 -8
  43. package/node_modules/@maka/runtime/dist/goal-state.js +7 -0
  44. package/node_modules/@maka/runtime/dist/grep-search.js +155 -0
  45. package/node_modules/@maka/runtime/dist/ledger-tool-result-archive-reader.js +84 -94
  46. package/node_modules/@maka/runtime/dist/model-history.js +25 -3
  47. package/node_modules/@maka/runtime/dist/pipe-tail-collector.js +6 -9
  48. package/node_modules/@maka/runtime/dist/read-page.js +231 -0
  49. package/node_modules/@maka/runtime/dist/request-projection.js +2 -15
  50. package/node_modules/@maka/runtime/dist/ripgrep-executable.js +62 -0
  51. package/node_modules/@maka/runtime/dist/ripgrep-guidance.js +81 -0
  52. package/node_modules/@maka/runtime/dist/runtime-event-read-model.js +187 -20
  53. package/node_modules/@maka/runtime/dist/runtime-read-model.js +2 -1
  54. package/node_modules/@maka/runtime/dist/sandbox/linux-profile-path.js +7 -1
  55. package/node_modules/@maka/runtime/dist/sandbox/linux-sandbox.js +20 -5
  56. package/node_modules/@maka/runtime/dist/session-manager.js +6 -6
  57. package/node_modules/@maka/runtime/dist/session-recap.js +9 -5
  58. package/node_modules/@maka/runtime/dist/shell-exec.js +7 -25
  59. package/node_modules/@maka/runtime/dist/shell-run-manager.js +1 -1
  60. package/node_modules/@maka/runtime/dist/shell-run-tool-result.js +1 -1
  61. package/node_modules/@maka/runtime/dist/shell-tools.js +6 -12
  62. package/node_modules/@maka/runtime/dist/tool-availability.js +0 -1
  63. package/node_modules/@maka/runtime/dist/tool-output.js +1 -1
  64. package/node_modules/@maka/runtime/dist/tool-result-archive-capability.js +24 -36
  65. package/node_modules/@maka/runtime/dist/tool-result-archive-resource.js +32 -527
  66. package/node_modules/@maka/runtime/dist/tool-result-archive-transition.js +17 -119
  67. package/node_modules/@maka/runtime/dist/tool-result-archive.js +7 -25
  68. package/node_modules/@maka/runtime/dist/tool-runtime.js +7 -5
  69. package/node_modules/@maka/runtime/dist/workers/filesystem-worker.js +6933 -3681
  70. package/node_modules/@maka/runtime/dist/workspace-executor.js +20 -24
  71. package/node_modules/@maka/runtime/package.json +2 -0
  72. package/node_modules/@maka/runtime-host/dist/client/host-handoff-copy.js +185 -191
  73. package/node_modules/@maka/runtime-host/dist/client/reconnecting-connection.js +3 -0
  74. package/node_modules/@maka/runtime-host/dist/protocol/index.js +5 -1
  75. package/node_modules/@maka/runtime-host/dist/protocol/message.js +2 -2
  76. package/node_modules/@maka/runtime-host/dist/protocol/operations.js +1 -0
  77. package/node_modules/@maka/runtime-host/dist/protocol/session-continuity.js +2 -2
  78. package/node_modules/@maka/runtime-host/dist/protocol/turn.js +10 -2
  79. package/node_modules/@maka/runtime-host/dist/protocol/workhub-coordination.js +38 -0
  80. package/node_modules/@maka/runtime-host/dist/server/execution-artifacts.js +2 -8
  81. package/node_modules/@maka/runtime-host/dist/server/execution-composition.js +2 -0
  82. package/node_modules/@maka/runtime-host/dist/server/goal-coordinator.js +81 -7
  83. package/node_modules/@maka/runtime-host/dist/server/hosted-execution-tool-profile.js +13 -13
  84. package/node_modules/@maka/runtime-host/dist/server/interaction-coordinator.js +65 -0
  85. package/node_modules/@maka/runtime-host/dist/server/root-turn-coordinator.js +1 -0
  86. package/node_modules/@maka/runtime-host/dist/server/session-continuity-coordinator.js +5 -2
  87. package/node_modules/@maka/runtime-host/dist/server/session-transcript-reader.js +88 -72
  88. package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-action-gate.js +21 -4
  89. package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-coordinator.js +145 -1
  90. package/node_modules/@maka/storage/dist/agent-run-store.js +5 -2
  91. package/node_modules/@maka/storage/dist/execution-stores.js +2 -1
  92. package/node_modules/@maka/storage/dist/runtime-transcript-query.js +27 -14
  93. package/node_modules/@maka/storage/dist/sqlite-runtime-store.js +69 -3
  94. package/node_modules/balanced-match/LICENSE.md +23 -0
  95. package/node_modules/balanced-match/README.md +57 -0
  96. package/node_modules/balanced-match/dist/commonjs/index.js +59 -0
  97. package/node_modules/balanced-match/dist/commonjs/package.json +3 -0
  98. package/node_modules/balanced-match/dist/esm/index.js +54 -0
  99. package/node_modules/balanced-match/dist/esm/package.json +3 -0
  100. package/node_modules/balanced-match/package.json +68 -0
  101. package/node_modules/brace-expansion/LICENSE +23 -0
  102. package/node_modules/brace-expansion/README.md +105 -0
  103. package/node_modules/brace-expansion/dist/commonjs/index.js +289 -0
  104. package/node_modules/brace-expansion/dist/commonjs/package.json +3 -0
  105. package/node_modules/brace-expansion/dist/esm/index.js +285 -0
  106. package/node_modules/brace-expansion/dist/esm/package.json +3 -0
  107. package/node_modules/brace-expansion/package.json +64 -0
  108. package/node_modules/glob/LICENSE.md +63 -0
  109. package/node_modules/glob/README.md +1203 -0
  110. package/node_modules/glob/dist/commonjs/glob.js +248 -0
  111. package/node_modules/glob/dist/commonjs/has-magic.js +27 -0
  112. package/node_modules/glob/dist/commonjs/ignore.js +119 -0
  113. package/node_modules/glob/dist/commonjs/index.js +68 -0
  114. package/node_modules/glob/dist/commonjs/index.min.js +4 -0
  115. package/node_modules/glob/dist/commonjs/package.json +3 -0
  116. package/node_modules/glob/dist/commonjs/pattern.js +223 -0
  117. package/node_modules/glob/dist/commonjs/processor.js +301 -0
  118. package/node_modules/glob/dist/commonjs/walker.js +387 -0
  119. package/node_modules/glob/dist/esm/glob.js +244 -0
  120. package/node_modules/glob/dist/esm/has-magic.js +23 -0
  121. package/node_modules/glob/dist/esm/ignore.js +115 -0
  122. package/node_modules/glob/dist/esm/index.js +55 -0
  123. package/node_modules/glob/dist/esm/index.min.js +4 -0
  124. package/node_modules/glob/dist/esm/package.json +3 -0
  125. package/node_modules/glob/dist/esm/pattern.js +219 -0
  126. package/node_modules/glob/dist/esm/processor.js +294 -0
  127. package/node_modules/glob/dist/esm/walker.js +381 -0
  128. package/node_modules/glob/package.json +98 -0
  129. package/node_modules/minimatch/LICENSE.md +55 -0
  130. package/node_modules/minimatch/README.md +528 -0
  131. package/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js +14 -0
  132. package/node_modules/minimatch/dist/commonjs/ast.js +845 -0
  133. package/node_modules/minimatch/dist/commonjs/brace-expressions.js +150 -0
  134. package/node_modules/minimatch/dist/commonjs/escape.js +30 -0
  135. package/node_modules/minimatch/dist/commonjs/index.js +1127 -0
  136. package/node_modules/minimatch/dist/commonjs/package.json +3 -0
  137. package/node_modules/minimatch/dist/commonjs/unescape.js +38 -0
  138. package/node_modules/minimatch/dist/esm/assert-valid-pattern.js +10 -0
  139. package/node_modules/minimatch/dist/esm/ast.js +841 -0
  140. package/node_modules/minimatch/dist/esm/brace-expressions.js +146 -0
  141. package/node_modules/minimatch/dist/esm/escape.js +26 -0
  142. package/node_modules/minimatch/dist/esm/index.js +1114 -0
  143. package/node_modules/minimatch/dist/esm/package.json +3 -0
  144. package/node_modules/minimatch/dist/esm/unescape.js +34 -0
  145. package/node_modules/minimatch/package.json +73 -0
  146. package/node_modules/minipass/LICENSE.md +55 -0
  147. package/node_modules/minipass/README.md +825 -0
  148. package/node_modules/minipass/dist/commonjs/index.js +1038 -0
  149. package/node_modules/minipass/dist/commonjs/package.json +3 -0
  150. package/node_modules/minipass/dist/esm/index.js +1020 -0
  151. package/node_modules/minipass/dist/esm/package.json +3 -0
  152. package/node_modules/minipass/package.json +77 -0
  153. package/node_modules/path-scurry/LICENSE.md +55 -0
  154. package/node_modules/path-scurry/README.md +636 -0
  155. package/node_modules/path-scurry/dist/commonjs/index.js +2018 -0
  156. package/node_modules/path-scurry/dist/commonjs/package.json +3 -0
  157. package/node_modules/path-scurry/dist/esm/index.js +1983 -0
  158. package/node_modules/path-scurry/dist/esm/package.json +3 -0
  159. package/node_modules/path-scurry/node_modules/lru-cache/LICENSE.md +55 -0
  160. package/node_modules/path-scurry/node_modules/lru-cache/README.md +469 -0
  161. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel.js +7 -0
  162. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.js +1726 -0
  163. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.min.js +2 -0
  164. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/perf.js +10 -0
  165. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/diagnostics-channel-cjs.d.cts.map +1 -0
  166. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/diagnostics-channel.js +7 -0
  167. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.js +1726 -0
  168. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.min.js +2 -0
  169. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel.js +9 -0
  170. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.js +1726 -0
  171. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.min.js +2 -0
  172. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/perf.js +10 -0
  173. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/package.json +3 -0
  174. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/perf.js +10 -0
  175. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/diagnostics-channel.js +4 -0
  176. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.js +1722 -0
  177. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.min.js +2 -0
  178. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/perf.js +7 -0
  179. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/diagnostics-channel-esm.d.mts.map +1 -0
  180. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/diagnostics-channel.js +19 -0
  181. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.js +1722 -0
  182. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.min.js +2 -0
  183. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/diagnostics-channel.js +6 -0
  184. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.js +1722 -0
  185. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.min.js +2 -0
  186. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/perf.js +7 -0
  187. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/package.json +3 -0
  188. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/perf.js +7 -0
  189. package/node_modules/path-scurry/node_modules/lru-cache/package.json +154 -0
  190. package/node_modules/path-scurry/package.json +72 -0
  191. package/package.json +1 -1
  192. package/node_modules/@maka/runtime/dist/active-tool-result-prune.js +0 -248
  193. package/node_modules/@maka/runtime/dist/active-tool-result-working-set.js +0 -218
  194. package/node_modules/@maka/runtime/dist/archive-read-tool.js +0 -115
@@ -16,37 +16,15 @@
16
16
  * specific language governing permissions and limitations
17
17
  * under the License.
18
18
  */
19
- /**
20
- * The one writer that turns a Tool Result prune decision into durable truth
21
- * (#4283).
22
- *
23
- * Both prune paths — the current Turn's active prune before the next provider
24
- * step, and the prior Turn's stale prune before compaction — come through here.
25
- * They used to keep their replacement in a Turn-local map and a policy-carried
26
- * ref table respectively, so each owned a private recovery contract and neither
27
- * survived a restart. Now each records one `ModelProjectionTransition`, and the
28
- * Session reducer is the only thing that decides what the model sees.
29
- *
30
- * Write order is the whole safety argument:
31
- *
32
- * 1. Archive the replaced body. A failure here leaves the projection untouched.
33
- * 2. Append the transition. A failure here leaves an artifact nothing points
34
- * at — unreachable by the reducer, so safe to reclaim once something does —
35
- * and again leaves the projection untouched.
36
- * 3. Only then may a caller show the replacement.
37
- *
38
- * There is no state in which the model has lost content the ledger cannot
39
- * explain, and none in which a completed tool effect is repeated.
40
- */
41
19
  import { MATERIALIZED_IMAGE_TOKENS } from '@maka/core/attachments';
42
20
  import { DURABLE_TOOL_RESULT_PROJECTION_VERSION } from '@maka/core/durable-tool-result-projection';
43
21
  import { buildModelProjectionTransition, durableToolResultProjectionDigest, } from '@maka/core/model-projection-transition';
44
- import { estimateTokens, finitePositive, sha256, turnKey, utf8ByteLength, } from './context-budget-helpers.js';
22
+ import { estimateTokens, sha256, utf8ByteLength } from './context-budget-helpers.js';
45
23
  import { projectionArtifactMedia } from './durable-tool-result-projection.js';
46
- import { baseToolResultProjection, nextInChain } from './model-projection-transition-ledger.js';
24
+ import { baseToolResultProjection } from './model-projection-transition-ledger.js';
47
25
  import { ARCHIVED_TOOL_RESULT_REWRITE_VERSION, buildArchivedToolResultPlaceholder, buildLedgerArchivedToolResultPlaceholder, isArchivedToolResultPlaceholder, } from './tool-result-archive.js';
48
26
  import { serializeToolResultProjectionV1 } from './tool-result-archive-encoding.js';
49
- const DEFAULT_MAX_TOOL_RESULT_ESTIMATED_TOKENS = 2048;
27
+ import { READ_PAGE_MAX_CHARS, readToolResultPage } from './read-page.js';
50
28
  /**
51
29
  * What the model actually reads for one Tool Result, as bytes.
52
30
  *
@@ -59,19 +37,19 @@ export function serializedToolResultProjection(projection) {
59
37
  return serializeToolResultProjectionV1(projection);
60
38
  }
61
39
  /** The replacement a pruned Tool Result projects to. */
62
- export function archivedToolResultProjection(placeholder) {
40
+ export function archivedToolResultProjection(placeholder, source) {
63
41
  return {
64
42
  version: DURABLE_TOOL_RESULT_PROJECTION_VERSION,
65
43
  kind: 'json',
66
44
  value: placeholder,
45
+ ...(source && 'isError' in source && source.isError ? { isError: true } : {}),
67
46
  };
68
47
  }
69
48
  /**
70
49
  * Archive one body and commit the transition that replaces its projection.
71
50
  *
72
- * Returns `undefined` when either durable step fails: the caller then leaves
73
- * the model-visible content exactly as it was, which is the only outcome that
74
- * keeps "visible history is append-only" true under partial failure.
51
+ * This is a write attempt, not a projection decision. The caller must read
52
+ * the durable ledger afterwards, including after a failed or uncertain write.
75
53
  */
76
54
  export async function archiveToolResultAsTransition(services, request) {
77
55
  const bodySha256 = sha256(request.serializedResult);
@@ -112,7 +90,6 @@ export async function archiveToolResultAsTransition(services, request) {
112
90
  originalEstimatedTokens: request.originalEstimatedTokens,
113
91
  originalBytes: request.originalBytes,
114
92
  reason: request.reason,
115
- ...(request.supersession ? { supersession: request.supersession } : {}),
116
93
  };
117
94
  let placeholder;
118
95
  try {
@@ -126,6 +103,7 @@ export async function archiveToolResultAsTransition(services, request) {
126
103
  : {}),
127
104
  })
128
105
  : buildArchivedToolResultPlaceholder({ ...common, artifactId: archived.artifactId });
106
+ placeholder.page = readToolResultPage(request.serializedResult, { path: placeholder.resourceRef }, READ_PAGE_MAX_CHARS - JSON.stringify(placeholder).length - 32);
129
107
  }
130
108
  catch {
131
109
  return undefined;
@@ -144,7 +122,7 @@ export async function archiveToolResultAsTransition(services, request) {
144
122
  // The placeholder inside the replacement is the whole archive record:
145
123
  // artifact id, body digest and original size. The transition does not
146
124
  // repeat them — one fact, one place.
147
- replacement: archivedToolResultProjection(placeholder),
125
+ replacement: archivedToolResultProjection(placeholder, request.sourceProjection),
148
126
  ...(request.previousTransitionId
149
127
  ? { previousTransitionId: request.previousTransitionId }
150
128
  : {}),
@@ -160,77 +138,35 @@ export async function archiveToolResultAsTransition(services, request) {
160
138
  else {
161
139
  await services.recordTransition(transition);
162
140
  }
163
- const winner = await winningTransition(services, transition);
164
- if (winner && winner.transitionId !== transition.transitionId) {
165
- // The rival won. Show what the ledger says, not what this writer wrote;
166
- // its own record stays durable and inert, and the body it archived is
167
- // unreachable exactly as a refused transition's archive should be.
168
- const replaced = winner.replacement.kind === 'json' ? winner.replacement.value : undefined;
169
- if (!isArchivedToolResultPlaceholder(replaced))
170
- return undefined;
171
- return { placeholder: replaced, transition: winner };
172
- }
173
141
  }
174
142
  catch {
175
- // The archive artifact is now unreferenced: nothing in the effective
176
- // history names it, which is what reducer-derived reachability reports. It
177
- // is content-addressed, so a retry of the same decision reuses it rather
178
- // than publishing a second one. No cleanup pass consumes that reachability
179
- // yet, so such an artifact is retained until one does — it cannot break
180
- // replay, but it is not reclaimed either (#4283).
143
+ // A storage failure does not prove that no transition committed. Only the
144
+ // caller's subsequent authoritative read can decide what is effective.
181
145
  return undefined;
182
146
  }
183
- return { placeholder, transition };
184
- }
185
- /** The transition the durable fold accepts for this target, after an append. */
186
- async function winningTransition(services, appended) {
187
- if (!services.loadTransitions)
188
- return appended;
189
- const { transitions } = await services.loadTransitions();
190
- return nextInChain(transitions, appended.previousTransitionId, appended.sourceProjectionDigest, {
191
- id: appended.target.toolCallId,
192
- name: appended.target.toolName,
193
- });
194
147
  }
195
- /**
196
- * Prior-Turn results large enough to archive before compaction.
197
- *
198
- * Collection reads events the transition reducer has already folded, so a
199
- * result an earlier transition replaced is measured at its replacement size and
200
- * simply falls below the threshold — there is no second "already pruned?"
201
- * predicate to keep in step with the fold.
202
- */
203
- export function collectStaleToolResultArchiveCandidates(events, prunePolicy, charsPerToken) {
148
+ export function collectToolResultArchiveCandidates(events, prunePolicy, charsPerToken) {
204
149
  if (prunePolicy?.enabled !== true)
205
150
  return [];
206
- const maxResultEstimatedTokens = finitePositive(prunePolicy.maxResultEstimatedTokens) ??
207
- DEFAULT_MAX_TOOL_RESULT_ESTIMATED_TOKENS;
208
- const minRecentTurnsFull = Math.max(0, Math.floor(prunePolicy.minRecentTurnsFull ?? 1));
209
- const protectedTurnIds = recentTurnIds(events, minRecentTurnsFull);
210
151
  const candidates = [];
211
152
  for (const event of events) {
212
153
  const content = event.content;
213
154
  if (event.partial ||
214
155
  event.modelVisibility === 'hidden' ||
215
156
  content?.kind !== 'function_response' ||
216
- protectedTurnIds.has(turnKey(event))) {
157
+ content.providerExecuted) {
217
158
  continue;
218
159
  }
219
160
  const sourceProjection = baseToolResultProjection(event);
220
- if (!sourceProjection)
161
+ if (!sourceProjection ||
162
+ (sourceProjection.kind === 'json' && isArchivedToolResultPlaceholder(sourceProjection.value)))
221
163
  continue;
222
164
  const serializedResult = serializedToolResultProjection(sourceProjection);
223
165
  const originalBytes = utf8ByteLength(serializedResult);
224
166
  const media = projectionArtifactMedia(sourceProjection);
225
- // An artifact serializes to a short reference and materializes to real
226
- // image bytes, so the string alone would price a screenshot at nothing.
227
167
  const originalEstimatedTokens = estimateTokens(serializedResult.length, charsPerToken) +
228
168
  media.length * MATERIALIZED_IMAGE_TOKENS;
229
- // A result that carries media is always a candidate: archiving it drops
230
- // whole images from the request, which is worth doing whatever the
231
- // reference text around them happens to weigh. The size gate is there to
232
- // spare small text results, so it only decides those.
233
- if (media.length === 0 && originalEstimatedTokens <= maxResultEstimatedTokens)
169
+ if (media.length > 0 || serializedResult.length <= READ_PAGE_MAX_CHARS)
234
170
  continue;
235
171
  candidates.push({
236
172
  runtimeEventId: event.id,
@@ -243,46 +179,8 @@ export function collectStaleToolResultArchiveCandidates(events, prunePolicy, cha
243
179
  originalEstimatedTokens,
244
180
  originalBytes,
245
181
  rewriteVersion: ARCHIVED_TOOL_RESULT_REWRITE_VERSION,
246
- reason: 'stale_tool_result_pruned_before_compact',
182
+ reason: 'tool_result_pruned',
247
183
  });
248
184
  }
249
185
  return candidates;
250
186
  }
251
- /**
252
- * Archive artifacts the effective history still needs.
253
- *
254
- * Derived from the folded events, never from a parallel bookkeeping table: an
255
- * artifact is reachable exactly when a placeholder the model can still see names
256
- * it. An archive whose transition was refused is therefore unreachable by
257
- * construction.
258
- *
259
- * This is the reachability authority a reclaiming pass must ask; no such pass
260
- * exists yet, so nothing here is reclaimed today (#4283). Adding one is what
261
- * makes an unreferenced archive temporary rather than retained.
262
- */
263
- export function collectReachableArchiveArtifactIds(events) {
264
- const reachable = new Set();
265
- for (const event of events) {
266
- const content = event.content;
267
- if (content?.kind !== 'function_response')
268
- continue;
269
- if (isArchivedToolResultPlaceholder(content.result) && content.result.rewriteVersion === 1) {
270
- reachable.add(content.result.artifactId);
271
- }
272
- }
273
- return reachable;
274
- }
275
- function recentTurnIds(events, count) {
276
- if (count <= 0)
277
- return new Set();
278
- const order = [];
279
- const seen = new Set();
280
- for (const event of events) {
281
- const key = turnKey(event);
282
- if (seen.has(key))
283
- continue;
284
- seen.add(key);
285
- order.push(key);
286
- }
287
- return new Set(order.slice(Math.max(0, order.length - count)));
288
- }
@@ -32,11 +32,11 @@ export function buildLedgerArchivedToolResultPlaceholder(input) {
32
32
  originalBytes: input.originalBytes,
33
33
  originalEstimatedTokens: input.originalEstimatedTokens,
34
34
  reason: input.reason,
35
- ...(input.supersession ? { supersession: input.supersession } : {}),
36
35
  kind: ARCHIVED_TOOL_RESULT_PLACEHOLDER_KIND,
37
36
  rewriteVersion: 2,
38
- resourceRef: buildToolResultArchiveResourceRef(input),
39
- readInstructions: TOOL_RESULT_ARCHIVE_READ_INSTRUCTIONS,
37
+ resourceRef: `maka://runtime/tool-results/${encodeURIComponent(input.runtimeEventId)}`,
38
+ readInstructions: 'Use Read with the next parameters to continue this result.',
39
+ ...(input.page ? { page: input.page } : {}),
40
40
  };
41
41
  }
42
42
  export function stableToolResultArchiveArtifactId(event) {
@@ -96,28 +96,11 @@ export function isArchivedToolResultPlaceholder(value) {
96
96
  typeof candidate.originalBytes === 'number' &&
97
97
  Number.isFinite(candidate.originalBytes) &&
98
98
  candidate.originalBytes > 0 &&
99
- (candidate.reason === 'stale_tool_result_pruned_before_compact' ||
100
- candidate.reason === 'active_current_turn_tool_result_pruned_before_next_step') &&
101
- isValidSupersession(candidate.supersession));
102
- }
103
- function isValidSupersession(value) {
104
- if (value === undefined)
105
- return true;
106
- if (!value || typeof value !== 'object')
107
- return false;
108
- const candidate = value;
109
- return ((candidate.reason === 'exact_duplicate' ||
110
- candidate.reason === 'newer_read_covers_range' ||
111
- candidate.reason === 'newer_snapshot' ||
112
- candidate.reason === 'failure_resolved') &&
113
- typeof candidate.supersededByToolCallId === 'string' &&
114
- candidate.supersededByToolCallId.length > 0 &&
115
- (candidate.reason === 'failure_resolved'
116
- ? typeof candidate.failureBodySha256 === 'string' &&
117
- /^[a-f0-9]{64}$/.test(candidate.failureBodySha256)
118
- : candidate.failureBodySha256 === undefined));
99
+ (candidate.reason === 'tool_result_pruned' ||
100
+ candidate.reason === 'stale_tool_result_pruned_before_compact' ||
101
+ candidate.reason === 'active_current_turn_tool_result_pruned_before_next_step'));
119
102
  }
120
- /** Add the canonical ArchiveRead address to persisted v1 placeholders. */
103
+ /** Normalize persisted archive metadata without expanding the body. */
121
104
  export function withToolResultArchiveResourceRef(value) {
122
105
  if (!isArchivedToolResultPlaceholder(value))
123
106
  return value;
@@ -151,6 +134,5 @@ export function buildArchivedToolResultPlaceholder(input) {
151
134
  originalEstimatedTokens: input.originalEstimatedTokens,
152
135
  originalBytes: input.originalBytes,
153
136
  reason: input.reason,
154
- ...(input.supersession ? { supersession: input.supersession } : {}),
155
137
  };
156
138
  }
@@ -372,6 +372,8 @@ export class ToolRuntime {
372
372
  return encodeDefaultDurableToolResultOutput(result, this.input.sessionId);
373
373
  }
374
374
  const output = tool.toModelOutput({ toolCallId, input, output: result });
375
+ if (output === undefined)
376
+ return encodeDefaultDurableToolResultOutput(result, this.input.sessionId);
375
377
  // Projection is deliberately synchronous and total at the tool boundary.
376
378
  // Fail closed for untyped/plugin implementations that violate the
377
379
  // contract so a completed effect can never be stranded before T2.
@@ -1319,7 +1321,7 @@ export class ToolRuntime {
1319
1321
  }
1320
1322
  const durationMs = Math.max(0, this.input.now() - startedAt);
1321
1323
  const terminalResult = this.errorReturn(terminalFailure.message);
1322
- const projected = this.projectToolResult(tool, turnId, toolUseId, executionArgs, terminalResult);
1324
+ const projected = this.projectToolResult(tool, turnId, toolUseId, executionArgs, terminalFailure.content);
1323
1325
  const modelProjection = isPromiseLike(projected) ? await projected : projected;
1324
1326
  const durableOutcome = await durableAttempt?.commitOutcome(terminalFailure.content, true, modelProjection, durationMs);
1325
1327
  queue.push({
@@ -2830,14 +2832,14 @@ function coerceTerminalFailure(tool, cwd, args, err) {
2830
2832
  const command = args && typeof args === 'object' && typeof args.command === 'string'
2831
2833
  ? args.command
2832
2834
  : '';
2833
- const stdout = redactSecrets(String(error.stdout ?? ''));
2834
- const stderr = redactSecrets(String(error.stderr ?? ''));
2835
+ const stdout = String(error.stdout ?? '');
2836
+ const stderr = String(error.stderr ?? '');
2835
2837
  const sandboxDenied = error.reason === 'sandbox_denial' && error.sandboxed === true;
2836
2838
  return {
2837
2839
  content: {
2838
2840
  kind: 'terminal',
2839
2841
  cwd,
2840
- cmd: redactSecrets(command),
2842
+ cmd: command,
2841
2843
  status: error.code === 124 ? 'timed_out' : error.code === 130 ? 'cancelled' : 'failed',
2842
2844
  exitCode: error.code,
2843
2845
  output: {
@@ -2846,7 +2848,7 @@ function coerceTerminalFailure(tool, cwd, args, err) {
2846
2848
  stderr,
2847
2849
  stdoutTruncated: error.stdoutTruncated === true,
2848
2850
  stderrTruncated: error.stderrTruncated === true,
2849
- redacted: stdout !== String(error.stdout ?? '') || stderr !== String(error.stderr ?? ''),
2851
+ redacted: false,
2850
2852
  },
2851
2853
  ...(sandboxDenied
2852
2854
  ? {