wai-quantum-service: the runs are MCP tasks, each task its job #615
Loading…
Reference in a new issue
No description provided.
Delete branch "wai/quantum-service-tasks"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The job service's three runs are MCP tasks (protocol 2025-11-25). A client that speaks tasks gets the job's id at once and follows the job by it, instead of holding a call open for 50 s and then switching to
get_quantum_job.It is one commit on main, after the idempotency key (#607) and the rerun (#613). It was written on top of their earlier commits and replayed onto main; the patch is unchanged.
What changes
wai-quantum-service (
src/mcp.rs,src/http.rs,src/jobs.rs)initializedeclarestasks(cancel, andrequests.tools.call) when the version it settles on is 2025-11-25, and not before.run_quantum_circuit,run_quantum_setandrun_on_targetdeclareexecution.taskSupport: "optional".tools/callwithtaskadmits the job exactly as the call does (the idempotency key, the target and set checks, the verdict asked), then answers at once with{ "task": … }. ItstaskIdis the job's id.-32602) whosedatais the refusal, with its codes and verdict.-32601. A dry run gets-32602: it answers at once.tasks/getgives the job as a task.workingwhile queued or running, withstatusMessagesaying which;completed;cancelled; orfailedfor a job that failed or that the service interrupted, with the error.createdAtandlastUpdatedAtare in ISO 8601,pollIntervalis 2 s, andttlis the service's retention. A job outlasts that from its creation, because it is kept that long after it ends.tasks/resultgivesget_quantum_job's answer for the ended job.isErroris set where the job failed or was interrupted, and_metanames the task (io.modelcontextprotocol/related-task).text/event-stream, the answer is an event stream. It is kept open with keep-alives, and its one event, when the job ends, is the JSON-RPC answer.tasks/get.tasks/cancelcancels the job and answers with the cancelled task. A task that has ended is refused with-32602.tasks/list. The public service binds a task to no one, so a list would give every client's tasks. A task's id, 128 random bits, is what reads it, as a job's id is, and the README says so as the spec asks. On a private deployment that takes API keys, a task is its key's alone:tasks/get,tasks/resultandtasks/cancelfrom another key find no task (Service::owned_by).tool_answer, shared bytools/callandtasks/result. The run admission is shared by the call and the task (admit_run,run_refusal).Tests
mcp::tests::a_run_as_a_task_is_its_job:executionon exactly the three runs;working(queued), with itsttl,pollIntervaland timestamps (isochecked at 1970 and at 2000-02-29);tasks/get;tasks/cancelonce, then refused;tasks/resultof the cancelled task, with its_meta;data);run_on_targetwith no target; andtasks/listnot offered;tasks/get,tasks/resultandtasks/cancelall find no task, and its cancel cancels nothing.tests/tasks.rs, against the service's binary:tasks/gettocompleted;tasks/resultgives the job with its task in_meta, and its receipt verifies;text/event-stream, whose event is the finished answer.Checked
On the build host, on this commit as replayed onto #613's:
-D warnings;check_schemas.pyover every schema file, both tool lists and a release build's answers.The public-name check is clean, and so are this description and the commit message.
🤖 Generated with Claude Code