Skip to content

Actor detail tabs

Selecting any node in the tree drives a detail.show-actor op into <director-detail>, which projects the introspection result across seven tabs plus a Chat surface. All eight subcomponents are mounted at all times — switching tabs toggles display: none/block, never tear-down/rebuild (per webapp-compliance.md).

The tab list is fixed at the source: TAB_IDS = ['overview', 'interface', 'state', 'cognitive', 'memory', 'children', 'chat'] (DirectorDetail.ts:25).

Overview tab — director-tab-overview

Source: src/components/tabs/TabOverview.ts.

A static field table:

FieldSource
mountIActorIntrospect.mount
componentClasscomponentClass
descriptiondescription (or )
purposepurpose
regimebadge
promptabletrue/false badge
continuationTypecontinuationType (default stateless)
planScopeplanScope (default session)

This tab does not call any actor ops; it only renders the introspect payload provided by DirectorApp.

Interface tab — director-tab-interface

Renders accepts, emits, tracks, and skills arrays from $introspect. For each accepted op, it renders the params shape from acceptsSchema. Skills come from skillsSchema if present.

State tab — director-tab-state

Reads stateScope, persistState, and stateSchema from introspect. There is no live state.read request in this tab today; the displayed schema is what the actor declares, not the current values. Live state values are surfaced by selecting the underlying actor in the tree or via direct matrix invoke <mount> state.get (when supported).

Cognitive tab — director-tab-cognitive

Reads the cognitive fields populated by Phase-1 introspection: purpose, systemPrompt, memoryScope, regime, promptable, promptTriggers, continuationType, planScope, and contract.interfaces. These are the fields that classify an actor as a "cognitive" actor. For non-cognitive actors most fields are empty.

Memory tab — director-tab-memory

Source: src/components/tabs/TabMemory.ts.

Issues DirectorDataAdapter.searchMemory({ mount, query, limit }) and renders the result rows. The dispatched mount list is ['system.agents.memory', 'system.memory'] — canonical-first, compat-fallback. The result includes a backendMode (canonical/compat) and searchTier for the badge.

Note: memory.write and memory.history are target ops in DESIGN.md §3.6. Today's tab is read-only; it shows the closest matches but cannot edit the memory store.

Children tab — director-tab-children

Reads IActorIntrospect.children[] and renders mount, componentClass, accepts/emits hints. qualifyChildren() (src/services/DirectorAddressing.ts) resolves child mounts so each row links to a fully qualified target.

Sessions tab — director-tab-sessions

Source: src/components/tabs/TabSessions.ts. Composes:

director-tab-sessions
├── backend-bar (badge: "agents" | "legacy", clickable to open backend)
├── mx-split (vertical, 24% / 76%)
│   ├── director-session-list  (session summaries)
│   └── director-session-chat  (history + input)
└── not-promptable (shown when the selected actor isn't promptable)

Calls into DirectorDataAdapter:

  • listSessions(context, root, { mount, principalId? })$sessionList against system.agents.
  • loadSessionHistory(context, root, { mount, sessionId })session_state.read({ sessionId, key: 'transcript' }).
  • promptSession(context, root, { mount, text, sessionId })$prompt against system.agents with a snapshotTree carrying the target mount.

Chat tab — director-chat-surface-host

Source: src/components/DirectorChatSurfaceHost.ts.

The chat tab is not a child of director-tab-*. It's a peer tab inside director-detail with its own load-state lifecycle:

'idle' → 'loading' → 'ready' | 'unavailable'

On first activation it dynamically imports @open-matrix/chat-component/surface. If the import succeeds and <conversation-surface> registers, the tab renders the surface and forwards surface.set-target { mount } events. If the import fails (chat-component not built into Director's bundle, network error in dev), the tab renders an "unavailable" message with rebuild instructions instead of throwing.

This is the M4-003 / HARVEST-005 pattern: the surface ships as a lazy chunk in Director's own dist, so identity of MatrixActorHtmlElement is preserved and there is no bare-specifier resolution failure in the browser. The genuine cross-package plugin loader (HARVEST-040) is target state.

See also

Source: projects/matrix-3/packages/director/src/components/DirectorDetail.ts (tab manifold), each components/tabs/* file, and components/DirectorChatSurfaceHost.ts.