maka-agent 0.2.0-dev.47.20260922 → 0.2.0-dev.48.20260923

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 (92) hide show
  1. package/dist/runtime-host-capability-provider-command.js +25 -6
  2. package/dist/tui-mcp-control.js +37 -24
  3. package/native/runtime-host-windows-task-launcher/prebuilds/win32-x64/maka-runtime-host-task-launcher.exe +0 -0
  4. package/node_modules/@maka/acp-executor-plugin/dist/acp-errors.js +26 -0
  5. package/node_modules/@maka/acp-executor-plugin/dist/acp-filesystem.js +103 -0
  6. package/node_modules/@maka/acp-executor-plugin/dist/acp-process.js +119 -0
  7. package/node_modules/@maka/acp-executor-plugin/dist/acp-projection.js +146 -0
  8. package/node_modules/@maka/acp-executor-plugin/dist/index.js +653 -0
  9. package/node_modules/@maka/acp-executor-plugin/dist/plugin.mjs +24446 -0
  10. package/node_modules/@maka/acp-executor-plugin/package.json +15 -0
  11. package/node_modules/@maka/antigravity-acp-plugin/dist/index.js +88 -0
  12. package/node_modules/@maka/antigravity-acp-plugin/dist/model-presentation.js +53 -0
  13. package/node_modules/@maka/antigravity-acp-plugin/dist/plugin.mjs +115 -0
  14. package/node_modules/@maka/antigravity-acp-plugin/package.json +15 -0
  15. package/node_modules/@maka/core/dist/executor-catalog.js +106 -0
  16. package/node_modules/@maka/core/dist/mcp.js +4 -1
  17. package/node_modules/@maka/core/dist/model-metadata.js +28 -1
  18. package/node_modules/@maka/core/dist/runtime-event-store.js +25 -0
  19. package/node_modules/@maka/core/dist/runtime-invocation.js +5 -0
  20. package/node_modules/@maka/core/dist/runtime-policy/credential-vault-codec.js +6 -0
  21. package/node_modules/@maka/core/dist/runtime-policy/policy-codec.js +21 -0
  22. package/node_modules/@maka/core/dist/session.js +2 -0
  23. package/node_modules/@maka/core/dist/settings.js +1 -0
  24. package/node_modules/@maka/core/dist/tool-ledger-scanner.js +365 -104
  25. package/node_modules/@maka/core/dist/turn-origin.js +14 -0
  26. package/node_modules/@maka/core/package.json +2 -0
  27. package/node_modules/@maka/mcp/dist/credential-coordinator.js +6 -1
  28. package/node_modules/@maka/mcp/dist/index.js +31 -5
  29. package/node_modules/@maka/mcp/dist/oauth.js +54 -6
  30. package/node_modules/@maka/runtime/dist/agent-run-inspect.js +1 -1
  31. package/node_modules/@maka/runtime/dist/conversation-copy.js +56 -1
  32. package/node_modules/@maka/runtime/dist/mcp-tools.js +9 -2
  33. package/node_modules/@maka/runtime/dist/plugin-executor-backend.js +116 -3
  34. package/node_modules/@maka/runtime/dist/plugin-executor-service.js +212 -16
  35. package/node_modules/@maka/runtime/dist/runtime-ledger-repair.js +2 -2
  36. package/node_modules/@maka/runtime/dist/session-event-runtime-mapper.js +3 -0
  37. package/node_modules/@maka/runtime/dist/session-manager.js +170 -125
  38. package/node_modules/@maka/runtime/dist/shell-run-manager.js +3 -0
  39. package/node_modules/@maka/runtime/dist/stream-graph-coordinator.js +29 -4
  40. package/node_modules/@maka/runtime-host/dist/candidate-entry.js +8 -5
  41. package/node_modules/@maka/runtime-host/dist/client/index.js +1 -1
  42. package/node_modules/@maka/runtime-host/dist/client/reconnect-lifecycle.js +8 -1
  43. package/node_modules/@maka/runtime-host/dist/client/session-catalog-summary.js +6 -1
  44. package/node_modules/@maka/runtime-host/dist/composition-identity.js +19 -0
  45. package/node_modules/@maka/runtime-host/dist/protocol/index.js +10 -2
  46. package/node_modules/@maka/runtime-host/dist/protocol/plugin-platform.js +34 -0
  47. package/node_modules/@maka/runtime-host/dist/protocol/session-catalog.js +40 -2
  48. package/node_modules/@maka/runtime-host/dist/server/builtin-external-agent-plugins.js +188 -0
  49. package/node_modules/@maka/runtime-host/dist/server/candidate.js +12 -7
  50. package/node_modules/@maka/runtime-host/dist/server/client-capability-recovery.js +44 -46
  51. package/node_modules/@maka/runtime-host/dist/server/context-coordinator.js +2 -0
  52. package/node_modules/@maka/runtime-host/dist/server/execution-composition-factory.js +1 -1
  53. package/node_modules/@maka/runtime-host/dist/server/execution-composition.js +159 -19
  54. package/node_modules/@maka/runtime-host/dist/server/execution-model-authority.js +3 -0
  55. package/node_modules/@maka/runtime-host/dist/server/extension-bundle.js +4 -0
  56. package/node_modules/@maka/runtime-host/dist/server/host-composition-source.js +47 -0
  57. package/node_modules/@maka/runtime-host/dist/server/host-composition.js +1 -29
  58. package/node_modules/@maka/runtime-host/dist/server/host-kernel.js +2 -9
  59. package/node_modules/@maka/runtime-host/dist/server/hosted-execution-recovery.js +75 -9
  60. package/node_modules/@maka/runtime-host/dist/server/hosted-execution-tool-profile.js +4 -0
  61. package/node_modules/@maka/runtime-host/dist/server/interaction-coordinator.js +45 -0
  62. package/node_modules/@maka/runtime-host/dist/server/jev-routing-model.js +157 -0
  63. package/node_modules/@maka/runtime-host/dist/server/listener-set.js +2 -2
  64. package/node_modules/@maka/runtime-host/dist/server/message-coordinator.js +4 -0
  65. package/node_modules/@maka/runtime-host/dist/server/plugin-platform-coordinator.js +11 -1
  66. package/node_modules/@maka/runtime-host/dist/server/process-lifecycle.js +1 -1
  67. package/node_modules/@maka/runtime-host/dist/server/process-termination-error.js +27 -0
  68. package/node_modules/@maka/runtime-host/dist/server/root-turn-coordinator.js +91 -12
  69. package/node_modules/@maka/runtime-host/dist/server/runtime-policy-coordinator.js +2 -0
  70. package/node_modules/@maka/runtime-host/dist/server/session-catalog-coordinator.js +99 -12
  71. package/node_modules/@maka/runtime-host/dist/server/session-effect-coordinator.js +12 -6
  72. package/node_modules/@maka/runtime-host/dist/server/session-transcript-reader.js +33 -0
  73. package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-coordinator.js +4 -0
  74. package/node_modules/@maka/runtime-host/dist/server/workhub-result-coordinator.js +173 -0
  75. package/node_modules/@maka/runtime-host/dist/server/workhub-result-runtime.js +293 -0
  76. package/node_modules/@maka/runtime-host/package.json +2 -0
  77. package/node_modules/@maka/storage/dist/agent-run-store-contract.js +8 -0
  78. package/node_modules/@maka/storage/dist/execution-stores.js +15 -3
  79. package/node_modules/@maka/storage/dist/mcp-config-store.js +91 -2
  80. package/node_modules/@maka/storage/dist/operational-state-store.js +15 -1
  81. package/node_modules/@maka/storage/dist/plan-authority.js +2 -0
  82. package/node_modules/@maka/storage/dist/plan-store.js +30 -0
  83. package/node_modules/@maka/storage/dist/runtime-event-persistence.js +1 -0
  84. package/node_modules/@maka/storage/dist/runtime-policy/credential-vault-document.js +4 -1
  85. package/node_modules/@maka/storage/dist/runtime-policy/policy-document.js +2 -0
  86. package/node_modules/@maka/storage/dist/session-store-values.js +16 -4
  87. package/node_modules/@maka/storage/dist/shell-run-authority.js +1 -0
  88. package/node_modules/@maka/storage/dist/shell-run-store.js +15 -0
  89. package/node_modules/@maka/storage/dist/sqlite-runtime-schema.js +74 -1
  90. package/node_modules/@maka/storage/dist/sqlite-runtime-store.js +724 -84
  91. package/node_modules/@maka/storage/dist/sqlite-session-metadata-store.js +16 -0
  92. package/package.json +1 -1
@@ -16,12 +16,14 @@
16
16
  * specific language governing permissions and limitations
17
17
  * under the License.
18
18
  */
19
+ import { isExecutorConfiguration, normalizeCatalogEntry, } from '@maka/core/executor-catalog';
19
20
  import { createHash } from 'node:crypto';
20
- import { TOOL_ACTIVITY_KINDS } from '@maka/core/events';
21
+ import { TOOL_ACTIVITY_KINDS, TOOL_OUTPUT_STREAMS } from '@maka/core/events';
21
22
  import { isExecutorId } from '@maka/core/executor-id';
22
23
  import { Service } from './plugin-kernel.js';
23
24
  import { MakaPluginRuntimeError, pluginIdentity, registerPluginContribution, } from './plugin-runtime.js';
24
25
  import { PluginScopeRegistry } from './plugin-scope-registry.js';
26
+ const MAX_EXECUTOR_COMPLETION_TEXT_BYTES = 256 * 1024;
25
27
  class ExecutorRetiredAbort extends Error {
26
28
  constructor(executorId) {
27
29
  super(`Executor was retired: ${executorId}`);
@@ -57,6 +59,16 @@ export class PluginExecutorService extends Service {
57
59
  ...(provider.displayName === undefined ? {} : { displayName: provider.displayName }),
58
60
  capabilities,
59
61
  execute: provider.execute.bind(provider),
62
+ ...(provider.disposeConversation
63
+ ? { disposeConversation: provider.disposeConversation.bind(provider) }
64
+ : {}),
65
+ ...(provider.configureConversation
66
+ ? { configureConversation: provider.configureConversation.bind(provider) }
67
+ : {}),
68
+ ...(provider.discover ? { discover: provider.discover.bind(provider) } : {}),
69
+ ...(provider.inspectConversation
70
+ ? { inspectConversation: provider.inspectConversation.bind(provider) }
71
+ : {}),
60
72
  });
61
73
  const entry = {
62
74
  ...identity,
@@ -99,6 +111,78 @@ export class PluginExecutorService extends Service {
99
111
  capabilities: normalizeCapabilities(provider.capabilities),
100
112
  })));
101
113
  }
114
+ /** Captures registrations before awaiting provider code; retirement cancels and drains probes. */
115
+ async catalog(input, signal = AbortSignal.timeout(35_000)) {
116
+ const scopeSessionId = input.sessionId ?? input.discoverySessionId;
117
+ const entries = scopeSessionId
118
+ ? [...this.registry.visible(scopeSessionId).values()]
119
+ : [...this.registry.entries('profile')];
120
+ const selected = entries.filter((entry) => !entry.retired && (!input.executorId || entry.provider.id === input.executorId));
121
+ if (input.executorId && !selected.length)
122
+ return [
123
+ {
124
+ id: input.executorId,
125
+ displayName: input.executorId,
126
+ readiness: 'unavailable',
127
+ models: [],
128
+ supportsAttachments: false,
129
+ supportsModelChange: false,
130
+ },
131
+ ];
132
+ return await Promise.all(selected.map((entry) => this.withActiveOperation(entry, { signal }, async (combined) => {
133
+ const fallback = {
134
+ id: entry.provider.id,
135
+ displayName: entry.provider.displayName ?? entry.provider.id,
136
+ readiness: 'ready',
137
+ models: [],
138
+ supportsAttachments: false,
139
+ supportsModelChange: false,
140
+ };
141
+ try {
142
+ combined.throwIfAborted();
143
+ const result = input.sessionId
144
+ ? await entry.provider.inspectConversation?.({
145
+ conversationKey: input.sessionId,
146
+ cwd: input.cwd,
147
+ ...(input.configuration ? { configuration: input.configuration } : {}),
148
+ })
149
+ : await entry.provider.discover?.({ cwd: input.cwd, signal: combined });
150
+ combined.throwIfAborted();
151
+ if (!result)
152
+ return fallback;
153
+ return normalizeCatalogEntry(result, entry.provider.id);
154
+ }
155
+ catch {
156
+ return { ...fallback, readiness: 'unavailable' };
157
+ }
158
+ })));
159
+ }
160
+ async configureConversation(sessionId, executorId, input) {
161
+ const entry = this.entry(sessionId, executorId);
162
+ const configure = entry.provider.configureConversation;
163
+ if ([...entry.active].some((execution) => execution.conversationKey === input.conversationKey) ||
164
+ !configure)
165
+ throw new Error('Executor configuration is unavailable or busy');
166
+ if (!isExecutorConfiguration(input.configuration))
167
+ throw new TypeError('Invalid executor configuration');
168
+ await this.withActiveOperation(entry, { conversationKey: input.conversationKey }, async (signal) => {
169
+ await configure(input, AbortSignal.any([signal, AbortSignal.timeout(30_000)]));
170
+ });
171
+ }
172
+ /** Task retirement releases retained provider resources; backend refresh must not. */
173
+ async retireConversation(sessionId) {
174
+ assertSessionId(sessionId);
175
+ const outcomes = await Promise.allSettled([...this.registry.visible(sessionId).values()].map(async (entry) => {
176
+ const running = [...entry.active].filter((active) => active.conversationKey === sessionId);
177
+ for (const active of running)
178
+ active.abort.abort(new Error('Task retired'));
179
+ await Promise.allSettled(running.map((active) => active.settled));
180
+ await entry.provider.disposeConversation?.(sessionId);
181
+ }));
182
+ const failures = outcomes.flatMap((outcome) => outcome.status === 'rejected' ? [outcome.reason] : []);
183
+ if (failures.length)
184
+ throw new AggregateError(failures, 'Executor conversation cleanup failed');
185
+ }
102
186
  identity(sessionId, executorId) {
103
187
  return this.identityForEntry(this.entry(sessionId, executorId));
104
188
  }
@@ -122,22 +206,14 @@ export class PluginExecutorService extends Service {
122
206
  }
123
207
  async executeEntry(entry, request, options) {
124
208
  const normalizedRequest = normalizeRequest(request);
125
- const abort = new AbortController();
126
- const signal = options.signal ? AbortSignal.any([options.signal, abort.signal]) : abort.signal;
127
- let settle;
128
- const settled = new Promise((resolve) => {
129
- settle = resolve;
130
- });
131
- const active = { abort, settled };
132
- entry.active.add(active);
133
- try {
209
+ return await this.withActiveOperation(entry, { conversationKey: normalizedRequest.conversationKey, signal: options.signal }, async (signal) => {
134
210
  if (entry.retired)
135
211
  return cancelledResult(new ExecutorRetiredAbort(entry.provider.id));
136
212
  try {
137
213
  const result = await entry.provider.execute(normalizedRequest, {
138
214
  signal,
139
215
  emit: (event) => {
140
- if (signal.aborted || entry.retired)
216
+ if (entry.retired)
141
217
  return;
142
218
  const normalized = normalizeOutputEvent(event, entry.provider.capabilities);
143
219
  try {
@@ -147,9 +223,29 @@ export class PluginExecutorService extends Service {
147
223
  // A presentation observer must not change external execution.
148
224
  }
149
225
  },
226
+ requestPermission: async (request) => {
227
+ if (signal.aborted || entry.retired)
228
+ return Object.freeze({ outcome: 'cancelled' });
229
+ const normalized = normalizePermissionRequest(request);
230
+ const result = options.onPermissionRequest
231
+ ? await options.onPermissionRequest(normalized)
232
+ : { outcome: 'cancelled' };
233
+ if (signal.aborted || entry.retired)
234
+ return Object.freeze({ outcome: 'cancelled' });
235
+ return normalizePermissionResult(result, normalized);
236
+ },
150
237
  });
151
- if (signal.aborted)
152
- return cancelledResult(signal.reason);
238
+ if (signal.aborted) {
239
+ const cancelled = cancelledResult(signal.reason);
240
+ const normalized = normalizeResult(result);
241
+ return normalized.status === 'cancelled'
242
+ ? {
243
+ ...normalized,
244
+ ...cancelled,
245
+ ...(normalized.reason ? { reason: normalized.reason } : {}),
246
+ }
247
+ : cancelled;
248
+ }
153
249
  return normalizeResult(result);
154
250
  }
155
251
  catch (error) {
@@ -157,6 +253,22 @@ export class PluginExecutorService extends Service {
157
253
  return cancelledResult(signal.reason);
158
254
  throw error;
159
255
  }
256
+ });
257
+ }
258
+ async withActiveOperation(entry, input, run) {
259
+ const abort = new AbortController();
260
+ const signal = input.signal ? AbortSignal.any([input.signal, abort.signal]) : abort.signal;
261
+ let settle;
262
+ const active = {
263
+ abort,
264
+ ...(input.conversationKey ? { conversationKey: input.conversationKey } : {}),
265
+ settled: new Promise((resolve) => {
266
+ settle = resolve;
267
+ }),
268
+ };
269
+ entry.active.add(active);
270
+ try {
271
+ return await run(signal);
160
272
  }
161
273
  finally {
162
274
  entry.active.delete(active);
@@ -213,6 +325,8 @@ function normalizeRequest(request) {
213
325
  if (!value || /[\0\r\n]/u.test(value))
214
326
  throw new TypeError(`Executor ${label} is invalid`);
215
327
  }
328
+ if (request.configuration !== undefined && !isExecutorConfiguration(request.configuration))
329
+ throw new TypeError('Executor configuration is invalid');
216
330
  if (typeof request.text !== 'string')
217
331
  throw new TypeError('Executor request text is invalid');
218
332
  if (request.runId !== undefined && (!request.runId || /[\0\r\n]/u.test(request.runId))) {
@@ -223,6 +337,9 @@ function normalizeRequest(request) {
223
337
  }
224
338
  return Object.freeze({
225
339
  ...request,
340
+ ...(request.configuration
341
+ ? { configuration: Object.freeze({ ...request.configuration }) }
342
+ : {}),
226
343
  ...(request.attachments ? { attachments: Object.freeze([...request.attachments]) } : {}),
227
344
  ...(request.directoryReferences
228
345
  ? { directoryReferences: Object.freeze([...request.directoryReferences]) }
@@ -269,6 +386,18 @@ function normalizeOutputEvent(event, capabilities) {
269
386
  ...(event.activityKind === undefined ? {} : { activityKind: event.activityKind }),
270
387
  });
271
388
  }
389
+ if (event.type === 'tool_output_delta' &&
390
+ capabilities?.toolActivity === true &&
391
+ isSafeEventId(event.toolCallId) &&
392
+ isSafeEventText(event.text) &&
393
+ (event.stream === undefined || TOOL_OUTPUT_STREAMS.some((stream) => stream === event.stream))) {
394
+ return Object.freeze({
395
+ type: event.type,
396
+ toolCallId: event.toolCallId,
397
+ text: event.text,
398
+ ...(event.stream === undefined ? {} : { stream: event.stream }),
399
+ });
400
+ }
272
401
  if (event.type === 'tool_progress' &&
273
402
  capabilities?.toolActivity === true &&
274
403
  isSafeEventId(event.toolCallId) &&
@@ -278,28 +407,54 @@ function normalizeOutputEvent(event, capabilities) {
278
407
  if (event.type === 'tool_result' &&
279
408
  capabilities?.toolActivity === true &&
280
409
  isSafeEventId(event.toolCallId) &&
281
- isSafeEventText(event.text) &&
410
+ isPluginToolResultContent(event.content) &&
282
411
  (event.isError === undefined || typeof event.isError === 'boolean')) {
283
412
  return Object.freeze({
284
413
  type: event.type,
285
414
  toolCallId: event.toolCallId,
286
- text: event.text,
415
+ content: event.content.kind === 'text'
416
+ ? Object.freeze({ kind: 'text', text: event.content.text })
417
+ : Object.freeze({
418
+ kind: 'file_diff',
419
+ paths: Object.freeze([...event.content.paths]),
420
+ diff: event.content.diff,
421
+ }),
287
422
  ...(event.isError === undefined ? {} : { isError: event.isError }),
288
423
  });
289
424
  }
290
425
  throw new TypeError('Executor output event is invalid or undeclared');
291
426
  }
427
+ function isPluginToolResultContent(value) {
428
+ if (!value || typeof value !== 'object')
429
+ return false;
430
+ if (value.kind === 'text')
431
+ return isSafeEventText(value.text);
432
+ return (value.kind === 'file_diff' &&
433
+ Array.isArray(value.paths) &&
434
+ value.paths.length > 0 &&
435
+ value.paths.length <= 64 &&
436
+ value.paths.every((path) => isSafeEventText(path) && path.trim().length > 0) &&
437
+ typeof value.diff === 'string' &&
438
+ value.diff.length <= 1024 * 1024 &&
439
+ !/[\0\r]/u.test(value.diff));
440
+ }
292
441
  function normalizeResult(result) {
293
442
  if (!result || typeof result !== 'object')
294
443
  throw new TypeError('Executor result is invalid');
295
444
  if (result.status === 'completed' && typeof result.text === 'string') {
445
+ if (Buffer.byteLength(result.text, 'utf8') > MAX_EXECUTOR_COMPLETION_TEXT_BYTES)
446
+ throw new TypeError('Executor completion text exceeds the size limit');
296
447
  return Object.freeze({ status: result.status, text: result.text });
297
448
  }
298
449
  if (result.status === 'cancelled' &&
299
- (result.reason === undefined || typeof result.reason === 'string')) {
450
+ (result.reason === undefined || typeof result.reason === 'string') &&
451
+ (result.providerStopReason === undefined || isSafeEventText(result.providerStopReason))) {
300
452
  return Object.freeze({
301
453
  status: result.status,
302
454
  ...(result.reason === undefined ? {} : { reason: result.reason }),
455
+ ...(result.providerStopReason === undefined
456
+ ? {}
457
+ : { providerStopReason: result.providerStopReason }),
303
458
  source: 'provider',
304
459
  });
305
460
  }
@@ -316,6 +471,47 @@ function normalizeResult(result) {
316
471
  }
317
472
  throw new TypeError('Executor result is invalid');
318
473
  }
474
+ function normalizePermissionRequest(request) {
475
+ if (!request ||
476
+ typeof request !== 'object' ||
477
+ (request.kind !== undefined && request.kind !== 'permission' && request.kind !== 'question') ||
478
+ !isSafeEventId(request.toolCallId) ||
479
+ !isSafeEventText(request.title) ||
480
+ !request.title.trim() ||
481
+ !Array.isArray(request.options) ||
482
+ request.options.length === 0 ||
483
+ request.options.length > 64) {
484
+ throw new TypeError('Executor permission request is invalid');
485
+ }
486
+ const seen = new Set();
487
+ const options = request.options.map((option) => {
488
+ if (!option ||
489
+ typeof option !== 'object' ||
490
+ !isSafeEventId(option.optionId) ||
491
+ !isSafeEventText(option.name) ||
492
+ !option.name.trim() ||
493
+ seen.has(option.optionId)) {
494
+ throw new TypeError('Executor permission option is invalid');
495
+ }
496
+ seen.add(option.optionId);
497
+ return Object.freeze({ optionId: option.optionId, name: option.name });
498
+ });
499
+ return Object.freeze({
500
+ ...(request.kind ? { kind: request.kind } : {}),
501
+ toolCallId: request.toolCallId,
502
+ title: request.title,
503
+ options: Object.freeze(options),
504
+ });
505
+ }
506
+ function normalizePermissionResult(result, request) {
507
+ if (result?.outcome === 'cancelled')
508
+ return Object.freeze({ outcome: 'cancelled' });
509
+ if (result?.outcome === 'selected' &&
510
+ request.options.some((option) => option.optionId === result.optionId)) {
511
+ return Object.freeze({ outcome: 'selected', optionId: result.optionId });
512
+ }
513
+ throw new TypeError('Executor permission result is invalid');
514
+ }
319
515
  function providerStateIdentity(identity) {
320
516
  return `sha256:${createHash('sha256')
321
517
  .update(JSON.stringify([
@@ -19,7 +19,7 @@
19
19
  import { createHash } from 'node:crypto';
20
20
  import { deriveTurnRecords, isConversationTextMessage } from '@maka/core/session';
21
21
  import { DEFAULT_TOOL_MODE } from '@maka/core/tool-mode';
22
- import { buildInvocationOpenedEvent, isSessionInlineInvocation, } from '@maka/core/runtime-invocation';
22
+ import { buildInvocationOpenedEvent, isSessionInlineInvocation, TRANSCRIPT_LEDGER_INVOCATION_ID_PREFIX, } from '@maka/core/runtime-invocation';
23
23
  import { backfillRuntimeEventsFromStoredMessages } from './runtime-event-backfill.js';
24
24
  /** How much of a legacy transcript one conversion page holds. */
25
25
  const TRANSCRIPT_CONVERSION_PAGE_MAX_MESSAGES = 256;
@@ -222,7 +222,7 @@ export function isTranscriptLedgerInvocation(invocation) {
222
222
  }
223
223
  function transcriptRunId(sessionId, turnId) {
224
224
  const digest = createHash('sha256').update(sessionId).update('\0').update(turnId).digest('hex');
225
- return `transcript-${digest.slice(0, 48)}`;
225
+ return `${TRANSCRIPT_LEDGER_INVOCATION_ID_PREFIX}${digest.slice(0, 48)}`;
226
226
  }
227
227
  /**
228
228
  * Ids for one run's converted events, numbered in the order the converter
@@ -589,6 +589,9 @@ function completeRuntimeEvent(base, event, memory) {
589
589
  stateDelta.failureClass =
590
590
  memory.failureClass ?? failureClassFromCompleteStopReason(stopReason) ?? 'runtime_error';
591
591
  }
592
+ if (event.providerStopReason !== undefined) {
593
+ stateDelta.providerStopReason = event.providerStopReason;
594
+ }
592
595
  if (event.contextCompactionOutcome !== undefined) {
593
596
  stateDelta.contextCompactionOutcome = event.contextCompactionOutcome;
594
597
  }