feat(agent-profiles): give a profile its own persona or extra instructions - #17843
Merged
Merged
Conversation
The editor asks the agent-server which tools may be picked and what a profile resolves to, so canvas keeps no tool list of its own. - Tools section in the profile editor: Standard shows the resolved set the server reports for this profile; Choose tools lists the catalog's selectable, runnable entries. - Gated on the tool_catalog_v1 capability; without it the section is hidden and the stored selection is left untouched. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Both switches controlled which tools an agent gets, which the tool picker now does. Two controls over the same thing meant a profile could say "delegation on" and "tools: [glob]" at once, and the picker could not show the tools the switches owned. `task_tool_set` and `SwitchLLMTool` are ordinary catalog entries in the picker now (software-agent-sdk#5151), so the editor drops both toggles and the version gate that guarded sending `enable_switch_llm_tool` on a profile save. The `agent_settings` launch path keeps its own `enable_sub_agents`, which the SDK still honours. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Canvas attaches this tool itself for every conversation it hosts, so it is not a per-profile capability, but the catalog offered it like one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ending answer The picker listed bare tool names, so a user had to know what `task_tool_set` or `ask_oracle` does. The server now sends a one-line blurb per tool (software-agent-sdk#5151); `ProfileScopeList` already renders one, so both the standard preview and the picker pass it through. Switching to "choose tools" while the standard set was still resolving seeded the selection from `undefined`, saving a profile with no tools at all. The mode control stays locked until the server has answered. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…file The guard against seeding from an unresolved standard set keyed off the query's `isPending`, which react-query also reports for a query disabled for want of a draft — so a profile being created, with no name typed yet, had its mode control locked with nothing to wait for. It now keys off the actual invariant: a draft exists but the server has not answered for it. The test mock models the disabled case, which is what hid this. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A draft whose `llm_profile_ref` dangles materialises 200 with no tools. The guard only covered `undefined`, so that answer counted as resolved and switching to "choose tools" seeded an empty selection — the very thing the guard exists to prevent. The standard set is never legitimately empty, so an empty answer now keeps the mode locked, as does a failed request. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`tools: []` is a bare agent the user asked for, but the seed treated an empty list as "nothing chosen yet" — so toggling to Standard and back silently refilled it with the standard set, un-baring the agent. The selection now tracks whether it is the user's: a stored list counts as chosen even when empty, and so does any toggle. Seeding happens once, when there is genuinely nothing to preserve. Raised three times in review, and independently by @rajshah4 testing against the SDK PR. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 9135274)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…atalog service The standard tool set now comes from the catalog's in_default_set flag, so the editor no longer POSTs a stand-in draft per keystroke. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…l toggles without one - Standard tools = catalog entries with in_default_set && usable; the mode dropdown only waits for the catalog, not a name/LLM-dependent materialize. - Backends without tool_catalog_v1 (cloud, older agent-servers) get the sub-agents and LLM-switching toggles back, writing enable_sub_agents / enable_switch_llm_tool exactly as on main. The global settings page keeps them too. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…rom a failed catalog - Where the server no longer stores enable_sub_agents / enable_switch_llm_tool (cloud once it moves to the tool-catalog SDK), seed the legacy toggles from the profile's `tools` rather than from hard-coded defaults, so a save round-trips what the profile launches. - Show an error with a Retry button when the tool catalog fails to load, instead of leaving the tools mode disabled with an empty standard list. - Drop a comment describing Canvas behaviour from CanvasUITool. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ools - Without a catalog (cloud), the sub-agent and switch_llm toggles now edit a stored explicit `tools` list instead of relying on the server to fold switches it ignores. switch_llm is only written into the list for schema v3 profiles, since older servers attach it from the switch alone. - Seed the sub-agents toggle from list membership when `tools` is explicit. - Standard → custom → standard no longer leaves the form dirty. - readProfileTools dedups with a Map, so tools named like Object.prototype members survive, and it reads SwitchLLMTool as switch_llm. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The profile editor had two controls over the same thing again: the tool picker, and sub-agent / LLM-switching toggles kept for backends without a catalog. Tools are now only chosen in the picker. A backend without a catalog gets no tool control, and a save leaves the stored `tools` as is. Cloud advertises no capabilities, so the editor asks it for `/api/tools/catalog` and reads a 404 as "no catalog". The profile-model version gate for `enable_switch_llm_tool` goes with the toggle. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The capability came from a module-level cache with no host check and no re-render, so the picker could stay hidden after server info loaded or reflect the previous backend after a switch. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…able Drop the tool_catalog_v1 capability gate (and the server-info query added for it): every supported backend is expected to serve the catalog, and the query stays keyed on the backend host. When the catalog 404s, fails, or is still loading, the draft leaves out tools, so the whole-profile save carries the stored tools and legacy tool switches through unchanged. The editor says the tools section is unavailable and that saving keeps the current tools. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The server now derives enable_sub_agents / enable_switch_llm_tool from tools and reads a changed switch as a toggle, so carrying the stored switches next to an edited tools list could re-add a tool the user removed. Without a tools draft the stored values still round-trip unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
# Conflicts: # src/i18n/translation.json
Canvas now requires the SDK release that serves /api/tools/catalog and stores profile tools only as `tools`, so remove the no-catalog 404 state, the stored tool-switch stripping on save, and the SwitchLLMTool class-name alias. Add a mock /api/tools/catalog handler so dev:mock can exercise the picker. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
`tools` is the only tool control now. Global agent settings leave it unset, so new conversations get the standard set (with switch_llm); sub-agents and a custom tool list are chosen on an agent profile. The adapter sends a configured tools list as given instead of adding it to the defaults, and never sends the retired flags. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- An agent_settings launch with no tools selection omits `tools`; the server resolves the standard set, adding the browser where it can run. An explicit list is sent as given. - Drop the client copy of the standard set and the advertised-tool gating (isAgentServerToolAvailable) it relied on. - VITE_ENABLE_BROWSER_TOOLS=false now starts the agent-server with OH_ENABLE_BROWSER=false instead of trimming the payload, so the flag is read when the stack starts rather than at build time. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
DEFAULT_SETTINGS carried agent_settings schema 6, which the server now migrates by adding switch_llm to an explicit tools list. The .pr notes and scripts cover the server-resolved default set, the browser-off switch and the dry run's valid flag. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ocal comments Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…SATION_IMAGE_HAS_BROWSER Settings migrated from the retired tool switches carry a pinned tools list that no editor shows. The agent-profile library now surfaces it with a reset to the standard set (tools: null). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…rompt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…alog Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…alog # Conflicts: # src/routes/agent-settings.tsx
…gh ToolClient Raise minimumAgentServer to 1.51.0, the first release serving /api/tools/catalog. Tools stay local-only: cloud does not serve the catalog or honour profile tools yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Stack on #17516, which pins agent-server 1.52.0 and raises the floor to 1.51.0. Every supported local server now accepts persona, so the profile_persona_v1 gate goes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…feat-profile-system-prompt
Local launches send the default profile through agent_settings, so its stored tools never reach the agent; the editor now says so instead of offering them. The secret-scope capability probe goes (every supported server enforces it), and test fixtures move above the new minimum agent-server version. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…feat-profile-system-prompt # Conflicts: # __tests__/api/agent-profiles-service/profile-field-support.test.ts # src/routes/agent-settings.tsx
7 tasks
Automation 1.18.0 is built on SDK 1.53.0, so the SDK version check passes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…feat-profile-system-prompt
2 of 5 tasks
…feat-profile-system-prompt
Taken on this head (stacked on #17516), so the editor shows the tool picker instead of the removed sub-agent and LLM-switch toggles. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rompt # Conflicts: # __tests__/api/agent-profiles-service/profile-field-support.test.ts # __tests__/routes/agent-settings.test.tsx # __tests__/routes/build-agent-profile-fields.test.ts # src/api/agent-profiles-service/profile-field-support.ts # src/routes/agent-settings.tsx
This was referenced Oct 5, 2026
Contributor
|
🚀 Released in v1.25.0. |
19 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
HUMAN:
Adds one System prompt section to the Agent Profile editor: keep the OpenHands default, add your own instructions, or give the agent a custom persona. The persona replaces only who the agent is and how it codes, so security, risk-assessment, memory and tool guidance stay. I had the agent run the full local Canvas stack on software-agent-sdk#5449 and launch real conversations in each mode. The System Message shows the persona followed by the kept guidance (screenshots below).
npm run buildpasses.AGENT:
Why
A task-tuned agent (a read-only explorer, a planner, a triage bot, a non-coding agent) needs a different identity and way of working. It still needs OpenHands' operating rules:
software-agent-sdk#5449 adds a profile
personathat replaces just the persona and coding-workflow part of the prompt. The profile already hadsystem_message_suffixfor adding instructions. This section exposes both as one choice.Summary
persona: null, system_message_suffix: null.system_message_suffix. The built-in prompt stays, and the text is appended to the dynamic block.personaand clears the instructions. It replaces Soul, Role and the coding-workflow sections. Memory, security policy, risk assessment, browser, external services, process management, model-specific guidance and the dynamic block are kept. The hint says so.personafirst, then a stored suffix, otherwise the default.persona, so there is no capability check.personayet, so neither choice would apply there.defaultprofile, with a hint to create a named profile. Local launches routedefaultthroughagent_settings, so a prompt stored on it would be ignored. feat(agent-profiles): pick every tool from the server's catalog; pin SDK 1.53.0 #17516 does the same for tools, and [Agent Profile] Launch the default profile like every other profile instead of from global settings #17991 tracks makingdefaultlaunch like every other profile.Issue Number
Part of #17234
How to Test
Unit tests cover:
readSystemPromptSeed;defaulthint;End to end, full local stack (
npm run dev: ingress, automation and Vite) on this head, with the released agent-server 1.53.0 and automation 1.18.0. State is in a scratch dir, the agent-server runs with an isolatedHOME, and the LLM is the recording mock. Playwright drove the real UI:explorer(Custom persona) andhelper(Default + your instructions), and create a pairedplain(default).Results are in
.pr/persona-live-check.md. Each row is taken from the mock LLM's recorded requests:explorer(Custom persona)<MEMORY>,<SECURITY>,<SECURITY_RISK_ASSESSMENT>,<BROWSER_TOOLS>,<EXTERNAL_SERVICES>,<PROCESS_MANAGEMENT>,<SKILLS>helper(Default + your instructions)<SOUL>,<ROLE>, …)</SKILLS>plain(OpenHands default)There were no page errors, apart from an unrelated 404 from the workspace picker probing
/projects.Video/Screenshots
All shots were taken on this head against agent-server 1.53.0. The editor shows the Tools section from #17516; the sub-agent and LLM-switching toggles no longer exist.
The three choices:
defaultprofileThe
defaultprofile shows hints instead of the System prompt and Tools controls: local launches send it through the global settings (#17991).System Message of the conversation launched from the Custom persona profile. The persona comes first, and the memory, security policy and risk-assessment guidance are still there:
<MEMORY>and<SECURITY><SECURITY_RISK_ASSESSMENT>kept</SKILLS><SOUL>,<ROLE>Type
Notes
defaulthint once thedefaultlaunch special case is gone ([Agent Profile] Launch the default profile like every other profile instead of from global settings #17991).🤖 Generated with Claude Code
🐳 Docker images for this PR
• GHCR package: https://github.com/OpenHands/OpenHands/pkgs/container/agent-canvas
ghcr.io/openhands/agent-canvasghcr.io/openhands/agent-server:1.53.0-pythonopenhands-automation==1.18.02a6126b8996553767005fef8eb5d171f7490a39cPull (multi-arch manifest)
# Multi-arch manifest — Docker automatically pulls the correct architecture docker pull ghcr.io/openhands/agent-canvas:sha-2a6126bRun
All tags pushed for this build
About Multi-Architecture Support
sha-2a6126b) is a multi-arch manifest supporting both amd64 and arm64sha-2a6126b-amd64) are also available if needed