maka-agent 0.2.0-dev.46.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/DISCLAIMER-WIP +6 -1
- package/README.md +6 -1
- package/dist/acp/maka-acp-agent.js +1 -1
- package/dist/acp/session-mcp.js +212 -0
- package/dist/acp/session-registry.js +52 -8
- package/dist/acp/stdio-server.js +3 -0
- package/dist/cli-core.js +1 -1
- package/dist/mcp-capability-provider.js +6 -1
- package/dist/mcp-capability-publication.js +139 -0
- package/dist/pi-tui-layout.js +46 -17
- package/dist/pi-tui-pickers.js +25 -14
- package/dist/pi-tui-runner.js +24 -15
- package/dist/runtime-host-capability-provider-command.js +25 -6
- package/dist/runtime-host-service-manager.js +26 -2
- package/dist/tui-context-refresh.js +15 -26
- package/dist/tui-mcp-control.js +66 -112
- 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/client-capability-grant.js +2 -2
- 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/model-thinking.js +36 -1
- package/node_modules/@maka/core/dist/provider-registry.js +0 -1
- package/node_modules/@maka/core/dist/refresh-read-coordinator.js +62 -0
- 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/connection-catalog-codec.js +4 -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 +19 -1
- package/node_modules/@maka/core/dist/settings.js +3 -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 +3 -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/ai-sdk-message-projection.js +15 -60
- package/node_modules/@maka/runtime/dist/ai-sdk-turn.js +18 -0
- package/node_modules/@maka/runtime/dist/apply-patch-profile.js +64 -14
- package/node_modules/@maka/runtime/dist/builtin-tools.js +3 -2
- package/node_modules/@maka/runtime/dist/codex-v4a-patch.js +18 -0
- 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/model-adapter.js +80 -3
- package/node_modules/@maka/runtime/dist/model-runtime.js +6 -0
- package/node_modules/@maka/runtime/dist/openai-apply-patch.js +5 -0
- package/node_modules/@maka/runtime/dist/plugin-executor-backend.js +122 -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 +184 -126
- 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/capability-provider-service.js +2 -0
- package/node_modules/@maka/runtime-host/dist/client/client-capability-channel.js +59 -20
- package/node_modules/@maka/runtime-host/dist/client/connection.js +6 -4
- 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/reconnecting-connection.js +4 -4
- 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/client-capability.js +20 -3
- package/node_modules/@maka/runtime-host/dist/protocol/external-session.js +8 -5
- package/node_modules/@maka/runtime-host/dist/protocol/index.js +20 -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 +75 -5
- package/node_modules/@maka/runtime-host/dist/protocol/workhub-coordination.js +1 -5
- 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-coordinator.js +234 -70
- package/node_modules/@maka/runtime-host/dist/server/client-capability-invocation-broker.js +14 -8
- 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 +188 -21
- package/node_modules/@maka/runtime-host/dist/server/execution-model-authority.js +6 -0
- package/node_modules/@maka/runtime-host/dist/server/extension-bundle.js +4 -0
- package/node_modules/@maka/runtime-host/dist/server/external-session-coordinator.js +29 -7
- 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 +5 -1
- 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-bundle-coordinator.js +4 -1
- package/node_modules/@maka/runtime-host/dist/server/session-catalog-coordinator.js +128 -13
- package/node_modules/@maka/runtime-host/dist/server/session-effect-coordinator.js +12 -6
- package/node_modules/@maka/runtime-host/dist/server/session-retirement-coordinator.js +2 -2
- 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,9 +16,10 @@
|
|
|
16
16
|
* specific language governing permissions and limitations
|
|
17
17
|
* under the License.
|
|
18
18
|
*/
|
|
19
|
+
import { watch } from 'node:fs';
|
|
19
20
|
import { readFile } from 'node:fs/promises';
|
|
20
|
-
import { dirname, join } from 'node:path';
|
|
21
|
-
import { MCP_CONFIG_VERSION, createDefaultMcpConfig, isNonLoopbackCleartextHttp, } from '@maka/core/mcp';
|
|
21
|
+
import { basename, dirname, join } from 'node:path';
|
|
22
|
+
import { MCP_CONFIG_VERSION, createDefaultMcpConfig, isNonLoopbackCleartextHttp, mcpConfigChangeRetiresCredentials, } from '@maka/core/mcp';
|
|
22
23
|
import { writeAtomicFile } from './atomic-file-write.js';
|
|
23
24
|
import { withProcessLifetimeFileUpdateLock } from './process-lifetime-file-update-lock.js';
|
|
24
25
|
import { hardenDirectory } from './stable-storage.js';
|
|
@@ -30,6 +31,9 @@ const MAX_ID_LENGTH = 128;
|
|
|
30
31
|
const MAX_STRING_LENGTH = 8_192;
|
|
31
32
|
const MAX_CONFIG_BYTES = 1_048_576;
|
|
32
33
|
const FORBIDDEN_KEYS = new Set(['__proto__', 'prototype', 'constructor']);
|
|
34
|
+
// An atomic replace is a temp write plus a rename; one settle window turns
|
|
35
|
+
// that burst into one notification.
|
|
36
|
+
const CHANGE_SETTLE_MS = 150;
|
|
33
37
|
export class McpConfigSourceError extends Error {
|
|
34
38
|
reason;
|
|
35
39
|
version;
|
|
@@ -54,6 +58,64 @@ export class McpServerExistsError extends Error {
|
|
|
54
58
|
export function createMcpConfigStore(workspaceRoot) {
|
|
55
59
|
return new FileMcpConfigStore(join(workspaceRoot, 'mcp.json'));
|
|
56
60
|
}
|
|
61
|
+
/** Watches the directory, not the file: an atomic replace renames a new
|
|
62
|
+
* inode over the old one, which ends a watch on the file itself. */
|
|
63
|
+
export function subscribeMcpConfigFileChanges(path, listener) {
|
|
64
|
+
const name = basename(path);
|
|
65
|
+
let timer;
|
|
66
|
+
let watcher;
|
|
67
|
+
const settle = () => {
|
|
68
|
+
clearTimeout(timer);
|
|
69
|
+
timer = setTimeout(() => listener(), CHANGE_SETTLE_MS);
|
|
70
|
+
};
|
|
71
|
+
try {
|
|
72
|
+
watcher = watch(dirname(path), { persistent: false }, (_event, filename) => {
|
|
73
|
+
if (filename === null || filename.toString() === name)
|
|
74
|
+
settle();
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
queueMicrotask(() => listener(error));
|
|
79
|
+
return () => { };
|
|
80
|
+
}
|
|
81
|
+
settle();
|
|
82
|
+
const stop = () => {
|
|
83
|
+
clearTimeout(timer);
|
|
84
|
+
watcher.close();
|
|
85
|
+
};
|
|
86
|
+
watcher.on('error', (error) => {
|
|
87
|
+
stop();
|
|
88
|
+
listener(error);
|
|
89
|
+
});
|
|
90
|
+
return stop;
|
|
91
|
+
}
|
|
92
|
+
export class McpConfigurationValidationError extends Error {
|
|
93
|
+
constructor(cause) {
|
|
94
|
+
super(cause instanceof Error ? cause.message : 'Invalid MCP configuration', { cause });
|
|
95
|
+
this.name = 'McpConfigurationValidationError';
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/** Validate before retiring credentials, and retire before publishing the
|
|
99
|
+
* replacement. Both effects run under the config file's cross-process lock. */
|
|
100
|
+
export function updateMcpConfiguration(store, prepare, retireCredentials) {
|
|
101
|
+
return store.transform(async (current) => {
|
|
102
|
+
const proposed = prepare(current);
|
|
103
|
+
let next;
|
|
104
|
+
try {
|
|
105
|
+
next = normalizeMcpConfig(proposed);
|
|
106
|
+
assertMcpEndpointPolicyOnChanges(current, next);
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
throw new McpConfigurationValidationError(error);
|
|
110
|
+
}
|
|
111
|
+
for (const [serverId, previous] of Object.entries(current.mcpServers)) {
|
|
112
|
+
if (mcpConfigChangeRetiresCredentials(previous, next.mcpServers[serverId])) {
|
|
113
|
+
await retireCredentials(serverId, previous);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return next;
|
|
117
|
+
});
|
|
118
|
+
}
|
|
57
119
|
export function normalizeMcpConfig(value) {
|
|
58
120
|
if (!isRecord(value))
|
|
59
121
|
throw new Error('MCP config must be an object');
|
|
@@ -114,6 +176,21 @@ class FileMcpConfigStore {
|
|
|
114
176
|
return this.withUpdateLock(() => this.readOrCreate());
|
|
115
177
|
}
|
|
116
178
|
}
|
|
179
|
+
subscribeChanges(listener) {
|
|
180
|
+
let stop;
|
|
181
|
+
let stopped = false;
|
|
182
|
+
void this.ensureDirectory().then(() => {
|
|
183
|
+
if (!stopped)
|
|
184
|
+
stop = subscribeMcpConfigFileChanges(this.path, listener);
|
|
185
|
+
}, (error) => {
|
|
186
|
+
if (!stopped)
|
|
187
|
+
listener(error);
|
|
188
|
+
});
|
|
189
|
+
return () => {
|
|
190
|
+
stopped = true;
|
|
191
|
+
stop?.();
|
|
192
|
+
};
|
|
193
|
+
}
|
|
117
194
|
async transform(apply) {
|
|
118
195
|
return this.withUpdateLock(async () => {
|
|
119
196
|
const current = await this.readOrCreate();
|
|
@@ -280,6 +357,18 @@ function normalizeOAuth(value, serverId) {
|
|
|
280
357
|
if (!isRecord(value))
|
|
281
358
|
throw new Error(`${serverId}.oauth must be an object`);
|
|
282
359
|
const result = {};
|
|
360
|
+
if (value.issuer !== undefined) {
|
|
361
|
+
const issuer = nonEmptyString(value.issuer, `${serverId}.oauth.issuer`);
|
|
362
|
+
const parsed = new URL(issuer);
|
|
363
|
+
if (!['https:', 'http:'].includes(parsed.protocol) ||
|
|
364
|
+
parsed.username ||
|
|
365
|
+
parsed.password ||
|
|
366
|
+
parsed.search ||
|
|
367
|
+
parsed.hash) {
|
|
368
|
+
throw new Error(`${serverId}.oauth.issuer must be an HTTP(S) issuer URL without credentials, query or fragment`);
|
|
369
|
+
}
|
|
370
|
+
result.issuer = issuer;
|
|
371
|
+
}
|
|
283
372
|
if (value.clientId !== undefined) {
|
|
284
373
|
result.clientId = nonEmptyString(value.clientId, `${serverId}.oauth.clientId`);
|
|
285
374
|
}
|
|
@@ -138,6 +138,8 @@ class OperationalStateDatabaseOwner {
|
|
|
138
138
|
references = 0;
|
|
139
139
|
closed = false;
|
|
140
140
|
transactionDepth = 0;
|
|
141
|
+
transactionWrote = false;
|
|
142
|
+
writeViewRevisionValue = 0;
|
|
141
143
|
settledCallbacks = [];
|
|
142
144
|
constructor(databasePath, options) {
|
|
143
145
|
this.databasePath = databasePath;
|
|
@@ -173,6 +175,7 @@ class OperationalStateDatabaseOwner {
|
|
|
173
175
|
return {
|
|
174
176
|
database: this.database,
|
|
175
177
|
databasePath: this.databasePath,
|
|
178
|
+
writeViewRevision: () => this.writeViewRevisionValue,
|
|
176
179
|
transaction: (mode, operation) => this.transaction(mode, operation),
|
|
177
180
|
onTransactionSettled: (callback) => {
|
|
178
181
|
if (this.transactionDepth === 0)
|
|
@@ -220,22 +223,33 @@ class OperationalStateDatabaseOwner {
|
|
|
220
223
|
transaction(mode, operation) {
|
|
221
224
|
if (this.closed)
|
|
222
225
|
throw new Error('Operational state database is closed');
|
|
223
|
-
if (this.transactionDepth > 0)
|
|
226
|
+
if (this.transactionDepth > 0) {
|
|
227
|
+
if (mode === 'write')
|
|
228
|
+
this.transactionWrote = true;
|
|
224
229
|
return operation();
|
|
230
|
+
}
|
|
225
231
|
this.database.exec(mode === 'write' ? 'BEGIN IMMEDIATE' : 'BEGIN');
|
|
226
232
|
this.transactionDepth += 1;
|
|
233
|
+
this.transactionWrote = mode === 'write';
|
|
227
234
|
let result;
|
|
228
235
|
try {
|
|
229
236
|
result = operation();
|
|
230
237
|
this.database.exec('COMMIT');
|
|
231
238
|
}
|
|
232
239
|
catch (error) {
|
|
240
|
+
const transactionWrote = this.transactionWrote;
|
|
233
241
|
rollback(this.database);
|
|
234
242
|
this.transactionDepth -= 1;
|
|
243
|
+
this.transactionWrote = false;
|
|
244
|
+
if (transactionWrote)
|
|
245
|
+
this.writeViewRevisionValue += 1;
|
|
235
246
|
this.settle(false);
|
|
236
247
|
throw error;
|
|
237
248
|
}
|
|
238
249
|
this.transactionDepth -= 1;
|
|
250
|
+
if (this.transactionWrote)
|
|
251
|
+
this.writeViewRevisionValue += 1;
|
|
252
|
+
this.transactionWrote = false;
|
|
239
253
|
this.settle(true);
|
|
240
254
|
return result;
|
|
241
255
|
}
|
|
@@ -53,6 +53,7 @@ export function observeInteractivePlanStoreWriter(source, onChanged, onPublicati
|
|
|
53
53
|
access: writer.access,
|
|
54
54
|
[writerBrand]: true,
|
|
55
55
|
readState: (sessionId) => writer.readState(sessionId),
|
|
56
|
+
listPlanRecoverySessionIds: () => writer.listPlanRecoverySessionIds(),
|
|
56
57
|
readOperationReceipt: (sessionId, operationId, operationInput) => writer.readOperationReceipt(sessionId, operationId, operationInput),
|
|
57
58
|
submitProposal: (input) => publish(input.sessionId, () => writer.submitProposal(input)),
|
|
58
59
|
requestRevision: (input) => publish(input.sessionId, () => writer.requestRevision(input)),
|
|
@@ -136,6 +137,7 @@ function createWriterFacade(lease, store) {
|
|
|
136
137
|
access: 'write',
|
|
137
138
|
[writerBrand]: true,
|
|
138
139
|
readState: (sessionId) => run(() => store.readState(sessionId)),
|
|
140
|
+
listPlanRecoverySessionIds: () => run(() => store.listPlanRecoverySessionIds()),
|
|
139
141
|
readOperationReceipt: (sessionId, operationId, operationInput) => run(() => store.readOperationReceipt(sessionId, operationId, structuredClone(operationInput))),
|
|
140
142
|
submitProposal: (input) => run(() => store.submitProposal(cloneSubmit(input))),
|
|
141
143
|
requestRevision: (input) => run(() => store.requestRevision(cloneInput(input))),
|
|
@@ -43,6 +43,36 @@ class SqlitePlanStoreImpl {
|
|
|
43
43
|
async readState(sessionId) {
|
|
44
44
|
return (await this.readLedger(sessionId)).state;
|
|
45
45
|
}
|
|
46
|
+
async listPlanRecoverySessionIds() {
|
|
47
|
+
const rows = this.#lease.database
|
|
48
|
+
.prepare(`
|
|
49
|
+
WITH lifecycle AS (
|
|
50
|
+
SELECT
|
|
51
|
+
session_id,
|
|
52
|
+
json_extract(record_json, '$.type') AS event_type,
|
|
53
|
+
ROW_NUMBER() OVER (PARTITION BY session_id ORDER BY sequence DESC) AS position
|
|
54
|
+
FROM workflow_plan_events
|
|
55
|
+
WHERE json_extract(record_json, '$.type') IN (
|
|
56
|
+
'plan_approved',
|
|
57
|
+
'plan_execution_completed',
|
|
58
|
+
'plan_execution_cancelled',
|
|
59
|
+
'plan_execution_interrupted',
|
|
60
|
+
'plan_execution_resumed'
|
|
61
|
+
)
|
|
62
|
+
)
|
|
63
|
+
SELECT session_id
|
|
64
|
+
FROM lifecycle
|
|
65
|
+
WHERE position = 1
|
|
66
|
+
AND event_type IN ('plan_approved', 'plan_execution_resumed')
|
|
67
|
+
ORDER BY session_id
|
|
68
|
+
`)
|
|
69
|
+
.all();
|
|
70
|
+
return rows.map((row) => {
|
|
71
|
+
if (typeof row.session_id !== 'string')
|
|
72
|
+
throw new Error('Invalid SQLite Plan row');
|
|
73
|
+
return row.session_id;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
46
76
|
async readOperationReceipt(sessionId, operationId, operationInput) {
|
|
47
77
|
assertSafeId(sessionId);
|
|
48
78
|
assertSafeId(operationId);
|
|
@@ -40,6 +40,7 @@ export async function openRuntimeEventReadPersistence(input) {
|
|
|
40
40
|
kind: 'sqlite',
|
|
41
41
|
runtimeEventStore: Object.freeze({
|
|
42
42
|
listSessionInvocations: (sessionId) => store.listSessionInvocations(sessionId),
|
|
43
|
+
listInvocationRecoveryInventory: (sessionIds) => store.listInvocationRecoveryInventory(sessionIds),
|
|
43
44
|
readRunInvocation: (sessionId, runId) => store.readRunInvocation(sessionId, runId),
|
|
44
45
|
listSessionInvocationsBounded: (sessionId, limit) => store.listSessionInvocationsBounded(sessionId, limit),
|
|
45
46
|
listSessionInvocationsPage: (sessionId, input) => store.listSessionInvocationsPage(sessionId, input),
|
|
@@ -237,7 +237,8 @@ function sameLocator(left, right) {
|
|
|
237
237
|
if (left.scope === 'web_search' && right.scope === 'web_search') {
|
|
238
238
|
return left.provider === right.provider;
|
|
239
239
|
}
|
|
240
|
-
return left.scope === 'network_proxy' && right.scope === 'network_proxy'
|
|
240
|
+
return ((left.scope === 'network_proxy' && right.scope === 'network_proxy') ||
|
|
241
|
+
(left.scope === 'jev' && right.scope === 'jev'));
|
|
241
242
|
}
|
|
242
243
|
function locatorKey(locator) {
|
|
243
244
|
switch (locator.scope) {
|
|
@@ -245,6 +246,8 @@ function locatorKey(locator) {
|
|
|
245
246
|
return `connection:${locator.connectionId}:${locator.kind}`;
|
|
246
247
|
case 'web_search':
|
|
247
248
|
return `web_search:${locator.provider}:api_key`;
|
|
249
|
+
case 'jev':
|
|
250
|
+
return 'jev:api_key';
|
|
248
251
|
case 'network_proxy':
|
|
249
252
|
return 'network_proxy:password';
|
|
250
253
|
}
|
|
@@ -84,6 +84,8 @@ export function policySnapshot(document) {
|
|
|
84
84
|
}
|
|
85
85
|
function applyMutation(policy, operation) {
|
|
86
86
|
switch (operation.kind) {
|
|
87
|
+
case 'set_jev':
|
|
88
|
+
return { ...policy, jev: operation.value };
|
|
87
89
|
case 'set_network_proxy':
|
|
88
90
|
return { ...policy, networkProxy: operation.value };
|
|
89
91
|
case 'set_personalization':
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* specific language governing permissions and limitations
|
|
17
17
|
* under the License.
|
|
18
18
|
*/
|
|
19
|
+
import { isExecutorConfiguration } from '@maka/core/executor-catalog';
|
|
19
20
|
import { randomUUID } from 'node:crypto';
|
|
20
21
|
import { DEFAULT_SESSION_NAME, normalizeUserSessionName } from '@maka/core/session-name';
|
|
21
22
|
import { isExecutorId } from '@maka/core/executor-id';
|
|
@@ -72,7 +73,12 @@ export function buildSessionHeader(workspaceRoot, input, sessionId = randomUUID(
|
|
|
72
73
|
...(input.revisionState ? { revisionState: input.revisionState } : {}),
|
|
73
74
|
hasUnread: false,
|
|
74
75
|
backend: input.executorId ? 'plugin-executor' : 'ai-sdk',
|
|
75
|
-
...(input.executorId
|
|
76
|
+
...(input.executorId
|
|
77
|
+
? {
|
|
78
|
+
executorId: input.executorId,
|
|
79
|
+
...(input.executorConfig ? { executorConfig: input.executorConfig } : {}),
|
|
80
|
+
}
|
|
81
|
+
: {}),
|
|
76
82
|
...(input.llmConnectionId === undefined ? {} : { llmConnectionId: input.llmConnectionId }),
|
|
77
83
|
llmConnectionSlug: input.llmConnectionSlug,
|
|
78
84
|
// A subagent Session's route is chosen by the spawn that created it and is
|
|
@@ -273,9 +279,10 @@ function isPersistedBackendKind(value) {
|
|
|
273
279
|
}
|
|
274
280
|
function isValidExecutorSelection(header) {
|
|
275
281
|
if (header.backend === 'plugin-executor') {
|
|
276
|
-
return isExecutorId(header.executorId)
|
|
282
|
+
return (isExecutorId(header.executorId) &&
|
|
283
|
+
(header.executorConfig === undefined || isExecutorConfiguration(header.executorConfig)));
|
|
277
284
|
}
|
|
278
|
-
return header.executorId === undefined;
|
|
285
|
+
return header.executorId === undefined && header.executorConfig === undefined;
|
|
279
286
|
}
|
|
280
287
|
function isFiniteNumber(value) {
|
|
281
288
|
return typeof value === 'number' && Number.isFinite(value);
|
|
@@ -314,7 +321,12 @@ export function toSummary(header) {
|
|
|
314
321
|
...(header.revisionIndex !== undefined ? { revisionIndex: header.revisionIndex } : {}),
|
|
315
322
|
...(header.revisionState ? { revisionState: header.revisionState } : {}),
|
|
316
323
|
backend: header.backend,
|
|
317
|
-
...(header.executorId
|
|
324
|
+
...(header.executorId
|
|
325
|
+
? {
|
|
326
|
+
executorId: header.executorId,
|
|
327
|
+
...(header.executorConfig ? { executorConfig: header.executorConfig } : {}),
|
|
328
|
+
}
|
|
329
|
+
: {}),
|
|
318
330
|
...(header.llmConnectionId === undefined ? {} : { llmConnectionId: header.llmConnectionId }),
|
|
319
331
|
llmConnectionSlug: header.llmConnectionSlug,
|
|
320
332
|
connectionLocked: header.connectionLocked,
|
|
@@ -97,6 +97,7 @@ function createWriterFacade(lease, store) {
|
|
|
97
97
|
},
|
|
98
98
|
readShellRun: (sessionId, shellRunId) => run(() => store.readShellRun(sessionId, shellRunId)),
|
|
99
99
|
listSessionShellRuns: (sessionId) => run(() => store.listSessionShellRuns(sessionId)),
|
|
100
|
+
listShellRunRecoverySessionIds: () => run(() => store.listShellRunRecoverySessionIds()),
|
|
100
101
|
close: () => {
|
|
101
102
|
if (closed)
|
|
102
103
|
return;
|
|
@@ -90,6 +90,21 @@ class SqliteShellRunStore {
|
|
|
90
90
|
return normalizeShellRunRecord(JSON.parse(row.record_json), sessionId, row.shell_run_id);
|
|
91
91
|
});
|
|
92
92
|
}
|
|
93
|
+
async listShellRunRecoverySessionIds() {
|
|
94
|
+
const rows = this.#lease.database
|
|
95
|
+
.prepare(`
|
|
96
|
+
SELECT DISTINCT session_id
|
|
97
|
+
FROM core_shell_runs
|
|
98
|
+
WHERE json_extract(record_json, '$.status') IN ('starting', 'running')
|
|
99
|
+
ORDER BY session_id
|
|
100
|
+
`)
|
|
101
|
+
.all();
|
|
102
|
+
return rows.map((row) => {
|
|
103
|
+
if (typeof row.session_id !== 'string')
|
|
104
|
+
throw new Error('Invalid SQLite ShellRun row');
|
|
105
|
+
return row.session_id;
|
|
106
|
+
});
|
|
107
|
+
}
|
|
93
108
|
close() {
|
|
94
109
|
this.#lease.close();
|
|
95
110
|
}
|
|
@@ -20,7 +20,7 @@ import { decodePersistedLegacyRunHeader, invocationOpeningFromLegacyRunHeader, }
|
|
|
20
20
|
import { encodeCanonicalRuntimeEvent } from '@maka/core/canonical-runtime-event';
|
|
21
21
|
import { rebuildTranscriptTurnExtents, TERMINAL_RUNTIME_EVENT_SQL, } from './runtime-transcript-query.js';
|
|
22
22
|
import { buildInvocationOpenedEvent, buildSyntheticTerminalRuntimeEvent, } from '@maka/core/runtime-invocation';
|
|
23
|
-
export const SQLITE_RUNTIME_SCHEMA_VERSION =
|
|
23
|
+
export const SQLITE_RUNTIME_SCHEMA_VERSION = 20;
|
|
24
24
|
export const RUNTIME_RECOVERY_AUTHORITY_CAPABILITY = 'runtime_recovery_authority';
|
|
25
25
|
export const RUNTIME_RECOVERY_AUTHORITY_CAPABILITY_VERSION = 1;
|
|
26
26
|
export const RUNTIME_CONTINUATION_AUTHORITY_CAPABILITY = 'runtime_continuation_authority';
|
|
@@ -624,6 +624,79 @@ const MIGRATIONS = new Map([
|
|
|
624
624
|
ON runtime_session_turn_extents(session_id, first_ordinal, last_ordinal);
|
|
625
625
|
`,
|
|
626
626
|
],
|
|
627
|
+
[
|
|
628
|
+
20,
|
|
629
|
+
`
|
|
630
|
+
CREATE INDEX runtime_events_recovery_user_message
|
|
631
|
+
ON runtime_events(
|
|
632
|
+
session_id,
|
|
633
|
+
turn_id,
|
|
634
|
+
event_id,
|
|
635
|
+
event_kind,
|
|
636
|
+
CASE
|
|
637
|
+
WHEN json_valid(payload_json)
|
|
638
|
+
THEN json_extract(payload_json, '$.partial')
|
|
639
|
+
END,
|
|
640
|
+
CASE
|
|
641
|
+
WHEN json_valid(payload_json)
|
|
642
|
+
THEN json_extract(payload_json, '$.role')
|
|
643
|
+
END,
|
|
644
|
+
coalesce(CASE
|
|
645
|
+
WHEN json_valid(payload_json)
|
|
646
|
+
THEN json_extract(payload_json, '$.content.steering')
|
|
647
|
+
END, 0)
|
|
648
|
+
)
|
|
649
|
+
WHERE event_kind = 'text'
|
|
650
|
+
AND CASE
|
|
651
|
+
WHEN json_valid(payload_json)
|
|
652
|
+
THEN json_extract(payload_json, '$.partial')
|
|
653
|
+
END = 0
|
|
654
|
+
AND CASE
|
|
655
|
+
WHEN json_valid(payload_json)
|
|
656
|
+
THEN json_extract(payload_json, '$.role')
|
|
657
|
+
END = 'user'
|
|
658
|
+
AND coalesce(CASE
|
|
659
|
+
WHEN json_valid(payload_json)
|
|
660
|
+
THEN json_extract(payload_json, '$.content.steering')
|
|
661
|
+
END, 0) = 0;
|
|
662
|
+
|
|
663
|
+
-- Historical duplicates must remain readable so the affected identity can
|
|
664
|
+
-- fail closed. This is intentionally non-unique. CASE keeps a malformed
|
|
665
|
+
-- legacy payload from aborting the whole schema migration.
|
|
666
|
+
CREATE INDEX runtime_events_steering_message
|
|
667
|
+
ON runtime_events(
|
|
668
|
+
session_id,
|
|
669
|
+
CASE
|
|
670
|
+
WHEN json_valid(payload_json)
|
|
671
|
+
THEN json_extract(payload_json, '$.refs.providerEventId')
|
|
672
|
+
END
|
|
673
|
+
)
|
|
674
|
+
WHERE event_kind = 'text'
|
|
675
|
+
AND CASE
|
|
676
|
+
WHEN json_valid(payload_json)
|
|
677
|
+
THEN json_extract(payload_json, '$.partial')
|
|
678
|
+
END = 0
|
|
679
|
+
AND CASE
|
|
680
|
+
WHEN json_valid(payload_json)
|
|
681
|
+
THEN json_extract(payload_json, '$.content.steering')
|
|
682
|
+
END = 1;
|
|
683
|
+
|
|
684
|
+
CREATE INDEX runtime_events_tool_dispatch_operation
|
|
685
|
+
ON runtime_events(
|
|
686
|
+
CASE
|
|
687
|
+
WHEN json_valid(payload_json)
|
|
688
|
+
THEN json_extract(payload_json, '$.actions.toolDispatch.operationId')
|
|
689
|
+
END
|
|
690
|
+
)
|
|
691
|
+
WHERE event_kind = 'tool_dispatch';
|
|
692
|
+
|
|
693
|
+
CREATE INDEX tool_operations_unsettled
|
|
694
|
+
ON tool_operations(invocation_id, operation_id)
|
|
695
|
+
WHERE current_state = 'prepared'
|
|
696
|
+
AND result_event_id IS NULL
|
|
697
|
+
AND dispatch_event_id IS NOT NULL;
|
|
698
|
+
`,
|
|
699
|
+
],
|
|
627
700
|
]);
|
|
628
701
|
/**
|
|
629
702
|
* Data migrations that a SQL statement cannot express, applied inside the same
|