@myagentroam/agent 0.9.141 → 0.9.143

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 (234) hide show
  1. package/dist/agent-core/host/contracts.d.ts +64 -0
  2. package/dist/{host → agent-core/host}/local-agent-host.d.ts +6 -5
  3. package/dist/{host → agent-core/host}/local-agent-host.js +4 -4
  4. package/dist/{model → agent-core/model}/anthropic-messages.js +24 -13
  5. package/dist/{model → agent-core/model}/contracts.d.ts +6 -16
  6. package/dist/{model → agent-core/model}/openai-responses.js +16 -9
  7. package/dist/agent-core/model/recovery.d.ts +4 -0
  8. package/dist/agent-core/model/recovery.js +71 -0
  9. package/dist/{prompts → agent-core/prompts}/core.d.ts +3 -13
  10. package/dist/{prompts → agent-core/prompts}/index.d.ts +1 -1
  11. package/dist/{prompts → agent-core/prompts}/modes.d.ts +1 -1
  12. package/dist/{prompts → agent-core/prompts}/resources.d.ts +1 -1
  13. package/dist/{runtime/compact.d.ts → agent-core/runtime/compaction/history.d.ts} +2 -23
  14. package/dist/{runtime/compact.js → agent-core/runtime/compaction/history.js} +2 -92
  15. package/dist/agent-core/runtime/compaction/operation.d.ts +22 -0
  16. package/dist/agent-core/runtime/compaction/operation.js +91 -0
  17. package/dist/agent-core/runtime/context/contracts.d.ts +12 -0
  18. package/dist/{runtime/environment-context.d.ts → agent-core/runtime/context/environment.d.ts} +2 -2
  19. package/dist/{runtime/environment-context.js → agent-core/runtime/context/environment.js} +1 -1
  20. package/dist/{runtime/context-gc-runtime.d.ts → agent-core/runtime/context/gc-runtime.d.ts} +4 -4
  21. package/dist/{runtime/context-gc-runtime.js → agent-core/runtime/context/gc-runtime.js} +3 -3
  22. package/dist/{runtime/context-gc-tokens.d.ts → agent-core/runtime/context/gc-tokens.d.ts} +2 -2
  23. package/dist/{runtime/context-gc-tokens.js → agent-core/runtime/context/gc-tokens.js} +7 -5
  24. package/dist/{runtime/context-gc.d.ts → agent-core/runtime/context/gc.d.ts} +3 -3
  25. package/dist/{runtime/context-gc.js → agent-core/runtime/context/gc.js} +152 -19
  26. package/dist/{runtime → agent-core/runtime/context}/instructions.d.ts +1 -1
  27. package/dist/{runtime → agent-core/runtime/context}/instructions.js +1 -1
  28. package/dist/{runtime → agent-core/runtime/context}/normalize.d.ts +1 -1
  29. package/dist/{runtime/context-projection.d.ts → agent-core/runtime/context/projection.d.ts} +3 -3
  30. package/dist/{runtime/context-projection.js → agent-core/runtime/context/projection.js} +35 -4
  31. package/dist/agent-core/runtime/context/request-budget.d.ts +6 -0
  32. package/dist/agent-core/runtime/context/request-budget.js +22 -0
  33. package/dist/agent-core/runtime/context/restore.d.ts +15 -0
  34. package/dist/agent-core/runtime/context/restore.js +85 -0
  35. package/dist/agent-core/runtime/context/usage.d.ts +18 -0
  36. package/dist/agent-core/runtime/context/usage.js +138 -0
  37. package/dist/agent-core/runtime/context/world-state.d.ts +35 -0
  38. package/dist/agent-core/runtime/context/world-state.js +133 -0
  39. package/dist/agent-core/runtime/contracts.d.ts +37 -0
  40. package/dist/agent-core/runtime/event-projection.d.ts +5 -0
  41. package/dist/agent-core/runtime/event-projection.js +17 -0
  42. package/dist/agent-core/runtime/events.d.ts +143 -0
  43. package/dist/agent-core/runtime/execution.d.ts +50 -0
  44. package/dist/agent-core/runtime/execution.js +397 -0
  45. package/dist/{runtime → agent-core/runtime}/rollout-budget.d.ts +1 -1
  46. package/dist/agent-core/sdk/agent.js +209 -0
  47. package/dist/agent-core/sdk/model-runtime.d.ts +13 -0
  48. package/dist/agent-core/sdk/model-runtime.js +63 -0
  49. package/dist/agent-core/sdk/session-title.d.ts +3 -0
  50. package/dist/agent-core/sdk/session-title.js +42 -0
  51. package/dist/agent-core/sdk/session.d.ts +62 -0
  52. package/dist/agent-core/sdk/session.js +1147 -0
  53. package/dist/agent-core/sdk/subagent-backend.d.ts +3 -0
  54. package/dist/agent-core/sdk/subagent-backend.js +46 -0
  55. package/dist/agent-core/sdk/types.d.ts +56 -0
  56. package/dist/{session → agent-core/session}/catalog.d.ts +2 -1
  57. package/dist/{session → agent-core/session}/context-gc-checkpoint.d.ts +3 -0
  58. package/dist/{session → agent-core/session}/context-gc-checkpoint.js +122 -23
  59. package/dist/agent-core/session/context-gc-observations.d.ts +38 -0
  60. package/dist/agent-core/session/context-gc-observations.js +150 -0
  61. package/dist/{session → agent-core/session}/context-gc-replacements.d.ts +1 -1
  62. package/dist/{session → agent-core/session}/context-gc-replacements.js +6 -2
  63. package/dist/{session → agent-core/session}/jsonl-store.d.ts +2 -2
  64. package/dist/{session → agent-core/session}/jsonl-store.js +1 -1
  65. package/dist/agent-core/subagent/contracts.d.ts +91 -0
  66. package/dist/agent-core/subagent/contracts.js +1 -0
  67. package/dist/agent-core/subagent/scheduler.d.ts +117 -0
  68. package/dist/{subagent → agent-core/subagent}/session-controller.d.ts +3 -2
  69. package/dist/agent-core/tools/agent/agent-cancel.d.ts +7 -0
  70. package/dist/{tools → agent-core/tools/agent}/agent-cancel.js +1 -1
  71. package/dist/agent-core/tools/agent/agent-message.d.ts +7 -0
  72. package/dist/{tools → agent-core/tools/agent}/agent-message.js +2 -2
  73. package/dist/{tools → agent-core/tools/agent}/agent-start.d.ts +3 -3
  74. package/dist/{tools → agent-core/tools/agent}/agent-start.js +3 -3
  75. package/dist/agent-core/tools/agent/agent-wait.d.ts +7 -0
  76. package/dist/{tools → agent-core/tools/agent}/agent-wait.js +2 -2
  77. package/dist/{tools → agent-core/tools/agent}/question.d.ts +2 -2
  78. package/dist/{tools → agent-core/tools/agent}/question.js +2 -2
  79. package/dist/{tools → agent-core/tools/agent}/skill.d.ts +2 -2
  80. package/dist/{tools → agent-core/tools/agent}/skill.js +2 -2
  81. package/dist/{tools → agent-core/tools/agent}/todo-read.d.ts +2 -2
  82. package/dist/{tools → agent-core/tools/agent}/todo-write.d.ts +2 -2
  83. package/dist/{tools → agent-core/tools/agent}/todo-write.js +2 -2
  84. package/dist/{tools → agent-core/tools/agent}/todo.d.ts +2 -9
  85. package/dist/{tools → agent-core/tools/agent}/todo.js +1 -1
  86. package/dist/{tools → agent-core/tools}/code-mode/cells.d.ts +4 -1
  87. package/dist/{tools → agent-core/tools}/code-mode/cells.js +60 -6
  88. package/dist/{tools → agent-core/tools}/code-mode/dispatch.d.ts +2 -4
  89. package/dist/{tools → agent-core/tools}/code-mode/dispatch.js +10 -6
  90. package/dist/{tools → agent-core/tools}/code-mode/engine.d.ts +13 -1
  91. package/dist/agent-core/tools/code-mode/engine.js +1 -0
  92. package/dist/{tools/code-mode.d.ts → agent-core/tools/code-mode/index.d.ts} +7 -7
  93. package/dist/{tools/code-mode.js → agent-core/tools/code-mode/index.js} +190 -28
  94. package/dist/agent-core/tools/code-mode/observations.d.ts +103 -0
  95. package/dist/agent-core/tools/code-mode/observations.js +195 -0
  96. package/dist/{tools → agent-core/tools}/code-mode/quickjs-engine.js +91 -17
  97. package/dist/{tools → agent-core/tools}/code-mode/state.d.ts +2 -13
  98. package/dist/agent-core/tools/code-mode/worker.d.ts +1 -0
  99. package/dist/{tools → agent-core/tools}/code-mode/worker.js +8 -1
  100. package/dist/agent-core/tools/contracts.d.ts +172 -0
  101. package/dist/agent-core/tools/contracts.js +1 -0
  102. package/dist/agent-core/tools/execution.d.ts +36 -0
  103. package/dist/agent-core/tools/execution.js +111 -0
  104. package/dist/agent-core/tools/local/apply-patch.d.ts +19 -0
  105. package/dist/{tools → agent-core/tools/local}/apply-patch.js +8 -2
  106. package/dist/{tools → agent-core/tools/local}/exec.d.ts +5 -17
  107. package/dist/{tools → agent-core/tools/local}/exec.js +4 -4
  108. package/dist/{tools → agent-core/tools/local}/read.d.ts +7 -15
  109. package/dist/{tools → agent-core/tools/local}/read.js +185 -2
  110. package/dist/{tools/local-registry.d.ts → agent-core/tools/local/registry.d.ts} +5 -5
  111. package/dist/agent-core/tools/local/registry.js +101 -0
  112. package/dist/{tools → agent-core/tools/local}/view-image.d.ts +4 -9
  113. package/dist/{tools → agent-core/tools/local}/view-image.js +2 -2
  114. package/dist/agent-core/tools/local/web-fetch.d.ts +4 -0
  115. package/dist/agent-core/tools/local/web-fetch.js +85 -0
  116. package/dist/agent-core/tools/local/web-search.d.ts +7 -0
  117. package/dist/agent-core/tools/local/web-search.js +34 -0
  118. package/dist/{tools/local-workspace-tools.js → agent-core/tools/local/workspace-tools.js} +1 -1
  119. package/dist/{sdk/mcp-catalog.d.ts → agent-core/tools/mcp/catalog.d.ts} +1 -2
  120. package/dist/{sdk/mcp-catalog.js → agent-core/tools/mcp/catalog.js} +1 -1
  121. package/dist/agent-core/tools/mcp/history.d.ts +4 -0
  122. package/dist/agent-core/tools/mcp/history.js +33 -0
  123. package/dist/{tools → agent-core/tools/mcp}/tool-search.d.ts +3 -3
  124. package/dist/{tools → agent-core/tools/mcp}/tool-search.js +4 -4
  125. package/dist/agent-core/tools/output-projection.d.ts +14 -0
  126. package/dist/agent-core/tools/output-projection.js +223 -0
  127. package/dist/{tools → agent-core/tools}/registry.d.ts +1 -1
  128. package/dist/agent-core/tools/registry.js +47 -0
  129. package/dist/{tools → agent-core/tools}/runtime-context.d.ts +8 -7
  130. package/dist/agent-core/tools/runtime-context.js +1 -0
  131. package/dist/{tools → agent-core/tools}/runtime.d.ts +1 -1
  132. package/dist/cli/codex-auth-file.d.ts +1 -1
  133. package/dist/cli/codex-auth-file.js +2 -2
  134. package/dist/cli/main.js +9 -9
  135. package/dist/index.d.ts +17 -15
  136. package/dist/index.js +8 -8
  137. package/dist/sandbox/linux/bubblewrap-sandbox-executor.d.ts +1 -1
  138. package/dist/sandbox/linux/bubblewrap-sandbox-executor.js +1 -1
  139. package/package.json +3 -3
  140. package/dist/host/contracts.d.ts +0 -21
  141. package/dist/sdk/agent.js +0 -2548
  142. package/dist/sdk/types.d.ts +0 -349
  143. package/dist/subagent/scheduler.d.ts +0 -206
  144. package/dist/tools/agent-cancel.d.ts +0 -7
  145. package/dist/tools/agent-message.d.ts +0 -7
  146. package/dist/tools/agent-wait.d.ts +0 -7
  147. package/dist/tools/apply-patch.d.ts +0 -32
  148. package/dist/tools/local-registry.js +0 -373
  149. package/dist/tools/registry.js +0 -47
  150. package/dist/tools/web-fetch.d.ts +0 -2
  151. package/dist/tools/web-fetch.js +0 -12
  152. package/dist/tools/web-search.d.ts +0 -2
  153. package/dist/tools/web-search.js +0 -15
  154. /package/dist/{error.d.ts → agent-core/error.d.ts} +0 -0
  155. /package/dist/{error.js → agent-core/error.js} +0 -0
  156. /package/dist/{host → agent-core/host}/contracts.js +0 -0
  157. /package/dist/{host → agent-core/host}/local-process-executor.d.ts +0 -0
  158. /package/dist/{host → agent-core/host}/local-process-executor.js +0 -0
  159. /package/dist/{host → agent-core/host}/network.d.ts +0 -0
  160. /package/dist/{host → agent-core/host}/network.js +0 -0
  161. /package/dist/{model → agent-core/model}/anthropic-messages.d.ts +0 -0
  162. /package/dist/{model → agent-core/model}/anthropic-thinking.d.ts +0 -0
  163. /package/dist/{model → agent-core/model}/anthropic-thinking.js +0 -0
  164. /package/dist/{model → agent-core/model}/catalog-file.d.ts +0 -0
  165. /package/dist/{model → agent-core/model}/catalog-file.js +0 -0
  166. /package/dist/{model → agent-core/model}/configuration.d.ts +0 -0
  167. /package/dist/{model → agent-core/model}/configuration.js +0 -0
  168. /package/dist/{model → agent-core/model}/contracts.js +0 -0
  169. /package/dist/{model → agent-core/model}/http.d.ts +0 -0
  170. /package/dist/{model → agent-core/model}/http.js +0 -0
  171. /package/dist/{model → agent-core/model}/openai-responses.d.ts +0 -0
  172. /package/dist/{model → agent-core/model}/runtime-credential.d.ts +0 -0
  173. /package/dist/{model → agent-core/model}/runtime-credential.js +0 -0
  174. /package/dist/{model → agent-core/model}/sse.d.ts +0 -0
  175. /package/dist/{model → agent-core/model}/sse.js +0 -0
  176. /package/dist/{model → agent-core/model}/transport-test.d.ts +0 -0
  177. /package/dist/{model → agent-core/model}/transport-test.js +0 -0
  178. /package/dist/{prompts → agent-core/prompts}/compact.d.ts +0 -0
  179. /package/dist/{prompts → agent-core/prompts}/compact.js +0 -0
  180. /package/dist/{prompts → agent-core/prompts}/core.js +0 -0
  181. /package/dist/{prompts → agent-core/prompts}/execution-budget.d.ts +0 -0
  182. /package/dist/{prompts → agent-core/prompts}/execution-budget.js +0 -0
  183. /package/dist/{prompts → agent-core/prompts}/index.js +0 -0
  184. /package/dist/{prompts → agent-core/prompts}/modes.js +0 -0
  185. /package/dist/{prompts → agent-core/prompts}/output.d.ts +0 -0
  186. /package/dist/{prompts → agent-core/prompts}/output.js +0 -0
  187. /package/dist/{prompts → agent-core/prompts}/resources.js +0 -0
  188. /package/dist/{prompts → agent-core/prompts}/subagent.d.ts +0 -0
  189. /package/dist/{prompts → agent-core/prompts}/subagent.js +0 -0
  190. /package/dist/{prompts → agent-core/prompts}/title.d.ts +0 -0
  191. /package/dist/{prompts → agent-core/prompts}/title.js +0 -0
  192. /package/dist/{prompts → agent-core/prompts}/workflow.d.ts +0 -0
  193. /package/dist/{prompts → agent-core/prompts}/workflow.js +0 -0
  194. /package/dist/{runtime → agent-core/runtime}/async-queue.d.ts +0 -0
  195. /package/dist/{runtime → agent-core/runtime}/async-queue.js +0 -0
  196. /package/dist/{sdk/types.js → agent-core/runtime/context/contracts.js} +0 -0
  197. /package/dist/{runtime → agent-core/runtime/context}/normalize.js +0 -0
  198. /package/dist/{session/types.js → agent-core/runtime/contracts.js} +0 -0
  199. /package/dist/{tools/code-mode/engine.js → agent-core/runtime/events.js} +0 -0
  200. /package/dist/{runtime → agent-core/runtime}/execution-policy.d.ts +0 -0
  201. /package/dist/{runtime → agent-core/runtime}/execution-policy.js +0 -0
  202. /package/dist/{runtime → agent-core/runtime}/plan-output.d.ts +0 -0
  203. /package/dist/{runtime → agent-core/runtime}/plan-output.js +0 -0
  204. /package/dist/{runtime → agent-core/runtime}/rollout-budget.js +0 -0
  205. /package/dist/{runtime → agent-core/runtime}/token-budget.d.ts +0 -0
  206. /package/dist/{runtime → agent-core/runtime}/token-budget.js +0 -0
  207. /package/dist/{sdk → agent-core/sdk}/agent.d.ts +0 -0
  208. /package/dist/{tools/code-mode/worker.d.ts → agent-core/sdk/types.js} +0 -0
  209. /package/dist/{session → agent-core/session}/catalog.js +0 -0
  210. /package/dist/{session → agent-core/session}/context-gc-subagent.d.ts +0 -0
  211. /package/dist/{session → agent-core/session}/context-gc-subagent.js +0 -0
  212. /package/dist/{session → agent-core/session}/transaction-recovery.d.ts +0 -0
  213. /package/dist/{session → agent-core/session}/transaction-recovery.js +0 -0
  214. /package/dist/{session → agent-core/session}/types.d.ts +0 -0
  215. /package/dist/{tools/runtime-context.js → agent-core/session/types.js} +0 -0
  216. /package/dist/{subagent → agent-core/subagent}/scheduler.js +0 -0
  217. /package/dist/{subagent → agent-core/subagent}/session-controller.js +0 -0
  218. /package/dist/{tools → agent-core/tools/agent}/todo-read.js +0 -0
  219. /package/dist/{tools → agent-core/tools}/callers.d.ts +0 -0
  220. /package/dist/{tools → agent-core/tools}/callers.js +0 -0
  221. /package/dist/{tools → agent-core/tools}/code-mode/quickjs-engine.d.ts +0 -0
  222. /package/dist/{tools → agent-core/tools}/code-mode/state.js +0 -0
  223. /package/dist/{tools → agent-core/tools}/code-mode/text-output.d.ts +0 -0
  224. /package/dist/{tools → agent-core/tools}/code-mode/text-output.js +0 -0
  225. /package/dist/{tools → agent-core/tools}/execution-limits.d.ts +0 -0
  226. /package/dist/{tools → agent-core/tools}/execution-limits.js +0 -0
  227. /package/dist/{tools → agent-core/tools/local}/read-context.d.ts +0 -0
  228. /package/dist/{tools → agent-core/tools/local}/read-context.js +0 -0
  229. /package/dist/{tools/local-workspace-tools.d.ts → agent-core/tools/local/workspace-tools.d.ts} +0 -0
  230. /package/dist/{tools → agent-core/tools}/runtime.js +0 -0
  231. /package/dist/{tools → agent-core/tools}/scheduler.d.ts +0 -0
  232. /package/dist/{tools → agent-core/tools}/scheduler.js +0 -0
  233. /package/dist/{tools → agent-core/tools}/shared/path-resolver.d.ts +0 -0
  234. /package/dist/{tools → agent-core/tools}/shared/path-resolver.js +0 -0
@@ -1,9 +1,9 @@
1
- import { type LocalProcessExecutor } from '../host/local-process-executor.js';
2
- import type { ClientToolDefinition, ModelMessage } from '../model/contracts.js';
3
- import type { ToolExecutionContext, ToolExecutionResult } from '../sdk/types.js';
4
- import { WorkspacePathResolver } from './shared/path-resolver.js';
5
- import type { CodeModeEngineFactory } from './code-mode/engine.js';
6
- import { type CellOutput } from './code-mode/cells.js';
1
+ import { type LocalProcessExecutor } from '../../host/local-process-executor.js';
2
+ import type { ClientToolDefinition, ModelMessage } from '../../model/contracts.js';
3
+ import { type CellOutput } from './cells.js';
4
+ import type { CodeModeEngineFactory } from './engine.js';
5
+ import type { ToolExecutionContext, ToolExecutionResult } from '../contracts.js';
6
+ import { WorkspacePathResolver } from '../shared/path-resolver.js';
7
7
  export declare const codeModeToolDefinition: ClientToolDefinition;
8
8
  export declare const codeExecWaitToolDefinition: ClientToolDefinition;
9
9
  /** Deferred definitions travel in search results, not in the stable Code Mode description. */
@@ -20,7 +20,7 @@ export declare class CodeModeTool {
20
20
  wait(value: unknown, context: ToolExecutionContext): Promise<ToolExecutionResult>;
21
21
  listSessionResources(sessionId: string): {
22
22
  cellId: string;
23
- status: "completed" | "cancelled" | "running" | "failed";
23
+ status: "completed" | "failed" | "cancelled" | "running";
24
24
  executionId: string;
25
25
  }[];
26
26
  constructor(paths: WorkspacePathResolver, environment?: NodeJS.ProcessEnv, executor?: LocalProcessExecutor, engineFactory?: CodeModeEngineFactory);
@@ -1,19 +1,19 @@
1
1
  import { randomUUID } from 'node:crypto';
2
- import { createRequire } from 'node:module';
3
- import { pathToFileURL } from 'node:url';
4
2
  import { readFile } from 'node:fs/promises';
3
+ import { createRequire } from 'node:module';
5
4
  import { dirname, sep } from 'node:path';
6
- import { fileURLToPath } from 'node:url';
7
5
  import { StringDecoder } from 'node:string_decoder';
8
- import { MarAgentError, describeMarAgentError } from '../error.js';
9
- import { directLocalProcessExecutor, signalProcessTree } from '../host/local-process-executor.js';
10
- import { TOOL_EXECUTION_LIMITS as limits } from './execution-limits.js';
11
- import { createToolCallScheduler } from './scheduler.js';
12
- import { detectImageMime } from './view-image.js';
13
- import { allowsDirectTool, allowsToolCaller } from './callers.js';
14
- import { CodeCells } from './code-mode/cells.js';
15
- import { BoundedTextOutput, renderCapturedText } from './code-mode/text-output.js';
16
- import { parseCodeModeStateMutations } from './code-mode/state.js';
6
+ import { fileURLToPath, pathToFileURL } from 'node:url';
7
+ import { MarAgentError, describeMarAgentError } from '../../error.js';
8
+ import { directLocalProcessExecutor, signalProcessTree } from '../../host/local-process-executor.js';
9
+ import { allowsDirectTool, allowsToolCaller } from '../callers.js';
10
+ import { CodeCells } from './cells.js';
11
+ import { newObservationId, renderObservations } from './observations.js';
12
+ import { parseCodeModeStateMutations } from './state.js';
13
+ import { BoundedTextOutput, renderCapturedText } from './text-output.js';
14
+ import { TOOL_EXECUTION_LIMITS as limits } from '../execution-limits.js';
15
+ import { createToolCallScheduler } from '../scheduler.js';
16
+ import { detectImageMime } from '../local/view-image.js';
17
17
  export const codeModeToolDefinition = {
18
18
  name: 'code_exec',
19
19
  description: `Run JavaScript to orchestrate or compose tool calls.
@@ -21,7 +21,7 @@ export const codeModeToolDefinition = {
21
21
  - Use bounded combinations, parallel independent calls, and filtering of large intermediate results to reduce model round trips.
22
22
  - Evaluates source in a fresh restricted ECMAScript runtime with top-level await and Promise.all. It is not Node.js or a browser. JavaScript globals do not survive between cells; bounded JSON state is available through state.
23
23
  - Accepts raw JavaScript source text, not JSON, quoted strings, or markdown code fences. Responses uses the source directly; Anthropic uses the code field of its tool input object. In either case, do not quote or fence the source again.
24
- - Use only standard ECMAScript built-ins and the explicitly documented tools, out, state, catalog and cell namespaces. Do not use Node.js, browser or Web APIs. Module imports, filesystem and network APIs are unavailable. Obtain external capabilities only through available tools. Use tools.exec to start managed processes when permitted; use tools.exec_wait afterward to wait, write stdin or cancel.
24
+ - Use only standard ECMAScript built-ins and the explicitly documented tools, observe, state, catalog and cell namespaces. Do not use Node.js, browser or Web APIs. Module imports, filesystem and network APIs are unavailable. Obtain external capabilities only through available tools. Use tools.exec to start managed processes when permitted; use tools.exec_wait afterward to wait, write stdin or cancel.
25
25
 
26
26
  Tool calls:
27
27
  - tools.NAME(input) returns a Promise. Use the existing tool input schema; freeform tools such as apply_patch accept a raw string, not a JSON wrapper.
@@ -30,25 +30,26 @@ Tool calls:
30
30
  - skill, tool_search, question, code_exec, code_exec_wait and direct-only tools cannot be called here. Load Skills directly and read their instructions before the next tool call. Use direct tool_search before a later code cell for deferred tools; the current cell's tools do not change.
31
31
 
32
32
  Built-in namespaces:
33
- - out.text(value): void emits text. Strings and scalar values are stringified; JSON-compatible objects/arrays are serialized as compact JSON. Structured image objects (image/* mimeType and string dataBase64, or native MCP type:image with string data) are recursively summarized without their Base64 payload; originals remain unchanged. Ordinary strings remain unchanged. This does not emit pixels: use out.image(result.images[0]) for images. Prefer result.data or result.content over the whole image result. Excess ordinary text is truncated with omission metadata, without stopping later code or tools. Cyclic or unsupported object values fail. Only explicitly emitted output reaches the model.
34
- - out.image(value: {mimeType:string,dataBase64:string}): void emits one returned image; for example out.image(result.images[0]) when that image exists and the model supports images. It does not accept a path, URL, or result.content.
33
+ - observe.result(result): void registers an unmodified complete tools.NAME result or caught tool error as a trusted tool_result, using the original text and all images without repeating program data. Non-original, copied or modified values are rejected. This selects evidence for the next model response, not a log and not a new model call.
34
+ - observe.text(value): void registers bounded text/JSON values. observe.image(value): void registers one image value using the existing capability, MIME, byte and count limits. Both accept original tool results for compatibility and use the same complete tool_result observation path; they do not select part of an original result. Extracted single images, copies and computed summaries are value observations, never trusted tool results. Observations are returned in registration order. Only explicitly observed evidence reaches the model; registration does not prove inspection. Sources and types are runtime-assigned. No out or callable observe(value) alias exists.
35
35
  - state.get(key), state.has(key), state.set(key, value), state.delete(key) access bounded session JSON state. Mutations commit atomically only when the cell succeeds; failed or cancelled cells discard them.
36
36
  - catalog.tools() returns a read-only snapshot of the tools callable in this cell, including name, description, inputSchema and inputMode. It does not discover or authorize additional tools.
37
37
  - await cell.sleep(ms) performs a cancellable Host-side delay up to 30000 ms and remains subject to the cell deadline.
38
38
  - await cell.yield_control() returns accumulated output to the model immediately while this cell continues running.
39
39
  - Optionally start source with // @options: {"yieldMs": ${limits.codeDefaultYieldMs}, "maxOutputTokens": 10000}. yieldMs defaults to ${limits.codeDefaultYieldMs} ms and is a wait window (0..${limits.codeMaxYieldMs}), not a cell timeout. Explicit values are preserved and do not change nested tools' wait windows. A running result includes cellId; use direct code_exec_wait for new output, completion or termination.
40
40
  - Registered cells are Session warm resources: ending or cancelling the model Execution cancels its wait, not the cell. Reuse retained cellId; do not start duplicate work. Host cleanup or explicit termination stops the cell.
41
- - tools, out, state, catalog and cell are frozen bindings. Do not shadow their names.
41
+ - tools, observe, state, catalog and cell are frozen bindings. Do not shadow their names.
42
42
  - Input max 1 MiB; cumulative text capture max 1 MiB with truncation; 128 calls, 120 seconds. Tool-specific limits apply before explicit text capture. Protocol, image, memory and time limits remain hard failures. Failures do not roll back completed tool work; do not replay successful operations blindly.
43
43
 
44
44
  Examples (copy the JavaScript source, not the fences; use only tools available in the current directory):
45
- Independent reads, emitting only source text:
45
+ Independent reads, observing the original tool results:
46
46
  \`\`\`js
47
47
  const [a, b] = await Promise.all([
48
48
  tools.read({ reads: [{ path: "a.txt" }] }),
49
49
  tools.read({ reads: [{ path: "b.txt" }] })
50
50
  ]);
51
- out.text({ a: a.data.results[0].text, b: b.data.results[0].text });
51
+ observe.result(a);
52
+ observe.result(b);
52
53
  \`\`\`
53
54
  Inspect before a dependent edit; successful await needs no invented success flag:
54
55
  \`\`\`js
@@ -56,7 +57,7 @@ const inspected = await tools.read({ reads: [{ path: "source.txt" }] });
56
57
  const sourceText = inspected.data.results[0].text;
57
58
  if (!sourceText?.includes("original=1")) throw new Error("Unexpected source");
58
59
  const patched = await tools.apply_patch("*** Begin Patch\\n*** Update File: source.txt\\n@@\\n original=1\\n+updated=2\\n*** End Patch");
59
- out.text({ files: patched.data.files.length });
60
+ observe.result(patched);
60
61
  \`\`\``,
61
62
  inputMode: 'freeform',
62
63
  inputSchema: {
@@ -154,10 +155,10 @@ function defaultEngineFactory() {
154
155
  return root.includes(`${sep}.pnpm${sep}`) ? dirname(dirname(root)) : root;
155
156
  };
156
157
  return {
157
- moduleUrl: new URL('./code-mode/quickjs-engine.js', import.meta.url).href,
158
+ moduleUrl: new URL('./quickjs-engine.js', import.meta.url).href,
158
159
  runtimeDirectories: [
159
160
  ...new Set([
160
- fileURLToPath(new URL('./code-mode/', import.meta.url)),
161
+ fileURLToPath(new URL('.', import.meta.url)),
161
162
  dependencyRoot(core),
162
163
  dependencyRoot(variant),
163
164
  dependencyRoot(ffi)
@@ -255,7 +256,7 @@ export class CodeModeTool {
255
256
  `--max-old-space-size=${limits.codeHeapMegabytes}`,
256
257
  '--input-type=module',
257
258
  '--eval',
258
- await readFile(new URL('./code-mode/worker.js', import.meta.url), 'utf8')
259
+ await readFile(new URL('./worker.js', import.meta.url), 'utf8')
259
260
  ],
260
261
  cwd,
261
262
  shell: false,
@@ -268,6 +269,34 @@ export class CodeModeTool {
268
269
  });
269
270
  const text = new BoundedTextOutput(limits.codeMaxOutputBytes);
270
271
  const images = [];
272
+ const observations = [];
273
+ let observationBytes = 0;
274
+ const appendObservation = (value, originalBytes) => {
275
+ const capture = new BoundedTextOutput(Math.max(0, limits.codeMaxOutputBytes - observationBytes), '');
276
+ const body = value.type === 'tool_result' ? value.result.content : value.value;
277
+ capture.append(body);
278
+ const bounded = capture.snapshot();
279
+ observationBytes += bounded.retainedBytes;
280
+ text.append(body, originalBytes ?? Buffer.byteLength(body));
281
+ output?.text(body, originalBytes ?? Buffer.byteLength(body));
282
+ const observation = value.type === 'tool_result'
283
+ ? {
284
+ ...value,
285
+ result: {
286
+ ...value.result,
287
+ content: bounded.text,
288
+ truncated: value.result.truncated === true || bounded.droppedBytes > 0
289
+ }
290
+ }
291
+ : {
292
+ ...value,
293
+ value: bounded.text,
294
+ truncated: value.truncated === true || bounded.droppedBytes > 0
295
+ };
296
+ observations.push(observation);
297
+ output?.observe(observation);
298
+ };
299
+ const toolResults = new Map();
271
300
  let transportBytes = 0;
272
301
  let calls = 0;
273
302
  let complete = false;
@@ -317,13 +346,94 @@ export class CodeModeTool {
317
346
  const receive = (frame) => {
318
347
  if (complete)
319
348
  throw new MarAgentError('MAR_AGENT_CODE_PROTOCOL_ERROR', 'Code Mode sent data after completion.');
320
- if (frame.kind === 'text' && typeof frame.value === 'string') {
349
+ if (frame.kind === 'observe' && frame.observation && typeof frame.observation === 'object') {
350
+ const value = frame.observation;
351
+ if (observations.length >= 4096)
352
+ throw new MarAgentError('MAR_AGENT_TOOL_OUTPUT_LIMIT', 'Too many Code Mode observations.');
353
+ const addImage = (raw) => {
354
+ if (!context.codeMode?.supportsImages)
355
+ throw new MarAgentError('MAR_AGENT_INPUT_CAPABILITY_UNSUPPORTED', 'The current model cannot receive image observations.');
356
+ if (images.length >= 5)
357
+ throw new MarAgentError('MAR_AGENT_TOOL_OUTPUT_LIMIT', 'Code Mode emitted too many images.');
358
+ const image = parseImage(raw);
359
+ const index = images.length;
360
+ images.push(image);
361
+ output?.image(image);
362
+ return index;
363
+ };
364
+ let observation;
365
+ if (value.type === 'tool_result' && typeof value.operationId === 'string') {
366
+ const original = toolResults.get(value.operationId);
367
+ if (!original)
368
+ throw new MarAgentError('MAR_AGENT_CODE_PROTOCOL_ERROR', 'Unknown observation source.');
369
+ const bounded = {
370
+ content: original.result.content,
371
+ truncated: original.result.truncated === true
372
+ };
373
+ const indices = original.result.images?.map(addImage);
374
+ const data = [
375
+ 'apply_patch',
376
+ 'todo_read',
377
+ 'todo_write',
378
+ 'agent_start',
379
+ 'agent_wait',
380
+ 'agent_message',
381
+ 'agent_cancel'
382
+ ].includes(original.source.toolName)
383
+ ? original.result.data
384
+ : undefined;
385
+ observation = {
386
+ type: 'tool_result',
387
+ id: newObservationId(),
388
+ source: original.source,
389
+ outcome: original.outcome,
390
+ result: {
391
+ content: bounded.content,
392
+ truncated: original.result.truncated === true || bounded.truncated,
393
+ ...(data === undefined ? {} : { data }),
394
+ ...(indices?.length ? { imageIndices: indices } : {})
395
+ }
396
+ };
397
+ }
398
+ else if (value.type === 'image') {
399
+ observation = {
400
+ type: 'value',
401
+ id: newObservationId(),
402
+ format: 'image',
403
+ value: '',
404
+ imageIndices: [addImage(value.value)]
405
+ };
406
+ }
407
+ else if (value.type === 'value' &&
408
+ typeof value.value === 'string' &&
409
+ ['text', 'json'].includes(String(value.format))) {
410
+ observation = {
411
+ type: 'value',
412
+ id: newObservationId(),
413
+ format: value.format,
414
+ value: value.value,
415
+ truncated: typeof value.originalBytes === 'number' &&
416
+ value.originalBytes > Buffer.byteLength(value.value)
417
+ };
418
+ }
419
+ else
420
+ throw new MarAgentError('MAR_AGENT_CODE_PROTOCOL_ERROR', 'Invalid observation frame.');
421
+ appendObservation(observation, value.type === 'value' && typeof value.originalBytes === 'number'
422
+ ? value.originalBytes
423
+ : undefined);
424
+ }
425
+ else if (frame.kind === 'text' && typeof frame.value === 'string') {
321
426
  const originalBytes = frame.originalBytes ?? Buffer.byteLength(frame.value);
322
427
  if (!Number.isSafeInteger(originalBytes) ||
323
428
  originalBytes < Buffer.byteLength(frame.value))
324
429
  throw new MarAgentError('MAR_AGENT_CODE_PROTOCOL_ERROR', 'Code Mode sent invalid text byte counts.');
325
- text.append(frame.value, originalBytes);
326
- output?.text(frame.value, originalBytes);
430
+ appendObservation({
431
+ type: 'value',
432
+ id: newObservationId(),
433
+ format: 'text',
434
+ value: frame.value,
435
+ truncated: originalBytes > Buffer.byteLength(frame.value)
436
+ }, originalBytes);
327
437
  }
328
438
  else if (frame.kind === 'image') {
329
439
  if (!context.codeMode?.supportsImages)
@@ -333,6 +443,13 @@ export class CodeModeTool {
333
443
  throw new MarAgentError('MAR_AGENT_TOOL_OUTPUT_LIMIT', 'Code Mode emitted too many images.');
334
444
  images.push(image);
335
445
  output?.image(image);
446
+ appendObservation({
447
+ type: 'value',
448
+ id: newObservationId(),
449
+ format: 'image',
450
+ value: '',
451
+ imageIndices: [images.length - 1]
452
+ });
336
453
  }
337
454
  else if (frame.kind === 'yield') {
338
455
  output?.yield();
@@ -344,6 +461,14 @@ export class CodeModeTool {
344
461
  if (seen.has(id) || ++calls > limits.codeMaxCalls)
345
462
  throw new MarAgentError('MAR_AGENT_CODE_PROTOCOL_ERROR', 'Code Mode call ID or call count is invalid.');
346
463
  seen.add(id);
464
+ const source = {
465
+ callId: randomUUID(),
466
+ toolName: frame.name,
467
+ input: frame.arguments
468
+ };
469
+ const operationId = typeof frame.operationId === 'string' ? frame.operationId : String(id);
470
+ const recordCall = (value) => output?.call(value);
471
+ recordCall({ ...source, status: 'running' });
347
472
  const job = (async () => {
348
473
  try {
349
474
  if (frame.name === 'code_exec' || !available.has(frame.name))
@@ -351,7 +476,27 @@ export class CodeModeTool {
351
476
  const output = await invoke({
352
477
  name: frame.name,
353
478
  arguments: frame.arguments,
354
- callId: randomUUID()
479
+ callId: source.callId
480
+ });
481
+ toolResults.set(operationId, { source, outcome: 'completed', result: output });
482
+ recordCall({
483
+ ...source,
484
+ status: 'completed',
485
+ result: {
486
+ content: '',
487
+ truncated: output.truncated === true,
488
+ data: [
489
+ 'apply_patch',
490
+ 'todo_read',
491
+ 'todo_write',
492
+ 'agent_start',
493
+ 'agent_wait',
494
+ 'agent_message',
495
+ 'agent_cancel'
496
+ ].includes(source.toolName)
497
+ ? output.data
498
+ : undefined
499
+ }
355
500
  });
356
501
  const { content, ...structured } = output;
357
502
  const projected = output.data !== undefined && content === JSON.stringify(output.data)
@@ -360,9 +505,24 @@ export class CodeModeTool {
360
505
  await write({ id, ok: true, output: projected });
361
506
  }
362
507
  catch (error) {
508
+ // Serialization/transport failures cannot undo an already completed tool call.
509
+ if (toolResults.get(operationId)?.outcome === 'completed')
510
+ throw error;
363
511
  if (context.signal.aborted)
364
512
  return;
365
513
  const diagnostic = describeMarAgentError(error, 'MAR_AGENT_HOST_OPERATION_FAILED');
514
+ recordCall({
515
+ ...source,
516
+ status: 'failed',
517
+ error: { code: diagnostic.code, message: diagnostic.message }
518
+ });
519
+ toolResults.set(operationId, {
520
+ source,
521
+ outcome: 'failed',
522
+ result: {
523
+ content: JSON.stringify({ error: diagnostic.code, message: diagnostic.message })
524
+ }
525
+ });
366
526
  await write({
367
527
  id,
368
528
  ok: false,
@@ -471,8 +631,10 @@ export class CodeModeTool {
471
631
  await context.codeMode.commitState?.(stateMutations);
472
632
  const captured = text.snapshot();
473
633
  return {
474
- content: renderCapturedText(captured, images.length) ||
475
- 'Code Mode completed without emitted text.',
634
+ content: observations.length
635
+ ? renderObservations(observations)
636
+ : renderCapturedText(captured, images.length) || '[]',
637
+ observations,
476
638
  data: {
477
639
  toolCalls: calls,
478
640
  outputBytes: captured.originalBytes,
@@ -0,0 +1,103 @@
1
+ /** Execution metadata is independent of explicit model observations. */
2
+ export interface CodeToolCallRecord {
3
+ callId: string;
4
+ toolName: string;
5
+ input: unknown;
6
+ status: 'running' | 'completed' | 'failed';
7
+ result?: {
8
+ content: string;
9
+ data?: unknown;
10
+ truncated?: boolean;
11
+ };
12
+ error?: {
13
+ code: string;
14
+ message: string;
15
+ };
16
+ }
17
+ export declare function parseCodeCalls(value: unknown): CodeToolCallRecord[] | undefined;
18
+ export type CodeObservation = {
19
+ type: 'tool_result';
20
+ id: string;
21
+ source: {
22
+ callId: string;
23
+ toolName: string;
24
+ input: unknown;
25
+ };
26
+ outcome: 'completed' | 'failed';
27
+ result: {
28
+ content: string;
29
+ data?: unknown;
30
+ truncated?: boolean;
31
+ imageIndices?: number[];
32
+ };
33
+ } | {
34
+ type: 'value';
35
+ id: string;
36
+ format: 'text' | 'json' | 'image';
37
+ value: string;
38
+ truncated?: boolean;
39
+ imageIndices?: number[];
40
+ };
41
+ export declare function observationContent(value: CodeObservation): string;
42
+ export declare function observationImages(value: CodeObservation): readonly number[];
43
+ export declare function selectObservationImages(values: readonly CodeObservation[], images: readonly {
44
+ mimeType: string;
45
+ dataBase64: string;
46
+ }[], offset?: number): {
47
+ observations: ({
48
+ result: {
49
+ imageIndices: number[];
50
+ content: string;
51
+ data?: unknown;
52
+ truncated?: boolean;
53
+ };
54
+ type: "tool_result";
55
+ id: string;
56
+ source: {
57
+ callId: string;
58
+ toolName: string;
59
+ input: unknown;
60
+ };
61
+ outcome: "completed" | "failed";
62
+ } | {
63
+ imageIndices: number[];
64
+ type: "value";
65
+ id: string;
66
+ format: "text" | "json" | "image";
67
+ value: string;
68
+ truncated?: boolean;
69
+ })[];
70
+ images: {
71
+ mimeType: string;
72
+ dataBase64: string;
73
+ }[];
74
+ };
75
+ /** Only the visible projection crosses into model text; program data and inputs stay private. */
76
+ export declare function visibleObservation(value: CodeObservation): Record<string, unknown>;
77
+ export declare function renderObservations(values: readonly CodeObservation[]): string;
78
+ export declare function renderObservationResult(values: readonly CodeObservation[], original: string): string;
79
+ /** Truncate each body before encoding, never a JSON array or its trusted identity. */
80
+ export declare function boundObservations(values: readonly CodeObservation[], maximumTokens: number): {
81
+ observations: CodeObservation[];
82
+ content: string;
83
+ truncated: boolean;
84
+ };
85
+ export declare function newObservationId(): string;
86
+ export declare function observationModelParts(message: {
87
+ content?: string;
88
+ observations?: readonly CodeObservation[];
89
+ images?: readonly {
90
+ mimeType: string;
91
+ dataBase64: string;
92
+ }[];
93
+ }): Array<{
94
+ type: 'text';
95
+ text: string;
96
+ } | {
97
+ type: 'image';
98
+ image: {
99
+ mimeType: string;
100
+ dataBase64: string;
101
+ };
102
+ }> | undefined;
103
+ export declare function parseObservations(value: unknown): CodeObservation[] | undefined;
@@ -0,0 +1,195 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { truncateModelText, countModelTokens } from '../../runtime/token-budget.js';
3
+ export function parseCodeCalls(value) {
4
+ if (!Array.isArray(value) || value.length > 128)
5
+ return undefined;
6
+ const ids = new Set();
7
+ for (const item of value) {
8
+ if (!item ||
9
+ typeof item !== 'object' ||
10
+ typeof item.callId !== 'string' ||
11
+ !item.callId ||
12
+ ids.has(item.callId) ||
13
+ typeof item.toolName !== 'string' ||
14
+ !['running', 'completed', 'failed'].includes(item.status))
15
+ return undefined;
16
+ if (item.result !== undefined && (!item.result || typeof item.result.content !== 'string'))
17
+ return undefined;
18
+ ids.add(item.callId);
19
+ }
20
+ return value;
21
+ }
22
+ export function observationContent(value) {
23
+ return value.type === 'tool_result' ? value.result.content : value.value;
24
+ }
25
+ export function observationImages(value) {
26
+ return value.type === 'tool_result'
27
+ ? (value.result.imageIndices ?? [])
28
+ : (value.imageIndices ?? []);
29
+ }
30
+ export function selectObservationImages(values, images, offset = 0) {
31
+ const selected = [];
32
+ const indices = new Map();
33
+ const observations = values.map((value) => {
34
+ const remap = observationImages(value).flatMap((index) => {
35
+ const image = images[index - offset];
36
+ if (!image)
37
+ return [];
38
+ let next = indices.get(index);
39
+ if (next === undefined) {
40
+ next = selected.length;
41
+ indices.set(index, next);
42
+ selected.push(image);
43
+ }
44
+ return [next];
45
+ });
46
+ return value.type === 'tool_result'
47
+ ? { ...value, result: { ...value.result, imageIndices: remap } }
48
+ : { ...value, imageIndices: remap };
49
+ });
50
+ return { observations, images: selected };
51
+ }
52
+ /** Only the visible projection crosses into model text; program data and inputs stay private. */
53
+ export function visibleObservation(value) {
54
+ return value.type === 'tool_result'
55
+ ? {
56
+ type: value.type,
57
+ toolName: value.source.toolName,
58
+ outcome: value.outcome,
59
+ content: value.result.content,
60
+ ...(value.result.truncated ? { truncated: true } : {})
61
+ }
62
+ : {
63
+ type: value.type,
64
+ format: value.format,
65
+ value: value.value,
66
+ ...(value.truncated ? { truncated: true } : {})
67
+ };
68
+ }
69
+ export function renderObservations(values) {
70
+ return JSON.stringify(values.map(visibleObservation));
71
+ }
72
+ export function renderObservationResult(values, original) {
73
+ try {
74
+ const envelope = JSON.parse(original);
75
+ if (envelope && !Array.isArray(envelope) && typeof envelope === 'object')
76
+ return JSON.stringify({ ...envelope, observations: values.map(visibleObservation) });
77
+ }
78
+ catch { }
79
+ return renderObservations(values);
80
+ }
81
+ /** Truncate each body before encoding, never a JSON array or its trusted identity. */
82
+ export function boundObservations(values, maximumTokens) {
83
+ let remaining = Math.max(0, maximumTokens - 2);
84
+ let truncated = false;
85
+ const observations = [];
86
+ const selected = [];
87
+ let overheadBudget = 0;
88
+ for (const original of values) {
89
+ const empty = original.type === 'tool_result'
90
+ ? { ...original, result: { ...original.result, content: '', truncated: true } }
91
+ : { ...original, value: '', truncated: true };
92
+ const overhead = countModelTokens(JSON.stringify(visibleObservation(empty))) + 8;
93
+ if (overheadBudget + overhead > remaining) {
94
+ truncated = true;
95
+ break;
96
+ }
97
+ selected.push({ original, overhead });
98
+ overheadBudget += overhead;
99
+ }
100
+ for (const { original, overhead } of selected) {
101
+ let bodyBudget = Math.max(0, remaining - overheadBudget - 12);
102
+ let value;
103
+ let bodyTruncated = false;
104
+ for (;;) {
105
+ const bounded = truncateModelText(observationContent(original), bodyBudget);
106
+ bodyTruncated ||= bounded.truncated;
107
+ value =
108
+ original.type === 'tool_result'
109
+ ? {
110
+ ...original,
111
+ result: {
112
+ ...original.result,
113
+ content: bounded.content,
114
+ truncated: original.result.truncated === true || bodyTruncated
115
+ }
116
+ }
117
+ : {
118
+ ...original,
119
+ value: bounded.content,
120
+ truncated: original.truncated === true || bodyTruncated
121
+ };
122
+ if (countModelTokens(JSON.stringify(visibleObservation(value))) + 1 <=
123
+ remaining - (overheadBudget - overhead) ||
124
+ bodyBudget === 0)
125
+ break;
126
+ bodyBudget = Math.floor(bodyBudget / 2);
127
+ }
128
+ overheadBudget -= overhead;
129
+ observations.push(value);
130
+ remaining -= countModelTokens(JSON.stringify(visibleObservation(value))) + 1;
131
+ truncated ||=
132
+ bodyTruncated ||
133
+ (original.type === 'tool_result'
134
+ ? original.result.truncated === true
135
+ : original.truncated === true);
136
+ }
137
+ return { observations, content: renderObservations(observations), truncated };
138
+ }
139
+ export function newObservationId() {
140
+ return randomUUID();
141
+ }
142
+ export function observationModelParts(message) {
143
+ if (!message.observations || !message.images?.length)
144
+ return undefined;
145
+ const prefix = [];
146
+ try {
147
+ const parsed = JSON.parse(message.content ?? '');
148
+ if (parsed && !Array.isArray(parsed) && typeof parsed === 'object') {
149
+ const { observations: _observations, ...metadata } = parsed;
150
+ prefix.push({ type: 'text', text: JSON.stringify(metadata) });
151
+ }
152
+ }
153
+ catch { }
154
+ return [
155
+ ...prefix,
156
+ ...message.observations.flatMap((value) => {
157
+ const parts = [{ type: 'text', text: JSON.stringify(visibleObservation(value)) }];
158
+ for (const index of observationImages(value)) {
159
+ const image = message.images?.[index];
160
+ if (image)
161
+ parts.push({ type: 'image', image });
162
+ }
163
+ return parts;
164
+ })
165
+ ];
166
+ }
167
+ export function parseObservations(value) {
168
+ if (!Array.isArray(value) || value.length > 4096)
169
+ return undefined;
170
+ const ids = new Set();
171
+ for (const item of value) {
172
+ if (!item || typeof item !== 'object' || typeof item.id !== 'string' || ids.has(item.id))
173
+ return undefined;
174
+ ids.add(item.id);
175
+ if (item.type === 'tool_result') {
176
+ if (!item.source ||
177
+ typeof item.source.callId !== 'string' ||
178
+ typeof item.source.toolName !== 'string' ||
179
+ !['completed', 'failed'].includes(item.outcome) ||
180
+ !item.result ||
181
+ typeof item.result.content !== 'string')
182
+ return undefined;
183
+ }
184
+ else if (item.type !== 'value' ||
185
+ !['text', 'json', 'image'].includes(item.format) ||
186
+ typeof item.value !== 'string')
187
+ return undefined;
188
+ const indices = item.type === 'tool_result' ? item.result.imageIndices : item.imageIndices;
189
+ if (indices !== undefined &&
190
+ (!Array.isArray(indices) ||
191
+ indices.some((i) => !Number.isSafeInteger(i) || Number(i) < 0 || Number(i) >= 5)))
192
+ return undefined;
193
+ }
194
+ return value;
195
+ }