Support with tools and human approval
A customer writes that part of an order arrived damaged. The agent looks the order up, checks the item and the amount, and calls issue_refund. Small refunds run at once. When the call crosses your threshold, or the sum of the month would pass the cap, the action does not run: it becomes an approval that waits for a person. You approve it by API (or in the dashboard) and only then the action runs and the agent tells the customer.
Who it is for. Stores and services that refund or credit money and want a person to decide the big ones. Scopes. agents:write, pipelines:write, actions:write, approvals:read, approvals:write, webhooks:write, cases:write, cases:converse, contacts:write.
Code
The runnable script is in examples/use-cases/support-with-approvals.
0. Set up
Code
1. Register the two actions
get_order reads and issue_refund writes. Both take the customer from Lelemon, not from the model: variables with contact.external_ref makes Lelemon send the customerRef itself, so the agent cannot ask for the order of another person. Your backend checks that the order belongs to that customer.
Your server verifies the signature of each call (how) and answers JSON. sharedWithSubaccounts is only needed if you want a floor.
2. Write the agent and the pipeline
The prompt carries the policy that approvals cannot: what a refund is for, what must be confirmed, what to say for each of the three answers of issue_refund, and when to hand over. It also says that a clear request is the confirmation, so the agent does not ask twice.
3. Put refunds behind a person
PUT /v2/agents/{id}/tools/{toolId} grants the action with an approval policy. mode: "rules" takes an ordered list and the first rule that applies decides:
- above $150.000 the call is rejected and the agent says so (
reject); - above $20.000 a person decides (
require_approval); - anything else runs.
accumulated adds a rolling cap per contact and action: it stops a split into small refunds, because each one is small and the sum is not. Here the month cannot pass $25.000 without a person. approvers names who may decide (here, the API key of your back office); expiresInMinutes is when the request dies and escalateAfterMinutes fires approval.escalated once.
Code
get_order is granted with no policy, so it runs freely. The other tools: save_case_data for the two fields and transfer_to_human for the stage Needs a person. See Approve agent actions for every rule.
4. Set a floor that no subaccount can lower
If you run Lelemon for other companies (platform), an action you share with your subaccounts can carry a floor: the least approval any subaccount can run it with. A subaccount can be stricter, never looser, and cannot grant the action with mode: "never" below the floor. Here, any refund above $100.000 waits for an owner, whatever the policy of the subaccount says.
Code
GET /v2/agents/{id}/tools shows both on the tool: approval (the policy of the agent) and approvalFloor.
5. Listen for approvals
6. Try it: a refund that runs, and one that waits
The first message names the item, the problem and the amount, so it is also the confirmation. $12.000 is under the threshold and under the cap, so issue_refund runs and the agent gives the refund id.
Code
The second item is also under $20.000, but the month would reach $30.000 and the cap is $25.000. The call does not run:
Code
reasonCode says why: policy_accumulated here, policy_rule for the threshold, policy_always or policy_condition for the other modes. The agent told the customer that a person is reviewing it and did not call the action again.
7. A person approves
approve runs the action now with the arguments you read, then the agent resumes the conversation with the result. It has the real effect of the action, so only the approvers of the policy can call it. To say no, POST /v2/approvals/{id}/reject with a reason: the action never runs and the agent tells the customer.
Code
status: "executed" and the result of your backend. Reading the approval at GET /v2/approvals/{id} shows the whole story: who decided, when and with which reason.
Notes
- Your backend receives real signed calls, so test the signature code too.
POST /v2/actions/{id}/testcalls your endpoint once with sample input, without a case.
What you see in the dashboard
- Approvals: the pending request with the action, its arguments, the reason and who may decide. Deciding there is the same as the API.
- Inbox: the thread, with the agent's message that a person is reviewing it, and the later one with the refund id.
- Agent, Tools:
issue_refundwith its policy and, for a shared action, the floor.
What's next
- Approve agent actions: rules, approvers, roles and automated decisions.
- Run Lelemon for your customers: share the action and fix the floor.
- Track usage and cap conversations.