@paybond/kit 0.9.8 → 0.11.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/completion-presets/catalog.json +1187 -0
- package/completion-presets/catalog.sha256 +1 -0
- package/dev/trace-ui/dashboard.html +617 -0
- package/dist/agent/adapter.d.ts +51 -0
- package/dist/agent/adapter.js +66 -0
- package/dist/agent/attach-bundle.d.ts +37 -0
- package/dist/agent/attach-bundle.js +118 -0
- package/dist/agent/authorization-cache.d.ts +22 -0
- package/dist/agent/authorization-cache.js +36 -0
- package/dist/agent/deferred-tools.d.ts +11 -0
- package/dist/agent/deferred-tools.js +62 -0
- package/dist/agent/discover.d.ts +41 -0
- package/dist/agent/discover.js +147 -0
- package/dist/agent/evidence.d.ts +9 -0
- package/dist/agent/evidence.js +28 -0
- package/dist/agent/facade.d.ts +48 -0
- package/dist/agent/facade.js +112 -0
- package/dist/agent/gateway-trace-reporter.d.ts +28 -0
- package/dist/agent/gateway-trace-reporter.js +49 -0
- package/dist/agent/generic-runner.d.ts +14 -0
- package/dist/agent/generic-runner.js +49 -0
- package/dist/agent/generic-sandbox-demo.d.ts +36 -0
- package/dist/agent/generic-sandbox-demo.js +82 -0
- package/dist/agent/guarded-agent.d.ts +49 -0
- package/dist/agent/guarded-agent.js +100 -0
- package/dist/agent/index.d.ts +13 -0
- package/dist/agent/index.js +13 -0
- package/dist/agent/instrument.d.ts +156 -0
- package/dist/agent/instrument.js +442 -0
- package/dist/agent/interceptor.d.ts +24 -0
- package/dist/agent/interceptor.js +440 -0
- package/dist/agent/lazy-context-tools.d.ts +15 -0
- package/dist/agent/lazy-context-tools.js +81 -0
- package/dist/agent/registry-file.d.ts +39 -0
- package/dist/agent/registry-file.js +219 -0
- package/dist/agent/registry.d.ts +37 -0
- package/dist/agent/registry.js +128 -0
- package/dist/agent/run.d.ts +124 -0
- package/dist/agent/run.js +301 -0
- package/dist/agent/types.d.ts +318 -0
- package/dist/agent/types.js +42 -0
- package/dist/agent-recognition.d.ts +72 -0
- package/dist/agent-recognition.js +165 -0
- package/dist/bincode-wire.d.ts +18 -0
- package/dist/bincode-wire.js +93 -0
- package/dist/claude-agents/config.d.ts +21 -0
- package/dist/claude-agents/config.js +145 -0
- package/dist/claude-agents/index.d.ts +2 -0
- package/dist/claude-agents/index.js +2 -0
- package/dist/claude-agents/sandbox-demo.d.ts +30 -0
- package/dist/claude-agents/sandbox-demo.js +91 -0
- package/dist/cli/agent/env-quote.d.ts +1 -0
- package/dist/cli/agent/env-quote.js +6 -0
- package/dist/cli/agent/env-write.d.ts +8 -0
- package/dist/cli/agent/env-write.js +47 -0
- package/dist/cli/agent/paybond.d.ts +16 -0
- package/dist/cli/agent/paybond.js +55 -0
- package/dist/cli/agent/policy-file.d.ts +29 -0
- package/dist/cli/agent/policy-file.js +61 -0
- package/dist/cli/agent/production-evidence.d.ts +24 -0
- package/dist/cli/agent/production-evidence.js +98 -0
- package/dist/cli/agent/run-store.d.ts +30 -0
- package/dist/cli/agent/run-store.js +42 -0
- package/dist/cli/agent/run-trace-store.d.ts +39 -0
- package/dist/cli/agent/run-trace-store.js +143 -0
- package/dist/cli/agent-run-trace-table.d.ts +9 -0
- package/dist/cli/agent-run-trace-table.js +24 -0
- package/dist/cli/agent-sandbox-smoke-checklist.d.ts +9 -0
- package/dist/cli/agent-sandbox-smoke-checklist.js +50 -0
- package/dist/cli/audit-export.d.ts +7 -0
- package/dist/cli/audit-export.js +120 -0
- package/dist/cli/automation.d.ts +25 -0
- package/dist/cli/automation.js +297 -0
- package/dist/cli/body.d.ts +7 -0
- package/dist/cli/body.js +22 -0
- package/dist/cli/color.d.ts +15 -0
- package/dist/cli/color.js +39 -0
- package/dist/cli/command-spec.d.ts +13 -0
- package/dist/cli/command-spec.js +611 -0
- package/dist/cli/commands/agent.d.ts +16 -0
- package/dist/cli/commands/agent.js +1135 -0
- package/dist/cli/commands/dev.d.ts +7 -0
- package/dist/cli/commands/dev.js +348 -0
- package/dist/cli/commands/discovery.d.ts +8 -0
- package/dist/cli/commands/discovery.js +194 -0
- package/dist/cli/commands/policy.d.ts +13 -0
- package/dist/cli/commands/policy.js +769 -0
- package/dist/cli/commands/setup.d.ts +18 -0
- package/dist/cli/commands/setup.js +513 -0
- package/dist/cli/commands/workflows.d.ts +7 -0
- package/dist/cli/commands/workflows.js +214 -0
- package/dist/cli/config.d.ts +16 -0
- package/dist/cli/config.js +98 -0
- package/dist/cli/context.d.ts +22 -0
- package/dist/cli/context.js +110 -0
- package/dist/cli/credentials.d.ts +21 -0
- package/dist/cli/credentials.js +141 -0
- package/dist/cli/doctor-agent-middleware.d.ts +5 -0
- package/dist/cli/doctor-agent-middleware.js +49 -0
- package/dist/cli/doctor-agent.d.ts +15 -0
- package/dist/cli/doctor-agent.js +311 -0
- package/dist/cli/envelope.d.ts +14 -0
- package/dist/cli/envelope.js +46 -0
- package/dist/cli/globals.d.ts +23 -0
- package/dist/cli/globals.js +248 -0
- package/dist/cli/help.d.ts +3 -0
- package/dist/cli/help.js +83 -0
- package/dist/cli/mcp-install.d.ts +41 -0
- package/dist/cli/mcp-install.js +95 -0
- package/dist/cli/mcp-policy.d.ts +26 -0
- package/dist/cli/mcp-policy.js +110 -0
- package/dist/cli/mcp-verify-config.d.ts +37 -0
- package/dist/cli/mcp-verify-config.js +172 -0
- package/dist/cli/redact.d.ts +4 -0
- package/dist/cli/redact.js +88 -0
- package/dist/cli/request-id.d.ts +2 -0
- package/dist/cli/request-id.js +5 -0
- package/dist/cli/router.d.ts +2 -0
- package/dist/cli/router.js +378 -0
- package/dist/cli/smoke-deep-links.d.ts +15 -0
- package/dist/cli/smoke-deep-links.js +63 -0
- package/dist/cli/suggest.d.ts +4 -0
- package/dist/cli/suggest.js +58 -0
- package/dist/cli/support-diagnostics.d.ts +19 -0
- package/dist/cli/support-diagnostics.js +47 -0
- package/dist/cli/telemetry.d.ts +17 -0
- package/dist/cli/telemetry.js +94 -0
- package/dist/cli/types.d.ts +72 -0
- package/dist/cli/types.js +60 -0
- package/dist/cli/ux.d.ts +8 -0
- package/dist/cli/ux.js +164 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +38 -0
- package/dist/completion-catalog-digest.d.ts +2 -0
- package/dist/completion-catalog-digest.js +2 -0
- package/dist/completion-catalog-integrity.d.ts +2 -0
- package/dist/completion-catalog-integrity.js +17 -0
- package/dist/completion-catalog.d.ts +49 -0
- package/dist/completion-catalog.js +62 -0
- package/dist/completion-contract-digest.d.ts +37 -0
- package/dist/completion-contract-digest.js +73 -0
- package/dist/completion-forbidden-fields.d.ts +5 -0
- package/dist/completion-forbidden-fields.js +26 -0
- package/dist/completion-init.d.ts +8 -0
- package/dist/completion-init.js +334 -0
- package/dist/completion-resolve.d.ts +21 -0
- package/dist/completion-resolve.js +86 -0
- package/dist/completion-validate-evidence.d.ts +24 -0
- package/dist/completion-validate-evidence.js +145 -0
- package/dist/dev/offline-gateway.d.ts +24 -0
- package/dist/dev/offline-gateway.js +102 -0
- package/dist/dev/trace-buffer.d.ts +61 -0
- package/dist/dev/trace-buffer.js +330 -0
- package/dist/dev/trace-security-headers.d.ts +11 -0
- package/dist/dev/trace-security-headers.js +16 -0
- package/dist/dev/trace-server.d.ts +8 -0
- package/dist/dev/trace-server.js +38 -0
- package/dist/dev/trace-ui.d.ts +4 -0
- package/dist/dev/trace-ui.js +25 -0
- package/dist/dev/wiremock-up.d.ts +15 -0
- package/dist/dev/wiremock-up.js +118 -0
- package/dist/doctor-completion.d.ts +17 -0
- package/dist/doctor-completion.js +428 -0
- package/dist/gateway-url.d.ts +7 -0
- package/dist/gateway-url.js +69 -0
- package/dist/index.d.ts +119 -2
- package/dist/index.js +267 -6
- package/dist/init.js +380 -68
- package/dist/langgraph/awrap-tool-call.d.ts +25 -0
- package/dist/langgraph/awrap-tool-call.js +81 -0
- package/dist/langgraph/config.d.ts +13 -0
- package/dist/langgraph/config.js +11 -0
- package/dist/langgraph/index.d.ts +4 -0
- package/dist/langgraph/index.js +4 -0
- package/dist/langgraph/sandbox-demo.d.ts +40 -0
- package/dist/langgraph/sandbox-demo.js +96 -0
- package/dist/langgraph/tool-node.d.ts +10 -0
- package/dist/langgraph/tool-node.js +38 -0
- package/dist/login.d.ts +14 -1
- package/dist/login.js +130 -63
- package/dist/mcp/index.d.ts +1 -0
- package/dist/mcp/index.js +1 -0
- package/dist/mcp/tool-surface.d.ts +25 -0
- package/dist/mcp/tool-surface.js +17 -0
- package/dist/mcp-capability-token-cache.d.ts +24 -0
- package/dist/mcp-capability-token-cache.js +101 -0
- package/dist/mcp-evidence-policy.d.ts +48 -0
- package/dist/mcp-evidence-policy.js +117 -0
- package/dist/mcp-policy-reload.d.ts +79 -0
- package/dist/mcp-policy-reload.js +200 -0
- package/dist/mcp-sep2828-evidence.d.ts +36 -0
- package/dist/mcp-sep2828-evidence.js +65 -0
- package/dist/mcp-server.d.ts +10 -0
- package/dist/mcp-server.js +423 -115
- package/dist/openai-agents/index.d.ts +40 -0
- package/dist/openai-agents/index.js +151 -0
- package/dist/openai-agents/sandbox-demo.d.ts +34 -0
- package/dist/openai-agents/sandbox-demo.js +118 -0
- package/dist/payee-evidence.js +2 -29
- package/dist/policy/catalog.d.ts +31 -0
- package/dist/policy/catalog.js +48 -0
- package/dist/policy/compose-utils.d.ts +3 -0
- package/dist/policy/compose-utils.js +4 -0
- package/dist/policy/compose.d.ts +20 -0
- package/dist/policy/compose.js +240 -0
- package/dist/policy/digest.d.ts +7 -0
- package/dist/policy/digest.js +75 -0
- package/dist/policy/domain.d.ts +15 -0
- package/dist/policy/domain.js +28 -0
- package/dist/policy/guardrail-spec.d.ts +17 -0
- package/dist/policy/guardrail-spec.js +140 -0
- package/dist/policy/guardrails.d.ts +48 -0
- package/dist/policy/guardrails.js +72 -0
- package/dist/policy/index.d.ts +21 -0
- package/dist/policy/index.js +21 -0
- package/dist/policy/init.d.ts +102 -0
- package/dist/policy/init.js +351 -0
- package/dist/policy/intent-spec.d.ts +52 -0
- package/dist/policy/intent-spec.js +176 -0
- package/dist/policy/json-path.d.ts +4 -0
- package/dist/policy/json-path.js +23 -0
- package/dist/policy/layers-io.d.ts +7 -0
- package/dist/policy/layers-io.js +28 -0
- package/dist/policy/load-effective.d.ts +22 -0
- package/dist/policy/load-effective.js +77 -0
- package/dist/policy/load.d.ts +85 -0
- package/dist/policy/load.js +164 -0
- package/dist/policy/merge.d.ts +29 -0
- package/dist/policy/merge.js +297 -0
- package/dist/policy/parse-text.d.ts +2 -0
- package/dist/policy/parse-text.js +126 -0
- package/dist/policy/policy-api.d.ts +45 -0
- package/dist/policy/policy-api.js +61 -0
- package/dist/policy/presets.d.ts +19 -0
- package/dist/policy/presets.js +66 -0
- package/dist/policy/registry.d.ts +7 -0
- package/dist/policy/registry.js +33 -0
- package/dist/policy/reload.d.ts +86 -0
- package/dist/policy/reload.js +233 -0
- package/dist/policy/render-yaml.d.ts +3 -0
- package/dist/policy/render-yaml.js +69 -0
- package/dist/policy/sandbox-bootstrap.d.ts +19 -0
- package/dist/policy/sandbox-bootstrap.js +66 -0
- package/dist/policy/schema.d.ts +204 -0
- package/dist/policy/schema.js +255 -0
- package/dist/policy/snapshot.d.ts +33 -0
- package/dist/policy/snapshot.js +23 -0
- package/dist/policy/validate-remote.d.ts +43 -0
- package/dist/policy/validate-remote.js +104 -0
- package/dist/policy/validate.d.ts +36 -0
- package/dist/policy/validate.js +150 -0
- package/dist/policy/watcher.d.ts +29 -0
- package/dist/policy/watcher.js +112 -0
- package/dist/principal-intent.d.ts +52 -0
- package/dist/principal-intent.js +193 -37
- package/dist/project-init.d.ts +34 -0
- package/dist/project-init.js +898 -0
- package/dist/sep2828-signature.d.ts +10 -0
- package/dist/sep2828-signature.js +134 -0
- package/dist/solutions/api.d.ts +22 -0
- package/dist/solutions/api.js +40 -0
- package/dist/solutions/catalog.d.ts +34 -0
- package/dist/solutions/catalog.js +129 -0
- package/dist/solutions/index.d.ts +2 -0
- package/dist/solutions/index.js +2 -0
- package/dist/template-init.d.ts +54 -0
- package/dist/template-init.js +203 -0
- package/dist/vercel-ai/config.d.ts +15 -0
- package/dist/vercel-ai/config.js +13 -0
- package/dist/vercel-ai/index.d.ts +4 -0
- package/dist/vercel-ai/index.js +4 -0
- package/dist/vercel-ai/sandbox-demo.d.ts +44 -0
- package/dist/vercel-ai/sandbox-demo.js +153 -0
- package/dist/vercel-ai/tool-approval.d.ts +16 -0
- package/dist/vercel-ai/tool-approval.js +41 -0
- package/dist/vercel-ai/wrap-tools.d.ts +9 -0
- package/dist/vercel-ai/wrap-tools.js +40 -0
- package/dist/x402-receipt-evidence.d.ts +29 -0
- package/dist/x402-receipt-evidence.js +97 -0
- package/dist/x402-receipt-signature.d.ts +12 -0
- package/dist/x402-receipt-signature.js +211 -0
- package/package.json +79 -4
- package/solutions/aws.json +17 -0
- package/solutions/saas.json +17 -0
- package/solutions/shopping.json +17 -0
- package/solutions/travel.json +18 -0
- package/templates/manifest.json +169 -0
- package/templates/openai-shopping-agent/.env.example +3 -0
- package/templates/openai-shopping-agent/.github/workflows/smoke.yml +20 -0
- package/templates/openai-shopping-agent/LICENSE +201 -0
- package/templates/openai-shopping-agent/README.md +29 -0
- package/templates/openai-shopping-agent/package.json +22 -0
- package/templates/openai-shopping-agent/paybond.policy.yaml +22 -0
- package/templates/openai-shopping-agent/src/index.ts +22 -0
- package/templates/openai-shopping-agent/src/paybond.config.ts +51 -0
- package/templates/openai-shopping-agent/tsconfig.json +13 -0
- package/templates/paybond-aws-operator/.env.example +3 -0
- package/templates/paybond-aws-operator/.github/workflows/smoke.yml +20 -0
- package/templates/paybond-aws-operator/LICENSE +201 -0
- package/templates/paybond-aws-operator/README.md +29 -0
- package/templates/paybond-aws-operator/package.json +20 -0
- package/templates/paybond-aws-operator/paybond.policy.yaml +22 -0
- package/templates/paybond-aws-operator/src/index.ts +54 -0
- package/templates/paybond-aws-operator/src/paybond.config.ts +51 -0
- package/templates/paybond-aws-operator/tsconfig.json +13 -0
- package/templates/paybond-claude-agents-demo/.env.example +3 -0
- package/templates/paybond-claude-agents-demo/.github/workflows/smoke.yml +20 -0
- package/templates/paybond-claude-agents-demo/LICENSE +201 -0
- package/templates/paybond-claude-agents-demo/README.md +29 -0
- package/templates/paybond-claude-agents-demo/package.json +22 -0
- package/templates/paybond-claude-agents-demo/paybond.policy.yaml +22 -0
- package/templates/paybond-claude-agents-demo/src/index.ts +22 -0
- package/templates/paybond-claude-agents-demo/src/paybond.config.ts +51 -0
- package/templates/paybond-claude-agents-demo/tsconfig.json +13 -0
- package/templates/paybond-invoice-agent/.env.example +3 -0
- package/templates/paybond-invoice-agent/.github/workflows/smoke.yml +19 -0
- package/templates/paybond-invoice-agent/LICENSE +201 -0
- package/templates/paybond-invoice-agent/README.md +29 -0
- package/templates/paybond-invoice-agent/app.py +27 -0
- package/templates/paybond-invoice-agent/package.json +6 -0
- package/templates/paybond-invoice-agent/paybond.policy.yaml +22 -0
- package/templates/paybond-invoice-agent/paybond_config.py +45 -0
- package/templates/paybond-invoice-agent/requirements.txt +2 -0
- package/templates/paybond-mcp-coding-agent/.env.example +3 -0
- package/templates/paybond-mcp-coding-agent/.github/workflows/smoke.yml +20 -0
- package/templates/paybond-mcp-coding-agent/LICENSE +201 -0
- package/templates/paybond-mcp-coding-agent/README.md +39 -0
- package/templates/paybond-mcp-coding-agent/package.json +20 -0
- package/templates/paybond-mcp-coding-agent/paybond.policy.yaml +25 -0
- package/templates/paybond-mcp-coding-agent/src/index.ts +40 -0
- package/templates/paybond-mcp-coding-agent/src/paybond.config.ts +51 -0
- package/templates/paybond-mcp-coding-agent/tsconfig.json +13 -0
- package/templates/paybond-openai-agents-demo/.env.example +3 -0
- package/templates/paybond-openai-agents-demo/.github/workflows/smoke.yml +20 -0
- package/templates/paybond-openai-agents-demo/LICENSE +201 -0
- package/templates/paybond-openai-agents-demo/README.md +29 -0
- package/templates/paybond-openai-agents-demo/package.json +22 -0
- package/templates/paybond-openai-agents-demo/paybond.policy.yaml +22 -0
- package/templates/paybond-openai-agents-demo/src/index.ts +22 -0
- package/templates/paybond-openai-agents-demo/src/paybond.config.ts +51 -0
- package/templates/paybond-openai-agents-demo/tsconfig.json +13 -0
- package/templates/paybond-procurement-agent/.env.example +3 -0
- package/templates/paybond-procurement-agent/.github/workflows/smoke.yml +20 -0
- package/templates/paybond-procurement-agent/LICENSE +201 -0
- package/templates/paybond-procurement-agent/README.md +29 -0
- package/templates/paybond-procurement-agent/package.json +20 -0
- package/templates/paybond-procurement-agent/paybond.policy.yaml +25 -0
- package/templates/paybond-procurement-agent/src/index.ts +54 -0
- package/templates/paybond-procurement-agent/src/paybond.config.ts +51 -0
- package/templates/paybond-procurement-agent/tsconfig.json +13 -0
- package/templates/paybond-travel-agent/.env.example +3 -0
- package/templates/paybond-travel-agent/.github/workflows/smoke.yml +20 -0
- package/templates/paybond-travel-agent/LICENSE +201 -0
- package/templates/paybond-travel-agent/README.md +29 -0
- package/templates/paybond-travel-agent/package.json +23 -0
- package/templates/paybond-travel-agent/paybond.policy.yaml +22 -0
- package/templates/paybond-travel-agent/src/index.ts +22 -0
- package/templates/paybond-travel-agent/src/paybond.config.ts +51 -0
- package/templates/paybond-travel-agent/tsconfig.json +13 -0
- package/templates/paybond-vercel-shopping-agent/.env.example +3 -0
- package/templates/paybond-vercel-shopping-agent/.github/workflows/smoke.yml +20 -0
- package/templates/paybond-vercel-shopping-agent/LICENSE +201 -0
- package/templates/paybond-vercel-shopping-agent/README.md +29 -0
- package/templates/paybond-vercel-shopping-agent/package.json +22 -0
- package/templates/paybond-vercel-shopping-agent/paybond.policy.yaml +22 -0
- package/templates/paybond-vercel-shopping-agent/src/index.ts +22 -0
- package/templates/paybond-vercel-shopping-agent/src/paybond.config.ts +51 -0
- package/templates/paybond-vercel-shopping-agent/tsconfig.json +13 -0
package/dist/init.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
5
|
+
import { runCli } from "./cli/router.js";
|
|
6
|
+
import { getCompletionPreset, jsonLiteral } from "./completion-catalog.js";
|
|
2
7
|
const FRAMEWORKS = new Set([
|
|
3
8
|
"generic",
|
|
4
9
|
"provider-agnostic",
|
|
@@ -11,7 +16,21 @@ const FRAMEWORKS = new Set([
|
|
|
11
16
|
"langgraph",
|
|
12
17
|
"mcp",
|
|
13
18
|
]);
|
|
14
|
-
const
|
|
19
|
+
const AGENT_MIDDLEWARE_FRAMEWORKS = new Set([
|
|
20
|
+
"generic",
|
|
21
|
+
"claude-agents",
|
|
22
|
+
"openai",
|
|
23
|
+
"langgraph",
|
|
24
|
+
"vercel-ai",
|
|
25
|
+
]);
|
|
26
|
+
const AGENT_MIDDLEWARE_FRAMEWORK_ALIASES = {
|
|
27
|
+
"provider-agnostic": "generic",
|
|
28
|
+
};
|
|
29
|
+
const PRESETS = new Set(["paid-tool-guard", "agent-middleware"]);
|
|
30
|
+
const PRESET_DEFAULT_OUT = {
|
|
31
|
+
"paid-tool-guard": "paybond-paid-tool-guard.ts",
|
|
32
|
+
"agent-middleware": "paybond-agent-middleware.ts",
|
|
33
|
+
};
|
|
15
34
|
const FRAMEWORK_NOTES = {
|
|
16
35
|
generic: "Wrap the returned function around any side-effecting tool handler.",
|
|
17
36
|
"provider-agnostic": "Use the guarded handler with OpenAI, Gemini, Claude/Anthropic, local models, or any custom runtime.",
|
|
@@ -26,15 +45,41 @@ const FRAMEWORK_NOTES = {
|
|
|
26
45
|
};
|
|
27
46
|
function usage() {
|
|
28
47
|
return [
|
|
29
|
-
"Usage: paybond-init [--preset paid-tool-guard] [--framework
|
|
48
|
+
"Usage: paybond-init [--preset paid-tool-guard|agent-middleware] [--framework <name>] [--out <path>] [--force]",
|
|
49
|
+
"",
|
|
50
|
+
"Presets:",
|
|
51
|
+
" paid-tool-guard Per-tool guardTool helper (default)",
|
|
52
|
+
" agent-middleware PaybondAgentRun + tool registry middleware",
|
|
30
53
|
"",
|
|
31
|
-
"
|
|
54
|
+
"Frameworks (paid-tool-guard): generic|provider-agnostic|openai|claude|anthropic|gemini|google-ai|vercel-ai|langgraph|mcp",
|
|
55
|
+
"Frameworks (agent-middleware): generic|claude-agents|openai|langgraph|vercel-ai",
|
|
32
56
|
].join("\n");
|
|
33
57
|
}
|
|
58
|
+
function normalizeAgentMiddlewareFramework(framework) {
|
|
59
|
+
const alias = AGENT_MIDDLEWARE_FRAMEWORK_ALIASES[framework];
|
|
60
|
+
if (alias) {
|
|
61
|
+
return alias;
|
|
62
|
+
}
|
|
63
|
+
if (!AGENT_MIDDLEWARE_FRAMEWORKS.has(framework)) {
|
|
64
|
+
throw new Error("invalid --framework for agent-middleware preset");
|
|
65
|
+
}
|
|
66
|
+
return framework;
|
|
67
|
+
}
|
|
68
|
+
function validateFrameworkForPreset(preset, framework) {
|
|
69
|
+
if (preset === "agent-middleware") {
|
|
70
|
+
normalizeAgentMiddlewareFramework(framework);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (!FRAMEWORKS.has(framework)) {
|
|
74
|
+
throw new Error("invalid --framework");
|
|
75
|
+
}
|
|
76
|
+
}
|
|
34
77
|
function parseArgs(argv) {
|
|
35
78
|
let preset = "paid-tool-guard";
|
|
36
79
|
let framework = "provider-agnostic";
|
|
37
|
-
let
|
|
80
|
+
let frameworkExplicit = false;
|
|
81
|
+
let out = PRESET_DEFAULT_OUT["paid-tool-guard"];
|
|
82
|
+
let outExplicit = false;
|
|
38
83
|
let force = false;
|
|
39
84
|
for (let i = 0; i < argv.length; i += 1) {
|
|
40
85
|
const arg = argv[i];
|
|
@@ -54,15 +99,19 @@ function parseArgs(argv) {
|
|
|
54
99
|
throw new Error("invalid --preset");
|
|
55
100
|
}
|
|
56
101
|
preset = raw;
|
|
102
|
+
if (!outExplicit) {
|
|
103
|
+
out = PRESET_DEFAULT_OUT[preset];
|
|
104
|
+
}
|
|
57
105
|
continue;
|
|
58
106
|
}
|
|
59
107
|
if (arg === "--framework") {
|
|
60
108
|
const raw = argv[i + 1];
|
|
61
109
|
i += 1;
|
|
62
|
-
if (!raw
|
|
110
|
+
if (!raw) {
|
|
63
111
|
throw new Error("invalid --framework");
|
|
64
112
|
}
|
|
65
113
|
framework = raw;
|
|
114
|
+
frameworkExplicit = true;
|
|
66
115
|
continue;
|
|
67
116
|
}
|
|
68
117
|
if (arg === "--out") {
|
|
@@ -72,55 +121,22 @@ function parseArgs(argv) {
|
|
|
72
121
|
throw new Error("invalid --out");
|
|
73
122
|
}
|
|
74
123
|
out = raw;
|
|
124
|
+
outExplicit = true;
|
|
75
125
|
continue;
|
|
76
126
|
}
|
|
77
127
|
throw new Error(`unknown argument: ${arg}`);
|
|
78
128
|
}
|
|
129
|
+
if (preset === "agent-middleware" && !frameworkExplicit) {
|
|
130
|
+
framework = "generic";
|
|
131
|
+
}
|
|
132
|
+
validateFrameworkForPreset(preset, framework);
|
|
79
133
|
return { preset, framework, out, force };
|
|
80
134
|
}
|
|
81
|
-
function
|
|
82
|
-
return `
|
|
83
|
-
Paybond,
|
|
84
|
-
type SandboxGuardrailBootstrapResult,
|
|
85
|
-
type SandboxGuardrailEvidenceResult,
|
|
86
|
-
} from "@paybond/kit";
|
|
87
|
-
|
|
88
|
-
declare const process: {
|
|
135
|
+
function envHelpersBlock() {
|
|
136
|
+
return `declare const process: {
|
|
89
137
|
env: Record<string, string | undefined>;
|
|
90
138
|
};
|
|
91
139
|
|
|
92
|
-
// Production integration helpers only. Add your paid-tool handler in
|
|
93
|
-
// application code and pass it to wrapPaidTool(...).
|
|
94
|
-
const DEFAULT_OPERATION = "paid_tool.operation";
|
|
95
|
-
const DEFAULT_REQUESTED_SPEND_CENTS = 500;
|
|
96
|
-
|
|
97
|
-
export type PaidToolHandler<TInput, TResult> = (input: TInput) => TResult | Promise<TResult>;
|
|
98
|
-
|
|
99
|
-
export type SandboxGuardrailIntentOptions = {
|
|
100
|
-
operation?: string;
|
|
101
|
-
requestedSpendCents?: number;
|
|
102
|
-
currency?: string;
|
|
103
|
-
evidenceSchema?: Record<string, unknown>;
|
|
104
|
-
metadata?: Record<string, unknown>;
|
|
105
|
-
idempotencyKey?: string;
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
export type SubmitSandboxEvidenceOptions = {
|
|
109
|
-
operation?: string;
|
|
110
|
-
requestedSpendCents?: number;
|
|
111
|
-
metadata?: Record<string, unknown>;
|
|
112
|
-
artifacts?: string[];
|
|
113
|
-
idempotencyKey?: string;
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
export type OpenPaybondFromEnvOptions = {
|
|
117
|
-
/**
|
|
118
|
-
* Load PAYBOND_API_KEY from this local env file when the process environment
|
|
119
|
-
* does not already provide it. Pass false when your agent host injects secrets.
|
|
120
|
-
*/
|
|
121
|
-
envFile?: string | false;
|
|
122
|
-
};
|
|
123
|
-
|
|
124
140
|
function readEnvValue(body: string, key: string): string | undefined {
|
|
125
141
|
const pattern = new RegExp("^\\\\s*(?:export\\\\s+)?" + key + "\\\\s*=\\\\s*(.*)$", "m");
|
|
126
142
|
const match = body.match(pattern);
|
|
@@ -139,8 +155,6 @@ function readEnvValue(body: string, key: string): string | undefined {
|
|
|
139
155
|
}
|
|
140
156
|
|
|
141
157
|
async function readTextFile(envFile: string): Promise<string | undefined> {
|
|
142
|
-
// @ts-ignore Node builtins are available in agent and CLI Node runtimes.
|
|
143
|
-
const fs: { readFile(path: string, encoding: "utf8"): Promise<string> } = await import("node:fs/promises");
|
|
144
158
|
try {
|
|
145
159
|
return await fs.readFile(envFile, "utf8");
|
|
146
160
|
} catch (err) {
|
|
@@ -159,6 +173,14 @@ export async function loadPaybondEnvFile(envFile = ".env.local"): Promise<void>
|
|
|
159
173
|
}
|
|
160
174
|
}
|
|
161
175
|
|
|
176
|
+
export type OpenPaybondFromEnvOptions = {
|
|
177
|
+
/**
|
|
178
|
+
* Load PAYBOND_API_KEY from this local env file when the process environment
|
|
179
|
+
* does not already provide it. Pass false when your agent host injects secrets.
|
|
180
|
+
*/
|
|
181
|
+
envFile?: string | false;
|
|
182
|
+
};
|
|
183
|
+
|
|
162
184
|
export async function openPaybondFromEnv(options: OpenPaybondFromEnvOptions = {}): Promise<Paybond> {
|
|
163
185
|
if (options.envFile !== false) {
|
|
164
186
|
await loadPaybondEnvFile(options.envFile ?? ".env.local");
|
|
@@ -173,8 +195,293 @@ export async function openPaybondFromEnv(options: OpenPaybondFromEnvOptions = {}
|
|
|
173
195
|
gatewayBaseUrl: process.env.PAYBOND_GATEWAY_URL ?? process.env.PAYBOND_GATEWAY_BASE_URL,
|
|
174
196
|
expectedEnvironment: "sandbox",
|
|
175
197
|
});
|
|
198
|
+
}`;
|
|
199
|
+
}
|
|
200
|
+
function agentMiddlewareFrameworkBlock(framework) {
|
|
201
|
+
switch (framework) {
|
|
202
|
+
case "claude-agents":
|
|
203
|
+
return `import { tool } from "@anthropic-ai/claude-agent-sdk";
|
|
204
|
+
import { z } from "zod";
|
|
205
|
+
import {
|
|
206
|
+
createGuardedAgent,
|
|
207
|
+
createGuardedAgentRunner,
|
|
208
|
+
type CreateGuardedAgentResult,
|
|
209
|
+
} from "@paybond/kit/agent";
|
|
210
|
+
|
|
211
|
+
const TRAVEL_AGENT_POLICY = {
|
|
212
|
+
version: 1,
|
|
213
|
+
name: "travel-agent-v1",
|
|
214
|
+
default_deny: true,
|
|
215
|
+
tools: {
|
|
216
|
+
"travel.book_hotel": {
|
|
217
|
+
side_effecting: true,
|
|
218
|
+
max_spend_cents: DEFAULT_REQUESTED_SPEND_CENTS,
|
|
219
|
+
evidence_preset: COMPLETION_PRESET_ID,
|
|
220
|
+
},
|
|
221
|
+
"search.web": {
|
|
222
|
+
side_effecting: false,
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
intent: {
|
|
226
|
+
allowed_tools: ["travel.book_hotel"],
|
|
227
|
+
budget: { currency: "usd", max_spend_usd: 200 },
|
|
228
|
+
},
|
|
229
|
+
} as const;
|
|
230
|
+
|
|
231
|
+
/** Policy-driven Claude Agent SDK wiring: bind run, wrap \`tool()\` handlers, expose MCP server config. */
|
|
232
|
+
export async function createClaudeAgentsGuardedRunner(
|
|
233
|
+
paybond: Paybond,
|
|
234
|
+
): Promise<CreateGuardedAgentResult> {
|
|
235
|
+
const sdkTools = [
|
|
236
|
+
tool(
|
|
237
|
+
"travel.book_hotel",
|
|
238
|
+
"Book a hotel room",
|
|
239
|
+
{ city: z.string(), estimatedPriceCents: z.number().int().nonnegative() },
|
|
240
|
+
async (args) => ({
|
|
241
|
+
content: [{ type: "text" as const, text: JSON.stringify(await bookHotel(args)) }],
|
|
242
|
+
structuredContent: await bookHotel(args),
|
|
243
|
+
}),
|
|
244
|
+
),
|
|
245
|
+
];
|
|
246
|
+
return createGuardedAgent(paybond, {
|
|
247
|
+
policy: TRAVEL_AGENT_POLICY,
|
|
248
|
+
framework: "claude-agents",
|
|
249
|
+
tools: sdkTools,
|
|
250
|
+
bootstrap: {
|
|
251
|
+
operation: DEFAULT_OPERATION,
|
|
252
|
+
requestedSpendCents: DEFAULT_REQUESTED_SPEND_CENTS,
|
|
253
|
+
completionPreset: COMPLETION_PRESET_ID,
|
|
254
|
+
},
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/** Alias matching {@link createGuardedAgentRunner} naming. */
|
|
259
|
+
export const createClaudeAgentsGuardedAgentRunner = createClaudeAgentsGuardedRunner;
|
|
260
|
+
|
|
261
|
+
export { createGuardedAgentRunner };`;
|
|
262
|
+
case "openai":
|
|
263
|
+
return `import { createOpenAIAgentsAdapter } from "@paybond/kit/openai-agents";
|
|
264
|
+
import type { FunctionTool } from "@openai/agents";
|
|
265
|
+
|
|
266
|
+
/** Wrap OpenAI Agents SDK function tools with Paybond middleware (verify → execute → auto-evidence). */
|
|
267
|
+
export function wrapOpenAIAgentTools<TContext>(
|
|
268
|
+
run: PaybondAgentRun,
|
|
269
|
+
tools: Array<FunctionTool<TContext>>,
|
|
270
|
+
): Array<FunctionTool<TContext>> {
|
|
271
|
+
return createOpenAIAgentsAdapter(run).guardFunctionTools(tools);
|
|
272
|
+
}`;
|
|
273
|
+
case "langgraph":
|
|
274
|
+
return `import { paybondAwrapToolCall, paybondToolNode } from "@paybond/kit/langgraph";
|
|
275
|
+
import type { PaybondAgentRun } from "@paybond/kit/agent";
|
|
276
|
+
|
|
277
|
+
/** LangGraph ToolNode hook — use with \`paybondToolNode(tools, run)\` or \`new ToolNode(tools, { awrapToolCall })\` when supported. */
|
|
278
|
+
export function createLangGraphToolCallWrapper(run: PaybondAgentRun) {
|
|
279
|
+
return paybondAwrapToolCall(run);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/** Convenience factory around LangGraph \`ToolNode\` with Paybond interceptor wiring. */
|
|
283
|
+
export function createPaybondLangGraphToolNode(
|
|
284
|
+
run: PaybondAgentRun,
|
|
285
|
+
tools: Parameters<typeof paybondToolNode>[0],
|
|
286
|
+
) {
|
|
287
|
+
return paybondToolNode(tools, run);
|
|
288
|
+
}`;
|
|
289
|
+
case "vercel-ai":
|
|
290
|
+
return `import { generateText, tool } from "ai";
|
|
291
|
+
import { z } from "zod";
|
|
292
|
+
import {
|
|
293
|
+
paybondVercelToolApproval,
|
|
294
|
+
paybondVercelWrapTools,
|
|
295
|
+
} from "@paybond/kit/vercel-ai";
|
|
296
|
+
|
|
297
|
+
export function createGuardedVercelTools(run: PaybondAgentRun) {
|
|
298
|
+
const tools = {
|
|
299
|
+
bookHotel: tool({
|
|
300
|
+
description: "Book a hotel room",
|
|
301
|
+
inputSchema: z.object({
|
|
302
|
+
city: z.string(),
|
|
303
|
+
estimatedPriceCents: z.number().int().nonnegative(),
|
|
304
|
+
}),
|
|
305
|
+
execute: async (args) => bookHotel(args),
|
|
306
|
+
}),
|
|
307
|
+
searchWeb: tool({
|
|
308
|
+
description: "Search the web",
|
|
309
|
+
inputSchema: z.object({ query: z.string() }),
|
|
310
|
+
execute: async (args) => searchWeb(args),
|
|
311
|
+
}),
|
|
312
|
+
};
|
|
313
|
+
return paybondVercelWrapTools(run, tools);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/** Example \`generateText\` wiring with Paybond \`toolApproval\` + wrapped tools. */
|
|
317
|
+
export async function runGuardedGenerateText(
|
|
318
|
+
run: PaybondAgentRun,
|
|
319
|
+
model: Parameters<typeof generateText>[0]["model"],
|
|
320
|
+
prompt: string,
|
|
321
|
+
) {
|
|
322
|
+
const tools = createGuardedVercelTools(run);
|
|
323
|
+
return generateText({
|
|
324
|
+
model,
|
|
325
|
+
tools,
|
|
326
|
+
toolApproval: paybondVercelToolApproval(run),
|
|
327
|
+
prompt,
|
|
328
|
+
});
|
|
329
|
+
}`;
|
|
330
|
+
default:
|
|
331
|
+
return `import { createPaybondGenericAgentConfig } from "@paybond/kit/agent";
|
|
332
|
+
|
|
333
|
+
/** Recommended default when the agent framework is unknown. */
|
|
334
|
+
export function createGenericAgentConfig(
|
|
335
|
+
run: PaybondAgentRun,
|
|
336
|
+
tools: Array<{ name: string; execute: (args: unknown) => unknown | Promise<unknown> }>,
|
|
337
|
+
) {
|
|
338
|
+
return createPaybondGenericAgentConfig(run, tools);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/** Wrap \`{ name, execute }\` tools for any agent-agnostic runtime. */
|
|
342
|
+
export function wrapAgentTools(
|
|
343
|
+
run: PaybondAgentRun,
|
|
344
|
+
tools: Array<{ name: string; execute: (args: unknown) => unknown | Promise<unknown> }>,
|
|
345
|
+
) {
|
|
346
|
+
return createGenericAgentConfig(run, tools).tools;
|
|
347
|
+
}`;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
function agentMiddlewareTemplate(framework) {
|
|
351
|
+
const completionPreset = getCompletionPreset("cost_and_completion");
|
|
352
|
+
const evidenceSchema = jsonLiteral(completionPreset.evidence_schema, 2);
|
|
353
|
+
return `import fs from "node:fs/promises";
|
|
354
|
+
import { Paybond } from "@paybond/kit";
|
|
355
|
+
import {
|
|
356
|
+
createPaybondToolRegistry,
|
|
357
|
+
type PaybondAgentRun,
|
|
358
|
+
type PaybondAgentRunBindInput,
|
|
359
|
+
} from "@paybond/kit/agent";
|
|
360
|
+
|
|
361
|
+
${envHelpersBlock()}
|
|
362
|
+
|
|
363
|
+
// Agent middleware preset maps to completion catalog archetype: cost_and_completion (${completionPreset.harbor_template_id}).
|
|
364
|
+
const COMPLETION_PRESET_ID = "cost_and_completion";
|
|
365
|
+
const DEFAULT_OPERATION = "travel.book_hotel";
|
|
366
|
+
const DEFAULT_REQUESTED_SPEND_CENTS = 20_000;
|
|
367
|
+
|
|
368
|
+
export type BookHotelArgs = {
|
|
369
|
+
city: string;
|
|
370
|
+
estimatedPriceCents: number;
|
|
371
|
+
};
|
|
372
|
+
|
|
373
|
+
export async function bookHotel(args: BookHotelArgs) {
|
|
374
|
+
return {
|
|
375
|
+
reservation: {
|
|
376
|
+
status: "confirmed" as const,
|
|
377
|
+
price_cents: args.estimatedPriceCents,
|
|
378
|
+
city: args.city,
|
|
379
|
+
},
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
export async function searchWeb(args: { query: string }) {
|
|
384
|
+
return { hits: [{ title: args.query, url: "https://example.com" }] };
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
export function createAgentToolRegistry() {
|
|
388
|
+
return createPaybondToolRegistry({
|
|
389
|
+
sideEffecting: {
|
|
390
|
+
"travel.book_hotel": {
|
|
391
|
+
spendCents: (args: BookHotelArgs) => args.estimatedPriceCents,
|
|
392
|
+
evidencePreset: COMPLETION_PRESET_ID,
|
|
393
|
+
evidenceMapper: (result: Awaited<ReturnType<typeof bookHotel>>) => ({
|
|
394
|
+
status: result.reservation.status === "confirmed" ? "completed" : result.reservation.status,
|
|
395
|
+
cost_cents: result.reservation.price_cents,
|
|
396
|
+
}),
|
|
397
|
+
},
|
|
398
|
+
},
|
|
399
|
+
defaultDeny: true,
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
export type BindAgentRunOptions = {
|
|
404
|
+
operation?: string;
|
|
405
|
+
requestedSpendCents?: number;
|
|
406
|
+
evidenceSchema?: Record<string, unknown>;
|
|
407
|
+
runId?: string;
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
export async function bindAgentRun(
|
|
411
|
+
paybond: Paybond,
|
|
412
|
+
registry: ReturnType<typeof createAgentToolRegistry>,
|
|
413
|
+
options: BindAgentRunOptions = {},
|
|
414
|
+
): Promise<PaybondAgentRun> {
|
|
415
|
+
const bindInput: PaybondAgentRunBindInput = {
|
|
416
|
+
bootstrap: {
|
|
417
|
+
kind: "sandbox",
|
|
418
|
+
operation: options.operation ?? DEFAULT_OPERATION,
|
|
419
|
+
requestedSpendCents: options.requestedSpendCents ?? DEFAULT_REQUESTED_SPEND_CENTS,
|
|
420
|
+
completionPreset: COMPLETION_PRESET_ID,
|
|
421
|
+
evidenceSchema: options.evidenceSchema ?? ${evidenceSchema},
|
|
422
|
+
},
|
|
423
|
+
registry,
|
|
424
|
+
runId: options.runId,
|
|
425
|
+
};
|
|
426
|
+
return paybond.agentRun.bind(bindInput);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
${agentMiddlewareFrameworkBlock(framework)}
|
|
430
|
+
`;
|
|
431
|
+
}
|
|
432
|
+
function paidToolGuardTemplate(framework) {
|
|
433
|
+
const completionPreset = getCompletionPreset("cost_and_completion");
|
|
434
|
+
const evidenceSchema = jsonLiteral(completionPreset.evidence_schema, 2);
|
|
435
|
+
return `import fs from "node:fs/promises";
|
|
436
|
+
import {
|
|
437
|
+
Paybond,
|
|
438
|
+
type SandboxGuardrailBootstrapResult,
|
|
439
|
+
type SandboxGuardrailEvidenceResult,
|
|
440
|
+
} from "@paybond/kit";
|
|
441
|
+
|
|
442
|
+
${envHelpersBlock()}
|
|
443
|
+
|
|
444
|
+
// Paid-tool guardrail preset maps to completion catalog archetype: cost_and_completion (${completionPreset.harbor_template_id}).
|
|
445
|
+
const COMPLETION_PRESET_ID = "cost_and_completion";
|
|
446
|
+
const HARBOR_TEMPLATE_ID = "${completionPreset.harbor_template_id}";
|
|
447
|
+
|
|
448
|
+
export type CompletionEvidence = {
|
|
449
|
+
status: string;
|
|
450
|
+
cost_cents: number;
|
|
451
|
+
};
|
|
452
|
+
|
|
453
|
+
export function buildCompletionEvidence(fields: CompletionEvidence): Record<string, unknown> {
|
|
454
|
+
return { ...fields };
|
|
176
455
|
}
|
|
177
456
|
|
|
457
|
+
// Production: use buildSignedCreateIntentBodyWithPolicyBinding from @paybond/kit after publishing ${completionPreset.harbor_template_id}.
|
|
458
|
+
export const policyBindingStub = {
|
|
459
|
+
template_id: HARBOR_TEMPLATE_ID,
|
|
460
|
+
parameters: ${jsonLiteral(completionPreset.parameters, 2)} as const,
|
|
461
|
+
};
|
|
462
|
+
|
|
463
|
+
const DEFAULT_OPERATION = "paid_tool.operation";
|
|
464
|
+
const DEFAULT_REQUESTED_SPEND_CENTS = 500;
|
|
465
|
+
|
|
466
|
+
export type PaidToolHandler<TInput, TResult> = (input: TInput) => TResult | Promise<TResult>;
|
|
467
|
+
|
|
468
|
+
export type SandboxGuardrailIntentOptions = {
|
|
469
|
+
operation?: string;
|
|
470
|
+
requestedSpendCents?: number;
|
|
471
|
+
currency?: string;
|
|
472
|
+
evidenceSchema?: Record<string, unknown>;
|
|
473
|
+
metadata?: Record<string, unknown>;
|
|
474
|
+
idempotencyKey?: string;
|
|
475
|
+
};
|
|
476
|
+
|
|
477
|
+
export type SubmitSandboxEvidenceOptions = {
|
|
478
|
+
operation?: string;
|
|
479
|
+
requestedSpendCents?: number;
|
|
480
|
+
metadata?: Record<string, unknown>;
|
|
481
|
+
artifacts?: string[];
|
|
482
|
+
idempotencyKey?: string;
|
|
483
|
+
};
|
|
484
|
+
|
|
178
485
|
export async function bootstrapSandboxGuardrailIntent(
|
|
179
486
|
paybond: Paybond,
|
|
180
487
|
options: SandboxGuardrailIntentOptions = {},
|
|
@@ -183,14 +490,8 @@ export async function bootstrapSandboxGuardrailIntent(
|
|
|
183
490
|
operation: options.operation ?? DEFAULT_OPERATION,
|
|
184
491
|
requestedSpendCents: options.requestedSpendCents ?? DEFAULT_REQUESTED_SPEND_CENTS,
|
|
185
492
|
currency: options.currency ?? "usd",
|
|
186
|
-
evidenceSchema: options.evidenceSchema ?? {
|
|
187
|
-
|
|
188
|
-
required: ["confirmation_id", "charged_cents"],
|
|
189
|
-
properties: {
|
|
190
|
-
confirmation_id: { type: "string" },
|
|
191
|
-
charged_cents: { type: "integer" },
|
|
192
|
-
},
|
|
193
|
-
},
|
|
493
|
+
evidenceSchema: options.evidenceSchema ?? ${evidenceSchema},
|
|
494
|
+
completionPreset: COMPLETION_PRESET_ID,
|
|
194
495
|
metadata: options.metadata,
|
|
195
496
|
idempotencyKey: options.idempotencyKey,
|
|
196
497
|
});
|
|
@@ -236,11 +537,20 @@ export async function submitSandboxEvidence(
|
|
|
236
537
|
idempotencyKey: options.idempotencyKey,
|
|
237
538
|
});
|
|
238
539
|
}
|
|
540
|
+
|
|
541
|
+
// Prefer buildCompletionEvidence({ status: "completed", cost_cents }) for catalog-aligned evidence.
|
|
239
542
|
`;
|
|
240
543
|
}
|
|
544
|
+
function scaffoldBody(preset, framework) {
|
|
545
|
+
if (preset === "agent-middleware") {
|
|
546
|
+
return agentMiddlewareTemplate(normalizeAgentMiddlewareFramework(framework));
|
|
547
|
+
}
|
|
548
|
+
return paidToolGuardTemplate(framework);
|
|
549
|
+
}
|
|
550
|
+
function scaffoldLabel(preset) {
|
|
551
|
+
return preset === "agent-middleware" ? "agent middleware integration" : "guardrail integration";
|
|
552
|
+
}
|
|
241
553
|
async function writeScaffold(out, body, force) {
|
|
242
|
-
// @ts-expect-error Node builtins are available in the published CLI runtime.
|
|
243
|
-
const fs = await import("node:fs/promises");
|
|
244
554
|
try {
|
|
245
555
|
await fs.stat(out);
|
|
246
556
|
if (!force) {
|
|
@@ -269,13 +579,13 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
269
579
|
return 0;
|
|
270
580
|
}
|
|
271
581
|
try {
|
|
272
|
-
await writeScaffold(parsed.out,
|
|
582
|
+
await writeScaffold(parsed.out, scaffoldBody(parsed.preset, parsed.framework), parsed.force);
|
|
273
583
|
}
|
|
274
584
|
catch (err) {
|
|
275
585
|
process.stderr.write(`${err instanceof Error ? err.message : String(err)}\n`);
|
|
276
586
|
return 1;
|
|
277
587
|
}
|
|
278
|
-
process.stdout.write(`Created Paybond
|
|
588
|
+
process.stdout.write(`Created Paybond ${scaffoldLabel(parsed.preset)}: ${parsed.out}\n`);
|
|
279
589
|
return 0;
|
|
280
590
|
}
|
|
281
591
|
function normalizeFileURL(url) {
|
|
@@ -286,12 +596,6 @@ async function invokedFromCLI() {
|
|
|
286
596
|
if (!scriptPath) {
|
|
287
597
|
return false;
|
|
288
598
|
}
|
|
289
|
-
// @ts-ignore Node builtins are available in the published CLI runtime.
|
|
290
|
-
const fs = (await import("node:fs/promises"));
|
|
291
|
-
// @ts-ignore Node builtins are available in the published CLI runtime.
|
|
292
|
-
const path = (await import("node:path"));
|
|
293
|
-
// @ts-ignore Node builtins are available in the published CLI runtime.
|
|
294
|
-
const url = (await import("node:url"));
|
|
295
599
|
async function realFileURL(filePath) {
|
|
296
600
|
let resolved = path.resolve(filePath);
|
|
297
601
|
try {
|
|
@@ -301,15 +605,23 @@ async function invokedFromCLI() {
|
|
|
301
605
|
// If realpath fails, compare the absolute path. This keeps direct execution
|
|
302
606
|
// working even when the script path disappears during process startup.
|
|
303
607
|
}
|
|
304
|
-
return normalizeFileURL(
|
|
608
|
+
return normalizeFileURL(pathToFileURL(resolved).href);
|
|
305
609
|
}
|
|
306
|
-
return (await realFileURL(scriptPath)) === (await realFileURL(
|
|
610
|
+
return (await realFileURL(scriptPath)) === (await realFileURL(fileURLToPath(import.meta.url)));
|
|
307
611
|
}
|
|
308
612
|
invokedFromCLI().then((invoked) => {
|
|
309
613
|
if (!invoked) {
|
|
310
614
|
return;
|
|
311
615
|
}
|
|
312
|
-
|
|
616
|
+
const argv = process.argv.slice(2);
|
|
617
|
+
const hasTemplateInit = argv.some((arg, index) => {
|
|
618
|
+
if (arg === "--template" || arg === "--repo") {
|
|
619
|
+
return Boolean(argv[index + 1]);
|
|
620
|
+
}
|
|
621
|
+
return false;
|
|
622
|
+
});
|
|
623
|
+
const initPath = hasTemplateInit ? ["init", ...argv] : ["init", "guardrail", ...argv];
|
|
624
|
+
runCli(initPath).then((code) => {
|
|
313
625
|
process.exitCode = code;
|
|
314
626
|
}, (err) => {
|
|
315
627
|
process.stderr.write(`${err instanceof Error ? err.message : String(err)}\n`);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ToolMessage } from "@langchain/core/messages";
|
|
2
|
+
import { type Command } from "@langchain/langgraph";
|
|
3
|
+
import type { PaybondAgentRun } from "../agent/run.js";
|
|
4
|
+
/** LangGraph `ToolCallRequest`-compatible shape used by Paybond interceptors. */
|
|
5
|
+
export type PaybondLangGraphToolCallRequest = {
|
|
6
|
+
tool_call: {
|
|
7
|
+
name: string;
|
|
8
|
+
id?: string;
|
|
9
|
+
args?: Record<string, unknown>;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
export type PaybondLangGraphAwrapToolCall = (request: PaybondLangGraphToolCallRequest, execute: (request: PaybondLangGraphToolCallRequest) => Promise<unknown>) => Promise<unknown>;
|
|
13
|
+
export declare function normalizeLangGraphHookResult(call: {
|
|
14
|
+
name: string;
|
|
15
|
+
id?: string;
|
|
16
|
+
}, result: unknown): ToolMessage | Command;
|
|
17
|
+
/**
|
|
18
|
+
* Build a LangGraph `awrapToolCall` interceptor backed by {@link PaybondToolInterceptor}.
|
|
19
|
+
*
|
|
20
|
+
* Prefer this over manual `guardTool` wrappers when the agent run is bound with a tool registry
|
|
21
|
+
* (registry spend resolvers, auto-evidence, and `defaultDeny`).
|
|
22
|
+
*/
|
|
23
|
+
export declare function paybondAwrapToolCall(run: PaybondAgentRun): PaybondLangGraphAwrapToolCall;
|
|
24
|
+
/** @deprecated Use {@link paybondAwrapToolCall}. */
|
|
25
|
+
export declare const paybondAwrapToolCallCapability: typeof paybondAwrapToolCall;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { ToolMessage } from "@langchain/core/messages";
|
|
2
|
+
import { isCommand } from "@langchain/langgraph";
|
|
3
|
+
import { PaybondAutoEvidenceSubmitError, PaybondUnregisteredSideEffectingToolError, } from "../agent/types.js";
|
|
4
|
+
import { PaybondSpendApprovalRequiredError, PaybondSpendDeniedError, } from "../index.js";
|
|
5
|
+
function toolCallFields(request) {
|
|
6
|
+
const call = request.tool_call;
|
|
7
|
+
return {
|
|
8
|
+
name: String(call.name ?? "").trim(),
|
|
9
|
+
toolCallId: String(call.id ?? "").trim(),
|
|
10
|
+
args: (call.args ?? {}),
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function denyToolMessage(name, toolCallId, content) {
|
|
14
|
+
return new ToolMessage({
|
|
15
|
+
content,
|
|
16
|
+
name: name || "unknown",
|
|
17
|
+
tool_call_id: toolCallId,
|
|
18
|
+
status: "error",
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function isToolMessage(value) {
|
|
22
|
+
return value instanceof ToolMessage;
|
|
23
|
+
}
|
|
24
|
+
export function normalizeLangGraphHookResult(call, result) {
|
|
25
|
+
if (isToolMessage(result) || isCommand(result)) {
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
return new ToolMessage({
|
|
29
|
+
status: "success",
|
|
30
|
+
name: call.name,
|
|
31
|
+
content: typeof result === "string" ? result : JSON.stringify(result),
|
|
32
|
+
tool_call_id: call.id ?? "",
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Build a LangGraph `awrapToolCall` interceptor backed by {@link PaybondToolInterceptor}.
|
|
37
|
+
*
|
|
38
|
+
* Prefer this over manual `guardTool` wrappers when the agent run is bound with a tool registry
|
|
39
|
+
* (registry spend resolvers, auto-evidence, and `defaultDeny`).
|
|
40
|
+
*/
|
|
41
|
+
export function paybondAwrapToolCall(run) {
|
|
42
|
+
return async (request, execute) => {
|
|
43
|
+
const { name, toolCallId, args } = toolCallFields(request);
|
|
44
|
+
if (!name) {
|
|
45
|
+
return denyToolMessage("unknown", toolCallId, "Paybond: tool call missing name");
|
|
46
|
+
}
|
|
47
|
+
if (!toolCallId) {
|
|
48
|
+
return denyToolMessage(name, "", "Paybond: tool call missing id");
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
const wrapped = await run.interceptor.wrapExecute({
|
|
52
|
+
toolName: name,
|
|
53
|
+
toolCallId,
|
|
54
|
+
arguments: args,
|
|
55
|
+
execute: () => execute(request),
|
|
56
|
+
});
|
|
57
|
+
return wrapped.toolResult;
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
if (err instanceof PaybondUnregisteredSideEffectingToolError) {
|
|
61
|
+
return denyToolMessage(name, toolCallId, `Paybond capability denied: unregistered side-effecting tool (${err.message})`);
|
|
62
|
+
}
|
|
63
|
+
if (err instanceof PaybondSpendApprovalRequiredError) {
|
|
64
|
+
const decisionId = err.result?.decisionId;
|
|
65
|
+
const suffix = decisionId ? ` (decision_id=${decisionId})` : "";
|
|
66
|
+
const msg = err.result?.message ?? err.result?.code ?? "approval required";
|
|
67
|
+
return denyToolMessage(name, toolCallId, `Paybond capability approval required: ${msg}${suffix}`);
|
|
68
|
+
}
|
|
69
|
+
if (err instanceof PaybondSpendDeniedError) {
|
|
70
|
+
const msg = err.result?.message ?? err.result?.code ?? "capability denied";
|
|
71
|
+
return denyToolMessage(name, toolCallId, `Paybond capability denied: ${msg}`);
|
|
72
|
+
}
|
|
73
|
+
if (err instanceof PaybondAutoEvidenceSubmitError) {
|
|
74
|
+
return denyToolMessage(name, toolCallId, `Paybond evidence submit failed: ${err.message}`);
|
|
75
|
+
}
|
|
76
|
+
throw err;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/** @deprecated Use {@link paybondAwrapToolCall}. */
|
|
81
|
+
export const paybondAwrapToolCallCapability = paybondAwrapToolCall;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ToolNodeOptions } from "@langchain/langgraph/prebuilt";
|
|
2
|
+
import type { PaybondAgentRun } from "../agent/run.js";
|
|
3
|
+
import { type PaybondLangGraphAwrapToolCall } from "./awrap-tool-call.js";
|
|
4
|
+
import { paybondToolNode } from "./tool-node.js";
|
|
5
|
+
/** LangGraph runner hooks: async tool-call wrapper and guarded `ToolNode` factory. */
|
|
6
|
+
export type PaybondLangGraphHooks = {
|
|
7
|
+
awrapToolCall: PaybondLangGraphAwrapToolCall;
|
|
8
|
+
createToolNode: (tools: Parameters<typeof paybondToolNode>[0], options?: ToolNodeOptions) => ReturnType<typeof paybondToolNode>;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Framework runner helper for LangGraph `ToolNode` and `awrap_tool_call` integration.
|
|
12
|
+
*/
|
|
13
|
+
export declare function createPaybondLangGraphHooks(run: PaybondAgentRun): PaybondLangGraphHooks;
|