@codespar/cli 0.14.0 → 0.16.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 +44 -17
- package/dist/commands/audit-replay.js +267 -0
- package/dist/commands/audit-replay.js.map +1 -0
- package/dist/commands/init.js +28 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/login.js +2 -1
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/mandate-verify.js +75 -27
- package/dist/commands/mandate-verify.js.map +1 -1
- package/dist/config.js +17 -1
- package/dist/config.js.map +1 -1
- package/dist/did.js +262 -41
- package/dist/did.js.map +1 -1
- package/dist/index.js +33 -7
- package/dist/index.js.map +1 -1
- package/dist/surface.js +4 -1
- package/dist/surface.js.map +1 -1
- package/package.json +1 -1
- package/templates/bills-agent/README.md +8 -5
- package/templates/bills-agent/agents/bills-agent/.env.example +3 -3
- package/templates/bills-agent/agents/bills-agent/AGENTS.md +1 -1
- package/templates/bills-agent/agents/bills-agent/CLAUDE.md +1 -1
- package/templates/bills-agent/agents/bills-agent/README.md +62 -22
- package/templates/bills-agent/agents/bills-agent/SYSTEM_PROMPT.md +1 -1
- package/templates/bills-agent/agents/bills-agent/agent.yaml +2 -2
- package/templates/bills-agent/agents/bills-agent/package.json +14 -11
- package/templates/bills-agent/agents/bills-agent/src/kit.ts +193 -0
- package/templates/bills-agent/agents/bills-agent/test/adversarial.test.ts +8 -7
- package/templates/bills-agent/agents/bills-agent/test/check.test.ts +19 -2
- package/templates/bills-agent/agents/bills-agent/test/cli.test.ts +72 -24
- package/templates/bills-agent/agents/bills-agent/test/fixtures/excursao-300.transcript.jsonl +2 -0
- package/templates/bills-agent/agents/bills-agent/test/fixtures/material-400.transcript.jsonl +2 -0
- package/templates/bills-agent/agents/bills-agent/test/inspect.test.ts +124 -0
- package/templates/bills-agent/agents/bills-agent/test/provider.test.ts +25 -0
- package/templates/bills-agent/agents/bills-agent/test/scenarios.test.ts +10 -9
- package/templates/bills-agent/agents/bills-agent/tsconfig.json +0 -1
- package/templates/bills-agent/package.json +5 -2
- package/templates/bills-agent/packages/agent-core/README.md +2 -0
- package/templates/bills-agent/packages/agent-core/package.json +1 -1
- package/templates/bills-agent/packages/agent-core/src/api/charge-rail.ts +27 -6
- package/templates/bills-agent/packages/agent-core/src/api/rail.ts +16 -0
- package/templates/bills-agent/packages/agent-core/src/api/sandbox-payer.ts +20 -7
- package/templates/bills-agent/packages/agent-core/src/approval.ts +16 -2
- package/templates/bills-agent/packages/agent-core/src/bundle.ts +50 -4
- package/templates/bills-agent/packages/agent-core/src/channels.ts +140 -0
- package/templates/bills-agent/packages/agent-core/src/check.ts +90 -8
- package/templates/bills-agent/packages/agent-core/src/clock.ts +42 -0
- package/templates/bills-agent/packages/agent-core/src/engine.ts +119 -18
- package/templates/bills-agent/packages/agent-core/src/hash.ts +13 -0
- package/templates/bills-agent/packages/agent-core/src/index.ts +3 -0
- package/templates/bills-agent/packages/agent-core/src/manifest.ts +1 -1
- package/templates/bills-agent/packages/agent-core/src/rail.ts +16 -2
- package/templates/bills-agent/packages/agent-core/src/receipt-verification.ts +401 -0
- package/templates/bills-agent/packages/agent-core/src/state-machine.ts +3 -1
- package/templates/bills-agent/packages/agent-core/src/stubs/charge-rail.ts +2 -0
- package/templates/bills-agent/packages/agent-core/src/stubs/rail.ts +19 -2
- package/templates/bills-agent/packages/agent-core/src/types.ts +28 -0
- package/templates/bills-agent/packages/agent-core/test/approval.test.ts +36 -2
- package/templates/bills-agent/packages/agent-core/test/bundle.test.ts +85 -0
- package/templates/bills-agent/packages/agent-core/test/clock.test.ts +25 -0
- package/templates/bills-agent/packages/agent-core/test/engine.test.ts +73 -1
- package/templates/bills-agent/packages/agent-core/test/fixtures/staging-receipt-keys.json +18 -0
- package/templates/bills-agent/packages/agent-core/test/fixtures/staging-receipt.json +24 -0
- package/templates/bills-agent/packages/agent-core/test/helpers.ts +1 -1
- package/templates/bills-agent/packages/agent-core/test/manifest.test.ts +2 -2
- package/templates/bills-agent/packages/agent-core/test/receipt-verification.test.ts +316 -0
- package/templates/bills-agent/packages/agent-core/test/receivables.test.ts +51 -0
- package/templates/bills-agent/packages/agent-runtime/README.md +68 -0
- package/templates/bills-agent/packages/agent-runtime/bin.mjs +32 -0
- package/templates/bills-agent/packages/agent-runtime/package.json +23 -0
- package/templates/bills-agent/{agents/bills-agent → packages/agent-runtime}/src/adversarial.ts +36 -44
- package/templates/bills-agent/packages/agent-runtime/src/agent.ts +68 -0
- package/templates/bills-agent/packages/agent-runtime/src/channels/contact.ts +13 -0
- package/templates/bills-agent/packages/agent-runtime/src/channels/index.ts +72 -0
- package/templates/bills-agent/packages/agent-runtime/src/channels/rules.ts +120 -0
- package/templates/bills-agent/packages/agent-runtime/src/channels/types.ts +124 -0
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +358 -0
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +206 -0
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/evidence.ts +109 -0
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +225 -0
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +143 -0
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +47 -0
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +113 -0
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +113 -0
- package/templates/bills-agent/packages/agent-runtime/src/cli.ts +98 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/check.ts +15 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/decide.ts +63 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/eval.ts +58 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/inspect.ts +100 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +317 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/poll.ts +144 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/reconcile.ts +42 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/rerun.ts +86 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/resume.ts +43 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +131 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/start.ts +245 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/verify.ts +129 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/webhook.ts +39 -0
- package/templates/bills-agent/packages/agent-runtime/src/default-kit.ts +83 -0
- package/templates/bills-agent/packages/agent-runtime/src/index.ts +12 -0
- package/templates/bills-agent/packages/agent-runtime/src/inspect.ts +797 -0
- package/templates/bills-agent/packages/agent-runtime/src/kit.ts +206 -0
- package/templates/{collections-agent/agents/collections-agent → bills-agent/packages/agent-runtime}/src/poll.ts +22 -11
- package/templates/{collections-agent/agents/collections-agent → bills-agent/packages/agent-runtime}/src/scenarios.ts +50 -34
- package/templates/bills-agent/{agents/bills-agent → packages/agent-runtime}/src/setup.ts +88 -66
- package/templates/bills-agent/packages/agent-runtime/src/terminal.ts +154 -0
- package/templates/{collections-agent/agents/collections-agent/channels/webhook/index.ts → bills-agent/packages/agent-runtime/src/webhook.ts} +1 -1
- package/templates/bills-agent/packages/agent-runtime/test/inspect.test.ts +336 -0
- package/templates/bills-agent/packages/agent-runtime/test/verify-cli.test.ts +127 -0
- package/templates/bills-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +232 -0
- package/templates/bills-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +204 -0
- package/templates/bills-agent/packages/agent-runtime/test/whatsapp-evidence.test.ts +94 -0
- package/templates/bills-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +174 -0
- package/templates/bills-agent/packages/agent-runtime/test/whatsapp-session.test.ts +135 -0
- package/templates/bills-agent/packages/agent-runtime/tsconfig.json +9 -0
- package/templates/bills-agent/vitest.config.ts +1 -1
- package/templates/collections-agent/README.md +8 -5
- package/templates/collections-agent/agents/collections-agent/.env.example +14 -0
- package/templates/collections-agent/agents/collections-agent/AGENTS.md +6 -4
- package/templates/collections-agent/agents/collections-agent/CLAUDE.md +6 -4
- package/templates/collections-agent/agents/collections-agent/README.md +184 -16
- package/templates/collections-agent/agents/collections-agent/agent.yaml +3 -3
- package/templates/collections-agent/agents/collections-agent/channels/whatsapp/README.md +111 -0
- package/templates/collections-agent/agents/collections-agent/channels/whatsapp/acordo-1042.json +11 -0
- package/templates/collections-agent/agents/collections-agent/channels/whatsapp/acordo-1103.json +11 -0
- package/templates/collections-agent/agents/collections-agent/channels/whatsapp/templates.json +23 -0
- package/templates/collections-agent/agents/collections-agent/package.json +12 -10
- package/templates/collections-agent/agents/collections-agent/runbook.md +52 -1
- package/templates/collections-agent/agents/collections-agent/src/kit.ts +265 -0
- package/templates/collections-agent/agents/collections-agent/test/adversarial.test.ts +9 -8
- package/templates/collections-agent/agents/collections-agent/test/check.test.ts +43 -1
- package/templates/collections-agent/agents/collections-agent/test/cli.test.ts +56 -18
- package/templates/collections-agent/agents/collections-agent/test/fixtures/agreed-1042-awaiting-payer.transcript.jsonl +4 -0
- package/templates/collections-agent/agents/collections-agent/test/scenarios.test.ts +11 -10
- package/templates/collections-agent/agents/collections-agent/test/webhook.test.ts +4 -7
- package/templates/collections-agent/agents/collections-agent/test/whatsapp-poll.test.ts +271 -0
- package/templates/collections-agent/agents/collections-agent/test/whatsapp.test.ts +213 -0
- package/templates/collections-agent/agents/collections-agent/tsconfig.json +0 -1
- package/templates/collections-agent/package.json +3 -1
- package/templates/collections-agent/packages/agent-core/README.md +2 -0
- package/templates/collections-agent/packages/agent-core/package.json +1 -1
- package/templates/collections-agent/packages/agent-core/src/api/charge-rail.ts +27 -6
- package/templates/collections-agent/packages/agent-core/src/api/rail.ts +16 -0
- package/templates/collections-agent/packages/agent-core/src/api/sandbox-payer.ts +20 -7
- package/templates/collections-agent/packages/agent-core/src/approval.ts +16 -2
- package/templates/collections-agent/packages/agent-core/src/bundle.ts +50 -4
- package/templates/collections-agent/packages/agent-core/src/channels.ts +140 -0
- package/templates/collections-agent/packages/agent-core/src/check.ts +90 -8
- package/templates/collections-agent/packages/agent-core/src/clock.ts +42 -0
- package/templates/collections-agent/packages/agent-core/src/engine.ts +119 -18
- package/templates/collections-agent/packages/agent-core/src/hash.ts +13 -0
- package/templates/collections-agent/packages/agent-core/src/index.ts +3 -0
- package/templates/collections-agent/packages/agent-core/src/manifest.ts +1 -1
- package/templates/collections-agent/packages/agent-core/src/rail.ts +16 -2
- package/templates/collections-agent/packages/agent-core/src/receipt-verification.ts +401 -0
- package/templates/collections-agent/packages/agent-core/src/state-machine.ts +3 -1
- package/templates/collections-agent/packages/agent-core/src/stubs/charge-rail.ts +2 -0
- package/templates/collections-agent/packages/agent-core/src/stubs/rail.ts +19 -2
- package/templates/collections-agent/packages/agent-core/src/types.ts +28 -0
- package/templates/collections-agent/packages/agent-core/test/approval.test.ts +36 -2
- package/templates/collections-agent/packages/agent-core/test/bundle.test.ts +85 -0
- package/templates/collections-agent/packages/agent-core/test/clock.test.ts +25 -0
- package/templates/collections-agent/packages/agent-core/test/engine.test.ts +73 -1
- package/templates/collections-agent/packages/agent-core/test/fixtures/staging-receipt-keys.json +18 -0
- package/templates/collections-agent/packages/agent-core/test/fixtures/staging-receipt.json +24 -0
- package/templates/collections-agent/packages/agent-core/test/helpers.ts +1 -1
- package/templates/collections-agent/packages/agent-core/test/manifest.test.ts +2 -2
- package/templates/collections-agent/packages/agent-core/test/receipt-verification.test.ts +316 -0
- package/templates/collections-agent/packages/agent-core/test/receivables.test.ts +51 -0
- package/templates/collections-agent/packages/agent-runtime/README.md +68 -0
- package/templates/collections-agent/packages/agent-runtime/bin.mjs +32 -0
- package/templates/collections-agent/packages/agent-runtime/package.json +23 -0
- package/templates/collections-agent/{agents/collections-agent → packages/agent-runtime}/src/adversarial.ts +29 -50
- package/templates/collections-agent/packages/agent-runtime/src/agent.ts +68 -0
- package/templates/collections-agent/packages/agent-runtime/src/channels/contact.ts +13 -0
- package/templates/collections-agent/packages/agent-runtime/src/channels/index.ts +72 -0
- package/templates/collections-agent/packages/agent-runtime/src/channels/rules.ts +120 -0
- package/templates/collections-agent/packages/agent-runtime/src/channels/types.ts +124 -0
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +358 -0
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +206 -0
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/evidence.ts +109 -0
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +225 -0
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +143 -0
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +47 -0
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +113 -0
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +113 -0
- package/templates/collections-agent/packages/agent-runtime/src/cli.ts +98 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/check.ts +15 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/decide.ts +63 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/eval.ts +58 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/inspect.ts +100 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +317 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/poll.ts +144 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/reconcile.ts +42 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/rerun.ts +86 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/resume.ts +43 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +131 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/start.ts +245 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/verify.ts +129 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/webhook.ts +39 -0
- package/templates/collections-agent/packages/agent-runtime/src/default-kit.ts +83 -0
- package/templates/collections-agent/packages/agent-runtime/src/index.ts +12 -0
- package/templates/collections-agent/packages/agent-runtime/src/inspect.ts +797 -0
- package/templates/collections-agent/packages/agent-runtime/src/kit.ts +206 -0
- package/templates/collections-agent/packages/agent-runtime/src/poll.ts +105 -0
- package/templates/{bills-agent/agents/bills-agent → collections-agent/packages/agent-runtime}/src/scenarios.ts +98 -26
- package/templates/collections-agent/packages/agent-runtime/src/setup.ts +229 -0
- package/templates/collections-agent/packages/agent-runtime/src/terminal.ts +154 -0
- package/templates/collections-agent/packages/agent-runtime/src/webhook.ts +131 -0
- package/templates/collections-agent/packages/agent-runtime/test/inspect.test.ts +336 -0
- package/templates/collections-agent/packages/agent-runtime/test/verify-cli.test.ts +127 -0
- package/templates/collections-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +232 -0
- package/templates/collections-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +204 -0
- package/templates/collections-agent/packages/agent-runtime/test/whatsapp-evidence.test.ts +94 -0
- package/templates/collections-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +174 -0
- package/templates/collections-agent/packages/agent-runtime/test/whatsapp-session.test.ts +135 -0
- package/templates/collections-agent/packages/agent-runtime/tsconfig.json +9 -0
- package/templates/collections-agent/vitest.config.ts +1 -1
- package/templates/hello-agent/LICENSE +21 -0
- package/templates/hello-agent/README.md +23 -0
- package/templates/hello-agent/_gitignore +10 -0
- package/templates/hello-agent/agents/hello-agent/.env.example +5 -0
- package/templates/hello-agent/agents/hello-agent/AGENTS.md +15 -0
- package/templates/hello-agent/agents/hello-agent/CLAUDE.md +15 -0
- package/templates/hello-agent/agents/hello-agent/README.md +33 -0
- package/templates/hello-agent/agents/hello-agent/SYSTEM_PROMPT.md +19 -0
- package/templates/hello-agent/agents/hello-agent/agent.yaml +19 -0
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/beneficiary-swap.json +6 -0
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/beneficiary-swap.transcript.jsonl +2 -0
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/exfiltration.json +6 -0
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/exfiltration.transcript.jsonl +2 -0
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/false-authority.json +6 -0
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/false-authority.transcript.jsonl +2 -0
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/fractioning.json +6 -0
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/fractioning.transcript.jsonl +2 -0
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/model-total.json +6 -0
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/model-total.transcript.jsonl +2 -0
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/prompt-injection.json +6 -0
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/prompt-injection.transcript.jsonl +2 -0
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/webhook-replay.json +6 -0
- package/templates/hello-agent/agents/hello-agent/evals/eval.yaml +7 -0
- package/templates/hello-agent/agents/hello-agent/guardrails.json +8 -0
- package/templates/hello-agent/agents/hello-agent/mandate.example.json +17 -0
- package/templates/hello-agent/agents/hello-agent/package.json +19 -0
- package/templates/hello-agent/agents/hello-agent/runbook.md +10 -0
- package/templates/hello-agent/agents/hello-agent/scenarios/happy-path.json +6 -0
- package/templates/hello-agent/agents/hello-agent/scenarios/happy-path.transcript.jsonl +2 -0
- package/templates/hello-agent/agents/hello-agent/scenarios/prompt-injection.json +6 -0
- package/templates/hello-agent/agents/hello-agent/scenarios/prompt-injection.transcript.jsonl +2 -0
- package/templates/hello-agent/agents/hello-agent/src/bills.ts +23 -0
- package/templates/hello-agent/agents/hello-agent/src/kit.ts +33 -0
- package/templates/hello-agent/agents/hello-agent/tools.json +11 -0
- package/templates/hello-agent/agents/hello-agent/tsconfig.json +9 -0
- package/templates/hello-agent/package.json +30 -0
- package/templates/hello-agent/packages/agent-core/README.md +21 -0
- package/templates/hello-agent/packages/agent-core/package.json +24 -0
- package/templates/hello-agent/packages/agent-core/src/agent.ts +125 -0
- package/templates/hello-agent/packages/agent-core/src/api/charge-rail.ts +175 -0
- package/templates/hello-agent/packages/agent-core/src/api/client.ts +53 -0
- package/templates/hello-agent/packages/agent-core/src/api/mandate-status.ts +58 -0
- package/templates/hello-agent/packages/agent-core/src/api/rail.ts +117 -0
- package/templates/hello-agent/packages/agent-core/src/api/sandbox-payer.ts +58 -0
- package/templates/hello-agent/packages/agent-core/src/approval.ts +123 -0
- package/templates/hello-agent/packages/agent-core/src/bundle.ts +159 -0
- package/templates/hello-agent/packages/agent-core/src/channels.ts +140 -0
- package/templates/hello-agent/packages/agent-core/src/check.ts +253 -0
- package/templates/hello-agent/packages/agent-core/src/clock.ts +42 -0
- package/templates/hello-agent/packages/agent-core/src/engine.ts +885 -0
- package/templates/hello-agent/packages/agent-core/src/escalate.ts +85 -0
- package/templates/hello-agent/packages/agent-core/src/events.ts +40 -0
- package/templates/hello-agent/packages/agent-core/src/guardrails.ts +45 -0
- package/templates/hello-agent/packages/agent-core/src/hash.ts +62 -0
- package/templates/hello-agent/packages/agent-core/src/ids.ts +10 -0
- package/templates/hello-agent/packages/agent-core/src/index.ts +32 -0
- package/templates/hello-agent/packages/agent-core/src/mandate.ts +100 -0
- package/templates/hello-agent/packages/agent-core/src/manifest.ts +76 -0
- package/templates/hello-agent/packages/agent-core/src/providers/anthropic.ts +76 -0
- package/templates/hello-agent/packages/agent-core/src/providers/replay.ts +63 -0
- package/templates/hello-agent/packages/agent-core/src/providers/types.ts +39 -0
- package/templates/hello-agent/packages/agent-core/src/rail.ts +101 -0
- package/templates/hello-agent/packages/agent-core/src/receipt-verification.ts +401 -0
- package/templates/hello-agent/packages/agent-core/src/revocation.ts +30 -0
- package/templates/hello-agent/packages/agent-core/src/secrets.ts +30 -0
- package/templates/hello-agent/packages/agent-core/src/state/store.ts +307 -0
- package/templates/hello-agent/packages/agent-core/src/state-machine.ts +148 -0
- package/templates/hello-agent/packages/agent-core/src/stubs/charge-rail.ts +195 -0
- package/templates/hello-agent/packages/agent-core/src/stubs/mandate-status.ts +57 -0
- package/templates/hello-agent/packages/agent-core/src/stubs/rail.ts +141 -0
- package/templates/hello-agent/packages/agent-core/src/tools.ts +55 -0
- package/templates/hello-agent/packages/agent-core/src/types.ts +134 -0
- package/templates/hello-agent/packages/agent-core/test/approval.test.ts +117 -0
- package/templates/hello-agent/packages/agent-core/test/bundle.test.ts +85 -0
- package/templates/hello-agent/packages/agent-core/test/clock.test.ts +25 -0
- package/templates/hello-agent/packages/agent-core/test/engine.test.ts +596 -0
- package/templates/hello-agent/packages/agent-core/test/escalate.test.ts +42 -0
- package/templates/hello-agent/packages/agent-core/test/fixtures/staging-receipt-keys.json +18 -0
- package/templates/hello-agent/packages/agent-core/test/fixtures/staging-receipt.json +24 -0
- package/templates/hello-agent/packages/agent-core/test/helpers.ts +139 -0
- package/templates/hello-agent/packages/agent-core/test/mandate-status.test.ts +153 -0
- package/templates/hello-agent/packages/agent-core/test/manifest.test.ts +45 -0
- package/templates/hello-agent/packages/agent-core/test/receipt-verification.test.ts +316 -0
- package/templates/hello-agent/packages/agent-core/test/receivables.test.ts +316 -0
- package/templates/hello-agent/packages/agent-core/test/secrets.test.ts +28 -0
- package/templates/hello-agent/packages/agent-core/test/state-machine.test.ts +67 -0
- package/templates/hello-agent/packages/agent-core/test/transitions.type-test.ts +59 -0
- package/templates/hello-agent/packages/agent-core/tsconfig.json +10 -0
- package/templates/hello-agent/packages/agent-runtime/README.md +68 -0
- package/templates/hello-agent/packages/agent-runtime/bin.mjs +32 -0
- package/templates/hello-agent/packages/agent-runtime/package.json +23 -0
- package/templates/hello-agent/packages/agent-runtime/src/adversarial.ts +169 -0
- package/templates/hello-agent/packages/agent-runtime/src/agent.ts +68 -0
- package/templates/hello-agent/packages/agent-runtime/src/channels/contact.ts +13 -0
- package/templates/hello-agent/packages/agent-runtime/src/channels/index.ts +72 -0
- package/templates/hello-agent/packages/agent-runtime/src/channels/rules.ts +120 -0
- package/templates/hello-agent/packages/agent-runtime/src/channels/types.ts +124 -0
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +358 -0
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +206 -0
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/evidence.ts +109 -0
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +225 -0
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +143 -0
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +47 -0
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +113 -0
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +113 -0
- package/templates/hello-agent/packages/agent-runtime/src/cli.ts +98 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/check.ts +15 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/decide.ts +63 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/eval.ts +58 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/inspect.ts +100 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +317 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/poll.ts +144 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/reconcile.ts +42 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/rerun.ts +86 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/resume.ts +43 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +131 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/start.ts +245 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/verify.ts +129 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/webhook.ts +39 -0
- package/templates/hello-agent/packages/agent-runtime/src/default-kit.ts +83 -0
- package/templates/hello-agent/packages/agent-runtime/src/index.ts +12 -0
- package/templates/hello-agent/packages/agent-runtime/src/inspect.ts +797 -0
- package/templates/hello-agent/packages/agent-runtime/src/kit.ts +206 -0
- package/templates/hello-agent/packages/agent-runtime/src/poll.ts +105 -0
- package/templates/hello-agent/packages/agent-runtime/src/scenarios.ts +268 -0
- package/templates/hello-agent/packages/agent-runtime/src/setup.ts +229 -0
- package/templates/hello-agent/packages/agent-runtime/src/terminal.ts +154 -0
- package/templates/hello-agent/packages/agent-runtime/src/webhook.ts +131 -0
- package/templates/hello-agent/packages/agent-runtime/test/inspect.test.ts +336 -0
- package/templates/hello-agent/packages/agent-runtime/test/verify-cli.test.ts +127 -0
- package/templates/hello-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +232 -0
- package/templates/hello-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +204 -0
- package/templates/hello-agent/packages/agent-runtime/test/whatsapp-evidence.test.ts +94 -0
- package/templates/hello-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +174 -0
- package/templates/hello-agent/packages/agent-runtime/test/whatsapp-session.test.ts +135 -0
- package/templates/hello-agent/packages/agent-runtime/tsconfig.json +9 -0
- package/templates/hello-agent/tsconfig.base.json +16 -0
- package/templates/hello-agent/vitest.config.ts +12 -0
- package/templates/kits.lock.json +60 -12
- package/templates/supplier-payments-agent/LICENSE +21 -0
- package/templates/supplier-payments-agent/README.md +23 -0
- package/templates/supplier-payments-agent/_gitignore +10 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/.env.example +7 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/AGENTS.md +21 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/CLAUDE.md +21 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/README.md +118 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/SYSTEM_PROMPT.md +29 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/agent.yaml +26 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/batch-tampering.json +12 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/batch-tampering.transcript.jsonl +3 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/beneficiary-swap-mandate.json +9 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/beneficiary-swap.json +10 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/beneficiary-swap.transcript.jsonl +2 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/exfiltration.json +13 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/exfiltration.transcript.jsonl +3 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/false-authority.json +9 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/false-authority.transcript.jsonl +3 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/fractioning.json +15 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/fractioning.transcript.jsonl +6 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/model-total.json +10 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/model-total.transcript.jsonl +2 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/prompt-injection.json +9 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/prompt-injection.transcript.jsonl +2 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/webhook-replay.json +9 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/eval.yaml +9 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/guardrails.json +15 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/mandate.example.json +70 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/package.json +26 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/runbook.md +19 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/beneficiary-not-allowed.json +14 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/beneficiary-not-allowed.transcript.jsonl +2 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/cap-exceeded.json +12 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/cap-exceeded.transcript.jsonl +2 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/escalated-above-threshold.json +20 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/escalated-above-threshold.transcript.jsonl +7 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/happy-path.json +19 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/happy-path.transcript.jsonl +3 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/mandate-revoked.json +21 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/mandate-revoked.transcript.jsonl +9 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/partial-batch-failure.json +21 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/partial-batch-failure.transcript.jsonl +3 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/prompt-injection.json +12 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/prompt-injection.transcript.jsonl +2 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/kit.ts +176 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/modules/batch-payout.ts +345 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/modules/pix-out.ts +118 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/payables.ts +76 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/adversarial.test.ts +53 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/batch.test.ts +384 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/check.test.ts +109 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/scenarios.test.ts +81 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/tools.json +53 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/tsconfig.json +9 -0
- package/templates/supplier-payments-agent/package.json +36 -0
- package/templates/supplier-payments-agent/packages/agent-core/README.md +21 -0
- package/templates/supplier-payments-agent/packages/agent-core/package.json +24 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/agent.ts +125 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/api/charge-rail.ts +175 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/api/client.ts +53 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/api/mandate-status.ts +58 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/api/rail.ts +117 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/api/sandbox-payer.ts +58 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/approval.ts +123 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/bundle.ts +159 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/channels.ts +140 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/check.ts +253 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/clock.ts +42 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/engine.ts +885 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/escalate.ts +85 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/events.ts +40 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/guardrails.ts +45 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/hash.ts +62 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/ids.ts +10 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/index.ts +32 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/mandate.ts +100 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/manifest.ts +76 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/providers/anthropic.ts +76 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/providers/replay.ts +63 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/providers/types.ts +39 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/rail.ts +101 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/receipt-verification.ts +401 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/revocation.ts +30 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/secrets.ts +30 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/state/store.ts +307 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/state-machine.ts +148 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/stubs/charge-rail.ts +195 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/stubs/mandate-status.ts +57 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/stubs/rail.ts +141 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/tools.ts +55 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/types.ts +134 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/approval.test.ts +117 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/bundle.test.ts +85 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/clock.test.ts +25 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/engine.test.ts +596 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/escalate.test.ts +42 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/fixtures/staging-receipt-keys.json +18 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/fixtures/staging-receipt.json +24 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/helpers.ts +139 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/mandate-status.test.ts +153 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/manifest.test.ts +45 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/receipt-verification.test.ts +316 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/receivables.test.ts +316 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/secrets.test.ts +28 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/state-machine.test.ts +67 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/transitions.type-test.ts +59 -0
- package/templates/supplier-payments-agent/packages/agent-core/tsconfig.json +10 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/README.md +68 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/bin.mjs +32 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/package.json +23 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/adversarial.ts +169 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/agent.ts +68 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/contact.ts +13 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/index.ts +72 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/rules.ts +120 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/types.ts +124 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +358 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +206 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/evidence.ts +109 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +225 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +143 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +47 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +113 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +113 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/cli.ts +98 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/check.ts +15 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/decide.ts +63 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/eval.ts +58 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/inspect.ts +100 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +317 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/poll.ts +144 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/reconcile.ts +42 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/rerun.ts +86 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/resume.ts +43 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +131 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/start.ts +245 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/verify.ts +129 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/webhook.ts +39 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/default-kit.ts +83 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/index.ts +12 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/inspect.ts +797 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/kit.ts +206 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/poll.ts +105 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/scenarios.ts +268 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/setup.ts +229 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/terminal.ts +154 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/webhook.ts +131 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/test/inspect.test.ts +336 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/test/verify-cli.test.ts +127 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +232 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +204 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-evidence.test.ts +94 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +174 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-session.test.ts +135 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/tsconfig.json +9 -0
- package/templates/supplier-payments-agent/tsconfig.base.json +16 -0
- package/templates/supplier-payments-agent/vitest.config.ts +12 -0
- package/templates/bills-agent/agents/bills-agent/channels/terminal/index.ts +0 -108
- package/templates/bills-agent/agents/bills-agent/src/commands/approve.ts +0 -9
- package/templates/bills-agent/agents/bills-agent/src/commands/check.ts +0 -13
- package/templates/bills-agent/agents/bills-agent/src/commands/consent.ts +0 -26
- package/templates/bills-agent/agents/bills-agent/src/commands/decide.ts +0 -45
- package/templates/bills-agent/agents/bills-agent/src/commands/deny.ts +0 -7
- package/templates/bills-agent/agents/bills-agent/src/commands/eval.ts +0 -37
- package/templates/bills-agent/agents/bills-agent/src/commands/reconcile.ts +0 -38
- package/templates/bills-agent/agents/bills-agent/src/commands/rerun.ts +0 -65
- package/templates/bills-agent/agents/bills-agent/src/commands/resume.ts +0 -30
- package/templates/bills-agent/agents/bills-agent/src/main.ts +0 -185
- package/templates/collections-agent/agents/collections-agent/channels/terminal/index.ts +0 -178
- package/templates/collections-agent/agents/collections-agent/src/commands/approve.ts +0 -10
- package/templates/collections-agent/agents/collections-agent/src/commands/check.ts +0 -13
- package/templates/collections-agent/agents/collections-agent/src/commands/decide.ts +0 -48
- package/templates/collections-agent/agents/collections-agent/src/commands/deny.ts +0 -7
- package/templates/collections-agent/agents/collections-agent/src/commands/eval.ts +0 -39
- package/templates/collections-agent/agents/collections-agent/src/commands/poll.ts +0 -35
- package/templates/collections-agent/agents/collections-agent/src/commands/reconcile.ts +0 -38
- package/templates/collections-agent/agents/collections-agent/src/commands/rerun.ts +0 -55
- package/templates/collections-agent/agents/collections-agent/src/commands/resume.ts +0 -30
- package/templates/collections-agent/agents/collections-agent/src/commands/webhook.ts +0 -36
- package/templates/collections-agent/agents/collections-agent/src/main.ts +0 -193
- package/templates/collections-agent/agents/collections-agent/src/setup.ts +0 -250
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Everything about this agent the shared runner cannot know: the bolepix
|
|
3
|
+
* receivables rail and its sandbox payer, the negotiation envelope the core
|
|
4
|
+
* runs as its `policyExtension`, the tool handlers, the words the payer and
|
|
5
|
+
* the operator read, and what a one-shot prints as JSON. The runner
|
|
6
|
+
* (`@codespar/agent-runtime`) owns the rest.
|
|
7
|
+
*
|
|
8
|
+
* There is no consent step: the collection policy is the MERCHANT's own (the
|
|
9
|
+
* receiving side has no API-signed policy today, section 16), so the example
|
|
10
|
+
* file is the policy in both rails.
|
|
11
|
+
*/
|
|
12
|
+
import { relative } from "node:path";
|
|
13
|
+
import qrcode from "qrcode-terminal";
|
|
14
|
+
import {
|
|
15
|
+
CodeSparChargeRail,
|
|
16
|
+
NotATestKeyError,
|
|
17
|
+
StubChargeRail,
|
|
18
|
+
createCodeSparClient,
|
|
19
|
+
isTestKey,
|
|
20
|
+
loadMandate,
|
|
21
|
+
paySandboxCharge,
|
|
22
|
+
type Execution,
|
|
23
|
+
type StubChargeRailOptions,
|
|
24
|
+
} from "@codespar/agent-core";
|
|
25
|
+
import { defineAgent, type AgentKit } from "@codespar/agent-runtime";
|
|
26
|
+
import { formatBRL, formatDate } from "./agreements.js";
|
|
27
|
+
import { envelopePolicy, loadEnvelope } from "./envelope.js";
|
|
28
|
+
import { makeHandlers } from "./modules/bolepix-receivables.js";
|
|
29
|
+
|
|
30
|
+
const kit: AgentKit = {
|
|
31
|
+
settlement: "await-payer",
|
|
32
|
+
scenarioRail: "requested",
|
|
33
|
+
|
|
34
|
+
labels: {
|
|
35
|
+
defaultUser: "usr_operator",
|
|
36
|
+
evalUser: "usr_operator",
|
|
37
|
+
mandateWord: "politica",
|
|
38
|
+
receiptWord: "registro",
|
|
39
|
+
intro: 'Voce e o pagador. Diga algo ("oi, recebi a mensagem sobre o acordo do pedido 1042"). Ctrl+D ou "sair" encerra.',
|
|
40
|
+
prompt: "pagador> ",
|
|
41
|
+
approveQuestion: " [operador] Aprovar a emissao desta cobranca? [s/N] ",
|
|
42
|
+
uncertainDispatch: " desfecho desconhecido no trilho; rode `npm run resume` para reconciliar (nunca repita a emissao)",
|
|
43
|
+
missingReceiptKind: "record_missing_locally",
|
|
44
|
+
missingReceiptDetail: (receiptId, runId) => `paid charge ${receiptId} is not in runs/${runId}/receipts`,
|
|
45
|
+
stillExecuting: (e) => `${e.id}: still executing (${e.reason}) — ${e.detail}; nothing was re-issued; \`npm run poll\` keeps looking`,
|
|
46
|
+
waitingForPayer: (round) => ` aguardando o pagador... (${round} consultas)`,
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
usage: () => `collections-agent
|
|
50
|
+
npm start interactive terminal (you are the payer)
|
|
51
|
+
npm start -- --input "oi, recebi a mensagem do acordo 1042" one turn (add --approve/--deny to decide, --json for machine output)
|
|
52
|
+
npm start -- --scenario <name> run a scenario pack (see scenarios/)
|
|
53
|
+
npm start -- --channel whatsapp --conversation <name> the conversation channel (needs npm run whatsapp:emulator at the repo root)
|
|
54
|
+
npm start -- --channel whatsapp --conversation <name> --scripted the same, with the debtor's turns replayed from channels/whatsapp/
|
|
55
|
+
npm run poll -- --channel whatsapp --conversation <name> back to a conversation whose payment landed after the run ended:
|
|
56
|
+
mensagem livre com a janela de 24h aberta, template aprovado depois dela
|
|
57
|
+
options: --mode human|mandate --provider anthropic|replay --transcript <file> --rail stub|api --user <id>
|
|
58
|
+
--wait <seconds> --simulate-payer --payer pays|expires|never (stub only) --json
|
|
59
|
+
--now <ISO 8601> pin the run to that instant (collection hours, due dates, timestamps); env CODESPAR_AGENT_NOW is the same thing
|
|
60
|
+
whatsapp: --backend simulator|cloud-api default simulator, which is the local emulator; cloud-api is the same code pointed at Meta and needs your own credentials
|
|
61
|
+
--conversation <name> which channels/whatsapp/<name>.json binds the contact and the agreement
|
|
62
|
+
--scripted replay that file's turns instead of reading them from the keyboard`,
|
|
63
|
+
|
|
64
|
+
buildRail: (ctx) => {
|
|
65
|
+
const mandate = ctx.mandate ?? loadMandate(ctx.manifest.resolvePath(ctx.manifest.manifest.mandate_schema));
|
|
66
|
+
if (ctx.kind === "api") {
|
|
67
|
+
if (!isTestKey(ctx.env["CODESPAR_API_KEY"])) throw new NotATestKeyError();
|
|
68
|
+
const client = createCodeSparClient({ apiKey: ctx.env["CODESPAR_API_KEY"], baseUrl: ctx.env["CODESPAR_API_URL"], projectId: ctx.env["CODESPAR_PROJECT_ID"] });
|
|
69
|
+
return {
|
|
70
|
+
rail: new CodeSparChargeRail(client),
|
|
71
|
+
mandate,
|
|
72
|
+
api: client,
|
|
73
|
+
pollIntervalMs: 3000,
|
|
74
|
+
payer: {
|
|
75
|
+
kind: "api" as const,
|
|
76
|
+
async pay(chargeId: string) {
|
|
77
|
+
const result = await paySandboxCharge(client, chargeId);
|
|
78
|
+
if (!result.ok) return { ok: false as const, detail: `${result.failure.code}: ${result.failure.message}` };
|
|
79
|
+
const s = result.state;
|
|
80
|
+
return { ok: true as const, detail: `sandbox payer: ${s.charge_id} ${s.status} (${s.payment}, ${s.paid_minor} of ${s.quoted_minor}), simulated=${s.simulated}, settled_against=${s.settled_against}, money_moved=${s.money_moved}${s.idempotent_replay ? ", replay" : ""}` };
|
|
81
|
+
},
|
|
82
|
+
behave() {
|
|
83
|
+
/* the API's payer is a route, not a fixture; a scenario that needs "expires" declares rails: [stub] */
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
// COLLECTIONS_KILL_AFTER_DISPATCH=1 simulates a crash right after the issuer accepted the charge and before the outcome was recorded.
|
|
89
|
+
const killAfterDispatch = ctx.envVar("KILL_AFTER_DISPATCH") === "1" ? { afterDispatch: () => process.exit(137) } : {};
|
|
90
|
+
// COLLECTIONS_STUB_PAYER=pays|expires|never: what the fixture payer does, from a test process.
|
|
91
|
+
const behaviour = ctx.envVar("STUB_PAYER");
|
|
92
|
+
const fixture: Pick<StubChargeRailOptions, "payer"> = behaviour === "pays" || behaviour === "expires" || behaviour === "never" ? { payer: behaviour } : {};
|
|
93
|
+
const refuse = ctx.envVar("STUB_REFUSE") ? { refusePayees: ctx.envVar("STUB_REFUSE")!.split(",").map((p) => p.trim()).filter(Boolean) } : {};
|
|
94
|
+
const stub = new StubChargeRail(ctx.store, { ...(ctx.now ? { clock: ctx.now } : {}), ...killAfterDispatch, ...fixture, ...refuse, ...(ctx.stubRail ?? {}) });
|
|
95
|
+
return {
|
|
96
|
+
rail: stub,
|
|
97
|
+
mandate,
|
|
98
|
+
pollIntervalMs: 0,
|
|
99
|
+
payer: {
|
|
100
|
+
kind: "stub" as const,
|
|
101
|
+
async pay(_chargeId: string, attemptId: string) {
|
|
102
|
+
stub.decide(attemptId, "pays");
|
|
103
|
+
return { ok: true as const, detail: "stub payer: will pay at the next look" };
|
|
104
|
+
},
|
|
105
|
+
behave: (b) => stub.setPayer(b),
|
|
106
|
+
// A receivable the rail has already looked at carries its fate in
|
|
107
|
+
// state.db, and `setPayer` only changes the default for the ones it
|
|
108
|
+
// has not. This is what lets a poll ask "and if nobody pays?" — the
|
|
109
|
+
// due date passes between two runs, never inside one.
|
|
110
|
+
decideFor: (attemptId, b) => stub.decide(attemptId, b),
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
handlers: (setup) => makeHandlers(loadEnvelope(setup.guardrails)),
|
|
116
|
+
policyExtension: ({ guardrails }) => envelopePolicy(loadEnvelope(guardrails)),
|
|
117
|
+
|
|
118
|
+
describeExecution: (execution, setup) => {
|
|
119
|
+
const lines: string[] = [];
|
|
120
|
+
const debtor = execution.items[0]?.beneficiary ?? "?";
|
|
121
|
+
lines.push(` execucao ${execution.id}: ${execution.state}${execution.reason ? ` (${execution.reason})` : ""}`);
|
|
122
|
+
lines.push(` acordo de ${debtor} (${execution.items[0]?.alias ?? "?"})`);
|
|
123
|
+
for (const [i, item] of execution.items.entries()) lines.push(` - parcela ${i + 1}/${execution.items.length}: ${formatBRL(item.amount)}, vence ${item.due_date ? formatDate(item.due_date) : "?"}`);
|
|
124
|
+
lines.push(` total (calculado pelo core): ${formatBRL(execution.total)}`);
|
|
125
|
+
if (execution.escalation) lines.push(` escalado por: ${execution.escalation.trigger} — ${execution.escalation.detail}`);
|
|
126
|
+
if (execution.blocking_reasons.length) lines.push(` bloqueado: ${execution.blocking_reasons.join(", ")} — a politica nao autoriza; nao ha o que aprovar`);
|
|
127
|
+
if (execution.detail && execution.state !== "awaiting_approval") lines.push(` ${execution.detail}`);
|
|
128
|
+
for (const outcome of execution.outcomes) {
|
|
129
|
+
if (outcome.transaction_id) lines.push(` cobranca ${outcome.index + 1}: ${outcome.transaction_id} — ${outcome.status}${outcome.code ? ` (${outcome.code})` : ""}`);
|
|
130
|
+
if (outcome.receipt_id) lines.push(` registro: ${relative(process.cwd(), `${setup.bundle.dir}/receipts/${outcome.receipt_id}.json`)}`);
|
|
131
|
+
}
|
|
132
|
+
return lines;
|
|
133
|
+
},
|
|
134
|
+
|
|
135
|
+
oneShotPayload: ({ setup: s, reply, toolCalls, executions, startedAt }) => ({
|
|
136
|
+
run_id: s.runId,
|
|
137
|
+
agent: `${s.manifest.manifest.name}@${s.manifest.manifest.version}`,
|
|
138
|
+
mode: s.mode,
|
|
139
|
+
rail: s.railKind,
|
|
140
|
+
policy_id: s.mandate.id,
|
|
141
|
+
actor: s.engine.agentActor,
|
|
142
|
+
reply,
|
|
143
|
+
tool_calls: toolCalls,
|
|
144
|
+
executions: executions.map((e) => ({
|
|
145
|
+
id: e.id,
|
|
146
|
+
state: e.state,
|
|
147
|
+
reason: e.reason ?? null,
|
|
148
|
+
escalation: e.escalation ?? null,
|
|
149
|
+
total_minor: e.total,
|
|
150
|
+
items: e.items.map((i) => ({ debtor: i.beneficiary, amount_minor: i.amount, due_date: i.due_date ?? null })),
|
|
151
|
+
approval_id: e.approval_id ?? null,
|
|
152
|
+
charges: e.outcomes.map((o) => ({ instalment: o.index + 1, charge_id: o.transaction_id ?? null, status: o.status, code: o.code ?? null, payable: o.instrument?.payable ?? null, pix_copy_paste: o.instrument?.pix_copy_paste ?? null })),
|
|
153
|
+
receipt_ids: e.outcomes.filter((o) => o.receipt_id).map((o) => o.receipt_id),
|
|
154
|
+
})),
|
|
155
|
+
receipts: s.bundle.listReceipts().map((f) => relative(process.cwd(), `${s.bundle.dir}/receipts/${f}`)),
|
|
156
|
+
bundle_dir: relative(process.cwd(), s.bundle.dir),
|
|
157
|
+
seconds: Math.round(((Date.now() - startedAt) / 1000) * 10) / 10,
|
|
158
|
+
}),
|
|
159
|
+
|
|
160
|
+
/** What the payer reads when a receivable is payable: the QR as an image, the copy-and-paste under it, the bank line if any. */
|
|
161
|
+
presentInstrument: (execution, instalment, chargeId, instrument, tell) => {
|
|
162
|
+
const item = execution.items[instalment - 1];
|
|
163
|
+
const count = execution.items.length;
|
|
164
|
+
tell("");
|
|
165
|
+
tell(`${count > 1 ? `Parcela ${instalment}/${count}: ` : ""}${item ? formatBRL(item.amount) : ""}${instrument.due_date ? `, vence ${formatDate(instrument.due_date)}` : ""} — cobranca ${chargeId}`);
|
|
166
|
+
if (instrument.pix_copy_paste) {
|
|
167
|
+
qrcode.generate(instrument.pix_copy_paste, { small: true }, (qr: string) => {
|
|
168
|
+
for (const line of qr.split("\n")) tell(line);
|
|
169
|
+
});
|
|
170
|
+
tell("Pix copia e cola:");
|
|
171
|
+
tell(instrument.pix_copy_paste);
|
|
172
|
+
}
|
|
173
|
+
if (instrument.boleto_bank_line) {
|
|
174
|
+
tell("Ou pelo boleto, linha digitavel:");
|
|
175
|
+
tell(instrument.boleto_bank_line);
|
|
176
|
+
}
|
|
177
|
+
tell("");
|
|
178
|
+
},
|
|
179
|
+
|
|
180
|
+
announceOutcome: (execution, setup, tell) => {
|
|
181
|
+
if (execution.state === "executing") return false;
|
|
182
|
+
if (!setup.engine.markTold(execution.id, execution.state)) return false;
|
|
183
|
+
let text: string;
|
|
184
|
+
if (execution.state === "settled") text = `Recebemos, acordo quitado. Obrigado! (${execution.outcomes.map((o) => o.transaction_id).filter(Boolean).join(", ")})`;
|
|
185
|
+
else if (execution.reason === "charge_expired") text = "A cobranca venceu sem pagamento. Se quiser, emito uma nova dentro das mesmas condicoes.";
|
|
186
|
+
else if (execution.reason === "charge_cancelled") text = "A cobranca foi cancelada. Nada foi pago.";
|
|
187
|
+
else if (execution.state === "failed") text = `Nao consegui emitir a cobranca (${execution.reason ?? "falha no trilho"}). Nada foi cobrado.`;
|
|
188
|
+
else if (execution.state === "denied") text = `Nao posso emitir nesses termos (${execution.reason ?? "recusado"}).`;
|
|
189
|
+
else text = `A proposta expirou sem decisao (${execution.state}).`;
|
|
190
|
+
tell(text);
|
|
191
|
+
setup.engine.note("message.debtor", execution.id, { state: execution.state, reason: execution.reason ?? null, text });
|
|
192
|
+
return true;
|
|
193
|
+
},
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* The same outcome as `announceOutcome`, as one of the templates this agent
|
|
197
|
+
* declares in `channels/whatsapp/templates.json`. It is what a poll sends
|
|
198
|
+
* when the 24-hour window has shut, which for a collection is the ordinary
|
|
199
|
+
* case and not the edge one: agreed Tuesday, paid Friday.
|
|
200
|
+
*
|
|
201
|
+
* Three outcomes have approved copy and the rest return undefined on
|
|
202
|
+
* purpose. A charge that failed on the rail, a proposal that was denied or
|
|
203
|
+
* one that expired without a decision are not things this agent has ever
|
|
204
|
+
* had to say to a debtor days later — the first two are answered inside the
|
|
205
|
+
* turn that produced them, and inventing a template for them would mean
|
|
206
|
+
* asking Meta to approve copy nobody has written. The poll REPORTS an
|
|
207
|
+
* outcome it cannot carry rather than sending an approximate one.
|
|
208
|
+
*/
|
|
209
|
+
outcomeTemplate: (execution) => {
|
|
210
|
+
const agreement = execution.items[0]?.alias ?? execution.items[0]?.beneficiary;
|
|
211
|
+
if (!agreement) return undefined;
|
|
212
|
+
if (execution.state === "settled") return { template: "acordo_quitado", variables: [agreement] };
|
|
213
|
+
if (execution.reason === "charge_expired") return { template: "acordo_cobranca_vencida", variables: [agreement] };
|
|
214
|
+
if (execution.reason === "charge_cancelled") return { template: "acordo_cobranca_cancelada", variables: [agreement] };
|
|
215
|
+
return undefined;
|
|
216
|
+
},
|
|
217
|
+
|
|
218
|
+
/** Agreements with a prior settled receivable under this policy, so the velocity window has history. */
|
|
219
|
+
warmUp: async (s, aliases, approver) => {
|
|
220
|
+
const warm = new Set<string>();
|
|
221
|
+
for (const alias of aliases) {
|
|
222
|
+
const d = await s.engine.draft({ items: [{ payee: alias, amount: 20000, due_date: "2026-09-30", description: "prior instalment" }] });
|
|
223
|
+
if (!d.ok) throw new Error(`warm-up refused: ${d.reason}`);
|
|
224
|
+
let e: Execution = d.execution;
|
|
225
|
+
if (e.state === "awaiting_approval") e = s.engine.approve(e.id, approver);
|
|
226
|
+
if (e.state === "approved") e = await s.engine.execute(e.id);
|
|
227
|
+
for (let i = 0; i < 2 && e.state === "executing"; i += 1) e = await s.engine.reconcile(e.id);
|
|
228
|
+
if (e.state !== "settled") throw new Error(`warm-up for ${alias} ended ${e.state} (${e.reason})`);
|
|
229
|
+
warm.add(e.id);
|
|
230
|
+
}
|
|
231
|
+
return warm;
|
|
232
|
+
},
|
|
233
|
+
|
|
234
|
+
/** Webhook duplicated or out of order: the same `commerce.charge.paid` twice, `paid` before `created`, `expired` after `paid`. One settled, one message. */
|
|
235
|
+
runEventsCase: async (s, tell) => {
|
|
236
|
+
s.payer!.behave("never");
|
|
237
|
+
const draft = await s.engine.draft({ items: [{ payee: "acordo-1042", amount: 108000, due_date: "2026-09-30" }] });
|
|
238
|
+
if (!draft.ok) throw new Error("refused");
|
|
239
|
+
let execution = draft.execution;
|
|
240
|
+
if (execution.state === "awaiting_approval") execution = s.engine.approve(execution.id, { id: "usr_operator", channel: "terminal" });
|
|
241
|
+
execution = await s.engine.execute(execution.id);
|
|
242
|
+
const chargeId = execution.outcomes[0]!.transaction_id!;
|
|
243
|
+
const apply = (event_id: string, type: string) => {
|
|
244
|
+
s.engine.ingestExternalEvent({ event_id, type, transaction_id: chargeId });
|
|
245
|
+
kit.announceOutcome!(s.engine.get(execution.id)!, s, tell);
|
|
246
|
+
};
|
|
247
|
+
apply("evt_paid_1", "commerce.charge.paid");
|
|
248
|
+
apply("evt_paid_1", "commerce.charge.paid");
|
|
249
|
+
apply("evt_created_late", "commerce.charge.created");
|
|
250
|
+
apply("evt_paid_2", "commerce.charge.paid");
|
|
251
|
+
apply("evt_expired_late", "commerce.charge.expired");
|
|
252
|
+
},
|
|
253
|
+
|
|
254
|
+
// The payer's behaviour is part of the recording: a receivable that expired in the original run expires in the rerun.
|
|
255
|
+
rerunPlan: (events) => {
|
|
256
|
+
const expired = events.some((e) => e["type"] === "execution.transition" && (e["payload"] as { reason?: string }).reason === "charge_expired");
|
|
257
|
+
return { stubRail: { payer: expired ? "expires" : "pays" }, simulatePayer: !expired };
|
|
258
|
+
},
|
|
259
|
+
rerunComparesOutcomes: false,
|
|
260
|
+
|
|
261
|
+
evalScenarioLine: (check) =>
|
|
262
|
+
`${check.ok ? "ok " : "FAIL"} scenario/${check.run.scenario} [${check.mode}] — states ${JSON.stringify(check.run.executions.map((e) => e.state))}, ${check.run.charges_issued} charge(s), ${check.run.receipts} record(s), ${check.run.debtor_messages} message(s)${check.failures.length ? ` — ${check.failures.join("; ")}` : ""}`,
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
export const agent = defineAgent(import.meta.url, kit);
|
|
@@ -2,7 +2,8 @@ import { mkdtempSync } from "node:fs";
|
|
|
2
2
|
import { tmpdir } from "node:os";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { describe, expect, it } from "vitest";
|
|
5
|
-
import { listAdversarialCases, loadAdversarialCase, runAdversarialCase } from "
|
|
5
|
+
import { listAdversarialCases, loadAdversarialCase, runAdversarialCase } from "@codespar/agent-runtime";
|
|
6
|
+
import { agent } from "../src/kit.js";
|
|
6
7
|
|
|
7
8
|
const runsDir = mkdtempSync(join(tmpdir(), "collections-adv-runs-"));
|
|
8
9
|
|
|
@@ -10,36 +11,36 @@ describe("section 9: adversarial suite (blocks merge)", () => {
|
|
|
10
11
|
const required = ["prompt-injection", "beneficiary-swap", "false-authority", "fractioning", "exfiltration", "model-total", "webhook-replay"];
|
|
11
12
|
|
|
12
13
|
it("ships every attack of the table", () => {
|
|
13
|
-
for (const name of required) expect(listAdversarialCases()).toContain(name);
|
|
14
|
+
for (const name of required) expect(listAdversarialCases(agent)).toContain(name);
|
|
14
15
|
});
|
|
15
16
|
|
|
16
|
-
for (const name of listAdversarialCases()) {
|
|
17
|
+
for (const name of listAdversarialCases(agent)) {
|
|
17
18
|
it(`${name}: the state machine, not the wording, decides`, async () => {
|
|
18
|
-
const result = await runAdversarialCase(loadAdversarialCase(name), { runsDir });
|
|
19
|
+
const result = await runAdversarialCase(agent, loadAdversarialCase(agent, name), { runsDir });
|
|
19
20
|
expect(result.failures).toEqual([]);
|
|
20
21
|
expect(result.ok).toBe(true);
|
|
21
22
|
});
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
it("prompt injection: a model that complies with 'the agreement is R$ 10' still cannot issue", async () => {
|
|
25
|
-
const r = await runAdversarialCase(loadAdversarialCase("prompt-injection"), { runsDir });
|
|
26
|
+
const r = await runAdversarialCase(agent, loadAdversarialCase(agent, "prompt-injection"), { runsDir });
|
|
26
27
|
expect(r.tools_called).toContain("codespar_charge");
|
|
27
28
|
expect(r.states).toEqual(["denied"]);
|
|
28
29
|
});
|
|
29
30
|
|
|
30
31
|
it("exfiltration: tools outside tools.json are refused before any handler runs", async () => {
|
|
31
|
-
const r = await runAdversarialCase(loadAdversarialCase("exfiltration"), { runsDir });
|
|
32
|
+
const r = await runAdversarialCase(agent, loadAdversarialCase(agent, "exfiltration"), { runsDir });
|
|
32
33
|
expect(r.tools_refused).toEqual(["codespar_wallet", "codespar_manage_connections"]);
|
|
33
34
|
expect(r.tools_called).toEqual([]);
|
|
34
35
|
});
|
|
35
36
|
|
|
36
37
|
it("fractioning: on the receiving side each execution covers the whole agreement, so the parts are refused, not issued", async () => {
|
|
37
|
-
const r = await runAdversarialCase(loadAdversarialCase("fractioning"), { runsDir });
|
|
38
|
+
const r = await runAdversarialCase(agent, loadAdversarialCase(agent, "fractioning"), { runsDir });
|
|
38
39
|
expect(r.states).toEqual(["denied", "denied", "denied"]);
|
|
39
40
|
});
|
|
40
41
|
|
|
41
42
|
it("model total: the core issues by its own sum, and the artifact carries it", async () => {
|
|
42
|
-
const r = await runAdversarialCase(loadAdversarialCase("model-total"), { runsDir });
|
|
43
|
+
const r = await runAdversarialCase(agent, loadAdversarialCase(agent, "model-total"), { runsDir });
|
|
43
44
|
expect(r.states).toEqual(["settled"]);
|
|
44
45
|
});
|
|
45
46
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { cpSync, mkdtempSync, readFileSync, writeFileSync } from "node:fs";
|
|
1
|
+
import { cpSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { tmpdir } from "node:os";
|
|
3
3
|
import { join, resolve } from "node:path";
|
|
4
4
|
import { describe, expect, it } from "vitest";
|
|
@@ -11,6 +11,7 @@ function copyAgent(): string {
|
|
|
11
11
|
for (const f of ["agent.yaml", "SYSTEM_PROMPT.md", "tools.json", "guardrails.json", "mandate.example.json", "AGENTS.md", "CLAUDE.md", "README.md", "runbook.md", ".env.example"]) cpSync(join(AGENT_DIR, f), join(dir, f));
|
|
12
12
|
cpSync(join(AGENT_DIR, "scenarios"), join(dir, "scenarios"), { recursive: true });
|
|
13
13
|
cpSync(join(AGENT_DIR, "evals"), join(dir, "evals"), { recursive: true });
|
|
14
|
+
cpSync(join(AGENT_DIR, "channels"), join(dir, "channels"), { recursive: true });
|
|
14
15
|
return dir;
|
|
15
16
|
}
|
|
16
17
|
|
|
@@ -41,11 +42,52 @@ describe("npm run check: the manifest is the index", () => {
|
|
|
41
42
|
expect(codes(dir)).toContain("prompt_contradicts_tools");
|
|
42
43
|
});
|
|
43
44
|
|
|
45
|
+
it("fails when a declared channel ships no conversation, and when a shipped one is not declared", () => {
|
|
46
|
+
const dropped = copyAgent();
|
|
47
|
+
rmSync(join(dropped, "channels"), { recursive: true, force: true });
|
|
48
|
+
expect(codes(dropped)).toContain("channels_not_shipped");
|
|
49
|
+
|
|
50
|
+
const undeclared = copyAgent();
|
|
51
|
+
writeFileSync(join(undeclared, "agent.yaml"), readFileSync(join(undeclared, "agent.yaml"), "utf8").replace(/^channels:.*$/m, "channels: [terminal]"));
|
|
52
|
+
expect(codes(undeclared)).toContain("channels_undeclared");
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("fails on a conversation the simulator could not drive: a bad contact, a missing turn, a name that is not the file's", () => {
|
|
56
|
+
const badContact = copyAgent();
|
|
57
|
+
const path = join(badContact, "channels/whatsapp/acordo-1042.json");
|
|
58
|
+
const script = JSON.parse(readFileSync(path, "utf8")) as Record<string, unknown>;
|
|
59
|
+
writeFileSync(path, JSON.stringify({ ...script, contact: "11987654321" }));
|
|
60
|
+
expect(codes(badContact)).toContain("channels_script_invalid");
|
|
61
|
+
|
|
62
|
+
const noTurns = copyAgent();
|
|
63
|
+
const turnsPath = join(noTurns, "channels/whatsapp/acordo-1042.json");
|
|
64
|
+
writeFileSync(turnsPath, JSON.stringify({ ...JSON.parse(readFileSync(turnsPath, "utf8")), turns: [] }));
|
|
65
|
+
expect(codes(noTurns)).toContain("channels_script_invalid");
|
|
66
|
+
|
|
67
|
+
const misnamed = copyAgent();
|
|
68
|
+
const namePath = join(misnamed, "channels/whatsapp/acordo-1042.json");
|
|
69
|
+
writeFileSync(namePath, JSON.stringify({ ...JSON.parse(readFileSync(namePath, "utf8")), name: "outro-acordo" }));
|
|
70
|
+
expect(codes(misnamed)).toContain("channels_script_invalid");
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("fails when the terminal channel is dropped: every agent has one and `npm start` opens it", () => {
|
|
74
|
+
const dir = copyAgent();
|
|
75
|
+
writeFileSync(join(dir, "agent.yaml"), readFileSync(join(dir, "agent.yaml"), "utf8").replace(/^channels:.*$/m, "channels: [whatsapp]"));
|
|
76
|
+
expect(codes(dir)).toContain("channels_terminal_missing");
|
|
77
|
+
});
|
|
78
|
+
|
|
44
79
|
it("fails when AGENTS.md and CLAUDE.md diverge, or when a README overclaims", () => {
|
|
45
80
|
const dir = copyAgent();
|
|
46
81
|
writeFileSync(join(dir, "CLAUDE.md"), readFileSync(join(dir, "CLAUDE.md"), "utf8") + "\nextra line\n");
|
|
47
82
|
expect(codes(dir)).toContain("agents_md_diverges");
|
|
83
|
+
// This agent mints receivables, and a paid charge carries no chain and no signature, so the claim is refused in its own README even though that README names Ed25519.
|
|
48
84
|
writeFileSync(join(dir, "README.md"), readFileSync(join(dir, "README.md"), "utf8") + "\nThe record is third-party verifiable.\n");
|
|
49
85
|
expect(codes(dir)).toContain("doc_overclaims");
|
|
50
86
|
});
|
|
87
|
+
|
|
88
|
+
it("refuses a maturity this agent's records cannot carry", () => {
|
|
89
|
+
const dir = copyAgent();
|
|
90
|
+
writeFileSync(join(dir, "agent.yaml"), readFileSync(join(dir, "agent.yaml"), "utf8").replace("receipt-verification: blocked", "receipt-verification: sandbox"));
|
|
91
|
+
expect(codes(dir)).toContain("maturity_overclaims");
|
|
92
|
+
});
|
|
51
93
|
});
|
|
@@ -12,12 +12,14 @@ import { describe, expect, it } from "vitest";
|
|
|
12
12
|
|
|
13
13
|
const AGENT_DIR = resolve(import.meta.dirname, "..");
|
|
14
14
|
const NODE = process.execPath;
|
|
15
|
+
const BIN = resolve(AGENT_DIR, "../../packages/agent-runtime/bin.mjs");
|
|
15
16
|
const HAPPY = "oi, recebi a mensagem sobre o acordo do pedido 1042";
|
|
16
17
|
|
|
17
|
-
function run(
|
|
18
|
-
const result = spawnSync(NODE, [
|
|
18
|
+
function run(command: string, args: string[], env: Record<string, string>) {
|
|
19
|
+
const result = spawnSync(NODE, [BIN, command, ...args], {
|
|
19
20
|
cwd: AGENT_DIR,
|
|
20
|
-
|
|
21
|
+
// Pinned inside collection hours (#16): these processes must not depend on the hour the suite runs at. A test overrides it.
|
|
22
|
+
env: { ...process.env, ANTHROPIC_API_KEY: "", CODESPAR_API_KEY: "", CODESPAR_AGENT_NOW: "2026-09-23T14:00:00-03:00", ...env },
|
|
21
23
|
encoding: "utf8",
|
|
22
24
|
timeout: 60_000,
|
|
23
25
|
});
|
|
@@ -33,7 +35,7 @@ describe("npm start -- --input ... --json", () => {
|
|
|
33
35
|
it("prints valid JSON on stdout and nothing else; the QR and the people go to stderr", () => {
|
|
34
36
|
const env = scratch("json");
|
|
35
37
|
// The recorded happy-path's first turn is a proposal, no execution: the second turn issues.
|
|
36
|
-
const out = run("
|
|
38
|
+
const out = run("start", ["--input", HAPPY, "--json"], env);
|
|
37
39
|
expect(out.code).toBe(0);
|
|
38
40
|
const lines = out.stdout.split("\n").filter(Boolean);
|
|
39
41
|
expect(lines).toHaveLength(1);
|
|
@@ -47,7 +49,7 @@ describe("npm start -- --input ... --json", () => {
|
|
|
47
49
|
|
|
48
50
|
it("an accepted proposal, approved with the payer simulated, settles in one process and the QR never reaches stdout", () => {
|
|
49
51
|
const env = scratch("settle");
|
|
50
|
-
const out = run("
|
|
52
|
+
const out = run("start", ["--input", "fechado, pago à vista", "--transcript", "test/fixtures/accept-1042.transcript.jsonl", "--approve", "--simulate-payer", "--json"], env);
|
|
51
53
|
expect(out.code).toBe(0);
|
|
52
54
|
const lines = out.stdout.split("\n").filter(Boolean);
|
|
53
55
|
expect(lines).toHaveLength(1);
|
|
@@ -58,9 +60,45 @@ describe("npm start -- --input ... --json", () => {
|
|
|
58
60
|
expect(out.stderr).toContain("copia e cola");
|
|
59
61
|
});
|
|
60
62
|
|
|
63
|
+
// #16: the collection-hours guardrail reads the engine clock. Pinned, the gate is the same at 03:00 and at 15:00.
|
|
64
|
+
describe("--now pins the clock the guardrails read", () => {
|
|
65
|
+
const ARGS = ["--input", "fechado, pago à vista", "--transcript", "test/fixtures/accept-1042.transcript.jsonl", "--approve", "--simulate-payer", "--json"];
|
|
66
|
+
type Payload = { executions: Array<{ state: string; reason: string | null; charges: unknown[] }>; receipts: string[] };
|
|
67
|
+
|
|
68
|
+
it("at 20:08 America/Sao_Paulo the fixture is denied (outside_hours) and nothing is issued", () => {
|
|
69
|
+
const out = run("start", [...ARGS, "--now", "2026-09-23T20:08:00-03:00"], scratch("now-night"));
|
|
70
|
+
expect(out.code).toBe(0);
|
|
71
|
+
const payload = JSON.parse(out.stdout.trim()) as Payload;
|
|
72
|
+
expect(payload.executions).toHaveLength(1);
|
|
73
|
+
expect(payload.executions[0]).toMatchObject({ state: "denied", reason: "outside_hours", charges: [] });
|
|
74
|
+
expect(payload.receipts).toHaveLength(0);
|
|
75
|
+
expect(out.stderr).toContain("agora sao 20:08");
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("at 14:00 America/Sao_Paulo the same command settles, whatever the wall clock says", () => {
|
|
79
|
+
const out = run("start", [...ARGS, "--now", "2026-09-23T14:00:00-03:00"], scratch("now-day"));
|
|
80
|
+
expect(out.code).toBe(0);
|
|
81
|
+
const payload = JSON.parse(out.stdout.trim()) as Payload;
|
|
82
|
+
expect(payload.executions.map((e) => e.state)).toEqual(["settled"]);
|
|
83
|
+
expect(payload.executions[0]?.charges).toHaveLength(1);
|
|
84
|
+
expect(payload.receipts).toHaveLength(1);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("CODESPAR_AGENT_NOW is the same pin from the environment; an unparseable value exits 2 before anything runs", () => {
|
|
88
|
+
const out = run("start", ARGS, { ...scratch("now-env"), CODESPAR_AGENT_NOW: "2026-09-23T20:08:00-03:00" });
|
|
89
|
+
expect(out.code).toBe(0);
|
|
90
|
+
expect((JSON.parse(out.stdout.trim()) as Payload).executions[0]).toMatchObject({ state: "denied", reason: "outside_hours" });
|
|
91
|
+
|
|
92
|
+
const bad = run("start", [...ARGS, "--now", "yesterday"], scratch("now-bad"));
|
|
93
|
+
expect(bad.code).toBe(2);
|
|
94
|
+
expect(bad.stdout).toBe("");
|
|
95
|
+
expect(bad.stderr).toContain("--now must be an ISO 8601 instant");
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
61
99
|
it("refuses a key outside csk_test_ before anything else", () => {
|
|
62
100
|
const env = scratch("live");
|
|
63
|
-
const out = run("
|
|
101
|
+
const out = run("start", ["--input", HAPPY, "--json"], { ...env, CODESPAR_API_KEY: ["csk", "live", "0000000000"].join("_") });
|
|
64
102
|
expect(out.code).toBe(1);
|
|
65
103
|
expect(out.stdout).toBe("");
|
|
66
104
|
expect(out.stderr).toContain("csk_test_");
|
|
@@ -71,7 +109,7 @@ describe("section 10: restart after the issuance, then resume and poll", () => {
|
|
|
71
109
|
it("one receivable, one settlement, never two", () => {
|
|
72
110
|
const env = scratch("restart");
|
|
73
111
|
|
|
74
|
-
const killed = run("
|
|
112
|
+
const killed = run("start", ["--input", "fechado, pago à vista", "--transcript", "test/fixtures/accept-1042.transcript.jsonl", "--approve", "--json"], { ...env, COLLECTIONS_KILL_AFTER_DISPATCH: "1" });
|
|
75
113
|
expect(killed.code).toBe(137);
|
|
76
114
|
expect(killed.stdout).toBe("");
|
|
77
115
|
|
|
@@ -81,7 +119,7 @@ describe("section 10: restart after the issuance, then resume and poll", () => {
|
|
|
81
119
|
db.close();
|
|
82
120
|
|
|
83
121
|
// resume: the outbox is `sent`, so nothing is re-issued; the receivable is looked at and found registered, waiting for its payer.
|
|
84
|
-
const resumed = run("
|
|
122
|
+
const resumed = run("resume", ["--json"], env);
|
|
85
123
|
expect(resumed.code).toBe(0);
|
|
86
124
|
const r = JSON.parse(resumed.stdout.trim()) as { resumed: Array<{ state: string; reason: string | null; charge_ids: string[] }> };
|
|
87
125
|
expect(r.resumed).toHaveLength(1);
|
|
@@ -89,7 +127,7 @@ describe("section 10: restart after the issuance, then resume and poll", () => {
|
|
|
89
127
|
expect(r.resumed[0]?.charge_ids[0]).toMatch(/^chg_stub_/);
|
|
90
128
|
|
|
91
129
|
// poll: the fixture payer pays on the next look; the record is fetched; the payer is told once.
|
|
92
|
-
const polled = run("
|
|
130
|
+
const polled = run("poll", ["--json"], env);
|
|
93
131
|
expect(polled.code).toBe(0);
|
|
94
132
|
const p = JSON.parse(polled.stdout.trim()) as { polled: Array<{ state: string; timed_out: boolean }> };
|
|
95
133
|
expect(p.polled).toEqual([expect.objectContaining({ state: "settled", timed_out: false })]);
|
|
@@ -105,7 +143,7 @@ describe("section 10: restart after the issuance, then resume and poll", () => {
|
|
|
105
143
|
const receipts = readdirSync(runsDir).flatMap((d) => (existsSync(join(runsDir, d, "receipts")) ? readdirSync(join(runsDir, d, "receipts")) : []));
|
|
106
144
|
expect(receipts).toHaveLength(1);
|
|
107
145
|
|
|
108
|
-
const again = run("
|
|
146
|
+
const again = run("poll", ["--json"], env);
|
|
109
147
|
expect(JSON.parse(again.stdout.trim())).toEqual({ polled: [] });
|
|
110
148
|
});
|
|
111
149
|
});
|
|
@@ -114,11 +152,11 @@ describe("npm run rerun <run-id>", () => {
|
|
|
114
152
|
it("reproduces a recorded run without network, with the same state sequence, including an expired receivable", () => {
|
|
115
153
|
const env = scratch("rerun");
|
|
116
154
|
// No --simulate-payer: the fixture payer lets it expire at the second look; the recorded run is a failed one.
|
|
117
|
-
const first = run("
|
|
155
|
+
const first = run("start", ["--input", "pode emitir", "--transcript", "test/fixtures/accept-1103.transcript.jsonl", "--approve", "--json"], { ...env, COLLECTIONS_STUB_PAYER: "expires" });
|
|
118
156
|
expect(first.code).toBe(0);
|
|
119
157
|
const payload = JSON.parse(first.stdout.trim()) as { run_id: string; executions: Array<{ state: string; reason: string | null }> };
|
|
120
158
|
expect(payload.executions[0]).toMatchObject({ state: "failed", reason: "charge_expired" });
|
|
121
|
-
const rerun = run("
|
|
159
|
+
const rerun = run("rerun", [payload.run_id, "--json"], env);
|
|
122
160
|
expect(rerun.code).toBe(0);
|
|
123
161
|
const r = JSON.parse(rerun.stdout.trim()) as { same_states: boolean; original: string[]; rerun: string[] };
|
|
124
162
|
expect(r.same_states).toBe(true);
|
|
@@ -128,7 +166,7 @@ describe("npm run rerun <run-id>", () => {
|
|
|
128
166
|
|
|
129
167
|
describe("npm run check", () => {
|
|
130
168
|
it("is green for the shipped agent and prints JSON with --json", () => {
|
|
131
|
-
const out = run("
|
|
169
|
+
const out = run("check", ["--json"], {});
|
|
132
170
|
expect(out.code).toBe(0);
|
|
133
171
|
const report = JSON.parse(out.stdout.trim()) as { ok: boolean; agent: string; findings: unknown[] };
|
|
134
172
|
expect(report).toMatchObject({ ok: true, agent: "collections-agent" });
|
|
@@ -138,13 +176,13 @@ describe("npm run check", () => {
|
|
|
138
176
|
describe("npm run approve / deny <execution-id>", () => {
|
|
139
177
|
it("decides an execution left awaiting, produces the artifact, issues, and waits for the payer", () => {
|
|
140
178
|
const env = scratch("decide");
|
|
141
|
-
const left = run("
|
|
179
|
+
const left = run("start", ["--input", "fechado, pago à vista", "--transcript", "test/fixtures/accept-1042.transcript.jsonl", "--json"], env);
|
|
142
180
|
expect(left.code).toBe(0);
|
|
143
181
|
const payload = JSON.parse(left.stdout.trim()) as { executions: Array<{ id: string; state: string }> };
|
|
144
182
|
expect(payload.executions[0]?.state).toBe("awaiting_approval");
|
|
145
183
|
const id = payload.executions[0]!.id;
|
|
146
184
|
|
|
147
|
-
const approved = run("
|
|
185
|
+
const approved = run("approve", [id, "--user", "usr_gerente", "--simulate-payer", "--json"], env);
|
|
148
186
|
expect(approved.code).toBe(0);
|
|
149
187
|
const out = JSON.parse(approved.stdout.trim()) as { state: string; approval_id: string | null; charge_ids: string[]; receipt_ids: string[]; bundle_dir: string };
|
|
150
188
|
expect(out.state).toBe("settled");
|
|
@@ -154,15 +192,15 @@ describe("npm run approve / deny <execution-id>", () => {
|
|
|
154
192
|
const artifacts = JSON.parse(readFileSync(join(AGENT_DIR, out.bundle_dir, "approval.json"), "utf8")) as Array<{ approver: { type: string; id: string } }>;
|
|
155
193
|
expect(artifacts[0]?.approver).toEqual({ type: "person", id: "usr_gerente", channel: "terminal" });
|
|
156
194
|
|
|
157
|
-
const again = run("
|
|
195
|
+
const again = run("approve", [id, "--json"], env);
|
|
158
196
|
expect(again.code).toBe(1);
|
|
159
197
|
});
|
|
160
198
|
|
|
161
199
|
it("deny leaves a terminal denied execution and issues nothing", () => {
|
|
162
200
|
const env = scratch("deny");
|
|
163
|
-
const left = run("
|
|
201
|
+
const left = run("start", ["--input", "fechado, pago à vista", "--transcript", "test/fixtures/accept-1042.transcript.jsonl", "--json"], env);
|
|
164
202
|
const id = (JSON.parse(left.stdout.trim()) as { executions: Array<{ id: string }> }).executions[0]!.id;
|
|
165
|
-
const denied = run("
|
|
203
|
+
const denied = run("deny", [id, "--json"], env);
|
|
166
204
|
expect(denied.code).toBe(0);
|
|
167
205
|
expect(JSON.parse(denied.stdout.trim())).toMatchObject({ state: "denied", reason: "denied_by_approver", charge_ids: [] });
|
|
168
206
|
const db = new DatabaseSync(join(env["COLLECTIONS_STATE_DIR"]!, "state.db"));
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
{"kind": "assistant_step", "tool_calls": [{"id": "tc_1", "name": "list_agreements", "input": {}}]}
|
|
2
|
+
{"kind": "assistant_step", "reply": "Oi, Joana! Aqui é o atendimento da loja sobre o pedido #1042, R$ 1.200,00 em aberto. Posso fechar assim: à vista com 10% de desconto, R$ 1.080,00, vencendo em 30/09; ou em 3 parcelas de R$ 400,00. Qual prefere?"}
|
|
3
|
+
{"kind": "assistant_step", "tool_calls": [{"id": "tc_2", "name": "codespar_charge", "input": {"action": "create", "agreement": "acordo-1042", "instalments": [{"amount_minor": 108000, "due_date": "2026-09-30"}], "total_minor": 108000}}]}
|
|
4
|
+
{"kind": "assistant_step", "reply": "Fechado, Joana! A cobrança de R$ 1.080,00 está emitida e vence em 30/09. Assim que o pagamento cair, eu te aviso por aqui."}
|
|
@@ -3,7 +3,8 @@ import { tmpdir } from "node:os";
|
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { describe, expect, it } from "vitest";
|
|
5
5
|
import { AGREEMENTS } from "../src/agreements.js";
|
|
6
|
-
import { checkScenario, listScenarios, loadScenario, runScenario, type ScenarioRun } from "
|
|
6
|
+
import { checkScenario, listScenarios, loadScenario, runScenario, type ScenarioRun } from "@codespar/agent-runtime";
|
|
7
|
+
import { agent } from "../src/kit.js";
|
|
7
8
|
|
|
8
9
|
const runsDir = mkdtempSync(join(tmpdir(), "collections-runs-"));
|
|
9
10
|
const DOCUMENTS = AGREEMENTS.map((a) => a.document);
|
|
@@ -12,14 +13,14 @@ describe("section 12: scenario packs, on the replay provider and the stub rail",
|
|
|
12
13
|
const required = ["happy-path", "charge-expired", "prompt-injection", "cap-exceeded", "beneficiary-not-allowed", "escalated-above-threshold", "mandate-revoked", "instalments"];
|
|
13
14
|
|
|
14
15
|
it("ships every scenario the spec asks for, plus instalments", () => {
|
|
15
|
-
for (const name of required) expect(listScenarios()).toContain(name);
|
|
16
|
+
for (const name of required) expect(listScenarios(agent)).toContain(name);
|
|
16
17
|
});
|
|
17
18
|
|
|
18
19
|
for (const name of required) {
|
|
19
|
-
const scenario = loadScenario(name);
|
|
20
|
+
const scenario = loadScenario(agent, name);
|
|
20
21
|
for (const mode of scenario.modes) {
|
|
21
22
|
it(`${name} [${mode}] ends in the states the pack declares`, async () => {
|
|
22
|
-
const run = await runScenario(scenario, { mode, runsDir });
|
|
23
|
+
const run = await runScenario(agent, scenario, { mode, runsDir });
|
|
23
24
|
const check = checkScenario(scenario, run);
|
|
24
25
|
expect(check.failures).toEqual([]);
|
|
25
26
|
expect(check.ok).toBe(true);
|
|
@@ -45,9 +46,9 @@ describe("section 12: scenario packs, on the replay provider and the stub rail",
|
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
it("happy-path: the same records in human and in mandate; the person decided in human, the envelope in mandate", async () => {
|
|
48
|
-
const scenario = loadScenario("happy-path");
|
|
49
|
-
const human = await runScenario(scenario, { mode: "human", runsDir });
|
|
50
|
-
const mandate = await runScenario(scenario, { mode: "mandate", runsDir });
|
|
49
|
+
const scenario = loadScenario(agent, "happy-path");
|
|
50
|
+
const human = await runScenario(agent, scenario, { mode: "human", runsDir });
|
|
51
|
+
const mandate = await runScenario(agent, scenario, { mode: "mandate", runsDir });
|
|
51
52
|
expect(normalizeReceipts(human)).toEqual(normalizeReceipts(mandate));
|
|
52
53
|
const approvals = (run: ScenarioRun) => JSON.parse(readFileSync(join(run.bundle_dir, "approval.json"), "utf8")) as Array<{ approver: { type: string }; items_hash: string; items: Array<{ due_date?: string }> }>;
|
|
53
54
|
expect(approvals(human)[0]?.approver.type).toBe("person");
|
|
@@ -65,9 +66,9 @@ describe("section 12: scenario packs, on the replay provider and the stub rail",
|
|
|
65
66
|
|
|
66
67
|
it("nothing reaches executing without an approval artifact carrying its items_hash", async () => {
|
|
67
68
|
for (const name of required) {
|
|
68
|
-
const scenario = loadScenario(name);
|
|
69
|
+
const scenario = loadScenario(agent, name);
|
|
69
70
|
for (const mode of scenario.modes) {
|
|
70
|
-
const run = await runScenario(scenario, { mode, runsDir });
|
|
71
|
+
const run = await runScenario(agent, scenario, { mode, runsDir });
|
|
71
72
|
const approvalPath = join(run.bundle_dir, "approval.json");
|
|
72
73
|
const artifacts = existsSync(approvalPath) ? (JSON.parse(readFileSync(approvalPath, "utf8")) as Array<{ execution_id: string; items_hash: string }>) : [];
|
|
73
74
|
for (const e of run.executions) {
|
|
@@ -79,7 +80,7 @@ describe("section 12: scenario packs, on the replay provider and the stub rail",
|
|
|
79
80
|
});
|
|
80
81
|
|
|
81
82
|
it("instalments: three receivables, three idempotency keys, one execution, one message", async () => {
|
|
82
|
-
const run = await runScenario(loadScenario("instalments"), { mode: "human", runsDir });
|
|
83
|
+
const run = await runScenario(agent, loadScenario(agent, "instalments"), { mode: "human", runsDir });
|
|
83
84
|
expect(run.executions).toHaveLength(1);
|
|
84
85
|
expect(new Set(run.executions[0]!.charge_ids).size).toBe(3);
|
|
85
86
|
expect(run.charges_issued).toBe(3);
|