Class EntityRef

java.lang.Object
dyntabs.ai.activity.EntityRef

public final class EntityRef extends Object
An immutable, lightweight pointer to one business entity the user just touched — not the entity itself, just enough to name it: a type (e.g. "order"), an id (e.g. "4711"), and a few optional human-readable attributes (e.g. label="Order #4711 — ACME").

What this class is for

EntityRef is the heart of the Ambient Activity Memory feature. When the user opens an order, edits a customer, or searches for an invoice, we don't copy the whole record into the activity timeline — we record a tiny reference to it. Later, when the user asks the assistant "cancel this order" or "who is that customer?", the recent stream of EntityRefs is what lets the assistant resolve the deixis ("this"/"that") to a concrete order #4711 without the user ever typing the id.

Familiar analogy: a sticky note with a name and a desk number on it — "Order 4711, 3rd drawer". It is not the file in the drawer; it is just enough to find the file. We keep a little pile of these sticky notes (the activity timeline) so that when you say "pull that one", we know which drawer you mean.

Why we store refs, not blobs

The application already owns the real data (in its database, its CDI beans, its DTOs). Duplicating it into an activity log would be wasteful, would go stale instantly, and would be a privacy liability. A reference is cheap, always re-resolvable through the app's own services, and carries only the labels a human (or the LLM) needs to recognise the thing. The optional attributes() map is for exactly those recognition hints (a display label, a status), not for mirroring the record.

Equality

Two refs are equal when their type and id match; attributes are descriptive decoration and are deliberately excluded. This makes a ref behave like a stable identity key, so the same entity referenced twice (perhaps with a richer label the second time) still de-duplicates cleanly in a timeline.

Instances are immutable and therefore safe to hand to another thread, queue, or store.

See Also:
  • Method Details

    • of

      public static EntityRef of(String type, String id)
      Create a bare reference with no descriptive attributes.
      Parameters:
      type - the kind of entity (e.g. "order", "customer"); required
      id - the entity's identifier as a string (e.g. "4711"); required
      Returns:
      a new immutable EntityRef
    • of

      public static EntityRef of(String type, String id, String attrKey, String attrValue)
      Create a reference carrying a single recognition hint — typically a human-readable label.

      Example: EntityRef.of("order", "4711", "label", "Order #4711 — ACME").

      Parameters:
      type - the kind of entity; required
      id - the entity's identifier; required
      attrKey - the attribute name (e.g. "label"); required
      attrValue - the attribute value; required
      Returns:
      a new immutable EntityRef
    • of

      public static EntityRef of(String type, String id, Map<String,String> attributes)
      Create a reference with an arbitrary set of recognition hints.
      Parameters:
      type - the kind of entity; required
      id - the entity's identifier; required
      attributes - descriptive hints (e.g. label, status); copied defensively, may be null or empty
      Returns:
      a new immutable EntityRef
    • type

      public String type()
      Returns:
      the kind of entity (e.g. "order"); never null.
    • id

      public String id()
      Returns:
      the entity's identifier as a string (e.g. "4711"); never null.
    • attributes

      public Map<String,String> attributes()
      Returns:
      an unmodifiable, insertion-ordered map of recognition hints; never null (empty when none were supplied).
    • attribute

      public String attribute(String key)
      Convenience lookup for a single attribute.
      Parameters:
      key - the attribute name
      Returns:
      the value, or null if absent
    • label

      public String label()
      The best human-readable label for this entity: the "label" attribute if present, otherwise a compact type#id fallback.

      This is what a renderer puts into the prompt so the LLM sees "Order #4711 — ACME" rather than a bare id.

      Returns:
      a never-null display string
    • equals

      public boolean equals(Object o)
      Overrides:
      equals in class Object
    • hashCode

      public int hashCode()
      Overrides:
      hashCode in class Object
    • toString

      public String toString()
      Overrides:
      toString in class Object