Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.crewship.ai/llms.txt

Use this file to discover all available pages before exploring further.

Agent Scheduling

Crewship includes a built-in scheduler that triggers agent runs on a cron schedule. Scheduled runs are fully autonomous — the agent receives a prompt, executes inside its crew container, and the result is recorded as a run with the SCHEDULED trigger type.

How It Works

The scheduler is a background goroutine that manages a pool of cron jobs, one per enabled agent schedule. On startup it loads all agents with schedule_enabled = 1 from the database and registers their cron expressions. Each tick of a cron job triggers a full agent run cycle.
Scheduler goroutine
    |
    v
cron library fires at scheduled time
    |
    v
triggerAgent(agent)
    |
    +--> Create chat session (deterministic ID)
    +--> Resolve chat (credentials, system prompt, skills)
    +--> Ensure crew container is running
    +--> Create run record (trigger: SCHEDULED)
    +--> Execute agent via orchestrator.RunAgent
    +--> Update run record (COMPLETED or FAILED)
    +--> Update schedule_last_run and schedule_next_run

Enabling a Schedule

Schedules attach to a saved routine (pipeline) and fire it on a cron expression. Manage them via crewship routine schedules:
SubcommandPurpose
list [--slug <routine>]List schedules in this workspace, optionally filtered by target routine.
create --slug <routine> --cron '<expr>' [--name ...] [--timezone <IANA>] [--inputs <json>] [--enabled=false]Create a schedule. --slug and --cron are required; defaults to UTC and enabled.
update <id> [--cron ...] [--timezone ...] [--name ...] [--enabled / --enabled=false] [--inputs <json>]Patch one or more fields.
enable <id>Enable a paused schedule (fires on next 30 s tick).
disable <id>Pause a schedule without deleting it.
now <id>Force-fire out of cycle (useful for smoke tests).
delete <id> [--yes]Permanently delete; prompts for confirmation unless --yes.
crewship routine schedules create --slug summarize-text \
  --name "daily-summary" --cron "0 9 * * *" --inputs '{"text":"..."}'
crewship routine schedules list --slug summarize-text
crewship routine schedules now <schedule_id>
The same operations are also available on the REST API under /api/v1/workspaces/{ws}/pipeline-schedules — the CLI is a thin wrapper around those endpoints, so server-side behavior (cron parsing, 30 s tick resolution, timezone handling) is identical.
Per-agent schedule_cron fields described elsewhere in this guide are a separate legacy path. New work should go through crewship routine schedules against a saved routine.

Cron Expression Format

The scheduler uses standard 5-field cron expressions:
┌───────────── minute (0-59)
│ ┌───────────── hour (0-23)
│ │ ┌───────────── day of month (1-31)
│ │ │ ┌───────────── month (1-12)
│ │ │ │ ┌───────────── day of week (0-6, Sun=0)
│ │ │ │ │
* * * * *
Examples:
ExpressionSchedule
0 9 * * 1-5Every weekday at 9:00 AM
*/15 * * * *Every 15 minutes
0 0 * * *Daily at midnight
30 8 1 * *8:30 AM on the 1st of every month
0 */2 * * *Every 2 hours
Invalid cron expressions are rejected at registration time. The API call will return an error if the expression cannot be parsed.

Execution Flow

Each scheduled trigger follows this sequence:

1. Chat Session Creation

A new chat session is created with a deterministic ID (format: sched_{unixnano}_{random_hex}). The chat title is set to "Scheduled: {agent_name}".

2. Chat Resolution

The ResolveChat call loads the full agent context: credentials, system prompt, skills, MCP servers, network policy, and crew membership. This ensures the scheduled run has the same capabilities as an interactive run.

3. Container Management

If a container provider is configured, the scheduler ensures the crew container is running before execution. Default resource limits:
ResourceDefault
Memory4096 MB
CPUs2.0

4. Run Record

A run record is created with trigger type SCHEDULED before execution begins. Metadata includes the CLI adapter, crew info, and a scheduled tag.

5. Agent Execution

The agent runs through orchestrator.RunAgent with the same pipeline as interactive runs: sidecar proxy, credential injection, memory, and conversation history.

6. Result Recording

After execution completes, the run record is updated with:
  • Status: COMPLETED or FAILED
  • Duration in milliseconds
  • Cost and usage metadata (if available from the LLM provider)
The assistant response is persisted to the conversation store and the message count is incremented.

Timeout

Each scheduled run has a 45-minute timeout. If the agent does not complete within this window, the context is cancelled and the run is marked as failed.
ctx, cancel := context.WithTimeout(s.ctx, 45*time.Minute)
This is separate from the per-agent timeout_secs setting, which controls the LLM execution timeout within the container. The 45-minute limit is the outer boundary for the entire scheduled run cycle including container startup and chat resolution.

Monitoring

Timestamp Fields

The scheduler maintains two fields on each agent:
FieldUpdatedDescription
schedule_last_runAfter each runISO 8601 timestamp of the last completed run
schedule_next_runAfter each run and on schedule updateISO 8601 timestamp of the next scheduled run
These fields are updated even on error — schedule_next_run always reflects the next trigger time so monitoring dashboards stay accurate.

Run Records

Scheduled runs appear in the standard agent runs list with trigger = "SCHEDULED":
# List scheduled runs for an agent
curl http://localhost:8080/api/v1/agents/{id}/runs?trigger=SCHEDULED
Each run record contains:
  • trigger: "SCHEDULED"
  • tags: ["scheduled", "{cli_adapter}"]
  • duration_ms: execution time
  • total_cost_usd: LLM cost (if reported)
  • num_turns: conversation turns
  • status: COMPLETED or FAILED

Dynamic Updates

When an agent’s schedule is modified via the API, the scheduler hot-reloads the cron entry without restart. The UpdateSchedule method:
  1. Removes the old cron entry (if any)
  2. Registers the new cron expression
  3. Immediately calculates and persists the next run time
Disabling a schedule (schedule_enabled: false) removes the cron entry and stops future triggers. The schedule_last_run timestamp is preserved for audit purposes.

Error Handling

If any step in the trigger pipeline fails (chat creation, resolution, container startup), the scheduler:
  1. Logs the error
  2. Updates schedule_next_run to the next trigger time
  3. Does not update schedule_last_run (only updated on successful execution start)
The next scheduled trigger will attempt the full pipeline again. There is no exponential backoff — the cron schedule determines retry timing.

What’s Next

  • Orchestration — multi-agent missions with task dependencies
  • Keeper — persistent agent memory