@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.
Files changed (161) hide show
  1. package/dist/cli/catalog-file.d.ts +2 -0
  2. package/dist/cli/main.js +11 -4
  3. package/dist/cli/subagent/control.d.ts +56 -0
  4. package/dist/cli/subagent/control.js +219 -0
  5. package/dist/cli/subagent/history.d.ts +17 -0
  6. package/dist/cli/subagent/history.js +85 -0
  7. package/dist/cli/subagent/index.d.ts +10 -0
  8. package/dist/cli/subagent/index.js +94 -0
  9. package/dist/cli/subagent/native.d.ts +91 -0
  10. package/dist/cli/subagent/native.js +359 -0
  11. package/dist/cli/subagent/observations.d.ts +57 -0
  12. package/dist/cli/subagent/observations.js +351 -0
  13. package/dist/cli/subagent/query.d.ts +4 -0
  14. package/dist/cli/subagent/query.js +114 -0
  15. package/dist/cli/subagent/resources.d.ts +3 -0
  16. package/dist/cli/subagent/resources.js +112 -0
  17. package/dist/cli/subagent/snapshot.d.ts +77 -0
  18. package/dist/cli/subagent/snapshot.js +127 -0
  19. package/dist/cli/subagent/start.d.ts +24 -0
  20. package/dist/cli/subagent/start.js +201 -0
  21. package/dist/cli/subagent/wait-output.d.ts +19 -0
  22. package/dist/cli/subagent/wait-output.js +56 -0
  23. package/dist/cli/subagent/wait.d.ts +175 -0
  24. package/dist/cli/subagent/wait.js +453 -0
  25. package/dist/extensions/contracts.d.ts +2 -5
  26. package/dist/extensions/manager.d.ts +0 -2
  27. package/dist/extensions/manager.js +1 -2
  28. package/dist/extensions/models.d.ts +3 -0
  29. package/dist/extensions/operation.d.ts +8 -0
  30. package/dist/extensions/operation.js +3 -0
  31. package/dist/extensions/services.d.ts +9 -1
  32. package/dist/extensions/services.js +26 -3
  33. package/dist/extensions/session-context.d.ts +18 -0
  34. package/dist/extensions/session-context.js +4 -0
  35. package/dist/extensions/session-input.d.ts +2 -2
  36. package/dist/extensions/session-input.js +3 -4
  37. package/dist/extensions/session-messages.d.ts +1 -1
  38. package/dist/extensions/session-tools.js +20 -3
  39. package/dist/extensions/session.d.ts +1 -4
  40. package/dist/extensions/session.js +2 -16
  41. package/dist/extensions/tools.js +21 -3
  42. package/dist/extensions.d.ts +5 -2
  43. package/dist/extensions.js +2 -1
  44. package/dist/host/local-agent-host.d.ts +2 -2
  45. package/dist/host/local-exec-tool.d.ts +1 -1
  46. package/dist/host/local-exec-tool.js +28 -3
  47. package/dist/host/local-tool-registry.d.ts +2 -2
  48. package/dist/index.d.ts +2 -2
  49. package/dist/model/configuration.d.ts +3 -1
  50. package/dist/model/configuration.js +1 -0
  51. package/dist/model/openai-responses.js +5 -0
  52. package/dist/model/responses-request.js +9 -0
  53. package/dist/prompts/index.js +1 -3
  54. package/dist/prompts/resources.d.ts +1 -5
  55. package/dist/prompts/resources.js +3 -12
  56. package/dist/prompts/subagent.d.ts +1 -1
  57. package/dist/prompts/subagent.js +1 -1
  58. package/dist/runtime/context/gc-candidates-web.d.ts +6 -0
  59. package/dist/runtime/context/gc-candidates-web.js +53 -1
  60. package/dist/runtime/context/gc-candidates.js +1 -9
  61. package/dist/runtime/context/gc.js +19 -11
  62. package/dist/runtime/context/projection.js +1 -0
  63. package/dist/runtime/events.d.ts +4 -3
  64. package/dist/runtime/execution-handle.d.ts +2 -0
  65. package/dist/runtime/wait.js +12 -2
  66. package/dist/sdk/agent.js +94 -5
  67. package/dist/sdk/execution-context-coordinator.d.ts +2 -3
  68. package/dist/sdk/execution-context-coordinator.js +3 -3
  69. package/dist/sdk/execution-input.d.ts +3 -4
  70. package/dist/sdk/execution-input.js +31 -25
  71. package/dist/sdk/execution-round-preparation.d.ts +1 -1
  72. package/dist/sdk/execution-round-preparation.js +4 -4
  73. package/dist/sdk/execution-tool-catalog.js +2 -10
  74. package/dist/sdk/execution-tool-scope.d.ts +1 -3
  75. package/dist/sdk/execution-tool-scope.js +10 -12
  76. package/dist/sdk/extension-models.js +3 -0
  77. package/dist/sdk/extension-session-launch.d.ts +3 -2
  78. package/dist/sdk/extension-session-launch.js +2 -3
  79. package/dist/sdk/extension-tools.js +0 -2
  80. package/dist/sdk/native-steer.d.ts +2 -2
  81. package/dist/sdk/native-steer.js +2 -2
  82. package/dist/sdk/session-composition.d.ts +2 -17
  83. package/dist/sdk/session-execution-factory.d.ts +2 -3
  84. package/dist/sdk/session-execution-factory.js +20 -114
  85. package/dist/sdk/session-execution.d.ts +13 -7
  86. package/dist/sdk/session-execution.js +11 -3
  87. package/dist/sdk/session-extension-messages.d.ts +1 -3
  88. package/dist/sdk/session-extension-messages.js +14 -9
  89. package/dist/sdk/session-extension-prompt.js +1 -3
  90. package/dist/sdk/session-maintenance.d.ts +1 -0
  91. package/dist/sdk/session-maintenance.js +16 -7
  92. package/dist/sdk/session-open.d.ts +2 -3
  93. package/dist/sdk/session-open.js +5 -24
  94. package/dist/sdk/session-runtime.d.ts +19 -8
  95. package/dist/sdk/session-runtime.js +36 -30
  96. package/dist/sdk/session.d.ts +3 -2
  97. package/dist/sdk/session.js +22 -89
  98. package/dist/sdk/types.d.ts +36 -0
  99. package/dist/session/catalog.d.ts +22 -1
  100. package/dist/session/catalog.js +102 -0
  101. package/dist/session/context-gc-checkpoint.js +30 -1
  102. package/dist/session/context-gc-contract.d.ts +7 -0
  103. package/dist/session/context-gc-replacements.d.ts +3 -0
  104. package/dist/session/context-gc-replacements.js +26 -0
  105. package/dist/session/store/contracts.d.ts +2 -2
  106. package/dist/session/store/jsonl/directory-index.d.ts +1 -1
  107. package/dist/session/store/jsonl/directory-index.js +18 -17
  108. package/dist/session/store/jsonl/history.js +1 -1
  109. package/dist/session/store/jsonl/index-transaction.js +2 -8
  110. package/dist/session/store/jsonl/jsonl-store.d.ts +1 -1
  111. package/dist/session/store/jsonl/jsonl-store.js +24 -9
  112. package/dist/session/types.d.ts +1 -0
  113. package/dist/tools/agent/sleep.js +1 -1
  114. package/dist/tools/callers.js +1 -12
  115. package/dist/tools/code-mode/dispatch.js +5 -2
  116. package/dist/tools/code-mode/index.d.ts +1 -1
  117. package/dist/tools/code-mode/index.js +2 -0
  118. package/dist/tools/contracts.d.ts +20 -0
  119. package/dist/tools/execution-limits.d.ts +5 -20
  120. package/dist/tools/execution-limits.js +0 -2
  121. package/dist/tools/execution.js +16 -4
  122. package/dist/tools/local/exec.js +8 -2
  123. package/dist/tools/output-projection.d.ts +5 -2
  124. package/dist/tools/output-projection.js +133 -92
  125. package/dist/tools/registry.js +1 -13
  126. package/dist/tools/runtime-context.d.ts +1 -21
  127. package/package.json +2 -2
  128. package/dist/extensions/agents.d.ts +0 -100
  129. package/dist/extensions/agents.js +0 -121
  130. package/dist/runtime/context/gc-candidates-subagent.d.ts +0 -6
  131. package/dist/runtime/context/gc-candidates-subagent.js +0 -100
  132. package/dist/sdk/extension-agent-controller.d.ts +0 -3
  133. package/dist/sdk/extension-agent-controller.js +0 -69
  134. package/dist/sdk/extension-agents.d.ts +0 -9
  135. package/dist/sdk/extension-agents.js +0 -58
  136. package/dist/sdk/subagent-backend.d.ts +0 -3
  137. package/dist/sdk/subagent-backend.js +0 -49
  138. package/dist/subagent/contracts.d.ts +0 -107
  139. package/dist/subagent/contracts.js +0 -1
  140. package/dist/subagent/limits.d.ts +0 -17
  141. package/dist/subagent/limits.js +0 -17
  142. package/dist/subagent/model-update.d.ts +0 -2
  143. package/dist/subagent/model-update.js +0 -81
  144. package/dist/subagent/session-controller.d.ts +0 -87
  145. package/dist/subagent/session-controller.js +0 -1343
  146. package/dist/subagent/task.d.ts +0 -134
  147. package/dist/subagent/task.js +0 -436
  148. package/dist/subagent/turn-contracts.d.ts +0 -64
  149. package/dist/subagent/turn-contracts.js +0 -1
  150. package/dist/subagent/wait-targets.d.ts +0 -10
  151. package/dist/subagent/wait-targets.js +0 -26
  152. package/dist/subagent/wait.d.ts +0 -26
  153. package/dist/subagent/wait.js +0 -73
  154. package/dist/tools/agent/agent-cancel.d.ts +0 -7
  155. package/dist/tools/agent/agent-cancel.js +0 -29
  156. package/dist/tools/agent/agent-message.d.ts +0 -7
  157. package/dist/tools/agent/agent-message.js +0 -57
  158. package/dist/tools/agent/agent-start.d.ts +0 -12
  159. package/dist/tools/agent/agent-start.js +0 -106
  160. package/dist/tools/agent/agent-wait.d.ts +0 -7
  161. package/dist/tools/agent/agent-wait.js +0 -91
@@ -9,6 +9,8 @@ export interface ClientToolDefinition extends ModelToolDefinition {
9
9
  outputSchema?: Record<string, unknown>;
10
10
  /** Runtime-only policy. MCP defaults to both callers; other tools default to direct only. */
11
11
  allowedCallers?: readonly ToolCaller[];
12
+ /** Runtime-only allowlist of scalar fields in the public tool.started input. */
13
+ eventInputFields?: readonly string[];
12
14
  /** Runtime-only exposure override; retains both permitted entry points with Code Mode enabled. */
13
15
  codeModeExposure?: 'both';
14
16
  parallelSafety?: 'safe' | 'serial';
@@ -95,12 +97,24 @@ export interface ExecOutputSnapshot {
95
97
  stdout: string;
96
98
  stderr: string;
97
99
  truncated: boolean;
100
+ displayOutput?: ExecDisplayOutput;
101
+ }
102
+ /** Bounded, non-consuming tail for public presentation, not model output. */
103
+ export interface ExecDisplayOutput {
104
+ stdout: string;
105
+ stderr: string;
106
+ stdoutDroppedBytes: number;
107
+ stderrDroppedBytes: number;
98
108
  }
99
109
  export interface ToolExecutionResult {
100
110
  calls?: readonly import('../session/code-observation-contract.js').CodeToolCallRecord[];
101
111
  content: string;
102
112
  observations?: readonly import('../session/code-observation-contract.js').CodeObservation[];
113
+ /** Explicit, bounded public structured projection; never inferred from data. */
114
+ eventData?: Readonly<Record<string, unknown>>;
103
115
  data?: unknown;
116
+ /** Explicit public event summary, separate from model-visible content. */
117
+ eventSummary?: string;
104
118
  /** Runtime-only definitions used to encode a Tool Search output. */
105
119
  toolSearchTools?: readonly ClientToolDefinition[];
106
120
  truncated?: boolean;
@@ -117,7 +131,12 @@ export interface CodeCellEventData {
117
131
  waitOutcome?: import('./wait.js').ToolWaitOutcome;
118
132
  reason?: 'steer';
119
133
  cached?: boolean;
134
+ truncated?: boolean;
120
135
  observations?: readonly import('../session/code-observation-contract.js').CodeObservation[];
136
+ error?: {
137
+ code: string;
138
+ message: string;
139
+ };
121
140
  }
122
141
  export interface ExecResult {
123
142
  status: 'running' | 'completed' | 'cancelled';
@@ -134,6 +153,7 @@ export interface ExecResult {
134
153
  stderrDroppedBytes: number;
135
154
  /** A terminal snapshot replay rather than new process output. */
136
155
  cached?: boolean;
156
+ displayOutput?: ExecDisplayOutput;
137
157
  }
138
158
  export interface ApplyPatchFileResult {
139
159
  path: string;
@@ -1,24 +1,4 @@
1
1
  export declare const TOOL_EXECUTION_LIMITS: Readonly<{
2
- sleepMaxDurationMs: 1800000;
3
- questionMaxTextCharacters: 1000;
4
- questionMaxOptionCharacters: 500;
5
- todoMaxItems: 100;
6
- todoMaxTextCharacters: 1000;
7
- agentWaitMinWaitMs: 0;
8
- agentWaitWaitFloorMs: 10000;
9
- agentWaitDefaultWaitMs: 30000;
10
- agentWaitMaxWaitMs: 300000;
11
- agentWaitMaxAgents: 8;
12
- subagentDescriptionMaxCharacters: 80;
13
- subagentPromptMaxBytes: 131072;
14
- subagentMessageMaxBytes: 131072;
15
- subagentReasoningEffortMaxCharacters: 64;
16
- subagentSummaryMaxBytes: 16384;
17
- subagentUpdateMaxBytes: 32768;
18
- subagentRunningLatestMessageMaxCharacters: 2000;
19
- subagentEvidenceMaxItems: 64;
20
- subagentVerificationMaxItems: 16;
21
- subagentChangedFilesMaxItems: 200;
22
2
  readDefaultLines: 200;
23
3
  readMaxLines: 2000;
24
4
  readMaxBytes: 1048576;
@@ -66,4 +46,9 @@ export declare const TOOL_EXECUTION_LIMITS: Readonly<{
66
46
  patchMaxFiles: 100;
67
47
  patchMaxFileBytes: 8388608;
68
48
  patchMaxTotalBytes: 33554432;
49
+ sleepMaxDurationMs: 1800000;
50
+ questionMaxTextCharacters: 1000;
51
+ questionMaxOptionCharacters: 500;
52
+ todoMaxItems: 100;
53
+ todoMaxTextCharacters: 1000;
69
54
  }>;
@@ -1,6 +1,5 @@
1
1
  import { CODE_STATE_LIMITS } from '../session/code-state.js';
2
2
  import { HISTORY_INPUT_LIMITS } from '../session/history-input-limits.js';
3
- import { SUBAGENT_LIMITS } from '../subagent/limits.js';
4
3
  export const TOOL_EXECUTION_LIMITS = Object.freeze({
5
4
  readDefaultLines: 200,
6
5
  readMaxLines: 2_000,
@@ -49,7 +48,6 @@ export const TOOL_EXECUTION_LIMITS = Object.freeze({
49
48
  patchMaxFiles: 100,
50
49
  patchMaxFileBytes: 8_388_608,
51
50
  patchMaxTotalBytes: 33_554_432,
52
- ...SUBAGENT_LIMITS,
53
51
  sleepMaxDurationMs: 1_800_000,
54
52
  questionMaxTextCharacters: 1_000,
55
53
  questionMaxOptionCharacters: 500,
@@ -3,7 +3,7 @@ import { toolEventSummary } from '../runtime/event-projection.js';
3
3
  import { allowsToolCaller } from './callers.js';
4
4
  import { CodeCellExecutionError } from './code-mode/cells.js';
5
5
  import { createCodeToolDispatch } from './code-mode/dispatch.js';
6
- import { boundedModelToolOutput, structuredToolArtifacts, structuredToolEventData, structuredToolFailureData } from './output-projection.js';
6
+ import { boundedModelToolOutput, publicToolEventInput, structuredToolArtifacts, publicExtensionToolEventData, structuredToolEventData, structuredToolFailureData } from './output-projection.js';
7
7
  import { publishModelResources } from '../runtime/resource-publication.js';
8
8
  import { executeRegisteredTool } from './runtime.js';
9
9
  import { failedToolResultExtensions } from './result-extensions.js';
@@ -78,12 +78,16 @@ export async function createRoundToolRuntimeContext(scope, call, signal) {
78
78
  /** Complete every call in model order even if individual execution fails. */
79
79
  export async function executeRoundTools(calls, scope) {
80
80
  const executeCall = async (call, signal = scope.context.signal, caller = 'direct', parentCallId) => {
81
+ const inputFields = scope.tools.find((tool) => tool.name === call.name)?.eventInputFields;
82
+ const publicInput = inputFields === undefined
83
+ ? call.arguments
84
+ : publicToolEventInput(call.arguments, inputFields);
81
85
  await scope.emit({
82
86
  type: 'tool.started',
83
87
  toolName: call.name,
84
88
  callId: call.callId,
85
89
  ...(parentCallId === undefined ? {} : { parentCallId }),
86
- input: call.arguments
90
+ input: publicInput
87
91
  });
88
92
  try {
89
93
  if (call.argumentError)
@@ -109,8 +113,16 @@ export async function executeRoundTools(calls, scope) {
109
113
  ...(publishedImages === undefined ? {} : { images: publishedImages })
110
114
  };
111
115
  const modelOutput = boundedModelToolOutput(call.name, output.content, output.data);
112
- const eventSummary = toolEventSummary(output.content);
113
- const structuredData = structuredToolEventData(call.name, output.data);
116
+ const eventSummary = toolEventSummary(output.eventSummary === undefined
117
+ ? output.content
118
+ : typeof output.eventSummary === 'string'
119
+ ? output.eventSummary
120
+ : '');
121
+ const structuredData = call.name === 'exec' || call.name === 'exec_wait'
122
+ ? structuredToolEventData(call.name, output.eventData ?? output.data)
123
+ : output.eventData === undefined
124
+ ? structuredToolEventData(call.name, output.data)
125
+ : publicExtensionToolEventData(output.eventData);
114
126
  const artifacts = structuredToolArtifacts(output.artifacts);
115
127
  await scope.emit({
116
128
  type: 'tool.completed',
@@ -2,7 +2,8 @@ import { AgentError } from '../../error.js';
2
2
  import { TOOL_EXECUTION_LIMITS } from '../execution-limits.js';
3
3
  /** Share the model-facing body across direct calls and original Code Mode observations. */
4
4
  export function formatExecResult(result) {
5
- const visible = { ...result };
5
+ const { displayOutput, ...modelResult } = result;
6
+ const visible = { ...modelResult };
6
7
  if (result.stderr === '')
7
8
  delete visible.stderr;
8
9
  if (!result.truncated) {
@@ -19,7 +20,12 @@ export function formatExecResult(result) {
19
20
  delete visible.stderrDroppedBytes;
20
21
  if (result.cached === false)
21
22
  delete visible.cached;
22
- return { content: JSON.stringify(visible), data: result, truncated: result.truncated };
23
+ return {
24
+ content: JSON.stringify(visible),
25
+ data: displayOutput === undefined ? result : modelResult,
26
+ ...(displayOutput === undefined ? {} : { eventData: { ...modelResult, displayOutput } }),
27
+ truncated: result.truncated
28
+ };
23
29
  }
24
30
  export const execToolDefinition = {
25
31
  name: 'exec',
@@ -1,16 +1,19 @@
1
- import type { SubagentTaskSnapshot, SubagentManyOutput } from '../subagent/contracts.js';
2
1
  import type { ApplyPatchResult, ApplyPatchPartialResult, CodeCellEventData, ExecResult, AgentToolArtifact, ToolExecutionResult, ReadEventData, ViewImageResult } from './contracts.js';
3
2
  import type { ToolRuntimeImage } from './runtime-context.js';
4
3
  import type { SleepResult } from './agent/sleep.js';
5
4
  import { type PublicToolMetadata } from '../runtime/public-tool-metadata.js';
6
5
  import type { ModelImage } from '../model/image.js';
6
+ /** Copy an explicitly public JSON object without exposing the full tool result. */
7
+ export declare function publicExtensionToolEventData(value: unknown): Readonly<Record<string, unknown>> | undefined;
7
8
  export declare function currentExecutionImages(modelInputImages: readonly ModelImage[] | undefined, toolImages: readonly ToolRuntimeImage[]): ToolRuntimeImage[];
8
9
  export declare function boundedModelToolOutput(toolName: string, value: string, data: unknown): {
9
10
  content: string;
10
11
  truncated: boolean;
11
12
  };
13
+ /** The opted-in allowlist fails closed and never mutates the invocation arguments. */
14
+ export declare function publicToolEventInput(value: unknown, fields: readonly string[]): Readonly<Record<string, unknown>>;
12
15
  /** Project only known, validated tool result shapes into public structured events. */
13
- export declare function structuredToolEventData(toolName: string, value: unknown): CodeCellEventData | ExecResult | ApplyPatchResult | ReadEventData | ViewImageResult | SubagentTaskSnapshot | SubagentManyOutput | SleepResult | PublicToolMetadata | undefined;
16
+ export declare function structuredToolEventData(toolName: string, value: unknown): CodeCellEventData | ExecResult | ApplyPatchResult | ReadEventData | ViewImageResult | SleepResult | PublicToolMetadata | undefined;
14
17
  /** Partial patch facts are allowlisted; arbitrary error details never become public event data. */
15
18
  export declare function structuredToolFailureData(toolName: string, error: unknown): ApplyPatchPartialResult | undefined;
16
19
  export declare function structuredToolArtifacts(value: readonly AgentToolArtifact[] | undefined): readonly AgentToolArtifact[] | undefined;
@@ -4,6 +4,21 @@ import { AGENT_EXECUTION_POLICY } from '../runtime/execution-policy.js';
4
4
  import { countModelTokens, countTextLines, truncateModelText } from '../runtime/token-budget.js';
5
5
  import { TOOL_EXECUTION_LIMITS } from './execution-limits.js';
6
6
  import { publicToolMetadata } from '../runtime/public-tool-metadata.js';
7
+ /** Copy an explicitly public JSON object without exposing the full tool result. */
8
+ export function publicExtensionToolEventData(value) {
9
+ if (!isRecord(value))
10
+ return undefined;
11
+ try {
12
+ const json = JSON.stringify(value);
13
+ if (Buffer.byteLength(json, 'utf8') > 8192)
14
+ return undefined;
15
+ const copy = JSON.parse(json);
16
+ return isRecord(copy) ? copy : undefined;
17
+ }
18
+ catch {
19
+ return undefined;
20
+ }
21
+ }
7
22
  export function currentExecutionImages(modelInputImages, toolImages) {
8
23
  return [
9
24
  ...(modelInputImages ?? [])
@@ -34,6 +49,105 @@ export function boundedModelToolOutput(toolName, value, data) {
34
49
  const result = truncateModelText(value, AGENT_EXECUTION_POLICY.modelToolOutputTokens, 'tool output', execDiagnostics);
35
50
  return { content: result.content, truncated: result.truncated };
36
51
  }
52
+ /** The opted-in allowlist fails closed and never mutates the invocation arguments. */
53
+ export function publicToolEventInput(value, fields) {
54
+ try {
55
+ if (!isRecord(value))
56
+ return {};
57
+ const projected = Object.fromEntries(fields
58
+ .filter((key) => Object.hasOwn(value, key) &&
59
+ (typeof value[key] === 'string' ||
60
+ typeof value[key] === 'boolean' ||
61
+ (typeof value[key] === 'number' && Number.isFinite(value[key])) ||
62
+ value[key] === null))
63
+ .map((key) => [key, value[key]]));
64
+ return publicExtensionToolEventData(projected) ?? {};
65
+ }
66
+ catch {
67
+ return {};
68
+ }
69
+ }
70
+ /** Explicit observations are public, but their event projection must remain bounded. */
71
+ function publicCodeObservations(values, data) {
72
+ if (!Array.isArray(values))
73
+ return data;
74
+ const retained = new Set(data.observations ?? []);
75
+ const selected = [];
76
+ let displayedCount = 0;
77
+ let remaining = 10_000;
78
+ let truncated = false;
79
+ const clip = (text) => {
80
+ let start = Math.max(0, text.length - remaining);
81
+ if (start > 0 && /[\uDC00-\uDFFF]/u.test(text[start]))
82
+ start++;
83
+ const result = text.slice(start);
84
+ remaining -= result.length;
85
+ truncated ||= start > 0;
86
+ return result;
87
+ };
88
+ for (let index = values.length - 1; index >= 0; index--) {
89
+ const entry = values[index];
90
+ if (!isRecord(entry))
91
+ continue;
92
+ if (entry.type === 'value' &&
93
+ typeof entry.value === 'string' &&
94
+ typeof entry.id === 'string' &&
95
+ (entry.format === 'text' || entry.format === 'json' || entry.format === 'image')) {
96
+ if (displayedCount >= 32) {
97
+ truncated = true;
98
+ continue;
99
+ }
100
+ displayedCount++;
101
+ truncated ||= entry.truncated === true;
102
+ const value = clip(entry.value);
103
+ selected.unshift({
104
+ type: 'value',
105
+ id: entry.id,
106
+ format: entry.format,
107
+ value,
108
+ ...(entry.truncated === true || value.length < entry.value.length
109
+ ? { truncated: true }
110
+ : {})
111
+ });
112
+ }
113
+ else if (entry.type === 'tool_result' && isRecord(entry.source) && isRecord(entry.result)) {
114
+ const name = entry.source.toolName;
115
+ if (name !== 'exec' && name !== 'exec_wait') {
116
+ if (retained.has(entry))
117
+ selected.unshift(entry);
118
+ }
119
+ else if ((name === 'exec' || name === 'exec_wait') &&
120
+ typeof entry.id === 'string' &&
121
+ typeof entry.source.callId === 'string' &&
122
+ (entry.outcome === 'completed' || entry.outcome === 'failed')) {
123
+ if (displayedCount >= 32) {
124
+ truncated = true;
125
+ continue;
126
+ }
127
+ displayedCount++;
128
+ truncated ||= entry.result.truncated === true;
129
+ const data = isRecord(entry.result.data) ? entry.result.data : undefined;
130
+ const stderr = typeof data?.stderr === 'string' ? clip(data.stderr) : undefined;
131
+ const stdout = typeof data?.stdout === 'string' ? clip(data.stdout) : undefined;
132
+ const content = stdout === undefined && stderr === undefined && typeof entry.result.content === 'string'
133
+ ? clip(entry.result.content)
134
+ : '';
135
+ selected.unshift({
136
+ type: 'tool_result',
137
+ id: entry.id,
138
+ source: { callId: entry.source.callId, toolName: name, input: null },
139
+ outcome: entry.outcome,
140
+ result: {
141
+ content,
142
+ ...(stdout === undefined && stderr === undefined ? {} : { data: { stdout, stderr } }),
143
+ ...(entry.result.truncated === true || truncated ? { truncated: true } : {})
144
+ }
145
+ });
146
+ }
147
+ }
148
+ }
149
+ return { ...data, observations: selected, ...(truncated ? { truncated: true } : {}) };
150
+ }
37
151
  /** Project only known, validated tool result shapes into public structured events. */
38
152
  export function structuredToolEventData(toolName, value) {
39
153
  if (!isRecord(value))
@@ -57,22 +171,10 @@ export function structuredToolEventData(toolName, value) {
57
171
  elapsedMs: value.elapsedMs,
58
172
  wakeReason: value.wakeReason
59
173
  };
60
- if (toolName === 'agent_wait' &&
61
- (value.mode === 'any' || value.mode === 'all') &&
62
- (value.waitFor === 'completion' || value.waitFor === 'message') &&
63
- ['snapshot', 'message', 'completion', 'timeout', 'interrupted'].includes(String(value.waitOutcome)) &&
64
- Array.isArray(value.agents) &&
65
- value.agents.length > 0 &&
66
- value.agents.length <= TOOL_EXECUTION_LIMITS.agentWaitMaxAgents &&
67
- value.agents.every((agent) => isRecord(agent) && isSubagentTaskSnapshot(agent)) &&
68
- Array.isArray(value.pendingAgentIds) &&
69
- value.pendingAgentIds.every((id) => typeof id === 'string' &&
70
- value.agents.some((agent) => agent.agentId === id)))
71
- return value;
72
174
  if ((toolName === 'code_exec' || toolName === 'code_exec_wait') &&
73
175
  typeof value.cellId === 'string' &&
74
176
  ['running', 'completed', 'failed', 'cancelled'].includes(String(value.status)))
75
- return {
177
+ return publicCodeObservations(value.observations, {
76
178
  cellId: value.cellId,
77
179
  status: value.status,
78
180
  cached: value.cached === true,
@@ -82,6 +184,21 @@ export function structuredToolEventData(toolName, value) {
82
184
  ...(value.waitOutcome === 'interrupted' && value.reason === 'steer'
83
185
  ? { reason: 'steer' }
84
186
  : {}),
187
+ ...(value.truncated === true ? { truncated: true } : {}),
188
+ ...(isRecord(value.error) &&
189
+ typeof value.error.code === 'string' &&
190
+ value.error.code.length > 0 &&
191
+ typeof value.error.message === 'string'
192
+ ? {
193
+ ...(value.error.code.length > 80 || value.error.message.length > 1000
194
+ ? { truncated: true }
195
+ : {}),
196
+ error: {
197
+ code: value.error.code.slice(0, 80).replace(/[\uD800-\uDBFF]$/u, ''),
198
+ message: value.error.message.slice(0, 1000).replace(/[\uD800-\uDBFF]$/u, '')
199
+ }
200
+ }
201
+ : {}),
85
202
  ...(isRecord(value.permissionStop)
86
203
  ? {
87
204
  permissionStop: value.permissionStop
@@ -90,15 +207,7 @@ export function structuredToolEventData(toolName, value) {
90
207
  ...(Array.isArray(value.calls)
91
208
  ? {
92
209
  calls: value.calls.filter((entry) => isRecord(entry) &&
93
- [
94
- 'apply_patch',
95
- 'todo_read',
96
- 'todo_write',
97
- 'agent_start',
98
- 'agent_wait',
99
- 'agent_message',
100
- 'agent_cancel'
101
- ].includes(String(entry.toolName)))
210
+ ['apply_patch', 'todo_read', 'todo_write'].includes(String(entry.toolName)))
102
211
  }
103
212
  : {}),
104
213
  ...(Array.isArray(value.observations)
@@ -106,24 +215,10 @@ export function structuredToolEventData(toolName, value) {
106
215
  observations: value.observations.filter((entry) => isRecord(entry) &&
107
216
  entry.type === 'tool_result' &&
108
217
  isRecord(entry.source) &&
109
- [
110
- 'apply_patch',
111
- 'todo_read',
112
- 'todo_write',
113
- 'agent_start',
114
- 'agent_wait',
115
- 'agent_message',
116
- 'agent_cancel'
117
- ].includes(String(entry.source.toolName)))
218
+ ['apply_patch', 'todo_read', 'todo_write'].includes(String(entry.source.toolName)))
118
219
  }
119
220
  : {})
120
- };
121
- if ((toolName === 'agent_start' ||
122
- toolName === 'agent_wait' ||
123
- toolName === 'agent_message' ||
124
- toolName === 'agent_cancel') &&
125
- isSubagentTaskSnapshot(value))
126
- return value;
221
+ });
127
222
  if (toolName === 'read' &&
128
223
  value.mode === 'batch' &&
129
224
  Array.isArray(value.results) &&
@@ -282,60 +377,6 @@ export function validateToolResult(value) {
282
377
  function isRecord(value) {
283
378
  return value !== null && typeof value === 'object' && !Array.isArray(value);
284
379
  }
285
- function isSubagentTaskSnapshot(value) {
286
- return (typeof value.agentId === 'string' &&
287
- value.agentId.length > 0 &&
288
- value.agentId.length <= 128 &&
289
- typeof value.description === 'string' &&
290
- value.description.length > 0 &&
291
- value.description.length <= TOOL_EXECUTION_LIMITS.subagentDescriptionMaxCharacters &&
292
- (value.status === 'queued' ||
293
- value.status === 'running' ||
294
- value.status === 'completed' ||
295
- value.status === 'failed' ||
296
- value.status === 'cancelled' ||
297
- value.status === 'interrupted') &&
298
- (value.modelId === undefined || typeof value.modelId === 'string') &&
299
- (value.modelName === undefined || typeof value.modelName === 'string') &&
300
- (value.reasoningEffort === undefined ||
301
- (typeof value.reasoningEffort === 'string' &&
302
- ['low', 'medium', 'high', 'xhigh', 'max', 'ultra'].includes(value.reasoningEffort))) &&
303
- (value.waitOutcome === undefined ||
304
- value.waitOutcome === 'snapshot' ||
305
- value.waitOutcome === 'message' ||
306
- value.waitOutcome === 'completion' ||
307
- value.waitOutcome === 'timeout' ||
308
- value.waitOutcome === 'interrupted') &&
309
- (value.latestMessage === undefined ||
310
- (isRecord(value.latestMessage) &&
311
- typeof value.latestMessage.itemId === 'string' &&
312
- typeof value.latestMessage.turnId === 'string' &&
313
- (value.latestMessage.phase === 'commentary' ||
314
- value.latestMessage.phase === 'final_answer') &&
315
- typeof value.latestMessage.text === 'string' &&
316
- typeof value.latestMessage.timestamp === 'string' &&
317
- typeof value.latestMessage.truncated === 'boolean')) &&
318
- (value.summary === undefined || typeof value.summary === 'string') &&
319
- (value.changedFiles === undefined ||
320
- (Array.isArray(value.changedFiles) &&
321
- value.changedFiles.every((path) => typeof path === 'string'))) &&
322
- (value.verification === undefined ||
323
- (Array.isArray(value.verification) &&
324
- value.verification.every((item) => typeof item === 'string'))) &&
325
- (value.evidence === undefined ||
326
- (Array.isArray(value.evidence) &&
327
- value.evidence.every((item) => isRecord(item) &&
328
- typeof item.path === 'string' &&
329
- (item.startLine === undefined ||
330
- (typeof item.startLine === 'number' &&
331
- Number.isInteger(item.startLine) &&
332
- item.startLine >= 1)) &&
333
- (item.endLine === undefined ||
334
- (typeof item.endLine === 'number' &&
335
- Number.isInteger(item.endLine) &&
336
- item.endLine >= 1))))) &&
337
- (value.errorCode === undefined || typeof value.errorCode === 'string'));
338
- }
339
380
  function isNonnegativeInteger(value) {
340
381
  return typeof value === 'number' && Number.isInteger(value) && value >= 0;
341
382
  }
@@ -1,7 +1,3 @@
1
- import { agentCancelToolDefinition, executeAgentCancel } from './agent/agent-cancel.js';
2
- import { agentMessageToolDefinition, executeAgentMessage } from './agent/agent-message.js';
3
- import { agentStartToolDefinition, executeAgentStart } from './agent/agent-start.js';
4
- import { agentWaitToolDefinition, executeAgentWait } from './agent/agent-wait.js';
5
1
  import { applyPatchToolDefinition } from './local/apply-patch.js';
6
2
  import { codeExecWaitToolDefinition, codeModeToolDefinition } from './code-mode/index.js';
7
3
  import { execToolDefinition, execWaitToolDefinition } from './local/exec.js';
@@ -27,10 +23,6 @@ export const BUILTIN_TOOL_DEFINITIONS = [
27
23
  questionToolDefinition,
28
24
  todoReadToolDefinition,
29
25
  todoWriteToolDefinition,
30
- agentStartToolDefinition,
31
- agentWaitToolDefinition,
32
- agentMessageToolDefinition,
33
- agentCancelToolDefinition,
34
26
  smartCompactToolDefinition,
35
27
  sleepToolDefinition
36
28
  ];
@@ -41,9 +33,5 @@ export const AGENT_TOOL_HANDLERS = new Map([
41
33
  ['tool_search', executeToolSearch],
42
34
  ['question', executeQuestion],
43
35
  ['todo_read', (_arguments, context) => executeTodoRead(context)],
44
- ['todo_write', executeTodoWrite],
45
- ['agent_start', executeAgentStart],
46
- ['agent_wait', executeAgentWait],
47
- ['agent_message', executeAgentMessage],
48
- ['agent_cancel', executeAgentCancel]
36
+ ['todo_write', executeTodoWrite]
49
37
  ]);
@@ -1,7 +1,6 @@
1
1
  import type { ResourcePublisher, ResourceStore } from '../runtime/resource-publication.js';
2
2
  import type { ExecutionMode } from '../runtime/contracts.js';
3
3
  import type { AgentSkill } from '../runtime/context/instructions.js';
4
- import type { SubagentController, SubagentLatestMessage } from '../subagent/contracts.js';
5
4
  import type { TodoStore } from './agent/todo.js';
6
5
  import type { McpToolCallContext, ToolCall, ToolExecutionContext, ToolExecutionResult } from './contracts.js';
7
6
  export interface ToolHost extends ResourcePublisher {
@@ -40,24 +39,6 @@ export type ToolRuntimeEvent = {
40
39
  } | {
41
40
  type: 'user_input.resolved';
42
41
  requestId: string;
43
- } | {
44
- type: 'subagent.started';
45
- agentId: string;
46
- description: string;
47
- modelId?: string;
48
- modelName?: string;
49
- reasoningEffort?: import('../model/configuration.js').AgentReasoningEffort;
50
- } | {
51
- type: 'subagent.completed';
52
- agentId: string;
53
- description: string;
54
- status: string;
55
- modelId?: string;
56
- modelName?: string;
57
- reasoningEffort?: import('../model/configuration.js').AgentReasoningEffort;
58
- latestMessage?: SubagentLatestMessage;
59
- errorCode?: string;
60
- errorMessage?: string;
61
42
  };
62
43
  export interface ToolRuntimeImage {
63
44
  readonly mimeType: string;
@@ -68,14 +49,13 @@ export interface ToolRuntimeContext {
68
49
  imageStore?: ToolImageStore;
69
50
  todo: TodoStore;
70
51
  requestSmartCompact?: () => void;
71
- subagents?: SubagentController;
72
52
  mode: ExecutionMode;
73
53
  sessionId: string;
74
54
  executionId: string;
75
55
  modelId?: string;
76
56
  signal: AbortSignal;
77
57
  waitInterrupt?: import('./wait.js').ToolWaitInterrupt | undefined;
78
- subagentMessages?: import('./wait.js').ToolWaitInterrupt;
58
+ contextUpdates?: import('./wait.js').ToolWaitInterrupt;
79
59
  permissionPolicy?: import('./permissions.js').ExecutionToolPermissions;
80
60
  parentCallId?: string;
81
61
  writeToolResultResource?: import('./result-extensions.js').ToolResultResourceWriter;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myagentroam/agent",
3
- "version": "0.11.39",
3
+ "version": "0.11.40",
4
4
  "description": "Embeddable MAR coding agent SDK and CLI.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -58,7 +58,7 @@
58
58
  "vitest": "^4.0.14"
59
59
  },
60
60
  "scripts": {
61
- "build": "node ../scripts/clean-build-output.mjs dist && tsc -p tsconfig.json",
61
+ "build": "node ../scripts/clean-build-output.mjs dist && tsc -p tsconfig.json && tsc -p extensions/subagent/tsconfig.json --outDir dist/cli/subagent",
62
62
  "typecheck": "tsc -p tsconfig.json --noEmit",
63
63
  "test:unit": "pnpm build && vitest run --config vitest.config.ts test/unit",
64
64
  "analyze:session": "node test/tools/session-analyzer.mjs",