@myagentroam/agent 0.11.39 → 0.11.40
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/cli/catalog-file.d.ts +2 -0
- package/dist/cli/main.js +11 -4
- package/dist/cli/subagent/control.d.ts +56 -0
- package/dist/cli/subagent/control.js +219 -0
- package/dist/cli/subagent/history.d.ts +17 -0
- package/dist/cli/subagent/history.js +85 -0
- package/dist/cli/subagent/index.d.ts +10 -0
- package/dist/cli/subagent/index.js +94 -0
- package/dist/cli/subagent/native.d.ts +91 -0
- package/dist/cli/subagent/native.js +359 -0
- package/dist/cli/subagent/observations.d.ts +57 -0
- package/dist/cli/subagent/observations.js +351 -0
- package/dist/cli/subagent/query.d.ts +4 -0
- package/dist/cli/subagent/query.js +114 -0
- package/dist/cli/subagent/resources.d.ts +3 -0
- package/dist/cli/subagent/resources.js +112 -0
- package/dist/cli/subagent/snapshot.d.ts +77 -0
- package/dist/cli/subagent/snapshot.js +127 -0
- package/dist/cli/subagent/start.d.ts +24 -0
- package/dist/cli/subagent/start.js +201 -0
- package/dist/cli/subagent/wait-output.d.ts +19 -0
- package/dist/cli/subagent/wait-output.js +56 -0
- package/dist/cli/subagent/wait.d.ts +175 -0
- package/dist/cli/subagent/wait.js +453 -0
- package/dist/extensions/contracts.d.ts +2 -5
- package/dist/extensions/manager.d.ts +0 -2
- package/dist/extensions/manager.js +1 -2
- package/dist/extensions/models.d.ts +3 -0
- package/dist/extensions/operation.d.ts +8 -0
- package/dist/extensions/operation.js +3 -0
- package/dist/extensions/services.d.ts +9 -1
- package/dist/extensions/services.js +26 -3
- package/dist/extensions/session-context.d.ts +18 -0
- package/dist/extensions/session-context.js +4 -0
- package/dist/extensions/session-input.d.ts +2 -2
- package/dist/extensions/session-input.js +3 -4
- package/dist/extensions/session-messages.d.ts +1 -1
- package/dist/extensions/session-tools.js +20 -3
- package/dist/extensions/session.d.ts +1 -4
- package/dist/extensions/session.js +2 -16
- package/dist/extensions/tools.js +21 -3
- package/dist/extensions.d.ts +5 -2
- package/dist/extensions.js +2 -1
- package/dist/host/local-agent-host.d.ts +2 -2
- package/dist/host/local-exec-tool.d.ts +1 -1
- package/dist/host/local-exec-tool.js +28 -3
- package/dist/host/local-tool-registry.d.ts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/model/configuration.d.ts +3 -1
- package/dist/model/configuration.js +1 -0
- package/dist/model/openai-responses.js +5 -0
- package/dist/model/responses-request.js +9 -0
- package/dist/prompts/index.js +1 -3
- package/dist/prompts/resources.d.ts +1 -5
- package/dist/prompts/resources.js +3 -12
- package/dist/prompts/subagent.d.ts +1 -1
- package/dist/prompts/subagent.js +1 -1
- package/dist/runtime/context/gc-candidates-web.d.ts +6 -0
- package/dist/runtime/context/gc-candidates-web.js +53 -1
- package/dist/runtime/context/gc-candidates.js +1 -9
- package/dist/runtime/context/gc.js +19 -11
- package/dist/runtime/context/projection.js +1 -0
- package/dist/runtime/events.d.ts +4 -3
- package/dist/runtime/execution-handle.d.ts +2 -0
- package/dist/runtime/wait.js +12 -2
- package/dist/sdk/agent.js +94 -5
- package/dist/sdk/execution-context-coordinator.d.ts +2 -3
- package/dist/sdk/execution-context-coordinator.js +3 -3
- package/dist/sdk/execution-input.d.ts +3 -4
- package/dist/sdk/execution-input.js +31 -25
- package/dist/sdk/execution-round-preparation.d.ts +1 -1
- package/dist/sdk/execution-round-preparation.js +4 -4
- package/dist/sdk/execution-tool-catalog.js +2 -10
- package/dist/sdk/execution-tool-scope.d.ts +1 -3
- package/dist/sdk/execution-tool-scope.js +10 -12
- package/dist/sdk/extension-models.js +3 -0
- package/dist/sdk/extension-session-launch.d.ts +3 -2
- package/dist/sdk/extension-session-launch.js +2 -3
- package/dist/sdk/extension-tools.js +0 -2
- package/dist/sdk/native-steer.d.ts +2 -2
- package/dist/sdk/native-steer.js +2 -2
- package/dist/sdk/session-composition.d.ts +2 -17
- package/dist/sdk/session-execution-factory.d.ts +2 -3
- package/dist/sdk/session-execution-factory.js +20 -114
- package/dist/sdk/session-execution.d.ts +13 -7
- package/dist/sdk/session-execution.js +11 -3
- package/dist/sdk/session-extension-messages.d.ts +1 -3
- package/dist/sdk/session-extension-messages.js +14 -9
- package/dist/sdk/session-extension-prompt.js +1 -3
- package/dist/sdk/session-maintenance.d.ts +1 -0
- package/dist/sdk/session-maintenance.js +16 -7
- package/dist/sdk/session-open.d.ts +2 -3
- package/dist/sdk/session-open.js +5 -24
- package/dist/sdk/session-runtime.d.ts +19 -8
- package/dist/sdk/session-runtime.js +36 -30
- package/dist/sdk/session.d.ts +3 -2
- package/dist/sdk/session.js +22 -89
- package/dist/sdk/types.d.ts +36 -0
- package/dist/session/catalog.d.ts +22 -1
- package/dist/session/catalog.js +102 -0
- package/dist/session/context-gc-checkpoint.js +30 -1
- package/dist/session/context-gc-contract.d.ts +7 -0
- package/dist/session/context-gc-replacements.d.ts +3 -0
- package/dist/session/context-gc-replacements.js +26 -0
- package/dist/session/store/contracts.d.ts +2 -2
- package/dist/session/store/jsonl/directory-index.d.ts +1 -1
- package/dist/session/store/jsonl/directory-index.js +18 -17
- package/dist/session/store/jsonl/history.js +1 -1
- package/dist/session/store/jsonl/index-transaction.js +2 -8
- package/dist/session/store/jsonl/jsonl-store.d.ts +1 -1
- package/dist/session/store/jsonl/jsonl-store.js +24 -9
- package/dist/session/types.d.ts +1 -0
- package/dist/tools/agent/sleep.js +1 -1
- package/dist/tools/callers.js +1 -12
- package/dist/tools/code-mode/dispatch.js +5 -2
- package/dist/tools/code-mode/index.d.ts +1 -1
- package/dist/tools/code-mode/index.js +2 -0
- package/dist/tools/contracts.d.ts +20 -0
- package/dist/tools/execution-limits.d.ts +5 -20
- package/dist/tools/execution-limits.js +0 -2
- package/dist/tools/execution.js +16 -4
- package/dist/tools/local/exec.js +8 -2
- package/dist/tools/output-projection.d.ts +5 -2
- package/dist/tools/output-projection.js +133 -92
- package/dist/tools/registry.js +1 -13
- package/dist/tools/runtime-context.d.ts +1 -21
- package/package.json +2 -2
- package/dist/extensions/agents.d.ts +0 -100
- package/dist/extensions/agents.js +0 -121
- package/dist/runtime/context/gc-candidates-subagent.d.ts +0 -6
- package/dist/runtime/context/gc-candidates-subagent.js +0 -100
- package/dist/sdk/extension-agent-controller.d.ts +0 -3
- package/dist/sdk/extension-agent-controller.js +0 -69
- package/dist/sdk/extension-agents.d.ts +0 -9
- package/dist/sdk/extension-agents.js +0 -58
- package/dist/sdk/subagent-backend.d.ts +0 -3
- package/dist/sdk/subagent-backend.js +0 -49
- package/dist/subagent/contracts.d.ts +0 -107
- package/dist/subagent/contracts.js +0 -1
- package/dist/subagent/limits.d.ts +0 -17
- package/dist/subagent/limits.js +0 -17
- package/dist/subagent/model-update.d.ts +0 -2
- package/dist/subagent/model-update.js +0 -81
- package/dist/subagent/session-controller.d.ts +0 -87
- package/dist/subagent/session-controller.js +0 -1343
- package/dist/subagent/task.d.ts +0 -134
- package/dist/subagent/task.js +0 -436
- package/dist/subagent/turn-contracts.d.ts +0 -64
- package/dist/subagent/turn-contracts.js +0 -1
- package/dist/subagent/wait-targets.d.ts +0 -10
- package/dist/subagent/wait-targets.js +0 -26
- package/dist/subagent/wait.d.ts +0 -26
- package/dist/subagent/wait.js +0 -73
- package/dist/tools/agent/agent-cancel.d.ts +0 -7
- package/dist/tools/agent/agent-cancel.js +0 -29
- package/dist/tools/agent/agent-message.d.ts +0 -7
- package/dist/tools/agent/agent-message.js +0 -57
- package/dist/tools/agent/agent-start.d.ts +0 -12
- package/dist/tools/agent/agent-start.js +0 -106
- package/dist/tools/agent/agent-wait.d.ts +0 -7
- package/dist/tools/agent/agent-wait.js +0 -91
|
@@ -15,6 +15,10 @@ export class SessionExecution {
|
|
|
15
15
|
kind;
|
|
16
16
|
source;
|
|
17
17
|
snapshot;
|
|
18
|
+
#observedTerminal;
|
|
19
|
+
get observedTerminal() {
|
|
20
|
+
return this.#observedTerminal;
|
|
21
|
+
}
|
|
18
22
|
#contextInvalid = false;
|
|
19
23
|
#contextFailure;
|
|
20
24
|
#bindings;
|
|
@@ -227,10 +231,15 @@ export class SessionExecution {
|
|
|
227
231
|
full.type === 'execution.cancelled')
|
|
228
232
|
committedTerminal = this.persistedTerminal = true;
|
|
229
233
|
}
|
|
234
|
+
if (full.type === 'execution.completed' ||
|
|
235
|
+
full.type === 'execution.failed' ||
|
|
236
|
+
full.type === 'execution.cancelled')
|
|
237
|
+
this.#observedTerminal = structuredClone(full);
|
|
230
238
|
if (full.type === 'tool.output')
|
|
231
239
|
this.events.pushIfWaiting(full);
|
|
232
240
|
else
|
|
233
241
|
this.events.push(full);
|
|
242
|
+
ports.observe?.(full);
|
|
234
243
|
this.compactRequests.publish(full);
|
|
235
244
|
try {
|
|
236
245
|
await ports.publish?.(full);
|
|
@@ -363,7 +372,7 @@ export class SessionExecution {
|
|
|
363
372
|
join() {
|
|
364
373
|
return this.resultPromise;
|
|
365
374
|
}
|
|
366
|
-
handle(
|
|
375
|
+
handle() {
|
|
367
376
|
const owner = this;
|
|
368
377
|
return {
|
|
369
378
|
get persistedEvents() {
|
|
@@ -376,8 +385,7 @@ export class SessionExecution {
|
|
|
376
385
|
this.events.discardIfUnobserved();
|
|
377
386
|
return this.resultPromise;
|
|
378
387
|
},
|
|
379
|
-
cancel: () => owner.cancel(new AgentError('MAR_AGENT_CANCELLED', 'Execution was cancelled.'))
|
|
380
|
-
enqueueMessage
|
|
388
|
+
cancel: () => owner.cancel(new AgentError('MAR_AGENT_CANCELLED', 'Execution was cancelled.'))
|
|
381
389
|
};
|
|
382
390
|
}
|
|
383
391
|
cancel(reason) {
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import type { ExtensionSessionBackend } from '../extensions/session-input.js';
|
|
2
|
-
import type { ExtensionAgentsBackend } from '../extensions/agents.js';
|
|
3
2
|
import type { SessionStore } from '../session/store/contracts.js';
|
|
4
3
|
import type { SessionRuntime } from './session-runtime.js';
|
|
5
4
|
import type { ResolvedModelConfiguration } from './model-runtime.js';
|
|
6
5
|
/** Reads either a live request snapshot or the authoritative Session history. */
|
|
7
6
|
export declare function createSessionExtensionMessages(ports: {
|
|
8
7
|
sessionId: string;
|
|
9
|
-
store: Pick<SessionStore, 'readResource' | 'readInputImages' | 'readExecutionState' | 'readContextualWorldState'>;
|
|
10
|
-
agents(): Pick<ExtensionAgentsBackend, 'inspect'> | undefined;
|
|
8
|
+
store: Pick<SessionStore, 'getSession' | 'executionConfiguration' | 'readResource' | 'readInputImages' | 'readExecutionState' | 'readContextualWorldState'>;
|
|
11
9
|
runtime(id: string): Pick<SessionRuntime, 'execution' | 'contextualWorldState'> | undefined;
|
|
12
10
|
models(): {
|
|
13
11
|
models: ReadonlyMap<string, ResolvedModelConfiguration>;
|
|
@@ -5,19 +5,20 @@ import { latestContextualWorldStateGeneration, parsePersistedContextualWorldStat
|
|
|
5
5
|
import { projectSessionRequestMessages } from './request-preparation.js';
|
|
6
6
|
/** Reads either a live request snapshot or the authoritative Session history. */
|
|
7
7
|
export function createSessionExtensionMessages(ports) {
|
|
8
|
-
const { sessionId, store,
|
|
8
|
+
const { sessionId, store, runtime, models } = ports;
|
|
9
9
|
return async (input, call) => {
|
|
10
10
|
const selection = normalizeSessionMessagesInput(input);
|
|
11
11
|
call.signal.throwIfAborted();
|
|
12
12
|
let target = sessionId;
|
|
13
|
-
let targetModelId;
|
|
14
13
|
if (selection.agentId !== undefined) {
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
const child = await store.getSession(selection.agentId).catch((error) => {
|
|
15
|
+
if (error instanceof AgentError && error.code === 'MAR_AGENT_SESSION_NOT_FOUND')
|
|
16
|
+
throw new AgentError('MAR_AGENT_SUBAGENT_NOT_FOUND', 'Direct child Session not found.');
|
|
17
|
+
throw error;
|
|
18
|
+
});
|
|
19
|
+
if (child.source.parentSessionId !== sessionId)
|
|
20
|
+
throw new AgentError('MAR_AGENT_SUBAGENT_NOT_FOUND', 'Direct child Session not found.');
|
|
21
|
+
target = child.id;
|
|
21
22
|
}
|
|
22
23
|
call.signal.throwIfAborted();
|
|
23
24
|
const targetRuntime = runtime(target);
|
|
@@ -36,8 +37,12 @@ export function createSessionExtensionMessages(ports) {
|
|
|
36
37
|
return sessionMessagesPage(restored, selection);
|
|
37
38
|
}
|
|
38
39
|
const modelState = models();
|
|
40
|
+
const targetConfiguration = selection.view === 'request' && target !== sessionId
|
|
41
|
+
? await store.executionConfiguration(target)
|
|
42
|
+
: undefined;
|
|
43
|
+
call.signal.throwIfAborted();
|
|
39
44
|
const requestModel = selection.view === 'request'
|
|
40
|
-
? modelState.models.get(
|
|
45
|
+
? modelState.models.get(targetConfiguration?.modelId ?? modelState.defaultModelId)
|
|
41
46
|
: undefined;
|
|
42
47
|
if (selection.view === 'request' && !requestModel)
|
|
43
48
|
throw new AgentError('MAR_AGENT_MODEL_DISABLED', 'Selected model is unavailable.');
|
|
@@ -19,9 +19,7 @@ export function createSessionExtensionPrompt(ports) {
|
|
|
19
19
|
.filter((binding) => binding.available?.(call) !== false)
|
|
20
20
|
.map((binding) => binding.definition)
|
|
21
21
|
.filter((tool) => !(ports.source === 'subagent' &&
|
|
22
|
-
(tool.agentScope === 'ROOT_ONLY' ||
|
|
23
|
-
tool.name.startsWith('agent_') ||
|
|
24
|
-
tool.name === 'question')) &&
|
|
22
|
+
(tool.agentScope === 'ROOT_ONLY' || tool.name === 'question')) &&
|
|
25
23
|
!(tool.name === 'question' && mode !== 'plan') &&
|
|
26
24
|
!(tool.name === 'view_image' && !model.inputCapabilities.includes('IMAGE')) &&
|
|
27
25
|
!(['code_exec', 'code_exec_wait'].includes(tool.name) &&
|
|
@@ -20,6 +20,7 @@ export declare class SessionMaintenanceCoordinator {
|
|
|
20
20
|
join(): Promise<void>;
|
|
21
21
|
clear(id: string): Promise<void>;
|
|
22
22
|
delete(id: string): Promise<void>;
|
|
23
|
+
deleteMembers(members: readonly string[]): Promise<void>;
|
|
23
24
|
}
|
|
24
25
|
/** Complete all independent stages, reporting the first authoritative failure. */
|
|
25
26
|
export declare function completeAgentCleanup(steps: readonly (() => unknown | Promise<unknown>)[]): Promise<void>;
|
|
@@ -57,7 +57,6 @@ export class SessionMaintenanceCoordinator {
|
|
|
57
57
|
() => this.extensions.retireSession(id),
|
|
58
58
|
() => this.extensions.clearSession(id),
|
|
59
59
|
() => runtime?.retireInputs(),
|
|
60
|
-
() => runtime?.disposeSubagents(),
|
|
61
60
|
() => closeModelAdapters(runtime === undefined
|
|
62
61
|
? []
|
|
63
62
|
: runtime
|
|
@@ -84,8 +83,19 @@ export class SessionMaintenanceCoordinator {
|
|
|
84
83
|
});
|
|
85
84
|
}
|
|
86
85
|
delete(id) {
|
|
86
|
+
return this.deleteMembers([id]);
|
|
87
|
+
}
|
|
88
|
+
deleteMembers(members) {
|
|
89
|
+
const requestedIds = [...members];
|
|
90
|
+
if (requestedIds.length === 0 ||
|
|
91
|
+
requestedIds.some((id) => typeof id !== 'string' || id.length === 0) ||
|
|
92
|
+
new Set(requestedIds).size !== requestedIds.length)
|
|
93
|
+
return Promise.reject(new AgentError('MAR_AGENT_SESSION_INVALID', 'Invalid Session maintenance members.'));
|
|
94
|
+
requestedIds.sort();
|
|
95
|
+
const id = requestedIds[0];
|
|
96
|
+
const signature = JSON.stringify(requestedIds);
|
|
87
97
|
return this.#track(id, 'delete', async () => {
|
|
88
|
-
const maintenance = await this.store.acquireSessionMaintenance(id, 'delete', this.writerOwner);
|
|
98
|
+
const maintenance = await this.store.acquireSessionMaintenance(id, 'delete', this.writerOwner, requestedIds);
|
|
89
99
|
let failed = false;
|
|
90
100
|
const ids = maintenance.sessionIds;
|
|
91
101
|
for (const sessionId of ids)
|
|
@@ -119,7 +129,6 @@ export class SessionMaintenanceCoordinator {
|
|
|
119
129
|
...ids.map((sessionId) => () => this.extensions.retireSession(sessionId)),
|
|
120
130
|
...ids.map((sessionId) => () => this.extensions.clearSession(sessionId)),
|
|
121
131
|
() => completeAgentCleanup(runtimes.map((runtime) => () => runtime.retireInputs())),
|
|
122
|
-
() => completeAgentCleanup(runtimes.map((runtime) => () => runtime.disposeSubagents())),
|
|
123
132
|
() => Promise.all(runtimes.map((runtime) => runtime.joinExecutions())),
|
|
124
133
|
() => {
|
|
125
134
|
for (const sessionId of ids) {
|
|
@@ -157,25 +166,25 @@ export class SessionMaintenanceCoordinator {
|
|
|
157
166
|
}
|
|
158
167
|
}
|
|
159
168
|
}
|
|
160
|
-
});
|
|
169
|
+
}, signature);
|
|
161
170
|
}
|
|
162
171
|
#invalidate(ids) {
|
|
163
172
|
for (const id of ids)
|
|
164
173
|
this.#epochs.set(id, this.epoch(id) + 1);
|
|
165
174
|
}
|
|
166
|
-
#track(id, kind, operation) {
|
|
175
|
+
#track(id, kind, operation, signature = '') {
|
|
167
176
|
if (this.disposed())
|
|
168
177
|
return Promise.reject(new AgentError('MAR_AGENT_DISPOSED', 'Agent is disposed.'));
|
|
169
178
|
const current = this.#operations.get(id);
|
|
170
179
|
if (current)
|
|
171
|
-
return current.kind === kind
|
|
180
|
+
return current.kind === kind && current.signature === signature
|
|
172
181
|
? current.pending
|
|
173
182
|
: Promise.reject(new AgentError('MAR_AGENT_SESSION_CLOSING', 'Session is closing.'));
|
|
174
183
|
if (this.#treeAdmissions.has(id))
|
|
175
184
|
return Promise.reject(new AgentError('MAR_AGENT_SESSION_CLOSING', 'Session is closing.'));
|
|
176
185
|
const completion = Promise.withResolvers();
|
|
177
186
|
const pending = completion.promise.finally(() => this.#operations.delete(id));
|
|
178
|
-
this.#operations.set(id, { kind, pending });
|
|
187
|
+
this.#operations.set(id, { kind, signature, pending });
|
|
179
188
|
void pending.catch(() => undefined);
|
|
180
189
|
try {
|
|
181
190
|
completion.resolve(operation());
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type { ModelAdapter } from '../model/contracts.js';
|
|
2
2
|
import type { SessionStore } from '../session/store/contracts.js';
|
|
3
|
-
import type { SubagentSessionController } from '../subagent/session-controller.js';
|
|
4
3
|
import type { ResolvedModelConfiguration } from './model-runtime.js';
|
|
5
|
-
import {
|
|
4
|
+
import type { SessionRegistry } from './session-registry.js';
|
|
6
5
|
import { SessionRuntime } from './session-runtime.js';
|
|
7
6
|
type StoredSession = Awaited<ReturnType<SessionStore['getSession']>>;
|
|
8
7
|
interface SessionOpenPorts<Handle> {
|
|
@@ -11,7 +10,7 @@ interface SessionOpenPorts<Handle> {
|
|
|
11
10
|
readonly generation: () => number;
|
|
12
11
|
readonly createAdapter: (id: string, models: ReadonlyMap<string, ResolvedModelConfiguration>) => ModelAdapter;
|
|
13
12
|
readonly hasCustomAdapters: boolean;
|
|
14
|
-
readonly
|
|
13
|
+
readonly onExecutionRegistered: (runtime: SessionRuntime) => void;
|
|
15
14
|
readonly assertAdmission: (id: string) => void;
|
|
16
15
|
readonly epoch: (id: string) => number;
|
|
17
16
|
readonly canPublish: (id: string, epoch: number) => boolean;
|
package/dist/sdk/session-open.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { AgentError } from '../error.js';
|
|
2
|
-
import { SessionOpenCleanupError } from './session-registry.js';
|
|
3
2
|
import { SessionRuntime } from './session-runtime.js';
|
|
4
3
|
/** The open flow owns unpublished candidates; the registry owns only identity and barriers. */
|
|
5
4
|
export function createSessionOpen(ports) {
|
|
@@ -9,35 +8,17 @@ export function createSessionOpen(ports) {
|
|
|
9
8
|
return ports.registry.trackOpen(id, async () => {
|
|
10
9
|
const runtime = await ports.registry.getOrCreate(id, epoch, () => ports.canPublish(id, epoch), async (publish) => {
|
|
11
10
|
const stored = await ports.getSession(id);
|
|
12
|
-
const candidate = new SessionRuntime(stored, ports.generation(), ports.createAdapter, ports.hasCustomAdapters);
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
if (!publish(candidate))
|
|
18
|
-
throw new AgentError('MAR_AGENT_SESSION_CLOSING', 'Session is closing.');
|
|
19
|
-
return candidate;
|
|
20
|
-
}
|
|
21
|
-
catch (error) {
|
|
22
|
-
try {
|
|
23
|
-
await candidate.disposeSubagents();
|
|
24
|
-
}
|
|
25
|
-
catch (cleanupError) {
|
|
26
|
-
throw new SessionOpenCleanupError(cleanupError);
|
|
27
|
-
}
|
|
28
|
-
throw error;
|
|
29
|
-
}
|
|
11
|
+
const candidate = new SessionRuntime(stored, ports.generation(), ports.createAdapter, ports.hasCustomAdapters, ports.onExecutionRegistered);
|
|
12
|
+
ports.createHandle(id, candidate, stored, workspace);
|
|
13
|
+
if (!publish(candidate))
|
|
14
|
+
throw new AgentError('MAR_AGENT_SESSION_CLOSING', 'Session is closing.');
|
|
15
|
+
return candidate;
|
|
30
16
|
});
|
|
31
17
|
ports.assertAdmission(id);
|
|
32
18
|
const stored = await ports.getSession(id);
|
|
33
19
|
ports.assertAdmission(id);
|
|
34
20
|
if (!ports.canPublish(id, epoch))
|
|
35
21
|
throw new AgentError('MAR_AGENT_SESSION_CLOSING', 'Session is closing.');
|
|
36
|
-
if (stored.source.type === 'user' && runtime.subagents === undefined) {
|
|
37
|
-
await runtime.ensureSubagents(() => ports.openSubagents(id, stored.workspace));
|
|
38
|
-
if (!ports.canPublish(id, epoch))
|
|
39
|
-
throw new AgentError('MAR_AGENT_SESSION_CLOSING', 'Session is closing.');
|
|
40
|
-
}
|
|
41
22
|
return ports.createHandle(id, runtime, stored, workspace);
|
|
42
23
|
});
|
|
43
24
|
};
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { ExtensionRequestSnapshots, type ExtensionRequestSnapshot } from '../extensions/model-request.js';
|
|
2
2
|
import type { ExtensionSessionBackend, SessionInputCoordinator } from '../extensions/session-input.js';
|
|
3
|
-
import type { ExtensionAgentsBackend } from '../extensions/agents.js';
|
|
4
3
|
import type { ModelAdapter } from '../model/contracts.js';
|
|
5
4
|
import type { ModelCredentialProvider } from '../model/configuration.js';
|
|
6
5
|
import type { SessionModelRequest as ModelRequest } from '../session/model-request.js';
|
|
7
6
|
import type { SessionStore } from '../session/store/contracts.js';
|
|
8
7
|
import { type ContextualWorldState } from '../runtime/context/world-state.js';
|
|
9
|
-
import type { SubagentSessionController } from '../subagent/session-controller.js';
|
|
10
8
|
import { TodoStore } from '../tools/agent/todo.js';
|
|
11
9
|
import type { ExecutionResult } from './types.js';
|
|
10
|
+
import type { AgentEvent } from '../runtime/events.js';
|
|
12
11
|
import type { ResolvedModelConfiguration } from './model-runtime.js';
|
|
13
12
|
import type { SessionExecution, SessionExecutionContext } from './session-execution.js';
|
|
14
13
|
export declare class SessionRuntime {
|
|
15
14
|
#private;
|
|
16
15
|
readonly storedSession: Awaited<ReturnType<SessionStore['getSession']>>;
|
|
16
|
+
readonly onExecutionRegistered: (runtime: SessionRuntime) => void;
|
|
17
17
|
readonly scheduleTool: <T>(definition: import("../host.js").ClientToolDefinition | undefined, run: () => Promise<T>) => Promise<T>;
|
|
18
|
-
constructor(storedSession: Awaited<ReturnType<SessionStore['getSession']>>, generation: number, createAdapter: (modelId: string, models: ReadonlyMap<string, ResolvedModelConfiguration>) => ModelAdapter, hasCustomAdapters: boolean);
|
|
18
|
+
constructor(storedSession: Awaited<ReturnType<SessionStore['getSession']>>, generation: number, createAdapter: (modelId: string, models: ReadonlyMap<string, ResolvedModelConfiguration>) => ModelAdapter, hasCustomAdapters: boolean, onExecutionRegistered?: (runtime: SessionRuntime) => void);
|
|
19
19
|
adapter(modelId: string, models: ReadonlyMap<string, ResolvedModelConfiguration>): ModelAdapter;
|
|
20
20
|
refreshAdapters(generation: number, retained: ReadonlySet<ModelAdapter>): Promise<void>;
|
|
21
21
|
static stageModelReconfiguration(sessions: readonly SessionRuntime[], models: ReadonlyMap<string, ResolvedModelConfiguration>, active: ReadonlySet<ModelAdapter>, assertOpen: () => void): Promise<(generation: number) => void>;
|
|
@@ -26,9 +26,6 @@ export declare class SessionRuntime {
|
|
|
26
26
|
static closeModelAdapters(sessions: readonly SessionRuntime[]): Promise<void>;
|
|
27
27
|
retireInputs(): Promise<unknown> | undefined;
|
|
28
28
|
getOrCreateInputs(create: () => SessionInputCoordinator): SessionInputCoordinator;
|
|
29
|
-
disposeSubagents(): Promise<unknown> | undefined;
|
|
30
|
-
get subagents(): SubagentSessionController | undefined;
|
|
31
|
-
ensureSubagents(open: () => Promise<SubagentSessionController>): Promise<SubagentSessionController>;
|
|
32
29
|
resetAfterClear(generation: number): void;
|
|
33
30
|
recordRequest(modelId: string, request: ModelRequest): ExtensionRequestSnapshot;
|
|
34
31
|
completeRequest(snapshot: ExtensionRequestSnapshot): void;
|
|
@@ -54,19 +51,33 @@ export declare class SessionRuntime {
|
|
|
54
51
|
ensureSessionBackend(create: () => ExtensionSessionBackend & {
|
|
55
52
|
kick(): void;
|
|
56
53
|
}): void;
|
|
57
|
-
get agentsBackend(): ExtensionAgentsBackend | undefined;
|
|
58
|
-
ensureAgentsBackend(create: () => ExtensionAgentsBackend): void;
|
|
59
54
|
get execution(): SessionExecutionContext | undefined;
|
|
60
55
|
bindExecutionContext(context: SessionExecutionContext): void;
|
|
61
56
|
unbindExecutionContext(context: SessionExecutionContext): void;
|
|
62
57
|
get contextualWorldState(): ContextualWorldState | undefined;
|
|
63
58
|
updateContextualWorldState(state: ContextualWorldState): void;
|
|
64
59
|
get activeExecutionId(): string | undefined;
|
|
60
|
+
subscribe(listener: (event: AgentEvent) => void): {
|
|
61
|
+
unsubscribe: () => void;
|
|
62
|
+
terminalEvent?: (import("./types.js").AgentEventBase & {
|
|
63
|
+
type: "execution.completed";
|
|
64
|
+
permissionStop?: import("../host.js").PermissionStop;
|
|
65
|
+
}) | (import("./types.js").AgentEventBase & {
|
|
66
|
+
type: "execution.failed";
|
|
67
|
+
code: string;
|
|
68
|
+
message?: string;
|
|
69
|
+
}) | (import("./types.js").AgentEventBase & {
|
|
70
|
+
type: "execution.cancelled";
|
|
71
|
+
});
|
|
72
|
+
activeExecutionId?: string;
|
|
73
|
+
};
|
|
74
|
+
publishEvent(event: AgentEvent): void;
|
|
65
75
|
assertCanExecute(): void;
|
|
66
76
|
registerExecution(execution: SessionExecution): void;
|
|
67
77
|
deactivateExecution(execution: SessionExecution): void;
|
|
68
78
|
unregisterExecution(execution: SessionExecution): void;
|
|
69
79
|
cancelExecution(executionId: string): void;
|
|
80
|
+
joinExecution(executionId: string): Promise<ExecutionResult> | undefined;
|
|
70
81
|
cancelExecutions(): void;
|
|
71
82
|
joinExecutions(): Promise<PromiseSettledResult<ExecutionResult>[]>;
|
|
72
83
|
}
|
|
@@ -6,22 +6,22 @@ import { createSessionToolScheduler } from '../tools/scheduler.js';
|
|
|
6
6
|
import { SessionModelAdapters } from './session-model-adapters.js';
|
|
7
7
|
export class SessionRuntime {
|
|
8
8
|
storedSession;
|
|
9
|
+
onExecutionRegistered;
|
|
9
10
|
#executionContext;
|
|
10
11
|
#todo;
|
|
11
12
|
scheduleTool = createSessionToolScheduler();
|
|
12
13
|
#modelAdapters;
|
|
13
14
|
#contextualWorldState;
|
|
14
|
-
#subagents;
|
|
15
|
-
#subagentsOpening;
|
|
16
15
|
#inputs;
|
|
17
16
|
#requestSnapshots;
|
|
18
17
|
#recordProjection;
|
|
19
18
|
#sessionBackend;
|
|
20
|
-
#agentsBackend;
|
|
21
19
|
#executions = new Map();
|
|
22
20
|
#activeExecutionId;
|
|
23
|
-
|
|
21
|
+
#eventObservers = new Set();
|
|
22
|
+
constructor(storedSession, generation, createAdapter, hasCustomAdapters, onExecutionRegistered = () => { }) {
|
|
24
23
|
this.storedSession = storedSession;
|
|
24
|
+
this.onExecutionRegistered = onExecutionRegistered;
|
|
25
25
|
this.#modelAdapters = new SessionModelAdapters(generation, createAdapter, hasCustomAdapters);
|
|
26
26
|
}
|
|
27
27
|
adapter(modelId, models) {
|
|
@@ -54,29 +54,9 @@ export class SessionRuntime {
|
|
|
54
54
|
getOrCreateInputs(create) {
|
|
55
55
|
return (this.#inputs ??= create());
|
|
56
56
|
}
|
|
57
|
-
disposeSubagents() {
|
|
58
|
-
return this.#subagents?.dispose();
|
|
59
|
-
}
|
|
60
|
-
get subagents() {
|
|
61
|
-
return this.#subagents;
|
|
62
|
-
}
|
|
63
|
-
async ensureSubagents(open) {
|
|
64
|
-
if (this.#subagents)
|
|
65
|
-
return this.#subagents;
|
|
66
|
-
const pending = (this.#subagentsOpening ??= open());
|
|
67
|
-
try {
|
|
68
|
-
return (this.#subagents = await pending);
|
|
69
|
-
}
|
|
70
|
-
finally {
|
|
71
|
-
if (this.#subagentsOpening === pending)
|
|
72
|
-
this.#subagentsOpening = undefined;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
57
|
resetAfterClear(generation) {
|
|
76
58
|
this.#modelAdapters.setGeneration(generation);
|
|
77
59
|
this.#todo = undefined;
|
|
78
|
-
this.#subagents = undefined;
|
|
79
|
-
this.#subagentsOpening = undefined;
|
|
80
60
|
this.#contextualWorldState = undefined;
|
|
81
61
|
this.#inputs = undefined;
|
|
82
62
|
this.#requestSnapshots = undefined;
|
|
@@ -146,12 +126,6 @@ export class SessionRuntime {
|
|
|
146
126
|
ensureSessionBackend(create) {
|
|
147
127
|
this.#sessionBackend ??= create();
|
|
148
128
|
}
|
|
149
|
-
get agentsBackend() {
|
|
150
|
-
return this.#agentsBackend;
|
|
151
|
-
}
|
|
152
|
-
ensureAgentsBackend(create) {
|
|
153
|
-
this.#agentsBackend ??= create();
|
|
154
|
-
}
|
|
155
129
|
get execution() {
|
|
156
130
|
return this.#executionContext;
|
|
157
131
|
}
|
|
@@ -171,6 +145,34 @@ export class SessionRuntime {
|
|
|
171
145
|
get activeExecutionId() {
|
|
172
146
|
return this.#activeExecutionId;
|
|
173
147
|
}
|
|
148
|
+
subscribe(listener) {
|
|
149
|
+
const observer = (event) => listener(structuredClone(event));
|
|
150
|
+
this.#eventObservers.add(observer);
|
|
151
|
+
const terminal = this.#activeExecutionId === undefined
|
|
152
|
+
? undefined
|
|
153
|
+
: this.#executions.get(this.#activeExecutionId)?.observedTerminal;
|
|
154
|
+
return {
|
|
155
|
+
...(this.#activeExecutionId === undefined
|
|
156
|
+
? {}
|
|
157
|
+
: { activeExecutionId: this.#activeExecutionId }),
|
|
158
|
+
...(terminal === undefined ? {} : { terminalEvent: structuredClone(terminal) }),
|
|
159
|
+
unsubscribe: () => {
|
|
160
|
+
this.#eventObservers.delete(observer);
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
publishEvent(event) {
|
|
165
|
+
for (const listener of [...this.#eventObservers]) {
|
|
166
|
+
if (!this.#eventObservers.has(listener))
|
|
167
|
+
continue;
|
|
168
|
+
try {
|
|
169
|
+
listener(event);
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
/* Observers cannot change the owning Execution. */
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
174
176
|
assertCanExecute() {
|
|
175
177
|
if (this.#activeExecutionId !== undefined)
|
|
176
178
|
throw new AgentError('MAR_AGENT_EXECUTION_ACTIVE', 'Session already has an active execution.');
|
|
@@ -179,6 +181,7 @@ export class SessionRuntime {
|
|
|
179
181
|
this.assertCanExecute();
|
|
180
182
|
this.#executions.set(execution.executionId, execution);
|
|
181
183
|
this.#activeExecutionId = execution.executionId;
|
|
184
|
+
this.onExecutionRegistered(this);
|
|
182
185
|
}
|
|
183
186
|
deactivateExecution(execution) {
|
|
184
187
|
if (this.#executions.get(execution.executionId) === execution &&
|
|
@@ -192,6 +195,9 @@ export class SessionRuntime {
|
|
|
192
195
|
cancelExecution(executionId) {
|
|
193
196
|
this.#executions.get(executionId)?.cancel();
|
|
194
197
|
}
|
|
198
|
+
joinExecution(executionId) {
|
|
199
|
+
return this.#executions.get(executionId)?.join();
|
|
200
|
+
}
|
|
195
201
|
cancelExecutions() {
|
|
196
202
|
for (const execution of this.#executions.values())
|
|
197
203
|
execution.cancel();
|
package/dist/sdk/session.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SessionServices } from './session-composition.js';
|
|
2
|
+
import type { AgentSession } from './types.js';
|
|
2
3
|
/** SDK Session orchestration owns warm resources; Runtime owns only the model/tool loop. */
|
|
3
|
-
export declare function createSessionOpener(services: SessionServices): (id: string, workspace?: string) => Promise<
|
|
4
|
+
export declare function createSessionOpener(services: SessionServices): (id: string, workspace?: string) => Promise<AgentSession>;
|
package/dist/sdk/session.js
CHANGED
|
@@ -2,21 +2,15 @@ import { createExtensionSessionLaunch, extensionInputSource } from './extension-
|
|
|
2
2
|
import { createSessionExecutionFactory } from './session-execution-factory.js';
|
|
3
3
|
import { createSessionExtensionMessages } from './session-extension-messages.js';
|
|
4
4
|
import { createSessionExtensionPrompt } from './session-extension-prompt.js';
|
|
5
|
-
import { createSubagentBackend } from './subagent-backend.js';
|
|
6
5
|
import { AgentError } from '../error.js';
|
|
7
6
|
import { SessionInputCoordinator, recordSessionInputCommit } from '../extensions/session-input.js';
|
|
8
7
|
import { buildSystemPromptSections } from '../prompts/index.js';
|
|
9
8
|
import { childSubagentInstruction } from '../prompts/subagent.js';
|
|
10
9
|
import { DEFAULT_COMPACTION_FOCUS } from '../runtime/compaction/history.js';
|
|
11
10
|
import { restoreEnvironmentState } from '../runtime/context/environment.js';
|
|
12
|
-
import { SubagentSessionController } from '../subagent/session-controller.js';
|
|
13
11
|
import { allowsDirectTool } from '../tools/callers.js';
|
|
14
|
-
import { createExtensionAgentsBackend } from './extension-agents.js';
|
|
15
12
|
import { createExtensionSessionBackend } from './extension-session.js';
|
|
16
13
|
import { createSessionOpen } from './session-open.js';
|
|
17
|
-
function restoreSubagentOrigin(origin) {
|
|
18
|
-
return { ...origin.correlation, signal: origin.signal };
|
|
19
|
-
}
|
|
20
14
|
/** SDK Session orchestration owns warm resources; Runtime owns only the model/tool loop. */
|
|
21
15
|
export function createSessionOpener(services) {
|
|
22
16
|
const { host, description, settings, store, createAdapter, activeAdaptersExcept } = services;
|
|
@@ -27,11 +21,7 @@ export function createSessionOpener(services) {
|
|
|
27
21
|
generation: () => services.modelState().generation,
|
|
28
22
|
createAdapter,
|
|
29
23
|
hasCustomAdapters: services.hasCustomAdapters,
|
|
30
|
-
|
|
31
|
-
parentSessionId: id,
|
|
32
|
-
rootSessionId: id,
|
|
33
|
-
backend: createSubagentBackend(store, workspace)
|
|
34
|
-
}),
|
|
24
|
+
onExecutionRegistered: services.agentResources.onExecutionRegistered,
|
|
35
25
|
assertAdmission: services.assertSessionAdmission,
|
|
36
26
|
epoch: services.openEpoch,
|
|
37
27
|
canPublish: services.canPublishSession,
|
|
@@ -149,8 +139,7 @@ export function createSessionOpener(services) {
|
|
|
149
139
|
refreshSessionAdapters,
|
|
150
140
|
sessionInputs,
|
|
151
141
|
withRecordProjection,
|
|
152
|
-
appendExtensionMessage
|
|
153
|
-
startSubagentTurn: async (id, input) => (await openSession(id)).startSubagentTurn(input)
|
|
142
|
+
appendExtensionMessage
|
|
154
143
|
});
|
|
155
144
|
sessionRuntime.ensureSessionBackend(() => createExtensionSessionBackend({
|
|
156
145
|
describe: async (call) => {
|
|
@@ -200,70 +189,32 @@ export function createSessionOpener(services) {
|
|
|
200
189
|
messages: createSessionExtensionMessages({
|
|
201
190
|
sessionId,
|
|
202
191
|
store,
|
|
203
|
-
agents: () => sessionRuntime.agentsBackend,
|
|
204
192
|
runtime: (id) => sessionRuntimes.get(id),
|
|
205
193
|
models: () => services.modelState()
|
|
206
194
|
}),
|
|
207
|
-
launch: createExtensionSessionLaunch(
|
|
195
|
+
launch: createExtensionSessionLaunch(execution),
|
|
208
196
|
diagnose: (code, operationId) => services.extensions.session(sessionId)?.diagnose({ code, operationId, sessionId })
|
|
209
197
|
}));
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
return sessionRuntime.subagents;
|
|
221
|
-
},
|
|
222
|
-
parent: (controller, call) => {
|
|
223
|
-
const current = call.executionId === undefined
|
|
224
|
-
? undefined
|
|
225
|
-
: controller.parentExecution(call.executionId);
|
|
226
|
-
if (call.executionId !== undefined && !current)
|
|
227
|
-
throw new AgentError('MAR_AGENT_SUBAGENT_FAILED', 'Parent Execution source is unavailable.');
|
|
228
|
-
const state = services.modelState();
|
|
229
|
-
const selected = state.models.get(state.defaultModelId);
|
|
230
|
-
return {
|
|
231
|
-
...(current ?? {
|
|
232
|
-
modelId: selected.id,
|
|
233
|
-
reasoningEffort: selected.defaultReasoningEffort,
|
|
234
|
-
models: state.models,
|
|
235
|
-
emitTerminal: async () => { },
|
|
236
|
-
startTurn: async (turn) => {
|
|
237
|
-
const child = await openSession(turn.sessionId);
|
|
238
|
-
return child.startSubagentTurn({
|
|
239
|
-
prompt: turn.prompt,
|
|
240
|
-
modelId: turn.modelId,
|
|
241
|
-
reasoningEffort: turn.reasoningEffort,
|
|
242
|
-
role: turn.role,
|
|
243
|
-
initialMailbox: turn.initialMailbox,
|
|
244
|
-
turnId: turn.turnId,
|
|
245
|
-
...(turn.origin === undefined
|
|
246
|
-
? {}
|
|
247
|
-
: { origin: restoreSubagentOrigin(turn.origin) }),
|
|
248
|
-
...(turn.delivery === undefined ? {} : { delivery: turn.delivery })
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
}),
|
|
252
|
-
operationId: call.operationId,
|
|
253
|
-
origin: { signal: call.signal, correlation: call },
|
|
254
|
-
signal: call.signal,
|
|
255
|
-
...(call.ownerInstanceId === undefined
|
|
256
|
-
? {}
|
|
257
|
-
: { ownerInstanceId: call.ownerInstanceId }),
|
|
258
|
-
...(call.extensionId === undefined ? {} : { extensionId: call.extensionId })
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
}));
|
|
198
|
+
const inputSource = () => {
|
|
199
|
+
const current = services.extensions.operations.current();
|
|
200
|
+
return current && current.sessionId !== sessionId && current.extensionId
|
|
201
|
+
? extensionInputSource(current)
|
|
202
|
+
: undefined;
|
|
203
|
+
};
|
|
204
|
+
const inputOptions = () => {
|
|
205
|
+
const source = inputSource();
|
|
206
|
+
return source ? { extensionSource: source } : {};
|
|
207
|
+
};
|
|
262
208
|
return {
|
|
263
209
|
id: sessionId,
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
210
|
+
subscribe: (listener) => {
|
|
211
|
+
services.assertSessionAdmission(sessionId);
|
|
212
|
+
return sessionRuntime.subscribe(listener);
|
|
213
|
+
},
|
|
214
|
+
run: (input) => execution('run', input, input.clientMessageId ? inputOptions() : undefined),
|
|
215
|
+
plan: (input) => execution('plan', input, input.clientMessageId ? inputOptions() : undefined),
|
|
216
|
+
steer: (input) => sessionRuntime.execution?.steer?.(input, inputSource()) ??
|
|
217
|
+
Promise.resolve({ status: 'notAccepted' }),
|
|
267
218
|
compact: (input = {}) => {
|
|
268
219
|
const requests = sessionRuntime.execution?.compactRequests;
|
|
269
220
|
if (requests) {
|
|
@@ -276,25 +227,7 @@ export function createSessionOpener(services) {
|
|
|
276
227
|
});
|
|
277
228
|
},
|
|
278
229
|
cancel: async (executionId) => sessionRuntime.cancelExecution(executionId),
|
|
279
|
-
|
|
280
|
-
prompt: turn.prompt,
|
|
281
|
-
modelId: turn.modelId,
|
|
282
|
-
reasoningEffort: turn.reasoningEffort,
|
|
283
|
-
...(turn.permissionMode === undefined ? {} : { permissionMode: turn.permissionMode })
|
|
284
|
-
}, {
|
|
285
|
-
publishHostEvents: false,
|
|
286
|
-
...(turn.origin === undefined ? {} : { signal: turn.origin.signal }),
|
|
287
|
-
inputSource: turn.origin === undefined ? 'parent_agent' : 'extension',
|
|
288
|
-
...(turn.origin === undefined
|
|
289
|
-
? {}
|
|
290
|
-
: { extensionSource: extensionInputSource(turn.origin) }),
|
|
291
|
-
initialMailbox: turn.initialMailbox,
|
|
292
|
-
turnId: turn.turnId,
|
|
293
|
-
...(turn.mcpExecutionScopeId === undefined
|
|
294
|
-
? {}
|
|
295
|
-
: { mcpExecutionScopeId: turn.mcpExecutionScopeId }),
|
|
296
|
-
...(turn.delivery ? { delivery: turn.delivery } : {})
|
|
297
|
-
})
|
|
230
|
+
joinExecution: (executionId) => sessionRuntime.joinExecution(executionId)
|
|
298
231
|
};
|
|
299
232
|
};
|
|
300
233
|
return openSession;
|