Skip to main content

🧠 context-driven-llm-scheduler

Context-driven scheduled tasks for LLMs with persistent memory.

PyPI version Python versions License: MIT


Most scheduled tasks and cron jobs are stateless — they wake up with no memory of prior runs.

context-driven-llm-scheduler solves this by giving LLM-powered recurring tasks persistent context and memory across executions.

It lets you build reliable, intelligent scheduled agents that remember what they've seen, what they've done, and what still needs attention.

Inspired by the Heartbeat pattern from OpenClaw.

What is context-driven-llm-scheduler?

context-driven-llm-scheduler is a lightweight Python library for defining and running memoryful LLM scheduled tasks (called pulses).

You define each pulse in a markdown file (schedule, memory rules, model, and instructions). The library handles the complex parts:

  • Recalling relevant memory and context from previous runs
  • Assembling token-efficient prompts (with transparent trimming)
  • Atomic persistence of the LLM's decisions
  • Built-in deduplication (seen) and rate-limiting (throttle)

You bring your own scheduler, LLM adapter, and storage backend (or use some default options we provide).

Features

  • Markdown-first configuration — prompts, schedules, and rules are easy to edit
  • True persistent memory — notes, seen items, key-value facts, throttles
  • No lock-in — compatible with cron, APScheduler, Lambda, Airflow, etc.
  • Production-ready — concurrency-safe, atomic transactions, honest token budgeting
  • Minimal dependencies

Quickstart

1. Create a pulse definition at pulses/inbox-triage.md:

---
id: inbox-triage
schedule: "*/15 * * * *"
throttle: { notify: 1h }
keep: { notes: 20, seen: 500 }
model: anthropic/claude-sonnet-4-6
---

You are my inbox triage assistant.

For each new urgent email:
- Decide if it genuinely needs my attention.
- If yes and the `notify` throttle allows, alert me and record the throttle.
- Always mark the email as `seen`.

Be conservative. Never notify about the same thing twice.

2. Wire it up in Python:

from context_driven_llm_scheduler import PulseManager, FileStore, LiteLLMAdapter

manager = PulseManager.from_dir("pulses", FileStore("./state"))
adapter = LiteLLMAdapter("anthropic/claude-sonnet-4-6")

@manager.pulse("inbox-triage")
def triage(pulse, extra=None):
    prompt = pulse.recall(extra={"emails": fetch_urgent_emails()})
    ops = adapter.propose_memory_ops(prompt)
    return pulse.persist(ops)

3. Trigger the pulse:

manager.trigger("inbox-triage")   # Call from cron, scheduler, Lambda, etc.

Core Concepts

The Pulse Interface

Pull Data into the LLM Context Before the Scheduled Job

pulse.recall(...) — assembles instructions + historical memory + fresh input data

Store Data After the Scheduled Job

pulse.persist(ops) — atomically applies the LLM's structured memory operations

Supported Memory Operations

The LLM outputs operations via tool calling:

note — free-text observation seen — mark item as handled (deduplication) throttle — record action for rate limiting set / forget — key/value persistent facts

Multi-tenant pulses

If your product runs the same recurring task for many customers — one readiness check per team, one digest per account, one monitor per project — two things usually get in the way:

  1. Shared memory. By default a task keeps a single memory. Run it for 50 teams and they all write to the same notebook, so one team's history overwrites another's.
  2. Fixed, file-based setup. By default a task is defined in a file and registered when the app starts. But in a real product each customer's rule lives in your database and changes over time — you want to run the rule you just fetched, right now.

These two capabilities remove both walls:

  • Per-customer isolation — run one shared task separately for each customer, each with its own private memory. You tell the library which customer a run is for (instance=); it keeps them apart. One customer's run can never see or overwrite another's history. Runs with no customer specified behave exactly as before.
  • Run a rule on the fly — take a task description straight from your database and run it immediately, with no need to register it ahead of time (trigger_definition(...)).

Put together: one rule, authored per customer and stored in your database, runs on its own schedule for each customer with fully separate memory.

from context_driven_llm_scheduler import PulseDefinition

# Each team's rule is a markdown doc stored in your database.
# Build it at call time and run it for that team, with isolated memory.
definition = PulseDefinition.from_markdown(rule_body, default_id="readiness-check")

for team_id in active_teams:
    manager.trigger_definition(definition, readiness_check, instance=team_id)

Every team_id shares the one readiness-check rule but keeps its own memory; the single readiness_check handler never has to deal with a team id itself. See examples/multi_tenant_pulses.py.

Installation

pip install context-driven-llm-scheduler

Optional extras:

pip install "context-driven-llm-scheduler[litellm,sqlite,scheduler]"

Examples

See the examples/ directory.

Metadata

Release files for context-driven-llm-scheduler 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for context-driven-llm-scheduler 1.1.0
File Size Uploaded Provenance Actions
context_driven_llm_scheduler-1.1.0.tar.gz 44.3 kB Without provenance Details for context_driven_llm_scheduler-1.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for context-driven-llm-scheduler 1.1.0
File Interpreter ABI Platform Actions
context_driven_llm_scheduler-1.1.0-py3-none-any.whl Python 3 none any Details for context_driven_llm_scheduler-1.1.0-py3-none-any.whl

Total release size: 82.9 kB

Release files / context_driven_llm_scheduler-1.1.0.tar.gz

Download URL context_driven_llm_scheduler-1.1.0.tar.gz
Size 44.3 kB
Tags Source
SHA-256 checksum
How to use checksums
f86772449847f1d83b63fc81e1a3c8d6bfd66d27f1acab8a70c671c720c6a993
BLAKE2b-256 checksum
How to use checksums
e97b9a800ff56045e7a01d1c2fe4ab2b352df517a66e4e764d31f405235f4634
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.24 {"installer":{"name":"uv","version":"0.9.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / context_driven_llm_scheduler-1.1.0-py3-none-any.whl

Download URL context_driven_llm_scheduler-1.1.0-py3-none-any.whl
Size 38.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
aaaac640e79ef352393e91a63647007770a270d6777ef2b638b1f19b4a2a2d74
BLAKE2b-256 checksum
How to use checksums
6041440a40f33aa42a3e9c020b9c0d5505d0ad5ceefe30fad843026c97cf44cf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.24 {"installer":{"name":"uv","version":"0.9.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for context-driven-llm-scheduler 1.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page