Skip to content

[Feature] Declarative [[triggers]] in agent.toml (symmetric to cron_jobs) #5014

Description

@nevgenov

name: Feature Request
about: Suggest a new feature
labels: ["enhancement", "area/agents"]

Summary

Support a declarative [[triggers]] section in agent.toml (symmetric to existing [[cron_jobs]]), so event triggers can be version-controlled, migrated with agents, and recreated reproducibly after a fresh install / reset.

Motivation

Currently the only way to create event triggers (e.g. task_posted, task_claimed, task_completed for A2A delegation) is at runtime:

  • librefang trigger create <OWNER_ID> '<pattern_json>' --prompt ... (CLI)
  • POST /api/triggers (HTTP)

Triggers are persisted to ~/.librefang/trigger_jobs.json and survive daemon restarts in beta10. But:

  1. No declarative source of truth. Triggers live in an internal JSON blob, not in agent config. Operators write imperative bash/Python scripts (we maintain setup_a2a_triggers.py) just to bootstrap them. Such scripts are fragile (shell-escape vs subprocess-list-arg pitfalls, idempotency, etc.).
  2. Lost on reset / migration / fresh install. If librefang reset is run, or the user moves their agent dir to a new machine, all triggers vanish silently — only agent.toml and workspace files are reproducible, triggers are not.
  3. Inconsistent with cron_jobs. Cron jobs for an agent live declaratively in [[cron_jobs]] inside agent.toml. Triggers are conceptually the same reactive primitive (cron = schedule-based, trigger = event-based), but live in a totally different storage with a different lifecycle. This is surprising for operators.

Proposed Behavior

Add a [[triggers]] section to agent.toml:

[[triggers]]
pattern = { task_posted = {} }
prompt_template = """
New task assigned. Execute strictly in order:
1. task_claim() -- if returns empty, STOP immediately.
2. Perform the research thoroughly.
3. task_complete(task_id, result_string)
"""
max_fires = 0
cooldown_secs = 0
session_mode = "persistent"
target_agent = ""  # optional cross-session wake routing
enabled = true

On daemon start (or POST /api/agents/{id}/reload):

  1. Parse agent.toml [[triggers]].
  2. Reconcile with trigger_jobs.json for this agent:
    • Create missing (declared in TOML, not in JSON).
    • Optionally remove orphans (in JSON, not declared — under a reconcile_orphans = "warn"|"delete"|"keep" per-agent flag for safety, default keep).
    • Update mismatched (TOML wins on conflict).
  3. Triggers created purely via API/CLI (not declared in TOML) continue to work as today — TOML is additive.

Migration / Compat

  • Existing triggers in trigger_jobs.json continue to work — no schema change to runtime store.
  • A one-shot helper: librefang trigger export --agent <name> writes current runtime triggers as a [[triggers]] block to stdout for paste into agent.toml.

Use Case

Our A2A delegation setup needs 3 triggers wired across 2 agents:

Owner Pattern Action
researcher task_posted claim → execute → complete
nick-assistant (UI) task_claimed notify user "⚙️ Задача взята"
nick-assistant (UI) task_completed notify user with result

Today this requires setup_a2a_triggers.py (with notorious shell-escape bugs in subprocess list-args). With declarative [[triggers]] in each agent's agent.toml, it'd just be: git the dirs, daemon restart, done.

Symmetric to current [[cron_jobs]] of Дядька (which is already declarative in his agent.toml) — same conceptual layer.

Tested on 2026.5.8-beta.10.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/kernelCore kernel (scheduling, RBAC, workflows)has-prA pull request has been linked to this issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions