# Accepted Company Tasks run on the durable queue and come back for review

> Agno's POST /company/tasks/{id}/runs starts an accepted CompanyOS Task on its registered agent, team or workflow through the durable queue, and GET /company/attention counts proposals, Tasks in review and failed runs.

- Published: 2026-10-16
- Author: Ashpreet Bedi
- Categories: Changelog
- Canonical: https://www.agno.com/blog/accepted-company-tasks-run-on-the-durable-queue-and-come-back-for-review
- Markdown: https://www.agno.com/blog/accepted-company-tasks-run-on-the-durable-queue-and-come-back-for-review.md

Agno's `POST /company/tasks/{id}/runs` hands an accepted [CompanyOS](https://www.agno.com/blog/introducing-companyos) Task to its executor's ordinary run route on the durable queue and answers 202 with a run ID built from the Task ID and attempt number. Send attempt 1 twice and both calls get the same run. The executor receives one JSON message holding the Task brief, its evidence and the current company and Product wiki pages.

```python
import json

from agno.agent import Agent
from agno.db.postgres import PostgresDb
from agno.job_queue import QueueConfig
from agno.os import AgentOS, CompanyConfig
from agno.workflow import Step, StepInput, StepOutput, Workflow

db = PostgresDb(db_url="postgresql+psycopg://ai:ai@localhost:5532/ai")

def draft(step_input: StepInput) -> StepOutput:
    task = json.loads(step_input.input)  # keys: brief, evidence, wiki
    return StepOutput(content="Draft ready for review: " + task["brief"])

agent_os = AgentOS(
    db=db,
    workflows=[Workflow(id="draft", db=db, steps=[Step(name="Draft", executor=draft)])],
    agents=[Agent(id="site-builder", db=db)],
    company=CompanyConfig(),
    queue=QueueConfig(durable=True, db=db),
)
```

We ran this setup on an embedded PostgreSQL with `max_attempts=1` and one accepted Task per executor. The `draft` step finished its Task. The agent had no model key in our sandbox, so its run failed.

```text
# real output: two accepted Tasks, one run each
POST /company/tasks/{id}/runs attempt 1 -> 202 {"status": "PENDING"}
repeat attempt 1 -> 202, same run_id: True
workflow Task -> in_review, result COMPLETED
agent Task    -> in_progress, result ERROR "OPENAI_API_KEY not set. ..."
GET /company/attention -> {"proposals": 1, "in_review": 1, "failed": 1}
```

A successful run moves the Task to `in_review` for a person, and the run stays readable at `GET /company/tasks/{id}/runs`. A run that exhausts its retries, fails permanently or gets cancelled leaves the Task `in_progress` with the result attached, ready for attempt 2 or a return to Backlog. `GET /company/attention` counts Backlog proposals, Tasks in review and those failures, and `GET /company/tasks?failed=true` lists the failures.

Archiving cascades. `DELETE /company/products/{id}` archives the Product's Projects and Tasks, a Project archive takes its Tasks, and each child records `archived_by` in its transition history so a restore brings back exactly those children. A parent with Ready, In progress or In review work refuses.

```text
# real output: the same Product, before and after cancelling both Tasks
DELETE /company/products/{id} -> 409 {"detail": {"message": "Cannot archive with active Tasks", "tasks": [{"id": "6280...", "title": "Rebuild docs site"}, {"id": "af6f...", "title": "Draft release notes"}]}}
DELETE /company/products/{id} -> 204
POST /company/products/{id}/restore -> 200, visible Tasks: 3
```

Product and Project responses also carry `counts`, the open Projects and Tasks per status, computed in one grouped query for the whole page.

Three fixes round out the release. The standalone Product Manager now answers at `/agents/product-manager-internal`. Optional Company tool arguments advertise a nullable schema, and an empty string from a model counts as omitted. `AsyncPostgresDb` derives its default ID from the connection URL and schema, matching `PostgresDb`, so a Task's saved run database reference resolves after a restart or on another replica.

```text
# real output: two AsyncPostgresDb instances on the same URL and schema
earlier releases: 0dbba9e9-... vs 3a725f2b-...   equal: False
this release:     f1e71e62-... vs f1e71e62-...   equal: True
```

See the [cookbook](https://github.com/agno-agi/agno/blob/main/cookbook/05_agent_os/30_company/06_execute_tasks.py), and learn more about [durable background execution](https://docs.agno.com/agent-os/background-execution/overview#with-durability) in the documentation.
