← Back to Plugins
Tools

Cron Memory

easternbloc By easternbloc 👁 16 views ▲ 0 votes

An OpenClaw plugin that gives cron jobs persistent memory. Isolated cron runs normally have zero context about their previous outputs โ€” this plugin captures every cron output into a SQLite database and makes it available for both future cron runs and regular chat sessions.

GitHub

Install

npm install
```

Configuration Example

{
  "plugins": {
    "load": {
      "paths": ["~/projects/openclaw-cron-memory"]
    },
    "entries": {
      "cron-memory": {
        "enabled": true
      }
    }
  }
}

README

# openclaw-cron-memory

An [OpenClaw](https://github.com/openclaw/openclaw) plugin that gives cron jobs persistent memory. Isolated cron runs normally have zero context about their previous outputs โ€” this plugin captures every cron output into a SQLite database and makes it available for both future cron runs and regular chat sessions.

## The Problem

OpenClaw cron jobs with `sessionTarget: "isolated"` start with a fresh session every run. The agent has no idea what it said last time. If you ask your agent in chat "what did you find in yesterday's daily report?", it has no way to answer.

## What This Plugin Does

```
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  CRON RUN                                           โ”‚
โ”‚                                                     โ”‚
โ”‚  before_agent_start โ†’ injects last N run summaries  โ”‚
โ”‚  agent does its work with prior context             โ”‚
โ”‚  agent_end โ†’ captures output to SQLite              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  REGULAR CHAT                                       โ”‚
โ”‚                                                     โ”‚
โ”‚  User: "from your daily report, what was the        โ”‚
โ”‚         API error rate?"                            โ”‚
โ”‚  Agent calls cron_history_search โ†’ finds the run    โ”‚
โ”‚  Agent calls cron_history_get โ†’ reads full output   โ”‚
โ”‚  Agent: "Yesterday's report showed 2.3% error rate" โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
```

**Cron-to-cron continuity:** Each cron run gets the last N summaries injected as context, so it knows what happened before.

**Chat-to-cron recall:** Three tools (`cron_history_search`, `cron_history_get`, `cron_history_list`) are available in all sessions. Zero tokens wasted until the agent actually needs the data.

## Installation

### Prerequisites

- OpenClaw with plugin support
- Node.js 20+

### Setup

```bash
# Clone or create the plugin directory
git clone <this-repo> ~/projects/openclaw-cron-memory
cd ~/projects/openclaw-cron-memory
npm install
```

Add to your OpenClaw config (`~/.openclaw/openclaw.json`):

```json
{
  "plugins": {
    "load": {
      "paths": ["~/projects/openclaw-cron-memory"]
    },
    "entries": {
      "cron-memory": {
        "enabled": true
      }
    }
  }
}
```

Restart the gateway. The plugin will create its database automatically on first use.

### Verify It Loaded

```bash
openclaw cron-memory stats
```

You should see the database path and a run count (0 until your first cron job fires).

## Configuration

All settings are optional โ€” defaults are sensible for most setups.

```json
{
  "plugins": {
    "entries": {
      "cron-memory": {
        "enabled": true,
        "config": {
          "dbPath": "~/.openclaw/memory/cron-memory.sqlite",
          "maxHistoryPerJob": 50,
          "contextEntries": 3,
          "maxContextChars": 2000,
          "retentionDays": 90
        }
      }
    }
  }
}
```

| Setting | Default | Description |
|---------|---------|-------------|
| `dbPath` | `~/.openclaw/memory/cron-memory.sqlite` | SQLite database location |
| `maxHistoryPerJob` | `50` | Max stored runs per cron job (oldest pruned) |
| `contextEntries` | `3` | How many recent runs to inject as context for cron sessions |
| `maxContextChars` | `2000` | Max characters for the injected context block |
| `retentionDays` | `90` | Auto-prune records older than this |

## Agent Tools

These tools are available in **all** sessions (cron, DM, group, web):

### `cron_history_search`

Keyword search across all cron outputs.

```
Query: "API error rate"
โ†’ Finds runs where output/summary/job name matches
```

### `cron_history_get`

Fetch full output for a specific run (by ID) or the most recent runs for a job (by job ID).

```
Job ID: "daily-report", Limit: 3
โ†’ Returns the last 3 full outputs from daily-report
```

### `cron_history_list`

List all jobs with run counts and last run info. Useful for discovering what jobs exist.

## CLI Commands

```bash
# Show database stats
openclaw cron-memory stats

# List recent runs (all jobs)
openclaw cron-memory list
openclaw cron-memory list --job daily-report --limit 5

# Search outputs
openclaw cron-memory search "error rate"
openclaw cron-memory search "migration" --job db-check

# Show full output of a specific run
openclaw cron-memory show <run-id>

# Clean up old records
openclaw cron-memory prune --days 30
```

## How It Works

### Capture (agent_end hook)

After every agent run, the plugin checks if the session key matches the cron pattern (`agent:*:cron:*`). If so, it:

1. Extracts the assistant's output from the run messages
2. Parses the job ID from the session key and job name from the cron prompt
3. Generates a summary (first paragraph, up to 500 chars)
4. Stores everything in SQLite
5. Prunes excess runs per job if over the limit

### Recall โ€” Cron Sessions (before_agent_start hook)

When a cron job starts, the plugin queries the last N runs for that job and injects them as a `<cron-history>` context block via `prependContext`. This is token-efficient:

- Fixed small context (default 2000 chars max)
- Only summaries, not full outputs
- Only injected for cron sessions, not regular chat

### Recall โ€” Regular Chat (tools)

The three `cron_history_*` tools are registered globally. When a user references a cron output in conversation, the agent calls the appropriate tool. Zero tokens wasted until needed.

### Maintenance (background service)

A daily background prune removes records older than `retentionDays`. The `pruneExcessPerJob` runs after every capture to keep per-job history bounded.

## Development

```bash
# Run tests
npm test

# Watch mode
npm run test:watch

# Typecheck
npm run typecheck

# Both
npm run check
```

### Testing

- **DB tests** (`src/db.test.ts`): Full CRUD, search, and pruning coverage using temporary SQLite files
- **Helper tests** (`index.test.ts`): Session key parsing, message extraction, summary generation, context formatting, config validation

## Token Budget

| Session Type | Token Cost |
|-------------|-----------|
| Cron run | ~200-500 tokens (injected context block with last 3 summaries) |
| Regular chat (no cron reference) | 0 tokens |
| Regular chat (user asks about cron) | Variable โ€” only the tool result payload |

## Security

Cron outputs may contain sensitive data (API keys in error traces, internal hostnames, user data). Keep this in mind:

- The SQLite database lives at `~/.openclaw/memory/cron-memory.sqlite` by default โ€” ensure the directory has appropriate permissions (`chmod 700 ~/.openclaw/memory`)
- Set `retentionDays` to match your data retention policies โ€” shorter is safer
- The `pruneExcessPerJob` cap prevents unbounded storage growth
- Cron outputs are stored as-is; no redaction is applied. If your cron jobs handle secrets, consider filtering them at the job prompt level

## Compatibility

Tested with OpenClaw 2026.2.x+. Requires plugin hook support (`agent_end`, `before_agent_start`, `registerTool`, `registerCli`, `registerService`).

## License

MIT
tools

Comments

Sign in to leave a comment

Loading comments...