maka-agent 0.2.0-dev.46.20260922 → 0.2.0-dev.47.20260922
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-service-manager.js +26 -2
- package/dist/tui-context-refresh.js +15 -26
- package/dist/tui-mcp-control.js +29 -88
- package/native/runtime-host-windows-task-launcher/prebuilds/win32-x64/maka-runtime-host-task-launcher.exe +0 -0
- package/node_modules/@maka/core/dist/client-capability-grant.js +2 -2
- 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-policy/connection-catalog-codec.js +4 -0
- package/node_modules/@maka/core/dist/session.js +17 -1
- package/node_modules/@maka/core/dist/settings.js +2 -0
- package/node_modules/@maka/core/package.json +1 -0
- 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/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 +6 -0
- package/node_modules/@maka/runtime/dist/session-manager.js +15 -2
- 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/reconnecting-connection.js +4 -4
- 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 +11 -1
- package/node_modules/@maka/runtime-host/dist/protocol/session-catalog.js +35 -3
- package/node_modules/@maka/runtime-host/dist/protocol/workhub-coordination.js +1 -5
- 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/execution-composition.js +29 -2
- package/node_modules/@maka/runtime-host/dist/server/execution-model-authority.js +3 -0
- package/node_modules/@maka/runtime-host/dist/server/external-session-coordinator.js +29 -7
- package/node_modules/@maka/runtime-host/dist/server/hosted-execution-tool-profile.js +1 -1
- 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 +32 -4
- package/node_modules/@maka/runtime-host/dist/server/session-retirement-coordinator.js +2 -2
- package/package.json +1 -1
|
@@ -82,7 +82,7 @@ export class ClientCapabilityInvocationBroker {
|
|
|
82
82
|
}));
|
|
83
83
|
}
|
|
84
84
|
#prepare(registration, signal, timeoutMs, onProgress, requestInteraction, frameFor) {
|
|
85
|
-
const sender = this.#senderFor(registration
|
|
85
|
+
const sender = this.#senderFor(registration);
|
|
86
86
|
if (!sender) {
|
|
87
87
|
throw new ClientCapabilityInvocationError('capability_lost', 'Client Capability provider is unavailable');
|
|
88
88
|
}
|
|
@@ -162,7 +162,7 @@ export class ClientCapabilityInvocationBroker {
|
|
|
162
162
|
invocation.requestInteraction = requestInteraction ?? invocation.requestInteraction;
|
|
163
163
|
invocation.phase = 'admitted';
|
|
164
164
|
this.#armTimer(invocation);
|
|
165
|
-
const currentSender = this.#senderFor(invocation.registration
|
|
165
|
+
const currentSender = this.#senderFor(invocation.registration);
|
|
166
166
|
if (!currentSender) {
|
|
167
167
|
this.#settle(invocation, undefined, new ClientCapabilityInvocationError('capability_lost', 'Client Capability provider disappeared before admission'), false);
|
|
168
168
|
}
|
|
@@ -183,7 +183,7 @@ export class ClientCapabilityInvocationBroker {
|
|
|
183
183
|
const invocation = this.#invocations.get(invocationId);
|
|
184
184
|
if (!invocation)
|
|
185
185
|
return;
|
|
186
|
-
const currentSender = this.#senderFor(invocation.registration
|
|
186
|
+
const currentSender = this.#senderFor(invocation.registration);
|
|
187
187
|
void currentSender
|
|
188
188
|
?.send({ kind: 'client.capability.cancel', invocationId })
|
|
189
189
|
.catch(() => { });
|
|
@@ -279,10 +279,16 @@ export class ClientCapabilityInvocationBroker {
|
|
|
279
279
|
this.#acceptChunk(invocation, frame.index, frame.data);
|
|
280
280
|
}
|
|
281
281
|
}
|
|
282
|
-
|
|
282
|
+
releaseConnection(connectionId) {
|
|
283
|
+
return this.#releaseWhere((registration) => registration.connectionId === connectionId);
|
|
284
|
+
}
|
|
285
|
+
releaseRegistration(registration) {
|
|
286
|
+
return this.#releaseWhere((candidate) => candidate === registration);
|
|
287
|
+
}
|
|
288
|
+
async #releaseWhere(matches) {
|
|
283
289
|
const interactions = [];
|
|
284
290
|
for (const invocation of [...this.#invocations.values()]) {
|
|
285
|
-
if (invocation.registration
|
|
291
|
+
if (!matches(invocation.registration))
|
|
286
292
|
continue;
|
|
287
293
|
if (invocation.phase === 'dispatched' || invocation.phase === 'accepted') {
|
|
288
294
|
invocation.providerAvailability.abort(new ClientCapabilityInvocationError('capability_lost', 'Client Capability provider disconnected before admission'));
|
|
@@ -379,7 +385,7 @@ export class ClientCapabilityInvocationBroker {
|
|
|
379
385
|
this.#settle(invocation, undefined, terminalBeforeSend.error, terminalBeforeSend.releaseRemote);
|
|
380
386
|
return;
|
|
381
387
|
}
|
|
382
|
-
const sender = this.#senderFor(invocation.registration
|
|
388
|
+
const sender = this.#senderFor(invocation.registration);
|
|
383
389
|
if (!sender) {
|
|
384
390
|
this.#settle(invocation, undefined, new ToolOutcomeUnknownError('Client Capability provider disappeared before receiving an interaction result'), false);
|
|
385
391
|
return;
|
|
@@ -433,7 +439,7 @@ export class ClientCapabilityInvocationBroker {
|
|
|
433
439
|
const current = this.#invocations.get(invocation.invocationId);
|
|
434
440
|
if (current !== invocation)
|
|
435
441
|
return;
|
|
436
|
-
const sender = this.#senderFor(current.registration
|
|
442
|
+
const sender = this.#senderFor(current.registration);
|
|
437
443
|
void sender
|
|
438
444
|
?.send({ kind: 'client.capability.cancel', invocationId: current.invocationId })
|
|
439
445
|
.catch(() => { });
|
|
@@ -456,7 +462,7 @@ export class ClientCapabilityInvocationBroker {
|
|
|
456
462
|
}
|
|
457
463
|
this.#rememberRetired(invocation.invocationId);
|
|
458
464
|
if (releaseRemote) {
|
|
459
|
-
const sender = this.#senderFor(invocation.registration
|
|
465
|
+
const sender = this.#senderFor(invocation.registration);
|
|
460
466
|
void sender
|
|
461
467
|
?.send({
|
|
462
468
|
kind: 'client.capability.release',
|
|
@@ -102,6 +102,7 @@ import { createInteractiveRunComposer, createInteractiveRunComposerFactory, rout
|
|
|
102
102
|
import { createHostGoalEvaluator, createHostDailyReviewModel, createHostMemoryExtractionModel, createHostPluginModel, createHostSessionEffectModel, } from './execution-model-authority.js';
|
|
103
103
|
import { HostExecutionInspectCoordinator } from './execution-inspect-coordinator.js';
|
|
104
104
|
import { HostExternalSessionCoordinator } from './external-session-coordinator.js';
|
|
105
|
+
import { boundedFailureDiagnostic } from './failure-diagnostic.js';
|
|
105
106
|
import { HostSessionBundleCoordinator } from './session-bundle-coordinator.js';
|
|
106
107
|
import { HostGoalCoordinator } from './goal-coordinator.js';
|
|
107
108
|
import { HostGoalExecutionCoordinator } from './goal-execution-coordinator.js';
|
|
@@ -835,6 +836,12 @@ export async function createExecutionRuntimeHostComposition(context, options = {
|
|
|
835
836
|
build: (factoryContext) => new PluginExecutorBackend({
|
|
836
837
|
sessionId: factoryContext.sessionId,
|
|
837
838
|
cwd: factoryContext.header.cwd,
|
|
839
|
+
...(factoryContext.header.model === executorId
|
|
840
|
+
? {}
|
|
841
|
+
: { model: factoryContext.header.model }),
|
|
842
|
+
...(factoryContext.header.thinkingLevel
|
|
843
|
+
? { thinkingLevel: factoryContext.header.thinkingLevel }
|
|
844
|
+
: {}),
|
|
838
845
|
...(factoryContext.systemPrompt ? { instructions: factoryContext.systemPrompt } : {}),
|
|
839
846
|
binding,
|
|
840
847
|
}),
|
|
@@ -1160,6 +1167,10 @@ export async function createExecutionRuntimeHostComposition(context, options = {
|
|
|
1160
1167
|
};
|
|
1161
1168
|
clientCapabilities = new HostClientCapabilityCoordinator({
|
|
1162
1169
|
activation: runtimePolicyActivation,
|
|
1170
|
+
isSessionRetired: async (sessionId) => {
|
|
1171
|
+
const state = await stores.sessionStore.probeSessionRemoval(sessionId);
|
|
1172
|
+
return (state.kind === 'removed' || (state.kind === 'present' && state.record.header.isArchived));
|
|
1173
|
+
},
|
|
1163
1174
|
onModelToolsChanged: registerBackendInvalidation,
|
|
1164
1175
|
interactions,
|
|
1165
1176
|
grants: stores.interactionStore,
|
|
@@ -1789,7 +1800,12 @@ export async function createExecutionRuntimeHostComposition(context, options = {
|
|
|
1789
1800
|
workspace: input.create.workspace,
|
|
1790
1801
|
name: input.create.title,
|
|
1791
1802
|
...(input.create.defaults?.executorId
|
|
1792
|
-
? {
|
|
1803
|
+
? {
|
|
1804
|
+
executorId: input.create.defaults.executorId,
|
|
1805
|
+
...(input.create.defaults.executorModel
|
|
1806
|
+
? { executorModel: input.create.defaults.executorModel }
|
|
1807
|
+
: {}),
|
|
1808
|
+
}
|
|
1793
1809
|
: {
|
|
1794
1810
|
modelTarget: input.create.defaults?.model
|
|
1795
1811
|
? {
|
|
@@ -1803,6 +1819,9 @@ export async function createExecutionRuntimeHostComposition(context, options = {
|
|
|
1803
1819
|
...(input.create.defaults?.permissionMode
|
|
1804
1820
|
? { permissionMode: input.create.defaults.permissionMode }
|
|
1805
1821
|
: {}),
|
|
1822
|
+
...(input.create.defaults?.thinkingLevel
|
|
1823
|
+
? { thinkingLevel: input.create.defaults.thinkingLevel }
|
|
1824
|
+
: {}),
|
|
1806
1825
|
collaborationMode: 'agent',
|
|
1807
1826
|
orchestrationMode: 'default',
|
|
1808
1827
|
})
|
|
@@ -1950,6 +1969,9 @@ export async function createExecutionRuntimeHostComposition(context, options = {
|
|
|
1950
1969
|
const sessionBundles = new HostSessionBundleCoordinator({
|
|
1951
1970
|
lease: context.owner.lease,
|
|
1952
1971
|
fenceSubtree: (sessionId, operation) => requireSessionManager(manager).runSessionSubtreeQuiescentMutation(sessionId, operation),
|
|
1972
|
+
recoverInterruptedSessions: (sessionIds) => requireSessionManager(manager)
|
|
1973
|
+
.recoverInterruptedSessionsForSessions(sessionIds)
|
|
1974
|
+
.then(() => undefined),
|
|
1953
1975
|
onImported: (sessionId) => hostChanges.publishSessionCatalog(sessionId),
|
|
1954
1976
|
});
|
|
1955
1977
|
const externalSessions = new HostExternalSessionCoordinator({
|
|
@@ -2194,8 +2216,13 @@ export async function createExecutionRuntimeHostComposition(context, options = {
|
|
|
2194
2216
|
await clientBoundRecovery;
|
|
2195
2217
|
}
|
|
2196
2218
|
catch (error) {
|
|
2219
|
+
// The registration mutation has already committed. Returning a
|
|
2220
|
+
// failure now would make the Client discard its new registration
|
|
2221
|
+
// identity and mistake the old registration's release for
|
|
2222
|
+
// authoritative Session retirement. Drain the unhealthy Host, but
|
|
2223
|
+
// acknowledge the committed mutation so reconnect can republish it.
|
|
2224
|
+
console.error(`[runtime-host] post-commit Client Capability recovery failed: ${boundedFailureDiagnostic(error)}`);
|
|
2197
2225
|
context.requestDrain();
|
|
2198
|
-
throw error;
|
|
2199
2226
|
}
|
|
2200
2227
|
}
|
|
2201
2228
|
return outcome;
|
|
@@ -589,6 +589,9 @@ function parseDailyReviewModelKey(modelKey) {
|
|
|
589
589
|
return connectionSlug && modelId ? { connectionSlug, modelId } : undefined;
|
|
590
590
|
}
|
|
591
591
|
export async function resolveExecutionTarget(header, runtimePolicy, oauthCredentials, createFetchTransport) {
|
|
592
|
+
if (header.backend === 'plugin-executor') {
|
|
593
|
+
throw new AuxiliaryModelCallConfigurationError('Plugin Executor Sessions do not expose the native auxiliary model authority');
|
|
594
|
+
}
|
|
592
595
|
const resolved = await runtimePolicy.operations.resolveExecutionConnection(executionConnectionRef(header));
|
|
593
596
|
if (resolved.kind !== 'ready') {
|
|
594
597
|
throw new AuxiliaryModelCallConfigurationError(`Runtime Host model connection is not ready: ${resolved.kind}`);
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
import { JsonArrayPageBudget } from './json-array-page-budget.js';
|
|
20
20
|
import { ExternalSessionCatalogCursorError, ExternalSessionLimitError, ExternalSessionNotFoundError, } from '@maka/core/external-session';
|
|
21
21
|
import { redactSecrets } from '@maka/core/redaction';
|
|
22
|
-
import { ExternalSessionImporter } from '@maka/storage/external-sessions';
|
|
22
|
+
import { ExternalSessionImporter, } from '@maka/storage/external-sessions';
|
|
23
23
|
import { EXTERNAL_SESSION_CWD_MAX_BYTES, EXTERNAL_SESSION_IMPORTED_SESSION_IDS_MAX_ITEMS, EXTERNAL_SESSION_NAME_MAX_BYTES, EXTERNAL_SESSION_PAGE_MAX_ITEMS, EXTERNAL_SESSION_RESULT_MAX_BYTES, EXTERNAL_SESSION_SOURCE_MAX_ITEMS, EXTERNAL_SESSION_SOURCE_SESSION_ID_MAX_BYTES, } from '../protocol/index.js';
|
|
24
24
|
import { projectSessionCatalogRecord, SessionOperationFailure, NoUsableImportModelError, } from './session-catalog-coordinator.js';
|
|
25
25
|
import { WorkspaceResolutionError } from './workspace-resolver.js';
|
|
@@ -52,9 +52,10 @@ export class HostExternalSessionCoordinator {
|
|
|
52
52
|
* be unmounted mid-import by design, and its in-flight state goes with it —
|
|
53
53
|
* as would a second window's, or the CLI's.
|
|
54
54
|
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
* a
|
|
55
|
+
* Requests for the same destination share the first outcome. A different
|
|
56
|
+
* destination is a conflicting intent: it must not receive a successful
|
|
57
|
+
* Session in a workspace it did not request. The source key also owns the
|
|
58
|
+
* catalog's isImporting projection, regardless of the chosen destination.
|
|
58
59
|
*/
|
|
59
60
|
#importsInFlight = new Map();
|
|
60
61
|
constructor(options) {
|
|
@@ -180,10 +181,13 @@ export class HostExternalSessionCoordinator {
|
|
|
180
181
|
async importSession(input) {
|
|
181
182
|
const key = importKey(input.adapterId, input.sourceSessionId);
|
|
182
183
|
const running = this.#importsInFlight.get(key);
|
|
183
|
-
if (running)
|
|
184
|
-
return running
|
|
184
|
+
if (running) {
|
|
185
|
+
return sameImportWorkspace(running.workspace, input.workspace)
|
|
186
|
+
? running.outcome
|
|
187
|
+
: importFailure('operation_conflict', 'This source is already being imported into a different workspace');
|
|
188
|
+
}
|
|
185
189
|
const attempt = this.#importSession(input);
|
|
186
|
-
this.#importsInFlight.set(key, attempt);
|
|
190
|
+
this.#importsInFlight.set(key, { workspace: input.workspace, outcome: attempt });
|
|
187
191
|
try {
|
|
188
192
|
return await attempt;
|
|
189
193
|
}
|
|
@@ -201,6 +205,14 @@ export class HostExternalSessionCoordinator {
|
|
|
201
205
|
let target;
|
|
202
206
|
try {
|
|
203
207
|
target = await this.#resolveTarget();
|
|
208
|
+
if (input.workspace !== undefined) {
|
|
209
|
+
const workspace = await this.#workspaceResolver.resolve(input.workspace);
|
|
210
|
+
target = {
|
|
211
|
+
...target,
|
|
212
|
+
cwd: workspace.cwd,
|
|
213
|
+
projectId: workspace.projectId,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
204
216
|
}
|
|
205
217
|
catch (error) {
|
|
206
218
|
if (error instanceof NoUsableImportModelError) {
|
|
@@ -209,6 +221,9 @@ export class HostExternalSessionCoordinator {
|
|
|
209
221
|
if (error instanceof SessionOperationFailure) {
|
|
210
222
|
return importFailure(error.code, error.message);
|
|
211
223
|
}
|
|
224
|
+
if (error instanceof WorkspaceResolutionError) {
|
|
225
|
+
return importFailure(error.code, error.message);
|
|
226
|
+
}
|
|
212
227
|
return importFailure('persistence_failed', 'Session defaults are unavailable');
|
|
213
228
|
}
|
|
214
229
|
let commitAttempted = false;
|
|
@@ -369,6 +384,13 @@ function safeTimestamp(value) {
|
|
|
369
384
|
function importKey(adapterId, sourceSessionId) {
|
|
370
385
|
return JSON.stringify([adapterId, sourceSessionId]);
|
|
371
386
|
}
|
|
387
|
+
function sameImportWorkspace(left, right) {
|
|
388
|
+
if (left === undefined || right === undefined)
|
|
389
|
+
return left === right;
|
|
390
|
+
return left.kind === 'project'
|
|
391
|
+
? right.kind === 'project' && left.projectId === right.projectId
|
|
392
|
+
: right.kind === 'host_path' && left.path === right.path;
|
|
393
|
+
}
|
|
372
394
|
function queryFailure(code, message) {
|
|
373
395
|
return { ok: false, error: { code, message } };
|
|
374
396
|
}
|
|
@@ -31,7 +31,7 @@ const HEADLESS_CODING_V1_TOOL_NAMES = [
|
|
|
31
31
|
];
|
|
32
32
|
const HEADLESS_CODING_V1_SYSTEM_PROMPT = [
|
|
33
33
|
'Complete the task by acting with the available tools, not by narrating.',
|
|
34
|
-
'Prefer Read, Glob, and Grep for inspection,
|
|
34
|
+
'Prefer Read, Glob, and Grep for inspection, the available file-editing tool for file changes, and Bash for shell commands and tests.',
|
|
35
35
|
'Verify the result when practical.',
|
|
36
36
|
'Stop when the task is complete.',
|
|
37
37
|
].join('\n');
|
|
@@ -71,7 +71,10 @@ export class HostSessionBundleCoordinator {
|
|
|
71
71
|
}
|
|
72
72
|
async #fenced(sessionId, operation) {
|
|
73
73
|
try {
|
|
74
|
-
return await this.#options.fenceSubtree(sessionId,
|
|
74
|
+
return await this.#options.fenceSubtree(sessionId, async (fencedSessionIds) => {
|
|
75
|
+
await this.#options.recoverInterruptedSessions(fencedSessionIds);
|
|
76
|
+
return operation(fencedSessionIds);
|
|
77
|
+
});
|
|
75
78
|
}
|
|
76
79
|
catch (error) {
|
|
77
80
|
// Two types, because the Session manager translates on the way out: the
|
|
@@ -839,17 +839,40 @@ export class HostSessionCatalogCoordinator {
|
|
|
839
839
|
};
|
|
840
840
|
}
|
|
841
841
|
async #mergeConfigurationPatch(current, patch) {
|
|
842
|
-
if (current.backend === 'fake' &&
|
|
842
|
+
if (current.backend === 'fake' &&
|
|
843
|
+
patch.modelTarget === undefined &&
|
|
844
|
+
patch.executorTarget === undefined) {
|
|
843
845
|
throw new SessionOperationFailure('operation_conflict', 'Legacy test backend configuration requires an explicit account selection');
|
|
844
846
|
}
|
|
845
847
|
if (current.backend !== 'plugin-executor' &&
|
|
846
848
|
current.llmConnectionId === undefined &&
|
|
847
|
-
patch.modelTarget === undefined
|
|
849
|
+
patch.modelTarget === undefined &&
|
|
850
|
+
patch.executorTarget === undefined) {
|
|
848
851
|
throw new SessionOperationFailure('operation_conflict', 'Legacy Session configuration requires an explicit account selection');
|
|
849
852
|
}
|
|
850
853
|
const thinkingLevel = patch.thinkingLevel === undefined
|
|
851
854
|
? current.thinkingLevel
|
|
852
855
|
: (patch.thinkingLevel ?? undefined);
|
|
856
|
+
if (patch.executorTarget !== undefined) {
|
|
857
|
+
try {
|
|
858
|
+
this.#assertExecutorAvailable?.(current.id, patch.executorTarget.executorId);
|
|
859
|
+
}
|
|
860
|
+
catch {
|
|
861
|
+
throw new SessionOperationFailure('operation_unavailable', `Plugin executor is unavailable: ${patch.executorTarget.executorId}`);
|
|
862
|
+
}
|
|
863
|
+
return {
|
|
864
|
+
backend: 'plugin-executor',
|
|
865
|
+
executorId: patch.executorTarget.executorId,
|
|
866
|
+
llmConnectionId: undefined,
|
|
867
|
+
llmConnectionSlug: `executor:${patch.executorTarget.executorId}`,
|
|
868
|
+
model: patch.executorTarget.model ?? patch.executorTarget.executorId,
|
|
869
|
+
thinkingLevel,
|
|
870
|
+
connectionLocked: current.connectionLocked,
|
|
871
|
+
permissionMode: patch.permissionMode ?? current.permissionMode,
|
|
872
|
+
collaborationMode: patch.collaborationMode ?? current.collaborationMode ?? 'agent',
|
|
873
|
+
orchestrationMode: patch.orchestrationMode ?? current.orchestrationMode ?? 'default',
|
|
874
|
+
};
|
|
875
|
+
}
|
|
853
876
|
let model = {
|
|
854
877
|
...(current.llmConnectionId === undefined ? {} : { connectionId: current.llmConnectionId }),
|
|
855
878
|
connectionSlug: current.llmConnectionSlug,
|
|
@@ -891,7 +914,8 @@ export class HostSessionCatalogCoordinator {
|
|
|
891
914
|
return {
|
|
892
915
|
executorId: input.executorId,
|
|
893
916
|
connectionSlug: `executor:${input.executorId}`,
|
|
894
|
-
model: input.executorId,
|
|
917
|
+
model: input.executorModel ?? input.executorId,
|
|
918
|
+
thinkingLevel: input.thinkingLevel ?? undefined,
|
|
895
919
|
};
|
|
896
920
|
}
|
|
897
921
|
if (!input.modelTarget) {
|
|
@@ -923,6 +947,7 @@ function sessionConfigurationMatches(header, configuration) {
|
|
|
923
947
|
function isPermissionModeOnlyPatch(patch) {
|
|
924
948
|
return (patch.permissionMode !== undefined &&
|
|
925
949
|
patch.modelTarget === undefined &&
|
|
950
|
+
patch.executorTarget === undefined &&
|
|
926
951
|
patch.thinkingLevel === undefined &&
|
|
927
952
|
patch.collaborationMode === undefined &&
|
|
928
953
|
patch.orchestrationMode === undefined);
|
|
@@ -934,6 +959,9 @@ async function prepareCreate(input) {
|
|
|
934
959
|
if (input.executorId !== undefined && !isExecutorId(input.executorId)) {
|
|
935
960
|
throw new SessionOperationFailure('invalid_request', 'Session executor id is invalid');
|
|
936
961
|
}
|
|
962
|
+
if (input.executorModel !== undefined && input.executorId === undefined) {
|
|
963
|
+
throw new SessionOperationFailure('invalid_request', 'Executor model requires an executor id');
|
|
964
|
+
}
|
|
937
965
|
if (input.labels?.some(isExecutionSemanticLabel)) {
|
|
938
966
|
throw new SessionOperationFailure('invalid_request', 'Session creation cannot set reserved execution labels');
|
|
939
967
|
}
|
|
@@ -960,7 +988,7 @@ function createRequestFingerprint(input, prepared) {
|
|
|
960
988
|
prepared.name,
|
|
961
989
|
prepared.labels,
|
|
962
990
|
input.executorId
|
|
963
|
-
? ['executor', input.executorId]
|
|
991
|
+
? ['executor', input.executorId, input.executorModel ?? null]
|
|
964
992
|
: input.modelTarget?.kind === 'default'
|
|
965
993
|
? ['default']
|
|
966
994
|
: [
|
|
@@ -146,7 +146,7 @@ export class HostSessionRetirementCoordinator {
|
|
|
146
146
|
handles.goal.commit();
|
|
147
147
|
handles.scheduledTasks.commit();
|
|
148
148
|
await this.#graphWake.retireSessions(family.sessionIds);
|
|
149
|
-
this.#capabilities.retireSessions(family.sessionIds);
|
|
149
|
+
await this.#capabilities.retireSessions(family.sessionIds);
|
|
150
150
|
this.#messages.retireSessions(family.sessionIds);
|
|
151
151
|
await this.#refreshFamily(family);
|
|
152
152
|
return lifecycleSuccess(projectSessionCatalogRecord(await this.#stores.readCatalogRecord(target.header.id)));
|
|
@@ -215,7 +215,7 @@ export class HostSessionRetirementCoordinator {
|
|
|
215
215
|
await this.#graphWake.retireSessions(allSessionIds);
|
|
216
216
|
this.#rememberRetiredWorktrees(committableRemove, removedSessionIds);
|
|
217
217
|
this.#scheduleCleanup(removedSessionIds);
|
|
218
|
-
this.#capabilities.retireSessions(allSessionIds);
|
|
218
|
+
await this.#capabilities.retireSessions(allSessionIds);
|
|
219
219
|
this.#messages.retireSessions(allSessionIds);
|
|
220
220
|
await this.#continuity.retireSessions(plan.remove.sessionIds, plan.remove.admission);
|
|
221
221
|
await this.#refreshFamily(plan.archive);
|