refactor(api): tranche 4 — migrate Agents admin calls to /wp-abilities/v1 and delete wrapper routes - #3473
Conversation
…s/v1 and delete wrapper routes
…gent, owner default contract test, PHPStan stub ignores
… access grant rows for static analysis
…interim manage-agent-access ability The write side of agent access belongs in the Agents API substrate, not patched over from Data Machine. Automattic/agents-api#537 adds agents/grant-agent-access, revoke-agent-access, and list-agent-users; until that lands the three datamachine/v1 access routes stay and the admin keeps calling them. Every other Agents route is deleted as planned.
|
Reworked per maintainer: the interim |
…aseline smoke-stub shadowing of WP_Agent_Access_Grant
…ugh agents-api abilities Automattic/agents-api#538 shipped agents/grant-agent-access, revoke-agent-access, and list-agent-users over WP_Agent_Access_Store, which Data Machine already implements via AgentAccessStoreAdapter. The admin Access panel now calls those slugs (keyed by agent slug, per the registry) and enriches grants with WP user display fields client-side via /wp/v2/users. executeAbility() accepts a qualified slug so non-datamachine namespaces work without a second helper. Reverts the out-of-scope AgentsCommand/AgentAccess touches from the previous fixup; they dragged 28 pre-existing smoke-stub PHPStan findings (#3474) into changed-file scope.
|
Superseded the retained-routes plan: Automattic/agents-api#538 merged ( Dependency note: DM pins |
…y-group and unused catch binding
…ent return type to grant objects
Part of #3456 (tranche 4: agents family)
Summary
inc/Api/Agents.php(981 lines, 0 ability calls) is deleted. The React admin now executes the registered REST-visible agent abilities through/wp-abilities/v1/abilities/datamachine/<slug>/runvia the existingexecuteAbility()helper, exactly like tranches 1–3.Net: −646 total lines; −629 production PHP (
inc/Api/Agents.php981 → 0;AgentAbilities.php+82;AgentAccessAbilities.php+268 new).Route table
datamachine/v1)datamachine/*)GET /agentslist-agentsshared/queries/agents.js(useAgents→ AgentSwitcher, LogsAgentTabs),Pages/Agent/.../api/agents.js::fetchAgents(useManageAgents→ AgentListTab)handle_listPOST /agentscreate-agentapi/agents.js::createAgent,shared/CreateAgentModal.jsxhandle_createGET /agents/meget-agentwithme: true(new input option; no consumer existed in the admin — kept for external token integrations)handle_meGET /agents/{agent}+GET /agents/{agent_id}compat loopget-agentapi/agents.js::fetchAgent(useAgent→ AgentEditView)handle_get+ compat loopPUT /agents/{agent}+ compat loopupdate-agentapi/agents.js::updateAgent(useUpdateAgent→ AgentEditView)handle_updateDELETE /agents/{agent}+ compat loopdelete-agentapi/agents.js::deleteAgent(useDeleteAgent)handle_deleteGET/POST /agents/{id}/access+ compat loopmanage-agent-access(action: list|grant) — new abilityapi/agents.js::fetchAgentAccess/grantAccess(useAgentAccess,useGrantAccess→ AgentEditView)handle_list_access/handle_grant_accessDELETE /agents/{id}/access/{user_id}+ compat loopmanage-agent-access(action: revoke)api/agents.js::revokeAccess(useRevokeAccess)handle_revoke_accessGET/POST /agents/{id}/tokens+ compat looplist-agent-tokens/create-agent-tokenhandle_list_tokens/handle_create_tokenDELETE /agents/{id}/tokens/{key}+ compat looprevoke-agent-tokenhandle_revoke_token/agent/authorize*and/agent/auth/*(browser authorization flow,inc/Core/Auth/) are not part of this tranche — they stay as transport routes.docs/api/endpoints/agents.mdwas rescoped rather than deleted to keep documenting those live routes (same treatmentfiles.mdgot in tranche 3b).Access routes decision
GET/POST /agents/{id}/accessandDELETE .../access/{user_id}call theAgentAccessstore directly. agents-api (Automattic/agents-api) only exposes the read side as abilities today:agents/can-access-agentandagents/list-accessible-agents(src/Auth/register-agent-access-abilities.php); there is no grant/revoke/list-for-agent ability. Per the tranche plan I added one DM ability,datamachine/manage-agent-access(action: list|grant|revoke, permissionmanage_agents— same as the retired routes,show_in_rest: true,inc/Abilities/AgentAccessAbilities.php, new class modeled onAgentTokenAbilities) rather than forking the access store. Grant/revoke belong upstream in agents-api: Automattic/agents-api#537 tracks that; the DM ability is the interim.Defaults moved (parity ledger)
owner_id => get_current_user_id()(POST /agents): moved into the ability (AgentAbilities::createAgentdefaultsowner_idtoPermissionHelper::acting_user_id()when absent). This is permission-relevant (it decides who owns the created agent), so it lives in the ability where non-admin self-service scoping already lives; CLI--ownerbehavior unchanged.include_role => true(GET /agents): dropped, not ported. No admin JS readsuser_role/is_owner/description(greppedinc/Core/Admin); the wrapper's "attaches timestamps" comment was stale — it never attached them, soAgentListTab'screated_atcolumn was already empty before and after this change.role => viewer,label => '',config => [],delete_files => false: already defaulted in the abilities or the JS callers — no changes needed./agents/mepayload (agent_*,owner_id,site_url,site_name): folded intoget-agentme: trueoutput (agentobject +sitekey, both declared in the output schema). Permission note:get-agentrequiresmanage_agents(agent tokens pass through theagent_cancapability ceiling), slightly tighter than the old route'sis_user_logged_in(); acceptable because no in-repo consumer relied on the looser gate.Verification
php -lon all six changed PHP files: cleannpm ci && npm run build(wp-scripts/webpack): compiled successfully (build output not committed)npx eslinton the three changed JS/JSX files: cleantests/Unit/Abilities/AgentsAbilityRestTest.phpruns the full surface as admin through the core REST runner: CRUD round trip (create with owner default → get → update name+config → list w/ role → delete w/ files → 404 after),meresolution + site metadata, token create/list/revoke (+404 double-revoke), access grant/list/revoke (+owner-revoke 400, unknown-agent 404). Replaces the deletedtests/Unit/Api/Agents*route tests;AllAbilitiesRegisteredTestgainsdatamachine/manage-agent-access.Manual admin smoke checklist (Agents page)
POST /wp-abilities/v1/abilities/datamachine/get-agent/runwith{"input":{"me":true}}+ agent bearer token returns identity + siteAI-generated with Claude Code via Homeboy worktree