maka-agent 0.2.0-dev.31.20260913 → 0.2.0-dev.32.20260914

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 (71) hide show
  1. package/dist/pi-transcript.js +3 -4
  2. package/native/runtime-host-windows-task-launcher/prebuilds/win32-x64/maka-runtime-host-task-launcher.exe +0 -0
  3. package/node_modules/@maka/core/dist/agent-graph-schedule.js +15 -4
  4. package/node_modules/@maka/core/dist/executor-id.js +22 -0
  5. package/node_modules/@maka/core/dist/external-session.js +18 -0
  6. package/node_modules/@maka/core/dist/model-call-usage-projection.js +0 -13
  7. package/node_modules/@maka/core/dist/runtime-event.js +19 -3
  8. package/node_modules/@maka/core/dist/session-send-projection.js +6 -3
  9. package/node_modules/@maka/core/dist/session.js +8 -2
  10. package/node_modules/@maka/core/dist/shell-run-result.js +1 -0
  11. package/node_modules/@maka/core/dist/shell-run.js +4 -0
  12. package/node_modules/@maka/core/dist/work-board.js +94 -1
  13. package/node_modules/@maka/core/package.json +1 -0
  14. package/node_modules/@maka/eval/dist/fleet-simulation.js +270 -0
  15. package/node_modules/@maka/eval/dist/fleet-store.js +243 -0
  16. package/node_modules/@maka/eval/dist/fleet-worker.js +125 -0
  17. package/node_modules/@maka/eval/dist/fleet.js +329 -0
  18. package/node_modules/@maka/eval/dist/index.js +3 -0
  19. package/node_modules/@maka/runtime/dist/agent-run.js +2 -17
  20. package/node_modules/@maka/runtime/dist/ai-sdk-compaction.js +6 -2
  21. package/node_modules/@maka/runtime/dist/ai-sdk-message-projection.js +36 -24
  22. package/node_modules/@maka/runtime/dist/ai-sdk-turn.js +257 -330
  23. package/node_modules/@maka/runtime/dist/background-task-health-tool.js +104 -0
  24. package/node_modules/@maka/runtime/dist/history-compaction.js +3 -1
  25. package/node_modules/@maka/runtime/dist/local-web-fetch.js +1 -1
  26. package/node_modules/@maka/runtime/dist/model-adapter.js +62 -53
  27. package/node_modules/@maka/runtime/dist/model-history.js +1 -5
  28. package/node_modules/@maka/runtime/dist/plugin-executor-backend.js +311 -0
  29. package/node_modules/@maka/runtime/dist/plugin-executor-service.js +344 -0
  30. package/node_modules/@maka/runtime/dist/provider-error-classification.js +7 -1
  31. package/node_modules/@maka/runtime/dist/provider-request-telemetry.js +35 -8
  32. package/node_modules/@maka/runtime/dist/runtime-event-backfill.js +7 -1
  33. package/node_modules/@maka/runtime/dist/runtime-event-read-model.js +1 -0
  34. package/node_modules/@maka/runtime/dist/runtime-invocation-route.js +49 -0
  35. package/node_modules/@maka/runtime/dist/runtime-kernel.js +72 -150
  36. package/node_modules/@maka/runtime/dist/runtime-read-model.js +0 -2
  37. package/node_modules/@maka/runtime/dist/session-event-runtime-mapper.js +3 -0
  38. package/node_modules/@maka/runtime/dist/session-manager.js +100 -58
  39. package/node_modules/@maka/runtime/dist/shell-run-manager.js +9 -3
  40. package/node_modules/@maka/runtime/dist/shell-run-tool-result.js +1 -0
  41. package/node_modules/@maka/runtime/dist/stream-graph-schedule-reconcile.js +1 -0
  42. package/node_modules/@maka/runtime/dist/stream-graph-supervisor-tools.js +26 -4
  43. package/node_modules/@maka/runtime/dist/subagent-tools.js +7 -0
  44. package/node_modules/@maka/runtime/dist/tool-runtime.js +45 -466
  45. package/node_modules/@maka/runtime/package.json +3 -0
  46. package/node_modules/@maka/runtime-host/dist/adapter/session-projector.js +7 -2
  47. package/node_modules/@maka/runtime-host/dist/client/session-catalog-summary.js +1 -0
  48. package/node_modules/@maka/runtime-host/dist/protocol/external-session.js +24 -3
  49. package/node_modules/@maka/runtime-host/dist/protocol/index.js +4 -1
  50. package/node_modules/@maka/runtime-host/dist/protocol/plugin-platform.js +42 -5
  51. package/node_modules/@maka/runtime-host/dist/protocol/session-catalog.js +31 -3
  52. package/node_modules/@maka/runtime-host/dist/protocol/session-continuity.js +6 -0
  53. package/node_modules/@maka/runtime-host/dist/server/child-agent-composition.js +1 -0
  54. package/node_modules/@maka/runtime-host/dist/server/execution-artifacts.js +1 -22
  55. package/node_modules/@maka/runtime-host/dist/server/execution-composition.js +54 -8
  56. package/node_modules/@maka/runtime-host/dist/server/external-session-coordinator.js +14 -1
  57. package/node_modules/@maka/runtime-host/dist/server/host-session-availability.js +10 -2
  58. package/node_modules/@maka/runtime-host/dist/server/plugin-platform-coordinator.js +6 -0
  59. package/node_modules/@maka/runtime-host/dist/server/plugin-platform.js +6 -0
  60. package/node_modules/@maka/runtime-host/dist/server/session-catalog-coordinator.js +56 -16
  61. package/node_modules/@maka/runtime-host/dist/server/session-continuity-coordinator.js +4 -3
  62. package/node_modules/@maka/runtime-host/dist/server/session-revision-coordinator.js +4 -0
  63. package/node_modules/@maka/runtime-host/dist/server/web-fetch-tool.js +37 -1
  64. package/node_modules/@maka/storage/dist/claude-code-session-adapter.js +450 -234
  65. package/node_modules/@maka/storage/dist/claude-code-transcript-lineage.js +106 -77
  66. package/node_modules/@maka/storage/dist/legacy-run-header.js +2 -2
  67. package/node_modules/@maka/storage/dist/model-call-usage-sql.js +1 -1
  68. package/node_modules/@maka/storage/dist/session-store.js +12 -2
  69. package/node_modules/@maka/storage/dist/sqlite-long-term-memory-store.js +86 -12
  70. package/node_modules/@maka/storage/dist/work-board-store.js +40 -1
  71. package/package.json +1 -1
@@ -18,7 +18,7 @@
18
18
  */
19
19
  import { MODEL_CALL_ATTEMPT_SCHEMA_VERSION, } from '@maka/core/model-call-attempt';
20
20
  import { preparedPromptComposition } from './request-shape.js';
21
- import { rawFinishReasonString } from './model-protocol.js';
21
+ import { rawFinishReasonString, } from './model-protocol.js';
22
22
  import { providerFailureDiagnostic } from './provider-error-classification.js';
23
23
  import { latestContextProjectionInput } from './latest-context-snapshot.js';
24
24
  import { computeCost } from './telemetry/cost.js';
@@ -147,6 +147,7 @@ export function withProviderStreamTracking(input) {
147
147
  providerId: model.provider,
148
148
  modelId: model.modelId,
149
149
  params,
150
+ ...(input.onAttempt ? { onAttempt: input.onAttempt } : {}),
150
151
  ...(input.abortSignal ? { abortSignal: input.abortSignal } : {}),
151
152
  ...(input.historyCompactRoute ? { historyCompactRoute: input.historyCompactRoute } : {}),
152
153
  ...(input.historyCompactBoundary
@@ -222,12 +223,30 @@ export class ProviderRequestTracker {
222
223
  throwIfAbortedBeforeDispatch(input.abortSignal);
223
224
  let sawOutput = false;
224
225
  const attempt = this.beginAttempt(step, composition, input);
226
+ let evidence = {};
227
+ input.onAttempt?.(async (outcome) => {
228
+ await attempt.finalize(outcome.kind === 'completed'
229
+ ? 'completed'
230
+ : outcome.failure.kind === 'abort'
231
+ ? 'aborted'
232
+ : 'failed', {
233
+ ...evidence,
234
+ ...(outcome.kind === 'completed'
235
+ ? { reason: outcome.finishReason }
236
+ : { failure: outcome.failure }),
237
+ });
238
+ });
239
+ const finalize = async (status, finish) => {
240
+ evidence = { ...evidence, ...finish };
241
+ if (!input.onAttempt)
242
+ await attempt.finalize(status, finish);
243
+ };
225
244
  let result;
226
245
  try {
227
246
  result = await input.doStream();
228
247
  }
229
248
  catch (error) {
230
- await attempt.finalize(abortStatus(input.abortSignal, error), { error });
249
+ await finalize(abortStatus(input.abortSignal, error), { error });
231
250
  throw error;
232
251
  }
233
252
  const reader = result.stream.getReader();
@@ -236,7 +255,7 @@ export class ProviderRequestTracker {
236
255
  try {
237
256
  const next = await reader.read();
238
257
  if (next.done) {
239
- await attempt.finalize(input.abortSignal?.aborted ? 'aborted' : 'interrupted');
258
+ await finalize(input.abortSignal?.aborted ? 'aborted' : 'interrupted');
240
259
  controller.close();
241
260
  return;
242
261
  }
@@ -246,18 +265,18 @@ export class ProviderRequestTracker {
246
265
  attempt.observeOutput();
247
266
  }
248
267
  if (part?.type === 'finish') {
249
- await attempt.finalize(input.abortSignal?.aborted ? 'aborted' : 'completed', {
268
+ await finalize(input.abortSignal?.aborted ? 'aborted' : 'completed', {
250
269
  reason: rawFinishReasonString(part.finishReason),
251
270
  usage: asUsage(part.usage),
252
271
  });
253
272
  }
254
273
  else if (part?.type === 'error') {
255
- await attempt.finalize(input.abortSignal?.aborted ? 'aborted' : sawOutput ? 'interrupted' : 'failed', { error: part.error });
274
+ await finalize(input.abortSignal?.aborted ? 'aborted' : sawOutput ? 'interrupted' : 'failed', { error: part.error });
256
275
  }
257
276
  controller.enqueue(next.value);
258
277
  }
259
278
  catch (error) {
260
- await attempt.finalize(input.abortSignal?.aborted
279
+ await finalize(input.abortSignal?.aborted
261
280
  ? 'aborted'
262
281
  : sawOutput
263
282
  ? 'interrupted'
@@ -270,7 +289,7 @@ export class ProviderRequestTracker {
270
289
  await reader.cancel(reason);
271
290
  }
272
291
  finally {
273
- await attempt.finalize(input.abortSignal?.aborted ? 'aborted' : 'interrupted');
292
+ await finalize(input.abortSignal?.aborted ? 'aborted' : 'interrupted');
274
293
  }
275
294
  },
276
295
  });
@@ -335,7 +354,15 @@ export class ProviderRequestTracker {
335
354
  const completedAt = this.input.now();
336
355
  const usage = strictProviderRequestUsage(finish?.usage);
337
356
  const contextWindow = positiveInteger(this.input.contextWindow);
338
- const failure = finish?.error !== undefined ? providerFailureDiagnostic(finish.error) : undefined;
357
+ const diagnostic = finish?.error !== undefined ? providerFailureDiagnostic(finish.error) : undefined;
358
+ const failure = finish?.failure
359
+ ? {
360
+ ...diagnostic,
361
+ errorClass: finish.failure.kind,
362
+ retryable: finish.failure.retryable,
363
+ ...(finish.failure.code ? { providerCode: finish.failure.code } : {}),
364
+ }
365
+ : diagnostic;
339
366
  const finishReason = finish?.reason;
340
367
  const firstTokenMs = timeToFirstTokenMs;
341
368
  accountingSettlement = accountingSettlement.then(async () => {
@@ -86,7 +86,12 @@ export function backfillRuntimeEventsFromStoredMessages(input) {
86
86
  id: newId(),
87
87
  role: 'model',
88
88
  author: 'agent',
89
- content: { kind: 'text', text: message.text },
89
+ ...(message.interrupted ? { modelVisibility: 'hidden' } : {}),
90
+ content: {
91
+ kind: 'text',
92
+ text: message.text,
93
+ ...(message.interrupted ? { interrupted: true } : {}),
94
+ },
90
95
  actions: { stateDelta: recoveryState(now, message) },
91
96
  refs: { storedMessageId: message.id },
92
97
  });
@@ -96,6 +101,7 @@ export function backfillRuntimeEventsFromStoredMessages(input) {
96
101
  for (const part of parts) {
97
102
  events.push({
98
103
  ...base,
104
+ ...(message.interrupted ? { modelVisibility: 'hidden' } : {}),
99
105
  id: newId(),
100
106
  role: 'model',
101
107
  author: 'agent',
@@ -638,6 +638,7 @@ function projectText(event, state, messages) {
638
638
  turnId: event.turnId,
639
639
  ts: event.ts,
640
640
  text: event.content.text,
641
+ ...(event.content.interrupted ? { interrupted: true } : {}),
641
642
  ...(event.content.providerOptions !== undefined
642
643
  ? { providerOptions: structuredClone(event.content.providerOptions) }
643
644
  : {}),
@@ -0,0 +1,49 @@
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 { isExecutorId } from '@maka/core/executor-id';
20
+ export function runtimeInvocationRouteForHeader(header, providerStateIdentity) {
21
+ if (header.backend === 'plugin-executor' &&
22
+ isExecutorId(header.executorId) &&
23
+ providerStateIdentity) {
24
+ return {
25
+ provenance: 'runtime',
26
+ backendKind: header.backend,
27
+ executorId: header.executorId,
28
+ llmConnectionSlug: header.llmConnectionSlug,
29
+ modelId: header.model,
30
+ providerStateIdentity,
31
+ };
32
+ }
33
+ if (header.backend !== 'plugin-executor' && header.llmConnectionId !== undefined) {
34
+ return {
35
+ provenance: 'runtime',
36
+ backendKind: header.backend,
37
+ llmConnectionId: header.llmConnectionId,
38
+ llmConnectionSlug: header.llmConnectionSlug,
39
+ modelId: header.model,
40
+ ...(providerStateIdentity ? { providerStateIdentity } : {}),
41
+ };
42
+ }
43
+ return {
44
+ provenance: 'unknown',
45
+ backendKind: header.backend,
46
+ llmConnectionSlug: header.llmConnectionSlug,
47
+ modelId: header.model,
48
+ };
49
+ }
@@ -38,6 +38,7 @@ import { RuntimeInteractionFailStopError, RuntimeInteractionInvariantError, bind
38
38
  import { DeliveryAckQueue, isDeliveryAckQueueClosed } from './delivery-ack-queue.js';
39
39
  import { runtimeHandoffPause } from '@maka/core/runtime-handoff';
40
40
  import { preserveHandoffOpening } from './runtime-resume.js';
41
+ import { runtimeInvocationRouteForHeader } from './runtime-invocation-route.js';
41
42
  export class SessionQuiescentMutationBusyError extends Error {
42
43
  sessionIds;
43
44
  name = 'SessionQuiescentMutationBusyError';
@@ -833,9 +834,7 @@ export class RuntimeKernel {
833
834
  }
834
835
  async *runAgentTurn(sessionId, run, execution, options = {}) {
835
836
  const { steering = false, onRunStarted, initialHeader, prepareBackendActivation } = options;
836
- const sessionEvents = new DeliveryAckQueue();
837
837
  const { abortController, release: releaseExecutionAbort } = this.inheritExecutionAbort(execution);
838
- let flowDone = false;
839
838
  const owners = this.createRunOwnerScope(run, execution);
840
839
  let begin;
841
840
  try {
@@ -865,25 +864,15 @@ export class RuntimeKernel {
865
864
  await this.finalizeFailedRunStart(owners, run, execution, error);
866
865
  return;
867
866
  }
868
- const interactionRun = owners.interactionRun;
869
- const messageOwner = owners.messageOwner;
870
- const stopBackend = this.stopBackendFor(begin.backend);
871
- const eventContext = this.runtimeEventMapContext({
867
+ yield* this.streamAgentRun({
872
868
  sessionId,
873
- invocationId: begin.initialRuntimeEvent.invocationId,
874
- runId: run.runId,
875
- turnId: run.turnId,
876
- });
877
- if (run.isStopped())
878
- abortController.abort();
879
- const streamResult = this.runBackendEventStream({
869
+ run,
870
+ owners,
880
871
  backend: begin.backend,
881
- stopBackend,
882
- beforeDispatch: () => this.assertRunCanDispatch(run, begin.backend),
883
- hasCommittedHandoff: () => run.hasCommittedHandoff(),
884
- ...(interactionRun ? { hostedInteraction: interactionRun } : {}),
885
- abortSignal: abortController.signal,
886
- eventContext,
872
+ abortController,
873
+ releaseExecutionAbort,
874
+ requireTerminalWrite: Boolean(this.deps.runtimeEventStore),
875
+ invocationId: begin.initialRuntimeEvent.invocationId,
887
876
  backendInput: {
888
877
  invocationId: begin.initialRuntimeEvent.invocationId,
889
878
  runId: run.runId,
@@ -892,90 +881,10 @@ export class RuntimeKernel {
892
881
  handoffBoundary: (signal, remainingSteps) => run.reachHandoffBoundary(signal, remainingSteps),
893
882
  ...runtimeSteeringInput(owners.messageOwner),
894
883
  },
895
- onSessionEvent: async (sessionEvent, runtimeEvent) => {
896
- this.assertInteractionPublication(interactionRun, sessionEvent);
897
- await run.acceptMappedEvent(sessionEvent, runtimeEvent, {
898
- requireTerminalWrite: Boolean(this.deps.runtimeEventStore),
899
- allowInteractionResume: await interactionResumeAllowed(interactionRun, sessionEvent),
900
- });
901
- this.observeInteractionEvent(sessionId, begin.backend, sessionEvent);
902
- await sessionEvents.push(sessionEvent);
903
- },
904
- onError: async (error) => {
905
- if (!isDeliveryAckQueueClosed(error)) {
906
- await run.recordFailure(error);
907
- sessionEvents.fail(error);
908
- }
909
- },
910
- onFinally: async () => {
911
- flowDone = true;
912
- try {
913
- await owners.finalize();
914
- // Release Runtime access BEFORE the event stream closes. Embedded
915
- // queues still emit their final steering → followup projection here;
916
- // a hosted owner is only sealed, then the Host performs that handoff
917
- // under its Session admission gate. The outer finally remains an
918
- // idempotent backstop for paths that never reach this hook.
919
- if (messageOwner)
920
- owners.releaseMessage();
921
- sessionEvents.close();
922
- }
923
- catch (error) {
924
- sessionEvents.fail(error);
925
- throw error;
926
- }
927
- },
928
- }).then(async (result) => {
929
- if (!flowDone) {
930
- try {
931
- flowDone = true;
932
- await owners.finalize();
933
- owners.releaseMessage();
934
- sessionEvents.close();
935
- }
936
- catch (error) {
937
- sessionEvents.fail(error);
938
- throw error;
939
- }
940
- }
941
- return result;
942
- }, (error) => {
943
- sessionEvents.fail(error);
944
- throw error;
945
884
  });
946
- try {
947
- for await (const event of sessionEvents) {
948
- yield event;
949
- }
950
- await streamResult;
951
- }
952
- finally {
953
- try {
954
- await this.cleanupRunExecution({
955
- run,
956
- stopBackend,
957
- flowDone,
958
- abortController,
959
- sessionEvents,
960
- streamResult,
961
- interactionRun,
962
- finalizeRun: () => owners.finalize(),
963
- releaseOwner: () => {
964
- if (messageOwner)
965
- owners.releaseMessage();
966
- },
967
- });
968
- }
969
- finally {
970
- this.clearInteractionRequestOwners(sessionId, run.turnId);
971
- releaseExecutionAbort();
972
- }
973
- }
974
885
  }
975
886
  async *runAgentContinuation(continuation, admissionRoute, run, execution, messageOwner, options = {}, revalidateSafety, inheritedSandboxBoundaryDenied = false) {
976
- const sessionEvents = new DeliveryAckQueue();
977
887
  const { abortController, release: releaseExecutionAbort } = this.inheritExecutionAbort(execution);
978
- let flowDone = false;
979
888
  const owners = this.createRunOwnerScope(run, execution);
980
889
  let begin;
981
890
  try {
@@ -1014,7 +923,6 @@ export class RuntimeKernel {
1014
923
  await this.finalizeFailedRunStart(owners, run, execution, error);
1015
924
  return;
1016
925
  }
1017
- const interactionRun = owners.interactionRun;
1018
926
  let continuationMetadata;
1019
927
  try {
1020
928
  continuationMetadata = consumeAdmittedRuntimeContinuation({
@@ -1034,20 +942,16 @@ export class RuntimeKernel {
1034
942
  await this.finalizeFailedRunStart(owners, run, execution, error);
1035
943
  return;
1036
944
  }
1037
- const stopBackend = this.stopBackendFor(begin.backend);
1038
- const eventContext = this.runtimeEventMapContext({
945
+ yield* this.streamAgentRun({
1039
946
  sessionId: continuation.sessionId,
1040
- invocationId: continuation.invocationId,
1041
- runId: continuation.runId,
1042
- turnId: continuation.turnId,
1043
- });
1044
- if (run.isStopped())
1045
- abortController.abort();
1046
- let streamFailure;
1047
- const streamResult = this.runBackendEventStream({
947
+ run,
948
+ owners,
1048
949
  backend: begin.backend,
1049
- stopBackend,
1050
- beforeDispatch: () => this.assertRunCanDispatch(run, begin.backend),
950
+ abortController,
951
+ releaseExecutionAbort,
952
+ requireTerminalWrite: true,
953
+ recordUnobservedStreamFailure: true,
954
+ invocationId: continuation.invocationId,
1051
955
  ...(continuation.handoffRootRunId !== undefined
1052
956
  ? {
1053
957
  prepareBeforeDispatch: async () => {
@@ -1060,10 +964,6 @@ export class RuntimeKernel {
1060
964
  },
1061
965
  }
1062
966
  : {}),
1063
- hasCommittedHandoff: () => run.hasCommittedHandoff(),
1064
- ...(interactionRun ? { hostedInteraction: interactionRun } : {}),
1065
- abortSignal: abortController.signal,
1066
- eventContext,
1067
967
  backendInput: {
1068
968
  invocationId: continuation.invocationId,
1069
969
  runId: continuation.runId,
@@ -1090,26 +990,57 @@ export class RuntimeKernel {
1090
990
  : {}),
1091
991
  handoffBoundary: (signal, remainingSteps) => run.reachHandoffBoundary(signal, remainingSteps),
1092
992
  },
993
+ });
994
+ }
995
+ async *streamAgentRun(input) {
996
+ const sessionEvents = new DeliveryAckQueue();
997
+ const interactionRun = input.owners.interactionRun;
998
+ const stopBackend = this.stopBackendFor(input.backend);
999
+ let flowDone = false;
1000
+ let streamFailure;
1001
+ if (input.run.isStopped())
1002
+ input.abortController.abort();
1003
+ const streamResult = this.runBackendEventStream({
1004
+ backend: input.backend,
1005
+ stopBackend,
1006
+ beforeDispatch: () => this.assertRunCanDispatch(input.run, input.backend),
1007
+ ...(input.prepareBeforeDispatch
1008
+ ? { prepareBeforeDispatch: input.prepareBeforeDispatch }
1009
+ : {}),
1010
+ hasCommittedHandoff: () => input.run.hasCommittedHandoff(),
1011
+ ...(interactionRun ? { hostedInteraction: interactionRun } : {}),
1012
+ abortSignal: input.abortController.signal,
1013
+ eventContext: this.runtimeEventMapContext({
1014
+ sessionId: input.sessionId,
1015
+ invocationId: input.invocationId,
1016
+ runId: input.run.runId,
1017
+ turnId: input.run.turnId,
1018
+ }),
1019
+ backendInput: input.backendInput,
1093
1020
  onSessionEvent: async (sessionEvent, runtimeEvent) => {
1094
1021
  this.assertInteractionPublication(interactionRun, sessionEvent);
1095
- await run.acceptMappedEvent(sessionEvent, runtimeEvent, {
1096
- requireTerminalWrite: true,
1022
+ await input.run.acceptMappedEvent(sessionEvent, runtimeEvent, {
1023
+ requireTerminalWrite: input.requireTerminalWrite,
1097
1024
  allowInteractionResume: await interactionResumeAllowed(interactionRun, sessionEvent),
1098
1025
  });
1099
- this.observeInteractionEvent(continuation.sessionId, begin.backend, sessionEvent);
1026
+ this.observeInteractionEvent(input.sessionId, input.backend, sessionEvent);
1100
1027
  await sessionEvents.push(sessionEvent);
1101
1028
  },
1102
1029
  onError: async (error) => {
1103
1030
  if (!isDeliveryAckQueueClosed(error)) {
1104
- await run.recordFailure(error);
1031
+ await input.run.recordFailure(error);
1105
1032
  sessionEvents.fail(error);
1106
1033
  }
1107
1034
  },
1108
1035
  onFinally: async () => {
1109
1036
  flowDone = true;
1110
1037
  try {
1111
- await owners.finalize();
1112
- owners.releaseMessage();
1038
+ await input.owners.finalize();
1039
+ // Release Runtime access before closing the event stream. Embedded
1040
+ // queues publish their final steering projection here; hosted owners
1041
+ // are only sealed, then the Host performs the handoff under its
1042
+ // Session admission gate.
1043
+ input.owners.releaseMessage();
1113
1044
  sessionEvents.close();
1114
1045
  }
1115
1046
  catch (error) {
@@ -1121,8 +1052,8 @@ export class RuntimeKernel {
1121
1052
  if (!flowDone) {
1122
1053
  try {
1123
1054
  flowDone = true;
1124
- await owners.finalize();
1125
- owners.releaseMessage();
1055
+ await input.owners.finalize();
1056
+ input.owners.releaseMessage();
1126
1057
  sessionEvents.close();
1127
1058
  }
1128
1059
  catch (error) {
@@ -1138,29 +1069,30 @@ export class RuntimeKernel {
1138
1069
  throw error;
1139
1070
  });
1140
1071
  try {
1141
- for await (const event of sessionEvents) {
1072
+ for await (const event of sessionEvents)
1142
1073
  yield event;
1143
- }
1144
1074
  await streamResult;
1145
1075
  }
1146
1076
  finally {
1147
1077
  try {
1148
1078
  await this.cleanupRunExecution({
1149
- run,
1079
+ run: input.run,
1150
1080
  stopBackend,
1151
1081
  flowDone,
1152
- abortController,
1082
+ abortController: input.abortController,
1153
1083
  sessionEvents,
1154
1084
  streamResult,
1155
1085
  interactionRun,
1156
- ...(streamFailure !== undefined ? { streamFailure } : {}),
1157
- finalizeRun: () => owners.finalize(),
1158
- releaseOwner: () => owners.releaseMessage(),
1086
+ ...(input.recordUnobservedStreamFailure && streamFailure !== undefined
1087
+ ? { streamFailure }
1088
+ : {}),
1089
+ finalizeRun: () => input.owners.finalize(),
1090
+ releaseOwner: () => input.owners.releaseMessage(),
1159
1091
  });
1160
1092
  }
1161
1093
  finally {
1162
- this.clearInteractionRequestOwners(continuation.sessionId, run.turnId);
1163
- releaseExecutionAbort();
1094
+ this.clearInteractionRequestOwners(input.sessionId, input.run.turnId);
1095
+ input.releaseExecutionAbort();
1164
1096
  }
1165
1097
  }
1166
1098
  }
@@ -1955,6 +1887,12 @@ export class RuntimeKernel {
1955
1887
  if (!header.subagentParent) {
1956
1888
  throw new Error('Subagent runtime snapshot requires a linked child session');
1957
1889
  }
1890
+ if (header.backend === 'plugin-executor') {
1891
+ return {
1892
+ systemPrompt: snapshot.systemPrompt,
1893
+ tools: [],
1894
+ };
1895
+ }
1958
1896
  const snapshotDefinition = {
1959
1897
  id: snapshot.agentId,
1960
1898
  permissionMode: header.permissionMode,
@@ -2318,23 +2256,7 @@ function continuationTargetOpeningForExecution(input) {
2318
2256
  const opening = {
2319
2257
  kind: 'invocation_opened',
2320
2258
  protocol: 'invocation_opened_v1',
2321
- route: sessionHeader.llmConnectionId === undefined
2322
- ? {
2323
- provenance: 'unknown',
2324
- backendKind: sessionHeader.backend,
2325
- llmConnectionSlug: sessionHeader.llmConnectionSlug,
2326
- modelId: sessionHeader.model,
2327
- }
2328
- : {
2329
- provenance: 'runtime',
2330
- backendKind: sessionHeader.backend,
2331
- llmConnectionId: sessionHeader.llmConnectionId,
2332
- llmConnectionSlug: sessionHeader.llmConnectionSlug,
2333
- modelId: sessionHeader.model,
2334
- ...(input.targetProviderStateIdentity
2335
- ? { providerStateIdentity: input.targetProviderStateIdentity }
2336
- : {}),
2337
- },
2259
+ route: runtimeInvocationRouteForHeader(sessionHeader, input.targetProviderStateIdentity),
2338
2260
  configuration: {
2339
2261
  cwd: sessionHeader.cwd,
2340
2262
  permissionMode: sessionHeader.permissionMode,
@@ -19,7 +19,6 @@
19
19
  import { deriveTurnRecords } from '@maka/core/session';
20
20
  import { isSessionInlineInvocation } from '@maka/core/runtime-invocation';
21
21
  import { activePresentationRuntimeEvents, classifyRuntimeEventTerminalFact, isHardRuntimeEventReadModelDiagnostic, projectRuntimeEventsToStoredMessages, projectTranscriptToolResult, } from './runtime-event-read-model.js';
22
- import { buildRuntimeEventModelReplayPlan, } from './model-history.js';
23
22
  const CANONICAL_PERMISSION_READ_CONCURRENCY = 8;
24
23
  export class RuntimeReadModelError extends Error {
25
24
  diagnostics;
@@ -138,7 +137,6 @@ export class RuntimeReadModel {
138
137
  invocations: input.invocations,
139
138
  diagnostics,
140
139
  terminalFacts: input.terminalFacts ?? [],
141
- replayPlan: buildRuntimeEventModelReplayPlan(input.events),
142
140
  };
143
141
  }
144
142
  async readCanonicalPermissionOutcomes(events) {
@@ -135,11 +135,13 @@ function mapBackendSessionEvent(event, ctx, memory) {
135
135
  case 'text_complete':
136
136
  return {
137
137
  ...base,
138
+ ...(event.interrupted ? { modelVisibility: 'hidden' } : {}),
138
139
  role: 'model',
139
140
  author: 'agent',
140
141
  content: {
141
142
  kind: 'text',
142
143
  text: event.text,
144
+ ...(event.interrupted ? { interrupted: true } : {}),
143
145
  ...(event.providerOptions !== undefined
144
146
  ? { providerOptions: structuredClone(event.providerOptions) }
145
147
  : {}),
@@ -159,6 +161,7 @@ function mapBackendSessionEvent(event, ctx, memory) {
159
161
  case 'thinking_complete':
160
162
  return {
161
163
  ...base,
164
+ ...(event.interrupted ? { modelVisibility: 'hidden' } : {}),
162
165
  role: 'model',
163
166
  author: 'agent',
164
167
  content: {