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
@@ -18,7 +18,7 @@
18
18
  */
19
19
  import { isRuntimeSystemNoteKind } from '@maka/core/session';
20
20
  import { createRuntimeEventId } from '@maka/core/runtime-event';
21
- export const RUNTIME_EVENT_BACKFILL_STATE_KEY = 'makaRuntimeRecovery';
21
+ const RUNTIME_EVENT_BACKFILL_STATE_KEY = 'makaRuntimeRecovery';
22
22
  export function backfillRuntimeEventsFromStoredMessages(input) {
23
23
  const newId = input.newId ?? (() => createRuntimeEventId('rt-backfill'));
24
24
  const now = input.now ?? (() => Date.now());
@@ -53,13 +53,27 @@ export function isContinuationStartRuntimeEvent(event) {
53
53
  return (event.actions?.stateDelta?.continuationStart === true ||
54
54
  event.actions?.continuationStart !== undefined);
55
55
  }
56
+ export function projectRuntimeEventCoordinationReceipt(event) {
57
+ if (!event.actions?.coordination)
58
+ return undefined;
59
+ return {
60
+ type: 'workhub_coordination',
61
+ kind: 'action_receipt',
62
+ schemaVersion: 1,
63
+ id: event.id,
64
+ turnId: event.turnId,
65
+ ts: event.ts,
66
+ receipt: event.actions.coordination,
67
+ };
68
+ }
56
69
  /**
57
70
  * Whether the event can affect the StoredMessage projection or the state needed
58
71
  * to construct one. Pure control-plane facts are intentionally absent so a
59
72
  * transcript reader can stream past them without retaining the whole ledger.
60
73
  */
61
74
  export function affectsRuntimeEventStoredMessageProjection(event) {
62
- return (event.content !== undefined ||
75
+ return (event.actions?.coordination !== undefined ||
76
+ event.content !== undefined ||
63
77
  isTerminalRuntimeEvent(event) ||
64
78
  event.actions?.permissionRequest !== undefined ||
65
79
  event.actions?.permissionDecision !== undefined ||
@@ -143,6 +157,11 @@ export function projectRuntimeEventsToStoredMessages(events, options) {
143
157
  break;
144
158
  }
145
159
  }
160
+ const coordinationReceipt = projectRuntimeEventCoordinationReceipt(event);
161
+ if (coordinationReceipt) {
162
+ messages.push(coordinationReceipt);
163
+ projected = true;
164
+ }
146
165
  if (event.actions?.permissionRequest) {
147
166
  const request = event.actions.permissionRequest;
148
167
  state.permissionRequestById.set(request.requestId, {
@@ -357,6 +376,7 @@ export function applyArchivedToolResultReadModelStatuses(events, archiveStatuses
357
376
  toolCallId: placeholder.toolCallId,
358
377
  toolName: placeholder.toolName,
359
378
  artifactId: placeholder.artifactId,
379
+ ...(placeholder.rewriteVersion === 2 ? { resourceRef: placeholder.resourceRef } : {}),
360
380
  bodySha256: placeholder.bodySha256,
361
381
  originalEstimatedTokens: placeholder.originalEstimatedTokens,
362
382
  originalBytes: placeholder.originalBytes,
@@ -658,6 +678,9 @@ function projectFunctionResponse(event, state, messages) {
658
678
  toolName: archivedPlaceholder.toolName,
659
679
  artifactId: archivedPlaceholder.artifactId,
660
680
  bodySha256: archivedPlaceholder.bodySha256,
681
+ ...(archivedPlaceholder.rewriteVersion === 2
682
+ ? { resourceRef: archivedPlaceholder.resourceRef }
683
+ : {}),
661
684
  originalEstimatedTokens: archivedPlaceholder.originalEstimatedTokens,
662
685
  originalBytes: archivedPlaceholder.originalBytes,
663
686
  rewriteVersion: archivedPlaceholder.rewriteVersion,
@@ -530,6 +530,111 @@ export class RuntimeKernel {
530
530
  runId: continuation.runId,
531
531
  }, options, () => this.revalidateContinuationSafety(continuation), inheritedSandboxBoundaryDenied);
532
532
  }
533
+ /** Host coordination uses the same Run owner and terminal authority without a provider send. */
534
+ async *runCoordinationOperation(sessionId, input, options, execute) {
535
+ const execution = this.takeExecutionClaim(sessionId);
536
+ execution.hostOperation = true;
537
+ try {
538
+ await this.enterExecutionClaim(execution);
539
+ const header = await this.deps.store.readHeader(sessionId);
540
+ const run = new AgentRun({
541
+ sessionId,
542
+ header,
543
+ userInput: input,
544
+ runId: options.runId,
545
+ userMessageId: options.userMessageId,
546
+ durability: 'required',
547
+ runStore: this.deps.runStore,
548
+ runtimeEventStore: this.deps.runtimeEventStore,
549
+ newId: this.deps.newId,
550
+ now: this.deps.now,
551
+ effectiveOrchestration: resolveEffectiveOrchestration('default', undefined),
552
+ hooks: {
553
+ reserveRun: async (id, nextHeader, activeRun) => {
554
+ const active = await this.reserveParentRun(id, nextHeader, activeRun, execution);
555
+ this.reserveExecutionClaim(execution, active, activeRun);
556
+ return active;
557
+ },
558
+ unregisterRun: (active, activeRun) => this.unregisterParentRun(active, activeRun),
559
+ updateHeader: (id, patch) => this.updateHeader(id, patch),
560
+ updateStatus: (id, status, reason, ts) => this.updateStatus(id, status, reason, ts),
561
+ ...this.messageProjectionHook(),
562
+ },
563
+ });
564
+ this.attachExecutionClaim(execution, run);
565
+ const owners = this.createRunOwnerScope(run, execution);
566
+ try {
567
+ owners.bindMessage(this.deps.messageAuthority, {
568
+ sessionId,
569
+ turnId: input.turnId,
570
+ runId: run.runId,
571
+ });
572
+ // Keep the execution claim attached until finalization. Stop/drain can
573
+ // therefore cancel and await this Run without a provider generation.
574
+ await run.beginCoordination();
575
+ await options.onRunStarted?.(run.runId, header);
576
+ }
577
+ catch (error) {
578
+ await this.finalizeFailedRunStart(owners, run, execution, error);
579
+ return;
580
+ }
581
+ try {
582
+ if (run.isStopped())
583
+ return;
584
+ const executed = await execute();
585
+ const receipt = {
586
+ ...executed,
587
+ result: executed.result.disposition === 'clarify'
588
+ ? { ...executed.result, coordinationTurnId: input.turnId }
589
+ : executed.result,
590
+ };
591
+ const receiptEvent = {
592
+ id: this.deps.newId(),
593
+ sessionId,
594
+ turnId: input.turnId,
595
+ runId: run.runId,
596
+ invocationId: run.runId,
597
+ ts: this.deps.now(),
598
+ partial: false,
599
+ role: 'system',
600
+ author: 'host',
601
+ modelVisibility: 'hidden',
602
+ actions: { coordination: receipt },
603
+ };
604
+ await run.recordRuntimeEvents([receiptEvent], { requireDurableWrite: true });
605
+ if (run.isStopped())
606
+ return;
607
+ const complete = {
608
+ type: 'complete',
609
+ id: this.deps.newId(),
610
+ turnId: input.turnId,
611
+ ts: this.deps.now(),
612
+ stopReason: 'end_turn',
613
+ };
614
+ await run.acceptMappedEvent(complete, mapSessionEventToRuntimeEvent(complete, this.runtimeEventMapContext({
615
+ sessionId,
616
+ invocationId: run.runId,
617
+ runId: run.runId,
618
+ turnId: input.turnId,
619
+ })), { requireTerminalWrite: true });
620
+ yield complete;
621
+ }
622
+ catch (error) {
623
+ await run.recordFailure(error);
624
+ throw error;
625
+ }
626
+ finally {
627
+ const failures = new FailureCollector();
628
+ await failures.capture(() => owners.finalize());
629
+ await failures.capture(() => owners.releaseMessage());
630
+ failures.throwIfAny(`Coordination cleanup failed for ${run.runId}`);
631
+ }
632
+ }
633
+ finally {
634
+ this.releaseExecutionClaim(execution);
635
+ await this.flushBackendInvalidation(sessionId);
636
+ }
637
+ }
533
638
  async *compactSession(sessionId, input = {}) {
534
639
  const execution = this.takeExecutionClaim(sessionId);
535
640
  try {
@@ -1455,24 +1560,26 @@ export class RuntimeKernel {
1455
1560
  const generations = this.backendGenerationsFor(sessionId);
1456
1561
  await Promise.all(generations.map((active) => active.backend.respondToUserQuestion?.(response)));
1457
1562
  }
1563
+ activeRunsFor(sessionId) {
1564
+ const runs = new Set();
1565
+ for (const active of this.backendGenerationsFor(sessionId)) {
1566
+ for (const run of active.activeRuns.values())
1567
+ runs.add(run);
1568
+ }
1569
+ for (const claim of this.executionClaims.get(sessionId) ?? []) {
1570
+ if (claim.hostOperation && claim.run)
1571
+ runs.add(claim.run);
1572
+ }
1573
+ return [...runs];
1574
+ }
1458
1575
  hasActiveRuns(sessionId) {
1459
- return this.backendGenerationsFor(sessionId).some((active) => active.activeRuns.size > 0);
1576
+ return this.activeRunsFor(sessionId).length > 0;
1460
1577
  }
1461
1578
  runningTurnIds(sessionId) {
1462
- const turnIds = [];
1463
- for (const active of this.backendGenerationsFor(sessionId)) {
1464
- for (const run of active.activeRuns.values()) {
1465
- if (!turnIds.includes(run.turnId))
1466
- turnIds.push(run.turnId);
1467
- }
1468
- }
1469
- return turnIds;
1579
+ return [...new Set(this.activeRunsFor(sessionId).map((run) => run.turnId))];
1470
1580
  }
1471
1581
  hasActiveRun(sessionId, runId, turnId) {
1472
- return this.backendGenerationsFor(sessionId).some((active) => {
1473
- const run = active.activeRuns.get(runId);
1474
- return run !== undefined && (turnId === undefined || run.turnId === turnId);
1475
- });
1582
+ return this.activeRunsFor(sessionId).some((run) => run.runId === runId && (turnId === undefined || run.turnId === turnId));
1476
1583
  }
1477
1584
  requestRunHandoff(sessionId, runId, pause, signal) {
1478
1585
  if (!this.deps.inspectContinuationSafety)
@@ -1694,6 +1801,13 @@ export class RuntimeKernel {
1694
1801
  }
1695
1802
  return run.recordRunComposition(snapshot);
1696
1803
  },
1804
+ recordRequestComposition: (runId, snapshot) => {
1805
+ const run = this.active.get(sessionId)?.activeRuns.get(runId);
1806
+ if (!run) {
1807
+ return Promise.reject(new Error('No active AgentRun for Request Composition'));
1808
+ }
1809
+ return run.recordRequestComposition(snapshot);
1810
+ },
1697
1811
  loadHistoryCompactCheckpoint: () => this.historyCompactCoordinator.load(sessionId),
1698
1812
  recordHistoryCompactCheckpoint: (checkpoint, turnId) => this.historyCompactCoordinator.record(sessionId, checkpoint, runFor(turnId)),
1699
1813
  loadModelProjectionTransitions: async () => loadModelProjectionTransitionsFromRunLedger(this.deps.runStore, sessionId, await this.sessionRunIds(sessionId)),
@@ -16,17 +16,6 @@
16
16
  * specific language governing permissions and limitations
17
17
  * under the License.
18
18
  */
19
- /**
20
- * SessionManager — the public Runtime API.
21
- *
22
- * Ties together:
23
- * SessionStore (storage) — SQLite persistence
24
- * AgentBackend (AiSdkBackend etc) — SDK adapter
25
- * ExecutionBoundary — session sandbox authority
26
- *
27
- * `SessionStore` comes from `@maka/storage`; its public interface owns
28
- * persistence and same-session serialization semantics.
29
- */
30
19
  import { createHash } from 'node:crypto';
31
20
  import { isDeepStrictEqual } from 'node:util';
32
21
  import { setTimeout as delay } from 'node:timers/promises';
@@ -1280,6 +1269,9 @@ export class SessionManager {
1280
1269
  // Operational telemetry must never alter resume correctness.
1281
1270
  }
1282
1271
  }
1272
+ runCoordinationOperation(sessionId, input, options, execute) {
1273
+ return this.runtimeKernel.runCoordinationOperation(sessionId, input, options, execute);
1274
+ }
1283
1275
  async *compactSession(sessionId, input = {}) {
1284
1276
  yield* this.runtimeKernel.compactSession(sessionId, input);
1285
1277
  }
@@ -2314,43 +2306,30 @@ export class SessionManager {
2314
2306
  const hostedAuthority = isRuntimeHostedRootAuthority(this.deps.messageAuthority)
2315
2307
  ? this.deps.messageAuthority
2316
2308
  : undefined;
2317
- const ownStop = hostedAuthority
2309
+ await this.#stopSessionTree(sessionId, hostedAuthority
2318
2310
  ? hostedAuthority.stopSession(sessionId, input)
2319
- : this.runtimeKernel.stopSession(sessionId, input);
2320
- let childStops = [];
2321
- let childLookupError;
2322
- try {
2323
- const children = await this.listChildSessions(sessionId);
2324
- childStops = await Promise.allSettled(children
2325
- .filter((child) => child.subagentParent?.lifecycle === 'foreground')
2326
- .map((child) => hostedAuthority
2327
- ? hostedAuthority.stopSession(child.id, input)
2328
- : this.runtimeKernel.stopSession(child.id, input)));
2329
- }
2330
- catch (error) {
2331
- childLookupError = error;
2332
- }
2333
- await ownStop;
2334
- const childStopError = childStops.find((result) => result.status === 'rejected')?.reason;
2335
- if (childLookupError !== undefined)
2336
- throw childLookupError;
2337
- if (childStopError !== undefined)
2338
- throw childStopError;
2311
+ : this.runtimeKernel.stopSession(sessionId, input), (childSessionId) => hostedAuthority
2312
+ ? hostedAuthority.stopSession(childSessionId, input)
2313
+ : this.runtimeKernel.stopSession(childSessionId, input));
2339
2314
  }
2340
2315
  async deliverHostedRootStop(sessionId, input = {}) {
2341
- const ownStop = this.runtimeKernel.stopSession(sessionId, input);
2342
2316
  const authority = isRuntimeHostedRootAuthority(this.deps.messageAuthority)
2343
2317
  ? this.deps.messageAuthority
2344
2318
  : undefined;
2319
+ await this.#stopSessionTree(sessionId, this.runtimeKernel.stopSession(sessionId, input), (childSessionId) => authority
2320
+ ? authority.stopSession(childSessionId, input)
2321
+ : this.runtimeKernel.stopSession(childSessionId, input));
2322
+ }
2323
+ async #stopSessionTree(sessionId, ownStop, stopChild) {
2324
+ // Observe immediately while child lookup runs; await below still propagates the original error.
2325
+ void ownStop.catch(() => undefined);
2345
2326
  let childStops = [];
2346
2327
  let childLookupError;
2347
2328
  try {
2348
2329
  const children = await this.listChildSessions(sessionId);
2349
2330
  childStops = await Promise.allSettled(children
2350
2331
  .filter((child) => child.subagentParent?.lifecycle === 'foreground')
2351
- .map((child) => authority
2352
- ? authority.stopSession(child.id, input)
2353
- : this.runtimeKernel.stopSession(child.id, input)));
2332
+ .map((child) => stopChild(child.id)));
2354
2333
  }
2355
2334
  catch (error) {
2356
2335
  childLookupError = error;
@@ -2385,6 +2364,11 @@ export class SessionManager {
2385
2364
  goalId: input.execution.goalId,
2386
2365
  };
2387
2366
  }
2367
+ else if (input.execution.kind === 'workhub_coordination' &&
2368
+ input.execution.operation === 'action') {
2369
+ recoveryReason = 'coordination_action_admission_without_run';
2370
+ diagnostic = { executionKind: input.execution.kind, operation: input.execution.operation };
2371
+ }
2388
2372
  else if (input.execution.kind === 'legacy_automation') {
2389
2373
  root = { kind: 'legacy_automation', legacyAutomationId: input.execution.automationId };
2390
2374
  recoveryReason = 'legacy_automation_authority_removed';
@@ -184,6 +184,27 @@ export class AgentGraphCoordinator {
184
184
  async hasLiveSessionState(rootSessionId) {
185
185
  return (await this.readSessionState(rootSessionId)) === 'live';
186
186
  }
187
+ /**
188
+ * Classify durable graph state for Session retirement without changing the
189
+ * broader live-state semantics used by recovery and graph epoch selection.
190
+ */
191
+ async readRetirementDisposition(rootSessionId) {
192
+ const snapshot = buildAgentGraphClientSnapshot(await this.#readClientModelInputForGraph(rootSessionId, await this.currentGraphId(rootSessionId)));
193
+ if (snapshot.scheduleRevision === 0)
194
+ return { kind: 'clear' };
195
+ switch (snapshot.status) {
196
+ case 'empty':
197
+ case 'completed':
198
+ return { kind: 'clear' };
199
+ case 'stopped':
200
+ case 'failed':
201
+ return { kind: 'quiescent_open' };
202
+ case 'active':
203
+ case 'waiting':
204
+ case 'closing':
205
+ return { kind: 'busy', status: snapshot.status };
206
+ }
207
+ }
187
208
  /**
188
209
  * Reconstruct one stable, reference-only control/data-plane timeline page.
189
210
  *
@@ -22,11 +22,6 @@ import { stableHash } from './request-shape.js';
22
22
  export const VIEW_AGENT_GRAPH_TOOL_NAME = 'view_agent_graph';
23
23
  export const UPDATE_AGENT_GRAPH_TOOL_NAME = 'update_agent_graph';
24
24
  export const YIELD_AGENT_GRAPH_TOOL_NAME = 'yield_agent_graph';
25
- export const AGENT_GRAPH_SUPERVISOR_TOOL_NAMES = [
26
- VIEW_AGENT_GRAPH_TOOL_NAME,
27
- UPDATE_AGENT_GRAPH_TOOL_NAME,
28
- YIELD_AGENT_GRAPH_TOOL_NAME,
29
- ];
30
25
  const TOOL_VIEW_MAX_TERMINAL_WORK = 64;
31
26
  const TOOL_VIEW_MAX_STOPPED_TARGETS = 64;
32
27
  const TOOL_VIEW_MAX_INSTRUCTION_CHARS = 2_000;
@@ -337,7 +337,6 @@ async function httpFailure(r, t0) {
337
337
  await r.cancel();
338
338
  return {
339
339
  ok: false,
340
- errorMessage: 'OAuth 已登录,但当前账号或 provider 正在 rate limit。请稍后重试,或先切换到其它可用模型。',
341
340
  statusCode,
342
341
  errorClass: 'provider_unavailable',
343
342
  latencyMs: Date.now() - t0,
@@ -0,0 +1,41 @@
1
+ /*
2
+ * Licensed to the Apache Software Foundation (ASF) under one
3
+ * or more contributor license agreements. See the NOTICE file
4
+ * distributed with this work for additional information
5
+ * regarding copyright ownership. The ASF licenses this file
6
+ * to you under the Apache License, Version 2.0 (the
7
+ * "License"); you may not use this file except in compliance
8
+ * with the License. You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing,
13
+ * software distributed under the License is distributed on an
14
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ * KIND, either express or implied. See the License for the
16
+ * specific language governing permissions and limitations
17
+ * under the License.
18
+ */
19
+ import { stableHash, toolCatalogHash } from './request-shape.js';
20
+ const TOOL_ACTIVATION_IDENTITY = Symbol('maka.toolActivationIdentity');
21
+ /** Bind a Runtime-owned contribution identity to a Tool without exposing it to providers. */
22
+ export function bindToolActivationIdentity(tool, identity) {
23
+ return Object.freeze({
24
+ ...tool,
25
+ [TOOL_ACTIVATION_IDENTITY]: stableHash({
26
+ identity,
27
+ schemaHash: toolCatalogHash([tool]),
28
+ }),
29
+ });
30
+ }
31
+ /**
32
+ * Stable logical identity used by deferred-tool activation.
33
+ *
34
+ * Host wrappers without explicit contribution metadata fall back to their
35
+ * canonical provider-visible shape, so rebuilding an equivalent wrapper does
36
+ * not revoke activation. Dynamic contributors bind generation-aware metadata.
37
+ */
38
+ export function toolActivationKey(tool) {
39
+ const explicit = tool[TOOL_ACTIVATION_IDENTITY];
40
+ return explicit ?? stableHash({ kind: 'host', schemaHash: toolCatalogHash([tool]) });
41
+ }
@@ -20,6 +20,7 @@ import MiniSearch from 'minisearch';
20
20
  import { z } from 'zod';
21
21
  import { estimateTokens } from './context-budget-helpers.js';
22
22
  import { canonicalizeToolSet, stableHash, toolSchemaCharsForDiagnostics } from './request-shape.js';
23
+ import { toolActivationKey } from './tool-activation-identity.js';
23
24
  /** Canonical name of Maka's provider-independent deferred-tool search connector. */
24
25
  export const TOOL_SEARCH_NAME = 'tool_search';
25
26
  /** Provider-safe alias used because OpenAI Responses reserves `tool_search`. */
@@ -101,6 +102,7 @@ export class ToolAvailabilityRuntime {
101
102
  invalidTool;
102
103
  tools;
103
104
  toolsByName;
105
+ activationKeysByName;
104
106
  groups;
105
107
  searchableNames;
106
108
  directNames;
@@ -115,6 +117,7 @@ export class ToolAvailabilityRuntime {
115
117
  }
116
118
  this.tools = [...tools];
117
119
  this.toolsByName = new Map(tools.map((tool) => [tool.name, tool]));
120
+ this.activationKeysByName = new Map(tools.map((tool) => [tool.name, toolActivationKey(tool)]));
118
121
  const known = new Set(this.toolsByName.keys());
119
122
  const searchable = config === undefined
120
123
  ? new Set()
@@ -240,6 +243,13 @@ export class ToolAvailabilityRuntime {
240
243
  const allTools = [...this.tools, connector];
241
244
  const canonical = canonicalizeToolSet(allTools, this.invalidTool);
242
245
  const knownNames = new Set(canonical.providerTools.map((tool) => tool.name));
246
+ // Activation belongs to a stable logical contribution, not a temporary
247
+ // wrapper object or merely its name. Equivalent Host wrappers survive
248
+ // per-step rebuilding; a replaced Plugin generation does not.
249
+ for (const [name, activatedKey] of activeTools) {
250
+ if (this.activationKeysByName.get(name) !== activatedKey)
251
+ activeTools.delete(name);
252
+ }
243
253
  const requiredNames = [...requiredToolNames].filter((name) => knownNames.has(name));
244
254
  const step = { active: new Set() };
245
255
  const computeActive = () => {
@@ -308,7 +318,7 @@ export class ToolAvailabilityRuntime {
308
318
  schemaChars += chars;
309
319
  }
310
320
  for (const name of activated)
311
- activeTools.set(name, this.toolsByName.get(name));
321
+ activeTools.set(name, this.activationKeysByName.get(name));
312
322
  const result = {
313
323
  activated,
314
324
  ...(blocked ? { blocked } : {}),
@@ -35,12 +35,72 @@ const MAX_SEARCH_SNIPPET_CHARS = 240;
35
35
  const MAX_SEARCH_PATTERN_CHARS = 256;
36
36
  /** Preview length surfaced by inspect for text/object payloads. */
37
37
  const INSPECT_PREVIEW_CHARS = 600;
38
+ export function isLedgerArchiveIdentity(value) {
39
+ if (!isRecord(value))
40
+ return false;
41
+ return (value.storage === 'ledger' &&
42
+ value.artifactId === undefined &&
43
+ ['runtimeEventId', 'toolCallId', 'toolName'].every((key) => typeof value[key] === 'string' &&
44
+ value[key].length > 0 &&
45
+ value[key].length <= 512) &&
46
+ typeof value.sourceProjectionDigest === 'string' &&
47
+ /^sha256:[a-f0-9]{64}$/.test(value.sourceProjectionDigest) &&
48
+ (value.previousTransitionId === undefined ||
49
+ (typeof value.previousTransitionId === 'string' &&
50
+ /^mptransition-[a-f0-9]{32}$/.test(value.previousTransitionId))) &&
51
+ typeof value.bodySha256 === 'string' &&
52
+ /^[a-f0-9]{64}$/.test(value.bodySha256) &&
53
+ Number.isSafeInteger(value.originalBytes) &&
54
+ Number(value.originalBytes) > 0);
55
+ }
38
56
  export function buildToolResultArchiveResourceRef(input) {
57
+ if (input.storage === 'ledger') {
58
+ if (!isLedgerArchiveIdentity(input))
59
+ throw new Error('Invalid ledger archive identity');
60
+ const value = [
61
+ input.runtimeEventId,
62
+ input.toolCallId,
63
+ input.toolName,
64
+ input.sourceProjectionDigest,
65
+ input.previousTransitionId ?? null,
66
+ input.bodySha256,
67
+ input.originalBytes,
68
+ ];
69
+ return `maka://archive-ledger/v1/${encodeURIComponent(JSON.stringify(value))}`;
70
+ }
39
71
  const artifactId = encodeURIComponent(input.artifactId);
40
72
  const sha256 = encodeURIComponent(input.bodySha256);
41
73
  return `maka://archive/${artifactId}/${sha256}/${input.originalBytes}`;
42
74
  }
43
75
  export function parseToolResultArchiveResourceRef(ref) {
76
+ if (ref.startsWith('maka://archive-ledger/')) {
77
+ try {
78
+ const prefix = 'maka://archive-ledger/v1/';
79
+ if (!ref.startsWith(prefix) || ref.length > 16384)
80
+ return null;
81
+ const values = JSON.parse(decodeURIComponent(ref.slice(prefix.length)));
82
+ if (!Array.isArray(values) || values.length !== 7)
83
+ return null;
84
+ const [runtimeEventId, toolCallId, toolName, sourceProjectionDigest, previous, bodySha256, originalBytes,] = values;
85
+ const identity = {
86
+ storage: 'ledger',
87
+ runtimeEventId,
88
+ toolCallId,
89
+ toolName,
90
+ sourceProjectionDigest,
91
+ ...(previous === null ? {} : { previousTransitionId: previous }),
92
+ bodySha256,
93
+ originalBytes,
94
+ };
95
+ return isLedgerArchiveIdentity(identity) &&
96
+ buildToolResultArchiveResourceRef(identity) === ref
97
+ ? identity
98
+ : null;
99
+ }
100
+ catch {
101
+ return null;
102
+ }
103
+ }
44
104
  let url;
45
105
  try {
46
106
  url = new URL(ref);
@@ -162,7 +222,9 @@ function inspectArchive(ref, identity, value, serializedResult) {
162
222
  kind: 'tool_result_archive',
163
223
  operation: 'inspect',
164
224
  ref,
165
- artifactId: identity.artifactId,
225
+ ...(identity.storage === 'ledger'
226
+ ? { storage: 'ledger', runtimeEventId: identity.runtimeEventId }
227
+ : { artifactId: identity.artifactId }),
166
228
  originalBytes: identity.originalBytes,
167
229
  };
168
230
  const readHint = 'Call ArchiveRead with operation "read" (unit "char" or "line"), offset, and limit for bounded pages, or operation "search" with a pattern to locate text.';
@@ -40,11 +40,12 @@
40
40
  */
41
41
  import { MATERIALIZED_IMAGE_TOKENS } from '@maka/core/attachments';
42
42
  import { DURABLE_TOOL_RESULT_PROJECTION_VERSION } from '@maka/core/durable-tool-result-projection';
43
- import { buildModelProjectionTransition, } from '@maka/core/model-projection-transition';
43
+ import { buildModelProjectionTransition, durableToolResultProjectionDigest, } from '@maka/core/model-projection-transition';
44
44
  import { estimateTokens, finitePositive, sha256, turnKey, utf8ByteLength, } from './context-budget-helpers.js';
45
- import { durableProjectionToToolResultOutput, projectionArtifactMedia, } from './durable-tool-result-projection.js';
45
+ import { projectionArtifactMedia } from './durable-tool-result-projection.js';
46
46
  import { baseToolResultProjection, nextInChain } from './model-projection-transition-ledger.js';
47
- import { ARCHIVED_TOOL_RESULT_REWRITE_VERSION, buildArchivedToolResultPlaceholder, isArchivedToolResultPlaceholder, serializeToolResultForArchive, } from './tool-result-archive.js';
47
+ import { ARCHIVED_TOOL_RESULT_REWRITE_VERSION, buildArchivedToolResultPlaceholder, buildLedgerArchivedToolResultPlaceholder, isArchivedToolResultPlaceholder, } from './tool-result-archive.js';
48
+ import { serializeToolResultProjectionV1 } from './tool-result-archive-encoding.js';
48
49
  const DEFAULT_MAX_TOOL_RESULT_ESTIMATED_TOKENS = 2048;
49
50
  /**
50
51
  * What the model actually reads for one Tool Result, as bytes.
@@ -55,8 +56,7 @@ const DEFAULT_MAX_TOOL_RESULT_ESTIMATED_TOKENS = 2048;
55
56
  * body that is not the one removed from the model's view.
56
57
  */
57
58
  export function serializedToolResultProjection(projection) {
58
- const output = durableProjectionToToolResultOutput(projection);
59
- return serializeToolResultForArchive(output.type === 'execution-denied' ? { kind: 'text', text: output.reason ?? '' } : output.value);
59
+ return serializeToolResultProjectionV1(projection);
60
60
  }
61
61
  /** The replacement a pruned Tool Result projects to. */
62
62
  export function archivedToolResultProjection(placeholder) {
@@ -90,16 +90,21 @@ export async function archiveToolResultAsTransition(services, request) {
90
90
  originalEstimatedTokens: request.originalEstimatedTokens,
91
91
  rewriteVersion: ARCHIVED_TOOL_RESULT_REWRITE_VERSION,
92
92
  reason: request.reason,
93
+ sourceProjectionDigest: durableToolResultProjectionDigest(request.sourceProjection),
94
+ ...(request.previousTransitionId
95
+ ? { previousTransitionId: request.previousTransitionId }
96
+ : {}),
93
97
  }));
94
98
  }
95
99
  catch {
96
100
  return undefined;
97
101
  }
98
- const artifactId = archived?.artifactId;
99
- if (typeof artifactId !== 'string' || artifactId.trim().length === 0)
102
+ if (!archived)
103
+ return undefined;
104
+ if (!archived.ledger &&
105
+ (typeof archived.artifactId !== 'string' || archived.artifactId.trim().length === 0))
100
106
  return undefined;
101
- const placeholder = buildArchivedToolResultPlaceholder({
102
- artifactId,
107
+ const common = {
103
108
  runtimeEventId: request.runtimeEventId,
104
109
  toolCallId: request.toolCallId,
105
110
  toolName: request.toolName,
@@ -108,7 +113,23 @@ export async function archiveToolResultAsTransition(services, request) {
108
113
  originalBytes: request.originalBytes,
109
114
  reason: request.reason,
110
115
  ...(request.supersession ? { supersession: request.supersession } : {}),
111
- });
116
+ };
117
+ let placeholder;
118
+ try {
119
+ placeholder = archived.ledger
120
+ ? buildLedgerArchivedToolResultPlaceholder({
121
+ ...common,
122
+ storage: 'ledger',
123
+ sourceProjectionDigest: durableToolResultProjectionDigest(request.sourceProjection),
124
+ ...(request.previousTransitionId
125
+ ? { previousTransitionId: request.previousTransitionId }
126
+ : {}),
127
+ })
128
+ : buildArchivedToolResultPlaceholder({ ...common, artifactId: archived.artifactId });
129
+ }
130
+ catch {
131
+ return undefined;
132
+ }
112
133
  let transition;
113
134
  try {
114
135
  transition = buildModelProjectionTransition({
@@ -129,7 +150,16 @@ export async function archiveToolResultAsTransition(services, request) {
129
150
  : {}),
130
151
  now: services.now(),
131
152
  });
132
- await services.recordTransition(transition);
153
+ if (placeholder.rewriteVersion === 2 &&
154
+ Buffer.byteLength(JSON.stringify(transition)) > 32 * 1024)
155
+ return undefined;
156
+ if (archived.ledger && archived.commitTransition) {
157
+ if (!(await archived.commitTransition(transition, services.recordTransition)))
158
+ return undefined;
159
+ }
160
+ else {
161
+ await services.recordTransition(transition);
162
+ }
133
163
  const winner = await winningTransition(services, transition);
134
164
  if (winner && winner.transitionId !== transition.transitionId) {
135
165
  // The rival won. Show what the ledger says, not what this writer wrote;
@@ -236,7 +266,7 @@ export function collectReachableArchiveArtifactIds(events) {
236
266
  const content = event.content;
237
267
  if (content?.kind !== 'function_response')
238
268
  continue;
239
- if (isArchivedToolResultPlaceholder(content.result)) {
269
+ if (isArchivedToolResultPlaceholder(content.result) && content.result.rewriteVersion === 1) {
240
270
  reachable.add(content.result.artifactId);
241
271
  }
242
272
  }