@myagentroam/agent 0.11.18 → 0.11.20

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.
@@ -14,9 +14,12 @@ export function normalizeContextGcSubagentSnapshot(modelContent, completedPayloa
14
14
  export function contextGcCompletedSubagentTurnId(snapshot) {
15
15
  if (snapshot.status !== 'completed' ||
16
16
  !isNonemptyString(snapshot.summary) ||
17
- snapshot.latestMessage?.phase !== 'final_answer' ||
18
17
  (snapshot.deliveryStatus !== undefined && snapshot.deliveryStatus !== 'applied'))
19
18
  return undefined;
19
+ if (snapshot.latestMessage === undefined)
20
+ return isNonemptyString(snapshot.turnId) ? snapshot.turnId : undefined;
21
+ if (snapshot.latestMessage.phase !== 'final_answer')
22
+ return undefined;
20
23
  const turnId = snapshot.latestMessage.turnId;
21
24
  return snapshot.turnId === undefined || snapshot.turnId === turnId ? turnId : undefined;
22
25
  }
@@ -34,7 +37,10 @@ export function contextGcSubagentPriorFinalIsRetained(source, retained) {
34
37
  retained.agentId === source.agentId &&
35
38
  retained.description === source.description &&
36
39
  contextGcCompletedSubagentTurnId(retained) === source.latestMessage.turnId &&
37
- stableJson(retained.latestMessage) === stableJson(source.latestMessage));
40
+ (stableJson(retained.latestMessage) === stableJson(source.latestMessage) ||
41
+ (retained.latestMessage === undefined &&
42
+ source.latestMessage.truncated !== true &&
43
+ retained.summary === source.latestMessage.text)));
38
44
  }
39
45
  export function contextGcSubagentSnapshotIsSuperseded(source, terminal, retainedPriorFinal) {
40
46
  const terminalTurnId = contextGcCompletedSubagentTurnId(terminal);
@@ -195,8 +201,10 @@ function parseContextGcSubagentSnapshot(value) {
195
201
  !isOptionalStringArray(parsed.verification) ||
196
202
  !isOptionalSubagentEvidence(parsed.evidence))
197
203
  return undefined;
198
- const receiptCount = [parsed.messageId, parsed.turnId, parsed.deliveryStatus].filter((item) => item !== undefined).length;
199
- if (receiptCount !== 0 && receiptCount !== 3)
204
+ if ((parsed.messageId !== undefined || parsed.deliveryStatus !== undefined) &&
205
+ (parsed.messageId === undefined ||
206
+ parsed.turnId === undefined ||
207
+ parsed.deliveryStatus === undefined))
200
208
  return undefined;
201
209
  const latestMessage = parseContextGcSubagentLatestMessage(parsed.latestMessage);
202
210
  if (parsed.latestMessage !== undefined && !latestMessage)
@@ -75,10 +75,6 @@ export function renderSubagentUpdate(snapshot, truncated = false) {
75
75
  field('summary', snapshot.summary);
76
76
  for (const path of snapshot.changedFiles ?? [])
77
77
  field('changed_file', path);
78
- for (const text of snapshot.verification ?? [])
79
- field('verification', text);
80
- for (const { path, startLine, endLine } of snapshot.evidence ?? [])
81
- field('evidence', path, { startLine, endLine });
82
78
  if (snapshot.latestActivity)
83
79
  field('activity', '', snapshot.latestActivity);
84
80
  return root + ' truncated="' + String(truncated) + '">\n' + lines.join('') + close;
@@ -216,7 +216,9 @@ export class SubagentScheduler {
216
216
  agentId: task.agentId,
217
217
  description: task.input.description,
218
218
  status: task.status,
219
- ...(task.result ? { ...task.result } : {}),
219
+ ...(task.result
220
+ ? { summary: task.result.summary, changedFiles: [...task.result.changedFiles] }
221
+ : {}),
220
222
  ...(task.errorCode ? { errorCode: task.errorCode } : {}),
221
223
  ...(task.errorMessage ? { errorMessage: task.errorMessage } : {})
222
224
  };
@@ -191,11 +191,7 @@ export class SubagentSessionController {
191
191
  truncated: snapshot.latestMessage?.truncated === true ||
192
192
  (includeTerminalDetails &&
193
193
  (snapshot.summary !== state.summary ||
194
- (snapshot.changedFiles?.length ?? 0) < state.changedFiles.length ||
195
- (snapshot.evidence?.length ?? 0) < state.evidence.length ||
196
- (snapshot.verification?.length ?? 0) < state.verification.length ||
197
- (snapshot.verification?.some((value, index) => value !== state.verification[index]) ??
198
- false))),
194
+ (snapshot.changedFiles?.length ?? 0) < state.changedFiles.length)),
199
195
  acknowledge: () => {
200
196
  state.observedMessageRevision = Math.max(state.observedMessageRevision, messageRevision);
201
197
  if (includeTerminalDetails)
@@ -1211,6 +1207,17 @@ export class SubagentSessionController {
1211
1207
  : full
1212
1208
  ? { ...state.latestMessage }
1213
1209
  : projectLatestMessage(state.latestMessage, terminal);
1210
+ const summary = !includeTerminalDetails || state.summary === undefined
1211
+ ? undefined
1212
+ : full
1213
+ ? state.summary
1214
+ : truncateUtf8(state.summary, TOOL_EXECUTION_LIMITS.subagentSummaryMaxBytes);
1215
+ const omitDuplicateMessage = !full &&
1216
+ terminal &&
1217
+ latestMessage?.phase === 'final_answer' &&
1218
+ summary !== undefined &&
1219
+ summary === state.latestMessage?.text &&
1220
+ (state.receipt === undefined || state.receipt.turnId === latestMessage.turnId);
1214
1221
  return {
1215
1222
  agentId: state.agentId,
1216
1223
  description: state.description,
@@ -1225,20 +1232,15 @@ export class SubagentSessionController {
1225
1232
  ? { permissionStop: state.permissionStop }
1226
1233
  : {}),
1227
1234
  ...state.receipt,
1235
+ ...(omitDuplicateMessage ? { turnId: latestMessage.turnId } : {}),
1228
1236
  ...(state.modelId === undefined ? {} : { modelId: state.modelId }),
1229
1237
  ...(state.modelName === undefined ? {} : { modelName: state.modelName }),
1230
1238
  ...(state.reasoningEffort === undefined ? {} : { reasoningEffort: state.reasoningEffort }),
1231
- ...(latestMessage === undefined ? {} : { latestMessage }),
1239
+ ...(latestMessage === undefined || omitDuplicateMessage ? {} : { latestMessage }),
1232
1240
  ...(!includeLatestActivity || state.latestActivity === undefined
1233
1241
  ? {}
1234
1242
  : { latestActivity: { ...state.latestActivity } }),
1235
- ...(!includeTerminalDetails || state.summary === undefined
1236
- ? {}
1237
- : {
1238
- summary: full
1239
- ? state.summary
1240
- : truncateUtf8(state.summary, TOOL_EXECUTION_LIMITS.subagentSummaryMaxBytes)
1241
- }),
1243
+ ...(summary === undefined ? {} : { summary }),
1242
1244
  ...(!includeTerminalDetails || !terminal || state.changedFiles.length === 0
1243
1245
  ? {}
1244
1246
  : {
@@ -1246,22 +1248,12 @@ export class SubagentSessionController {
1246
1248
  ? [...state.changedFiles]
1247
1249
  : state.changedFiles.slice(0, TOOL_EXECUTION_LIMITS.subagentChangedFilesMaxItems)
1248
1250
  }),
1249
- ...(!includeTerminalDetails || !terminal || state.verification.length === 0
1251
+ ...(!full || !includeTerminalDetails || !terminal || state.verification.length === 0
1250
1252
  ? {}
1251
- : {
1252
- verification: full
1253
- ? [...state.verification]
1254
- : state.verification
1255
- .slice(0, TOOL_EXECUTION_LIMITS.subagentVerificationMaxItems)
1256
- .map((text) => truncateUtf8(text, 2_000))
1257
- }),
1258
- ...(!includeTerminalDetails || !terminal || state.evidence.length === 0
1253
+ : { verification: [...state.verification] }),
1254
+ ...(!full || !includeTerminalDetails || !terminal || state.evidence.length === 0
1259
1255
  ? {}
1260
- : {
1261
- evidence: (full
1262
- ? state.evidence
1263
- : state.evidence.slice(0, TOOL_EXECUTION_LIMITS.subagentEvidenceMaxItems)).map((item) => ({ ...item }))
1264
- }),
1256
+ : { evidence: state.evidence.map((item) => ({ ...item })) }),
1265
1257
  ...(state.errorCode === undefined ? {} : { errorCode: state.errorCode }),
1266
1258
  ...(state.errorMessage === undefined ? {} : { errorMessage: state.errorMessage })
1267
1259
  };
@@ -5,7 +5,7 @@ export const agentWaitToolDefinition = {
5
5
  name: 'agent_wait',
6
6
  allowedCallers: ['direct'],
7
7
  parallelSafety: 'serial',
8
- description: 'Read or wait a bounded time for a child agent result. Unread child messages and terminal results are supplied automatically before the next model request. Wait only when the next local step depends on the child result; otherwise continue useful non-overlapping work. waitFor defaults to "completion"; use "message" only when a fresh public commentary/final message would change the next decision. Omit agentId to wait for whichever live child returns first, matching Codex-style untargeted waiting and avoiding UUID transcription; provide the exact agentId returned by agent_start only when observing a specific child. If no child is live, untargeted waiting reads the most recently created child. For an exec processId, use exec_wait instead (tools.exec_wait in Code Mode). Omitting waitMs waits up to 30 seconds by default; waitMs=0 returns the current snapshot immediately. Positive waits range up to 5 minutes, and positive values below 10 seconds are raised to 10 seconds. When blocked on a live child result, prefer one 300000 ms completion wait rather than repeated short waits. Use agentIds with mode any (default) or all to wait for an explicit non-empty set of up to 8 distinct child IDs; never combine agentId and agentIds or use mode without agentIds. mode and waitFor are independent. A group uses one deadline and returns mode, waitFor, waitOutcome, agents in input order, and pendingAgentIds. Failed, cancelled and interrupted turns also satisfy completion; terminal state satisfies message waits too. Group waitMs=0 returns only snapshots without consuming messages. Single-target and untargeted results include waitOutcome as snapshot, message, completion, or timeout plus the real agentId and description. A message, timeout with unread progress, or first terminal completion result includes the newly observed latest public commentary/final message; snapshots and repeated observations omit previously observed message text. latestActivity can still identify a public message or bounded tool started/completed/failed status. A queued or running result is not completion. A message wait consumes only the latest unread public message in the current Session runtime; tool activity does not wake it, and parent cancellation preserves unread progress for a later Execution. waitOutcome distinguishes snapshot, message, completion, and timeout. A foreground steer may return interrupted with reason=steer without cancelling any child. Do not use message waits as heartbeat checks or request progress merely to confirm that a child is still running. First terminal results include bounded summary, changedFiles, verification, and read evidence with path/line ranges; use that evidence to avoid repeating the full exploration, while independently checking consequential edits and claims.',
8
+ description: 'Read or wait a bounded time for a child agent result. Unread child messages and terminal results are supplied automatically before the next model request. Wait only when the next local step depends on the child result; otherwise continue useful non-overlapping work. waitFor defaults to "completion"; use "message" only when a fresh public commentary/final message would change the next decision. Omit agentId to wait for whichever live child returns first, matching Codex-style untargeted waiting and avoiding UUID transcription; provide the exact agentId returned by agent_start only when observing a specific child. If no child is live, untargeted waiting reads the most recently created child. For an exec processId, use exec_wait instead (tools.exec_wait in Code Mode). Omitting waitMs waits up to 30 seconds by default; waitMs=0 returns the current snapshot immediately. Positive waits range up to 5 minutes, and positive values below 10 seconds are raised to 10 seconds. When blocked on a live child result, prefer one 300000 ms completion wait rather than repeated short waits. Use agentIds with mode any (default) or all to wait for an explicit non-empty set of up to 8 distinct child IDs; never combine agentId and agentIds or use mode without agentIds. mode and waitFor are independent. A group uses one deadline and returns mode, waitFor, waitOutcome, agents in input order, and pendingAgentIds. Failed, cancelled and interrupted turns also satisfy completion; terminal state satisfies message waits too. Group waitMs=0 returns only snapshots without consuming messages. Single-target and untargeted results include waitOutcome as snapshot, message, completion, or timeout plus the real agentId and description. A message or timeout with unread progress includes the newly observed public message; first terminal results follow the result projection below. Snapshots and repeated observations omit previously observed message text. latestActivity can still identify a public message or bounded tool started/completed/failed status. A queued or running result is not completion. A message wait consumes only the latest unread public message in the current Session runtime; tool activity does not wake it, and parent cancellation preserves unread progress for a later Execution. waitOutcome distinguishes snapshot, message, completion, and timeout. A foreground steer may return interrupted with reason=steer without cancelling any child. Do not use message waits as heartbeat checks or request progress merely to confirm that a child is still running. First terminal results retain bounded summary and changedFiles, without automatic command or read records. A final latestMessage fully covered by the complete summary is omitted while its turnId is retained. Use public child conclusions and relevant file references to avoid repeating the full exploration, while independently checking consequential edits and claims.',
9
9
  inputSchema: {
10
10
  type: 'object',
11
11
  properties: {
@@ -31,7 +31,10 @@ export async function executeTodoWrite(arguments_, context) {
31
31
  const value = parseTodoWriteInput(arguments_);
32
32
  const todo = context.todo.write(value);
33
33
  await context.emit({ type: 'todo.updated', revision: todo.revision, items: todo.items });
34
- return { content: JSON.stringify(todo), data: todo };
34
+ return {
35
+ content: JSON.stringify({ revision: todo.revision, count: todo.items.length }),
36
+ data: todo
37
+ };
35
38
  }
36
39
  function parseTodoWriteInput(value) {
37
40
  if (!value || typeof value !== 'object' || Array.isArray(value))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myagentroam/agent",
3
- "version": "0.11.18",
3
+ "version": "0.11.20",
4
4
  "description": "Embeddable MAR coding agent SDK and CLI.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",