/** * Example 13: Worker Sandbox and Execution Control * * This example demonstrates advanced execution control in worker mode. * It shows how to: * - Implement execution timeouts and cancellation with AbortController * - Use execution loops with limited iterations * - Create monitoring tools for long-running processes * - Handle execution signals and cleanup * - Control sandbox execution with safety limits * * Key concepts: * - AbortController for execution cancellation * - Execution timeout patterns * - Loop limits with options.loop * - Signal-based process control * - Monitoring and checkin patterns for long-running tasks */ import { Client } from '@botpress/client' import { z } from '@bpinternal/zui' import { execute, Tool } from 'llmz' import { printTrace } from '../utils/debug' // Initialize Botpress client const client = new Client({ botId: process.env.BOTPRESS_BOT_ID!, token: process.env.BOTPRESS_TOKEN!, }) // Tracking variables for execution monitoring let startedAt: number // AbortController for cancelling long-running operations // This provides a safety mechanism to prevent runaway executions const controller = new AbortController() // Tool for introducing delays in execution // Demonstrates controlled timing in worker processes const wait = new Tool({ name: 'wait', description: 'pauses the execution for a given number of milliseconds', input: z.object({ ms: z.number().min(0, 'The number of milliseconds must be a positive integer'), }), async handler(input) { // Set up automatic abort after 5 seconds as a safety measure // This prevents infinite or excessively long waits setTimeout(() => controller.abort('5 seconds elasped'), 1000 * 5) // Implement the actual wait using Promise and setTimeout await new Promise((resolve) => { setTimeout(() => resolve(), input.ms) }) }, }) // Monitoring tool for tracking execution progress // This allows long-running processes to report their status const checkin = new Tool({ name: 'checkin', description: 'must call after every 2 seconds', async handler() { // Log current execution time since start console.log(`Checkin at ${Date.now() - startedAt}ms`) }, }) // Execute a long-running task with safety controls const result = await execute({ // Instructions for a potentially long-running process instructions: 'console.log the number 1 to 10,000 in a for loop, pausing for 500 milliseconds between each number. Make sure to comment the code very well. Checkin when appropriate.', // Provide tools for timing control and monitoring tools: [wait, checkin], client, // Attach the abort signal for execution cancellation // This allows external cancellation of the execution signal: controller.signal, // Monitor execution progress with detailed tracing onTrace: ({ trace }) => { printTrace(trace) // Track when LLM execution begins for timing calculations if (trace.type === 'llm_call_success') { startedAt = Date.now() } }, // Execution options for safety and control options: { loop: 10, // Limit to maximum 10 execution iterations // This prevents infinite loops and provides bounds on execution }, }) // Report execution completion status console.log('Execution finished') console.log('Last iteration:', result.iteration?.status)