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.
- package/dist/runtime-host-capability-provider-command.js +25 -6
- package/dist/tui-mcp-control.js +37 -24
- package/native/runtime-host-windows-task-launcher/prebuilds/win32-x64/maka-runtime-host-task-launcher.exe +0 -0
- package/node_modules/@maka/acp-executor-plugin/dist/acp-errors.js +26 -0
- package/node_modules/@maka/acp-executor-plugin/dist/acp-filesystem.js +103 -0
- package/node_modules/@maka/acp-executor-plugin/dist/acp-process.js +119 -0
- package/node_modules/@maka/acp-executor-plugin/dist/acp-projection.js +146 -0
- package/node_modules/@maka/acp-executor-plugin/dist/index.js +653 -0
- package/node_modules/@maka/acp-executor-plugin/dist/plugin.mjs +24446 -0
- package/node_modules/@maka/acp-executor-plugin/package.json +15 -0
- package/node_modules/@maka/antigravity-acp-plugin/dist/index.js +88 -0
- package/node_modules/@maka/antigravity-acp-plugin/dist/model-presentation.js +53 -0
- package/node_modules/@maka/antigravity-acp-plugin/dist/plugin.mjs +115 -0
- package/node_modules/@maka/antigravity-acp-plugin/package.json +15 -0
- package/node_modules/@maka/core/dist/executor-catalog.js +106 -0
- package/node_modules/@maka/core/dist/mcp.js +4 -1
- package/node_modules/@maka/core/dist/model-metadata.js +28 -1
- package/node_modules/@maka/core/dist/runtime-event-store.js +25 -0
- package/node_modules/@maka/core/dist/runtime-invocation.js +5 -0
- package/node_modules/@maka/core/dist/runtime-policy/credential-vault-codec.js +6 -0
- package/node_modules/@maka/core/dist/runtime-policy/policy-codec.js +21 -0
- package/node_modules/@maka/core/dist/session.js +2 -0
- package/node_modules/@maka/core/dist/settings.js +1 -0
- package/node_modules/@maka/core/dist/tool-ledger-scanner.js +365 -104
- package/node_modules/@maka/core/dist/turn-origin.js +14 -0
- package/node_modules/@maka/core/package.json +2 -0
- package/node_modules/@maka/mcp/dist/credential-coordinator.js +6 -1
- package/node_modules/@maka/mcp/dist/index.js +31 -5
- package/node_modules/@maka/mcp/dist/oauth.js +54 -6
- package/node_modules/@maka/runtime/dist/agent-run-inspect.js +1 -1
- package/node_modules/@maka/runtime/dist/conversation-copy.js +56 -1
- package/node_modules/@maka/runtime/dist/mcp-tools.js +9 -2
- package/node_modules/@maka/runtime/dist/plugin-executor-backend.js +116 -3
- package/node_modules/@maka/runtime/dist/plugin-executor-service.js +212 -16
- package/node_modules/@maka/runtime/dist/runtime-ledger-repair.js +2 -2
- package/node_modules/@maka/runtime/dist/session-event-runtime-mapper.js +3 -0
- package/node_modules/@maka/runtime/dist/session-manager.js +170 -125
- package/node_modules/@maka/runtime/dist/shell-run-manager.js +3 -0
- package/node_modules/@maka/runtime/dist/stream-graph-coordinator.js +29 -4
- package/node_modules/@maka/runtime-host/dist/candidate-entry.js +8 -5
- package/node_modules/@maka/runtime-host/dist/client/index.js +1 -1
- package/node_modules/@maka/runtime-host/dist/client/reconnect-lifecycle.js +8 -1
- package/node_modules/@maka/runtime-host/dist/client/session-catalog-summary.js +6 -1
- package/node_modules/@maka/runtime-host/dist/composition-identity.js +19 -0
- package/node_modules/@maka/runtime-host/dist/protocol/index.js +10 -2
- package/node_modules/@maka/runtime-host/dist/protocol/plugin-platform.js +34 -0
- package/node_modules/@maka/runtime-host/dist/protocol/session-catalog.js +40 -2
- package/node_modules/@maka/runtime-host/dist/server/builtin-external-agent-plugins.js +188 -0
- package/node_modules/@maka/runtime-host/dist/server/candidate.js +12 -7
- package/node_modules/@maka/runtime-host/dist/server/client-capability-recovery.js +44 -46
- package/node_modules/@maka/runtime-host/dist/server/context-coordinator.js +2 -0
- package/node_modules/@maka/runtime-host/dist/server/execution-composition-factory.js +1 -1
- package/node_modules/@maka/runtime-host/dist/server/execution-composition.js +159 -19
- package/node_modules/@maka/runtime-host/dist/server/execution-model-authority.js +3 -0
- package/node_modules/@maka/runtime-host/dist/server/extension-bundle.js +4 -0
- package/node_modules/@maka/runtime-host/dist/server/host-composition-source.js +47 -0
- package/node_modules/@maka/runtime-host/dist/server/host-composition.js +1 -29
- package/node_modules/@maka/runtime-host/dist/server/host-kernel.js +2 -9
- package/node_modules/@maka/runtime-host/dist/server/hosted-execution-recovery.js +75 -9
- package/node_modules/@maka/runtime-host/dist/server/hosted-execution-tool-profile.js +4 -0
- package/node_modules/@maka/runtime-host/dist/server/interaction-coordinator.js +45 -0
- package/node_modules/@maka/runtime-host/dist/server/jev-routing-model.js +157 -0
- package/node_modules/@maka/runtime-host/dist/server/listener-set.js +2 -2
- package/node_modules/@maka/runtime-host/dist/server/message-coordinator.js +4 -0
- package/node_modules/@maka/runtime-host/dist/server/plugin-platform-coordinator.js +11 -1
- package/node_modules/@maka/runtime-host/dist/server/process-lifecycle.js +1 -1
- package/node_modules/@maka/runtime-host/dist/server/process-termination-error.js +27 -0
- package/node_modules/@maka/runtime-host/dist/server/root-turn-coordinator.js +91 -12
- package/node_modules/@maka/runtime-host/dist/server/runtime-policy-coordinator.js +2 -0
- package/node_modules/@maka/runtime-host/dist/server/session-catalog-coordinator.js +99 -12
- package/node_modules/@maka/runtime-host/dist/server/session-effect-coordinator.js +12 -6
- package/node_modules/@maka/runtime-host/dist/server/session-transcript-reader.js +33 -0
- package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-coordinator.js +4 -0
- package/node_modules/@maka/runtime-host/dist/server/workhub-result-coordinator.js +173 -0
- package/node_modules/@maka/runtime-host/dist/server/workhub-result-runtime.js +293 -0
- package/node_modules/@maka/runtime-host/package.json +2 -0
- package/node_modules/@maka/storage/dist/agent-run-store-contract.js +8 -0
- package/node_modules/@maka/storage/dist/execution-stores.js +15 -3
- package/node_modules/@maka/storage/dist/mcp-config-store.js +91 -2
- package/node_modules/@maka/storage/dist/operational-state-store.js +15 -1
- package/node_modules/@maka/storage/dist/plan-authority.js +2 -0
- package/node_modules/@maka/storage/dist/plan-store.js +30 -0
- package/node_modules/@maka/storage/dist/runtime-event-persistence.js +1 -0
- package/node_modules/@maka/storage/dist/runtime-policy/credential-vault-document.js +4 -1
- package/node_modules/@maka/storage/dist/runtime-policy/policy-document.js +2 -0
- package/node_modules/@maka/storage/dist/session-store-values.js +16 -4
- package/node_modules/@maka/storage/dist/shell-run-authority.js +1 -0
- package/node_modules/@maka/storage/dist/shell-run-store.js +15 -0
- package/node_modules/@maka/storage/dist/sqlite-runtime-schema.js +74 -1
- package/node_modules/@maka/storage/dist/sqlite-runtime-store.js +724 -84
- package/node_modules/@maka/storage/dist/sqlite-session-metadata-store.js +16 -0
- 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
|
-
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
}
|