> ## Documentation Index
> Fetch the complete documentation index at: https://docs.clarkos.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Social Agent

> An agent that engages across social platforms

## Overview

This example shows how to build a social agent that posts content based on mood and implements cooldown timers. It demonstrates mood-gated behavior and plugin patterns for social integrations.

<Card title="View Source" icon="github" href="https://github.com/clarkOS/clark/tree/main/example/convex">
  See the complete example agent implementation on GitHub
</Card>

## What It Does

* Posts content only when agent is expressive and healthy
* Implements cooldown timers between posts
* Logs activity for monitoring
* Supports multiple platforms via configuration

## Architecture

```
Tick ──► Mood Check ──► Expressive? ──► Cooldown Check ──► Post
                  │
                  └──► Other moods ──► Monitor only
```

The key insight: agents don't always need to post. They wait for the right conditions.

## Social Plugin

A plugin that manages posting with cooldowns:

**Key features:**

* Configurable cooldown period
* Mood and health gating
* Multi-platform support
* Actions: `post(content, platform)`, `getStatus()`

```typescript theme={null}
export function createSocialPlugin(config: {
  postCooldownMinutes: number;
  platforms: string[];
}): Plugin {
  let lastPostTime = 0;

  const canPost = () => Date.now() - lastPostTime > config.postCooldownMinutes * 60 * 1000;

  return {
    name: "social",
    version: "1.0.0",

    onTick(context) {
      // Only post when conditions are right
      if (context.state.mood === "expressive" && context.state.health > 50 && canPost()) {
        console.log("Ready to post");
      }
    },

    actions: {
      async post(params) { /* ... */ },
      async getStatus() { /* ... */ }
    }
  };
}
```

**Reference:** See the [`src/plugins`](https://github.com/clarkOS/clark/tree/main/example/convex/src/plugins) directory in the example agent.

## Logger Plugin

A simple companion plugin for monitoring:

```typescript theme={null}
export const loggerPlugin: Plugin = {
  name: "logger",
  version: "1.0.0",

  onTick(context) {
    console.log(`Mood: ${context.state.mood}, Health: ${context.state.health}`);
    console.log(`Memories: ${context.memories.length}`);
  }
};
```

## Agent Setup

```typescript theme={null}
const agent = new Agent({
  backend: new ConvexBackend({ url: process.env.CONVEX_URL }),
  plugins: [
    loggerPlugin,
    createSocialPlugin({
      postCooldownMinutes: 60,  // 1 hour between posts
      platforms: ["twitter", "discord"],
    }),
  ],
});
```

## Mood-Based Posting

The agent only posts when:

1. **Mood is expressive** — Agent has something to share
2. **Health is above 50** — Agent has capacity
3. **Cooldown has elapsed** — Prevents spam

This creates natural, periodic engagement rather than constant output.

## Rate Limits

Respect platform limits in your implementation:

| Platform | Limit                                |
| -------- | ------------------------------------ |
| Twitter  | \~300 tweets per 3 hours             |
| Discord  | 5 messages per 5 seconds per channel |

Build in cooldowns that exceed these limits to stay safe.

## Running

```bash theme={null}
npm run dev

# Check social plugin status
curl http://localhost:3001/actions/social/getStatus

# Manual post (for testing)
curl -X POST http://localhost:3001/actions/social/post \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"content": "Hello world", "platform": "twitter"}'
```

## Best Practices

* **Quality over quantity** — Let mood naturally gate output
* **Respect rate limits** — Build in generous cooldowns
* **Log everything** — Track all posts for debugging
* **Start conservative** — Begin with longer cooldowns, reduce as needed

## Next Steps

<CardGroup cols={2}>
  <Card title="Basic Agent" href="/examples/basic-agent">
    Review the fundamentals.
  </Card>

  <Card title="Custom Plugins" href="/guides/custom-plugins">
    Build your own integrations.
  </Card>
</CardGroup>
