spec: tab configs specify agent profile (#10171)#10229
spec: tab configs specify agent profile (#10171)#10229lonexreb wants to merge 6 commits intowarpdotdev:masterfrom
Conversation
|
Thanks for writing this up. A few details seem worth aligning with the issue thread before this spec lands:
|
There was a problem hiding this comment.
Overview
This spec adds a profile field for agent-typed tab-config panes and covers core parsing, defaulting, UI picker, round-trip, and missing-profile behavior.
Concerns
- The spec needs to define the trust/consent model before a tab config can switch an Agent Mode pane to a named profile and dispatch input under that profile.
- The missing-profile "one-time toast" behavior is underspecified.
- The test plan should explicitly cover the ordering guarantee that profile application completes before any initial agent input is dispatched.
Security
- A shared or imported tab config can select a high-autonomy profile by display name before agent input runs; the spec should state the user-visible disclosure or confirmation behavior for this privilege-affecting binding.
Verdict
Found: 0 critical, 2 important, 1 suggestions
Request changes
Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).
Powered by Oz
| type = "agent" | ||
| profile = "Coder devbox" | ||
| ``` | ||
| - B2. When the tab config opens, the named profile is applied to |
There was a problem hiding this comment.
| - B2. When the tab config opens, the named profile is applied to | ||
| the pane before any agent input is dispatched. The profile | ||
| lookup is by display name; if no matching profile exists, the | ||
| pane opens with the default profile and a one-time toast warns |
There was a problem hiding this comment.
| ## Test plan | ||
|
|
||
| - T1. Schema round-trip with the new field. | ||
| - T2. Open path applies the named profile when present. |
There was a problem hiding this comment.
💡 [SUGGESTION] Add a test where the agent pane has initial input and assert the selected profile is applied before that input is dispatched.
Co-Authored-By: Warp <agent@warp.dev>
|
/oz-review |
|
I'm re-reviewing this spec-only pull request in response to a review request. You can view the conversation on Warp. I completed the review and no human review was requested for this pull request. Comment Powered by Oz |
There was a problem hiding this comment.
Overview
Reviewed the spec-only change adding a profile field for agent tab-config panes. The proposed behavior covers the happy path, omitted profile behavior, round-tripping, UI picker, and confirmation before dispatch for a resolved profile.
Concerns
- Profile lookup by display name is underspecified when names are duplicated, which can select the wrong autonomy/environment profile.
- The confirmation requirement does not explicitly cover the existing tab-config
commandsinput path or other open-time agent inputs. - Missing-profile fallback does not define what happens when the pane also has initial input, so an implementation could dispatch under the default profile without confirmation.
Security
- The unresolved duplicate-name and missing-profile cases can cause initial agent input to run under a different profile than the tab config author or user expected.
Verdict
Found: 0 critical, 3 important, 0 suggestions
Request changes
Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).
Powered by Oz
| type = "agent" | ||
| profile = "Coder devbox" | ||
| ``` | ||
| - B2. When the tab config opens, profile lookup is by trimmed, |
There was a problem hiding this comment.
Coder devbox can resolve to the wrong autonomy/environment settings.
| case-sensitive display name. If the profile exists and the agent | ||
| pane has no initial input to auto-dispatch, the named profile is | ||
| applied before the pane is shown. | ||
| - B2a. If the profile exists and the agent pane has initial input |
There was a problem hiding this comment.
commands array, so every auto-dispatch path is gated by the confirmation requirement.
| default profile and dispatches the initial input. Cancelling opens | ||
| the pane with the initial input preserved as an editable draft and | ||
| dispatches nothing. | ||
| - B2b. If no matching profile exists, the pane opens with the |
There was a problem hiding this comment.
|
Round-1 fixes for oz-for-oss review: (1) added Trust & Consent Model — imported/shared configs require inline confirmation before agent dispatch; user-saved configs are pre-trusted; (2) defined missing-profile behavior with Disabled-Agent state holding initial input AND commands; (3) resolved duplicate-name lookup via (name, source) pairs and qualified |
|
/oz-review |
|
I'm re-reviewing this spec-only pull request in response to a review request. You can view the conversation on Warp. I completed the review and no human review was requested for this pull request. Comment Powered by Oz |
There was a problem hiding this comment.
Overview
This spec adds a profile field for agent panes in tab configs and defines profile resolution, imported-config consent, disabled-agent fallback, and tests.
Concerns
- The profile identity model contradicts the ambiguous-name behavior, so implementation cannot know whether same-source duplicate names are legal or resolvable.
- Imported-config trust and disclosure need tighter security requirements so external TOML cannot self-declare as owned and the consent card exposes exact open-time inputs.
- The Cancel flow can leave imported draft input in an elevated default profile, which weakens the intended consent gate.
- The qualified
source:namesyntax needs parsing rules for profile names that contain:.
Security
- Treat trust markers as local metadata only: imported files must default to
importedand must not be able to carry an authoritativeownedvalue. - Require the confirmation UI to show exact, inspectable prompts and command entries rather than an unspecified summary.
- Define a safe Cancel state when the default profile is elevated.
Verdict
Found: 1 critical, 3 important, 1 suggestions
Request changes
Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).
Powered by Oz
| (e.g. `"Coder devbox"`) OR a qualified | ||
| `source:name` form (e.g. `"team:reviewer"`, | ||
| `"user:Coder devbox"`, `"builtin:Default"`). | ||
| - B1b. Profiles are uniquely identified internally by the |
There was a problem hiding this comment.
🚨 [CRITICAL] B1b says (name, source) uniquely identifies a profile, but B-LOOKUP and A-AMBIG require multiple profiles with the same name inside one source. Either enforce per-source name uniqueness and remove intra-source ambiguity, or add a stable profile ID for exact lookup.
|
|
||
| ### Trust & Consent model | ||
|
|
||
| - B-TRUST. Each tab config carries an internal trust marker |
There was a problem hiding this comment.
owned, and any missing or externally supplied marker must be treated as imported, otherwise a shared config can bypass the consent gate.
| then the pane MUST display an inline disclosure card before | ||
| dispatching ANY agent input. The card states: | ||
| > "This tab config wants to use the **'[name]'** profile | ||
| > (autonomy: **[level]**) and will run **[summary of input]** |
There was a problem hiding this comment.
summary of input; require the card to show the exact initial prompt and command entries, or an expandable exact view, so imported configs cannot hide dangerous open-time dispatch behind a benign summary.
| inputs uniformly — the initial prompt field, the `commands` | ||
| array, and any future tab-config-driven dispatch path. None | ||
| may dispatch until the user has confirmed (when required). | ||
| - B-TRUST-5. Cancel on the disclosure card opens the pane with |
There was a problem hiding this comment.
| ``` | ||
| - B1a. The `profile` field accepts EITHER a bare display name | ||
| (e.g. `"Coder devbox"`) OR a qualified | ||
| `source:name` form (e.g. `"team:reviewer"`, |
There was a problem hiding this comment.
💡 [SUGGESTION] Define escaping or validation for profile names containing :; without that, the source:name form is ambiguous and may not round-trip for existing display names.
|
Round-2 fixes: (1) CRITICAL resolved — single-source name uniqueness is now an enforced invariant (B-IDENTITY); the profile store rejects create/import/rename collisions. Only cross-source ambiguity remains and is resolved deterministically by precedence (user > team > builtin); (2) trust marker is LOCAL-ONLY in |
|
/oz-review |
|
I'm re-reviewing this spec-only pull request in response to a review request. You can view the conversation on Warp. I completed the review and no human review was requested for this pull request. Comment Powered by Oz |
There was a problem hiding this comment.
Overview
This spec adds profile selection for agent panes in tab configs and defines profile resolution, trust, consent, fallback, and test-plan behavior.
Concerns
- The trust upgrade path from settings can bypass the consent card's verbatim disclosure.
- Multi-pane consent/cancel behavior is underspecified.
- Consent rendering does not specify inert/escaped display for untrusted prompts and commands.
- Session-scoped consent semantics conflict with the imported-until-trusted model.
Security
- Imported tab configs can contain deceptive prompts/commands; the spec needs an explicit inert rendering contract.
- Trust promotion outside the consent card needs the same disclosure before sidecar writes.
Verdict
Found: 0 critical, 4 important, 0 suggestions
Request changes
Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).
Powered by Oz
| defaults to `imported` until the user re-trusts. | ||
| - B-TRUST-UPGRADE. Upgrading an `imported` config to `trusted` | ||
| requires an explicit user action: a "Trust this tab config" | ||
| control on the consent card (B-CONSENT) or in the Tab Configs |
There was a problem hiding this comment.
| has been raised), OR | ||
| - any open-time agent input (initial prompt field, `commands` | ||
| array, or any other tab-config-driven dispatch path), | ||
| then the pane MUST display an inline consent card before |
There was a problem hiding this comment.
| characters, show the first 800 characters followed by an | ||
| `[expand]` toggle that reveals the rest. The card MUST NOT | ||
| truncate silently. | ||
| - **`commands` array**: every entry rendered on its own line |
There was a problem hiding this comment.
| B-TRUST-UPGRADE. | ||
| 2. `[Open with default profile]` — see B-CANCEL-DEFAULT. | ||
| 3. `[Cancel]` — see B-CANCEL. | ||
| - B-CONSENT-SESSION. For an `imported` (not yet trusted) config, |
There was a problem hiding this comment.
|
Round-3 review fixes (commit 9c587af):
|
|
/oz-review |
|
Round-4 review addressed: tightened B-TRUST-UPGRADE to enumerate the only two trust-write surfaces (consent-card checkbox + settings modal) and explicitly forbid all other sidecar write paths. The settings surface now mandates B-TRUST-UPGRADE-DISCLOSURE as a precondition. Multi-pane consent/cancel (B-CONSENT-MULTIPANE, B-CANCEL-MULTIPANE), inert/escaped rendering (B-CONSENT-INERT), and session-scope reconciliation (B-CONSENT-EVERY-OPEN) remain in place from prior rounds. |
|
/oz-review |
Adds support for specifying an AI execution profile by display name on
agent-typed panes in tab configurations.
Schema:
- `TabConfigPaneNode` gains `profile: Option<String>` (deny_unknown_fields
is preserved; the field is trimmed and empty-after-trim is treated as
omitted).
- `PaneTemplateType::PaneTemplate` gains `agent_profile_name: Option<String>`
to carry the resolved name from the tab-config layer to the pane-launch
layer.
Lookup helper:
- New `AIExecutionProfilesModel::find_profile_by_display_name` resolves a
trimmed name against `AIExecutionProfile::display_name`. Returns
`ProfileLookupError::NotFound` for no match and
`ProfileLookupError::Ambiguous { count }` when multiple profiles share
the requested display name. This honors moirahuang's binding direction
in warpdotdev#10171: error on duplicate names rather than silently picking one.
Apply paths:
- Immediate launch (`pane_group::PaneGroup::pane_tree_from_template_recursive`)
applies the profile via `set_active_profile` before
`enter_agent_view_for_new_conversation`. A per-launch
`HashSet<String>` deduplicates the missing-profile toast so a tab config
with multiple panes referencing the same missing name produces a single
toast.
- Deferred launch (`TerminalView` after `PendingCommandCompleted`) stashes
the profile name on a new `pending_agent_profile_name` field and
applies it via the mirror helper just before the deferred
`enter_agent_view_for_new_conversation` call.
UX policy (per FINAL_PLAN locked decisions):
- Missing name: fall back to default profile + warning toast (recoverable
for typos / unsynced profiles).
- Ambiguous name: abort agent-mode entry with an error toast pointing the
user at Settings → Agents → Profiles. The pane stays as a terminal.
- `profile` set on a non-agent pane: `log::warn!` and ignore (matches the
existing soft-warn precedent in `tab_config.rs`).
- Omitted: preserve current behavior (no `set_active_profile` call;
`active_profile(Some(id))` already falls back to default).
Tests:
- 7 unit tests in `profiles_tests.rs` covering unique match, NotFound,
Ambiguous, default-resolves, two-Untitled-collide, trim, and
empty-input cases.
- 5 unit tests in `tab_config_tests.rs` covering schema propagation,
whitespace trim, empty-as-omitted, terminal-pane-with-profile passes,
and TOML round-trip.
Trust/consent:
- Profile selection is permission-affecting via
`BlocklistAIPermissions::active_permissions_profile`. Disclosure is via
the agent input footer chrome (already shows the active profile);
tab-config TOML edits serve as primary user consent.
Wiring:
- `TerminalView::Event::ShowToast` (already a variant) is now propagated
to `pane_group::Event::ShowToast` in `handle_terminal_view_event` so
the deferred-path toast actually reaches the workspace toast stack.
Closes warpdotdev#10171
Refs warpdotdev#10229
Spec for #10171. New
profilefield on agent-typed panes in tab configs. When the tab opens, the named profile is applied before any agent input is dispatched. Missing profile = default + one-time toast.Closes (spec-only) #10171.