Skip to content

Prompt and plugin presets ignore the selected agent profile at run time #557

Open

Description

@simonrosenberg

Problem

On main (and the released 1.17.0 and 1.18.0), the prompt and plugin presets ignore an automation's selected agent profile when they run. The run uses the default agent instead of the profile's tools, prompt, MCP servers and LLM, and nothing reports that the profile was dropped.

What happens today:

  1. Create rejects the profile. POST /v1/preset/prompt and /v1/preset/plugin return 422 "Extra inputs are not permitted" for agent_profile_id (CreatePromptAutomationRequest / CreatePluginAutomationRequest in preset_router.py are extra="forbid" and have no such field). Agent Canvas tracks the UI side as [Bug]: Automation setup offers an Agent profile for Prompt and Plugin actions, but choosing one blocks creation with "Extra inputs are not permitted" OpenHands#17960.
  2. Update accepts it. PATCH on the automation stores agent_profile_id (router.py), which is the path Canvas's edit modal uses.
  3. The dispatcher passes it on. It sets AUTOMATION_AGENT_PROFILE_ID in the run environment (dispatcher.py:347).
  4. The preset scripts never read it. presets/prompt/sdk_main.py:446 and presets/plugin/sdk_main.py:477 build get_default_agent(llm=..., cli_mode=True, ...) client-side. The only reference to the variable outside the dispatcher is tests/test_dispatcher.py.

Reproduction

Verified 2026-10-05 against Agent Canvas with agent-server 1.52.0 and automation 1.17.0. Main and 1.18.0 have the same code.

  1. Save an agent profile with a custom tool selection, e.g. tools: [terminal, file_editor, task_tool_set].
  2. Create a prompt-preset automation. Adding agent_profile_id to the create request returns 422.
  3. Set agent_profile_id on the automation with PATCH; it's accepted.
  4. Run it.

Observed: the run's conversation gets the default tools (terminal, file_editor, task_tracker), not the profile's, and the conversation has launched_agent_profile: null.

Expected

A preset run with a selected profile launches that profile, so launched_agent_profile is set and the profile's tools, prompt, MCP servers and LLM apply. Until that works, selecting a profile on a preset automation should be rejected consistently on create and update, rather than accepted and silently ignored.

Context

Acceptance criteria

  • On main, a prompt- or plugin-preset run with agent_profile_id launches through that profile (launched_agent_profile matches; the model is offered the profile's tools).
  • Create and update agree on whether presets accept agent_profile_id.
  • A run whose profile can't be applied fails visibly instead of falling back to the default agent.
  • Shipped in a release that Agent Canvas can pin.

OpenHands AI triage

The following comments and acceptance criteria were added by the OpenHands AI agent.

Triage

Verified on main (2da02a5) and in released 1.18.0: CreatePromptAutomationRequest and CreatePluginAutomationRequest (preset_router.py) set extra="forbid" and omit agent_profile_id, so POST /v1/preset/prompt and /v1/preset/plugin reject it with 422. UpdateAutomationRequest and the PATCH path accept and persist it, and the dispatcher sets AUTOMATION_AGENT_PROFILE_ID (dispatcher.py:356), but the only reader of that variable anywhere is tests/test_dispatcher.py — both preset sdk_main.py scripts build get_default_agent(llm=..., cli_mode=True, ...) and never consult it. The field is therefore accepted on update and silently dropped at run time.

Scope: make the two preset endpoints accept agent_profile_id consistently with raw create and PATCH, and make a preset run apply the selected profile (profile-resolved tools, prompt, MCP servers, and LLM) to the launched conversation, with a visible failure when the profile cannot be applied. This reuses the repository's authoritative profile mechanism (ensure_agent_profile_exists / validate_agent_profile_combination for selection, and agent_profile_id + AUTOMATION_AGENT_PROFILE_ID for dispatch) rather than adding a new profile loader. A profile owns its model, so agent_profile_id and model remain mutually exclusive, matching raw create.

Non-goals: the factory/automation branch work (#453) and its preset FinishTool hook follow-up (#457) are not in scope here — this issue is the main-and-release behavior; no UI/Canvas change (tracked in OpenHands/OpenHands#17960 / #17971); no new agent-profile schema, tool, or MCP plumbing; no change to raw /v1 automations beyond keeping preset acceptance consistent with them.

Actual Behavior

Adding agent_profile_id to a POST /v1/preset/prompt or /v1/preset/plugin request returns 422 "Extra inputs are not permitted". Setting it with PATCH is accepted and stored, and the dispatcher exports AUTOMATION_AGENT_PROFILE_ID, but a preset run still launches the default agent: the conversation gets the default tools (terminal, file_editor, task_tracker) and launched_agent_profile is null. No error or warning reports that the profile was dropped.

Desired Behavior

A prompt- or plugin-preset automation that selects agent_profile_id runs through that profile: the launched conversation reports launched_agent_profile matching the selection and offers the profile's tools, prompt, MCP servers, and LLM. Create and update agree on accepting the field (and on rejecting a combined agent_profile_id + model). If the profile cannot be applied at run time, the run fails visibly instead of falling back to the default agent.

Acceptance Criteria

  • POST /v1/preset/prompt and POST /v1/preset/plugin accept an optional agent_profile_id, store it on the created automation, and return it in the response (parity with POST /v1 and PATCH /v1/{id}).
  • Both preset create endpoints reject agent_profile_id combined with model with the same error as raw create, and an unknown profile is rejected the same way raw create rejects it.
  • POST /v1/validate with endpoint: "/v1/preset/prompt" (and /v1/preset/plugin) treats agent_profile_id as valid input and reports a missing or conflicting profile as a field-level validation error, consistent with endpoint: "/v1".
  • A prompt-preset run whose automation has agent_profile_id set launches a conversation with launched_agent_profile equal to that id, and the conversation's available tools match the profile's tool selection (verified live, e.g. in Agent Canvas against agent-server).
  • The same holds for a plugin-preset run with agent_profile_id set.
  • When the selected profile cannot be resolved or applied at run time, the run fails with a visible error (non-success run status and/or an error surfaced to the caller) rather than launching the default agent; no silent fallback occurs.
  • An automation with no agent_profile_id continues to run with the existing default-agent behavior (no regression to the model-profile path).
  • A regression test asserts that both preset sdk_main.py scripts apply the profile rather than only the model profile, and a test covers create/update parity for the preset endpoints.
  • The fix is included in a released version that Agent Canvas can pin.

Activity

  1. rajshah4 commented on Oct 16, 2026

    @rajshah4
    Member

    This affects the normal Create Automation → enter a prompt workflow. I enabled sub-agents in my saved agent profile, but automation runs still launch without the task tool and silently proceed without delegation.
    Users should be able to use sub-agents through the normal automation setup without writing a custom script. This blocks a customer-facing demo and appears to affect newly created automations too. Could we raise the priority and assign an owner?

  2. simonrosenberg commented on Oct 16, 2026

    @simonrosenberg
    MemberAuthor

    I'm an AI agent (Claude Code) helping @simonrosenberg. I reproduced this on the versions in @rajshah4's setup: OpenHands Enterprise on Replicated 0.81.x. 0.81.0 and 0.81.1 pin the same components:

    Component Version
    enterprise-server 1.71.0 (SDK 1.50.1)
    agent-server (sandbox image) 1.50.1-python
    automation 1.19.1 (bundles SDK 1.53.0; preset setup.sh installs that in the sandbox)
    agent-canvas 1.27.1

    Why sub-agents never reach a prompt-preset run

    • Ordinary conversations work because enterprise 1.71.0 overlays the selected or active profile when it starts a conversation (resolve_agent_profile=True in live_status_app_conversation_service.py). enable_sub_agents then adds task_tool_set through get_default_tools(enable_sub_agents=...).
    • The prompt preset doesn't go through that path. presets/prompt/sdk_main.py (1.19.1) always builds get_default_agent(llm=llm, cli_mode=True, finish_tool_response_schema=TaskOutcome). In SDK 1.53.0 that never enables sub-agents. It then creates a RemoteConversation directly on the sandbox's agent-server, so no profile is consulted. AUTOMATION_AGENT_PROFILE_ID is set by the dispatcher (dispatcher.py:356) but read by neither preset. That's still true in 1.20.1 and on main.
    • In Canvas 1.27.1, the create form's Agent Profile pill defaults to "Active profile" and displays that profile's name, but sends no agent_profile_id. The run therefore falls back to the default agent without an error. Picking a profile explicitly sends agent_profile_id, which POST /v1/preset/prompt rejects with 422 (CreatePromptAutomationRequest is extra="forbid" and has no such field).

    Runtime check (mock LLM recording the tools it is offered)

    Setup: agent-server 1.50.1 with an agent profile that has enable_sub_agents: true, set as active.

    • Conversation started with that agent_profile_id: the model is offered task (plus terminal, file_editor, task_tracker, browser tools, …).
    • The 1.19.1 presets/prompt/sdk_main.py with SDK/tools/workspace 1.53.0 and AUTOMATION_AGENT_PROFILE_ID set to that profile. The script logs tools: ['terminal', 'file_editor', 'task_tracker', 'FinishTool']. The model is offered file_editor, finish, invoke_skill, task_tracker, terminal, think and no task, and the conversation has launched_agent_profile: null.

    The preset ran in local mode (AGENT_SERVER_URL). Cloud mode differs only in the workspace class (OpenHandsCloudWorkspace(local_agent_server_mode=True)); the agent-building code is the same.

    Implications

    • No released automation version fixes this, and there's no open PR for it, so upgrading doesn't help. On these versions, the only way to get delegation in an automation is a custom-code automation that builds the agent with sub-agents enabled.
    • In OHE the profile lives in enterprise, not in the sandbox's agent-server, so the preset can't simply forward AUTOMATION_AGENT_PROFILE_ID to StartConversationRequest.agent_profile_id. The conversation has to be created from the profile by the side that owns it, which is the feat: select agent profiles on automation definitions #453 approach on factory/automation. Or the preset has to receive the resolved launch from enterprise.
    • The fix should also define what the "Active profile" default means for automations (the pill implies the user's active profile is used). Getting it to OHE users then takes an automation release, an OpenHands-Cloud chart bump, and a Replicated release.
  3. croakingtoad commented on Oct 16, 2026

    @croakingtoad

    Related: the Agent Canvas frontend bug that produced the 422 this issue describes (pick a profile, POST /v1/preset/prompt rejects agent_profile_id) is tracked separately now that it's confirmed to also affect the ordinary New Automation conversation panel, not just the catalog Setup Dialog #17971 fixed: OpenHands/OpenHands#18569. That issue is scoped to hiding the picker for prompt/plugin kinds — it does not address the deeper problem this issue describes (preset run scripts ignoring AUTOMATION_AGENT_PROFILE_ID even when a profile is legitimately accepted on the raw /v1 endpoint).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't workingpriority:lowready-for-devScoped for contribution; managed by repository readiness checks.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions