# Plugins

Plugins are reusable event handlers. Package capabilities and reuse them across agents.

## Quick Start

```python
from connectonion import Agent
from connectonion.useful_plugins import re_act

agent = Agent("assistant", tools=[search], plugins=[re_act])
agent.input("Search for Python")
# 💭 Planning: Will search for Python info first.
# ... tool executes ...
# 🤔 Reflecting: Found Python basics, task complete.
```

## What is a Plugin?

A plugin is a list of event handlers:

```python
from connectonion import after_user_input, after_tools

# Define handlers
def plan(agent):
    print("Planning...")

def reflect(agent):
    print("Reflecting...")

# Plugin = list of event handlers
re_act = [after_user_input(plan), after_tools(reflect)]

# Use it
agent = Agent("assistant", tools=[search], plugins=[re_act])
```

## Plugin vs on_events

```python
# on_events: one list (custom for this agent)
agent = Agent("a", on_events=[after_llm(handler)])

# plugins: list of lists (reusable across agents)
agent = Agent("a", plugins=[re_act, logger])
```

## Built-in Plugins

| Plugin | Purpose | Docs |
|--------|---------|------|
| `skills` | Invoke pre-packaged workflows with scoped permissions | [skills.md](skills.md) |
| `subagents` | Run tasks in parallel sub-agents | [subagents.md](../useful_plugins/subagents.md) |
| `re_act` | Planning + reflection (ReAct pattern) | [re_act.md](../useful_plugins/re_act.md) |
| `eval` | Task evaluation for debugging | [eval.md](../useful_plugins/eval.md) |
| `image_result_formatter` | Format images for vision models | [image_result_formatter.md](../useful_plugins/image_result_formatter.md) |
| `shell_approval` | Approve shell commands before execution | [shell_approval.md](../useful_plugins/shell_approval.md) |
| `tool_approval` | Web-based approval for dangerous tools | [tool_approval.md](../useful_plugins/tool_approval.md) |
| `ui_stream` | Stream agent events to WebSocket clients | [ui_stream.md](../useful_plugins/ui_stream.md) |
| `system_reminder` | Inject contextual reminders into tool results | [system_reminder.md](../useful_plugins/system_reminder.md) |
| `auto_compact` | Compact conversation when context gets large | [auto_compact.md](../useful_plugins/auto_compact.md) |
| `prefer_write_tool` | Guide agent to prefer write over edit for new files | [prefer_write_tool.md](../useful_plugins/prefer_write_tool.md) |
| `ulw` | Ultra-light workflow: pause loop for user input | [ulw.md](../useful_plugins/ulw.md) |
| `gmail_plugin` | Gmail OAuth flow | [gmail_plugin.md](../useful_plugins/gmail_plugin.md) |
| `calendar_plugin` | Google Calendar OAuth flow | [calendar_plugin.md](../useful_plugins/calendar_plugin.md) |

```python
from connectonion.useful_plugins import skills, re_act, eval, image_result_formatter, tool_approval

# Combine plugins
agent = Agent("assistant", plugins=[skills, tool_approval, re_act])
```

## Writing Custom Plugins

Simple example - log each tool execution:

```python
from connectonion import Agent, after_each_tool

def log_tool(agent):
    trace = agent.current_session['trace'][-1]
    print(f"✓ {trace['tool_name']} completed")

# Plugin = list of handlers
logger = [after_each_tool(log_tool)]

# Use it
agent = Agent("assistant", tools=[search], plugins=[logger])
```

For more complex plugins, see [Events](events.md) for available event hooks.

## Reusing Plugins

```python
# Define once
logger = [after_each_tool(log_tool)]

# Use across agents
researcher = Agent("researcher", tools=[search], plugins=[logger])
writer = Agent("writer", tools=[generate], plugins=[logger])
```

## Next Steps

- [Events](events.md) - Available event hooks
- [llm_do](llm_do.md) - Use LLM in handlers
- [Built-in Plugins](../useful_plugins/) - Detailed plugin docs
