diff --git a/docs/swarm/ui.md b/docs/swarm/ui.md
index 606819a9..da523eab 100644
--- a/docs/swarm/ui.md
+++ b/docs/swarm/ui.md
@@ -296,22 +296,6 @@ row shows the new value before the agent runs under it. The panel reads
`GET /api/agents/{agent}/limits`. [hivectl](../tools/hivectl.md#per-agent-resource-limits)
sets the hive's own limits.
-### Settings at creation
-
-The **+ agent** dialog has two collapsed sections, **resource caps** and
-**inference**, with the same fields as the detail panel's editors. Leave the
-fields empty and the request is the plain name and hive; collapsing a section doesn't
-withdraw what you typed in it. Fill them and `POST /api/agents` carries them
-as optional `limits` and `inference` objects, the same shapes the two `PUT`
-routes take. The controller checks them with the `PUT` rules before it queues
-anything, so a bad value gets a refusal with its reason and creates no agent.
-
-It stores them ahead of the job graph, before it declares the agent, so they
-are in place before the agent first runs. If the creation then fails, the
-controller puts back what it replaced. Each agent name keys its settings and
-destroying an agent doesn't clear them, so a name set up before keeps its
-stored settings when you leave the fields empty.
-
### Linking external accounts
Each agent on `/agents` opens three dialogs that write a credential for it
diff --git a/frontend/packages/swarm-ui/src/agent/detail/AgentInference.tsx b/frontend/packages/swarm-ui/src/agent/detail/AgentInference.tsx
index 4bea9102..b7ebca60 100644
--- a/frontend/packages/swarm-ui/src/agent/detail/AgentInference.tsx
+++ b/frontend/packages/swarm-ui/src/agent/detail/AgentInference.tsx
@@ -88,104 +88,6 @@ function inferenceUrl(agent: string): string {
return `/api/agents/${encodeURIComponent(agent)}/inference`;
}
-// The four inference boxes as typed. Shared by the editor here and the
-// create-agent form, which send what `draftBody` makes of them.
-export interface InferenceDraft {
- model: string;
- effort: string;
- subagents: string;
- maxSubagents: string;
-}
-
-export const EMPTY_INFERENCE_DRAFT: InferenceDraft = {
- model: "",
- effort: "",
- subagents: "",
- maxSubagents: "",
-};
-
-// Why the draft would be refused, or null when it is fine to send.
-export function draftProblem(d: InferenceDraft): string | null {
- return (
- modelNameProblem(d.model.trim()) ??
- parseModels(d.subagents)
- .map(modelNameProblem)
- .find((p) => p !== null) ??
- (maxSubagentsValue(d.maxSubagents) === null
- ? `max subagents is a whole number from 1 to ${MAX_SUBAGENTS}, or empty for no cap`
- : null)
- );
-}
-
-export function draftIsEmpty(d: InferenceDraft): boolean {
- return (
- d.model.trim() === "" &&
- d.effort === "" &&
- parseModels(d.subagents).length === 0 &&
- d.maxSubagents.trim() === ""
- );
-}
-
-// Only the filled fields: an empty one leaves the agent on its own value.
-export function draftBody(d: InferenceDraft): Settings {
- const body: Settings = {};
- if (d.model.trim() !== "") body.model = d.model.trim();
- if (d.effort !== "") body.effort = d.effort;
- const models = parseModels(d.subagents);
- if (models.length > 0) body.subagent_models = models;
- const max = maxSubagentsValue(d.maxSubagents);
- if (typeof max === "number") body.max_subagents = max;
- return body;
-}
-
-export function InferenceFields({
- draft,
- onChange,
- idPrefix = "inference",
-}: {
- draft: InferenceDraft;
- onChange: (d: InferenceDraft) => void;
- // Ids must be unique on the page, and the agents page can hold the editor
- // and the create dialog at once.
- idPrefix?: string;
-}) {
- const problem = draftProblem(draft);
- return (
- <>
- {problem}