The cloud tool
The local model can delegate to the cloud and manage the threads it started, through one tool with an op field (named cloud, or cloud_agent when another tool already has that name). The tool's own description tells the model when to use it: work that is independent of this machine and long-running or parallel (broad refactors, test suites, research or review reports, batch jobs, several independent tasks at once), not quick edits or anything that needs this machine's services or secrets. Ops:
delegatestarts one thread withtask, or 1 to 8 withtasks(one snapshot is shared and at most 4 uploads run at once;contextis prepended to every task's prompt, andmodel,thinking,policy,workspace,conversationandwipgiven besidetasksare the defaults of each). A task can setname,ref,model,thinking,policy(it can only tighten the service's limits:spend.turnUSD,spend.threadUSD,egress,fetch,webSearch,browser),workspace,conversation: "none"(ship no conversation) andwip: false(ship no uncommitted work). Inside a git repository with a commit the cloud agent gets the repository including uncommitted work; outside one, or withworkspace: "scratch", it works in an empty repository (a scratch thread). Aref(1 to 64 ofA-Z a-z 0-9 . _ -) names the thread and makes the call safe to repeat: the samerefwith the same task replays the first thread instead of creating a second (the result saysreplayed), and the samerefwith a different task is refused (conflict: use another ref or none). Two tasks of one call cannot share aref.listpages through threads, newest first (filter:phase,origin,mine,repo,ref,since;limit20 by default, 100 at most;N of totaland a cursor).statusshows one or several threads (phase, current activity, cost and context, who follows it, a pending question with its kind and expiry, recent turns and the result).readpages the full text of a turn's reply, error or prompt (without a page asked, the latest result isagent://<id>, which omp's ownreadshows too).eventslists what the agent did.diffandfilesread the change and the files of its result without pulling it.infoshows the service version and capabilities, models, limits and today's spend against the day cap.sendqueues a message. In the default queue mode it is the same path aswrite agent://<id>(jobs): an idle thread is woken (delivered: woken; turn N queued), a running turn gets the message at its next step (delivered: into the running turn at its next step (injected)), an archived thread is revived, anddetails.receiptcarries omp's receipt; a service without thethreads.irccapability queues it as a turn.mode: "interrupt"stops the running turn, cancels the turns queued behind it and runs the message next (the result lists the cancelled turns). A thread that failed takes no more messages (conflict). A slash command is sent to the cloud agent's own omp.stoptakes one thread, a list, or"all-mine".deleteneedsconfirm: true, and a thread the model did not start in this session alsoforce: true.answeranswers a question of the kindask. Tool approvals and push questions are the user's decision: the tool refuses them (forbidden) and tells the model to say so, and you answer with/cloud answeror the card buttons.waitblocks until threads settle (done, failed or a question), on named threads or, without any, on every thread the model started in this session that is working or waiting;untilisany(the default) orall, andonnarrows what ends the wait. It returns per-thread outcomes (done,failed,question,deleted,timeout,stale) and the call to make next. The default timeout is 10 minutes (timeoutSec, at most 30 minutes); a timeout is a result, not an error.pullbrings a result into the local repository:fetch(the default; branchomp-cloud/<id>, working tree untouched),merge(fast-forward the current branch; refused on a dirty tree or a detached HEAD) orworktree(a new checkout;intonames it, else<repo>-<short id>beside the repository; refused when a worktree already holds the branch or the directory is not empty). It refuses a repository the thread did not start from unlessforceis set (your own/cloud pull, the hub and the card's Pull button skip that check, because you name the thread). A branch that is checked out in another worktree is fast-forwarded there, and a worktree that cannot fast-forward refuses with aconflictnaming it. A scratch thread is cloned into the new directoryinto.
Threads the model starts come back to it without polling: a finished turn as omp's async-result of the thread's job, a question as a [cloud] card, and wait returns the result itself when it is blocked on the job. A thread that is no longer working settles a wait with its real outcome, whatever on says. Adoption of a thread you started, a lost connection and a deleted thread are in how results arrive.
Every result starts cloud <op>: ok … or, for a failure, cloud <op>: error <code>: <message>, with a hint and a line saying whether retrying can help. The codes are invalid, not_found, ambiguous_ref (a reference matched several threads; the candidates are listed), conflict, forbidden, unauthorized (a revoked device must /cloud connect again), not_configured, unreachable, timeout, ambiguous_outcome, too_large, rate_limited, unavailable, capacity, aborted and version_skew (the service lacks a feature of this plugin: update it, see Updating).
Retries: the model's reads, stop, answer, delete and a create that carries a ref retry themselves up to three times (about 0.5 s, 1.5 s and 4 s, honouring Retry-After up to 30 s); your own /cloud commands, the hub, the card buttons, /cloud <task>, /cloud status and /cloud disconnect retry once after at most 0.25 s (Retry-After up to 1 s). A retried write that finally fails after an attempt that may have been delivered reports that its outcome is unknown, and a delegate then says repeat with ref: <key>, so repeating the same call replays the first thread instead of creating another. A retried delete that finds the thread already gone counts as done, and a retried answer whose question already holds the same answer counts as answered. A queue-mode send carries a message id, so it retries safely (up to four attempts, all with that id; the service answers a repeated id as the first time): when every attempt fails without an answer, the error says the message may have been delivered. A send with mode: "interrupt" is never repeated: when its answer is lost the result is ambiguous_outcome ("the request may have been received"), and the model checks the thread before sending again.
Every op that takes thread accepts the references /cloud commands take (thread references); status, stop, wait and delete also take a list.
Native views#
In Tern the tool's calls and results draw natively instead of as text: wait and status as job tiles under omp's own wait head (waiting on N of M jobs, M jobs settled, counts of done, failed and cancelled), list as tiles in a section per repository, and the other ops as key-value, text, code and diff blocks. A call's partial view is replaced by its result view. A terminal UI and the model see the text result.
Scratch threads#
/cloud hands off the repository you are in. For work that needs none, such as research, a review of a pasted document or a scratch script, the model delegates with workspace: "scratch" (the default outside a git repository, or in one without a commit): the cloud agent starts in an empty repository, nothing of your machine's files is shipped, and its result is an ordinary branch. /cloud pull <id> --into <dir> (or pull with into) clones it into a new directory.