Background Processes
Create and manage long-running background tasks in DAIN services
Overview
Background processes enable tools to start long-running tasks that continue executing after the initial response. This is ideal for operations like data analysis, file processing, or any task that may take significant time to complete.
A user can see the progress of a background process in the process viewer and in their dashboard, while continuing to interact with the assistant.
Process Store Configuration
Services using background processes must configure a process store for persistence. Two options are available:
import {
defineDAINService,
RedisProcessStore
} from "@dainprotocol/service-sdk";
// Option 1: Redis Store (recommended for production)
const processStore = new RedisProcessStore(process.env.REDIS_URL);
// Option 2: Memory Store (default, for development)
const dainService = defineDAINService({
// Memory store is used if processStore is not specified
metadata: { /* ... */ }
});
// Using Redis Store
const dainService = defineDAINService({
metadata: { /* ... */ },
processStore: processStore // Redis store for persistence
});
Creating a Process
Start a background process using the processes API:
handler: async (input, agentInfo, { app }) => {
// Create a process with a descriptive name
const processId = await app.processes!.createProcess(
agentInfo,
"one-time",
"Data Analysis",
"Analyzing dataset"
);
// Start background work
(async () => {
try {
// Your long-running task
} catch (error) {
await app.processes!.failProcess(processId, error.message);
}
})();
// Return immediately with process viewer
return new DainResponse({
text: "Analysis started",
data: { processId },
ui: { type: "processViewer", props: { processId } },
processes: [processId]
});
}
Updating Progress
Keep users informed about task progress:
await app.processes!.addUpdate(processId, {
percentage: 20,
text: "Processing data..."
});
Adding Results
Return UI components when the process completes:
import { CardListUIBuilder, ImageCardUIBuilder } from "@dainprotocol/utils";
// Create visualization UI
const visualizations = results.map(result =>
new ImageCardUIBuilder(result.imageUrl)
.title("Analysis Result")
.description(result.description)
.build()
);
// Add final results
await app.processes!.addResult(processId, {
text: "Analysis complete",
data: results,
ui: new CardListUIBuilder()
.title("Analysis Results")
.description("Visualizations from your analysis")
.addCards(visualizations)
.build()
});
Example: Phone Call Service
Here's an example using Redis process store for a phone call service:
import { RedisProcessStore } from "@dainprotocol/service-sdk";
// Initialize Redis store
const processStore = new RedisProcessStore(process.env.REDIS_URL);
const makePhoneCallConfig: ToolConfig = {
id: "make-phone-call",
name: "Make Phone Call",
handler: async ({ phoneNumber, goal }, agentInfo, { app }) => {
// Create process
const processId = await app.processes!.createProcess(
agentInfo,
"one-time",
"Phone Call",
`Calling ${phoneNumber}`
);
// Start call in background
initiatePhoneCall(processId, app, phoneNumber, goal);
return new DainResponse({
text: "Initiating phone call",
data: { processId },
ui: { type: "processViewer", props: { processId } },
processes: [processId]
});
}
};
const dainService = defineDAINService({
metadata: { /* ... */ },
processStore: processStore, // Use Redis store
tools: [makePhoneCallConfig]
});
Process States
A background process can be in one of these states:
running
: Process is actively executingcompleted
: Process finished successfullyfailed
: Process encountered an errorcancelled
: Process was manually stopped