| 1 | # Agent Editor Plugin DOX |
| 2 | |
| 3 | ## Purpose |
| 4 | |
| 5 | - Own the deterministic Easy and Advanced Agent Editor API and WebUI workflow. |
| 6 | |
| 7 | ## Ownership |
| 8 | |
| 9 | - `helpers/editor.py` composes existing profile, prompt, model, tool, and skill |
| 10 | owners into editor state and sparse change plans. |
| 11 | - `api/` owns authenticated/CSRF-protected state, save, and avatar routes. |
| 12 | - `webui/` owns the Alpine store, modal surface, styling, and client-side draft. |
| 13 | - `extensions/webui/` owns lifecycle registration on the shared modal stack and |
| 14 | the global entry points used by existing WebUI surfaces. |
| 15 | |
| 16 | ## Local Contracts |
| 17 | |
| 18 | - The editor performs zero model calls. |
| 19 | - Profile list requests stay lightweight: summary rows inspect only sparse |
| 20 | editor-owned keys and files and never construct full save or removal plans. |
| 21 | - Writes are limited to the selected profile layer — global |
| 22 | `usr/agents/<profile-id>` or project |
| 23 | `usr/projects/<project>/.a0proj/agents/<profile-id>` — and only to paths or |
| 24 | config keys listed in the validated change plan. The availability toggle |
| 25 | reuses the existing project `.a0proj/agents.json` load/save owner; the WebUI |
| 26 | permits one availability save at a time. Global availability remains a sparse |
| 27 | `enabled` profile override. |
| 28 | - Every profile, including `Default`, can be made unavailable. The backend |
| 29 | rejects only the change that would leave the selected scope with no available |
| 30 | profile, then reconciles loaded chats through the shared project owner. |
| 31 | - Destructive cleanup and custom-profile deletion require an explicit confirmed |
| 32 | apply request. Profile creation and availability invariants are rechecked at |
| 33 | the existing editor mutation boundary; project availability refuses malformed |
| 34 | `agents.json` and changes only the requested profile entry through the existing |
| 35 | project storage owner. |
| 36 | - Never call `helpers.subagents.save_agent_data`. |
| 37 | - Fast creation from slash commands and connector clients calls |
| 38 | `helpers/editor.py:save_easy_profile`, so profile IDs, validation, sparse |
| 39 | writes, and the mutation boundary stay identical to Easy mode. |
| 40 | - Authored profile definitions remain YAML; editor-written plugin configs remain |
| 41 | JSON. |
| 42 | - Profile config paths use `helpers.plugins.determine_plugin_asset_path` for the |
| 43 | selected Global or project scope and remain rooted in that exact validated |
| 44 | profile boundary. |
| 45 | - Project profiles inherit the existing global, plugin, and bundled layers. |
| 46 | Removing or deleting in project scope never mutates those inherited layers; |
| 47 | only agents created in the selected scope are deletable. |
| 48 | - Bundled `agents/` files are read-only. |
| 49 | - Advanced prompt text is edited with a full-height bundled ACE editor in |
| 50 | Markdown mode. The selected file's customization path sits below its name; |
| 51 | per-file close/check actions discard or accept the current edit checkpoint, |
| 52 | while the editor's global save remains the only persistence boundary. |
| 53 | - New profiles require a display name and non-empty agent instructions in both |
| 54 | Easy and Advanced; existing Advanced prompt edits retain per-file semantics. |
| 55 | - Easy and Advanced share the same segmented capability controls: Default |
| 56 | removes the item from `allowed` and `blocked`, On stores it in `allowed`, and |
| 57 | Off stores it in `blocked`. Tools, canonical MCP entries, and Skills expose |
| 58 | independent default switches; explicit choices remain pinned when a default |
| 59 | changes, and opening then undoing an inherited policy produces no write. Easy |
| 60 | places each initially closed native accordion directly below its default |
| 61 | switch. Advanced gives Tools, MCPs, and Skills separate sections while keeping |
| 62 | unavailable retained IDs reviewable. Framework-required tools remain absent. |
| 63 | - Model selection in both modes reuses `_model_config`'s compact preset dropdown |
| 64 | and preset editor; Agent Editor persists only the scoped preset reference. |
| 65 | - The exact `default` profile is an internal baseline and is omitted only from |
| 66 | selectable and editable UI rows. Runtime discovery remains unchanged, and an |
| 67 | existing chat using it may still report it as current status. |
| 68 | - Manage agents reuses the plugin-settings project vocabulary: Global or one |
| 69 | existing project. The active chat profile appears once above the list; each |
| 70 | row exposes scoped availability, duplication, restore for inherited profiles, |
| 71 | icon-only Edit, and Delete for profiles owned by that scope. Duplicate |
| 72 | materializes the effective source profile into the selected writable layer |
| 73 | with a collision-free ID and title. Restore visibility follows the sparse |
| 74 | removal plan, ignores unrelated profile files, and reports successful reset. |
| 75 | Availability changes quietly refresh the adjacent profile switcher catalog |
| 76 | without a success toast. |
| 77 | - The same project selector is available inside Create and Edit. Create keeps |
| 78 | the in-progress draft when its destination changes; Edit reloads the selected |
| 79 | profile from the new scope after guarding unsaved changes. |
| 80 | - Save & test activates the saved profile in a fresh chat using that same scope. |
| 81 | - The WebUI uses the shared modal stack, labeled prompt scroll regions, and |
| 82 | 24px-or-larger policy and text-action targets. |
| 83 | |
| 84 | ## Verification |
| 85 | |
| 86 | - Run Agent Editor, profile merge, tool policy, skill policy, API security, and |
| 87 | WebUI tests, then verify the explicitly named bind-mounted runtime. |
| 88 | |
| 89 | ## Child DOX Index |
| 90 | |
| 91 | No child DOX files. |