Repository navigation
V2 Admin Settings: manage global agents and actions, fix category scroll - #1672
Merged
Paul Lizer (paullizer) merged 9 commits intoOct 7, 2026
Merged
Paul Lizer (paullizer) merged 9 commits into
Paul Lizer (paullizer) merged 9 commits into
Conversation
- Choosing an Admin Settings category, in the rail or the phone select, now opens it at its top and restarts the On this page index. - Global Agents and Global Actions sections list, create, edit, enable, disable and delete the organisation's agents and actions, and choose the default agent, using the same V2 editors workspaces use. Thirteen new admin-only routes under /api/v2/admin serve them through the shared editor engine, now with a global scope: masked secrets, global Key Vault names, conditional writes and case-insensitive name checks. - Templates start and publish global agents; Agent Template Approvals links to the approvals queue in a new tab. - Remove the Global agent delegation card. Call agent is an ordinary global action whose targets are global agents; the target picker now follows the editor's scope instead of always reading personal targets. - Admin Settings asks before opening a global editor would drop unsaved settings. - The classic global agent delete reads stored Key Vault references, so it removes credentials the V2 editor saved instead of failing. - Version 0.261.260. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
… and actions editors to 0.261.268 The base already uses 0.261.260 through 0.261.267, so this change moves to 0.261.268: config.py, the release notes section, and every version this branch added to its docs and test headers. The generated docs inventory is rebuilt from the merged source, and the category rail keeps both the base's collapsed-rail tooltip and this branch's scroll reset. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The full-page agent and action editors, shared by My Workspace, group workspaces and Admin Settings, now use the Admin Settings card system. - EditorLayout primitives: setting rows with the label and help beside the control on a wide row, fieldsets, switch rows with a lead switch and indented dependents, collapsible groups, titled panels and fieldset panels. - WorkspaceEditorFrame: section rail with icons that marks the section in view, section cards with an icon, title and description, a save status chip, and a pinned jump (initialSection) that keeps the chosen section in place while lists above it load; ?templates=1 now uses it. - Every agent and action section, including the MCP, OpenAPI and Call agent connectors, converted to rows, switches, groups and panels with the same accessible names. - Global Agents and Global Actions lists use the AI Connections row pattern with Enabled/Disabled and Default agent badges and icon actions. - Editor rows measure their own width instead of being CSS size containers: in Chromium 145 a size container could keep a stale, collapsed layout when React added a section after it, hiding the Action type row once a new action's type was chosen. A UI test now guards this. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
A section chosen from the editor rail stayed pinned through Save, because the pin was only released by input inside the scrolling pane and Save sits in the header. When the save failed, or native validation revealed a field in a closed group, the content resized and the pin scrolled the focused error or field back out of view. The pin is now released by pointer or key input anywhere in the editor form, on submit, on an invalid field, before the error summary is focused, and when focus moves to anything other than the pinned section. A rail choice still pins, because its click follows the pointerdown or keydown. Two UI tests cover a failed save and an invalid field after a rail jump. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…ditors to 0.261.269 Brings in the durable batched search metadata sync port (#1674), which took 0.261.268, the version this pull request used. - config.py: VERSION 0.261.269 (both sides had bumped 0.261.267 to 0.261.268). - release_notes.md: this pull request's section moves to v0.261.269 above the base's v0.261.268 section, which is kept unchanged. - Renumbered this pull request's 30 other 0.261.268 references (feature, fix, admin and guide docs, functional and UI test headers, version assertions). The fix doc's version transition now reads 0.261.268 -> 0.261.269. The base's own 0.261.268 references are untouched. - docs/_data/app_surface.yml regenerated; unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…ditors to 0.261.270 Brings in the V2 Operations settings parity (#1675), which took 0.261.269, the version this pull request had just moved to. - AdminSettingsPage.tsx: kept both sides in all three conflicts. Imports keep the global agents, global actions and approvals components and the base's Operations helpers; the Global agent delegation imports stay removed, because nothing on the page uses that card any more. Helpers keep selectCategory (category scroll reset) beside the base's readSwitch and renderRelatedSection. Overlays keep the unsaved-settings prompt for the global editors and the base's section guide dialog. - admin_settings_fields.py auto-merged; the global manager components are intact and no delegation card was reintroduced. - config.py: VERSION 0.261.270 (both sides had moved to 0.261.269). - release_notes.md: this pull request's section moves to v0.261.270 above the base's v0.261.269 Operations section, which is kept unchanged. - Renumbered this pull request's 30 other 0.261.269 references; the fix doc's version transition now reads 0.261.269 -> 0.261.270. The base's own 0.261.269 references are untouched. - docs/_data/app_surface.yml regenerated; unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…ditors to 0.261.271 Brings in the shared Orchestrate fixes (#1676), which took 0.261.270, the version this pull request had moved to. - config.py: VERSION 0.261.271 (both sides had moved to 0.261.270). - release_notes.md: this pull request's section moves to v0.261.271 above the base's v0.261.270 Orchestrate section, which is kept unchanged. - Renumbered this pull request's 30 other 0.261.270 references; the fix doc's version transition now reads 0.261.270 -> 0.261.271. The base's own 0.261.270 references are untouched. - No other files changed on both sides; docs/_data/app_surface.yml regenerated and unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Address the CodeQL review findings on the global agents and actions editor. - route_backend_agents.py: _prepare_global_agent_payload no longer returns a caught AgentPayloadError or AssignedKnowledgeError's text in its 400 response (py/stack-trace-exposure, alerts 4054 and 4055). It answers with a fixed message and logs the reason as a warning. The editor engine already replaced the body with "Invalid agent configuration.", so nothing changes on screen; the reason, which was discarded, is now kept in the server log. - test_v2_admin_global_editor_backend.py: a test runs the real function from its source and checks both refusals answer with a fixed message while the log keeps the reason, and that no response in the function names a caught exception. It fails against the previous code. Also drops the unused MagicMock import (alert 4057) and passes deepcopy directly instead of wrapping it in a lambda (alert 4058). - The feature doc notes where a refused global agent's reason is logged. The connect_options import flagged in the UI test (alert 4056) is kept: it overrides pytest-playwright's fixture by name, as in the other UI tests. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Paul Lizer (paullizer)
merged commit Oct 7, 2026
78d7cef
into
paullizer-react-v2-ui
11 checks passed
15 of 24 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.
Summary
V2 Admin Settings had no way to see or author the organisation's global agents and actions. Agents & Actions only offered a "Global agent delegation" card for Call agent actions, so admins still had to use the classic page. Separately, switching settings categories kept the previous category's scroll offset, so leaving Knowledge near its end opened Security near its end.
GLOBAL_AGENT_WORKBENCH/GLOBAL_ACTION_WORKBENCHadapters and 13 admin-only routes under/api/v2/admin.Backend approach.
functions_workspace_authoring.pygains aglobal_scopepath through the existing editor engine instead of a parallel implementation. Credentials stage under fresh names in the global Key Vault namespace ({id}--agent|action|action-addset--global--...), every write is conditional on the opened revision (_etag), names are unique case-insensitively, the stored shape matches what the classic global saves write, the default agent cannot be deleted and follows renames, and Call agent targets and bindings are validated for the global scope. Enable/disable and make-default reuse the classic routes.Worth a careful look
paullizer-react-v2-uihas moved 26 commits ahead and is at0.261.266. Merging conflicts inconfig.py,docs/_data/app_surface.yml, anddocs/explanation/release_notes.md, and0.261.260(used here) is already taken on the target, so the version, the release-notes section, and doc/test version headers need renumbering when resolving.delete_global_agentnow reads the stored document instead of the masked one, so the classic delete removes credentials the V2 editor stored. It used to rebuild the classic secret name from theStored_In_KeyVaultplaceholder and fail. Known limitation, shared with the personal and group editors and documented: after V2 replaces a classic-named key, a classic edit that enters a new value for that key fails until the soft-deleted name is purged (entering it in V2 works).AdminSettingsPagenow registers auseBlockerscoped to navigations into the global editors, so opening an editor asks before dropping unsaved settings. Other navigation is unchanged.ui_tests/test_agent_delegation_v2.pyand its MemoryRouter harness only covered the removed card;ui_tests/test_v2_admin_global_agents_actions.pyreplaces them.Screenshots (built SPA, fixture data):
Linked issue
N/A (no linked issue)
Release Notes & Latest Features
Is this visible to end users?
Is this admin-facing (Admin Settings, governance, deployment, config)?
Should this become a Latest Feature card?
Screenshot needed for the card?
Version bump
application/single_app/config.pyVERSIONthird segment bumped, or not needed because this is docs-only (0.261.259 -> 0.261.260; needs renumbering past the target's 0.261.266 when the conflicts are resolved)deployers/version.txtbumped, or not needed becausedeployers/was not changedTesting / validation
npm --prefix application/v2_ui run typecheck- passednpm --prefix application/v2_ui run build- passedpython -m pytest ui_tests/test_v2_admin_global_agents_actions.py- 13 passedpython -m pytest ui_tests/test_v2_admin_global_agents_actions.py ui_tests/test_v2_workspace_authoring.py ui_tests/test_v2_group_agents.py ui_tests/test_v2_group_actions.py ui_tests/test_v2_group_workspace_shell.py ui_tests/test_v2_workspace_draft_navigation.py ui_tests/test_v2_admin_settings_wide_layout.py ui_tests/test_v2_admin_agents_visual_hierarchy.py ui_tests/test_v2_admin_version_status.py ui_tests/test_admin_orchestration_actions.py ui_tests/test_v2_admin_model_catalog_workbench.py(withPYTHONPATH=ui_tests/fixtures) - 254 passed, 1 failed:test_v2_workspace_authoring.py::test_create_reload_edit_each_agent_type_with_applicable_controls[chromium-aifoundry], which then passed in 8 isolated reruns (flake under load)python -m pytest ui_tests/test_v2_cross_scope_journeys.py ui_tests/test_v2_group_journeys.py- 51 passedselectCategoryscroll reset removed; the unsaved-settings test fails with the blocker disabled; the classic global delete test fails against the previousfunctions_global_agents.pypython -m pytest functional_tests/test_v2_admin_global_editor_backend.py functional_tests/test_workspace_authoring_credential_compatibility.py functional_tests/test_v2_admin_agents_parity.py functional_tests/test_v2_admin_actions_parity.py functional_tests/test_v2_admin_field_renderer_coverage.py functional_tests/test_v2_admin_capability_placement.py functional_tests/test_admin_global_item_enabled_state.py- 56 passed, 1 failed (pre-existing, identical on the base commit:test_real_sdk_retry_preserves_potentially_committed_credentials)python -m pytest functional_tests/test_admin_settings_nav_map.py functional_tests/test_v2_admin_settings_schema.py- 13 passed, 2 failed (both pre-existing, identical on the base commit: thecontent-screeningtab has no pane, andm365_trusted_download_hostsdefault type)node functional_tests/test_v2_admin_global_editor_logic.mjs- 12 passednode functional_tests/test_v2_workspace_action_connectors_logic.mjs- 36 passednode functional_tests/test_v2_admin_agents_logic.mjs- 40/40 passednode functional_tests/test_v2_workspace_authoring_logic.mjs- 27 passedpython functional_tests/route_tests/test_route_blueprint_policy_inventory.py- 12/12 passed;test_route_unauthenticated_policy_contract.py- 7/7 passed;test_route_policy_test_coverage.py- 2/2 passedpython scripts/build_docs_inventory.py(regenerated), thenpython functional_tests/test_docs_app_surface_coverage.py- 7/7 passed andpython functional_tests/test_docs_site_quality.py- 6/6 passedpython functional_tests/test_docs_release_notes_integrity.py- failed, pre-existing: the generated release-note pages were already 192 releases behind before this change; not regenerated herepython scripts/check_xss_sinks.py --base-sha 1b8d4c47b --head-sha HEAD <45 changed files>- passedgit diff --check- cleanDocumentation
V2_ADMIN_GLOBAL_AGENTS_ACTIONS.mdnew;V2_ADMIN_AGENTS_ACTIONS.md,AGENT_DELEGATION_ACTION.md,docs/admin/agents-actions.md,docs/guides/call-another-agent.mdupdated)V2_ADMIN_CATEGORY_SCROLL_RESET_FIX.md)Security checklist
@swagger_route(security=get_auth_security())(all 13, plus@login_requiredand@admin_requiredon an admin-required blueprint)sanitize_settings_for_user()(new routes are admin-only; agent options still pass through it and mask connection secrets)