maka-agent 0.2.0-dev.24.20260907 → 0.2.0-dev.26.20260909

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 (154) hide show
  1. package/README.md +38 -19
  2. package/README.zh-CN.md +34 -19
  3. package/dist/mcp-capability-provider.js +4 -1
  4. package/dist/pi-transcript-tools.js +6 -0
  5. package/dist/pi-tui-layout.js +56 -10
  6. package/dist/pi-tui-mcp-status.js +2 -2
  7. package/dist/pi-tui-pickers.js +121 -30
  8. package/dist/pi-tui-runner.js +156 -42
  9. package/dist/pi-tui-todo.js +221 -0
  10. package/dist/pi-tui-transcript-viewer.js +134 -7
  11. package/dist/runtime-host-cli-context.js +70 -13
  12. package/dist/runtime-host-handoff-surface.js +51 -26
  13. package/dist/runtime-host-local-handoff.js +11 -1
  14. package/dist/runtime-host-service-manager.js +0 -3
  15. package/dist/runtime-host-session-channel.js +13 -0
  16. package/dist/runtime-host-session-driver.js +42 -1
  17. package/dist/tui-autocomplete-layout.js +3 -1
  18. package/dist/tui-copy-catalog.js +85 -6
  19. package/dist/tui-editor-render.js +36 -0
  20. package/dist/tui-mcp-control.js +41 -6
  21. package/native/runtime-host-windows-task-launcher/prebuilds/win32-x64/maka-runtime-host-task-launcher.exe +0 -0
  22. package/node_modules/@maka/core/dist/agent-run.js +1 -0
  23. package/node_modules/@maka/core/dist/attachments.js +3 -0
  24. package/node_modules/@maka/core/dist/canonical-json.js +27 -0
  25. package/node_modules/@maka/core/dist/capabilities.js +35 -0
  26. package/node_modules/@maka/core/dist/computer-use.js +0 -1
  27. package/node_modules/@maka/core/dist/display-redaction.js +18 -0
  28. package/node_modules/@maka/core/dist/llm-connections.js +13 -0
  29. package/node_modules/@maka/core/dist/model-call-attempt.js +2 -0
  30. package/node_modules/@maka/core/dist/model-metadata.js +4 -0
  31. package/node_modules/@maka/core/dist/redaction.js +35 -0
  32. package/node_modules/@maka/core/dist/run-composition.js +77 -2
  33. package/node_modules/@maka/core/dist/runtime-event.js +3 -0
  34. package/node_modules/@maka/core/dist/session.js +57 -6
  35. package/node_modules/@maka/core/dist/slash-command-catalog.js +1 -0
  36. package/node_modules/@maka/core/dist/tool-result-record-schema.js +2 -1
  37. package/node_modules/@maka/core/dist/workhub-action-result.js +68 -0
  38. package/node_modules/@maka/core/package.json +3 -3
  39. package/node_modules/@maka/eval/dist/experiment-directory.js +4 -13
  40. package/node_modules/@maka/eval/dist/toolchain-verification.js +1 -1
  41. package/node_modules/@maka/mcp/dist/form-elicitation.js +213 -0
  42. package/node_modules/@maka/mcp/dist/index.js +337 -71
  43. package/node_modules/@maka/runtime/dist/agent-run-inspect.js +0 -13
  44. package/node_modules/@maka/runtime/dist/agent-run.js +90 -2
  45. package/node_modules/@maka/runtime/dist/ai-sdk-backend.js +16 -8
  46. package/node_modules/@maka/runtime/dist/ai-sdk-turn.js +57 -50
  47. package/node_modules/@maka/runtime/dist/archive-read-tool.js +2 -2
  48. package/node_modules/@maka/runtime/dist/context-budget-helpers.js +0 -16
  49. package/node_modules/@maka/runtime/dist/conversation-copy.js +153 -11
  50. package/node_modules/@maka/runtime/dist/github-copilot-oauth-enrollment.js +3 -3
  51. package/node_modules/@maka/runtime/dist/goal-continuation.js +5 -1
  52. package/node_modules/@maka/runtime/dist/ledger-tool-result-archive-reader.js +69 -1
  53. package/node_modules/@maka/runtime/dist/mcp-tools.js +7 -2
  54. package/node_modules/@maka/runtime/dist/model-fetcher.js +42 -2
  55. package/node_modules/@maka/runtime/dist/model-history.js +0 -112
  56. package/node_modules/@maka/runtime/dist/plugin-runtime.js +20 -10
  57. package/node_modules/@maka/runtime/dist/plugin-tool-service.js +205 -0
  58. package/node_modules/@maka/runtime/dist/provider-request-telemetry.js +8 -1
  59. package/node_modules/@maka/runtime/dist/request-shape.js +23 -0
  60. package/node_modules/@maka/runtime/dist/runtime-event-backfill.js +1 -1
  61. package/node_modules/@maka/runtime/dist/runtime-event-read-model.js +24 -1
  62. package/node_modules/@maka/runtime/dist/runtime-kernel.js +127 -13
  63. package/node_modules/@maka/runtime/dist/session-manager.js +20 -36
  64. package/node_modules/@maka/runtime/dist/stream-graph-coordinator.js +21 -0
  65. package/node_modules/@maka/runtime/dist/stream-graph-supervisor-tools.js +0 -5
  66. package/node_modules/@maka/runtime/dist/test-connection.js +0 -1
  67. package/node_modules/@maka/runtime/dist/tool-activation-identity.js +41 -0
  68. package/node_modules/@maka/runtime/dist/tool-availability.js +11 -1
  69. package/node_modules/@maka/runtime/dist/tool-result-archive-resource.js +63 -1
  70. package/node_modules/@maka/runtime/dist/tool-result-archive-transition.js +42 -12
  71. package/node_modules/@maka/runtime/dist/tool-result-archive.js +27 -4
  72. package/node_modules/@maka/runtime/package.json +1 -0
  73. package/node_modules/@maka/runtime-host/dist/client/connection.js +30 -5
  74. package/node_modules/@maka/runtime-host/dist/client/host-handoff-copy.js +52 -13
  75. package/node_modules/@maka/runtime-host/dist/client/host-handoff.js +2 -0
  76. package/node_modules/@maka/runtime-host/dist/client/host-retirement.js +4 -2
  77. package/node_modules/@maka/runtime-host/dist/client/peer-client.js +18 -1
  78. package/node_modules/@maka/runtime-host/dist/client/session-subscription.js +19 -0
  79. package/node_modules/@maka/runtime-host/dist/control/endpoint.js +1 -3
  80. package/node_modules/@maka/runtime-host/dist/node-error.js +22 -0
  81. package/node_modules/@maka/runtime-host/dist/operator/managed-deployment.js +1 -3
  82. package/node_modules/@maka/runtime-host/dist/peer-mesh/limits.js +0 -1
  83. package/node_modules/@maka/runtime-host/dist/peer-mesh/model.js +1 -1
  84. package/node_modules/@maka/runtime-host/dist/peer-reachability/publisher.js +1 -3
  85. package/node_modules/@maka/runtime-host/dist/protocol/index.js +9 -1
  86. package/node_modules/@maka/runtime-host/dist/protocol/operations.js +3 -2
  87. package/node_modules/@maka/runtime-host/dist/protocol/plan.js +1 -0
  88. package/node_modules/@maka/runtime-host/dist/protocol/plugin-platform.js +27 -5
  89. package/node_modules/@maka/runtime-host/dist/protocol/project-catalog.js +2 -2
  90. package/node_modules/@maka/runtime-host/dist/protocol/session-continuity.js +1 -0
  91. package/node_modules/@maka/runtime-host/dist/protocol/workhub-coordination.js +86 -157
  92. package/node_modules/@maka/runtime-host/dist/server/access-credential-store.js +4 -0
  93. package/node_modules/@maka/runtime-host/dist/server/agent-graph-coordinator.js +0 -3
  94. package/node_modules/@maka/runtime-host/dist/server/canonical-session-projection.js +2 -1
  95. package/node_modules/@maka/runtime-host/dist/server/connection-session.js +28 -8
  96. package/node_modules/@maka/runtime-host/dist/server/daily-review-coordinator.js +112 -56
  97. package/node_modules/@maka/runtime-host/dist/server/execution-artifacts.js +32 -32
  98. package/node_modules/@maka/runtime-host/dist/server/execution-composition.js +85 -25
  99. package/node_modules/@maka/runtime-host/dist/server/execution-model-composition.js +42 -14
  100. package/node_modules/@maka/runtime-host/dist/server/failure-diagnostic.js +24 -0
  101. package/node_modules/@maka/runtime-host/dist/server/goal-coordinator.js +7 -3
  102. package/node_modules/@maka/runtime-host/dist/server/host-kernel.js +3 -3
  103. package/node_modules/@maka/runtime-host/dist/server/host-session-availability.js +5 -2
  104. package/node_modules/@maka/runtime-host/dist/server/hosted-execution-recovery.js +3 -2
  105. package/node_modules/@maka/runtime-host/dist/server/hosted-execution-tool-profile.js +34 -4
  106. package/node_modules/@maka/runtime-host/dist/server/interactive-run-composer.js +51 -23
  107. package/node_modules/@maka/runtime-host/dist/server/operation-dispatcher.js +2 -7
  108. package/node_modules/@maka/runtime-host/dist/server/plugin-platform-coordinator.js +6 -0
  109. package/node_modules/@maka/runtime-host/dist/server/plugin-platform.js +6 -0
  110. package/node_modules/@maka/runtime-host/dist/server/root-turn-coordinator.js +110 -14
  111. package/node_modules/@maka/runtime-host/dist/server/runtime-resource-coordinator.js +11 -8
  112. package/node_modules/@maka/runtime-host/dist/server/scheduled-task-coordinator.js +31 -21
  113. package/node_modules/@maka/runtime-host/dist/server/serial-outbound-writer.js +1 -1
  114. package/node_modules/@maka/runtime-host/dist/server/session-catalog-coordinator.js +20 -8
  115. package/node_modules/@maka/runtime-host/dist/server/session-retirement-coordinator.js +5 -2
  116. package/node_modules/@maka/runtime-host/dist/server/session-revision-coordinator.js +4 -0
  117. package/node_modules/@maka/runtime-host/dist/server/session-transcript-reader.js +15 -104
  118. package/node_modules/@maka/runtime-host/dist/server/shared-session-transcript.js +3 -0
  119. package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-action-gate.js +59 -82
  120. package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-coordinator.js +132 -139
  121. package/node_modules/@maka/runtime-host/dist/server/workhub-message-attachments.js +46 -0
  122. package/node_modules/@maka/storage/dist/agent-run-store.js +14 -1
  123. package/node_modules/@maka/storage/dist/artifact-store.js +40 -3
  124. package/node_modules/@maka/storage/dist/atomic-file-write.js +74 -0
  125. package/node_modules/@maka/storage/dist/claude-code-session-adapter.js +0 -1
  126. package/node_modules/@maka/storage/dist/codex-session-adapter.js +284 -196
  127. package/node_modules/@maka/storage/dist/credential-store.js +12 -63
  128. package/node_modules/@maka/storage/dist/execution-stores.js +4 -1
  129. package/node_modules/@maka/storage/dist/git-exec.js +61 -0
  130. package/node_modules/@maka/storage/dist/git-worktree-child-executor.js +8 -35
  131. package/node_modules/@maka/storage/dist/goal-authority.js +2 -2
  132. package/node_modules/@maka/storage/dist/interaction-store.js +2 -2
  133. package/node_modules/@maka/storage/dist/mcp-config-store.js +10 -25
  134. package/node_modules/@maka/storage/dist/project-catalog.js +2 -23
  135. package/node_modules/@maka/storage/dist/runtime-event-invariants.js +2 -2
  136. package/node_modules/@maka/storage/dist/runtime-policy/connection-catalog-document.js +8 -3
  137. package/node_modules/@maka/storage/dist/scheduled-task-store.js +249 -283
  138. package/node_modules/@maka/storage/dist/session-bundle-manifest.js +5 -17
  139. package/node_modules/@maka/storage/dist/session-bundle-policy.js +2 -1
  140. package/node_modules/@maka/storage/dist/session-copy-cleanup.js +2 -1
  141. package/node_modules/@maka/storage/dist/session-store.js +14 -2
  142. package/node_modules/@maka/storage/dist/settings-store.js +8 -4
  143. package/node_modules/@maka/storage/dist/sqlite-artifact-metadata.js +11 -0
  144. package/node_modules/@maka/storage/dist/sqlite-runtime-store.js +1 -2
  145. package/node_modules/@maka/storage/dist/sqlite-session-metadata-schema.js +12 -1
  146. package/node_modules/@maka/storage/dist/sqlite-session-metadata-store.js +67 -3
  147. package/node_modules/@maka/storage/dist/stable-storage.js +14 -1
  148. package/node_modules/@maka/storage/dist/storage-id.js +28 -0
  149. package/node_modules/@maka/storage/dist/tool-result-archive-evidence.js +31 -4
  150. package/node_modules/@maka/storage/dist/workspace-identity.js +2 -15
  151. package/node_modules/@maka/storage/dist/workspace-version-authority-internal.js +1 -8
  152. package/package.json +1 -1
  153. package/node_modules/@maka/core/dist/workhub-creation-intent.js +0 -990
  154. package/node_modules/@maka/core/dist/workhub-session-resolver.js +0 -50
@@ -41,11 +41,15 @@ export class HostDailyReviewCoordinator {
41
41
  #setInterval;
42
42
  #clearInterval;
43
43
  #inFlight = new Map();
44
- #abortControllers = new Set();
44
+ #shutdown = new AbortController();
45
45
  #prepared = false;
46
46
  #started = false;
47
47
  #schedulerEnabled = false;
48
- #draining = false;
48
+ #handoffHeld = false;
49
+ #schedulerTask;
50
+ get #draining() {
51
+ return this.#shutdown.signal.aborted;
52
+ }
49
53
  #timer;
50
54
  #residency;
51
55
  #closeTask;
@@ -92,16 +96,50 @@ export class HostDailyReviewCoordinator {
92
96
  beginDrain() {
93
97
  if (this.#draining)
94
98
  return;
95
- this.#draining = true;
99
+ this.#shutdown.abort(new DOMException('Runtime Host is draining', 'AbortError'));
96
100
  this.#stopScheduler();
97
- for (const controller of this.#abortControllers) {
98
- controller.abort(new DOMException('Runtime Host is draining', 'AbortError'));
99
- }
101
+ }
102
+ holdForHandoff() {
103
+ if (this.#draining || this.#handoffHeld)
104
+ return undefined;
105
+ this.#handoffHeld = true;
106
+ this.#stopTimer();
107
+ let released = false;
108
+ return {
109
+ settled: async () => {
110
+ // Include scheduler reads as well as generation: a tick may still be
111
+ // checking configuration or an archive when the hold is acquired.
112
+ while (this.#schedulerTask || this.#inFlight.size > 0) {
113
+ await Promise.allSettled([
114
+ this.#schedulerTask,
115
+ ...[...this.#inFlight.values()].map((entry) => entry.promise),
116
+ ]);
117
+ }
118
+ },
119
+ residencies: () => {
120
+ if (released || this.#draining || this.#schedulerTask || this.#inFlight.size > 0)
121
+ return undefined;
122
+ return this.#residency ? [this.#residency] : [];
123
+ },
124
+ release: () => {
125
+ if (released)
126
+ return;
127
+ released = true;
128
+ this.#handoffHeld = false;
129
+ if (this.#draining)
130
+ return;
131
+ this.#reconcileScheduler(this.#schedulerEnabled);
132
+ void this.#tickScheduler().catch((error) => this.#handleSchedulerError(error));
133
+ },
134
+ };
100
135
  }
101
136
  close() {
102
137
  this.#closeTask ??= (async () => {
103
138
  this.beginDrain();
104
- await Promise.allSettled([...this.#inFlight.values()].map((entry) => entry.promise));
139
+ await Promise.allSettled([
140
+ this.#schedulerTask,
141
+ ...[...this.#inFlight.values()].map((entry) => entry.promise),
142
+ ]);
105
143
  })();
106
144
  return this.#closeTask;
107
145
  }
@@ -238,6 +276,10 @@ export class HostDailyReviewCoordinator {
238
276
  await inFlight.promise.catch(() => undefined);
239
277
  return this.#run(input);
240
278
  }
279
+ // Keep actual generation distinct from the idle scheduler hold. Besides
280
+ // protecting a run when scheduling is disabled, its release tells handoff
281
+ // observers that work finished after a bounded safe-pause attempt timed out.
282
+ const residency = this.#acquireResidency();
241
283
  const pending = this.#generateArchive(archiveId, day, now, modelKeyOverride, input);
242
284
  const entry = {
243
285
  modelKeyOverride,
@@ -252,14 +294,18 @@ export class HostDailyReviewCoordinator {
252
294
  finally {
253
295
  if (this.#inFlight.get(archiveId) === entry)
254
296
  this.#inFlight.delete(archiveId);
297
+ residency.release();
255
298
  }
256
299
  }
257
300
  async #generateArchive(archiveId, day, now, modelKeyOverride, input) {
301
+ const signal = this.#shutdown.signal;
302
+ signal.throwIfAborted();
258
303
  const summary = await this.#buildSummary(day, now);
259
304
  const existing = await this.#store.getArchive(archiveId);
260
305
  if (existing && !input.replaceExisting)
261
306
  return existing;
262
307
  const config = await this.#store.readConfig();
308
+ signal.throwIfAborted();
263
309
  const modelKey = modelKeyOverride || config.config.modelKey;
264
310
  const base = {
265
311
  id: archiveId,
@@ -278,56 +324,50 @@ export class HostDailyReviewCoordinator {
278
324
  errorMessage: 'No local activity data was available for this review.',
279
325
  });
280
326
  }
281
- const controller = new AbortController();
282
- this.#abortControllers.add(controller);
283
- try {
284
- const result = await this.#model.generate({
285
- modelKey,
286
- prompt: buildModelPrompt(summary, input.range),
287
- abortSignal: controller.signal,
288
- });
289
- if (!result.ok) {
290
- if (result.errorClass === 'aborted') {
291
- throw (controller.signal.reason ?? new DOMException('Daily Review was aborted', 'AbortError'));
292
- }
293
- if (result.errorClass === 'persistence') {
294
- this.#requestDrain();
295
- throw new Error('Daily Review model accounting failed');
296
- }
297
- return this.#publish({
298
- ...base,
299
- status: result.errorClass === 'configuration' ? 'no_model' : 'failed',
300
- sections: buildRuleBasedSections(summary, input.range),
301
- errorMessage: result.errorClass === 'configuration'
302
- ? 'No executable analysis model is configured.'
303
- : result.errorClass === 'timeout'
304
- ? 'The analysis model timed out while generating this review.'
305
- : 'The analysis model failed to generate this review.',
306
- });
307
- }
308
- let sections;
309
- try {
310
- sections = parseSections(result.text);
327
+ const result = await this.#model.generate({
328
+ modelKey,
329
+ prompt: buildModelPrompt(summary, input.range),
330
+ abortSignal: signal,
331
+ });
332
+ signal.throwIfAborted();
333
+ if (!result.ok) {
334
+ if (result.errorClass === 'aborted') {
335
+ throw signal.reason ?? new DOMException('Daily Review was aborted', 'AbortError');
311
336
  }
312
- catch {
313
- return this.#publish({
314
- ...base,
315
- modelKey: result.modelKey,
316
- status: 'failed',
317
- sections: buildRuleBasedSections(summary, input.range),
318
- errorMessage: 'The analysis model returned an invalid review.',
319
- });
337
+ if (result.errorClass === 'persistence') {
338
+ this.#requestDrain();
339
+ throw new Error('Daily Review model accounting failed');
320
340
  }
321
341
  return this.#publish({
322
342
  ...base,
323
- modelKey: result.modelKey,
324
- status: 'ok',
325
- sections,
343
+ status: result.errorClass === 'configuration' ? 'no_model' : 'failed',
344
+ sections: buildRuleBasedSections(summary, input.range),
345
+ errorMessage: result.errorClass === 'configuration'
346
+ ? 'No executable analysis model is configured.'
347
+ : result.errorClass === 'timeout'
348
+ ? 'The analysis model timed out while generating this review.'
349
+ : 'The analysis model failed to generate this review.',
326
350
  });
327
351
  }
328
- finally {
329
- this.#abortControllers.delete(controller);
352
+ let sections;
353
+ try {
354
+ sections = parseSections(result.text);
330
355
  }
356
+ catch {
357
+ return this.#publish({
358
+ ...base,
359
+ modelKey: result.modelKey,
360
+ status: 'failed',
361
+ sections: buildRuleBasedSections(summary, input.range),
362
+ errorMessage: 'The analysis model returned an invalid review.',
363
+ });
364
+ }
365
+ return this.#publish({
366
+ ...base,
367
+ modelKey: result.modelKey,
368
+ status: 'ok',
369
+ sections,
370
+ });
331
371
  }
332
372
  async #publish(archive) {
333
373
  const encodedBytes = Buffer.byteLength(JSON.stringify(archive), 'utf8');
@@ -337,27 +377,41 @@ export class HostDailyReviewCoordinator {
337
377
  return this.#store.publishArchive(archive, ARCHIVE_LIMIT);
338
378
  }
339
379
  #reconcileScheduler(enabled) {
380
+ this.#schedulerEnabled = enabled;
340
381
  if (!enabled || this.#draining) {
341
382
  this.#stopScheduler();
342
383
  return;
343
384
  }
344
- this.#residency ??= this.#acquireResidency();
385
+ if (this.#handoffHeld)
386
+ return;
387
+ this.#residency ??= this.#acquireResidency('idle');
345
388
  this.#timer ??= this.#setInterval(() => {
346
389
  void this.#tickScheduler().catch((error) => this.#handleSchedulerError(error));
347
390
  }, SCHEDULER_INTERVAL_MS);
348
391
  }
349
392
  #stopScheduler() {
393
+ this.#stopTimer();
394
+ this.#residency?.release();
395
+ this.#residency = undefined;
396
+ }
397
+ #stopTimer() {
350
398
  if (this.#timer !== undefined) {
351
399
  this.#clearInterval(this.#timer);
352
400
  this.#timer = undefined;
353
401
  }
354
- this.#residency?.release();
355
- this.#residency = undefined;
356
402
  }
357
- async #tickScheduler() {
358
- if (!this.#prepared || this.#draining)
359
- return;
403
+ #tickScheduler() {
404
+ if (!this.#prepared || this.#draining || this.#handoffHeld)
405
+ return Promise.resolve();
406
+ this.#schedulerTask ??= this.#runScheduler().finally(() => {
407
+ this.#schedulerTask = undefined;
408
+ });
409
+ return this.#schedulerTask;
410
+ }
411
+ async #runScheduler() {
360
412
  const { config } = await this.#store.readConfig();
413
+ if (this.#draining || this.#handoffHeld)
414
+ return;
361
415
  this.#reconcileScheduler(config.enabled);
362
416
  const now = this.#now();
363
417
  if (!config.enabled || !scheduledTimeHasPassed(now, config.executeTime))
@@ -368,6 +422,8 @@ export class HostDailyReviewCoordinator {
368
422
  const archiveId = dailyReviewArchiveId(day, 1);
369
423
  if (await this.#store.getArchive(archiveId))
370
424
  return;
425
+ if (this.#draining || this.#handoffHeld)
426
+ return;
371
427
  await this.#run({
372
428
  range: 1,
373
429
  offsetDays: -1,
@@ -22,7 +22,7 @@ import { isAbsolute, resolve } from 'node:path';
22
22
  import { MAX_ATTACHMENT_BYTES } from '@maka/core/attachments';
23
23
  import { createToolResultArchiveCapability, } from '@maka/runtime/tool-result-archive-capability';
24
24
  import { isPathInside } from '@maka/runtime/path-containment';
25
- import { stableToolResultArchiveArtifactId } from '@maka/runtime/tool-result-archive';
25
+ import { createLedgerArchivePreparer, createLedgerArchiveResourceReader, createLedgerToolResultArchiveReader, } from '@maka/runtime/ledger-tool-result-archive-reader';
26
26
  export function createHostExecutionArtifactServices(input) {
27
27
  const runWrite = async (operation) => {
28
28
  try {
@@ -58,6 +58,30 @@ export function createHostExecutionArtifactServices(input) {
58
58
  });
59
59
  }
60
60
  };
61
+ const prepareLedger = input.archiveEvidence
62
+ ? createLedgerArchivePreparer(input.archiveEvidence)
63
+ : undefined;
64
+ const readLedger = input.archiveEvidence
65
+ ? createLedgerToolResultArchiveReader(input.archiveEvidence)
66
+ : undefined;
67
+ const readLedgerResource = input.archiveEvidence
68
+ ? createLedgerArchiveResourceReader(input.archiveEvidence)
69
+ : undefined;
70
+ const prepareLedgerForCommit = async (event) => {
71
+ const accepted = { ...event };
72
+ if (!prepareLedger || !(await prepareLedger(accepted)))
73
+ return;
74
+ return {
75
+ ledger: true,
76
+ commitTransition: (transition, persist) => input.sessionAdmission.runOrJoin(accepted.sessionId, async () => {
77
+ if ((await input.sessions.probeSessionRemoval(accepted.sessionId)).kind !== 'present' ||
78
+ !(await prepareLedger(accepted)))
79
+ return false;
80
+ await persist(transition);
81
+ return true;
82
+ }),
83
+ };
84
+ };
61
85
  const services = {
62
86
  recordToolArtifacts,
63
87
  publishChildWorkspacePatch: async ({ sessionId, turnId, binding, patch }) => {
@@ -77,37 +101,13 @@ export function createHostExecutionArtifactServices(input) {
77
101
  return artifact;
78
102
  },
79
103
  toolResultArchive: createToolResultArchiveCapability({
80
- archiveToolResult: (event) => runWrite(async () => {
81
- const artifactId = stableToolResultArchiveArtifactId(event);
82
- const existing = await input.artifacts.getInSession(event.sessionId, artifactId);
83
- if (existing.record) {
84
- const read = await readArchive(input.artifacts, {
85
- artifactId,
86
- sessionId: event.sessionId,
87
- bodySha256: event.bodySha256,
88
- originalBytes: event.originalBytes,
89
- maxBytes: event.originalBytes,
90
- });
91
- if (!read.ok) {
92
- throw new Error(`Tool result archive identity conflict: ${read.reason}`);
93
- }
94
- return { artifactId };
95
- }
96
- const artifact = await input.artifacts.create({
97
- id: artifactId,
98
- sessionId: event.sessionId,
99
- turnId: event.turnId,
100
- name: `archived-${event.toolName}-${event.runtimeEventId}.json`,
101
- kind: 'file',
102
- content: event.serializedResult,
103
- mimeType: 'application/json',
104
- source: 'tool_result_archive',
105
- summary: `Archived ${event.toolName} tool result for context budget replay`,
106
- });
107
- return { artifactId: artifact.id };
108
- }),
109
- readToolResultArchive: (event) => readArchive(input.artifacts, event),
110
- readArchivedToolResultResource: (event) => readArchive(input.artifacts, event),
104
+ archiveToolResult: prepareLedgerForCommit,
105
+ readToolResultArchive: (event) => event.rewriteVersion === 2
106
+ ? (readLedger?.(event) ?? { ok: false, reason: 'read_failed' })
107
+ : readArchive(input.artifacts, event),
108
+ readArchivedToolResultResource: (event) => event.storage === 'ledger'
109
+ ? (readLedgerResource?.(event) ?? { ok: false, reason: 'read_failed' })
110
+ : readArchive(input.artifacts, event),
111
111
  }),
112
112
  };
113
113
  return Object.freeze(services);