docs: add spending policy integration guide (LetAgentPay)#166
Conversation
Adds docs/spending-policies-with-letagentpay.md plus one row in the Documentation table. Shows the pre-flight requestPurchase -> ClawRouter chat -> confirmPurchase wrapper pattern for putting a vendor-neutral spending policy engine in front of wallet-based routed calls.
📝 WalkthroughWalkthroughThis PR adds comprehensive documentation for a spending policy integration pattern between ClawRouter and LetAgentPay. A new guide describes the policedChat workflow: pre-flight authorization via ChangesLetAgentPay Spending Policy Documentation
🎯 1 (Trivial) | ⏱️ ~3 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
docs/spending-policies-with-letagentpay.md (1)
77-77: ⚡ Quick winConsider clarifying that these controls are available but not shown in the starter policy.
Line 77 references
weekly_limit,monthly_limit, and account budget controls that don't appear in the starter policy JSON above (lines 57-68). This could confuse readers who expect the table to map directly to the example.💡 Suggested clarification
-| Total wallet protection | `weekly_limit` / `monthly_limit` / account budget | +| Total wallet protection | `weekly_limit` / `monthly_limit` / account budget (see full docs) |Or add these fields to the starter policy JSON as commented-out examples.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/spending-policies-with-letagentpay.md` at line 77, The table entry "Total wallet protection" mentions controls named weekly_limit, monthly_limit, and account budget that are not present in the starter policy JSON example; update the docs by either adding these fields as commented-out examples inside the starter policy JSON (include sample keys weekly_limit, monthly_limit, account_budget) or add a concise clarifying sentence immediately below the table stating that these controls exist but are intentionally omitted from the starter policy example for brevity. Ensure the chosen change references the exact field names (weekly_limit, monthly_limit, account_budget) so readers can map the table to the example.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/spending-policies-with-letagentpay.md`:
- Around line 22-52: The policedChat flow must release the hold if the routed
call fails: wrap the router.chat call in a try/catch inside policedChat, and on
success call policy.confirmPurchase(purchase.requestId, { success: true,
actualAmount: result.costUsd }) as done now; on catch call
policy.confirmPurchase(purchase.requestId, { success: false, actualAmount: 0 })
(await it) to release the hold, then rethrow the original error; reference the
policedChat function, router.chat call, purchase.requestId, and
policy.confirmPurchase to locate and update the code.
---
Nitpick comments:
In `@docs/spending-policies-with-letagentpay.md`:
- Line 77: The table entry "Total wallet protection" mentions controls named
weekly_limit, monthly_limit, and account budget that are not present in the
starter policy JSON example; update the docs by either adding these fields as
commented-out examples inside the starter policy JSON (include sample keys
weekly_limit, monthly_limit, account_budget) or add a concise clarifying
sentence immediately below the table stating that these controls exist but are
intentionally omitted from the starter policy example for brevity. Ensure the
chosen change references the exact field names (weekly_limit, monthly_limit,
account_budget) so readers can map the table to the example.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: d3960563-715a-43e1-80e7-989d01d7638b
📒 Files selected for processing (2)
README.mddocs/spending-policies-with-letagentpay.md
| async function policedChat(opts: { | ||
| messages: { role: string; content: string }[]; | ||
| estimatedCostUsd: number; | ||
| description?: string; | ||
| }) { | ||
| // 1. Pre-flight: ask the policy engine before the spend | ||
| const purchase = await policy.requestPurchase({ | ||
| amount: opts.estimatedCostUsd, | ||
| category: "llm_inference", | ||
| merchantName: "ClawRouter", | ||
| description: opts.description ?? "Routed LLM call", | ||
| }); | ||
|
|
||
| if (purchase.status === "rejected") { | ||
| throw new Error(`Policy denied: ${purchase.policyCheck?.failedCheck}`); | ||
| } | ||
| if (purchase.status === "pending") { | ||
| throw new Error(`Policy escalated to human review: ${purchase.requestId}`); | ||
| } | ||
|
|
||
| // 2. Auto-approved — proceed with ClawRouter | ||
| const result = await router.chat({ messages: opts.messages }); | ||
|
|
||
| // 3. Confirm actual x402-settled cost | ||
| await policy.confirmPurchase(purchase.requestId, { | ||
| success: true, | ||
| actualAmount: result.costUsd, | ||
| }); | ||
|
|
||
| return result; | ||
| } |
There was a problem hiding this comment.
Add error handling to match documented guidance.
The code snippet doesn't implement the failure handling described in the Notes section (line 82). If router.chat throws an error or rejects the request, the code should call confirmPurchase with success: false to release the hold, but currently errors would leave the hold unreleased.
🛡️ Proposed fix to add error handling
// 2. Auto-approved — proceed with ClawRouter
- const result = await router.chat({ messages: opts.messages });
+ let result;
+ try {
+ result = await router.chat({ messages: opts.messages });
+ } catch (error) {
+ // Release the hold on failure
+ await policy.confirmPurchase(purchase.requestId, {
+ success: false,
+ actualAmount: 0,
+ });
+ throw error;
+ }
// 3. Confirm actual x402-settled cost
await policy.confirmPurchase(purchase.requestId, {
success: true,
actualAmount: result.costUsd,
});
return result;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/spending-policies-with-letagentpay.md` around lines 22 - 52, The
policedChat flow must release the hold if the routed call fails: wrap the
router.chat call in a try/catch inside policedChat, and on success call
policy.confirmPurchase(purchase.requestId, { success: true, actualAmount:
result.costUsd }) as done now; on catch call
policy.confirmPurchase(purchase.requestId, { success: false, actualAmount: 0 })
(await it) to release the hold, then rethrow the original error; reference the
policedChat function, router.chat call, purchase.requestId, and
policy.confirmPurchase to locate and update the code.
ClawRouter gives agents wallets and x402 micropayments — elegant infrastructure for "how does an agent pay". There's currently no built-in budget cap, so a runaway agent loop can drain its wallet across hundreds of routed calls in seconds. We see ClawRouter users asking about this gap.
This PR adds a single doc —
docs/spending-policies-with-letagentpay.md— that shows the wrapper pattern for putting a vendor-neutral spending policy engine (LetAgentPay, open-source, MIT) in front of ClawRouter calls:requestPurchase→ ClawRouterchat→confirmPurchasewith actual costAlso adds a row to the Documentation table in the README.
Disclosure: I work on LetAgentPay. Wrote this because the question keeps coming up and the integration is straightforward. Happy to revise tone, cut promotional language, or move into a different section if you'd prefer a different shape.
— Maxim Berg
Summary by CodeRabbit