Agent Resource Data Runtime
How Core derives generic Agent read and write tools from App-owned Resource, permission, schema, route, and controller contracts.
Agent Resource Data Runtime
Make the normal Resource contract complete: publish its model and permissions, declare fields, and keep matching read/write controller routes. Start with Create a Resource. An authorized Agent should then discover only supported operations through data.catalog and data.describe; no generic Agent adapter belongs in your App.
Prepare the Resource
Agent Resource Data is the Core runtime that turns ordinary App-owned Resources
into governed Agent data operations. It publishes the generic data.catalog,
data.describe, data.query, data.detail, data.preview, data.verify, data.mutate,
data.mutate_batch, and data.action tool flow.
Apps do not register those tools and do not import Agent classes from Core.
Instead, Core derives the available surface from declarations the App already
owns: its Resource catalog entry, Eloquent model, permissions, Resource
descriptor, list schema, API routes, controller, and request validation.
Agent tools
AgentDataResourceRegistry starts with the Core-governed Resource catalog. A
Resource participates only when its contribution exposes both a
PermissionContribution and an Eloquent model. The registry reads the
Resource's own permission definitions; missing either contract excludes the
Resource rather than inventing defaults.
The tool flow separates discovery, preflight, and execution:
| Stage | Result |
|---|---|
data.catalog | Lists only Resources visible to the actor and suitable for generic data access |
data.describe | Returns the Resource's fields, capabilities, filters, sorts, search behavior, reference metadata, and allowed lifecycle actions |
data.query | Executes a bounded query after current tenant and Resource authorization |
data.detail | Reads one record through its authorized App detail API, including its domain DTO |
data.preview | Executes a declared read-only domain evaluator using its exact HTTP method and schema |
data.verify | Performs side-effect-free write preflight and returns a verdict for each proposed record |
data.mutate | Executes one approved create, update, or delete through the Resource API |
data.mutate_batch | Executes an approved plan sequentially and records each outcome |
data.action | Runs a declared lifecycle verb such as submit or cancel through the Resource's own action endpoint after confirmation |
AgentDataFieldSchema resolves field descriptions in a fixed priority:
ResourceDescriptor first, Resource transfer columns second, and database
schema last. The response reports that field_source so a caller can distinguish
an intentional domain declaration from fallback inference. Filter, sort, and
search capability come from the list schema rather than being guessed from a
column. Reference fields retain Resource identity and display-label metadata.
The write flow also reuses the Resource API. AgentDataWriteRoutes requires the
model and controller basenames to match inside the same App namespace, then
pairs each write with that controller's exact GET collection or member URI:
POST for create, PUT or PATCH for update, and DELETE for delete. This is
the route shape emitted by nexia-apps:make-package-resource; Laravel scoped
bindings such as {legalEntity:public_id} are filled from trusted delegation
context. Therefore Form Request validation, policies, transactions, domain
services, and events remain in force. A missing controller, missing read/write
pair, or more than one candidate leaves the action unsupported; the generic
runtime never writes an Eloquent model directly.
Nested child Resources use AgentScopedRouteResolver. A nested child Resource is reachable only under its resolved parent route and
cannot be addressed as an unscoped top-level record. This protects both route
identity and parent authorization.
For an approved batch, Core stores an actor-scoped registration run. One user
approval authorizes the submitted plan, then outcomes are recorded sequentially
as the run moves through pending, running, and completed, partial, or
failed. The batch is ordered and best effort, not one atomic transaction across
all records. A later failure does not claim that earlier successful controller
requests were rolled back.
Authorization and validation
agent.data.read only opens the generic tool surface; each Resource still requires its current permission. Writes also require agent.data.write, the Resource action permission, and approval for the write-tier tool.
An App must not import App\Agent\* or register Core's generic routes. Publish
normal SDK contributions and normal App routes. Core discovers them through the
installed App map and preserves the request's tenant boundary and authenticated
user through the App route.
Do not treat data.verify as a reservation or authorization token. It is a
side-effect-free preflight against current inputs; the approved write is
authorized and validated again when executed. Likewise, a catalog result is not
a durable grant. Permission and App operational state are evaluated at use time.
Generic data does not bypass Resource-specific invariants. If a domain write cannot be expressed safely through the Resource's public controller route, leave that action unsupported or publish a purpose-built route-backed tool through the SDK Contribution contracts. Do not weaken controller validation so the generic runtime can force an otherwise invalid record through.
Keep field metadata intentional. Database fallback makes a Resource inspectable,
but a ResourceDescriptor is the correct owner for user-facing descriptions,
enum values, localized label keys, reference semantics, and field intent. Request validation remains the authority for accepted writes. Do not
expose secrets, internal bookkeeping columns, or values that the ordinary API
would not return.
Resource operations and complete discovery
Declare reusable operations in ResourceDescriptor::$actions, using ResourceActionDescriptor with an exact permission, HTTP method, route path, and inputSchema. The action key does not imply its permission: a reject action can require approve. Declare ResourceActionEffect::Read only for side-effect-free evaluators; mutations use Mutate. Optional description explains state requirements and business meaning. data.describe exposes these contracts without adding a model tool for every Resource action.
Declare ResourceDescriptor::$mutation with ResourceMutationDescriptor(createInputSchema: ..., updateInputSchema: ...) to preserve the complete accepted payload, including nested lines. A field schema alone is not a write contract. The existing controller remains authoritative for validation, authorization, and state changes.
Follow data.catalog.next_cursor until it is null to traverse all authorized Resources. app.navigation.read discovers installed, accessible Apps and their descriptions; include_guides returns guide summaries and guide retrieves one guide's steps. Resources and navigation have different eligibility rules. Neither response claims access to unavailable Apps or unauthorized Resources.
App-specific tools remain available through AgentToolContribution for a distinct business capability that generic Resource operations cannot represent. Do not register duplicate list/show/create/update tools. Multi-step guidance can use Feature Guides; executable business steps can use Process Work Action contributions. A guide explains a workflow and does not grant permission or implement the workflow itself.
Check the result
For your generated Resource, compare data.describe with its declared fields and supported controller routes. A query must enforce the same read permission as the browser API. An approved mutation must reach the same validation and domain action. If an App is unavailable or a permission is revoked, the next operation must refuse access.
Related
- Create a Resource — publish the model, permissions, descriptor, routes, and controller the runtime composes
- Resource contracts — exact Resource and descriptor surfaces
- HTTP middleware — the tenant, authorization, and scope guards that remain active on App routes
- Permissions and roles — distinguish the coarse Agent capability from live Resource action permission
- Enable the Agent Gateway — configure the optional gateway that invokes Agent tools