Scheduling
Cron-based automation for agents using APScheduler. Schedule recurring tasks with timezone support, execution history, and manual triggers.
Concepts
misfire_grace_time=3600, coalesce=True, max_instances=1).
Creating Schedules
Open the agent detail page and go to the scheduling section.
Click Create Schedule.
Configure: name, cron expression (e.g., 0 9 * * 1-5 for weekdays at 9 AM), message/task, timezone, and description.
Optionally select a model override (Opus, Sonnet, Haiku, or custom).
Enable or disable individual schedules with the toggle.
View execution history with status, duration, and cost.
Click Run Now to trigger a schedule immediately.

Execution Flow
Scheduler fires and sends a POST to /api/internal/execute-task with async_mode=True.
Backend spawns a background task and returns immediately.
Scheduler polls the database every 10 seconds until execution completes.
Execution record is updated with response, cost, and duration.
Schedule API
| Endpoint | Method | Description |
|---|---|---|
| /api/agents/{name}/schedules | GET | List schedules |
| /api/agents/{name}/schedules | POST | Create schedule |
| /api/agents/{name}/schedules/{id} | GET/PUT/DELETE | CRUD operations |
| /api/agents/{name}/schedules/{id}/enable | POST | Enable schedule |
| /api/agents/{name}/schedules/{id}/trigger | POST | Manual trigger |
| /api/agents/{name}/schedules/{id}/executions | GET | Execution history |
Skills and Playbooks
Platform-managed skills that can be assigned to agents and invoked from the UI via the Playbooks tab or chat autocomplete.
Key Concepts
SKILL.md) stored in the platform's skills library./ in the Chat tab to see available playbooks with ghost text showing command syntax.Managing Skills (Admin)
Go to Settings or the Skills admin page.
Sync the skills library from GitHub.
Create, edit, or delete skills (full CRUD). View skill details and usage.
Assigning Skills (Owner)
Open the agent detail page, go to the skills/playbooks section, and assign skills from the library. Skills are injected on the next agent start.
Running Playbooks (User)
Open agent detail, click the Playbooks tab, and click Run on a playbook. Or type / in the Chat tab to autocomplete a playbook command.
Skill Injection on Agent Start
When an agent starts, all assigned skills are written to the agent's .claude/commands/ directory. The agent can then use them as slash commands during execution.

Approvals
Human-in-the-loop approval gates for process engine workflows. Processes pause at approval steps and wait for human decisions before continuing.
A process execution reaches a human_approval step. The step pauses the process (status: PAUSED).
An approval request appears in the Approvals inbox (accessible from the navigation bar).
The approver sees the process name, step description, context, and who requested it.
The approver can Approve or Reject, with an optional comment.
On approval, the process continues. On rejection, the execution is cancelled or follows the rejection path. Approvals can have configurable timeouts.
A approval_required WebSocket event is fired when a process needs human approval.
Approval API
| Endpoint | Method | Description |
|---|---|---|
| /api/approvals | GET | List pending approvals |
| /api/approvals/{id} | GET | Get approval details |
| /api/approvals/{id}/decide | POST | Submit decision (approve/reject) |
Automatic Retry
Failed executions can automatically retry with configurable delay and attempt limits.
Configuration
| Field | Default | Range | Description |
|---|---|---|---|
| max_retries | 1 | 0-5 | Max retry attempts (0 = disabled) |
| retry_delay_seconds | 60 | 30-600 | Delay between retries |
Retry Behavior
Execution fails (error or timeout)
If max_retries > 0 and attempts remain, scheduler waits retry_delay_seconds
Rate-limit errors (429) use 2x delay, capped at 300 seconds
Retry creates a new execution record linked to the original
Process repeats until success or max retries exhausted
Execution Statuses
| Status | Meaning |
|---|---|
| pending_retry | Failed, retry scheduled but not yet fired |
| running | Retry in progress |
| success / failed | Final outcome |
MCP Tools
| Tool | Description |
|---|---|
| list_agent_schedules(name) | List schedules |
| create_agent_schedule(name, ...) | Create schedule |
| get_agent_schedule(name, id) | Get schedule details |
| update_agent_schedule(name, id, ...) | Update schedule |
| delete_agent_schedule(name, id) | Delete schedule |
| toggle_agent_schedule(name, id) | Enable or disable |
| trigger_agent_schedule(name, id) | Manual trigger |
| get_schedule_executions(name, id) | Execution history |
Pre-Check Hook
An optional executable shipped by an agent template that gates each cron tick before Claude is invoked. When present, it lets the agent decide at runtime whether the scheduled work is actually needed — so empty polls (no new PRs, no new emails, no alerts) consume zero tokens.
How It Works
Template ships ~/.trinity/pre-check as an executable file with a shebang
Before each scheduled cron tick, Trinity runs the file inside the agent container
Scheduler acts on the output (see table below)
| Pre-check result | Scheduler action |
|---|---|
No ~/.trinity/pre-check file | Fire as usual (backward-compatible) |
| Exit 0, non-empty stdout | Fire — stdout becomes the chat message (overrides schedule's configured message) |
| Exit 0, empty stdout | Skip — record a skipped execution row, no Claude invocation, zero cost |
| Exit non-zero | Fail-open — log the error and fire with the original message |
| Timeout (>60s) or error | Fail-open — fire with the original message |
Key Behaviors
skipped, zero cost, and a reason string. They do not count against retry limitsFor Template Authors
Place the hook at ~/.trinity/pre-check (no extension), make it executable (chmod +x), and include a shebang. The hook receives no arguments. Print a work description to stdout if there is work, or print nothing if there is nothing to do.
#!/usr/bin/env python3
import sys
# ... check for new items ...
if new_items:
print(f"Review {len(new_items)} new PRs: {', '.join(new_items)}")
# else: exit 0 with empty stdout → Trinity records a skipPer-Schedule Timeout
Each schedule has its own timeout_seconds. It cannot exceed the agent's execution_timeout_seconds cap:
timeout_seconds > agent.execution_timeout_seconds returns 400 error=schedule_timeout_exceeds_agent_cap.400 error=agent_timeout_below_active_schedules.Raise the agent cap first, then raise the schedule timeout.
Limitations
developer user inside the container).