@codespar/cli 0.17.0 → 0.18.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.
- package/README.md +1 -0
- package/package.json +1 -1
- package/templates/bills-agent/README.md +1 -1
- package/templates/bills-agent/agents/bills-agent/AGENTS.md +1 -1
- package/templates/bills-agent/agents/bills-agent/CLAUDE.md +1 -1
- package/templates/bills-agent/agents/bills-agent/README.md +6 -5
- package/templates/bills-agent/agents/bills-agent/src/modules/embedded-consent.ts +5 -4
- package/templates/bills-agent/packages/agent-core/README.md +14 -1
- package/templates/bills-agent/packages/agent-core/package.json +1 -1
- package/templates/bills-agent/packages/agent-core/src/agent.ts +39 -1
- package/templates/bills-agent/packages/agent-core/src/api/charge-rail.ts +54 -34
- package/templates/bills-agent/packages/agent-core/src/api/client.ts +28 -5
- package/templates/bills-agent/packages/agent-core/src/api/mandate-status.ts +28 -12
- package/templates/bills-agent/packages/agent-core/src/api/rail.ts +62 -26
- package/templates/bills-agent/packages/agent-core/src/api/sandbox-payer.ts +3 -18
- package/templates/bills-agent/packages/agent-core/src/approval.ts +14 -2
- package/templates/bills-agent/packages/agent-core/src/bundle.ts +35 -3
- package/templates/bills-agent/packages/agent-core/src/channels.ts +49 -3
- package/templates/bills-agent/packages/agent-core/src/check.ts +25 -2
- package/templates/bills-agent/packages/agent-core/src/engine.ts +235 -46
- package/templates/bills-agent/packages/agent-core/src/hash.ts +57 -1
- package/templates/bills-agent/packages/agent-core/src/index.ts +2 -0
- package/templates/bills-agent/packages/agent-core/src/quote.ts +50 -0
- package/templates/bills-agent/packages/agent-core/src/rail.ts +89 -4
- package/templates/bills-agent/packages/agent-core/src/receipt-chain.ts +270 -0
- package/templates/bills-agent/packages/agent-core/src/receipt-verification.ts +194 -18
- package/templates/bills-agent/packages/agent-core/src/revocation.ts +1 -1
- package/templates/bills-agent/packages/agent-core/src/state-machine.ts +10 -1
- package/templates/bills-agent/packages/agent-core/src/stubs/mandate-status.ts +4 -3
- package/templates/bills-agent/packages/agent-core/src/stubs/rail.ts +100 -32
- package/templates/bills-agent/packages/agent-core/src/tools.ts +17 -6
- package/templates/bills-agent/packages/agent-core/src/types.ts +54 -1
- package/templates/bills-agent/packages/agent-core/test/approval-seal.test.ts +233 -0
- package/templates/bills-agent/packages/agent-core/test/attempt-replay.test.ts +265 -0
- package/templates/bills-agent/packages/agent-core/test/composition.test.ts +204 -0
- package/templates/bills-agent/packages/agent-core/test/fixtures/production-receipt-keys.json +1 -0
- package/templates/bills-agent/packages/agent-core/test/helpers.ts +4 -1
- package/templates/bills-agent/packages/agent-core/test/mandate-status.test.ts +85 -9
- package/templates/bills-agent/packages/agent-core/test/quote.test.ts +198 -0
- package/templates/bills-agent/packages/agent-core/test/receipt-chain.test.ts +220 -0
- package/templates/bills-agent/packages/agent-core/test/receipt-read-verification.test.ts +197 -0
- package/templates/bills-agent/packages/agent-core/test/receivables.test.ts +103 -3
- package/templates/bills-agent/packages/agent-runtime/README.md +12 -0
- package/templates/bills-agent/packages/agent-runtime/src/adversarial.ts +32 -2
- package/templates/bills-agent/packages/agent-runtime/src/channels/types.ts +53 -4
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +123 -22
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +30 -20
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +146 -21
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +40 -3
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +8 -1
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +16 -2
- package/templates/bills-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +70 -20
- package/templates/bills-agent/packages/agent-runtime/src/commands/poll.ts +2 -1
- package/templates/bills-agent/packages/agent-runtime/src/commands/resume.ts +8 -2
- package/templates/bills-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +3 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/start.ts +6 -3
- package/templates/bills-agent/packages/agent-runtime/src/commands/verify.ts +239 -38
- package/templates/bills-agent/packages/agent-runtime/src/commands/webhook.ts +3 -2
- package/templates/bills-agent/packages/agent-runtime/src/index.ts +1 -0
- package/templates/bills-agent/packages/agent-runtime/src/inspect.ts +5 -1
- package/templates/bills-agent/packages/agent-runtime/src/kit.ts +25 -2
- package/templates/bills-agent/packages/agent-runtime/src/scenarios.ts +8 -2
- package/templates/bills-agent/packages/agent-runtime/src/setup.ts +13 -3
- package/templates/bills-agent/packages/agent-runtime/src/terminal.ts +127 -18
- package/templates/bills-agent/packages/agent-runtime/test/verify-cli.test.ts +211 -9
- package/templates/bills-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +45 -0
- package/templates/bills-agent/packages/agent-runtime/test/whatsapp-session.test.ts +32 -0
- package/templates/bills-agent/packages/agent-runtime/test/whatsapp-status-replies.test.ts +182 -0
- package/templates/checkout-agent/LICENSE +21 -0
- package/templates/checkout-agent/README.md +28 -0
- package/templates/checkout-agent/_gitignore +10 -0
- package/templates/checkout-agent/agents/checkout-agent/.env.example +5 -0
- package/templates/checkout-agent/agents/checkout-agent/AGENTS.md +20 -0
- package/templates/checkout-agent/agents/checkout-agent/CLAUDE.md +20 -0
- package/templates/checkout-agent/agents/checkout-agent/README.md +94 -0
- package/templates/checkout-agent/agents/checkout-agent/SYSTEM_PROMPT.md +36 -0
- package/templates/checkout-agent/agents/checkout-agent/agent.yaml +30 -0
- package/templates/checkout-agent/agents/checkout-agent/channels/whatsapp/README.md +28 -0
- package/templates/checkout-agent/agents/checkout-agent/channels/whatsapp/pedido-beatriz.json +11 -0
- package/templates/checkout-agent/agents/checkout-agent/channels/whatsapp/pedido-marina-retomada.json +10 -0
- package/templates/checkout-agent/agents/checkout-agent/channels/whatsapp/pedido-marina.json +11 -0
- package/templates/checkout-agent/agents/checkout-agent/channels/whatsapp/templates.json +49 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/beneficiary-swap-human.json +12 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/beneficiary-swap.json +11 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/beneficiary-swap.transcript.jsonl +5 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/coupon-unknown.json +13 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/coupon-unknown.transcript.jsonl +4 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/exfiltration.json +26 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/exfiltration.transcript.jsonl +3 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/false-authority.json +11 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/false-authority.transcript.jsonl +5 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/fractioning.json +12 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/fractioning.transcript.jsonl +5 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/model-total.json +13 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/model-total.transcript.jsonl +5 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/payment-claimed.json +15 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/payment-claimed.transcript.jsonl +7 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/price-injected.json +12 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/price-injected.transcript.jsonl +5 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/prompt-injection.json +13 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/prompt-injection.transcript.jsonl +4 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/quantity-swapped-human.json +16 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/quantity-swapped-human.transcript.jsonl +9 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/quantity-swapped.json +15 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/quantity-swapped.transcript.jsonl +8 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/webhook-replay.json +11 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/eval.yaml +11 -0
- package/templates/checkout-agent/agents/checkout-agent/guardrails.json +25 -0
- package/templates/checkout-agent/agents/checkout-agent/mandate.example.json +28 -0
- package/templates/checkout-agent/agents/checkout-agent/package.json +33 -0
- package/templates/checkout-agent/agents/checkout-agent/runbook.md +19 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/beneficiary-not-allowed.json +42 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/beneficiary-not-allowed.transcript.jsonl +4 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/cap-exceeded.json +32 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/cap-exceeded.transcript.jsonl +4 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/cart-recomposed.json +61 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/cart-recomposed.transcript.jsonl +9 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/cart-replaced.json +61 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/cart-replaced.transcript.jsonl +9 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/charge-expired.json +36 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/charge-expired.transcript.jsonl +6 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/coupon-unknown.json +23 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/coupon-unknown.transcript.jsonl +4 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/escalated-above-threshold.json +72 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/escalated-above-threshold.transcript.jsonl +9 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/happy-path.json +15 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/happy-path.transcript.jsonl +6 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/item-unavailable.json +23 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/item-unavailable.transcript.jsonl +3 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/mandate-revoked.json +42 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/mandate-revoked.transcript.jsonl +12 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/nfse-failed.json +14 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/nfse-failed.transcript.jsonl +9 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/payment-claimed.json +34 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/payment-claimed.transcript.jsonl +7 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/price-injected.json +33 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/price-injected.transcript.jsonl +4 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/prompt-injection.json +32 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/prompt-injection.transcript.jsonl +4 -0
- package/templates/checkout-agent/agents/checkout-agent/src/catalog.ts +92 -0
- package/templates/checkout-agent/agents/checkout-agent/src/kit.ts +338 -0
- package/templates/checkout-agent/agents/checkout-agent/src/modules/bolepix-receivables.ts +179 -0
- package/templates/checkout-agent/agents/checkout-agent/src/modules/nfse-invoice.ts +374 -0
- package/templates/checkout-agent/agents/checkout-agent/src/modules/storefront-cart.ts +220 -0
- package/templates/checkout-agent/agents/checkout-agent/src/pricing.ts +297 -0
- package/templates/checkout-agent/agents/checkout-agent/test/adversarial.test.ts +117 -0
- package/templates/checkout-agent/agents/checkout-agent/test/check.test.ts +67 -0
- package/templates/checkout-agent/agents/checkout-agent/test/cli.test.ts +169 -0
- package/templates/checkout-agent/agents/checkout-agent/test/fixtures/order-marina.transcript.jsonl +5 -0
- package/templates/checkout-agent/agents/checkout-agent/test/fixtures/ordered-marina-awaiting-payer.transcript.jsonl +6 -0
- package/templates/checkout-agent/agents/checkout-agent/test/fixtures/tap-falar-agora-marina.transcript.jsonl +2 -0
- package/templates/checkout-agent/agents/checkout-agent/test/nfse.test.ts +170 -0
- package/templates/checkout-agent/agents/checkout-agent/test/pricing.test.ts +138 -0
- package/templates/checkout-agent/agents/checkout-agent/test/scenarios.test.ts +113 -0
- package/templates/checkout-agent/agents/checkout-agent/test/whatsapp.test.ts +171 -0
- package/templates/checkout-agent/agents/checkout-agent/tools.json +68 -0
- package/templates/checkout-agent/agents/checkout-agent/tsconfig.json +10 -0
- package/templates/checkout-agent/package.json +38 -0
- package/templates/checkout-agent/packages/agent-core/README.md +34 -0
- package/templates/checkout-agent/packages/agent-core/package.json +24 -0
- package/templates/checkout-agent/packages/agent-core/src/agent.ts +163 -0
- package/templates/checkout-agent/packages/agent-core/src/api/charge-rail.ts +195 -0
- package/templates/checkout-agent/packages/agent-core/src/api/client.ts +76 -0
- package/templates/checkout-agent/packages/agent-core/src/api/mandate-status.ts +74 -0
- package/templates/checkout-agent/packages/agent-core/src/api/rail.ts +153 -0
- package/templates/checkout-agent/packages/agent-core/src/api/sandbox-payer.ts +43 -0
- package/templates/checkout-agent/packages/agent-core/src/approval.ts +135 -0
- package/templates/checkout-agent/packages/agent-core/src/bundle.ts +191 -0
- package/templates/checkout-agent/packages/agent-core/src/channels.ts +186 -0
- package/templates/checkout-agent/packages/agent-core/src/check.ts +276 -0
- package/templates/checkout-agent/packages/agent-core/src/clock.ts +42 -0
- package/templates/checkout-agent/packages/agent-core/src/engine.ts +1074 -0
- package/templates/checkout-agent/packages/agent-core/src/escalate.ts +85 -0
- package/templates/checkout-agent/packages/agent-core/src/events.ts +40 -0
- package/templates/checkout-agent/packages/agent-core/src/guardrails.ts +45 -0
- package/templates/checkout-agent/packages/agent-core/src/hash.ts +118 -0
- package/templates/checkout-agent/packages/agent-core/src/ids.ts +10 -0
- package/templates/checkout-agent/packages/agent-core/src/index.ts +34 -0
- package/templates/checkout-agent/packages/agent-core/src/mandate.ts +100 -0
- package/templates/checkout-agent/packages/agent-core/src/manifest.ts +76 -0
- package/templates/checkout-agent/packages/agent-core/src/providers/anthropic.ts +76 -0
- package/templates/checkout-agent/packages/agent-core/src/providers/replay.ts +63 -0
- package/templates/checkout-agent/packages/agent-core/src/providers/types.ts +39 -0
- package/templates/checkout-agent/packages/agent-core/src/quote.ts +50 -0
- package/templates/checkout-agent/packages/agent-core/src/rail.ts +186 -0
- package/templates/checkout-agent/packages/agent-core/src/receipt-chain.ts +270 -0
- package/templates/checkout-agent/packages/agent-core/src/receipt-verification.ts +577 -0
- package/templates/checkout-agent/packages/agent-core/src/revocation.ts +30 -0
- package/templates/checkout-agent/packages/agent-core/src/secrets.ts +30 -0
- package/templates/checkout-agent/packages/agent-core/src/state/store.ts +307 -0
- package/templates/checkout-agent/packages/agent-core/src/state-machine.ts +157 -0
- package/templates/checkout-agent/packages/agent-core/src/stubs/charge-rail.ts +195 -0
- package/templates/checkout-agent/packages/agent-core/src/stubs/mandate-status.ts +58 -0
- package/templates/checkout-agent/packages/agent-core/src/stubs/rail.ts +209 -0
- package/templates/checkout-agent/packages/agent-core/src/tools.ts +66 -0
- package/templates/checkout-agent/packages/agent-core/src/types.ts +187 -0
- package/templates/checkout-agent/packages/agent-core/test/approval-seal.test.ts +233 -0
- package/templates/checkout-agent/packages/agent-core/test/approval.test.ts +117 -0
- package/templates/checkout-agent/packages/agent-core/test/attempt-replay.test.ts +265 -0
- package/templates/checkout-agent/packages/agent-core/test/bundle.test.ts +85 -0
- package/templates/checkout-agent/packages/agent-core/test/clock.test.ts +25 -0
- package/templates/checkout-agent/packages/agent-core/test/composition.test.ts +204 -0
- package/templates/checkout-agent/packages/agent-core/test/engine.test.ts +596 -0
- package/templates/checkout-agent/packages/agent-core/test/escalate.test.ts +42 -0
- package/templates/checkout-agent/packages/agent-core/test/fixtures/production-receipt-keys.json +1 -0
- package/templates/checkout-agent/packages/agent-core/test/fixtures/staging-receipt-keys.json +18 -0
- package/templates/checkout-agent/packages/agent-core/test/fixtures/staging-receipt.json +24 -0
- package/templates/checkout-agent/packages/agent-core/test/helpers.ts +142 -0
- package/templates/checkout-agent/packages/agent-core/test/mandate-status.test.ts +229 -0
- package/templates/checkout-agent/packages/agent-core/test/manifest.test.ts +45 -0
- package/templates/checkout-agent/packages/agent-core/test/quote.test.ts +198 -0
- package/templates/checkout-agent/packages/agent-core/test/receipt-chain.test.ts +220 -0
- package/templates/checkout-agent/packages/agent-core/test/receipt-read-verification.test.ts +197 -0
- package/templates/checkout-agent/packages/agent-core/test/receipt-verification.test.ts +316 -0
- package/templates/checkout-agent/packages/agent-core/test/receivables.test.ts +416 -0
- package/templates/checkout-agent/packages/agent-core/test/secrets.test.ts +28 -0
- package/templates/checkout-agent/packages/agent-core/test/state-machine.test.ts +67 -0
- package/templates/checkout-agent/packages/agent-core/test/transitions.type-test.ts +59 -0
- package/templates/checkout-agent/packages/agent-core/tsconfig.json +10 -0
- package/templates/checkout-agent/packages/agent-runtime/README.md +80 -0
- package/templates/checkout-agent/packages/agent-runtime/bin.mjs +32 -0
- package/templates/checkout-agent/packages/agent-runtime/package.json +23 -0
- package/templates/checkout-agent/packages/agent-runtime/src/adversarial.ts +199 -0
- package/templates/checkout-agent/packages/agent-runtime/src/agent.ts +68 -0
- package/templates/checkout-agent/packages/agent-runtime/src/channels/contact.ts +13 -0
- package/templates/checkout-agent/packages/agent-runtime/src/channels/index.ts +72 -0
- package/templates/checkout-agent/packages/agent-runtime/src/channels/rules.ts +120 -0
- package/templates/checkout-agent/packages/agent-runtime/src/channels/types.ts +173 -0
- package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +459 -0
- package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +216 -0
- package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/evidence.ts +109 -0
- package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +350 -0
- package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +180 -0
- package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +47 -0
- package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +120 -0
- package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +127 -0
- package/templates/checkout-agent/packages/agent-runtime/src/cli.ts +98 -0
- package/templates/checkout-agent/packages/agent-runtime/src/commands/check.ts +15 -0
- package/templates/checkout-agent/packages/agent-runtime/src/commands/decide.ts +63 -0
- package/templates/checkout-agent/packages/agent-runtime/src/commands/eval.ts +58 -0
- package/templates/checkout-agent/packages/agent-runtime/src/commands/inspect.ts +100 -0
- package/templates/checkout-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +367 -0
- package/templates/checkout-agent/packages/agent-runtime/src/commands/poll.ts +145 -0
- package/templates/checkout-agent/packages/agent-runtime/src/commands/reconcile.ts +42 -0
- package/templates/checkout-agent/packages/agent-runtime/src/commands/rerun.ts +86 -0
- package/templates/checkout-agent/packages/agent-runtime/src/commands/resume.ts +49 -0
- package/templates/checkout-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +134 -0
- package/templates/checkout-agent/packages/agent-runtime/src/commands/start.ts +248 -0
- package/templates/checkout-agent/packages/agent-runtime/src/commands/verify.ts +330 -0
- package/templates/checkout-agent/packages/agent-runtime/src/commands/webhook.ts +40 -0
- package/templates/checkout-agent/packages/agent-runtime/src/default-kit.ts +83 -0
- package/templates/checkout-agent/packages/agent-runtime/src/index.ts +13 -0
- package/templates/checkout-agent/packages/agent-runtime/src/inspect.ts +801 -0
- package/templates/checkout-agent/packages/agent-runtime/src/kit.ts +229 -0
- package/templates/checkout-agent/packages/agent-runtime/src/poll.ts +105 -0
- package/templates/checkout-agent/packages/agent-runtime/src/scenarios.ts +274 -0
- package/templates/checkout-agent/packages/agent-runtime/src/setup.ts +239 -0
- package/templates/checkout-agent/packages/agent-runtime/src/terminal.ts +263 -0
- package/templates/checkout-agent/packages/agent-runtime/src/webhook.ts +131 -0
- package/templates/checkout-agent/packages/agent-runtime/test/inspect.test.ts +336 -0
- package/templates/checkout-agent/packages/agent-runtime/test/verify-cli.test.ts +329 -0
- package/templates/checkout-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +277 -0
- package/templates/checkout-agent/packages/agent-runtime/test/whatsapp-evidence.test.ts +94 -0
- package/templates/checkout-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +174 -0
- package/templates/checkout-agent/packages/agent-runtime/test/whatsapp-session.test.ts +167 -0
- package/templates/checkout-agent/packages/agent-runtime/test/whatsapp-status-replies.test.ts +182 -0
- package/templates/checkout-agent/packages/agent-runtime/tsconfig.json +9 -0
- package/templates/checkout-agent/scripts/whatsapp-emulator.mjs +84 -0
- package/templates/checkout-agent/tsconfig.base.json +16 -0
- package/templates/checkout-agent/vitest.config.ts +12 -0
- package/templates/collections-agent/README.md +6 -1
- package/templates/collections-agent/agents/collections-agent/README.md +12 -8
- package/templates/collections-agent/agents/collections-agent/channels/whatsapp/README.md +8 -0
- package/templates/collections-agent/agents/collections-agent/channels/whatsapp/acordo-1042-retomada.json +10 -0
- package/templates/collections-agent/agents/collections-agent/channels/whatsapp/templates.json +27 -1
- package/templates/collections-agent/agents/collections-agent/src/kit.ts +2 -0
- package/templates/collections-agent/agents/collections-agent/src/modules/bolepix-receivables.ts +12 -2
- package/templates/collections-agent/agents/collections-agent/test/ambiguous-charge.test.ts +55 -0
- package/templates/collections-agent/agents/collections-agent/test/fixtures/tap-emitir-nova-1042.transcript.jsonl +2 -0
- package/templates/collections-agent/agents/collections-agent/test/whatsapp-poll.test.ts +12 -6
- package/templates/collections-agent/agents/collections-agent/test/whatsapp-status-replies.test.ts +148 -0
- package/templates/collections-agent/agents/collections-agent/test/whatsapp.test.ts +5 -0
- package/templates/collections-agent/package.json +1 -0
- package/templates/collections-agent/packages/agent-core/README.md +14 -1
- package/templates/collections-agent/packages/agent-core/package.json +1 -1
- package/templates/collections-agent/packages/agent-core/src/agent.ts +39 -1
- package/templates/collections-agent/packages/agent-core/src/api/charge-rail.ts +54 -34
- package/templates/collections-agent/packages/agent-core/src/api/client.ts +28 -5
- package/templates/collections-agent/packages/agent-core/src/api/mandate-status.ts +28 -12
- package/templates/collections-agent/packages/agent-core/src/api/rail.ts +62 -26
- package/templates/collections-agent/packages/agent-core/src/api/sandbox-payer.ts +3 -18
- package/templates/collections-agent/packages/agent-core/src/approval.ts +14 -2
- package/templates/collections-agent/packages/agent-core/src/bundle.ts +35 -3
- package/templates/collections-agent/packages/agent-core/src/channels.ts +49 -3
- package/templates/collections-agent/packages/agent-core/src/check.ts +25 -2
- package/templates/collections-agent/packages/agent-core/src/engine.ts +235 -46
- package/templates/collections-agent/packages/agent-core/src/hash.ts +57 -1
- package/templates/collections-agent/packages/agent-core/src/index.ts +2 -0
- package/templates/collections-agent/packages/agent-core/src/quote.ts +50 -0
- package/templates/collections-agent/packages/agent-core/src/rail.ts +89 -4
- package/templates/collections-agent/packages/agent-core/src/receipt-chain.ts +270 -0
- package/templates/collections-agent/packages/agent-core/src/receipt-verification.ts +194 -18
- package/templates/collections-agent/packages/agent-core/src/revocation.ts +1 -1
- package/templates/collections-agent/packages/agent-core/src/state-machine.ts +10 -1
- package/templates/collections-agent/packages/agent-core/src/stubs/mandate-status.ts +4 -3
- package/templates/collections-agent/packages/agent-core/src/stubs/rail.ts +100 -32
- package/templates/collections-agent/packages/agent-core/src/tools.ts +17 -6
- package/templates/collections-agent/packages/agent-core/src/types.ts +54 -1
- package/templates/collections-agent/packages/agent-core/test/approval-seal.test.ts +233 -0
- package/templates/collections-agent/packages/agent-core/test/attempt-replay.test.ts +265 -0
- package/templates/collections-agent/packages/agent-core/test/composition.test.ts +204 -0
- package/templates/collections-agent/packages/agent-core/test/fixtures/production-receipt-keys.json +1 -0
- package/templates/collections-agent/packages/agent-core/test/helpers.ts +4 -1
- package/templates/collections-agent/packages/agent-core/test/mandate-status.test.ts +85 -9
- package/templates/collections-agent/packages/agent-core/test/quote.test.ts +198 -0
- package/templates/collections-agent/packages/agent-core/test/receipt-chain.test.ts +220 -0
- package/templates/collections-agent/packages/agent-core/test/receipt-read-verification.test.ts +197 -0
- package/templates/collections-agent/packages/agent-core/test/receivables.test.ts +103 -3
- package/templates/collections-agent/packages/agent-runtime/README.md +12 -0
- package/templates/collections-agent/packages/agent-runtime/src/adversarial.ts +32 -2
- package/templates/collections-agent/packages/agent-runtime/src/channels/types.ts +53 -4
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +123 -22
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +30 -20
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +146 -21
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +40 -3
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +8 -1
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +16 -2
- package/templates/collections-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +70 -20
- package/templates/collections-agent/packages/agent-runtime/src/commands/poll.ts +2 -1
- package/templates/collections-agent/packages/agent-runtime/src/commands/resume.ts +8 -2
- package/templates/collections-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +3 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/start.ts +6 -3
- package/templates/collections-agent/packages/agent-runtime/src/commands/verify.ts +239 -38
- package/templates/collections-agent/packages/agent-runtime/src/commands/webhook.ts +3 -2
- package/templates/collections-agent/packages/agent-runtime/src/index.ts +1 -0
- package/templates/collections-agent/packages/agent-runtime/src/inspect.ts +5 -1
- package/templates/collections-agent/packages/agent-runtime/src/kit.ts +25 -2
- package/templates/collections-agent/packages/agent-runtime/src/scenarios.ts +8 -2
- package/templates/collections-agent/packages/agent-runtime/src/setup.ts +13 -3
- package/templates/collections-agent/packages/agent-runtime/src/terminal.ts +127 -18
- package/templates/collections-agent/packages/agent-runtime/test/verify-cli.test.ts +211 -9
- package/templates/collections-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +45 -0
- package/templates/collections-agent/packages/agent-runtime/test/whatsapp-session.test.ts +32 -0
- package/templates/collections-agent/packages/agent-runtime/test/whatsapp-status-replies.test.ts +182 -0
- package/templates/collections-agent/scripts/whatsapp-emulator.mjs +84 -0
- package/templates/hello-agent/README.md +1 -1
- package/templates/hello-agent/packages/agent-core/README.md +14 -1
- package/templates/hello-agent/packages/agent-core/package.json +1 -1
- package/templates/hello-agent/packages/agent-core/src/agent.ts +39 -1
- package/templates/hello-agent/packages/agent-core/src/api/charge-rail.ts +54 -34
- package/templates/hello-agent/packages/agent-core/src/api/client.ts +28 -5
- package/templates/hello-agent/packages/agent-core/src/api/mandate-status.ts +28 -12
- package/templates/hello-agent/packages/agent-core/src/api/rail.ts +62 -26
- package/templates/hello-agent/packages/agent-core/src/api/sandbox-payer.ts +3 -18
- package/templates/hello-agent/packages/agent-core/src/approval.ts +14 -2
- package/templates/hello-agent/packages/agent-core/src/bundle.ts +35 -3
- package/templates/hello-agent/packages/agent-core/src/channels.ts +49 -3
- package/templates/hello-agent/packages/agent-core/src/check.ts +25 -2
- package/templates/hello-agent/packages/agent-core/src/engine.ts +235 -46
- package/templates/hello-agent/packages/agent-core/src/hash.ts +57 -1
- package/templates/hello-agent/packages/agent-core/src/index.ts +2 -0
- package/templates/hello-agent/packages/agent-core/src/quote.ts +50 -0
- package/templates/hello-agent/packages/agent-core/src/rail.ts +89 -4
- package/templates/hello-agent/packages/agent-core/src/receipt-chain.ts +270 -0
- package/templates/hello-agent/packages/agent-core/src/receipt-verification.ts +194 -18
- package/templates/hello-agent/packages/agent-core/src/revocation.ts +1 -1
- package/templates/hello-agent/packages/agent-core/src/state-machine.ts +10 -1
- package/templates/hello-agent/packages/agent-core/src/stubs/mandate-status.ts +4 -3
- package/templates/hello-agent/packages/agent-core/src/stubs/rail.ts +100 -32
- package/templates/hello-agent/packages/agent-core/src/tools.ts +17 -6
- package/templates/hello-agent/packages/agent-core/src/types.ts +54 -1
- package/templates/hello-agent/packages/agent-core/test/approval-seal.test.ts +233 -0
- package/templates/hello-agent/packages/agent-core/test/attempt-replay.test.ts +265 -0
- package/templates/hello-agent/packages/agent-core/test/composition.test.ts +204 -0
- package/templates/hello-agent/packages/agent-core/test/fixtures/production-receipt-keys.json +1 -0
- package/templates/hello-agent/packages/agent-core/test/helpers.ts +4 -1
- package/templates/hello-agent/packages/agent-core/test/mandate-status.test.ts +85 -9
- package/templates/hello-agent/packages/agent-core/test/quote.test.ts +198 -0
- package/templates/hello-agent/packages/agent-core/test/receipt-chain.test.ts +220 -0
- package/templates/hello-agent/packages/agent-core/test/receipt-read-verification.test.ts +197 -0
- package/templates/hello-agent/packages/agent-core/test/receivables.test.ts +103 -3
- package/templates/hello-agent/packages/agent-runtime/README.md +12 -0
- package/templates/hello-agent/packages/agent-runtime/src/adversarial.ts +32 -2
- package/templates/hello-agent/packages/agent-runtime/src/channels/types.ts +53 -4
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +123 -22
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +30 -20
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +146 -21
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +40 -3
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +8 -1
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +16 -2
- package/templates/hello-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +70 -20
- package/templates/hello-agent/packages/agent-runtime/src/commands/poll.ts +2 -1
- package/templates/hello-agent/packages/agent-runtime/src/commands/resume.ts +8 -2
- package/templates/hello-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +3 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/start.ts +6 -3
- package/templates/hello-agent/packages/agent-runtime/src/commands/verify.ts +239 -38
- package/templates/hello-agent/packages/agent-runtime/src/commands/webhook.ts +3 -2
- package/templates/hello-agent/packages/agent-runtime/src/index.ts +1 -0
- package/templates/hello-agent/packages/agent-runtime/src/inspect.ts +5 -1
- package/templates/hello-agent/packages/agent-runtime/src/kit.ts +25 -2
- package/templates/hello-agent/packages/agent-runtime/src/scenarios.ts +8 -2
- package/templates/hello-agent/packages/agent-runtime/src/setup.ts +13 -3
- package/templates/hello-agent/packages/agent-runtime/src/terminal.ts +127 -18
- package/templates/hello-agent/packages/agent-runtime/test/verify-cli.test.ts +211 -9
- package/templates/hello-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +45 -0
- package/templates/hello-agent/packages/agent-runtime/test/whatsapp-session.test.ts +32 -0
- package/templates/hello-agent/packages/agent-runtime/test/whatsapp-status-replies.test.ts +182 -0
- package/templates/kits.lock.json +29 -6
- package/templates/supplier-payments-agent/README.md +1 -1
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/AGENTS.md +1 -1
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/CLAUDE.md +1 -1
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/README.md +11 -9
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/kit.ts +1 -1
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/modules/batch-payout.ts +67 -20
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/batch.test.ts +504 -5
- package/templates/supplier-payments-agent/packages/agent-core/README.md +14 -1
- package/templates/supplier-payments-agent/packages/agent-core/package.json +1 -1
- package/templates/supplier-payments-agent/packages/agent-core/src/agent.ts +39 -1
- package/templates/supplier-payments-agent/packages/agent-core/src/api/charge-rail.ts +54 -34
- package/templates/supplier-payments-agent/packages/agent-core/src/api/client.ts +28 -5
- package/templates/supplier-payments-agent/packages/agent-core/src/api/mandate-status.ts +28 -12
- package/templates/supplier-payments-agent/packages/agent-core/src/api/rail.ts +62 -26
- package/templates/supplier-payments-agent/packages/agent-core/src/api/sandbox-payer.ts +3 -18
- package/templates/supplier-payments-agent/packages/agent-core/src/approval.ts +14 -2
- package/templates/supplier-payments-agent/packages/agent-core/src/bundle.ts +35 -3
- package/templates/supplier-payments-agent/packages/agent-core/src/channels.ts +49 -3
- package/templates/supplier-payments-agent/packages/agent-core/src/check.ts +25 -2
- package/templates/supplier-payments-agent/packages/agent-core/src/engine.ts +235 -46
- package/templates/supplier-payments-agent/packages/agent-core/src/hash.ts +57 -1
- package/templates/supplier-payments-agent/packages/agent-core/src/index.ts +2 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/quote.ts +50 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/rail.ts +89 -4
- package/templates/supplier-payments-agent/packages/agent-core/src/receipt-chain.ts +270 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/receipt-verification.ts +194 -18
- package/templates/supplier-payments-agent/packages/agent-core/src/revocation.ts +1 -1
- package/templates/supplier-payments-agent/packages/agent-core/src/state-machine.ts +10 -1
- package/templates/supplier-payments-agent/packages/agent-core/src/stubs/mandate-status.ts +4 -3
- package/templates/supplier-payments-agent/packages/agent-core/src/stubs/rail.ts +100 -32
- package/templates/supplier-payments-agent/packages/agent-core/src/tools.ts +17 -6
- package/templates/supplier-payments-agent/packages/agent-core/src/types.ts +54 -1
- package/templates/supplier-payments-agent/packages/agent-core/test/approval-seal.test.ts +233 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/attempt-replay.test.ts +265 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/composition.test.ts +204 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/fixtures/production-receipt-keys.json +1 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/helpers.ts +4 -1
- package/templates/supplier-payments-agent/packages/agent-core/test/mandate-status.test.ts +85 -9
- package/templates/supplier-payments-agent/packages/agent-core/test/quote.test.ts +198 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/receipt-chain.test.ts +220 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/receipt-read-verification.test.ts +197 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/receivables.test.ts +103 -3
- package/templates/supplier-payments-agent/packages/agent-runtime/README.md +12 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/adversarial.ts +32 -2
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/types.ts +53 -4
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +123 -22
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +30 -20
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +146 -21
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +40 -3
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +8 -1
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +16 -2
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +70 -20
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/poll.ts +2 -1
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/resume.ts +8 -2
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +3 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/start.ts +6 -3
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/verify.ts +239 -38
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/webhook.ts +3 -2
- package/templates/supplier-payments-agent/packages/agent-runtime/src/index.ts +1 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/inspect.ts +5 -1
- package/templates/supplier-payments-agent/packages/agent-runtime/src/kit.ts +25 -2
- package/templates/supplier-payments-agent/packages/agent-runtime/src/scenarios.ts +8 -2
- package/templates/supplier-payments-agent/packages/agent-runtime/src/setup.ts +13 -3
- package/templates/supplier-payments-agent/packages/agent-runtime/src/terminal.ts +127 -18
- package/templates/supplier-payments-agent/packages/agent-runtime/test/verify-cli.test.ts +211 -9
- package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +45 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-session.test.ts +32 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-status-replies.test.ts +182 -0
- package/templates/bills-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +0 -204
- package/templates/collections-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +0 -204
- package/templates/hello-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +0 -204
- package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +0 -204
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* STUB, for runs without a key: the CI, the scenarios and `rerun`, where
|
|
3
|
+
* there is no network. Answers the section 4.7 status check from the local
|
|
4
|
+
* state.db, so a scenario can revoke or pause a mandate mid-run
|
|
5
|
+
* (`before_decision`, `before_execute` in the scenario packs) and the core
|
|
6
|
+
* reacts exactly as it does against the API. Behind the same
|
|
7
|
+
* `MandateStatusSource` interface as `api/mandate-status.ts`, which is what
|
|
8
|
+
* a run with a test key gets instead; this file is never consulted on that
|
|
9
|
+
* path.
|
|
10
|
+
*
|
|
11
|
+
* It also holds the organization kill switch (`pauseAll`), so `org_paused`
|
|
12
|
+
* can be exercised locally the way `GET /v1/mandates/{id}` reports it
|
|
13
|
+
* (ent#1648): a flag next to the mandate's own status, which it leaves alone.
|
|
14
|
+
*/
|
|
15
|
+
import type { MandateStatusSource, MandateStatus, MandateStatusReport } from "../revocation.js";
|
|
16
|
+
import type { StateStore } from "../state/store.js";
|
|
17
|
+
|
|
18
|
+
export const STUB_ORG_ID = "org_local_stub";
|
|
19
|
+
|
|
20
|
+
export class LocalMandateStatusStub implements MandateStatusSource {
|
|
21
|
+
constructor(
|
|
22
|
+
private readonly store: StateStore,
|
|
23
|
+
private readonly clock: () => Date = () => new Date(),
|
|
24
|
+
) {}
|
|
25
|
+
|
|
26
|
+
async check(mandateId: string): Promise<MandateStatusReport> {
|
|
27
|
+
const row = this.store.stubMandateStatus(mandateId);
|
|
28
|
+
return {
|
|
29
|
+
mandate_id: mandateId,
|
|
30
|
+
status: (row?.status as MandateStatus | undefined) ?? "active",
|
|
31
|
+
org_paused: this.store.stubOrgPaused(STUB_ORG_ID),
|
|
32
|
+
checked_at: this.clock().toISOString(),
|
|
33
|
+
source: "stub",
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** `codespar mandate revoke <id>`, locally. */
|
|
38
|
+
revoke(mandateId: string, reason = "revoked by operator"): void {
|
|
39
|
+
this.store.stubSetMandateStatus(mandateId, "revoked", reason, this.clock().toISOString());
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
pause(mandateId: string, reason = "paused by operator"): void {
|
|
43
|
+
this.store.stubSetMandateStatus(mandateId, "paused", reason, this.clock().toISOString());
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
resume(mandateId: string): void {
|
|
47
|
+
this.store.stubSetMandateStatus(mandateId, "active", null, this.clock().toISOString());
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** The organization kill switch, locally. Against the API it is pressed with `POST /v1/orgs/{orgId}/pause`, which the kit never calls. */
|
|
51
|
+
pauseAll(): void {
|
|
52
|
+
this.store.stubSetOrgPaused(STUB_ORG_ID, true, this.clock().toISOString());
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
resumeAll(): void {
|
|
56
|
+
this.store.stubSetOrgPaused(STUB_ORG_ID, false, this.clock().toISOString());
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* STUB rail. A deterministic stand-in for the CodeSpar sandbox so the
|
|
3
|
+
* scenarios, the adversarial suite and the restart test run offline. Every
|
|
4
|
+
* attempt is persisted in state.db before the outcome is returned, which is
|
|
5
|
+
* what lets a process killed right after "the money left" be reconciled on
|
|
6
|
+
* `resume` instead of paying again. A repeat of an attempt id is answered the
|
|
7
|
+
* way the deployed API answers it (ent#1671): replayed when it settled,
|
|
8
|
+
* in flight while the provider is on it, spent when it failed, and refused
|
|
9
|
+
* when the id arrives with a different payment. A stub that simply replayed
|
|
10
|
+
* whatever it held would let a suite pass that the API fails. Receipts here are HMAC-shaped only in
|
|
11
|
+
* form; nothing about them is verifiable by anyone.
|
|
12
|
+
*/
|
|
13
|
+
import { canonicalJson, sha256Hex } from "../hash.js";
|
|
14
|
+
import { checkQuote } from "../quote.js";
|
|
15
|
+
import { checkSpendApproval, type PaymentRail, type RailLookup, type RailOutcome, type RailPayment, type RailReceipt } from "../rail.js";
|
|
16
|
+
import type { StateStore } from "../state/store.js";
|
|
17
|
+
import type { Actor } from "../types.js";
|
|
18
|
+
|
|
19
|
+
export interface StubRailOptions {
|
|
20
|
+
clock?: () => Date;
|
|
21
|
+
/** Payees the stub refuses, to script a `failed` outcome. */
|
|
22
|
+
refusePayees?: string[];
|
|
23
|
+
/** Attempt ids the stub answers `uncertain` for, once. */
|
|
24
|
+
uncertainOnce?: string[];
|
|
25
|
+
/**
|
|
26
|
+
* Payees whose first presentation answers `uncertain`, the way a timeout
|
|
27
|
+
* does: the provider still took the attempt, so a later lookup finds it.
|
|
28
|
+
* The payee twin of `refusePayees`, for scripting an unknown outcome in the
|
|
29
|
+
* MIDDLE of a multi-item execution, where the attempt ids are not known
|
|
30
|
+
* until the execution exists.
|
|
31
|
+
*/
|
|
32
|
+
uncertainPayees?: string[];
|
|
33
|
+
/** Test hook: called after the attempt is persisted and before the outcome is returned. */
|
|
34
|
+
afterDispatch?: (attemptId: string) => void;
|
|
35
|
+
/** Attempt ids whose first lookup answers `in_flight` and whose second lookup finds the provider finished (settled), with no pay() in between. */
|
|
36
|
+
inFlightThenSettled?: string[];
|
|
37
|
+
/**
|
|
38
|
+
* Where the "provider" keeps its books, when that is not the agent's own
|
|
39
|
+
* state file. The real rail is a server two machines share; a test that
|
|
40
|
+
* runs the same batch from two state files points both at one ledger.
|
|
41
|
+
*/
|
|
42
|
+
ledger?: StateStore;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** What the stub's books hold for an attempt the "provider" took and has not finished. */
|
|
46
|
+
const IN_FLIGHT = { status: "in_flight" } as const;
|
|
47
|
+
|
|
48
|
+
type Recorded = RailOutcome | typeof IN_FLIGHT;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The fields a repeat of an attempt id is compared on, the stub's share of
|
|
52
|
+
* the API's attempt tuple (ent#1671): whose money, how much, to whom, the
|
|
53
|
+
* digest of the quote and the approval the spend carried (ent#1670). Rail
|
|
54
|
+
* and instrument are the API's and have no stub counterpart.
|
|
55
|
+
*/
|
|
56
|
+
function mismatchedFields(recorded: Omit<RailPayment, "actor">, asked: Omit<RailPayment, "actor">): string[] {
|
|
57
|
+
const out: string[] = [];
|
|
58
|
+
if (recorded.mandate_id !== asked.mandate_id) out.push("mandate");
|
|
59
|
+
if (recorded.amount_minor !== asked.amount_minor) out.push("amount_minor");
|
|
60
|
+
if (recorded.currency !== asked.currency) out.push("currency");
|
|
61
|
+
if (recorded.payee !== asked.payee) out.push("payee");
|
|
62
|
+
if (canonicalJson(recorded.quote ?? null) !== canonicalJson(asked.quote ?? null)) out.push("quote");
|
|
63
|
+
if (canonicalJson(recorded.approval ?? null) !== canonicalJson(asked.approval ?? null)) out.push("approval");
|
|
64
|
+
return out;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export class StubRail implements PaymentRail {
|
|
68
|
+
readonly name = "stub" as const;
|
|
69
|
+
private readonly clock: () => Date;
|
|
70
|
+
private readonly uncertainPending: Set<string>;
|
|
71
|
+
|
|
72
|
+
private readonly store: StateStore;
|
|
73
|
+
|
|
74
|
+
constructor(
|
|
75
|
+
store: StateStore,
|
|
76
|
+
private readonly options: StubRailOptions = {},
|
|
77
|
+
) {
|
|
78
|
+
this.store = options.ledger ?? store;
|
|
79
|
+
this.clock = options.clock ?? (() => new Date());
|
|
80
|
+
this.uncertainPending = new Set(options.uncertainOnce ?? []);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
private uncertainArmed = false;
|
|
84
|
+
private readonly inFlightSeen = new Set<string>();
|
|
85
|
+
/** Attempts that already gave their one `uncertain`, so a re-presentation behaves normally. */
|
|
86
|
+
private readonly uncertainAnswered = new Set<string>();
|
|
87
|
+
/** How many times pay() reached the point of persisting a NEW attempt. */
|
|
88
|
+
payCount = 0;
|
|
89
|
+
|
|
90
|
+
/** The NEXT new attempt answers `uncertain` once, whatever its id; the provider still took it, so a later lookup sees it in flight and then settled. For scenarios that reconcile. */
|
|
91
|
+
armUncertainOnce(): void {
|
|
92
|
+
this.uncertainArmed = true;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async pay(payment: RailPayment): Promise<RailOutcome> {
|
|
96
|
+
// The same refusal the CodeSpar rail makes before its call, so a scenario exercises it.
|
|
97
|
+
const quoted = checkQuote(payment);
|
|
98
|
+
if (!quoted.ok) return { status: "failed", code: quoted.code, message: `${quoted.detail}; nothing was sent` };
|
|
99
|
+
const approval = checkSpendApproval(payment);
|
|
100
|
+
if (!approval.ok) return { status: "failed", code: approval.code, message: `${approval.detail}; nothing was sent` };
|
|
101
|
+
const { actor: _actor, ...request } = payment;
|
|
102
|
+
const existing = this.store.stubRailGet(payment.attempt_id);
|
|
103
|
+
if (existing) return this.repeat(payment.attempt_id, existing.request as Omit<RailPayment, "actor">, existing.outcome as Recorded, request);
|
|
104
|
+
|
|
105
|
+
const uncertainPayee = this.options.uncertainPayees?.includes(payment.payee) === true && !this.uncertainAnswered.has(payment.attempt_id);
|
|
106
|
+
if (this.uncertainArmed || this.uncertainPending.has(payment.attempt_id) || uncertainPayee) {
|
|
107
|
+
// Armed and payee-scripted attempts were TAKEN by the provider, so they are on its books as in flight; `uncertainOnce` never reached it.
|
|
108
|
+
if (this.uncertainArmed || uncertainPayee) this.store.stubRailPut(payment.attempt_id, request, IN_FLIGHT, this.clock().toISOString());
|
|
109
|
+
this.uncertainAnswered.add(payment.attempt_id);
|
|
110
|
+
this.uncertainArmed = false;
|
|
111
|
+
this.uncertainPending.delete(payment.attempt_id);
|
|
112
|
+
return { status: "uncertain", code: "psp_dispatch_uncertain", message: "stub: outcome unknown on first presentation" };
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const at = this.clock().toISOString();
|
|
116
|
+
const outcome: RailOutcome = this.options.refusePayees?.includes(payment.payee)
|
|
117
|
+
? { status: "failed", code: "psp_dispatch_failed", message: `stub: provider refused payee ${payment.payee}` }
|
|
118
|
+
: settledOutcome(payment.attempt_id, { stub: true, attempt_id: payment.attempt_id, at });
|
|
119
|
+
this.payCount += 1;
|
|
120
|
+
this.store.stubRailPut(payment.attempt_id, request, outcome, at);
|
|
121
|
+
this.options.afterDispatch?.(payment.attempt_id);
|
|
122
|
+
return outcome;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* A presentation of an attempt id the books already hold, answered the way
|
|
127
|
+
* the deployed API answers it (ent#1671, #1683), and never by paying:
|
|
128
|
+
* a different payment under the id is `attempt_id_conflict`, checked before
|
|
129
|
+
* the state; a settled one is its ORIGINAL outcome with `idempotent_replay`;
|
|
130
|
+
* one still in flight is `psp_attempt_in_flight`; a failed one is
|
|
131
|
+
* `psp_attempt_conflict`, spent for good.
|
|
132
|
+
*/
|
|
133
|
+
private repeat(attemptId: string, recorded: Omit<RailPayment, "actor">, outcome: Recorded, asked: Omit<RailPayment, "actor">): RailOutcome {
|
|
134
|
+
const mismatched = mismatchedFields(recorded, asked);
|
|
135
|
+
if (mismatched.length > 0) {
|
|
136
|
+
return { status: "failed", code: "attempt_id_conflict", message: `stub: attempt ${attemptId} was already used for a different payment (differs in: ${mismatched.join(", ")}); nothing was held or sent`, held: "conflict" };
|
|
137
|
+
}
|
|
138
|
+
switch (outcome.status) {
|
|
139
|
+
case "in_flight":
|
|
140
|
+
return { status: "uncertain", code: "psp_attempt_in_flight", message: `stub: attempt ${attemptId} is claimed and its outcome is not yet recorded` };
|
|
141
|
+
case "settled":
|
|
142
|
+
return { ...outcome, replayed: true, raw: { ...(outcome.raw as Record<string, unknown>), idempotent_replay: true } };
|
|
143
|
+
case "failed":
|
|
144
|
+
return { status: "failed", code: "psp_attempt_conflict", message: `stub: attempt ${attemptId} already failed and moved no money; use a fresh attempt_id`, spent: true };
|
|
145
|
+
default:
|
|
146
|
+
return outcome;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
async lookup(attemptId: string, payment: RailPayment): Promise<RailLookup> {
|
|
151
|
+
const { actor: _actor, ...request } = payment;
|
|
152
|
+
const existing = this.store.stubRailGet(attemptId);
|
|
153
|
+
const recorded = existing?.outcome as Recorded | undefined;
|
|
154
|
+
// Looking up IS presenting again on the real rail, so a recorded attempt answers exactly what a repeat of it answers.
|
|
155
|
+
if (existing && recorded && recorded.status !== "in_flight") return this.repeat(attemptId, existing.request as Omit<RailPayment, "actor">, recorded, request);
|
|
156
|
+
if (this.options.inFlightThenSettled?.includes(attemptId) || recorded?.status === "in_flight") {
|
|
157
|
+
if (!this.inFlightSeen.has(attemptId)) {
|
|
158
|
+
this.inFlightSeen.add(attemptId);
|
|
159
|
+
return { status: "in_flight" };
|
|
160
|
+
}
|
|
161
|
+
// The provider finished on its own; the stub records the outcome as the rail would, without a new dispatch.
|
|
162
|
+
const outcome = settledOutcome(attemptId, { stub: true, attempt_id: attemptId, finished_in_background: true });
|
|
163
|
+
this.store.stubRailReplace(attemptId, existing?.request ?? request, outcome, this.clock().toISOString());
|
|
164
|
+
return outcome;
|
|
165
|
+
}
|
|
166
|
+
return undefined;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async receipt(receiptId: string, actor: Actor): Promise<RailReceipt | undefined> {
|
|
170
|
+
const sealed = this.store.stubRailFindByReceipt(receiptId);
|
|
171
|
+
if (!sealed) return undefined;
|
|
172
|
+
const req = sealed.request as Omit<RailPayment, "actor">;
|
|
173
|
+
const out = sealed.outcome as Extract<RailOutcome, { status: "settled" }>;
|
|
174
|
+
// Like the API: the payee on the receipt is the one the quote sealed, and none when the spend carried no quote.
|
|
175
|
+
const body = {
|
|
176
|
+
receipt_id: receiptId,
|
|
177
|
+
state: "paid",
|
|
178
|
+
mandate: { id: req.mandate_id },
|
|
179
|
+
// Like the API since ent#1670: the approval the spend carried is sealed and read back, batch_hash null when none was sent.
|
|
180
|
+
chain_version: req.approval ? 4 : 1,
|
|
181
|
+
approval: req.approval ? { items_hash: req.approval.items_hash, batch_hash: req.approval.batch_hash ?? null } : null,
|
|
182
|
+
payment: { amount_minor: req.amount_minor, payee: req.quote?.payee ?? null, attempt_id: req.attempt_id, money_moved: false, sandbox: true, at: sealed.at },
|
|
183
|
+
};
|
|
184
|
+
const chain = `sha256:${sha256Hex(JSON.stringify(req.quote ? { ...body, quote: req.quote } : body))}`;
|
|
185
|
+
return {
|
|
186
|
+
...body,
|
|
187
|
+
chain,
|
|
188
|
+
receipt_sig: `stub:${sha256Hex(`sig:${chain}`).slice(0, 32)}`,
|
|
189
|
+
// The stub holds no CodeSpar key and must not look as though it did:
|
|
190
|
+
// `npm run verify` answers `unsigned` on a stub receipt, which is the
|
|
191
|
+
// truth about it.
|
|
192
|
+
receipt_sig_ed25519: null,
|
|
193
|
+
receipt_sig_kid: null,
|
|
194
|
+
actor,
|
|
195
|
+
raw: { stub: true, transaction_id: out.transaction_id },
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function settledOutcome(attemptId: string, raw: Record<string, unknown>): RailOutcome {
|
|
201
|
+
return {
|
|
202
|
+
status: "settled",
|
|
203
|
+
transaction_id: `stubtx_${sha256Hex(attemptId).slice(0, 16)}`,
|
|
204
|
+
receipt_id: `rcpt_stub_${sha256Hex(`receipt:${attemptId}`).slice(0, 16)}`,
|
|
205
|
+
money_moved: false,
|
|
206
|
+
sandbox: true,
|
|
207
|
+
raw,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `tools.json`: the closed list of tools the model may call. Tool-level
|
|
3
|
+
* authority comes before mandate-level authority: a tool that is not in
|
|
4
|
+
* this file is refused before anything else looks at the call.
|
|
5
|
+
*
|
|
6
|
+
* Two kinds. `meta_tools` borrow a CodeSpar meta-tool's name for the job
|
|
7
|
+
* they do, but the input shape is the kit's own and the kit's handler runs it:
|
|
8
|
+
* a payment or charge becomes a `drafted` execution, and the core sends the
|
|
9
|
+
* real call over REST. It is not a copy of the MCP's schema and does not match
|
|
10
|
+
* it (OPEN_QUESTIONS section 8 has the comparison). `local_tools` are the
|
|
11
|
+
* agent's own helpers: reads, and state the agent keeps for itself.
|
|
12
|
+
*/
|
|
13
|
+
import { readFileSync } from "node:fs";
|
|
14
|
+
import { z } from "zod";
|
|
15
|
+
import type { ToolSpec } from "./providers/types.js";
|
|
16
|
+
|
|
17
|
+
const ToolDefinitionSchema = z
|
|
18
|
+
.object({
|
|
19
|
+
name: z.string().regex(/^[a-z][a-z0-9_]*$/),
|
|
20
|
+
description: z.string().min(1),
|
|
21
|
+
input_schema: z.record(z.string(), z.unknown()),
|
|
22
|
+
/**
|
|
23
|
+
* `payment` and `charge` tools create a `drafted` execution and nothing
|
|
24
|
+
* else; `read` tools never touch money and change nothing. `charge` is the
|
|
25
|
+
* receivable side: the counterparty pays us. `state` changes durable local
|
|
26
|
+
* state (a cart in `state.db`) and moves no money — not a read, because
|
|
27
|
+
* calling it twice is not calling it once, and not a payment, because no
|
|
28
|
+
* execution comes out of it.
|
|
29
|
+
*/
|
|
30
|
+
effect: z.enum(["payment", "charge", "read", "state"]),
|
|
31
|
+
})
|
|
32
|
+
.strict();
|
|
33
|
+
|
|
34
|
+
export const ToolsFileSchema = z
|
|
35
|
+
.object({
|
|
36
|
+
meta_tools: z.array(ToolDefinitionSchema),
|
|
37
|
+
local_tools: z.array(ToolDefinitionSchema),
|
|
38
|
+
})
|
|
39
|
+
.strict()
|
|
40
|
+
.superRefine((t, ctx) => {
|
|
41
|
+
const names = new Set<string>();
|
|
42
|
+
for (const tool of [...t.meta_tools, ...t.local_tools]) {
|
|
43
|
+
if (names.has(tool.name)) ctx.addIssue({ code: z.ZodIssueCode.custom, message: `duplicate tool ${tool.name}` });
|
|
44
|
+
names.add(tool.name);
|
|
45
|
+
}
|
|
46
|
+
for (const [i, tool] of t.meta_tools.entries()) {
|
|
47
|
+
if (!tool.name.startsWith("codespar_")) ctx.addIssue({ code: z.ZodIssueCode.custom, path: ["meta_tools", i, "name"], message: "meta-tools are named codespar_*" });
|
|
48
|
+
// A meta-tool borrows a CodeSpar name for a job CodeSpar does; the state the agent keeps for itself is not one.
|
|
49
|
+
if (tool.effect === "state") ctx.addIssue({ code: z.ZodIssueCode.custom, path: ["meta_tools", i, "effect"], message: "a state tool is local: meta-tools move money or read" });
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
export type ToolsFile = z.infer<typeof ToolsFileSchema>;
|
|
54
|
+
export type ToolDefinition = z.infer<typeof ToolDefinitionSchema>;
|
|
55
|
+
|
|
56
|
+
export function loadToolsFile(path: string): ToolsFile {
|
|
57
|
+
return ToolsFileSchema.parse(JSON.parse(readFileSync(path, "utf8")));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function toolSpecs(tools: ToolsFile): ToolSpec[] {
|
|
61
|
+
return [...tools.meta_tools, ...tools.local_tools].map((t) => ({ name: t.name, description: t.description, input_schema: t.input_schema }));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function allowedToolNames(tools: ToolsFile): Set<string> {
|
|
65
|
+
return new Set([...tools.meta_tools, ...tools.local_tools].map((t) => t.name));
|
|
66
|
+
}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared shapes of the core. Amounts are always integer minor units (BRL
|
|
3
|
+
* cents). Timestamps are ISO 8601 strings so they survive SQLite and JSON
|
|
4
|
+
* unchanged.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export type ApprovalMode = "human" | "mandate";
|
|
8
|
+
|
|
9
|
+
/** Section 4.5: who acted. Every API call and every receipt carries one. */
|
|
10
|
+
export type Actor =
|
|
11
|
+
| { type: "agent"; agent: string; on_behalf_of: string }
|
|
12
|
+
| { type: "human"; id: string; channel: string };
|
|
13
|
+
|
|
14
|
+
/** One line of an execution: a payee and an amount, resolved by the core. */
|
|
15
|
+
export interface ExecutionItem {
|
|
16
|
+
/** The alias the model used (`escola`), when it used one. */
|
|
17
|
+
alias?: string;
|
|
18
|
+
/** Display name from the mandate's named payees, when known. */
|
|
19
|
+
beneficiary: string;
|
|
20
|
+
/** The pinned payee key (a Pix key for `pix-key` mandates). */
|
|
21
|
+
payee: string;
|
|
22
|
+
amount: number;
|
|
23
|
+
currency: string;
|
|
24
|
+
description?: string;
|
|
25
|
+
/** A receivable's due date (`YYYY-MM-DD`). Part of the `items_hash` when present: moving it after approval is a different charge. */
|
|
26
|
+
due_date?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The SET a line belongs to, when the line is one execution of a batch.
|
|
31
|
+
*
|
|
32
|
+
* A batch of N lines is N executions, each attested by its own `items_hash`.
|
|
33
|
+
* That leaves the list itself unattested: a person who approved four lines
|
|
34
|
+
* while the agent ran three leaves a bundle that does not say a fourth
|
|
35
|
+
* existed. `batch_hash` binds the set — computed once over the ordered lines
|
|
36
|
+
* at the moment the list is presented for approval, and carried by every
|
|
37
|
+
* artifact of that batch together with the line's own position in it.
|
|
38
|
+
*
|
|
39
|
+
* Absent on an execution that is not part of a batch, and an artifact
|
|
40
|
+
* without it is the artifact of section 4.2 unchanged, byte for byte: the
|
|
41
|
+
* field is omitted rather than null, so the canonical payload it signs is
|
|
42
|
+
* the same payload it signed before this existed.
|
|
43
|
+
*/
|
|
44
|
+
export interface ExecutionBatch {
|
|
45
|
+
/** The batch's reference, as the kit names it (`folha-2026-10`). */
|
|
46
|
+
ref: string;
|
|
47
|
+
/** `batchHash` over the batch's ordered lines, as they were presented. */
|
|
48
|
+
batch_hash: string;
|
|
49
|
+
/** This line's position in that ordered list, counting from 0. */
|
|
50
|
+
index: number;
|
|
51
|
+
/** How many lines the presented list held. */
|
|
52
|
+
count: number;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* One line of what an execution's amount is MADE OF, as the kit resolved it:
|
|
57
|
+
* a cart line (`ref` a SKU, a quantity, the unit price the catalog gave it)
|
|
58
|
+
* or a discount line (a negative `amount`). Only `compositionHash` reads it;
|
|
59
|
+
* the core never stores the lines, only their hash and their count.
|
|
60
|
+
*/
|
|
61
|
+
export interface CompositionLine {
|
|
62
|
+
ref: string;
|
|
63
|
+
quantity: number;
|
|
64
|
+
unit_amount: number;
|
|
65
|
+
amount: number;
|
|
66
|
+
currency: string;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* What an execution's single amount was composed from, when it was composed
|
|
71
|
+
* from something: a sale is ONE charge, so ONE item whose amount is the
|
|
72
|
+
* order's total, and the lines of the cart behind that total are not items.
|
|
73
|
+
*
|
|
74
|
+
* That leaves the composition unattested by `items_hash`: two units at 100
|
|
75
|
+
* and one unit at 200 are the same item, the same amount, the same hash.
|
|
76
|
+
* `composition_hash` binds the lines — computed by the kit over the resolved
|
|
77
|
+
* lines in order, carried by the execution and by every artifact of it — so a
|
|
78
|
+
* cart recomposed at a constant total after approval is not the cart that was
|
|
79
|
+
* approved.
|
|
80
|
+
*
|
|
81
|
+
* Absent on an execution that is not composed from anything, and an artifact
|
|
82
|
+
* without it is the artifact of section 4.2 unchanged, byte for byte: the
|
|
83
|
+
* field is omitted rather than null, the same discipline as `batch`.
|
|
84
|
+
*/
|
|
85
|
+
export interface ExecutionComposition {
|
|
86
|
+
/** The kit's reference for what was composed (`cart_id`). */
|
|
87
|
+
ref: string;
|
|
88
|
+
/** `compositionHash` over the resolved lines, in order. */
|
|
89
|
+
composition_hash: string;
|
|
90
|
+
/** How many lines that hash covers. */
|
|
91
|
+
line_count: number;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** The trigger of section 4.4 that sent a `mandate` execution to a human. */
|
|
95
|
+
export type EscalationTrigger = "amount" | "new_beneficiary" | "outside_hours";
|
|
96
|
+
|
|
97
|
+
/** Stable reasons a transition can carry. They are the readable-failure contract. */
|
|
98
|
+
export type ExecutionReason =
|
|
99
|
+
| "mandate_revoked"
|
|
100
|
+
| "mandate_paused"
|
|
101
|
+
| "mandate_expired"
|
|
102
|
+
| "mandate_status_unavailable"
|
|
103
|
+
| "org_paused"
|
|
104
|
+
| "beneficiary_not_allowed"
|
|
105
|
+
| "per_tx_cap_exceeded"
|
|
106
|
+
| "window_cap_exceeded"
|
|
107
|
+
| "approval_expired"
|
|
108
|
+
| "items_hash_mismatch"
|
|
109
|
+
/** The quote a spend would present does not name the approved amount and payee; refused before the call. */
|
|
110
|
+
| "quote_mismatch"
|
|
111
|
+
| "mandate_changed"
|
|
112
|
+
| "denied_by_approver"
|
|
113
|
+
| "rail_failed"
|
|
114
|
+
| "rail_uncertain"
|
|
115
|
+
| "tool_not_allowed"
|
|
116
|
+
| "model_total_mismatch"
|
|
117
|
+
| "outside_hours"
|
|
118
|
+
| "escalated"
|
|
119
|
+
/** The agent's own envelope (guardrails) refused what the model proposed: a discount, an instalment count or a due date outside it. */
|
|
120
|
+
| "outside_envelope"
|
|
121
|
+
/** A receivable was issued and the rail is waiting for the payer; the execution stays `executing` until `commerce.charge.*` closes it. */
|
|
122
|
+
| "awaiting_settlement"
|
|
123
|
+
| "charge_expired"
|
|
124
|
+
| "charge_cancelled"
|
|
125
|
+
/**
|
|
126
|
+
* An ISSUED receivable whose read now answers that its reference matches more than one charge. Terminal for the
|
|
127
|
+
* execution, but not "nothing moved": the charge exists and may still be paid. Reconcile it by the charge id; never
|
|
128
|
+
* issue another to the same payee until that is done, which is why the core refuses one (`policy`).
|
|
129
|
+
*/
|
|
130
|
+
| "charge_reference_ambiguous";
|
|
131
|
+
|
|
132
|
+
export interface MandateRef {
|
|
133
|
+
id: string;
|
|
134
|
+
version: number;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** Section 4.2. */
|
|
138
|
+
export interface ApprovalArtifact {
|
|
139
|
+
approval_id: string;
|
|
140
|
+
execution_id: string;
|
|
141
|
+
mode: ApprovalMode;
|
|
142
|
+
approver:
|
|
143
|
+
| { type: "person"; id: string; channel: string }
|
|
144
|
+
| { type: "mandate"; id: string };
|
|
145
|
+
approved_at: string;
|
|
146
|
+
expires_at: string;
|
|
147
|
+
mandate: MandateRef;
|
|
148
|
+
items: ExecutionItem[];
|
|
149
|
+
items_hash: string;
|
|
150
|
+
/** Present when this execution is one line of a batch: what binds the SET this line was approved inside. */
|
|
151
|
+
batch?: ExecutionBatch;
|
|
152
|
+
/** Present when this execution's amount is composed of lines (a cart): what binds the composition that was approved. */
|
|
153
|
+
composition?: ExecutionComposition;
|
|
154
|
+
/** Present when a section 4.4 trigger sent the execution to a human first. */
|
|
155
|
+
escalation?: { trigger: EscalationTrigger; detail: string };
|
|
156
|
+
actor: Actor;
|
|
157
|
+
signature: { alg: "HMAC-SHA256"; key_id: string; value: string };
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export interface ItemOutcome {
|
|
161
|
+
index: number;
|
|
162
|
+
attempt_id: string;
|
|
163
|
+
/** `accepted`: the rail took the attempt and the outcome comes later (a receivable waiting for its payer). Not terminal. */
|
|
164
|
+
status: "settled" | "failed" | "accepted";
|
|
165
|
+
receipt_id?: string;
|
|
166
|
+
transaction_id?: string;
|
|
167
|
+
/** The rail's code on a failed outcome (`charge_expired`, `charge_cancelled`, a provider code). */
|
|
168
|
+
code?: string;
|
|
169
|
+
/** A failed outcome because the attempt id is held for another payment or another project (`RailOutcome.held`). */
|
|
170
|
+
held?: "conflict" | "unavailable";
|
|
171
|
+
/** A settled outcome the rail answered from its record of an earlier presentation (`RailOutcome.replayed`). */
|
|
172
|
+
replayed?: true;
|
|
173
|
+
error?: string;
|
|
174
|
+
/** What the payer is shown for an accepted receivable, as the rail handed it back. Presentation only; nothing here decides money. */
|
|
175
|
+
instrument?: ChargeInstrument;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** The payable legs of a receivable. Null until the issuer registers the instrument (a cobranca com vencimento answers PROCESSING first). */
|
|
179
|
+
export interface ChargeInstrument {
|
|
180
|
+
payable: boolean;
|
|
181
|
+
pix_copy_paste: string | null;
|
|
182
|
+
boleto_bank_line: string | null;
|
|
183
|
+
boleto_bar_code: string | null;
|
|
184
|
+
due_date: string | null;
|
|
185
|
+
/** The issuer's normalized state as last read: PROCESSING, PENDING, CONFIRMED, EXPIRED, CANCELLED. */
|
|
186
|
+
status: string;
|
|
187
|
+
}
|