About the Project

ChronosAI is a CP-SAT-first scheduling assistant. You describe your plans in plain English; the LLM only parses your intent into a strict schema, and a deterministic OR-Tools CP-SAT model does all time math, feasibility, and optimization. The result is explainable, safe scheduling with hard guarantees like “no overlaps” and “before the deadline.”

What inspired us

Most “AI calendars” let a model pick times directly, which is brittle for time zones, buffers, and conflicts. We flipped the pattern: • LLM: parsing only (extract structure, never schedule). • CP-SAT: constraint satisfaction + optimization (do the hard math deterministically).

This split keeps the system reliable, auditable, and predictable.

What we learned

• Separation of concerns works. Confine the LLM to natural-language understanding; keep feasibility/optimization in CP-SAT.
• Time zones matter. Normalize everything to tz-aware datetimes to avoid naive/aware comparison bugs.
• Follow-ups should be surgical. Ask for one missing fact (e.g., “How long should the meeting be?”) then proceed.
• Multi-item parsing is a superpower. One message can describe multiple tasks/meetings; the LLM emits an array of items ready for the solver.
• Environment-driven ops. Model choice and keys come from .env (ANTHROPIC_API_KEY, ANTHROPIC_MODEL), making deploys straightforward.

How we built it

• Frontend: Figma, React + TypeScript (Vite), Radix UI + Tailwind. A chat panel posts to POST /schedule-and-save, handles follow-ups inline, and renders placements.
• Backend: FastAPI + SQLAlchemy (SQLite by default).
• Parsing: parse_llm.py calls Anthropic (model from .env). The adapter returns either:
• a follow-up (single clarifying question + partial items), or
• a final parse (one or more fully specified items).
• Scheduling: CP-SAT receives the structured schema and solves with strict time limits, respecting:
• work hours, buffers, availability windows, deadlines
• no overlaps, task splitting with min/max session sizes
• spaced repetition: we spread blocks across days where possible to reinforce learning without cramming
• Sync: Google Calendar via Composio for simple OAuth + bidirectional sync.
• No regex fallback. The LLM is the single parser; we removed regex heuristics to keep a clean LLM→CP-SAT boundary.

Schema the LLM must output (per item):

{ "intent": "event|meeting|task", "title": "string", "start_dt": "ISO8601 or null", "deadline_dt": "ISO8601 or null", "availability_windows": [{"start":"ISO","end":"ISO"}], "duration_minutes": 30, "can_split": true, "confidence": { "overall": 0.0, "start_dt": 0.0, "deadline_dt": 0.0, "availability": 0.0, "duration_minutes": 0.0 }, "assumptions": ["notes the LLM inferred"] }

The scheduling math (at a glance)

We discretize time into slots (e.g., 15 minutes). For each item i with duration D_i (in slots) and feasible windows W_i, we build candidate starts [ \mathcal{S}i={\,t \mid [t,t+D_i)\subseteq W_i\,}. \] Meetings/events choose exactly one start: [ \sum{t\in\mathcal{S}i} x{i,t}=1. \] Tasks may split across blocks subject to min/max session lengths and daily caps. We enforce NoOverlap across all chosen intervals (existing busy + buffers + new placements).

Our objective (weighted sum) typically minimizes: [ \alpha \cdot \text{lateness} +\beta \cdot \text{fragmentation} +\gamma \cdot \text{energy_penalty} +\delta \cdot \text{churn}. \] Spaced repetition appears as a dispersion preference and per-day caps so blocks don’t cluster and never overlap.

Challenges we faced

• Finding the right algorithm. We explored greedy heuristics and dynamic programming, but they failed to respect the full set of interrelated constraints (buffers, windows, deadlines, splitting, daily caps). CP-SAT gave us the expressive constraints and guarantees we needed.
• Ensuring no overlaps, ever. Overlaps are disallowed via hard NoOverlap constraints; buffers are pre-expanded into busy intervals to keep gaps.
• Spaced repetition & healthy pacing. Spreading study blocks across days required explicit fragmentation penalties and daily caps to avoid back-to-back cramming.
• Model availability & configuration. Provisioning models can 404; we parameterized ANTHROPIC_MODEL and surfaced clear errors rather than silently falling back.
• Datetime correctness. We eliminated offset-naive datetimes and normalize everything with dateutil.tz.

What we’re proud of

• A crisp handoff: LLM emits a contract; CP-SAT enforces reality.
• Explainable results with reason codes and alternatives.
• Robust handling of multi-item requests, spaced repetition, and strict non-overlap—all with deterministic, time-bounded solves.

Tech notes

• Backend: FastAPI, OR-Tools CP-SAT, SQLAlchemy, Anthropic SDK
• Frontend: React + Vite, Radix UI, Tailwind
• Sync: Composio (Google Calendar)
• Config: .env (e.g., ANTHROPIC_API_KEY, ANTHROPIC_MODEL, DATABASE_URL)

With this architecture, ChronosAI stays friendly and conversational while still delivering hard scheduling guarantees.

Built With

Share this project:

Updates