feat: select agent profiles on automation definitions - #453
Conversation
|
🤖 OpenHands is reviewing this PR. Head commit: This comment was posted by an AI agent (OpenHands). |
|
Warning Your comment is too long (maximum is 65536 characters), so the coverage report was not added. See the job log for how to reduce it. |
all-hands-bot
left a comment
There was a problem hiding this comment.
This review was created by an AI agent (OpenHands) on behalf of the repository maintainers.
Review Summary
ð�¡ Acceptable â�� Core design is sound, but one critical bug will break Cloud and profile-less local dispatch.
Critical Issue
backend.api_prefix raises AttributeError on non-conversation backends (openhands/automation/dispatcher.py, line 515)
The old code checked get_config().service.run_agent_profile � a config string that was truthy when a profile was configured. The replacement backend.api_prefix is a property defined only on ConversationAgentServerBackend. Neither CloudSandboxBackend nor LocalAgentServerBackend defines it, so accessing it raises AttributeError.
This line is reached after a successful execution (if result.success:). The exception propagates to _execute_run_safe's broad except Exception, which marks the run FAILED � despite the actual execution having succeeded. The conversation_id link is also skipped.
Impact: Every successful Cloud dispatch and every successful local-mode-without-profile dispatch will be incorrectly marked FAILED.
Fix: Use isinstance(backend, ConversationAgentServerBackend) instead, or add an api_prefix property to the ExecutionBackend base class returning "" by default.
Risk Assessment
- Overall PR: ð�¡ MEDIUM â�� The
AttributeErrorbug is a regression that breaks the primary dispatch path for Cloud and non-profile local runs. Once fixed, the rest of the change is well-structured: migration is correct, run snapshot logic is sound, validation properly rejects conflicting model+profile selections, git sync round-trip is tested, and the Docker compatibility backend removal is clean.
Verdict
� Needs rework � The backend.api_prefix AttributeError must be fixed before merge. All other changes look good.
Key Insight: The api_prefix property is conversation-backend-specific, but the guard that uses it runs for every backend type.
Improve this review? If any feedback above seems incorrect or irrelevant to this repository, you can teach the reviewer to do better:
- Add a
.agents/skills/custom-codereview-guide.mdfile to your branch (or edit it if one already exists) with the/codereviewtrigger and the context the reviewer is missing. See the customization docs for the required frontmatter format.- Re-request a review - the reviewer reads guidelines from the PR branch, so your changes take effect immediately.
- 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
/iterateto automatically drive this PR through CI, review, and QA until it's merge-ready.Was this review helpful? React with � or � to give feedback.
all-hands-bot
left a comment
There was a problem hiding this comment.
This review was created by an AI agent (OpenHands) on behalf of the repository maintainers.
Summary
This PR persists agent_profile_id on automation definitions and snapshots it on queued runs, replacing the previous host-controlled deployment-level profile override map with per-automation profile selection. The CRUD API, preset endpoints, git sync, run history, and capability discovery all carry the selection. The unreleased Docker-only compatibility backend and profile override settings are removed.
Analysis
Data model & migration: The migration (023) adds a nullable agent_profile_id Uuid column to both automations and automation_runs, using generic SQLAlchemy types for cross-database compatibility. The snapshot-on-queue pattern in create_pending_run correctly ensures that editing a definition affects only future runs, not already-queued ones. The fallback to the deployment default (AUTOMATION_AGENT_PROFILE) when the automation has no explicit profile is handled correctly.
Validation: validate_agent_profile_selection consistently rejects (a) profiles in non-local mode and (b) a conflicting model field. This is applied uniformly across the CRUD create, CRUD update, prompt preset, plugin preset, and validate-draft endpoints. The update path correctly uses the pending update_data value (or the existing value when only model is being changed) for validation.
Dispatcher concurrency: Changing the gate from run_agent_profile to is_local_mode means all local-mode deployments now enforce conversation_max_concurrent_runs, not just those with a profile configured. This is correct — LocalAgentServerBackend also dispatches to the agent server, which has resource constraints. Since the removed settings were unreleased, no existing deployment loses behavior it was relying on.
Preset runner changes: The load_provisioned_agent helper fetches the conversation from the agent server, validates the launched profile matches AUTOMATION_AGENT_PROFILE_ID, and returns the already-configured agent. When a provisioned agent is present, the runner skips get_llm, get_secrets, get_mcp_config, and get_default_agent — meaning the host secret store is never forwarded to the sandbox. This is a genuine security improvement.
Profile-change tarball refresh: When an existing preset automation's profile is changed, the tarball is rebuilt with the current runner files (refresh_runner=True) while preserving prompt and plugin/repo configuration. The _replace_prompt_in_tarball function handles this correctly by tracking seen members and appending any replacement files that weren't already present.
Watchdog: The cleanup and staleness checks correctly shifted from deployment-level (run_agent_profile) to per-run (run.agent_profile_id or settings.agent_profile) and per-mode (is_local_mode) checks, which is more precise.
Risk Assessment
🟡 MEDIUM — The PR removes unreleased configuration options (AUTOMATION_DOCKER_AGENT_PROFILE, AUTOMATION_AGENT_PROFILE_OVERRIDES, docker_max_concurrent_runs) and the DockerAgentServerBackend compatibility class. Since these were unreleased, this is safe. The dispatcher concurrency behavior change for local-mode deployments without profiles is a behavioral shift but is correct. The SDK dependency bump (79021c6 → 85b8bc7) is a first-party package from the same organization and is excluded from the 7-day waiting rule, but the PR description notes a live factory rollout is in progress, which serves as real-world validation.
Verdict
✅ Worth merging — The design is sound, the data model is clean, validation is consistent across all entry points, and the preset runner changes improve security by avoiding host secret forwarding. Test coverage is thorough for the new behavior. No material issues found.
Improve this review? If any feedback above seems incorrect or irrelevant for this repository, you can teach the reviewer to do better:
- Add a
.agents/skills/custom-codereview-guide.mdfile to your branch (or edit it if one already exists) with the/codereviewtrigger and the context the reviewer is missing (e.g., "Security concerns about X do not apply here because Y"). See the customization docs for the required frontmatter format.- Re-request a review - the reviewer reads guidelines from the PR branch, so your changes take effect immediately.
- 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
/iterateto automatically drive this PR through CI, review, and QA until it's merge-ready.Was this review helpful? React with 👍 or 👎 to give feedback.
Automated review used the wrong decision (APPROVED instead of COMMENT) and is dismissed. Findings are reposted as a comment.
|
🤖 OpenHands is reviewing this PR. Head commit: This comment was posted by an AI agent (OpenHands). |
|
🤖 OpenHands is reviewing this PR. Head commit: This comment was posted by an AI agent (OpenHands). |
all-hands-bot
left a comment
There was a problem hiding this comment.
This review was created by an AI agent (OpenHands) on behalf of the repository maintainers.
Summary
This PR adds agent_profile_id to automation definitions and queued-run snapshots, carrying it through CRUD, presets, git sync, capabilities, and the watchdog. The design is clean: validation is centralized in validate_agent_profile_selection, the snapshot-on-queue pattern in create_pending_run is correct, and the preset runner scripts have a well-structured dual path (provisioned-conversation attach vs. legacy create).
Findings
No material issues found. A few observations:
-
Dispatcher/watchdog scope change is correct: The switch from
settings.agent_profiletosettings.is_local_modeindispatcher.pyandwatchdog.pybroadens the concurrency-limiting and staleness-scan logic to cover all local-mode runs, not just profile-based ones. This is the right call — local mode always uses the conversation backend pattern, so the concurrency limit and broader scan condition apply regardless of whether an individual run has a profile. -
PATCH clearing without model restoration: In
update_automation, whenagent_profile_idis explicitly set tonullwithout also providing amodel, the existingmodel=None(set when the profile was attached) stays as-is rather than being resolved to the user's active default. This is a minor design choice, not a bug —model=Nonemeans "use deployment default," which is functionally equivalent in most cases. The test suite confirms the profile-clearing path works. -
Git sync import consistency: The git import path in
_validate_and_resolve_fieldsreusesvalidate_agent_profile_selectionbefore resolving the tarball, which correctly rejects conflictingmodel+agent_profile_idcombinations without side effects. Themodelvalue from YAML is stored directly withoutresolve_model_profile_for_user— this is pre-existing behavior, not a regression. -
Security posture: The validation rejects profiles in cloud mode (preventing privilege escalation through a more privileged agent), and the README documents that missing profiles fail rather than falling back. The preset runner scripts correctly skip loading secrets/LLM/MCP when attaching to a provisioned conversation, avoiding secret-scope leakage.
-
Migration: Simple nullable
sa.Uuid()column addition to bothautomationsandautomation_runstables. Cross-database compatible.
Risk Assessment
🟢 LOW — The change is well-contained. Profile selection is validated consistently across all entry points. The snapshot pattern ensures queued runs are unaffected by definition edits. Tests cover round-trip creation, queued-run snapshots, preset runner refresh, git import validation, and credential handoff failure.
Verdict
✅ Worth merging — Core logic is sound, validation is consistent across all paths, and the security model is correct.
Improve this review? If any feedback above seems incorrect or irrelevant to this repository, you can teach the reviewer to do better:
- Add a
.agents/skills/custom-codereview-guide.mdfile to your branch with the/codereviewtrigger and context the reviewer is missing.- Re-request a review — the reviewer reads guidelines from the PR branch, so changes take effect immediately.
- When your PR is merged, the guideline file goes through normal code review.
Was this review helpful? React with 👍 or 👎 to give feedback.
|
@all-hands-bot please review the current head after restacking on the SDK pin refresh and explicitly approve it if there are no material findings. |
Code Review � PR #453 (current head
|
all-hands-bot
left a comment
There was a problem hiding this comment.
Reviewed head e17c670 (post SDK pin restack). No material findings. See the detailed review comment for the full assessment. Verdict: APPROVED, risk LOW.
Generated by OpenHands AI on behalf of the user.
e17c670 to
4c6ef57
Compare
4c6ef57 to
0106d63
Compare
0106d63 to
a8290ee
Compare
a8290ee to
edd59ae
Compare
edd59ae to
b62aac5
Compare
b62aac5 to
df845df
Compare
df845df to
cf5bd94
Compare
cf5bd94 to
0b14138
Compare
0b14138 to
93d0bee
Compare
|
👋 This PR needs a couple of things fixed before OpenHands can review it:
Push an update once this is addressed and this check re-runs automatically. This is an automated check - no AI was used to generate this comment. |
Why
Different automations need different model, tool, MCP, egress, and secret policy. A definition therefore needs to select a saved Agent Server profile. Profile selection is policy; it is independent of the execution scope and Agent Server provisioning interfaces introduced by #449.
Summary
agent_profile_idon definitions and queued-run snapshots.The migration is revision
026, after #449's execution-scope revision025.Issue Number
Implements #273. Canvas selector: OpenHands/OpenHands#17396.
How to Test
Live Agent Canvas evidence
Animated queued-profile demonstration · scenario, revisions, and limits. It demonstrates selected-profile conversation creation and a queued run retaining its snapshotted profile in local and Docker workspaces.
Dependencies and review order
Native stack #454: #449 → #453. Merged software-agent-sdk #5010 supplies typed conversation creation and attachment. Replace the temporary SDK source pin with a released SDK before merge.
Profile-selected secret enforcement is completed by merged software-agent-sdk #4931 and open #5017; selecting a profile alone is not the secret boundary.
Known pre-existing limitation: profile-created preset conversations do not yet receive the preset FinishTool enforcement hook. #457 tracks that separate correction.