Repository navigation
Prompt and plugin presets ignore the selected agent profile at run time #557
Description
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:
- Create rejects the profile.
POST /v1/preset/promptand/v1/preset/pluginreturn 422 "Extra inputs are not permitted" foragent_profile_id(CreatePromptAutomationRequest/CreatePluginAutomationRequestinpreset_router.pyareextra="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. - Update accepts it.
PATCHon the automation storesagent_profile_id(router.py), which is the path Canvas's edit modal uses. - The dispatcher passes it on. It sets
AUTOMATION_AGENT_PROFILE_IDin the run environment (dispatcher.py:347). - The preset scripts never read it.
presets/prompt/sdk_main.py:446andpresets/plugin/sdk_main.py:477buildget_default_agent(llm=..., cli_mode=True, ...)client-side. The only reference to the variable outside the dispatcher istests/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.
- Save an agent profile with a custom tool selection, e.g.
tools: [terminal, file_editor, task_tool_set]. - Create a prompt-preset automation. Adding
agent_profile_idto the create request returns 422. - Set
agent_profile_idon the automation withPATCH; it's accepted. - 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
- The behaviour is already implemented on the
factory/automationbranch by feat: select agent profiles on automation definitions #453 ("select agent profiles on automation definitions": the backend creates the conversation from the profile and the worker attaches to it), with Apply preset FinishTool hooks to profile-created conversations #457 tracking the preset FinishTool hook on that path. It hasn't reachedmainor a release, so Canvas and cloud, which consume released versions, still get the old behaviour. - Related: feat: select an agent profile for delegated automation work #479 and feat: support agent profiles in cloud mode #541 (profile selection plumbing on
main), [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, and fix(automations): hide agent profiles for preset actions OpenHands#17971 (Canvas hides the profile picker for preset actions on create; the edit modal still offers it).
Acceptance criteria
- On
main, a prompt- or plugin-preset run withagent_profile_idlaunches through that profile (launched_agent_profilematches; 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/promptandPOST /v1/preset/pluginaccept an optionalagent_profile_id, store it on the created automation, and return it in the response (parity withPOST /v1andPATCH /v1/{id}). - Both preset create endpoints reject
agent_profile_idcombined withmodelwith the same error as raw create, and an unknown profile is rejected the same way raw create rejects it. -
POST /v1/validatewithendpoint: "/v1/preset/prompt"(and/v1/preset/plugin) treatsagent_profile_idas valid input and reports a missing or conflicting profile as a field-level validation error, consistent withendpoint: "/v1". - A prompt-preset run whose automation has
agent_profile_idset launches a conversation withlaunched_agent_profileequal 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_idset. - 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_idcontinues to run with the existing default-agent behavior (no regression to the model-profile path). - A regression test asserts that both preset
sdk_main.pyscripts 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
rajshah4 commentedon Oct 16, 2026
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?
simonrosenberg commentedon Oct 16, 2026
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:
setup.shinstalls that in the sandbox)Why sub-agents never reach a prompt-preset run
resolve_agent_profile=Trueinlive_status_app_conversation_service.py).enable_sub_agentsthen addstask_tool_setthroughget_default_tools(enable_sub_agents=...).presets/prompt/sdk_main.py(1.19.1) always buildsget_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 aRemoteConversationdirectly on the sandbox's agent-server, so no profile is consulted.AUTOMATION_AGENT_PROFILE_IDis set by the dispatcher (dispatcher.py:356) but read by neither preset. That's still true in 1.20.1 and onmain.agent_profile_id. The run therefore falls back to the default agent without an error. Picking a profile explicitly sendsagent_profile_id, whichPOST /v1/preset/promptrejects with 422 (CreatePromptAutomationRequestisextra="forbid"and has no such field).Runtime check (mock LLM recording the
toolsit is offered)Setup: agent-server 1.50.1 with an agent profile that has
enable_sub_agents: true, set as active.agent_profile_id: the model is offeredtask(plusterminal,file_editor,task_tracker, browser tools, …).presets/prompt/sdk_main.pywith SDK/tools/workspace 1.53.0 andAUTOMATION_AGENT_PROFILE_IDset to that profile. The script logstools: ['terminal', 'file_editor', 'task_tracker', 'FinishTool']. The model is offeredfile_editor, finish, invoke_skill, task_tracker, terminal, thinkand notask, and the conversation haslaunched_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
AUTOMATION_AGENT_PROFILE_IDtoStartConversationRequest.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 onfactory/automation. Or the preset has to receive the resolved launch from enterprise.croakingtoad commentedon Oct 16, 2026
Related: the Agent Canvas frontend bug that produced the 422 this issue describes (pick a profile,
POST /v1/preset/promptrejectsagent_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 ignoringAUTOMATION_AGENT_PROFILE_IDeven when a profile is legitimately accepted on the raw/v1endpoint).