Route generation through the AI Client; migrate all tools to the Abilities API - #347
Merged
mmtr merged 13 commits intoJul 14, 2026
Conversation
Add includes/ai-copilot/abilities.php: a `desktop-mode` ability category plus one ability per built-in Copilot tool (search-posts/pages/comments, search-comments-by-post, list-admin-pages, search-wporg-plugins, get-php-error-log) and a comment-spam analyze-comment ability. Each carries a model-facing description, input/output JSON Schema, a permission_callback mirroring the old gates (read for search/nav; manage_options for the error log; moderate_comments for analysis), and meta annotations/show_in_rest/mcp. Execute callbacks delegate to the existing query handlers so there is one implementation. The agentic loop still uses the legacy tool path; wiring it to using_abilities() + the ability resolver (and removing the old registry) follows in later commits. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ol registry - search.php: advertise the built-in tools from their WordPress Abilities (description + input schema) and dispatch each call through wp_get_ability()->execute(), which runs the permission_callback and validates input/output. A denial or bad input surfaces as a clean tool error + fires desktop_mode_ai_search_error; never a fatal. Tool names are derived from the ability names and match the historical names, so progress labels, the system prompt, and the answer schema are unchanged. - Hard-remove desktop_mode_register_ai_tool() and the whole tools-registry.php (+ its test) and the dead desktop_mode_ai_search_tool_definitions(). - client.php: add the desktop_mode_ai_model filter -> using_model_preference() (soft, with fallback); return per-turn token usage + resolved model metadata, accumulated into the desktop_mode_ai_search_completed observability payload. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cover category + ability registration with populated schemas, the permission gates (reader vs manage_options vs moderate_comments), execute() round-trips with output validation, the tool-name mapping the loop relies on, limited MCP exposure, and the desktop_mode_ai_model preference filter. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- abilities.php: make the Copilot's advertised ability list filterable via desktop_mode_ai_abilities — the replacement extension point for the removed desktop_mode_register_ai_tool(). Register an ability + append its name; the loop advertises + dispatches it through execute(). Dedupes. - tests: cover the filter. - docs: hooks-reference (remove register_ai_tool/tool_registered; add desktop_mode_ai_abilities + desktop_mode_ai_model; document usage/model on search_completed + tool_execute stage on search_error; built-ins are abilities), examples/ai-ask.md (ability recipe replaces the tool recipe), migration-ai-connectors.md, javascript-reference.md. Provider-neutral wording. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR migrates the Desktop Mode AI Copilot’s server-dispatched tools from a plugin-owned registry to WordPress 7.0’s Abilities API, routing tool execution through wp_get_ability()->execute() so that permission checks and JSON-Schema input/output validation are enforced by Core.
Changes:
- Introduces
desktop-mode/*Abilities (category + one ability per built-in tool, plusanalyze-comment) and wires them into the/ai/searchagent loop. - Reworks generation to run through the Core AI Client, adding soft model preference (
desktop_mode_ai_model) and propagating token usage + resolved model metadata. - Removes the old PHP tool registry (
desktop_mode_register_ai_tool()), replaces extensibility withdesktop_mode_ai_abilities, and updates docs/examples accordingly.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/phpunit/tests/aiToolsRegistry.php | Removes tests for the deleted PHP tool registry API. |
| tests/phpunit/tests/aiAbilities.php | Adds PHPUnit coverage for ability registration, permission gates, execute(), tool-name mapping, and model-preference normalization. |
| includes/ai-copilot/tools-registry.php | Deletes the old desktop_mode_register_ai_tool() registry implementation. |
| includes/ai-copilot/search.php | Switches tool assembly/dispatch to Abilities (execute()), adds usage/model accrual, and updates observability payloads. |
| includes/ai-copilot/client.php | Adds AI Client model preference support plus helpers to extract token usage and model metadata from results. |
| includes/ai-copilot/bootstrap.php | Loads the new abilities module instead of the removed tools registry. |
| includes/ai-copilot/abilities.php | Registers the desktop-mode ability category and all built-in Copilot abilities with schemas + permission callbacks. |
| docs/migration-ai-connectors.md | Documents the Tools → Abilities migration and the new extensibility surface. |
| docs/javascript-reference.md | Updates server-side tool guidance to Abilities + desktop_mode_ai_abilities. |
| docs/hooks-reference.md | Removes registry docs, adds desktop_mode_ai_model + desktop_mode_ai_abilities, and updates hook semantics. |
| docs/examples/ai-ask.md | Updates the example to register server tools via Abilities and to reflect provider-neutral wording. |
Comments suppressed due to low confidence (1)
includes/ai-copilot/search.php:1124
- This docblock still says the hook fires for “built-in and registered” tools, but this PR removes the PHP tool registry. The hook now effectively applies to ability-dispatched tools (and will also run for ability error envelopes) before the FunctionResponse is sent back to the model, so the comment should be updated to avoid pointing developers at a removed surface.
/**
* Transform a tool result before it goes back to the
* model. Fires for every tool, built-in and registered.
*
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- search.php: guard the $ability_by_tool lookup with isset() so a name in $valid_tools without a mapping returns a clean tool error instead of a notice / wp_get_ability(null). Fix stale tool_result docblock. - abilities.php: normalize the derived tool name to [a-z0-9_] (lowercase, collapse other chars) so third-party ability names with extra slashes or mixed case can't produce a function name providers reject. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
0.9.4 is the current unreleased dev version (latest tag is v0.9.3), so this work ships in 0.9.4. Fix every @SInCE / doc "0.9.5" → "0.9.4", clarify that the `desktop_mode_ai_model` filter name is reused (old provider-selection filter gone, now a soft model preference), and add a 0.9.4 changelog line. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Pre-1.0 APIs are unstable; deleted APIs don't need documenting outside the changelog. Drop the desktop_mode_register_ai_tool() removal framing from hooks-reference and the ai-ask example — describe the current ability + desktop_mode_ai_abilities/desktop_mode_ai_model surface positively instead. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Drop the desktop_mode_ai_model filter: provider and model are delegated entirely to the Core AI Client (there was no prior filter to preserve). - Drop the desktop_mode_ai_abilities opt-in filter. The assistant now offers every registered read-only ability (its own, Core's, or another plugin's) — register a read-only ability and it's picked up automatically; permission is still enforced by the ability's permission_callback. Only read-only abilities are offered, since a search turn can be steered by attacker-controlled content. - Link "WordPress Abilities" to the Abilities API docs; drop Linear issue refs from code/docs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…acks The system prompt hard-scoped the assistant to five tracks and only listed the built-in tools, so it declined questions the auto-included read-only abilities (Core's site/user/environment info, third-party tools) could answer. Broaden the prompt: the tool list is authoritative; call any tool that fits and summarise the result as a chat answer. Also fix ability dispatch for tools with no input schema (e.g. Core's get-*-info): execute() rejects a non-null input when no schema is defined, so pass null in that case instead of the (empty) args array. Verified: "what PHP version…" -> get_environment_info, "what WP version…" -> get_site_info, and content search still resolves via search_posts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The assistant now answers with any read-only ability (site/environment info, plugin tools), not just content search + wp-admin navigation, so widen the footer hint accordingly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Match the assistant's wider scope (site questions via any read-only ability), not just content search + wp-admin navigation. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
AllTerrainDeveloper
approved these changes
Jul 14, 2026
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
mmtr
deleted the
deskmod-9-route-generation-through-the-wp-ai-client-migrate-all-tools
branch
July 14, 2026 13:26
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.


What & why
The Copilot's built-in tools are now WordPress Abilities, and the agent loop dispatches them through Core (
wp_get_ability()->execute()) instead of a hand-rolled registry. Permission checks and input/output validation now live in the ability, not our code. Because the assistant offers the model every registered read-only ability, it's now a general agent — it answers site questions (version, environment, current user) via Core's own abilities, and picks up any read-only ability a plugin registers, with no opt-in.Changes
includes/ai-copilot/abilities.php— adesktop-modeability category plus one ability per built-in tool (search-posts/pages/comments,search-comments-by-post,list-admin-pages,search-wporg-plugins,get-php-error-log) andanalyze-comment. Each has input/output JSON Schema, apermission_callback, andmeta(annotations,show_in_rest,mcpon the safe read-only ones). They appear inGET /wp-abilities/v1/abilities.search.php) — the assistant offers the model every registered read-only ability (its own, Core's, or another plugin's) and runs each call viaexecute(). A permission denial or bad input becomes a clean tool error (never a fatal) and firesdesktop_mode_ai_search_error. The system prompt tells the model its tool list is authoritative, so it uses whatever fits.desktop_mode_register_ai_tool()+ the whole tool registry.client.php) — provider + model fully delegated to the Core AI Client;desktop_mode_ai_search_completednow carriesusage(tokens) +model.wp_ai_client_prevent_promptis honored via Core.Testing
Requires WordPress 7.0 with an AI provider in Settings → Connectors and the AI assistant enabled in OS Settings → Features.
get_environment_info; "What's my WordPress version?" →get_site_info. No plugin code needed — the assistant offers every read-only ability. (Confirm the call in the debug log:desktop_mode_ai_tool_calledwithtool_name=get_environment_info.)GET /wp-abilities/v1/abilitieslists thedesktop-mode/*abilities with schemas.Automated: build, lint, typecheck, JS + PHP suites green.
🤖 Generated with Claude Code