Skip to content
Changelog

CompanyOS automation runs hourly, on a cron you can set

October 22, 20261 min read

Agno's CompanyConfig now takes a cron_expr that controls how often CompanyOS checks Ready Tasks and authorized Routine proposals. AgentOS writes that value to the runtime-owned Company automation schedule at startup, and the default "0 * * * *" fires at the top of every hour.

Earlier releases created the schedule with a one-minute cron. On the first start after the upgrade, AgentOS finds the old * * * * * row, rewrites its cron and recomputes next_run_at. We started AgentOS three times against one SQLite database, once on the previous release and twice on this one:

Real output from three AgentOS starts on one SQLite database at 21:34 UTC. Before, the Company automation schedule has cron_expr star star star star star and next_run_at 21:35:00 UTC. Now, after a restart on this release, cron_expr is 0 star star star star and next_run_at is 22:00:00 UTC. With CompanyConfig cron_expr set to every five minutes, next_run_at is 21:35:00 UTC.

With the default, a Ready Task or an auto-accepted Routine proposal can wait up to an hour for pickup. A person can still start a Task right away with POST /company/tasks/{task_id}/runs. A deployment that wants the old pace sets the cron back:

agent_os = AgentOS(
    db=db,
    company=CompanyConfig(cron_expr="* * * * *"),
    scheduler=True,
)

CompanyConfig refuses an empty value when you build it. Anything else that is not a cron expression builds fine and is caught at AgentOS startup, by the scheduler's own cron validator, before the poller runs. Both errors below are real output:

# raised by CompanyConfig
CompanyConfig(cron_expr="")
ValueError: cron_expr must be a cron expression
 
# raised when an AgentOS carrying this config starts up
CompanyConfig(cron_expr="every hour")
ValueError: Invalid cron expression: every hour

This release also renames the six Company tools that act on a single Product. Models see the new names, and the earlier names no longer exist, so update any agent or Routine instructions that mention them. The methods on CompanyTools change the same way, including the async versions with an a prefix such as aread_product_source. Company-wide tools and HTTP routes keep their names.

Earlier nameNew name
list_company_sourceslist_product_sources
add_company_sourceadd_product_source
read_company_sourceread_product_source
intake_company_sourceintake_product_source
create_company_routinecreate_product_routine
update_company_statusupdate_product_status

See the cookbook, and learn more about the AgentOS scheduler in the documentation.

Frequently asked questions

Once an hour. The Company automation schedule uses the cron 0 * * * * unless you pass a different cron_expr to CompanyConfig.

Pass CompanyConfig(cron_expr="* * * * *") to AgentOS and restart it. AgentOS writes the new cron to the Company automation schedule and recomputes its next due time during startup.

No. When AgentOS starts with the scheduler enabled, it compares the stored schedule with CompanyConfig.cron_expr and updates the row if they differ, so an old one-minute schedule becomes hourly on its own.

The six tools that act on a single Product: list_product_sources, add_product_source, read_product_source, intake_product_source, create_product_routine and update_product_status. Each one previously carried company in its name.

Shipped around the same time