@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
@@ -0,0 +1,179 @@
1
+ /**
2
+ * What this agent prints, per locale: the runner's words for it, the lines an
3
+ * order reads as, the one message per outcome the customer receives, and the
4
+ * words pricing and the order tools write (the cart's issues, the gate's
5
+ * refusal details, an order's status). Every key exists in both entries (`npm
6
+ * run check`).
7
+ *
8
+ * The issue CODES (`coupon_unknown`, `quantity_above_stock`) and the reason
9
+ * codes are machine words and are the same in every locale; a test reads the
10
+ * code, a person reads the message. The details never quote the envelope's
11
+ * numbers or a cost, in either language (checkout §5.6).
12
+ */
13
+ import type { LocaleTable } from "@codespar/agent-core";
14
+ import type { KitStrings } from "@codespar/agent-runtime";
15
+
16
+ const pt = {
17
+ mandateWord: "política",
18
+ receiptWord: "pedido",
19
+ intro: 'Você é o cliente. Diga o que quer ("oi, sou a Marina, quero o pacote de dez aulas e uma avaliação inicial"). Ctrl+D ou "sair" encerra.',
20
+ prompt: "cliente> ",
21
+ approveQuestion: " [atendente] Confirmar este pedido? [s/N] ",
22
+ uncertainDispatch: " desfecho desconhecido no trilho; rode `npm run resume` para reconciliar (nunca repita a emissão)",
23
+ notAuthorized: "a política não autoriza",
24
+ waitingForPayer: (round: number) => ` aguardando o pagamento... (${round} consultas)`,
25
+
26
+ order: "pedido",
27
+ customerLine: (customer: string, cart: string | undefined) => `cliente ${customer}${cart ? `, carrinho ${cart}` : ""}`,
28
+ lineDiscount: (pct: number) => ` (desconto ${pct}%)`,
29
+ coupon: (code: string) => `cupom ${code}`,
30
+ orderDiscount: "desconto no pedido",
31
+ cartLines: (count: number) => `${count} linha(s)`,
32
+ charge: "cobrança",
33
+ paidOrder: "pedido pago",
34
+ invoiceDocument: (id: string) => ` — documento ${id}`,
35
+ orderOf: (total: string) => `Pedido de ${total}`,
36
+
37
+ toldSettled: (chargeIds: string) => `Recebemos, pedido confirmado! Obrigado. (${chargeIds})`,
38
+ toldExpired: "A cobrança venceu sem pagamento. Se quiser, emito uma nova para o mesmo pedido.",
39
+ toldCancelled: "A cobrança foi cancelada. Nada foi pago.",
40
+ toldAmbiguous: "A cobrança deste pedido já foi emitida e estamos conferindo a situação dela. Não pague de novo; te aviso assim que estiver conferida.",
41
+ toldFailed: (reason: string | undefined) => `Não consegui emitir a cobrança (${reason ?? "falha no trilho"}). Nada foi cobrado.`,
42
+ toldDenied: (reason: string | undefined) => `Não consigo fechar o pedido nesses termos (${reason ?? "recusado"}).`,
43
+ toldUndecided: (why: string) => `O pedido expirou sem confirmação (${why}).`,
44
+
45
+ orderApproved: "pedido confirmado; a cobrança sai quando o cliente pedir (action=issue)",
46
+ orderCartChanged: "o carrinho mudou depois da confirmação; o pedido voltou para o atendente",
47
+ orderAwaitingAttendant: "aguardando o atendente confirmar o pedido",
48
+ orderIssued: "cobrança emitida; aguardando o pagamento",
49
+ orderUncertain: "desfecho da emissão desconhecido; nada será reemitido",
50
+ orderPaid: "pago",
51
+ noOrderForCart: (cartId: string) => `o carrinho ${cartId} ainda não virou pedido`,
52
+ noOrder: "nenhum pedido nesta conversa",
53
+ alreadyOrdered: (executionId: string) => `este carrinho já é o pedido ${executionId}; nada novo foi criado`,
54
+ noCart: "nenhum carrinho aberto nesta conversa; cart_update abre um",
55
+
56
+ totalItems: "Itens",
57
+ totalItemsDiscount: "Descontos nos itens",
58
+ totalSubtotal: "Subtotal",
59
+ totalOrderDiscount: "Desconto do pedido",
60
+ totalTotal: "Total",
61
+ lineValue: "Valor",
62
+ lineDiscountTotal: "Desconto",
63
+ lineTotal: "Total da linha",
64
+
65
+ issuePriceNotInput: "o preço vem do catálogo da loja; a linha foi recusada inteira",
66
+ issueSkuUnknown: (sku: string) => `não temos ${sku || "esse item"} no catálogo`,
67
+ issueUnavailable: (title: string) => `${title} está indisponível`,
68
+ issueQuantityInvalid: (max: number) => `quantidade deve ser um inteiro de 1 a ${max}`,
69
+ issueDuplicateSku: (sku: string) => `${sku} aparece mais de uma vez; uma linha por item, com a quantidade total`,
70
+ issueAboveStock: (stock: number, title: string) => `só há ${stock} de ${title}`,
71
+ issueCouponUnknown: (code: string) => `o cupom ${code} não existe nesta loja`,
72
+ issueCouponExpired: (code: string) => `o cupom ${code} expirou`,
73
+ issueCouponMinimum: (code: string, minimum: string) => `o cupom ${code} vale para pedidos a partir de ${minimum}`,
74
+
75
+ outsideServiceHours: (window: string, timezone: string, clock: string) => `fora do horário de atendimento (${window} ${timezone}); agora são ${clock}`,
76
+ gateOneItem: "um pedido é uma cobrança: um item, cujo valor é o total do carrinho",
77
+ gateNoCart: "um pedido nasce de um carrinho; esta execução não nomeia nenhum",
78
+ gateCartMissing: (ref: string) => `o carrinho ${ref} não existe neste estado`,
79
+ gateCartChanged: "o pedido não corresponde ao carrinho atual; o carrinho mudou depois",
80
+ gateCartEmpty: "carrinho vazio",
81
+ gateCartIssues: (codes: string) => `o carrinho tem pendências (${codes})`,
82
+ gateTotalMismatch: (charged: number, cart: number) => `o pedido cobra ${charged} e o carrinho soma ${cart}`,
83
+ gateNotForSale: (sku: string) => `${sku} não está à venda`,
84
+ gateNotListPrice: (sku: string) => `${sku} não está pelo preço de tabela`,
85
+ gateQuantity: (sku: string) => `quantidade de ${sku} fora do permitido`,
86
+ gateLineDiscount: (sku: string) => `desconto em ${sku} acima do que a política da loja permite`,
87
+ gateLineMargin: (sku: string) => `${sku} ficaria abaixo do piso de margem da loja`,
88
+ gateOrderDiscount: "desconto no pedido acima do que a política da loja permite",
89
+ gateCouponAndDiscount: "cupom e desconto negociado não se somam",
90
+ gateCouponInvalid: (code: string) => `o cupom ${code} não vale para este pedido`,
91
+ gateOrderMargin: "o pedido ficaria abaixo do piso de margem da loja",
92
+ gateTicket: (total: string) => `pedido de ${total} acima do ticket máximo da loja`,
93
+ gateNoDueDate: "a cobrança do pedido não tem vencimento",
94
+ gateDueOutsideWindow: (due: string, today: string, last: string) => `vencimento ${due} fora da janela da loja (de ${today} até ${last})`,
95
+ };
96
+
97
+ export const STRINGS: LocaleTable<typeof pt & KitStrings> = {
98
+ "pt-BR": pt,
99
+ en: {
100
+ mandateWord: "policy",
101
+ receiptWord: "order",
102
+ intro: 'You are the customer. Say what you want ("hi, I am Marina, I want the ten-class pack and an initial assessment"). Ctrl+D or "exit" ends.',
103
+ prompt: "customer> ",
104
+ approveQuestion: " [attendant] Confirm this order? [y/N] ",
105
+ uncertainDispatch: " outcome unknown on the rail; run `npm run resume` to reconcile (never repeat the issuance)",
106
+ notAuthorized: "the policy does not authorize it",
107
+ waitingForPayer: (round) => ` waiting for the payment... (${round} looks)`,
108
+
109
+ order: "order",
110
+ customerLine: (customer, cart) => `customer ${customer}${cart ? `, cart ${cart}` : ""}`,
111
+ lineDiscount: (pct) => ` (discount ${pct}%)`,
112
+ coupon: (code) => `coupon ${code}`,
113
+ orderDiscount: "order discount",
114
+ cartLines: (count) => `${count} line(s)`,
115
+ charge: "charge",
116
+ paidOrder: "paid order",
117
+ invoiceDocument: (id) => ` — document ${id}`,
118
+ orderOf: (total) => `Order of ${total}`,
119
+
120
+ toldSettled: (chargeIds) => `Payment received, order confirmed! Thank you. (${chargeIds})`,
121
+ toldExpired: "The charge reached its due date unpaid. If you like, I can issue a new one for the same order.",
122
+ toldCancelled: "The charge was cancelled. Nothing was paid.",
123
+ toldAmbiguous: "The charge for this order was already issued and we are checking where it stands. Do not pay again; I will let you know as soon as it is checked.",
124
+ toldFailed: (reason) => `I could not issue the charge (${reason ?? "rail failure"}). Nothing was charged.`,
125
+ toldDenied: (reason) => `I cannot close the order on those terms (${reason ?? "refused"}).`,
126
+ toldUndecided: (why) => `The order expired without a confirmation (${why}).`,
127
+
128
+ orderApproved: "order confirmed; the charge goes out when the customer asks for it (action=issue)",
129
+ orderCartChanged: "the cart changed after the confirmation; the order went back to the attendant",
130
+ orderAwaitingAttendant: "waiting for the attendant to confirm the order",
131
+ orderIssued: "charge issued; waiting for the payment",
132
+ orderUncertain: "outcome of the issuance unknown; nothing will be re-issued",
133
+ orderPaid: "paid",
134
+ noOrderForCart: (cartId) => `cart ${cartId} has not become an order yet`,
135
+ noOrder: "no order in this conversation",
136
+ alreadyOrdered: (executionId) => `this cart is already order ${executionId}; nothing new was created`,
137
+ noCart: "no cart open in this conversation; cart_update opens one",
138
+
139
+ totalItems: "Items",
140
+ totalItemsDiscount: "Item discounts",
141
+ totalSubtotal: "Subtotal",
142
+ totalOrderDiscount: "Order discount",
143
+ totalTotal: "Total",
144
+ lineValue: "Amount",
145
+ lineDiscountTotal: "Discount",
146
+ lineTotal: "Line total",
147
+
148
+ issuePriceNotInput: "the price comes from the store's catalog; the whole line was refused",
149
+ issueSkuUnknown: (sku) => `we do not have ${sku || "that item"} in the catalog`,
150
+ issueUnavailable: (title) => `${title} is unavailable`,
151
+ issueQuantityInvalid: (max) => `the quantity must be a whole number from 1 to ${max}`,
152
+ issueDuplicateSku: (sku) => `${sku} appears more than once; one line per item, with the total quantity`,
153
+ issueAboveStock: (stock, title) => `there are only ${stock} of ${title}`,
154
+ issueCouponUnknown: (code) => `coupon ${code} does not exist in this store`,
155
+ issueCouponExpired: (code) => `coupon ${code} has expired`,
156
+ issueCouponMinimum: (code, minimum) => `coupon ${code} applies to orders from ${minimum}`,
157
+
158
+ outsideServiceHours: (window, timezone, clock) => `outside service hours (${window} ${timezone}); it is ${clock} now`,
159
+ gateOneItem: "an order is one charge: one item, whose amount is the cart's total",
160
+ gateNoCart: "an order is born from a cart; this execution names none",
161
+ gateCartMissing: (ref) => `cart ${ref} does not exist in this state`,
162
+ gateCartChanged: "the order does not match the current cart; the cart changed afterwards",
163
+ gateCartEmpty: "empty cart",
164
+ gateCartIssues: (codes) => `the cart has pending issues (${codes})`,
165
+ gateTotalMismatch: (charged, cart) => `the order charges ${charged} and the cart adds up to ${cart}`,
166
+ gateNotForSale: (sku) => `${sku} is not for sale`,
167
+ gateNotListPrice: (sku) => `${sku} is not at the list price`,
168
+ gateQuantity: (sku) => `the quantity of ${sku} is outside what is allowed`,
169
+ gateLineDiscount: (sku) => `the discount on ${sku} is above what the store's policy allows`,
170
+ gateLineMargin: (sku) => `${sku} would fall below the store's margin floor`,
171
+ gateOrderDiscount: "the order discount is above what the store's policy allows",
172
+ gateCouponAndDiscount: "a coupon and a negotiated discount do not add up",
173
+ gateCouponInvalid: (code) => `coupon ${code} does not apply to this order`,
174
+ gateOrderMargin: "the order would fall below the store's margin floor",
175
+ gateTicket: (total) => `an order of ${total} is above the store's maximum ticket`,
176
+ gateNoDueDate: "the order's charge has no due date",
177
+ gateDueOutsideWindow: (due, today, last) => `due date ${due} is outside the store's window (from ${today} to ${last})`,
178
+ },
179
+ };
@@ -37,7 +37,10 @@ describe("npm run check: the manifest is the index", () => {
37
37
  writeFileSync(join(dir, "tools.json"), JSON.stringify({ ...t, meta_tools: t.meta_tools.filter((x) => x.effect !== "charge") }));
38
38
  expect(codes(dir)).toContain("tools_contradict_manifest");
39
39
  const again = copyAgent();
40
- writeFileSync(join(again, "agent.yaml"), readFileSync(join(again, "agent.yaml"), "utf8").replace(" bolepix-receivables: sandbox\n", ""));
40
+ const manifest = readFileSync(join(again, "agent.yaml"), "utf8");
41
+ const dropped = manifest.replace(/^ bolepix-receivables:.*\n/m, "");
42
+ expect(dropped).not.toBe(manifest);
43
+ writeFileSync(join(again, "agent.yaml"), dropped);
41
44
  expect(codes(again)).toContain("tools_contradict_manifest");
42
45
  });
43
46
 
@@ -2,4 +2,4 @@
2
2
  {"kind": "assistant_step", "tool_calls": [{"id": "tc_2", "name": "cart_update", "input": {"lines": [{"sku": "aula-avulsa", "quantity": 2}]}}]}
3
3
  {"kind": "assistant_step", "tool_calls": [{"id": "tc_3", "name": "codespar_charge", "input": {"action": "create", "customer": "marina", "total_minor": 20000}}]}
4
4
  {"kind": "assistant_step", "tool_calls": [{"id": "tc_4", "name": "codespar_charge", "input": {"action": "issue"}}]}
5
- {"kind": "assistant_step", "reply": "Pedido de duas aulas avulsas, R$ 200,00: o QR e o copia e cola estao acima."}
5
+ {"kind": "assistant_step", "reply": "Pedido de duas aulas avulsas, R$ 200,00: o QR e o copia e cola estão acima."}
@@ -1,6 +1,6 @@
1
1
  {"kind": "assistant_step", "tool_calls": [{"id": "tc_1", "name": "list_catalog", "input": {}}]}
2
2
  {"kind": "assistant_step", "tool_calls": [{"id": "tc_2", "name": "cart_update", "input": {"lines": [{"sku": "pacote-10-aulas", "quantity": 1}, {"sku": "avaliacao-inicial", "quantity": 1}]}}]}
3
- {"kind": "assistant_step", "reply": "Oi, Marina! Montei o carrinho: pacote de 10 aulas de violao (R$ 390,00) e avaliacao inicial de nivel (R$ 89,90). Total R$ 479,90, cobranca por Pix ou boleto com vencimento hoje. Posso fechar o pedido?"}
3
+ {"kind": "assistant_step", "reply": "Oi, Marina! Montei o carrinho: pacote de 10 aulas de violão (R$ 390,00) e avaliação inicial de nível (R$ 89,90). Total R$ 479,90, cobrança por Pix ou boleto com vencimento hoje. Posso fechar o pedido?"}
4
4
  {"kind": "assistant_step", "tool_calls": [{"id": "tc_3", "name": "codespar_charge", "input": {"action": "create", "customer": "marina", "total_minor": 47990}}]}
5
5
  {"kind": "assistant_step", "tool_calls": [{"id": "tc_4", "name": "codespar_charge", "input": {"action": "issue"}}]}
6
- {"kind": "assistant_step", "reply": "Pronto, Marina: a cobranca de R$ 479,90 esta emitida, o codigo esta acima. Assim que o pagamento cair, eu te confirmo por aqui."}
6
+ {"kind": "assistant_step", "reply": "Pronto, Marina: a cobrança de R$ 479,90 está emitida, o código está acima. Assim que o pagamento cair, eu te confirmo por aqui."}
@@ -1,2 +1,2 @@
1
1
  {"kind": "assistant_step", "tool_calls": [{"id": "tc_1", "name": "codespar_charge", "input": {"action": "status"}}]}
2
- {"kind": "assistant_step", "reply": "Oi, Marina! Nao ha pedido em aberto nesta conversa. Quer montar um novo?"}
2
+ {"kind": "assistant_step", "reply": "Oi, Marina! Não há pedido em aberto nesta conversa. Quer montar um novo?"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * The false green of OPEN_QUESTIONS §63: on staging (2026-09-27) the issuer
3
+ * ended the bolepix in ERROR, with no QR and no boleto line, and the run still
4
+ * answered `settled` with a cycle time, because the sandbox payer paid what
5
+ * nobody could have paid and the API's test route settled it (ent#1816). The
6
+ * stub scripts both halves here: an issuer that ends in ERROR, and a charge
7
+ * that is settled without ever becoming payable.
8
+ */
9
+ import { mkdtempSync, readFileSync } from "node:fs";
10
+ import { tmpdir } from "node:os";
11
+ import { join } from "node:path";
12
+ import { describe, expect, it } from "vitest";
13
+ import { checkScenario, loadScenario, runScenario } from "@codespar/agent-runtime";
14
+ import { agent } from "../src/kit.js";
15
+
16
+ const runsDir = mkdtempSync(join(tmpdir(), "checkout-payable-"));
17
+ /** The buyer the happy path issues to. */
18
+ const BUYER = "27548613008";
19
+
20
+ function events(bundleDir: string): Array<{ type: string; payload: Record<string, unknown> }> {
21
+ return readFileSync(join(bundleDir, "events.jsonl"), "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l) as { type: string; payload: Record<string, unknown> });
22
+ }
23
+
24
+ describe("a cycle closes on a payable instrument, or it does not close", () => {
25
+ const scenario = loadScenario(agent, "happy-path");
26
+
27
+ it("an issuer that ends the registration in ERROR fails the order with the issuer's code: never settled, never paid, no cycle to boast of", async () => {
28
+ const run = await runScenario(agent, scenario, { mode: "human", runsDir, stubRail: { issuerErrorPayees: [BUYER] } });
29
+ expect(run.executions.map((e) => [e.state, e.reason])).toEqual([["failed", "charge_issuer_error"]]);
30
+ expect(run.settled_total).toBe(0);
31
+ expect(run.receipts).toBe(0);
32
+ expect(run.payer_calls).toEqual([]);
33
+ expect(run.executions[0]!.payable_seen).toBeNull();
34
+ const told = events(run.bundle_dir).filter((e) => e.type === "message.debtor").map((e) => String(e.payload["text"]));
35
+ expect(told).toEqual([expect.stringContaining("charge_issuer_error")]);
36
+ expect(told[0]).not.toMatch(/Recebemos/);
37
+ // The NFS-e follows a paid order, so an order the issuer failed opens none.
38
+ expect(events(run.bundle_dir).filter((e) => e.type.startsWith("invoice."))).toEqual([]);
39
+ expect(checkScenario(scenario, run).ok).toBe(false);
40
+ });
41
+
42
+ it("a charge settled with no payable instrument seen first is refused by the gate as no_payable_instrument, and no cycle is reported", async () => {
43
+ const run = await runScenario(agent, scenario, { mode: "human", runsDir, stubRail: { settlesUnpayablePayees: [BUYER] } });
44
+ expect(run.executions.map((e) => e.state)).toEqual(["settled"]);
45
+ expect(run.executions[0]!.payable_seen).toBe(false);
46
+ expect(run.cycle_seconds).toBeNull();
47
+ const check = checkScenario(scenario, run);
48
+ expect(check.ok).toBe(false);
49
+ expect(check.failures).toEqual([expect.stringMatching(/^no_payable_instrument: /)]);
50
+ });
51
+
52
+ it("the ordinary happy path saw its QR before the payment, and reports its cycle", async () => {
53
+ const run = await runScenario(agent, scenario, { mode: "human", runsDir });
54
+ expect(run.executions[0]!.payable_seen).toBe(true);
55
+ expect(run.cycle_seconds).toEqual(expect.any(Number));
56
+ expect(checkScenario(scenario, run).failures).toEqual([]);
57
+ });
58
+ });
@@ -110,7 +110,7 @@ describe("checkout §3.3, §5: the gate the core runs at every gate", () => {
110
110
  const over = priceCart({ lines: [{ sku: "aula-avulsa", quantity: 2 }], order_discount_pct: 9 }, envelope, TODAY);
111
111
  expect(checkOrder(order(over), over, envelope, AFTERNOON, TZ)?.reason).toBe("outside_envelope");
112
112
  const stacked = priceCart({ lines: [{ sku: "aula-avulsa", quantity: 2 }], coupon: "BEMVINDO10", order_discount_pct: 2 }, envelope, TODAY);
113
- expect(checkOrder(order(stacked), stacked, envelope, AFTERNOON, TZ)?.detail).toContain("nao se somam");
113
+ expect(checkOrder(order(stacked), stacked, envelope, AFTERNOON, TZ)?.detail).toContain("não se somam");
114
114
  const coupon = priceCart({ lines: [{ sku: "aula-avulsa", quantity: 2 }], coupon: "BEMVINDO10" }, envelope, TODAY);
115
115
  expect(checkOrder(order(coupon), coupon, envelope, AFTERNOON, TZ)).toBeUndefined();
116
116
  });
@@ -133,6 +133,6 @@ describe("checkout §3.3, §5: the gate the core runs at every gate", () => {
133
133
 
134
134
  it("refuses an order above the ticket ceiling", () => {
135
135
  const big = priceCart({ lines: [{ sku: "pacote-10-aulas", quantity: 6 }] }, envelope, TODAY);
136
- expect(checkOrder(order(big), big, envelope, AFTERNOON, TZ)?.detail).toContain("ticket maximo");
136
+ expect(checkOrder(order(big), big, envelope, AFTERNOON, TZ)?.detail).toContain("ticket máximo");
137
137
  });
138
138
  });
@@ -0,0 +1,47 @@
1
+ /**
2
+ * A charge that was out and unpaid when the run ended is the payer's doing,
3
+ * not the model's: the rerun's payer pays, so it would settle an order the
4
+ * original left open. The rerun says so instead of reporting that it DIFFERS.
5
+ */
6
+ import { spawnSync } from "node:child_process";
7
+ import { mkdtempSync } from "node:fs";
8
+ import { tmpdir } from "node:os";
9
+ import { join, resolve } from "node:path";
10
+ import { describe, expect, it } from "vitest";
11
+ import { loadScenario, runScenario } from "@codespar/agent-runtime";
12
+ import { agent } from "../src/kit.js";
13
+
14
+ const AGENT_DIR = resolve(import.meta.dirname, "..");
15
+ const BIN = resolve(AGENT_DIR, "../../packages/agent-runtime/bin.mjs");
16
+
17
+ function rerun(runsDir: string, runId: string) {
18
+ const result = spawnSync(process.execPath, [BIN, "rerun", runId, "--json"], {
19
+ cwd: AGENT_DIR,
20
+ env: { ...process.env, ANTHROPIC_API_KEY: "", CODESPAR_API_KEY: "", CHECKOUT_RUNS_DIR: runsDir, CHECKOUT_STATE_DIR: join(runsDir, "state") },
21
+ encoding: "utf8",
22
+ timeout: 60_000,
23
+ });
24
+ return { code: result.status, stderr: result.stderr, report: JSON.parse(result.stdout.trim()) as { same_states?: boolean; error?: string; not_replayed?: string[] } };
25
+ }
26
+
27
+ describe("npm run rerun <run-id> on a checkout run", () => {
28
+ it("payment-claimed: the charge nobody paid is named, and nothing is replayed", async () => {
29
+ const runsDir = mkdtempSync(join(tmpdir(), "checkout-rerun-unpaid-"));
30
+ const original = await runScenario(agent, loadScenario(agent, "payment-claimed"), { mode: "human", rail: "stub", runsDir });
31
+ expect(original.executions.map((e) => e.state)).toEqual(["executing"]);
32
+
33
+ const out = rerun(runsDir, original.run_id);
34
+ expect(out.code).toBe(1);
35
+ expect(out.report.not_replayed).toEqual(["a payer who had not paid when it ended"]);
36
+ expect(out.report.error).toBe(`runs/${original.run_id} cannot be compared with a rerun: it met a payer who had not paid when it ended, which a rerun does not replay`);
37
+ expect(out.stderr).not.toContain("DIFFERS");
38
+ });
39
+
40
+ it("happy-path, where the payer paid, is replayed to the same states on the run's clock", async () => {
41
+ const runsDir = mkdtempSync(join(tmpdir(), "checkout-rerun-paid-"));
42
+ const original = await runScenario(agent, loadScenario(agent, "happy-path"), { mode: "human", rail: "stub", runsDir });
43
+ const out = rerun(runsDir, original.run_id);
44
+ expect(out.code).toBe(0);
45
+ expect(out.report.same_states).toBe(true);
46
+ });
47
+ });
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Two things `npm start` says with no model key: which recording an `--input`
3
+ * replays, and how long a scenario pack took.
4
+ */
5
+ import { spawnSync } from "node:child_process";
6
+ import { mkdtempSync } from "node:fs";
7
+ import { tmpdir } from "node:os";
8
+ import { join, resolve } from "node:path";
9
+ import { describe, expect, it } from "vitest";
10
+ import { loadScenario } from "@codespar/agent-runtime";
11
+ import { agent } from "../src/kit.js";
12
+
13
+ const AGENT_DIR = resolve(import.meta.dirname, "..");
14
+ const BIN = resolve(AGENT_DIR, "../../packages/agent-runtime/bin.mjs");
15
+
16
+ function start(args: string[]) {
17
+ const stateDir = mkdtempSync(join(tmpdir(), "checkout-reach-"));
18
+ const result = spawnSync(process.execPath, [BIN, "start", ...args], {
19
+ cwd: AGENT_DIR,
20
+ // Pinned inside the service hours, as the other process tests of this agent are.
21
+ env: { ...process.env, ANTHROPIC_API_KEY: "", CODESPAR_API_KEY: "", CODESPAR_AGENT_NOW: "2026-09-23T14:00:00-03:00", CHECKOUT_STATE_DIR: stateDir, CHECKOUT_RUNS_DIR: join(stateDir, "runs") },
22
+ encoding: "utf8",
23
+ timeout: 60_000,
24
+ });
25
+ return { code: result.status, stdout: result.stdout, stderr: result.stderr };
26
+ }
27
+
28
+ describe("npm start -- --input <the first turn of a scenario>", () => {
29
+ // The three that opened with one sentence, of which --input could only ever replay the first.
30
+ it.each(["cart-recomposed", "cart-replaced", "charge-expired"])("%s: replays its own recording", (name) => {
31
+ const out = start(["--input", loadScenario(agent, name).turns[0]!.input, "--json"]);
32
+ expect(out.code).toBe(0);
33
+ expect(out.stderr).toContain(`replaying ${join(AGENT_DIR, "scenarios", `${name}.transcript.jsonl`)}`);
34
+ });
35
+ });
36
+
37
+ describe("npm start -- --scenario <name> on the stub rail", () => {
38
+ it("says ok and where the bundle is, and no seconds: the stub's clock is the scenario's, not a watch", () => {
39
+ const began = Date.now();
40
+ const out = start(["--scenario", "happy-path", "--mode", "human"]);
41
+ const wall = (Date.now() - began) / 1000;
42
+ expect(out.code).toBe(0);
43
+ const ok = out.stderr.split("\n").find((line) => line.startsWith("== ok"))!;
44
+ expect(ok).toMatch(/^== ok — bundle em /);
45
+ expect(ok).not.toMatch(/\d+(\.\d+)?s — /);
46
+ // What the line used to claim: the scenario's clock counts 16 seconds here, and the process takes a fraction of that.
47
+ expect(wall).toBeLessThan(16);
48
+ });
49
+
50
+ it("--json still carries the cycle the scenario's clock counted, for the checks that read it", () => {
51
+ const out = start(["--scenario", "happy-path", "--mode", "human", "--json"]);
52
+ const report = JSON.parse(out.stdout.trim()) as { results: Array<{ ok: boolean; run: { rail: string; cycle_seconds: number | null } }> };
53
+ expect(report.results[0]).toMatchObject({ ok: true, run: { rail: "stub", cycle_seconds: expect.any(Number) } });
54
+ });
55
+ });
@@ -11,7 +11,7 @@ import { existsSync, mkdtempSync, readFileSync, writeFileSync } from "node:fs";
11
11
  import { tmpdir } from "node:os";
12
12
  import { isAbsolute, join, resolve } from "node:path";
13
13
  import { describe, expect, it } from "vitest";
14
- import { parseConversationScript, parseTemplateRegistry, templateArity, type Execution } from "@codespar/agent-core";
14
+ import { WHATSAPP_LANGUAGE, parseConversationScript, parseTemplateRegistry, templateArity, type Execution } from "@codespar/agent-core";
15
15
  import { handleExecution, setup } from "@codespar/agent-runtime";
16
16
  import { agent } from "../src/kit.js";
17
17
 
@@ -65,9 +65,18 @@ const conversationOf = (p: Payload) => {
65
65
  };
66
66
 
67
67
  const EMULATOR = process.env["WHATSAPP_SIM_URL"] ?? "http://127.0.0.1:4290";
68
+ /**
69
+ * The probe closes its connection, as every emulator call in these tests does.
70
+ * An agent run here is a `spawnSync`, which blocks this process's event loop
71
+ * for longer than the emulator's keep-alive (`Keep-Alive: timeout=5`), so a
72
+ * pooled socket is never expired by fetch and the next call on it dies
73
+ * `fetch failed … ECONNRESET`. This file makes one call today; the header is
74
+ * here so the next one does not inherit a pooled socket.
75
+ */
76
+ const FRESH_CONNECTION = { connection: "close" } as const;
68
77
  const emulatorUp = await (async () => {
69
78
  try {
70
- return (await fetch(`${EMULATOR}/health`, { signal: AbortSignal.timeout(2000) })).ok;
79
+ return (await fetch(`${EMULATOR}/health`, { headers: FRESH_CONNECTION, signal: AbortSignal.timeout(2000) })).ok;
71
80
  } catch {
72
81
  return false;
73
82
  }
@@ -82,6 +91,10 @@ describe.skipIf(!emulatorUp)("the sale closes over the WhatsApp channel", () =>
82
91
  expect(out.code).toBe(0);
83
92
  const p = payloadOf(out.stdout);
84
93
  expect(p.executions.map((e) => e.state)).toEqual(["settled"]);
94
+ // The channel's one-shot carries the same count and refusal list as the terminal's.
95
+ const counted = p as unknown as { run_outcome: Record<string, number>; refused_before_draft: unknown[] };
96
+ expect(counted.run_outcome).toMatchObject({ settled: 1, failed: 0 });
97
+ expect(counted.refused_before_draft).toEqual([]);
85
98
  expect(p.invoices.map((i) => i.state)).toEqual(["accepted"]);
86
99
  expect(p.channel.backend).toBe("emulator");
87
100
  const outbound = conversationOf(p).filter((l) => l.direction === "out");
@@ -158,14 +171,17 @@ describe("the conversation decides who is charged, with no emulator in sight", (
158
171
  it("every template the kit can send is declared, with the arity it is sent with", () => {
159
172
  const registry = parseTemplateRegistry(readFileSync(join(AGENT_DIR, "channels/whatsapp/templates.json"), "utf8"));
160
173
  const order = { total: 47990 } as Execution;
161
- for (const e of [{ ...order, state: "settled" }, { ...order, state: "failed", reason: "charge_expired" }, { ...order, state: "failed", reason: "charge_cancelled" }] as Execution[]) {
162
- const t = agent.kit.outcomeTemplate!(e)!;
163
- const declared = registry.templates.find((x) => x.name === t.template);
164
- expect(declared).toBeDefined();
165
- expect(templateArity(declared!.body)).toBe(t.variables.length);
166
- expect(t.variables).toEqual(["R$ 479,90"]);
174
+ // In each locale: the same template names, declared in that locale's language, the total formatted for its reader.
175
+ for (const [locale, total] of [["pt-BR", "R$ 479,90"], ["en", "R$479.90"]] as const) {
176
+ for (const e of [{ ...order, state: "settled" }, { ...order, state: "failed", reason: "charge_expired" }, { ...order, state: "failed", reason: "charge_cancelled" }] as Execution[]) {
177
+ const t = agent.kit.outcomeTemplate!(e, locale)!;
178
+ const declared = registry.templates.find((x) => x.name === t.template && x.language === WHATSAPP_LANGUAGE[locale]);
179
+ expect(declared).toBeDefined();
180
+ expect(templateArity(declared!.body)).toBe(t.variables.length);
181
+ expect(t.variables).toEqual([total]);
182
+ }
183
+ // An order refused or never approved is answered in the turn; no template pretends otherwise.
184
+ expect(agent.kit.outcomeTemplate!({ ...order, state: "denied", reason: "outside_envelope" } as Execution, locale)).toBeUndefined();
167
185
  }
168
- // An order refused or never approved is answered in the turn; no template pretends otherwise.
169
- expect(agent.kit.outcomeTemplate!({ ...order, state: "denied", reason: "outside_envelope" } as Execution)).toBeUndefined();
170
186
  });
171
187
  });
@@ -3,7 +3,7 @@
3
3
  {
4
4
  "name": "codespar_charge",
5
5
  "effect": "charge",
6
- "description": "The order and its charge. action=create turns the cart into an ORDER for the customer you are talking to: the code prices it from the catalog, checks it against the sales policy (price, discount, margin floor, ticket, service hours) and, depending on the approval mode, asks the attendant or confirms it alone. Nothing is issued by create. action=issue sends the confirmed order's charge: ONE bolepix (cobranca com vencimento, due today: the customer pays by Pix or by boleto) for the cart's total, with an idempotency key, so asking twice returns the same charge; the code presents the QR and the copy-and-paste. If the cart changed after the order was confirmed, issue sends it back to the attendant instead. action=status reads the order. You never pass an amount or a document: the code takes the total from the cart and the customer's name and document from the store's customer book.",
6
+ "description": "The order and its charge. action=create turns the cart into an ORDER for the customer you are talking to: the code prices it from the catalog, checks it against the sales policy (price, discount, margin floor, ticket, service hours) and, depending on the approval mode, asks the attendant or confirms it alone. Nothing is issued by create. action=issue sends the confirmed order's charge: ONE bolepix (cobrança com vencimento, due today: the customer pays by Pix or by boleto) for the cart's total, with an idempotency key, so asking twice returns the same charge; the code presents the QR and the copy-and-paste. If the cart changed after the order was confirmed, issue sends it back to the attendant instead. action=status reads the order. You never pass an amount or a document: the code takes the total from the cart and the customer's name and document from the store's customer book.",
7
7
  "input_schema": {
8
8
  "type": "object",
9
9
  "properties": {
@@ -1,8 +1,8 @@
1
1
  # @codespar/agent-core
2
2
 
3
- The primitives every CodeSpar starter-kit agent inherits (spec v5.1.1, section 4): the execution state machine, the approval artifact, the `agent.yaml` manifest, `escalate_above`, `actor`, local state in SQLite, the proof bundle, the rail contract and the two providers.
3
+ The primitives every CodeSpar starter-kit agent inherits (section 4 of spec v5.1.1, [`docs/spec-v5.1.1.md`](../../docs/spec-v5.1.1.md), the only spec version in this repository; [`docs/OPEN_QUESTIONS.md`](../../docs/OPEN_QUESTIONS.md) says where later parts were built against v5.2 and the checkout spec v0.2): the execution state machine, the approval artifact, the `agent.yaml` manifest, `escalate_above`, `actor`, local state in SQLite, the proof bundle, the rail contract, the conversation loop and the two providers.
4
4
 
5
- This package is the decisions. The RUNNER around them — the terminal channel, `codespar-agent start|consent|approve|deny|resume|rerun|reconcile|poll|webhook|check|eval`, the setup that wires this package to an agent directory, and the scenario and adversarial runners — is [`@codespar/agent-runtime`](../agent-runtime), which depends on this one and is what an agent's `package.json` scripts call (#13). Nothing here knows an agent's name.
5
+ This package is the decisions. The RUNNER around them — the terminal channel, `codespar-agent start|consent|approve|deny|resume|rerun|reconcile|poll|webhook|inspect|check|eval|verify`, the setup that wires this package to an agent directory, and the scenario and adversarial runners — is [`@codespar/agent-runtime`](../agent-runtime), which depends on this one and is what an agent's `package.json` scripts call (#13). Nothing here knows an agent's name.
6
6
 
7
7
  ## The state machine, and what the types do and do not prove
8
8
 
@@ -25,10 +25,29 @@ This package is the decisions. The RUNNER around them — the terminal channel,
25
25
 
26
26
  Every spend carries `approval: { items_hash, batch_hash? }`, the artifact's own hashes (`spendApprovalOf`), and the API seals them into the receipt's chain as a link of their own (chain v4, ent#1670). Both rails refuse a spend without them before any call. `composition` is not sent: the API takes the two hashes and nothing else, and only charges carry a composition today. `receipt-chain.ts` recomputes a chain from the receipt read under the `chain_recipe` the key document publishes (RFC 8785 implemented locally, `node:crypto` only), and `verifyReceiptRead` holds the signature, the body and the sealed approval link against the artifact, in that order. It proves WHAT was approved to anybody holding the read; WHO approved stays in the artifact, under the local key. `docs/OPEN_QUESTIONS.md` §3 and §47.
27
27
 
28
+ ## Who acted, on the wire
29
+
30
+ Every spend sends the kit's actor as the SDK's `PaymentActor` (`wireActorOf` in `rail.ts`): an agent is `{ type: "agent", id: "<name>@<version>", on_behalf_of: <the mandate's consumer> }`, a person `{ type: "human", id, channel }`. `agent_id` still goes too; it names the agent the mandate was signed for. The rail reads the actor the API recorded back as `sealed_actor`, the bundle's receipt copy keeps it beside the kit's own `actor`, and one that differs from what was sent, or is missing, is a `receipt.actor_mismatch` event. It does not stop the run: the actor is what the receipt records, not what it proves. It is not in the chain, so a third party checking the Ed25519 signature learns nothing about who triggered the spend, and a charge carries no actor at all. §2.
31
+
32
+ ## A settlement this run did not make
33
+
34
+ A spend presented again under the same attempt id is answered with the earlier payment (`idempotent_replay`). Dispatch marks that outcome `replayed: true`, and `isReplayedSettlement(execution)` is true when every settled attempt carries the mark. The money moved, and this execution did not move it. The execution is still `settled`. Only dispatch writes the mark, because dispatch is always this execution's first presentation of an id. Reconcile does not copy it: a lookup presents the attempt again, and the API answers every look at a settled attempt as a replay, this execution's own payment included. The tool results and a one-shot's `--json` read this predicate (`replayed`); `inspect` reads the same mark from the bundle's rail answers. An attempt closed by reconcile is still counted as paid by the execution that looked it up. §39c.
35
+
28
36
  ## Reconcile never re-dispatches
29
37
 
30
38
  An execution left in `executing` is looked up on the rail, attempt by attempt. A recorded settled or failed outcome closes it; `in_flight`, `uncertain` or unknown leaves it in `executing` with `reason: rail_uncertain` for a human. The single exception is an outbox row still `pending` (the state changed, no call was ever made): those attempts go out once, under the same ids.
31
39
 
40
+ ## The conversation loop
41
+
42
+ `AgentLoop.turn` (`agent.ts`) sends the model the system prompt, the conversation and the tool specs, and hands each tool call to the kit's handler for it; a tool outside `tools.json` is refused `tool_not_allowed`. Only the engine behind the handlers moves money. Two things it adds that no prompt can:
43
+
44
+ - **The reply language.** `detectLanguage` (`language.ts`) reads the language of what the person typed, Brazilian Portuguese or English, from function words; payee names, amounts and Pix keys count for neither. The loop appends a "Reply language for this turn" section naming it to the system prompt of every step of the turn. Tool results do not count: on the Messages API they are user-role messages, and a prompt rule alone lost to their Portuguese data. A turn with no lead either way keeps the previous turn's language, and before any lead the prompt's own default stands. The transcript's user line records `reply_language` (`null` before any lead). §64.
45
+ - **The date.** `ExecutionEngine.today()` is the date in the guardrails' timezone at the engine's clock, so `--now` pins it. `list_bills`, `list_payables` and `list_agreements` return it as `today`, and bills and payables also carry `days_until_due` (`daysUntil`), because the model has no calendar of its own.
46
+
47
+ ## What the code prints, per locale
48
+
49
+ `locale.ts` and `strings.ts` (#64). A run has one locale, `pt-BR` or `en`: `--locale`, else the optional `locale:` of `agent.yaml`, else `pt-BR` (`resolveLocale`). `CORE_STRINGS` holds the lines every agent shares (the batch gesture, the waits, how an execution and a payable instrument read, the WhatsApp operator lines) in both locales, and `tableGaps` is what `npm run check` runs over it and over each kit's table: a key one locale lacks, an empty string, or a function whose arity differs is an error. `formatBRL` and `formatDay` format for the locale's reader ("R$ 1.850,00" / "R$1,850.00"; "30/09/2026" / "2026-09-30"). `WHATSAPP_LANGUAGE` maps a locale to the language Meta approves a template in (`pt_BR`, `en_US`); the template registry holds one copy per (name, language), and the check requires every template in the language of every locale. None of it touches what an answer decides, and it is independent of the reply language above.
50
+
32
51
  ## Stubs
33
52
 
34
53
  `stubs/mandate-status.ts` (the section 4.7 status source for runs without a key: revocation, pause and the organization kill switch, over the local state.db) and `stubs/rail.ts` (the sandbox rail) are stand-ins for the CI, the scenarios and `rerun`, marked as such. With a test key the engine reads the mandate status from the API instead (`api/mandate-status.ts`, `GET /v1/mandates/{id}`), fail-closed: anything but `active` refuses `executing`, `org_paused: true` (the organization kill switch, ent#1648) refuses it whatever `status` says, and a read that does not answer, or answers without `org_paused`, is `mandate_status_unavailable`, never "assume active". The approval artifact is signed with a local development key (`approval.ts`); the API does not sign approval lists.
@@ -17,7 +17,7 @@
17
17
  },
18
18
  "dependencies": {
19
19
  "@anthropic-ai/sdk": "0.128.0",
20
- "@codespar/sdk": "0.16.10",
20
+ "@codespar/sdk": "0.16.16",
21
21
  "yaml": "2.9.1",
22
22
  "zod": "3.25.76"
23
23
  }