What are Actions?

Actions = discrete tasks agents can perform.

Action Interface

interface Action {
  name: string;              // Unique identifier
  description: string;       // What it does
  similes?: string[];       // Alternative names
  examples?: ActionExample[][];  // Usage examples
  validate: Validator;       // Can this run?
  handler: Handler;          // Execute the action
}

Core Actions (Bootstrap Plugin)

The bootstrap plugin provides 13 essential actions:

Communication Actions

ActionDescriptionExample Trigger
REPLYGenerate response”Tell me about…”
SEND_MESSAGESend to specific room”Message the team…”
NONEAcknowledge silently”Thanks!”
IGNORESkip messageSpam/irrelevant

Room Management

ActionDescriptionExample Trigger
FOLLOW_ROOMSubscribe to updates”Join #general”
UNFOLLOW_ROOMUnsubscribe”Leave #general”
MUTE_ROOMMute notifications”Mute this channel”
UNMUTE_ROOMUnmute”Unmute #general”

Data & Configuration

ActionDescriptionExample Trigger
UPDATE_CONTACTUpdate contact info”Remember that I…”
UPDATE_ROLEChange roles”Make me admin”
UPDATE_SETTINGSModify settings”Set model to gpt-4”

Media & Utilities

ActionDescriptionExample Trigger
GENERATE_IMAGECreate AI images”Draw a cat”
CHOICEPresent options”Should I A or B?”

Plugin Action Examples

ActionPluginExample
GET_PRICEplugin-binance”BTC price?”
EXECUTE_TRADEplugin-binance”Buy 0.1 BTC”
TOKEN_PRICEplugin-dexscreener”Price of $PEPE”

Creating Actions

Minimal Action

const action: Action = {
  name: 'MY_ACTION',
  description: 'Does something',
  validate: async () => true,
  handler: async (runtime, message) => {
    return { text: "Done!" };
  }
};

With Validation

const sendTokenAction: Action = {
  name: 'SEND_TOKEN',
  description: 'Send tokens to address',
  
  validate: async (runtime, message) => {
    return message.content.includes('send') && 
           message.content.includes('0x');
  },
  
  handler: async (runtime, message) => {
    const address = extractAddress(message.content);
    const amount = extractAmount(message.content);
    await sendToken(address, amount);
    return {
      text: `Sent ${amount} tokens to ${address}`
    };
  }
};

With Examples

const action: Action = {
  name: 'WEATHER',
  description: 'Get weather info',
  examples: [[
    { name: "user", content: { text: "What's the weather?" } },
    { name: "agent", content: { text: "Let me check the weather for you." } }
  ]],
  validate: async (runtime, message) => {
    return message.content.toLowerCase().includes('weather');
  },
  handler: async (runtime, message) => {
    const weather = await fetchWeather();
    return { text: `It's ${weather.temp}°C and ${weather.condition}` };
  }
};

Handler Patterns

// Using callbacks
handler: async (runtime, message, state, options, callback) => {
  const result = await doWork();
  if (callback) {
    await callback({ text: result }, []);
  }
  return result;
}

// Using services
handler: async (runtime, message) => {
  const service = runtime.getService<TwitterService>('twitter');
  return service.post(message.content);
}

// Using database
handler: async (runtime, message) => {
  const memories = await runtime.databaseAdapter.searchMemories({
    query: message.content,
    limit: 5
  });
  return { memories };
}

## Best Practices

- Name actions clearly (VERB_NOUN format)
- Validate before executing
- Return consistent response format
- Use similes for alternative triggers
- Provide diverse examples

## Next Steps

<CardGroup cols={2}>
  <Card title="Providers" icon="database" href="/core-concepts/plugins/providers">
    Learn about data providers
  </Card>
  
  <Card title="Evaluators" icon="scale-balanced" href="/core-concepts/plugins/evaluators">
    Explore response evaluation
  </Card>
</CardGroup>