Skip to content

feat(automations): select saved agent profiles - #17396

Draft
neubig wants to merge 1 commit into
mainfrom
factory/automation-profile-selector
Draft

neubig wants to merge 1 commit into
mainfrom
factory/automation-profile-selector

Conversation

@neubig

@neubig neubig commented Sep 13, 2026

Copy link
Copy Markdown
Member

AGENT:

Why

Automations can select a model but cannot select the saved agent profile that owns their tools and available secrets. Add profile selection to creation and editing, show the saved selection in details, and preserve it through import/export.

Summary

Reuses the existing profile query/service and settings dropdown. Capability discovery controls availability; a selected profile suppresses the separate model field. Deleted profiles remain visible as unavailable rather than silently changing privileges.

Issue Number

Closes #17395. Requires the Automation Service API in OpenHands/automation#453. No runtime transport or profile-resolution logic is added to Canvas.

How to Test

Validation: the fresh-install UI walkthrough exposed a missing profile in the bundle creation path. Bundle creation now reuses the existing optional-property builder for both preflight and create. Sixteen setup/bundle tests pass, including saved-profile precedence over model selection; focused lint passes. Live UI recreation and saved-profile verification passed; the linked before/after recording reproduces and resolves the omission. Earlier selection, explicit clearing, missing-profile, and import/export checks passed.

Live Canvas evidence

Live before/after evidence now reproduces the bundle bug: the chosen profile disappears before the fix and persists after the same UI creation flow. Request and private database observations confirm the saved profile ID.

Scenario, exact revisions, and limitations. The isolated integration uses the PR change and its required unreleased dependencies.

Live Canvas evidence


🐳 Docker images for this PR

GHCR package: https://github.com/OpenHands/OpenHands/pkgs/container/agent-canvas

Component Value
Image ghcr.io/openhands/agent-canvas
Architectures amd64, arm64
Agent Server ghcr.io/openhands/agent-server:1.46.0-python
Automation openhands-automation==1.11.1
Commit cc4d3ce25bc9d7055cf0be9e580ec90b748617ad

Pull (multi-arch manifest)

# Multi-arch manifest — Docker automatically pulls the correct architecture
docker pull ghcr.io/openhands/agent-canvas:sha-cc4d3ce

Run

docker run -it --rm \
  -p 8000:8000 \
  ghcr.io/openhands/agent-canvas:sha-cc4d3ce

All tags pushed for this build

ghcr.io/openhands/agent-canvas:sha-cc4d3ce-amd64
ghcr.io/openhands/agent-canvas:factory-automation-profile-selector-amd64
ghcr.io/openhands/agent-canvas:pr-17396-amd64
ghcr.io/openhands/agent-canvas:sha-cc4d3ce-arm64
ghcr.io/openhands/agent-canvas:factory-automation-profile-selector-arm64
ghcr.io/openhands/agent-canvas:pr-17396-arm64
ghcr.io/openhands/agent-canvas:sha-cc4d3ce
ghcr.io/openhands/agent-canvas:factory-automation-profile-selector
ghcr.io/openhands/agent-canvas:pr-17396

About Multi-Architecture Support

  • Each tag (e.g., sha-cc4d3ce) is a multi-arch manifest supporting both amd64 and arm64
  • Docker automatically pulls the correct architecture for your platform
  • Individual architecture tags (e.g., sha-cc4d3ce-amd64) are also available if needed

Merge and release prerequisites

Must merge and be available first: automation#453 (and its native predecessor #449). The backend must persist and dispatch agent_profile_id before shipping the UI selection. This PR targets main; that does not represent or remove its cross-repository prerequisite.

Catalog automations requiring agentProfiles must select a saved profile before review or creation; the edit dialog uses existing template provenance to preserve that requirement. Ordinary automations retain the deployment-default option. Setup, edit, and selector regressions pass (38 tests); full TypeScript checking and focused lint pass.

Live setup regression evidence

Fresh isolated Canvas evidence shows the old form saving a null profile, then the fixed form blocking Continue before preflight until a profile is selected. The selected UUID survives reload, and Edit no longer offers Default for this profile-required automation. The definition remained inactive and never ran.

Before/after GIFs, exact revisions, request/persistence evidence, and scope.

Live Canvas before/after

@all-hands-bot

Copy link
Copy Markdown
Collaborator

🤖 OpenHands is reviewing this PR.

Head commit: afcc0848b426b0a0eabe3b6b2a7b560a36a34ea3
View the conversation: https://oss-agent-canvas.ngrok.dev/conversations/a3a91dd6-a6c9-48c6-84fb-51a267834b9f

This comment was posted by an AI agent (OpenHands).

@all-hands-bot all-hands-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This review was created by an AI agent (OpenHands) on behalf of the repository maintainers.

Summary

This PR adds agent profile selection to automations — creation, editing, details display, and import/export — reusing the existing useAgentProfiles hook and SettingsDropdownInput component. A selected profile takes precedence over the separate model field, and deleted profiles remain visible as unavailable rather than silently changing privileges. The implementation is clean: one shared selector component, consistent precedence logic across all code paths, and focused tests.

Acceptance Criteria Checklist (from #17395)

  • Profile selection in automation creation (manifest-setup-dialog.tsx)
  • Profile selection in automation editing (edit-automation-modal.tsx)
  • Saved selection shown in details (configuration-section.tsx)
  • Selection preserved through import/export (automation-export.ts)
  • Capability discovery controls availability (features.includes("agentProfiles"))
  • Selected profile suppresses the separate model field
  • Deleted profiles remain visible as unavailable

Findings

CI-Blocking: Missing translations for new i18n keys

The two new translation keys AUTOMATIONS$DEFAULT_AGENT_PROFILE and AUTOMATIONS$UNAVAILABLE_AGENT_PROFILE only have English ("en") values. Every other key in translation.json has translations for all 15 supported languages. The check-translation-completeness script (run via lint-staged on every commit and as part of CI) explicitly fails on keys missing any supported language:

ERROR: Missing translations detected
- Key "AUTOMATIONS$DEFAULT_AGENT_PROFILE" is missing translations for: ja, zh-CN, zh-TW, ko-KR, no, ar, de, fr, it, pt, es, ca, tr, uk
- Key "AUTOMATIONS$UNAVAILABLE_AGENT_PROFILE" is missing translations for: ja, zh-CN, zh-TW, ko-KR, no, ar, de, fr, it, pt, es, ca, tr, uk

This will block both local commits (lint-staged) and CI. See the inline comment on translation.json for the exact location.

Risk Assessment

  • Overall PR: 🟡 MEDIUM
    • The translation completeness failure will block CI and should be fixed before merge.
    • The core logic (profile precedence over model, deleted-profile retention, import/export round-trip) is sound and well-tested.
    • No security concerns — profile IDs are UUIDs from the backend, not user-supplied free text.
    • No raw API calls or contract redeclarations — the PR correctly reuses existing hooks, services, and typed clients.

Verdict: COMMENT

The change is architecturally sound and well-tested. The only blocking issue is the missing translations, which the author should add before marking the PR ready.

Comment thread src/i18n/translation.json Outdated
@all-hands-bot

Copy link
Copy Markdown
Collaborator

🤖 OpenHands is reviewing this PR.

Head commit: 2ffcb495c40ba5a07f3a90c81c75a420b409cc5f
View the conversation: https://oss-agent-canvas.ngrok.dev/conversations/2fe70058-051d-4538-99df-0a8bc9d689d0

This comment was posted by an AI agent (OpenHands).

@all-hands-bot all-hands-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This review was created by an AI agent (OpenHands) on behalf of the repository maintainers.

Summary

This PR adds agent-profile selection to automation creation, editing, details, and import/export. The implementation is clean and follows established patterns: it reuses useAgentProfiles, SettingsDropdownInput, and the deployment capabilities gate, and consistently enforces agent_profile_id / model mutual exclusivity across all code paths.

Acceptance Criteria Checklist (issue #17395)

  • ✅ Creation and editing persist agent_profile_id through the Automation Service API — buildCreateAutomationRequest and EditAutomationModal.handleSubmit both send it.
  • ✅ Selection offered only when deployment advertises agentProfiles — gated in both edit-automation-modal.tsx and manifest-setup-dialog.tsx.
  • ✅ Selecting a profile suppresses model selection; clearing restores default — __default__ sentinel maps to null; model dropdown hidden via !form.agentProfileId.
  • ✅ Existing selections visible in details and survive import/export — configuration-section.tsx renders read-only selector; automation-export.ts round-trips the field.
  • ✅ Missing profiles visible as unavailable — agent-profile-selector.tsx appends the unavailable ID with a localized label.

Findings

No material bugs, security issues, or design flaws found. A few observations:

Minor UX edge case (not blocking): In edit-automation-modal.tsx, if an automation was created with agent_profile_id set but the deployment no longer reports the agentProfiles capability (e.g. server downgrade), neither the profile selector nor the model dropdown renders. The form state preserves agentProfileId so saving won't silently change privileges, but the user has no visible control. This is an unlikely server-downgrade scenario and the behavior is safe (no privilege change), just not editable.

Model clearing is correct: Traced through the handleSubmit logic for all transitions (profile→model, model→profile, no-change save with both set). The selectedModel = form.agentProfileId ? "" : form.model.trim() line correctly forces body.model = null when a profile is selected, enforcing mutual exclusivity even for legacy automations that might have both fields.

Risk Assessment

  • Overall PR: 🟢 LOW
  • Canvas-only change; no runtime transport or profile-resolution logic added. The backend (OpenHands/automation#453) owns profile resolution. No raw API calls introduced — reuses existing typed client patterns. No new dependencies.

Note

The PR is marked draft and the description notes type checking and lint are in progress. This review covers the code as committed at the head SHA.

Improve this review? If any feedback above seems incorrect or irrelevant to this repository, you can teach the reviewer to do better:

  1. Add a .agents/skills/custom-codereview-guide.md file to your branch (or edit it if one already exists) with the /codereview trigger and the context the reviewer is missing.
  2. Re-request a review - the reviewer reads guidelines from the PR branch, so your changes take effect immediately.
  3. When your PR is merged, the guideline file goes through normal code review by repository maintainers.
    Resolve with AI? Install the iterate skill in your agent and run /iterate to automatically drive this PR through CI, review, and QA until it's merge-ready.
    Was this review helpful? React with 👍 or 👎 to give feedback.

@github-actions

github-actions Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

PR Artifacts Cleaned Up

The .pr/ directory is no longer present.

@all-hands-bot

Copy link
Copy Markdown
Collaborator

🤖 OpenHands is reviewing this PR.

Head commit: 89e1e2fd6fa85dfc6eed28eca3c8f934f2b3aeb1
View the conversation: https://oss-agent-canvas.ngrok.dev/conversations/dfadaa3d-e1dc-4ed4-bb45-f069b290fb5a

This comment was posted by an AI agent (OpenHands).

@all-hands-bot

Copy link
Copy Markdown
Collaborator

🤖 OpenHands is reviewing this PR.

Head commit: 89e1e2fd6fa85dfc6eed28eca3c8f934f2b3aeb1
View the conversation: https://oss-agent-canvas.ngrok.dev/conversations/135d550b-0891-4530-84fc-63d054dab08b

This comment was posted by an AI agent (OpenHands).

@neubig
neubig requested review from all-hands-bot and removed request for all-hands-bot September 13, 2026 14:58

@all-hands-bot all-hands-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This review was created by an AI agent (OpenHands) on behalf of the repository maintainers.

Summary

This PR adds agent-profile selection to automation creation, editing, details display, and import/export. The implementation is clean, reuses existing infrastructure (useAgentProfiles hook, SettingsDropdownInput, AgentProfilesService), and follows the repository API access rules (no direct agent-server calls).

Acceptance Criteria Checklist (issue #17395)

  • Creation and editing persist agent_profile_id — Verified in automation-service.api.ts (import/create path sends agent_profile_id with model suppression), edit-automation-modal.tsx (PATCH body includes agent_profile_id on change), and automation-setup.ts (OPTIONAL_CREATE_PROPERTIES includes agent_profile_id, model skipped when profile is set).
  • Offer selection only when deployment advertises agentProfiles — Both manifest-setup-dialog.tsx and edit-automation-modal.tsx gate the selector on capabilities.features.includes("agentProfiles").
  • Selecting a profile suppresses model selection; clearing restores default — All three paths (setup dialog field filter, edit modal conditional render, optionalCreateProperties model skip) enforce mutual exclusivity. Clearing sends model: null in the edit path.
  • Existing selections visible in details and survive import/exportconfiguration-section.tsx renders a read-only AutomationAgentProfileSelector. automation-export.ts serializes and parses agent_profile_id through validateNullableSelection.
  • Missing profiles visible as unavailableagent-profile-selector.tsx shows "Unavailable profile ({{id}})" and retains the deleted profile as a dropdown item rather than silently selecting another.

Architecture

  • No direct fetch/axios to agent-server endpoints — useAgentProfilesAgentProfilesService is the proper service-layer path.
  • agent_profile_id on Automation and AutomationRun types mirrors the existing model field pattern (Canvas-local mirror of server-owned fields).
  • No new dependencies, no telemetry changes, no wire-contract redeclarations.
  • The AutomationAgentProfileSelector is a single reusable component shared across setup dialog, edit modal, and details view — good ownership.

Testing & Evidence

  • Unit tests cover: profile selection/clearing (agent-profile-selector.test.tsx), deleted-profile retention, bundle preflight/create profile preservation with model suppression (manifest-bundle.test.ts), custom-automation profile precedence (automation-setup.test.ts), and import/export round-trip for both null and UUID values (automation-export.test.ts).
  • Live evidence in .pr/ includes a GIF recording through real Canvas/Agent Server/Automation services showing before (null profile) and after (saved profile) behavior, plus supporting DB/payload JSON snapshots.

Risk Assessment

🟢 Low risk — The change is additive: a new optional field flows through existing UI patterns and service layers. When agentProfiles capability is absent, the feature is invisible and behavior is unchanged. The mutual-exclusivity between agent_profile_id and model is enforced consistently across all code paths. No agent runtime behavior, prompts, or tool selection is modified in Canvas.

Recommendation: A human maintainer should confirm the companion Automation Service API change (OpenHands/automation#453) is merged or will merge alongside this, since the frontend relies on the backend accepting agent_profile_id in create/update requests.

all-hands-bot
all-hands-bot previously approved these changes Sep 13, 2026

@all-hands-bot all-hands-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This review was created by an AI agent (OpenHands) on behalf of the repository maintainers.

Summary

PR #17396 adds agent-profile selection to automations — creation, editing, details display, and import/export — reusing the existing useAgentProfiles hook and SettingsDropdownInput. A selected profile suppresses the separate model field; deleted profiles remain visible as unavailable. Capability discovery (agentProfiles feature) gates the UI.

Acceptance Criteria Checklist (Issue #17395)

  • Creation and editing persist agent_profile_idbuildCreateAutomationRequest sends it; edit-automation-modal.tsx sends it in PATCH; bundle creation reuses optionalCreateProperties.
  • Offer selection only when deployment advertises agentProfiles — both the edit modal and setup dialog gate on capabilities.features.includes("agentProfiles").
  • Selecting a profile suppresses model selection; clearing restores default — model dropdown hidden when profile set; __default__ sentinel clears to null; save logic forces model: null when a profile is active.
  • Existing selections visible in details; survive import/exportconfiguration-section.tsx renders read-only selector; serializeAutomation/parseAutomationFile round-trip the field.
  • Missing profiles visible as unavailable — selector shows "Unavailable profile ({id})" and retains the stale ID in the dropdown.

Analysis

The mutual-exclusivity logic between agent_profile_id and model is consistently enforced across all paths:

  • API layer (automation-service.api.ts): spec.agent_profile_id ? { agent_profile_id } : spec.model && { model } — only one is sent.
  • Edit modal save: selectedModel = form.agentProfileId ? "" : form.model.trim() — forces model to empty when a profile is selected, and sends model: null if the automation previously had a model.
  • Manifest setup: optionalCreateProperties skips model when values.agent_profile_id is truthy; manifest-local-validation.ts skips llm-profile field validation when a profile is selected.
  • Export/import: validateNullableSelection validates both fields symmetrically; profile takes precedence on creation if both are present in an imported file.

No direct agent-server calls, raw fetch/axios, or Canvas-local wire-contract redeclarations were introduced. The new AUTOMATIONS$UNAVAILABLE_AGENT_PROFILE i18n key has all 15 supported languages. Live evidence is provided under .pr/.

No material issues found.

Risk Assessment

🟢 LOW — The change is additive: a new optional field flows through existing patterns (profile query, settings dropdown, manifest builder, export validator). The capability gate ensures deployments without agentProfiles see no change. No agent behavior, prompts, or tool-selection paths are modified in Canvas — the profile is passed through to the automation service API, which owns resolution.

Verdict: APPROVE

@all-hands-bot
all-hands-bot dismissed their stale review September 13, 2026 15:03

Automated review used the wrong decision (APPROVED instead of COMMENT) and is dismissed. Findings are reposted as a comment.

@neubig

neubig commented Sep 13, 2026

Copy link
Copy Markdown
Member Author

Audited all review feedback. Missing translations were fixed in2ffcb495c and current CI verifies the implementation. The nonblocking server-downgrade observation is intentionally kept safe: unsupported deployments do not expose profile edits, while the saved profile ID is preserved and remains visible in configuration details. I did not add a fallback that could change privileges. Companion Automation453 availability and the existing HUMAN-note validation gate remain separate. Please review the current head.

@neubig
neubig requested review from all-hands-bot and removed request for all-hands-bot September 13, 2026 18:03

@all-hands-bot all-hands-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This review was created by an AI agent (OpenHands) on behalf of the repository maintainers.

Summary

This PR adds agent-profile selection to automation creation, editing, details, and import/export. It reuses the existing useAgentProfiles hook, SettingsDropdownInput, and deployment capability discovery (agentProfiles feature flag) — no new API access patterns or raw endpoint calls are introduced.

Acceptance Criteria Checklist (issue #17395)

  • ✅ Creation and editing persist agent_profile_id through the Automation Service API — buildCreateAutomationRequest sends it; the edit modal PATCH body includes it.
  • ✅ Offer selection only when the deployment advertises agentProfiles — both the setup dialog and edit modal gate on capabilities?.features.includes("agentProfiles").
  • ✅ Selecting a profile suppresses the separate model field, and clearing restores it — setup dialog filters out llm-profile fields; edit modal hides the model dropdown; save handler forces model: null when a profile is selected.
  • ✅ Existing selections remain visible in details and survive import/export — configuration-section.tsx renders the selector read-only; serializeAutomation/parseAutomationFile round-trip agent_profile_id via validateNullableSelection.
  • ✅ Missing profiles are visible as unavailable — the selector appends an "Unavailable profile" entry for deleted profile IDs rather than silently selecting another.

Findings

No material bugs, security issues, or design flaws found. The model/profile mutual exclusivity is consistently enforced across all three data-flow paths (create payload, edit PATCH body, preflight draft). The optionalCreateProperties reuse for bundle payloads (the bug fix called out in the PR description) is verified: buildBundlePayload now calls optionalCreateProperties, and buildPreflightBody delegates to buildCreatePayload, so both paths carry agent_profile_id.

Cross-Repo Prerequisite

The PR description correctly notes this requires OpenHands/automation#453 for the backend to persist and dispatch agent_profile_id. The Canvas-side code is complete; the backend prerequisite must merge and ship first.

Risk Assessment

🟡 Medium — This PR affects agent behavior (tool selection, available secrets via the selected profile). The Canvas implementation is sound, but the cross-repo backend dependency and the agent-behavior surface warrant human review before merge. Recommend verifying end-to-end with a deployment that advertises agentProfiles once automation#453 ships.


Improve this review? If any feedback above seems incorrect or irrelevant to this repository, you can teach the reviewer to do better:

  1. Add a .agents/skills/custom-codereview-guide.md file to your branch (or edit it if one already exists) with the /codereview trigger and the context the reviewer is missing.
  2. Re-request a review - the reviewer reads guidelines from the PR branch, so your changes take effect immediately.
  3. When your PR is merged, the guideline file goes through normal code review by repository maintainers.

Resolve with AI? Install the iterate skill in your agent and run /iterate to automatically drive this PR through CI, review, and QA until it's merge-ready.

Was this review helpful? React with 👍 or 👎 to give feedback.

@neubig
neubig requested review from all-hands-bot and removed request for all-hands-bot September 13, 2026 23:28
@all-hands-bot

Copy link
Copy Markdown
Collaborator

🤖 OpenHands is reviewing this PR.

Head commit: 491960676179fc723960dd85f670d780b566ec79
View the conversation: https://oss-agent-canvas.ngrok.dev/conversations/7bf761da-7f9b-4f08-b91f-ad7d906fa42e

This comment was posted by an AI agent (OpenHands).

@all-hands-bot all-hands-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This review was created by an AI agent (OpenHands) on behalf of the repository maintainers.

Summary

This PR adds agent profile selection to automation creation, editing, details, and import/export. The agent_profile_id field is mutually exclusive with model -- when a profile is selected, the model field is suppressed across all paths (create request builder, optional-properties builder, form validation, and UI rendering). Deleted profiles remain visible as unavailable rather than silently changing privileges. The bundle creation path is fixed to include optional properties (previously missing).

Acceptance Criteria Checklist (Issue #17395)

  • Profile selection in automation creation (manifest-setup-dialog.tsx)
  • Profile selection in automation editing (edit-automation-modal.tsx)
  • Saved selection shown in details (configuration-section.tsx, read-only mode)
  • Profile preserved through import/export (automation-export.ts)
  • Selected profile suppresses the separate model field (consistent across all code paths)
  • Capability discovery controls availability (agentProfiles feature gate)
  • Deleted profiles remain visible as unavailable (agent-profile-selector.tsx)
  • Catalog automations requiring profiles enforce selection before submit

Analysis

Mutual exclusivity is consistently enforced. The agent_profile_id vs model precedence is applied in:

  • buildCreateAutomationRequest (automation-service.api.ts:199-201): ternary spread -- profile OR model
  • optionalCreateProperties (automation-setup.ts:278): skips model when profile is set
  • edit-automation-modal.tsx:250: selectedModel = form.agentProfileId ? "" : form.model.trim()
  • manifest-local-validation.ts:271: skips llm-profile validation when profile is set
  • manifest-setup-dialog.tsx:558-561: filters out llm-profile field when profile is set

Bundle path fix is correct. buildBundlePayload now calls optionalCreateProperties(entry.setup, values) (line 543), matching the non-bundle path which already did so at line 417-420. This closes the gap where bundle-created automations lost profile/model/timeout.

Component design is clean. AutomationAgentProfileSelector handles both interactive (with onChange) and read-only (without onChange) modes through a single interface, used consistently across setup dialog, edit modal, details view, and review step.

Deleted profile handling is a good security/UX decision. Rather than silently selecting a different profile or clearing the field, the selector appends an unavailable entry with the original ID visible, preserving the user's awareness of what was configured.

Cross-repo dependency is correctly scoped. The PR adds no runtime transport or profile-resolution logic to Canvas -- that belongs in automation#453. The merge prerequisite is documented.

Risk Assessment

LOW -- The change is additive: a new optional field with proper capability gating, consistent mutual exclusivity logic, and proportional test coverage. No existing behavior is altered for automations without a selected profile. The bundle path fix is a correctness improvement (previously missing optional properties). The cross-repo prerequisite (automation#453) must merge and ship before this has runtime effect.

Verdict

No material findings. The change is well-structured with consistent enforcement of the profile/model mutual exclusivity across all code paths, graceful handling of deleted profiles, and adequate test coverage. Live before/after evidence is provided.

all-hands-bot
all-hands-bot previously approved these changes Sep 14, 2026

@all-hands-bot all-hands-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This review was created by an AI agent (OpenHands) on behalf of the repository maintainers.

Summary

This PR adds agent-profile selection to automation creation, editing, details display, and import/export. The implementation is clean: one shared AutomationAgentProfileSelector component is reused across setup dialog, edit modal, and read-only details view. A selected profile suppresses the separate model field consistently across all code paths. Deleted profiles remain visible as unavailable rather than silently changing privileges. The bundle creation path is also fixed to include optional properties (previously missing).

Acceptance Criteria Checklist (Issue #17395)

  • Profile selection in creationmanifest-setup-dialog.tsx renders the selector gated on agentProfiles capability; agent_profile_id flows through buildCreatePayloadoptionalCreateProperties.
  • Profile selection in editingedit-automation-modal.tsx renders the selector and sends agent_profile_id in the PATCH body.
  • Saved selection shown in detailsconfiguration-section.tsx renders a read-only AutomationAgentProfileSelector.
  • Selection preserved through import/exportautomation-export.ts serializes and parses agent_profile_id via validateNullableSelection.
  • Capability discovery controls availability — both setup dialog and edit modal gate on capabilities.features.includes("agentProfiles").
  • Selected profile suppresses the separate model field — enforced in 5 places: buildCreateAutomationRequest (ternary spread), optionalCreateProperties (skip model when profile set), handleSubmit (selectedModel = form.agentProfileId ? "" : form.model.trim()), validateFormValues (skip llm-profile validation), and manifest-setup-dialog.tsx (filter llm-profile fields from render).
  • Deleted profiles remain visible as unavailable — selector appends the stale ID with a localized "Unavailable profile" label.
  • Catalog automations requiring profiles enforce selection — both setup dialog and edit modal block submit when requiresAgentProfile && !agent_profile_id.

Analysis

Mutual exclusivity is consistently enforced. The profile/model precedence is applied identically across all data-flow paths. The edit modal's PATCH body correctly handles all transitions (profile→model, model→profile, no-change save) — switching to a profile forces model: null in the body even for legacy automations that had both fields.

Bundle path fix is correct. buildBundlePayload now calls optionalCreateProperties(entry.setup, values), matching the non-bundle direct path. This closes the gap where bundle-created automations lost profile/model/timeout.

Architecture follows repository rules. No raw fetch/axios calls — useAgentProfilesAgentProfilesService is the proper service-layer path. The agent_profile_id on Automation and AutomationRun types mirrors the existing model field pattern. The new i18n key AUTOMATIONS$UNAVAILABLE_AGENT_PROFILE has all 15 supported languages.

Cross-repo dependency is correctly scoped. The PR adds no runtime transport or profile-resolution logic to Canvas — that belongs in automation#453. The merge prerequisite is documented.

Risk Assessment

🟢 LOW — The change is additive: a new optional field flows through existing UI patterns and service layers. The capability gate ensures deployments without agentProfiles see no change. No agent behavior, prompts, or tool-selection paths are modified in Canvas. Profile IDs are UUIDs from the backend, not user-supplied free text. No new dependencies. The bundle path fix is a correctness improvement.

@all-hands-bot
all-hands-bot dismissed their stale review September 14, 2026 12:00

Automated review used the wrong decision (APPROVED instead of COMMENT) and is dismissed. Findings are reposted as a comment.

@neubig
neubig force-pushed the factory/automation-profile-selector branch from 08213f3 to 0f995ed Compare September 14, 2026 16:44
Co-authored-by: openhands <openhands@all-hands.dev>
@neubig
neubig force-pushed the factory/automation-profile-selector branch from 0f995ed to cc4d3ce Compare September 15, 2026 01:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: feat A new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Select an agent profile when creating or editing an automation

3 participants