AgentForge

Compensating Actions

Define rollback behavior for tools — compensate functions and irreversible markers.

Overview

When an agent run fails, AgentForge can automatically rollback side effects using compensating actions. Each tool can declare how to undo its work.

Compensate Function

Provide a function that reverses the tool's effect:

const createOrder = defineTool({
  name: 'create-order',
  description: 'Create a new order',
  input: z.object({ items: z.array(z.string()), customerId: z.string() }),
  output: z.object({ orderId: z.string() }),
  execute: async (input) => {
    const orderId = await orderService.create(input);
    return { orderId };
  },
  compensate: async (input, output) => {
    // Undo: cancel the order that was created
    await orderService.cancel(output.orderId);
  },
});

Irreversible Tools

Mark tools as irreversible when there's no way to undo their effect:

const sendEmail = defineTool({
  name: 'send-email',
  description: 'Send an email',
  input: z.object({ to: z.string(), subject: z.string(), body: z.string() }),
  output: z.object({ messageId: z.string() }),
  execute: async (input) => { /* ... */ },
  compensate: 'irreversible',
});

Irreversible tools are tracked in the rollback ledger but skipped during rollback.

RollbackLedger

AgentForge records every tool execution in a RollbackLedger. On failure with rollbackOnFailure: true, it calls compensate functions in reverse order:

const agent = defineAgent({
  name: 'transactional-agent',
  description: 'Agent with rollback',
  tools: [createOrder, chargePayment, sendConfirmation],
  llm,
  systemPrompt: '...',
  rollbackOnFailure: true,
});

const result = await agent.run({ task: 'Process order' });

if (result.rollback) {
  console.log('Rollback performed:', result.rollback);
  // { compensated: ['charge-payment', 'create-order'], skipped: ['send-confirmation'] }
}

RollbackResult

interface RollbackResult {
  compensated: string[];   // Tools that were successfully rolled back
  skipped: string[];       // Irreversible tools that were skipped
  failed: string[];        // Compensations that threw errors
}

Next Steps