@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,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The seam between the shared runner and one agent. Everything the runner
|
|
3
|
+
* cannot know — which rail the agent drives, what the person at the keyboard
|
|
4
|
+
* is called, which tools the model may reach, what a one-shot prints as JSON —
|
|
5
|
+
* comes from the `kit` the agent exports; everything else is here and is the
|
|
6
|
+
* same for every agent.
|
|
7
|
+
*
|
|
8
|
+
* An agent that needs none of it ships no kit at all: `defaultKit` drives the
|
|
9
|
+
* stub payment rail with the example mandate, which is what a read-only agent
|
|
10
|
+
* wants.
|
|
11
|
+
*/
|
|
12
|
+
import type {
|
|
13
|
+
ChargeInstrument,
|
|
14
|
+
Execution,
|
|
15
|
+
LoadedManifest,
|
|
16
|
+
LocalMandateStatusStub,
|
|
17
|
+
Guardrails,
|
|
18
|
+
Mandate,
|
|
19
|
+
MandateStatusSource,
|
|
20
|
+
PaymentRail,
|
|
21
|
+
PolicyExtension,
|
|
22
|
+
StateStore,
|
|
23
|
+
StubPayerBehaviour,
|
|
24
|
+
StubRailOptions,
|
|
25
|
+
StubChargeRailOptions,
|
|
26
|
+
ToolHandler,
|
|
27
|
+
} from "@codespar/agent-core";
|
|
28
|
+
import type { ApiClient } from "@codespar/sdk";
|
|
29
|
+
import type { Setup } from "./setup.js";
|
|
30
|
+
import type { ScenarioCheck } from "./scenarios.js";
|
|
31
|
+
import type { AdversarialResult } from "./adversarial.js";
|
|
32
|
+
|
|
33
|
+
export type RailKind = "stub" | "api";
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* How an execution reaches a terminal state. `immediate`: the rail answers
|
|
37
|
+
* and the execution is settled or failed (money out). `await-payer`: the rail
|
|
38
|
+
* accepts and somebody else has to act, so the run looks at the receivable
|
|
39
|
+
* until it closes (money in).
|
|
40
|
+
*/
|
|
41
|
+
export type Settlement = "immediate" | "await-payer";
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Who plays the counterparty in the sandbox. With the stub rail it is the
|
|
45
|
+
* fixture inside the rail; with a test key it is the API's own test route.
|
|
46
|
+
*/
|
|
47
|
+
export interface SandboxPayer {
|
|
48
|
+
kind: RailKind;
|
|
49
|
+
/** Pays a receivable this run issued. Returns what the payer reported, or the refusal. */
|
|
50
|
+
pay(chargeId: string, attemptId: string): Promise<{ ok: true; detail: string } | { ok: false; detail: string }>;
|
|
51
|
+
/** Stub only: what the fixture does with receivables issued from now on. */
|
|
52
|
+
behave(behaviour: StubPayerBehaviour): void;
|
|
53
|
+
/**
|
|
54
|
+
* Stub only: what the fixture does with ONE receivable that was already
|
|
55
|
+
* issued and looked at.
|
|
56
|
+
*
|
|
57
|
+
* It is separate from `behave` because they answer different questions, and
|
|
58
|
+
* a poll needs the second one. `behave` sets the default for receivables
|
|
59
|
+
* the rail has not seen yet; by the time a poll resumes a conversation the
|
|
60
|
+
* rail HAS seen this one, and its fate is a row in state.db that only this
|
|
61
|
+
* rewrites. It is separate from `pay` because `pay` means pay — the
|
|
62
|
+
* scenario runner's late payer calls it after telling the fixture to sit on
|
|
63
|
+
* everything, and it has to pay anyway.
|
|
64
|
+
*
|
|
65
|
+
* The API's payer is a route and has no equivalent, so this is optional.
|
|
66
|
+
*/
|
|
67
|
+
decideFor?(attemptId: string, behaviour: StubPayerBehaviour): void;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface RailContext {
|
|
71
|
+
kind: RailKind;
|
|
72
|
+
env: NodeJS.ProcessEnv;
|
|
73
|
+
agentDir: string;
|
|
74
|
+
stateDir: string;
|
|
75
|
+
manifest: LoadedManifest;
|
|
76
|
+
store: StateStore;
|
|
77
|
+
gate: LocalMandateStatusStub;
|
|
78
|
+
now: (() => Date) | undefined;
|
|
79
|
+
/** The mandate a caller pinned (a scenario, a test), if any. */
|
|
80
|
+
mandate: Mandate | undefined;
|
|
81
|
+
/** Stub-rail overrides a caller pinned (rerun, a scenario). */
|
|
82
|
+
stubRail: StubRailOptions | StubChargeRailOptions | undefined;
|
|
83
|
+
/** Reads `<PREFIX>_<NAME>` from the environment, the prefix being the agent's own. */
|
|
84
|
+
envVar(name: string): string | undefined;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export interface RailBuild {
|
|
88
|
+
rail: PaymentRail;
|
|
89
|
+
mandate: Mandate;
|
|
90
|
+
/** The section 4.7 source. Defaults to the local stub gate. */
|
|
91
|
+
status?: MandateStatusSource;
|
|
92
|
+
api?: ApiClient | undefined;
|
|
93
|
+
payer?: SandboxPayer;
|
|
94
|
+
/** Milliseconds between two looks at an issued receivable. */
|
|
95
|
+
pollIntervalMs?: number;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export interface RuntimeLabels {
|
|
99
|
+
/** Who decides when no `--user` is given: `usr_terminal`, `usr_operator`. */
|
|
100
|
+
defaultUser: string;
|
|
101
|
+
/** Who decides inside a scenario or an adversarial case. */
|
|
102
|
+
evalUser: string;
|
|
103
|
+
/** The word for the signed instrument in the banner: `mandato`, `politica`. */
|
|
104
|
+
mandateWord: string;
|
|
105
|
+
/** The word for a sealed outcome in the console: `recibo`, `registro`. */
|
|
106
|
+
receiptWord: string;
|
|
107
|
+
/** What the interactive loop prints under the banner. */
|
|
108
|
+
intro: string;
|
|
109
|
+
/** The interactive prompt. */
|
|
110
|
+
prompt: string;
|
|
111
|
+
/** The question an `awaiting_approval` execution asks at the keyboard. */
|
|
112
|
+
approveQuestion: string;
|
|
113
|
+
/** What the console says when a dispatch ended with an unknown outcome. */
|
|
114
|
+
uncertainDispatch: string;
|
|
115
|
+
/** `reconcile`'s finding kind and detail for a sealed outcome the bundle does not hold. */
|
|
116
|
+
missingReceiptKind: string;
|
|
117
|
+
missingReceiptDetail(receiptId: string, runId: string): string;
|
|
118
|
+
/** `resume`'s line for an execution it could not close. */
|
|
119
|
+
stillExecuting(execution: Execution): string;
|
|
120
|
+
/** `await-payer` only: the line printed every few looks while the payer has not acted. */
|
|
121
|
+
waitingForPayer?(round: number): string;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface OneShotContext {
|
|
125
|
+
setup: Setup;
|
|
126
|
+
reply: string;
|
|
127
|
+
toolCalls: Array<{ name: string; refused: boolean }>;
|
|
128
|
+
executions: Execution[];
|
|
129
|
+
/** `Date.now()` when the turn started, for an agent that reports its cycle. */
|
|
130
|
+
startedAt: number;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export interface ConsentContext {
|
|
134
|
+
agentDir: string;
|
|
135
|
+
argv: string[];
|
|
136
|
+
say(line: string): void;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export interface EnsureMandateContext extends ConsentContext {
|
|
140
|
+
railKind: RailKind;
|
|
141
|
+
/** True when the run has no conversation to fall back on (a one-shot). */
|
|
142
|
+
oneShot: boolean;
|
|
143
|
+
ask(question: string): Promise<string>;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export interface AgentKit {
|
|
147
|
+
/** `immediate` (money out) or `await-payer` (money in). Default `immediate`. */
|
|
148
|
+
settlement?: Settlement;
|
|
149
|
+
/**
|
|
150
|
+
* Which rail a `--scenario` run uses: the stub always, or the one the
|
|
151
|
+
* environment resolved. An agent whose packs declare `rails` wants
|
|
152
|
+
* `requested`; one whose packs are offline fixtures wants `stub`.
|
|
153
|
+
*/
|
|
154
|
+
scenarioRail?: "stub" | "requested";
|
|
155
|
+
labels: RuntimeLabels;
|
|
156
|
+
/** The usage text `--help`, a bad flag and a bad `--now` print. */
|
|
157
|
+
usage(manifest: LoadedManifest): string;
|
|
158
|
+
buildRail(ctx: RailContext): RailBuild;
|
|
159
|
+
handlers(setup: Setup): Record<string, ToolHandler>;
|
|
160
|
+
/** The deterministic policy the core runs as its `policyExtension`. */
|
|
161
|
+
policyExtension?(ctx: { agentDir: string; manifest: LoadedManifest; guardrails: Guardrails }): PolicyExtension | undefined;
|
|
162
|
+
/** The console lines that describe one execution. */
|
|
163
|
+
describeExecution(execution: Execution, setup: Setup): string[];
|
|
164
|
+
/** The `--json` body of a one-shot. */
|
|
165
|
+
oneShotPayload(ctx: OneShotContext): Record<string, unknown>;
|
|
166
|
+
/** `await-payer` only: what the payer reads when a receivable becomes payable. */
|
|
167
|
+
presentInstrument?(execution: Execution, instalment: number, chargeId: string, instrument: ChargeInstrument, tell: (line: string) => void): void;
|
|
168
|
+
/** `await-payer` only: the one message per outcome the counterparty receives. */
|
|
169
|
+
announceOutcome?(execution: Execution, setup: Setup, tell: (line: string) => void): boolean;
|
|
170
|
+
/**
|
|
171
|
+
* The SAME outcome as `announceOutcome`, carried as an approved template.
|
|
172
|
+
*
|
|
173
|
+
* It exists because a channel can have a rule about WHEN free text may be
|
|
174
|
+
* sent, and WhatsApp does: outside the 24 hours after the person's last
|
|
175
|
+
* message only a template Meta approved goes out. A collection reaches that
|
|
176
|
+
* state as its normal case — agreed Tuesday, paid Friday — so an agent that
|
|
177
|
+
* closes its cycle on a channel owns a template for each outcome it can
|
|
178
|
+
* close on, or it cannot tell the person at all.
|
|
179
|
+
*
|
|
180
|
+
* The name must be one the agent declares in
|
|
181
|
+
* `channels/whatsapp/templates.json`; the language is the registry's and is
|
|
182
|
+
* not repeated here. `undefined` means this agent has no approved copy for
|
|
183
|
+
* that outcome, which the caller REPORTS rather than papers over: a person
|
|
184
|
+
* who was not told was not told.
|
|
185
|
+
*/
|
|
186
|
+
outcomeTemplate?(execution: Execution): { template: string; variables: string[] } | undefined;
|
|
187
|
+
/** Runs before a one-shot or an interactive session, when the mandate may have to be born first. Returns false to stop the run. */
|
|
188
|
+
ensureMandate?(ctx: EnsureMandateContext): Promise<boolean>;
|
|
189
|
+
/** `codespar-agent consent`. Absent means the agent has no consent step. */
|
|
190
|
+
consent?(ctx: ConsentContext): Promise<number>;
|
|
191
|
+
/** The prior settled executions an adversarial case asks for, so a velocity window has history. */
|
|
192
|
+
warmUp?(setup: Setup, aliases: string[], approver: { id: string; channel: string }): Promise<Set<string>>;
|
|
193
|
+
/** The `kind: events` adversarial case: duplicated and out-of-order deliveries. */
|
|
194
|
+
runEventsCase?(setup: Setup, tell: (line: string) => void): Promise<void>;
|
|
195
|
+
/**
|
|
196
|
+
* What a `rerun` has to reproduce from the recorded events, beyond the
|
|
197
|
+
* model's own outputs: a payee the rail refused, a receivable the payer let
|
|
198
|
+
* expire. The rail's and the counterparty's answers are part of the recording.
|
|
199
|
+
*/
|
|
200
|
+
rerunPlan?(events: Array<Record<string, unknown>>): { stubRail?: StubRailOptions | StubChargeRailOptions; simulatePayer?: boolean };
|
|
201
|
+
/** Whether `rerun` compares the rail's outcomes as well as the state trail. */
|
|
202
|
+
rerunComparesOutcomes?: boolean;
|
|
203
|
+
/** The one line `eval` prints per scenario run and per adversarial case. */
|
|
204
|
+
evalScenarioLine?(check: ScenarioCheck): string;
|
|
205
|
+
evalAdversarialLine?(result: AdversarialResult): string;
|
|
206
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How the cycle closes without a webhook: the kit LOOKS at the receivable
|
|
3
|
+
* (`GET /v1/charges/{id}` through the rail's `lookup`, the stub's fixture
|
|
4
|
+
* offline) until the payer acted or the wait ran out. Each look is a
|
|
5
|
+
* `reconcile`, which is read-only on the rail and never re-issues. The
|
|
6
|
+
* instrument (QR, copy-and-paste, bank line) is presented the first time a
|
|
7
|
+
* look finds it payable; the debtor is told the outcome once, whatever the
|
|
8
|
+
* number of looks or events that carried it.
|
|
9
|
+
*/
|
|
10
|
+
import type { ChargeInstrument, Execution, ExecutionEngine } from "@codespar/agent-core";
|
|
11
|
+
import type { SandboxPayer } from "./kit.js";
|
|
12
|
+
|
|
13
|
+
export interface PollHooks {
|
|
14
|
+
/**
|
|
15
|
+
* A receivable became payable: show the payer how to pay. Called once per
|
|
16
|
+
* instalment, and AWAITED — on a console the lines are on the screen by the
|
|
17
|
+
* time the call returns, but on a channel the message still has to go out,
|
|
18
|
+
* and a payer told how to pay after the poll already closed was not told.
|
|
19
|
+
*/
|
|
20
|
+
onInstrument?: (execution: Execution, instalment: number, chargeId: string, instrument: ChargeInstrument) => void | Promise<void>;
|
|
21
|
+
/** The execution reached a terminal state. Called once. */
|
|
22
|
+
onClosed?: (execution: Execution) => void;
|
|
23
|
+
/** Called before each look after the first. */
|
|
24
|
+
onWait?: (execution: Execution, round: number) => void;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface PollOptions extends PollHooks {
|
|
28
|
+
intervalMs: number;
|
|
29
|
+
/** Wall-clock budget for the wait. */
|
|
30
|
+
timeoutMs: number;
|
|
31
|
+
/** Cap on looks, for a zero-interval (stub) loop: the fixture payer acts within two looks; a third proves nothing changes. */
|
|
32
|
+
maxRounds?: number;
|
|
33
|
+
/** When set, the payer plays once every instalment is payable, or after `payerAfterRounds` looks (a scenario, `--simulate-payer`). */
|
|
34
|
+
payer?: SandboxPayer | undefined;
|
|
35
|
+
payerAfterRounds?: number;
|
|
36
|
+
clock?: () => Date;
|
|
37
|
+
sleep?: (ms: number) => Promise<void>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface PollResult {
|
|
41
|
+
execution: Execution;
|
|
42
|
+
rounds: number;
|
|
43
|
+
/** Seconds from the first look to the terminal state, or to the end of the wait. */
|
|
44
|
+
seconds: number;
|
|
45
|
+
timed_out: boolean;
|
|
46
|
+
payer_calls: string[];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const defaultSleep = (ms: number) => new Promise<void>((r) => setTimeout(r, ms));
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Presents each instalment once, records `message.debtor` once per outcome,
|
|
53
|
+
* and returns when the execution is terminal or the wait is over. Safe to
|
|
54
|
+
* call again on the same execution (a restart): what was already shown is
|
|
55
|
+
* remembered in the state.db cursor table, not in memory.
|
|
56
|
+
*/
|
|
57
|
+
export async function pollUntilClosed(engine: ExecutionEngine, executionId: string, options: PollOptions): Promise<PollResult> {
|
|
58
|
+
const clock = options.clock ?? (() => new Date());
|
|
59
|
+
const sleep = options.sleep ?? defaultSleep;
|
|
60
|
+
const startedWall = Date.now();
|
|
61
|
+
const started = clock().getTime();
|
|
62
|
+
const maxRounds = options.maxRounds ?? (options.intervalMs === 0 ? 3 : Number.POSITIVE_INFINITY);
|
|
63
|
+
const payerCalls: string[] = [];
|
|
64
|
+
let execution = engine.get(executionId);
|
|
65
|
+
if (!execution) throw new Error(`unknown execution ${executionId}`);
|
|
66
|
+
let rounds = 0;
|
|
67
|
+
let paidRequested = false;
|
|
68
|
+
|
|
69
|
+
const present = async (e: Execution) => {
|
|
70
|
+
for (const outcome of e.outcomes) {
|
|
71
|
+
if (outcome.status !== "accepted" || !outcome.instrument?.payable || !outcome.transaction_id) continue;
|
|
72
|
+
if (!engine.markShown(e.id, outcome.attempt_id)) continue;
|
|
73
|
+
await options.onInstrument?.(e, outcome.index + 1, outcome.transaction_id, outcome.instrument);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
await present(execution);
|
|
78
|
+
while (execution.state === "executing") {
|
|
79
|
+
if (rounds > 0) {
|
|
80
|
+
// A zero-interval loop (the stub) is bounded by looks; a real one by the wall clock.
|
|
81
|
+
if (rounds >= maxRounds || (options.intervalMs > 0 && Date.now() - startedWall >= options.timeoutMs)) break;
|
|
82
|
+
options.onWait?.(execution, rounds);
|
|
83
|
+
if (options.intervalMs > 0) await sleep(options.intervalMs);
|
|
84
|
+
}
|
|
85
|
+
rounds += 1;
|
|
86
|
+
execution = await engine.reconcile(execution.id);
|
|
87
|
+
await present(execution);
|
|
88
|
+
// The sandbox payer plays once every receivable is payable (the QR was shown first, as in the scene), or after a few looks if the
|
|
89
|
+
// clearing house is still registering: the API's test route settles a PROCESSING charge too, and on the shared sandbox the
|
|
90
|
+
// registration can take minutes. A real payer is not this hook.
|
|
91
|
+
const issued = execution.outcomes.filter((o) => o.status === "accepted" && o.transaction_id);
|
|
92
|
+
const allPayable = issued.length > 0 && issued.every((o) => o.instrument?.payable);
|
|
93
|
+
const patienceOver = rounds >= (options.payerAfterRounds ?? 5);
|
|
94
|
+
if (options.payer && !paidRequested && execution.state === "executing" && issued.length > 0 && issued.length === execution.outcomes.filter((o) => o.status === "accepted").length && (allPayable || patienceOver)) {
|
|
95
|
+
paidRequested = true;
|
|
96
|
+
for (const outcome of issued) {
|
|
97
|
+
const result = await options.payer.pay(outcome.transaction_id!, outcome.attempt_id);
|
|
98
|
+
payerCalls.push(result.detail);
|
|
99
|
+
engine.note("sandbox_payer", execution.id, { charge_id: outcome.transaction_id, ok: result.ok, detail: result.detail });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (execution.state !== "executing") options.onClosed?.(execution);
|
|
104
|
+
return { execution, rounds, seconds: Math.round(((clock().getTime() - started) / 1000) * 10) / 10, timed_out: execution.state === "executing", payer_calls: payerCalls };
|
|
105
|
+
}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Section 12: scenario packs. A scenario is a JSON file with the person's
|
|
3
|
+
* turns, the decision the approver gives, what the counterparty does with what
|
|
4
|
+
* the run produced, the hooks that make the world change mid-run (revocation,
|
|
5
|
+
* an uncertain rail answer) and what the trail must look like at the end. The
|
|
6
|
+
* model's outputs come from a recorded transcript, so the same file feeds the
|
|
7
|
+
* CI, the live demo and the docs.
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync, mkdtempSync, readdirSync, readFileSync } from "node:fs";
|
|
10
|
+
import { tmpdir } from "node:os";
|
|
11
|
+
import { basename, join, resolve } from "node:path";
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
import type { ApprovalMode, Execution } from "@codespar/agent-core";
|
|
14
|
+
import type { Agent } from "./agent.js";
|
|
15
|
+
import type { RailKind } from "./kit.js";
|
|
16
|
+
import { setup, type Setup } from "./setup.js";
|
|
17
|
+
import { announceOutcome, handleExecution } from "./terminal.js";
|
|
18
|
+
|
|
19
|
+
const TurnSchema = z
|
|
20
|
+
.object({
|
|
21
|
+
input: z.string().min(1),
|
|
22
|
+
decision: z.enum(["approve", "deny", "none"]).default("approve"),
|
|
23
|
+
/** `await-payer` only: what the payer does with what this turn issued — pays during the turn, pays only after the last turn (`late`), lets it expire (stub-only), or nothing. */
|
|
24
|
+
payer: z.enum(["pays", "late", "expires", "never"]).default("pays"),
|
|
25
|
+
/** Runs after the execution is drafted and before the decision is taken. */
|
|
26
|
+
before_decision: z.enum(["revoke_mandate", "pause_all"]).optional(),
|
|
27
|
+
/** Runs after approval, before the rail is called; the core must catch it. */
|
|
28
|
+
before_execute: z.enum(["revoke_mandate", "pause_all"]).optional(),
|
|
29
|
+
/** The stub rail answers `uncertain` to the next attempt; the run ends with a reconcile. */
|
|
30
|
+
rail_uncertain: z.boolean().default(false),
|
|
31
|
+
})
|
|
32
|
+
.strict();
|
|
33
|
+
|
|
34
|
+
const ExpectSchema = z
|
|
35
|
+
.object({
|
|
36
|
+
/** Final states of the executions, in order. */
|
|
37
|
+
states: z.array(z.string()).optional(),
|
|
38
|
+
/** History of each execution (the `to` of every transition). */
|
|
39
|
+
trails: z.array(z.array(z.string())).optional(),
|
|
40
|
+
reasons: z.array(z.string().nullable()).optional(),
|
|
41
|
+
triggers: z.array(z.string().nullable()).optional(),
|
|
42
|
+
receipts: z.number().int().nonnegative().optional(),
|
|
43
|
+
refused_before_draft: z.number().int().nonnegative().optional(),
|
|
44
|
+
/** Sum of the totals that reached `settled`. */
|
|
45
|
+
settled_total: z.number().int().nonnegative().optional(),
|
|
46
|
+
/** Receivables the rail issued (one per instalment; a retry never adds one). */
|
|
47
|
+
charges_issued: z.number().int().nonnegative().optional(),
|
|
48
|
+
/** Messages the counterparty received about outcomes: one per outcome, never two. */
|
|
49
|
+
debtor_messages: z.number().int().nonnegative().optional(),
|
|
50
|
+
/** With a real key: the happy path closes inside this many seconds from issuance. */
|
|
51
|
+
max_cycle_seconds: z.number().positive().optional(),
|
|
52
|
+
})
|
|
53
|
+
.strict();
|
|
54
|
+
|
|
55
|
+
export const ScenarioSchema = z
|
|
56
|
+
.object({
|
|
57
|
+
name: z.string().regex(/^[a-z0-9-]+$/),
|
|
58
|
+
description: z.string(),
|
|
59
|
+
modes: z.array(z.enum(["human", "mandate"])).nonempty(),
|
|
60
|
+
/** Which rails can run it. A fixture-only outcome (`expires`) needs the stub. */
|
|
61
|
+
rails: z.array(z.enum(["stub", "api"])).nonempty().default(["stub", "api"]),
|
|
62
|
+
now: z.string().datetime().default("2026-09-23T18:00:00.000Z"),
|
|
63
|
+
/**
|
|
64
|
+
* Payees the stub rail refuses for the whole run, by their pinned key.
|
|
65
|
+
* The rail's answer is the only part of a partial failure a pack cannot
|
|
66
|
+
* script from the mandate: an allowlist refusal never reaches the rail,
|
|
67
|
+
* and a payout that the provider itself declines is what a batch has to
|
|
68
|
+
* survive. Empty by default, so a pack that does not name one runs
|
|
69
|
+
* exactly as before.
|
|
70
|
+
*/
|
|
71
|
+
stub_refuse_payees: z.array(z.string()).default([]),
|
|
72
|
+
transcript: z.string(),
|
|
73
|
+
turns: z.array(TurnSchema).nonempty(),
|
|
74
|
+
expect: z.record(z.enum(["human", "mandate", "both"]), ExpectSchema),
|
|
75
|
+
})
|
|
76
|
+
.strict();
|
|
77
|
+
|
|
78
|
+
export type Scenario = z.infer<typeof ScenarioSchema>;
|
|
79
|
+
|
|
80
|
+
export interface ScenarioRun {
|
|
81
|
+
scenario: string;
|
|
82
|
+
mode: ApprovalMode;
|
|
83
|
+
rail: RailKind;
|
|
84
|
+
run_id: string;
|
|
85
|
+
bundle_dir: string;
|
|
86
|
+
replies: string[];
|
|
87
|
+
executions: Array<{ id: string; state: string; reason: string | null; trigger: string | null; total: number; trail: string[]; charge_ids: string[]; receipt_ids: string[] }>;
|
|
88
|
+
refused_before_draft: number;
|
|
89
|
+
receipts: number;
|
|
90
|
+
settled_total: number;
|
|
91
|
+
charges_issued: number;
|
|
92
|
+
debtor_messages: number;
|
|
93
|
+
/** Seconds from the first issuance to the last terminal state (wall clock on the API; the fake clock's ticks on the stub). */
|
|
94
|
+
cycle_seconds: number;
|
|
95
|
+
payer_calls: string[];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export interface ScenarioCheck {
|
|
99
|
+
ok: boolean;
|
|
100
|
+
mode: ApprovalMode;
|
|
101
|
+
failures: string[];
|
|
102
|
+
run: ScenarioRun;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function scenariosDir(agent: Agent): string {
|
|
106
|
+
return join(agent.dir, "scenarios");
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function listScenarios(agent: Agent): string[] {
|
|
110
|
+
return readdirSync(scenariosDir(agent))
|
|
111
|
+
.filter((f) => f.endsWith(".json"))
|
|
112
|
+
.map((f) => basename(f, ".json"))
|
|
113
|
+
.sort();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function loadScenario(agent: Agent, name: string): Scenario {
|
|
117
|
+
const path = join(scenariosDir(agent), `${name}.json`);
|
|
118
|
+
if (!existsSync(path)) throw new Error(`unknown scenario ${name}; available: ${listScenarios(agent).join(", ")}`);
|
|
119
|
+
return ScenarioSchema.parse(JSON.parse(readFileSync(path, "utf8")));
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export interface RunScenarioOptions {
|
|
123
|
+
mode: ApprovalMode;
|
|
124
|
+
rail?: RailKind;
|
|
125
|
+
runsDir?: string;
|
|
126
|
+
stateDir?: string;
|
|
127
|
+
say?: (line: string) => void;
|
|
128
|
+
tell?: (line: string) => void;
|
|
129
|
+
waitSeconds?: number | undefined;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export async function runScenario(agent: Agent, scenario: Scenario, options: RunScenarioOptions): Promise<ScenarioRun> {
|
|
133
|
+
const say = options.say ?? (() => undefined);
|
|
134
|
+
const tell = options.tell ?? (() => undefined);
|
|
135
|
+
const rail = options.rail ?? "stub";
|
|
136
|
+
const awaitsPayer = agent.settlement === "await-payer";
|
|
137
|
+
// On the stub the clock is the scenario's and ticks a second per read; on the API it is the wall clock, so the cycle is measured for real.
|
|
138
|
+
let clock = new Date(scenario.now);
|
|
139
|
+
const tick = () => {
|
|
140
|
+
clock = new Date(clock.getTime() + 1000);
|
|
141
|
+
return clock;
|
|
142
|
+
};
|
|
143
|
+
const stateDir = options.stateDir ?? mkdtempSync(join(tmpdir(), `${agent.slug}-${scenario.name}-${options.mode}-`));
|
|
144
|
+
const s: Setup = setup(agent, {
|
|
145
|
+
mode: options.mode,
|
|
146
|
+
rail,
|
|
147
|
+
provider: "replay",
|
|
148
|
+
transcript: resolve(scenariosDir(agent), scenario.transcript),
|
|
149
|
+
runsDir: options.runsDir ?? join(agent.dir, "runs"),
|
|
150
|
+
stateDir,
|
|
151
|
+
...(rail === "stub" ? { now: tick } : {}),
|
|
152
|
+
...(scenario.stub_refuse_payees.length > 0 ? { stubRail: { refusePayees: scenario.stub_refuse_payees } } : {}),
|
|
153
|
+
say,
|
|
154
|
+
});
|
|
155
|
+
const stub = s.rail as { armUncertainOnce?: () => void };
|
|
156
|
+
const runtime = s.makeRuntime();
|
|
157
|
+
const replies: string[] = [];
|
|
158
|
+
const approver = { id: s.kit.labels.evalUser, channel: "terminal" };
|
|
159
|
+
let refusedBeforeDraft = 0;
|
|
160
|
+
const payerCalls: string[] = [];
|
|
161
|
+
const late: string[] = [];
|
|
162
|
+
let firstIssued: number | undefined;
|
|
163
|
+
let lastClosed: number | undefined;
|
|
164
|
+
|
|
165
|
+
try {
|
|
166
|
+
for (const turn of scenario.turns) {
|
|
167
|
+
if (turn.rail_uncertain) stub.armUncertainOnce?.();
|
|
168
|
+
s.payer?.behave(turn.payer === "late" ? "never" : turn.payer);
|
|
169
|
+
const before = new Set(s.engine.list().map((e) => e.id));
|
|
170
|
+
const loop = s.makeLoop(runtime, async (execution: Execution) => {
|
|
171
|
+
applyHook(s, turn.before_decision);
|
|
172
|
+
const decided = await handleExecution(execution, {
|
|
173
|
+
setup: s,
|
|
174
|
+
approver,
|
|
175
|
+
decision: turn.decision,
|
|
176
|
+
say,
|
|
177
|
+
tell,
|
|
178
|
+
ask: async () => (turn.decision === "approve" ? "s" : "n"),
|
|
179
|
+
...(awaitsPayer ? { simulatePayer: turn.payer === "pays", waitSeconds: options.waitSeconds ?? (rail === "api" ? 60 : 0) } : {}),
|
|
180
|
+
});
|
|
181
|
+
if (turn.before_execute && decided.state === "approved") {
|
|
182
|
+
applyHook(s, turn.before_execute);
|
|
183
|
+
return s.engine.execute(decided.id);
|
|
184
|
+
}
|
|
185
|
+
return decided;
|
|
186
|
+
});
|
|
187
|
+
const result = await loop.turn(turn.input);
|
|
188
|
+
replies.push(result.reply);
|
|
189
|
+
refusedBeforeDraft += s.store.listEvents({ run_id: s.runId }).filter((e) => e.type === "execution.refused_before_draft").length - refusedBeforeDraft;
|
|
190
|
+
if (turn.payer === "late") for (const e of s.engine.list({ state: "executing" })) if (!before.has(e.id)) late.push(e.id);
|
|
191
|
+
}
|
|
192
|
+
// A late payer pays after the conversation ended (the receivable was in flight while the world changed).
|
|
193
|
+
for (const id of late) {
|
|
194
|
+
for (const o of s.engine.get(id)?.outcomes ?? []) {
|
|
195
|
+
if (o.status !== "accepted" || !o.transaction_id) continue;
|
|
196
|
+
if (rail === "stub") await s.engine.reconcile(id); // the fixture registers the instrument on the first look
|
|
197
|
+
const r = await s.payer!.pay(o.transaction_id, o.attempt_id);
|
|
198
|
+
s.engine.note("sandbox_payer", id, { charge_id: o.transaction_id, ok: r.ok, detail: r.detail });
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
// Section 10: what is still executing is reconciled, never repeated. A rail that answers late needs more than one look.
|
|
202
|
+
for (let round = 0; round < (rail === "api" ? 20 : 3) && s.engine.list({ state: "executing" }).length > 0; round += 1) {
|
|
203
|
+
if (rail === "api" && round > 0) await new Promise((r) => setTimeout(r, s.pollIntervalMs));
|
|
204
|
+
for (const stuck of s.engine.list({ state: "executing" })) await s.engine.reconcile(stuck.id);
|
|
205
|
+
}
|
|
206
|
+
// Whatever closed after the conversation is told to the counterparty once, as the poll or the webhook would.
|
|
207
|
+
if (awaitsPayer) for (const e of s.engine.list()) if (e.run_id === s.runId) announceOutcome(e, s, tell);
|
|
208
|
+
|
|
209
|
+
const events = s.store.listEvents({ run_id: s.runId });
|
|
210
|
+
for (const e of events) {
|
|
211
|
+
if (e.type === "rail.outcome" && (e.payload as { status: string }).status === "accepted" && firstIssued === undefined) firstIssued = new Date(e.at).getTime();
|
|
212
|
+
if (e.type === "execution.transition" && ["settled", "failed"].includes((e.payload as { to: string }).to)) lastClosed = new Date(e.at).getTime();
|
|
213
|
+
if (e.type === "sandbox_payer") payerCalls.push(String((e.payload as { detail: string }).detail));
|
|
214
|
+
}
|
|
215
|
+
const executions = s.engine.list().filter((e) => e.run_id === s.runId);
|
|
216
|
+
return {
|
|
217
|
+
scenario: scenario.name,
|
|
218
|
+
mode: options.mode,
|
|
219
|
+
rail,
|
|
220
|
+
run_id: s.runId,
|
|
221
|
+
bundle_dir: s.bundle.dir,
|
|
222
|
+
replies,
|
|
223
|
+
executions: executions.map((e) => ({
|
|
224
|
+
id: e.id,
|
|
225
|
+
state: e.state,
|
|
226
|
+
reason: e.reason ?? null,
|
|
227
|
+
trigger: e.escalation?.trigger ?? null,
|
|
228
|
+
total: e.total,
|
|
229
|
+
trail: e.history.map((h) => h.to),
|
|
230
|
+
charge_ids: e.outcomes.map((o) => o.transaction_id).filter((x): x is string => typeof x === "string"),
|
|
231
|
+
receipt_ids: e.outcomes.filter((o) => o.receipt_id).map((o) => o.receipt_id as string),
|
|
232
|
+
})),
|
|
233
|
+
refused_before_draft: refusedBeforeDraft,
|
|
234
|
+
receipts: s.bundle.listReceipts().length,
|
|
235
|
+
settled_total: executions.filter((e) => e.state === "settled").reduce((sum, e) => sum + e.total, 0),
|
|
236
|
+
charges_issued: events.filter((e) => e.type === "rail.outcome" && (e.payload as { status: string }).status === "accepted").length,
|
|
237
|
+
debtor_messages: events.filter((e) => e.type === "message.debtor").length,
|
|
238
|
+
cycle_seconds: firstIssued !== undefined && lastClosed !== undefined ? Math.round(((lastClosed - firstIssued) / 1000) * 10) / 10 : 0,
|
|
239
|
+
payer_calls: payerCalls,
|
|
240
|
+
};
|
|
241
|
+
} finally {
|
|
242
|
+
s.close();
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function applyHook(s: Setup, hook: "revoke_mandate" | "pause_all" | undefined): void {
|
|
247
|
+
if (hook === "revoke_mandate") s.gate.revoke(s.mandate.id, "revoked mid-run by the scenario");
|
|
248
|
+
if (hook === "pause_all") s.gate.pauseAll();
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export function checkScenario(scenario: Scenario, run: ScenarioRun): ScenarioCheck {
|
|
252
|
+
const failures: string[] = [];
|
|
253
|
+
const expectations = [scenario.expect["both"], scenario.expect[run.mode]].filter((e): e is z.infer<typeof ExpectSchema> => e !== undefined);
|
|
254
|
+
for (const expect of expectations) {
|
|
255
|
+
if (expect.states && JSON.stringify(run.executions.map((e) => e.state)) !== JSON.stringify(expect.states)) failures.push(`states ${JSON.stringify(run.executions.map((e) => e.state))} != ${JSON.stringify(expect.states)}`);
|
|
256
|
+
if (expect.trails && JSON.stringify(run.executions.map((e) => e.trail)) !== JSON.stringify(expect.trails)) failures.push(`trails ${JSON.stringify(run.executions.map((e) => e.trail))} != ${JSON.stringify(expect.trails)}`);
|
|
257
|
+
if (expect.reasons && JSON.stringify(run.executions.map((e) => e.reason)) !== JSON.stringify(expect.reasons)) failures.push(`reasons ${JSON.stringify(run.executions.map((e) => e.reason))} != ${JSON.stringify(expect.reasons)}`);
|
|
258
|
+
if (expect.triggers && JSON.stringify(run.executions.map((e) => e.trigger)) !== JSON.stringify(expect.triggers)) failures.push(`triggers ${JSON.stringify(run.executions.map((e) => e.trigger))} != ${JSON.stringify(expect.triggers)}`);
|
|
259
|
+
if (expect.receipts !== undefined && run.receipts !== expect.receipts) failures.push(`receipts ${run.receipts} != ${expect.receipts}`);
|
|
260
|
+
if (expect.refused_before_draft !== undefined && run.refused_before_draft !== expect.refused_before_draft) failures.push(`refused_before_draft ${run.refused_before_draft} != ${expect.refused_before_draft}`);
|
|
261
|
+
if (expect.settled_total !== undefined && run.settled_total !== expect.settled_total) failures.push(`settled_total ${run.settled_total} != ${expect.settled_total}`);
|
|
262
|
+
if (expect.charges_issued !== undefined && run.charges_issued !== expect.charges_issued) failures.push(`charges_issued ${run.charges_issued} != ${expect.charges_issued}`);
|
|
263
|
+
if (expect.debtor_messages !== undefined && run.debtor_messages !== expect.debtor_messages) failures.push(`debtor_messages ${run.debtor_messages} != ${expect.debtor_messages}`);
|
|
264
|
+
if (expect.max_cycle_seconds !== undefined && run.rail === "api" && run.cycle_seconds > expect.max_cycle_seconds) failures.push(`cycle_seconds ${run.cycle_seconds} > ${expect.max_cycle_seconds}`);
|
|
265
|
+
}
|
|
266
|
+
// Every run, every mode: nothing reaches executing without an approval artifact carrying its hash.
|
|
267
|
+
return { ok: failures.length === 0, mode: run.mode, failures, run };
|
|
268
|
+
}
|