@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,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A request made under a revoked mandate creates no execution: the engine
|
|
3
|
+
* refuses it before a draft. The terminal used to say nothing about it (the
|
|
4
|
+
* recorded reply even says "see the result on the terminal"), and only
|
|
5
|
+
* `inspect` showed the event. Driven as real processes, over a scratch state
|
|
6
|
+
* whose stub mandate is revoked between two runs.
|
|
7
|
+
*/
|
|
8
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
9
|
+
import { mkdtempSync } from "node:fs";
|
|
10
|
+
import { tmpdir } from "node:os";
|
|
11
|
+
import { join, resolve } from "node:path";
|
|
12
|
+
import { DatabaseSync } from "node:sqlite";
|
|
13
|
+
import { describe, expect, it } from "vitest";
|
|
14
|
+
|
|
15
|
+
const AGENT_DIR = resolve(import.meta.dirname, "..");
|
|
16
|
+
const BIN = resolve(AGENT_DIR, "../../packages/agent-runtime/bin.mjs");
|
|
17
|
+
const SCHOOL = "pague a escola de outubro";
|
|
18
|
+
const BASE_ENV = { ANTHROPIC_API_KEY: "", CODESPAR_API_KEY: "", CODESPAR_AGENT_NOW: "2026-10-07T14:00:00-03:00" };
|
|
19
|
+
|
|
20
|
+
function run(args: string[], env: Record<string, string>) {
|
|
21
|
+
const result = spawnSync(process.execPath, [BIN, "start", ...args], { cwd: AGENT_DIR, env: { ...process.env, ...BASE_ENV, ...env }, encoding: "utf8", timeout: 60_000 });
|
|
22
|
+
return { code: result.status, stdout: result.stdout, stderr: result.stderr };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** A scratch state holding one settled payment, with the stub mandate then revoked: what `codespar mandate revoke` leaves behind. */
|
|
26
|
+
function revoked(label: string): Record<string, string> {
|
|
27
|
+
const stateDir = mkdtempSync(join(tmpdir(), `bills-refused-${label}-`));
|
|
28
|
+
const env = { BILLS_STATE_DIR: stateDir, BILLS_RUNS_DIR: join(stateDir, "runs") };
|
|
29
|
+
const first = run(["--input", SCHOOL, "--approve", "--json"], env);
|
|
30
|
+
expect(first.code).toBe(0);
|
|
31
|
+
const mandateId = (JSON.parse(first.stdout.trim()) as { mandate_id: string }).mandate_id;
|
|
32
|
+
const db = new DatabaseSync(join(stateDir, "state.db"));
|
|
33
|
+
db.prepare("INSERT OR REPLACE INTO stub_mandate_status (mandate_id, status, reason, updated_at) VALUES (?, 'revoked', 'revoked by the test', ?)").run(mandateId, new Date().toISOString());
|
|
34
|
+
db.close();
|
|
35
|
+
return env;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
describe("a request under a revoked mandate, one-shot", () => {
|
|
39
|
+
it("names the refusal and its reason on the terminal, counts it, and exits 1", () => {
|
|
40
|
+
const out = run(["--input", SCHOOL, "--approve"], revoked("text"));
|
|
41
|
+
expect(out.stderr).toContain("-> refused_before_draft (mandate_revoked)");
|
|
42
|
+
expect(out.stdout).toContain("resultado deste run: 0 liquidada(s), 1 com falha ou recusada(s)");
|
|
43
|
+
expect(out.code).toBe(1);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("carries the same refusal in --json, with no execution", () => {
|
|
47
|
+
const out = run(["--input", SCHOOL, "--approve", "--json"], revoked("json"));
|
|
48
|
+
const payload = JSON.parse(out.stdout.trim()) as { executions: unknown[]; run_outcome: { failed: number }; refused_before_draft: Array<{ reason: string; detail: string }> };
|
|
49
|
+
expect(payload.executions).toHaveLength(0);
|
|
50
|
+
expect(payload.refused_before_draft).toHaveLength(1);
|
|
51
|
+
expect(payload.refused_before_draft[0]).toMatchObject({ reason: "mandate_revoked" });
|
|
52
|
+
expect(payload.refused_before_draft[0]?.detail).not.toBe("");
|
|
53
|
+
expect(payload.run_outcome.failed).toBe(1);
|
|
54
|
+
expect(out.code).toBe(1);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
describe("a request under a revoked mandate, interactive", () => {
|
|
59
|
+
it("names the refusal under the turn that made it", async () => {
|
|
60
|
+
const env = revoked("interactive");
|
|
61
|
+
const out = await new Promise<{ stdout: string; stderr: string }>((done, fail) => {
|
|
62
|
+
const child = spawn(process.execPath, [BIN, "start", "--transcript", "scenarios/mandate-revoked.transcript.jsonl"], { cwd: AGENT_DIR, env: { ...process.env, ...BASE_ENV, ...env } });
|
|
63
|
+
let stdout = "";
|
|
64
|
+
let stderr = "";
|
|
65
|
+
let typed = false;
|
|
66
|
+
// Typed when the prompt shows: readline drops a line that arrives before the question.
|
|
67
|
+
const feed = () => {
|
|
68
|
+
if (!typed && stderr.includes("> ")) {
|
|
69
|
+
typed = true;
|
|
70
|
+
child.stdin.end(SCHOOL + "\n");
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
child.stdout.on("data", (chunk: Buffer) => { stdout += chunk.toString(); });
|
|
74
|
+
child.stderr.on("data", (chunk: Buffer) => { stderr += chunk.toString(); feed(); });
|
|
75
|
+
child.on("error", fail);
|
|
76
|
+
child.on("close", () => done({ stdout, stderr }));
|
|
77
|
+
});
|
|
78
|
+
expect(out.stderr).toContain("-> refused_before_draft (mandate_revoked)");
|
|
79
|
+
expect(out.stdout).toContain("1 com falha ou recusada(s)");
|
|
80
|
+
});
|
|
81
|
+
});
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Issue #60 on the one-off payment: `codespar_pay` says `paid: true` only for
|
|
3
|
+
* a payment this call made. A bill's attempt id comes from its own execution,
|
|
4
|
+
* so the rail cannot replay one at dispatch today; the rail is scripted to
|
|
5
|
+
* answer the way the API answers a repeat, so the report is pinned before
|
|
6
|
+
* anything makes that reachable.
|
|
7
|
+
*/
|
|
8
|
+
import { mkdtempSync } from "node:fs";
|
|
9
|
+
import { tmpdir } from "node:os";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
import { describe, expect, it } from "vitest";
|
|
12
|
+
import { fixedClock, type Execution, type StubRail, type ToolContext } from "@codespar/agent-core";
|
|
13
|
+
import { setup, type Setup } from "@codespar/agent-runtime";
|
|
14
|
+
import { agent } from "../src/kit.js";
|
|
15
|
+
import { codesparPay } from "../src/modules/pix-out.js";
|
|
16
|
+
|
|
17
|
+
const APPROVER = { id: "usr_demo", channel: "terminal" };
|
|
18
|
+
|
|
19
|
+
function open(): Setup {
|
|
20
|
+
return setup(agent, {
|
|
21
|
+
mode: "human",
|
|
22
|
+
rail: "stub",
|
|
23
|
+
provider: "replay",
|
|
24
|
+
runsDir: mkdtempSync(join(tmpdir(), "bills-replay-runs-")),
|
|
25
|
+
stateDir: mkdtempSync(join(tmpdir(), "bills-replay-state-")),
|
|
26
|
+
now: fixedClock("2026-09-23T14:00:00-03:00"),
|
|
27
|
+
say: () => undefined,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function context(s: Setup): ToolContext {
|
|
32
|
+
return {
|
|
33
|
+
engine: s.engine,
|
|
34
|
+
onExecution: async (execution: Execution) => {
|
|
35
|
+
let current = execution;
|
|
36
|
+
if (current.state === "awaiting_approval") current = s.engine.approve(current.id, APPROVER);
|
|
37
|
+
if (current.state === "approved") current = await s.engine.execute(current.id);
|
|
38
|
+
return current;
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const PIX = { action: "pix", items: [{ payee: "mercado", amount_minor: 64000, description: "compras da semana" }] };
|
|
44
|
+
|
|
45
|
+
describe("codespar_pay: a settlement this call did not make is not reported as paid (#60)", () => {
|
|
46
|
+
it("a payment this call made is paid, and not replayed", async () => {
|
|
47
|
+
const s = open();
|
|
48
|
+
try {
|
|
49
|
+
const result = await codesparPay(PIX, context(s));
|
|
50
|
+
expect(result).toMatchObject({ status: "settled", paid: true, replayed: false });
|
|
51
|
+
} finally {
|
|
52
|
+
s.close();
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("a payment the rail answered from an earlier presentation is settled, replayed, and not paid by this call", async () => {
|
|
57
|
+
const s = open();
|
|
58
|
+
try {
|
|
59
|
+
const rail = s.rail as StubRail;
|
|
60
|
+
const pay = rail.pay.bind(rail);
|
|
61
|
+
rail.pay = async (payment) => {
|
|
62
|
+
const outcome = await pay(payment);
|
|
63
|
+
return outcome.status === "settled" ? { ...outcome, replayed: true } : outcome;
|
|
64
|
+
};
|
|
65
|
+
const result = (await codesparPay(PIX, context(s))) as { status: string; paid: boolean; replayed: boolean; receipt_ids: string[] };
|
|
66
|
+
expect(result).toMatchObject({ status: "settled", paid: false, replayed: true });
|
|
67
|
+
expect(result.receipt_ids).toHaveLength(1);
|
|
68
|
+
|
|
69
|
+
const oneShot = agent.kit.oneShotPayload({ setup: s, reply: "", toolCalls: [], executions: s.engine.list(), startedAt: 0 }) as { executions: Array<{ state: string; replayed: boolean }> };
|
|
70
|
+
expect(oneShot.executions).toEqual([expect.objectContaining({ state: "settled", replayed: true })]);
|
|
71
|
+
expect(agent.kit.describeExecution(s.engine.list()[0]!, s).join("\n")).toContain("esta execução não moveu dinheiro");
|
|
72
|
+
} finally {
|
|
73
|
+
s.close();
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
});
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The replayed reply of `happy-path` is the same sentence whatever the run
|
|
3
|
+
* does with the payment it proposed. It promises a result, which every run
|
|
4
|
+
* has, and no receipt, which only a settled one has.
|
|
5
|
+
*/
|
|
6
|
+
import { spawnSync } from "node:child_process";
|
|
7
|
+
import { mkdtempSync } from "node:fs";
|
|
8
|
+
import { tmpdir } from "node:os";
|
|
9
|
+
import { join, resolve } from "node:path";
|
|
10
|
+
import { describe, expect, it } from "vitest";
|
|
11
|
+
|
|
12
|
+
const AGENT_DIR = resolve(import.meta.dirname, "..");
|
|
13
|
+
const BIN = resolve(AGENT_DIR, "../../packages/agent-runtime/bin.mjs");
|
|
14
|
+
/** Inside the escalation hours and inside the example mandate's validity, whatever the day and the shell the suite runs in. */
|
|
15
|
+
const DAYTIME = "2026-09-23T14:00:00-03:00";
|
|
16
|
+
/** The line the terminal prints for a receipt that exists, in the locale these runs are pinned to. */
|
|
17
|
+
const RECEIPT_LINE = /^\s*recibo: .*rcpt_stub_/;
|
|
18
|
+
|
|
19
|
+
interface Payload {
|
|
20
|
+
reply: string;
|
|
21
|
+
executions: Array<{ state: string; escalation: { trigger: string } | null; receipt_ids: string[] }>;
|
|
22
|
+
receipts: string[];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function scratch(): Record<string, string> {
|
|
26
|
+
const stateDir = mkdtempSync(join(tmpdir(), "bills-reply-"));
|
|
27
|
+
return { BILLS_STATE_DIR: stateDir, BILLS_RUNS_DIR: join(stateDir, "runs") };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** One `npm start`, in pt-BR and on a pinned clock; `--now` in `args` overrides the clock. */
|
|
31
|
+
function start(args: string[], env: Record<string, string> = scratch()) {
|
|
32
|
+
const result = spawnSync(process.execPath, [BIN, "start", "--locale", "pt-BR", ...args], {
|
|
33
|
+
cwd: AGENT_DIR,
|
|
34
|
+
env: { ...process.env, ANTHROPIC_API_KEY: "", CODESPAR_API_KEY: "", CODESPAR_AGENT_NOW: DAYTIME, ...env },
|
|
35
|
+
encoding: "utf8",
|
|
36
|
+
timeout: 60_000,
|
|
37
|
+
});
|
|
38
|
+
return { code: result.status, stdout: result.stdout, stderr: result.stderr, payload: () => JSON.parse(result.stdout.trim()) as Payload };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const receiptLines = (terminal: string) => terminal.split("\n").filter((line) => RECEIPT_LINE.test(line));
|
|
42
|
+
|
|
43
|
+
describe("npm start -- --input: the replayed reply against what the run did", () => {
|
|
44
|
+
const INPUT = ["--input", "pague a escola de outubro", "--json"];
|
|
45
|
+
|
|
46
|
+
it.each([
|
|
47
|
+
{ name: "a person denied", flags: ["--deny"], state: "denied" },
|
|
48
|
+
{ name: "nobody decided", flags: [], state: "awaiting_approval" },
|
|
49
|
+
])("cites no receipt when $name, and there is none", ({ flags, state }) => {
|
|
50
|
+
const out = start([...INPUT, ...flags]);
|
|
51
|
+
const payload = out.payload();
|
|
52
|
+
expect(payload.executions.map((e) => e.state)).toEqual([state]);
|
|
53
|
+
expect(payload.receipts).toEqual([]);
|
|
54
|
+
expect(payload.reply).toContain("O resultado está no terminal.");
|
|
55
|
+
expect(payload.reply).not.toMatch(/recibo/i);
|
|
56
|
+
expect(receiptLines(out.stderr)).toEqual([]);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("says the same when the payment settled, and the receipt is the terminal's own line", () => {
|
|
60
|
+
const out = start([...INPUT, "--approve"]);
|
|
61
|
+
expect(out.code).toBe(0);
|
|
62
|
+
const payload = out.payload();
|
|
63
|
+
expect(payload.executions.map((e) => e.state)).toEqual(["settled"]);
|
|
64
|
+
expect(payload.receipts).toHaveLength(1);
|
|
65
|
+
expect(payload.reply).toContain("O resultado está no terminal.");
|
|
66
|
+
expect(payload.reply).not.toMatch(/recibo/i);
|
|
67
|
+
// The receipt is named once, by the terminal, on the line that gives its path.
|
|
68
|
+
expect(receiptLines(out.stderr)).toHaveLength(1);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it("a payment inside the mandate that the hour sends to a human is not said to be paid", () => {
|
|
72
|
+
// The payee has a settled payment under this mandate first, so what escalates the next one is the hour and not `new_beneficiary`, which is checked before it.
|
|
73
|
+
const env = scratch();
|
|
74
|
+
const seed = start(["--mode", "mandate", "--input", "paga 400 reais pra escola (material)", "--transcript", "test/fixtures/material-400.transcript.jsonl", "--approve", "--json"], env);
|
|
75
|
+
expect(seed.payload().executions[0]).toMatchObject({ state: "settled", escalation: { trigger: "new_beneficiary" } });
|
|
76
|
+
|
|
77
|
+
const night = start(["--mode", "mandate", "--input", "e mais 300 reais pra escola, a excursao", "--transcript", "test/fixtures/excursao-300.transcript.jsonl", "--now", "2026-09-23T23:00:00-03:00", "--json"], env);
|
|
78
|
+
const payload = night.payload();
|
|
79
|
+
expect(payload.executions).toHaveLength(1);
|
|
80
|
+
expect(payload.executions[0]).toMatchObject({ state: "awaiting_approval", escalation: { trigger: "outside_hours" }, receipt_ids: [] });
|
|
81
|
+
expect(payload.reply).not.toMatch(/paguei|recibo/i);
|
|
82
|
+
expect(receiptLines(night.stderr)).toEqual([]);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The request the Anthropic provider actually sends, captured at `fetch`, for
|
|
3
|
+
* one turn in each language (docs/OPEN_QUESTIONS.md §64). The real-model run
|
|
4
|
+
* of 9a5383e answered five English requests out of five in Portuguese, with a
|
|
5
|
+
* `## Language` rule in the system prompt. What these requests show: the
|
|
6
|
+
* system prompt is the file, the person's words arrive untouched, and the
|
|
7
|
+
* last user-role message the model reads before it replies is a tool result
|
|
8
|
+
* full of Portuguese data. So "the language of the person's latest message"
|
|
9
|
+
* was a rule the context argued against on every turn that used a tool. The
|
|
10
|
+
* loop now reads the language of what the person typed and states it in the
|
|
11
|
+
* system prompt of every step of that turn.
|
|
12
|
+
*/
|
|
13
|
+
import { mkdtempSync, readFileSync } from "node:fs";
|
|
14
|
+
import { tmpdir } from "node:os";
|
|
15
|
+
import { join } from "node:path";
|
|
16
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
17
|
+
import { fixedClock, type Execution } from "@codespar/agent-core";
|
|
18
|
+
import { setup, type Setup } from "@codespar/agent-runtime";
|
|
19
|
+
import { agent } from "../src/kit.js";
|
|
20
|
+
|
|
21
|
+
interface SentRequest {
|
|
22
|
+
system: string;
|
|
23
|
+
messages: Array<{ role: string; content: unknown }>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function message(content: unknown[], stop: string) {
|
|
27
|
+
return { id: "msg_test", type: "message", role: "assistant", model: "claude-sonnet-5", content, stop_reason: stop, stop_sequence: null, usage: { input_tokens: 1, output_tokens: 1 } };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** The model's side, scripted: read the bills, then answer. Every request body is kept. */
|
|
31
|
+
function scriptedAnthropic(): SentRequest[] {
|
|
32
|
+
const sent: SentRequest[] = [];
|
|
33
|
+
const answers = [message([{ type: "tool_use", id: "toolu_1", name: "list_bills", input: {} }], "tool_use"), message([{ type: "text", text: "ok" }], "end_turn")];
|
|
34
|
+
vi.stubGlobal("fetch", async (_url: unknown, init?: { body?: unknown }) => {
|
|
35
|
+
sent.push(JSON.parse(String(init?.body)) as SentRequest);
|
|
36
|
+
const body = answers[Math.min(sent.length - 1, answers.length - 1)];
|
|
37
|
+
return new Response(JSON.stringify(body), { status: 200, headers: { "content-type": "application/json" } });
|
|
38
|
+
});
|
|
39
|
+
return sent;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function open(): Setup {
|
|
43
|
+
return setup(agent, {
|
|
44
|
+
mode: "human",
|
|
45
|
+
rail: "stub",
|
|
46
|
+
provider: "anthropic",
|
|
47
|
+
env: { ANTHROPIC_API_KEY: "sk-ant-test-not-a-key" },
|
|
48
|
+
runsDir: mkdtempSync(join(tmpdir(), "bills-lang-runs-")),
|
|
49
|
+
stateDir: mkdtempSync(join(tmpdir(), "bills-lang-state-")),
|
|
50
|
+
now: fixedClock("2026-09-28T14:00:00-03:00"),
|
|
51
|
+
say: () => undefined,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async function oneTurn(text: string): Promise<SentRequest[]> {
|
|
56
|
+
const sent = scriptedAnthropic();
|
|
57
|
+
const s = open();
|
|
58
|
+
try {
|
|
59
|
+
const loop = s.makeLoop(s.makeRuntime(), async (e: Execution) => e);
|
|
60
|
+
await loop.turn(text);
|
|
61
|
+
} finally {
|
|
62
|
+
s.close();
|
|
63
|
+
}
|
|
64
|
+
return sent;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const PROMPT = readFileSync(join(agent.dir, "SYSTEM_PROMPT.md"), "utf8");
|
|
68
|
+
|
|
69
|
+
afterEach(() => vi.unstubAllGlobals());
|
|
70
|
+
|
|
71
|
+
describe("the reply language travels in the request, not only in the prompt", () => {
|
|
72
|
+
it("an English turn: every request of the turn states English, and the person's words arrive as typed", async () => {
|
|
73
|
+
const sent = await oneTurn("pay the cleaner for September, please");
|
|
74
|
+
expect(sent).toHaveLength(2);
|
|
75
|
+
for (const request of sent) {
|
|
76
|
+
expect(request.system.startsWith(PROMPT)).toBe(true);
|
|
77
|
+
expect(request.system).toMatch(/wrote their last message in English\. Write your reply in English/);
|
|
78
|
+
expect(request.messages[0]).toEqual({ role: "user", content: "pay the cleaner for September, please" });
|
|
79
|
+
}
|
|
80
|
+
// What the model reads last before it answers: a user-role tool result, in Portuguese.
|
|
81
|
+
const last = sent[1]!.messages.at(-1)!;
|
|
82
|
+
expect(last.role).toBe("user");
|
|
83
|
+
expect(JSON.stringify(last.content)).toContain("mensalidade outubro");
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("a Portuguese turn states Brazilian Portuguese", async () => {
|
|
87
|
+
const sent = await oneTurn("pague a escola de outubro");
|
|
88
|
+
for (const request of sent) expect(request.system).toMatch(/wrote their last message in Brazilian Portuguese\. Write your reply in Brazilian Portuguese/);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it("a turn whose language cannot be read adds nothing, and the prompt's own default stands", async () => {
|
|
92
|
+
const sent = await oneTurn("ok");
|
|
93
|
+
for (const request of sent) expect(request.system).toBe(PROMPT);
|
|
94
|
+
});
|
|
95
|
+
});
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Two refusals and one replay that need a real process: `rerun` on a run that
|
|
3
|
+
* stopped at `awaiting_approval`, and `start --transcript` on a file that is
|
|
4
|
+
* not there.
|
|
5
|
+
*/
|
|
6
|
+
import { spawnSync } from "node:child_process";
|
|
7
|
+
import { existsSync, mkdtempSync, readdirSync } from "node:fs";
|
|
8
|
+
import { tmpdir } from "node:os";
|
|
9
|
+
import { join, resolve } from "node:path";
|
|
10
|
+
import { describe, expect, it } from "vitest";
|
|
11
|
+
import { loadAdversarialCase, runAdversarialCase } from "@codespar/agent-runtime";
|
|
12
|
+
import { agent } from "../src/kit.js";
|
|
13
|
+
|
|
14
|
+
const AGENT_DIR = resolve(import.meta.dirname, "..");
|
|
15
|
+
const NODE = process.execPath;
|
|
16
|
+
const BIN = resolve(AGENT_DIR, "../../packages/agent-runtime/bin.mjs");
|
|
17
|
+
|
|
18
|
+
function run(command: string, args: string[], env: Record<string, string>) {
|
|
19
|
+
const result = spawnSync(NODE, [BIN, command, ...args], {
|
|
20
|
+
cwd: AGENT_DIR,
|
|
21
|
+
env: { ...process.env, ANTHROPIC_API_KEY: "", CODESPAR_API_KEY: "", ...env },
|
|
22
|
+
encoding: "utf8",
|
|
23
|
+
timeout: 60_000,
|
|
24
|
+
});
|
|
25
|
+
return { code: result.status, stdout: result.stdout, stderr: result.stderr };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface RerunReport {
|
|
29
|
+
same_states: boolean;
|
|
30
|
+
original: string[];
|
|
31
|
+
rerun: string[];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* A rerun recomputes every decision of the core and takes the person's from
|
|
36
|
+
* the recording. Where the recording holds none, because nobody decided, the
|
|
37
|
+
* rerun decides nothing either.
|
|
38
|
+
*/
|
|
39
|
+
describe("npm run rerun <run-id> on a run that stopped at awaiting_approval", () => {
|
|
40
|
+
const LEFT = "1 execution(s) left in awaiting_approval, as the original left it";
|
|
41
|
+
|
|
42
|
+
it("replays an adversarial case that only escalates to the same open approval", async () => {
|
|
43
|
+
const runsDir = mkdtempSync(join(tmpdir(), "bills-rerun-open-"));
|
|
44
|
+
const env = { BILLS_STATE_DIR: join(runsDir, "state"), BILLS_RUNS_DIR: runsDir };
|
|
45
|
+
const original = await runAdversarialCase(agent, loadAdversarialCase(agent, "false-authority"), { runsDir });
|
|
46
|
+
expect(original.ok).toBe(true);
|
|
47
|
+
expect(original.states).toEqual(["awaiting_approval"]);
|
|
48
|
+
|
|
49
|
+
const out = run("rerun", [original.run_id, "--json"], env);
|
|
50
|
+
expect(out.stderr).not.toContain("DIFFERS");
|
|
51
|
+
expect(out.code).toBe(0);
|
|
52
|
+
const report = JSON.parse(out.stdout.trim()) as RerunReport;
|
|
53
|
+
expect(report.same_states).toBe(true);
|
|
54
|
+
expect(report.original).toEqual(["awaiting_approval"]);
|
|
55
|
+
expect(report.rerun).toEqual(["awaiting_approval"]);
|
|
56
|
+
expect(out.stderr).toContain(`rerun ok: 1 transition(s), same sequence as ${original.run_id}; ${LEFT}`);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("replays a one-shot nobody decided to the same open approval", () => {
|
|
60
|
+
const stateDir = mkdtempSync(join(tmpdir(), "bills-rerun-open-"));
|
|
61
|
+
const env = { BILLS_STATE_DIR: stateDir, BILLS_RUNS_DIR: join(stateDir, "runs") };
|
|
62
|
+
const left = run("start", ["--input", "pague a escola de outubro", "--json"], env);
|
|
63
|
+
expect(left.code).toBe(0);
|
|
64
|
+
const { run_id } = JSON.parse(left.stdout.trim()) as { run_id: string };
|
|
65
|
+
|
|
66
|
+
const out = run("rerun", [run_id, "--json"], env);
|
|
67
|
+
expect(out.code).toBe(0);
|
|
68
|
+
expect((JSON.parse(out.stdout.trim()) as RerunReport).rerun).toEqual(["awaiting_approval"]);
|
|
69
|
+
expect(out.stderr).toContain(LEFT);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("still replays the decision of a run somebody decided, and says nothing was left open", () => {
|
|
73
|
+
for (const [flag, last] of [
|
|
74
|
+
["--approve", "settled"],
|
|
75
|
+
["--deny", "denied"],
|
|
76
|
+
] as const) {
|
|
77
|
+
const stateDir = mkdtempSync(join(tmpdir(), "bills-rerun-decided-"));
|
|
78
|
+
const env = { BILLS_STATE_DIR: stateDir, BILLS_RUNS_DIR: join(stateDir, "runs") };
|
|
79
|
+
const decided = run("start", ["--input", "pague a escola de outubro", flag, "--json"], env);
|
|
80
|
+
const { run_id } = JSON.parse(decided.stdout.trim()) as { run_id: string };
|
|
81
|
+
|
|
82
|
+
const out = run("rerun", [run_id, "--json"], env);
|
|
83
|
+
expect(out.code).toBe(0);
|
|
84
|
+
const report = JSON.parse(out.stdout.trim()) as RerunReport;
|
|
85
|
+
expect(report.same_states).toBe(true);
|
|
86
|
+
expect(report.rerun.at(-1)).toBe(last);
|
|
87
|
+
expect(out.stderr).toContain("rerun ok");
|
|
88
|
+
expect(out.stderr).not.toContain("left in awaiting_approval, as the original");
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
describe("npm start -- --transcript <a file that is not there>", () => {
|
|
94
|
+
it("refuses it by its path, with no stack, and opens no run", () => {
|
|
95
|
+
const stateDir = mkdtempSync(join(tmpdir(), "bills-no-transcript-"));
|
|
96
|
+
const runsDir = join(stateDir, "runs");
|
|
97
|
+
const env = { BILLS_STATE_DIR: stateDir, BILLS_RUNS_DIR: runsDir };
|
|
98
|
+
const missing = join(stateDir, "nowhere.transcript.jsonl");
|
|
99
|
+
|
|
100
|
+
// A path that does not exist, and one that exists and is a directory.
|
|
101
|
+
for (const path of [missing, stateDir]) {
|
|
102
|
+
const out = run("start", ["--input", "pague a escola de outubro", "--provider", "replay", "--transcript", path, "--json"], env);
|
|
103
|
+
expect(out.code).toBe(1);
|
|
104
|
+
expect(out.stdout).toBe("");
|
|
105
|
+
expect(out.stderr.trim()).toBe(`no transcript at ${path}`);
|
|
106
|
+
expect(out.stderr).not.toMatch(/ENOENT|EISDIR/);
|
|
107
|
+
expect(out.stderr).not.toMatch(/^\s+at /m);
|
|
108
|
+
}
|
|
109
|
+
expect(existsSync(runsDir) ? readdirSync(runsDir) : []).toEqual([]);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it("still replays a transcript that is there", () => {
|
|
113
|
+
const stateDir = mkdtempSync(join(tmpdir(), "bills-transcript-"));
|
|
114
|
+
const env = { BILLS_STATE_DIR: stateDir, BILLS_RUNS_DIR: join(stateDir, "runs") };
|
|
115
|
+
const recorded = join(AGENT_DIR, "evals", "adversarial", "false-authority.transcript.jsonl");
|
|
116
|
+
const out = run("start", ["--input", loadAdversarialCase(agent, "false-authority").input, "--mode", "mandate", "--provider", "replay", "--transcript", recorded, "--json"], env);
|
|
117
|
+
expect(out.code).toBe(0);
|
|
118
|
+
expect(out.stderr).toContain(`replaying ${recorded}`);
|
|
119
|
+
});
|
|
120
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A rerun replays the model's side and the person's decisions. What the world
|
|
3
|
+
* did in the original (the mandate revoked mid-run, a rail that answered
|
|
4
|
+
* "uncertain") is not replayed, and a rerun that ignored it paid what the
|
|
5
|
+
* original denied and reported a run that DIFFERS. It refuses by name.
|
|
6
|
+
*/
|
|
7
|
+
import { spawnSync } from "node:child_process";
|
|
8
|
+
import { mkdtempSync, readdirSync } from "node:fs";
|
|
9
|
+
import { tmpdir } from "node:os";
|
|
10
|
+
import { join, resolve } from "node:path";
|
|
11
|
+
import { describe, expect, it } from "vitest";
|
|
12
|
+
import { loadScenario, runScenario } from "@codespar/agent-runtime";
|
|
13
|
+
import { agent } from "../src/kit.js";
|
|
14
|
+
|
|
15
|
+
const AGENT_DIR = resolve(import.meta.dirname, "..");
|
|
16
|
+
const BIN = resolve(AGENT_DIR, "../../packages/agent-runtime/bin.mjs");
|
|
17
|
+
|
|
18
|
+
function rerun(runsDir: string, args: string[]) {
|
|
19
|
+
const result = spawnSync(process.execPath, [BIN, "rerun", ...args], {
|
|
20
|
+
cwd: AGENT_DIR,
|
|
21
|
+
env: { ...process.env, ANTHROPIC_API_KEY: "", CODESPAR_API_KEY: "", BILLS_RUNS_DIR: runsDir, BILLS_STATE_DIR: join(runsDir, "state") },
|
|
22
|
+
encoding: "utf8",
|
|
23
|
+
timeout: 60_000,
|
|
24
|
+
});
|
|
25
|
+
return { code: result.status, stdout: result.stdout, stderr: result.stderr };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
describe("npm run rerun <run-id> on a run the world interfered with", () => {
|
|
29
|
+
it.each(["human", "mandate"] as const)("mandate-revoked [%s]: names the revocation and the uncertain answer, and replays nothing", async (mode) => {
|
|
30
|
+
const runsDir = mkdtempSync(join(tmpdir(), "bills-rerun-world-"));
|
|
31
|
+
const original = await runScenario(agent, loadScenario(agent, "mandate-revoked"), { mode, rail: "stub", runsDir });
|
|
32
|
+
expect(original.executions.map((e) => e.state)).toEqual(["settled", "settled", "denied"]);
|
|
33
|
+
const NAMED = `runs/${original.run_id} cannot be compared with a rerun: it met an uncertain answer from the rail, and a mandate that was revoked, which a rerun does not replay`;
|
|
34
|
+
|
|
35
|
+
const out = rerun(runsDir, [original.run_id]);
|
|
36
|
+
expect(out.code).toBe(1);
|
|
37
|
+
expect(out.stderr.trim().split("\n").at(-1)).toBe(NAMED);
|
|
38
|
+
expect(out.stderr).not.toContain("DIFFERS");
|
|
39
|
+
expect(out.stdout).toBe("");
|
|
40
|
+
|
|
41
|
+
const asJson = rerun(runsDir, [original.run_id, "--json"]);
|
|
42
|
+
expect(asJson.code).toBe(1);
|
|
43
|
+
expect(JSON.parse(asJson.stdout.trim())).toEqual({ run_id: original.run_id, error: NAMED, not_replayed: ["an uncertain answer from the rail", "a mandate that was revoked"] });
|
|
44
|
+
// Nothing was replayed: the runs folder holds the original and no rerun of it.
|
|
45
|
+
expect(readdirSync(runsDir).filter((entry) => entry.startsWith("run_"))).toEqual([original.run_id]);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("a run the world left alone is still replayed", async () => {
|
|
49
|
+
const runsDir = mkdtempSync(join(tmpdir(), "bills-rerun-world-"));
|
|
50
|
+
const original = await runScenario(agent, loadScenario(agent, "happy-path"), { mode: "human", rail: "stub", runsDir });
|
|
51
|
+
const out = rerun(runsDir, [original.run_id]);
|
|
52
|
+
expect(out.code).toBe(0);
|
|
53
|
+
expect(out.stderr).toContain("rerun ok");
|
|
54
|
+
});
|
|
55
|
+
});
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
{
|
|
45
45
|
"name": "list_bills",
|
|
46
46
|
"effect": "read",
|
|
47
|
-
"description": "The bills of the current month: payee alias, name, amount in BRL cents, due date and whether it was already paid in this mandate window. Read-only.",
|
|
47
|
+
"description": "The bills of the current month: payee alias, name, amount in BRL cents, due date, days until it falls due (negative once past) and whether it was already paid in this mandate window, plus `today`, the only date you know. Read-only.",
|
|
48
48
|
"input_schema": { "type": "object", "properties": {} }
|
|
49
49
|
}
|
|
50
50
|
]
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# @codespar/agent-core
|
|
2
2
|
|
|
3
|
-
The primitives every CodeSpar starter-kit agent inherits (spec v5.1.1,
|
|
3
|
+
The primitives every CodeSpar starter-kit agent inherits (section 4 of spec v5.1.1, [`docs/spec-v5.1.1.md`](../../docs/spec-v5.1.1.md), the only spec version in this repository; [`docs/OPEN_QUESTIONS.md`](../../docs/OPEN_QUESTIONS.md) says where later parts were built against v5.2 and the checkout spec v0.2): the execution state machine, the approval artifact, the `agent.yaml` manifest, `escalate_above`, `actor`, local state in SQLite, the proof bundle, the rail contract, the conversation loop and the two providers.
|
|
4
4
|
|
|
5
|
-
This package is the decisions. The RUNNER around them — the terminal channel, `codespar-agent start|consent|approve|deny|resume|rerun|reconcile|poll|webhook|check|eval`, the setup that wires this package to an agent directory, and the scenario and adversarial runners — is [`@codespar/agent-runtime`](../agent-runtime), which depends on this one and is what an agent's `package.json` scripts call (#13). Nothing here knows an agent's name.
|
|
5
|
+
This package is the decisions. The RUNNER around them — the terminal channel, `codespar-agent start|consent|approve|deny|resume|rerun|reconcile|poll|webhook|inspect|check|eval|verify`, the setup that wires this package to an agent directory, and the scenario and adversarial runners — is [`@codespar/agent-runtime`](../agent-runtime), which depends on this one and is what an agent's `package.json` scripts call (#13). Nothing here knows an agent's name.
|
|
6
6
|
|
|
7
7
|
## The state machine, and what the types do and do not prove
|
|
8
8
|
|
|
@@ -25,10 +25,29 @@ This package is the decisions. The RUNNER around them — the terminal channel,
|
|
|
25
25
|
|
|
26
26
|
Every spend carries `approval: { items_hash, batch_hash? }`, the artifact's own hashes (`spendApprovalOf`), and the API seals them into the receipt's chain as a link of their own (chain v4, ent#1670). Both rails refuse a spend without them before any call. `composition` is not sent: the API takes the two hashes and nothing else, and only charges carry a composition today. `receipt-chain.ts` recomputes a chain from the receipt read under the `chain_recipe` the key document publishes (RFC 8785 implemented locally, `node:crypto` only), and `verifyReceiptRead` holds the signature, the body and the sealed approval link against the artifact, in that order. It proves WHAT was approved to anybody holding the read; WHO approved stays in the artifact, under the local key. `docs/OPEN_QUESTIONS.md` §3 and §47.
|
|
27
27
|
|
|
28
|
+
## Who acted, on the wire
|
|
29
|
+
|
|
30
|
+
Every spend sends the kit's actor as the SDK's `PaymentActor` (`wireActorOf` in `rail.ts`): an agent is `{ type: "agent", id: "<name>@<version>", on_behalf_of: <the mandate's consumer> }`, a person `{ type: "human", id, channel }`. `agent_id` still goes too; it names the agent the mandate was signed for. The rail reads the actor the API recorded back as `sealed_actor`, the bundle's receipt copy keeps it beside the kit's own `actor`, and one that differs from what was sent, or is missing, is a `receipt.actor_mismatch` event. It does not stop the run: the actor is what the receipt records, not what it proves. It is not in the chain, so a third party checking the Ed25519 signature learns nothing about who triggered the spend, and a charge carries no actor at all. §2.
|
|
31
|
+
|
|
32
|
+
## A settlement this run did not make
|
|
33
|
+
|
|
34
|
+
A spend presented again under the same attempt id is answered with the earlier payment (`idempotent_replay`). Dispatch marks that outcome `replayed: true`, and `isReplayedSettlement(execution)` is true when every settled attempt carries the mark. The money moved, and this execution did not move it. The execution is still `settled`. Only dispatch writes the mark, because dispatch is always this execution's first presentation of an id. Reconcile does not copy it: a lookup presents the attempt again, and the API answers every look at a settled attempt as a replay, this execution's own payment included. The tool results and a one-shot's `--json` read this predicate (`replayed`); `inspect` reads the same mark from the bundle's rail answers. An attempt closed by reconcile is still counted as paid by the execution that looked it up. §39c.
|
|
35
|
+
|
|
28
36
|
## Reconcile never re-dispatches
|
|
29
37
|
|
|
30
38
|
An execution left in `executing` is looked up on the rail, attempt by attempt. A recorded settled or failed outcome closes it; `in_flight`, `uncertain` or unknown leaves it in `executing` with `reason: rail_uncertain` for a human. The single exception is an outbox row still `pending` (the state changed, no call was ever made): those attempts go out once, under the same ids.
|
|
31
39
|
|
|
40
|
+
## The conversation loop
|
|
41
|
+
|
|
42
|
+
`AgentLoop.turn` (`agent.ts`) sends the model the system prompt, the conversation and the tool specs, and hands each tool call to the kit's handler for it; a tool outside `tools.json` is refused `tool_not_allowed`. Only the engine behind the handlers moves money. Two things it adds that no prompt can:
|
|
43
|
+
|
|
44
|
+
- **The reply language.** `detectLanguage` (`language.ts`) reads the language of what the person typed, Brazilian Portuguese or English, from function words; payee names, amounts and Pix keys count for neither. The loop appends a "Reply language for this turn" section naming it to the system prompt of every step of the turn. Tool results do not count: on the Messages API they are user-role messages, and a prompt rule alone lost to their Portuguese data. A turn with no lead either way keeps the previous turn's language, and before any lead the prompt's own default stands. The transcript's user line records `reply_language` (`null` before any lead). §64.
|
|
45
|
+
- **The date.** `ExecutionEngine.today()` is the date in the guardrails' timezone at the engine's clock, so `--now` pins it. `list_bills`, `list_payables` and `list_agreements` return it as `today`, and bills and payables also carry `days_until_due` (`daysUntil`), because the model has no calendar of its own.
|
|
46
|
+
|
|
47
|
+
## What the code prints, per locale
|
|
48
|
+
|
|
49
|
+
`locale.ts` and `strings.ts` (#64). A run has one locale, `pt-BR` or `en`: `--locale`, else the optional `locale:` of `agent.yaml`, else `pt-BR` (`resolveLocale`). `CORE_STRINGS` holds the lines every agent shares (the batch gesture, the waits, how an execution and a payable instrument read, the WhatsApp operator lines) in both locales, and `tableGaps` is what `npm run check` runs over it and over each kit's table: a key one locale lacks, an empty string, or a function whose arity differs is an error. `formatBRL` and `formatDay` format for the locale's reader ("R$ 1.850,00" / "R$1,850.00"; "30/09/2026" / "2026-09-30"). `WHATSAPP_LANGUAGE` maps a locale to the language Meta approves a template in (`pt_BR`, `en_US`); the template registry holds one copy per (name, language), and the check requires every template in the language of every locale. None of it touches what an answer decides, and it is independent of the reply language above.
|
|
50
|
+
|
|
32
51
|
## Stubs
|
|
33
52
|
|
|
34
53
|
`stubs/mandate-status.ts` (the section 4.7 status source for runs without a key: revocation, pause and the organization kill switch, over the local state.db) and `stubs/rail.ts` (the sandbox rail) are stand-ins for the CI, the scenarios and `rerun`, marked as such. With a test key the engine reads the mandate status from the API instead (`api/mandate-status.ts`, `GET /v1/mandates/{id}`), fail-closed: anything but `active` refuses `executing`, `org_paused: true` (the organization kill switch, ent#1648) refuses it whatever `status` says, and a read that does not answer, or answers without `org_paused`, is `mandate_status_unavailable`, never "assume active". The approval artifact is signed with a local development key (`approval.ts`); the API does not sign approval lists.
|