@myagentroam/agent 0.11.39 → 0.11.41
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/permissions.d.ts +1 -1
- package/dist/prompts/permissions.js +1 -0
- 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/store/jsonl/resources.js +5 -1
- 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 +4 -2
- 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/permissions.d.ts +0 -1
- package/dist/tools/permissions.js +1 -9
- 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
|
@@ -12,6 +12,7 @@ export declare function writeModelCatalog(home: string, catalog: CliModelCatalog
|
|
|
12
12
|
export declare function serializeModel(model: CliModelConfiguration): {
|
|
13
13
|
apiKey: string;
|
|
14
14
|
conversationModel?: boolean;
|
|
15
|
+
subagentModel?: boolean;
|
|
15
16
|
useResourceUrl?: boolean;
|
|
16
17
|
responsesConfigurationUpdates?: boolean;
|
|
17
18
|
responsesTransport?: import("../index.js").ResponsesTransport;
|
|
@@ -46,6 +47,7 @@ export declare function serializeModel(model: CliModelConfiguration): {
|
|
|
46
47
|
type: "CODEX_AUTH_FILE";
|
|
47
48
|
};
|
|
48
49
|
conversationModel?: boolean;
|
|
50
|
+
subagentModel?: boolean;
|
|
49
51
|
useResourceUrl?: boolean;
|
|
50
52
|
responsesConfigurationUpdates?: boolean;
|
|
51
53
|
responsesTransport?: import("../index.js").ResponsesTransport;
|
package/dist/cli/main.js
CHANGED
|
@@ -16,7 +16,7 @@ Usage:
|
|
|
16
16
|
maragent run <prompt> [--permission-mode auto|full-access] [--reasoning-effort EFFORT] [--format text|json|stream-json] [--codex-auth-file PATH]
|
|
17
17
|
maragent resume [sessionId] [--reasoning-effort EFFORT] [--codex-auth-file PATH]
|
|
18
18
|
maragent sessions list|delete <sessionId>
|
|
19
|
-
maragent models list|add|edit|remove|test [id] [--default-reasoning-effort EFFORT] [--code-mode|--no-code-mode] [--fast-mode|--no-fast-mode] [--codex-auth-file PATH]
|
|
19
|
+
maragent models list|add|edit|remove|test [id] [--default-reasoning-effort EFFORT] [--conversation-model|--no-conversation-model] [--subagent-model|--no-subagent-model] [--code-mode|--no-code-mode] [--fast-mode|--no-fast-mode] [--codex-auth-file PATH]
|
|
20
20
|
`;
|
|
21
21
|
function takeOption(arguments_, name) {
|
|
22
22
|
const index = arguments_.indexOf(name);
|
|
@@ -68,7 +68,7 @@ async function modelsCommand(home, arguments_, codexAuthFile) {
|
|
|
68
68
|
const catalog = await loadCatalog(home);
|
|
69
69
|
if (action === 'list') {
|
|
70
70
|
for (const model of catalog.models)
|
|
71
|
-
stdout.write(`${model.id}\t${model.name}\t${model.protocol}\t${model.modelId}\tcredential=${model.apiKey === undefined ? 'codex-auth-file' : 'api-key'}\n`);
|
|
71
|
+
stdout.write(`${model.id}\t${model.name}\t${model.protocol}\t${model.modelId}\tcredential=${model.apiKey === undefined ? 'codex-auth-file' : 'api-key'}\tconversation=${model.conversationModel !== false}\tsubagent=${model.subagentModel === true}\n`);
|
|
72
72
|
return;
|
|
73
73
|
}
|
|
74
74
|
const id = arguments_[2];
|
|
@@ -171,7 +171,8 @@ async function modelsCommand(home, arguments_, codexAuthFile) {
|
|
|
171
171
|
defaultReasoningEffort: existing?.defaultReasoningEffort
|
|
172
172
|
})
|
|
173
173
|
: parseReasoningEffort(defaultReasoningEffortOption, '--default-reasoning-effort'),
|
|
174
|
-
conversationModel: existing?.conversationModel ?? true,
|
|
174
|
+
conversationModel: booleanFlag(arguments_, '--conversation-model', '--no-conversation-model', existing?.conversationModel ?? true),
|
|
175
|
+
subagentModel: booleanFlag(arguments_, '--subagent-model', '--no-subagent-model', existing?.subagentModel ?? false),
|
|
175
176
|
titleGeneration: existing?.titleGeneration ?? false,
|
|
176
177
|
codeMode: booleanFlag(arguments_, '--code-mode', '--no-code-mode', existing?.codeMode ?? false),
|
|
177
178
|
...(credential === 'codex-auth-file' && fastMode ? { fastMode: true } : {}),
|
|
@@ -278,10 +279,16 @@ async function main() {
|
|
|
278
279
|
}
|
|
279
280
|
});
|
|
280
281
|
const runtime = runtimeModels(catalog.models, codexAuthFile);
|
|
281
|
-
|
|
282
|
+
// The CLI-only build contains the independently published extension's same source.
|
|
283
|
+
const extensionPath = './subagent/index.js';
|
|
284
|
+
const extensionModule = (await import(extensionPath));
|
|
285
|
+
let agent;
|
|
286
|
+
const subagent = extensionModule.createSubagentExtension({ agent: () => agent });
|
|
287
|
+
agent = await createAgent({
|
|
282
288
|
mode: 'normal',
|
|
283
289
|
host,
|
|
284
290
|
models: runtime.models,
|
|
291
|
+
extensions: [subagent],
|
|
285
292
|
...(modelId === undefined ? {} : { defaultModelId: modelId })
|
|
286
293
|
});
|
|
287
294
|
try {
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type Agent, type AgentSession, type ExecutionResult } from '@myagentroam/agent';
|
|
2
|
+
import type { ExtensionOperationContext, SessionExtensionContext } from '@myagentroam/agent/extensions';
|
|
3
|
+
import type { SessionObservations } from './observations.js';
|
|
4
|
+
import type { StartAdmission } from './start.js';
|
|
5
|
+
export declare function target(agent: Agent, actorId: string, id: string): Promise<{
|
|
6
|
+
session: AgentSession;
|
|
7
|
+
summary: import("@myagentroam/agent").AgentSessionSummary & {
|
|
8
|
+
automaticTitlePending: boolean;
|
|
9
|
+
};
|
|
10
|
+
child: boolean;
|
|
11
|
+
parent: boolean;
|
|
12
|
+
}>;
|
|
13
|
+
/** Local operations use the Session owner for all execution and input transitions. */
|
|
14
|
+
export declare function registerControlTools(context: SessionExtensionContext, agent: Agent, observations: SessionObservations, warmObservations: ReadonlyMap<string, SessionObservations>, admission: StartAdmission): void;
|
|
15
|
+
export declare function sendChild(context: SessionExtensionContext, agent: Agent, observations: SessionObservations, warmObservations: ReadonlyMap<string, SessionObservations>, admission: StartAdmission, input: {
|
|
16
|
+
agentId: string;
|
|
17
|
+
content: string;
|
|
18
|
+
delivery?: 'append' | 'replace';
|
|
19
|
+
}, call: ExtensionOperationContext, mode: 'model' | 'native'): Promise<{
|
|
20
|
+
agentId: string;
|
|
21
|
+
delivery: string;
|
|
22
|
+
clientMessageId: `${string}-${string}-${string}-${string}-${string}`;
|
|
23
|
+
}>;
|
|
24
|
+
/** Stop through the Session owner; native callers use their own observation cursor. */
|
|
25
|
+
export declare function stopChild(context: SessionExtensionContext, agent: Agent, observations: SessionObservations, input: {
|
|
26
|
+
agentId: string;
|
|
27
|
+
executionId?: string;
|
|
28
|
+
}, call: ExtensionOperationContext): Promise<{
|
|
29
|
+
updates?: {
|
|
30
|
+
permissionStop?: import("@myagentroam/agent").PermissionStop;
|
|
31
|
+
errorMessage?: string;
|
|
32
|
+
errorCode?: string;
|
|
33
|
+
truncated?: boolean;
|
|
34
|
+
final?: boolean;
|
|
35
|
+
kind: "message" | "terminal";
|
|
36
|
+
value: string;
|
|
37
|
+
}[];
|
|
38
|
+
changedFilesTruncated?: boolean;
|
|
39
|
+
changedFiles?: string[];
|
|
40
|
+
turnId?: string;
|
|
41
|
+
summaryTruncated?: boolean;
|
|
42
|
+
summary?: string;
|
|
43
|
+
permissionStop?: import("@myagentroam/agent").PermissionStop;
|
|
44
|
+
errorCode?: string;
|
|
45
|
+
agentId: string;
|
|
46
|
+
executionId: string;
|
|
47
|
+
status: "completed" | "failed" | "cancelled";
|
|
48
|
+
} | {
|
|
49
|
+
status: "idle" | "running" | "interrupted" | "completed" | "failed" | "cancelled";
|
|
50
|
+
executionId?: string;
|
|
51
|
+
details?: ReturnType<typeof import("./snapshot.js").nativeChildSnapshot>;
|
|
52
|
+
errorCode?: string;
|
|
53
|
+
errorMessage?: string;
|
|
54
|
+
permissionStop?: ExecutionResult["permissionStop"];
|
|
55
|
+
agentId: string;
|
|
56
|
+
}>;
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { AgentError } from '@myagentroam/agent';
|
|
3
|
+
import { publicChildSnapshot } from './snapshot.js';
|
|
4
|
+
import { historicalExecutionStatus } from './history.js';
|
|
5
|
+
async function relation(agent, actorId, id) {
|
|
6
|
+
const [actor, other] = await Promise.all([agent.getSession(actorId), agent.getSession(id)]);
|
|
7
|
+
if (actor.workspace !== other.workspace || actorId === id)
|
|
8
|
+
throw new AgentError('MAR_AGENT_SUBAGENT_NOT_FOUND', 'Session is not available.');
|
|
9
|
+
const child = other.source.parentSessionId === actorId;
|
|
10
|
+
const parent = actor.source.parentSessionId === id;
|
|
11
|
+
if (!child && !parent)
|
|
12
|
+
throw new AgentError('MAR_AGENT_SUBAGENT_NOT_FOUND', 'Session is not available.');
|
|
13
|
+
return { summary: other, child, parent };
|
|
14
|
+
}
|
|
15
|
+
export async function target(agent, actorId, id) {
|
|
16
|
+
const resolved = await relation(agent, actorId, id);
|
|
17
|
+
if (!resolved.child)
|
|
18
|
+
throw new AgentError('MAR_AGENT_SUBAGENT_NOT_FOUND', 'Session is not available.');
|
|
19
|
+
return { ...resolved, session: await agent.openSession(id) };
|
|
20
|
+
}
|
|
21
|
+
function active(session) {
|
|
22
|
+
const snapshot = session.subscribe(() => { });
|
|
23
|
+
snapshot.unsubscribe();
|
|
24
|
+
return snapshot;
|
|
25
|
+
}
|
|
26
|
+
async function join(promise, signal) {
|
|
27
|
+
signal.throwIfAborted();
|
|
28
|
+
let abort;
|
|
29
|
+
const cancelled = new Promise((_, reject) => {
|
|
30
|
+
abort = () => reject(signal.reason);
|
|
31
|
+
signal.addEventListener('abort', abort, { once: true });
|
|
32
|
+
if (signal.aborted)
|
|
33
|
+
abort();
|
|
34
|
+
});
|
|
35
|
+
try {
|
|
36
|
+
return await Promise.race([promise, cancelled]);
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
signal.removeEventListener('abort', abort);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function origin(id, parent, message) {
|
|
43
|
+
const relation = parent ? 'other session' : 'parent session';
|
|
44
|
+
return `<mar_session_origin sessionId="${id}" relation="${parent ? 'other' : 'parent'}">\n <instruction>Message from the ${relation}.</instruction>\n</mar_session_origin>\n\n${message}`;
|
|
45
|
+
}
|
|
46
|
+
/** Local operations use the Session owner for all execution and input transitions. */
|
|
47
|
+
export function registerControlTools(context, agent, observations, warmObservations, admission) {
|
|
48
|
+
context.tools.register({
|
|
49
|
+
name: 'agent_send',
|
|
50
|
+
description: 'Send a message to a direct child or report to the direct parent.',
|
|
51
|
+
allowedCallers: ['direct', 'programmatic'],
|
|
52
|
+
inputSchema: {
|
|
53
|
+
type: 'object',
|
|
54
|
+
properties: {
|
|
55
|
+
agentId: { type: 'string', minLength: 1 },
|
|
56
|
+
content: { type: 'string', minLength: 1 },
|
|
57
|
+
delivery: { type: 'string', enum: ['append', 'replace'] }
|
|
58
|
+
},
|
|
59
|
+
required: ['agentId', 'content'],
|
|
60
|
+
additionalProperties: false
|
|
61
|
+
},
|
|
62
|
+
async execute(value, call) {
|
|
63
|
+
const input = value;
|
|
64
|
+
const data = await sendChild(context, agent, observations, warmObservations, admission, input, call, 'model');
|
|
65
|
+
return { data, content: JSON.stringify(data) };
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
context.tools.register({
|
|
69
|
+
name: 'agent_stop',
|
|
70
|
+
description: 'Stop a direct child execution and wait for its cleanup.',
|
|
71
|
+
allowedCallers: ['direct', 'programmatic'],
|
|
72
|
+
inputSchema: {
|
|
73
|
+
type: 'object',
|
|
74
|
+
properties: {
|
|
75
|
+
agentId: { type: 'string', minLength: 1 },
|
|
76
|
+
executionId: { type: 'string', minLength: 1 }
|
|
77
|
+
},
|
|
78
|
+
required: ['agentId'],
|
|
79
|
+
additionalProperties: false
|
|
80
|
+
},
|
|
81
|
+
async execute(value, call) {
|
|
82
|
+
const input = value;
|
|
83
|
+
const data = await stopChild(context, agent, observations, input, call);
|
|
84
|
+
return { data, content: JSON.stringify(data) };
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
export async function sendChild(context, agent, observations, warmObservations, admission, input, call, mode) {
|
|
89
|
+
if (!input.content.trim() || (mode === 'model' && Buffer.byteLength(input.content) > 131072))
|
|
90
|
+
throw new AgentError('MAR_AGENT_TOOL_INPUT_INVALID', 'Message is invalid.');
|
|
91
|
+
const { summary, child, parent } = await relation(agent, context.sessionId, input.agentId);
|
|
92
|
+
if (parent && input.delivery === 'replace')
|
|
93
|
+
throw new AgentError('MAR_AGENT_SUBAGENT_NOT_FOUND', 'Session is not available.');
|
|
94
|
+
call.signal.throwIfAborted();
|
|
95
|
+
if (parent) {
|
|
96
|
+
const receiver = warmObservations.get(input.agentId);
|
|
97
|
+
if (!call.executionId ||
|
|
98
|
+
!receiver?.report(context.sessionId, call.executionId, origin(context.sessionId, true, input.content)))
|
|
99
|
+
throw new AgentError('MAR_AGENT_SUBAGENT_PARENT_IDLE', 'Parent Session is not available for reports.');
|
|
100
|
+
const data = { agentId: input.agentId, delivery: 'reported', clientMessageId: randomUUID() };
|
|
101
|
+
return data;
|
|
102
|
+
}
|
|
103
|
+
const session = await agent.openSession(input.agentId);
|
|
104
|
+
call.signal.throwIfAborted();
|
|
105
|
+
const current = active(session);
|
|
106
|
+
const acknowledgePrevious = observations.acknowledgement(session.id);
|
|
107
|
+
const content = origin(context.sessionId, parent, input.content);
|
|
108
|
+
const clientMessageId = randomUUID();
|
|
109
|
+
if (current.activeExecutionId && !current.terminalEvent && input.delivery !== 'replace') {
|
|
110
|
+
const receipt = await session.steer({
|
|
111
|
+
expectedExecutionId: current.activeExecutionId,
|
|
112
|
+
prompt: content,
|
|
113
|
+
clientMessageId
|
|
114
|
+
});
|
|
115
|
+
if (receipt.status !== 'notAccepted') {
|
|
116
|
+
acknowledgePrevious();
|
|
117
|
+
if (receipt.status === 'accepted')
|
|
118
|
+
(mode === 'native'
|
|
119
|
+
? observations
|
|
120
|
+
: (warmObservations.get(context.sessionId) ?? observations)).rememberReceipt(session.id, { clientMessageId, executionId: current.activeExecutionId });
|
|
121
|
+
const data = {
|
|
122
|
+
agentId: session.id,
|
|
123
|
+
executionId: current.activeExecutionId,
|
|
124
|
+
delivery: receipt.status,
|
|
125
|
+
clientMessageId,
|
|
126
|
+
...(receipt.status === 'accepted'
|
|
127
|
+
? { messageId: clientMessageId, turnId: receipt.entry.turnId, deliveryStatus: 'accepted' }
|
|
128
|
+
: {})
|
|
129
|
+
};
|
|
130
|
+
return data;
|
|
131
|
+
}
|
|
132
|
+
const after = active(session);
|
|
133
|
+
if (after.activeExecutionId && !after.terminalEvent)
|
|
134
|
+
throw new AgentError('MAR_AGENT_SUBAGENT_INPUT_NOT_ACCEPTED', 'Target did not accept the message.');
|
|
135
|
+
}
|
|
136
|
+
if (!child)
|
|
137
|
+
throw new AgentError('MAR_AGENT_SUBAGENT_NOT_FOUND', 'Session is not available.');
|
|
138
|
+
if (current.activeExecutionId) {
|
|
139
|
+
const completion = session.joinExecution(current.activeExecutionId);
|
|
140
|
+
if (!current.terminalEvent && input.delivery === 'replace')
|
|
141
|
+
await session.cancel(current.activeExecutionId);
|
|
142
|
+
if (completion)
|
|
143
|
+
await join(completion, call.signal);
|
|
144
|
+
}
|
|
145
|
+
const models = context.models.list();
|
|
146
|
+
const model = models.find((item) => item.id === (summary.modelId ?? models.find((item) => item.isDefault)?.id));
|
|
147
|
+
if (!model?.conversationModel || !model.subagentModel)
|
|
148
|
+
throw new AgentError('MAR_AGENT_SUBAGENT_MODEL_INVALID', 'Target model is not available for child Sessions.');
|
|
149
|
+
const effort = summary.reasoningEffort &&
|
|
150
|
+
model.reasoningEfforts.includes(summary.reasoningEffort)
|
|
151
|
+
? summary.reasoningEffort
|
|
152
|
+
: model.defaultReasoningEffort;
|
|
153
|
+
call.signal.throwIfAborted();
|
|
154
|
+
const executionInput = {
|
|
155
|
+
prompt: content,
|
|
156
|
+
clientMessageId,
|
|
157
|
+
modelId: model.id,
|
|
158
|
+
reasoningEffort: effort,
|
|
159
|
+
permissionMode: call.permissionMode ?? 'auto'
|
|
160
|
+
};
|
|
161
|
+
const release = admission.reserveResume(agent, context.sessionId);
|
|
162
|
+
let execution;
|
|
163
|
+
try {
|
|
164
|
+
execution =
|
|
165
|
+
summary.source.type === 'subagent' && summary.source.role === 'explore'
|
|
166
|
+
? session.plan(executionInput)
|
|
167
|
+
: session.run(executionInput);
|
|
168
|
+
}
|
|
169
|
+
finally {
|
|
170
|
+
release();
|
|
171
|
+
}
|
|
172
|
+
acknowledgePrevious();
|
|
173
|
+
(mode === 'native'
|
|
174
|
+
? observations
|
|
175
|
+
: (warmObservations.get(context.sessionId) ?? observations)).rememberReceipt(session.id, { clientMessageId, executionId: execution.executionId });
|
|
176
|
+
const data = {
|
|
177
|
+
agentId: session.id,
|
|
178
|
+
executionId: execution.executionId,
|
|
179
|
+
delivery: 'started',
|
|
180
|
+
clientMessageId,
|
|
181
|
+
messageId: clientMessageId,
|
|
182
|
+
deliveryStatus: 'accepted',
|
|
183
|
+
...(execution.turnId === undefined ? {} : { turnId: execution.turnId })
|
|
184
|
+
};
|
|
185
|
+
return data;
|
|
186
|
+
}
|
|
187
|
+
/** Stop through the Session owner; native callers use their own observation cursor. */
|
|
188
|
+
export async function stopChild(context, agent, observations, input, call) {
|
|
189
|
+
const { child, session } = await target(agent, context.sessionId, input.agentId);
|
|
190
|
+
if (!child)
|
|
191
|
+
throw new AgentError('MAR_AGENT_SUBAGENT_NOT_FOUND', 'Session is not available.');
|
|
192
|
+
const current = active(session);
|
|
193
|
+
if (!current.activeExecutionId && !input.executionId) {
|
|
194
|
+
const state = await historicalExecutionStatus(agent, session.id, call.signal);
|
|
195
|
+
return { agentId: session.id, ...state };
|
|
196
|
+
}
|
|
197
|
+
if (!current.activeExecutionId ||
|
|
198
|
+
(input.executionId && input.executionId !== current.activeExecutionId))
|
|
199
|
+
throw new AgentError('MAR_AGENT_SUBAGENT_EXECUTION_STALE', 'Execution is not active.');
|
|
200
|
+
const completion = session.joinExecution(current.activeExecutionId);
|
|
201
|
+
if (!completion)
|
|
202
|
+
throw new AgentError('MAR_AGENT_SUBAGENT_EXECUTION_STALE', 'Execution is not active.');
|
|
203
|
+
if (!current.terminalEvent)
|
|
204
|
+
await session.cancel(current.activeExecutionId);
|
|
205
|
+
const result = await join(completion, call.signal);
|
|
206
|
+
call.signal.throwIfAborted();
|
|
207
|
+
const observation = observations.capture(session.id, current.activeExecutionId);
|
|
208
|
+
const data = {
|
|
209
|
+
agentId: session.id,
|
|
210
|
+
executionId: current.activeExecutionId,
|
|
211
|
+
status: result.status,
|
|
212
|
+
...(result.errorCode ? { errorCode: result.errorCode } : {}),
|
|
213
|
+
...(result.permissionStop ? { permissionStop: result.permissionStop } : {}),
|
|
214
|
+
...publicChildSnapshot(observations.snapshot(session.id, current.activeExecutionId)),
|
|
215
|
+
...(observation?.updates.length ? { updates: observation.updates } : {})
|
|
216
|
+
};
|
|
217
|
+
observation?.acknowledge();
|
|
218
|
+
return data;
|
|
219
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type Agent, type ExecutionResult } from '@myagentroam/agent';
|
|
2
|
+
import { nativeChildSnapshot } from './snapshot.js';
|
|
3
|
+
/** Share only in-flight history pages within one parent scope; completed reads are never cached. */
|
|
4
|
+
export declare function sharedSessionHistory(agent: Pick<Agent, 'sessionHistory'>): Pick<Agent, 'sessionHistory'>;
|
|
5
|
+
/** Read the latest historical Execution without opening the Session. */
|
|
6
|
+
export declare function historicalExecutionStatus(agent: Agent, sessionId: string, signal: AbortSignal, options?: {
|
|
7
|
+
details?: boolean;
|
|
8
|
+
activeExecutionId?: string;
|
|
9
|
+
history?: Pick<Agent, 'sessionHistory'>;
|
|
10
|
+
}): Promise<{
|
|
11
|
+
status: 'idle' | 'running' | 'interrupted' | 'completed' | 'failed' | 'cancelled';
|
|
12
|
+
executionId?: string;
|
|
13
|
+
details?: ReturnType<typeof nativeChildSnapshot>;
|
|
14
|
+
errorCode?: string;
|
|
15
|
+
errorMessage?: string;
|
|
16
|
+
permissionStop?: ExecutionResult['permissionStop'];
|
|
17
|
+
}>;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { AgentError } from '@myagentroam/agent';
|
|
2
|
+
import { nativeChildSnapshot, projectChildEvent } from './snapshot.js';
|
|
3
|
+
/** Share only in-flight history pages within one parent scope; completed reads are never cached. */
|
|
4
|
+
export function sharedSessionHistory(agent) {
|
|
5
|
+
const pending = new Map();
|
|
6
|
+
return {
|
|
7
|
+
sessionHistory(sessionId, options) {
|
|
8
|
+
const key = JSON.stringify([sessionId, options?.limit ?? null, options?.cursor ?? null]);
|
|
9
|
+
const existing = pending.get(key);
|
|
10
|
+
if (existing)
|
|
11
|
+
return existing;
|
|
12
|
+
const request = agent.sessionHistory(sessionId, options);
|
|
13
|
+
pending.set(key, request);
|
|
14
|
+
void request
|
|
15
|
+
.finally(() => {
|
|
16
|
+
if (pending.get(key) === request)
|
|
17
|
+
pending.delete(key);
|
|
18
|
+
})
|
|
19
|
+
.catch(() => { });
|
|
20
|
+
return request;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/** Read the latest historical Execution without opening the Session. */
|
|
25
|
+
export async function historicalExecutionStatus(agent, sessionId, signal, options = {}) {
|
|
26
|
+
let cursor;
|
|
27
|
+
let latest;
|
|
28
|
+
const pages = [];
|
|
29
|
+
do {
|
|
30
|
+
signal.throwIfAborted();
|
|
31
|
+
const page = await (options.history ?? agent).sessionHistory(sessionId, {
|
|
32
|
+
limit: 100,
|
|
33
|
+
...(cursor === undefined ? {} : { cursor })
|
|
34
|
+
});
|
|
35
|
+
signal.throwIfAborted();
|
|
36
|
+
const events = page.entries.flatMap((entry) => (entry.kind === 'event' ? [entry.event] : []));
|
|
37
|
+
latest ??= events.findLast((event) => event.type === 'execution.started' ||
|
|
38
|
+
event.type === 'execution.completed' ||
|
|
39
|
+
event.type === 'execution.failed' ||
|
|
40
|
+
event.type === 'execution.cancelled');
|
|
41
|
+
if (latest && !options.details)
|
|
42
|
+
break;
|
|
43
|
+
if (latest) {
|
|
44
|
+
const matching = events.filter((event) => event.executionId === latest.executionId);
|
|
45
|
+
pages.push(matching);
|
|
46
|
+
if (matching.some((event) => event.type === 'execution.started'))
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
cursor = page.nextCursor;
|
|
50
|
+
} while (cursor);
|
|
51
|
+
if (!latest)
|
|
52
|
+
return { status: 'idle' };
|
|
53
|
+
let status;
|
|
54
|
+
if (latest.type === 'execution.started') {
|
|
55
|
+
if (latest.executionId === options.activeExecutionId)
|
|
56
|
+
status = 'running';
|
|
57
|
+
else {
|
|
58
|
+
const interrupted = await agent.sessionExecutionWasInterrupted(sessionId, latest.executionId, { signal });
|
|
59
|
+
signal.throwIfAborted();
|
|
60
|
+
if (!interrupted)
|
|
61
|
+
throw new AgentError('MAR_AGENT_SESSION_EXECUTION_CHANGED', 'Session Execution changed during inspection.');
|
|
62
|
+
status = 'interrupted';
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else
|
|
66
|
+
status = latest.type.slice('execution.'.length);
|
|
67
|
+
const projection = { changedFiles: [] };
|
|
68
|
+
for (const events of pages.reverse())
|
|
69
|
+
for (const event of events)
|
|
70
|
+
projectChildEvent(projection, event, true);
|
|
71
|
+
return {
|
|
72
|
+
status,
|
|
73
|
+
executionId: latest.executionId,
|
|
74
|
+
...(options.details ? { details: nativeChildSnapshot(projection) } : {}),
|
|
75
|
+
...(latest.type === 'execution.completed' && latest.permissionStop
|
|
76
|
+
? { permissionStop: latest.permissionStop }
|
|
77
|
+
: {}),
|
|
78
|
+
...(latest.type === 'execution.failed'
|
|
79
|
+
? {
|
|
80
|
+
errorCode: latest.code,
|
|
81
|
+
...(latest.message === undefined ? {} : { errorMessage: latest.message })
|
|
82
|
+
}
|
|
83
|
+
: {})
|
|
84
|
+
};
|
|
85
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Agent } from '@myagentroam/agent';
|
|
2
|
+
import { type AgentExtension } from '@myagentroam/agent/extensions';
|
|
3
|
+
export { SUBAGENT_NATIVE_SERVICE } from './native.js';
|
|
4
|
+
export type { NativeAgentGroup, NativeAgentSnapshot, NativeSpawnInput, NativeWaitInput, NativeSubagentClient, NativeSubagentService, ExtensionAgentSnapshot, ExtensionAgentManySnapshot, ExtensionAgentSpawnInput, ExtensionAgentWaitInput, ExtensionAgentsApi } from './native.js';
|
|
5
|
+
export interface SubagentExtensionOptions {
|
|
6
|
+
/** Resolve the Agent after Host composition; it owns all Session execution. */
|
|
7
|
+
readonly agent: () => Agent;
|
|
8
|
+
}
|
|
9
|
+
/** Optional local consumer of Core Session lifecycle and observation APIs. */
|
|
10
|
+
export declare function createSubagentExtension(options: SubagentExtensionOptions): AgentExtension;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { SESSION_CONTEXT_PROVIDER } from '@myagentroam/agent/extensions';
|
|
2
|
+
import { SessionObservations } from './observations.js';
|
|
3
|
+
import { registerStart, StartAdmission } from './start.js';
|
|
4
|
+
import { registerControlTools } from './control.js';
|
|
5
|
+
import { registerWait } from './wait.js';
|
|
6
|
+
import { registerQueryTools } from './query.js';
|
|
7
|
+
import { nativeSubagentService, SUBAGENT_NATIVE_SERVICE } from './native.js';
|
|
8
|
+
import { childResources } from './resources.js';
|
|
9
|
+
import { sharedSessionHistory } from './history.js';
|
|
10
|
+
export { SUBAGENT_NATIVE_SERVICE } from './native.js';
|
|
11
|
+
/** Optional local consumer of Core Session lifecycle and observation APIs. */
|
|
12
|
+
export function createSubagentExtension(options) {
|
|
13
|
+
const admission = new StartAdmission();
|
|
14
|
+
const warmObservations = new Map();
|
|
15
|
+
return {
|
|
16
|
+
id: 'subagent',
|
|
17
|
+
apiVersion: '1.0',
|
|
18
|
+
provides: [{ key: SUBAGENT_NATIVE_SERVICE }],
|
|
19
|
+
async attachSession(context) {
|
|
20
|
+
const agent = options.agent();
|
|
21
|
+
const parent = await agent.getSession(context.sessionId);
|
|
22
|
+
const history = sharedSessionHistory(agent);
|
|
23
|
+
const observations = new SessionObservations(false, history);
|
|
24
|
+
const native = nativeSubagentService(context, agent, admission, warmObservations, parent.workspace, history);
|
|
25
|
+
if (warmObservations.has(context.sessionId))
|
|
26
|
+
throw new Error('SUBAGENT_SESSION_ALREADY_ATTACHED');
|
|
27
|
+
warmObservations.set(context.sessionId, observations);
|
|
28
|
+
let disposed = false;
|
|
29
|
+
let parentUnsubscribe;
|
|
30
|
+
const observe = (session) => {
|
|
31
|
+
if (disposed)
|
|
32
|
+
return;
|
|
33
|
+
if (session.id === context.sessionId) {
|
|
34
|
+
parentUnsubscribe?.();
|
|
35
|
+
const subscription = session.subscribe((event) => {
|
|
36
|
+
if (event.type !== 'execution.completed' &&
|
|
37
|
+
event.type !== 'execution.failed' &&
|
|
38
|
+
event.type !== 'execution.cancelled')
|
|
39
|
+
return;
|
|
40
|
+
admission.finish(event.executionId);
|
|
41
|
+
parentUnsubscribe?.();
|
|
42
|
+
parentUnsubscribe = undefined;
|
|
43
|
+
});
|
|
44
|
+
parentUnsubscribe = subscription.unsubscribe;
|
|
45
|
+
if (subscription.terminalEvent) {
|
|
46
|
+
admission.finish(subscription.terminalEvent.executionId);
|
|
47
|
+
parentUnsubscribe();
|
|
48
|
+
parentUnsubscribe = undefined;
|
|
49
|
+
}
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (session.source.parentSessionId === context.sessionId &&
|
|
53
|
+
session.workspace === parent.workspace)
|
|
54
|
+
observations.observe(session);
|
|
55
|
+
};
|
|
56
|
+
const registration = agent.observeSessionExecutions(observe);
|
|
57
|
+
try {
|
|
58
|
+
for (const session of registration.sessions)
|
|
59
|
+
observe(session);
|
|
60
|
+
context.services.provide(SUBAGENT_NATIVE_SERVICE, native.service);
|
|
61
|
+
context.services.provide(SESSION_CONTEXT_PROVIDER, {
|
|
62
|
+
collect: (signal) => observations.collect(signal),
|
|
63
|
+
wake: observations.wake,
|
|
64
|
+
async resources(signal) {
|
|
65
|
+
const resources = await childResources(agent, context.sessionId, signal, () => disposed, history);
|
|
66
|
+
return disposed ? [] : resources;
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
registerStart(context, agent, admission);
|
|
70
|
+
registerControlTools(context, agent, observations, warmObservations, admission);
|
|
71
|
+
registerWait(context, agent, observations, history);
|
|
72
|
+
registerQueryTools(context, agent);
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
disposed = true;
|
|
76
|
+
void native.close().catch(() => { });
|
|
77
|
+
registration.unsubscribe();
|
|
78
|
+
parentUnsubscribe?.();
|
|
79
|
+
warmObservations.delete(context.sessionId);
|
|
80
|
+
observations.close();
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
return async () => {
|
|
84
|
+
disposed = true;
|
|
85
|
+
const closing = native.close();
|
|
86
|
+
registration.unsubscribe();
|
|
87
|
+
parentUnsubscribe?.();
|
|
88
|
+
warmObservations.delete(context.sessionId);
|
|
89
|
+
observations.close();
|
|
90
|
+
await closing;
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { type Agent, type AgentReasoningEffort, type AgentSessionInputReceipt, type ExecutionResult } from '@myagentroam/agent';
|
|
2
|
+
import type { ExtensionServiceKey, SessionExtensionContext } from '@myagentroam/agent/extensions';
|
|
3
|
+
import { SessionObservations } from './observations.js';
|
|
4
|
+
import { type StartAdmission } from './start.js';
|
|
5
|
+
import { type WaitInput } from './wait.js';
|
|
6
|
+
import { type ChildSnapshot } from './snapshot.js';
|
|
7
|
+
export interface NativeSpawnInput {
|
|
8
|
+
readonly prompt: string;
|
|
9
|
+
readonly description?: string;
|
|
10
|
+
readonly role?: 'general-purpose' | 'explore';
|
|
11
|
+
readonly modelId?: string;
|
|
12
|
+
readonly reasoningEffort?: AgentReasoningEffort;
|
|
13
|
+
readonly background?: boolean;
|
|
14
|
+
readonly waitFor?: 'start' | 'completion';
|
|
15
|
+
readonly signal?: AbortSignal;
|
|
16
|
+
readonly turnSignal?: AbortSignal;
|
|
17
|
+
}
|
|
18
|
+
export interface NativeWaitInput extends WaitInput {
|
|
19
|
+
readonly signal?: AbortSignal;
|
|
20
|
+
}
|
|
21
|
+
export interface NativeAgentSnapshot extends Record<string, unknown> {
|
|
22
|
+
readonly agentId: string;
|
|
23
|
+
readonly description: string;
|
|
24
|
+
readonly status: 'idle' | 'not-started' | 'running' | 'completed' | 'failed' | 'cancelled' | 'interrupted';
|
|
25
|
+
readonly executionId?: string;
|
|
26
|
+
readonly role?: 'general-purpose' | 'explore';
|
|
27
|
+
readonly extensionId?: string;
|
|
28
|
+
readonly modelId?: string;
|
|
29
|
+
readonly modelName?: string;
|
|
30
|
+
readonly reasoningEffort?: string;
|
|
31
|
+
readonly summary?: string;
|
|
32
|
+
readonly turnId?: string;
|
|
33
|
+
readonly receipt?: AgentSessionInputReceipt;
|
|
34
|
+
readonly changedFiles?: readonly string[];
|
|
35
|
+
readonly latestMessage?: ChildSnapshot['latestMessage'];
|
|
36
|
+
readonly latestActivity?: ChildSnapshot['latestActivity'];
|
|
37
|
+
readonly verification?: readonly string[];
|
|
38
|
+
readonly evidence?: readonly {
|
|
39
|
+
path: string;
|
|
40
|
+
startLine?: number;
|
|
41
|
+
endLine?: number;
|
|
42
|
+
}[];
|
|
43
|
+
readonly errorCode?: string;
|
|
44
|
+
readonly errorMessage?: string;
|
|
45
|
+
readonly permissionStop?: ExecutionResult['permissionStop'];
|
|
46
|
+
readonly waitOutcome?: 'snapshot' | 'message' | 'completion' | 'timeout' | 'interrupted';
|
|
47
|
+
}
|
|
48
|
+
export interface NativeAgentGroup extends Record<string, unknown> {
|
|
49
|
+
readonly mode: 'any' | 'all';
|
|
50
|
+
readonly waitFor: 'message' | 'completion';
|
|
51
|
+
readonly waitOutcome: 'snapshot' | 'message' | 'completion' | 'timeout' | 'interrupted';
|
|
52
|
+
readonly agents: readonly NativeAgentSnapshot[];
|
|
53
|
+
readonly pendingAgentIds: readonly string[];
|
|
54
|
+
}
|
|
55
|
+
export interface NativeSubagentClient {
|
|
56
|
+
spawn(input: NativeSpawnInput): Promise<NativeAgentSnapshot>;
|
|
57
|
+
wait(input: NativeWaitInput): Promise<NativeAgentSnapshot | NativeAgentGroup>;
|
|
58
|
+
list(input?: {
|
|
59
|
+
signal?: AbortSignal;
|
|
60
|
+
}): Promise<readonly NativeAgentSnapshot[]>;
|
|
61
|
+
inspect(input: {
|
|
62
|
+
agentId: string;
|
|
63
|
+
signal?: AbortSignal;
|
|
64
|
+
}): Promise<NativeAgentSnapshot>;
|
|
65
|
+
message(input: {
|
|
66
|
+
agentId: string;
|
|
67
|
+
message: string;
|
|
68
|
+
delivery?: 'append' | 'replace';
|
|
69
|
+
signal?: AbortSignal;
|
|
70
|
+
}): Promise<Record<string, unknown>>;
|
|
71
|
+
cancel(input: {
|
|
72
|
+
agentId: string;
|
|
73
|
+
executionId?: string;
|
|
74
|
+
signal?: AbortSignal;
|
|
75
|
+
}): Promise<NativeAgentSnapshot>;
|
|
76
|
+
close(): Promise<void>;
|
|
77
|
+
}
|
|
78
|
+
export interface NativeSubagentService {
|
|
79
|
+
open(): NativeSubagentClient;
|
|
80
|
+
}
|
|
81
|
+
export type ExtensionAgentSnapshot = NativeAgentSnapshot;
|
|
82
|
+
export type ExtensionAgentManySnapshot = NativeAgentGroup;
|
|
83
|
+
export type ExtensionAgentSpawnInput = NativeSpawnInput;
|
|
84
|
+
export type ExtensionAgentWaitInput = NativeWaitInput;
|
|
85
|
+
export type ExtensionAgentsApi = NativeSubagentClient;
|
|
86
|
+
export declare const SUBAGENT_NATIVE_SERVICE: ExtensionServiceKey<NativeSubagentService>;
|
|
87
|
+
/** Each native client owns an independent observation cursor, never a Session Execution. */
|
|
88
|
+
export declare function nativeSubagentService(context: SessionExtensionContext, agent: Agent, admission: StartAdmission, warmObservations: ReadonlyMap<string, SessionObservations>, parentWorkspace: string, historyReader?: Pick<Agent, 'sessionHistory'>): {
|
|
89
|
+
service: NativeSubagentService;
|
|
90
|
+
close(): Promise<void>;
|
|
91
|
+
};
|