Skip to content
Select themeSelect language

`POST /api/agent-profiles/{id}/workspace-default` — promote a profile to the workspace default (or clear it) (#708 who-4; #242/ADR 0033 — a task with no `agent_profile_id` resolves to this default, so it drives WHO). Atomic (clears the team's other defaults + sets one). Workspace-admin gated.

POST
/api/agent-profiles/{id}/workspace-default
curl --request POST \
--url https://example.com/api/agent-profiles/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/workspace-default \
--header 'Content-Type: application/json' \
--cookie supacloud_session=<supacloud_session> \
--data '{ "enabled": true }'
id
required
string format: uuid
Media typeapplication/json

The POST body for promoting/clearing the workspace-default agent profile (#708 who-4). enabled defaults to true (promote); false clears the workspace default entirely.

object
enabled
boolean
Examplegenerated
{
"enabled": true
}
Media typeapplication/json
object
autonomy_level

ADR 0045 §3.1 Stage 4 — OPTIONAL profile autonomy override (mig 214, nullable SMALLINT). None = inherit the project/workspace level (sits between project and workspace in the §3.1 precedence chain). #[serde(default)] keeps old AgentProfileVersion JSON snapshots (pre-214) deserializable — they default to None (a no-op).

integer | null format: int32
autonomy_overrides

ADR 0045 §3.1 — per-axis Advanced override vector (mig 214, JSONB NOT NULL DEFAULT '{}'). Empty {} = no per-axis override; the editor reads an optional level key. #[serde(default)] keeps old snapshots deserializable. Runtime stays serde_json::Value; the spec types it as an open map.

object
key
additional properties
avatar_kind
required

Avatar rendering kind (color | initial | icon | image). Runtime String; the spec narrows it to the closed [AvatarKind] the editor offers.

string
Allowed values: color initial icon image
avatar_value
string | null
capability_allowlist
required
Array<string>
color
required
string
created_at
required
string format: date-time
default_agent_type
required
string
description
string | null
effort_default
One of:
null
enabled
required
boolean
execution_mode

Issue #364 / ADR 0039 (D7) — Claude execution mode lever (normal | workflow; ultracode was RETIRED from this dimension by #708 who-3, migration 285 — it survives only as the top EFFORT stage). #[serde(default = ...)] keeps old AgentProfileVersion JSON snapshots (written before this column existed) deserializable; they default to "normal" (a no-op). Runtime String; the spec narrows it to the closed [ExecutionMode].

string
Allowed values: normal workflow
fixed_model
string | null
id
required
string format: uuid
interactive_approval

ADR 0045 §3.2 Stage 3 — when true, a task running under this profile arms the interactive-approval gate (the runner’s canUseTool / pre-exec hook pauses on a dangerous tool call, an open question, or a visual before/after and waits for a human Approve/Reject; migration 213). false is today’s behaviour (no gate). #[serde(default)] keeps old AgentProfileVersion JSON snapshots (written before this column existed) deserializable — they default to false (a no-op).

boolean
is_workspace_default

Issue #242 — when true, this profile’s capability_allowlist is the workspace fallback MCP tool set for profile-less / empty-allowlist tasks. At most one profile per team carries this flag (enforced by the partial unique index uq_agent_profiles_workspace_default in migration 119).

boolean
max_subagents

#838 — per-profile DEFAULT for the subagent concurrency ceiling (migration 358, nullable; 1..=64). The env build folds task.config.max_subagents ?? profile.max_subagents ?? workspace_settings.default_max_subagents ?? (no env), so this is the middle tier: the launch override still wins, and with every tier absent no SUBAGENT_MAX_PARALLEL is emitted and the harness keeps its own default. None = today’s behaviour.

The ceiling is only as strong as the harness allows — codex takes a real per-session cap, the rest receive it as an instruction — which is why the UI labels it from model_capabilities.subagent_cap_level instead of implying a guarantee. #[serde(default)] keeps pre-358 AgentProfileVersion snapshots deserializable.

integer | null format: int32
max_turns

#1018 — per-profile DEFAULT for the harness turn limit (migration 340, nullable; > 0). The env build folds task.config.max_turns ?? profile.max_turns ?? (no env) — the task config stays the per-launch override, and with both absent no MAX_TURNS env is emitted so the runner default (500, DEFAULT_MAX_TURNS) applies. None = today’s behaviour. #[serde(default)] keeps pre-340 AgentProfileVersion snapshots deserializable.

integer | null format: int32
mcp_memory_create

ADR 0049 (#547 / #548) — opt-in gate for the agent memory.create MCP tool (migration 249, BOOLEAN NOT NULL DEFAULT false). When false (the default for every profile) a task running under this profile CANNOT directly create a memory — memory.create fails closed; only a workspace admin enabling this on the profile editor opens the unreviewed direct-write path. Distinct from memory_policy.allow_propose_create (the default-true review-first gate). #[serde(default)] keeps old AgentProfileVersion JSON snapshots (written before this column existed) deserializable — they default to false (a no-op).

boolean
mcp_ops_per_hour_cap

#858 W4a — per-profile override of the rolling profile-hourly MCP Ops budget (migration 320, nullable; range 1–1000). None = the ADR 0028 default (30). The workspace-daily Ops ceiling (100/day) is NOT overridable. #[serde(default)] keeps pre-320 snapshots deserializable.

integer | null format: int32
mcp_ops_per_task_cap

#858 W4a — per-profile override of the per-task/per-tool MCP Ops budget (migration 320, nullable; range 1–500). None = the ADR 0028 default (10). Admin-gated via the profile PUT; a long-lived coordinator session raises it deliberately instead of the global default weakening. #[serde(default)] keeps pre-320 AgentProfileVersion snapshots deserializable.

integer | null format: int32
memory_policy
required

The fixed memory-policy knobs the editor reads. Runtime stays serde_json::Value; the spec types it as [AgentMemoryPolicy].

object
allow_personal
required
boolean
auto_inject_kinds
required
Array<string>
auto_inject_scopes
required
Array<string>
max_auto_memories
required
integer format: int64
mcp_read_kinds
required
Array<string>
mcp_read_scopes
required
Array<string>
model_policy
required

Model-selection policy (manual | fixed | auto). Runtime String; the spec narrows it to the closed [ModelPolicy].

string
Allowed values: manual fixed auto
name
required
string
persona_prompt
required
string
post_flight_checks
required

Forward-compatible list of post-flight check entries (e.g. the kind:"visual_verify" gate). Runtime stays serde_json::Value; spec-typed as an array of open maps.

Array<object>
object
key
additional properties
pr_template
string | null
pre_flight_checks
required

Forward-compatible list of pre-flight check entries (each an open object, e.g. a kind-discriminated gate). Runtime stays serde_json::Value; the spec types it as an array of open maps so the value is not stripped.

Array<object>
object
key
additional properties
required_worker_group_ids

ADR 0046 RUNG 1b — OPTIONAL profile worker-group affinity override (mig 227, nullable UUID[]). None = inherit (the head of the first-non-null profile->project->task chain — NULL contributes nothing); Some(vec![]) = an explicit “no affinity from this source”. Resolved into the task’s required_labels by services::runners::groups. #[serde(default)] keeps old AgentProfileVersion JSON snapshots (pre-227) deserializable.

NB: this binding is intentionally EXCLUDED from agent-profile version snapshot/restore — it is dispatch-routing scope (a live operational binding), not part of the profile’s behavioural definition, so a version restore does not carry or revert it (ADR 0046 RUNG 1b review).

Array<string> | null
resource_class
One of:
null
retry_policy
required

Open retry-policy bag. Runtime stays serde_json::Value; spec-typed as an open map.

object
key
additional properties
review_required
required
boolean
script_allowlist

Issue #217 / ADR 0028 — optional slug whitelist for the script.run MCP tool. NULL means any script in the workspace is callable; a non-NULL array (including empty) is an explicit whitelist.

Array<string> | null
slug
required
string
tags
required
Array<string>
tool_approval_deny_minutes

#1175 (migration 363, nullable) — the profile’s TOOL-GATE deny budget in minutes. The middle tier of task.config.tool_approval_deny_minutes ?? profile ?? workspace_settings.default_tool_approval_deny_minutes ?? 1440.

It sits on the profile for the same reason the resource class does: a profile already decides WHO runs and how far it may go unattended, and how long that runbook’s gate may wait before an explicit deny policy expires is the same kind of fact. None = today’s behaviour.

It NEVER affects a hold gate, which is the default for every runner-raised gate and carries no deadline at all (#1164).

integer | null format: int32
updated_at
required
string format: date-time
version
required
integer format: int32
workspace_id
required
string format: uuid
Example
{
"avatar_kind": "color",
"effort_default": "minimal",
"execution_mode": "normal",
"model_policy": "manual",
"resource_class": "normal"
}