@sema-agent/core 7.51.2 → 7.53.0

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 (446) hide show
  1. package/CHANGELOG.md +698 -2
  2. package/README.md +3 -1
  3. package/dist/agents/agent-transcript-tool.d.ts +1 -1
  4. package/dist/agents/cascade.js +4 -0
  5. package/dist/agents/cross-session-envelope.d.ts +8 -0
  6. package/dist/agents/cross-session-envelope.js +6 -0
  7. package/dist/agents/cross-session-judge.d.ts +21 -1
  8. package/dist/agents/cross-session-judge.js +8 -0
  9. package/dist/agents/cross-session-ref.d.ts +5 -0
  10. package/dist/agents/cross-session-ref.js +1 -0
  11. package/dist/agents/cumulative-stats.d.ts +3 -0
  12. package/dist/agents/cumulative-stats.js +3 -0
  13. package/dist/agents/list-agents-tool.d.ts +1 -1
  14. package/dist/agents/org-delivery-gate.d.ts +122 -0
  15. package/dist/agents/org-delivery-gate.js +69 -0
  16. package/dist/agents/peer-held-queue.d.ts +9 -4
  17. package/dist/agents/peer-held-queue.js +6 -5
  18. package/dist/agents/peer-session-drain.d.ts +35 -5
  19. package/dist/agents/peer-session-drain.js +271 -180
  20. package/dist/agents/read-inbox-tool.d.ts +8 -1
  21. package/dist/agents/read-inbox-tool.js +5 -1
  22. package/dist/agents/repair-loop.js +4 -0
  23. package/dist/agents/send-message-tool.d.ts +11 -16
  24. package/dist/agents/send-message-tool.js +11 -13
  25. package/dist/agents/subagent.d.ts +3 -0
  26. package/dist/agents/subagent.js +105 -76
  27. package/dist/agents/tool-filter.d.ts +58 -13
  28. package/dist/agents/tool-filter.js +34 -14
  29. package/dist/bench/metrics.d.ts +1 -0
  30. package/dist/brain/anthropic.d.ts +6 -1
  31. package/dist/brain/anthropic.js +17 -13
  32. package/dist/brain/model-presets.d.ts +4 -5
  33. package/dist/brain/model-presets.js +6 -5
  34. package/dist/brain/open-responses.js +16 -12
  35. package/dist/brain/openai.js +16 -12
  36. package/dist/brain/request-params.d.ts +12 -33
  37. package/dist/brain/request-params.js +5 -2
  38. package/dist/brain/request-route.d.ts +9 -8
  39. package/dist/brain/request-route.js +1 -0
  40. package/dist/brain/route-adjudicator.d.ts +123 -47
  41. package/dist/brain/route-adjudicator.js +171 -42
  42. package/dist/brain/route-conformance.js +2 -2
  43. package/dist/brain/routing.d.ts +24 -1
  44. package/dist/brain/routing.js +54 -19
  45. package/dist/brain/status-sink.d.ts +18 -0
  46. package/dist/brain/status-sink.js +7 -0
  47. package/dist/brain/timeout.js +5 -4
  48. package/dist/core/a2a.d.ts +5 -2
  49. package/dist/core/a2a.js +30 -13
  50. package/dist/core/allow-entry.d.ts +42 -9
  51. package/dist/core/allow-entry.js +25 -18
  52. package/dist/core/auto-compaction.d.ts +80 -20
  53. package/dist/core/auto-compaction.js +65 -18
  54. package/dist/core/auto-promote.d.ts +2 -1
  55. package/dist/core/auto-promote.js +2 -2
  56. package/dist/core/caller-tool-name.d.ts +9 -0
  57. package/dist/core/caller-tool-name.js +13 -0
  58. package/dist/core/checkpoint-requirements.d.ts +7 -1
  59. package/dist/core/checkpoint-requirements.js +2 -0
  60. package/dist/core/checkpoint-store.d.ts +57 -24
  61. package/dist/core/checkpoint-store.js +3 -3
  62. package/dist/core/child-clamp-seats.d.ts +6 -0
  63. package/dist/core/child-clamp-seats.js +2 -1
  64. package/dist/core/compliance.js +3 -1
  65. package/dist/core/credential-vocabulary.d.ts +33 -8
  66. package/dist/core/credential-vocabulary.js +32 -7
  67. package/dist/core/decision-receipt.d.ts +2 -2
  68. package/dist/core/delegation-frames.d.ts +9 -2
  69. package/dist/core/delegation-name.d.ts +18 -0
  70. package/dist/core/delegation-name.js +47 -0
  71. package/dist/core/effective-path-target.d.ts +25 -6
  72. package/dist/core/effective-path-target.js +24 -2
  73. package/dist/core/engine-capabilities.d.ts +8 -1
  74. package/dist/core/engine-capabilities.js +1 -1
  75. package/dist/core/engine-notice.d.ts +49 -21
  76. package/dist/core/frontmatter-fence.d.ts +10 -0
  77. package/dist/core/frontmatter-fence.js +6 -0
  78. package/dist/core/gate-fold.js +8 -25
  79. package/dist/core/gate-lanes.js +358 -274
  80. package/dist/core/gate-outcome.d.ts +11 -6
  81. package/dist/core/governance-codes.d.ts +11 -4
  82. package/dist/core/governance-codes.js +12 -3
  83. package/dist/core/hands-band-screen.d.ts +7 -0
  84. package/dist/core/hands-band-screen.js +32 -0
  85. package/dist/core/hooks.d.ts +283 -739
  86. package/dist/core/hooks.js +100 -193
  87. package/dist/{tools/fs → core}/image-admission.d.ts +21 -3
  88. package/dist/{tools/fs → core}/image-admission.js +24 -6
  89. package/dist/core/locked-config.d.ts +84 -32
  90. package/dist/core/locked-config.js +128 -42
  91. package/dist/core/mcp-connection-pool.d.ts +4 -1
  92. package/dist/core/mcp-connection-pool.js +7 -2
  93. package/dist/core/mcp-probe.d.ts +12 -9
  94. package/dist/core/mcp-probe.js +3 -3
  95. package/dist/core/mcp-server-spec.d.ts +104 -10
  96. package/dist/core/mcp-server-spec.js +183 -33
  97. package/dist/core/mcp.d.ts +31 -20
  98. package/dist/core/mcp.js +66 -56
  99. package/dist/core/memory-engine/data-plane.js +5 -1
  100. package/dist/core/memory-engine/distiller.js +16 -2
  101. package/dist/core/memory-engine/engine.d.ts +22 -30
  102. package/dist/core/memory-engine/engine.js +16 -10
  103. package/dist/core/memory-engine/frontmatter.d.ts +6 -0
  104. package/dist/core/memory-engine/frontmatter.js +19 -16
  105. package/dist/core/memory.d.ts +2 -2
  106. package/dist/core/mode-policy.d.ts +5 -16
  107. package/dist/core/mode-policy.js +7 -19
  108. package/dist/core/model-seat.d.ts +4 -1
  109. package/dist/core/mods/dollar.d.ts +109 -0
  110. package/dist/core/mods/dollar.js +154 -0
  111. package/dist/core/mods/host.d.ts +23 -0
  112. package/dist/core/mods/host.js +21 -0
  113. package/dist/core/mods/kernel/budget.d.ts +43 -0
  114. package/dist/core/mods/kernel/budget.js +83 -0
  115. package/dist/core/mods/kernel/dispatch.d.ts +100 -0
  116. package/dist/core/mods/kernel/dispatch.js +699 -0
  117. package/dist/core/mods/kernel/events.d.ts +245 -0
  118. package/dist/core/mods/kernel/events.js +210 -0
  119. package/dist/core/mods/kernel/index.d.ts +6 -0
  120. package/dist/core/mods/kernel/index.js +5 -0
  121. package/dist/core/mods/kernel/receive.d.ts +94 -0
  122. package/dist/core/mods/kernel/receive.js +188 -0
  123. package/dist/core/mods/kernel/registration.d.ts +131 -0
  124. package/dist/core/mods/kernel/registration.js +102 -0
  125. package/dist/core/mods/kernel/site-rules.d.ts +149 -0
  126. package/dist/core/mods/kernel/site-rules.js +296 -0
  127. package/dist/core/mods/stations.d.ts +344 -0
  128. package/dist/core/mods/stations.js +437 -0
  129. package/dist/core/mounted-mcp.d.ts +57 -0
  130. package/dist/core/mounted-mcp.js +71 -2
  131. package/dist/core/own-property-receipt.d.ts +13 -0
  132. package/dist/core/own-property-receipt.js +13 -23
  133. package/dist/core/parent-spec-seat.d.ts +18 -7
  134. package/dist/core/parent-spec-seat.js +6 -2
  135. package/dist/core/path-identity.js +2 -1
  136. package/dist/core/permission-rule-model.d.ts +58 -9
  137. package/dist/core/permission-rule-model.js +81 -7
  138. package/dist/core/permission-rule-org.d.ts +163 -33
  139. package/dist/core/permission-rule-org.js +205 -71
  140. package/dist/core/permission-rule-syntax.d.ts +15 -0
  141. package/dist/core/permission-rule-syntax.js +24 -16
  142. package/dist/core/permission-rules.d.ts +14 -2
  143. package/dist/core/permission-rules.js +63 -23
  144. package/dist/core/prompt-section-seat.d.ts +15 -27
  145. package/dist/core/prompt-section-seat.js +73 -40
  146. package/dist/core/protocol-http-auth.d.ts +3 -1
  147. package/dist/core/protocol-http-auth.js +2 -0
  148. package/dist/core/reminder-mint.d.ts +2 -2
  149. package/dist/core/remote-env.d.ts +24 -12
  150. package/dist/core/remote-env.js +1 -0
  151. package/dist/core/resume-startup-cause.d.ts +16 -1
  152. package/dist/core/resume-startup-cause.js +4 -1
  153. package/dist/core/retention.js +7 -2
  154. package/dist/core/retired-keys.d.ts +12 -2
  155. package/dist/core/retired-keys.js +15 -1
  156. package/dist/core/roles.js +60 -10
  157. package/dist/core/rule-lane-reads.js +1 -1
  158. package/dist/core/runner/announce-once-ledger.d.ts +31 -1
  159. package/dist/core/runner/announce-once-ledger.js +22 -0
  160. package/dist/core/runner/assemble-result.d.ts +9 -0
  161. package/dist/core/runner/assemble-result.js +3 -1
  162. package/dist/core/runner/call-hook-stations.d.ts +23 -27
  163. package/dist/core/runner/call-hook-stations.js +58 -42
  164. package/dist/core/runner/caller-stop-gate.d.ts +25 -0
  165. package/dist/core/runner/caller-stop-gate.js +7 -0
  166. package/dist/core/runner/compaction-seams.d.ts +8 -22
  167. package/dist/core/runner/compaction-seams.js +28 -53
  168. package/dist/core/runner/construction-doors.js +11 -1
  169. package/dist/core/runner/contracts.d.ts +86 -83
  170. package/dist/core/runner/credential-origin-seat.d.ts +2 -0
  171. package/dist/core/runner/credential-origin-seat.js +19 -0
  172. package/dist/core/runner/extra-body-dropped-seat.d.ts +2 -6
  173. package/dist/core/runner/gate-exit.d.ts +47 -36
  174. package/dist/core/runner/gate-exit.js +12 -5
  175. package/dist/core/runner/image.js +1 -2
  176. package/dist/core/runner/inline-image.js +1 -1
  177. package/dist/core/runner/mcp-redial.d.ts +52 -10
  178. package/dist/core/runner/mcp-redial.js +38 -9
  179. package/dist/core/runner/notice-seat-input.d.ts +11 -0
  180. package/dist/core/runner/notice-seat-input.js +1 -0
  181. package/dist/core/runner/permission-rule-lanes.d.ts +5 -2
  182. package/dist/core/runner/permission-rule-lanes.js +22 -10
  183. package/dist/core/runner/person-path-rows.d.ts +3 -1
  184. package/dist/core/runner/person-path-rows.js +3 -2
  185. package/dist/core/runner/prepare-acquire-reconcile.js +5 -1
  186. package/dist/core/runner/prepare-ask-lane.d.ts +5 -7
  187. package/dist/core/runner/prepare-ask-lane.js +6 -15
  188. package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -2
  189. package/dist/core/runner/prepare-caps-and-workflow.js +25 -8
  190. package/dist/core/runner/prepare-config-doors.d.ts +52 -1
  191. package/dist/core/runner/prepare-config-doors.js +168 -143
  192. package/dist/core/runner/prepare-defer-classify.js +7 -11
  193. package/dist/core/runner/prepare-delegation-surface.d.ts +2 -2
  194. package/dist/core/runner/prepare-delegation-surface.js +7 -5
  195. package/dist/core/runner/prepare-gate-stations.d.ts +8 -11
  196. package/dist/core/runner/prepare-gate-stations.js +11 -10
  197. package/dist/core/runner/prepare-hands-readface.d.ts +1 -1
  198. package/dist/core/runner/prepare-hands-readface.js +2 -1
  199. package/dist/core/runner/prepare-inherited-gate.d.ts +8 -12
  200. package/dist/core/runner/prepare-inherited-gate.js +10 -23
  201. package/dist/core/runner/prepare-listings.d.ts +1 -1
  202. package/dist/core/runner/prepare-listings.js +4 -2
  203. package/dist/core/runner/prepare-memory-engine-session.d.ts +0 -6
  204. package/dist/core/runner/prepare-memory-engine-session.js +20 -7
  205. package/dist/core/runner/prepare-memory.d.ts +3 -2
  206. package/dist/core/runner/prepare-memory.js +6 -2
  207. package/dist/core/runner/prepare-offload-wrappers.d.ts +4 -4
  208. package/dist/core/runner/prepare-offload-wrappers.js +2 -1
  209. package/dist/core/runner/prepare-park-ask.js +10 -14
  210. package/dist/core/runner/prepare-policy-chain.d.ts +17 -15
  211. package/dist/core/runner/prepare-policy-chain.js +104 -109
  212. package/dist/core/runner/prepare-project-context.d.ts +1 -1
  213. package/dist/core/runner/prepare-project-context.js +11 -12
  214. package/dist/core/runner/prepare-prompt-assembly.d.ts +45 -40
  215. package/dist/core/runner/prepare-prompt-assembly.js +138 -101
  216. package/dist/core/runner/prepare-prompt-inputs.d.ts +28 -23
  217. package/dist/core/runner/prepare-prompt-inputs.js +11 -10
  218. package/dist/core/runner/prepare-protocol-tools.d.ts +11 -7
  219. package/dist/core/runner/prepare-protocol-tools.js +20 -13
  220. package/dist/core/runner/prepare-question-face.d.ts +4 -2
  221. package/dist/core/runner/prepare-question-face.js +4 -3
  222. package/dist/core/runner/prepare-safety-scan.js +6 -10
  223. package/dist/core/runner/prepare-suspend-saga.d.ts +6 -0
  224. package/dist/core/runner/prepare-suspend-saga.js +7 -5
  225. package/dist/core/runner/prepare-task.js +41 -23
  226. package/dist/core/runner/prepare-turn-wiring.d.ts +13 -15
  227. package/dist/core/runner/prepare-turn-wiring.js +29 -27
  228. package/dist/core/runner/prepare-wiring-manifest.d.ts +13 -9
  229. package/dist/core/runner/prepare-wiring-manifest.js +14 -11
  230. package/dist/core/runner/resume-admission.d.ts +4 -1
  231. package/dist/core/runner/resume-admission.js +7 -5
  232. package/dist/core/runner/resume-apply.d.ts +5 -2
  233. package/dist/core/runner/resume-apply.js +24 -42
  234. package/dist/core/runner/resume-checkpoint-screen.d.ts +1 -0
  235. package/dist/core/runner/resume-checkpoint-screen.js +9 -1
  236. package/dist/core/runner/resume-internals-and-config.d.ts +3 -3
  237. package/dist/core/runner/resume-internals-and-config.js +3 -8
  238. package/dist/core/runner/resume-preflight.js +38 -16
  239. package/dist/core/runner/retired-runner-deps.d.ts +5 -6
  240. package/dist/core/runner/retired-runner-deps.js +4 -5
  241. package/dist/core/runner/run-brain-sinks.d.ts +3 -2
  242. package/dist/core/runner/run-brain-sinks.js +5 -1
  243. package/dist/core/runner/run-compaction-machinery.d.ts +7 -1
  244. package/dist/core/runner/run-compaction-machinery.js +7 -33
  245. package/dist/core/runner/run-harness-handlers.js +4 -2
  246. package/dist/core/runner/run-identity-wiring.d.ts +3 -1
  247. package/dist/core/runner/run-identity-wiring.js +3 -2
  248. package/dist/core/runner/run-leg.js +103 -95
  249. package/dist/core/runner/run-notification-lane.js +1 -0
  250. package/dist/core/runner/run-recovery-lanes.d.ts +3 -0
  251. package/dist/core/runner/run-recovery-lanes.js +14 -11
  252. package/dist/core/runner/run-settle-and-teardown.js +9 -28
  253. package/dist/core/runner/run-stop-and-final-verify.js +18 -25
  254. package/dist/core/runner/run-terminal-adoption.d.ts +3 -0
  255. package/dist/core/runner/run-terminal-adoption.js +34 -22
  256. package/dist/core/runner/run-tool-mount-facts.js +5 -3
  257. package/dist/core/runner/run-turn-boundary.js +32 -37
  258. package/dist/core/runner/runtask.d.ts +6 -7
  259. package/dist/core/runner/runtask.js +15 -73
  260. package/dist/core/runner/session-rule-policy.d.ts +5 -5
  261. package/dist/core/runner/session-rule-policy.js +13 -8
  262. package/dist/core/runner/side-call-account.d.ts +68 -0
  263. package/dist/core/runner/side-call-account.js +61 -0
  264. package/dist/core/runner/skills-seat.d.ts +15 -0
  265. package/dist/core/runner/skills-seat.js +57 -0
  266. package/dist/core/runner/stream-halt-verbs.js +12 -17
  267. package/dist/core/runner/stream-lifecycle-verbs.js +8 -5
  268. package/dist/core/runner/stream-steer-verb.d.ts +1 -1
  269. package/dist/core/runner/stream-steer-verb.js +20 -38
  270. package/dist/core/runner/sub-agent-deny-lists.d.ts +124 -23
  271. package/dist/core/runner/sub-agent-deny-lists.js +230 -71
  272. package/dist/core/runner/synthetic-tools.d.ts +5 -2
  273. package/dist/core/runner/synthetic-tools.js +2 -12
  274. package/dist/core/runner/tool-end-body.d.ts +5 -6
  275. package/dist/core/runner/tool-end-body.js +6 -4
  276. package/dist/core/runner/tool-not-executed.d.ts +15 -0
  277. package/dist/core/runner/tool-not-executed.js +30 -0
  278. package/dist/core/runner/tool-occurrence.d.ts +8 -7
  279. package/dist/core/runner/tool-occurrence.js +5 -5
  280. package/dist/core/runner/tool-result-media-seat.d.ts +1 -1
  281. package/dist/core/runner-deps.d.ts +43 -36
  282. package/dist/core/safety-merge-corpus.js +18 -2
  283. package/dist/core/secret-env.d.ts +88 -20
  284. package/dist/core/secret-env.js +192 -38
  285. package/dist/core/session-policy-store.d.ts +71 -16
  286. package/dist/core/session-policy-store.js +138 -28
  287. package/dist/core/session-reconcile.d.ts +4 -0
  288. package/dist/core/session-reconcile.js +2 -1
  289. package/dist/core/shell-read-silence.js +3 -32
  290. package/dist/core/side-query.d.ts +5 -3
  291. package/dist/core/skill-grant.d.ts +3 -2
  292. package/dist/core/skill-grant.js +17 -9
  293. package/dist/core/skills-directory.d.ts +31 -11
  294. package/dist/core/skills-directory.js +655 -104
  295. package/dist/core/store-contracts/mailbox-store-contract.js +13 -0
  296. package/dist/core/task-event.d.ts +49 -3
  297. package/dist/core/task-notification.js +2 -2
  298. package/dist/core/task-result.d.ts +8 -0
  299. package/dist/core/task-spec.d.ts +20 -19
  300. package/dist/core/task-stream.d.ts +14 -4
  301. package/dist/core/tighten-task-spec.d.ts +4 -3
  302. package/dist/core/tighten-task-spec.js +2 -4
  303. package/dist/core/tool-check-reading.d.ts +74 -0
  304. package/dist/core/tool-check-reading.js +80 -0
  305. package/dist/core/tool-policy.d.ts +62 -18
  306. package/dist/core/tool-policy.js +86 -15
  307. package/dist/core/tool-registry.d.ts +20 -0
  308. package/dist/core/tool-registry.js +4 -0
  309. package/dist/core/tool-spec.d.ts +10 -6
  310. package/dist/core/tools.js +2 -0
  311. package/dist/core/trace.d.ts +51 -32
  312. package/dist/core/types.d.ts +2 -2
  313. package/dist/core/types.js +1 -1
  314. package/dist/core/unc-spelling.d.ts +10 -0
  315. package/dist/core/unc-spelling.js +3 -0
  316. package/dist/core/untrusted-egress.d.ts +8 -0
  317. package/dist/core/untrusted-egress.js +4 -1
  318. package/dist/core/untrusted-text.d.ts +16 -0
  319. package/dist/core/untrusted-text.js +7 -2
  320. package/dist/core/user-attachment.d.ts +25 -4
  321. package/dist/core/user-attachment.js +63 -42
  322. package/dist/core/wiring-manifest.d.ts +18 -15
  323. package/dist/core/wiring-manifest.js +2 -2
  324. package/dist/engine/compaction/utils.js +1 -2
  325. package/dist/engine/execution-env/node-execution-env.d.ts +4 -3
  326. package/dist/engine/execution-env/symlink-chain.js +1 -1
  327. package/dist/engine/harness/agent-harness.d.ts +1 -1
  328. package/dist/engine/harness/agent-harness.js +5 -4
  329. package/dist/engine/harness/types.d.ts +20 -16
  330. package/dist/engine/harness/types.js +7 -1
  331. package/dist/engine/llm/types.d.ts +12 -7
  332. package/dist/engine/loop/agent-loop.d.ts +12 -1
  333. package/dist/engine/loop/agent-loop.js +18 -6
  334. package/dist/engine/loop/types.d.ts +8 -2
  335. package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
  336. package/dist/engine/session/import-validate.js +3 -10
  337. package/dist/engine/session/session.d.ts +4 -4
  338. package/dist/engine/session/session.js +4 -4
  339. package/dist/index.d.ts +33 -23
  340. package/dist/index.js +23 -15
  341. package/dist/internal/harness.d.ts +2 -1
  342. package/dist/internal/harness.js +2 -1
  343. package/dist/orchestration/goal.d.ts +24 -1
  344. package/dist/orchestration/goal.js +3 -2
  345. package/dist/orchestration/run-spec.d.ts +4 -6
  346. package/dist/orchestration/run-spec.js +39 -63
  347. package/dist/orchestration/run-workflow-tool.js +1 -2
  348. package/dist/orchestration/workflow.d.ts +11 -3
  349. package/dist/orchestration/workflow.js +11 -2
  350. package/dist/prompt-assembly/artifact-store.d.ts +72 -56
  351. package/dist/prompt-assembly/artifact-store.js +60 -52
  352. package/dist/prompt-assembly/artifact.d.ts +90 -76
  353. package/dist/prompt-assembly/artifact.js +197 -145
  354. package/dist/prompt-assembly/assemble.d.ts +36 -29
  355. package/dist/prompt-assembly/assemble.js +34 -220
  356. package/dist/prompt-assembly/bands.d.ts +20 -0
  357. package/dist/prompt-assembly/bands.js +18 -0
  358. package/dist/prompt-assembly/catalog/constitution.d.ts +23 -0
  359. package/dist/prompt-assembly/catalog/constitution.js +69 -0
  360. package/dist/prompt-assembly/catalog/core-behavior.d.ts +9 -0
  361. package/dist/prompt-assembly/catalog/core-behavior.js +85 -0
  362. package/dist/prompt-assembly/catalog/index.d.ts +11 -0
  363. package/dist/prompt-assembly/catalog/index.js +60 -0
  364. package/dist/prompt-assembly/catalog/memory.d.ts +13 -0
  365. package/dist/prompt-assembly/catalog/memory.js +6 -0
  366. package/dist/prompt-assembly/catalog/modes.d.ts +15 -0
  367. package/dist/prompt-assembly/catalog/modes.js +137 -0
  368. package/dist/prompt-assembly/catalog/role.d.ts +10 -0
  369. package/dist/prompt-assembly/catalog/role.js +157 -0
  370. package/dist/prompt-assembly/catalog/schema.d.ts +138 -0
  371. package/dist/prompt-assembly/catalog/schema.js +25 -0
  372. package/dist/prompt-assembly/catalog/sections.d.ts +9 -0
  373. package/dist/prompt-assembly/catalog/sections.js +98 -0
  374. package/dist/prompt-assembly/catalog/team.d.ts +4 -0
  375. package/dist/prompt-assembly/catalog/team.js +258 -0
  376. package/dist/prompt-assembly/composer.d.ts +26 -28
  377. package/dist/prompt-assembly/composer.js +124 -46
  378. package/dist/prompt-assembly/epoch.d.ts +89 -79
  379. package/dist/prompt-assembly/epoch.js +115 -142
  380. package/dist/prompt-assembly/explain.d.ts +58 -34
  381. package/dist/prompt-assembly/explain.js +21 -24
  382. package/dist/prompt-assembly/overlay.d.ts +137 -0
  383. package/dist/prompt-assembly/overlay.js +339 -0
  384. package/dist/prompt-assembly/renderers.d.ts +21 -0
  385. package/dist/prompt-assembly/renderers.js +39 -0
  386. package/dist/prompt-assembly/section-usage.d.ts +3 -3
  387. package/dist/prompt-assembly/section-usage.js +1 -1
  388. package/dist/prompt-assembly/select.d.ts +71 -0
  389. package/dist/prompt-assembly/select.js +106 -0
  390. package/dist/prompt-assembly/sugar.d.ts +31 -0
  391. package/dist/prompt-assembly/sugar.js +20 -0
  392. package/dist/prompt-assembly/turn-snapshot.d.ts +3 -2
  393. package/dist/prompt-assembly/types.d.ts +45 -148
  394. package/dist/prompts/coordinator.d.ts +2 -21
  395. package/dist/prompts/coordinator.js +3 -255
  396. package/dist/prompts/cowork.d.ts +27 -16
  397. package/dist/prompts/cowork.js +2 -23
  398. package/dist/prompts/default.d.ts +38 -511
  399. package/dist/prompts/default.js +20 -288
  400. package/dist/prompts/supervisor.d.ts +6 -71
  401. package/dist/prompts/supervisor.js +6 -117
  402. package/dist/stores/file/permission-rule-store.d.ts +1 -1
  403. package/dist/stores/file/permission-rule-store.js +2 -1
  404. package/dist/tools/artifact/artifact-tool.js +4 -3
  405. package/dist/tools/fs/bash-readonly-classifier.d.ts +6 -5
  406. package/dist/tools/fs/dir-entries.d.ts +4 -2
  407. package/dist/tools/fs/dir-entries.js +16 -4
  408. package/dist/tools/fs/fs-bash.d.ts +1 -1
  409. package/dist/tools/fs/fs-bash.js +22 -11
  410. package/dist/tools/fs/fs-pdf.js +17 -13
  411. package/dist/tools/fs/fs-read.js +4 -3
  412. package/dist/tools/fs/fs-shared.d.ts +1 -10
  413. package/dist/tools/fs/fs-shared.js +3 -4
  414. package/dist/tools/fs/fs-write.js +2 -1
  415. package/dist/tools/fs/notebook.js +1 -1
  416. package/dist/tools/fs/pdf.d.ts +20 -10
  417. package/dist/tools/fs/pdf.js +19 -10
  418. package/dist/tools/fs/program-read-model.d.ts +68 -8
  419. package/dist/tools/fs/program-read-model.js +112 -33
  420. package/dist/tools/fs/program-read-model.rows.js +30 -10
  421. package/dist/tools/fs/read-deny-home.d.ts +25 -9
  422. package/dist/tools/fs/read-deny-home.js +28 -27
  423. package/dist/tools/fs/read-deny.d.ts +41 -11
  424. package/dist/tools/fs/read-deny.js +51 -5
  425. package/dist/tools/fs/safety.d.ts +4 -26
  426. package/dist/tools/fs/safety.js +10 -32
  427. package/dist/tools/fs/search.js +15 -10
  428. package/dist/tools/fs/shell-read-argv.d.ts +3 -2
  429. package/dist/tools/fs/shell-read-argv.js +118 -38
  430. package/dist/tools/fs/shell-read-establish.d.ts +5 -5
  431. package/dist/tools/fs/shell-read-establish.js +11 -61
  432. package/dist/tools/fs/shell-read-identity.js +6 -3
  433. package/dist/tools/fs/shell-read-judge.d.ts +13 -15
  434. package/dist/tools/fs/shell-read-judge.js +18 -4
  435. package/dist/tools/fs/shell-read-plan.d.ts +2 -2
  436. package/dist/tools/web.js +1 -1
  437. package/package.json +13 -1
  438. package/test/export-surface.snapshot.json +306 -103
  439. package/wire-changes/core@7.52.0.json +5859 -0
  440. package/wire-changes/core@7.53.0.json +1946 -0
  441. package/dist/core/hook-seats.d.ts +0 -66
  442. package/dist/core/hook-seats.js +0 -37
  443. package/dist/prompt-assembly/packs/sema-default.d.ts +0 -2
  444. package/dist/prompt-assembly/packs/sema-default.js +0 -147
  445. package/dist/prompts/simple-sections.d.ts +0 -58
  446. package/dist/prompts/simple-sections.js +0 -43
@@ -64,6 +64,7 @@ function renderFile(f) {
64
64
  return isTextMedia(f.mediaType) ? `${head}\n${Buffer.from(f.content).toString("utf8")}` : `${head}\n[binary content, not shown]`;
65
65
  }
66
66
  const isRecord = (x) => x !== null && typeof x === "object";
67
+ const withDefaultAction = (args) => (isRecord(args) && args["action"] === undefined ? { ...args, action: "publish" } : args);
67
68
  const everyItem = (x, pred) => Array.isArray(x) && x.every(pred);
68
69
  const optString = (v) => v === undefined || typeof v === "string";
69
70
  const isRef = (x) => isRecord(x) && typeof x["url"] === "string" && typeof x["slug"] === "string" && typeof x["version"] === "string" && optString(x["title"]);
@@ -445,11 +446,11 @@ export function createArtifactTool(opts) {
445
446
  contentOrigin: ARTIFACT_PLANE_CONTENT_ORIGIN[caps.plane],
446
447
  description: artifactDescription(caps.plane, caps.actions),
447
448
  parameters: buildSchema(caps),
448
- prepareArguments: (args) => (isRecord(args) && args["action"] === undefined ? { ...args, action: "publish" } : args),
449
+ prepareArguments: withDefaultAction,
449
450
  isConcurrencySafe: (args) => isRecord(args) && typeof args["action"] === "string" && ARTIFACT_ACTION_CONCURRENCY_SAFE[args["action"]] === true,
450
451
  execute: async (args, ctx) => {
451
- const a = args;
452
- const action = a.action ?? "publish";
452
+ const a = withDefaultAction(args);
453
+ const action = a.action;
453
454
  const target = typeof a.url === "string" ? a.url : undefined;
454
455
  if (target !== undefined)
455
456
  activeTargets.set(target, (activeTargets.get(target) ?? 0) + 1);
@@ -305,11 +305,12 @@ export interface BashReadonlyRootBoundary {
305
305
  * EVERY read face wires this one seat, the `bash_readonly` shell included, at BOTH of its judging
306
306
  * moments — roots answer WHERE a command may read and the allowlist WHICH verb runs, neither answers
307
307
  * WHICH FILES are off the table. What this seat is and is not is stated once, at
308
- * `shell.read_boundary.friction_floor`. `walked` — the path is a member a traversal enumerated, not a
309
- * spelling of the command ({@link import("./read-deny.js").ReadDenyMatcher.matchPath}). */
310
- denyMatch?: (resolvedPath: string, opts?: {
311
- readonly walked?: boolean;
312
- }) => string | null;
308
+ * `shell.read_boundary.friction_floor`. */
309
+ denyMatch?: (resolvedPath: string) => string | null;
310
+ /** The row a directory NAMES or contains, or `{ unplaced }` — a home-anchored row no home places, which any root may hold
311
+ * ({@link import("./read-deny.js").ReadDenyMatcher.rowUnderRoot}), or null — read for a recursive read's root, the
312
+ * one question the table answers about a tree without enumerating it. PRESENT-IFF {@link denyMatch} is. */
313
+ denyUnder?: (resolvedPath: string) => import("./read-deny.js").ReadDenyRootAnswer;
313
314
  /** What the wired {@link denyMatch} judge would apply — the ACTIVE deny patterns. Read for ONE question:
314
315
  * is there anything for a traversal to defeat? EMPTY ⇒ the judge refuses nothing, so a walk under it
315
316
  * bypasses nothing and {@link CompoundReadonlyVerdict.recursiveReadPaths} is not minted. ABSENT ⇒ the
@@ -22,7 +22,7 @@
22
22
  * judging was cut short by an abort — the listing is a prefix, not the directory).
23
23
  */
24
24
  import type { ExecutionEnv } from "../../internal/harness-types.js";
25
- import type { FileError, FileInfo, FileKind, Result } from "../../internal/harness.js";
25
+ import { FileError, type FileInfo, type FileKind, type Result } from "../../internal/harness.js";
26
26
  import { type HomeViewEnv, type HomeViewsCarrier } from "./read-deny-home.js";
27
27
  /** The upstream at-mention's cap on listed entries. */
28
28
  export declare const DIRECTORY_LISTING_MAX_ENTRIES = 1000;
@@ -37,7 +37,9 @@ export type EntryDenyTable = {
37
37
  export type EntryDenyJudge = (path: string, leaf?: "file") => Promise<{
38
38
  pattern: string;
39
39
  } | null>;
40
- /** The per-entry judge over `deny` (literal spelling, then the home view). */
40
+ /** The per-entry judge over `deny` (literal spelling, then the home view). An entry whose home view nobody could read is not
41
+ * an entry with no view: the judgment of the traversal did not finish, and the call is refused whole
42
+ * ({@link HomeViewUnreadError}, thrown) — what the walk would serve was not judged, so neither it nor a partial result is. */
41
43
  export declare function createEntryDenyJudge(env: HomeViewEnv, deny: EntryDenyTable, signal?: AbortSignal): EntryDenyJudge;
42
44
  export interface DirectoryEntry {
43
45
  name: string;
@@ -1,4 +1,5 @@
1
- import { homeViewsOf } from "./read-deny-home.js";
1
+ import { FileError } from "../../internal/harness.js";
2
+ import { HomeViewUnreadError, homeViewsOf } from "./read-deny-home.js";
2
3
  import { DATA_LABEL_UNSAFE, quoteDataLabel } from "../../internal/llm.js";
3
4
  export const DIRECTORY_LISTING_MAX_ENTRIES = 1000;
4
5
  export function createEntryDenyJudge(env, deny, signal) {
@@ -7,8 +8,11 @@ export function createEntryDenyJudge(env, deny, signal) {
7
8
  const hit = deny.matchPath(path);
8
9
  if (hit)
9
10
  return hit;
10
- const view = await views.of(path, leaf !== undefined ? { leaf } : undefined);
11
- return view !== undefined ? deny.matchPath(view) : null;
11
+ const home = await views.of(path, leaf !== undefined ? { leaf } : undefined);
12
+ const viewHit = home.view !== undefined ? deny.matchPath(home.view) : null;
13
+ if (viewHit === null && home.unread !== undefined)
14
+ throw new HomeViewUnreadError(path, home.unread);
15
+ return viewHit;
12
16
  };
13
17
  }
14
18
  export async function enumerateDirectory(env, dir, judge, signal, list = (d) => env.listDir(d, signal)) {
@@ -25,7 +29,15 @@ export async function enumerateDirectory(env, dir, judge, signal, list = (d) =>
25
29
  incomplete = true;
26
30
  break;
27
31
  }
28
- const hit = judge === undefined ? null : await judge(info.path, info.kind === "directory" ? undefined : "file");
32
+ let hit;
33
+ try {
34
+ hit = judge === undefined ? null : await judge(info.path, info.kind === "directory" ? undefined : "file");
35
+ }
36
+ catch (e) {
37
+ if (e instanceof HomeViewUnreadError)
38
+ return { ok: false, error: new FileError("unknown", e.message, info.path) };
39
+ throw e;
40
+ }
29
41
  if (hit) {
30
42
  omitted++;
31
43
  if (!omittedPatterns.includes(hit.pattern))
@@ -1,4 +1,4 @@
1
- import type { AgentTool, ExecutionEnv } from "../../internal/harness-types.js";
1
+ import { type AgentTool, type ExecutionEnv } from "../../internal/harness.js";
2
2
  import { type TaskRegistry } from "../../core/task-registry.js";
3
3
  import { type CwdRef } from "./fs-shared.js";
4
4
  import type { ReversibilityVerdict } from "../../core/types.js";
@@ -1,6 +1,7 @@
1
1
  import { randomBytes } from "node:crypto";
2
2
  import { Type } from "typebox";
3
3
  import { defineTool, errorResult } from "../../core/tools.js";
4
+ import { isTimeCutCode } from "../../internal/harness.js";
4
5
  import { defaultTaskRegistry } from "../../core/task-registry.js";
5
6
  import { accountDroppedBytes, spoolDropNote } from "../../core/task-registry-shared.js";
6
7
  import { RollingTailBuffer } from "../../core/exec-output-tail.js";
@@ -8,7 +9,8 @@ import { TASK_OUTPUT_TOOL_NAME, TASK_STOP_TOOL_NAME, TASK_OUTPUT_MISSING_ID_MESS
8
9
  import { envDeclaresRetain, hasBackgroundShell, retainsBackgroundProcesses } from "../../core/background-shell.js";
9
10
  import { delimitUntrusted } from "../../core/untrusted-text.js";
10
11
  import { MCP_IMAGE_MAX_BASE64 } from "../../core/mcp.js";
11
- import { imageMagicMatches, withinAnyRoot } from "./safety.js";
12
+ import { withinAnyRoot } from "./safety.js";
13
+ import { imageMagicMatches } from "../../core/image-admission.js";
12
14
  import { isDeadCwd, diagnoseDeadCwd } from "./dead-cwd.js";
13
15
  import { boundaryIsTheSandbox, hasDestroy, isIsolated } from "../../core/remote-env.js";
14
16
  import { ghRateLimitHint } from "./gh-rate-limit.js";
@@ -375,7 +377,7 @@ async function runShell(env, cwd, toolName, command, timeoutSec, caps, signal, c
375
377
  isError: true,
376
378
  };
377
379
  }
378
- if (res.error.code === "timeout" || res.error.code === "aborted" || res.error.code === "callback_error") {
380
+ if (isTimeCutCode(res.error.code) || res.error.code === "aborted" || res.error.code === "callback_error") {
379
381
  const rawStdout = res.error.partialStdout ?? "";
380
382
  const rawStderr = res.error.partialStderr ?? "";
381
383
  const cutOverflowFile = rawStdout.length > bashMaxOutputChars() || rawStderr.length > bashMaxOutputChars()
@@ -383,19 +385,26 @@ async function runShell(env, cwd, toolName, command, timeoutSec, caps, signal, c
383
385
  : undefined;
384
386
  const pStdout = clipShellOutput(rawStdout);
385
387
  const pStderr = clipShellOutput(rawStderr);
388
+ const noOutputSec = res.error.code === "liveness_no_output" && typeof res.error.noOutputSec === "number" && Number.isFinite(res.error.noOutputSec) && Math.floor(res.error.noOutputSec) >= 1
389
+ ? Math.floor(res.error.noOutputSec)
390
+ : undefined;
386
391
  const headline = res.error.code === "timeout"
387
392
  ? cappedByMaxTimeout
388
393
  ? `Command timed out after ${timeout}s — requested ${requestedSec}s, capped at ${caps.maxSec}s (engine ceiling: requests above ${caps.maxSec}s are reduced to it). The process was killed; output produced before the cutoff is shown below. Re-running with a larger timeout gets the same ${caps.maxSec}s ceiling — use run_in_background for work that needs longer, a narrower command, or resume from the partial progress below.`
389
394
  : `Command timed out after ${timeout}s (timeout limit: ${timeout}s). The process was killed; output produced before the cutoff is shown below. Re-running the same command will likely time out again — consider run_in_background for long commands, a narrower command, or resuming from the partial progress below.`
390
- : res.error.code === "aborted"
391
- ? `Command was interrupted (aborted) before completion. Output produced before the interrupt is shown below.`
392
- : `Command started but its completion could not be observed — a host-side output-stream callback failed mid-run and the process was terminated (${res.error.message}). Output captured before the cut is shown below; its effects up to that point may have landed. Verify before assuming it needs a full re-run.`;
395
+ : res.error.code === "liveness_no_output"
396
+ ? `Command was killed after producing no output for ${noOutputSec !== undefined ? `${noOutputSec}s` : "the environment's no-output window"} (a command that writes nothing to stdout or stderr that long is treated as hung; this is not the timeout you requested). Output produced before the cutoff is shown below. Re-running the same command will likely stall the same way — make it print progress as it works, use run_in_background for long quiet commands, or split it into smaller steps.`
397
+ : res.error.code === "aborted"
398
+ ? `Command was interrupted (aborted) before completion. Output produced before the interrupt is shown below.`
399
+ : `Command started but its completion could not be observed — a host-side output-stream callback failed mid-run and the process was terminated (${res.error.message}). Output captured before the cut is shown below; its effects up to that point may have landed. Verify before assuming it needs a full re-run.`;
393
400
  const captured = (pStdout ? `--- partial stdout ---\n${pStdout}` : "") +
394
401
  (pStderr ? `${pStdout ? "\n" : ""}--- partial stderr ---\n${pStderr}` : "");
395
402
  const zeroOutput = captured.length === 0;
396
- const zeroOutputHint = res.error.code === "timeout" && timeout >= 60
397
- ? ` — the process ran the full ${timeout}s without writing to its stdio; it may have been stalled before producing output, or holding it in a block buffer`
398
- : "";
403
+ const zeroOutputHint = res.error.code === "liveness_no_output"
404
+ ? ` — the process wrote nothing to its stdio for ${noOutputSec !== undefined ? `the whole ${noOutputSec}s window` : "the whole window"}; it may have been stalled before producing output, or holding it in a block buffer`
405
+ : res.error.code === "timeout" && timeout >= 60
406
+ ? ` — the process ran the full ${timeout}s without writing to its stdio; it may have been stalled before producing output, or holding it in a block buffer`
407
+ : "";
399
408
  const body = !zeroOutput
400
409
  ? `\n${delimitUntrusted("partial command output", captured)}`
401
410
  : `\n(no output was produced before the cutoff${zeroOutputHint})`;
@@ -414,9 +423,11 @@ async function runShell(env, cwd, toolName, command, timeoutSec, caps, signal, c
414
423
  timeoutSec: timeout,
415
424
  ...(cappedByMaxTimeout ? { requestedTimeoutSec: requestedSec, cappedToMaxTimeoutSec: caps.maxSec } : {}),
416
425
  }
417
- : res.error.code === "aborted"
418
- ? { aborted: true }
419
- : { callbackError: true }),
426
+ : res.error.code === "liveness_no_output"
427
+ ? { livenessNoOutput: true, ...(noOutputSec !== undefined ? { noOutputSec } : {}) }
428
+ : res.error.code === "aborted"
429
+ ? { aborted: true }
430
+ : { callbackError: true }),
420
431
  },
421
432
  ...(zeroOutput ? { isError: true } : {}),
422
433
  };
@@ -1,6 +1,7 @@
1
1
  import { delimitUntrusted } from "../../core/untrusted-text.js";
2
2
  import { MCP_IMAGE_MAX_BASE64 } from "../../core/mcp.js";
3
- import { PDF_FALLBACK_RENDER_PAGES, PDF_INLINE_PAGE_THRESHOLD, PDF_MAX_EXTRACT_SIZE, PDF_MAX_PAGES_PER_READ, PDF_TARGET_RAW_SIZE, extractPdfPagesAsImages, extractPdfTextLayer, getPdfPageCount, parsePdfPageRange, pdfMagicMatches, } from "./pdf.js";
3
+ import { PDF_FALLBACK_RENDER_PAGES, PDF_INLINE_PAGE_THRESHOLD, PDF_MAX_EXTRACT_SIZE, PDF_MAX_PAGES_PER_READ, extractPdfPagesAsImages, extractPdfTextLayer, getPdfPageCount, parsePdfPageRange, pdfCutWords, } from "./pdf.js";
4
+ import { PDF_TARGET_RAW_SIZE, pdfMagicMatches } from "../../core/image-admission.js";
4
5
  import { resolveAutoDownsampler, enoentMessage, MAX_READ_BYTES } from "./fs-shared.js";
5
6
  import { planReminderDisclosure, renderReminderDisclosureTrailer } from "../../core/reminder-disclosure.js";
6
7
  import { MARKED_BLOCK_AFTER_DATA } from "../../core/reminder-mint.js";
@@ -81,8 +82,9 @@ export async function readPdfFile(env, path, key, pages, signal, downsamplerOpt,
81
82
  const t = await extractPdfTextLayer(env, key, { first: range.first, last }, signal);
82
83
  if (t.ok) {
83
84
  const { body, truncated } = boundPdfExtractedText(t.text);
84
- const timeoutNote = t.timedOutAfterSec !== undefined
85
- ? `; PARTIAL — pdftotext timed out after ${t.timedOutAfterSec}s, so the text below covers only what was extracted before the timeout; use a narrower pages range for the rest`
85
+ const words = t.cut !== undefined ? pdfCutWords(t.cut) : undefined;
86
+ const timeoutNote = words !== undefined
87
+ ? `; PARTIAL — pdftotext ${words.clause}, so the text below covers only what was extracted before the ${words.noun}; use a narrower pages range for the rest`
86
88
  : "";
87
89
  return {
88
90
  content: [
@@ -94,7 +96,7 @@ export async function readPdfFile(env, path, key, pages, signal, downsamplerOpt,
94
96
  ],
95
97
  details: {
96
98
  type: "document",
97
- file: { type: "application/pdf", originalSize: size, ...(pageCount !== undefined ? { pageCount } : {}), pages: `${range.first}-${last}`, ...(t.timedOutAfterSec !== undefined ? { timedOut: true } : {}) },
99
+ file: { type: "application/pdf", originalSize: size, ...(pageCount !== undefined ? { pageCount } : {}), pages: `${range.first}-${last}`, ...(t.cut !== undefined ? { timedOut: true } : {}) },
98
100
  fallback: { level: 1, reason: "model lacks document input; text layer extracted via pdftotext" },
99
101
  },
100
102
  };
@@ -128,10 +130,11 @@ export async function readPdfFile(env, path, key, pages, signal, downsamplerOpt,
128
130
  return blocks;
129
131
  const requestedPages = last - range.first + 1;
130
132
  const renderedAll = extract.pages.length >= requestedPages;
131
- const header = extract.timedOutAfterSec !== undefined
133
+ const words = extract.cut !== undefined ? pdfCutWords(extract.cut) : undefined;
134
+ const header = words !== undefined
132
135
  ? renderedAll
133
- ? `[PDF: ${path} — pages ${range.first}-${last}${pageCount !== undefined ? ` of ${pageCount}` : ""}: pdftoppm timed out after ${extract.timedOutAfterSec}s, but all ${requestedPages} requested page${requestedPages === 1 ? "" : "s"} were rendered before the timeout hit at teardown (100 dpi); nothing is missing.]`
134
- : `[PDF: ${path} — pages ${range.first}-${last}${pageCount !== undefined ? ` of ${pageCount}` : ""}: pdftoppm timed out after ${extract.timedOutAfterSec}s; rendered ${extract.pages.length} of ${requestedPages} requested page${requestedPages === 1 ? "" : "s"} before the timeout (100 dpi). Read the remaining pages with a narrower range (e.g. pages: "${range.first + extract.pages.length}-${last}").]`
136
+ ? `[PDF: ${path} — pages ${range.first}-${last}${pageCount !== undefined ? ` of ${pageCount}` : ""}: pdftoppm ${words.clause}, but all ${requestedPages} requested page${requestedPages === 1 ? "" : "s"} were rendered before the ${words.noun} hit at teardown (100 dpi); nothing is missing.]`
137
+ : `[PDF: ${path} — pages ${range.first}-${last}${pageCount !== undefined ? ` of ${pageCount}` : ""}: pdftoppm ${words.clause}; rendered ${extract.pages.length} of ${requestedPages} requested page${requestedPages === 1 ? "" : "s"} before the ${words.noun} (100 dpi). Read the remaining pages with a narrower range (e.g. pages: "${range.first + extract.pages.length}-${last}").]`
135
138
  : `[PDF: ${path} — pages ${range.first}-${last}${pageCount !== undefined ? ` of ${pageCount}` : ""} rendered as ${extract.pages.length} image${extract.pages.length === 1 ? "" : "s"} (100 dpi)]`;
136
139
  const content = [
137
140
  { type: "text", text: header },
@@ -147,7 +150,7 @@ export async function readPdfFile(env, path, key, pages, signal, downsamplerOpt,
147
150
  ...(pageCount !== undefined ? { pageCount } : {}),
148
151
  pages: `${range.first}-${last}`,
149
152
  renderedPages: extract.pages.length,
150
- ...(extract.timedOutAfterSec !== undefined ? { requestedPages, timedOut: true } : {}),
153
+ ...(extract.cut !== undefined ? { requestedPages, timedOut: true } : {}),
151
154
  },
152
155
  },
153
156
  };
@@ -164,8 +167,9 @@ export async function readPdfFile(env, path, key, pages, signal, downsamplerOpt,
164
167
  const t = await extractPdfTextLayer(env, key, undefined, signal);
165
168
  if (t.ok) {
166
169
  const { body, truncated } = boundPdfExtractedText(t.text);
167
- const timeoutNote = t.timedOutAfterSec !== undefined
168
- ? `; PARTIAL — pdftotext timed out after ${t.timedOutAfterSec}s, so the text below covers only what was extracted before the timeout; use the pages parameter for the rest`
170
+ const words = t.cut !== undefined ? pdfCutWords(t.cut) : undefined;
171
+ const timeoutNote = words !== undefined
172
+ ? `; PARTIAL — pdftotext ${words.clause}, so the text below covers only what was extracted before the ${words.noun}; use the pages parameter for the rest`
169
173
  : "";
170
174
  return {
171
175
  content: [
@@ -177,7 +181,7 @@ export async function readPdfFile(env, path, key, pages, signal, downsamplerOpt,
177
181
  ],
178
182
  details: {
179
183
  type: "document",
180
- file: { ...fileCard, ...(t.timedOutAfterSec !== undefined ? { timedOut: true } : {}) },
184
+ file: { ...fileCard, ...(t.cut !== undefined ? { timedOut: true } : {}) },
181
185
  fallback: { level: 1, reason: "model lacks document input; text layer extracted via pdftotext" },
182
186
  },
183
187
  };
@@ -190,7 +194,7 @@ export async function readPdfFile(env, path, key, pages, signal, downsamplerOpt,
190
194
  if (extract.ok) {
191
195
  const blocks = await pdfPagesToImageBlocks(extract.pages, path, downsamplerOpt);
192
196
  if (typeof blocks !== "string") {
193
- const renderTimeoutNote = extract.timedOutAfterSec !== undefined ? ` pdftoppm timed out after ${extract.timedOutAfterSec}s — only the pages that finished rendering are included.` : "";
197
+ const renderTimeoutNote = extract.cut !== undefined ? ` pdftoppm ${pdfCutWords(extract.cut).clause} — only the pages that finished rendering are included.` : "";
194
198
  return {
195
199
  content: [
196
200
  {
@@ -202,7 +206,7 @@ export async function readPdfFile(env, path, key, pages, signal, downsamplerOpt,
202
206
  ],
203
207
  details: {
204
208
  type: "document",
205
- file: { ...fileCard, pages: `1-${extract.pages.length}`, renderedPages: extract.pages.length, ...(extract.timedOutAfterSec !== undefined ? { timedOut: true } : {}) },
209
+ file: { ...fileCard, pages: `1-${extract.pages.length}`, renderedPages: extract.pages.length, ...(extract.cut !== undefined ? { timedOut: true } : {}) },
206
210
  fallback: { level: 2, reason: `model lacks document input; ${textWhy}; rendered first ${extract.pages.length} page(s) via pdftoppm` },
207
211
  },
208
212
  };
@@ -1,10 +1,10 @@
1
1
  import { Type } from "typebox";
2
2
  import { defineTool, errorResult } from "../../core/tools.js";
3
- import { sha256, resolveKey, violationText, violationDetails, binaryMagicFormat, hasBinaryExtension, isBinaryContent, fileArgPath, imageMimeForRead, } from "./safety.js";
3
+ import { sha256, resolveKey, violationText, violationDetails, binaryMagicFormat, hasBinaryExtension, isBinaryContent, imageMimeForRead, } from "./safety.js";
4
4
  import { decodeTextBytes } from "./encoding.js";
5
5
  import { isNotebookPath, parseNotebookCells, renderNotebookCells, stripNotebookImageData, NOTEBOOK_IMAGE_BASE64_BUDGET } from "./notebook.js";
6
6
  import { MCP_IMAGE_MAX_BASE64, IMAGE_TARGET_RAW_SIZE } from "../../core/mcp.js";
7
- import { countPdfPagesFromBytes, PDF_MAX_PAGES_PER_READ, PDF_TARGET_RAW_SIZE, pdfMagicMatches } from "./pdf.js";
7
+ import { countPdfPagesFromBytes, PDF_MAX_PAGES_PER_READ } from "./pdf.js";
8
8
  import { MAX_READ_BYTES, SLICED_READ_MAX_BYTES, NO_DOWNSAMPLER_IMAGE_CAP_HINT, resolveAutoDownsampler, MAX_READ_OUTPUT_CHARS, FILE_PATH_PARAMS, countLines, seededFileUnchangedReminder, enoentMessage, } from "./fs-shared.js";
9
9
  import { readPdfFile } from "./fs-pdf.js";
10
10
  import { seatForCall, seatReady } from "./read-deny.js";
@@ -12,7 +12,8 @@ import { thrownText } from "../../core/thrown-value.js";
12
12
  import { MARKED_BLOCK_AFTER_DATA, openSystemReminder } from "../../core/reminder-mint.js";
13
13
  import { planReminderDisclosure, commitReminderDisclosureEffects, renderReminderDisclosureTrailer, } from "../../core/reminder-disclosure.js";
14
14
  import { toolFace } from "../../core/tool-catalog-entries.js";
15
- import { admitImageBytes, imageReadCap } from "./image-admission.js";
15
+ import { fileArgPath } from "../../core/tool-registry.js";
16
+ import { admitImageBytes, imageReadCap, PDF_TARGET_RAW_SIZE, pdfMagicMatches } from "../../core/image-admission.js";
16
17
  import { createEntryDenyJudge, enumerateDirectory } from "./dir-entries.js";
17
18
  import { FileError } from "../../internal/harness.js";
18
19
  export const READ_OUTCOMES = Object.freeze(["attached", "partial", "unchanged", "not_attached"]);
@@ -111,16 +111,7 @@ export declare function applyRecordedEdit(text: string, edit: RecordedEdit): str
111
111
  * both sharper shapes describe files Read handled successfully, so the encoding-deadlock sentence
112
112
  * would be false there — and stacking two escape routes on one refusal buries the one that applies. */
113
113
  export declare function notReadRefusalText(env: ExecutionEnv, toolName: string, key: string, v: Pick<FsViolation, "code" | "message" | "partialView">, signal?: AbortSignal, fallbackHint?: string): Promise<string>;
114
- /** Byte cap on a Read-image WITHOUT a downsampler: an image file is returned AS a visual
115
- * `ImageContent` block (base64) rather than refused. Bounded so a huge image cannot blow the request.
116
- * This stat-time cap only bounds the READ; the accept/refuse decision is the base64 gate below (the
117
- * provider limit is on base64 LENGTH, so the effective no-sharp accept bound is raw ≤ 3.75MB). */
118
- export declare const MAX_IMAGE_READ_BYTES: number;
119
- /** Byte cap on a Read-image WITH a downsampler: sharp can shrink a big photo to CC's 2000×2000/3.75MB
120
- * target, so the smaller hard refusal does not apply (CC readImageWithTokenBudget reads the file
121
- * unbounded; we keep an OOM sanity bound — deliberate delta, camera photos fit comfortably). */
122
- export declare const MAX_IMAGE_DOWNSAMPLE_INPUT_BYTES: number;
123
- /** The no-downsampler cap above is a DELIBERATE bound and does not move — but its refusal must not
114
+ /** The no-downsampler cap (`MAX_IMAGE_READ_BYTES`, core/image-admission.ts) is a DELIBERATE bound and does not move — but its refusal must not
124
115
  * read like a hard ceiling. Whether the higher cap is reachable depends on an OPTIONAL dependency the
125
116
  * caller can install, and only this package knows that, so the refusal names the move instead of
126
117
  * leaving the caller to guess that the limit is negotiable. Appended ONLY on the no-downsampler
@@ -6,6 +6,7 @@ import { shellQuote } from "./search.js";
6
6
  import { isNotebookPath } from "./notebook.js";
7
7
  import { homeViewsOf } from "./read-deny-home.js";
8
8
  import { sharpImageDownsampler } from "../../core/mcp.js";
9
+ import { MAX_IMAGE_DOWNSAMPLE_INPUT_BYTES } from "../../core/image-admission.js";
9
10
  import { deliverEngineNotice } from "../../core/types.js";
10
11
  import { resolveEnvBudget } from "../../core/env-budget.js";
11
12
  import { openSystemReminder } from "../../core/reminder-mint.js";
@@ -55,8 +56,6 @@ export async function notReadRefusalText(env, toolName, key, v, signal, fallback
55
56
  return `${base} ${OVERSIZE_READ_ESCAPE_HINT}`;
56
57
  return fallbackHint === undefined ? base : `${base} ${fallbackHint}`;
57
58
  }
58
- export const MAX_IMAGE_READ_BYTES = 5 * 1024 * 1024;
59
- export const MAX_IMAGE_DOWNSAMPLE_INPUT_BYTES = 64 * 1024 * 1024;
60
59
  export const NO_DOWNSAMPLER_IMAGE_CAP_HINT = `Install the optional "sharp" dependency (declared in this package's optionalDependencies) to read images up to ${MAX_IMAGE_DOWNSAMPLE_INPUT_BYTES} bytes — it downsamples them to fit the API image limit.`;
61
60
  let autoDownsampler;
62
61
  export function resolveAutoDownsampler() {
@@ -366,8 +365,8 @@ export async function enoentMessage(env, key, cwd, signal, readDeny) {
366
365
  return false;
367
366
  if (readDeny.matchPath(path) != null)
368
367
  return true;
369
- const view = await views.of(path, leaf !== undefined ? { leaf } : undefined);
370
- return view !== undefined && readDeny.matchPath(view) != null;
368
+ const home = await views.of(path, leaf !== undefined ? { leaf } : undefined);
369
+ return home.unread !== undefined || (home.view !== undefined && readDeny.matchPath(home.view) != null);
371
370
  };
372
371
  if (sep > 0) {
373
372
  const parent = key.slice(0, sep);
@@ -1,11 +1,12 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { Type } from "typebox";
3
3
  import { defineTool, errorResult } from "../../core/tools.js";
4
- import { sha256, resolveKey, violationText, violationDetails, requireRead, checkStale, checkEditMatch, checkNoChange, fileArgPath, resolveQuoteMatch, adaptNewStringQuotes, resolveEscapeMatch, adaptNewStringEscapes, escapeMatchWasAttempted, ESCAPE_MATCH_MISS_NOTE, deletionOldString, countOccurrences, READ_REFUSED_ESCAPE_HINT, } from "./safety.js";
4
+ import { sha256, resolveKey, violationText, violationDetails, requireRead, checkStale, checkEditMatch, checkNoChange, resolveQuoteMatch, adaptNewStringQuotes, resolveEscapeMatch, adaptNewStringEscapes, escapeMatchWasAttempted, ESCAPE_MATCH_MISS_NOTE, deletionOldString, countOccurrences, READ_REFUSED_ESCAPE_HINT, } from "./safety.js";
5
5
  import { decodeTextBytes, encodeTextForFile, normalizeEditText, normalizeFileText } from "./encoding.js";
6
6
  import { seatForCall } from "./read-deny.js";
7
7
  import { MAX_EDIT_BYTES, decodeEditBytes, tooLargeToEditMessage, truncatedUtf16BodyMessage, persistedTextOf, notReadRefusalText, enoentMessage, FILE_STATE_TRAILER, FILE_PATH_PARAMS, coerceWriteArguments, ipynbRedirect, countLines, applyRecordedEdit, } from "./fs-shared.js";
8
8
  import { toolFace } from "../../core/tool-catalog-entries.js";
9
+ import { fileArgPath } from "../../core/tool-registry.js";
9
10
  import { thrownText } from "../../core/thrown-value.js";
10
11
  async function envFinalWrite(env, key, content, signal, opts) {
11
12
  const fireEdited = () => {
@@ -1,4 +1,4 @@
1
- import { imageMagicMatches } from "./safety.js";
1
+ import { imageMagicMatches } from "../../core/image-admission.js";
2
2
  export function isNotebookPath(p) {
3
3
  return p.toLowerCase().endsWith(".ipynb");
4
4
  }
@@ -20,13 +20,10 @@ import type { ExecutionEnv } from "../../internal/harness-types.js";
20
20
  export declare const PDF_MAX_PAGES_PER_READ = 20;
21
21
  /** Above this page count a whole-PDF read is refused and `pages` is required (CC `PDF_AT_MENTION_INLINE_THRESHOLD`). */
22
22
  export declare const PDF_INLINE_PAGE_THRESHOLD = 10;
23
- /** Max raw size sent whole as a document block (CC `PDF_TARGET_RAW_SIZE`). */
24
- export declare const PDF_TARGET_RAW_SIZE: number;
25
- /** Max raw size the page-extraction (pdftoppm) path accepts (CC `PDF_MAX_EXTRACT_SIZE`). */
23
+ /** Max raw size the page-extraction (pdftoppm) path accepts (CC `PDF_MAX_EXTRACT_SIZE`). The whole-send target
24
+ * (`PDF_TARGET_RAW_SIZE`) and the `%PDF-` signature test (`pdfMagicMatches`) are the document admission's own
25
+ * (core/image-admission.ts). */
26
26
  export declare const PDF_MAX_EXTRACT_SIZE: number;
27
- /** True when the bytes start with the `%PDF-` magic. Magic outranks extension both ways: a mis-named
28
- * `.pdf` without it is refused, and a non-`.pdf` file carrying it is read AS a PDF. */
29
- export declare function pdfMagicMatches(bytes: Uint8Array): boolean;
30
27
  /** A parsed 1-indexed inclusive page range. `last === Infinity` for an open range ("10-"). */
31
28
  export interface PdfPageRange {
32
29
  first: number;
@@ -75,12 +72,25 @@ export declare function pdfModelCapabilitiesOf(model?: {
75
72
  }): PdfModelCapabilities;
76
73
  /** Timeout for the poppler extraction commands (pdftotext / pdftoppm), in seconds. */
77
74
  export declare const PDF_EXEC_TIMEOUT_SEC = 120;
75
+ /** What cut a run short: the wall-clock budget (always a number), or the env's silence window (a number only when the env states it — otherwise the budget did not elapse and no number is honest). */
76
+ export type PdfCut = {
77
+ readonly kind: "budget";
78
+ readonly sec: number;
79
+ } | {
80
+ readonly kind: "silence";
81
+ readonly sec?: number;
82
+ };
83
+ /** A cut in words: the clause that says it (`timed out after 120s` / `was cut after producing no output for 30s` / `was cut for producing no output`) and the noun a later clause calls it. */
84
+ export declare function pdfCutWords(cut: PdfCut): {
85
+ clause: string;
86
+ noun: string;
87
+ };
78
88
  export type PdfTextResult = {
79
89
  ok: true;
80
90
  text: string;
81
- /** Set when pdftotext hit its exec timeout but had already written partial text: the extraction is
91
+ /** Set when pdftotext was cut by a time bound but had already written partial text: the extraction is
82
92
  * INCOMPLETE (covers only the leading part of the requested range) and the caller must say so. */
83
- timedOutAfterSec?: number;
93
+ cut?: PdfCut;
84
94
  } | {
85
95
  ok: false;
86
96
  toolMissing: boolean;
@@ -104,9 +114,9 @@ export type PdfExtractResult = {
104
114
  pageNumber: number;
105
115
  jpeg: Uint8Array;
106
116
  }>;
107
- /** Set when pdftoppm hit its exec timeout but had already rendered complete leading pages: `pages`
117
+ /** Set when pdftoppm was cut by a time bound but had already rendered complete leading pages: `pages`
108
118
  * covers only a PREFIX of the requested range and the caller must label the delivery as partial. */
109
- timedOutAfterSec?: number;
119
+ cut?: PdfCut;
110
120
  } | {
111
121
  ok: false;
112
122
  toolMissing: boolean;
@@ -1,10 +1,7 @@
1
+ import { isTimeCutCode } from "../../internal/harness.js";
1
2
  export const PDF_MAX_PAGES_PER_READ = 20;
2
3
  export const PDF_INLINE_PAGE_THRESHOLD = 10;
3
- export const PDF_TARGET_RAW_SIZE = 20 * 1024 * 1024;
4
4
  export const PDF_MAX_EXTRACT_SIZE = 100 * 1024 * 1024;
5
- export function pdfMagicMatches(bytes) {
6
- return bytes.length >= 5 && bytes[0] === 0x25 && bytes[1] === 0x50 && bytes[2] === 0x44 && bytes[3] === 0x46 && bytes[4] === 0x2d;
7
- }
8
5
  export function parsePdfPageRange(pages) {
9
6
  const s = pages.trim();
10
7
  const single = /^(\d+)$/.exec(s);
@@ -60,6 +57,16 @@ export function pdfModelCapabilitiesOf(model) {
60
57
  return { document, vision };
61
58
  }
62
59
  export const PDF_EXEC_TIMEOUT_SEC = 120;
60
+ function cutOf(e) {
61
+ if (e.code !== "liveness_no_output")
62
+ return { kind: "budget", sec: PDF_EXEC_TIMEOUT_SEC };
63
+ return e.noOutputSec !== undefined ? { kind: "silence", sec: e.noOutputSec } : { kind: "silence" };
64
+ }
65
+ export function pdfCutWords(cut) {
66
+ if (cut.kind === "budget")
67
+ return { clause: `timed out after ${cut.sec}s`, noun: "timeout" };
68
+ return { clause: cut.sec !== undefined ? `was cut after producing no output for ${cut.sec}s` : "was cut for producing no output", noun: "cut" };
69
+ }
63
70
  export async function extractPdfTextLayer(env, absPath, range, signal) {
64
71
  const tmp = await env.createTempDir("sema-pdf-text-", signal);
65
72
  if (!tmp.ok)
@@ -73,16 +80,17 @@ export async function extractPdfTextLayer(env, absPath, range, signal) {
73
80
  const cmd = `pdftotext -layout ${rangeArgs}${shellQuote(absPath)} ${shellQuote(outR.value)}`;
74
81
  const r = await env.exec(cmd, { timeout: PDF_EXEC_TIMEOUT_SEC, abortSignal: signal });
75
82
  if (!r.ok) {
76
- if (r.error.code === "timeout") {
83
+ if (isTimeCutCode(r.error.code)) {
84
+ const cut = cutOf(r.error);
77
85
  const partial = await env.readBinaryFile(outR.value, signal);
78
86
  const text = partial.ok ? Buffer.from(partial.value).toString("utf8") : "";
79
87
  if (text.trim())
80
- return { ok: true, text, timedOutAfterSec: PDF_EXEC_TIMEOUT_SEC };
88
+ return { ok: true, text, cut };
81
89
  return {
82
90
  ok: false,
83
91
  toolMissing: false,
84
92
  timedOut: true,
85
- error: `pdftotext timed out after ${PDF_EXEC_TIMEOUT_SEC}s before writing any text. Use the pages parameter to extract a narrower range (e.g. pages: "1-5").`,
93
+ error: `pdftotext ${pdfCutWords(cut).clause} before writing any text. Use the pages parameter to extract a narrower range (e.g. pages: "1-5").`,
86
94
  };
87
95
  }
88
96
  return { ok: false, toolMissing: false, error: r.error.message };
@@ -129,7 +137,8 @@ export async function extractPdfPagesAsImages(env, absPath, first, last, signal)
129
137
  const cmd = `pdftoppm -jpeg -r 100 -f ${first} -l ${last} ${shellQuote(absPath)} ${shellQuote(prefixR.value)}`;
130
138
  const r = await env.exec(cmd, { timeout: PDF_EXEC_TIMEOUT_SEC, abortSignal: signal });
131
139
  if (!r.ok) {
132
- if (r.error.code === "timeout") {
140
+ if (isTimeCutCode(r.error.code)) {
141
+ const cut = cutOf(r.error);
133
142
  const listed = await listRenderedJpegs(env, dir, signal);
134
143
  const jpgs = listed.ok ? listed.jpgs : [];
135
144
  const pages = [];
@@ -140,12 +149,12 @@ export async function extractPdfPagesAsImages(env, absPath, first, last, signal)
140
149
  pages.push({ pageNumber: first + i, jpeg: bin.value });
141
150
  }
142
151
  if (pages.length > 0)
143
- return { ok: true, pages, timedOutAfterSec: PDF_EXEC_TIMEOUT_SEC };
152
+ return { ok: true, pages, cut };
144
153
  return {
145
154
  ok: false,
146
155
  toolMissing: false,
147
156
  timedOut: true,
148
- error: `pdftoppm timed out after ${PDF_EXEC_TIMEOUT_SEC}s before finishing any page. Request a narrower pages range (e.g. a single page like pages: "${first}").`,
157
+ error: `pdftoppm ${pdfCutWords(cut).clause} before finishing any page. Request a narrower pages range (e.g. a single page like pages: "${first}").`,
149
158
  };
150
159
  }
151
160
  return { ok: false, toolMissing: false, error: r.error.message };