@myagentroam/agent 0.11.38 → 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
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
import { AgentError } from '@myagentroam/agent';
|
|
2
|
+
import { SessionObservations } from './observations.js';
|
|
3
|
+
import { startChild } from './start.js';
|
|
4
|
+
import { sendChild, stopChild } from './control.js';
|
|
5
|
+
import { waitForChild } from './wait.js';
|
|
6
|
+
import { nativeChildSnapshot, projectChildEvent } from './snapshot.js';
|
|
7
|
+
import { historicalExecutionStatus } from './history.js';
|
|
8
|
+
export const SUBAGENT_NATIVE_SERVICE = {
|
|
9
|
+
id: 'subagent.native',
|
|
10
|
+
scope: 'session',
|
|
11
|
+
bindConsumer: (service, consumer) => service.bind(consumer)
|
|
12
|
+
};
|
|
13
|
+
/** Each native client owns an independent observation cursor, never a Session Execution. */
|
|
14
|
+
export function nativeSubagentService(context, agent, admission, warmObservations, parentWorkspace, historyReader = agent) {
|
|
15
|
+
const clients = new Set();
|
|
16
|
+
let closed = false;
|
|
17
|
+
return {
|
|
18
|
+
service: {
|
|
19
|
+
open() {
|
|
20
|
+
throw new AgentError('MAR_AGENT_EXTENSION_SERVICE_SCOPE', 'A consumer scope is required.');
|
|
21
|
+
},
|
|
22
|
+
bind(consumer) {
|
|
23
|
+
return {
|
|
24
|
+
open() {
|
|
25
|
+
if (closed)
|
|
26
|
+
throw new AgentError('MAR_AGENT_EXTENSION_DISPOSED', 'Subagent service is closed.');
|
|
27
|
+
const observations = new SessionObservations(true, historyReader);
|
|
28
|
+
const pending = new Set();
|
|
29
|
+
const closingSignal = new AbortController();
|
|
30
|
+
let clientClosed = false;
|
|
31
|
+
const observe = (session) => {
|
|
32
|
+
if (!clientClosed &&
|
|
33
|
+
session.source.parentSessionId === context.sessionId &&
|
|
34
|
+
session.workspace === parentWorkspace)
|
|
35
|
+
observations.observe(session);
|
|
36
|
+
};
|
|
37
|
+
const registration = agent.observeSessionExecutions(observe);
|
|
38
|
+
for (const session of registration.sessions)
|
|
39
|
+
observe(session);
|
|
40
|
+
let closing;
|
|
41
|
+
const close = () => (closing ??= (async () => {
|
|
42
|
+
clientClosed = true;
|
|
43
|
+
closingSignal.abort();
|
|
44
|
+
registration.unsubscribe();
|
|
45
|
+
await Promise.allSettled([...pending]);
|
|
46
|
+
observations.close();
|
|
47
|
+
clients.delete(close);
|
|
48
|
+
})());
|
|
49
|
+
clients.add(close);
|
|
50
|
+
try {
|
|
51
|
+
consumer.onDispose(close);
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
void close().catch(() => { });
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
const run = (action, signal) => {
|
|
58
|
+
if (clientClosed)
|
|
59
|
+
throw new AgentError('MAR_AGENT_EXTENSION_DISPOSED', 'Subagent client is closed.');
|
|
60
|
+
const effectiveSignal = signal
|
|
61
|
+
? AbortSignal.any([signal, closingSignal.signal])
|
|
62
|
+
: closingSignal.signal;
|
|
63
|
+
const operation = consumer.run(action, effectiveSignal);
|
|
64
|
+
pending.add(operation);
|
|
65
|
+
void operation.finally(() => pending.delete(operation)).catch(() => { });
|
|
66
|
+
return operation;
|
|
67
|
+
};
|
|
68
|
+
return {
|
|
69
|
+
async spawn(input) {
|
|
70
|
+
if (!input ||
|
|
71
|
+
typeof input.prompt !== 'string' ||
|
|
72
|
+
!input.prompt.trim() ||
|
|
73
|
+
(input.description !== undefined && !input.description.trim()) ||
|
|
74
|
+
(input.role !== undefined &&
|
|
75
|
+
!['general-purpose', 'explore'].includes(input.role)) ||
|
|
76
|
+
(input.waitFor !== undefined &&
|
|
77
|
+
!['start', 'completion'].includes(input.waitFor)) ||
|
|
78
|
+
(input.background !== undefined && typeof input.background !== 'boolean'))
|
|
79
|
+
throw new AgentError('MAR_AGENT_EXTENSION_AGENT_INPUT_INVALID', 'Agent spawn input is invalid.');
|
|
80
|
+
return run(async (call) => {
|
|
81
|
+
const started = await startChild(context, agent, admission, {
|
|
82
|
+
prompt: input.prompt,
|
|
83
|
+
description: input.description ?? 'Extension agent',
|
|
84
|
+
role: input.role ?? 'general-purpose',
|
|
85
|
+
...(input.turnSignal === undefined ? {} : { turnSignal: input.turnSignal }),
|
|
86
|
+
...(input.modelId === undefined ? {} : { modelId: input.modelId }),
|
|
87
|
+
...(input.reasoningEffort === undefined
|
|
88
|
+
? {}
|
|
89
|
+
: { reasoningEffort: input.reasoningEffort })
|
|
90
|
+
}, call, 'native');
|
|
91
|
+
if (!started.execution ||
|
|
92
|
+
!(input.waitFor === 'completion' ||
|
|
93
|
+
(input.waitFor === undefined && input.background === false)))
|
|
94
|
+
return started.data;
|
|
95
|
+
const result = await waitForChild(context, agent, observations, { agentId: String(started.data.agentId), untilSettled: true }, call, 'native', observations, historyReader);
|
|
96
|
+
return { ...started.data, ...result.data };
|
|
97
|
+
}, input.signal);
|
|
98
|
+
},
|
|
99
|
+
async wait(input) {
|
|
100
|
+
if (!input || typeof input !== 'object')
|
|
101
|
+
throw new AgentError('MAR_AGENT_EXTENSION_AGENT_INPUT_INVALID', 'Agent wait input is invalid.');
|
|
102
|
+
return run(async (call) => (await waitForChild(context, agent, observations, input, call, 'native', observations, historyReader)).data, input.signal);
|
|
103
|
+
},
|
|
104
|
+
async list(input = {}) {
|
|
105
|
+
return run(async (call) => {
|
|
106
|
+
const parent = await agent.getSession(context.sessionId);
|
|
107
|
+
const children = [];
|
|
108
|
+
const live = new Map();
|
|
109
|
+
const registration = agent.observeSessionExecutions((session) => {
|
|
110
|
+
live.set(session.id, session);
|
|
111
|
+
});
|
|
112
|
+
for (const session of registration.sessions)
|
|
113
|
+
live.set(session.id, session);
|
|
114
|
+
let cursor;
|
|
115
|
+
try {
|
|
116
|
+
do {
|
|
117
|
+
call.signal.throwIfAborted();
|
|
118
|
+
const page = await agent.listSessions({
|
|
119
|
+
parentSessionId: context.sessionId,
|
|
120
|
+
limit: 100,
|
|
121
|
+
...(cursor ? { cursor } : {})
|
|
122
|
+
});
|
|
123
|
+
for (const session of page.sessions)
|
|
124
|
+
if (session.workspace === parent.workspace) {
|
|
125
|
+
call.signal.throwIfAborted();
|
|
126
|
+
const subscription = live.get(session.id)?.subscribe(() => { });
|
|
127
|
+
const terminalEvent = subscription?.terminalEvent;
|
|
128
|
+
const active = subscription?.activeExecutionId;
|
|
129
|
+
subscription?.unsubscribe();
|
|
130
|
+
let history;
|
|
131
|
+
try {
|
|
132
|
+
history = await historicalExecutionStatus(agent, session.id, call.signal, {
|
|
133
|
+
details: true,
|
|
134
|
+
history: historyReader,
|
|
135
|
+
...(active ? { activeExecutionId: active } : {})
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
if (error instanceof Error &&
|
|
140
|
+
'code' in error &&
|
|
141
|
+
error.code === 'MAR_AGENT_SESSION_NOT_FOUND')
|
|
142
|
+
continue;
|
|
143
|
+
throw error;
|
|
144
|
+
}
|
|
145
|
+
let status = active
|
|
146
|
+
? 'running'
|
|
147
|
+
: history.status;
|
|
148
|
+
let currentExecutionId = active ?? history.executionId;
|
|
149
|
+
if (terminalEvent)
|
|
150
|
+
status = terminalEvent.type.slice('execution.'.length);
|
|
151
|
+
else if (!active) {
|
|
152
|
+
const latest = live.get(session.id)?.subscribe(() => { });
|
|
153
|
+
if (latest?.activeExecutionId && !latest.terminalEvent) {
|
|
154
|
+
status = 'running';
|
|
155
|
+
currentExecutionId = latest.activeExecutionId;
|
|
156
|
+
}
|
|
157
|
+
else if (latest?.terminalEvent) {
|
|
158
|
+
status = latest.terminalEvent.type.slice('execution.'.length);
|
|
159
|
+
currentExecutionId = latest.activeExecutionId;
|
|
160
|
+
}
|
|
161
|
+
latest?.unsubscribe();
|
|
162
|
+
}
|
|
163
|
+
const observed = observations.terminal(session.id);
|
|
164
|
+
if (status !== 'running' &&
|
|
165
|
+
!terminalEvent &&
|
|
166
|
+
observed &&
|
|
167
|
+
observed.executionId !== history.executionId) {
|
|
168
|
+
status = observed.type.slice('execution.'.length);
|
|
169
|
+
currentExecutionId = observed.executionId;
|
|
170
|
+
}
|
|
171
|
+
const details = history.executionId === currentExecutionId
|
|
172
|
+
? history.details
|
|
173
|
+
: currentExecutionId
|
|
174
|
+
? nativeChildSnapshot(observations.snapshot(session.id, currentExecutionId))
|
|
175
|
+
: undefined;
|
|
176
|
+
const visibleDetails = status === 'running' && details
|
|
177
|
+
? {
|
|
178
|
+
...(details.latestMessage
|
|
179
|
+
? { latestMessage: details.latestMessage }
|
|
180
|
+
: {}),
|
|
181
|
+
...(details.latestActivity
|
|
182
|
+
? { latestActivity: details.latestActivity }
|
|
183
|
+
: {})
|
|
184
|
+
}
|
|
185
|
+
: details;
|
|
186
|
+
children.push({
|
|
187
|
+
createdAt: session.createdAt,
|
|
188
|
+
snapshot: {
|
|
189
|
+
agentId: session.id,
|
|
190
|
+
status,
|
|
191
|
+
description: session.source.type === 'subagent'
|
|
192
|
+
? session.source.description
|
|
193
|
+
: session.title,
|
|
194
|
+
...(currentExecutionId === undefined
|
|
195
|
+
? {}
|
|
196
|
+
: { executionId: currentExecutionId }),
|
|
197
|
+
...visibleDetails,
|
|
198
|
+
...(history.executionId === currentExecutionId &&
|
|
199
|
+
history.errorCode !== undefined
|
|
200
|
+
? {
|
|
201
|
+
errorCode: history.errorCode,
|
|
202
|
+
...(history.errorMessage === undefined
|
|
203
|
+
? {}
|
|
204
|
+
: { errorMessage: history.errorMessage })
|
|
205
|
+
}
|
|
206
|
+
: {}),
|
|
207
|
+
...(history.executionId === currentExecutionId &&
|
|
208
|
+
history.permissionStop
|
|
209
|
+
? { permissionStop: history.permissionStop }
|
|
210
|
+
: {}),
|
|
211
|
+
...(observed?.type === 'execution.failed' &&
|
|
212
|
+
observed.executionId === currentExecutionId
|
|
213
|
+
? {
|
|
214
|
+
errorCode: observed.code,
|
|
215
|
+
...(observed.message === undefined
|
|
216
|
+
? {}
|
|
217
|
+
: { errorMessage: observed.message })
|
|
218
|
+
}
|
|
219
|
+
: {}),
|
|
220
|
+
...(session.modelId === undefined
|
|
221
|
+
? {}
|
|
222
|
+
: { modelId: session.modelId }),
|
|
223
|
+
...(session.modelName === undefined
|
|
224
|
+
? {}
|
|
225
|
+
: { modelName: session.modelName }),
|
|
226
|
+
...(session.reasoningEffort === undefined
|
|
227
|
+
? {}
|
|
228
|
+
: { reasoningEffort: session.reasoningEffort }),
|
|
229
|
+
...(session.source.type === 'subagent'
|
|
230
|
+
? {
|
|
231
|
+
role: session.source.role,
|
|
232
|
+
...(session.source.extensionId === undefined
|
|
233
|
+
? {}
|
|
234
|
+
: { extensionId: session.source.extensionId })
|
|
235
|
+
}
|
|
236
|
+
: {})
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
cursor = page.nextCursor;
|
|
241
|
+
} while (cursor);
|
|
242
|
+
}
|
|
243
|
+
finally {
|
|
244
|
+
registration.unsubscribe();
|
|
245
|
+
}
|
|
246
|
+
return children
|
|
247
|
+
.sort((left, right) => left.createdAt.localeCompare(right.createdAt))
|
|
248
|
+
.map(({ snapshot }) => snapshot);
|
|
249
|
+
}, input.signal);
|
|
250
|
+
},
|
|
251
|
+
async inspect(input) {
|
|
252
|
+
if (!input || typeof input.agentId !== 'string' || !input.agentId)
|
|
253
|
+
throw new AgentError('MAR_AGENT_EXTENSION_AGENT_INPUT_INVALID', 'Agent target is invalid.');
|
|
254
|
+
return run(async (call) => {
|
|
255
|
+
const parent = await agent.getSession(context.sessionId);
|
|
256
|
+
const child = await agent.getSession(input.agentId);
|
|
257
|
+
if (child.workspace !== parent.workspace ||
|
|
258
|
+
child.source.parentSessionId !== parent.id)
|
|
259
|
+
throw new AgentError('MAR_AGENT_SUBAGENT_NOT_FOUND', 'Session is not available.');
|
|
260
|
+
call.signal.throwIfAborted();
|
|
261
|
+
try {
|
|
262
|
+
const state = (await waitForChild(context, agent, observations, { agentId: child.id, waitMs: 0 }, call, 'native', observations, historyReader)).data;
|
|
263
|
+
const pages = [];
|
|
264
|
+
let cursor;
|
|
265
|
+
if (state.executionId)
|
|
266
|
+
do {
|
|
267
|
+
call.signal.throwIfAborted();
|
|
268
|
+
const page = await historyReader.sessionHistory(child.id, {
|
|
269
|
+
limit: 100,
|
|
270
|
+
...(cursor === undefined ? {} : { cursor })
|
|
271
|
+
});
|
|
272
|
+
call.signal.throwIfAborted();
|
|
273
|
+
const events = page.entries.flatMap((entry) => entry.kind === 'event' && entry.event.executionId === state.executionId
|
|
274
|
+
? [entry.event]
|
|
275
|
+
: []);
|
|
276
|
+
pages.push(events);
|
|
277
|
+
cursor = events.some((event) => event.type === 'execution.started')
|
|
278
|
+
? undefined
|
|
279
|
+
: page.nextCursor;
|
|
280
|
+
} while (cursor);
|
|
281
|
+
const full = { changedFiles: [] };
|
|
282
|
+
for (const events of pages.reverse())
|
|
283
|
+
for (const event of events)
|
|
284
|
+
projectChildEvent(full, event, true);
|
|
285
|
+
if (state.executionId) {
|
|
286
|
+
const live = observations.snapshot(child.id, state.executionId);
|
|
287
|
+
if (live.summary !== undefined) {
|
|
288
|
+
full.summary = live.summary;
|
|
289
|
+
if (live.turnId === undefined)
|
|
290
|
+
delete full.turnId;
|
|
291
|
+
else
|
|
292
|
+
full.turnId = live.turnId;
|
|
293
|
+
}
|
|
294
|
+
for (const file of live.changedFiles)
|
|
295
|
+
if (!full.changedFiles.includes(file))
|
|
296
|
+
full.changedFiles.push(file);
|
|
297
|
+
}
|
|
298
|
+
return {
|
|
299
|
+
...state,
|
|
300
|
+
...nativeChildSnapshot(full),
|
|
301
|
+
modelId: child.modelId,
|
|
302
|
+
description: child.source.type === 'subagent' ? child.source.description : child.title
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
catch (error) {
|
|
306
|
+
if (!(error instanceof AgentError) ||
|
|
307
|
+
error.code !== 'MAR_AGENT_SUBAGENT_EXECUTION_NOT_FOUND')
|
|
308
|
+
throw error;
|
|
309
|
+
return {
|
|
310
|
+
agentId: child.id,
|
|
311
|
+
status: 'idle',
|
|
312
|
+
modelId: child.modelId,
|
|
313
|
+
description: child.source.type === 'subagent' ? child.source.description : child.title
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
}, input.signal);
|
|
317
|
+
},
|
|
318
|
+
async message(input) {
|
|
319
|
+
if (!input ||
|
|
320
|
+
typeof input.agentId !== 'string' ||
|
|
321
|
+
!input.agentId ||
|
|
322
|
+
typeof input.message !== 'string' ||
|
|
323
|
+
!input.message.trim() ||
|
|
324
|
+
(input.delivery !== undefined && !['append', 'replace'].includes(input.delivery)))
|
|
325
|
+
throw new AgentError('MAR_AGENT_EXTENSION_AGENT_INPUT_INVALID', 'Agent message input is invalid.');
|
|
326
|
+
return run(async (call) => {
|
|
327
|
+
const result = await sendChild(context, agent, observations, warmObservations, admission, {
|
|
328
|
+
agentId: input.agentId,
|
|
329
|
+
content: input.message,
|
|
330
|
+
...(input.delivery ? { delivery: input.delivery } : {})
|
|
331
|
+
}, call, 'native');
|
|
332
|
+
return result;
|
|
333
|
+
}, input.signal);
|
|
334
|
+
},
|
|
335
|
+
async cancel(input) {
|
|
336
|
+
if (!input || typeof input.agentId !== 'string' || !input.agentId)
|
|
337
|
+
throw new AgentError('MAR_AGENT_EXTENSION_AGENT_INPUT_INVALID', 'Agent target is invalid.');
|
|
338
|
+
return run(async (call) => {
|
|
339
|
+
const result = await stopChild(context, agent, observations, input, call);
|
|
340
|
+
const child = await agent.getSession(input.agentId);
|
|
341
|
+
return {
|
|
342
|
+
...result,
|
|
343
|
+
description: child.source.type === 'subagent' ? child.source.description : child.title,
|
|
344
|
+
modelId: child.modelId
|
|
345
|
+
};
|
|
346
|
+
}, input.signal);
|
|
347
|
+
},
|
|
348
|
+
close
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
},
|
|
354
|
+
async close() {
|
|
355
|
+
closed = true;
|
|
356
|
+
await Promise.all([...clients].map((close) => close()));
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { Agent, AgentEvent, AgentSession } from '@myagentroam/agent';
|
|
2
|
+
import type { ExtensionSessionContextProvider } from '@myagentroam/agent/extensions';
|
|
3
|
+
import { type ChildSnapshot } from './snapshot.js';
|
|
4
|
+
/** One warm parent Session's live observations; Execution remains owned by Core. */
|
|
5
|
+
export declare class SessionObservations implements ExtensionSessionContextProvider {
|
|
6
|
+
#private;
|
|
7
|
+
readonly full: boolean;
|
|
8
|
+
private readonly agent?;
|
|
9
|
+
constructor(full?: boolean, agent?: Pick<Agent, "sessionHistory"> | undefined);
|
|
10
|
+
readonly wake: {
|
|
11
|
+
pending: () => boolean;
|
|
12
|
+
subscribe: (listener: () => void) => () => boolean;
|
|
13
|
+
};
|
|
14
|
+
observe(session: Pick<AgentSession, 'id' | 'subscribe'>): void;
|
|
15
|
+
/** Upward reports are collected at the parent's next natural round, without waking it. */
|
|
16
|
+
report(sessionId: string, executionId: string, value: string): boolean;
|
|
17
|
+
snapshot(sessionId: string, executionId: string): ChildSnapshot;
|
|
18
|
+
terminal(sessionId: string): AgentEvent | undefined;
|
|
19
|
+
rememberReceipt(sessionId: string, receipt: {
|
|
20
|
+
clientMessageId: string;
|
|
21
|
+
executionId: string;
|
|
22
|
+
}): void;
|
|
23
|
+
receipt(sessionId: string): {
|
|
24
|
+
clientMessageId: string;
|
|
25
|
+
executionId: string;
|
|
26
|
+
} | undefined;
|
|
27
|
+
capture(sessionId: string, executionId?: string): {
|
|
28
|
+
sessionId: string;
|
|
29
|
+
executionId: string;
|
|
30
|
+
snapshot: {
|
|
31
|
+
changedFilesTruncated?: boolean;
|
|
32
|
+
changedFiles?: string[];
|
|
33
|
+
turnId?: string;
|
|
34
|
+
summaryTruncated?: boolean;
|
|
35
|
+
summary?: string;
|
|
36
|
+
};
|
|
37
|
+
updates: {
|
|
38
|
+
permissionStop?: import("@myagentroam/agent").PermissionStop;
|
|
39
|
+
errorMessage?: string;
|
|
40
|
+
errorCode?: string;
|
|
41
|
+
truncated?: boolean;
|
|
42
|
+
final?: boolean;
|
|
43
|
+
kind: "message" | "terminal";
|
|
44
|
+
value: string;
|
|
45
|
+
}[];
|
|
46
|
+
acknowledge: () => void;
|
|
47
|
+
} | undefined;
|
|
48
|
+
/** Capture the currently unread versions without consuming later events. */
|
|
49
|
+
acknowledgement(sessionId: string): () => void;
|
|
50
|
+
/** Claim a terminal projection once per warm parent, including restored history. */
|
|
51
|
+
claimTerminal(sessionId: string, executionId: string): boolean;
|
|
52
|
+
collect(signal: AbortSignal): {
|
|
53
|
+
content: string;
|
|
54
|
+
acknowledge: () => void;
|
|
55
|
+
}[];
|
|
56
|
+
close(): void;
|
|
57
|
+
}
|