Skip to content
LVIS AI
EN|KO

Routines

RoutineEngineV2 — Two Triggers

LVIS's routine engine is a single implementation at src/routines/v2/routine-engine-v2.ts (v2-only). Only two triggers exist: 'shutdown' and 'schedule.' Each routine fire creates a brand-new dedicated ConversationLoop instance, isolated from the interactive main loop.

src/routines/v2/routine-engine-v2.ts
trigger: shutdown | schedule
per-fire fresh loop

schedule

Uses a cron-like expression. Evaluator: src/routines/cron-evaluator.ts. Examples: every day at 09:00, every Friday at 17:00.

shutdown

Fired by the host right before it exits. Used for daily cleanup, daily backups, or reporting.
Event/combination triggers belong to the detector, not the routine
Event-based automation such as a mail arriving or a meeting ending is handled by the Work Assistant's detector, not a routine. A Routine is a simple engine with only two triggers: "time" or "shutdown."

Registering a Routine (mockup)

Routine — schedule type example

Trigger

trigger: "schedule"
cron: "0 9 * * 1-5"

Conversation seed

  1. user: "Put together the daily briefing"
  2. → work_assistant_generate_daily_briefing
  3. → Result shown as a card in the chat body

Firing stages

  1. 01

    Registration — UI or plugin manifest

    The user adds one from the RoutinePanel, or a plugin manifest provides the routine-provider capability together with a recommended routine.

  2. 02

    Scheduler registration

    src/main/routines-scheduler.ts books the time trigger with an OS timer. The shutdown trigger is registered on the host's lifecycle hook.

  3. 03

    Per-fire fresh ConversationLoop

    isolation

    A new ConversationLoop instance is created at fire time. It is isolated from the interactive main loop's memory / permissions / TODOs.

  4. 04

    Session recording

    The message stream and tool calls for a single fire are appended as JSONL to ~/.lvis/routine/sessions/<routineId>/<firedAt>.jsonl.

  5. 05

    Result surfaced

    On completion, a "routine run complete" card appears in the chat body. On failure, it goes to the audit log and the next fire proceeds normally.

The 'Q9 isolation lock' name doesn't exist in code
The concept older docs / CLAUDE.md refer to as "Q9 isolation lock" is implemented in code as the "per-fire fresh ConversationLoop" pattern (comment at routine-engine-v2.ts:5-7). The literal identifier Q9 does not appear anywhere in the source.