@codespar/cli 0.18.1 → 0.20.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 (558) hide show
  1. package/README.md +1 -1
  2. package/dist/commands/login.js +52 -12
  3. package/dist/commands/login.js.map +1 -1
  4. package/dist/index.js +1 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/surface.js +31 -13
  7. package/dist/surface.js.map +1 -1
  8. package/package.json +1 -1
  9. package/templates/bills-agent/README.md +2 -2
  10. package/templates/bills-agent/agents/bills-agent/.env.example +2 -2
  11. package/templates/bills-agent/agents/bills-agent/README.md +25 -18
  12. package/templates/bills-agent/agents/bills-agent/SYSTEM_PROMPT.md +13 -3
  13. package/templates/bills-agent/agents/bills-agent/agent.yaml +2 -1
  14. package/templates/bills-agent/agents/bills-agent/evals/adversarial/exfiltration.transcript.jsonl +1 -1
  15. package/templates/bills-agent/agents/bills-agent/evals/adversarial/false-authority.transcript.jsonl +1 -1
  16. package/templates/bills-agent/agents/bills-agent/evals/adversarial/prompt-injection.transcript.jsonl +1 -1
  17. package/templates/bills-agent/agents/bills-agent/mandate.example.json +1 -1
  18. package/templates/bills-agent/agents/bills-agent/runbook.md +1 -1
  19. package/templates/bills-agent/agents/bills-agent/scenarios/beneficiary-not-allowed.transcript.jsonl +1 -1
  20. package/templates/bills-agent/agents/bills-agent/scenarios/cap-exceeded.transcript.jsonl +1 -1
  21. package/templates/bills-agent/agents/bills-agent/scenarios/escalated-above-threshold.transcript.jsonl +4 -4
  22. package/templates/bills-agent/agents/bills-agent/scenarios/happy-path.transcript.jsonl +1 -1
  23. package/templates/bills-agent/agents/bills-agent/scenarios/mandate-revoked.json +1 -1
  24. package/templates/bills-agent/agents/bills-agent/scenarios/mandate-revoked.transcript.jsonl +4 -4
  25. package/templates/bills-agent/agents/bills-agent/scenarios/prompt-injection.transcript.jsonl +1 -1
  26. package/templates/bills-agent/agents/bills-agent/src/bills.ts +1 -1
  27. package/templates/bills-agent/agents/bills-agent/src/kit.ts +15 -28
  28. package/templates/bills-agent/agents/bills-agent/src/modules/embedded-consent.ts +42 -15
  29. package/templates/bills-agent/agents/bills-agent/src/modules/pix-out.ts +21 -3
  30. package/templates/bills-agent/agents/bills-agent/src/strings.ts +68 -0
  31. package/templates/bills-agent/agents/bills-agent/test/cli.test.ts +130 -2
  32. package/templates/bills-agent/agents/bills-agent/test/consent-money.test.ts +25 -0
  33. package/templates/bills-agent/agents/bills-agent/test/dates-and-approval.test.ts +98 -0
  34. package/templates/bills-agent/agents/bills-agent/test/eval-runs.test.ts +81 -0
  35. package/templates/bills-agent/agents/bills-agent/test/fixtures/excursao-300.transcript.jsonl +2 -2
  36. package/templates/bills-agent/agents/bills-agent/test/fixtures/material-400.transcript.jsonl +1 -1
  37. package/templates/bills-agent/agents/bills-agent/test/locale.test.ts +161 -0
  38. package/templates/bills-agent/agents/bills-agent/test/mandate-state.test.ts +108 -0
  39. package/templates/bills-agent/agents/bills-agent/test/refused-before-draft.test.ts +81 -0
  40. package/templates/bills-agent/agents/bills-agent/test/replay.test.ts +76 -0
  41. package/templates/bills-agent/agents/bills-agent/test/reply-and-outcome.test.ts +84 -0
  42. package/templates/bills-agent/agents/bills-agent/test/reply-language.test.ts +95 -0
  43. package/templates/bills-agent/agents/bills-agent/test/rerun-and-missing-transcript.test.ts +120 -0
  44. package/templates/bills-agent/agents/bills-agent/test/rerun-world-events.test.ts +55 -0
  45. package/templates/bills-agent/agents/bills-agent/tools.json +1 -1
  46. package/templates/bills-agent/packages/agent-core/README.md +21 -2
  47. package/templates/bills-agent/packages/agent-core/package.json +1 -1
  48. package/templates/bills-agent/packages/agent-core/src/agent.ts +33 -6
  49. package/templates/bills-agent/packages/agent-core/src/api/charge-rail.ts +15 -1
  50. package/templates/bills-agent/packages/agent-core/src/api/rail.ts +11 -5
  51. package/templates/bills-agent/packages/agent-core/src/api/sandbox-payer.ts +36 -0
  52. package/templates/bills-agent/packages/agent-core/src/bundle.ts +2 -0
  53. package/templates/bills-agent/packages/agent-core/src/channels.ts +18 -8
  54. package/templates/bills-agent/packages/agent-core/src/check.ts +25 -3
  55. package/templates/bills-agent/packages/agent-core/src/engine.ts +90 -9
  56. package/templates/bills-agent/packages/agent-core/src/escalate.ts +10 -0
  57. package/templates/bills-agent/packages/agent-core/src/index.ts +3 -0
  58. package/templates/bills-agent/packages/agent-core/src/language.ts +52 -0
  59. package/templates/bills-agent/packages/agent-core/src/locale.ts +88 -0
  60. package/templates/bills-agent/packages/agent-core/src/manifest.ts +4 -1
  61. package/templates/bills-agent/packages/agent-core/src/rail.ts +29 -1
  62. package/templates/bills-agent/packages/agent-core/src/receipt-verification.ts +30 -2
  63. package/templates/bills-agent/packages/agent-core/src/secrets.ts +53 -8
  64. package/templates/bills-agent/packages/agent-core/src/state-machine.ts +14 -0
  65. package/templates/bills-agent/packages/agent-core/src/strings.ts +175 -0
  66. package/templates/bills-agent/packages/agent-core/src/stubs/charge-rail.ts +15 -2
  67. package/templates/bills-agent/packages/agent-core/src/stubs/rail.ts +7 -4
  68. package/templates/bills-agent/packages/agent-core/src/types.ts +15 -2
  69. package/templates/bills-agent/packages/agent-core/test/actor-on-the-wire.test.ts +144 -0
  70. package/templates/bills-agent/packages/agent-core/test/attempt-replay.test.ts +2 -2
  71. package/templates/bills-agent/packages/agent-core/test/engine.test.ts +23 -0
  72. package/templates/bills-agent/packages/agent-core/test/helpers.ts +1 -1
  73. package/templates/bills-agent/packages/agent-core/test/language.test.ts +40 -0
  74. package/templates/bills-agent/packages/agent-core/test/locale.test.ts +137 -0
  75. package/templates/bills-agent/packages/agent-core/test/mandate-status.test.ts +2 -2
  76. package/templates/bills-agent/packages/agent-core/test/manifest.test.ts +2 -2
  77. package/templates/bills-agent/packages/agent-core/test/rail-errors.test.ts +74 -0
  78. package/templates/bills-agent/packages/agent-core/test/receipt-read-verification.test.ts +32 -0
  79. package/templates/bills-agent/packages/agent-core/test/receivables.test.ts +49 -0
  80. package/templates/bills-agent/packages/agent-core/test/recorded-turns.ts +29 -0
  81. package/templates/bills-agent/packages/agent-core/test/secrets.test.ts +40 -1
  82. package/templates/bills-agent/packages/agent-runtime/README.md +31 -4
  83. package/templates/bills-agent/packages/agent-runtime/src/channels/rules.ts +4 -2
  84. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +11 -5
  85. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +43 -21
  86. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +3 -0
  87. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +8 -12
  88. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +8 -4
  89. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +12 -9
  90. package/templates/bills-agent/packages/agent-runtime/src/cli.ts +30 -4
  91. package/templates/bills-agent/packages/agent-runtime/src/commands/check.ts +18 -2
  92. package/templates/bills-agent/packages/agent-runtime/src/commands/decide.ts +13 -4
  93. package/templates/bills-agent/packages/agent-runtime/src/commands/eval.ts +7 -2
  94. package/templates/bills-agent/packages/agent-runtime/src/commands/inspect.ts +11 -13
  95. package/templates/bills-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +32 -24
  96. package/templates/bills-agent/packages/agent-runtime/src/commands/poll.ts +12 -5
  97. package/templates/bills-agent/packages/agent-runtime/src/commands/rerun.ts +83 -10
  98. package/templates/bills-agent/packages/agent-runtime/src/commands/resume.ts +2 -1
  99. package/templates/bills-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +10 -5
  100. package/templates/bills-agent/packages/agent-runtime/src/commands/start.ts +48 -17
  101. package/templates/bills-agent/packages/agent-runtime/src/commands/verify.ts +37 -12
  102. package/templates/bills-agent/packages/agent-runtime/src/commands/webhook.ts +11 -3
  103. package/templates/bills-agent/packages/agent-runtime/src/default-kit.ts +52 -22
  104. package/templates/bills-agent/packages/agent-runtime/src/env.ts +64 -0
  105. package/templates/bills-agent/packages/agent-runtime/src/index.ts +2 -0
  106. package/templates/bills-agent/packages/agent-runtime/src/inspect.ts +81 -10
  107. package/templates/bills-agent/packages/agent-runtime/src/kit.ts +34 -12
  108. package/templates/bills-agent/packages/agent-runtime/src/outcome.ts +118 -0
  109. package/templates/bills-agent/packages/agent-runtime/src/poll.ts +7 -7
  110. package/templates/bills-agent/packages/agent-runtime/src/runs.ts +51 -0
  111. package/templates/bills-agent/packages/agent-runtime/src/scenarios.ts +55 -8
  112. package/templates/bills-agent/packages/agent-runtime/src/setup.ts +75 -5
  113. package/templates/bills-agent/packages/agent-runtime/src/terminal.ts +71 -33
  114. package/templates/bills-agent/packages/agent-runtime/test/env-names.test.ts +56 -0
  115. package/templates/bills-agent/packages/agent-runtime/test/inspect-mandate-status.test.ts +80 -0
  116. package/templates/bills-agent/packages/agent-runtime/test/inspect.test.ts +63 -2
  117. package/templates/bills-agent/packages/agent-runtime/test/outcome.test.ts +72 -0
  118. package/templates/bills-agent/packages/agent-runtime/test/poll-payer.test.ts +64 -0
  119. package/templates/bills-agent/packages/agent-runtime/test/rerun-not-replayed.test.ts +46 -0
  120. package/templates/bills-agent/packages/agent-runtime/test/transition-line.test.ts +29 -0
  121. package/templates/bills-agent/packages/agent-runtime/test/verify-cli.test.ts +99 -6
  122. package/templates/bills-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +8 -0
  123. package/templates/bills-agent/packages/agent-runtime/test/whatsapp-session.test.ts +77 -0
  124. package/templates/bills-agent/packages/agent-runtime/test/whatsapp-status-replies.test.ts +27 -1
  125. package/templates/checkout-agent/README.md +2 -2
  126. package/templates/checkout-agent/agents/checkout-agent/.env.example +6 -4
  127. package/templates/checkout-agent/agents/checkout-agent/README.md +16 -8
  128. package/templates/checkout-agent/agents/checkout-agent/SYSTEM_PROMPT.md +17 -7
  129. package/templates/checkout-agent/agents/checkout-agent/agent.yaml +4 -3
  130. package/templates/checkout-agent/agents/checkout-agent/channels/whatsapp/README.md +2 -2
  131. package/templates/checkout-agent/agents/checkout-agent/channels/whatsapp/templates.json +48 -4
  132. package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/beneficiary-swap-human.json +1 -1
  133. package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/beneficiary-swap.json +1 -1
  134. package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/beneficiary-swap.transcript.jsonl +1 -1
  135. package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/coupon-unknown.json +1 -1
  136. package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/exfiltration.transcript.jsonl +1 -1
  137. package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/fractioning.transcript.jsonl +1 -1
  138. package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/payment-claimed.json +1 -1
  139. package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/payment-claimed.transcript.jsonl +1 -1
  140. package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/price-injected.json +1 -1
  141. package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/prompt-injection.transcript.jsonl +1 -1
  142. package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/quantity-swapped.transcript.jsonl +1 -1
  143. package/templates/checkout-agent/agents/checkout-agent/package.json +1 -1
  144. package/templates/checkout-agent/agents/checkout-agent/runbook.md +4 -4
  145. package/templates/checkout-agent/agents/checkout-agent/scenarios/beneficiary-not-allowed.transcript.jsonl +1 -1
  146. package/templates/checkout-agent/agents/checkout-agent/scenarios/cart-recomposed.transcript.jsonl +2 -2
  147. package/templates/checkout-agent/agents/checkout-agent/scenarios/cart-replaced.json +2 -2
  148. package/templates/checkout-agent/agents/checkout-agent/scenarios/cart-replaced.transcript.jsonl +2 -2
  149. package/templates/checkout-agent/agents/checkout-agent/scenarios/charge-expired.json +1 -1
  150. package/templates/checkout-agent/agents/checkout-agent/scenarios/charge-expired.transcript.jsonl +2 -2
  151. package/templates/checkout-agent/agents/checkout-agent/scenarios/coupon-unknown.transcript.jsonl +1 -1
  152. package/templates/checkout-agent/agents/checkout-agent/scenarios/escalated-above-threshold.transcript.jsonl +1 -1
  153. package/templates/checkout-agent/agents/checkout-agent/scenarios/happy-path.transcript.jsonl +2 -2
  154. package/templates/checkout-agent/agents/checkout-agent/scenarios/item-unavailable.transcript.jsonl +1 -1
  155. package/templates/checkout-agent/agents/checkout-agent/scenarios/mandate-revoked.transcript.jsonl +3 -3
  156. package/templates/checkout-agent/agents/checkout-agent/scenarios/payment-claimed.json +1 -1
  157. package/templates/checkout-agent/agents/checkout-agent/scenarios/payment-claimed.transcript.jsonl +2 -2
  158. package/templates/checkout-agent/agents/checkout-agent/scenarios/price-injected.transcript.jsonl +1 -1
  159. package/templates/checkout-agent/agents/checkout-agent/scenarios/prompt-injection.transcript.jsonl +1 -1
  160. package/templates/checkout-agent/agents/checkout-agent/src/catalog.ts +7 -7
  161. package/templates/checkout-agent/agents/checkout-agent/src/kit.ts +47 -43
  162. package/templates/checkout-agent/agents/checkout-agent/src/modules/bolepix-receivables.ts +20 -12
  163. package/templates/checkout-agent/agents/checkout-agent/src/modules/nfse-invoice.ts +4 -4
  164. package/templates/checkout-agent/agents/checkout-agent/src/modules/storefront-cart.ts +9 -6
  165. package/templates/checkout-agent/agents/checkout-agent/src/pricing.ts +44 -41
  166. package/templates/checkout-agent/agents/checkout-agent/src/strings.ts +179 -0
  167. package/templates/checkout-agent/agents/checkout-agent/test/check.test.ts +4 -1
  168. package/templates/checkout-agent/agents/checkout-agent/test/fixtures/order-marina.transcript.jsonl +1 -1
  169. package/templates/checkout-agent/agents/checkout-agent/test/fixtures/ordered-marina-awaiting-payer.transcript.jsonl +2 -2
  170. package/templates/checkout-agent/agents/checkout-agent/test/fixtures/tap-falar-agora-marina.transcript.jsonl +1 -1
  171. package/templates/checkout-agent/agents/checkout-agent/test/payable-instrument.test.ts +58 -0
  172. package/templates/checkout-agent/agents/checkout-agent/test/pricing.test.ts +2 -2
  173. package/templates/checkout-agent/agents/checkout-agent/test/rerun-unpaid.test.ts +47 -0
  174. package/templates/checkout-agent/agents/checkout-agent/test/scenario-reach-and-seconds.test.ts +55 -0
  175. package/templates/checkout-agent/agents/checkout-agent/test/whatsapp.test.ts +26 -10
  176. package/templates/checkout-agent/agents/checkout-agent/tools.json +1 -1
  177. package/templates/checkout-agent/packages/agent-core/README.md +21 -2
  178. package/templates/checkout-agent/packages/agent-core/package.json +1 -1
  179. package/templates/checkout-agent/packages/agent-core/src/agent.ts +33 -6
  180. package/templates/checkout-agent/packages/agent-core/src/api/charge-rail.ts +15 -1
  181. package/templates/checkout-agent/packages/agent-core/src/api/rail.ts +11 -5
  182. package/templates/checkout-agent/packages/agent-core/src/api/sandbox-payer.ts +36 -0
  183. package/templates/checkout-agent/packages/agent-core/src/bundle.ts +2 -0
  184. package/templates/checkout-agent/packages/agent-core/src/channels.ts +18 -8
  185. package/templates/checkout-agent/packages/agent-core/src/check.ts +25 -3
  186. package/templates/checkout-agent/packages/agent-core/src/engine.ts +90 -9
  187. package/templates/checkout-agent/packages/agent-core/src/escalate.ts +10 -0
  188. package/templates/checkout-agent/packages/agent-core/src/index.ts +3 -0
  189. package/templates/checkout-agent/packages/agent-core/src/language.ts +52 -0
  190. package/templates/checkout-agent/packages/agent-core/src/locale.ts +88 -0
  191. package/templates/checkout-agent/packages/agent-core/src/manifest.ts +4 -1
  192. package/templates/checkout-agent/packages/agent-core/src/rail.ts +29 -1
  193. package/templates/checkout-agent/packages/agent-core/src/receipt-verification.ts +30 -2
  194. package/templates/checkout-agent/packages/agent-core/src/secrets.ts +53 -8
  195. package/templates/checkout-agent/packages/agent-core/src/state-machine.ts +14 -0
  196. package/templates/checkout-agent/packages/agent-core/src/strings.ts +175 -0
  197. package/templates/checkout-agent/packages/agent-core/src/stubs/charge-rail.ts +15 -2
  198. package/templates/checkout-agent/packages/agent-core/src/stubs/rail.ts +7 -4
  199. package/templates/checkout-agent/packages/agent-core/src/types.ts +15 -2
  200. package/templates/checkout-agent/packages/agent-core/test/actor-on-the-wire.test.ts +144 -0
  201. package/templates/checkout-agent/packages/agent-core/test/attempt-replay.test.ts +2 -2
  202. package/templates/checkout-agent/packages/agent-core/test/engine.test.ts +23 -0
  203. package/templates/checkout-agent/packages/agent-core/test/helpers.ts +1 -1
  204. package/templates/checkout-agent/packages/agent-core/test/language.test.ts +40 -0
  205. package/templates/checkout-agent/packages/agent-core/test/locale.test.ts +137 -0
  206. package/templates/checkout-agent/packages/agent-core/test/mandate-status.test.ts +2 -2
  207. package/templates/checkout-agent/packages/agent-core/test/manifest.test.ts +2 -2
  208. package/templates/checkout-agent/packages/agent-core/test/rail-errors.test.ts +74 -0
  209. package/templates/checkout-agent/packages/agent-core/test/receipt-read-verification.test.ts +32 -0
  210. package/templates/checkout-agent/packages/agent-core/test/receivables.test.ts +49 -0
  211. package/templates/checkout-agent/packages/agent-core/test/recorded-turns.ts +29 -0
  212. package/templates/checkout-agent/packages/agent-core/test/secrets.test.ts +40 -1
  213. package/templates/checkout-agent/packages/agent-runtime/README.md +31 -4
  214. package/templates/checkout-agent/packages/agent-runtime/src/channels/rules.ts +4 -2
  215. package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +11 -5
  216. package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +43 -21
  217. package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +3 -0
  218. package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +8 -12
  219. package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +8 -4
  220. package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +12 -9
  221. package/templates/checkout-agent/packages/agent-runtime/src/cli.ts +30 -4
  222. package/templates/checkout-agent/packages/agent-runtime/src/commands/check.ts +18 -2
  223. package/templates/checkout-agent/packages/agent-runtime/src/commands/decide.ts +13 -4
  224. package/templates/checkout-agent/packages/agent-runtime/src/commands/eval.ts +7 -2
  225. package/templates/checkout-agent/packages/agent-runtime/src/commands/inspect.ts +11 -13
  226. package/templates/checkout-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +32 -24
  227. package/templates/checkout-agent/packages/agent-runtime/src/commands/poll.ts +12 -5
  228. package/templates/checkout-agent/packages/agent-runtime/src/commands/rerun.ts +83 -10
  229. package/templates/checkout-agent/packages/agent-runtime/src/commands/resume.ts +2 -1
  230. package/templates/checkout-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +10 -5
  231. package/templates/checkout-agent/packages/agent-runtime/src/commands/start.ts +48 -17
  232. package/templates/checkout-agent/packages/agent-runtime/src/commands/verify.ts +37 -12
  233. package/templates/checkout-agent/packages/agent-runtime/src/commands/webhook.ts +11 -3
  234. package/templates/checkout-agent/packages/agent-runtime/src/default-kit.ts +52 -22
  235. package/templates/checkout-agent/packages/agent-runtime/src/env.ts +64 -0
  236. package/templates/checkout-agent/packages/agent-runtime/src/index.ts +2 -0
  237. package/templates/checkout-agent/packages/agent-runtime/src/inspect.ts +81 -10
  238. package/templates/checkout-agent/packages/agent-runtime/src/kit.ts +34 -12
  239. package/templates/checkout-agent/packages/agent-runtime/src/outcome.ts +118 -0
  240. package/templates/checkout-agent/packages/agent-runtime/src/poll.ts +7 -7
  241. package/templates/checkout-agent/packages/agent-runtime/src/runs.ts +51 -0
  242. package/templates/checkout-agent/packages/agent-runtime/src/scenarios.ts +55 -8
  243. package/templates/checkout-agent/packages/agent-runtime/src/setup.ts +75 -5
  244. package/templates/checkout-agent/packages/agent-runtime/src/terminal.ts +71 -33
  245. package/templates/checkout-agent/packages/agent-runtime/test/env-names.test.ts +56 -0
  246. package/templates/checkout-agent/packages/agent-runtime/test/inspect-mandate-status.test.ts +80 -0
  247. package/templates/checkout-agent/packages/agent-runtime/test/inspect.test.ts +63 -2
  248. package/templates/checkout-agent/packages/agent-runtime/test/outcome.test.ts +72 -0
  249. package/templates/checkout-agent/packages/agent-runtime/test/poll-payer.test.ts +64 -0
  250. package/templates/checkout-agent/packages/agent-runtime/test/rerun-not-replayed.test.ts +46 -0
  251. package/templates/checkout-agent/packages/agent-runtime/test/transition-line.test.ts +29 -0
  252. package/templates/checkout-agent/packages/agent-runtime/test/verify-cli.test.ts +99 -6
  253. package/templates/checkout-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +8 -0
  254. package/templates/checkout-agent/packages/agent-runtime/test/whatsapp-session.test.ts +77 -0
  255. package/templates/checkout-agent/packages/agent-runtime/test/whatsapp-status-replies.test.ts +27 -1
  256. package/templates/collections-agent/README.md +2 -2
  257. package/templates/collections-agent/agents/collections-agent/.env.example +6 -3
  258. package/templates/collections-agent/agents/collections-agent/README.md +14 -9
  259. package/templates/collections-agent/agents/collections-agent/SYSTEM_PROMPT.md +16 -5
  260. package/templates/collections-agent/agents/collections-agent/agent.yaml +4 -3
  261. package/templates/collections-agent/agents/collections-agent/channels/whatsapp/README.md +21 -4
  262. package/templates/collections-agent/agents/collections-agent/channels/whatsapp/templates.json +49 -5
  263. package/templates/collections-agent/agents/collections-agent/mandate.example.json +1 -1
  264. package/templates/collections-agent/agents/collections-agent/runbook.md +3 -3
  265. package/templates/collections-agent/agents/collections-agent/src/agreements.ts +1 -1
  266. package/templates/collections-agent/agents/collections-agent/src/envelope.ts +15 -13
  267. package/templates/collections-agent/agents/collections-agent/src/kit.ts +38 -35
  268. package/templates/collections-agent/agents/collections-agent/src/modules/bolepix-receivables.ts +16 -8
  269. package/templates/collections-agent/agents/collections-agent/src/strings.ts +91 -0
  270. package/templates/collections-agent/agents/collections-agent/test/ambiguous-charge.test.ts +2 -2
  271. package/templates/collections-agent/agents/collections-agent/test/check.test.ts +4 -1
  272. package/templates/collections-agent/agents/collections-agent/test/cli.test.ts +1 -1
  273. package/templates/collections-agent/agents/collections-agent/test/envelope.test.ts +2 -2
  274. package/templates/collections-agent/agents/collections-agent/test/fixtures/accept-1103.transcript.jsonl +1 -1
  275. package/templates/collections-agent/agents/collections-agent/test/fixtures/tap-emitir-nova-1042.transcript.jsonl +1 -1
  276. package/templates/collections-agent/agents/collections-agent/test/payable-instrument.test.ts +56 -0
  277. package/templates/collections-agent/agents/collections-agent/test/rerun-clock.test.ts +54 -0
  278. package/templates/collections-agent/agents/collections-agent/test/whatsapp-poll.test.ts +69 -2
  279. package/templates/collections-agent/agents/collections-agent/test/whatsapp-status-replies.test.ts +16 -3
  280. package/templates/collections-agent/agents/collections-agent/test/whatsapp.test.ts +16 -4
  281. package/templates/collections-agent/agents/collections-agent/tools.json +2 -2
  282. package/templates/collections-agent/packages/agent-core/README.md +21 -2
  283. package/templates/collections-agent/packages/agent-core/package.json +1 -1
  284. package/templates/collections-agent/packages/agent-core/src/agent.ts +33 -6
  285. package/templates/collections-agent/packages/agent-core/src/api/charge-rail.ts +15 -1
  286. package/templates/collections-agent/packages/agent-core/src/api/rail.ts +11 -5
  287. package/templates/collections-agent/packages/agent-core/src/api/sandbox-payer.ts +36 -0
  288. package/templates/collections-agent/packages/agent-core/src/bundle.ts +2 -0
  289. package/templates/collections-agent/packages/agent-core/src/channels.ts +18 -8
  290. package/templates/collections-agent/packages/agent-core/src/check.ts +25 -3
  291. package/templates/collections-agent/packages/agent-core/src/engine.ts +90 -9
  292. package/templates/collections-agent/packages/agent-core/src/escalate.ts +10 -0
  293. package/templates/collections-agent/packages/agent-core/src/index.ts +3 -0
  294. package/templates/collections-agent/packages/agent-core/src/language.ts +52 -0
  295. package/templates/collections-agent/packages/agent-core/src/locale.ts +88 -0
  296. package/templates/collections-agent/packages/agent-core/src/manifest.ts +4 -1
  297. package/templates/collections-agent/packages/agent-core/src/rail.ts +29 -1
  298. package/templates/collections-agent/packages/agent-core/src/receipt-verification.ts +30 -2
  299. package/templates/collections-agent/packages/agent-core/src/secrets.ts +53 -8
  300. package/templates/collections-agent/packages/agent-core/src/state-machine.ts +14 -0
  301. package/templates/collections-agent/packages/agent-core/src/strings.ts +175 -0
  302. package/templates/collections-agent/packages/agent-core/src/stubs/charge-rail.ts +15 -2
  303. package/templates/collections-agent/packages/agent-core/src/stubs/rail.ts +7 -4
  304. package/templates/collections-agent/packages/agent-core/src/types.ts +15 -2
  305. package/templates/collections-agent/packages/agent-core/test/actor-on-the-wire.test.ts +144 -0
  306. package/templates/collections-agent/packages/agent-core/test/attempt-replay.test.ts +2 -2
  307. package/templates/collections-agent/packages/agent-core/test/engine.test.ts +23 -0
  308. package/templates/collections-agent/packages/agent-core/test/helpers.ts +1 -1
  309. package/templates/collections-agent/packages/agent-core/test/language.test.ts +40 -0
  310. package/templates/collections-agent/packages/agent-core/test/locale.test.ts +137 -0
  311. package/templates/collections-agent/packages/agent-core/test/mandate-status.test.ts +2 -2
  312. package/templates/collections-agent/packages/agent-core/test/manifest.test.ts +2 -2
  313. package/templates/collections-agent/packages/agent-core/test/rail-errors.test.ts +74 -0
  314. package/templates/collections-agent/packages/agent-core/test/receipt-read-verification.test.ts +32 -0
  315. package/templates/collections-agent/packages/agent-core/test/receivables.test.ts +49 -0
  316. package/templates/collections-agent/packages/agent-core/test/recorded-turns.ts +29 -0
  317. package/templates/collections-agent/packages/agent-core/test/secrets.test.ts +40 -1
  318. package/templates/collections-agent/packages/agent-runtime/README.md +31 -4
  319. package/templates/collections-agent/packages/agent-runtime/src/channels/rules.ts +4 -2
  320. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +11 -5
  321. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +43 -21
  322. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +3 -0
  323. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +8 -12
  324. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +8 -4
  325. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +12 -9
  326. package/templates/collections-agent/packages/agent-runtime/src/cli.ts +30 -4
  327. package/templates/collections-agent/packages/agent-runtime/src/commands/check.ts +18 -2
  328. package/templates/collections-agent/packages/agent-runtime/src/commands/decide.ts +13 -4
  329. package/templates/collections-agent/packages/agent-runtime/src/commands/eval.ts +7 -2
  330. package/templates/collections-agent/packages/agent-runtime/src/commands/inspect.ts +11 -13
  331. package/templates/collections-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +32 -24
  332. package/templates/collections-agent/packages/agent-runtime/src/commands/poll.ts +12 -5
  333. package/templates/collections-agent/packages/agent-runtime/src/commands/rerun.ts +83 -10
  334. package/templates/collections-agent/packages/agent-runtime/src/commands/resume.ts +2 -1
  335. package/templates/collections-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +10 -5
  336. package/templates/collections-agent/packages/agent-runtime/src/commands/start.ts +48 -17
  337. package/templates/collections-agent/packages/agent-runtime/src/commands/verify.ts +37 -12
  338. package/templates/collections-agent/packages/agent-runtime/src/commands/webhook.ts +11 -3
  339. package/templates/collections-agent/packages/agent-runtime/src/default-kit.ts +52 -22
  340. package/templates/collections-agent/packages/agent-runtime/src/env.ts +64 -0
  341. package/templates/collections-agent/packages/agent-runtime/src/index.ts +2 -0
  342. package/templates/collections-agent/packages/agent-runtime/src/inspect.ts +81 -10
  343. package/templates/collections-agent/packages/agent-runtime/src/kit.ts +34 -12
  344. package/templates/collections-agent/packages/agent-runtime/src/outcome.ts +118 -0
  345. package/templates/collections-agent/packages/agent-runtime/src/poll.ts +7 -7
  346. package/templates/collections-agent/packages/agent-runtime/src/runs.ts +51 -0
  347. package/templates/collections-agent/packages/agent-runtime/src/scenarios.ts +55 -8
  348. package/templates/collections-agent/packages/agent-runtime/src/setup.ts +75 -5
  349. package/templates/collections-agent/packages/agent-runtime/src/terminal.ts +71 -33
  350. package/templates/collections-agent/packages/agent-runtime/test/env-names.test.ts +56 -0
  351. package/templates/collections-agent/packages/agent-runtime/test/inspect-mandate-status.test.ts +80 -0
  352. package/templates/collections-agent/packages/agent-runtime/test/inspect.test.ts +63 -2
  353. package/templates/collections-agent/packages/agent-runtime/test/outcome.test.ts +72 -0
  354. package/templates/collections-agent/packages/agent-runtime/test/poll-payer.test.ts +64 -0
  355. package/templates/collections-agent/packages/agent-runtime/test/rerun-not-replayed.test.ts +46 -0
  356. package/templates/collections-agent/packages/agent-runtime/test/transition-line.test.ts +29 -0
  357. package/templates/collections-agent/packages/agent-runtime/test/verify-cli.test.ts +99 -6
  358. package/templates/collections-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +8 -0
  359. package/templates/collections-agent/packages/agent-runtime/test/whatsapp-session.test.ts +77 -0
  360. package/templates/collections-agent/packages/agent-runtime/test/whatsapp-status-replies.test.ts +27 -1
  361. package/templates/hello-agent/README.md +2 -2
  362. package/templates/hello-agent/agents/hello-agent/README.md +6 -0
  363. package/templates/hello-agent/agents/hello-agent/SYSTEM_PROMPT.md +27 -13
  364. package/templates/hello-agent/agents/hello-agent/agent.yaml +2 -1
  365. package/templates/hello-agent/agents/hello-agent/evals/adversarial/exfiltration.transcript.jsonl +1 -1
  366. package/templates/hello-agent/agents/hello-agent/evals/adversarial/prompt-injection.transcript.jsonl +1 -1
  367. package/templates/hello-agent/agents/hello-agent/mandate.example.json +1 -1
  368. package/templates/hello-agent/agents/hello-agent/scenarios/happy-path.json +1 -1
  369. package/templates/hello-agent/agents/hello-agent/scenarios/happy-path.transcript.jsonl +1 -1
  370. package/templates/hello-agent/agents/hello-agent/scenarios/prompt-injection.json +1 -1
  371. package/templates/hello-agent/agents/hello-agent/scenarios/prompt-injection.transcript.jsonl +1 -1
  372. package/templates/hello-agent/agents/hello-agent/src/bills.ts +9 -5
  373. package/templates/hello-agent/agents/hello-agent/src/kit.ts +4 -1
  374. package/templates/hello-agent/agents/hello-agent/tools.json +1 -1
  375. package/templates/hello-agent/packages/agent-core/README.md +21 -2
  376. package/templates/hello-agent/packages/agent-core/package.json +1 -1
  377. package/templates/hello-agent/packages/agent-core/src/agent.ts +33 -6
  378. package/templates/hello-agent/packages/agent-core/src/api/charge-rail.ts +15 -1
  379. package/templates/hello-agent/packages/agent-core/src/api/rail.ts +11 -5
  380. package/templates/hello-agent/packages/agent-core/src/api/sandbox-payer.ts +36 -0
  381. package/templates/hello-agent/packages/agent-core/src/bundle.ts +2 -0
  382. package/templates/hello-agent/packages/agent-core/src/channels.ts +18 -8
  383. package/templates/hello-agent/packages/agent-core/src/check.ts +25 -3
  384. package/templates/hello-agent/packages/agent-core/src/engine.ts +90 -9
  385. package/templates/hello-agent/packages/agent-core/src/escalate.ts +10 -0
  386. package/templates/hello-agent/packages/agent-core/src/index.ts +3 -0
  387. package/templates/hello-agent/packages/agent-core/src/language.ts +52 -0
  388. package/templates/hello-agent/packages/agent-core/src/locale.ts +88 -0
  389. package/templates/hello-agent/packages/agent-core/src/manifest.ts +4 -1
  390. package/templates/hello-agent/packages/agent-core/src/rail.ts +29 -1
  391. package/templates/hello-agent/packages/agent-core/src/receipt-verification.ts +30 -2
  392. package/templates/hello-agent/packages/agent-core/src/secrets.ts +53 -8
  393. package/templates/hello-agent/packages/agent-core/src/state-machine.ts +14 -0
  394. package/templates/hello-agent/packages/agent-core/src/strings.ts +175 -0
  395. package/templates/hello-agent/packages/agent-core/src/stubs/charge-rail.ts +15 -2
  396. package/templates/hello-agent/packages/agent-core/src/stubs/rail.ts +7 -4
  397. package/templates/hello-agent/packages/agent-core/src/types.ts +15 -2
  398. package/templates/hello-agent/packages/agent-core/test/actor-on-the-wire.test.ts +144 -0
  399. package/templates/hello-agent/packages/agent-core/test/attempt-replay.test.ts +2 -2
  400. package/templates/hello-agent/packages/agent-core/test/engine.test.ts +23 -0
  401. package/templates/hello-agent/packages/agent-core/test/helpers.ts +1 -1
  402. package/templates/hello-agent/packages/agent-core/test/language.test.ts +40 -0
  403. package/templates/hello-agent/packages/agent-core/test/locale.test.ts +137 -0
  404. package/templates/hello-agent/packages/agent-core/test/mandate-status.test.ts +2 -2
  405. package/templates/hello-agent/packages/agent-core/test/manifest.test.ts +2 -2
  406. package/templates/hello-agent/packages/agent-core/test/rail-errors.test.ts +74 -0
  407. package/templates/hello-agent/packages/agent-core/test/receipt-read-verification.test.ts +32 -0
  408. package/templates/hello-agent/packages/agent-core/test/receivables.test.ts +49 -0
  409. package/templates/hello-agent/packages/agent-core/test/recorded-turns.ts +29 -0
  410. package/templates/hello-agent/packages/agent-core/test/secrets.test.ts +40 -1
  411. package/templates/hello-agent/packages/agent-runtime/README.md +31 -4
  412. package/templates/hello-agent/packages/agent-runtime/src/channels/rules.ts +4 -2
  413. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +11 -5
  414. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +43 -21
  415. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +3 -0
  416. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +8 -12
  417. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +8 -4
  418. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +12 -9
  419. package/templates/hello-agent/packages/agent-runtime/src/cli.ts +30 -4
  420. package/templates/hello-agent/packages/agent-runtime/src/commands/check.ts +18 -2
  421. package/templates/hello-agent/packages/agent-runtime/src/commands/decide.ts +13 -4
  422. package/templates/hello-agent/packages/agent-runtime/src/commands/eval.ts +7 -2
  423. package/templates/hello-agent/packages/agent-runtime/src/commands/inspect.ts +11 -13
  424. package/templates/hello-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +32 -24
  425. package/templates/hello-agent/packages/agent-runtime/src/commands/poll.ts +12 -5
  426. package/templates/hello-agent/packages/agent-runtime/src/commands/rerun.ts +83 -10
  427. package/templates/hello-agent/packages/agent-runtime/src/commands/resume.ts +2 -1
  428. package/templates/hello-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +10 -5
  429. package/templates/hello-agent/packages/agent-runtime/src/commands/start.ts +48 -17
  430. package/templates/hello-agent/packages/agent-runtime/src/commands/verify.ts +37 -12
  431. package/templates/hello-agent/packages/agent-runtime/src/commands/webhook.ts +11 -3
  432. package/templates/hello-agent/packages/agent-runtime/src/default-kit.ts +52 -22
  433. package/templates/hello-agent/packages/agent-runtime/src/env.ts +64 -0
  434. package/templates/hello-agent/packages/agent-runtime/src/index.ts +2 -0
  435. package/templates/hello-agent/packages/agent-runtime/src/inspect.ts +81 -10
  436. package/templates/hello-agent/packages/agent-runtime/src/kit.ts +34 -12
  437. package/templates/hello-agent/packages/agent-runtime/src/outcome.ts +118 -0
  438. package/templates/hello-agent/packages/agent-runtime/src/poll.ts +7 -7
  439. package/templates/hello-agent/packages/agent-runtime/src/runs.ts +51 -0
  440. package/templates/hello-agent/packages/agent-runtime/src/scenarios.ts +55 -8
  441. package/templates/hello-agent/packages/agent-runtime/src/setup.ts +75 -5
  442. package/templates/hello-agent/packages/agent-runtime/src/terminal.ts +71 -33
  443. package/templates/hello-agent/packages/agent-runtime/test/env-names.test.ts +56 -0
  444. package/templates/hello-agent/packages/agent-runtime/test/inspect-mandate-status.test.ts +80 -0
  445. package/templates/hello-agent/packages/agent-runtime/test/inspect.test.ts +63 -2
  446. package/templates/hello-agent/packages/agent-runtime/test/outcome.test.ts +72 -0
  447. package/templates/hello-agent/packages/agent-runtime/test/poll-payer.test.ts +64 -0
  448. package/templates/hello-agent/packages/agent-runtime/test/rerun-not-replayed.test.ts +46 -0
  449. package/templates/hello-agent/packages/agent-runtime/test/transition-line.test.ts +29 -0
  450. package/templates/hello-agent/packages/agent-runtime/test/verify-cli.test.ts +99 -6
  451. package/templates/hello-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +8 -0
  452. package/templates/hello-agent/packages/agent-runtime/test/whatsapp-session.test.ts +77 -0
  453. package/templates/hello-agent/packages/agent-runtime/test/whatsapp-status-replies.test.ts +27 -1
  454. package/templates/kits.lock.json +12 -12
  455. package/templates/supplier-payments-agent/README.md +2 -2
  456. package/templates/supplier-payments-agent/agents/supplier-payments-agent/.env.example +2 -2
  457. package/templates/supplier-payments-agent/agents/supplier-payments-agent/README.md +12 -7
  458. package/templates/supplier-payments-agent/agents/supplier-payments-agent/SYSTEM_PROMPT.md +14 -3
  459. package/templates/supplier-payments-agent/agents/supplier-payments-agent/agent.yaml +2 -1
  460. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/exfiltration.transcript.jsonl +1 -1
  461. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/false-authority.transcript.jsonl +1 -1
  462. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/prompt-injection.transcript.jsonl +1 -1
  463. package/templates/supplier-payments-agent/agents/supplier-payments-agent/mandate.example.json +3 -3
  464. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/beneficiary-not-allowed.transcript.jsonl +1 -1
  465. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/cap-exceeded.transcript.jsonl +1 -1
  466. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/escalated-above-threshold.transcript.jsonl +5 -5
  467. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/happy-path.transcript.jsonl +1 -1
  468. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/mandate-revoked.transcript.jsonl +5 -5
  469. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/partial-batch-failure.json +1 -1
  470. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/partial-batch-failure.transcript.jsonl +1 -1
  471. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/prompt-injection.transcript.jsonl +1 -1
  472. package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/kit.ts +37 -26
  473. package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/modules/batch-payout.ts +41 -14
  474. package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/modules/pix-out.ts +12 -3
  475. package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/payables.ts +8 -8
  476. package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/batch.test.ts +75 -10
  477. package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/locale.test.ts +101 -0
  478. package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/run-outcome.test.ts +127 -0
  479. package/templates/supplier-payments-agent/agents/supplier-payments-agent/tools.json +1 -1
  480. package/templates/supplier-payments-agent/packages/agent-core/README.md +21 -2
  481. package/templates/supplier-payments-agent/packages/agent-core/package.json +1 -1
  482. package/templates/supplier-payments-agent/packages/agent-core/src/agent.ts +33 -6
  483. package/templates/supplier-payments-agent/packages/agent-core/src/api/charge-rail.ts +15 -1
  484. package/templates/supplier-payments-agent/packages/agent-core/src/api/rail.ts +11 -5
  485. package/templates/supplier-payments-agent/packages/agent-core/src/api/sandbox-payer.ts +36 -0
  486. package/templates/supplier-payments-agent/packages/agent-core/src/bundle.ts +2 -0
  487. package/templates/supplier-payments-agent/packages/agent-core/src/channels.ts +18 -8
  488. package/templates/supplier-payments-agent/packages/agent-core/src/check.ts +25 -3
  489. package/templates/supplier-payments-agent/packages/agent-core/src/engine.ts +90 -9
  490. package/templates/supplier-payments-agent/packages/agent-core/src/escalate.ts +10 -0
  491. package/templates/supplier-payments-agent/packages/agent-core/src/index.ts +3 -0
  492. package/templates/supplier-payments-agent/packages/agent-core/src/language.ts +52 -0
  493. package/templates/supplier-payments-agent/packages/agent-core/src/locale.ts +88 -0
  494. package/templates/supplier-payments-agent/packages/agent-core/src/manifest.ts +4 -1
  495. package/templates/supplier-payments-agent/packages/agent-core/src/rail.ts +29 -1
  496. package/templates/supplier-payments-agent/packages/agent-core/src/receipt-verification.ts +30 -2
  497. package/templates/supplier-payments-agent/packages/agent-core/src/secrets.ts +53 -8
  498. package/templates/supplier-payments-agent/packages/agent-core/src/state-machine.ts +14 -0
  499. package/templates/supplier-payments-agent/packages/agent-core/src/strings.ts +175 -0
  500. package/templates/supplier-payments-agent/packages/agent-core/src/stubs/charge-rail.ts +15 -2
  501. package/templates/supplier-payments-agent/packages/agent-core/src/stubs/rail.ts +7 -4
  502. package/templates/supplier-payments-agent/packages/agent-core/src/types.ts +15 -2
  503. package/templates/supplier-payments-agent/packages/agent-core/test/actor-on-the-wire.test.ts +144 -0
  504. package/templates/supplier-payments-agent/packages/agent-core/test/attempt-replay.test.ts +2 -2
  505. package/templates/supplier-payments-agent/packages/agent-core/test/engine.test.ts +23 -0
  506. package/templates/supplier-payments-agent/packages/agent-core/test/helpers.ts +1 -1
  507. package/templates/supplier-payments-agent/packages/agent-core/test/language.test.ts +40 -0
  508. package/templates/supplier-payments-agent/packages/agent-core/test/locale.test.ts +137 -0
  509. package/templates/supplier-payments-agent/packages/agent-core/test/mandate-status.test.ts +2 -2
  510. package/templates/supplier-payments-agent/packages/agent-core/test/manifest.test.ts +2 -2
  511. package/templates/supplier-payments-agent/packages/agent-core/test/rail-errors.test.ts +74 -0
  512. package/templates/supplier-payments-agent/packages/agent-core/test/receipt-read-verification.test.ts +32 -0
  513. package/templates/supplier-payments-agent/packages/agent-core/test/receivables.test.ts +49 -0
  514. package/templates/supplier-payments-agent/packages/agent-core/test/recorded-turns.ts +29 -0
  515. package/templates/supplier-payments-agent/packages/agent-core/test/secrets.test.ts +40 -1
  516. package/templates/supplier-payments-agent/packages/agent-runtime/README.md +31 -4
  517. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/rules.ts +4 -2
  518. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +11 -5
  519. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +43 -21
  520. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +3 -0
  521. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +8 -12
  522. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +8 -4
  523. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +12 -9
  524. package/templates/supplier-payments-agent/packages/agent-runtime/src/cli.ts +30 -4
  525. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/check.ts +18 -2
  526. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/decide.ts +13 -4
  527. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/eval.ts +7 -2
  528. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/inspect.ts +11 -13
  529. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +32 -24
  530. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/poll.ts +12 -5
  531. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/rerun.ts +83 -10
  532. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/resume.ts +2 -1
  533. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +10 -5
  534. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/start.ts +48 -17
  535. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/verify.ts +37 -12
  536. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/webhook.ts +11 -3
  537. package/templates/supplier-payments-agent/packages/agent-runtime/src/default-kit.ts +52 -22
  538. package/templates/supplier-payments-agent/packages/agent-runtime/src/env.ts +64 -0
  539. package/templates/supplier-payments-agent/packages/agent-runtime/src/index.ts +2 -0
  540. package/templates/supplier-payments-agent/packages/agent-runtime/src/inspect.ts +81 -10
  541. package/templates/supplier-payments-agent/packages/agent-runtime/src/kit.ts +34 -12
  542. package/templates/supplier-payments-agent/packages/agent-runtime/src/outcome.ts +118 -0
  543. package/templates/supplier-payments-agent/packages/agent-runtime/src/poll.ts +7 -7
  544. package/templates/supplier-payments-agent/packages/agent-runtime/src/runs.ts +51 -0
  545. package/templates/supplier-payments-agent/packages/agent-runtime/src/scenarios.ts +55 -8
  546. package/templates/supplier-payments-agent/packages/agent-runtime/src/setup.ts +75 -5
  547. package/templates/supplier-payments-agent/packages/agent-runtime/src/terminal.ts +71 -33
  548. package/templates/supplier-payments-agent/packages/agent-runtime/test/env-names.test.ts +56 -0
  549. package/templates/supplier-payments-agent/packages/agent-runtime/test/inspect-mandate-status.test.ts +80 -0
  550. package/templates/supplier-payments-agent/packages/agent-runtime/test/inspect.test.ts +63 -2
  551. package/templates/supplier-payments-agent/packages/agent-runtime/test/outcome.test.ts +72 -0
  552. package/templates/supplier-payments-agent/packages/agent-runtime/test/poll-payer.test.ts +64 -0
  553. package/templates/supplier-payments-agent/packages/agent-runtime/test/rerun-not-replayed.test.ts +46 -0
  554. package/templates/supplier-payments-agent/packages/agent-runtime/test/transition-line.test.ts +29 -0
  555. package/templates/supplier-payments-agent/packages/agent-runtime/test/verify-cli.test.ts +99 -6
  556. package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +8 -0
  557. package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-session.test.ts +77 -0
  558. package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-status-replies.test.ts +27 -1
@@ -6,8 +6,9 @@
6
6
  */
7
7
  import { relative } from "node:path";
8
8
  import { stderr, stdout } from "node:process";
9
+ import { railErrorOf } from "@codespar/agent-core";
9
10
  import type { Agent } from "../agent.js";
10
- import { setup } from "../setup.js";
11
+ import { localeFlag, setup } from "../setup.js";
11
12
  import { handleExecution } from "../terminal.js";
12
13
 
13
14
  export async function decide(agent: Agent, decision: "approve" | "deny", argv: string[]): Promise<number> {
@@ -16,13 +17,20 @@ export async function decide(agent: Agent, decision: "approve" | "deny", argv: s
16
17
  const user = argv.includes("--user") ? argv[argv.indexOf("--user") + 1] : undefined;
17
18
  const wait = awaitsPayer && argv.includes("--wait") ? Number(argv[argv.indexOf("--wait") + 1]) : undefined;
18
19
  const simulatePayer = awaitsPayer && argv.includes("--simulate-payer");
19
- const executionId = argv.find((a, i) => !a.startsWith("--") && argv[i - 1] !== "--user" && (!awaitsPayer || argv[i - 1] !== "--wait"));
20
+ const executionId = argv.find((a, i) => !a.startsWith("--") && argv[i - 1] !== "--user" && argv[i - 1] !== "--locale" && (!awaitsPayer || argv[i - 1] !== "--wait"));
20
21
  const say = (l: string) => stderr.write(l + "\n");
22
+ let locale;
23
+ try {
24
+ locale = localeFlag(argv);
25
+ } catch (err) {
26
+ say(err instanceof Error ? err.message : String(err));
27
+ return 2;
28
+ }
21
29
  if (!executionId) {
22
- say(`usage: npm run ${decision} <execution-id> [--user <id>]${awaitsPayer ? " [--wait <seconds>] [--simulate-payer]" : ""} [--json]`);
30
+ say(`usage: npm run ${decision} <execution-id> [--user <id>]${awaitsPayer ? " [--wait <seconds>] [--simulate-payer]" : ""} [--locale pt-BR|en] [--json]`);
23
31
  return 2;
24
32
  }
25
- const s = setup(agent, { say, runId: `run_${decision}_${Date.now().toString(36)}` });
33
+ const s = setup(agent, { say, runId: `run_${decision}_${Date.now().toString(36)}`, locale });
26
34
  try {
27
35
  const execution = s.engine.get(executionId);
28
36
  if (!execution) {
@@ -48,6 +56,7 @@ export async function decide(agent: Agent, decision: "approve" | "deny", argv: s
48
56
  execution_id: final.id,
49
57
  state: final.state,
50
58
  reason: final.reason ?? null,
59
+ rail_error: railErrorOf(final),
51
60
  approval_id: final.approval_id ?? null,
52
61
  ...(awaitsPayer ? { charge_ids: final.outcomes.map((o) => o.transaction_id ?? null) } : {}),
53
62
  receipt_ids: final.outcomes.filter((o) => o.receipt_id).map((o) => o.receipt_id),
@@ -3,22 +3,27 @@
3
3
  * section 9 plus every scenario of section 12 in every mode it declares. Runs
4
4
  * on the replay provider and the stub rail, with no model and no network. A
5
5
  * regression blocks merge.
6
+ *
7
+ * Its proof bundles go to `runs/eval/`, apart from the runs a person made
8
+ * (`runs.ts`); `inspect` and `rerun` find them by run id all the same.
6
9
  */
7
10
  import { stderr, stdout } from "node:process";
8
11
  import type { Agent } from "../agent.js";
9
12
  import { listAdversarialCases, loadAdversarialCase, runAdversarialCase, type AdversarialResult } from "../adversarial.js";
10
13
  import { checkScenario, listScenarios, loadScenario, runScenario, type ScenarioCheck } from "../scenarios.js";
14
+ import { evalRunsDir } from "../runs.js";
11
15
 
12
16
  export async function runEval(agent: Agent, argv: string[]): Promise<number> {
13
17
  const json = argv.includes("--json");
14
18
  const only = argv.includes("--case") ? argv[argv.indexOf("--case") + 1] : undefined;
15
19
  const say = (l: string) => stderr.write(l + "\n");
16
20
  const awaitsPayer = agent.settlement === "await-payer";
21
+ const runsDir = evalRunsDir(agent);
17
22
 
18
23
  const adversarial = [];
19
24
  for (const name of listAdversarialCases(agent)) {
20
25
  if (only && only !== name) continue;
21
- const result = await runAdversarialCase(agent, loadAdversarialCase(agent, name));
26
+ const result = await runAdversarialCase(agent, loadAdversarialCase(agent, name), { runsDir });
22
27
  adversarial.push(result);
23
28
  say(agent.kit.evalAdversarialLine?.(result) ?? adversarialLine(result));
24
29
  }
@@ -29,7 +34,7 @@ export async function runEval(agent: Agent, argv: string[]): Promise<number> {
29
34
  const scenario = loadScenario(agent, name);
30
35
  if (!scenario.rails.includes("stub")) continue;
31
36
  for (const mode of scenario.modes) {
32
- const check = checkScenario(scenario, await runScenario(agent, scenario, { mode, rail: "stub" }));
37
+ const check = checkScenario(scenario, await runScenario(agent, scenario, { mode, rail: "stub", runsDir }));
33
38
  scenarios.push({
34
39
  name,
35
40
  mode,
@@ -7,12 +7,12 @@
7
7
  * It reads the bundle and nothing else, so it works on any agent's run, and
8
8
  * on a folder copied off the machine that produced it.
9
9
  */
10
- import { existsSync, readdirSync, writeFileSync } from "node:fs";
10
+ import { existsSync, writeFileSync } from "node:fs";
11
11
  import { resolve } from "node:path";
12
12
  import { stderr, stdout } from "node:process";
13
- import { ProofBundle } from "@codespar/agent-core";
14
13
  import type { Agent } from "../agent.js";
15
14
  import { runsDir } from "../setup.js";
15
+ import { listRuns, openRun } from "../runs.js";
16
16
  import { assembleTimeline, renderHtml, renderText } from "../inspect.js";
17
17
 
18
18
  const USAGE = "usage: npm run inspect <run-id> [--json] [--html <file>]";
@@ -50,15 +50,15 @@ export function inspect(agent: Agent, argv: string[]): number {
50
50
  const runs = runsDir(agent);
51
51
  if (!runId) {
52
52
  say(USAGE);
53
- say(available(runs));
53
+ say(available(agent));
54
54
  return 2;
55
55
  }
56
56
 
57
57
  // An unknown run id is a refusal a person can act on, never a stack trace.
58
- const bundle = ProofBundle.open(runs, runId);
58
+ const bundle = openRun(agent, runId)?.bundle;
59
59
  if (!bundle) {
60
60
  say(`no proof bundle for run ${runId}: nothing at ${resolve(runs, runId)}`);
61
- say(available(runs));
61
+ say(available(agent));
62
62
  return 1;
63
63
  }
64
64
 
@@ -87,14 +87,12 @@ export function inspect(agent: Agent, argv: string[]): number {
87
87
  }
88
88
 
89
89
  /** What the person can inspect instead. Bounded: a long-lived agent has many runs and this is an error message, not a listing command. */
90
- function available(runs: string): string {
90
+ function available(agent: Agent): string {
91
+ const { dir: runs, ids, evalDir, evalCount } = listRuns(agent);
92
+ // The eval suite's runs are counted, not listed: they are found by id like any other, and there are dozens per pass.
93
+ const evalNote = evalCount > 0 ? `\n${evalCount} more from \`npm run eval\` in ${evalDir}, inspected by run id the same way` : "";
91
94
  if (!existsSync(runs)) return `no runs yet: ${runs} does not exist. Run the agent once, then inspect the run id it printed.`;
92
- const ids = readdirSync(runs, { withFileTypes: true })
93
- .filter((e) => e.isDirectory())
94
- .map((e) => e.name)
95
- .sort()
96
- .reverse();
97
- if (!ids.length) return `no runs yet in ${runs}. Run the agent once, then inspect the run id it printed.`;
95
+ if (!ids.length) return `no runs yet in ${runs}. Run the agent once, then inspect the run id it printed.${evalNote}`;
98
96
  const shown = ids.slice(0, 10);
99
- return `runs in ${runs}${ids.length > shown.length ? ` (newest ${shown.length} of ${ids.length})` : ""}:\n${shown.map((id) => ` ${id}`).join("\n")}`;
97
+ return `runs in ${runs}${ids.length > shown.length ? ` (newest ${shown.length} of ${ids.length})` : ""}:\n${shown.map((id) => ` ${id}`).join("\n")}${evalNote}`;
100
98
  }
@@ -29,7 +29,7 @@
29
29
  */
30
30
  import { stdout } from "node:process";
31
31
  import { relative } from "node:path";
32
- import { ProofBundle, type ChargeInstrument, type Execution } from "@codespar/agent-core";
32
+ import { ProofBundle, isLocale, type ChargeInstrument, type Execution, type Locale } from "@codespar/agent-core";
33
33
  import type { Agent } from "../agent.js";
34
34
  import { runsDir, type Setup } from "../setup.js";
35
35
  import { followUp, waitForPayer } from "../terminal.js";
@@ -53,6 +53,8 @@ export interface PollWhatsAppOptions {
53
53
  payer?: "pays" | "expires" | "never" | undefined;
54
54
  now: () => Date;
55
55
  say: (line: string) => void;
56
+ /** `--locale`, when given. The conversation's recorded locale wins, and a flag that disagrees with it is refused. */
57
+ locale?: Locale | undefined;
56
58
  }
57
59
 
58
60
  /** How the outcome reached the person, or why it did not. */
@@ -97,14 +99,14 @@ export async function pollWhatsApp(options: PollWhatsAppOptions): Promise<number
97
99
  const mine = subject ? open.filter((e) => e.items.length > 0 && e.items.every((i) => i.alias === subject || i.payee === subject)) : [];
98
100
 
99
101
  if (!subject && open.length) {
100
- say(`a conversa ${script.name} nao declara subject: nao da para dizer quais execucoes sao dela, e mandar o desfecho de outra pessoa nesta conversa e exatamente o que a regra de sigilo proibe`);
102
+ say(s.coreStrings.pollNoSubject(script.name));
101
103
  return 2;
102
104
  }
103
105
  if (!mine.length) {
104
106
  // A clean no-op: nothing is waiting, so nothing is opened. The emulator is
105
107
  // not even contacted, which is the point — a poll with no work does no work.
106
108
  if (options.json) stdout.write(JSON.stringify({ polled: [], conversation: script.name, channel: null }) + "\n");
107
- else say(`nada aguardando pagador em ${script.name}`);
109
+ else say(s.coreStrings.pollNothingWaiting(script.name));
108
110
  return 0;
109
111
  }
110
112
 
@@ -114,10 +116,22 @@ export async function pollWhatsApp(options: PollWhatsAppOptions): Promise<number
114
116
  // one conversation stays one record instead of ending in a second folder.
115
117
  const { bundle, session, lines: priorLines } = conversationRecord(agent, mine);
116
118
  if (!bundle) {
117
- say(`nenhum bundle encontrado para ${mine.map((e) => e.run_id).join(", ")}: a conversa nao pode ser retomada sem o registro dela`);
119
+ say(s.coreStrings.pollNoBundle(mine.map((e) => e.run_id).join(", ")));
118
120
  return 1;
119
121
  }
120
122
 
123
+ // The conversation keeps the locale it was recorded in: the outcome is told
124
+ // in the language the person was spoken to in, template and all. A bundle
125
+ // written before the field existed records none, and the run's own stands.
126
+ const recorded = bundle.readMeta()?.["locale"];
127
+ if (isLocale(recorded)) {
128
+ if (options.locale !== undefined && options.locale !== recorded) {
129
+ say(s.coreStrings.pollLocaleConflict(script.name, recorded, options.locale));
130
+ return 2;
131
+ }
132
+ s.locale = recorded;
133
+ }
134
+
121
135
  const built = buildWhatsApp({
122
136
  agent,
123
137
  setup: s,
@@ -159,11 +173,7 @@ export async function pollWhatsApp(options: PollWhatsAppOptions): Promise<number
159
173
  const results: Polled[] = [];
160
174
  try {
161
175
  const remaining = channel.sessionRemainingSeconds;
162
- say(
163
- `${s.manifest.manifest.name} ${s.manifest.manifest.version} — poll no canal whatsapp (${channel.backend}) — conversa ${script.name} — janela de 24h ${
164
- channel.sessionOpen ? `ABERTA (${Math.round(remaining / 60)} min restantes): mensagem livre` : "FECHADA: so template aprovado"
165
- }`,
166
- );
176
+ say(s.coreStrings.pollBanner(s.manifest.manifest.name, s.manifest.manifest.version, channel.backend, script.name, channel.sessionOpen ? Math.round(remaining / 60) : undefined));
167
177
  for (const execution of mine) {
168
178
  const sessionOpen = channel.sessionOpen;
169
179
  const result = await waitForPayer(execution.id, {
@@ -188,11 +198,8 @@ export async function pollWhatsApp(options: PollWhatsAppOptions): Promise<number
188
198
  session_open: sessionOpen,
189
199
  delivery,
190
200
  });
191
- say(
192
- `${closed.id}: ${closed.state}${closed.reason ? ` (${closed.reason})` : ""} apos ${result.rounds} consulta(s), ${result.seconds}s — ${
193
- delivery.told ? `avisado por ${delivery.carrier === "template" ? `template ${delivery.template}${delivery.fallback ? " (reserva: o kit nao tem copia para este desfecho)" : ""}` : "mensagem livre"}` : `nao avisado (${delivery.reason}${delivery.detail ? `: ${delivery.detail}` : ""})`
194
- }`,
195
- );
201
+ const told = delivery.told ? (delivery.carrier === "template" ? s.coreStrings.pollToldByTemplate(delivery.template ?? "?", delivery.fallback === true) : s.coreStrings.pollToldByText) : s.coreStrings.pollNotTold(delivery.reason, delivery.detail);
202
+ say(`${closed.id}: ${closed.state}${closed.reason ? ` (${closed.reason})` : ""}${s.coreStrings.afterLooks(result.rounds, result.seconds, false)} — ${told}`);
196
203
  }
197
204
  } finally {
198
205
  await channel.close();
@@ -213,7 +220,7 @@ export async function pollWhatsApp(options: PollWhatsAppOptions): Promise<number
213
220
  };
214
221
 
215
222
  if (options.json) stdout.write(JSON.stringify({ polled: results, conversation: script.name, channel: channelSummary }) + "\n");
216
- else say(`conversa em ${channelSummary.log} — ${channelSummary.messages_out} enviada(s)${refused.length ? `, ${refused.length} recusada(s)` : ""}`);
223
+ else say(s.coreStrings.waConversationSummary(channelSummary.log, undefined, channelSummary.messages_out, refused.length));
217
224
 
218
225
  if (results.some((r) => r.timed_out)) return 3;
219
226
  // A cycle that closed and a person who was not told is a failure worth an
@@ -267,7 +274,7 @@ function conversationRecord(agent: Agent, executions: readonly Execution[]): { b
267
274
  * it either.
268
275
  */
269
276
  async function presentInstrument(channel: WhatsAppChannel, s: Setup, execution: Execution, instalment: number, chargeId: string, instrument: ChargeInstrument): Promise<void> {
270
- for (const body of instrumentBodies(execution, instalment, chargeId, instrument, s.mandate.currency)) await channel.send(body);
277
+ for (const body of instrumentBodies(execution, instalment, chargeId, instrument, s.mandate.currency, s.locale)) await channel.send(body);
271
278
  }
272
279
 
273
280
  /**
@@ -298,7 +305,7 @@ async function tellOutcome(channel: WhatsAppChannel, s: Setup, execution: Execut
298
305
  // The provider's is the one the window is counted on, so the message goes
299
306
  // the way it would have gone had we known: as the template. The cursor is
300
307
  // already this call's, taken by `announceOutcome` above.
301
- if (sent.refused?.rule !== "session_window_closed") return confirmed(channel, sent, deliveryOf(sent, "text"));
308
+ if (sent.refused?.rule !== "session_window_closed") return confirmed(channel, sent, deliveryOf(s, sent, "text"));
302
309
  return tellByTemplate(channel, s, execution, { cursorHeld: true });
303
310
  }
304
311
  return tellByTemplate(channel, s, execution, { cursorHeld: false });
@@ -337,22 +344,23 @@ async function confirmed(channel: WhatsAppChannel, sent: SentMessage, delivery:
337
344
  * defect, reported as one and not papered over by the fallback.
338
345
  */
339
346
  async function tellByTemplate(channel: WhatsAppChannel, s: Setup, execution: Execution, options: { cursorHeld: boolean }): Promise<Delivery> {
340
- const chosen: { template: string; variables: string[]; fallback?: true } | undefined = s.kit.outcomeTemplate?.(execution) ?? fallbackOf(channel);
347
+ const chosen: { template: string; variables: string[]; fallback?: true } | undefined = s.kit.outcomeTemplate?.(execution, s.locale) ?? fallbackOf(channel);
341
348
  if (!chosen) {
342
349
  return {
343
350
  told: false,
344
351
  reason: "no_template_for_outcome",
345
- detail: `a janela de 24h esta fechada e o agente nao declara template para ${execution.state}${execution.reason ? ` (${execution.reason})` : ""}, nem um template de reserva`,
352
+ detail: s.coreStrings.pollNoTemplateForOutcome(`${execution.state}${execution.reason ? ` (${execution.reason})` : ""}`),
346
353
  };
347
354
  }
355
+ // The copy in the conversation's language: an English conversation is never sent the pt_BR template.
348
356
  const declared = channel.declaredTemplate(chosen.template);
349
357
  if (!declared) {
350
- return { told: false, reason: "no_template_for_outcome", detail: `o kit pediu o template ${chosen.template}, que channels/whatsapp/templates.json nao declara` };
358
+ return { told: false, reason: "no_template_for_outcome", detail: s.coreStrings.pollTemplateNotDeclared(`${chosen.template} (${channel.language})`) };
351
359
  }
352
360
  if (!options.cursorHeld && !s.engine.markTold(execution.id, execution.state)) return toldBefore(s, execution);
353
361
  const sent = await channel.send({ kind: "template", template: declared.name, language: declared.language, variables: chosen.variables, about: aboutOf(execution) });
354
- s.engine.note("message.debtor", execution.id, { state: execution.state, reason: execution.reason ?? null, template: declared.name, variables: chosen.variables, ...(chosen.fallback ? { fallback: true } : {}) });
355
- return confirmed(channel, sent, deliveryOf(sent, "template", declared.name, chosen.fallback));
362
+ s.engine.note("message.debtor", execution.id, { state: execution.state, reason: execution.reason ?? null, template: declared.name, language: declared.language, variables: chosen.variables, ...(chosen.fallback ? { fallback: true } : {}) });
363
+ return confirmed(channel, sent, deliveryOf(s, sent, "template", declared.name, chosen.fallback));
356
364
  }
357
365
 
358
366
  function fallbackOf(channel: WhatsAppChannel): { template: string; variables: string[]; fallback: true } | undefined {
@@ -360,8 +368,8 @@ function fallbackOf(channel: WhatsAppChannel): { template: string; variables: st
360
368
  return name ? { template: name, variables: [], fallback: true } : undefined;
361
369
  }
362
370
 
363
- function deliveryOf(sent: SentMessage, carrier: "text" | "template", template?: string, fallback?: boolean): Delivery {
371
+ function deliveryOf(s: Setup, sent: SentMessage, carrier: "text" | "template", template?: string, fallback?: boolean): Delivery {
364
372
  if (sent.refused) return { told: false, reason: "refused", detail: `${sent.refused.rule}: ${sent.refused.detail}` };
365
- if (sent.state === "failed") return { told: false, reason: "refused", detail: "o provedor nao aceitou a mensagem" };
373
+ if (sent.state === "failed") return { told: false, reason: "refused", detail: s.coreStrings.pollProviderRefused };
366
374
  return { told: true, carrier, ...(template ? { template } : {}), ...(fallback ? { fallback: true as const } : {}) };
367
375
  }
@@ -15,9 +15,9 @@
15
15
  */
16
16
  import { stderr, stdout } from "node:process";
17
17
  import { join } from "node:path";
18
- import { loadManifest, resolveFixedClock, type ChannelName } from "@codespar/agent-core";
18
+ import { loadManifest, parseLocale, resolveFixedClock, type ChannelName, type Locale } from "@codespar/agent-core";
19
19
  import type { Agent } from "../agent.js";
20
- import { setup } from "../setup.js";
20
+ import { inLocaleOf, setup } from "../setup.js";
21
21
  import { announceOutcome, followUp, waitForPayer } from "../terminal.js";
22
22
  import { pollWhatsApp } from "./poll-whatsapp.js";
23
23
  import type { WhatsAppBackendName } from "../channels/whatsapp/open.js";
@@ -30,6 +30,8 @@ const USAGE = `codespar-agent poll [options]
30
30
  --simulate-payer let the sandbox payer act once the receivable is payable
31
31
  --payer pays|expires|never what the fixture payer does when it acts (stub rail only)
32
32
  --now <ISO 8601> pin the run's clock; env CODESPAR_AGENT_NOW is the same thing
33
+ --locale pt-BR|en the language of this command's lines. An outcome is told in the locale its run recorded,
34
+ and --channel whatsapp refuses a --locale that disagrees with the conversation's
33
35
  --json machine output on stdout, everything else on stderr`;
34
36
 
35
37
  interface Args {
@@ -40,6 +42,7 @@ interface Args {
40
42
  simulatePayer: boolean;
41
43
  payer?: "pays" | "expires" | "never";
42
44
  now?: string;
45
+ locale?: Locale;
43
46
  json: boolean;
44
47
  }
45
48
 
@@ -73,6 +76,7 @@ export function parsePollArgs(argv: string[]): Args {
73
76
  args.payer = v;
74
77
  } else if (a === "--conversation") args.conversation = next();
75
78
  else if (a === "--now") args.now = next();
79
+ else if (a === "--locale") args.locale = parseLocale(next());
76
80
  else throw new Error(`unknown argument ${a}`);
77
81
  }
78
82
  if (args.channel !== "whatsapp" && (args.backend !== undefined || args.conversation !== undefined)) {
@@ -97,7 +101,7 @@ export async function poll(agent: Agent, argv: string[]): Promise<number> {
97
101
  return 2;
98
102
  }
99
103
 
100
- const s = setup(agent, { say, runId: `run_poll_${Date.now().toString(36)}`, ...(now ? { now } : {}) });
104
+ const s = setup(agent, { say, runId: `run_poll_${Date.now().toString(36)}`, ...(now ? { now } : {}), ...(args.locale ? { locale: args.locale } : {}) });
101
105
  // The same flag `start` has, and it means more here: a receivable nobody
102
106
  // paid reaches its due date BETWEEN two runs, never inside one, so "what
103
107
  // happens when it expires" is a question only a poll can be asked.
@@ -115,6 +119,7 @@ export async function poll(agent: Agent, argv: string[]): Promise<number> {
115
119
  ...(args.payer ? { payer: args.payer } : {}),
116
120
  now: now ?? (() => new Date()),
117
121
  say,
122
+ ...(args.locale ? { locale: args.locale } : {}),
118
123
  });
119
124
  }
120
125
  // `behave` only changes the default for receivables the rail has not
@@ -129,8 +134,10 @@ export async function poll(agent: Agent, argv: string[]): Promise<number> {
129
134
  const results = [];
130
135
  for (const open of s.engine.list({ state: "executing" })) {
131
136
  if (open.reason !== "awaiting_settlement") continue;
132
- const r = await waitForPayer(open.id, { setup: s, approver: { id: s.kit.labels.defaultUser, channel: "terminal" }, say, tell, waitSeconds: args.wait, simulatePayer: args.simulatePayer });
133
- announceOutcome(r.execution, s, tell);
137
+ // The payer is told in the locale of the run that issued the charge, which is where they were spoken to.
138
+ const told = inLocaleOf(s, open);
139
+ const r = await waitForPayer(open.id, { setup: told, approver: { id: s.kit.labels.defaultUser, channel: "terminal" }, say, tell, waitSeconds: args.wait, simulatePayer: args.simulatePayer });
140
+ announceOutcome(r.execution, told, tell);
134
141
  if (r.execution.state !== "executing") await s.engine.collectReceipts(r.execution.id);
135
142
  await followUp(r.execution, s, say);
136
143
  results.push({ id: r.execution.id, state: r.execution.state, reason: r.execution.reason ?? null, rounds: r.rounds, seconds: r.seconds, timed_out: r.timed_out });
@@ -8,11 +8,54 @@ import { mkdtempSync } from "node:fs";
8
8
  import { tmpdir } from "node:os";
9
9
  import { join } from "node:path";
10
10
  import { stderr, stdout } from "node:process";
11
- import { ProofBundle, type ApprovalMode, type Execution } from "@codespar/agent-core";
11
+ import { isLocale, type ApprovalMode, type Execution } from "@codespar/agent-core";
12
12
  import type { Agent } from "../agent.js";
13
- import { runsDir, setup } from "../setup.js";
13
+ import { setup } from "../setup.js";
14
+ import { openRun } from "../runs.js";
14
15
  import { handleExecution } from "../terminal.js";
15
16
 
17
+ /**
18
+ * A clock that starts where the original run did and moves a second per
19
+ * read, which is how the scenario and the adversarial runners keep theirs. Its
20
+ * first read is the original's `started_at`.
21
+ */
22
+ function clockFrom(startedAt: Date): () => Date {
23
+ let at = startedAt.getTime() - 1000;
24
+ return () => new Date((at += 1000));
25
+ }
26
+
27
+ const MANDATE_STOPPED: Record<string, string> = {
28
+ mandate_revoked: "a mandate that was revoked",
29
+ mandate_paused: "a mandate that was paused",
30
+ org_paused: "an organization that paused every mandate",
31
+ };
32
+
33
+ /**
34
+ * What the original run met that only the world can do, read off its events.
35
+ * The rerun starts from an active mandate, a rail that answers and a payer
36
+ * that pays; a run that met anything else would be replayed as a different
37
+ * run and reported as one that DIFFERS, with nothing to say why.
38
+ */
39
+ export function notReplayed(events: ReadonlyArray<Record<string, unknown>>): string[] {
40
+ const found = new Set<string>();
41
+ const last = new Map<string, string>();
42
+ const accepted = new Set<string>();
43
+ for (const event of events) {
44
+ const payload = (event["payload"] ?? {}) as { reason?: unknown; status?: unknown; to?: unknown };
45
+ const execution = typeof event["execution_id"] === "string" ? event["execution_id"] : undefined;
46
+ // An own key only: the reason is a string from a recording, and `constructor` is a key of every object.
47
+ const stopped = typeof payload.reason === "string" && Object.hasOwn(MANDATE_STOPPED, payload.reason) ? MANDATE_STOPPED[payload.reason] : undefined;
48
+ if (stopped && (event["type"] === "execution.transition" || event["type"] === "execution.refused_before_draft")) found.add(stopped);
49
+ // The engine writes all three for one uncertain dispatch; any of them is the run saying the rail did not answer.
50
+ if ((event["type"] === "rail.outcome" && payload.status === "uncertain") || event["type"] === "rail.uncertain" || event["type"] === "execution.uncertain") found.add("an uncertain answer from the rail");
51
+ if (event["type"] === "rail.outcome" && payload.status === "accepted" && execution) accepted.add(execution);
52
+ if (event["type"] === "execution.transition" && execution && typeof payload.to === "string") last.set(execution, payload.to);
53
+ }
54
+ // Issued and never closed: the charge was out when the run ended, and nobody paid it.
55
+ if ([...accepted].some((execution) => last.get(execution) === "executing")) found.add("a payer who had not paid when it ended");
56
+ return [...found];
57
+ }
58
+
16
59
  export async function rerun(agent: Agent, argv: string[]): Promise<number> {
17
60
  const json = argv.includes("--json");
18
61
  const runId = argv.find((a) => !a.startsWith("--"));
@@ -21,17 +64,40 @@ export async function rerun(agent: Agent, argv: string[]): Promise<number> {
21
64
  say("usage: npm run rerun <run-id> [--json]");
22
65
  return 2;
23
66
  }
24
- const original = ProofBundle.open(runsDir(agent), runId);
25
- if (!original) {
67
+ const found = openRun(agent, runId);
68
+ const original = found?.bundle;
69
+ if (!found || !original) {
26
70
  say(`no bundle at runs/${runId}`);
27
71
  return 1;
28
72
  }
29
73
  const meta = original.readMeta() ?? {};
74
+ const startedAt = typeof meta["started_at"] === "string" && Number.isFinite(Date.parse(meta["started_at"])) ? new Date(meta["started_at"]) : undefined;
30
75
  const mode = (meta["mode"] as ApprovalMode | undefined) ?? "human";
31
76
  const events = original.readEvents();
32
- const originalTrail = events.filter((e) => e["type"] === "execution.transition").map((e) => (e["payload"] as { to: string }).to);
33
- const originalDecisions = events.filter((e) => e["type"] === "approval.created").map((e) => ((e["payload"] as { approver: { type: string } }).approver.type === "person" ? "approve" : "mandate"));
34
- const userTurns = original.readTranscript().filter((l) => l.kind === "user").map((l) => l["text"] as string);
77
+ const transitions = events.filter((e) => e["type"] === "execution.transition").map((e) => ({ execution: e["execution_id"] as string, ...(e["payload"] as { from: string; to: string }) }));
78
+ const originalTrail = transitions.map((t) => t.to);
79
+ // What the original did with each approval it asked for, in the order it asked: approved it, denied it, or left it open. A run that stopped at `awaiting_approval` (a one-shot with no --approve or --deny, an adversarial case that only has to escalate) is replayed to the same place, not decided on its behalf.
80
+ const asked = transitions.flatMap((t, i) => (t.to === "awaiting_approval" ? [transitions.slice(i + 1).find((n) => n.execution === t.execution)?.to] : []));
81
+ // Nobody decides an approval that expired either: the rerun's clock does, or the sequences differ and the last line says so.
82
+ const originalDecisions = asked.map((next) => (next === "approved" ? "approve" : next === "denied" ? "deny" : "none"));
83
+ const leftOpen = asked.filter((next) => next === undefined).length;
84
+ const transcript = original.readTranscript();
85
+ // The transcript is the model's side, and replaying it is all a rerun does. A run that never asked the model recorded no step to replay: an adversarial case of `kind: events` drives rail deliveries and writes no transcript at all.
86
+ if (!transcript.some((l) => l.kind === "assistant_step")) {
87
+ const error = `runs/${runId} has no model turn in transcript.jsonl, so there is nothing to replay`;
88
+ if (json) stdout.write(JSON.stringify({ run_id: runId, error }) + "\n");
89
+ say(error);
90
+ return 1;
91
+ }
92
+ // What the world did in the original is not in the transcript, and a rerun that ignores it pays what the original denied. It is said by name, before anything is replayed.
93
+ const unreplayed = notReplayed(events);
94
+ if (unreplayed.length > 0) {
95
+ const error = `runs/${runId} cannot be compared with a rerun: it met ${unreplayed.join(", and ")}, which a rerun does not replay`;
96
+ if (json) stdout.write(JSON.stringify({ run_id: runId, error, not_replayed: unreplayed }) + "\n");
97
+ say(error);
98
+ return 1;
99
+ }
100
+ const userTurns = transcript.filter((l) => l.kind === "user").map((l) => l["text"] as string);
35
101
  const transcriptPath = join(original.dir, "transcript.jsonl");
36
102
  const plan = agent.kit.rerunPlan?.(events) ?? {};
37
103
 
@@ -40,16 +106,22 @@ export async function rerun(agent: Agent, argv: string[]): Promise<number> {
40
106
  rail: "stub",
41
107
  provider: "replay",
42
108
  transcript: transcriptPath,
43
- runId: `${runId}_rerun_${Date.now().toString(36)}`,
109
+ runId: `${original.runId}_rerun_${Date.now().toString(36)}`,
110
+ // Beside the run it replays: the rerun of an eval run stays with the eval runs.
111
+ runsDir: found.runsDir,
44
112
  stateDir: mkdtempSync(join(tmpdir(), `${agent.slug}-rerun-`)),
45
113
  stubRail: plan.stubRail,
114
+ // The original's clock, from where it started: a rule on a due date or on the hours of service decides today what it decided then.
115
+ ...(startedAt ? { now: clockFrom(startedAt) } : {}),
46
116
  say,
117
+ // The recording's locale, so the rerun's refusal details read as the original's did.
118
+ ...(isLocale(meta["locale"]) ? { locale: meta["locale"] } : {}),
47
119
  });
48
120
  try {
49
121
  let decisionIndex = 0;
50
122
  const runtime = s.makeRuntime();
51
123
  const loop = s.makeLoop(runtime, (execution: Execution) => {
52
- const decision = execution.state === "awaiting_approval" ? (originalDecisions[decisionIndex++] === "approve" ? "approve" : "deny") : "none";
124
+ const decision = execution.state === "awaiting_approval" ? (originalDecisions[decisionIndex++] ?? "deny") : "none";
53
125
  return handleExecution(execution, {
54
126
  setup: s,
55
127
  approver: { id: "usr_rerun", channel: "terminal" },
@@ -78,7 +150,8 @@ export async function rerun(agent: Agent, argv: string[]): Promise<number> {
78
150
  }) + "\n",
79
151
  );
80
152
  }
81
- say(same ? `rerun ok: ${trail.length} transition(s), same sequence as ${runId}` : `rerun DIFFERS: original ${JSON.stringify(originalTrail)} vs rerun ${JSON.stringify(trail)}`);
153
+ const open = leftOpen > 0 ? `; ${leftOpen} execution(s) left in awaiting_approval, as the original left ${leftOpen === 1 ? "it" : "them"}` : "";
154
+ say(same ? `rerun ok: ${trail.length} transition(s), same sequence as ${runId}${open}` : `rerun DIFFERS: original ${JSON.stringify(originalTrail)} vs rerun ${JSON.stringify(trail)}`);
82
155
  return same ? 0 : 1;
83
156
  } finally {
84
157
  s.close();
@@ -6,7 +6,7 @@
6
6
  * ones expire.
7
7
  */
8
8
  import { stderr, stdout } from "node:process";
9
- import type { Execution } from "@codespar/agent-core";
9
+ import { railErrorOf, type Execution } from "@codespar/agent-core";
10
10
  import type { Agent } from "../agent.js";
11
11
  import { setup } from "../setup.js";
12
12
  import { followUp } from "../terminal.js";
@@ -37,6 +37,7 @@ export async function resume(agent: Agent, argv: string[]): Promise<number> {
37
37
  state: e.state,
38
38
  ...(awaitsPayer ? { reason: e.reason ?? null } : {}),
39
39
  detail: e.detail ?? null,
40
+ rail_error: railErrorOf(e),
40
41
  ...(awaitsPayer ? { charge_ids: e.outcomes.map((o) => o.transaction_id ?? null) } : {}),
41
42
  receipt_ids: e.outcomes.filter((o) => o.receipt_id).map((o) => o.receipt_id),
42
43
  }));
@@ -14,6 +14,7 @@ import { stdout } from "node:process";
14
14
  import { relative } from "node:path";
15
15
  import type { ConversationScript } from "@codespar/agent-core";
16
16
  import type { Agent } from "../agent.js";
17
+ import { outcomeExitCode, refusalLine, sayOutcome } from "../outcome.js";
17
18
  import type { Setup } from "../setup.js";
18
19
  import { defaultAsk } from "../terminal.js";
19
20
  import { converse } from "../channels/whatsapp/run.js";
@@ -116,19 +117,23 @@ export async function startWhatsApp(options: StartWhatsAppOptions): Promise<numb
116
117
  ...(cost ? { simulated_cost: cost } : {}),
117
118
  };
118
119
 
120
+ // The same count, refusals and exit code as the terminal's one-shot: the channel changes who is told, not what the run did.
121
+ const { executions, refusals, outcome, line } = sayOutcome(s, result.notRun);
122
+ for (const refusal of refusals) say(refusalLine(refusal));
119
123
  if (options.json) {
120
124
  const payload = s.kit.oneShotPayload({
121
125
  setup: s,
122
126
  reply: result.replies[result.replies.length - 1] ?? "",
123
127
  toolCalls: result.toolCalls,
124
- executions: result.executions,
128
+ executions,
125
129
  startedAt: options.startedAt,
126
130
  });
127
- stdout.write(JSON.stringify({ ...payload, channel: channelSummary }) + "\n");
131
+ stdout.write(JSON.stringify({ ...payload, run_outcome: outcome, refused_before_draft: refusals, channel: channelSummary }) + "\n");
128
132
  } else {
129
- say(`conversa em ${channelSummary.log} — ${channelSummary.messages_in} recebida(s), ${channelSummary.messages_out} enviada(s)${refused.length ? `, ${refused.length} recusada(s)` : ""}`);
130
- if (cost) say(`custo simulado desta conversa nas regras da Meta: ${cost.total.toFixed(4)} ${cost.currency} (conta do emulador, nao nossa)`);
133
+ say(line);
134
+ say(s.coreStrings.waConversationSummary(channelSummary.log, channelSummary.messages_in, channelSummary.messages_out, refused.length));
135
+ if (cost) say(s.coreStrings.waSimulatedCost(cost.total.toFixed(4), cost.currency));
131
136
  }
132
137
 
133
- return result.executions.some((e) => e.state === "executing") ? 3 : 0;
138
+ return outcomeExitCode(outcome, executions);
134
139
  }