|
| 1 | +This cookbook provides a step-by-step guide to use the asynchronous API for DevRev agents. It assumes you've already created an agent using the DevRev agent builder platform. |
| 2 | + |
| 3 | +This DevRev async API enables you to execute agents without any execution timeout concerns. The execution occurs as an asynchronous workflow that sends events to you via webhooks. This approach ensures: |
| 4 | + |
| 5 | +- Agent complexity does not bring timeout concerns with it. |
| 6 | +- Complete execution tracking via progress events. |
| 7 | +- Ability to handle long-running agent tasks. |
| 8 | + |
| 9 | +<Callout type="note"> |
| 10 | + In any unlikely and unforeseen circumstances, if an individual operation of the workflow times out, you do not receive an error event right now to notify that you should not wait for any more messages. It is better to have a client side timeout for now while the issue is brainstormed and fixed for you. |
| 11 | +</Callout> |
| 12 | + |
| 13 | +## Setting up webhook |
| 14 | + |
| 15 | +Before using the async API, you need to create a webhook to receive agent execution events: |
| 16 | + |
| 17 | +<CodeBlocks> |
| 18 | + ```bash |
| 19 | + curl --location 'https://api.devrev.ai/internal/webhooks.create' \ |
| 20 | + --header 'Content-Type: application/json' \ |
| 21 | + --header 'Authorization: <YOUR_API_TOKEN>' \ |
| 22 | + --data '{ |
| 23 | + "url": "https://your-application.com/webhook-endpoint", |
| 24 | + "event_types": ["ai_agent_response"], |
| 25 | + "headers": [ |
| 26 | + { |
| 27 | + "name": "x-api-key", |
| 28 | + "value": "your-secret-key" |
| 29 | + } |
| 30 | + ] |
| 31 | + }' |
| 32 | + ``` |
| 33 | + |
| 34 | + ```javascript |
| 35 | + const axios = require('axios'); |
| 36 | + |
| 37 | + async function createWebhook() { |
| 38 | + const response = await axios.post('https://api.devrev.ai/internal/webhooks.create', { |
| 39 | + url: "https://your-application.com/webhook-endpoint", |
| 40 | + event_types: ["ai_agent_response"], |
| 41 | + headers: [ |
| 42 | + { |
| 43 | + name: "x-api-key", |
| 44 | + value: "your-secret-key" |
| 45 | + } |
| 46 | + ] |
| 47 | + }, { |
| 48 | + headers: { |
| 49 | + 'Content-Type': 'application/json', |
| 50 | + 'Authorization': '<YOUR_API_TOKEN>' |
| 51 | + } |
| 52 | + }); |
| 53 | + |
| 54 | + return response.data; |
| 55 | + } |
| 56 | + ``` |
| 57 | +</CodeBlocks> |
| 58 | + |
| 59 | +Save the webhook ID from the response (format: `don:integration:dvrv-us-1:devo/0:webhook/auCJ7By8`). You need this when making async API calls. |
| 60 | + |
| 61 | +Make sure that your webhook endpoint can appropriately respond to the verify events sent by DevRev to verify your webhook. This verify event has a challenge string which you need to return in response. You return the response like this: |
| 62 | + |
| 63 | + ```json |
| 64 | + 200 OK |
| 65 | + { |
| 66 | + "challenge": "DlrVaK7zRyZWwbJhj5dZHDlrVaK7Jhj5dZZjH" |
| 67 | + } |
| 68 | + ``` |
| 69 | + |
| 70 | + |
| 71 | +You should follow the documentation provided for webhooks [here](https://developer.devrev.ai/public/guides/webhooks) |
| 72 | + |
| 73 | +## Make async API calls |
| 74 | + |
| 75 | +**Key parameters:** |
| 76 | + |
| 77 | +- `agent`: Your agent's ID. |
| 78 | +- `event.input_message.message`: The query for your agent. |
| 79 | +- `session_object`: A unique identifier for the conversation session (maintains agent memory). |
| 80 | +- `webhook_target.webhook`: The webhook ID created earlier. |
| 81 | + |
| 82 | +**To execute an agent asynchronously:** |
| 83 | + |
| 84 | +<CodeBlocks> |
| 85 | + ```bash |
| 86 | + curl --location 'https://api.devrev.ai/internal/ai-agents.events.execute-async' \ |
| 87 | + --header 'Content-Type: application/json' \ |
| 88 | + --header 'Accept: application/json' \ |
| 89 | + --header 'Authorization: <YOUR_API_KEY>' \ |
| 90 | + --data '{ |
| 91 | + "agent": "don:core:dvrv-us-1:devo/0:ai_agent/1", |
| 92 | + "event": { |
| 93 | + "input_message": { |
| 94 | + "message": "Your query to the agent" |
| 95 | + } |
| 96 | + }, |
| 97 | + "session_object": "unique_conversation_identifier", |
| 98 | + "webhook_target": { |
| 99 | + "webhook": "don:integration:dvrv-us-1:devo/0:webhook/auCJ7By8" |
| 100 | + }, |
| 101 | + "client_metadata": { |
| 102 | + "user_id": "12345", |
| 103 | + "conversation_id": "conv-789" |
| 104 | + } |
| 105 | + }' |
| 106 | + ``` |
| 107 | + |
| 108 | + ```javascript |
| 109 | + const executeAgent = async () => { |
| 110 | + const response = await fetch('https://api.devrev.ai/internal/ai-agents.events.execute-async', { |
| 111 | + method: 'POST', |
| 112 | + headers: { |
| 113 | + 'Content-Type': 'application/json', |
| 114 | + 'Accept': 'application/json', |
| 115 | + 'Authorization': '<YOUR_API_KEY>' |
| 116 | + }, |
| 117 | + body: JSON.stringify({ |
| 118 | + agent: "don:core:dvrv-us-1:devo/0:ai_agent/1", |
| 119 | + event: { |
| 120 | + input_message: { |
| 121 | + message: "Your query to the agent" |
| 122 | + } |
| 123 | + }, |
| 124 | + session_object: "unique_conversation_identifier", |
| 125 | + webhook_target: { |
| 126 | + webhook: "don:integration:dvrv-us-1:devo/0:webhook/auCJ7By8" |
| 127 | + }, |
| 128 | + client_metadata: { |
| 129 | + user_id: "12345", |
| 130 | + conversation_id: "conv-789" |
| 131 | + } |
| 132 | + }) |
| 133 | + }); |
| 134 | + |
| 135 | + return await response.json(); |
| 136 | + }; |
| 137 | + ``` |
| 138 | +</CodeBlocks> |
| 139 | + |
| 140 | +<Callout type="warning"> |
| 141 | + The session_object parameter is critical for maintaining conversation state |
| 142 | + across multiple calls. |
| 143 | +</Callout> |
| 144 | + |
| 145 | +## Handling webhook events |
| 146 | + |
| 147 | +Your webhook endpoint receives three types of events. |
| 148 | + |
| 149 | +### Progress messages |
| 150 | + |
| 151 | +These show which skills are being triggered and executed. |
| 152 | + |
| 153 | +```json Skill triggered |
| 154 | +{ |
| 155 | + "payload": { |
| 156 | + "ai_agent_response": { |
| 157 | + "agent": "don:core:dvrv-us-1:devo/xyz:ai_agent/123", |
| 158 | + "agent_response": "progress", |
| 159 | + "client_metadata": { /* your original metadata */ }, |
| 160 | + "progress": { |
| 161 | + "progress_state": "skill_triggered", |
| 162 | + "skill_triggered": { |
| 163 | + "args": { /* skill arguments */ }, |
| 164 | + "skill_name": "SkillName", |
| 165 | + "workflow": { /* This is not populated if KnowledgeSearch skill is called */ |
| 166 | + "display_id": "workflow-84", |
| 167 | + "id": "don:integration:dvrv-us-1:devo/xyz:workflow/84" |
| 168 | + } |
| 169 | + } |
| 170 | + }, |
| 171 | + "session": "don:core:dvrv-us-1:devo/xyz:ai_agent_session/3810", |
| 172 | + "session_object": "unique_conversation_identifier" |
| 173 | + }, |
| 174 | + "type": "ai_agent_response" |
| 175 | + } |
| 176 | +} |
| 177 | +``` |
| 178 | + |
| 179 | +```json Skill executed |
| 180 | +{ |
| 181 | + "payload": { |
| 182 | + "ai_agent_response": { |
| 183 | + "agent": "don:core:dvrv-us-1:devo/xyz:ai_agent/123", |
| 184 | + "agent_response": "progress", |
| 185 | + "client_metadata": { /* your original metadata */ }, |
| 186 | + "progress": { |
| 187 | + "progress_state": "skill_executed", |
| 188 | + "skill_executed": { |
| 189 | + "output": { /* skill output */ }, |
| 190 | + "skill_name": "SkillName" |
| 191 | + } |
| 192 | + }, |
| 193 | + "session": "don:core:dvrv-us-1:devo/xyz:ai_agent_session/3810", |
| 194 | + "session_object": "unique_conversation_identifier" |
| 195 | + }, |
| 196 | + "type": "ai_agent_response" |
| 197 | + } |
| 198 | +} |
| 199 | +``` |
| 200 | + |
| 201 | +### Final message |
| 202 | + |
| 203 | +This event contains the agent's final response after all skills are executed. |
| 204 | + |
| 205 | +```json |
| 206 | +{ |
| 207 | + "payload": { |
| 208 | + "ai_agent_response": { |
| 209 | + "agent": "don:core:dvrv-us-1:devo/xyz:ai_agent/123", |
| 210 | + "agent_response": "message", |
| 211 | + "client_metadata": { |
| 212 | + /* your original metadata */ |
| 213 | + }, |
| 214 | + "message": "The agent's final response message", |
| 215 | + "session": "don:core:dvrv-us-1:devo/xyz:ai_agent_session/3810", |
| 216 | + "session_object": "unique_conversation_identifier" |
| 217 | + }, |
| 218 | + "type": "ai_agent_response" |
| 219 | + } |
| 220 | +} |
| 221 | +``` |
| 222 | + |
| 223 | +### Error message |
| 224 | + |
| 225 | +This event indicates an error occurred during execution. |
| 226 | + |
| 227 | +```json |
| 228 | +{ |
| 229 | + "payload": { |
| 230 | + "ai_agent_response": { |
| 231 | + "agent": "don:core:dvrv-us-1:devo/xyz:ai_agent/123", |
| 232 | + "agent_response": "error", |
| 233 | + "client_metadata": { |
| 234 | + /* your original metadata */ |
| 235 | + }, |
| 236 | + "error": { |
| 237 | + "error": "Error description" |
| 238 | + }, |
| 239 | + "session": "don:core:dvrv-us-1:devo/xyz:ai_agent_session/3810", |
| 240 | + "session_object": "unique_conversation_identifier" |
| 241 | + }, |
| 242 | + "type": "ai_agent_response" |
| 243 | + } |
| 244 | +} |
| 245 | +``` |
| 246 | + |
| 247 | +## Implementation patterns |
| 248 | + |
| 249 | +### Custom applications |
| 250 | + |
| 251 | +<Callout type="info"> |
| 252 | + This pattern is ideal for custom chat interfaces, backend systems, or any |
| 253 | + application that needs to interact with DevRev agents. |
| 254 | +</Callout> |
| 255 | + |
| 256 | +For building custom applications with the async API: |
| 257 | + |
| 258 | +1. Create a webhook endpoint in your application that can receive POST requests. |
| 259 | +2. Register this endpoint with DevRev using the webhooks.create API. |
| 260 | +3. Make async API calls with your agent ID and webhook ID. |
| 261 | +4. Process incoming webhook events to: |
| 262 | + - Track progress (optional). |
| 263 | + - Display the final agent response to the user. |
| 264 | + - Handle any errors. |
| 265 | + |
| 266 | +Example flow for a chat application: |
| 267 | + |
| 268 | +```javascript |
| 269 | +// 1. When user sends a message |
| 270 | +function handleUserMessage(message) { |
| 271 | + // Show loading indicator |
| 272 | + displayLoadingIndicator(); |
| 273 | + |
| 274 | + // Make async API call |
| 275 | + fetch("https://api.devrev.ai/internal/ai-agents.events.execute-async", { |
| 276 | + method: "POST", |
| 277 | + headers: { |
| 278 | + "Content-Type": "application/json", |
| 279 | + Authorization: "YOUR_API_KEY", |
| 280 | + }, |
| 281 | + body: JSON.stringify({ |
| 282 | + agent: "your_agent_id", |
| 283 | + event: { |
| 284 | + input_message: { |
| 285 | + message: message, |
| 286 | + }, |
| 287 | + }, |
| 288 | + session_object: "conversation_" + userId, |
| 289 | + webhook_target: { |
| 290 | + webhook: "your_webhook_id", |
| 291 | + }, |
| 292 | + client_metadata: { |
| 293 | + conversation_id: conversationId, |
| 294 | + }, |
| 295 | + }), |
| 296 | + }); |
| 297 | +} |
| 298 | + |
| 299 | +// 2. Webhook handler (server-side) |
| 300 | +app.post("/webhook-endpoint", (req, res) => { |
| 301 | + const event = req.body; |
| 302 | + |
| 303 | + // Add handling for verify events |
| 304 | + |
| 305 | + const conversationId = |
| 306 | + event.payload.ai_agent_response.client_metadata.conversation_id; |
| 307 | + |
| 308 | + if (event.payload.ai_agent_response.agent_response === "message") { |
| 309 | + // Final message |
| 310 | + const message = event.payload.ai_agent_response.message; |
| 311 | + sendToClient(conversationId, { |
| 312 | + type: "agent_response", |
| 313 | + message: message, |
| 314 | + }); |
| 315 | + } else if (event.payload.ai_agent_response.agent_response === "error") { |
| 316 | + // Error occurred |
| 317 | + sendToClient(conversationId, { |
| 318 | + type: "agent_error", |
| 319 | + error: event.payload.ai_agent_response.error.error, |
| 320 | + }); |
| 321 | + } |
| 322 | + |
| 323 | + res.status(200).send("OK"); |
| 324 | +}); |
| 325 | +``` |
| 326 | + |
| 327 | +<Callout type="tip"> |
| 328 | + Using WebSockets or Server-Sent Events can provide real-time updates to your |
| 329 | + UI as events are received. |
| 330 | +</Callout> |
| 331 | + |
| 332 | +### Talk to agent node in workflows |
| 333 | + |
| 334 | +<Callout type="note"> |
| 335 | + This is in early access, please contact support to have it enabled for you. |
| 336 | +</Callout> |
| 337 | + |
| 338 | +If you're using DevRev workflows: |
| 339 | + |
| 340 | +<Callout type="info"> |
| 341 | + The workflow engine handles the async API calls for you when using the Talk To |
| 342 | + Agent node. |
| 343 | +</Callout> |
| 344 | + |
| 345 | +1. Add the "Talk To Agent" node to your workflow |
| 346 | +2. Configure it with your agent ID |
| 347 | +3. Connect it to response nodes to process the agent's output |
| 348 | +4. The async API is used automatically by the workflow engine |
| 349 | + |
| 350 | + |
| 351 | +## Troubleshooting |
| 352 | + |
| 353 | +<Callout type="warning">Common issues and their solutions</Callout> |
| 354 | + |
| 355 | +**Not receiving webhook events?** |
| 356 | + |
| 357 | +- Verify your webhook URL is publicly accessible |
| 358 | +- Check that you've registered for the "ai_agent_response" event type |
| 359 | +- Ensure your server responds with a 2xx status code quickly |
| 360 | + |
| 361 | +**Execution errors?** |
| 362 | + |
| 363 | +- Check the error message in the error event |
| 364 | +- Verify your agent ID is correct |
| 365 | +- Ensure your session_object is a valid string |
| 366 | + |
| 367 | +**Agent not responding as expected?** |
| 368 | + |
| 369 | +- Review the skill_triggered and skill_executed events to see which skills were invoked |
| 370 | +- Check if any skills returned error outputs |
| 371 | +- Verify your agent's configuration in the DevRev agent builder |
0 commit comments