Canvas AI: Add the set_page_value AI tool (+ kernel test)
## Summary Add a new AI tool `canvas_ai:set_page_value` (class `SetPageValue`) to `canvas_ai`, ported from the POC (MR !1214). A single key-based tool that sets the page `title` or meta `description`. It lands **inert** — no agent lists it yet. Add a kernel test. ## Why (this sprint) `set_page_value` consolidates three separate page-field tools into one. In the flat-agent architecture the orchestrator sets page fields directly, so the old `create_field_content`, `edit_field_content`, and `add_metadata` tools (and the title/metadata sub-agents that drove them) collapse into a single tool keyed by the field being set. It is trivial deterministic PHP — no services, no layout — so it can land now, tested, in parallel. Additive and inert on landing; the old tools remain until graduation. - Roadmap: https://git.drupalcode.org/project/canvas/-/work_items/3591777 - Reference implementation (POC, no test in the MR): https://git.drupalcode.org/project/canvas/-/merge_requests/1214 ## What to build Port `SetPageValue` from the POC to `canvas_ai` under the final ID `canvas_ai:set_page_value`. It is the simplest tool: no injected services and no validation — just a switch on `key`. - **Arguments.** `key` (required, string; allowed values `title` or `description`) and `value` (required, string). - **Interfaces.** `final class SetPageValue extends FunctionCallBase implements ExecutableFunctionCallInterface, AiAgentContextInterface, BuilderResponseFunctionCallInterface`. `module_dependencies: ['canvas']`, `group: 'modification_tools'`. ### Change vs the POC: emit `canvas_page_data` directly The POC tool emits intermediate keys (`created_content`, `metadata.metatag_description`) that the controller then rewrites into the UI shape via `CanvasAiPageBuilderHelper::processCanvasPageFields()`. Have the tool emit the final shape itself, so it is self-contained and no controller post-processing is needed: - `key = title` → `setStructuredOutput(['canvas_page_data' => ['title[0][value]' => $value]])`, readable output `Page title set successfully.` - `key = description` → `setStructuredOutput(['canvas_page_data' => ['description[0][value]' => $value]])`, readable output `Page description set successfully.` - unknown `key` → no structured output; readable output `Unknown page value key "<key>". Allowed keys are: title, description.` `title[0][value]` / `description[0][value]` is exactly the shape `processCanvasPageFields()` produced under `canvas_page_data`, which the UI already consumes. **Do not remove `processCanvasPageFields()` in this issue.** The live `create_field_content` / `edit_field_content` / `add_metadata` tools still depend on it (`CanvasBuilder.php:276`). Making `set_page_value` self-contained is what lets that method — and those tools — be deleted at graduation; the deletion itself is a graduation step. ### Inert on landing Do **not** add `set_page_value` to any agent's tool list. It ships as an available plugin only; wiring it to the dev agent is a later issue. ## Tests New kernel test `modules/canvas_ai/tests/src/Kernel/Plugin/AiFunctionCall/SetPageValueTest.php` extending `CanvasKernelTestBase`. Cover the three branches: - **Title.** `key=title`, `value=…` → `getStructuredOutput()` equals `['canvas_page_data' => ['title[0][value]' => …]]`; readable output `Page title set successfully.` - **Description.** `key=description` → `['canvas_page_data' => ['description[0][value]' => …]]`; readable output `Page description set successfully.` - **Unknown key.** `key=body` → empty structured output; readable output contains `Unknown page value key "body"`. ## Explicitly NOT doing - Not removing `processCanvasPageFields()` or the old `create_field_content` / `edit_field_content` / `add_metadata` tools (graduation). - Not wiring `set_page_value` to any agent. - Not building `get_component_details` — separate issue. --- _Issue generated with AI assistance._
issue