@codespar/cli 0.18.0 → 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.
- package/README.md +1 -1
- package/dist/commands/login.js +52 -12
- package/dist/commands/login.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/surface.js +79 -9
- package/dist/surface.js.map +1 -1
- package/package.json +1 -1
- package/templates/bills-agent/README.md +2 -2
- package/templates/bills-agent/agents/bills-agent/.env.example +2 -2
- package/templates/bills-agent/agents/bills-agent/README.md +25 -18
- package/templates/bills-agent/agents/bills-agent/SYSTEM_PROMPT.md +13 -3
- package/templates/bills-agent/agents/bills-agent/agent.yaml +2 -1
- package/templates/bills-agent/agents/bills-agent/evals/adversarial/exfiltration.transcript.jsonl +1 -1
- package/templates/bills-agent/agents/bills-agent/evals/adversarial/false-authority.transcript.jsonl +1 -1
- package/templates/bills-agent/agents/bills-agent/evals/adversarial/prompt-injection.transcript.jsonl +1 -1
- package/templates/bills-agent/agents/bills-agent/mandate.example.json +1 -1
- package/templates/bills-agent/agents/bills-agent/runbook.md +1 -1
- package/templates/bills-agent/agents/bills-agent/scenarios/beneficiary-not-allowed.transcript.jsonl +1 -1
- package/templates/bills-agent/agents/bills-agent/scenarios/cap-exceeded.transcript.jsonl +1 -1
- package/templates/bills-agent/agents/bills-agent/scenarios/escalated-above-threshold.transcript.jsonl +4 -4
- package/templates/bills-agent/agents/bills-agent/scenarios/happy-path.transcript.jsonl +1 -1
- package/templates/bills-agent/agents/bills-agent/scenarios/mandate-revoked.json +1 -1
- package/templates/bills-agent/agents/bills-agent/scenarios/mandate-revoked.transcript.jsonl +4 -4
- package/templates/bills-agent/agents/bills-agent/scenarios/prompt-injection.transcript.jsonl +1 -1
- package/templates/bills-agent/agents/bills-agent/src/bills.ts +1 -1
- package/templates/bills-agent/agents/bills-agent/src/kit.ts +15 -28
- package/templates/bills-agent/agents/bills-agent/src/modules/embedded-consent.ts +42 -15
- package/templates/bills-agent/agents/bills-agent/src/modules/pix-out.ts +21 -3
- package/templates/bills-agent/agents/bills-agent/src/strings.ts +68 -0
- package/templates/bills-agent/agents/bills-agent/test/cli.test.ts +130 -2
- package/templates/bills-agent/agents/bills-agent/test/consent-money.test.ts +25 -0
- package/templates/bills-agent/agents/bills-agent/test/dates-and-approval.test.ts +98 -0
- package/templates/bills-agent/agents/bills-agent/test/eval-runs.test.ts +81 -0
- package/templates/bills-agent/agents/bills-agent/test/fixtures/excursao-300.transcript.jsonl +2 -2
- package/templates/bills-agent/agents/bills-agent/test/fixtures/material-400.transcript.jsonl +1 -1
- package/templates/bills-agent/agents/bills-agent/test/locale.test.ts +161 -0
- package/templates/bills-agent/agents/bills-agent/test/mandate-state.test.ts +108 -0
- package/templates/bills-agent/agents/bills-agent/test/refused-before-draft.test.ts +81 -0
- package/templates/bills-agent/agents/bills-agent/test/replay.test.ts +76 -0
- package/templates/bills-agent/agents/bills-agent/test/reply-and-outcome.test.ts +84 -0
- package/templates/bills-agent/agents/bills-agent/test/reply-language.test.ts +95 -0
- package/templates/bills-agent/agents/bills-agent/test/rerun-and-missing-transcript.test.ts +120 -0
- package/templates/bills-agent/agents/bills-agent/test/rerun-world-events.test.ts +55 -0
- package/templates/bills-agent/agents/bills-agent/tools.json +1 -1
- package/templates/bills-agent/packages/agent-core/README.md +21 -2
- package/templates/bills-agent/packages/agent-core/package.json +1 -1
- package/templates/bills-agent/packages/agent-core/src/agent.ts +33 -6
- package/templates/bills-agent/packages/agent-core/src/api/charge-rail.ts +15 -1
- package/templates/bills-agent/packages/agent-core/src/api/rail.ts +11 -5
- package/templates/bills-agent/packages/agent-core/src/api/sandbox-payer.ts +36 -0
- package/templates/bills-agent/packages/agent-core/src/bundle.ts +2 -0
- package/templates/bills-agent/packages/agent-core/src/channels.ts +18 -8
- package/templates/bills-agent/packages/agent-core/src/check.ts +25 -3
- package/templates/bills-agent/packages/agent-core/src/engine.ts +90 -9
- package/templates/bills-agent/packages/agent-core/src/escalate.ts +10 -0
- package/templates/bills-agent/packages/agent-core/src/index.ts +3 -0
- package/templates/bills-agent/packages/agent-core/src/language.ts +52 -0
- package/templates/bills-agent/packages/agent-core/src/locale.ts +88 -0
- package/templates/bills-agent/packages/agent-core/src/manifest.ts +4 -1
- package/templates/bills-agent/packages/agent-core/src/rail.ts +29 -1
- package/templates/bills-agent/packages/agent-core/src/receipt-verification.ts +30 -2
- package/templates/bills-agent/packages/agent-core/src/secrets.ts +53 -8
- package/templates/bills-agent/packages/agent-core/src/state-machine.ts +14 -0
- package/templates/bills-agent/packages/agent-core/src/strings.ts +175 -0
- package/templates/bills-agent/packages/agent-core/src/stubs/charge-rail.ts +15 -2
- package/templates/bills-agent/packages/agent-core/src/stubs/rail.ts +7 -4
- package/templates/bills-agent/packages/agent-core/src/types.ts +15 -2
- package/templates/bills-agent/packages/agent-core/test/actor-on-the-wire.test.ts +144 -0
- package/templates/bills-agent/packages/agent-core/test/attempt-replay.test.ts +2 -2
- package/templates/bills-agent/packages/agent-core/test/engine.test.ts +23 -0
- package/templates/bills-agent/packages/agent-core/test/helpers.ts +1 -1
- package/templates/bills-agent/packages/agent-core/test/language.test.ts +40 -0
- package/templates/bills-agent/packages/agent-core/test/locale.test.ts +137 -0
- package/templates/bills-agent/packages/agent-core/test/mandate-status.test.ts +2 -2
- package/templates/bills-agent/packages/agent-core/test/manifest.test.ts +2 -2
- package/templates/bills-agent/packages/agent-core/test/rail-errors.test.ts +74 -0
- package/templates/bills-agent/packages/agent-core/test/receipt-read-verification.test.ts +32 -0
- package/templates/bills-agent/packages/agent-core/test/receivables.test.ts +49 -0
- package/templates/bills-agent/packages/agent-core/test/recorded-turns.ts +29 -0
- package/templates/bills-agent/packages/agent-core/test/secrets.test.ts +40 -1
- package/templates/bills-agent/packages/agent-runtime/README.md +31 -4
- package/templates/bills-agent/packages/agent-runtime/src/channels/rules.ts +4 -2
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +11 -5
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +43 -21
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +3 -0
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +8 -12
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +8 -4
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +12 -9
- package/templates/bills-agent/packages/agent-runtime/src/cli.ts +30 -4
- package/templates/bills-agent/packages/agent-runtime/src/commands/check.ts +18 -2
- package/templates/bills-agent/packages/agent-runtime/src/commands/decide.ts +13 -4
- package/templates/bills-agent/packages/agent-runtime/src/commands/eval.ts +7 -2
- package/templates/bills-agent/packages/agent-runtime/src/commands/inspect.ts +11 -13
- package/templates/bills-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +32 -24
- package/templates/bills-agent/packages/agent-runtime/src/commands/poll.ts +12 -5
- package/templates/bills-agent/packages/agent-runtime/src/commands/rerun.ts +83 -10
- package/templates/bills-agent/packages/agent-runtime/src/commands/resume.ts +2 -1
- package/templates/bills-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +10 -5
- package/templates/bills-agent/packages/agent-runtime/src/commands/start.ts +48 -17
- package/templates/bills-agent/packages/agent-runtime/src/commands/verify.ts +37 -12
- package/templates/bills-agent/packages/agent-runtime/src/commands/webhook.ts +11 -3
- package/templates/bills-agent/packages/agent-runtime/src/default-kit.ts +52 -22
- package/templates/bills-agent/packages/agent-runtime/src/env.ts +64 -0
- package/templates/bills-agent/packages/agent-runtime/src/index.ts +2 -0
- package/templates/bills-agent/packages/agent-runtime/src/inspect.ts +81 -10
- package/templates/bills-agent/packages/agent-runtime/src/kit.ts +34 -12
- package/templates/bills-agent/packages/agent-runtime/src/outcome.ts +118 -0
- package/templates/bills-agent/packages/agent-runtime/src/poll.ts +7 -7
- package/templates/bills-agent/packages/agent-runtime/src/runs.ts +51 -0
- package/templates/bills-agent/packages/agent-runtime/src/scenarios.ts +55 -8
- package/templates/bills-agent/packages/agent-runtime/src/setup.ts +75 -5
- package/templates/bills-agent/packages/agent-runtime/src/terminal.ts +71 -33
- package/templates/bills-agent/packages/agent-runtime/test/env-names.test.ts +56 -0
- package/templates/bills-agent/packages/agent-runtime/test/inspect-mandate-status.test.ts +80 -0
- package/templates/bills-agent/packages/agent-runtime/test/inspect.test.ts +63 -2
- package/templates/bills-agent/packages/agent-runtime/test/outcome.test.ts +72 -0
- package/templates/bills-agent/packages/agent-runtime/test/poll-payer.test.ts +64 -0
- package/templates/bills-agent/packages/agent-runtime/test/rerun-not-replayed.test.ts +46 -0
- package/templates/bills-agent/packages/agent-runtime/test/transition-line.test.ts +29 -0
- package/templates/bills-agent/packages/agent-runtime/test/verify-cli.test.ts +99 -6
- package/templates/bills-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +8 -0
- package/templates/bills-agent/packages/agent-runtime/test/whatsapp-session.test.ts +77 -0
- package/templates/bills-agent/packages/agent-runtime/test/whatsapp-status-replies.test.ts +27 -1
- package/templates/checkout-agent/README.md +2 -2
- package/templates/checkout-agent/agents/checkout-agent/.env.example +6 -4
- package/templates/checkout-agent/agents/checkout-agent/README.md +16 -8
- package/templates/checkout-agent/agents/checkout-agent/SYSTEM_PROMPT.md +17 -7
- package/templates/checkout-agent/agents/checkout-agent/agent.yaml +4 -3
- package/templates/checkout-agent/agents/checkout-agent/channels/whatsapp/README.md +2 -2
- package/templates/checkout-agent/agents/checkout-agent/channels/whatsapp/templates.json +48 -4
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/beneficiary-swap-human.json +1 -1
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/beneficiary-swap.json +1 -1
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/beneficiary-swap.transcript.jsonl +1 -1
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/coupon-unknown.json +1 -1
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/exfiltration.transcript.jsonl +1 -1
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/fractioning.transcript.jsonl +1 -1
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/payment-claimed.json +1 -1
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/payment-claimed.transcript.jsonl +1 -1
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/price-injected.json +1 -1
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/prompt-injection.transcript.jsonl +1 -1
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/quantity-swapped.transcript.jsonl +1 -1
- package/templates/checkout-agent/agents/checkout-agent/package.json +1 -1
- package/templates/checkout-agent/agents/checkout-agent/runbook.md +4 -4
- package/templates/checkout-agent/agents/checkout-agent/scenarios/beneficiary-not-allowed.transcript.jsonl +1 -1
- package/templates/checkout-agent/agents/checkout-agent/scenarios/cart-recomposed.transcript.jsonl +2 -2
- package/templates/checkout-agent/agents/checkout-agent/scenarios/cart-replaced.json +2 -2
- package/templates/checkout-agent/agents/checkout-agent/scenarios/cart-replaced.transcript.jsonl +2 -2
- package/templates/checkout-agent/agents/checkout-agent/scenarios/charge-expired.json +1 -1
- package/templates/checkout-agent/agents/checkout-agent/scenarios/charge-expired.transcript.jsonl +2 -2
- package/templates/checkout-agent/agents/checkout-agent/scenarios/coupon-unknown.transcript.jsonl +1 -1
- package/templates/checkout-agent/agents/checkout-agent/scenarios/escalated-above-threshold.transcript.jsonl +1 -1
- package/templates/checkout-agent/agents/checkout-agent/scenarios/happy-path.transcript.jsonl +2 -2
- package/templates/checkout-agent/agents/checkout-agent/scenarios/item-unavailable.transcript.jsonl +1 -1
- package/templates/checkout-agent/agents/checkout-agent/scenarios/mandate-revoked.transcript.jsonl +3 -3
- package/templates/checkout-agent/agents/checkout-agent/scenarios/payment-claimed.json +1 -1
- package/templates/checkout-agent/agents/checkout-agent/scenarios/payment-claimed.transcript.jsonl +2 -2
- package/templates/checkout-agent/agents/checkout-agent/scenarios/price-injected.transcript.jsonl +1 -1
- package/templates/checkout-agent/agents/checkout-agent/scenarios/prompt-injection.transcript.jsonl +1 -1
- package/templates/checkout-agent/agents/checkout-agent/src/catalog.ts +7 -7
- package/templates/checkout-agent/agents/checkout-agent/src/kit.ts +47 -43
- package/templates/checkout-agent/agents/checkout-agent/src/modules/bolepix-receivables.ts +20 -12
- package/templates/checkout-agent/agents/checkout-agent/src/modules/nfse-invoice.ts +4 -4
- package/templates/checkout-agent/agents/checkout-agent/src/modules/storefront-cart.ts +9 -6
- package/templates/checkout-agent/agents/checkout-agent/src/pricing.ts +44 -41
- package/templates/checkout-agent/agents/checkout-agent/src/strings.ts +179 -0
- package/templates/checkout-agent/agents/checkout-agent/test/check.test.ts +4 -1
- package/templates/checkout-agent/agents/checkout-agent/test/fixtures/order-marina.transcript.jsonl +1 -1
- package/templates/checkout-agent/agents/checkout-agent/test/fixtures/ordered-marina-awaiting-payer.transcript.jsonl +2 -2
- package/templates/checkout-agent/agents/checkout-agent/test/fixtures/tap-falar-agora-marina.transcript.jsonl +1 -1
- package/templates/checkout-agent/agents/checkout-agent/test/payable-instrument.test.ts +58 -0
- package/templates/checkout-agent/agents/checkout-agent/test/pricing.test.ts +2 -2
- package/templates/checkout-agent/agents/checkout-agent/test/rerun-unpaid.test.ts +47 -0
- package/templates/checkout-agent/agents/checkout-agent/test/scenario-reach-and-seconds.test.ts +55 -0
- package/templates/checkout-agent/agents/checkout-agent/test/whatsapp.test.ts +26 -10
- package/templates/checkout-agent/agents/checkout-agent/tools.json +1 -1
- package/templates/checkout-agent/packages/agent-core/README.md +21 -2
- package/templates/checkout-agent/packages/agent-core/package.json +1 -1
- package/templates/checkout-agent/packages/agent-core/src/agent.ts +33 -6
- package/templates/checkout-agent/packages/agent-core/src/api/charge-rail.ts +15 -1
- package/templates/checkout-agent/packages/agent-core/src/api/rail.ts +11 -5
- package/templates/checkout-agent/packages/agent-core/src/api/sandbox-payer.ts +36 -0
- package/templates/checkout-agent/packages/agent-core/src/bundle.ts +2 -0
- package/templates/checkout-agent/packages/agent-core/src/channels.ts +18 -8
- package/templates/checkout-agent/packages/agent-core/src/check.ts +25 -3
- package/templates/checkout-agent/packages/agent-core/src/engine.ts +90 -9
- package/templates/checkout-agent/packages/agent-core/src/escalate.ts +10 -0
- package/templates/checkout-agent/packages/agent-core/src/index.ts +3 -0
- package/templates/checkout-agent/packages/agent-core/src/language.ts +52 -0
- package/templates/checkout-agent/packages/agent-core/src/locale.ts +88 -0
- package/templates/checkout-agent/packages/agent-core/src/manifest.ts +4 -1
- package/templates/checkout-agent/packages/agent-core/src/rail.ts +29 -1
- package/templates/checkout-agent/packages/agent-core/src/receipt-verification.ts +30 -2
- package/templates/checkout-agent/packages/agent-core/src/secrets.ts +53 -8
- package/templates/checkout-agent/packages/agent-core/src/state-machine.ts +14 -0
- package/templates/checkout-agent/packages/agent-core/src/strings.ts +175 -0
- package/templates/checkout-agent/packages/agent-core/src/stubs/charge-rail.ts +15 -2
- package/templates/checkout-agent/packages/agent-core/src/stubs/rail.ts +7 -4
- package/templates/checkout-agent/packages/agent-core/src/types.ts +15 -2
- package/templates/checkout-agent/packages/agent-core/test/actor-on-the-wire.test.ts +144 -0
- package/templates/checkout-agent/packages/agent-core/test/attempt-replay.test.ts +2 -2
- package/templates/checkout-agent/packages/agent-core/test/engine.test.ts +23 -0
- package/templates/checkout-agent/packages/agent-core/test/helpers.ts +1 -1
- package/templates/checkout-agent/packages/agent-core/test/language.test.ts +40 -0
- package/templates/checkout-agent/packages/agent-core/test/locale.test.ts +137 -0
- package/templates/checkout-agent/packages/agent-core/test/mandate-status.test.ts +2 -2
- package/templates/checkout-agent/packages/agent-core/test/manifest.test.ts +2 -2
- package/templates/checkout-agent/packages/agent-core/test/rail-errors.test.ts +74 -0
- package/templates/checkout-agent/packages/agent-core/test/receipt-read-verification.test.ts +32 -0
- package/templates/checkout-agent/packages/agent-core/test/receivables.test.ts +49 -0
- package/templates/checkout-agent/packages/agent-core/test/recorded-turns.ts +29 -0
- package/templates/checkout-agent/packages/agent-core/test/secrets.test.ts +40 -1
- package/templates/checkout-agent/packages/agent-runtime/README.md +31 -4
- package/templates/checkout-agent/packages/agent-runtime/src/channels/rules.ts +4 -2
- package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +11 -5
- package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +43 -21
- package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +3 -0
- package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +8 -12
- package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +8 -4
- package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +12 -9
- package/templates/checkout-agent/packages/agent-runtime/src/cli.ts +30 -4
- package/templates/checkout-agent/packages/agent-runtime/src/commands/check.ts +18 -2
- package/templates/checkout-agent/packages/agent-runtime/src/commands/decide.ts +13 -4
- package/templates/checkout-agent/packages/agent-runtime/src/commands/eval.ts +7 -2
- package/templates/checkout-agent/packages/agent-runtime/src/commands/inspect.ts +11 -13
- package/templates/checkout-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +32 -24
- package/templates/checkout-agent/packages/agent-runtime/src/commands/poll.ts +12 -5
- package/templates/checkout-agent/packages/agent-runtime/src/commands/rerun.ts +83 -10
- package/templates/checkout-agent/packages/agent-runtime/src/commands/resume.ts +2 -1
- package/templates/checkout-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +10 -5
- package/templates/checkout-agent/packages/agent-runtime/src/commands/start.ts +48 -17
- package/templates/checkout-agent/packages/agent-runtime/src/commands/verify.ts +37 -12
- package/templates/checkout-agent/packages/agent-runtime/src/commands/webhook.ts +11 -3
- package/templates/checkout-agent/packages/agent-runtime/src/default-kit.ts +52 -22
- package/templates/checkout-agent/packages/agent-runtime/src/env.ts +64 -0
- package/templates/checkout-agent/packages/agent-runtime/src/index.ts +2 -0
- package/templates/checkout-agent/packages/agent-runtime/src/inspect.ts +81 -10
- package/templates/checkout-agent/packages/agent-runtime/src/kit.ts +34 -12
- package/templates/checkout-agent/packages/agent-runtime/src/outcome.ts +118 -0
- package/templates/checkout-agent/packages/agent-runtime/src/poll.ts +7 -7
- package/templates/checkout-agent/packages/agent-runtime/src/runs.ts +51 -0
- package/templates/checkout-agent/packages/agent-runtime/src/scenarios.ts +55 -8
- package/templates/checkout-agent/packages/agent-runtime/src/setup.ts +75 -5
- package/templates/checkout-agent/packages/agent-runtime/src/terminal.ts +71 -33
- package/templates/checkout-agent/packages/agent-runtime/test/env-names.test.ts +56 -0
- package/templates/checkout-agent/packages/agent-runtime/test/inspect-mandate-status.test.ts +80 -0
- package/templates/checkout-agent/packages/agent-runtime/test/inspect.test.ts +63 -2
- package/templates/checkout-agent/packages/agent-runtime/test/outcome.test.ts +72 -0
- package/templates/checkout-agent/packages/agent-runtime/test/poll-payer.test.ts +64 -0
- package/templates/checkout-agent/packages/agent-runtime/test/rerun-not-replayed.test.ts +46 -0
- package/templates/checkout-agent/packages/agent-runtime/test/transition-line.test.ts +29 -0
- package/templates/checkout-agent/packages/agent-runtime/test/verify-cli.test.ts +99 -6
- package/templates/checkout-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +8 -0
- package/templates/checkout-agent/packages/agent-runtime/test/whatsapp-session.test.ts +77 -0
- package/templates/checkout-agent/packages/agent-runtime/test/whatsapp-status-replies.test.ts +27 -1
- package/templates/collections-agent/README.md +2 -2
- package/templates/collections-agent/agents/collections-agent/.env.example +6 -3
- package/templates/collections-agent/agents/collections-agent/README.md +14 -9
- package/templates/collections-agent/agents/collections-agent/SYSTEM_PROMPT.md +16 -5
- package/templates/collections-agent/agents/collections-agent/agent.yaml +4 -3
- package/templates/collections-agent/agents/collections-agent/channels/whatsapp/README.md +21 -4
- package/templates/collections-agent/agents/collections-agent/channels/whatsapp/templates.json +49 -5
- package/templates/collections-agent/agents/collections-agent/mandate.example.json +1 -1
- package/templates/collections-agent/agents/collections-agent/runbook.md +3 -3
- package/templates/collections-agent/agents/collections-agent/src/agreements.ts +1 -1
- package/templates/collections-agent/agents/collections-agent/src/envelope.ts +15 -13
- package/templates/collections-agent/agents/collections-agent/src/kit.ts +38 -35
- package/templates/collections-agent/agents/collections-agent/src/modules/bolepix-receivables.ts +16 -8
- package/templates/collections-agent/agents/collections-agent/src/strings.ts +91 -0
- package/templates/collections-agent/agents/collections-agent/test/ambiguous-charge.test.ts +2 -2
- package/templates/collections-agent/agents/collections-agent/test/check.test.ts +4 -1
- package/templates/collections-agent/agents/collections-agent/test/cli.test.ts +1 -1
- package/templates/collections-agent/agents/collections-agent/test/envelope.test.ts +2 -2
- package/templates/collections-agent/agents/collections-agent/test/fixtures/accept-1103.transcript.jsonl +1 -1
- package/templates/collections-agent/agents/collections-agent/test/fixtures/tap-emitir-nova-1042.transcript.jsonl +1 -1
- package/templates/collections-agent/agents/collections-agent/test/payable-instrument.test.ts +56 -0
- package/templates/collections-agent/agents/collections-agent/test/rerun-clock.test.ts +54 -0
- package/templates/collections-agent/agents/collections-agent/test/whatsapp-poll.test.ts +69 -2
- package/templates/collections-agent/agents/collections-agent/test/whatsapp-status-replies.test.ts +16 -3
- package/templates/collections-agent/agents/collections-agent/test/whatsapp.test.ts +16 -4
- package/templates/collections-agent/agents/collections-agent/tools.json +2 -2
- package/templates/collections-agent/packages/agent-core/README.md +21 -2
- package/templates/collections-agent/packages/agent-core/package.json +1 -1
- package/templates/collections-agent/packages/agent-core/src/agent.ts +33 -6
- package/templates/collections-agent/packages/agent-core/src/api/charge-rail.ts +15 -1
- package/templates/collections-agent/packages/agent-core/src/api/rail.ts +11 -5
- package/templates/collections-agent/packages/agent-core/src/api/sandbox-payer.ts +36 -0
- package/templates/collections-agent/packages/agent-core/src/bundle.ts +2 -0
- package/templates/collections-agent/packages/agent-core/src/channels.ts +18 -8
- package/templates/collections-agent/packages/agent-core/src/check.ts +25 -3
- package/templates/collections-agent/packages/agent-core/src/engine.ts +90 -9
- package/templates/collections-agent/packages/agent-core/src/escalate.ts +10 -0
- package/templates/collections-agent/packages/agent-core/src/index.ts +3 -0
- package/templates/collections-agent/packages/agent-core/src/language.ts +52 -0
- package/templates/collections-agent/packages/agent-core/src/locale.ts +88 -0
- package/templates/collections-agent/packages/agent-core/src/manifest.ts +4 -1
- package/templates/collections-agent/packages/agent-core/src/rail.ts +29 -1
- package/templates/collections-agent/packages/agent-core/src/receipt-verification.ts +30 -2
- package/templates/collections-agent/packages/agent-core/src/secrets.ts +53 -8
- package/templates/collections-agent/packages/agent-core/src/state-machine.ts +14 -0
- package/templates/collections-agent/packages/agent-core/src/strings.ts +175 -0
- package/templates/collections-agent/packages/agent-core/src/stubs/charge-rail.ts +15 -2
- package/templates/collections-agent/packages/agent-core/src/stubs/rail.ts +7 -4
- package/templates/collections-agent/packages/agent-core/src/types.ts +15 -2
- package/templates/collections-agent/packages/agent-core/test/actor-on-the-wire.test.ts +144 -0
- package/templates/collections-agent/packages/agent-core/test/attempt-replay.test.ts +2 -2
- package/templates/collections-agent/packages/agent-core/test/engine.test.ts +23 -0
- package/templates/collections-agent/packages/agent-core/test/helpers.ts +1 -1
- package/templates/collections-agent/packages/agent-core/test/language.test.ts +40 -0
- package/templates/collections-agent/packages/agent-core/test/locale.test.ts +137 -0
- package/templates/collections-agent/packages/agent-core/test/mandate-status.test.ts +2 -2
- package/templates/collections-agent/packages/agent-core/test/manifest.test.ts +2 -2
- package/templates/collections-agent/packages/agent-core/test/rail-errors.test.ts +74 -0
- package/templates/collections-agent/packages/agent-core/test/receipt-read-verification.test.ts +32 -0
- package/templates/collections-agent/packages/agent-core/test/receivables.test.ts +49 -0
- package/templates/collections-agent/packages/agent-core/test/recorded-turns.ts +29 -0
- package/templates/collections-agent/packages/agent-core/test/secrets.test.ts +40 -1
- package/templates/collections-agent/packages/agent-runtime/README.md +31 -4
- package/templates/collections-agent/packages/agent-runtime/src/channels/rules.ts +4 -2
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +11 -5
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +43 -21
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +3 -0
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +8 -12
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +8 -4
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +12 -9
- package/templates/collections-agent/packages/agent-runtime/src/cli.ts +30 -4
- package/templates/collections-agent/packages/agent-runtime/src/commands/check.ts +18 -2
- package/templates/collections-agent/packages/agent-runtime/src/commands/decide.ts +13 -4
- package/templates/collections-agent/packages/agent-runtime/src/commands/eval.ts +7 -2
- package/templates/collections-agent/packages/agent-runtime/src/commands/inspect.ts +11 -13
- package/templates/collections-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +32 -24
- package/templates/collections-agent/packages/agent-runtime/src/commands/poll.ts +12 -5
- package/templates/collections-agent/packages/agent-runtime/src/commands/rerun.ts +83 -10
- package/templates/collections-agent/packages/agent-runtime/src/commands/resume.ts +2 -1
- package/templates/collections-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +10 -5
- package/templates/collections-agent/packages/agent-runtime/src/commands/start.ts +48 -17
- package/templates/collections-agent/packages/agent-runtime/src/commands/verify.ts +37 -12
- package/templates/collections-agent/packages/agent-runtime/src/commands/webhook.ts +11 -3
- package/templates/collections-agent/packages/agent-runtime/src/default-kit.ts +52 -22
- package/templates/collections-agent/packages/agent-runtime/src/env.ts +64 -0
- package/templates/collections-agent/packages/agent-runtime/src/index.ts +2 -0
- package/templates/collections-agent/packages/agent-runtime/src/inspect.ts +81 -10
- package/templates/collections-agent/packages/agent-runtime/src/kit.ts +34 -12
- package/templates/collections-agent/packages/agent-runtime/src/outcome.ts +118 -0
- package/templates/collections-agent/packages/agent-runtime/src/poll.ts +7 -7
- package/templates/collections-agent/packages/agent-runtime/src/runs.ts +51 -0
- package/templates/collections-agent/packages/agent-runtime/src/scenarios.ts +55 -8
- package/templates/collections-agent/packages/agent-runtime/src/setup.ts +75 -5
- package/templates/collections-agent/packages/agent-runtime/src/terminal.ts +71 -33
- package/templates/collections-agent/packages/agent-runtime/test/env-names.test.ts +56 -0
- package/templates/collections-agent/packages/agent-runtime/test/inspect-mandate-status.test.ts +80 -0
- package/templates/collections-agent/packages/agent-runtime/test/inspect.test.ts +63 -2
- package/templates/collections-agent/packages/agent-runtime/test/outcome.test.ts +72 -0
- package/templates/collections-agent/packages/agent-runtime/test/poll-payer.test.ts +64 -0
- package/templates/collections-agent/packages/agent-runtime/test/rerun-not-replayed.test.ts +46 -0
- package/templates/collections-agent/packages/agent-runtime/test/transition-line.test.ts +29 -0
- package/templates/collections-agent/packages/agent-runtime/test/verify-cli.test.ts +99 -6
- package/templates/collections-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +8 -0
- package/templates/collections-agent/packages/agent-runtime/test/whatsapp-session.test.ts +77 -0
- package/templates/collections-agent/packages/agent-runtime/test/whatsapp-status-replies.test.ts +27 -1
- package/templates/hello-agent/README.md +2 -2
- package/templates/hello-agent/agents/hello-agent/README.md +6 -0
- package/templates/hello-agent/agents/hello-agent/SYSTEM_PROMPT.md +27 -13
- package/templates/hello-agent/agents/hello-agent/agent.yaml +2 -1
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/exfiltration.transcript.jsonl +1 -1
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/prompt-injection.transcript.jsonl +1 -1
- package/templates/hello-agent/agents/hello-agent/mandate.example.json +1 -1
- package/templates/hello-agent/agents/hello-agent/scenarios/happy-path.json +1 -1
- package/templates/hello-agent/agents/hello-agent/scenarios/happy-path.transcript.jsonl +1 -1
- package/templates/hello-agent/agents/hello-agent/scenarios/prompt-injection.json +1 -1
- package/templates/hello-agent/agents/hello-agent/scenarios/prompt-injection.transcript.jsonl +1 -1
- package/templates/hello-agent/agents/hello-agent/src/bills.ts +9 -5
- package/templates/hello-agent/agents/hello-agent/src/kit.ts +4 -1
- package/templates/hello-agent/agents/hello-agent/tools.json +1 -1
- package/templates/hello-agent/packages/agent-core/README.md +21 -2
- package/templates/hello-agent/packages/agent-core/package.json +1 -1
- package/templates/hello-agent/packages/agent-core/src/agent.ts +33 -6
- package/templates/hello-agent/packages/agent-core/src/api/charge-rail.ts +15 -1
- package/templates/hello-agent/packages/agent-core/src/api/rail.ts +11 -5
- package/templates/hello-agent/packages/agent-core/src/api/sandbox-payer.ts +36 -0
- package/templates/hello-agent/packages/agent-core/src/bundle.ts +2 -0
- package/templates/hello-agent/packages/agent-core/src/channels.ts +18 -8
- package/templates/hello-agent/packages/agent-core/src/check.ts +25 -3
- package/templates/hello-agent/packages/agent-core/src/engine.ts +90 -9
- package/templates/hello-agent/packages/agent-core/src/escalate.ts +10 -0
- package/templates/hello-agent/packages/agent-core/src/index.ts +3 -0
- package/templates/hello-agent/packages/agent-core/src/language.ts +52 -0
- package/templates/hello-agent/packages/agent-core/src/locale.ts +88 -0
- package/templates/hello-agent/packages/agent-core/src/manifest.ts +4 -1
- package/templates/hello-agent/packages/agent-core/src/rail.ts +29 -1
- package/templates/hello-agent/packages/agent-core/src/receipt-verification.ts +30 -2
- package/templates/hello-agent/packages/agent-core/src/secrets.ts +53 -8
- package/templates/hello-agent/packages/agent-core/src/state-machine.ts +14 -0
- package/templates/hello-agent/packages/agent-core/src/strings.ts +175 -0
- package/templates/hello-agent/packages/agent-core/src/stubs/charge-rail.ts +15 -2
- package/templates/hello-agent/packages/agent-core/src/stubs/rail.ts +7 -4
- package/templates/hello-agent/packages/agent-core/src/types.ts +15 -2
- package/templates/hello-agent/packages/agent-core/test/actor-on-the-wire.test.ts +144 -0
- package/templates/hello-agent/packages/agent-core/test/attempt-replay.test.ts +2 -2
- package/templates/hello-agent/packages/agent-core/test/engine.test.ts +23 -0
- package/templates/hello-agent/packages/agent-core/test/helpers.ts +1 -1
- package/templates/hello-agent/packages/agent-core/test/language.test.ts +40 -0
- package/templates/hello-agent/packages/agent-core/test/locale.test.ts +137 -0
- package/templates/hello-agent/packages/agent-core/test/mandate-status.test.ts +2 -2
- package/templates/hello-agent/packages/agent-core/test/manifest.test.ts +2 -2
- package/templates/hello-agent/packages/agent-core/test/rail-errors.test.ts +74 -0
- package/templates/hello-agent/packages/agent-core/test/receipt-read-verification.test.ts +32 -0
- package/templates/hello-agent/packages/agent-core/test/receivables.test.ts +49 -0
- package/templates/hello-agent/packages/agent-core/test/recorded-turns.ts +29 -0
- package/templates/hello-agent/packages/agent-core/test/secrets.test.ts +40 -1
- package/templates/hello-agent/packages/agent-runtime/README.md +31 -4
- package/templates/hello-agent/packages/agent-runtime/src/channels/rules.ts +4 -2
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +11 -5
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +43 -21
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +3 -0
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +8 -12
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +8 -4
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +12 -9
- package/templates/hello-agent/packages/agent-runtime/src/cli.ts +30 -4
- package/templates/hello-agent/packages/agent-runtime/src/commands/check.ts +18 -2
- package/templates/hello-agent/packages/agent-runtime/src/commands/decide.ts +13 -4
- package/templates/hello-agent/packages/agent-runtime/src/commands/eval.ts +7 -2
- package/templates/hello-agent/packages/agent-runtime/src/commands/inspect.ts +11 -13
- package/templates/hello-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +32 -24
- package/templates/hello-agent/packages/agent-runtime/src/commands/poll.ts +12 -5
- package/templates/hello-agent/packages/agent-runtime/src/commands/rerun.ts +83 -10
- package/templates/hello-agent/packages/agent-runtime/src/commands/resume.ts +2 -1
- package/templates/hello-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +10 -5
- package/templates/hello-agent/packages/agent-runtime/src/commands/start.ts +48 -17
- package/templates/hello-agent/packages/agent-runtime/src/commands/verify.ts +37 -12
- package/templates/hello-agent/packages/agent-runtime/src/commands/webhook.ts +11 -3
- package/templates/hello-agent/packages/agent-runtime/src/default-kit.ts +52 -22
- package/templates/hello-agent/packages/agent-runtime/src/env.ts +64 -0
- package/templates/hello-agent/packages/agent-runtime/src/index.ts +2 -0
- package/templates/hello-agent/packages/agent-runtime/src/inspect.ts +81 -10
- package/templates/hello-agent/packages/agent-runtime/src/kit.ts +34 -12
- package/templates/hello-agent/packages/agent-runtime/src/outcome.ts +118 -0
- package/templates/hello-agent/packages/agent-runtime/src/poll.ts +7 -7
- package/templates/hello-agent/packages/agent-runtime/src/runs.ts +51 -0
- package/templates/hello-agent/packages/agent-runtime/src/scenarios.ts +55 -8
- package/templates/hello-agent/packages/agent-runtime/src/setup.ts +75 -5
- package/templates/hello-agent/packages/agent-runtime/src/terminal.ts +71 -33
- package/templates/hello-agent/packages/agent-runtime/test/env-names.test.ts +56 -0
- package/templates/hello-agent/packages/agent-runtime/test/inspect-mandate-status.test.ts +80 -0
- package/templates/hello-agent/packages/agent-runtime/test/inspect.test.ts +63 -2
- package/templates/hello-agent/packages/agent-runtime/test/outcome.test.ts +72 -0
- package/templates/hello-agent/packages/agent-runtime/test/poll-payer.test.ts +64 -0
- package/templates/hello-agent/packages/agent-runtime/test/rerun-not-replayed.test.ts +46 -0
- package/templates/hello-agent/packages/agent-runtime/test/transition-line.test.ts +29 -0
- package/templates/hello-agent/packages/agent-runtime/test/verify-cli.test.ts +99 -6
- package/templates/hello-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +8 -0
- package/templates/hello-agent/packages/agent-runtime/test/whatsapp-session.test.ts +77 -0
- package/templates/hello-agent/packages/agent-runtime/test/whatsapp-status-replies.test.ts +27 -1
- package/templates/kits.lock.json +12 -12
- package/templates/supplier-payments-agent/README.md +2 -2
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/.env.example +2 -2
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/README.md +12 -7
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/SYSTEM_PROMPT.md +14 -3
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/agent.yaml +2 -1
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/exfiltration.transcript.jsonl +1 -1
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/false-authority.transcript.jsonl +1 -1
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/prompt-injection.transcript.jsonl +1 -1
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/mandate.example.json +3 -3
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/beneficiary-not-allowed.transcript.jsonl +1 -1
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/cap-exceeded.transcript.jsonl +1 -1
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/escalated-above-threshold.transcript.jsonl +5 -5
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/happy-path.transcript.jsonl +1 -1
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/mandate-revoked.transcript.jsonl +5 -5
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/partial-batch-failure.json +1 -1
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/partial-batch-failure.transcript.jsonl +1 -1
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/prompt-injection.transcript.jsonl +1 -1
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/kit.ts +37 -26
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/modules/batch-payout.ts +41 -14
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/modules/pix-out.ts +12 -3
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/payables.ts +8 -8
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/batch.test.ts +75 -10
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/locale.test.ts +101 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/run-outcome.test.ts +127 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/tools.json +1 -1
- package/templates/supplier-payments-agent/packages/agent-core/README.md +21 -2
- package/templates/supplier-payments-agent/packages/agent-core/package.json +1 -1
- package/templates/supplier-payments-agent/packages/agent-core/src/agent.ts +33 -6
- package/templates/supplier-payments-agent/packages/agent-core/src/api/charge-rail.ts +15 -1
- package/templates/supplier-payments-agent/packages/agent-core/src/api/rail.ts +11 -5
- package/templates/supplier-payments-agent/packages/agent-core/src/api/sandbox-payer.ts +36 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/bundle.ts +2 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/channels.ts +18 -8
- package/templates/supplier-payments-agent/packages/agent-core/src/check.ts +25 -3
- package/templates/supplier-payments-agent/packages/agent-core/src/engine.ts +90 -9
- package/templates/supplier-payments-agent/packages/agent-core/src/escalate.ts +10 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/index.ts +3 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/language.ts +52 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/locale.ts +88 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/manifest.ts +4 -1
- package/templates/supplier-payments-agent/packages/agent-core/src/rail.ts +29 -1
- package/templates/supplier-payments-agent/packages/agent-core/src/receipt-verification.ts +30 -2
- package/templates/supplier-payments-agent/packages/agent-core/src/secrets.ts +53 -8
- package/templates/supplier-payments-agent/packages/agent-core/src/state-machine.ts +14 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/strings.ts +175 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/stubs/charge-rail.ts +15 -2
- package/templates/supplier-payments-agent/packages/agent-core/src/stubs/rail.ts +7 -4
- package/templates/supplier-payments-agent/packages/agent-core/src/types.ts +15 -2
- package/templates/supplier-payments-agent/packages/agent-core/test/actor-on-the-wire.test.ts +144 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/attempt-replay.test.ts +2 -2
- package/templates/supplier-payments-agent/packages/agent-core/test/engine.test.ts +23 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/helpers.ts +1 -1
- package/templates/supplier-payments-agent/packages/agent-core/test/language.test.ts +40 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/locale.test.ts +137 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/mandate-status.test.ts +2 -2
- package/templates/supplier-payments-agent/packages/agent-core/test/manifest.test.ts +2 -2
- package/templates/supplier-payments-agent/packages/agent-core/test/rail-errors.test.ts +74 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/receipt-read-verification.test.ts +32 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/receivables.test.ts +49 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/recorded-turns.ts +29 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/secrets.test.ts +40 -1
- package/templates/supplier-payments-agent/packages/agent-runtime/README.md +31 -4
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/rules.ts +4 -2
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +11 -5
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +43 -21
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +3 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +8 -12
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +8 -4
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +12 -9
- package/templates/supplier-payments-agent/packages/agent-runtime/src/cli.ts +30 -4
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/check.ts +18 -2
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/decide.ts +13 -4
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/eval.ts +7 -2
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/inspect.ts +11 -13
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +32 -24
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/poll.ts +12 -5
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/rerun.ts +83 -10
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/resume.ts +2 -1
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +10 -5
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/start.ts +48 -17
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/verify.ts +37 -12
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/webhook.ts +11 -3
- package/templates/supplier-payments-agent/packages/agent-runtime/src/default-kit.ts +52 -22
- package/templates/supplier-payments-agent/packages/agent-runtime/src/env.ts +64 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/index.ts +2 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/inspect.ts +81 -10
- package/templates/supplier-payments-agent/packages/agent-runtime/src/kit.ts +34 -12
- package/templates/supplier-payments-agent/packages/agent-runtime/src/outcome.ts +118 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/poll.ts +7 -7
- package/templates/supplier-payments-agent/packages/agent-runtime/src/runs.ts +51 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/scenarios.ts +55 -8
- package/templates/supplier-payments-agent/packages/agent-runtime/src/setup.ts +75 -5
- package/templates/supplier-payments-agent/packages/agent-runtime/src/terminal.ts +71 -33
- package/templates/supplier-payments-agent/packages/agent-runtime/test/env-names.test.ts +56 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/test/inspect-mandate-status.test.ts +80 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/test/inspect.test.ts +63 -2
- package/templates/supplier-payments-agent/packages/agent-runtime/test/outcome.test.ts +72 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/test/poll-payer.test.ts +64 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/test/rerun-not-replayed.test.ts +46 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/test/transition-line.test.ts +29 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/test/verify-cli.test.ts +99 -6
- package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +8 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-session.test.ts +77 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-status-replies.test.ts +27 -1
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #64: the language of the strings the code prints. Resolved once per run
|
|
3
|
+
* (flag, manifest, default), declared in `agent.yaml` as an optional field,
|
|
4
|
+
* and backed by tables whose every key exists in every locale.
|
|
5
|
+
*/
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { CORE_STRINGS, DEFAULT_LOCALE, LOCALES, WHATSAPP_LANGUAGE, formatBRL, formatDay, parseLocale, parseManifest, parseTemplateRegistry, resolveLocale, tableGaps } from "../src/index.js";
|
|
8
|
+
|
|
9
|
+
const MANIFEST = `
|
|
10
|
+
schema: 1
|
|
11
|
+
name: bills-agent
|
|
12
|
+
version: 0.1.0
|
|
13
|
+
approval: [human, mandate]
|
|
14
|
+
default_approval: human
|
|
15
|
+
mcp: "@codespar/mcp@0.5.8"
|
|
16
|
+
cli: "@codespar/cli@0.18.1"
|
|
17
|
+
tools: ./tools.json
|
|
18
|
+
guardrails: ./guardrails.json
|
|
19
|
+
mandate_schema: ./mandate.example.json
|
|
20
|
+
events: [commerce.payment.succeeded]
|
|
21
|
+
channels: [terminal]
|
|
22
|
+
maturity:
|
|
23
|
+
pix-out: sandbox
|
|
24
|
+
scenarios: ./scenarios/
|
|
25
|
+
evals: ./evals/
|
|
26
|
+
agents_md: ./AGENTS.md
|
|
27
|
+
`;
|
|
28
|
+
|
|
29
|
+
/** Calls a table entry with placeholder arguments of the arity it declares, so a function key is read as the text it prints. */
|
|
30
|
+
function render(value: unknown): string {
|
|
31
|
+
if (typeof value === "string") return value;
|
|
32
|
+
const fn = value as (...args: unknown[]) => string;
|
|
33
|
+
return fn(...Array.from({ length: fn.length }, (_, i) => (i % 2 === 0 ? "X" : 2)));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
describe("the locale of a run", () => {
|
|
37
|
+
it("is the flag, else the manifest's, else pt-BR", () => {
|
|
38
|
+
expect(resolveLocale("en", { locale: "pt-BR" })).toBe("en");
|
|
39
|
+
expect(resolveLocale(undefined, { locale: "en" })).toBe("en");
|
|
40
|
+
expect(resolveLocale(undefined, {})).toBe("pt-BR");
|
|
41
|
+
expect(DEFAULT_LOCALE).toBe("pt-BR");
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it("is one of the two the kits speak, and anything else is refused by name", () => {
|
|
45
|
+
expect(parseLocale("en")).toBe("en");
|
|
46
|
+
expect(parseLocale("pt-BR")).toBe("pt-BR");
|
|
47
|
+
for (const bad of ["pt", "pt_BR", "en-US", "es", "EN", ""]) expect(() => parseLocale(bad)).toThrow(/--locale must be pt-BR or en/);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("is an optional agent.yaml field: absent parses as before, en parses, anything else is refused", () => {
|
|
51
|
+
expect(parseManifest(MANIFEST).locale).toBeUndefined();
|
|
52
|
+
expect(parseManifest(MANIFEST + "locale: en\n").locale).toBe("en");
|
|
53
|
+
expect(parseManifest(MANIFEST + "locale: pt-BR\n").locale).toBe("pt-BR");
|
|
54
|
+
expect(() => parseManifest(MANIFEST + "locale: es\n")).toThrow();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("sends a WhatsApp template in the language Meta approved it in for that locale", () => {
|
|
58
|
+
expect(WHATSAPP_LANGUAGE).toEqual({ "pt-BR": "pt_BR", en: "en_US" });
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("formats money and dates for its reader, from the same minor units", () => {
|
|
62
|
+
expect(formatBRL(185000, "pt-BR")).toBe("R$ 1.850,00");
|
|
63
|
+
expect(formatBRL(185000, "en")).toBe("R$1,850.00");
|
|
64
|
+
expect(formatBRL(-9, "pt-BR")).toBe("-R$ 0,09");
|
|
65
|
+
expect(formatBRL(-9, "en")).toBe("-R$0.09");
|
|
66
|
+
expect(formatDay("2026-09-30", "pt-BR")).toBe("30/09/2026");
|
|
67
|
+
expect(formatDay("2026-09-30", "en")).toBe("2026-09-30");
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
describe("the shared string table", () => {
|
|
72
|
+
it("has every key in every locale, with the same shape", () => {
|
|
73
|
+
expect(tableGaps("CORE_STRINGS", CORE_STRINGS)).toEqual([]);
|
|
74
|
+
expect(Object.keys(CORE_STRINGS.en).sort()).toEqual(Object.keys(CORE_STRINGS["pt-BR"]).sort());
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("prints text for every key in both locales, and never the word undefined", () => {
|
|
78
|
+
for (const locale of LOCALES) {
|
|
79
|
+
for (const [key, value] of Object.entries(CORE_STRINGS[locale])) {
|
|
80
|
+
const text = render(value);
|
|
81
|
+
expect(text.trim(), `${locale}.${key}`).not.toBe("");
|
|
82
|
+
expect(text, `${locale}.${key}`).not.toContain("undefined");
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("offers the answers the parsers read, in the language it asks in", () => {
|
|
88
|
+
expect(CORE_STRINGS["pt-BR"].batchQuestion).toContain("todas / todas exceto 3,7 / nenhuma");
|
|
89
|
+
expect(CORE_STRINGS.en.batchQuestion).toContain("all / all except 3,7 / none");
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it("writes the Portuguese with its accents (#64)", () => {
|
|
93
|
+
const pt = CORE_STRINGS["pt-BR"];
|
|
94
|
+
expect(pt.execution).toBe("execução");
|
|
95
|
+
expect(pt.onlyDeny).toContain("o único desfecho possível é negar");
|
|
96
|
+
expect(pt.boletoLine).toBe("Ou pelo boleto, linha digitável:");
|
|
97
|
+
expect(pt.batchUnreadable(3)).toContain("não entendi");
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
describe("tableGaps: what npm run check reports", () => {
|
|
102
|
+
it("names a key one locale lacks, an empty string, a string against a function, and a different arity", () => {
|
|
103
|
+
const gaps = tableGaps("t", {
|
|
104
|
+
"pt-BR": { a: "a", b: "b", c: (x: string) => x, d: (x: string, y: string) => x + y, e: "" },
|
|
105
|
+
en: { a: "a", c: "c", d: (x: string) => x, e: "e" },
|
|
106
|
+
});
|
|
107
|
+
expect(gaps).toEqual([
|
|
108
|
+
"t.b is missing in en",
|
|
109
|
+
"t.c differs in shape across locales: pt-BR function/1, en string",
|
|
110
|
+
"t.d differs in shape across locales: pt-BR function/2, en function/1",
|
|
111
|
+
"t.e is empty string in pt-BR",
|
|
112
|
+
"t.e differs in shape across locales: pt-BR empty string, en string",
|
|
113
|
+
]);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it("names a locale with no entry at all", () => {
|
|
117
|
+
expect(tableGaps("t", { "pt-BR": { a: "a" } })).toContain("t has no en entry");
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
describe("the template registry holds one copy per (name, language)", () => {
|
|
122
|
+
const template = (language: string, extra: Record<string, unknown> = {}) => ({ name: "acordo_quitado", language, description: "paid", body: "{{1}} quitado", ...extra });
|
|
123
|
+
|
|
124
|
+
it("accepts the same name in two languages, which is two templates to Meta", () => {
|
|
125
|
+
expect(parseTemplateRegistry(JSON.stringify({ channel: "whatsapp", templates: [template("pt_BR"), template("en_US")] })).templates).toHaveLength(2);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it("refuses the same pair declared twice", () => {
|
|
129
|
+
expect(() => parseTemplateRegistry(JSON.stringify({ channel: "whatsapp", templates: [template("pt_BR"), template("pt_BR")] }))).toThrow(/acordo_quitado is declared twice in pt_BR/);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("refuses one reply id offered by two different templates, which would make a tap ambiguous", () => {
|
|
133
|
+
const button = { id: "emitir_nova", title: "Emitir nova", intent: "emita" };
|
|
134
|
+
const doc = { channel: "whatsapp", templates: [template("pt_BR", { buttons: [button] }), { ...template("pt_BR", { buttons: [button] }), name: "outro" }] };
|
|
135
|
+
expect(() => parseTemplateRegistry(JSON.stringify(doc))).toThrow(/reply id emitir_nova/);
|
|
136
|
+
});
|
|
137
|
+
});
|
|
@@ -75,8 +75,8 @@ beforeEach(() => {
|
|
|
75
75
|
});
|
|
76
76
|
|
|
77
77
|
function apiClient(timeoutMs = 5_000) {
|
|
78
|
-
//
|
|
79
|
-
return createCodeSparClient({ apiKey: "
|
|
78
|
+
// Not the placeholder, which the guard refuses (#50); the underscore keeps it below the secret scan's key shape.
|
|
79
|
+
return createCodeSparClient({ apiKey: "csk_test_unit_0000", baseUrl, timeoutMs });
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
function apiSource(timeoutMs = 5_000): ApiMandateStatusSource {
|
|
@@ -12,7 +12,7 @@ escalate_above:
|
|
|
12
12
|
new_beneficiary: true
|
|
13
13
|
outside_hours: "22:00-07:00"
|
|
14
14
|
mcp: "@codespar/mcp@0.5.8"
|
|
15
|
-
cli: "@codespar/cli@0.
|
|
15
|
+
cli: "@codespar/cli@0.18.1"
|
|
16
16
|
tools: ./tools.json
|
|
17
17
|
guardrails: ./guardrails.json
|
|
18
18
|
mandate_schema: ./mandate.example.json
|
|
@@ -36,7 +36,7 @@ describe("section 4.3: agent.yaml schema 1", () => {
|
|
|
36
36
|
|
|
37
37
|
it("refuses an unpinned mcp or cli, a wrong schema, and an unknown field", () => {
|
|
38
38
|
expect(() => parseManifest(valid.replace('"@codespar/mcp@0.5.8"', '"@codespar/mcp"'))).toThrow(/mcp/);
|
|
39
|
-
expect(() => parseManifest(valid.replace('"@codespar/cli@0.
|
|
39
|
+
expect(() => parseManifest(valid.replace('"@codespar/cli@0.18.1"', '"@codespar/cli@latest"'))).toThrow(/cli/);
|
|
40
40
|
expect(() => parseManifest(valid.replace("schema: 1", "schema: 2"))).toThrow();
|
|
41
41
|
expect(() => parseManifest(valid + "telemetry: true\n")).toThrow(/unrecognized/i);
|
|
42
42
|
expect(() => parseManifest(valid.replace("default_approval: human", "default_approval: mandate").replace("approval: [human, mandate]", "approval: [human]"))).toThrow(/default_approval/);
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #50: a rail failure carries the API's own code and message, verbatim, out
|
|
3
|
+
* of the engine — not only `rail_failed`. Both answers are real ones the
|
|
4
|
+
* deployed API gave the kits on production test mode: the 409
|
|
5
|
+
* `insufficient_funds` of an unfunded wallet (ent#1803) and the 5xx
|
|
6
|
+
* `provider_error` of a charge with no receiving identity (ent#1809). They go
|
|
7
|
+
* through the real SDK client against a local server, so the code and the
|
|
8
|
+
* message are the ones the SDK hands the rail, not ones a fake invents.
|
|
9
|
+
*/
|
|
10
|
+
import { createServer, type Server } from "node:http";
|
|
11
|
+
import type { AddressInfo } from "node:net";
|
|
12
|
+
import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
|
13
|
+
import { CodeSparRail } from "../src/api/rail.js";
|
|
14
|
+
import { createCodeSparClient } from "../src/api/client.js";
|
|
15
|
+
import { railErrorOf } from "../src/engine.js";
|
|
16
|
+
import { harness } from "./helpers.js";
|
|
17
|
+
|
|
18
|
+
const INSUFFICIENT = { status: 409, body: { error: { code: "insufficient_funds", message: "wallet cannot reserve the requested amount" }, request_id: null } };
|
|
19
|
+
const PROVIDER = {
|
|
20
|
+
status: 502,
|
|
21
|
+
body: { error: { code: "provider_error", message: "charge_boleto_brl_celcoin_v1: no receiving identity at the provider for this consumer" }, request_id: null },
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
let server: Server;
|
|
25
|
+
let baseUrl: string;
|
|
26
|
+
let answer: { status: number; body: unknown } = INSUFFICIENT;
|
|
27
|
+
|
|
28
|
+
beforeAll(async () => {
|
|
29
|
+
server = createServer((_req, res) => {
|
|
30
|
+
res.writeHead(answer.status, { "content-type": "application/json" });
|
|
31
|
+
res.end(JSON.stringify(answer.body));
|
|
32
|
+
});
|
|
33
|
+
await new Promise<void>((ok) => server.listen(0, "127.0.0.1", ok));
|
|
34
|
+
baseUrl = `http://127.0.0.1:${(server.address() as AddressInfo).port}`;
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
afterAll(async () => {
|
|
38
|
+
server.closeAllConnections();
|
|
39
|
+
await new Promise<void>((ok) => server.close(() => ok()));
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
async function spend() {
|
|
43
|
+
// Not the placeholder, which the guard refuses (#50); the underscore keeps it below the secret scan's key shape.
|
|
44
|
+
const h = harness({ mode: "human", wrapRail: () => new CodeSparRail(createCodeSparClient({ apiKey: "csk_test_unit_0000", baseUrl, timeoutMs: 5_000 })) });
|
|
45
|
+
const d = await h.engine.draft({ items: [{ payee: "escola", amount: 185000 }] });
|
|
46
|
+
if (!d.ok) throw new Error("refused");
|
|
47
|
+
return h.engine.execute(h.engine.approve(d.execution.id, { id: "usr_demo", channel: "terminal" }).id);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
describe("the rail's answer, verbatim", () => {
|
|
51
|
+
it("a 409 insufficient_funds closes the execution failed, and says so in the API's words", async () => {
|
|
52
|
+
answer = INSUFFICIENT;
|
|
53
|
+
const out = await spend();
|
|
54
|
+
expect(out.state).toBe("failed");
|
|
55
|
+
expect(out.reason).toBe("rail_failed");
|
|
56
|
+
expect(railErrorOf(out)).toEqual({ outcome: "failed", attempt_id: out.outcomes[0]!.attempt_id, code: "insufficient_funds", message: "wallet cannot reserve the requested amount" });
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("a 5xx provider_error leaves the attempt unknown, and still carries what the API said", async () => {
|
|
60
|
+
answer = PROVIDER;
|
|
61
|
+
const out = await spend();
|
|
62
|
+
expect(out.state).toBe("executing");
|
|
63
|
+
expect(out.reason).toBe("rail_uncertain");
|
|
64
|
+
expect(out.outcomes).toHaveLength(0);
|
|
65
|
+
expect(railErrorOf(out)).toMatchObject({ outcome: "uncertain", code: "provider_error", message: PROVIDER.body.error.message });
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it("an unknown answer is superseded once its attempt has an outcome", () => {
|
|
69
|
+
const answers = [{ attempt_id: "att_0", code: "provider_error", message: "x" }];
|
|
70
|
+
expect(railErrorOf({ outcomes: [], uncertain_answers: answers })).toMatchObject({ outcome: "uncertain" });
|
|
71
|
+
expect(railErrorOf({ outcomes: [{ index: 0, attempt_id: "att_0", status: "settled" }], uncertain_answers: answers })).toBeNull();
|
|
72
|
+
expect(railErrorOf({ outcomes: [] })).toBeNull();
|
|
73
|
+
});
|
|
74
|
+
});
|
|
@@ -124,6 +124,37 @@ describe("a v4 receipt: signature, body and approval", () => {
|
|
|
124
124
|
expect(report.message).toContain(ITEMS_HASH);
|
|
125
125
|
});
|
|
126
126
|
|
|
127
|
+
it("reports sandbox and money_moved off the bound body, and no other field of the read", () => {
|
|
128
|
+
for (const report of [verifyReceiptRead(sealed(4), keyDocument()), verifyReceiptRead(sealed(4), keyDocument(), { approval: artifact() })]) {
|
|
129
|
+
expect(report.sealed_payment).toEqual({ sandbox: true, money_moved: false });
|
|
130
|
+
expect(JSON.stringify(report)).not.toContain(MANDATE_SIG);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it("reports a field the recipe does not seal as null, not as the read's value", () => {
|
|
135
|
+
const base = PUBLISHED["chain_recipe"] as { links: Array<{ from: string; fields?: string[] }> };
|
|
136
|
+
const recipe = { ...base, links: base.links.map((l) => (l.from === "payment" ? { ...l, fields: l.fields!.filter((f) => f !== "sandbox?") } : l)) };
|
|
137
|
+
const b = body(4, { items_hash: ITEMS_HASH, batch_hash: null });
|
|
138
|
+
const m = b.mandate;
|
|
139
|
+
const q = b.quote;
|
|
140
|
+
const p = b.payment;
|
|
141
|
+
const chain = sha256(
|
|
142
|
+
canonicalize({
|
|
143
|
+
v: 4,
|
|
144
|
+
links: [
|
|
145
|
+
{ id: m.id, nonce: m.nonce, scope: m.scope, currency: m.currency, sig_sha256: m.sig_sha256 },
|
|
146
|
+
{ seller: q.seller, resource: q.resource, price_minor: q.price_minor, payee: q.payee, session_id: q.session_id, sig: q.sig, at: q.at },
|
|
147
|
+
b.approval,
|
|
148
|
+
{ rail: p.rail, provider: p.provider, tx_id: p.tx_id, amount_minor: p.amount_minor, attempt_id: p.attempt_id, money_moved: p.money_moved, at: p.at },
|
|
149
|
+
],
|
|
150
|
+
}),
|
|
151
|
+
);
|
|
152
|
+
const read = { ...sealed(4), chain, receipt_sig_ed25519: signDetached(null, Buffer.from(`codespar-receipt:v1:${RECEIPT_ID}:${chain}`, "utf8"), privateKey).toString("base64url") };
|
|
153
|
+
const report = verifyReceiptRead(read, keyDocument({ chain_recipe: recipe }));
|
|
154
|
+
expect(report.verdict).toBe("verified");
|
|
155
|
+
expect(report.sealed_payment).toEqual({ sandbox: null, money_moved: false });
|
|
156
|
+
});
|
|
157
|
+
|
|
127
158
|
it("is chain_mismatch when the body beside a genuine signature was changed: payee, amount, approval", () => {
|
|
128
159
|
const read = sealed(4);
|
|
129
160
|
const q = read["quote"] as Record<string, unknown>;
|
|
@@ -136,6 +167,7 @@ describe("a v4 receipt: signature, body and approval", () => {
|
|
|
136
167
|
const report = verifyReceiptRead(altered, keyDocument(), { approval: artifact() });
|
|
137
168
|
expect(report.verdict).toBe("chain_mismatch");
|
|
138
169
|
expect(report.chain_check).toMatchObject({ status: "mismatch", version: 4 });
|
|
170
|
+
expect(report.sealed_payment).toBeUndefined();
|
|
139
171
|
expect(VERDICT_EXIT_CODES[report.verdict]).toBe(8);
|
|
140
172
|
}
|
|
141
173
|
});
|
|
@@ -261,6 +261,12 @@ describe("outcomeOf: the API's charge view, mapped by fields and never by prose"
|
|
|
261
261
|
expect(outcomeOf({ ...base, status: "CANCELLED" })).toMatchObject({ status: "failed", code: "charge_cancelled" });
|
|
262
262
|
expect(outcomeOf({ ...base, id: null, issuance_unconfirmed: true })).toEqual({ status: "in_flight" });
|
|
263
263
|
});
|
|
264
|
+
it("an issuer that ends the registration in ERROR fails the attempt with charge_issuer_error; a status nobody documented stays accepted and unpayable", () => {
|
|
265
|
+
const errored = { ...base, status: "ERROR", payable: false, pix_copy_paste: null, boleto_bank_line: null, boleto_bar_code: null };
|
|
266
|
+
expect(outcomeOf(errored)).toMatchObject({ status: "failed", code: "charge_issuer_error" });
|
|
267
|
+
expect((outcomeOf(errored) as { message: string }).message).toContain("ERROR");
|
|
268
|
+
expect(outcomeOf({ ...errored, status: "SOMETHING_NEW" })).toMatchObject({ status: "accepted", instrument: { payable: false, status: "SOMETHING_NEW" } });
|
|
269
|
+
});
|
|
264
270
|
it("a payment notified and not yet credited is still accepted: nothing settles on a notification", () => {
|
|
265
271
|
expect(outcomeOf({ ...base, payment_in_flight: true, settlement: "pending" })).toMatchObject({ status: "accepted" });
|
|
266
272
|
});
|
|
@@ -317,6 +323,49 @@ describe("paySandboxCharge: the SDK's typed call to the payer route", () => {
|
|
|
317
323
|
});
|
|
318
324
|
});
|
|
319
325
|
|
|
326
|
+
describe("payIfPayable: the sandbox payer pays only what a payer could have paid (OPEN_QUESTIONS §63, ent#1816)", () => {
|
|
327
|
+
const view = (over: Record<string, unknown>) => ({ id: "chg_1", status: "PENDING", local_status: "pending", status_conflict: false, method: "boleto", currency: "BRL", amount: 1080, amount_minor: 108000, due_date: "2026-09-30", payable: true, boleto_bar_code: "1".repeat(44), boleto_bank_line: "2".repeat(47), pix_copy_paste: "000201...", credit_correlation_armed: true, payment_in_flight: false, settlement: null, issuance_unconfirmed: false, ...over });
|
|
328
|
+
const paid = { charge_id: "chg_1", status: "paid", local_status: "settled", simulated: true, settled_against: "sandbox_fixture", money_moved: false, quoted_minor: 108000, paid_minor: 108000, payment: "full", idempotent_replay: false };
|
|
329
|
+
|
|
330
|
+
async function withCharge(read: Record<string, unknown>) {
|
|
331
|
+
const { payIfPayable } = await import("../src/api/sandbox-payer.js");
|
|
332
|
+
const { createCodeSparClient } = await import("../src/api/client.js");
|
|
333
|
+
const seen: Array<{ method: string; url: string }> = [];
|
|
334
|
+
const realFetch = globalThis.fetch;
|
|
335
|
+
globalThis.fetch = (async (url: string | URL | Request, init?: RequestInit) => {
|
|
336
|
+
const method = init?.method ?? "GET";
|
|
337
|
+
seen.push({ method, url: String(url) });
|
|
338
|
+
return new Response(JSON.stringify(method === "GET" ? read : paid), { status: 200, headers: { "content-type": "application/json" } });
|
|
339
|
+
}) as typeof fetch;
|
|
340
|
+
try {
|
|
341
|
+
const out = await payIfPayable(createCodeSparClient({ apiKey: "csk_test_unit_0000", baseUrl: "https://api.example.test/" }), "chg_1");
|
|
342
|
+
return { out, seen };
|
|
343
|
+
} finally {
|
|
344
|
+
globalThis.fetch = realFetch;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
const posts = (seen: Array<{ method: string }>) => seen.filter((s) => s.method === "POST").length;
|
|
348
|
+
|
|
349
|
+
it("a charge the issuer ended in ERROR: refused as charge_issuer_error, and the pay route is never called", async () => {
|
|
350
|
+
const { out, seen } = await withCharge(view({ status: "ERROR", payable: false, pix_copy_paste: null, boleto_bank_line: null, boleto_bar_code: null }));
|
|
351
|
+
expect(out).toMatchObject({ ok: false, refused: { code: "charge_issuer_error" } });
|
|
352
|
+
expect(seen.map((s) => `${s.method} ${s.url}`)).toEqual(["GET https://api.example.test/v1/charges/chg_1"]);
|
|
353
|
+
expect(posts(seen)).toBe(0);
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
it("a charge still registering, with no QR and no line: refused as no_payable_instrument, and the pay route is never called", async () => {
|
|
357
|
+
const { out, seen } = await withCharge(view({ status: "PROCESSING", payable: false, pix_copy_paste: null, boleto_bank_line: null, boleto_bar_code: null }));
|
|
358
|
+
expect(out).toMatchObject({ ok: false, refused: { code: "no_payable_instrument" } });
|
|
359
|
+
expect(posts(seen)).toBe(0);
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
it("a payable charge is paid, once", async () => {
|
|
363
|
+
const { out, seen } = await withCharge(view({}));
|
|
364
|
+
expect(out).toMatchObject({ ok: true, state: { status: "paid", settled_against: "sandbox_fixture" } });
|
|
365
|
+
expect(seen.map((s) => `${s.method} ${s.url}`)).toEqual(["GET https://api.example.test/v1/charges/chg_1", "POST https://api.example.test/v1/test/charges/chg_1/pay"]);
|
|
366
|
+
});
|
|
367
|
+
});
|
|
368
|
+
|
|
320
369
|
describe("CodeSparChargeRail.read: a 409 is branched on its code, never on the status alone", () => {
|
|
321
370
|
const VIEW = { id: "chg_409", status: "PROCESSING", local_status: "pending", status_conflict: false, method: "boleto", currency: "BRL", amount: 1080, amount_minor: 108000, due_date: "2026-09-30", payable: false, boleto_bar_code: null, boleto_bank_line: null, pix_copy_paste: null, credit_correlation_armed: false, payment_in_flight: false, settlement: null, issuance_unconfirmed: false };
|
|
322
371
|
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { readdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Every turn a person types in a recorded scenario or WhatsApp conversation
|
|
6
|
+
* under `root/agents`: all Portuguese. `root` is this repository, with every
|
|
7
|
+
* agent, or a scaffold made by `codespar init --template`, with one.
|
|
8
|
+
*/
|
|
9
|
+
export function recordedTurns(root: string): string[] {
|
|
10
|
+
const out: string[] = [];
|
|
11
|
+
for (const agent of readdirSync(join(root, "agents"))) {
|
|
12
|
+
for (const dir of ["scenarios", join("channels", "whatsapp")]) {
|
|
13
|
+
let files: string[] = [];
|
|
14
|
+
try {
|
|
15
|
+
files = readdirSync(join(root, "agents", agent, dir)).filter((f) => f.endsWith(".json") && f !== "templates.json");
|
|
16
|
+
} catch {
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
for (const f of files) {
|
|
20
|
+
const doc = JSON.parse(readFileSync(join(root, "agents", agent, dir, f), "utf8")) as { turns?: Array<{ input?: string; text?: string }> };
|
|
21
|
+
for (const t of doc.turns ?? []) {
|
|
22
|
+
const text = t.input ?? t.text;
|
|
23
|
+
if (typeof text === "string") out.push(text);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return out;
|
|
29
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
2
|
import { createCodeSparClient } from "../src/api/client.js";
|
|
3
|
-
import { assertTestKey, isTestKey, NotATestKeyError, redactKey } from "../src/secrets.js";
|
|
3
|
+
import { assertTestKey, CODESPAR_KEY_PLACEHOLDER, isTestKey, NotATestKeyError, redactKey, testKeyMessage, testKeyProblem } from "../src/secrets.js";
|
|
4
4
|
|
|
5
5
|
// Built at runtime so the secret scan (which refuses key-shaped literals) stays honest about this file.
|
|
6
6
|
const TEST = ["csk", "test", "0123456789abcdef"].join("_");
|
|
@@ -21,6 +21,45 @@ describe("sandbox by construction", () => {
|
|
|
21
21
|
expect(createCodeSparClient({ apiKey: TEST })).toBeDefined();
|
|
22
22
|
});
|
|
23
23
|
|
|
24
|
+
it("tells the three mistakes apart (#50): no key, the placeholder, a key that is not a test key", () => {
|
|
25
|
+
for (const missing of [undefined, "", " "]) expect(testKeyProblem(missing)).toBe("missing");
|
|
26
|
+
expect(testKeyProblem(CODESPAR_KEY_PLACEHOLDER)).toBe("placeholder");
|
|
27
|
+
expect(testKeyProblem(LIVE)).toBe("not_test");
|
|
28
|
+
expect(testKeyProblem("csk_test_")).toBe("not_test");
|
|
29
|
+
expect(testKeyProblem(TEST)).toBeUndefined();
|
|
30
|
+
expect(isTestKey(CODESPAR_KEY_PLACEHOLDER)).toBe(false);
|
|
31
|
+
for (const [key, problem] of [[undefined, "missing"], [CODESPAR_KEY_PLACEHOLDER, "placeholder"], [LIVE, "not_test"]] as const) {
|
|
32
|
+
try {
|
|
33
|
+
assertTestKey(key);
|
|
34
|
+
throw new Error("accepted");
|
|
35
|
+
} catch (err) {
|
|
36
|
+
expect(err).toBeInstanceOf(NotATestKeyError);
|
|
37
|
+
expect((err as NotATestKeyError).problem).toBe(problem);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it("gives each its own remediation, naming the file the agent reads", () => {
|
|
43
|
+
const file = "agents/bills-agent/.env";
|
|
44
|
+
const missing = testKeyMessage("missing", file);
|
|
45
|
+
const placeholder = testKeyMessage("placeholder", file);
|
|
46
|
+
const live = testKeyMessage("not_test", file);
|
|
47
|
+
expect(missing).toContain("CODESPAR_API_KEY is not set");
|
|
48
|
+
expect(missing).toContain(`copy ${file}.example to ${file}`);
|
|
49
|
+
expect(missing).not.toContain("live");
|
|
50
|
+
expect(placeholder).toContain(`still the placeholder from .env.example (${CODESPAR_KEY_PLACEHOLDER})`);
|
|
51
|
+
expect(placeholder).toContain(file);
|
|
52
|
+
expect(placeholder).not.toContain("live");
|
|
53
|
+
expect(live).toContain("a live key is refused");
|
|
54
|
+
expect(new Set([missing, placeholder, live]).size).toBe(3);
|
|
55
|
+
expect(new NotATestKeyError("missing", file).message).toBe(missing);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("refuses to build a client on the placeholder too, before any network", () => {
|
|
59
|
+
expect(() => createCodeSparClient({ apiKey: CODESPAR_KEY_PLACEHOLDER })).toThrow(/placeholder/);
|
|
60
|
+
expect(() => createCodeSparClient({ apiKey: undefined })).toThrow(/is not set/);
|
|
61
|
+
});
|
|
62
|
+
|
|
24
63
|
it("redacts keys for logs", () => {
|
|
25
64
|
expect(redactKey(TEST)).toBe("csk_test_…cdef");
|
|
26
65
|
expect(redactKey(TEST)).not.toContain("0123456789");
|
|
@@ -33,11 +33,33 @@ nothing else.
|
|
|
33
33
|
`--conversation`, `--scripted`), `consent`, `approve`, `deny`, `resume`,
|
|
34
34
|
`rerun`, `reconcile`, `inspect` (`--json`, `--html <file>`), `poll`
|
|
35
35
|
(`--channel`, `--conversation`, `--backend`, `--wait`, `--simulate-payer`,
|
|
36
|
-
`--payer`, `--now`, `--json`), `webhook`, `check`, `eval
|
|
36
|
+
`--payer`, `--now`, `--json`), `webhook`, `check`, `eval`, `verify`
|
|
37
|
+
(`--from-api`, `--json`, `--keys`/`--url`, `--approval`), which needs no
|
|
38
|
+
agent directory.
|
|
39
|
+
- What a report says about a settlement the API replayed: the terminal line
|
|
40
|
+
"já estava pago", `replayed` on the executions of a paying agent's one-shot
|
|
41
|
+
`--json`, and "replayed, not paid by this run" in `inspect`. The first two
|
|
42
|
+
read agent-core's `isReplayedSettlement`; `inspect` reads the same mark from
|
|
43
|
+
the bundle's rail answers (`docs/OPEN_QUESTIONS.md` §39c).
|
|
44
|
+
- What `verify` prints: the verdict, the chain it recomputed, the approval it
|
|
45
|
+
matched and, off a body that bound, `sandbox` and `money_moved` as the chain
|
|
46
|
+
sealed them. Nothing else of the API's read, which still carries
|
|
47
|
+
`mandate.sig` (§47).
|
|
37
48
|
- Setup: the manifest, the guardrails, the tools file, the system prompt, the
|
|
38
49
|
local state, the signer, the proof bundle, the provider (Anthropic with a
|
|
39
50
|
real key, replay without one), and the pinned clock (`--now`,
|
|
40
|
-
`CODESPAR_AGENT_NOW`).
|
|
51
|
+
`CODESPAR_AGENT_NOW`), which also pins the `today` the list tools return.
|
|
52
|
+
- The locale of what the code prints (#64). `setup` resolves it once per run:
|
|
53
|
+
`--locale`, else `locale:` in `agent.yaml`, else `pt-BR`, and records it in
|
|
54
|
+
the bundle's `run.json`. The terminal's own lines come from agent-core's
|
|
55
|
+
`CORE_STRINGS` and the kit's from `kit.strings`, both in that locale; the
|
|
56
|
+
parsers do not change with it (`parseApproval`, `parseBatchGesture` read both
|
|
57
|
+
languages whatever is shown). A command that tells an outcome later (`poll`,
|
|
58
|
+
`webhook`, `approve`) tells the counterparty in the locale of the run that
|
|
59
|
+
proposed it, and `poll --channel whatsapp` sends the template copy in the
|
|
60
|
+
conversation's recorded language and refuses a `--locale` that disagrees.
|
|
61
|
+
The model's reply language is a different thing, read per turn from what
|
|
62
|
+
the person types.
|
|
41
63
|
- The section 9 adversarial runner and the section 12 scenario runner.
|
|
42
64
|
- The `csk_test_` guard and the `.env.example` placeholder rule.
|
|
43
65
|
|
|
@@ -57,11 +79,16 @@ export const agent = defineAgent(import.meta.url, {
|
|
|
57
79
|
```
|
|
58
80
|
|
|
59
81
|
`AgentKit` (in `src/kit.ts`) is the whole seam: the rail adapter
|
|
60
|
-
(`buildRail`), the tool handlers, the `policyExtension`, the console
|
|
61
|
-
|
|
82
|
+
(`buildRail`), the tool handlers, the `policyExtension`, the console words
|
|
83
|
+
(`strings`, one entry per locale, and `labels`, which holds what must not vary
|
|
84
|
+
by locale: who approves and the record kinds), what a one-shot prints as JSON, and — for an agent whose money comes IN — the
|
|
62
85
|
sandbox payer and the one message per outcome. An agent that declares none of
|
|
63
86
|
it gets `defaultKit`: the stub rail, the example mandate, no tools.
|
|
64
87
|
|
|
88
|
+
`npm run check` fails when a key of `kit.strings` or of `CORE_STRINGS` is
|
|
89
|
+
missing from one locale (`strings_incomplete`), so an English run never prints
|
|
90
|
+
`undefined` where a Portuguese one prints a word.
|
|
91
|
+
|
|
65
92
|
`defineAgent(import.meta.url, kit)` finds the nearest `agent.yaml` above the
|
|
66
93
|
module, which is what makes every path (`scenarios/`, `evals/`, `.codespar/`,
|
|
67
94
|
`runs/`) and every test-only environment variable (`BILLS_STATE_DIR`,
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
* Every rule can only REFUSE. None of them rewrites a message: a message
|
|
25
25
|
* that is edited on the way out is not the message the transcript shows.
|
|
26
26
|
*/
|
|
27
|
-
import { isOutsideHours, localClock } from "@codespar/agent-core";
|
|
27
|
+
import { CORE_STRINGS, isOutsideHours, localClock, type Locale } from "@codespar/agent-core";
|
|
28
28
|
import type { Conversation, OutboundBody } from "./types.js";
|
|
29
29
|
|
|
30
30
|
export interface ChannelRefusal {
|
|
@@ -44,6 +44,8 @@ export interface RuleContext {
|
|
|
44
44
|
now: () => Date;
|
|
45
45
|
/** Agreement aliases this agent knows, so "names another agreement" is decidable. */
|
|
46
46
|
knownSubjects?: readonly string[] | undefined;
|
|
47
|
+
/** The language of the refusal details. It never changes what is refused. Default pt-BR. */
|
|
48
|
+
locale?: Locale | undefined;
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
/** `123.456.789-00`, `12345678900`, `12.345.678/0001-95`, `12345678000195`. */
|
|
@@ -90,7 +92,7 @@ export function checkOutbound(to: string, body: OutboundBody, ctx: RuleContext):
|
|
|
90
92
|
if (isOutsideHours(`${close}-${open}`, ctx.now(), ctx.hours.timezone)) {
|
|
91
93
|
return {
|
|
92
94
|
rule: "collection_hours",
|
|
93
|
-
detail:
|
|
95
|
+
detail: CORE_STRINGS[ctx.locale ?? "pt-BR"].outsideCollectionHours(ctx.hours.window, ctx.hours.timezone, localClock(ctx.now(), ctx.hours.timezone)),
|
|
94
96
|
};
|
|
95
97
|
}
|
|
96
98
|
}
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* fetches `@dyvit/whatsapp-simulator-cli` at a pinned version and runs it;
|
|
26
26
|
* `npm run whatsapp:emulator` is the command.
|
|
27
27
|
*/
|
|
28
|
-
import type
|
|
28
|
+
import { CORE_STRINGS, type ConversationScript, type Locale } from "@codespar/agent-core";
|
|
29
29
|
import type { ChannelBackend, InboundMessage, OutboundBody, SentMessage, StatusUpdate } from "../types.js";
|
|
30
30
|
import { WhatsAppCloudApi, type CloudApiOptions } from "./cloud-api.js";
|
|
31
31
|
|
|
@@ -129,6 +129,8 @@ export interface EmulatorBackendOptions extends CloudApiOptions {
|
|
|
129
129
|
ask?: ((question: string) => Promise<string>) | undefined;
|
|
130
130
|
/** Where the console draws the conversation as it goes. */
|
|
131
131
|
render: (line: string) => void;
|
|
132
|
+
/** The language of the console lines above. Default pt-BR. */
|
|
133
|
+
locale?: Locale | undefined;
|
|
132
134
|
}
|
|
133
135
|
|
|
134
136
|
/**
|
|
@@ -147,7 +149,7 @@ export class WhatsAppEmulator implements ChannelBackend {
|
|
|
147
149
|
private closed = false;
|
|
148
150
|
|
|
149
151
|
constructor(private readonly options: EmulatorBackendOptions) {
|
|
150
|
-
const { driver: _driver, script: _script, pinAt: _pinAt, ask: _ask, render: _render, ...api } = options;
|
|
152
|
+
const { driver: _driver, script: _script, pinAt: _pinAt, ask: _ask, render: _render, locale: _locale, ...api } = options;
|
|
151
153
|
this.api = new WhatsAppCloudApi(api);
|
|
152
154
|
}
|
|
153
155
|
|
|
@@ -156,7 +158,7 @@ export class WhatsAppEmulator implements ChannelBackend {
|
|
|
156
158
|
await this.options.driver.health();
|
|
157
159
|
if (this.options.pinAt) await this.options.driver.pin(this.options.pinAt);
|
|
158
160
|
this.options.render("");
|
|
159
|
-
this.options.render(
|
|
161
|
+
this.options.render(this.text.waEmulatorOpen);
|
|
160
162
|
}
|
|
161
163
|
|
|
162
164
|
async next(): Promise<InboundMessage | undefined> {
|
|
@@ -193,7 +195,7 @@ export class WhatsAppEmulator implements ChannelBackend {
|
|
|
193
195
|
if (!this.options.ask) return undefined;
|
|
194
196
|
let answer: string;
|
|
195
197
|
try {
|
|
196
|
-
answer = await this.options.ask(
|
|
198
|
+
answer = await this.options.ask(this.text.waYou);
|
|
197
199
|
} catch {
|
|
198
200
|
return undefined;
|
|
199
201
|
}
|
|
@@ -207,10 +209,14 @@ export class WhatsAppEmulator implements ChannelBackend {
|
|
|
207
209
|
return this.api.deliver(to, body);
|
|
208
210
|
}
|
|
209
211
|
|
|
212
|
+
private get text() {
|
|
213
|
+
return CORE_STRINGS[this.options.locale ?? "pt-BR"];
|
|
214
|
+
}
|
|
215
|
+
|
|
210
216
|
async close(): Promise<void> {
|
|
211
217
|
if (this.closed) return;
|
|
212
218
|
this.closed = true;
|
|
213
219
|
await this.api.close();
|
|
214
|
-
this.options.render(
|
|
220
|
+
this.options.render(this.text.waEmulatorClosed);
|
|
215
221
|
}
|
|
216
222
|
}
|