# `A2UICore.Message.Operation`
[🔗](https://github.com/a2ui-elixir/a2ui/blob/v0.1.1/umbrella/apps/a2ui_core/lib/a2ui_core/message/operation.ex#L126)

Version-neutral operations: what `A2UICore.Message.decode/2` returns
and `A2UICore.Processor.apply_operations/3` applies.

Adapters (`A2UICore.Message.Adapter`) normalize wire envelopes into
these structs; every later stage (surface lifecycle, data model,
RPC) works only against them. Field names mirror the wire (`surfaceId`
→ `surface_id`), and the version-specific edge cases are smoothed out
at construction:

  * `v0.9.x` `updateDataModel` may omit `value` (delete) — `value` is
    `nil` either way; v1.0's explicit `null` and v0.9's omission are
    the same canonical op.
  * `v1.0` `createSurface` may inline `components` and `dataModel`;
    the v1.0 adapter expands those into separate
    `update_components`/`update_data_model` ops after the
    `create_surface` op, exactly like the reference implementation.
  * `v0.9.x` carries `theme` through to the surface; v1.0 drops it.

# `t`
*since 0.1.0* 

```elixir
@type t() ::
  A2UICore.Message.Operation.CreateSurface.t()
  | A2UICore.Message.Operation.UpdateComponents.t()
  | A2UICore.Message.Operation.UpdateDataModel.t()
  | A2UICore.Message.Operation.DeleteSurface.t()
  | A2UICore.Message.Operation.CallRendererFunction.t()
  | A2UICore.Message.Operation.AgentFunctionResponse.t()
```

# `action`
*since 0.1.0* 

```elixir
@spec action(t()) :: String.t()
```

The canonical action key of an operation (matching the wire's
message-type keys).

---

*Consult [api-reference.md](api-reference.md) for complete listing*
