Toolsets¶
A toolset (site_agent_toolset config entity, at
/admin/config/ai/site-agent/toolsets) holds:
- entries, each with a primary tool, optional fallbacks and an approval mode. The runner offers the first tool of an entry that is installed and whose refinements still apply;
- refinements per tool:
allowedlimits an input to a list of values, andpresetfixes an input's value and hides the input from the model. Both are applied to the schema the model sees and checked before a call runs; a call outside an allowlist is refused. A tool whose refinements no longer apply is dropped, never offered unrefined; - a system prompt fragment and a card style,
editororsite_builder.

Approval modes are pre_approved, once (per thread) and always, the
default. Destructive and unclassified tools, and content writes that don't
land as drafts, prompt on every call whatever the entry says. So does a call
of a drafting tool that publishes at once, or writes an entity type without
revisions or without a published state, such as a redirect or an account.
Two entries naming the same tool offer it once: the first wins, and the later entry offers nothing.
Editor¶
The module ships an Editor toolset. Each entry lists Content Deployment's tool first and Tool Belt's as the fallback:
| Entry | Tools | Refinements | Approval |
|---|---|---|---|
| Field definitions | content_spec_model, tool_belt:entity_field_value_definitions |
Tool Belt's entity_type_id: node, media |
pre-approved |
| Listing | content_spec_query, tool_belt:entity_list |
Tool Belt's entity_type_id: node, media |
pre-approved |
| Find by property | content_spec_query, tool_belt:entity_load_by_property |
Tool Belt's entity_type_id: node, media |
pre-approved |
| Load | content_spec_read, tool_belt:entity_load_by_id |
Tool Belt's entity_type_id: node, media |
pre-approved |
| Field values | content_spec_read, tool_belt:entity_field_values |
pre-approved | |
| Moderation state | content_spec_read, tool_belt:moderation_state_get |
Tool Belt's entity_type_id: node |
pre-approved |
| Drafts awaiting review | content_spec_pending, tool_belt:moderation_content_list |
Tool Belt's entity_type_id: node |
pre-approved |
| Text formats | tool_belt:text_format_explain |
pre-approved | |
| Create, including media | content_spec_create, tool_belt:entity_create |
publish: preset FALSE; Tool Belt's entity_type_id: node, media |
pre-approved |
| Update | content_spec_apply, tool_belt:entity_update |
publish: preset FALSE; Tool Belt's entity_type_id: node, media |
pre-approved |
| Media ingest | content_spec_media_ingest |
always | |
| Start a draft | tool_belt:moderation_state_set |
entity_type_id: node; state: draft |
always |


With the Site Agent AI Context submodule, the toolset also gets a page context
entry, site_agent_ai_context:page_context, pre-approved; see
Site context.
It holds no configuration, workspace, email or delete tool. The model can't
publish: publishing is the user's, from the card, and a call that passes
publish is refused.
With Content Deployment, a page edit is a spec applied as a pending revision, and a new entity is created unpublished, so both run without a prompt; an account or redirect spec, which can't wait as a draft, prompts. Media ingest publishes the new media item, so it prompts. The content spec tools check access themselves, with the call's arguments: create or update access, edit access to each field changed, and the use of each text format. A spec names its entity type itself, so create and apply aren't limited to nodes and media.
With Tool Belt alone, every write prompts, since Tool Belt's writes save default revisions; on a page under a workflow, a write to a draft started with the moderation tool stays a draft until it is published.
Site builder¶
The module also ships a Site builder toolset, installed where the Editor toolset is. It holds every Editor entry, and:
- reads: Tool Belt's entity type, bundle, field and image style definitions, and this project's display, role permission, block, recent log, menu, view and URL alias pattern reads, pre-approved;
- writes, each always prompting: Tool Belt's bundle, field storage, field and image style tools, including their delete tools, which are destructive; and this project's display placement, role permission, block placement, menu, menu link, view display edit, view clone and URL alias pattern tools.

With the Site Agent AI Context submodule, it gets the page context entry too.
Where configuration is locked, the configuration writes leave the tool list, so the toolset offers what Editor offers, plus its reads and menu links, which are content; the chat offers it there only to accounts that may use no other toolset. The system prompt then says the site's structure can't change there, and the chat shows no "Configuration changes" button. Its prompt fragment carries the field rules: read the schema before adding a field, reuse a field storage of the same type and cardinality, and check that a new field has a widget and a formatter.
Permissions¶
| Permission | Grants |
|---|---|
use TOOLSET toolset |
Chatting with that toolset; one is generated per toolset. |
administer site_agent toolsets |
Editing toolsets, and the refused-calls report. |
view any site_agent thread |
Reading other accounts' threads and tool calls, and the refused-calls report. |
Tool classifications¶
Every tool is classified as read, content_write or config_write,
optionally destructive and, for content writes, as drafting or not, by
MODULE.site_agent_tools.yml files and
hook_site_agent_tools_alter(); see site_agent.api.php. A tool with no
classification counts as a destructive config write. This module ships the
classifications of Tool Belt's tools, with interim access hints used to keep
tools an account can't run out of the model's tool list, and of Content
Deployment's tools, whose payload is a content spec (changes.spec).
Drush¶
drush site-agent:tools TOOLSET --uid=UID lists the tools a toolset offers
the model for an account: function name, tool, classification and the approval
mode that applies. It also says whether configuration is writable on the site.