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 scheduler

What 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 checker

Who 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 = false

How 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-scheduler is Link Scheduler: subagents and schedules for any harness that reads who a message is from