forked from admin/VolcanicAgenticCore
Skill directories may now declare prompt or watcher jobs as files (cron or one-off at). The file is the source of truth: the scheduler re-reads every chat's jobs/ every minute, around agent runs and before /jobs and /skills, and schedules, re-plans or removes them. Ids are <skill>/<job>; run state lives in .volcanic/scheduler/skill-jobs-state.json, never in jobs.json. Watchers run from the skill directory with VOLCANIC_WORKSPACE and VOLCANIC_SKILL_DIR. Broken files are shown with the reason in /jobs, /skills, schedule list and the new <skill_jobs> prompt section; cancel answers with the file to edit. Every part of a skill directory is optional; file reading and frontmatter parsing move to Abstractions.
3.6 KiB
3.6 KiB
Skill jobs — design
Goal
Let a skill declare scheduled jobs as files: <workspace>/.volcanic/skills/<skill>/jobs/<job>.md, prompt or watcher,
cron or one-off at. Every part of a skill directory (SKILL.md, INSTRUCTIONS.md, scripts, jobs/) is optional, in any
combination. The owner's spec (2026-10-14) was accepted with the eight amendments below.
Decisions
- One scheduler, separate source. Skill jobs run in the process-wide
JobScheduler: one timer, the same script runner, script environment (GOOGLE_ACCESS_TOKEN), redaction, failure alerts without repeats, and the skip of an occurrence while the previous run is in flight. They are never written tojobs.json: the file is the source of truth.SyncSkillJobsAsync(target)re-reads the target's files and adds, re-plans (definition changed) or removes (file gone,enabled: false, broken) entries; an unchanged definition keeps its next run. Entries carryScheduledJob.Skill([JsonIgnore]), and their table key includes the target because<skill>/<job>is only unique per chat. - Sync points: on start (before overdue one-offs fire), every
Scheduler:SkillJobSyncInterval(1 min) for every deliverable known target, inSchedulerExtensiononbefore_agent_startandagent_end(a file the agent just wrote is in/jobsat once), and before/jobs,/skillsandschedule list. - State per workspace in
.volcanic/scheduler/skill-jobs-state.json: last run and result, theattext that fired (doneAt), and theattext last seen with when it was first seen. State of deleted files is dropped. - Amendments (accepted):
- The id comes from paths only:
<skill dir>/<file name without .md>.nameis a label. - The header carries the file:
[Scheduled job "<skill>/<job>" (skill job, .volcanic/skills/<skill>/jobs/<job>.md)]; the failure alert too. - An
atalready past (more than 60 s) when the bot first saw thatatnever fires and is shown as not scheduled; anatseen before it was due and missed while the bot was down fires late on start. - Sync every minute plus before and after each run (above).
- File reading and the simplified frontmatter parser live in Abstractions (
SkillFiles,Frontmatter), shared by the core'sSkillCatalogand the scheduler. Job files additionally cut YAML comments (#after whitespace). - The format and the chat's skill jobs go into the system prompt from
SchedulerExtension(<skill_jobs>), so sessions without the scheduler never advertise them. - Prompt text up to 16 KB.
enabled: falseunschedules the job; it stays listed asdisabled.
- The id comes from paths only:
- No frequency guard: cron has 5 fields (no seconds), so once a minute is the floor, and overlapping runs are skipped already.
- Limit:
Scheduler:MaxSkillJobsPerTarget(50), separate fromMaxJobsPerTarget; beyond it, files are listed as over the limit. At most 200 job files are read per workspace. - Watchers run from the skill directory with
VOLCANIC_WORKSPACEandVOLCANIC_SKILL_DIRadded after the environment filter; those paths are not redacted (only the host's extra values are). - Control is by files only:
/cancelandschedule cancelon a skill job id answer with the file to edit. - Errors aren't silent: missing
kind, neither or both ofcron/at, a watcher withoutcommand, an invalid cron,at,timeoutSecondsorenabled→ not scheduled, shown with the reason in/jobs,/skills,schedule listand the prompt section.
User docs
docs/telegram-bot.md#skill-jobs, and the skill directory rules under #skills.