Scheduler sends subagents and timed messages
Your agent can start subagents, schedule messages to itself, and message the rest of its team. Ask for a briefing at six, a check every hour, or three searches at once, and Link Harness has it on already.
lnk up agents # the agents plugins, Link Scheduler among them
lnk agent start # your agent, with its schedulerWhat it needs
You need the agents plugins, which lnk up agents installs and which
bring Link Scheduler, and a harness that reads who a message is from.
Link Harness does. There's nothing to set up, because each start gives
the agent its scheduler.
What your agent can do
Your agent can start a subagent, schedule a message to itself, and list
or cancel either. It sees them as four tools, scheduler__task,
scheduler__schedule, scheduler__list and scheduler__cancel.
task
task starts a subagent, a new conversation of its own that begins now
with the task it's given. The subagent has the same tools, or fewer if
task is given a list of names, and it sees nothing else of the
conversation it came from. It runs on the model task names, a model or
an alias of the spec's [model.aliases], else on the one its
conversation runs on. Its answer comes back to that conversation, so
your agent can start three, say so, and answer when they're in.
schedule
schedule sends your agent a message later in this conversation, at
a time such as 18:00, in a while such as 10m or 2h, or every so
often by cron, as 0 6 * * 1-5 for six on weekdays. Times are in the
agent's time zone, this machine's unless its spec names one. The answer
comes to you on this chat, or with answer = "nowhere" stays in the
conversation.
list and cancel
list shows what's scheduled in this conversation and the subagents it
started that haven't answered, the soonest 100 and how many more, and
cancel cancels one by its id. A conversation never sees or cancels
another's.
Asked first
Your agent does these without asking you. Set [tool.scheduler] ask = true in its spec and each waits for you to allow it, as any tool's call
you haven't allowed does (lnk sandbox asks). A message from a schedule
or a subagent is never taken for yours, and your agent is told who's
speaking.
Choose where a scheduled answer arrives
Ask for a joke on Telegram in three minutes, or a reminder on Discord.
The schedule tool's answer can name a connected service, such as
telegram, discord, slack or signal, or cli. The owner receives
the answer in their direct chat there; a CLI answer waits for an active
or newly opened CLI chat. here keeps the current chat and nowhere
keeps the result private. Delivery to an unconnected service fails
clearly. The agent's send tool sends immediately when no timer is
needed.
Message its team
On a team, your agent has
a fifth tool, scheduler__send, to message a teammate by its name, or
every member at once by the team's name. The message lands in the
teammate's conversation with your agent (or the team's), marked as
from your agent, and the teammate's answer comes back to the
conversation it was sent from, as a message from it, never from you.
So the member you text can hand out parts of a task, say it has, and
answer you once their answers are in.
lnk agent team create research --agent scout --agent writer --agent checkerWho it may send to
It may send only to the members of its teams, as their files say: each
teammate's bridge takes a message from another agent only when the two
share a team. Every message and every answer is a hop, so two members
answering each other stop at the cap on hops, and send says so.
Turn it off
Turn the scheduler off in your agent's
spec, which you give with
lnk agent start --spec <file>.
[tool.scheduler]
enabled = falseHow it runs
Your agent's bridge fires each job when it's due. The jobs are kept in
the agent's own folder (~/Link/Agents/<agent>/Agent/schedule), and
the bridge is the background service that carries its connections and
starts again with your computer.
One bridge for every agent
Where machine.toml says shared_bridge = true, one bridge carries
every agent, and one runner fires every agent's jobs in each time zone.
driver = "cron"
With [tool.scheduler] driver = "cron" in your agent's spec, your
computer's calendar wakes it instead, once a minute (launchd on a Mac,
cron elsewhere), so nothing of it runs between firings: lnk agent start puts the entry in place and lnk agent stop takes it away.
driver = "address"
On a machine that runs your agent only while it answers, [tool.scheduler] driver = "address": the scheduler tells the machine when your agent's
jobs are next due, each time they change, and the machine wakes your
agent then to fire them. Nothing of the scheduler runs between.
A firing that fails
A job is kept until its firing ends, and a restart loses nothing. A
message cut off by a restart may come twice. A firing that fails, say
because the bridge isn't up yet or the model provider is unreachable,
is tried again a minute later, then two, four, eight and sixteen
minutes later. After that it's given up, and the bridge's log says so.
A firing that takes longer than the agent's firing limit, 30 minutes
by default, is given up too, and never sent again.
A computer that was asleep
A computer that was asleep through a firing fires it once on waking, or
skips it, as [tool.scheduler] late says. A recurring job never fires
once for every time it missed.
Where the answer goes
The answer goes where the job says: to the chat, the owner's selected connection, or the conversation a subagent came from, or nowhere. The chat is the one you talk to your agent in, on Telegram, Slack, Discord or Signal, or a group where you talked to it, unless your agent's spec says it never answers in groups. On Signal the answer goes out while the agent's bridge is running, as it does whenever the agent is started.
Its limits and settings
Link's limits are 100 messages a day, 5 subagents at work at once, and
chains 8 deep, as when a subagent starts a subagent. They are keys of
your agent's spec under [tool.scheduler], and
Agent Spec lists them all.
The day's cap
The day is the one in the agent's time zone. Past the day's cap the tool says so and nothing fires: a job due once waits for the next day, and a recurring one for its next time. The cap is what bounds how many messages agents send each other.
More about it
Developing it, how its runner fires and where its jobs are kept: Developing, and the flags an agent's spec gives it: Scheduler Contract.
Docs
- Developing:
lnk-link-scheduleris Link Scheduler: subagents and schedules for any harness that reads who a message is from