Skip to main content
Version: 2026.1

Field Hint System

When the agent asks Pimcore "what fields does the Car class have?", it doesn't just get a list of names and types - it gets a format hint for every field telling it exactly what JSON shape to produce. Without this, an agent would have to guess the layout of a classification store or a localized field, and it would get it wrong. Field hints are why propose_data_object_update works reliably across all 40+ Pimcore field types.

What the agent sees

When the agent calls get_class_definition("Car") or get_field_schema(...), each field definition includes an editableDataFormat string and optional metadata:

{
"name": "mileage",
"type": "quantityValue",
"required": false,
"editableDataFormat": "{\"value\": <number>, \"unitId\": \"<unit>\"}",
"example": "{\"value\": 42000, \"unitId\": \"km\"}",
"metadata": {
"validUnits": ["km", "mi", "m"],
"defaultUnit": "km"
}
}

The agent uses this schema when composing updates - the format string becomes the template, the metadata constrains its choices. Combined with the HITL proposal flow (see Features → HITL Proposals), this is how agents reliably edit complex types without guessing.

Covered field types

The bundle ships nine providers that together cover every Pimcore data type. Each provider handles a family of related types:

ProviderTypes
Simple30+ scalar types - input, textarea, wysiwyg, numeric, checkbox, date, datetime, image, link, geopoint, …
Selectselect, multiselect, booleanSelect - extracts static options; notes dynamic providers.
RelationmanyToOneRelation, manyToManyRelation, advancedManyToManyRelation, … - metadata for allowed classes, types, max items, relation columns.
QuantityValuequantityValue, inputQuantityValue - resolves unit labels, lists valid units.
LocalizedFieldsResolves configured locales; recursively formats child fields.
BlockRecursively formats block child fields.
FieldCollectionsExtracts allowed collection types.
ObjectBricksExtracts allowed brick types.
ClassificationStoreResolves store ID and group count; formats the nested {groupId: {default: {keyId: value}}} structure.

A few concrete format strings

  • checkboxtrue | false
  • datetime<unix timestamp> with example 1700000000
  • numeric<number> with metadata {min, max} from the field config
  • image{"id": <assetId>, "type": "asset"}
  • quantityValue{"value": <number>, "unitId": "<unit>"} with validUnits
  • block[{"<field>": <value>, ...}] with maxItems
  • localizedfields{"<field>": {"<locale>": <value>}} with locales

How the system is organised

Field hints use a provider pattern with a central registry:

GetClassDefinitionTool / GetFieldSchemaTool
└─ FieldDefinitionFormatter (facade for tool consumers)
└─ FieldFormatHintRegistry
└─ SimpleFieldHintProvider
└─ BlockHintProvider
└─ ClassificationStoreHintProvider
└─ …

The registry receives every provider via a tagged iterator (pimcore_agent.field_format_hint_provider), builds a fieldType → provider map once at construction, and delegates hint resolution to the right provider.

Recursive types (blocks of blocks, bricks containing bricks) are bounded by a depth guard at 4 levels - beyond that the registry returns a generic <value> fallback to keep tool responses bounded.

Extending

If you ship a custom Pimcore data type, you also need a field-hint provider or the agent will see a generic <value> for it. One class implementing FieldFormatHintProviderInterface, one service tag. See Extending → Custom Field Hint Providers.