Skip to content

feat(agent): let the assistant create workloads - #290

Open
scotwells wants to merge 4 commits into
mainfrom
feat/assistant-workload-creation
Open

feat(agent): let the assistant create workloads#290
scotwells wants to merge 4 commits into
mainfrom
feat/assistant-workload-creation

Conversation

@scotwells

@scotwells scotwells commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

What a customer gets

Until now the assistant could only explain why a workload was broken. This PR lets it help create one, without the customer needing a shell or knowing the Workload API.

A customer can now ask Patch "deploy my image to Dallas" and have the assistant discover what the project may use, draft a valid manifest, check it against the platform before anything is created, show the customer exactly what will change, and only then apply it. Every step runs as the customer, and the assistant cannot apply anything it has not first shown them.

Discovery. Four new read-only tools answer the questions a first deploy stalls on: compute_locations_list (where compute is offered and this project can use it, resolved from compute's own ServiceAvailability records), compute_networks_list, compute_quota_get (limit, used, available), and compute_instance_types_list. Nothing to guess and no submit-and-read-the-error loop.

Draft and check. compute_workload_render turns a handful of inputs (image, location, replicas, port, env, ConfigMap and Secret mounts, public IPv4, VM) into a complete manifest, and tells the customer in plain words which choices cannot be changed after create. compute_workload_validate runs the real server-side dry-run and returns the exact rejection as a field error. Both write nothing.

Plan, confirm, apply. compute_workload_plan validates, reports create vs update, shows the diff, says whether the network will be created, and mints a token bound to that exact manifest, project, and object version. compute_workload_apply only accepts a manifest whose token still matches. Edit one character, wait past fifteen minutes, or let someone else change the workload first, and it refuses and asks the assistant to re-plan. A refusal is the check working.

A skill to drive it. workload-create walks the assistant through prerequisites, the container-vs-VM choice, the input list, the traps in customer language (one instance type today, name vs secretName, every volume must be attached, IPv6-only by default, SSH keys for VMs, ConfigMap size limits), and the render, validate, plan, confirm, apply, diagnose sequence. It is written API-first; datumctl appears only as an optional aside for customers who have a shell.

Also in this PR

Verified against staging

Ran the server locally against datum-cloud on staging with a real session token, before and after merging main's move to location-named placements: all thirteen tools published; compute_locations_list returned us-central-1 and us-east-1 from the availability records; networks, quota, and instance types returned correct data; render emitted placements[].locations; validate accepted a good manifest and surfaced the webhook's exact rejection for an unknown location name; plan minted a token and reported the network state; apply refused a forged token and a tampered manifest, and the workload was confirmed absent afterwards. Apply was not run for real.

Follow-ups

  • Update the assistant's capability document with the compute_ tool names and the workload-create runbook URL.
  • Fold datumctl compute deploy's spec building onto internal/workloadspec so the CLI and the assistant render identical manifests.
  • Set PLAN_TOKEN_KEY in the compute-mcp deployment so plan tokens validate across replicas.
  • The manager gains ServiceAvailability as a locationSource but its default is still NetworkServices, so the webhook validates placements against LocationBindings while the tool reads availability records. Switch the manager in deployment config so the two cannot disagree.
  • Placements use locations and locationSelector from Use canonical locations for compute placement #264; cityCodes is deprecated and not emitted by the renderer.
  • Image building and log access remain outside what a hosted assistant can do.

scotwells and others added 2 commits September 9, 2026 20:02
Add discovery, render, validate, and token-bound plan/apply tools to
compute-mcp, a workload-create skill, and a shared workloadspec package
used by both the assistant and datumctl compute deploy. Prefix every
published tool with compute_.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
compute_locations_list now reads compute's own ServiceAvailability
records and the Locations they name, never LocationBindings. A control
plane that does not serve those kinds fails loudly instead of answering
with an empty list. Adds ServiceAvailability as a manager location
source without changing the default.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
scotwells and others added 2 commits September 10, 2026 09:32
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Main moved placement from city codes to locations (#264), added runtime
classes (#259), published a shared instance-type catalog, and grew
`datumctl compute deploy` a URL-publishing path (#289). The assistant's
workload-creation surface was rebuilt on top of those rather than beside
them.

Semantic resolutions:

- Placements are locations. `workloadspec.Placement` drops `CityCodes` for
  `Locations []string` plus `LocationSelector`, exactly one of which must be
  set; render emits `spec.placements[].locations` or the selector and refuses
  an empty or malformed one, the way admission does. The render tool's schema,
  its notes, the diff summary, the workload-create skill, llms-full.txt and
  the README all say "location" and point the model at
  `compute_locations_list` for the names, with `locationSelector` named as the
  way to place in every location of a city or region.

- Location resolution keeps main's structure. `SourceServiceAvailability` is
  gone; `locations.ListAvailableLocations` is built on main's
  `AvailableLocations` and errors with `ErrAvailabilityNotServed` when the
  control plane serves no availability, so `compute_locations_list` still
  fails loud rather than reporting a project with nowhere to run. The
  manager's placement reads, which treat an unserved kind as no gate at all,
  are unchanged. The tool now reports `placeable` and `ready` alongside the
  name, city code and topology.

- Instance types read `pkg/instancetype`. `validation.SupportedInstanceTypes`
  and the duplicated sizing table in the agent are deleted, along with
  TODO(#137): the catalog is the single source now.

- Runtime classes: `workloadspec.Input` gains an optional `RuntimeClass`,
  passed through verbatim with no default, so the server picks its own.

- `internal/cmd/compute/deploy/deploy.go` is main's version wholesale, for
  `--location`, `--location-selector`, `--city` and `--http-port`. The CLI no
  longer renders through workloadspec, so the parity test that pinned the two
  together is deleted rather than left stale.

- Docs take main's triage-skill changes with this branch's `compute_` renames
  on top, and workload-create now says that a public HTTPS URL is published
  separately — today only by `datumctl compute deploy --http-port` — so
  `ports` makes a port reachable on the instance's address, not on a managed
  URL.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant