@theoremjs/agents 0.0.0-stage → 0.3.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 (514) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1264 -2
  3. package/esm/_dnt.polyfills.d.ts +66 -0
  4. package/esm/_dnt.polyfills.js +51 -0
  5. package/esm/mod.d.ts +65 -0
  6. package/esm/mod.js +42 -0
  7. package/esm/package.json +3 -0
  8. package/esm/src/cli/bin.d.ts +7 -0
  9. package/esm/src/cli/bin.js +9 -0
  10. package/esm/src/cli/commands/bench.d.ts +6 -0
  11. package/esm/src/cli/commands/bench.js +458 -0
  12. package/esm/src/cli/commands/egress-compile.d.ts +17 -0
  13. package/esm/src/cli/commands/egress-compile.js +25 -0
  14. package/esm/src/cli/commands/eval.d.ts +37 -0
  15. package/esm/src/cli/commands/eval.js +190 -0
  16. package/esm/src/cli/commands/fuzz-canary.d.ts +15 -0
  17. package/esm/src/cli/commands/fuzz-canary.js +202 -0
  18. package/esm/src/cli/commands/fuzz-guardrails.d.ts +2 -0
  19. package/esm/src/cli/commands/fuzz-guardrails.js +5 -0
  20. package/esm/src/cli/commands/profile.d.ts +2 -0
  21. package/esm/src/cli/commands/profile.js +80 -0
  22. package/esm/src/cli/commands/run.d.ts +13 -0
  23. package/esm/src/cli/commands/run.js +45 -0
  24. package/esm/src/cli/commands/test.d.ts +25 -0
  25. package/esm/src/cli/commands/test.js +143 -0
  26. package/esm/src/cli/event-log.d.ts +15 -0
  27. package/esm/src/cli/event-log.js +136 -0
  28. package/esm/src/cli/index.d.ts +10 -0
  29. package/esm/src/cli/index.js +267 -0
  30. package/esm/src/cli/matrix/fixtures.d.ts +10 -0
  31. package/esm/src/cli/matrix/fixtures.js +72 -0
  32. package/esm/src/cli/matrix/synthesizer.d.ts +18 -0
  33. package/esm/src/cli/matrix/synthesizer.js +103 -0
  34. package/esm/src/evals/attachments.d.ts +4 -0
  35. package/esm/src/evals/attachments.js +53 -0
  36. package/esm/src/evals/breakdown.d.ts +28 -0
  37. package/esm/src/evals/breakdown.js +68 -0
  38. package/esm/src/evals/graders/answer.d.ts +13 -0
  39. package/esm/src/evals/graders/answer.js +133 -0
  40. package/esm/src/evals/graders/code.d.ts +64 -0
  41. package/esm/src/evals/graders/code.js +205 -0
  42. package/esm/src/evals/graders/judge.d.ts +20 -0
  43. package/esm/src/evals/graders/judge.js +365 -0
  44. package/esm/src/evals/graders/latency.d.ts +5 -0
  45. package/esm/src/evals/graders/latency.js +81 -0
  46. package/esm/src/evals/graders/live.d.ts +11 -0
  47. package/esm/src/evals/graders/live.js +40 -0
  48. package/esm/src/evals/graders/media.d.ts +18 -0
  49. package/esm/src/evals/graders/media.js +92 -0
  50. package/esm/src/evals/graders/shared.d.ts +11 -0
  51. package/esm/src/evals/graders/shared.js +62 -0
  52. package/esm/src/evals/graders/transcript.d.ts +17 -0
  53. package/esm/src/evals/graders/transcript.js +200 -0
  54. package/esm/src/evals/mod.d.ts +42 -0
  55. package/esm/src/evals/mod.js +30 -0
  56. package/esm/src/evals/record.d.ts +35 -0
  57. package/esm/src/evals/record.js +105 -0
  58. package/esm/src/evals/rubrics/catalog.d.ts +148 -0
  59. package/esm/src/evals/rubrics/catalog.js +846 -0
  60. package/esm/src/evals/rubrics/mod.d.ts +24 -0
  61. package/esm/src/evals/rubrics/mod.js +55 -0
  62. package/esm/src/evals/rubrics/mustache.d.ts +23 -0
  63. package/esm/src/evals/rubrics/mustache.js +154 -0
  64. package/esm/src/evals/rubrics/types.d.ts +54 -0
  65. package/esm/src/evals/rubrics/types.js +74 -0
  66. package/esm/src/evals/run.d.ts +118 -0
  67. package/esm/src/evals/run.js +452 -0
  68. package/esm/src/evals/suite.d.ts +19 -0
  69. package/esm/src/evals/suite.js +92 -0
  70. package/esm/src/evals/summary.d.ts +32 -0
  71. package/esm/src/evals/summary.js +30 -0
  72. package/esm/src/evals/trial.d.ts +27 -0
  73. package/esm/src/evals/trial.js +158 -0
  74. package/esm/src/evals/types.d.ts +260 -0
  75. package/esm/src/evals/types.js +126 -0
  76. package/esm/src/evals/verdict.d.ts +18 -0
  77. package/esm/src/evals/verdict.js +45 -0
  78. package/esm/src/guardrails/canary-gate.d.ts +21 -0
  79. package/esm/src/guardrails/canary-gate.js +40 -0
  80. package/esm/src/guardrails/canary.d.ts +112 -0
  81. package/esm/src/guardrails/canary.js +901 -0
  82. package/esm/src/guardrails/compile-egress.d.ts +11 -0
  83. package/esm/src/guardrails/compile-egress.js +11 -0
  84. package/esm/src/guardrails/corpus/canary-egress-attacks.d.ts +22 -0
  85. package/esm/src/guardrails/corpus/canary-egress-attacks.js +303 -0
  86. package/esm/src/guardrails/corpus/fuzz-inbound.d.ts +5 -0
  87. package/esm/src/guardrails/corpus/fuzz-inbound.js +202 -0
  88. package/esm/src/guardrails/corpus/inbound-payloads.d.ts +3 -0
  89. package/esm/src/guardrails/corpus/inbound-payloads.js +118 -0
  90. package/esm/src/guardrails/corpus/live-attacks.d.ts +13 -0
  91. package/esm/src/guardrails/corpus/live-attacks.js +224 -0
  92. package/esm/src/guardrails/corpus/mod.d.ts +7 -0
  93. package/esm/src/guardrails/corpus/mod.js +4 -0
  94. package/esm/src/guardrails/corpus/secrets.d.ts +12 -0
  95. package/esm/src/guardrails/corpus/secrets.js +16 -0
  96. package/esm/src/guardrails/corpus/strings.d.ts +23 -0
  97. package/esm/src/guardrails/corpus/strings.js +29 -0
  98. package/esm/src/guardrails/corpus/types.d.ts +32 -0
  99. package/esm/src/guardrails/corpus/types.js +1 -0
  100. package/esm/src/guardrails/egress-automata.d.ts +14 -0
  101. package/esm/src/guardrails/egress-automata.js +6059 -0
  102. package/esm/src/guardrails/egress-compiler.d.ts +33 -0
  103. package/esm/src/guardrails/egress-compiler.js +237 -0
  104. package/esm/src/guardrails/egress-patterns.d.ts +24 -0
  105. package/esm/src/guardrails/egress-patterns.js +32 -0
  106. package/esm/src/guardrails/egress-policy.d.ts +27 -0
  107. package/esm/src/guardrails/egress-policy.js +76 -0
  108. package/esm/src/guardrails/egress-rules.d.ts +54 -0
  109. package/esm/src/guardrails/egress-rules.js +49 -0
  110. package/esm/src/guardrails/egress-stream.d.ts +105 -0
  111. package/esm/src/guardrails/egress-stream.js +645 -0
  112. package/esm/src/guardrails/egress-urls.d.ts +83 -0
  113. package/esm/src/guardrails/egress-urls.js +917 -0
  114. package/esm/src/guardrails/egress.d.ts +106 -0
  115. package/esm/src/guardrails/egress.js +374 -0
  116. package/esm/src/guardrails/error.d.ts +26 -0
  117. package/esm/src/guardrails/error.js +91 -0
  118. package/esm/src/guardrails/event-schemas.d.ts +57 -0
  119. package/esm/src/guardrails/event-schemas.js +41 -0
  120. package/esm/src/guardrails/events.d.ts +9 -0
  121. package/esm/src/guardrails/events.js +42 -0
  122. package/esm/src/guardrails/hits.d.ts +8 -0
  123. package/esm/src/guardrails/hits.js +19 -0
  124. package/esm/src/guardrails/injection-patterns.d.ts +15 -0
  125. package/esm/src/guardrails/injection-patterns.js +94 -0
  126. package/esm/src/guardrails/injection.d.ts +14 -0
  127. package/esm/src/guardrails/injection.js +237 -0
  128. package/esm/src/guardrails/lexicon.d.ts +30 -0
  129. package/esm/src/guardrails/lexicon.js +478 -0
  130. package/esm/src/guardrails/live-outbound-gate.d.ts +54 -0
  131. package/esm/src/guardrails/live-outbound-gate.js +305 -0
  132. package/esm/src/guardrails/mod.d.ts +46 -0
  133. package/esm/src/guardrails/mod.js +29 -0
  134. package/esm/src/guardrails/network.d.ts +42 -0
  135. package/esm/src/guardrails/network.js +328 -0
  136. package/esm/src/guardrails/normalize.d.ts +6 -0
  137. package/esm/src/guardrails/normalize.js +132 -0
  138. package/esm/src/guardrails/policy.d.ts +19 -0
  139. package/esm/src/guardrails/policy.js +50 -0
  140. package/esm/src/guardrails/progressive-yield.d.ts +69 -0
  141. package/esm/src/guardrails/progressive-yield.js +237 -0
  142. package/esm/src/guardrails/prompt-echo.d.ts +38 -0
  143. package/esm/src/guardrails/prompt-echo.js +225 -0
  144. package/esm/src/guardrails/quota.d.ts +20 -0
  145. package/esm/src/guardrails/quota.js +80 -0
  146. package/esm/src/guardrails/rules.d.ts +56 -0
  147. package/esm/src/guardrails/rules.js +54 -0
  148. package/esm/src/guardrails/sanitize.d.ts +23 -0
  149. package/esm/src/guardrails/sanitize.js +184 -0
  150. package/esm/src/guardrails/sensitive.d.ts +29 -0
  151. package/esm/src/guardrails/sensitive.js +113 -0
  152. package/esm/src/guardrails/serialize.d.ts +14 -0
  153. package/esm/src/guardrails/serialize.js +37 -0
  154. package/esm/src/guardrails/testing.d.ts +9 -0
  155. package/esm/src/guardrails/testing.js +8 -0
  156. package/esm/src/guardrails/theorem-error.d.ts +18 -0
  157. package/esm/src/guardrails/theorem-error.js +53 -0
  158. package/esm/src/guardrails/thought-guard.d.ts +55 -0
  159. package/esm/src/guardrails/thought-guard.js +464 -0
  160. package/esm/src/guardrails/tool-directives.d.ts +19 -0
  161. package/esm/src/guardrails/tool-directives.js +109 -0
  162. package/esm/src/guardrails/tool-result.d.ts +61 -0
  163. package/esm/src/guardrails/tool-result.js +248 -0
  164. package/esm/src/guardrails/types.d.ts +242 -0
  165. package/esm/src/guardrails/types.js +54 -0
  166. package/esm/src/host/client-turn.d.ts +9 -0
  167. package/esm/src/host/client-turn.js +38 -0
  168. package/esm/src/host/mint-trace.d.ts +28 -0
  169. package/esm/src/host/mint-trace.js +59 -0
  170. package/esm/src/host/mod.d.ts +13 -0
  171. package/esm/src/host/mod.js +11 -0
  172. package/esm/src/host/readStreamingJsonStringField.d.ts +2 -0
  173. package/esm/src/host/readStreamingJsonStringField.js +68 -0
  174. package/esm/src/host/reply.d.ts +7 -0
  175. package/esm/src/host/reply.js +35 -0
  176. package/esm/src/interface/blocks.d.ts +8 -0
  177. package/esm/src/interface/blocks.js +213 -0
  178. package/esm/src/interface/composer-actions.d.ts +20 -0
  179. package/esm/src/interface/composer-actions.js +31 -0
  180. package/esm/src/interface/draft.d.ts +14 -0
  181. package/esm/src/interface/draft.js +28 -0
  182. package/esm/src/interface/from-profile.d.ts +12 -0
  183. package/esm/src/interface/from-profile.js +144 -0
  184. package/esm/src/interface/history.d.ts +40 -0
  185. package/esm/src/interface/history.js +269 -0
  186. package/esm/src/interface/inputs.d.ts +10 -0
  187. package/esm/src/interface/inputs.js +64 -0
  188. package/esm/src/interface/mod.d.ts +31 -0
  189. package/esm/src/interface/mod.js +21 -0
  190. package/esm/src/interface/models.d.ts +19 -0
  191. package/esm/src/interface/models.js +45 -0
  192. package/esm/src/interface/pending.d.ts +48 -0
  193. package/esm/src/interface/pending.js +146 -0
  194. package/esm/src/interface/profile-interface.d.ts +4 -0
  195. package/esm/src/interface/profile-interface.js +223 -0
  196. package/esm/src/interface/session.d.ts +64 -0
  197. package/esm/src/interface/session.js +121 -0
  198. package/esm/src/interface/tool-calls.d.ts +20 -0
  199. package/esm/src/interface/tool-calls.js +73 -0
  200. package/esm/src/interface/tool-invoke.d.ts +4 -0
  201. package/esm/src/interface/tool-invoke.js +20 -0
  202. package/esm/src/interface/tool-media.d.ts +9 -0
  203. package/esm/src/interface/tool-media.js +112 -0
  204. package/esm/src/interface/types.d.ts +213 -0
  205. package/esm/src/interface/types.js +4 -0
  206. package/esm/src/kernel/auth/credential-source.d.ts +23 -0
  207. package/esm/src/kernel/auth/credential-source.js +11 -0
  208. package/esm/src/kernel/auth/crypto.d.ts +51 -0
  209. package/esm/src/kernel/auth/crypto.js +161 -0
  210. package/esm/src/kernel/auth/mod.d.ts +5 -0
  211. package/esm/src/kernel/auth/mod.js +5 -0
  212. package/esm/src/kernel/auth/oauth.d.ts +17 -0
  213. package/esm/src/kernel/auth/oauth.js +438 -0
  214. package/esm/src/kernel/auth/scope-refusal.d.ts +9 -0
  215. package/esm/src/kernel/auth/scope-refusal.js +8 -0
  216. package/esm/src/kernel/auth/typed-secret.d.ts +13 -0
  217. package/esm/src/kernel/auth/typed-secret.js +23 -0
  218. package/esm/src/kernel/auth/types.d.ts +139 -0
  219. package/esm/src/kernel/auth/types.js +1 -0
  220. package/esm/src/kernel/default-scope.d.ts +34 -0
  221. package/esm/src/kernel/default-scope.js +72 -0
  222. package/esm/src/kernel/engine/compaction.d.ts +70 -0
  223. package/esm/src/kernel/engine/compaction.js +202 -0
  224. package/esm/src/kernel/engine/decision.d.ts +41 -0
  225. package/esm/src/kernel/engine/decision.js +412 -0
  226. package/esm/src/kernel/engine/hash.d.ts +6 -0
  227. package/esm/src/kernel/engine/hash.js +22 -0
  228. package/esm/src/kernel/engine/live-inbound.d.ts +9 -0
  229. package/esm/src/kernel/engine/live-inbound.js +19 -0
  230. package/esm/src/kernel/engine/live-ingress.d.ts +9 -0
  231. package/esm/src/kernel/engine/live-ingress.js +37 -0
  232. package/esm/src/kernel/engine/media-probe/audio.d.ts +7 -0
  233. package/esm/src/kernel/engine/media-probe/audio.js +342 -0
  234. package/esm/src/kernel/engine/media-probe/bytes.d.ts +6 -0
  235. package/esm/src/kernel/engine/media-probe/bytes.js +26 -0
  236. package/esm/src/kernel/engine/media-probe/image.d.ts +5 -0
  237. package/esm/src/kernel/engine/media-probe/image.js +171 -0
  238. package/esm/src/kernel/engine/media-probe/iso-bmff.d.ts +19 -0
  239. package/esm/src/kernel/engine/media-probe/iso-bmff.js +48 -0
  240. package/esm/src/kernel/engine/media-probe/matroska.d.ts +35 -0
  241. package/esm/src/kernel/engine/media-probe/matroska.js +226 -0
  242. package/esm/src/kernel/engine/media-probe/mp4.d.ts +22 -0
  243. package/esm/src/kernel/engine/media-probe/mp4.js +279 -0
  244. package/esm/src/kernel/engine/media-probe/opus.d.ts +4 -0
  245. package/esm/src/kernel/engine/media-probe/opus.js +23 -0
  246. package/esm/src/kernel/engine/media-probe/pdf.d.ts +5 -0
  247. package/esm/src/kernel/engine/media-probe/pdf.js +117 -0
  248. package/esm/src/kernel/engine/media-probe/video.d.ts +15 -0
  249. package/esm/src/kernel/engine/media-probe/video.js +49 -0
  250. package/esm/src/kernel/engine/record.d.ts +3 -0
  251. package/esm/src/kernel/engine/record.js +11 -0
  252. package/esm/src/kernel/engine/repair.d.ts +7 -0
  253. package/esm/src/kernel/engine/repair.js +36 -0
  254. package/esm/src/kernel/engine/runner/gates.d.ts +5 -0
  255. package/esm/src/kernel/engine/runner/gates.js +322 -0
  256. package/esm/src/kernel/engine/runner/mod.d.ts +15 -0
  257. package/esm/src/kernel/engine/runner/mod.js +574 -0
  258. package/esm/src/kernel/engine/runner/schema-validation.d.ts +14 -0
  259. package/esm/src/kernel/engine/runner/schema-validation.js +105 -0
  260. package/esm/src/kernel/engine/runner/stages.d.ts +28 -0
  261. package/esm/src/kernel/engine/runner/stages.js +48 -0
  262. package/esm/src/kernel/engine/runner/state.d.ts +76 -0
  263. package/esm/src/kernel/engine/runner/state.js +40 -0
  264. package/esm/src/kernel/engine/runner/steps.d.ts +14 -0
  265. package/esm/src/kernel/engine/runner/steps.js +360 -0
  266. package/esm/src/kernel/engine/runner/stream.d.ts +40 -0
  267. package/esm/src/kernel/engine/runner/stream.js +225 -0
  268. package/esm/src/kernel/engine/runner/usage.d.ts +45 -0
  269. package/esm/src/kernel/engine/runner/usage.js +150 -0
  270. package/esm/src/kernel/engine/session/mod.d.ts +31 -0
  271. package/esm/src/kernel/engine/session/mod.js +951 -0
  272. package/esm/src/kernel/engine/session/session-trace.d.ts +115 -0
  273. package/esm/src/kernel/engine/session/session-trace.js +489 -0
  274. package/esm/src/kernel/engine/token-estimate.d.ts +77 -0
  275. package/esm/src/kernel/engine/token-estimate.js +218 -0
  276. package/esm/src/kernel/engine/tool-trace.d.ts +58 -0
  277. package/esm/src/kernel/engine/tool-trace.js +131 -0
  278. package/esm/src/kernel/engine/tree.d.ts +2 -0
  279. package/esm/src/kernel/engine/tree.js +17 -0
  280. package/esm/src/kernel/engine/turn-trace.d.ts +118 -0
  281. package/esm/src/kernel/engine/turn-trace.js +863 -0
  282. package/esm/src/kernel/engine/usage.d.ts +30 -0
  283. package/esm/src/kernel/engine/usage.js +134 -0
  284. package/esm/src/kernel/interaction-parts.d.ts +10 -0
  285. package/esm/src/kernel/interaction-parts.js +22 -0
  286. package/esm/src/kernel/mod.d.ts +47 -0
  287. package/esm/src/kernel/mod.js +30 -0
  288. package/esm/src/kernel/profile-graph.d.ts +140 -0
  289. package/esm/src/kernel/profile-graph.js +151 -0
  290. package/esm/src/kernel/profile-presence.d.ts +9 -0
  291. package/esm/src/kernel/profile-presence.js +143 -0
  292. package/esm/src/kernel/profile-scope.d.ts +36 -0
  293. package/esm/src/kernel/profile-scope.js +262 -0
  294. package/esm/src/kernel/registry/attachments.d.ts +35 -0
  295. package/esm/src/kernel/registry/attachments.js +211 -0
  296. package/esm/src/kernel/registry/catalog.d.ts +19 -0
  297. package/esm/src/kernel/registry/catalog.js +78 -0
  298. package/esm/src/kernel/registry/ingress.d.ts +8 -0
  299. package/esm/src/kernel/registry/ingress.js +134 -0
  300. package/esm/src/kernel/registry/kernel-registry.d.ts +12 -0
  301. package/esm/src/kernel/registry/kernel-registry.js +8 -0
  302. package/esm/src/kernel/registry/profile-outputs.d.ts +3 -0
  303. package/esm/src/kernel/registry/profile-outputs.js +7 -0
  304. package/esm/src/kernel/registry/profiles.d.ts +92 -0
  305. package/esm/src/kernel/registry/profiles.js +698 -0
  306. package/esm/src/kernel/registry/provider-request.d.ts +6 -0
  307. package/esm/src/kernel/registry/provider-request.js +42 -0
  308. package/esm/src/kernel/registry/resolve.d.ts +14 -0
  309. package/esm/src/kernel/registry/resolve.js +237 -0
  310. package/esm/src/kernel/registry/schemas.d.ts +9 -0
  311. package/esm/src/kernel/registry/schemas.js +25 -0
  312. package/esm/src/kernel/registry/sole-model.d.ts +2 -0
  313. package/esm/src/kernel/registry/sole-model.js +4 -0
  314. package/esm/src/kernel/registry/system-prompt.d.ts +8 -0
  315. package/esm/src/kernel/registry/system-prompt.js +33 -0
  316. package/esm/src/kernel/registry/system-role.d.ts +3 -0
  317. package/esm/src/kernel/registry/system-role.js +9 -0
  318. package/esm/src/kernel/registry/vault.d.ts +13 -0
  319. package/esm/src/kernel/registry/vault.js +14 -0
  320. package/esm/src/kernel/schema.d.ts +172 -0
  321. package/esm/src/kernel/schema.js +653 -0
  322. package/esm/src/kernel/scope.d.ts +22 -0
  323. package/esm/src/kernel/scope.js +25 -0
  324. package/esm/src/kernel/stages.d.ts +141 -0
  325. package/esm/src/kernel/stages.js +388 -0
  326. package/esm/src/kernel/stop.d.ts +93 -0
  327. package/esm/src/kernel/stop.js +125 -0
  328. package/esm/src/kernel/system-parts.d.ts +26 -0
  329. package/esm/src/kernel/system-parts.js +98 -0
  330. package/esm/src/kernel/tools/activity-label.d.ts +16 -0
  331. package/esm/src/kernel/tools/activity-label.js +209 -0
  332. package/esm/src/kernel/tools/events.d.ts +51 -0
  333. package/esm/src/kernel/tools/events.js +149 -0
  334. package/esm/src/kernel/tools/execute.d.ts +64 -0
  335. package/esm/src/kernel/tools/execute.js +801 -0
  336. package/esm/src/kernel/tools/gate-answer.d.ts +50 -0
  337. package/esm/src/kernel/tools/gate-answer.js +54 -0
  338. package/esm/src/kernel/tools/harness.d.ts +16 -0
  339. package/esm/src/kernel/tools/harness.js +42 -0
  340. package/esm/src/kernel/tools/invoke.d.ts +10 -0
  341. package/esm/src/kernel/tools/invoke.js +129 -0
  342. package/esm/src/kernel/tools/mcp-sessions.d.ts +20 -0
  343. package/esm/src/kernel/tools/mcp-sessions.js +64 -0
  344. package/esm/src/kernel/tools/mod.d.ts +9 -0
  345. package/esm/src/kernel/tools/mod.js +6 -0
  346. package/esm/src/kernel/tools/model-text.d.ts +11 -0
  347. package/esm/src/kernel/tools/model-text.js +25 -0
  348. package/esm/src/kernel/tools/permission.d.ts +6 -0
  349. package/esm/src/kernel/tools/permission.js +38 -0
  350. package/esm/src/kernel/tools/project.d.ts +8 -0
  351. package/esm/src/kernel/tools/project.js +25 -0
  352. package/esm/src/kernel/tools/registry.d.ts +20 -0
  353. package/esm/src/kernel/tools/registry.js +84 -0
  354. package/esm/src/kernel/tools/remote.d.ts +110 -0
  355. package/esm/src/kernel/tools/remote.js +998 -0
  356. package/esm/src/kernel/tools/resolve.d.ts +28 -0
  357. package/esm/src/kernel/tools/resolve.js +259 -0
  358. package/esm/src/kernel/tools/schema.d.ts +10 -0
  359. package/esm/src/kernel/tools/schema.js +174 -0
  360. package/esm/src/kernel/tools/signed-in-fetch.d.ts +18 -0
  361. package/esm/src/kernel/tools/signed-in-fetch.js +45 -0
  362. package/esm/src/kernel/tools/stage-run.d.ts +93 -0
  363. package/esm/src/kernel/tools/stage-run.js +140 -0
  364. package/esm/src/kernel/tools/types.d.ts +287 -0
  365. package/esm/src/kernel/tools/types.js +1 -0
  366. package/esm/src/kernel/turn-events.d.ts +599 -0
  367. package/esm/src/kernel/turn-events.js +425 -0
  368. package/esm/src/kernel/types.d.ts +884 -0
  369. package/esm/src/kernel/types.js +1 -0
  370. package/esm/src/kernel/util/base64.d.ts +2 -0
  371. package/esm/src/kernel/util/base64.js +13 -0
  372. package/esm/src/kernel/util/exact-type.d.ts +31 -0
  373. package/esm/src/kernel/util/exact-type.js +1 -0
  374. package/esm/src/kernel/util/find-last.d.ts +3 -0
  375. package/esm/src/kernel/util/find-last.js +9 -0
  376. package/esm/src/kernel/util/mime.d.ts +2 -0
  377. package/esm/src/kernel/util/mime.js +4 -0
  378. package/esm/src/kernel/util/record.d.ts +1 -0
  379. package/esm/src/kernel/util/record.js +3 -0
  380. package/esm/src/observability/destinations.d.ts +9 -0
  381. package/esm/src/observability/destinations.js +38 -0
  382. package/esm/src/observability/jsonl.d.ts +18 -0
  383. package/esm/src/observability/jsonl.js +117 -0
  384. package/esm/src/observability/mod.d.ts +22 -0
  385. package/esm/src/observability/mod.js +16 -0
  386. package/esm/src/observability/openinference.d.ts +11 -0
  387. package/esm/src/observability/openinference.js +205 -0
  388. package/esm/src/observability/otlp.d.ts +68 -0
  389. package/esm/src/observability/otlp.js +98 -0
  390. package/esm/src/observability/phoenix.d.ts +29 -0
  391. package/esm/src/observability/phoenix.js +71 -0
  392. package/esm/src/observability/policy.d.ts +14 -0
  393. package/esm/src/observability/policy.js +69 -0
  394. package/esm/src/observability/resolve-policy.d.ts +8 -0
  395. package/esm/src/observability/resolve-policy.js +58 -0
  396. package/esm/src/observability/spans.d.ts +16 -0
  397. package/esm/src/observability/spans.js +56 -0
  398. package/esm/src/observability/trace-catalog.d.ts +111 -0
  399. package/esm/src/observability/trace-catalog.js +865 -0
  400. package/esm/src/observability/trace-record.d.ts +23 -0
  401. package/esm/src/observability/trace-record.js +223 -0
  402. package/esm/src/observability/trace-schema.d.ts +54 -0
  403. package/esm/src/observability/trace-schema.js +59 -0
  404. package/esm/src/observability/trace-sink.d.ts +13 -0
  405. package/esm/src/observability/trace-sink.js +3 -0
  406. package/esm/src/observability/trace-span.d.ts +92 -0
  407. package/esm/src/observability/trace-span.js +199 -0
  408. package/esm/src/observability/trace.d.ts +11 -0
  409. package/esm/src/observability/trace.js +35 -0
  410. package/esm/src/observability/types.d.ts +85 -0
  411. package/esm/src/observability/types.js +3 -0
  412. package/esm/src/presets/google/speech-voices.d.ts +8 -0
  413. package/esm/src/presets/google/speech-voices.js +38 -0
  414. package/esm/src/presets/google-limits.d.ts +12 -0
  415. package/esm/src/presets/google-limits.js +18 -0
  416. package/esm/src/presets/google.d.ts +104 -0
  417. package/esm/src/presets/google.js +188 -0
  418. package/esm/src/presets/mod.d.ts +10 -0
  419. package/esm/src/presets/mod.js +9 -0
  420. package/esm/src/presets/openrouter.d.ts +13 -0
  421. package/esm/src/presets/openrouter.js +13 -0
  422. package/esm/src/presets/typesafe.d.ts +2 -0
  423. package/esm/src/presets/typesafe.js +2 -0
  424. package/esm/src/providers/create-provider.d.ts +21 -0
  425. package/esm/src/providers/create-provider.js +90 -0
  426. package/esm/src/providers/decision/usage.d.ts +3 -0
  427. package/esm/src/providers/decision/usage.js +25 -0
  428. package/esm/src/providers/google/api-error.d.ts +8 -0
  429. package/esm/src/providers/google/api-error.js +123 -0
  430. package/esm/src/providers/google/grounding.d.ts +5 -0
  431. package/esm/src/providers/google/grounding.js +226 -0
  432. package/esm/src/providers/google/interactions/framing.d.ts +15 -0
  433. package/esm/src/providers/google/interactions/framing.js +263 -0
  434. package/esm/src/providers/google/interactions/mod.d.ts +2 -0
  435. package/esm/src/providers/google/interactions/mod.js +2 -0
  436. package/esm/src/providers/google/interactions/steps.d.ts +12 -0
  437. package/esm/src/providers/google/interactions/steps.js +200 -0
  438. package/esm/src/providers/google/interactions/stream.d.ts +24 -0
  439. package/esm/src/providers/google/interactions/stream.js +297 -0
  440. package/esm/src/providers/google/keys.d.ts +20 -0
  441. package/esm/src/providers/google/keys.js +87 -0
  442. package/esm/src/providers/google/live/framing.d.ts +51 -0
  443. package/esm/src/providers/google/live/framing.js +597 -0
  444. package/esm/src/providers/google/live/mod.d.ts +7 -0
  445. package/esm/src/providers/google/live/mod.js +7 -0
  446. package/esm/src/providers/google/live/openapi-schema.d.ts +1 -0
  447. package/esm/src/providers/google/live/openapi-schema.js +42 -0
  448. package/esm/src/providers/google/live/session.d.ts +14 -0
  449. package/esm/src/providers/google/live/session.js +150 -0
  450. package/esm/src/providers/google/live/stream.d.ts +51 -0
  451. package/esm/src/providers/google/live/stream.js +263 -0
  452. package/esm/src/providers/google/thinking.d.ts +3 -0
  453. package/esm/src/providers/google/thinking.js +8 -0
  454. package/esm/src/providers/google/urls.d.ts +6 -0
  455. package/esm/src/providers/google/urls.js +6 -0
  456. package/esm/src/providers/google/usage.d.ts +7 -0
  457. package/esm/src/providers/google/usage.js +49 -0
  458. package/esm/src/providers/local/local.d.ts +12 -0
  459. package/esm/src/providers/local/local.js +186 -0
  460. package/esm/src/providers/local/mod.d.ts +8 -0
  461. package/esm/src/providers/local/mod.js +8 -0
  462. package/esm/src/providers/mod.d.ts +11 -0
  463. package/esm/src/providers/mod.js +7 -0
  464. package/esm/src/providers/openrouter/cache-control.d.ts +5 -0
  465. package/esm/src/providers/openrouter/cache-control.js +4 -0
  466. package/esm/src/providers/openrouter/chat.d.ts +64 -0
  467. package/esm/src/providers/openrouter/chat.js +490 -0
  468. package/esm/src/providers/openrouter/image.d.ts +24 -0
  469. package/esm/src/providers/openrouter/image.js +187 -0
  470. package/esm/src/providers/openrouter/openai/compat.d.ts +19 -0
  471. package/esm/src/providers/openrouter/openai/compat.js +162 -0
  472. package/esm/src/providers/openrouter/openai/image-payload.d.ts +9 -0
  473. package/esm/src/providers/openrouter/openai/image-payload.js +115 -0
  474. package/esm/src/providers/openrouter/openai/sdk-messages.d.ts +10 -0
  475. package/esm/src/providers/openrouter/openai/sdk-messages.js +99 -0
  476. package/esm/src/providers/openrouter/openai/usage.d.ts +8 -0
  477. package/esm/src/providers/openrouter/openai/usage.js +56 -0
  478. package/esm/src/providers/openrouter/resolve-api-key.d.ts +3 -0
  479. package/esm/src/providers/openrouter/resolve-api-key.js +8 -0
  480. package/esm/src/providers/openrouter/speech.d.ts +18 -0
  481. package/esm/src/providers/openrouter/speech.js +109 -0
  482. package/esm/src/providers/probe.d.ts +5 -0
  483. package/esm/src/providers/probe.js +15 -0
  484. package/esm/src/providers/shared/builtin-wire.d.ts +4 -0
  485. package/esm/src/providers/shared/builtin-wire.js +9 -0
  486. package/esm/src/providers/shared/pcm.d.ts +14 -0
  487. package/esm/src/providers/shared/pcm.js +78 -0
  488. package/esm/src/providers/shared/response-identity.d.ts +11 -0
  489. package/esm/src/providers/shared/response-identity.js +12 -0
  490. package/esm/src/providers/shared/sse.d.ts +10 -0
  491. package/esm/src/providers/shared/sse.js +79 -0
  492. package/esm/src/providers/shared/structured-output.d.ts +4 -0
  493. package/esm/src/providers/shared/structured-output.js +11 -0
  494. package/esm/src/providers/shared/tool-args.d.ts +25 -0
  495. package/esm/src/providers/shared/tool-args.js +84 -0
  496. package/esm/src/providers/shared/upstream-tap.d.ts +8 -0
  497. package/esm/src/providers/shared/upstream-tap.js +85 -0
  498. package/esm/src/providers/shared/upstream-tape.d.ts +6 -0
  499. package/esm/src/providers/shared/upstream-tape.js +88 -0
  500. package/esm/src/providers/shared/vault.d.ts +13 -0
  501. package/esm/src/providers/shared/vault.js +41 -0
  502. package/esm/src/providers/types.d.ts +19 -0
  503. package/esm/src/providers/types.js +1 -0
  504. package/esm/src/surface/formats.d.ts +28 -0
  505. package/esm/src/surface/formats.js +139 -0
  506. package/esm/src/surface/mod.d.ts +14 -0
  507. package/esm/src/surface/mod.js +10 -0
  508. package/esm/src/surface/runtime.d.ts +40 -0
  509. package/esm/src/surface/runtime.js +439 -0
  510. package/esm/src/surface/tools.d.ts +15 -0
  511. package/esm/src/surface/tools.js +80 -0
  512. package/esm/src/surface/types.d.ts +104 -0
  513. package/esm/src/surface/types.js +4 -0
  514. package/package.json +108 -4
@@ -0,0 +1,139 @@
1
+ import { sensitiveSpans } from '../guardrails/sensitive.js';
2
+ import { applySpans } from '../observability/spans.js';
3
+ const MASK = '••••';
4
+ /** Names that carry a credential, in a URL's query or a header. */
5
+ const CREDENTIAL_NAME = /auth|key|token|secret|passw|pwd|cookie|session|signature|^sig$|credential|^code$|appid/i;
6
+ /** Names a query parameter carries a credential under, in a URL too malformed to parse. */
7
+ const QUERY_CREDENTIAL = /auth|key|token|secret|passw|pwd|signature|credential|appid/i;
8
+ /** What a secret's prefix says it is. Nothing else about the value is told. */
9
+ const SECRET_KINDS = [
10
+ [/^AIza/, 'Google API key'],
11
+ [/^sk-or-/, 'OpenRouter key'],
12
+ [/^sk-ant-/, 'Anthropic key'],
13
+ [/^sk-/, 'OpenAI key'],
14
+ [/^(?:ghp_|github_pat_)/, 'GitHub token'],
15
+ [/^xox[baprs]-/, 'Slack token'],
16
+ [/^AKIA/, 'AWS access key id'],
17
+ [/^eyJ[\w-]+\.[\w-]+\./, 'JWT'],
18
+ [/^Bearer\s/i, 'a whole Bearer header, not a bare token'],
19
+ [/^https?:\/\//i, 'a URL, not a key'],
20
+ ];
21
+ /** Below this, a value is told as "short" and is too short to scrub safely. */
22
+ const SHORT = 16;
23
+ const SCRUB_MIN = 6;
24
+ const TEXT_CAP = 2000;
25
+ const BYTES_CAP = 200;
26
+ export function secretCard(value, extra = {}) {
27
+ const text = typeof value === 'string' ? value : '';
28
+ const core = text.trim();
29
+ const problems = [];
30
+ if (/^(?:<.*>|x{3,}|\.{3}|your[-_ ]?(?:api[-_ ]?)?key|changeme|todo)$/i.test(core)) {
31
+ problems.push('a placeholder, not a real value');
32
+ }
33
+ else {
34
+ if (core && core !== text)
35
+ problems.push('spaces or a line break around it');
36
+ if (/[\r\n]/.test(core))
37
+ problems.push('a line break inside');
38
+ else if (/\s/.test(core))
39
+ problems.push('a space inside');
40
+ if (/^(['"`]).*\1$/.test(core))
41
+ problems.push('wrapped in quotes');
42
+ if (core && core.length < SHORT)
43
+ problems.push('shorter than keys usually are');
44
+ }
45
+ const looksLike = SECRET_KINDS.find(([pattern]) => pattern.test(core))?.[1];
46
+ return {
47
+ secret: true,
48
+ set: core.length > 0,
49
+ ...(looksLike ? { looksLike } : {}),
50
+ problems,
51
+ sameAs: [...(extra.sameAs ?? [])],
52
+ usedBy: [...(extra.usedBy ?? [])],
53
+ };
54
+ }
55
+ /** A URL with its credential query parameters and `user:pass@` masked. */
56
+ export function maskUrl(raw) {
57
+ let url;
58
+ try {
59
+ url = new URL(raw);
60
+ }
61
+ catch {
62
+ return raw.replace(/[?&;][^?&;#\s]*/g, (pair) => {
63
+ const at = pair.indexOf('=');
64
+ const name = pair.slice(1, at);
65
+ return at > 1 && at < pair.length - 1 && QUERY_CREDENTIAL.test(name)
66
+ ? `${pair.slice(0, at + 1)}${MASK}`
67
+ : pair;
68
+ });
69
+ }
70
+ const credentials = [...new Set(url.searchParams.keys())].filter((name) => CREDENTIAL_NAME.test(name));
71
+ if (!url.username && !url.password && credentials.length === 0)
72
+ return raw;
73
+ if (url.username)
74
+ url.username = MASK;
75
+ if (url.password)
76
+ url.password = MASK;
77
+ for (const name of credentials)
78
+ url.searchParams.set(name, MASK);
79
+ return url.href.replaceAll(encodeURIComponent(MASK), MASK);
80
+ }
81
+ /**
82
+ * Headers as JSON, credential-named values masked. Text that is not a JSON object is
83
+ * told only by its length: a parse error would quote it.
84
+ */
85
+ export function maskHeaders(raw) {
86
+ if (raw === undefined || raw === null || raw === '')
87
+ return raw;
88
+ let headers = raw;
89
+ if (typeof raw === 'string') {
90
+ try {
91
+ headers = JSON.parse(raw);
92
+ }
93
+ catch {
94
+ return `(not a JSON object, ${String(raw.length)} characters)`;
95
+ }
96
+ }
97
+ if (typeof headers !== 'object' || headers === null || Array.isArray(headers)) {
98
+ return '(not a JSON object)';
99
+ }
100
+ const masked = Object.fromEntries(Object.entries(headers).map(([name, value]) => [
101
+ name,
102
+ CREDENTIAL_NAME.test(name) ? MASK : value,
103
+ ]));
104
+ return typeof raw === 'string' ? JSON.stringify(masked) : masked;
105
+ }
106
+ /** Scrubs text: each known secret value by name, then the kernel's sensitive patterns. */
107
+ export function scrubText(text, known) {
108
+ let out = text;
109
+ for (const [name, value] of known) {
110
+ if (value.length >= SCRUB_MIN)
111
+ out = out.replaceAll(value, `[secret ${name}]`);
112
+ }
113
+ return applySpans(out, sensitiveSpans(out));
114
+ }
115
+ /** Known secret values worth scrubbing: trimmed, long enough, longest first. */
116
+ export function knownSecrets(secrets) {
117
+ return Object.entries(secrets)
118
+ .map(([name, value]) => [name, value.trim()])
119
+ .filter(([, value]) => value.length >= SCRUB_MIN)
120
+ .sort((a, b) => b[1].length - a[1].length);
121
+ }
122
+ /** Every string in `value` scrubbed and capped; long base64 under `data` told as bytes. */
123
+ export function scrubDeep(value, known) {
124
+ if (typeof value === 'string') {
125
+ const text = scrubText(value, known);
126
+ return text.length > TEXT_CAP ? `${text.slice(0, TEXT_CAP)}…(cut)` : text;
127
+ }
128
+ if (Array.isArray(value))
129
+ return value.map((item) => scrubDeep(item, known));
130
+ if (typeof value === 'object' && value !== null) {
131
+ return Object.fromEntries(Object.entries(value).map(([key, inner]) => [
132
+ key,
133
+ key === 'data' && typeof inner === 'string' && inner.length > BYTES_CAP
134
+ ? '(bytes)'
135
+ : scrubDeep(inner, known),
136
+ ]));
137
+ }
138
+ return value;
139
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Surfaces: one protocol for an agent to see and work in a client's screen. A page mounts a
3
+ * surface (nodes with fields and actions); the agent uses two tools, `look` and `act`, and the
4
+ * runtime projects every answer so secrets reach it only as cards.
5
+ */
6
+ import "../../_dnt.polyfills.js";
7
+ export type { SecretCard } from './formats.js';
8
+ export { knownSecrets, maskHeaders, maskUrl, scrubDeep, scrubText, secretCard } from './formats.js';
9
+ export type { SurfaceLedgerEntry, SurfaceRuntime, SurfaceRuntimeOptions, } from './runtime.js';
10
+ export { createSurfaceRuntime, SURFACE_TOOL_NAMES } from './runtime.js';
11
+ export type { SurfaceToolsOptions } from './tools.js';
12
+ export { clientAnsweredHandler, SURFACE_PROMPT, surfaceTools } from './tools.js';
13
+ export type { Surface, SurfaceAction, SurfaceActionContext, SurfaceActionOutcome, SurfaceAuthor, SurfaceChange, SurfaceEffect, SurfaceField, SurfaceFieldFormat, SurfaceIssue, SurfaceNode, SurfaceRejection, } from './types.js';
14
+ export { defineAction } from './types.js';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Surfaces: one protocol for an agent to see and work in a client's screen. A page mounts a
3
+ * surface (nodes with fields and actions); the agent uses two tools, `look` and `act`, and the
4
+ * runtime projects every answer so secrets reach it only as cards.
5
+ */
6
+ import "../../_dnt.polyfills.js";
7
+ export { knownSecrets, maskHeaders, maskUrl, scrubDeep, scrubText, secretCard } from './formats.js';
8
+ export { createSurfaceRuntime, SURFACE_TOOL_NAMES } from './runtime.js';
9
+ export { clientAnsweredHandler, SURFACE_PROMPT, surfaceTools } from './tools.js';
10
+ export { defineAction } from './types.js';
@@ -0,0 +1,40 @@
1
+ import type { Surface } from './types.js';
2
+ /** One answered `act`, kept so a retried call replays instead of applying twice. */
3
+ export interface SurfaceLedgerEntry {
4
+ callId: string;
5
+ at: string;
6
+ action: string;
7
+ intent?: string;
8
+ /** Whether it changed the surface, so a cancel or a lost answer after the fact can be told. */
9
+ applied: boolean;
10
+ result: unknown;
11
+ time: number;
12
+ }
13
+ export interface SurfaceRuntimeOptions {
14
+ now?: () => number;
15
+ /** Opens a declared surface that isn't mounted (goes to its page). */
16
+ open?: (surfaceId: string) => void;
17
+ mountWaitMs?: number;
18
+ /** A silent line for the agent: the person changed something, or a call's fate after the fact. */
19
+ onNote?: (line: string) => void;
20
+ /** Keeps the ledger across reloads; in memory when left out. */
21
+ ledger?: {
22
+ load(): readonly SurfaceLedgerEntry[];
23
+ save(entries: readonly SurfaceLedgerEntry[]): void;
24
+ };
25
+ }
26
+ export interface SurfaceRuntime {
27
+ /** Mounts a surface until the returned function is called. */
28
+ mount(surface: Surface): () => void;
29
+ /** A surface the agent may open though it isn't mounted: `open` takes it there. */
30
+ declare(id: string, title: string): void;
31
+ isSurfaceTool(name: string): boolean;
32
+ /** Answers a `look` or `act` call. Every answer is projected and scrubbed. */
33
+ answer(tool: string, args: unknown, callId: string): Promise<unknown>;
34
+ /** A call that changed the surface was cancelled, or its answer never got back: tells the agent once. */
35
+ settled(callId: string, how: 'cancelled' | 'undelivered'): void;
36
+ /** Where every mounted surface stands and what the agent last did; `null` when there is nothing. */
37
+ stateLine(): string | null;
38
+ }
39
+ export declare const SURFACE_TOOL_NAMES: readonly ["look", "act"];
40
+ export declare function createSurfaceRuntime(options?: SurfaceRuntimeOptions): SurfaceRuntime;
@@ -0,0 +1,439 @@
1
+ import { z } from 'zod';
2
+ import { jsonSchemaFromZod } from '../kernel/tools/schema.js';
3
+ import { knownSecrets, maskHeaders, maskUrl, scrubDeep, secretCard } from './formats.js';
4
+ const LEDGER_SIZE = 100;
5
+ const INTENT_WINDOW_MS = 60_000;
6
+ const MOUNT_WAIT_MS = 5000;
7
+ const NODE_LIST_CAP = 80;
8
+ const RECENT_IN_STATE = 5;
9
+ export const SURFACE_TOOL_NAMES = ['look', 'act'];
10
+ const lookArgs = z.object({ at: z.string().optional() });
11
+ const actArgs = z.object({
12
+ at: z.string().min(1),
13
+ action: z.string().min(1),
14
+ input: z.record(z.string(), z.unknown()).optional(),
15
+ basedOn: z.number().int().optional(),
16
+ intent: z.string().optional(),
17
+ });
18
+ const setInput = z.object({
19
+ changes: z
20
+ .record(z.string(), z.unknown())
21
+ .describe('Field name (or a dotted path in one, "include.usage") to its new value'),
22
+ });
23
+ const pointInput = z.object({
24
+ field: z.string().optional().describe('A field to focus; leave out to show the whole node'),
25
+ });
26
+ const BUILT_IN = {
27
+ set: {
28
+ description: 'Change fields. Each one refused comes back with why; the rest apply.',
29
+ effect: 'write',
30
+ input: setInput,
31
+ },
32
+ point: {
33
+ description: 'Show this node, or one of its fields, to the person: it is selected and focused. Use it to have them enter a secret.',
34
+ effect: 'read',
35
+ input: pointInput,
36
+ },
37
+ };
38
+ function issueCount(count) {
39
+ return `${String(count)} ${count === 1 ? 'issue' : 'issues'}`;
40
+ }
41
+ function rejectionsFrom(error) {
42
+ return error.issues.map((issue) => ({
43
+ field: issue.path.join('.') || 'input',
44
+ why: issue.message,
45
+ }));
46
+ }
47
+ function errorText(err) {
48
+ return err instanceof Error ? err.message : String(err);
49
+ }
50
+ export function createSurfaceRuntime(options = {}) {
51
+ const now = options.now ?? Date.now;
52
+ const mounted = new Map();
53
+ const declared = new Map();
54
+ const mountWaiters = new Set();
55
+ let ledger = [...(options.ledger?.load() ?? [])];
56
+ const note = (line) => options.onNote?.(line);
57
+ const remember = (entry) => {
58
+ ledger = [...ledger.filter((old) => old.callId !== entry.callId), entry].slice(-LEDGER_SIZE);
59
+ options.ledger?.save(ledger);
60
+ };
61
+ const address = (surface, nodeId) => nodeId ? `${surface.id}/${nodeId}` : surface.id;
62
+ const nodeIssues = (surface, nodeId) => (surface.issues?.() ?? []).filter((issue) => issue.node === nodeId);
63
+ /** Every secret value showing on the page, by name: what the surface says, and every secret field. */
64
+ const secretsOf = (surface) => {
65
+ const found = { ...surface.secrets?.() };
66
+ for (const node of surface.nodes()) {
67
+ for (const [name, field] of Object.entries(node.fields?.() ?? {})) {
68
+ if (field.format === 'secret' && typeof field.value === 'string') {
69
+ found[`${address(surface, node.id)}.${name}`] = field.value;
70
+ }
71
+ }
72
+ }
73
+ return found;
74
+ };
75
+ const known = () => knownSecrets(Object.assign({}, ...[...mounted.values()].map((surface) => secretsOf(surface))));
76
+ const project = (surface, node, name, field) => {
77
+ if (field.format === 'secret') {
78
+ const value = typeof field.value === 'string' ? field.value.trim() : '';
79
+ const self = `${address(surface, node.id)}.${name}`;
80
+ const sameAs = value
81
+ ? Object.entries(secretsOf(surface))
82
+ .filter(([other, otherValue]) => other !== self && otherValue.trim() === value)
83
+ .map(([other]) => other)
84
+ : [];
85
+ return secretCard(field.value, { sameAs, usedBy: field.usedBy });
86
+ }
87
+ if (field.format === 'url' && typeof field.value === 'string')
88
+ return maskUrl(field.value);
89
+ if (field.format === 'headers')
90
+ return maskHeaders(field.value);
91
+ return field.value;
92
+ };
93
+ const actionsOf = (node) => {
94
+ const own = Object.entries(node.actions ?? {});
95
+ const builtIn = [];
96
+ if (node.set && node.fields)
97
+ builtIn.push(['set', BUILT_IN.set]);
98
+ if (node.point)
99
+ builtIn.push(['point', BUILT_IN.point]);
100
+ return [...builtIn, ...own];
101
+ };
102
+ const children = (surface, nodeId) => surface
103
+ .nodes()
104
+ .filter((child) => child.id && (child.parent ?? '') === nodeId)
105
+ .map((child) => {
106
+ const count = nodeIssues(surface, child.id).length;
107
+ return {
108
+ at: address(surface, child.id),
109
+ title: child.title,
110
+ ...(count ? { issues: count } : {}),
111
+ };
112
+ });
113
+ const nodeView = ({ surface, node, at }) => {
114
+ const fields = node.fields?.() ?? {};
115
+ const about = Object.fromEntries(Object.entries(fields).flatMap(([name, field]) => {
116
+ const info = {
117
+ ...(field.type ? { type: field.type } : {}),
118
+ ...(field.doc ? { doc: field.doc } : {}),
119
+ ...(field.options?.length ? { options: field.options } : {}),
120
+ ...(field.format && field.format !== 'text' ? { format: field.format } : {}),
121
+ ...(field.readOnly ? { readOnly: field.readOnly } : {}),
122
+ };
123
+ return Object.keys(info).length ? [[name, info]] : [];
124
+ }));
125
+ const issues = nodeIssues(surface, node.id).map(({ field, message }) => ({
126
+ ...(field ? { field } : {}),
127
+ message,
128
+ }));
129
+ const kids = children(surface, node.id);
130
+ return {
131
+ at,
132
+ title: node.title,
133
+ revision: surface.revision(),
134
+ ...(node.summary ? { summary: node.summary } : {}),
135
+ ...(Object.keys(fields).length
136
+ ? {
137
+ fields: Object.fromEntries(Object.entries(fields).map(([name, field]) => [
138
+ name,
139
+ project(surface, node, name, field),
140
+ ])),
141
+ }
142
+ : {}),
143
+ ...(Object.keys(about).length ? { about } : {}),
144
+ ...(issues.length ? { issues } : {}),
145
+ actions: actionsOf(node).map(([name, action]) => ({
146
+ name,
147
+ effect: action.effect,
148
+ description: action.description,
149
+ ...(action.input ? { input: jsonSchemaFromZod(action.input, 'input') } : {}),
150
+ })),
151
+ ...(kids.length ? { children: kids } : {}),
152
+ };
153
+ };
154
+ const overview = () => ({
155
+ surfaces: [...mounted.values()].map((surface) => {
156
+ const issues = surface.issues?.() ?? [];
157
+ return {
158
+ at: surface.id,
159
+ title: surface.title,
160
+ revision: surface.revision(),
161
+ summary: surface.summary(),
162
+ ...(issues.length ? { issues: issues.length } : {}),
163
+ nodes: surface
164
+ .nodes()
165
+ .filter((node) => node.id)
166
+ .slice(0, NODE_LIST_CAP)
167
+ .map((node) => {
168
+ const count = issues.filter((issue) => issue.node === node.id).length;
169
+ return {
170
+ at: address(surface, node.id),
171
+ title: node.title,
172
+ ...(node.parent ? { parent: address(surface, node.parent) } : {}),
173
+ ...(count ? { issues: count } : {}),
174
+ };
175
+ }),
176
+ };
177
+ }),
178
+ ...([...declared.keys()].some((id) => !mounted.has(id))
179
+ ? {
180
+ closed: [...declared]
181
+ .filter(([id]) => !mounted.has(id))
182
+ .map(([id, title]) => ({ at: id, title, note: 'Look or act on it to open it.' })),
183
+ }
184
+ : {}),
185
+ });
186
+ const waitForMount = (id, ms) => new Promise((resolve) => {
187
+ if (mounted.has(id)) {
188
+ resolve(true);
189
+ return;
190
+ }
191
+ const check = () => {
192
+ if (!mounted.has(id))
193
+ return;
194
+ clearTimeout(timer);
195
+ mountWaiters.delete(check);
196
+ resolve(true);
197
+ };
198
+ const timer = setTimeout(() => {
199
+ mountWaiters.delete(check);
200
+ resolve(false);
201
+ }, ms);
202
+ mountWaiters.add(check);
203
+ });
204
+ /** The node `at` names, opening its surface first when it is declared but not mounted. */
205
+ const resolve = async (at) => {
206
+ const slash = at.indexOf('/');
207
+ const surfaceId = slash < 0 ? at : at.slice(0, slash);
208
+ const nodeId = slash < 0 ? '' : at.slice(slash + 1);
209
+ if (!mounted.has(surfaceId)) {
210
+ if (!declared.has(surfaceId) || !options.open) {
211
+ return { refused: `Nothing called ${surfaceId} is open. Look to see what is.` };
212
+ }
213
+ options.open(surfaceId);
214
+ if (!(await waitForMount(surfaceId, options.mountWaitMs ?? MOUNT_WAIT_MS))) {
215
+ return { refused: `${surfaceId} did not open. Look to see where the person is.` };
216
+ }
217
+ }
218
+ const surface = mounted.get(surfaceId);
219
+ const node = surface?.nodes().find((candidate) => candidate.id === nodeId);
220
+ if (!surface || !node) {
221
+ return { refused: `No ${at} here. Look at ${surfaceId} for what is.` };
222
+ }
223
+ return { surface, node, at: address(surface, node.id) };
224
+ };
225
+ const changedSince = (surface, revision) => [
226
+ ...new Set((surface.changesSince?.(revision) ?? []).flatMap((change) => change.nodes.map((id) => address(surface, id)))),
227
+ ];
228
+ const look = async (args) => {
229
+ const parsed = lookArgs.safeParse(args ?? {});
230
+ if (!parsed.success)
231
+ return { status: 'refused', why: 'at must be text' };
232
+ if (!parsed.data.at)
233
+ return overview();
234
+ const target = await resolve(parsed.data.at);
235
+ if ('refused' in target)
236
+ return { status: 'refused', why: target.refused };
237
+ return nodeView(target);
238
+ };
239
+ const runBuiltIn = (target, name, input, ctx) => {
240
+ const { node } = target;
241
+ if (name === 'point') {
242
+ const field = typeof input.field === 'string' ? input.field : undefined;
243
+ node.point?.(field);
244
+ return { result: { shown: field ? `${target.at}.${field}` : target.at } };
245
+ }
246
+ const fields = node.fields?.() ?? {};
247
+ const rejected = [];
248
+ const allowed = {};
249
+ for (const [path, value] of Object.entries(input.changes)) {
250
+ const field = fields[path.split('.', 1)[0] ?? path];
251
+ if (!field)
252
+ rejected.push({ field: path, why: 'no such field; look at the node for its fields' });
253
+ else if (field.format === 'secret') {
254
+ rejected.push({
255
+ field: path,
256
+ why: 'only the person enters this: act point on it, then ask them to type it in',
257
+ });
258
+ }
259
+ else if (field.readOnly)
260
+ rejected.push({ field: path, why: field.readOnly });
261
+ else
262
+ allowed[path] = value;
263
+ }
264
+ if (Object.keys(allowed).length && node.set) {
265
+ rejected.push(...node.set(allowed, ctx).rejected);
266
+ }
267
+ return { rejected, node: node.id };
268
+ };
269
+ /** What an `act` call resolved to, or the answer that ends it before anything runs. */
270
+ const prepareAct = async (args) => {
271
+ const parsed = actArgs.safeParse(args ?? {});
272
+ if (!parsed.success) {
273
+ return {
274
+ done: { status: 'refused', why: 'Bad call.', rejected: rejectionsFrom(parsed.error) },
275
+ };
276
+ }
277
+ const { at, action: name, basedOn, intent } = parsed.data;
278
+ const target = await resolve(at);
279
+ if ('refused' in target)
280
+ return { done: { status: 'refused', why: target.refused } };
281
+ const { surface, node } = target;
282
+ const action = actionsOf(node).find(([candidate]) => candidate === name)?.[1];
283
+ if (!action) {
284
+ return {
285
+ done: {
286
+ status: 'refused',
287
+ why: `${target.at} has no ${name}. It has: ${actionsOf(node)
288
+ .map(([candidate]) => candidate)
289
+ .join(', ')}.`,
290
+ },
291
+ };
292
+ }
293
+ const checked = action.input
294
+ ? action.input.safeParse(parsed.data.input ?? {})
295
+ : { success: true, data: parsed.data.input ?? {} };
296
+ if (!checked.success) {
297
+ return {
298
+ done: { status: 'refused', why: 'Bad input.', rejected: rejectionsFrom(checked.error) },
299
+ };
300
+ }
301
+ const write = action.effect === 'write';
302
+ if (write && basedOn === undefined) {
303
+ return {
304
+ done: {
305
+ status: 'refused',
306
+ why: 'Pass basedOn: the revision from your last look.',
307
+ revision: surface.revision(),
308
+ },
309
+ };
310
+ }
311
+ if (write && action.intent && intent) {
312
+ const repeat = ledger.find((entry) => entry.intent === intent &&
313
+ entry.at === target.at &&
314
+ now() - entry.time < INTENT_WINDOW_MS);
315
+ if (repeat)
316
+ return { done: repeat.result };
317
+ }
318
+ return { ready: { target, name, basedOn, intent, data: checked.data, write } };
319
+ };
320
+ const act = async (args, callId) => {
321
+ const seen = ledger.find((entry) => entry.callId === callId);
322
+ if (seen)
323
+ return seen.result;
324
+ const prepared = await prepareAct(args);
325
+ if (!prepared.ready)
326
+ return prepared.done;
327
+ const { target, name, basedOn, intent, data, write } = prepared.ready;
328
+ const { surface, node } = target;
329
+ let result;
330
+ let applied = false;
331
+ if (write && basedOn !== surface.revision()) {
332
+ result = {
333
+ status: 'stale',
334
+ why: 'The page changed since your look; nothing applied. Look again.',
335
+ revision: surface.revision(),
336
+ changed: changedSince(surface, basedOn ?? 0),
337
+ };
338
+ }
339
+ else {
340
+ const before = surface.revision();
341
+ const ctx = { callId, by: 'agent' };
342
+ try {
343
+ const own = node.actions?.[name];
344
+ const outcome = name in BUILT_IN && !own
345
+ ? runBuiltIn(target, name, data, ctx)
346
+ : await own.run(data, ctx);
347
+ const after = surface.revision();
348
+ applied = after !== before;
349
+ const landed = outcome.node === undefined ? undefined : await resolve(address(surface, outcome.node));
350
+ const issues = surface.issues?.() ?? [];
351
+ result = {
352
+ status: write ? (applied ? 'applied' : 'unchanged') : 'done',
353
+ revision: after,
354
+ ...(applied ? { changed: changedSince(surface, before) } : {}),
355
+ ...(outcome.rejected?.length ? { rejected: outcome.rejected } : {}),
356
+ ...(outcome.result === undefined ? {} : { result: outcome.result }),
357
+ ...(landed && !('refused' in landed) ? { node: nodeView(landed) } : {}),
358
+ ...(write ? { issues: issues.length } : {}),
359
+ };
360
+ }
361
+ catch (err) {
362
+ result = { status: 'failed', why: errorText(err), revision: surface.revision() };
363
+ }
364
+ }
365
+ const scrubbed = scrubDeep(result, known());
366
+ remember({
367
+ callId,
368
+ at: target.at,
369
+ action: name,
370
+ ...(intent ? { intent } : {}),
371
+ applied,
372
+ result: scrubbed,
373
+ time: now(),
374
+ });
375
+ return scrubbed;
376
+ };
377
+ return {
378
+ mount(surface) {
379
+ mounted.set(surface.id, surface);
380
+ for (const waiter of [...mountWaiters])
381
+ waiter();
382
+ let seen = surface.revision();
383
+ const titles = () => new Map(surface.nodes().map((node) => [node.id, node.title]));
384
+ const stop = surface.subscribe?.(() => {
385
+ const changes = surface.changesSince?.(seen) ?? [];
386
+ seen = surface.revision();
387
+ const nodes = [
388
+ ...new Set(changes.filter((change) => change.by === 'person').flatMap((c) => c.nodes)),
389
+ ];
390
+ if (nodes.length === 0)
391
+ return;
392
+ const named = titles();
393
+ const what = nodes.map((id) => named.get(id) ?? (id || surface.title)).join(', ');
394
+ const count = surface.issues?.().length ?? 0;
395
+ note(`${surface.id} r${String(seen)}: the person changed ${what}; ${issueCount(count)}`);
396
+ });
397
+ return () => {
398
+ stop?.();
399
+ if (mounted.get(surface.id) === surface)
400
+ mounted.delete(surface.id);
401
+ };
402
+ },
403
+ declare(id, title) {
404
+ declared.set(id, title);
405
+ },
406
+ isSurfaceTool(name) {
407
+ return SURFACE_TOOL_NAMES.includes(name);
408
+ },
409
+ async answer(tool, args, callId) {
410
+ try {
411
+ if (tool === 'look')
412
+ return scrubDeep(await look(args), known());
413
+ if (tool === 'act')
414
+ return await act(args, callId);
415
+ return { status: 'refused', why: `${tool} is not a surface tool.` };
416
+ }
417
+ catch (err) {
418
+ return scrubDeep({ status: 'failed', why: errorText(err) }, known());
419
+ }
420
+ },
421
+ settled(callId, how) {
422
+ const entry = ledger.find((candidate) => candidate.callId === callId);
423
+ if (!entry?.applied)
424
+ return;
425
+ note(`${entry.at} ${entry.action} applied, but ${how === 'cancelled' ? 'the call was cancelled after' : 'its answer never reached you'}`);
426
+ },
427
+ stateLine() {
428
+ const surfaces = [...mounted.values()].map((surface) => `${surface.id} r${String(surface.revision())}: ${surface.summary()}`);
429
+ const recent = ledger
430
+ .slice(-RECENT_IN_STATE)
431
+ .map((entry) => `${entry.at} ${entry.action}`)
432
+ .join(', ');
433
+ if (!surfaces.length && !recent)
434
+ return null;
435
+ const line = [surfaces.join('; '), recent ? `last calls: ${recent}` : ''].filter(Boolean);
436
+ return scrubDeep(`(state) ${line.join('; ')}`, known());
437
+ },
438
+ };
439
+ }
@@ -0,0 +1,15 @@
1
+ import type { ToolContext, ToolDefinitionInput } from '../kernel/tools/types.js';
2
+ /**
3
+ * The handler for a function tool the client answers: it returns what the client sent back for
4
+ * the call, which the relay bridge hands over as `ctx.host.clientOutput`. With no output the call
5
+ * fails to the model, naming the tool; so does a call the bridge settled because the client never
6
+ * answered (`host.clientTimedOut`).
7
+ */
8
+ export declare function clientAnsweredHandler(name: string): (input: unknown, ctx: ToolContext) => unknown;
9
+ export interface SurfaceToolsOptions {
10
+ category?: string;
11
+ }
12
+ /** `look` and `act`: the two tools an agent uses to see and work in every surface a client mounts. */
13
+ export declare function surfaceTools(options?: SurfaceToolsOptions): ToolDefinitionInput[];
14
+ /** How to use `look` and `act`, for an agent's instructions. */
15
+ export declare const SURFACE_PROMPT = "You see and work in the person's screen through surfaces, with two tools.\n- look: no `at` lists every surface. Look at a node before you act on it.\n- act: do one of the actions look lists. Pass basedOn (the revision from your last look) for writes.\n- Say a change is done only when act comes back applied. If it lists rejected fields, say which and why.\n- stale means the person changed something: look again, then go on. After refused or failed, look before retrying; never retry blind.\n- Secrets (keys, tokens, passwords) show only as cards: set or not, what they look like, their problems. You never see or type the value. To have the person enter one, act point on it and ask them to paste it. To find out whether it works, use the node's test action.\n- When something isn't working, look for issues, test what can be tested, and tell the person what you found in plain words.\n- A line starting \"(state)\" is a silent note about what changed on the page. It is background; never read it out. If it says something you did applied late or was cancelled, tell the person once, in a few words.";