Skip to main content
A cloud task is one unit of work handed to an agent: a title and description, an executor that decides how the model loop runs, an environment to run it in, optional GitHub repositories to mount, and a result that comes back as a summary plus structured data. Tasks live in the client app under the Tasks sidebar group as Cloud Tasks (/tasks: list, /tasks/new, /tasks/:taskId, /tasks/:taskId/edit) next to Tickets (/tickets, /tickets/:ticketId). Executors are configured under Orchestration > Executors (/executors, /executors/new, /executors/:executorId/edit), and the work-item queue that carries every task is visible as Orchestration > System Activity (/work-items, /work-items/:workItemId). Runners, pools, environments, agents, sandboxes and skills have their own pages.

What it does

A task moves through seven statuses. created (editable, not yet placed), dispatched (a work item exists), queued and running (reported by the runner), then one of the terminal states completed, failed or cancelled. Every transition and every activity signal from the runner is stored as a CloudTaskEvent (task.created, task.dispatched, work_item.queued, task.queued, task.started, task.phase, agent.text, agent.tool_start, agent.cost_update, task.verify_attempt, task.completed, task.failed, task.cancelled, task.retried, task.billing_refused, task.placement_refused). The detail page reads them with cloudTaskEvents and streams new ones over the cloudTaskEvents subscription. Five ways a task is created.
  1. From the UI or API: createCloudTask(title, description, agentId, priority, effortTier, workingDir, ticketId, repositories). The task stays created until someone dispatches it.
  2. From a workflow: the create_task node renders title_template and description_template, stores the triggering data as task_context and attaches repositories; dispatch_task then dispatches it and suspends the run until the task ends (see Workflows).
  3. From a schedule with target olyros: each tick creates and dispatches a task carrying schedule_id and schedule_run_number; a dispatch failure marks the task failed and counts towards the schedule’s auto-pause (see Schedules).
  4. From a GitHub issue: a label or YAML front matter naming an agent slug creates a task, mounts the triggering repository at /workspace/<repo> as working directory (repositories no longer granted to the installation are skipped), posts an acknowledgment comment and dispatches when a backend is available; closing the issue cancels an active task (see GitHub).
  5. From a Jira issue only through a workflow: a jira_event trigger followed by create_task. Jira labels no longer route issues to agents (see Jira).
An Olyros ticket (createTicket, linkTaskToTicket, ticketTasks) groups tasks and carries verify_description and max_verify_attempts, which the runner uses to re-run a completed task as verification passes. Dispatch assembles a self-contained execution stack. dispatchCloudTask(taskId, backendId | ohoInstanceId, agentId, executorIdOverride, environmentIdOverride, workingDir) requires an agent. The stack sent to the runner carries the task fields (title, description, priority, effort_tier defaulting to standard, working_dir, task_context); an agent_config of the agent’s name, its provider/model string and its system prompt with active knowledge items appended as a “Knowledge Base”; the agent’s LLM integration decrypted into credentials; the executor definition; the environment (type, Dockerfile, build args, env vars merged with decrypted secrets, timeout_seconds); one GitHub installation token per connection for the mounted repositories; and a trace id. Executor and environment resolve as override, then agent default, then the company default row; the integration as override, then agent default. Dispatch fails with “No executor configured”, “No environment configured” or “No integration configured” when nothing matches. A mounted repository the GitHub App installation no longer grants fails the dispatch with a “no longer granted” error; a repository row of another company is skipped, never mounted. What the stack does not carry. agent_config.tools is always empty: the agent’s HTTP API tools, built-in tools, MCP server bindings (sandbox scope only), skills and memory are not part of a task run. A Claude Agent SDK task gets the Claude Code tools in allowed_tools plus the OHO bridge tools store_temp_file and request_authentication; a litellm task gets only the container tools listed below. Placement picks a backend. The selector tries the agent’s pinned backend, then the company default, then every attached backend the company is entitled to, and records placement_reason as agent_pin, company_default, only_backend or least_loaded. A pin or default to a gcp/aws backend the company is not entitled to, or a cloud backend while the company’s Olyros Cloud toggle is off, is a hard refusal: the task gets a task.placement_refused event and no work item. A technical failure (no backend, capability unmet, all offline or at capacity) falls back to an unaffined work item any online OHO may claim. A suspended account or a wallet below the floor emits task.billing_refused. An explicit OHO target must be online and connected. Every dispatch is a work item. The task becomes one agent_execution work item requiring the agent_supervisor capability, with the task’s priority, no automatic retries and a 1800 s heartbeat window; a unique index allows one active item per task. OHO instances pull over POST /api/v1/work-items/pull on a poll or a nudge, claim in priority then age order, and report POST .../status and POST .../heartbeat with their device token, which also fixes the tenant; a cloud backend’s driver loop pulls only items fenced to its backend id. An OHO creating an item (POST /api/v1/work-items) gets 400 for server-handler types and server-only capabilities. Two executor types run tasks. Stage mechanics: the context starts with task.title, task.description and the workflow task_context; each stage’s output is stored under its stage_name; context_writes maps a key to a template such as {{output.severity}} (a single placeholder keeps the original type). transitions is a list of {target, condition, max_count} tried in order with conditions always, field_equals, field_truthy and not; without transitions the next stage runs, done ends the graph, and 100 transitions in total abort the task. In tool_calling mode the stage may call bash, file_read, file_write, glob and grep when listed in allowed_tools. A stage may set underlying_executor to claude_agent_sdk (max_cost_usd 2.0, max_duration_seconds 300 by default). The executors page offers prebuilt templates (quick-pipeline, multi-stage-pipeline, bug-triage, pr-review, claude-agent-sdk-simple). Repositories mount into a fresh workspace. Each task gets an empty /workspace; the OHO clones each selected repository at /workspace/<org>/<repo>, read-only or read-write per access_level, one may be is_cwd, and working_dir is relative to /workspace. The run’s GitHub token has contents: write only if some mount is read_write. Results flow back three ways. The terminal callback copies result_summary, result_data, tokens and cost onto the task (preserving values already streamed), stamps billable_seconds, emits usage events and an agent interaction for cost reporting, and resumes a suspended workflow, whose dispatch_task node exposes result_summary, error_message, cost_usd, task_url and every context_writes key. On an OHO terminal event the linked GitHub issue gets a result comment, a label olyros:completed, olyros:failed or olyros:cancelled, and is closed on success; A task linked to a Jira issue still gets the comment and a Done transition. An agent can publish a file with the store_temp_file tool: POST /api/v1/files/store uploads it and returns a signed URL valid 7 days, the object living 30 days. Cancel, retry, delete. cancelCloudTask cancels the work item, sends task.cancel to the OHO and resumes a waiting workflow at once; retryCloudTask resets a terminal task to created with results and costs cleared; updateCloudTask and deleteCloudTask work only while the task is created.

Who can use it

  • Creating, updating, dispatching, cancelling, retrying and deleting tasks; listing and reading tasks, events and repositories; creating, editing and deleting executors and tickets; cancelling and retrying work items: any company member (membership only). No editor or admin gate exists in this domain; the executor.manage ability (editor) is not applied to executor writes.
  • The work-item and file REST endpoints accept only an OHO device token; the company is derived from the token.
  • The cloudTaskEvents subscription is scoped to the caller’s company.
  • No plan or tier gate exists per feature. Dispatch is subject to the billing gate (account state and wallet floor, staged dark or live) and to pool entitlements for gcp and aws backends.

How to configure it

  1. Create an executor (Executors -> New): createExecutor(name, type, description, maxTurns, maxTokens, allowedTools, stages, transitionRules, config). name is 1 to 100 characters of letters, digits, _ and -, unique among active executors; description is at most 500 characters; type is litellm, claude_agent_sdk, codex_cli or gemini_cli; maxTurns and maxTokens are at least 1. Stages: at most 20, unique stage_name other than done, llm_mode text or tool_calling, positive max_turns, context_writes keys not task, _system_error or starting with _, output_schema types among string, number, boolean, array, object, integer, transition targets naming a stage or done with a positive max_count. updateExecutor bumps version; deleteExecutor deactivates the row.
  2. Give the agent defaults on the agent page: executor, environment, LLM integration and optionally a pinned backend (see Agents).
  3. Create the task (Cloud Tasks -> New): title, description, agent, priority and repositories. Repositories must belong to the company’s GitHub connections, the requested access_level may not exceed the connection’s level, a repository with access none or no longer granted to the installation is rejected, and at most one may be the working directory. The agent and the ticket must be the company’s own; another company’s id answers “not found” like an unknown one.
  4. Dispatch from the task detail page: choose the backend, optionally override the agent, executor, environment and working directory. The dispatch event records where it runs and with which executor, environment and agent; previewContainerSpec shows the container an OHO would build without running it.
  5. Watch the event log on the detail page; use cloudTasksPage(status, search, orderBy, orderDir, limit, offset) for the list.
  6. Optional ticket: createTicket(input) with verifyDescription and maxVerifyAttempts, then linkTaskToTicket; a completed task is re-run as a verification pass with the description appended until the attempts are used up.

Limits and defaults

What it emits

  • CloudTask rows with status, tokens, cost, billable_seconds, placement_reason, actor attribution and links to the schedule, workflow execution and ticket.
  • CloudTaskEvent rows for every lifecycle and activity signal, also published live.
  • WorkItem and WorkItemEvent rows (queued, dispatched, started, completed, failed, cancelled, retried, timeout_detected, callback_failed).
  • Compute usage events and an agent interaction per terminal task for billing and the usage reports.
  • Comments, labels and closures on linked GitHub issues; comments and Done transitions on legacy Jira issue links.
  • Workflow resumption with the task outcome on the success or failure port, and temporary files in cloud storage with signed URLs.

Known gaps

  • A task on a gcp or aws backend gets no repository checkout: nothing in the cloud runtime or driver reads the stack’s github_repositories.
  • Results of a cloud-backend task are not posted to linked GitHub or Jira issues; that posting runs only on the OHO WebSocket terminal event.
  • No task creates a pull request; a read_write mount lets the agent push only.
  • on_failure, success_condition, max_iterations and transition_rules are accepted and stored but no runtime code reads them; any stage exception fails the whole task.
  • codex_cli and gemini_cli executors save but cannot be dispatched as tasks; the task wire contract accepts only litellm and claude_agent_sdk.
  • No mutation sets an executor’s is_default; company defaults are set outside the API.
  • A ticket’s default_agent_id, default_executor_id and default_environment_id are stored but not applied at dispatch; only its verify fields are read.
  • Ticket status, priority and ticket_type accept any string; the documented values (open, in_progress, blocked, in_review, done, cancelled) are not validated.
  • effort_tier is a free string with no defined values; result_data has no cap.
  • No per-task or per-workflow timeout override: the container timeout comes from the environment only, and a cancel marks the task cancelled before the runner has stopped.
  • Dispatching overwrites the task’s created_by with the dispatching user.

Customer-safe summary

A cloud task is a single job you hand to one of your agents. Describe the work, pick the agent and, if needed, the repositories it should see, and dispatch it to one of your connected runners or to a managed cloud pool. Executors define how the agent works through the job, either as a configurable sequence of stages with structured outputs that later steps and workflows can use, or as a single pass of Claude Code with chosen tools. Tasks can also be created by workflows, on a schedule, straight from a GitHub issue, which then receives the outcome as a comment, or from a Jira issue through a workflow. Every task records its progress, cost and result; you can cancel, retry, or re-run it as a verification pass against a ticket’s acceptance notes.