@memberjunction/ng-conversations 6.2.0-edge.4 → 6.2.0-edge.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -0
- package/dist/lib/components/attachment/image-viewer.component.d.ts +3 -1
- package/dist/lib/components/attachment/image-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/attachment/image-viewer.component.js +5 -1
- package/dist/lib/components/attachment/image-viewer.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-agent-picker.component.d.ts +1 -1
- package/dist/lib/components/conversation/conversation-agent-picker.component.js +3 -3
- package/dist/lib/components/conversation/conversation-agent-picker.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +88 -20
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.js +785 -387
- package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
- package/dist/lib/components/message/message-input.component.d.ts +60 -20
- package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input.component.js +290 -389
- package/dist/lib/components/message/message-input.component.js.map +1 -1
- package/dist/lib/components/message/message-item.component.d.ts +153 -17
- package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-item.component.js +1400 -299
- package/dist/lib/components/message/message-item.component.js.map +1 -1
- package/dist/lib/components/message/message-list.component.d.ts +25 -2
- package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-list.component.js +79 -40
- package/dist/lib/components/message/message-list.component.js.map +1 -1
- package/dist/lib/components/overlay/chat-overlay.component.d.ts +19 -0
- package/dist/lib/components/overlay/chat-overlay.component.d.ts.map +1 -1
- package/dist/lib/components/overlay/chat-overlay.component.js +125 -13
- package/dist/lib/components/overlay/chat-overlay.component.js.map +1 -1
- package/dist/lib/components/project/project-form-modal.component.js +2 -2
- package/dist/lib/components/project/project-form-modal.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts +6 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.js +110 -82
- package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-call-failure-notice.d.ts +13 -0
- package/dist/lib/components/realtime/realtime-call-failure-notice.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-call-failure-notice.js +21 -0
- package/dist/lib/components/realtime/realtime-call-failure-notice.js.map +1 -0
- package/dist/lib/components/realtime/realtime-composer.component.js +114 -102
- package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +21 -2
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-session-overlay.component.js +113 -76
- package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts.map +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js +7 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js.map +1 -1
- package/dist/lib/components/sidebar/routines-section.component.js +1 -1
- package/dist/lib/components/sidebar/routines-section.component.js.map +1 -1
- package/dist/lib/components/task/tasks-full-view.component.d.ts +152 -31
- package/dist/lib/components/task/tasks-full-view.component.d.ts.map +1 -1
- package/dist/lib/components/task/tasks-full-view.component.js +2227 -214
- package/dist/lib/components/task/tasks-full-view.component.js.map +1 -1
- package/dist/lib/components/tasks/tasks-dropdown.component.js +4 -4
- package/dist/lib/components/tasks/tasks-dropdown.component.js.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts +11 -1
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.js +25 -28
- package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
- package/dist/lib/services/agent-state.service.d.ts.map +1 -1
- package/dist/lib/services/agent-state.service.js +8 -8
- package/dist/lib/services/agent-state.service.js.map +1 -1
- package/dist/lib/services/browser-realtime-media-host.d.ts +7 -7
- package/dist/lib/services/browser-realtime-media-host.js +8 -78
- package/dist/lib/services/browser-realtime-media-host.js.map +1 -1
- package/dist/lib/services/conversation-agent.service.d.ts +53 -20
- package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-agent.service.js +108 -54
- package/dist/lib/services/conversation-agent.service.js.map +1 -1
- package/dist/lib/services/conversation-detail-window.store.d.ts +5 -0
- package/dist/lib/services/conversation-detail-window.store.d.ts.map +1 -1
- package/dist/lib/services/conversation-detail-window.store.js +52 -5
- package/dist/lib/services/conversation-detail-window.store.js.map +1 -1
- package/dist/lib/services/conversation-naming.d.ts.map +1 -1
- package/dist/lib/services/conversation-naming.js +9 -2
- package/dist/lib/services/conversation-naming.js.map +1 -1
- package/dist/lib/services/conversation-tasks-filter.d.ts +15 -0
- package/dist/lib/services/conversation-tasks-filter.d.ts.map +1 -0
- package/dist/lib/services/conversation-tasks-filter.js +69 -0
- package/dist/lib/services/conversation-tasks-filter.js.map +1 -0
- package/dist/lib/services/realtime-audio-recorder.d.ts +94 -86
- package/dist/lib/services/realtime-audio-recorder.d.ts.map +1 -1
- package/dist/lib/services/realtime-audio-recorder.js +222 -195
- package/dist/lib/services/realtime-audio-recorder.js.map +1 -1
- package/dist/lib/services/realtime-session.service.d.ts +30 -2
- package/dist/lib/services/realtime-session.service.d.ts.map +1 -1
- package/dist/lib/services/realtime-session.service.js +35 -7
- package/dist/lib/services/realtime-session.service.js.map +1 -1
- package/dist/lib/services/recording/libopus-wasm-binary.d.ts +3 -0
- package/dist/lib/services/recording/libopus-wasm-binary.d.ts.map +1 -0
- package/dist/lib/services/recording/libopus-wasm-binary.js +489 -0
- package/dist/lib/services/recording/libopus-wasm-binary.js.map +1 -0
- package/dist/lib/services/recording/libopus-worker-source.d.ts +48 -0
- package/dist/lib/services/recording/libopus-worker-source.d.ts.map +1 -0
- package/dist/lib/services/recording/libopus-worker-source.js +170 -0
- package/dist/lib/services/recording/libopus-worker-source.js.map +1 -0
- package/dist/lib/services/recording/linear-resampler.d.ts +45 -0
- package/dist/lib/services/recording/linear-resampler.d.ts.map +1 -0
- package/dist/lib/services/recording/linear-resampler.js +85 -0
- package/dist/lib/services/recording/linear-resampler.js.map +1 -0
- package/dist/lib/services/recording/opus-packet-encoder.d.ts +50 -0
- package/dist/lib/services/recording/opus-packet-encoder.d.ts.map +1 -0
- package/dist/lib/services/recording/opus-packet-encoder.js +41 -0
- package/dist/lib/services/recording/opus-packet-encoder.js.map +1 -0
- package/dist/lib/services/recording/wasm-opus-encoder.d.ts +86 -0
- package/dist/lib/services/recording/wasm-opus-encoder.d.ts.map +1 -0
- package/dist/lib/services/recording/wasm-opus-encoder.js +232 -0
- package/dist/lib/services/recording/wasm-opus-encoder.js.map +1 -0
- package/dist/lib/services/recording/webcodecs-opus-encoder.d.ts +39 -0
- package/dist/lib/services/recording/webcodecs-opus-encoder.d.ts.map +1 -0
- package/dist/lib/services/recording/webcodecs-opus-encoder.js +101 -0
- package/dist/lib/services/recording/webcodecs-opus-encoder.js.map +1 -0
- package/dist/lib/services/search.service.d.ts.map +1 -1
- package/dist/lib/services/search.service.js +3 -16
- package/dist/lib/services/search.service.js.map +1 -1
- package/dist/lib/utils/agent-failure-display.d.ts +14 -0
- package/dist/lib/utils/agent-failure-display.d.ts.map +1 -0
- package/dist/lib/utils/agent-failure-display.js +26 -0
- package/dist/lib/utils/agent-failure-display.js.map +1 -0
- package/dist/lib/utils/distinct-artifacts.d.ts +9 -3
- package/dist/lib/utils/distinct-artifacts.d.ts.map +1 -1
- package/dist/lib/utils/distinct-artifacts.js +24 -5
- package/dist/lib/utils/distinct-artifacts.js.map +1 -1
- package/dist/lib/utils/message-list-order.d.ts +13 -0
- package/dist/lib/utils/message-list-order.d.ts.map +1 -0
- package/dist/lib/utils/message-list-order.js +31 -0
- package/dist/lib/utils/message-list-order.js.map +1 -0
- package/dist/lib/utils/pin-state.d.ts +11 -0
- package/dist/lib/utils/pin-state.d.ts.map +1 -0
- package/dist/lib/utils/pin-state.js +9 -0
- package/dist/lib/utils/pin-state.js.map +1 -0
- package/dist/public-api.d.ts +1 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +1 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +36 -36
- package/dist/lib/services/browser-recording-unload-guard.d.ts +0 -30
- package/dist/lib/services/browser-recording-unload-guard.d.ts.map +0 -1
- package/dist/lib/services/browser-recording-unload-guard.js +0 -43
- package/dist/lib/services/browser-recording-unload-guard.js.map +0 -1
- package/dist/lib/services/realtime-pcm-wav.d.ts +0 -79
- package/dist/lib/services/realtime-pcm-wav.d.ts.map +0 -1
- package/dist/lib/services/realtime-pcm-wav.js +0 -213
- package/dist/lib/services/realtime-pcm-wav.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"realtime-session-overlay.component.js","sourceRoot":"","sources":["../../../../src/lib/components/realtime/realtime-session-overlay.component.ts","../../../../src/lib/components/realtime/realtime-session-overlay.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, ElementRef, EventEmitter, HostListener, Input, Output, OnDestroy, AfterViewInit, AfterViewChecked, ChangeDetectorRef, NgZone, TemplateRef, ViewChild, inject } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { Subscription } from 'rxjs';\nimport type { VideoSourceState } from '@memberjunction/ai-realtime-client';\nimport { UserInfo } from '@memberjunction/core';\nimport { UserInfoEngine } from '@memberjunction/core-entities';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { SharedGenericModule } from '@memberjunction/ng-shared-generic';\nimport { MJStorageMediaPlayerComponent, MediaTranscriptCue } from '@memberjunction/ng-media-player';\nimport {\n DescribeCallEnd,\n REALTIME_CAPTURES_OFF,\n REALTIME_CAPTURE_OFFERS_NONE,\n REALTIME_MICROPHONE_NONE,\n type RealtimeAvatarNotice,\n type RealtimeCaptureOffers,\n type RealtimeCaptureState,\n type RealtimeCaptureStates,\n type RealtimeConnectionState,\n type RealtimeMicrophoneState,\n} from '@memberjunction/realtime-runtime';\nimport { MJAlertComponent } from '@memberjunction/ng-ui-components';\nimport { RealtimeSessionService } from '../../services/realtime-session.service';\nimport { ParsedDelegationArtifact } from '@memberjunction/realtime-runtime';\nimport { BuildReviewThreadItems, RealtimeSessionReview, RealtimeSessionReviewTurn } from '../../services/realtime-session-review.service';\nimport { RealtimeSessionState } from './realtime-session-state';\nimport { RealtimeAgentBannerComponent } from './realtime-agent-banner.component';\nimport { RealtimeSessionThreadComponent } from './realtime-session-thread.component';\nimport { RealtimeChannelStripComponent } from './realtime-channel-strip.component';\nimport { RealtimePerceptionChipComponent, RealtimePerceptionToggle } from './realtime-perception-chip.component';\nimport { RealtimeComposerComponent } from './realtime-composer.component';\nimport { RealtimeSurfaceTabsComponent, RealtimeChannelSlot } from './realtime-surface-tabs.component';\nimport { RealtimeSurfaceStageModel } from './realtime-surface-stage.model';\nimport { AgentOrbStateFor, RealtimeAgentOrbComponent, type RealtimeAgentOrbState } from './realtime-agent-orb.component';\nimport { RealtimeCameraCheckCardComponent } from './capture/realtime-camera-check-card.component';\nimport { SURFACE_PIP_PREF_KEY, SURFACE_PLACEMENT_PREF_KEY } from './realtime-surface-placement-prefs';\nimport { RealtimeChannelPaneComponent } from './channels/realtime-channel-pane.component';\nimport {\n ClampSurfacePanelWidth, DefaultSurfacePanelWidth, IsSurfacePanelDrag, ParseSurfacePanelPref,\n SerializeSurfacePanelPref, SurfacePanelDragWidth,\n SURFACE_PANEL_COLLAPSED_WIDTH, SURFACE_PANEL_DEFAULT_WIDTH, SURFACE_PANEL_PREF_KEY\n} from './realtime-surface-panel-prefs';\nimport { RealtimeDisclosureModel, RealtimeUxDensity, SerializeUxMilestones, REALTIME_UX_PREF_KEY } from './realtime-disclosure';\nimport {\n ResolveRealtimeUi, DEFAULT_REALTIME_UI_INPUTS, DEFAULT_REALTIME_UI_SIGNALS,\n RealtimeUiInputs, RealtimeUiSignals, ResolvedRealtimeUi,\n RealtimeChromeMode, RealtimeControlId, RealtimeUiConnectionState\n} from './realtime-ui-config';\nimport { RealtimeAudioVisualFrame, RealtimeAudioVisualSmoother, RealtimeDirection } from './realtime-audio-visuals';\nimport { RealtimeChannelTabRegistration, ShouldRemoveReviewWhiteboardTab } from './realtime-surface-tabs.model';\nimport { ShouldRegisterChannelTabUpFront } from './realtime-surface-tab-style';\nimport { BaseRealtimeChannelClient } from '@memberjunction/realtime-runtime';\nimport { RealtimeWhiteboardBoardComponent, WhiteboardState } from '@memberjunction/ng-whiteboard';\nimport {\n AvatarNoticeText, MediaMoveMenuComponent, MediaStageComponent, MediaStagePipActionsDirective, MediaStageSurfaceDirective,\n SharePanelDirective, SharePanelRegistry,\n type AvatarNoticeOverrides, type MediaMoveRequest, type MediaSharePanel, type MediaShareRequest, type MediaStagePipRectChange\n} from '@memberjunction/ng-realtime-media';\nimport { MediaLayoutPrefs, RecordPipRect, type MediaDevice, type MediaDeviceSelection, type MediaPipRect } from '@memberjunction/ai-realtime-client/media';\n\n/** How long the call's avatar notice stays before it hides itself (N5: it also has a dismiss button). */\nconst AVATAR_NOTICE_VISIBLE_MS = 10_000;\n\n/**\n * What the call says while no microphone works, by why: a microphone the browser blocked must be allowed before a pick\n * can open it. `{Agent}` stands for the agent's name. The arrow is the device chevron on the microphone button.\n */\nconst MICROPHONE_NOTICE_TEXT = {\n Blocked: \"{Agent} can't hear you: the browser blocked the microphone. Allow it for this site, then choose it from the arrow next to the microphone button.\",\n Lost: \"{Agent} can't hear you: no microphone is working. Connect one, or choose one from the arrow next to the microphone button.\",\n} as const;\n\n/**\n * A request to open an entity record, emitted by the call overlay's gear-gated developer\n * links (\"Open run\" / \"Open session\"). The Generic host (chat area) converts it onto its\n * existing `openEntityRecord` output chain — the package never navigates itself (no Router).\n */\nexport interface RealtimeNavigateRequest {\n /** Entity to open (e.g. `MJ: AI Agent Runs`, `MJ: AI Agent Sessions`). */\n EntityName: string;\n /** ID of the record to open. */\n RecordID: string;\n}\n\n/**\n * A request to RESUME a reviewed session as a NEW live call, emitted by review mode's\n * \"Start live session\" button. The host (chat area) clears its review state and starts a\n * voice session through the same path the composer's mic uses, passing\n * {@link LastSessionId} so the server chains the new session to the reviewed one\n * (restoring saved channel states such as the whiteboard via `PriorChannelStatesJson`).\n */\nexport interface RealtimeStartLiveRequest {\n /** Agent the resumed session should front (review Config `targetAgentID`, else the session's `AgentID`). */\n TargetAgentId: string;\n /** Conversation the reviewed session was bound to, when any. */\n ConversationId: string | null;\n /** The reviewed session's id — chained as the new session's `lastSessionId`. */\n LastSessionId: string;\n}\n\n/** A caption as it runs over the agent's video: who said it (`null` for the agent, whose video it is) and what. */\nexport interface RealtimeAvatarCaption {\n Speaker: string | null;\n Text: string;\n}\n\n\n/**\n * The \"call mode\" overlay for a live real-time voice session. Hosted by the\n * conversation chat area (`<mj-conversation-chat-area>`) behind `Active$`, it fills the\n * conversation panel IN PLACE (`position:absolute; inset:0` over the panel — not a\n * fixed app-wide dialog), replacing the conversation view including the composer.\n *\n * Two-column layout:\n * - MAIN column — {@link RealtimeAgentBannerComponent} (the unified APP-BAR: identity +\n * turn-state + the disclosure-gated action cluster), the unified\n * {@link RealtimeSessionThreadComponent} (or the level-0 pure-audio hero), the channel\n * strip, and {@link RealtimeComposerComponent} (the bottom dock: phone-call strip ⇄\n * fused minis+composer).\n * - RIGHT PANEL — {@link RealtimeSurfaceTabsComponent}: the TABBED surface panel.\n * Tab 1 \"Activity\" hosts the session activity rail; one tab opens per ARTIFACT a\n * delegated run produces (auto-focused + flashed on arrival, viewed read-only via the\n * standard artifact viewer); ONE TAB PER INTERACTIVE CHANNEL the session resolved from\n * the `MJ: AI Agent Channels` registry. Collapsible to a slim strip at the panel level.\n *\n * INTERACTIVE CHANNELS ARE PLUGINS — this shell is channel-agnostic. It subscribes\n * {@link RealtimeSessionService.ActiveChannels$} and registers one surface tab per\n * {@link BaseRealtimeChannelClient} (key/title/icon from the plugin). Every plugin's surface\n * lives on ONE STAGE (`mj-media-stage`) over the whole overlay: created the first time it is\n * seen, laid over its tab's pane while that tab is active, and kept until its channel leaves\n * (see {@link RealtimeSurfaceStageModel}). The PLUGIN wires its own inputs/outputs.\n * Each surface starts where its channel's registry row places it (its tab unless the row says\n * otherwise). The user moves it with \"Move to…\" (beside its tab, in the call pill, or on a\n * picture-in-picture box): to the STAGE, a picture-in-picture box, its tab, or out of sight,\n * as far as its channel allows. The moves are saved per user and carry over to later\n * sessions. A surface on the stage is the FOCUS layout: the main call column collapses\n * (`.board-focus`), the surface fills the overlay and the floating call pill appears. A channel\n * may ask for it too (via its context's `SetFocusMode` → {@link RealtimeSessionService.ChannelFocus$}),\n * which moves its surface to the stage or back.\n *\n * Owns the shared {@link RealtimeSessionState} — the SINGLE merge of the service's\n * caption/delegation/narration streams — and passes it to both thread and rail via\n * inputs, so neither duplicates subscription logic.\n *\n * DEVELOPER MODE: the controls row's gear toggles {@link DevMode} (per-session, off by\n * default, never persisted), revealing \"Open run\" links on delegation cards / rail items\n * and an \"Open session\" link in the banner. Clicking one emits {@link NavigateRequest}\n * and MINIMIZES the call (via {@link RealtimeSessionService.SetMinimized}) — the session\n * stays live while the host navigates to the record.\n *\n * SESSION REVIEW MODE: when the host supplies {@link ReviewData} (a loaded\n * `RealtimeSessionReview`) and NO live session is active, the overlay renders what went\n * down in that PAST session instead of a live call: the banner shows a \"Session review\"\n * badge + lifecycle range + close-reason chip; the SAME thread/rail components render the\n * historical caption turns and delegated-run cards (via\n * {@link RealtimeSessionState.LoadHistoricalItems}); a read-only Whiteboard tab is\n * registered ONLY when the session saved a parseable Whiteboard channel state. Everything\n * live is DEAD in review — no mic, no captions stream, no composer, no channel strip; the\n * controls collapse to a single \"Start live session\" button ({@link StartLiveRequested},\n * which resumes by chaining `lastSessionId`) and a Close button ({@link ReviewClosed}).\n */\n@Component({\n standalone: true,\n selector: 'mj-realtime-session-overlay',\n imports: [\n CommonModule,\n SharedGenericModule,\n RealtimeAgentBannerComponent,\n RealtimeAgentOrbComponent,\n RealtimeCameraCheckCardComponent,\n RealtimeSessionThreadComponent,\n RealtimeChannelStripComponent,\n RealtimePerceptionChipComponent,\n RealtimeComposerComponent,\n RealtimeSurfaceTabsComponent,\n RealtimeChannelPaneComponent,\n MediaMoveMenuComponent,\n MediaStageComponent,\n MediaStageSurfaceDirective,\n MediaStagePipActionsDirective,\n SharePanelDirective,\n RealtimeWhiteboardBoardComponent,\n MJStorageMediaPlayerComponent,\n MJAlertComponent\n ],\n templateUrl: './realtime-session-overlay.component.html',\n styleUrl: './realtime-session-overlay.component.css'\n})\nexport class RealtimeSessionOverlayComponent extends BaseAngularComponent implements AfterViewInit, AfterViewChecked, OnDestroy {\n private _agentName = 'Sage';\n\n /**\n * True while the call is MINIMIZED: the overlay hides itself (CSS, not destruction) so\n * the host can show its floating \"on call\" pill WITHOUT losing this shell's merged\n * session state (delegation cards ride non-replaying streams) or view state (dev mode,\n * expanded chips, scroll position). The host binds this from `Minimized$`.\n */\n @Input() Hidden = false;\n\n /** Display name of the agent the voice session fronts (e.g. \"Sage\"). */\n @Input()\n set AgentName(value: string) {\n this._agentName = value || 'Sage';\n this.State.AgentName = this._agentName;\n }\n get AgentName(): string {\n return this._agentName;\n }\n\n /** The signed-in user, threaded to the surface panel's artifact viewer. */\n @Input() CurrentUser: UserInfo | null = null;\n\n /** The active environment id, threaded to the surface panel's artifact viewer. */\n @Input() EnvironmentID = '';\n\n /**\n * The host's own words for why the call shows no avatar, per reason (for example its product's name for \"this app\").\n * A reason it leaves out keeps the stock line from `ng-realtime-media` (`AVATAR_NOTICE_TEXT`). `unknown` words a reason\n * this version doesn't know, such as a newer server's, in place of `AVATAR_NOTICE_CALL_UNKNOWN_REASON_TEXT`.\n */\n @Input() AvatarNoticeLabels: AvatarNoticeOverrides | null = null;\n\n // ── Declarative UI configuration (host controls every aspect of the surface) ──\n //\n // Each input is a thin, PascalCase setter over a private slot in {@link _uiInputs}.\n // When a host binds it, that field wins over the {@link UiConfig} bag (individual\n // input precedence). Setting any of these recomputes the resolved view-model so the\n // change takes effect on the next CD pass. Every field is optional and defaults to\n // the historical behaviour via {@link DEFAULT_REALTIME_UI_INPUTS}, so existing call\n // sites that bind none of them behave exactly as before.\n //\n // See {@link RealtimeUiInputs} / the package README for the full contract + recipes.\n\n /**\n * The chrome the widget renders: the ambient `'orb'`, the structured `'console'`, or\n * `'auto'` (default) which starts as an orb and graduates to a console once the\n * container is wide enough AND the user has revealed text. Mirrors\n * {@link RealtimeUiInputs.chrome}.\n *\n * @example Force the rich console for a full-screen route:\n * ```html\n * <mj-realtime-session-overlay [Chrome]=\"'console'\"></mj-realtime-session-overlay>\n * ```\n */\n @Input()\n set Chrome(value: RealtimeChromeMode | undefined) { this.setUiInput('chrome', value); }\n get Chrome(): RealtimeChromeMode | undefined { return this._uiInputs.chrome; }\n\n /**\n * In `'auto'` chrome, the container width (px) at/above which the widget may graduate\n * to a console (still gated on text being revealed). Default `560`. Mirrors\n * {@link RealtimeUiInputs.consoleBreakpointPx}.\n */\n @Input()\n set ConsoleBreakpointPx(value: number | undefined) { this.setUiInput('consoleBreakpointPx', value); }\n get ConsoleBreakpointPx(): number | undefined { return this._uiInputs.consoleBreakpointPx; }\n\n /**\n * Force dense spacing/typography regardless of width (useful for tight mobile sheets).\n * Default `false` — compactness is otherwise inferred from the container width.\n */\n @Input()\n set Compact(value: boolean | undefined) { this.setUiInput('compact', value); }\n get Compact(): boolean | undefined { return this._uiInputs.compact; }\n\n /** Fade non-essential controls when the session is idle (orb chrome only). Default `true`. */\n @Input()\n set AutoHideControls(value: boolean | undefined) { this.setUiInput('autoHideControls', value); }\n get AutoHideControls(): boolean | undefined { return this._uiInputs.autoHideControls; }\n\n /**\n * May the user reveal the transcript at all? `false` makes the widget a pure voice orb\n * with no path to text (and never graduates to a console in `'auto'`). Default `true`.\n */\n @Input()\n set AllowTextReveal(value: boolean | undefined) { this.setUiInput('allowTextReveal', value); }\n get AllowTextReveal(): boolean | undefined { return this._uiInputs.allowTextReveal; }\n\n /** Show the captions toggle. Default `true`. */\n @Input()\n set ShowCaptionsControl(value: boolean | undefined) { this.setUiInput('showCaptionsControl', value); }\n get ShowCaptionsControl(): boolean | undefined { return this._uiInputs.showCaptionsControl; }\n\n /** Show the density picker inside the gear menu. Default `true`. */\n @Input()\n set ShowDensityPicker(value: boolean | undefined) { this.setUiInput('showDensityPicker', value); }\n get ShowDensityPicker(): boolean | undefined { return this._uiInputs.showDensityPicker; }\n\n /** Show the minimize control (collapse the call without ending it). Default `true`. */\n @Input()\n set ShowMinimize(value: boolean | undefined) { this.setUiInput('showMinimize', value); }\n get ShowMinimize(): boolean | undefined { return this._uiInputs.showMinimize; }\n\n /** Show the end-call control. Default `true` (hosts that own their own end button may hide it). */\n @Input()\n set ShowEnd(value: boolean | undefined) { this.setUiInput('showEnd', value); }\n get ShowEnd(): boolean | undefined { return this._uiInputs.showEnd; }\n\n /**\n * Show the right-hand surface panel (whiteboard / browser / interactive channels).\n * Default `true`; only renders in console chrome and once a panel is actually earned.\n */\n @Input()\n set ShowSurfacePanel(value: boolean | undefined) { this.setUiInput('showSurfacePanel', value); }\n get ShowSurfacePanel(): boolean | undefined { return this._uiInputs.showSurfacePanel; }\n\n /** Show the channel strip (active interactive channels). Default `true`. */\n @Input()\n set ShowChannels(value: boolean | undefined) { this.setUiInput('showChannels', value); }\n get ShowChannels(): boolean | undefined { return this._uiInputs.showChannels; }\n\n /** Show the Activity rail/tab (delegations, artifacts timeline). Default `true`. */\n @Input()\n set ShowActivityRail(value: boolean | undefined) { this.setUiInput('showActivityRail', value); }\n get ShowActivityRail(): boolean | undefined { return this._uiInputs.showActivityRail; }\n\n /**\n * Show developer affordances (\"open session / open run\" links). Default `true`, but\n * still additionally gated by the per-session dev-mode toggle — a hard ceiling, not a\n * force-on.\n */\n @Input()\n set ShowDevLinks(value: boolean | undefined) { this.setUiInput('showDevLinks', value); }\n get ShowDevLinks(): boolean | undefined { return this._uiInputs.showDevLinks; }\n\n /** Allow drag-to-resize of the surface panel. Default `true`. */\n @Input()\n set AllowResize(value: boolean | undefined) { this.setUiInput('allowResize', value); }\n get AllowResize(): boolean | undefined { return this._uiInputs.allowResize; }\n\n /**\n * A programmatic override bag, merged UNDER the individual inputs — any field also set\n * via a dedicated `@Input()` wins over its entry here. Lets a host configure the whole\n * surface in one binding (e.g. a saved per-context preset) without enumerating a dozen\n * attributes.\n *\n * @example\n * ```html\n * <mj-realtime-session-overlay [UiConfig]=\"leanOverlayPreset\"></mj-realtime-session-overlay>\n * ```\n */\n @Input()\n set UiConfig(value: RealtimeUiInputs | null | undefined) {\n this._uiConfigBag = value ?? null;\n this.recomputeUi();\n }\n get UiConfig(): RealtimeUiInputs | null | undefined { return this._uiConfigBag; }\n\n /**\n * SESSION REVIEW data: when set (and no live session is active) the overlay renders\n * the reviewed past session instead of a live call. Setting it populates the shared\n * {@link State} with the historical thread and prepares the read-only whiteboard tab;\n * clearing it returns the state to its live-merge baseline.\n */\n @Input()\n set ReviewData(value: RealtimeSessionReview | null) {\n if (value === this._reviewData) {\n return;\n }\n this._reviewData = value;\n if (value && !this.realtime.IsActive) {\n this.enterReview(value);\n } else if (!value) {\n this.exitReview();\n }\n }\n get ReviewData(): RealtimeSessionReview | null {\n return this._reviewData;\n }\n\n /**\n * Review mode: whether the \"Start live session\" action is offered. A host turns it off where\n * a voice session cannot start (the chat area does so while a draft fork is open).\n */\n @Input() AllowStartLive = true;\n\n /** Emitted after the call ends so the host can react (visibility is driven by Active$). */\n @Output() Ended = new EventEmitter<void>();\n\n /**\n * Emitted when a gear-gated developer link asks to open an entity record. The host is\n * expected to bubble this through its standard record-open path (the chat area re-emits\n * it on `openEntityRecord`, which Explorer routes via `NavigationService`). The overlay\n * minimizes itself first so the live call survives the navigation.\n */\n @Output() NavigateRequest = new EventEmitter<RealtimeNavigateRequest>();\n\n /**\n * Review mode's \"Start live session\": the host clears its review state and resumes the\n * reviewed session as a new live call (chaining `LastSessionId` to restore channel states).\n */\n @Output() StartLiveRequested = new EventEmitter<RealtimeStartLiveRequest>();\n\n /** Review mode's Close: the host clears its review state, returning to the conversation. */\n @Output() ReviewClosed = new EventEmitter<void>();\n\n // ── Declarative UI outputs (observe everything the surface does) ─────────────\n\n /** Emitted when the user minimizes the call view (the call stays live). */\n @Output() Minimized = new EventEmitter<void>();\n\n /** Emitted when the user reveals the transcript (opens text from the orb). */\n @Output() TextRevealed = new EventEmitter<void>();\n\n /** Emitted whenever the EFFECTIVE chrome flips between `'orb'` and `'console'`. */\n @Output() ChromeChanged = new EventEmitter<'orb' | 'console'>();\n\n /** Emitted when the connection lifecycle state changes (e.g. connecting → listening). */\n @Output() ConnectionStateChanged = new EventEmitter<RealtimeUiConnectionState>();\n\n /** Emitted when the mic mute is toggled; payload is the new muted state. */\n @Output() MuteChanged = new EventEmitter<boolean>();\n\n /** Emitted when the interface density changes. */\n @Output() DensityChanged = new EventEmitter<RealtimeUxDensity>();\n\n /** Emitted (px) when the user finishes resizing the surface panel. */\n @Output() SurfacePanelResized = new EventEmitter<number>();\n\n /**\n * A generic hook fired when ANY control is invoked — even one the host hid via inputs\n * and re-rendered itself. Lets a host observe/react to the full control surface from a\n * single binding.\n */\n @Output() ControlInvoked = new EventEmitter<RealtimeControlId>();\n\n private realtime = inject(RealtimeSessionService);\n private cdr = inject(ChangeDetectorRef);\n\n /**\n * The consumer's individually-bound UI inputs (each dedicated `@Input()` writes its own\n * slot here). Starts empty; only fields a host actually binds appear, so the resolver's\n * defaults fill the rest. Merged OVER {@link _uiConfigBag} (individual inputs win).\n */\n private _uiInputs: RealtimeUiInputs = {};\n\n /** The programmatic {@link UiConfig} override bag, merged UNDER the individual inputs. */\n private _uiConfigBag: RealtimeUiInputs | null = null;\n\n /**\n * The latest measured width (px) of the rendered overlay element, fed to the resolver as\n * {@link RealtimeUiSignals.ContainerWidthPx}. Maintained by a {@link ResizeObserver}; 0\n * until the first measurement (the resolver treats 0 as \"narrow\", i.e. an orb in auto).\n */\n private containerWidthPx = 0;\n\n /** Observes the rendered overlay element so chrome re-resolves as the host resizes. */\n private resizeObserver: ResizeObserver | null = null;\n\n /** The last connection state seen on {@link RealtimeSessionService.ConnectionState$}. */\n private currentConnectionState: RealtimeConnectionState = 'closed';\n\n /**\n * The resolved, render-ready view-model — the SINGLE source of truth the template binds\n * to (no `&&` chains in HTML). Rebuilt by {@link recomputeUi} whenever an input, the\n * disclosure model, the connection state, the container width, or the channel/activity\n * set changes. Read-only to consumers via the {@link Ui} getter.\n */\n // Seed from a dependency-free baseline — this runs as a field initializer, BEFORE the\n // disclosure model / session state / ResizeObserver exist. recomputeUi() produces the real\n // value once dependencies are ready (post-init + on every wired change source).\n private _ui: ResolvedRealtimeUi = ResolveRealtimeUi(DEFAULT_REALTIME_UI_INPUTS, DEFAULT_REALTIME_UI_SIGNALS);\n\n /**\n * The current resolved UI view-model. Every visibility/affordance decision the template\n * makes reads from this — bind to its boolean fields rather than composing logic inline.\n *\n * @example\n * ```ts\n * if (this.voice.Ui.chrome === 'console') { ... }\n * ```\n */\n public get Ui(): ResolvedRealtimeUi {\n return this._ui;\n }\n\n /** Local mic-muted state, the single source the resolver-independent controls reflect. */\n public Muted = false;\n\n private _reviewData: RealtimeSessionReview | null = null;\n\n /**\n * Set by {@link OnStartLive} just before emitting {@link StartLiveRequested}, so the\n * ReviewData→null transition that follows is recognized as a REVIEW→LIVE CONTINUATION\n * (keep the historical thread + append the \"Resumed live session\" divider) rather than\n * a plain review close (clear everything).\n */\n private pendingLiveContinuation = false;\n\n /**\n * The reviewed chain's history artifacts, surfaced inside the Activity tab's \"Session\n * artifacts\" group (no longer their own tabs). Bound into the surface panel via\n * {@link ReviewArtifacts}. Empty for a live session.\n */\n private reviewArtifacts: ParsedDelegationArtifact[] = [];\n\n /** The reviewed chain's history artifacts for the surface panel's Activity tab. */\n public get ReviewArtifacts(): ParsedDelegationArtifact[] {\n return this.reviewArtifacts;\n }\n\n /**\n * True while the surface panel carries the REVIEW-registered (template-based, read-only)\n * Whiteboard tab. Drives the review→live continuation edge: when the resumed live\n * session's channel set resolves WITHOUT a Whiteboard channel, the stale review tab is\n * removed (see {@link cleanupStaleReviewBoardTab}); when it resolves WITH one, the live\n * plugin re-registers the same key and the tab upgrades in place.\n */\n private reviewWhiteboardTabRegistered = false;\n\n /** True while the overlay renders a PAST session (review data set, no live call). */\n public get IsReviewing(): boolean {\n return this._reviewData !== null && !this.realtime.IsActive;\n }\n\n /**\n * The reviewed session's rehydrated whiteboard, when it saved a parseable Whiteboard\n * channel state — rendered read-only by the review whiteboard tab. Null = no tab.\n */\n public ReviewWhiteboard: WhiteboardState | null = null;\n\n /**\n * The `MJ: Files` id of the reviewed session's recording, or null when nothing was recorded.\n * Bound into the storage media player, which resolves the authenticated audio itself.\n */\n public get ReviewRecordingFileID(): string | null {\n return this._reviewData?.RecordingFileID ?? null;\n }\n\n /**\n * The reviewed session's transcript cues (built from its turns) for the recording player's\n * transcript panel. Empty outside review.\n */\n public ReviewCues: MediaTranscriptCue[] = [];\n\n /** True while the Recording tab is registered (a recording exists for the reviewed session). */\n private reviewRecordingTabRegistered = false;\n\n /** Shared session state — single source for the thread AND the activity rail. */\n public readonly State = new RealtimeSessionState();\n\n /**\n * PROGRESSIVE DISCLOSURE: the levels/milestones model behind the pure-audio-first UX\n * (see {@link RealtimeDisclosureModel}). Loaded from UserInfoEngine at construction;\n * content events ({@link onSessionStateChanged}, {@link onChannelActivity}) raise the\n * volatile session level; milestones ratchet + persist when the call ends. REVIEW mode\n * bypasses disclosure entirely — a past session always renders the full console.\n */\n public readonly Disclosure = new RealtimeDisclosureModel();\n\n /**\n * The strip's Details peek: shows the surface panel ON DEMAND while it isn't earned yet\n * (disclosure level < 2) — Activity and channel surfaces exist before their content\n * does. Cleared automatically once content earns the panel for real.\n */\n public DetailsPeek = false;\n\n /**\n * Whether the typed-input dock is open — a TWO-WAY user door (the strip's Type\n * control / the T hotkey open it; the dock's hide control closes it), volatile and\n * reset per session. Typing never becomes permanent chrome.\n */\n public ComposerOpen = false;\n\n /** Live turn-state from the session service — drives the banner + connecting screen. */\n public readonly ConnectionState$ = this.realtime.ConnectionState$;\n\n /** Server-reported realtime model name for the active session — shown subtly in the banner. */\n public readonly ModelName$ = this.realtime.ModelName$;\n\n /**\n * Whether the conversation renders as TEXT (the thread) or stays voice-first (the\n * orb hero). A PERSISTED per-user preference (`mj.realtimeVoice.captions.v1`) —\n * default OFF: voice-first, the orb owns the screen until the user opts into text.\n */\n public ShowCaptions = false;\n\n /**\n * Whether the user asked for the conversation itself (the hero's \"Show the conversation\", {@link RevealText}), not only\n * captions. While the agent's video presents in the hero, captions alone keep the hero and run over the video; this\n * opens the thread. Cleared when captions turn off.\n */\n private conversationShown = false;\n\n /** UserInfoEngine key for the persisted captions (text-vs-orb) preference. */\n private static readonly captionsPrefKey = 'mj.realtimeVoice.captions.v1';\n\n /**\n * Whether developer affordances (open-record links) are revealed. Per-session view\n * state on this shell — off by default, reset with the overlay, never persisted.\n */\n public DevMode = false;\n\n /** ID of the live server-side agent session record, for the banner's dev link. */\n public get SessionID(): string | null {\n return this.realtime.CurrentAgentSessionId;\n }\n\n /**\n * The tabbed surface panel (right panel) — channel registrations are forwarded to it.\n * A SETTER because the panel is disclosure-gated (`@if`): it can be created LATE (the\n * first delegation / channel activity reveals it mid-call), at which point any queued\n * channel registrations and a pending auto-reveal must flush to the fresh instance.\n */\n private surfaceTabs?: RealtimeSurfaceTabsComponent;\n @ViewChild(RealtimeSurfaceTabsComponent)\n private set surfaceTabsRef(ref: RealtimeSurfaceTabsComponent | undefined) {\n this.surfaceTabs = ref;\n if (!ref) {\n // The panel went away with its slots. StageSlot reads null while it is away, so the bindings don't change.\n this.channelSlot = null;\n this.SurfaceStage.SetActiveTab(null);\n // The panel that comes back is a new one, which starts as PanelCollapsed says: expanded unless only the call's\n // width hid this one (#5387, #5433).\n this.resetPanelCollapseUnlessWaitingForRoom();\n } else {\n // A (re)created panel starts with a FRESH tab model. Re-register the live channel set\n // here (gated to whiteboard + already-used channels) so hiding the panel (pure-audio\n // return, Details off) never loses the Whiteboard or an already-used channel's tab.\n // Artifacts live in the Activity rail now (driven by session state), so there's\n // nothing artifact-specific to recover on the panel.\n this.registerChannelTabs([...this.realtime.ActiveChannels]);\n this.flushPendingChannelTabs();\n const reveal = this.pendingRevealKey;\n this.pendingRevealKey = null;\n // Deferred: focus/expand feed the parent's width bindings (wide tier) — never\n // mutate those inside the change-detection pass that created the panel.\n setTimeout(() => {\n if (reveal) {\n // The agent's first channel activity caused this creation — land ON the board.\n ref.RevealChannel(reveal);\n } else {\n // Default for a fresh panel (live AND review): the marquee surface — channels\n // lead the strip — NOT the Activity rail; agent-run plumbing is opt-in only.\n // (Review channel tabs register a beat later and take focus themselves.)\n ref.FocusFirstTab();\n // The panel reports its wide tier only when it flips, from a start that is not wide, so landing on Activity\n // reports nothing. PanelWide may still hold the tier of the panel before, whose focused channel left the call\n // while it was away, so it takes the tier of the tab this one landed on (#5433). Only a different tier moves\n // the width. A reveal always lands on a channel's tab, which the panel reports itself.\n if (ref.IsWide !== this.PanelWide) {\n this.OnPanelWideChanged(ref.IsWide);\n }\n }\n });\n }\n }\n\n /** The bottom dock — type-to-compose seeds + focuses its input. */\n @ViewChild(RealtimeComposerComponent) private composer?: RealtimeComposerComponent;\n\n /** Channel keys already auto-revealed this session (first activity only). */\n private revealedChannelKeys = new Set<string>();\n\n /** Auto-reveal that arrived before the (disclosure-gated) panel rendered. */\n private pendingRevealKey: string | null = null;\n\n /** Previous Active$ value — edges drive disclosure session begin/ratchet. */\n private prevActive = false;\n\n /** Template hosting the read-only review whiteboard (root-level, so always resolvable). */\n @ViewChild('reviewBoardTpl') private reviewBoardTpl?: TemplateRef<unknown>;\n\n /** Template hosting the review-mode recording player (root-level, so always resolvable). */\n @ViewChild('recordingTpl') private recordingTpl?: TemplateRef<unknown>;\n\n /** Channel registrations received before the surface panel rendered (flushed in ngAfterViewInit). */\n private pendingChannelTabs: RealtimeChannelTabRegistration[] = [];\n\n /** True once the view (and the review-board template ref) exists. */\n private viewReady = false;\n\n // ── Channel FOCUS layout (channel-generic — any plugin may request it) ─────\n\n /**\n * True while a channel's surface is on the stage (FOCUS mode): the main call column collapses\n * (`.board-focus` on the overlay) and a compact floating call pill (orb + state +\n * mute / show-thread / move / end) rides over the surface. A surface that presents the agent\n * ({@link PresenterOnStage}) takes the agent's place in the call instead, so it is not focus mode.\n */\n public get ChannelFocusMode(): boolean {\n return this.SurfaceStage.StageKey !== null && !this.PresenterOnStage;\n }\n\n /**\n * Whether the surface on the stage presents the agent: its channel shows the agent's video (the Avatar). It lies over\n * {@link PresenterSlot}, in the agent's place in the call (the hero, or above the thread in the console), rather than\n * filling the overlay.\n */\n public get PresenterOnStage(): boolean {\n return this.StagePlugin?.ShowsAgentVideo ?? false;\n }\n\n /** Whether captions run over the agent's video: they are on, and the video presents in the hero. */\n public get ShowAvatarCaptions(): boolean {\n return this.ShowCaptions && this.ShowHero && this.PresenterOnStage;\n }\n\n /**\n * Whether the call body shows the connecting screen for `state`: while the call connects, outside review, unless the\n * agent's video presents in the hero. The hero then stays, so a resume on a new connection keeps the video in its place\n * with its last frame on screen, and the video's tile says the call is connecting. Taking the hero away would take the\n * video's place with it, and the stage would lay the video over the whole call until the hero came back.\n */\n public ShowConnectingScreen(state: RealtimeConnectionState): boolean {\n return !this.IsReviewing && state === 'connecting' && !(this.ShowHero && this.PresenterOnStage);\n }\n\n /** The newest caption, as the captions over the agent's video show it: the user's is marked \"You\". `null` before any. */\n public get AvatarCaption(): RealtimeAvatarCaption | null {\n const items = this.State.Items;\n for (let i = items.length - 1; i >= 0; i--) {\n const item = items[i];\n if (item.Kind === 'caption') {\n return { Speaker: item.Role === 'User' ? 'You' : null, Text: item.Text };\n }\n }\n return null;\n }\n\n /** The agent's place in the call, as last reported to the stage, or `null` while the call shows none. */\n public PresenterSlot: HTMLElement | null = null;\n\n /** The element the stage lays its stage surface over: the agent's place while it presents, else none (it fills the stage). */\n public get StageSurfaceSlot(): HTMLElement | null {\n return this.PresenterOnStage ? this.PresenterSlot : null;\n }\n\n /** The agent's place in the call: in the hero, or above the thread in the console. */\n @ViewChild('presenterSlot') private presenterSlotRef?: ElementRef<HTMLElement>;\n\n /** The presenter slot last reported through {@link PresenterSlot}. */\n private reportedPresenterSlot: HTMLElement | null = null;\n\n /** Mic-muted state reflected on the focus pill's mute button. */\n public FocusPillMuted = false;\n\n /** The channel whose surface is on the stage (the pill's exit routes back to it), or `null`. */\n public get StagePlugin(): BaseRealtimeChannelClient | null {\n const key = this.SurfaceStage.StageKey;\n return key ? this.SurfaceStage.PluginFor(key) : null;\n }\n\n // ── The stage: every channel surface, in one layer over the overlay ─────────\n\n /** Which channel surfaces the stage holds and where each shows. */\n public readonly SurfaceStage = new RealtimeSurfaceStageModel();\n\n /** The active channel tab's slot, as the panel last reported it. */\n private channelSlot: RealtimeChannelSlot | null = null;\n\n /** The slot the stage lays the active channel tab's surface over: none while the panel is away. */\n public get StageSlot(): RealtimeChannelSlot | null {\n return this.ShowPanelArea ? this.channelSlot : null;\n }\n\n /** The panel's active channel slot moved, or went away. */\n public OnChannelSlotChange(slot: RealtimeChannelSlot | null): void {\n this.channelSlot = slot;\n this.SurfaceStage.SetActiveTab(slot?.Key ?? null);\n this.cdr.markForCheck();\n }\n\n private subs: Subscription[] = [];\n\n constructor() {\n super();\n this.loadPlacementPref();\n this.loadPanelWidthPref();\n this.loadDisclosurePref();\n this.loadCaptionsPref();\n this.State.Attach(this.realtime);\n this.subs.push(\n // Re-render on merged-state changes; content arrival raises the disclosure level.\n this.State.Changed$.subscribe(() => this.onSessionStateChanged()),\n // Disclosure ratchet moved — re-resolve the view-model (thread/composer/gear gates).\n this.Disclosure.Changed$.subscribe(() => this.recomputeUi()),\n // One surface tab per registry-resolved channel plugin (replays the current set).\n this.realtime.ActiveChannels$.subscribe(channels => this.onActiveChannelsChanged(channels)),\n // Any channel may request the focus layout through its host context.\n this.realtime.ChannelFocus$.subscribe(event => this.onChannelFocus(event.Channel, event.Focused)),\n // The agent ACTED on a channel — auto-reveal its surface tab on first activity.\n this.realtime.ChannelActivity$.subscribe(plugin => this.onChannelActivity(plugin)),\n // What the agent can see (frames flowing from a whiteboard, browser, shared screen): feeds the\n // \"agent can see\" chip. Not gated by disclosure level — it is a privacy indicator, never earned.\n this.realtime.VideoSources$.subscribe(sources => { this.VideoSources = sources; this.cdr.markForCheck(); }),\n // The camera and screen share, and which of them the call offers: the composer's Camera and Share follow both.\n this.realtime.Captures$.subscribe(states => this.onCapturesChanged(states)),\n this.realtime.CaptureOffers$.subscribe(offers => { this.CaptureOffers = offers; this.cdr.markForCheck(); }),\n // The call's microphone and the ones it can move to: the composer's device menu lists them.\n this.realtime.Microphone$.subscribe(microphone => this.onMicrophoneChanged(microphone)),\n // The panels of the page on screen, which the Share menu offers under \"This panel\"; a shared one that goes away\n // ends its share.\n this.sharePanelRegistry.PanelsFor$(this.hostRef.nativeElement).subscribe(panels => {\n this.SharePanels = panels;\n this.cdr.markForCheck();\n }),\n this.sharePanelRegistry.Removed$.subscribe(key => this.onSharePanelRemoved(key)),\n // Live/idle flips: reset/ratchet disclosure + re-evaluate the review-vs-live branch.\n this.realtime.Active$.subscribe(active => this.onActiveChanged(active)),\n // Connection lifecycle drives chrome (the `connecting` loader) + the public output.\n this.realtime.ConnectionState$.subscribe(state => this.onConnectionStateChanged(state)),\n // Why the call shows no avatar its agent asked for: once per call, after it connects.\n this.realtime.AvatarNotice$.subscribe(notice => this.onAvatarNotice(notice))\n );\n }\n\n /** The runtime's notice for this call (`null` when none). */\n private avatarNotice: RealtimeAvatarNotice | null = null;\n\n /** The notice the user dismissed or that hid itself; this call does not show it again. */\n private avatarNoticeDone: RealtimeAvatarNotice | null = null;\n\n /** Hides the notice {@link AVATAR_NOTICE_VISIBLE_MS} after it appears. */\n private avatarNoticeTimer: ReturnType<typeof setTimeout> | null = null;\n\n /**\n * Why this live call shows no avatar its agent asked for, while the notice shows: from the moment the call connects\n * until the user dismisses it or it hides itself. `null` otherwise, and always in review.\n */\n public get AvatarNotice(): RealtimeAvatarNotice | null {\n const notice = this.avatarNotice;\n return notice && notice !== this.avatarNoticeDone && !this.IsReviewing ? notice : null;\n }\n\n /**\n * The notice's line, in the host's words when it gave some ({@link AvatarNoticeLabels}); a notice without a reason (one\n * this version doesn't know) reads the call's line for it.\n */\n public get AvatarNoticeMessage(): string {\n const notice = this.AvatarNotice;\n return notice ? AvatarNoticeText(notice.Reason ?? null, this.AvatarNoticeLabels, this.AgentName) : '';\n }\n\n /** The user dismissed the notice: it does not come back in this call. */\n public OnAvatarNoticeDismissed(): void {\n this.finishAvatarNotice();\n }\n\n /** A new notice starts its timer; a call's end (`null`) takes it away. */\n private onAvatarNotice(notice: RealtimeAvatarNotice | null): void {\n if (notice === this.avatarNotice) {\n return;\n }\n this.clearAvatarNoticeTimer();\n this.avatarNotice = notice;\n if (notice && notice !== this.avatarNoticeDone) {\n this.avatarNoticeTimer = setTimeout(() => this.ngZone.run(() => this.finishAvatarNotice()), AVATAR_NOTICE_VISIBLE_MS);\n }\n this.cdr.markForCheck();\n }\n\n /** Hides the current notice for the rest of its call. */\n private finishAvatarNotice(): void {\n this.clearAvatarNoticeTimer();\n this.avatarNoticeDone = this.avatarNotice;\n this.cdr.markForCheck();\n }\n\n private clearAvatarNoticeTimer(): void {\n if (this.avatarNoticeTimer !== null) {\n clearTimeout(this.avatarNoticeTimer);\n this.avatarNoticeTimer = null;\n }\n }\n\n /** The video sources the agent can or could see right now (see {@link RealtimeSessionService.VideoSources$}). */\n public VideoSources: readonly VideoSourceState[] = [];\n\n /** The user's camera and screen share (see {@link RealtimeSessionService.Captures$}). */\n public CaptureStates: RealtimeCaptureStates = REALTIME_CAPTURES_OFF;\n\n /** Which captures the call offers (see {@link RealtimeSessionService.CaptureOffers$}); the composer shows Camera and Share from it. */\n public CaptureOffers: RealtimeCaptureOffers = REALTIME_CAPTURE_OFFERS_NONE;\n\n /** Whether the camera is on or starting: the composer's Camera button reads as on. */\n public get CameraOn(): boolean {\n return isCapturing(this.CaptureStates.Camera);\n }\n\n /** The camera while the user checks it, before the agent sees it; `null` otherwise. The camera check card shows it. */\n public get CameraCheck(): RealtimeCaptureState | null {\n return this.CaptureStates.Camera.Checking ? this.CaptureStates.Camera : null;\n }\n\n /** The camera check's \"Turn on camera\": the agent sees the camera from now on. */\n public OnCameraCheckConfirmed(): void {\n this.realtime.ConfirmCamera();\n }\n\n /** The camera check's \"Not now\": the camera turns off. */\n public OnCameraCheckDeclined(): void {\n this.realtime.StopCamera();\n }\n\n /** Moves the camera being checked to another device: the camera check's picker. */\n public readonly SwitchCheckedCamera = (deviceId: string): Promise<RealtimeCaptureState> => this.realtime.SwitchCamera(deviceId);\n\n /** Whether a share is on or starting: the composer's Share button reads as sharing. */\n public get Sharing(): boolean {\n return isCapturing(this.CaptureStates.Screen);\n }\n\n /**\n * The composer's Camera button. The session starts or stops the camera; its channel's box shows it, or why it could not\n * start.\n */\n public OnCameraToggled(on: boolean): void {\n if (on) {\n void this.realtime.StartCamera();\n } else {\n this.realtime.StopCamera();\n }\n this.ControlInvoked.emit('camera');\n }\n\n /** The app's shareable panels: what the Share menu offers under \"This panel\", and the panel a pick names. */\n private readonly sharePanelRegistry = inject(SharePanelRegistry);\n\n /**\n * The panels of the page the Share menu offers under \"This panel\": those on screen, in page order, leaving out any that\n * holds this call. Empty where the browser cannot share a single panel.\n */\n public SharePanels: readonly MediaSharePanel[] = [];\n\n /** The key of the panel being shared, while a share of one panel starts or runs; `null` otherwise. */\n private sharedPanelKey: string | null = null;\n\n /**\n * The composer's Share button or menu: the session asks the browser's picker, offering the kind of surface picked first,\n * or this tab, to share the picked panel alone.\n */\n public OnShareRequested(request: MediaShareRequest): void {\n if (request.Kind === 'display') {\n void this.realtime.StartScreenShare(request.PreferredSurface ? { PreferredSurface: request.PreferredSurface } : undefined);\n } else {\n this.startPanelShare(request.PanelKey);\n }\n this.ControlInvoked.emit('share');\n }\n\n /** The composer's Stop sharing. */\n public OnStopShareRequested(): void {\n this.realtime.StopScreenShare();\n this.ControlInvoked.emit('share');\n }\n\n /** Shares one panel of the page, named by its label. A panel that went away since the menu listed it shares nothing. */\n private startPanelShare(key: string): void {\n const panel = this.sharePanelRegistry.Get(key);\n if (!panel) {\n return;\n }\n this.sharedPanelKey = key;\n void this.realtime.StartScreenShare({ Panel: panel.Element, PanelLabel: panel.Label });\n }\n\n /**\n * A panel went away, such as the whiteboard when its channel leaves the call. When it is the one shared, the share ends:\n * no frame comes from an element that is gone. A panel that is only out of sight keeps its share.\n */\n private onSharePanelRemoved(key: string): void {\n if (key === this.sharedPanelKey) {\n this.sharedPanelKey = null;\n this.realtime.StopScreenShare();\n }\n }\n\n /** The captures changed: the composer follows them, and a share that is over no longer holds its panel. */\n private onCapturesChanged(states: RealtimeCaptureStates): void {\n this.CaptureStates = states;\n if (!isCapturing(states.Screen)) {\n this.sharedPanelKey = null;\n }\n this.refreshCallDevices();\n this.cdr.markForCheck();\n }\n\n /** The call's microphone (see {@link RealtimeSessionService.Microphone$}). */\n private microphone: RealtimeMicrophoneState = REALTIME_MICROPHONE_NONE;\n\n /** The microphone and the camera the user picked in the device menu, each while the call switches to it. */\n private switchingTo: { microphone: string | null; camera: string | null } = { microphone: null, camera: null };\n\n /**\n * The microphones and cameras the composer's device menu offers: the call's microphones, and its cameras while the\n * camera is open (a browser names cameras only once the user has allowed one).\n */\n public CallDevices: readonly MediaDevice[] = [];\n\n /** The microphone the device menu shows: the one being switched to, else the one in use. */\n public get SelectedMicrophoneID(): string | null {\n return this.switchingTo.microphone ?? this.microphone.DeviceID ?? null;\n }\n\n /** The camera the device menu shows: the one being switched to, else the one in use. */\n public get SelectedCameraID(): string | null {\n return this.switchingTo.camera ?? this.CaptureStates.Camera.DeviceID ?? null;\n }\n\n /**\n * What the call says while no microphone works: the call lost its microphone (the one in use failed and so did the\n * default, or the last one went away), so the agent hears nothing until the user picks one in the device menu. Shown\n * under the banner for as long as that lasts. `null` while the microphone works, outside a call, and always in review.\n */\n public get MicrophoneNotice(): string | null {\n const failure = this.microphone.Failure;\n if (!failure || this.IsReviewing) {\n return null;\n }\n const line = failure === 'denied' ? MICROPHONE_NOTICE_TEXT.Blocked : MICROPHONE_NOTICE_TEXT.Lost;\n return line.split('{Agent}').join(this.AgentName);\n }\n\n /**\n * A microphone or camera picked in the composer's device menu: the session switches to it. The menu shows the pick\n * while the switch runs, then the device in use: the new one, or the old one when the new one could not open. A pick of\n * the device in use changes nothing. While no microphone works, the session opens the picked microphone, and the menu\n * then shows it, or none when it could not open.\n */\n public async OnDeviceSelected(selection: MediaDeviceSelection): Promise<void> {\n if (selection.Kind !== 'microphone' && selection.Kind !== 'camera') {\n return;\n }\n const kind = selection.Kind;\n const inUse = kind === 'microphone' ? this.microphone.DeviceID : this.CaptureStates.Camera.DeviceID;\n if (selection.DeviceID === inUse && this.switchingTo[kind] === null) {\n return;\n }\n this.ControlInvoked.emit('devices');\n this.switchingTo = { ...this.switchingTo, [kind]: selection.DeviceID };\n this.cdr.markForCheck();\n try {\n if (kind === 'microphone') {\n await this.realtime.SwitchMicrophone(selection.DeviceID);\n } else {\n await this.realtime.SwitchCamera(selection.DeviceID);\n }\n } finally {\n if (this.switchingTo[kind] === selection.DeviceID) {\n this.switchingTo = { ...this.switchingTo, [kind]: null };\n }\n this.cdr.markForCheck();\n }\n }\n\n /** The microphone changed: the device menu follows it. */\n private onMicrophoneChanged(microphone: RealtimeMicrophoneState): void {\n this.microphone = microphone;\n this.refreshCallDevices();\n this.cdr.markForCheck();\n }\n\n /** Lists the call's microphones and its cameras for the device menu, as a new list only when one of them changed. */\n private refreshCallDevices(): void {\n const cameras = this.CaptureStates.Camera.Devices ?? [];\n const devices = [...this.microphone.Devices, ...cameras];\n const same = devices.length === this.CallDevices.length && devices.every((d, i) => d === this.CallDevices[i]);\n if (!same) {\n this.CallDevices = devices;\n }\n }\n\n /**\n * The user switched one of the agent's video sources on or off in the \"agent can see\" chip. The session\n * applies it (and remembers it per channel) and tells the agent.\n */\n public OnVideoSourceToggled(toggle: RealtimePerceptionToggle): void {\n this.realtime.SetVideoSourceEnabled(toggle.SourceID, toggle.Enabled);\n }\n\n /**\n * The user picked the video source the agent sees in the \"agent can see\" chip, or let the call choose again (`null`).\n * The session's arbiter applies it and tells the agent.\n */\n public OnVideoSourcePicked(sourceId: string | null): void {\n this.realtime.SelectVideoSource(sourceId);\n }\n\n /**\n * The user moved to another channel's tab (or to a tab that is not a channel). When the model can watch only one\n * video source, the channel the user is looking at is the one it sees.\n */\n public OnActiveChannelChange(channelKey: string | null): void {\n this.realtime.SetFocusedChannel(channelKey);\n }\n\n ngAfterViewChecked(): void {\n this.reportPresenterSlot();\n }\n\n /** Reports the agent's place in the call when the element changed (the chrome switched, or the call body changed). */\n private reportPresenterSlot(): void {\n const element = this.presenterSlotRef?.nativeElement ?? null;\n if (element === this.reportedPresenterSlot) {\n return;\n }\n this.reportedPresenterSlot = element;\n // The view was just checked and the stage binds the slot, so it hears about it in a fresh turn.\n queueMicrotask(() => {\n this.PresenterSlot = element;\n this.cdr.markForCheck();\n });\n }\n\n ngAfterViewInit(): void {\n this.viewReady = true;\n this.startResizeObserver();\n this.flushPendingChannelTabs();\n this.registerReviewBoardTab();\n this.registerReviewArtifactTabs();\n // Cues were already built by enterReview() when ReviewData was set; here we only need to\n // (re)register the recording tab now that the #recordingTpl ref exists. The storage media\n // player resolves the authenticated audio itself from the RecordingFileID.\n this.registerReviewRecordingTab();\n }\n\n // ── Declarative UI config: inputs → signals → resolved view-model ────────────\n\n /**\n * Writes one individually-bound UI input into {@link _uiInputs} and re-resolves the\n * view-model. `undefined` clears the slot (so the {@link UiConfig} bag / default applies).\n * Called by every dedicated `@Input()` setter.\n *\n * @param key the {@link RealtimeUiInputs} field to set\n * @param value the bound value, or `undefined` to clear the override\n */\n private setUiInput<K extends keyof RealtimeUiInputs>(key: K, value: RealtimeUiInputs[K] | undefined): void {\n if (value === undefined) {\n delete this._uiInputs[key];\n } else {\n this._uiInputs[key] = value;\n }\n this.recomputeUi();\n }\n\n /**\n * The effective consumer inputs: the {@link UiConfig} bag with the individually-bound\n * inputs layered ON TOP, so a dedicated `@Input()` always wins over its bag entry.\n */\n private get mergedUiInputs(): RealtimeUiInputs {\n return { ...(this._uiConfigBag ?? {}), ...this._uiInputs };\n }\n\n /**\n * Maps the runtime {@link RealtimeConnectionState} onto the resolver's\n * {@link RealtimeUiConnectionState}. `'closed'` (no live call) maps to `'idle'`; the\n * other states pass through 1:1.\n */\n private mapConnectionState(state: RealtimeConnectionState): RealtimeUiConnectionState {\n return state === 'closed' ? 'idle' : state;\n }\n\n /**\n * Builds the live {@link RealtimeUiSignals} the resolver consumes, reading current facts\n * from the disclosure model, the session/channel state, review mode, focus mode, and the\n * {@link ResizeObserver}-measured width. Pure read — no side effects.\n */\n private buildSignals(): RealtimeUiSignals {\n // Defensive: this can be reached before every dependency is wired (field-init / early\n // change-detection). Fall back to the dependency-free baseline rather than throw — the\n // next recompute, once everything exists, produces the real value.\n const disclosure = this.Disclosure;\n if (!disclosure) {\n return DEFAULT_REALTIME_UI_SIGNALS;\n }\n const reviewing = this.IsReviewing;\n return {\n ContainerWidthPx: this.containerWidthPx ?? 0,\n // Text intent = the user EXPLICITLY asked to see text this session — i.e. captions are on\n // (the captions toggle, the hero's \"Show the conversation\", RevealText(), and SetCaptions()\n // all route through ShowCaptions). NOT the disclosure ratchet: a power user still opens to\n // the calm orb until they ask for text, matching the historical ShowHero = !ShowCaptions.\n // While the agent's video presents, captions alone keep the hero (they run over the video);\n // only asking for the conversation opens the thread.\n TextRevealed: this.ShowCaptions && (this.conversationShown || !this.PresenterOnStage),\n DisclosureShowThread: disclosure.ShowThread,\n DisclosureShowComposer: disclosure.ShowComposer,\n DisclosureShowPanel: disclosure.ShowPanel,\n DisclosureShowGear: disclosure.ShowGear,\n // A surface to populate: the on-demand Details peek, or review (always has a surface).\n SurfacePanelEarned: this.DetailsPeek || reviewing,\n hasChannels: (this.realtime?.ActiveChannels ?? []).some(c => c.HasSurface()),\n HasActivity: (this.State?.Cards?.length ?? 0) > 0,\n DevMode: this.DevMode,\n IsReviewing: reviewing,\n channelFocus: this.ChannelFocusMode,\n ConnectionState: this.mapConnectionState(this.currentConnectionState)\n };\n }\n\n /**\n * Re-resolves {@link Ui} from the merged inputs + current signals and emits the chrome /\n * connection-state outputs when they actually change. Safe to call on any of the wired\n * change sources (input write, disclosure ratchet, connection flip, resize, channel set);\n * the resolver is pure so redundant calls are cheap. Always marks for check.\n */\n private recomputeUi(): void {\n const next = ResolveRealtimeUi(this.mergedUiInputs, this.buildSignals());\n const prevChrome = this._ui.chrome;\n this._ui = next;\n if (next.chrome !== prevChrome) {\n this.ChromeChanged.emit(next.chrome);\n }\n // The panel's area may have just hidden, or, while it waited for room, been hidden for another reason too.\n this.resetPanelCollapseUnlessWaitingForRoom();\n this.cdr.markForCheck();\n }\n\n /** Connection lifecycle changed: store it, re-resolve chrome, and surface the public output. */\n private onConnectionStateChanged(state: RealtimeConnectionState): void {\n if (state === this.currentConnectionState) {\n return;\n }\n this.currentConnectionState = state;\n this.ConnectionStateChanged.emit(this.mapConnectionState(state));\n this.recomputeUi();\n }\n\n // ── Container-width observation (drives the auto orb ↔ console graduation) ────\n\n /**\n * Starts observing the rendered overlay element's width so the resolver can graduate\n * `'auto'` chrome to a console when the host gives it room. Guards SSR / environments\n * without `ResizeObserver` (plain-node tests) — there the width simply stays 0 (an orb in\n * auto), which is the safe ambient default. Idempotent.\n */\n private startResizeObserver(): void {\n if (this.resizeObserver || typeof ResizeObserver !== 'function') {\n return;\n }\n const el = this.overlayElement() ?? (this.hostRef.nativeElement as HTMLElement);\n if (!el) {\n return;\n }\n // Seed an immediate measurement so the first resolve sees a real width. Deferred to a\n // microtask (same reasoning as OnPanelWideChanged above): ngAfterViewInit runs inside the\n // SAME change-detection pass that already checked bindings derived from Ui (e.g. the\n // template's `@if (ShowPanelArea)` and `[Compact]`) using the field-initializer's width-0\n // baseline. Recomputing synchronously here can flip chrome orb→console mid-pass and trip\n // ExpressionChangedAfterItHasBeenCheckedError (NG0100). Landing the seed measurement in a\n // fresh microtask lets it recompute in its own CD cycle instead.\n Promise.resolve().then(() => {\n this.applyContainerWidth(el.getBoundingClientRect ? el.getBoundingClientRect().width : 0);\n });\n this.resizeObserver = new ResizeObserver(entries => {\n const width = entries[0]?.contentRect?.width ?? 0;\n this.ngZone.run(() => Promise.resolve().then(() => this.applyContainerWidth(width)));\n });\n this.resizeObserver.observe(el);\n }\n\n /** Adopts a new measured width and re-resolves only when it actually changed. */\n private applyContainerWidth(width: number): void {\n const rounded = Math.round(width);\n if (rounded === this.containerWidthPx) {\n return;\n }\n this.containerWidthPx = rounded;\n this.recomputeUi();\n }\n\n /** Disconnects the container-width observer. */\n private stopResizeObserver(): void {\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n }\n\n // ── Surface-panel sizing (flex layout + pointer-drag handle; width persisted per-user) ──\n //\n // The panel width is a PLAIN FIELD rendered via [style.width.px] — there is no split\n // library with its own internal size state to fight. The resize handle uses the same\n // mechanics as ui-components' slide-panel (`MjSlidePanelComponent`): mousedown →\n // document mousemove/mouseup registered OUTSIDE Angular, live clamp while dragging,\n // adopt + persist on release. A bare CLICK cannot move the panel by construction\n // (width follows the pointer delta) and the click-vs-drag guard keeps it from being\n // adopted or persisted.\n\n /**\n * Whether the surface panel is collapsed to its slim strip, as the panel reports it. A panel created again starts this\n * way (the overlay binds the panel's `Collapsed`). Back to `false` while the panel's area is hidden for any reason but\n * room, so the panel comes back expanded after Details, a channel on the stage or a review turning into a live call,\n * and as the user left it when only the call's width hid it.\n */\n public PanelCollapsed = false;\n /**\n * Wide tier active (a content tab is focused) — drives the DEFAULT width only. The panel reports it when it flips; a\n * panel created again also sets it from the tab it lands on.\n */\n public PanelWide = false;\n /** The user's explicit dragged width (persisted); null = follow the default tiers. */\n private userPanelWidth: number | null = null;\n /** Current expanded panel width in px (rendered as the panel's inline width). */\n public PanelWidthPx = SURFACE_PANEL_DEFAULT_WIDTH;\n /** True while the resize handle is mid-drag (brand-tints the handle). */\n public IsPanelResizing = false;\n private panelResizeStartX = 0;\n private panelResizeStartWidth = 0;\n private boundPanelResizeMove = this.onPanelResizeMove.bind(this);\n private boundPanelResizeEnd = this.onPanelResizeEnd.bind(this);\n private hostRef = inject(ElementRef);\n private ngZone = inject(NgZone);\n\n /** The panel's rendered width: slim strip when collapsed, otherwise the current width. */\n public get PanelAreaSize(): number {\n return this.PanelCollapsed ? SURFACE_PANEL_COLLAPSED_WIDTH : this.PanelWidthPx;\n }\n\n /**\n * Resizing is meaningless while collapsed or when the surface fills (focus mode), and a\n * host may hard-disable it via `[AllowResize]=\"false\"` — in review the resolver's\n * `allowResize` is false (no live surface to resize), so this also reads the host flag\n * directly (defaulting to the historical `true`) rather than the resolved value, keeping\n * drag available in review exactly as before.\n */\n public get PanelResizeDisabled(): boolean {\n const hostAllows = this.mergedUiInputs.allowResize ?? DEFAULT_REALTIME_UI_INPUTS.allowResize;\n return this.PanelCollapsed || this.ChannelFocusMode || !hostAllows;\n }\n\n public OnPanelCollapsedChange(collapsed: boolean): void {\n this.PanelCollapsed = collapsed;\n this.cdr.markForCheck();\n }\n\n /**\n * Resets {@link PanelCollapsed} while the panel's area is hidden for any reason but room. Details, a channel taking the\n * stage and a reviewed session turning into a live call hide the panel on purpose, and what brings it back asks to see\n * it, so it comes back expanded (#5387). A call that only got too narrow asked for nothing, so the panel comes back as\n * the user left it (#5433). Runs when the panel goes away and on every re-resolve, so a panel that waits for room and\n * is then hidden on purpose (Details closed meanwhile) comes back expanded too. No binding reads PanelCollapsed while\n * the area is hidden, so a change here trips no NG0100 check.\n */\n private resetPanelCollapseUnlessWaitingForRoom(): void {\n if (!this.ShowPanelArea && !this._ui.SurfacePanelWaitsForRoom) {\n this.PanelCollapsed = false;\n }\n }\n\n /** Wide-tier flips only move the DEFAULT width — an explicit user width always wins. */\n public OnPanelWideChanged(wide: boolean): void {\n this.PanelWide = wide;\n if (this.userPanelWidth === null) {\n // This can fire synchronously from the surface-tabs child during the FIRST change-detection\n // pass, while hostWidth() transitions 0 → real across that same pass — setting the bound width\n // inline then trips ExpressionChangedAfterItHasBeenCheckedError (380 → 308). Defer to a\n // microtask so the recompute lands in a fresh CD cycle. (Drag/reset handlers stay synchronous —\n // those run on real user events, not during CD.)\n Promise.resolve().then(() => {\n if (this.userPanelWidth === null) {\n this.PanelWidthPx = DefaultSurfacePanelWidth(this.PanelWide, this.hostWidth());\n this.cdr.markForCheck();\n }\n });\n return;\n }\n this.cdr.markForCheck();\n }\n\n /** Mousedown on the resize handle: capture the start state and track the pointer document-wide. */\n public OnPanelResizeStart(event: MouseEvent): void {\n if (this.PanelResizeDisabled) {\n return;\n }\n event.preventDefault();\n this.IsPanelResizing = true;\n this.panelResizeStartX = event.clientX;\n this.panelResizeStartWidth = this.PanelWidthPx;\n document.body.style.cursor = 'col-resize';\n document.body.style.userSelect = 'none';\n this.ngZone.runOutsideAngular(() => {\n document.addEventListener('mousemove', this.boundPanelResizeMove);\n document.addEventListener('mouseup', this.boundPanelResizeEnd);\n });\n this.cdr.markForCheck();\n }\n\n /** Live drag: panel width follows the pointer delta, clamped to [min, 70% of the overlay]. */\n private onPanelResizeMove(event: MouseEvent): void {\n if (!this.IsPanelResizing) {\n return;\n }\n this.PanelWidthPx = SurfacePanelDragWidth(\n this.panelResizeStartWidth, this.panelResizeStartX, event.clientX, this.hostWidth()\n );\n this.ngZone.run(() => this.cdr.markForCheck());\n }\n\n /**\n * Release: a genuine DRAG adopts the width as the user's explicit preference and\n * persists it (debounced); a bare CLICK (movement under the tolerance) restores the\n * start width and persists nothing — the handle never snaps on a click.\n */\n private onPanelResizeEnd(event: MouseEvent): void {\n if (!this.IsPanelResizing) {\n return;\n }\n this.teardownPanelResize();\n let resizedTo: number | null = null;\n if (IsSurfacePanelDrag(this.panelResizeStartX, event.clientX)) {\n this.userPanelWidth = this.PanelWidthPx;\n this.persistPanelWidth(this.PanelWidthPx);\n resizedTo = this.PanelWidthPx;\n } else {\n this.PanelWidthPx = this.panelResizeStartWidth;\n }\n this.ngZone.run(() => {\n this.IsPanelResizing = false;\n // Surface the new width to the host only on a genuine drag (not a bare click).\n if (resizedTo !== null) {\n this.SurfacePanelResized.emit(resizedTo);\n }\n this.cdr.markForCheck();\n });\n }\n\n /** Double-click the handle: back to the default tier width; persist the reset. */\n public OnPanelResizeReset(): void {\n this.userPanelWidth = null;\n this.PanelWidthPx = DefaultSurfacePanelWidth(this.PanelWide, this.hostWidth());\n this.persistPanelWidth(null);\n this.cdr.markForCheck();\n }\n\n /** Removes the document-wide drag listeners and restores the body cursor/selection. */\n private teardownPanelResize(): void {\n document.removeEventListener('mousemove', this.boundPanelResizeMove);\n document.removeEventListener('mouseup', this.boundPanelResizeEnd);\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n }\n\n /**\n * The overlay's measurable width for clamping. The component host is\n * `display: contents` (zero rect) — measure the rendered `.call-overlay` div instead.\n */\n private hostWidth(): number {\n const host = this.hostRef.nativeElement as HTMLElement;\n const el = (host.firstElementChild as HTMLElement | null) ?? host;\n return el.getBoundingClientRect ? el.getBoundingClientRect().width : 0;\n }\n\n /** Reads the persisted width once per overlay instance (no-op when the engine isn't configured). */\n private loadPanelWidthPref(): void {\n try {\n const pref = ParseSurfacePanelPref(UserInfoEngine.Instance.GetSetting(SURFACE_PANEL_PREF_KEY));\n if (pref) {\n this.userPanelWidth = pref.Width;\n // hostWidth() is 0 before first layout — the clamp then enforces only the\n // minimum, and the 70% cap re-applies on the next real drag.\n this.PanelWidthPx = ClampSurfacePanelWidth(pref.Width, this.hostWidth());\n this.cdr.markForCheck();\n }\n } catch {\n // UserInfoEngine not configured (plain-node tests / early bootstrap) — default tiers apply.\n }\n }\n\n /** Persists the width preference server-side (debounced); reset serializes {\"width\":null}. */\n private persistPanelWidth(width: number | null): void {\n try {\n UserInfoEngine.Instance.SetSettingDebounced(SURFACE_PANEL_PREF_KEY, SerializeSurfacePanelPref(width));\n } catch {\n // engine unavailable — width still applies for this session\n }\n }\n\n // ── Progressive disclosure (the console that grows with you) ────────────────\n\n /**\n * True while the PURE-AUDIO hero (the orb) owns the main column. Now reads from the\n * resolved view-model ({@link Ui}): the resolver decides hero-vs-thread from the\n * effective chrome + text intent + review, so host inputs (`[Chrome]`,\n * `[AllowTextReveal]`, the breakpoint) gate it. Review still always shows the thread.\n */\n public get ShowHero(): boolean {\n return this._ui.showHero;\n }\n\n /**\n * Whether the surface-panel area renders. Driven by the resolved {@link Ui.showSurfacePanel}\n * (console + earned + host's `[ShowSurfacePanel]`) OR review mode, which always carries the\n * panel. The Details toggle still earns the panel on demand (it flips `surfacePanelEarned`).\n */\n public get ShowPanelArea(): boolean {\n return this._ui.showSurfacePanel || this.IsReviewing;\n }\n\n /** The Details (tabs) toggle is offered while live — it's the panel's one door. */\n public get ShowDetailsControl(): boolean {\n return !this.IsReviewing;\n }\n\n /**\n * Whether the active-channels strip renders. Preserves the historical disclosure gate\n * (level 2+, {@link RealtimeDisclosureModel.ShowComposer}) AND honours the host's\n * `[ShowChannels]` input + the resolver's focus rule: a host that sets `[ShowChannels]`\n * false hard-disables the strip, and channel-focus mode hides it. The strip component\n * itself self-hides when no channels are active, so this stays decluttered.\n */\n public get ChannelStripVisible(): boolean {\n // Reads the RESOLVED Ui.showChannelStrip flag — which already ANDs the host's\n // [ShowChannels] input, an active channel, console chrome, and the no-focus rule.\n // In orb/compact chrome it is false, so the overlay never shows the \"CHANNELS · Voice\"\n // strip (the lean Calm-Orb surface). The strip component itself still self-hides when\n // no channels are active, keeping the console decluttered too.\n return this._ui.showChannelStrip;\n }\n\n /**\n * Whether the surface panel's Activity tab should be shown. Reads the resolved\n * {@link Ui.showActivityTab} (host's `[ShowActivityRail]` AND activity/review AND console)\n * OR review mode — a past session's activity is always relevant even before the resolver's\n * console gate would otherwise allow it.\n */\n public get ShowActivityTab(): boolean {\n return this._ui.showActivityTab || this.IsReviewing;\n }\n\n /** Reads the persisted disclosure milestones (tolerant; defaults to day one). */\n private loadDisclosurePref(): void {\n try {\n this.Disclosure.Load(UserInfoEngine.Instance.GetSetting(REALTIME_UX_PREF_KEY));\n } catch {\n // UserInfoEngine not configured (plain-node tests / early bootstrap) — day-one defaults.\n this.Disclosure.Load(null);\n }\n }\n\n /** Reads the persisted text-vs-orb preference (tolerant; default = voice-first OFF). */\n private loadCaptionsPref(): void {\n try {\n this.ShowCaptions = UserInfoEngine.Instance.GetSetting(RealtimeSessionOverlayComponent.captionsPrefKey) === 'true';\n } catch {\n // UserInfoEngine not configured — voice-first default applies.\n }\n }\n\n /** Persists the text-vs-orb preference (debounced, best-effort). */\n private persistCaptionsPref(): void {\n try {\n UserInfoEngine.Instance.SetSettingDebounced(RealtimeSessionOverlayComponent.captionsPrefKey, String(this.ShowCaptions));\n } catch {\n // engine unavailable — the preference still applies for this session\n }\n }\n\n /** Persists the disclosure milestones server-side (debounced, best-effort). */\n private persistDisclosure(serialized: string): void {\n try {\n UserInfoEngine.Instance.SetSettingDebounced(REALTIME_UX_PREF_KEY, serialized);\n } catch {\n // engine unavailable — the ratchet still applies for this browser session\n }\n }\n\n /**\n * Merged-state change: re-render only. DELIBERATELY no disclosure raise — per product\n * direction, content never flips the console open: a running delegation is narrated\n * aloud, a finished artifact lands as a GLOWING (unfocused) tab, and the ONLY thing\n * that auto-reveals is a channel's first agent activity (the whiteboard demands eyes).\n * A pure-audio user stays in pure audio until THEY ask for more.\n */\n private onSessionStateChanged(): void {\n // State.Cards drives the resolver's hasActivity signal — re-resolve (also marks for check).\n this.recomputeUi();\n }\n\n /**\n * The agent ACTED on a channel (a tool call routed to its local executor — e.g. the\n * first whiteboard write). THE ONE AUTO-REVEAL: the surface panel opens (as a peek —\n * the left column stays exactly as it was, pure audio included) with the channel's tab\n * focused and flashed, exactly once per channel — so the user discovers the board the\n * moment it comes alive. Disclosure levels are NOT raised: no text, no composer, no\n * extra chrome — just the board.\n */\n private onChannelActivity(plugin: BaseRealtimeChannelClient): void {\n if (this.IsReviewing || this.revealedChannelKeys.has(plugin.ChannelName)) {\n return;\n }\n this.revealedChannelKeys.add(plugin.ChannelName);\n if (plugin.ShowsAgentVideo) {\n this.revealPresenter(plugin);\n return;\n }\n this.DetailsPeek = true; // the panel shows via the same on-demand mechanism Details uses\n // FIRST USE: a non-whiteboard channel was tab-less until now — register its tab\n // SYNCHRONOUSLY (before the reveal/focus below) so the channel exists to be revealed.\n // The whiteboard already has its tab from session start; re-registering is idempotent.\n if (plugin.HasSurface()) {\n this.registerPluginChannelTab(plugin);\n }\n if (this.surfaceTabs) {\n // Stream handler (a tool call), not a change-detection pass — reveal synchronously\n // so the board is the visible tab the instant the agent's first stroke lands. The\n // microtask-deferred RegisterChannelTab above is ordered before this RevealChannel,\n // so the tab is in place when the focus lands.\n this.surfaceTabs.RevealChannel(plugin.ChannelName);\n } else {\n // Panel not rendered yet (the peek just created it) — reveal once it exists.\n this.pendingRevealKey = plugin.ChannelName;\n }\n // DetailsPeek flipped — surfacePanelEarned changed; re-resolve (marks for check).\n this.recomputeUi();\n }\n\n /**\n * The agent's video arrived: its channel's surface goes where its row places it (the stage is the agent's place in the\n * call) and gets its tab, where it can be moved from, without opening the panel: the video shows in the call itself.\n */\n private revealPresenter(plugin: BaseRealtimeChannelClient): void {\n if (plugin.HasSurface()) {\n this.registerPluginChannelTab(plugin);\n }\n this.recomputeUi();\n }\n\n /** Active$ edges: session start resets the volatile level; session end ratchets + persists. */\n private onActiveChanged(active: boolean): void {\n if (active && !this.prevActive) {\n this.Disclosure.BeginSession();\n this.DetailsPeek = false;\n this.ComposerOpen = false; // typing is opt-in per session (voice-first)\n this.revealedChannelKeys.clear();\n this.pendingRevealKey = null;\n this.startAudioVisualLoop();\n } else if (!active && this.prevActive) {\n this.persistDisclosure(this.Disclosure.RatchetOnSessionEnd());\n this.stopAudioVisualLoop();\n }\n this.prevActive = active;\n this.cdr.markForCheck();\n }\n\n // ── Audio-reactive visuals (the orb that vibrates like a speaker cone) ──────\n //\n // A requestAnimationFrame loop OUTSIDE Angular samples the client's audio meters\n // (RealtimeSessionService.GetAudioActivity → driver AnalyserNodes), runs the frame through\n // the smoothing state machine, and writes CSS custom properties + data attributes\n // straight onto the rendered overlay element — zero change detection per frame. CSS\n // gates on [data-audio-live]: with real metering the orb/EQ follow the waveform; when\n // the driver attached no meters the attribute stays 'false' and the turn-state-driven\n // keyframe animations keep working unchanged.\n\n /** Per-frame smoothing state (attack/decay envelopes + direction hysteresis). */\n private readonly audioSmoother = new RealtimeAudioVisualSmoother();\n private audioRafHandle: number | null = null;\n /** Last attribute values written (attributes are only touched on change). */\n private lastAudioLive: boolean | null = null;\n private lastDirection: RealtimeDirection | null = null;\n\n /** Starts the sampling loop (idempotent). Runs outside Angular — no CD per frame. */\n private startAudioVisualLoop(): void {\n if (this.audioRafHandle !== null || typeof requestAnimationFrame !== 'function') {\n return;\n }\n this.audioSmoother.Reset();\n this.ngZone.runOutsideAngular(() => {\n const tick = (): void => {\n this.audioRafHandle = requestAnimationFrame(tick);\n if (this.Hidden) {\n return; // minimized — skip the work, keep the loop armed\n }\n const frame = this.audioSmoother.Next(this.realtime.GetAudioActivity(), performance.now());\n this.applyAudioVisualFrame(frame);\n };\n this.audioRafHandle = requestAnimationFrame(tick);\n });\n }\n\n /** Stops the loop and returns the overlay to turn-state-driven animation. */\n private stopAudioVisualLoop(): void {\n if (this.audioRafHandle !== null) {\n cancelAnimationFrame(this.audioRafHandle);\n this.audioRafHandle = null;\n }\n this.audioSmoother.Reset();\n this.lastAudioLive = null;\n this.lastDirection = null;\n this.overlayElement()?.setAttribute('data-audio-live', 'false');\n }\n\n /** The rendered `.call-overlay` element (the :host is display:contents). */\n private overlayElement(): HTMLElement | null {\n const host = this.hostRef.nativeElement as HTMLElement;\n return (host.firstElementChild as HTMLElement | null) ?? null;\n }\n\n /** Writes one smoothed frame as CSS vars/attributes (attributes only on change). */\n private applyAudioVisualFrame(frame: RealtimeAudioVisualFrame | null): void {\n const el = this.overlayElement();\n if (!el) {\n return;\n }\n const live = frame !== null;\n if (live !== this.lastAudioLive) {\n this.lastAudioLive = live;\n el.setAttribute('data-audio-live', String(live));\n }\n if (!frame) {\n return;\n }\n el.style.setProperty('--voice-out', frame.OutputLevel.toFixed(3));\n el.style.setProperty('--voice-in', frame.InputLevel.toFixed(3));\n for (let i = 0; i < frame.Bins.length; i++) {\n el.style.setProperty(`--eq-${i + 1}`, frame.Bins[i].toFixed(3));\n }\n if (frame.Direction !== this.lastDirection) {\n this.lastDirection = frame.Direction;\n el.setAttribute('data-voice-dir', frame.Direction);\n }\n }\n\n /** The strip's Details control: peek at (or hide) the surface panel on demand. */\n public OnDetailsToggled(): void {\n this.DetailsPeek = !this.DetailsPeek;\n if (this.DetailsPeek) {\n // Land on the marquee surface (channels lead the strip; Activity is pinned last).\n setTimeout(() => this.surfaceTabs?.FocusFirstTab());\n }\n this.ControlInvoked.emit('surface');\n // DetailsPeek drives surfacePanelEarned — re-resolve (marks for check).\n this.recomputeUi();\n }\n\n /**\n * The gear popover picked an interface density — apply + persist + emit. `Simple` IS the\n * \"pure audio\" surface (the standalone headphones control was folded into the gear here): it\n * returns to the orb-only view AND makes it stick across refresh/next call, so picking it also\n * closes any open Details peek so the surface is genuinely orb-only — matching the old app-bar\n * \"Pure audio\" button exactly. In-session reveals (\"Show the conversation\", T-to-type, Details)\n * stay available and ephemeral; switching density back to Standard/Pro/Auto restores the console.\n */\n public OnDensityChanged(density: RealtimeUxDensity): void {\n this.Disclosure.SetDensity(density);\n this.persistDisclosure(SerializeUxMilestones(this.Disclosure.Milestones));\n if (density === 'simple') {\n this.DetailsPeek = false; // Simple = pure audio: collapse the surface peek back to the bare orb.\n }\n this.DensityChanged.emit(density);\n this.ControlInvoked.emit('density');\n // Density (and possibly DetailsPeek) changed — re-resolve (marks for check).\n this.recomputeUi();\n }\n\n /** The hero's \"Show the conversation\" affordance — turns the text preference on, and opens the thread even over the agent's video. */\n public OnTextReveal(): void {\n this.conversationShown = true;\n this.OnCaptionsToggled(true);\n this.TextRevealed.emit();\n this.ControlInvoked.emit('reveal-text');\n }\n\n /** App-bar Minimize: hide the call view (CSS) — the call stays fully live. */\n public OnMinimize(): void {\n this.realtime.SetMinimized(true);\n this.Minimized.emit();\n this.ControlInvoked.emit('minimize');\n }\n\n /** App-bar / strip End: tear the session down, then notify the host. */\n public async OnEndCall(): Promise<void> {\n this.ControlInvoked.emit('end');\n await this.realtime.EndRealtimeSession();\n this.Ended.emit();\n }\n\n /** Maps the realtime state onto the hero orb's `data-state` (active turn-states only). */\n public HeroOrbState(state: RealtimeConnectionState): RealtimeAgentOrbState {\n return AgentOrbStateFor(state);\n }\n\n /**\n * Why the call ended, when its client said so (a relayed call that reached its time limit): the label the banner and the\n * hero show in the `'error'` state in place of \"Connection error\"; `null` otherwise.\n */\n public get CallEndLabel(): string | null {\n return DescribeCallEnd(this.realtime.LastSessionError)?.Label ?? null;\n }\n\n /** Short first-person status line for the pure-audio hero. */\n public HeroStateLabel(state: RealtimeConnectionState): string {\n switch (state) {\n case 'speaking': return `${this.AgentName} is speaking…`;\n case 'thinking': return `${this.AgentName} is working…`;\n case 'listening': return 'Listening';\n case 'connecting': return 'Connecting…';\n case 'error': return this.CallEndLabel ?? 'Connection error';\n default: return 'On call';\n }\n }\n\n /**\n * TYPE-TO-COMPOSE: during a live call, pressing any single printable character (with nothing\n * focused) reveals the composer, raises disclosure to the engaged level, AND seeds that very\n * character into the draft — the user just starts typing and their first key is captured (the\n * old dedicated \"T\" key is gone; \"t\"/\"T\" now types like any other letter, and the visible\n * \"press T to type\" hint was removed in favour of this natural behaviour). Ignored while\n * review/minimized/inactive, with Ctrl/Cmd/Alt modifiers (don't hijack shortcuts), for\n * non-printable named keys (Enter/Tab/Arrow/Escape/F-keys → `key.length > 1`), for a bare\n * Space (ambiguous — no message starts with a space), or when an editable element / a\n * keyboard-capturing surface (the remote-browser canvas) already holds focus.\n */\n @HostListener('document:keydown', ['$event'])\n public OnDocumentKeydown(event: KeyboardEvent): void {\n if (this.Hidden || this.IsReviewing || !this.realtime.IsActive) {\n return;\n }\n if (event.metaKey || event.ctrlKey || event.altKey) {\n return;\n }\n if (event.key.length !== 1 || event.key === ' ') {\n return;\n }\n if (this.isEditableTarget(event.target) || this.isKeyboardCapturingSurfaceFocused()) {\n return;\n }\n event.preventDefault();\n const typedChar = event.key;\n this.OnComposerOpenChanged(true);\n // The dock may have just been created — seed the typed character + focus after this CD pass.\n setTimeout(() => this.composer?.AppendAndFocus(typedChar));\n }\n\n /**\n * True when the event target is a native text-editing element (an input, textarea, or contentEditable),\n * where a bare letter should type into that element — not trigger type-to-compose.\n *\n * @param eventTarget The keydown event's target.\n * @returns Whether the target is an editable element.\n */\n private isEditableTarget(eventTarget: EventTarget | null): boolean {\n const target = eventTarget as HTMLElement | null;\n return !!target && (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable);\n }\n\n /**\n * True when a surface that opts into capturing keyboard input currently holds focus — notably the Remote\n * Browser live canvas, which marks itself with `data-mj-capture-keys` while the user is driving it. When it\n * has focus, the overlay's global shortcuts (T-to-type) must stand down so the user's keystrokes land in the\n * remote browser, not the local composer. Decoupled by an attribute contract so the overlay needs no direct\n * reference to the surface component.\n *\n * @returns Whether a keyboard-capturing surface is focused.\n */\n private isKeyboardCapturingSurfaceFocused(): boolean {\n const active = (typeof document !== 'undefined' ? document.activeElement : null) as HTMLElement | null;\n return !!active && active.hasAttribute('data-mj-capture-keys');\n }\n\n /**\n * The composer dock opened (strip Type control / type-to-compose keystroke) or closed (the\n * dock's hide control). Opening raises the 'engaged' milestone for the cross-session ratchet —\n * but the dock itself stays a per-session, user-owned toggle either way.\n */\n public OnComposerOpenChanged(open: boolean): void {\n this.ComposerOpen = open;\n if (open) {\n this.Disclosure.Raise('engaged'); // emits Changed$ → recomputeUi()\n this.ControlInvoked.emit('type');\n setTimeout(() => this.composer?.FocusInput());\n }\n this.cdr.markForCheck();\n }\n\n ngOnDestroy(): void {\n this.stopAudioVisualLoop();\n this.stopResizeObserver();\n this.clearAvatarNoticeTimer();\n if (this.IsPanelResizing) {\n this.teardownPanelResize();\n this.IsPanelResizing = false;\n }\n for (const sub of this.subs) {\n sub.unsubscribe();\n }\n this.subs = [];\n this.State.Detach();\n }\n\n /**\n * Registers (or updates) an INTERACTIVE-CHANNEL tab on the surface panel. The overlay\n * calls it for every registry-resolved plugin; hosts may also call it for bespoke\n * template-based panes. Until a registration supplies a plugin / template, the tab\n * renders the \"coming online…\" placeholder (re-register the same `Key` to upgrade).\n * Safe to call before the panel has rendered — registrations are queued and flushed.\n */\n public RegisterChannelTab(registration: RealtimeChannelTabRegistration): void {\n if (this.surfaceTabs) {\n this.surfaceTabs.RegisterChannelTab(registration);\n } else {\n this.pendingChannelTabs.push(registration);\n }\n }\n\n /**\n * A done delegation card / rail entry asked to view a produced artifact's tab — an\n * EXPLICIT user request, so it may open the (otherwise Details-controlled) panel.\n */\n public OnOpenArtifactRequested(artifact: ParsedDelegationArtifact): void {\n if (this.surfaceTabs) {\n this.surfaceTabs.FocusArtifact(artifact);\n return;\n }\n // Panel hidden — open it (Details mechanism) and focus once it exists.\n this.DetailsPeek = true;\n this.cdr.markForCheck();\n setTimeout(() => this.surfaceTabs?.FocusArtifact(artifact));\n }\n\n /**\n * Registers a surface tab per active channel plugin THAT HAS A SURFACE — but ONLY for\n * channels already in play: the WHITEBOARD tabs immediately (a user may be the first to\n * draw), every OTHER channel stays tab-less until the agent first USES it (its first\n * {@link onChannelActivity}). This keeps the strip decluttered to surfaces actually in\n * play instead of pre-listing every registry-resolved channel.\n *\n * Server-only channels ({@link BaseRealtimeChannelClient.HasSurface} === `false`) render no\n * tab — their tools + perception are wired by the session service regardless.\n */\n private registerChannelTabs(channels: BaseRealtimeChannelClient[]): void {\n this.cleanupStaleReviewBoardTab(channels);\n for (const plugin of channels) {\n if (!plugin.HasSurface()) {\n continue; // server-only channel — no surface to tab.\n }\n if (!ShouldRegisterChannelTabUpFront(plugin.ChannelName, this.realtime.HasChannelBeenUsed(plugin.ChannelName))) {\n continue; // not the whiteboard and not used yet — it earns its tab on first activity.\n }\n this.registerPluginChannelTab(plugin);\n }\n this.cdr.markForCheck();\n }\n\n /**\n * The session's channel set changed: surfaces whose channel left are dropped (focus ends with a surface that leaves\n * the stage this way, while the user's move stays saved) and the channels in play get their tabs.\n */\n private onActiveChannelsChanged(channels: BaseRealtimeChannelClient[]): void {\n this.SurfaceStage.KeepOnly(channels);\n this.registerChannelTabs(channels);\n this.recomputeUi();\n }\n\n // ── Moving surfaces: \"Move to…\", saved per user ────────────────────────────\n\n /** The user moved a channel's surface (\"Move to…\", \"Bring it here\"). */\n public OnMoveRequested(move: MediaMoveRequest): void {\n this.moveSurface(move);\n }\n\n /** The user put every surface back where its channel places it (and every picture-in-picture box back in its corner). */\n public OnResetLayout(): void {\n this.SurfaceStage.ResetLayout();\n this.PipRects = new Map();\n this.layoutPrefs.SaveMoves(this.SurfaceStage.Moves);\n this.layoutPrefs.SavePipRects(this.PipRects);\n this.recomputeUi();\n }\n\n /** Where the user put each picture-in-picture box, by channel key, as fractions of the stage. */\n public PipRects: ReadonlyMap<string, MediaPipRect> = new Map();\n\n /** The user's saved layout of the call's surfaces, per user, under the call's own keys. */\n private readonly layoutPrefs = new MediaLayoutPrefs(() => UserInfoEngine.Instance, {\n Moves: SURFACE_PLACEMENT_PREF_KEY,\n PipRects: SURFACE_PIP_PREF_KEY,\n });\n\n /** The user moved or resized a picture-in-picture box: keep it and save it. */\n public OnPipRectChange(change: MediaStagePipRectChange): void {\n this.PipRects = RecordPipRect(this.PipRects, change.Key, change.Rect);\n this.layoutPrefs.SavePipRects(this.PipRects);\n }\n\n /** Moves a surface, saves the layout, and re-resolves the UI (a surface on the stage is the focus layout). */\n private moveSurface(move: MediaMoveRequest): void {\n if (!this.SurfaceStage.Move(move.Key, move.Placement)) {\n return;\n }\n this.layoutPrefs.SaveMoves(this.SurfaceStage.Moves);\n this.recomputeUi();\n }\n\n /**\n * Starts from the user's saved layout and picture-in-picture boxes. While `UserInfoEngine` is not configured (plain\n * node tests, early bootstrap), nothing is saved and every surface starts where its channel places it.\n */\n private loadPlacementPref(): void {\n this.SurfaceStage.LoadMoves(this.layoutPrefs.LoadMoves());\n this.PipRects = this.layoutPrefs.LoadPipRects();\n }\n\n /** Registers (or upgrades) one channel plugin's surface tab on the panel, and its surface on the stage. */\n private registerPluginChannelTab(plugin: BaseRealtimeChannelClient): void {\n this.SurfaceStage.Register(plugin);\n this.RegisterChannelTab({\n Key: plugin.ChannelName,\n Title: plugin.TabTitle,\n Icon: plugin.TabIcon,\n Color: plugin.TabColor,\n Plugin: plugin\n });\n }\n\n /**\n * REVIEW→LIVE continuation edge: when the resumed live session resolves its channel set\n * WITHOUT a Whiteboard channel, the review-registered read-only board tab is now a dead\n * surface — remove it (Activity regains focus if it was active). When the set HAS a\n * Whiteboard channel, the plugin registration above upgrades the same tab key in place,\n * so the review flag is simply released. Review ARTIFACT tabs are deliberately kept —\n * they are wanted carryover into the live session.\n */\n private cleanupStaleReviewBoardTab(channels: BaseRealtimeChannelClient[]): void {\n if (!this.reviewWhiteboardTabRegistered) {\n return;\n }\n if (ShouldRemoveReviewWhiteboardTab(this.realtime.IsActive, this.reviewWhiteboardTabRegistered, channels)) {\n this.surfaceTabs?.RemoveTab('Whiteboard');\n // Also drop a still-queued review registration (panel not rendered yet — rare but possible).\n this.pendingChannelTabs = this.pendingChannelTabs.filter(r => !(r.Key === 'Whiteboard' && r.Content));\n this.reviewWhiteboardTabRegistered = false;\n } else if (channels.some(c => c.ChannelName === 'Whiteboard')) {\n this.reviewWhiteboardTabRegistered = false; // live plugin owns the tab now (upgraded in place)\n }\n }\n\n /** Forwards channel registrations that arrived before the panel existed. */\n private flushPendingChannelTabs(): void {\n if (this.surfaceTabs && this.pendingChannelTabs.length > 0) {\n for (const reg of this.pendingChannelTabs) {\n this.surfaceTabs.RegisterChannelTab(reg);\n }\n this.pendingChannelTabs = [];\n }\n }\n\n /**\n * The captions toggle = the persisted text-vs-orb switch: on → the thread renders\n * (raising the text disclosure milestone); off → the orb hero owns the screen again,\n * at any level. Persisted per-user so the choice survives refresh and devices.\n */\n public OnCaptionsToggled(on: boolean): void {\n this.ShowCaptions = on;\n if (on) {\n this.Disclosure.Raise('text'); // emits Changed$ → recomputeUi()\n } else {\n this.conversationShown = false;\n }\n this.persistCaptionsPref();\n this.ControlInvoked.emit('captions');\n // ShowCaptions feeds the resolver's `textRevealed` signal (buildSignals), so BOTH directions must\n // re-resolve the view-model. Turning ON already recomputes via Disclosure.Raise → Changed$, but\n // turning OFF raises nothing — a bare markForCheck() would re-render against a STALE _ui (still\n // showThread=true / showHero=false), so the hero orb wouldn't return until the next unrelated\n // interaction recomputed. recomputeUi() rebuilds _ui from the current ShowCaptions and marks for\n // check itself; it's pure/idempotent, so the redundant call in the ON case is harmless.\n this.recomputeUi();\n }\n\n /** Reflect the gear toggle from the controls into the dev affordances. */\n public OnDevModeToggled(on: boolean): void {\n this.DevMode = on;\n this.ControlInvoked.emit('gear');\n // devMode drives the resolver's showDevLinks signal — re-resolve (marks for check).\n this.recomputeUi();\n }\n\n /** A dev link asked to open a delegated agent run record. */\n public OnOpenRunRequested(runId: string): void {\n this.requestNavigate('MJ: AI Agent Runs', runId);\n }\n\n /** The banner's dev link asked to open the live agent session record. */\n public OnOpenSessionRequested(sessionId: string): void {\n this.requestNavigate('MJ: AI Agent Sessions', sessionId);\n }\n\n // ── Session review mode ────────────────────────────────────────────────────\n\n /** Review banner convenience accessors (null-safe against the review data). */\n public get ReviewStartedAt(): Date | null {\n return this._reviewData?.StartedAt ?? null;\n }\n public get ReviewClosedAt(): Date | null {\n return this._reviewData?.ClosedAt ?? null;\n }\n public get ReviewCloseReason(): string | null {\n return this._reviewData?.CloseReason ?? null;\n }\n\n /** The reviewed session record's id — feeds the banner's dev \"Open session\" link. */\n public get ReviewSessionID(): string | null {\n return this._reviewData?.SessionID ?? null;\n }\n\n /**\n * Review controls: resume the reviewed session as a NEW live call (host handles the\n * start). Flags the upcoming ReviewData→null transition as a CONTINUATION so the\n * historical thread is kept (divider appended) instead of cleared.\n */\n public OnStartLive(): void {\n const review = this._reviewData;\n if (!review || !this.AllowStartLive) {\n return;\n }\n this.pendingLiveContinuation = true;\n this.StartLiveRequested.emit({\n TargetAgentId: review.TargetAgentID,\n ConversationId: review.ConversationID,\n LastSessionId: review.SessionID\n });\n }\n\n /** Review controls: close the review (host clears its review state). */\n public OnReviewClose(): void {\n this.ReviewClosed.emit();\n }\n\n /**\n * Enters review: replaces the shared state's thread with the historical items (all\n * chain legs, dividers between legs), names the cards after the reviewed agent,\n * rehydrates the saved whiteboard (when any), and registers the chain's history\n * ARTIFACTS as unfocused surface tabs.\n */\n private enterReview(review: RealtimeSessionReview): void {\n this.State.AgentName = review.AgentName;\n this.State.LoadHistoricalItems(BuildReviewThreadItems(review));\n this.ReviewWhiteboard = this.parseReviewWhiteboard(review);\n this.reviewArtifacts = review.Artifacts ?? [];\n this.ReviewCues = this.buildReviewCues(review);\n if (this.viewReady) {\n // Let this CD pass create/refresh the surface panel before registering the tabs.\n // ngZone.run is REQUIRED: review often opens through the deep-link/query-param\n // path (a plain RxJS stream outside Angular's zone) — without re-entering the\n // zone, the registration's markForCheck never gets a change-detection pass and\n // the Whiteboard tab stays invisible until the user's next click.\n setTimeout(() => this.ngZone.run(() => {\n this.registerReviewBoardTab();\n this.registerReviewArtifactTabs();\n this.registerReviewRecordingTab();\n }), 0);\n }\n // isReviewing flipped on — review always wants the console (marks for check).\n this.recomputeUi();\n }\n\n /**\n * Builds time-aligned {@link MediaTranscriptCue}s from the reviewed session's turns, for the\n * storage media player's transcript panel. Skips turns with no text; derives each cue's start from\n * `UtteranceStartMs`, falling back to (turn-created − recording-start) ms, else 0. Sorts by start.\n */\n private buildReviewCues(review: RealtimeSessionReview): MediaTranscriptCue[] {\n const startedAt = review.RecordingStartedAt;\n const cues: MediaTranscriptCue[] = [];\n (review.Turns ?? []).forEach((turn, index) => {\n const text = (turn.Text ?? turn.Message ?? '').trim();\n if (text.length === 0) {\n return;\n }\n cues.push({\n Id: turn.ID || `turn-${index}`,\n StartMs: this.reviewCueStartMs(turn, startedAt),\n EndMs: turn.UtteranceEndMs ?? undefined,\n SpeakerLabel: turn.Role === 'User' ? 'You' : review.AgentName,\n Text: text\n });\n });\n cues.sort((a, b) => a.StartMs - b.StartMs);\n return cues;\n }\n\n /** A review turn's media-relative start (ms): precise offset, else derived from t0, else 0. */\n private reviewCueStartMs(turn: RealtimeSessionReviewTurn, startedAt: Date | null): number {\n if (turn.UtteranceStartMs != null) {\n return turn.UtteranceStartMs;\n }\n if (startedAt && turn.__mj_CreatedAt) {\n return Math.max(0, turn.__mj_CreatedAt.getTime() - startedAt.getTime());\n }\n return 0;\n }\n\n /**\n * Leaves review. Two distinct exits:\n * - REVIEW→LIVE CONTINUATION ({@link OnStartLive} was clicked): KEEP the historical\n * thread and append the \"Resumed live session\" divider so the new live items read\n * as a new section of the same conversation. Artifact tabs are left in place — the\n * chain's artifacts carry into the live session.\n * - plain CLOSE: clear everything so the conversation view returns clean.\n */\n private exitReview(): void {\n this.ReviewWhiteboard = null;\n this.ReviewCues = [];\n if (this.reviewRecordingTabRegistered) {\n this.surfaceTabs?.RemoveTab('Recording');\n this.pendingChannelTabs = this.pendingChannelTabs.filter(r => r.Key !== 'Recording');\n this.reviewRecordingTabRegistered = false;\n }\n if (this.pendingLiveContinuation) {\n this.pendingLiveContinuation = false;\n this.State.StartLiveContinuation();\n } else {\n this.reviewArtifacts = [];\n this.State.Clear();\n }\n // isReviewing flipped off — re-resolve the chrome/gates (marks for check).\n this.recomputeUi();\n }\n\n /**\n * Surfaces the reviewed chain's history artifacts inside the Activity tab. In the redesign\n * there are no per-artifact tabs — the artifacts ride the {@link ReviewArtifacts} input into\n * the rail's \"Session artifacts\" group, so this only needs to ensure the Activity tab is\n * shown (it carries the carryover artifacts). Idempotent; no-op without any review artifacts.\n */\n private registerReviewArtifactTabs(): void {\n if (!this.surfaceTabs || this.reviewArtifacts.length === 0) {\n return;\n }\n // Show the Activity tab (where the carryover artifacts now live); RegisterArtifactTab\n // flips the gate on without opening any tab of its own.\n this.surfaceTabs.RegisterArtifactTab(this.reviewArtifacts[0], false);\n this.cdr.markForCheck();\n }\n\n /**\n * Rehydrates the reviewed session's saved Whiteboard channel state. TOLERANT: a missing\n * or malformed state returns null — review simply shows no whiteboard tab.\n */\n private parseReviewWhiteboard(review: RealtimeSessionReview): WhiteboardState | null {\n const channel = review.ChannelStates.find(c => c.ChannelName.toLowerCase() === 'whiteboard');\n if (!channel?.StateJson) {\n return null;\n }\n try {\n return WhiteboardState.FromJSON(channel.StateJson);\n } catch {\n console.warn('[RealtimeSessionReview] Saved whiteboard state was malformed — skipping the board tab.');\n return null;\n }\n }\n\n /**\n * Registers the read-only review whiteboard tab (no-op without a board / template) —\n * FOCUSED: the session's channel surface is what the reviewer came to see; the\n * Activity rail stays available but is never the default focus.\n */\n private registerReviewBoardTab(): void {\n if (!this.ReviewWhiteboard || !this.reviewBoardTpl) {\n return;\n }\n this.RegisterChannelTab({\n Key: 'Whiteboard',\n Title: 'Whiteboard',\n Icon: 'fa-solid fa-chalkboard',\n Content: this.reviewBoardTpl,\n Focus: true\n });\n this.reviewWhiteboardTabRegistered = true;\n this.cdr.markForCheck();\n }\n\n /**\n * Registers the read-only review RECORDING tab (the time-aligned storage media player) — ONLY when\n * the reviewed session carried a `RecordingFileID`. Idempotent (re-registering the same key updates\n * it in place). The player resolves the authenticated audio itself from the `RecordingFileID` and\n * shows its own no-access / loading states; the click-to-seek transcript is usable immediately.\n * NOT focused — the channel surface / Activity rail keeps the default focus.\n */\n private registerReviewRecordingTab(): void {\n if (!this._reviewData?.RecordingFileID || !this.recordingTpl) {\n return;\n }\n this.RegisterChannelTab({\n Key: 'Recording',\n Title: 'Recording',\n Icon: 'fa-solid fa-circle-play',\n Content: this.recordingTpl\n });\n this.reviewRecordingTabRegistered = true;\n this.cdr.markForCheck();\n }\n\n /**\n * A working delegation card's ✕ asked to cancel that delegated run — EXPLICIT user\n * intent (barge-in never cancels work, by deliberate policy). The service calls the\n * server cancel channel and flips the card to a failed \"Cancelled by user\" result.\n */\n public OnCancelDelegation(callId: string): void {\n void this.realtime.CancelDelegation(callId);\n }\n\n /** Minimizes the live call (it stays running) and asks the host to open the record. */\n private requestNavigate(entityName: string, recordId: string): void {\n this.realtime.SetMinimized(true);\n this.NavigateRequest.emit({ EntityName: entityName, RecordID: recordId });\n }\n\n // ── Focus layout + pill ────────────────────────────────────────────────────\n\n /**\n * A channel asked for the focus layout via its host context (the whiteboard's \"Move to stage\"): its surface moves to\n * the stage, or, when released, back where its channel places it.\n */\n private onChannelFocus(channel: BaseRealtimeChannelClient, focused: boolean): void {\n const key = channel.ChannelName;\n if (focused) {\n this.moveSurface({ Key: key, Placement: 'stage' });\n } else if (this.SurfaceStage.StageKey === key) {\n this.moveSurface({ Key: key, Placement: this.SurfaceStage.OffStagePlacement(key) });\n }\n }\n\n /** Focus pill: toggle the mic mute (routes through the overlay's single mute path). */\n public OnFocusPillMute(): void {\n this.ToggleMute();\n }\n\n /** Focus pill: leave focus mode: the surface on the stage goes back where its channel places it (show the thread column again). */\n public OnFocusPillExit(): void {\n const key = this.SurfaceStage.StageKey;\n // Route through the channel on the stage so ITS surface toggle stays in sync — it may\n // re-emit SetFocusMode(false) → onChannelFocus. Move it here too (idempotent), covering\n // channels that don't.\n this.StagePlugin?.RequestFocusExit();\n if (key) {\n this.moveSurface({ Key: key, Placement: this.SurfaceStage.OffStagePlacement(key) });\n }\n }\n\n /** Focus pill: end the call (mirrors the controls row's End button). */\n public async OnFocusPillEnd(): Promise<void> {\n await this.realtime.EndRealtimeSession();\n this.Ended.emit();\n }\n\n /** Short status line for the focus pill (first person — the co-agent owns the work). */\n public FocusStateLabel(state: RealtimeConnectionState): string {\n switch (state) {\n case 'speaking': return `${this.AgentName} is speaking…`;\n case 'thinking': return `${this.AgentName} is working…`;\n case 'listening': return 'Listening';\n case 'connecting': return 'Connecting…';\n default: return '';\n }\n }\n\n /**\n * The composer dock toggled the mic. Syncs the overlay's single {@link Muted} source (and\n * the focus pill) and surfaces the {@link MuteChanged} / {@link ControlInvoked} outputs.\n */\n public OnComposerMuteChanged(muted: boolean): void {\n if (muted !== this.Muted) {\n this.Muted = muted;\n this.FocusPillMuted = muted;\n this.cdr.markForCheck();\n }\n this.MuteChanged.emit(muted);\n this.ControlInvoked.emit('mute');\n }\n\n // ── Imperative API — drive the surface from a host via @ViewChild ────────────\n //\n // Each method maps to an existing internal handler/service so behaviour matches the\n // user clicking the corresponding control. See the package README's \"Methods\" table.\n\n /**\n * Override the chrome at runtime (equivalent to binding `[Chrome]`). Pass `'auto'` to\n * return to the size/intent-driven default.\n *\n * @param mode the chrome to force.\n * @example `voice.SetChrome('console');`\n */\n public SetChrome(mode: RealtimeChromeMode): void {\n this.setUiInput('chrome', mode);\n }\n\n /**\n * Reveal the transcript programmatically — the imperative twin of the orb's \"Show the\n * conversation\" affordance. Raises the text disclosure level, turns captions on, and\n * emits {@link TextRevealed}.\n */\n public RevealText(): void {\n this.OnTextReveal();\n }\n\n /**\n * Set the mic mute to an explicit state (no-op when already there). Drives the session\n * service, syncs every mute affordance, and emits {@link MuteChanged}.\n *\n * @param muted the desired muted state.\n */\n public SetMuted(muted: boolean): void {\n if (muted === this.Muted) {\n return;\n }\n this.ToggleMute();\n }\n\n /**\n * Toggle the mic mute. Drives the session service, syncs the overlay's {@link Muted}\n * source + the composer/focus-pill affordances, and emits {@link MuteChanged} +\n * {@link ControlInvoked}.\n */\n public ToggleMute(): void {\n this.Muted = this.realtime.ToggleMute();\n this.FocusPillMuted = this.Muted;\n this.MuteChanged.emit(this.Muted);\n this.ControlInvoked.emit('mute');\n this.cdr.markForCheck();\n }\n\n /**\n * Set captions (the text-vs-orb preference) to an explicit state. Persisted per-user;\n * turning them on also raises the text disclosure level.\n *\n * @param on whether captions/text should be shown.\n */\n public SetCaptions(on: boolean): void {\n if (on === this.ShowCaptions) {\n return;\n }\n this.OnCaptionsToggled(on);\n }\n\n /** Toggle captions (the text-vs-orb preference). */\n public ToggleCaptions(): void {\n this.OnCaptionsToggled(!this.ShowCaptions);\n }\n\n /**\n * Set the UX interface density (the gear's escape hatch). Applied + persisted immediately;\n * emits {@link DensityChanged}.\n *\n * @param density the density to apply.\n */\n public SetDensity(density: RealtimeUxDensity): void {\n this.OnDensityChanged(density);\n }\n\n /**\n * Open the surface panel (the on-demand Details peek), optionally focusing a specific\n * channel's tab. Equivalent to the strip's Details control plus a channel reveal.\n *\n * @param channelId when supplied, the channel tab to reveal once the panel is shown.\n */\n public OpenSurfacePanel(channelId?: string): void {\n if (!this.DetailsPeek) {\n this.DetailsPeek = true;\n this.ControlInvoked.emit('surface');\n this.recomputeUi();\n }\n setTimeout(() => {\n if (channelId) {\n this.surfaceTabs?.RevealChannel(channelId);\n } else {\n this.surfaceTabs?.FocusFirstTab();\n }\n });\n }\n\n /** Collapse the surface panel (hide the Details peek). No-op in review (always shown). */\n public CollapseSurfacePanel(): void {\n if (this.IsReviewing || !this.DetailsPeek) {\n return;\n }\n this.DetailsPeek = false;\n this.ControlInvoked.emit('surface');\n this.recomputeUi();\n }\n\n /** Minimize the call (it stays live) — the imperative twin of the app-bar Minimize. */\n public Minimize(): void {\n this.OnMinimize();\n }\n\n /** End the session (tear down the call) — the imperative twin of the End control. */\n public EndSession(): void {\n void this.OnEndCall();\n }\n}\n\n/** Whether a capture is on or on its way, as the composer's buttons show it. */\nfunction isCapturing(capture: RealtimeCaptureState): boolean {\n return capture.Status === 'on' || capture.Status === 'starting';\n}\n","@if (ConnectionState$ | async; as state) {\n <div class=\"call-overlay\"\n [class.call-overlay--hidden]=\"Hidden\"\n [class.call-overlay--review]=\"IsReviewing\"\n [class.board-focus]=\"ChannelFocusMode\"\n role=\"region\" [attr.aria-label]=\"IsReviewing ? 'Past session review' : 'Live voice session'\">\n\n <!-- PROGRESSIVE DISCLOSURE (the console that grows with you — Redesign A Progressive):\n level 0 is PURE AUDIO (the hero orb owns the main column; no thread, no composer;\n the strip's Details control peeks at the panels on demand); level 1 reveals the\n caption thread + captions control + type-to-type hint; level 2+ docks the composer\n and keeps the surface panel. CONTENT NEVER FLIPS THE CONSOLE OPEN: finished\n artifacts land as glowing unfocused tabs; the ONE auto-reveal is a channel's\n first agent activity (e.g. the first whiteboard write), which opens the panel as\n a peek with that tab focused — the left column stays exactly as it was.\n REVIEW always renders the full console. -->\n <div class=\"call-main\">\n <!-- The UNIFIED APP-BAR: identity + state + every session action (Redesign A). -->\n <mj-realtime-agent-banner\n [State]=\"state\"\n [Compact]=\"!IsReviewing && Ui.compact && Ui.chrome === 'orb'\"\n [AgentName]=\"AgentName\"\n [ErrorLabel]=\"CallEndLabel\"\n [ModelName]=\"IsReviewing ? null : (ModelName$ | async)\"\n [DevMode]=\"DevMode\"\n [SessionID]=\"IsReviewing ? ReviewSessionID : SessionID\"\n [ReviewMode]=\"IsReviewing\"\n [ReviewStartedAt]=\"ReviewStartedAt\"\n [ReviewClosedAt]=\"ReviewClosedAt\"\n [ReviewCloseReason]=\"ReviewCloseReason\"\n [ShowGear]=\"!IsReviewing && Ui.showGear\"\n [ShowDensityPicker]=\"Ui.showDensityPicker\"\n [ShowMinimize]=\"!IsReviewing && Ui.showMinimize\"\n [ShowStartLive]=\"AllowStartLive\"\n [Density]=\"Disclosure.Milestones.Density\"\n (OpenSessionRequested)=\"OnOpenSessionRequested($event)\"\n (DevModeToggled)=\"OnDevModeToggled($event)\"\n (DensityChanged)=\"OnDensityChanged($event)\"\n (MinimizeRequested)=\"OnMinimize()\"\n (StartLiveRequested)=\"OnStartLive()\"\n (CloseRequested)=\"OnReviewClose()\">\n </mj-realtime-agent-banner>\n\n <!-- No microphone works: the call lost its microphone, so the agent hears nothing until the user picks one in the\n device menu. It stays for as long as that lasts, with no dismiss button, and goes once a microphone is on.\n Never in review. -->\n @if (MicrophoneNotice; as message) {\n <mj-alert class=\"call-microphone-notice\"\n Variant=\"warning\"\n Size=\"sm\"\n Icon=\"fa-solid fa-microphone-slash\"\n [Message]=\"message\">\n </mj-alert>\n }\n\n <!-- Why the call shows no avatar its agent asked for: once per call, from the moment it connects, until the user\n dismisses it or it hides itself after 10 s. Never in review. -->\n @if (AvatarNotice) {\n <mj-alert class=\"call-avatar-notice\"\n Variant=\"info\"\n Size=\"sm\"\n Icon=\"fa-solid fa-video-slash\"\n [Message]=\"AvatarNoticeMessage\"\n Dismissible\n (Dismissed)=\"OnAvatarNoticeDismissed()\">\n </mj-alert>\n }\n\n <!-- Ephemeral narration with no active working card to anchor to → under the banner -->\n @if (!IsReviewing && State.Narration && !State.ActiveCallId && Disclosure.ShowThread) {\n <div class=\"banner-live-note\" role=\"status\" aria-live=\"polite\">\n <i class=\"fa-solid fa-comment-dots\" aria-hidden=\"true\"></i>\n {{ State.Narration }}\n </div>\n }\n\n <!-- The agent's place above the thread in the console: the agent's video (the Avatar) lies over it while it presents.\n Outside the scrolling body, so it stays in view as the conversation grows. -->\n @if (!ShowHero) {\n <div class=\"call-presenter\" [class.call-presenter--on]=\"PresenterOnStage\" #presenterSlot></div>\n }\n\n <!-- While the call connects, the connecting screen takes the body, except from a hero the agent's video presents in:\n a resume on a new connection keeps that hero, so the video keeps its place and its last frame. -->\n <div class=\"call-body\" [class.call-body--hero]=\"ShowHero && !ShowConnectingScreen(state)\">\n @if (ShowConnectingScreen(state)) {\n <div class=\"call-connecting\">\n <mj-loading text=\"Connecting to the live session…\" size=\"medium\"></mj-loading>\n </div>\n } @else if (ShowHero) {\n <!-- PURE-AUDIO HERO (level 0): the orb IS the interface — it breathes with the\n audio inside expanding sound-wave rings; nothing to read, nothing to configure. -->\n <div class=\"hero\" [class.hero--presenting]=\"PresenterOnStage\" [attr.data-state]=\"state\" role=\"status\" aria-live=\"polite\">\n @if (!PresenterOnStage) {\n <mj-realtime-agent-orb class=\"hero__orb\" [State]=\"HeroOrbState(state)\"></mj-realtime-agent-orb>\n <div class=\"hero__eq\" aria-hidden=\"true\">\n <span></span><span></span><span></span><span></span><span></span>\n <span></span><span></span><span></span><span></span>\n </div>\n }\n <!-- The agent's place in the hero: the agent's video (the Avatar) lies over it while it presents. With\n captions on, the newest caption runs over the video's lower third, as subtitles do. Hidden from\n assistive technology: the conversation, a click away, is the accessible transcript, and this live\n region would read every word as it arrives. -->\n <div class=\"hero__presenter\" [class.hero__presenter--on]=\"PresenterOnStage\" #presenterSlot>\n @if (ShowAvatarCaptions && AvatarCaption; as caption) {\n <p class=\"hero__caption\" aria-hidden=\"true\">\n <span class=\"hero__caption-window\">\n <span class=\"hero__caption-lines\">\n @if (caption.Speaker) {\n <span class=\"hero__caption-speaker\">{{ caption.Speaker }}:</span>\n }\n {{ caption.Text }}\n </span>\n </span>\n </p>\n }\n </div>\n @if (!PresenterOnStage) {\n <div class=\"hero__name\">{{ AgentName }}</div>\n <div class=\"hero__sub\">{{ HeroStateLabel(state) }}</div>\n } @else {\n <!-- The agent's tile names it and says what it is doing; this live region still says it for screen readers. -->\n <span class=\"hero__sr\">{{ HeroStateLabel(state) }}</span>\n }\n <button type=\"button\" class=\"hero__reveal\" (click)=\"OnTextReveal()\"\n title=\"Show the conversation as text\">\n <i class=\"fa-solid fa-closed-captioning\" aria-hidden=\"true\"></i>\n Show the conversation\n </button>\n </div>\n } @else {\n <mj-realtime-session-thread\n [State]=\"State\"\n [AgentName]=\"AgentName\"\n [UserName]=\"CurrentUser?.Name || 'You'\"\n [ShowCaptions]=\"IsReviewing ? true : ShowCaptions\"\n [DevMode]=\"DevMode\"\n (OpenRunRequested)=\"OnOpenRunRequested($event)\"\n (OpenArtifactRequested)=\"OnOpenArtifactRequested($event)\"\n (CancelRequested)=\"OnCancelDelegation($event)\">\n </mj-realtime-session-thread>\n }\n </div>\n\n <!-- The call's controls along the foot of the column. The stage starts its picture-in-picture boxes clear of\n them, so a camera or a shared screen never opens over End call (#5408). Empty, so with no size, in review. -->\n <div class=\"call-controls\" #callControls>\n @if (!IsReviewing) {\n <!-- \"Agent can see\": what the agent is looking at, with a switch per source. Always shown while any\n video source exists (a privacy indicator is never gated behind the disclosure ladder). -->\n <mj-realtime-perception-chip [Sources]=\"VideoSources\"\n (SourceToggled)=\"OnVideoSourceToggled($event)\"\n (SourcePicked)=\"OnVideoSourcePicked($event)\">\n </mj-realtime-perception-chip>\n\n <!-- Active channels (earned with the console at level 2+, host-gated via [ShowChannels]).\n The strip component self-hides when there are no active channels. -->\n @if (ChannelStripVisible) {\n <mj-realtime-channel-strip></mj-realtime-channel-strip>\n }\n\n <!-- The BOTTOM DOCK: phone-call strip ⇄ fused minis+composer — the user's own\n two-way toggle (Type opens, hide closes), never level-forced. -->\n <mj-realtime-composer\n [Open]=\"ComposerOpen\"\n [Compact]=\"Ui.compact && Ui.chrome === 'orb'\"\n (OpenChanged)=\"OnComposerOpenChanged($event)\"\n [CaptionsOn]=\"ShowCaptions\"\n [IsMuted]=\"Muted\"\n [ShowCamera]=\"CaptureOffers.Camera\"\n [ShowShare]=\"CaptureOffers.Screen\"\n [CameraOn]=\"CameraOn\"\n [Sharing]=\"Sharing\"\n [SharePanels]=\"SharePanels\"\n [Devices]=\"CallDevices\"\n [SelectedMicrophoneID]=\"SelectedMicrophoneID\"\n [SelectedCameraID]=\"SelectedCameraID\"\n (CameraToggled)=\"OnCameraToggled($event)\"\n (ShareRequested)=\"OnShareRequested($event)\"\n (StopShareRequested)=\"OnStopShareRequested()\"\n (DeviceSelected)=\"OnDeviceSelected($event)\"\n [ShowDetails]=\"ShowDetailsControl\"\n [DetailsOn]=\"DetailsPeek\"\n (CaptionsToggled)=\"OnCaptionsToggled($event)\"\n (DetailsToggled)=\"OnDetailsToggled()\"\n (MuteChanged)=\"OnComposerMuteChanged($event)\"\n (EndRequested)=\"OnEndCall()\">\n </mj-realtime-composer>\n }\n </div>\n </div>\n\n <!-- RIGHT: TABBED SURFACE PANEL — disclosure-gated: it EXISTS once earned (level 2+,\n which the first delegation forces), peeked on demand via the strip's Details\n control, or always in review. Slides in from the right when it arrives — the\n panel's arrival IS the progress cue. -->\n @if (ShowPanelArea) {\n <!-- Resize handle (hidden while the panel is collapsed or a channel holds focus). -->\n @if (!PanelResizeDisabled) {\n <div class=\"call-resizer\"\n [class.call-resizer--active]=\"IsPanelResizing\"\n role=\"separator\" aria-orientation=\"vertical\"\n aria-label=\"Resize the surface panel (double-click to reset)\"\n title=\"Drag to resize • double-click to reset\"\n (mousedown)=\"OnPanelResizeStart($event)\"\n (dblclick)=\"OnPanelResizeReset()\"></div>\n }\n\n <div class=\"call-panel\" [style.width.px]=\"PanelAreaSize\">\n <mj-realtime-surface-tabs\n [State]=\"State\"\n [DevMode]=\"DevMode\"\n [CurrentUser]=\"CurrentUser\"\n [EnvironmentID]=\"EnvironmentID\"\n [ShowActivityTab]=\"ShowActivityTab\"\n [ExtraArtifacts]=\"ReviewArtifacts\"\n (OpenRunRequested)=\"OnOpenRunRequested($event)\"\n [Collapsed]=\"PanelCollapsed\"\n (CollapsedChange)=\"OnPanelCollapsedChange($event)\"\n (WideChanged)=\"OnPanelWideChanged($event)\"\n (ActiveChannelChange)=\"OnActiveChannelChange($event)\"\n (ChannelSlotChange)=\"OnChannelSlotChange($event)\"\n [SurfacePlacements]=\"SurfaceStage.Placements\"\n [AllowedPlacements]=\"SurfaceStage.AllowedPlacements\"\n (MoveRequested)=\"OnMoveRequested($event)\"\n (ResetLayoutRequested)=\"OnResetLayout()\">\n </mj-realtime-surface-tabs>\n </div>\n }\n\n <!-- THE STAGE: every channel surface lives here, in one layer over the overlay. A surface\n is created the first time it is seen, lies over its tab's slot while that tab is\n active, fills the overlay while its channel holds focus (or, for the agent's video,\n lies in the agent's place in the call), and otherwise waits out of sight — so\n collapsing the panel, switching tabs or entering focus never reloads it.\n The pane tells each channel when its surface goes out of sight, so it can pause.\n A channel that opts in (SurfaceShareable, such as the whiteboard) marks its frame as a panel the Share menu\n offers under \"This panel\" while it is on screen. A picture-in-picture box the user has not moved starts\n clear of the call's controls. -->\n <mj-media-stage class=\"call-stage\"\n [Surfaces]=\"SurfaceStage.Surfaces\"\n [TabSlot]=\"StageSlot?.Element ?? null\"\n [StageSlot]=\"StageSurfaceSlot\"\n [ActiveTabKey]=\"StageSlot?.Key ?? null\"\n [PipRects]=\"PipRects\"\n [PipKeepClear]=\"callControls\"\n (PipRectChange)=\"OnPipRectChange($event)\">\n <ng-template mjMediaStageSurface let-key let-visible=\"Visible\" let-placement=\"Placement\">\n @if (SurfaceStage.PluginFor(key); as plugin) {\n <div class=\"stage-frame\" role=\"region\" [attr.aria-label]=\"plugin.TabTitle\"\n [mjSharePanel]=\"plugin.SurfaceShareable ? plugin.TabTitle : null\" [mjSharePanelIcon]=\"plugin.TabIcon\">\n <mj-realtime-channel-pane [Plugin]=\"plugin\" [Visible]=\"visible\" [Placement]=\"placement\"></mj-realtime-channel-pane>\n <!-- A surface presenting the agent has no focus pill, so its \"Move to…\" menu rides on it. -->\n @if (placement === 'stage' && plugin.ShowsAgentVideo) {\n <mj-media-move-menu\n class=\"stage-presenter-move\"\n [Key]=\"key\"\n [Title]=\"plugin.TabTitle\"\n Placement=\"stage\"\n [Allowed]=\"SurfaceStage.AllowedFor(key)\"\n (MoveRequested)=\"OnMoveRequested($event)\"\n (ResetLayoutRequested)=\"OnResetLayout()\">\n </mj-media-move-menu>\n }\n </div>\n }\n </ng-template>\n <!-- A picture-in-picture box's bar carries the same \"Move to…\" menu. -->\n <ng-template mjMediaStagePipActions let-key>\n @if (SurfaceStage.PluginFor(key); as plugin) {\n <mj-media-move-menu\n [Key]=\"key\"\n [Title]=\"plugin.TabTitle\"\n Placement=\"pip\"\n [Allowed]=\"SurfaceStage.AllowedFor(key)\"\n (MoveRequested)=\"OnMoveRequested($event)\"\n (ResetLayoutRequested)=\"OnResetLayout()\">\n </mj-media-move-menu>\n }\n </ng-template>\n </mj-media-stage>\n\n <!-- FOCUS floating call pill: the main column is hidden, so the live call's\n identity + state + mute / show-thread / end controls ride over the surface. -->\n @if (!IsReviewing && ChannelFocusMode) {\n <div class=\"board-focus-pill\" role=\"status\" aria-label=\"Live call (board focus)\">\n <span class=\"board-focus-pill__orb\" [attr.data-state]=\"state\" aria-hidden=\"true\"></span>\n <span class=\"board-focus-pill__text\">\n <span class=\"board-focus-pill__name\">Voice for {{ AgentName }}</span>\n @if (FocusStateLabel(state); as label) {\n <span class=\"board-focus-pill__state\">{{ label }}</span>\n }\n </span>\n <button type=\"button\" class=\"board-focus-pill__btn\"\n [class.board-focus-pill__btn--active]=\"FocusPillMuted\"\n (click)=\"OnFocusPillMute()\"\n [title]=\"FocusPillMuted ? 'Unmute' : 'Mute'\"\n [attr.aria-label]=\"FocusPillMuted ? 'Unmute microphone' : 'Mute microphone'\">\n <i class=\"fa-solid\" [class.fa-microphone]=\"!FocusPillMuted\" [class.fa-microphone-slash]=\"FocusPillMuted\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" class=\"board-focus-pill__btn\"\n (click)=\"OnFocusPillExit()\"\n title=\"Show thread\" aria-label=\"Show the conversation thread\">\n <i class=\"fa-solid fa-table-columns\" aria-hidden=\"true\"></i>\n </button>\n @if (StagePlugin; as stagePlugin) {\n <mj-media-move-menu\n [Key]=\"stagePlugin.ChannelName\"\n [Title]=\"stagePlugin.TabTitle\"\n Placement=\"stage\"\n [Allowed]=\"SurfaceStage.AllowedFor(stagePlugin.ChannelName)\"\n (MoveRequested)=\"OnMoveRequested($event)\"\n (ResetLayoutRequested)=\"OnResetLayout()\">\n </mj-media-move-menu>\n }\n <button type=\"button\" class=\"board-focus-pill__btn board-focus-pill__btn--end\"\n (click)=\"OnFocusPillEnd()\"\n title=\"End call\" aria-label=\"End the call\">\n <i class=\"fa-solid fa-phone-slash\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n\n <!-- THE CAMERA CHECK: the first time the user turns the camera on in a call, they see it, and can pick another\n camera, before the agent does. Until they choose, the camera's own box says it is waiting. -->\n @if (CameraCheck; as camera) {\n <mj-realtime-camera-check-card\n [Camera]=\"camera\"\n [AgentName]=\"AgentName\"\n [Switch]=\"SwitchCheckedCamera\"\n (Confirmed)=\"OnCameraCheckConfirmed()\"\n (Declined)=\"OnCameraCheckDeclined()\">\n </mj-realtime-camera-check-card>\n }\n\n </div>\n}\n\n<!-- SESSION REVIEW whiteboard pane body: the reviewed session's saved board, rehydrated\n locally (WhiteboardState.FromJSON) and rendered READ-ONLY (pan/zoom only). Registered\n as a template-based channel tab ONLY when a parseable Whiteboard state exists. -->\n<ng-template #reviewBoardTpl>\n @if (ReviewWhiteboard; as board) {\n <!-- The board host positions itself absolutely — give it a filling, positioned frame. -->\n <div class=\"review-board-host\">\n <mj-realtime-whiteboard\n [State]=\"board\"\n [AgentName]=\"AgentName\"\n [ReadOnly]=\"true\">\n </mj-realtime-whiteboard>\n </div>\n }\n</ng-template>\n\n<!-- SESSION REVIEW recording pane body: the reviewed session's recorded audio synced to its\n transcript, replayed via the shared storage media player (click-to-seek transcript + playhead\n highlight). Registered as a template-based channel tab ONLY when the reviewed session carries a\n RecordingFileID; the player resolves the authenticated audio itself from that file id. -->\n<ng-template #recordingTpl>\n <div class=\"review-recording-host\">\n <mj-storage-media-player\n [FileID]=\"ReviewRecordingFileID\"\n [Transcript]=\"ReviewCues\"\n [Provider]=\"Provider\">\n </mj-storage-media-player>\n </div>\n</ng-template>\n"]}
|
|
1
|
+
{"version":3,"file":"realtime-session-overlay.component.js","sourceRoot":"","sources":["../../../../src/lib/components/realtime/realtime-session-overlay.component.ts","../../../../src/lib/components/realtime/realtime-session-overlay.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, ElementRef, EventEmitter, HostListener, Input, Output, OnDestroy, AfterViewInit, AfterViewChecked, ChangeDetectorRef, NgZone, TemplateRef, ViewChild, inject } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { Subscription } from 'rxjs';\nimport type { VideoSourceState } from '@memberjunction/ai-realtime-client';\nimport { UserInfo } from '@memberjunction/core';\nimport { UserInfoEngine } from '@memberjunction/core-entities';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { SharedGenericModule } from '@memberjunction/ng-shared-generic';\nimport { MJStorageMediaPlayerComponent, MediaTranscriptCue } from '@memberjunction/ng-media-player';\nimport {\n DescribeCallEnd,\n REALTIME_CAPTURES_OFF,\n REALTIME_CAPTURE_OFFERS_NONE,\n REALTIME_MICROPHONE_NONE,\n type RealtimeAvatarNotice,\n type RealtimeCaptureOffers,\n type RealtimeCaptureState,\n type RealtimeCaptureStates,\n type RealtimeConnectionState,\n type RealtimeMicrophoneState,\n} from '@memberjunction/realtime-runtime';\nimport { MJAlertComponent } from '@memberjunction/ng-ui-components';\nimport { RealtimeSessionService } from '../../services/realtime-session.service';\nimport { ParsedDelegationArtifact } from '@memberjunction/realtime-runtime';\nimport { BuildReviewThreadItems, RealtimeSessionReview, RealtimeSessionReviewTurn } from '../../services/realtime-session-review.service';\nimport { RealtimeSessionState } from './realtime-session-state';\nimport { RealtimeAgentBannerComponent } from './realtime-agent-banner.component';\nimport { RealtimeSessionThreadComponent } from './realtime-session-thread.component';\nimport { RealtimeChannelStripComponent } from './realtime-channel-strip.component';\nimport { RealtimePerceptionChipComponent, RealtimePerceptionToggle } from './realtime-perception-chip.component';\nimport { RealtimeComposerComponent } from './realtime-composer.component';\nimport { RealtimeSurfaceTabsComponent, RealtimeChannelSlot } from './realtime-surface-tabs.component';\nimport { RealtimeSurfaceStageModel } from './realtime-surface-stage.model';\nimport { AgentOrbStateFor, RealtimeAgentOrbComponent, type RealtimeAgentOrbState } from './realtime-agent-orb.component';\nimport { RealtimeCameraCheckCardComponent } from './capture/realtime-camera-check-card.component';\nimport { SURFACE_PIP_PREF_KEY, SURFACE_PLACEMENT_PREF_KEY } from './realtime-surface-placement-prefs';\nimport { RealtimeChannelPaneComponent } from './channels/realtime-channel-pane.component';\nimport {\n ClampSurfacePanelWidth, DefaultSurfacePanelWidth, IsSurfacePanelDrag, ParseSurfacePanelPref,\n SerializeSurfacePanelPref, SurfacePanelDragWidth,\n SURFACE_PANEL_COLLAPSED_WIDTH, SURFACE_PANEL_DEFAULT_WIDTH, SURFACE_PANEL_PREF_KEY\n} from './realtime-surface-panel-prefs';\nimport { RealtimeDisclosureModel, RealtimeUxDensity, SerializeUxMilestones, REALTIME_UX_PREF_KEY } from './realtime-disclosure';\nimport {\n ResolveRealtimeUi, DEFAULT_REALTIME_UI_INPUTS, DEFAULT_REALTIME_UI_SIGNALS,\n RealtimeUiInputs, RealtimeUiSignals, ResolvedRealtimeUi,\n RealtimeChromeMode, RealtimeControlId, RealtimeUiConnectionState\n} from './realtime-ui-config';\nimport { RealtimeAudioVisualFrame, RealtimeAudioVisualSmoother, RealtimeDirection } from './realtime-audio-visuals';\nimport { RealtimeChannelTabRegistration, ShouldRemoveReviewWhiteboardTab } from './realtime-surface-tabs.model';\nimport { ShouldRegisterChannelTabUpFront } from './realtime-surface-tab-style';\nimport { BaseRealtimeChannelClient } from '@memberjunction/realtime-runtime';\nimport { RealtimeWhiteboardBoardComponent, WhiteboardState } from '@memberjunction/ng-whiteboard';\nimport {\n AvatarNoticeText, MediaMoveMenuComponent, MediaStageComponent, MediaStagePipActionsDirective, MediaStageSurfaceDirective,\n SharePanelDirective, SharePanelRegistry,\n type AvatarNoticeOverrides, type MediaMoveRequest, type MediaSharePanel, type MediaShareRequest, type MediaStagePipRectChange\n} from '@memberjunction/ng-realtime-media';\nimport { MediaLayoutPrefs, RecordPipRect, type MediaDevice, type MediaDeviceSelection, type MediaPipRect } from '@memberjunction/ai-realtime-client/media';\n\n/** How long the call's avatar notice stays before it hides itself (N5: it also has a dismiss button). */\nconst AVATAR_NOTICE_VISIBLE_MS = 10_000;\n\n/**\n * What the call says while no microphone works, by why: a microphone the browser blocked must be allowed before a pick\n * can open it. `{Agent}` stands for the agent's name. The arrow is the device chevron on the microphone button.\n */\nconst MICROPHONE_NOTICE_TEXT = {\n Blocked: \"{Agent} can't hear you: the browser blocked the microphone. Allow it for this site, then choose it from the arrow next to the microphone button.\",\n Lost: \"{Agent} can't hear you: no microphone is working. Connect one, or choose one from the arrow next to the microphone button.\",\n} as const;\n\n/**\n * A request to open an entity record, emitted by the call overlay's gear-gated developer\n * links (\"Open run\" / \"Open session\"). The Generic host (chat area) converts it onto its\n * existing `openEntityRecord` output chain — the package never navigates itself (no Router).\n */\nexport interface RealtimeNavigateRequest {\n /** Entity to open (e.g. `MJ: AI Agent Runs`, `MJ: AI Agent Sessions`). */\n EntityName: string;\n /** ID of the record to open. */\n RecordID: string;\n}\n\n/**\n * A request to RESUME a reviewed session as a NEW live call, emitted by review mode's\n * \"Start live session\" button. The host (chat area) clears its review state and starts a\n * voice session through the same path the composer's mic uses, passing\n * {@link LastSessionId} so the server chains the new session to the reviewed one\n * (restoring saved channel states such as the whiteboard via `PriorChannelStatesJson`).\n */\nexport interface RealtimeStartLiveRequest {\n /** Agent the resumed session should front (review Config `targetAgentID`, else the session's `AgentID`). */\n TargetAgentId: string;\n /** Conversation the reviewed session was bound to, when any. */\n ConversationId: string | null;\n /** The reviewed session's id — chained as the new session's `lastSessionId`. */\n LastSessionId: string;\n}\n\n/** A caption as it runs over the agent's video: who said it (`null` for the agent, whose video it is) and what. */\nexport interface RealtimeAvatarCaption {\n Speaker: string | null;\n Text: string;\n}\n\n\n/**\n * The \"call mode\" overlay for a live real-time voice session. Hosted by the\n * conversation chat area (`<mj-conversation-chat-area>`) behind `Active$`, it fills the\n * conversation panel IN PLACE (`position:absolute; inset:0` over the panel — not a\n * fixed app-wide dialog), replacing the conversation view including the composer.\n *\n * Two-column layout:\n * - MAIN column — {@link RealtimeAgentBannerComponent} (the unified APP-BAR: identity +\n * turn-state + the disclosure-gated action cluster), the unified\n * {@link RealtimeSessionThreadComponent} (or the level-0 pure-audio hero), the channel\n * strip, and {@link RealtimeComposerComponent} (the bottom dock: phone-call strip ⇄\n * fused minis+composer).\n * - RIGHT PANEL — {@link RealtimeSurfaceTabsComponent}: the TABBED surface panel.\n * Tab 1 \"Activity\" hosts the session activity rail; one tab opens per ARTIFACT a\n * delegated run produces (auto-focused + flashed on arrival, viewed read-only via the\n * standard artifact viewer); ONE TAB PER INTERACTIVE CHANNEL the session resolved from\n * the `MJ: AI Agent Channels` registry. Collapsible to a slim strip at the panel level.\n *\n * INTERACTIVE CHANNELS ARE PLUGINS — this shell is channel-agnostic. It subscribes\n * {@link RealtimeSessionService.ActiveChannels$} and registers one surface tab per\n * {@link BaseRealtimeChannelClient} (key/title/icon from the plugin). Every plugin's surface\n * lives on ONE STAGE (`mj-media-stage`) over the whole overlay: created the first time it is\n * seen, laid over its tab's pane while that tab is active, and kept until its channel leaves\n * (see {@link RealtimeSurfaceStageModel}). The PLUGIN wires its own inputs/outputs.\n * Each surface starts where its channel's registry row places it (its tab unless the row says\n * otherwise). The user moves it with \"Move to…\" (beside its tab, in the call pill, or on a\n * picture-in-picture box): to the STAGE, a picture-in-picture box, its tab, or out of sight,\n * as far as its channel allows. The moves are saved per user and carry over to later\n * sessions. A surface on the stage is the FOCUS layout: the main call column collapses\n * (`.board-focus`), the surface fills the overlay and the floating call pill appears. A channel\n * may ask for it too (via its context's `SetFocusMode` → {@link RealtimeSessionService.ChannelFocus$}),\n * which moves its surface to the stage or back.\n *\n * Owns the shared {@link RealtimeSessionState} — the SINGLE merge of the service's\n * caption/delegation/narration streams — and passes it to both thread and rail via\n * inputs, so neither duplicates subscription logic.\n *\n * DEVELOPER MODE: the controls row's gear toggles {@link DevMode} (per-session, off by\n * default, never persisted), revealing \"Open run\" links on delegation cards / rail items\n * and an \"Open session\" link in the banner. Clicking one emits {@link NavigateRequest}\n * and MINIMIZES the call (via {@link RealtimeSessionService.SetMinimized}) — the session\n * stays live while the host navigates to the record.\n *\n * SESSION REVIEW MODE: when the host supplies {@link ReviewData} (a loaded\n * `RealtimeSessionReview`) and NO live session is active, the overlay renders what went\n * down in that PAST session instead of a live call: the banner shows a \"Session review\"\n * badge + lifecycle range + close-reason chip; the SAME thread/rail components render the\n * historical caption turns and delegated-run cards (via\n * {@link RealtimeSessionState.LoadHistoricalItems}); a read-only Whiteboard tab is\n * registered ONLY when the session saved a parseable Whiteboard channel state. Everything\n * live is DEAD in review — no mic, no captions stream, no composer, no channel strip; the\n * controls collapse to a single \"Start live session\" button ({@link StartLiveRequested},\n * which resumes by chaining `lastSessionId`) and a Close button ({@link ReviewClosed}).\n */\n@Component({\n standalone: true,\n selector: 'mj-realtime-session-overlay',\n imports: [\n CommonModule,\n SharedGenericModule,\n RealtimeAgentBannerComponent,\n RealtimeAgentOrbComponent,\n RealtimeCameraCheckCardComponent,\n RealtimeSessionThreadComponent,\n RealtimeChannelStripComponent,\n RealtimePerceptionChipComponent,\n RealtimeComposerComponent,\n RealtimeSurfaceTabsComponent,\n RealtimeChannelPaneComponent,\n MediaMoveMenuComponent,\n MediaStageComponent,\n MediaStageSurfaceDirective,\n MediaStagePipActionsDirective,\n SharePanelDirective,\n RealtimeWhiteboardBoardComponent,\n MJStorageMediaPlayerComponent,\n MJAlertComponent\n ],\n templateUrl: './realtime-session-overlay.component.html',\n styleUrl: './realtime-session-overlay.component.css'\n})\nexport class RealtimeSessionOverlayComponent extends BaseAngularComponent implements AfterViewInit, AfterViewChecked, OnDestroy {\n private _agentName = 'Sage';\n\n /**\n * True while the call is MINIMIZED: the overlay hides itself (CSS, not destruction) so\n * the host can show its floating \"on call\" pill WITHOUT losing this shell's merged\n * session state (delegation cards ride non-replaying streams) or view state (dev mode,\n * expanded chips, scroll position). The host binds this from `Minimized$`.\n */\n @Input() Hidden = false;\n\n /** Display name of the agent the voice session fronts (e.g. \"Sage\"). */\n @Input()\n set AgentName(value: string) {\n this._agentName = value || 'Sage';\n this.State.AgentName = this._agentName;\n }\n get AgentName(): string {\n return this._agentName;\n }\n\n /** The signed-in user, threaded to the surface panel's artifact viewer. */\n @Input() CurrentUser: UserInfo | null = null;\n\n /** The active environment id, threaded to the surface panel's artifact viewer. */\n @Input() EnvironmentID = '';\n\n /**\n * The host's own words for why the call shows no avatar, per reason (for example its product's name for \"this app\").\n * A reason it leaves out keeps the stock line from `ng-realtime-media` (`AVATAR_NOTICE_TEXT`). `unknown` words a reason\n * this version doesn't know, such as a newer server's, in place of `AVATAR_NOTICE_CALL_UNKNOWN_REASON_TEXT`.\n */\n @Input() AvatarNoticeLabels: AvatarNoticeOverrides | null = null;\n\n /**\n * Whether the top \"Audio only: this voice model can't show an avatar\" notice banner is shown when\n * an audio-only call connects. Default `false` so standard voice sessions stay calm and uncluttered\n * unless a host explicitly opts into showing avatar capability notices.\n */\n @Input() ShowAvatarNotice = false;\n\n /**\n * Whether the bottom \"Agent can see\" perception chip is always shown even when only background channel\n * bridges exist. Default `false`: the chip is only shown when the user actively captures their camera or\n * screen ({@link CameraOn} / {@link Sharing}), or when explicitly enabled via `[ShowPerceptionChip]=\"true\"`.\n */\n @Input() ShowPerceptionChip = false;\n\n // ── Declarative UI configuration (host controls every aspect of the surface) ──\n //\n // Each input is a thin, PascalCase setter over a private slot in {@link _uiInputs}.\n // When a host binds it, that field wins over the {@link UiConfig} bag (individual\n // input precedence). Setting any of these recomputes the resolved view-model so the\n // change takes effect on the next CD pass. Every field is optional and defaults to\n // the historical behaviour via {@link DEFAULT_REALTIME_UI_INPUTS}, so existing call\n // sites that bind none of them behave exactly as before.\n //\n // See {@link RealtimeUiInputs} / the package README for the full contract + recipes.\n\n /**\n * The chrome the widget renders: the ambient `'orb'`, the structured `'console'`, or\n * `'auto'` (default) which starts as an orb and graduates to a console once the\n * container is wide enough AND the user has revealed text. Mirrors\n * {@link RealtimeUiInputs.chrome}.\n *\n * @example Force the rich console for a full-screen route:\n * ```html\n * <mj-realtime-session-overlay [Chrome]=\"'console'\"></mj-realtime-session-overlay>\n * ```\n */\n @Input()\n set Chrome(value: RealtimeChromeMode | undefined) { this.setUiInput('chrome', value); }\n get Chrome(): RealtimeChromeMode | undefined { return this._uiInputs.chrome; }\n\n /**\n * In `'auto'` chrome, the container width (px) at/above which the widget may graduate\n * to a console (still gated on text being revealed). Default `560`. Mirrors\n * {@link RealtimeUiInputs.consoleBreakpointPx}.\n */\n @Input()\n set ConsoleBreakpointPx(value: number | undefined) { this.setUiInput('consoleBreakpointPx', value); }\n get ConsoleBreakpointPx(): number | undefined { return this._uiInputs.consoleBreakpointPx; }\n\n /**\n * Force dense spacing/typography regardless of width (useful for tight mobile sheets).\n * Default `false` — compactness is otherwise inferred from the container width.\n */\n @Input()\n set Compact(value: boolean | undefined) { this.setUiInput('compact', value); }\n get Compact(): boolean | undefined { return this._uiInputs.compact; }\n\n /** Fade non-essential controls when the session is idle (orb chrome only). Default `true`. */\n @Input()\n set AutoHideControls(value: boolean | undefined) { this.setUiInput('autoHideControls', value); }\n get AutoHideControls(): boolean | undefined { return this._uiInputs.autoHideControls; }\n\n /**\n * May the user reveal the transcript at all? `false` makes the widget a pure voice orb\n * with no path to text (and never graduates to a console in `'auto'`). Default `true`.\n */\n @Input()\n set AllowTextReveal(value: boolean | undefined) { this.setUiInput('allowTextReveal', value); }\n get AllowTextReveal(): boolean | undefined { return this._uiInputs.allowTextReveal; }\n\n /** Show the captions toggle. Default `true`. */\n @Input()\n set ShowCaptionsControl(value: boolean | undefined) { this.setUiInput('showCaptionsControl', value); }\n get ShowCaptionsControl(): boolean | undefined { return this._uiInputs.showCaptionsControl; }\n\n /** Show the density picker inside the gear menu. Default `true`. */\n @Input()\n set ShowDensityPicker(value: boolean | undefined) { this.setUiInput('showDensityPicker', value); }\n get ShowDensityPicker(): boolean | undefined { return this._uiInputs.showDensityPicker; }\n\n /** Show the minimize control (collapse the call without ending it). Default `true`. */\n @Input()\n set ShowMinimize(value: boolean | undefined) { this.setUiInput('showMinimize', value); }\n get ShowMinimize(): boolean | undefined { return this._uiInputs.showMinimize; }\n\n /** Show the end-call control. Default `true` (hosts that own their own end button may hide it). */\n @Input()\n set ShowEnd(value: boolean | undefined) { this.setUiInput('showEnd', value); }\n get ShowEnd(): boolean | undefined { return this._uiInputs.showEnd; }\n\n /**\n * Show the right-hand surface panel (whiteboard / browser / interactive channels).\n * Default `true`; only renders in console chrome and once a panel is actually earned.\n */\n @Input()\n set ShowSurfacePanel(value: boolean | undefined) { this.setUiInput('showSurfacePanel', value); }\n get ShowSurfacePanel(): boolean | undefined { return this._uiInputs.showSurfacePanel; }\n\n /** Show the channel strip (active interactive channels). Default `true`. */\n @Input()\n set ShowChannels(value: boolean | undefined) { this.setUiInput('showChannels', value); }\n get ShowChannels(): boolean | undefined { return this._uiInputs.showChannels; }\n\n /** Show the Activity rail/tab (delegations, artifacts timeline). Default `true`. */\n @Input()\n set ShowActivityRail(value: boolean | undefined) { this.setUiInput('showActivityRail', value); }\n get ShowActivityRail(): boolean | undefined { return this._uiInputs.showActivityRail; }\n\n /**\n * Show developer affordances (\"open session / open run\" links). Default `true`, but\n * still additionally gated by the per-session dev-mode toggle — a hard ceiling, not a\n * force-on.\n */\n @Input()\n set ShowDevLinks(value: boolean | undefined) { this.setUiInput('showDevLinks', value); }\n get ShowDevLinks(): boolean | undefined { return this._uiInputs.showDevLinks; }\n\n /** Allow drag-to-resize of the surface panel. Default `true`. */\n @Input()\n set AllowResize(value: boolean | undefined) { this.setUiInput('allowResize', value); }\n get AllowResize(): boolean | undefined { return this._uiInputs.allowResize; }\n\n /**\n * A programmatic override bag, merged UNDER the individual inputs — any field also set\n * via a dedicated `@Input()` wins over its entry here. Lets a host configure the whole\n * surface in one binding (e.g. a saved per-context preset) without enumerating a dozen\n * attributes.\n *\n * @example\n * ```html\n * <mj-realtime-session-overlay [UiConfig]=\"leanOverlayPreset\"></mj-realtime-session-overlay>\n * ```\n */\n @Input()\n set UiConfig(value: RealtimeUiInputs | null | undefined) {\n this._uiConfigBag = value ?? null;\n this.recomputeUi();\n }\n get UiConfig(): RealtimeUiInputs | null | undefined { return this._uiConfigBag; }\n\n /**\n * SESSION REVIEW data: when set (and no live session is active) the overlay renders\n * the reviewed past session instead of a live call. Setting it populates the shared\n * {@link State} with the historical thread and prepares the read-only whiteboard tab;\n * clearing it returns the state to its live-merge baseline.\n */\n @Input()\n set ReviewData(value: RealtimeSessionReview | null) {\n if (value === this._reviewData) {\n return;\n }\n this._reviewData = value;\n if (value && !this.realtime.IsActive) {\n this.enterReview(value);\n } else if (!value) {\n this.exitReview();\n }\n }\n get ReviewData(): RealtimeSessionReview | null {\n return this._reviewData;\n }\n\n /**\n * Review mode: whether the \"Start live session\" action is offered. A host turns it off where\n * a voice session cannot start (the chat area does so while a draft fork is open).\n */\n @Input() AllowStartLive = true;\n\n /** Emitted after the call ends so the host can react (visibility is driven by Active$). */\n @Output() Ended = new EventEmitter<void>();\n\n /**\n * Emitted when a gear-gated developer link asks to open an entity record. The host is\n * expected to bubble this through its standard record-open path (the chat area re-emits\n * it on `openEntityRecord`, which Explorer routes via `NavigationService`). The overlay\n * minimizes itself first so the live call survives the navigation.\n */\n @Output() NavigateRequest = new EventEmitter<RealtimeNavigateRequest>();\n\n /**\n * Review mode's \"Start live session\": the host clears its review state and resumes the\n * reviewed session as a new live call (chaining `LastSessionId` to restore channel states).\n */\n @Output() StartLiveRequested = new EventEmitter<RealtimeStartLiveRequest>();\n\n /** Review mode's Close: the host clears its review state, returning to the conversation. */\n @Output() ReviewClosed = new EventEmitter<void>();\n\n // ── Declarative UI outputs (observe everything the surface does) ─────────────\n\n /** Emitted when the user minimizes the call view (the call stays live). */\n @Output() Minimized = new EventEmitter<void>();\n\n /** Emitted when the user reveals the transcript (opens text from the orb). */\n @Output() TextRevealed = new EventEmitter<void>();\n\n /** Emitted whenever the EFFECTIVE chrome flips between `'orb'` and `'console'`. */\n @Output() ChromeChanged = new EventEmitter<'orb' | 'console'>();\n\n /** Emitted when the connection lifecycle state changes (e.g. connecting → listening). */\n @Output() ConnectionStateChanged = new EventEmitter<RealtimeUiConnectionState>();\n\n /** Emitted when the mic mute is toggled; payload is the new muted state. */\n @Output() MuteChanged = new EventEmitter<boolean>();\n\n /** Emitted when the interface density changes. */\n @Output() DensityChanged = new EventEmitter<RealtimeUxDensity>();\n\n /** Emitted (px) when the user finishes resizing the surface panel. */\n @Output() SurfacePanelResized = new EventEmitter<number>();\n\n /**\n * A generic hook fired when ANY control is invoked — even one the host hid via inputs\n * and re-rendered itself. Lets a host observe/react to the full control surface from a\n * single binding.\n */\n @Output() ControlInvoked = new EventEmitter<RealtimeControlId>();\n\n private realtime = inject(RealtimeSessionService);\n private cdr = inject(ChangeDetectorRef);\n\n /**\n * The consumer's individually-bound UI inputs (each dedicated `@Input()` writes its own\n * slot here). Starts empty; only fields a host actually binds appear, so the resolver's\n * defaults fill the rest. Merged OVER {@link _uiConfigBag} (individual inputs win).\n */\n private _uiInputs: RealtimeUiInputs = {};\n\n /** The programmatic {@link UiConfig} override bag, merged UNDER the individual inputs. */\n private _uiConfigBag: RealtimeUiInputs | null = null;\n\n /**\n * The latest measured width (px) of the rendered overlay element, fed to the resolver as\n * {@link RealtimeUiSignals.ContainerWidthPx}. Maintained by a {@link ResizeObserver}; 0\n * until the first measurement (the resolver treats 0 as \"narrow\", i.e. an orb in auto).\n */\n private containerWidthPx = 0;\n\n /** Observes the rendered overlay element so chrome re-resolves as the host resizes. */\n private resizeObserver: ResizeObserver | null = null;\n\n /** The last connection state seen on {@link RealtimeSessionService.ConnectionState$}. */\n private currentConnectionState: RealtimeConnectionState = 'closed';\n\n /**\n * The resolved, render-ready view-model — the SINGLE source of truth the template binds\n * to (no `&&` chains in HTML). Rebuilt by {@link recomputeUi} whenever an input, the\n * disclosure model, the connection state, the container width, or the channel/activity\n * set changes. Read-only to consumers via the {@link Ui} getter.\n */\n // Seed from a dependency-free baseline — this runs as a field initializer, BEFORE the\n // disclosure model / session state / ResizeObserver exist. recomputeUi() produces the real\n // value once dependencies are ready (post-init + on every wired change source).\n private _ui: ResolvedRealtimeUi = ResolveRealtimeUi(DEFAULT_REALTIME_UI_INPUTS, DEFAULT_REALTIME_UI_SIGNALS);\n\n /**\n * The current resolved UI view-model. Every visibility/affordance decision the template\n * makes reads from this — bind to its boolean fields rather than composing logic inline.\n *\n * @example\n * ```ts\n * if (this.voice.Ui.chrome === 'console') { ... }\n * ```\n */\n public get Ui(): ResolvedRealtimeUi {\n return this._ui;\n }\n\n /** Local mic-muted state, the single source the resolver-independent controls reflect. */\n public Muted = false;\n\n private _reviewData: RealtimeSessionReview | null = null;\n\n /**\n * Set by {@link OnStartLive} just before emitting {@link StartLiveRequested}, so the\n * ReviewData→null transition that follows is recognized as a REVIEW→LIVE CONTINUATION\n * (keep the historical thread + append the \"Resumed live session\" divider) rather than\n * a plain review close (clear everything).\n */\n private pendingLiveContinuation = false;\n\n /**\n * The reviewed chain's history artifacts, surfaced inside the Activity tab's \"Session\n * artifacts\" group (no longer their own tabs). Bound into the surface panel via\n * {@link ReviewArtifacts}. Empty for a live session.\n */\n private reviewArtifacts: ParsedDelegationArtifact[] = [];\n\n /** The reviewed chain's history artifacts for the surface panel's Activity tab. */\n public get ReviewArtifacts(): ParsedDelegationArtifact[] {\n return this.reviewArtifacts;\n }\n\n /**\n * True while the surface panel carries the REVIEW-registered (template-based, read-only)\n * Whiteboard tab. Drives the review→live continuation edge: when the resumed live\n * session's channel set resolves WITHOUT a Whiteboard channel, the stale review tab is\n * removed (see {@link cleanupStaleReviewBoardTab}); when it resolves WITH one, the live\n * plugin re-registers the same key and the tab upgrades in place.\n */\n private reviewWhiteboardTabRegistered = false;\n\n /** True while the overlay renders a PAST session (review data set, no live call). */\n public get IsReviewing(): boolean {\n return this._reviewData !== null && !this.realtime.IsActive;\n }\n\n /**\n * The reviewed session's rehydrated whiteboard, when it saved a parseable Whiteboard\n * channel state — rendered read-only by the review whiteboard tab. Null = no tab.\n */\n public ReviewWhiteboard: WhiteboardState | null = null;\n\n /**\n * The `MJ: Files` id of the reviewed session's recording, or null when nothing was recorded.\n * Bound into the storage media player, which resolves the authenticated audio itself.\n */\n public get ReviewRecordingFileID(): string | null {\n return this._reviewData?.RecordingFileID ?? null;\n }\n\n /**\n * The reviewed session's transcript cues (built from its turns) for the recording player's\n * transcript panel. Empty outside review.\n */\n public ReviewCues: MediaTranscriptCue[] = [];\n\n /** True while the Recording tab is registered (a recording exists for the reviewed session). */\n private reviewRecordingTabRegistered = false;\n\n /** Shared session state — single source for the thread AND the activity rail. */\n public readonly State = new RealtimeSessionState();\n\n /**\n * PROGRESSIVE DISCLOSURE: the levels/milestones model behind the pure-audio-first UX\n * (see {@link RealtimeDisclosureModel}). Loaded from UserInfoEngine at construction;\n * content events ({@link onSessionStateChanged}, {@link onChannelActivity}) raise the\n * volatile session level; milestones ratchet + persist when the call ends. REVIEW mode\n * bypasses disclosure entirely — a past session always renders the full console.\n */\n public readonly Disclosure = new RealtimeDisclosureModel();\n\n /**\n * The strip's Details peek: shows the surface panel ON DEMAND while it isn't earned yet\n * (disclosure level < 2) — Activity and channel surfaces exist before their content\n * does. Cleared automatically once content earns the panel for real.\n */\n public DetailsPeek = false;\n\n /**\n * Whether the typed-input dock is open — a TWO-WAY user door (the strip's Type\n * control / the T hotkey open it; the dock's hide control closes it), volatile and\n * reset per session. Typing never becomes permanent chrome.\n */\n public ComposerOpen = false;\n\n /** Live turn-state from the session service — drives the banner + connecting screen. */\n public readonly ConnectionState$ = this.realtime.ConnectionState$;\n\n /** Server-reported realtime model name for the active session — shown subtly in the banner. */\n public readonly ModelName$ = this.realtime.ModelName$;\n\n /**\n * Whether the conversation renders as TEXT (the thread) or stays voice-first (the\n * orb hero). A PERSISTED per-user preference (`mj.realtimeVoice.captions.v1`) —\n * default OFF: voice-first, the orb owns the screen until the user opts into text.\n */\n public ShowCaptions = false;\n\n /**\n * Whether the user asked for the conversation itself (the hero's \"Show the conversation\", {@link RevealText}), not only\n * captions. While the agent's video presents in the hero, captions alone keep the hero and run over the video; this\n * opens the thread. Cleared when captions turn off.\n */\n private conversationShown = false;\n\n /** UserInfoEngine key for the persisted captions (text-vs-orb) preference. */\n private static readonly captionsPrefKey = 'mj.realtimeVoice.captions.v1';\n\n /**\n * Whether developer affordances (open-record links) are revealed. Per-session view\n * state on this shell — off by default, reset with the overlay, never persisted.\n */\n public DevMode = false;\n\n /** ID of the live server-side agent session record, for the banner's dev link. */\n public get SessionID(): string | null {\n return this.realtime.CurrentAgentSessionId;\n }\n\n /**\n * The tabbed surface panel (right panel) — channel registrations are forwarded to it.\n * A SETTER because the panel is disclosure-gated (`@if`): it can be created LATE (the\n * first delegation / channel activity reveals it mid-call), at which point any queued\n * channel registrations and a pending auto-reveal must flush to the fresh instance.\n */\n private surfaceTabs?: RealtimeSurfaceTabsComponent;\n @ViewChild(RealtimeSurfaceTabsComponent)\n private set surfaceTabsRef(ref: RealtimeSurfaceTabsComponent | undefined) {\n this.surfaceTabs = ref;\n if (!ref) {\n // The panel went away with its slots. StageSlot reads null while it is away, so the bindings don't change.\n this.channelSlot = null;\n this.SurfaceStage.SetActiveTab(null);\n // The panel that comes back is a new one, which starts as PanelCollapsed says: expanded unless only the call's\n // width hid this one (#5387, #5433).\n this.resetPanelCollapseUnlessWaitingForRoom();\n } else {\n // A (re)created panel starts with a FRESH tab model. Re-register the live channel set\n // here (gated to whiteboard + already-used channels) so hiding the panel (pure-audio\n // return, Details off) never loses the Whiteboard or an already-used channel's tab.\n // Artifacts live in the Activity rail now (driven by session state), so there's\n // nothing artifact-specific to recover on the panel.\n this.registerChannelTabs([...this.realtime.ActiveChannels]);\n this.flushPendingChannelTabs();\n const reveal = this.pendingRevealKey;\n this.pendingRevealKey = null;\n // Deferred: focus/expand feed the parent's width bindings (wide tier) — never\n // mutate those inside the change-detection pass that created the panel.\n setTimeout(() => {\n if (reveal) {\n // The agent's first channel activity caused this creation — land ON the board.\n ref.RevealChannel(reveal);\n } else {\n // Default for a fresh panel (live AND review): the marquee surface — channels\n // lead the strip — NOT the Activity rail; agent-run plumbing is opt-in only.\n // (Review channel tabs register a beat later and take focus themselves.)\n ref.FocusFirstTab();\n // The panel reports its wide tier only when it flips, from a start that is not wide, so landing on Activity\n // reports nothing. PanelWide may still hold the tier of the panel before, whose focused channel left the call\n // while it was away, so it takes the tier of the tab this one landed on (#5433). Only a different tier moves\n // the width. A reveal always lands on a channel's tab, which the panel reports itself.\n if (ref.IsWide !== this.PanelWide) {\n this.OnPanelWideChanged(ref.IsWide);\n }\n }\n });\n }\n }\n\n /** The bottom dock — type-to-compose seeds + focuses its input. */\n @ViewChild(RealtimeComposerComponent) private composer?: RealtimeComposerComponent;\n\n /** Channel keys already auto-revealed this session (first activity only). */\n private revealedChannelKeys = new Set<string>();\n\n /** Auto-reveal that arrived before the (disclosure-gated) panel rendered. */\n private pendingRevealKey: string | null = null;\n\n /** Previous Active$ value — edges drive disclosure session begin/ratchet. */\n private prevActive = false;\n\n /** Template hosting the read-only review whiteboard (root-level, so always resolvable). */\n @ViewChild('reviewBoardTpl') private reviewBoardTpl?: TemplateRef<unknown>;\n\n /** Template hosting the review-mode recording player (root-level, so always resolvable). */\n @ViewChild('recordingTpl') private recordingTpl?: TemplateRef<unknown>;\n\n /** Channel registrations received before the surface panel rendered (flushed in ngAfterViewInit). */\n private pendingChannelTabs: RealtimeChannelTabRegistration[] = [];\n\n /** True once the view (and the review-board template ref) exists. */\n private viewReady = false;\n\n // ── Channel FOCUS layout (channel-generic — any plugin may request it) ─────\n\n /**\n * True while a channel's surface is on the stage (FOCUS mode): the main call column collapses\n * (`.board-focus` on the overlay) and a compact floating call pill (orb + state +\n * mute / show-thread / move / end) rides over the surface. A surface that presents the agent\n * ({@link PresenterOnStage}) takes the agent's place in the call instead, so it is not focus mode.\n */\n public get ChannelFocusMode(): boolean {\n return this.SurfaceStage.StageKey !== null && !this.PresenterOnStage;\n }\n\n /**\n * Whether the surface on the stage presents the agent: its channel shows the agent's video (the Avatar). It lies over\n * {@link PresenterSlot}, in the agent's place in the call (the hero, or above the thread in the console), rather than\n * filling the overlay.\n */\n public get PresenterOnStage(): boolean {\n return this.StagePlugin?.ShowsAgentVideo ?? false;\n }\n\n /** Whether captions run over the agent's video: they are on, and the video presents in the hero. */\n public get ShowAvatarCaptions(): boolean {\n return this.ShowCaptions && this.ShowHero && this.PresenterOnStage;\n }\n\n /**\n * Whether the call body shows the connecting screen for `state`: while the call connects, outside review, unless the\n * agent's video presents in the hero. The hero then stays, so a resume on a new connection keeps the video in its place\n * with its last frame on screen, and the video's tile says the call is connecting. Taking the hero away would take the\n * video's place with it, and the stage would lay the video over the whole call until the hero came back.\n */\n public ShowConnectingScreen(state: RealtimeConnectionState): boolean {\n return !this.IsReviewing && state === 'connecting' && !(this.ShowHero && this.PresenterOnStage);\n }\n\n /** The newest caption, as the captions over the agent's video show it: the user's is marked \"You\". `null` before any. */\n public get AvatarCaption(): RealtimeAvatarCaption | null {\n const items = this.State.Items;\n for (let i = items.length - 1; i >= 0; i--) {\n const item = items[i];\n if (item.Kind === 'caption') {\n return { Speaker: item.Role === 'User' ? 'You' : null, Text: item.Text };\n }\n }\n return null;\n }\n\n /** The agent's place in the call, as last reported to the stage, or `null` while the call shows none. */\n public PresenterSlot: HTMLElement | null = null;\n\n /** The element the stage lays its stage surface over: the agent's place while it presents, else none (it fills the stage). */\n public get StageSurfaceSlot(): HTMLElement | null {\n return this.PresenterOnStage ? this.PresenterSlot : null;\n }\n\n /** The agent's place in the call: in the hero, or above the thread in the console. */\n @ViewChild('presenterSlot') private presenterSlotRef?: ElementRef<HTMLElement>;\n\n /** The presenter slot last reported through {@link PresenterSlot}. */\n private reportedPresenterSlot: HTMLElement | null = null;\n\n /** Mic-muted state reflected on the focus pill's mute button. */\n public FocusPillMuted = false;\n\n /** The channel whose surface is on the stage (the pill's exit routes back to it), or `null`. */\n public get StagePlugin(): BaseRealtimeChannelClient | null {\n const key = this.SurfaceStage.StageKey;\n return key ? this.SurfaceStage.PluginFor(key) : null;\n }\n\n // ── The stage: every channel surface, in one layer over the overlay ─────────\n\n /** Which channel surfaces the stage holds and where each shows. */\n public readonly SurfaceStage = new RealtimeSurfaceStageModel();\n\n /** The active channel tab's slot, as the panel last reported it. */\n private channelSlot: RealtimeChannelSlot | null = null;\n\n /** The slot the stage lays the active channel tab's surface over: none while the panel is away. */\n public get StageSlot(): RealtimeChannelSlot | null {\n return this.ShowPanelArea ? this.channelSlot : null;\n }\n\n /** The panel's active channel slot moved, or went away. */\n public OnChannelSlotChange(slot: RealtimeChannelSlot | null): void {\n this.channelSlot = slot;\n this.SurfaceStage.SetActiveTab(slot?.Key ?? null);\n this.cdr.markForCheck();\n }\n\n private subs: Subscription[] = [];\n\n constructor() {\n super();\n this.loadPlacementPref();\n this.loadPanelWidthPref();\n this.loadDisclosurePref();\n this.loadCaptionsPref();\n this.State.Attach(this.realtime);\n this.subs.push(\n // Re-render on merged-state changes; content arrival raises the disclosure level.\n this.State.Changed$.subscribe(() => this.onSessionStateChanged()),\n // Disclosure ratchet moved — re-resolve the view-model (thread/composer/gear gates).\n this.Disclosure.Changed$.subscribe(() => this.recomputeUi()),\n // One surface tab per registry-resolved channel plugin (replays the current set).\n this.realtime.ActiveChannels$.subscribe(channels => this.onActiveChannelsChanged(channels)),\n // Any channel may request the focus layout through its host context.\n this.realtime.ChannelFocus$.subscribe(event => this.onChannelFocus(event.Channel, event.Focused)),\n // The agent ACTED on a channel — auto-reveal its surface tab on first activity.\n this.realtime.ChannelActivity$.subscribe(plugin => this.onChannelActivity(plugin)),\n // What the agent can see (frames flowing from a whiteboard, browser, shared screen): feeds the\n // \"agent can see\" chip. Not gated by disclosure level — it is a privacy indicator, never earned.\n this.realtime.VideoSources$.subscribe(sources => { this.VideoSources = sources; this.cdr.markForCheck(); }),\n // The camera and screen share, and which of them the call offers: the composer's Camera and Share follow both.\n this.realtime.Captures$.subscribe(states => this.onCapturesChanged(states)),\n this.realtime.CaptureOffers$.subscribe(offers => { this.CaptureOffers = offers; this.cdr.markForCheck(); }),\n // The call's microphone and the ones it can move to: the composer's device menu lists them.\n this.realtime.Microphone$.subscribe(microphone => this.onMicrophoneChanged(microphone)),\n // The panels of the page on screen, which the Share menu offers under \"This panel\"; a shared one that goes away\n // ends its share.\n this.sharePanelRegistry.PanelsFor$(this.hostRef.nativeElement).subscribe(panels => {\n this.SharePanels = panels;\n this.cdr.markForCheck();\n }),\n this.sharePanelRegistry.Removed$.subscribe(key => this.onSharePanelRemoved(key)),\n // Live/idle flips: reset/ratchet disclosure + re-evaluate the review-vs-live branch.\n this.realtime.Active$.subscribe(active => this.onActiveChanged(active)),\n // Connection lifecycle drives chrome (the `connecting` loader) + the public output.\n this.realtime.ConnectionState$.subscribe(state => this.onConnectionStateChanged(state)),\n // Why the call shows no avatar its agent asked for: once per call, after it connects.\n this.realtime.AvatarNotice$.subscribe(notice => this.onAvatarNotice(notice))\n );\n }\n\n /** The runtime's notice for this call (`null` when none). */\n private avatarNotice: RealtimeAvatarNotice | null = null;\n\n /** The notice the user dismissed or that hid itself; this call does not show it again. */\n private avatarNoticeDone: RealtimeAvatarNotice | null = null;\n\n /** Hides the notice {@link AVATAR_NOTICE_VISIBLE_MS} after it appears. */\n private avatarNoticeTimer: ReturnType<typeof setTimeout> | null = null;\n\n /**\n * Why this live call shows no avatar its agent asked for, while the notice shows: from the moment the call connects\n * until the user dismisses it or it hides itself. `null` otherwise, when {@link ShowAvatarNotice} is off, and always in review.\n */\n public get AvatarNotice(): RealtimeAvatarNotice | null {\n const notice = this.avatarNotice;\n return this.ShowAvatarNotice && notice && notice !== this.avatarNoticeDone && !this.IsReviewing ? notice : null;\n }\n\n /**\n * The notice's line, in the host's words when it gave some ({@link AvatarNoticeLabels}); a notice without a reason (one\n * this version doesn't know) reads the call's line for it.\n */\n public get AvatarNoticeMessage(): string {\n const notice = this.AvatarNotice;\n return notice ? AvatarNoticeText(notice.Reason ?? null, this.AvatarNoticeLabels, this.AgentName) : '';\n }\n\n /** The user dismissed the notice: it does not come back in this call. */\n public OnAvatarNoticeDismissed(): void {\n this.finishAvatarNotice();\n }\n\n /** A new notice starts its timer; a call's end (`null`) takes it away. */\n private onAvatarNotice(notice: RealtimeAvatarNotice | null): void {\n if (notice === this.avatarNotice) {\n return;\n }\n this.clearAvatarNoticeTimer();\n this.avatarNotice = notice;\n if (notice && notice !== this.avatarNoticeDone) {\n this.avatarNoticeTimer = setTimeout(() => this.ngZone.run(() => this.finishAvatarNotice()), AVATAR_NOTICE_VISIBLE_MS);\n }\n this.cdr.markForCheck();\n }\n\n /** Hides the current notice for the rest of its call. */\n private finishAvatarNotice(): void {\n this.clearAvatarNoticeTimer();\n this.avatarNoticeDone = this.avatarNotice;\n this.cdr.markForCheck();\n }\n\n private clearAvatarNoticeTimer(): void {\n if (this.avatarNoticeTimer !== null) {\n clearTimeout(this.avatarNoticeTimer);\n this.avatarNoticeTimer = null;\n }\n }\n\n /** The video sources the agent can or could see right now (see {@link RealtimeSessionService.VideoSources$}). */\n public VideoSources: readonly VideoSourceState[] = [];\n\n /**\n * The video sources surfaced to `<mj-realtime-perception-chip>`.\n * By default (`ShowPerceptionChip = false`), the chip only appears when the user has an active camera or\n * screen capture (`CameraOn`, `Sharing`, or an enabled `'camera'` / `'screen'` source), preventing\n * background channel bridges from cluttering pure-voice calls.\n */\n public get VisibleVideoSources(): readonly VideoSourceState[] {\n const hasUserCapture =\n this.CameraOn ||\n this.Sharing ||\n this.VideoSources.some((s) => (s.Kind === 'camera' || s.Kind === 'screen') && s.Enabled);\n if (!this.ShowPerceptionChip && !hasUserCapture) {\n return [];\n }\n return this.VideoSources;\n }\n\n /** The user's camera and screen share (see {@link RealtimeSessionService.Captures$}). */\n public CaptureStates: RealtimeCaptureStates = REALTIME_CAPTURES_OFF;\n\n /** Which captures the call offers (see {@link RealtimeSessionService.CaptureOffers$}); the composer shows Camera and Share from it. */\n public CaptureOffers: RealtimeCaptureOffers = REALTIME_CAPTURE_OFFERS_NONE;\n\n /** Whether the camera is on or starting: the composer's Camera button reads as on. */\n public get CameraOn(): boolean {\n return isCapturing(this.CaptureStates.Camera);\n }\n\n /** The camera while the user checks it, before the agent sees it; `null` otherwise. The camera check card shows it. */\n public get CameraCheck(): RealtimeCaptureState | null {\n return this.CaptureStates.Camera.Checking ? this.CaptureStates.Camera : null;\n }\n\n /** The camera check's \"Turn on camera\": the agent sees the camera from now on. */\n public OnCameraCheckConfirmed(): void {\n this.realtime.ConfirmCamera();\n }\n\n /** The camera check's \"Not now\": the camera turns off. */\n public OnCameraCheckDeclined(): void {\n this.realtime.StopCamera();\n }\n\n /** Moves the camera being checked to another device: the camera check's picker. */\n public readonly SwitchCheckedCamera = (deviceId: string): Promise<RealtimeCaptureState> => this.realtime.SwitchCamera(deviceId);\n\n /** Whether a share is on or starting: the composer's Share button reads as sharing. */\n public get Sharing(): boolean {\n return isCapturing(this.CaptureStates.Screen);\n }\n\n /**\n * The composer's Camera button. The session starts or stops the camera; its channel's box shows it, or why it could not\n * start.\n */\n public OnCameraToggled(on: boolean): void {\n if (on) {\n void this.realtime.StartCamera();\n } else {\n this.realtime.StopCamera();\n }\n this.ControlInvoked.emit('camera');\n }\n\n /** The app's shareable panels: what the Share menu offers under \"This panel\", and the panel a pick names. */\n private readonly sharePanelRegistry = inject(SharePanelRegistry);\n\n /**\n * The panels of the page the Share menu offers under \"This panel\": those on screen, in page order, leaving out any that\n * holds this call. Empty where the browser cannot share a single panel.\n */\n public SharePanels: readonly MediaSharePanel[] = [];\n\n /** The key of the panel being shared, while a share of one panel starts or runs; `null` otherwise. */\n private sharedPanelKey: string | null = null;\n\n /**\n * The composer's Share button or menu: the session asks the browser's picker, offering the kind of surface picked first,\n * or this tab, to share the picked panel alone.\n */\n public OnShareRequested(request: MediaShareRequest): void {\n if (request.Kind === 'display') {\n void this.realtime.StartScreenShare(request.PreferredSurface ? { PreferredSurface: request.PreferredSurface } : undefined);\n } else {\n this.startPanelShare(request.PanelKey);\n }\n this.ControlInvoked.emit('share');\n }\n\n /** The composer's Stop sharing. */\n public OnStopShareRequested(): void {\n this.realtime.StopScreenShare();\n this.ControlInvoked.emit('share');\n }\n\n /** Shares one panel of the page, named by its label. A panel that went away since the menu listed it shares nothing. */\n private startPanelShare(key: string): void {\n const panel = this.sharePanelRegistry.Get(key);\n if (!panel) {\n return;\n }\n this.sharedPanelKey = key;\n void this.realtime.StartScreenShare({ Panel: panel.Element, PanelLabel: panel.Label });\n }\n\n /**\n * A panel went away, such as the whiteboard when its channel leaves the call. When it is the one shared, the share ends:\n * no frame comes from an element that is gone. A panel that is only out of sight keeps its share.\n */\n private onSharePanelRemoved(key: string): void {\n if (key === this.sharedPanelKey) {\n this.sharedPanelKey = null;\n this.realtime.StopScreenShare();\n }\n }\n\n /** The captures changed: the composer follows them, and a share that is over no longer holds its panel. */\n private onCapturesChanged(states: RealtimeCaptureStates): void {\n this.CaptureStates = states;\n if (!isCapturing(states.Screen)) {\n this.sharedPanelKey = null;\n }\n this.refreshCallDevices();\n this.cdr.markForCheck();\n }\n\n /** The call's microphone (see {@link RealtimeSessionService.Microphone$}). */\n private microphone: RealtimeMicrophoneState = REALTIME_MICROPHONE_NONE;\n\n /** The microphone and the camera the user picked in the device menu, each while the call switches to it. */\n private switchingTo: { microphone: string | null; camera: string | null } = { microphone: null, camera: null };\n\n /**\n * The microphones and cameras the composer's device menu offers: the call's microphones, and its cameras while the\n * camera is open (a browser names cameras only once the user has allowed one).\n */\n public CallDevices: readonly MediaDevice[] = [];\n\n /** The microphone the device menu shows: the one being switched to, else the one in use. */\n public get SelectedMicrophoneID(): string | null {\n return this.switchingTo.microphone ?? this.microphone.DeviceID ?? null;\n }\n\n /** The camera the device menu shows: the one being switched to, else the one in use. */\n public get SelectedCameraID(): string | null {\n return this.switchingTo.camera ?? this.CaptureStates.Camera.DeviceID ?? null;\n }\n\n /**\n * What the call says while no microphone works: the call lost its microphone (the one in use failed and so did the\n * default, or the last one went away), so the agent hears nothing until the user picks one in the device menu. Shown\n * under the banner for as long as that lasts. `null` while the microphone works, outside a call, and always in review.\n */\n public get MicrophoneNotice(): string | null {\n const failure = this.microphone.Failure;\n if (!failure || this.IsReviewing) {\n return null;\n }\n const line = failure === 'denied' ? MICROPHONE_NOTICE_TEXT.Blocked : MICROPHONE_NOTICE_TEXT.Lost;\n return line.split('{Agent}').join(this.AgentName);\n }\n\n /**\n * A microphone or camera picked in the composer's device menu: the session switches to it. The menu shows the pick\n * while the switch runs, then the device in use: the new one, or the old one when the new one could not open. A pick of\n * the device in use changes nothing. While no microphone works, the session opens the picked microphone, and the menu\n * then shows it, or none when it could not open.\n */\n public async OnDeviceSelected(selection: MediaDeviceSelection): Promise<void> {\n if (selection.Kind !== 'microphone' && selection.Kind !== 'camera') {\n return;\n }\n const kind = selection.Kind;\n const inUse = kind === 'microphone' ? this.microphone.DeviceID : this.CaptureStates.Camera.DeviceID;\n if (selection.DeviceID === inUse && this.switchingTo[kind] === null) {\n return;\n }\n this.ControlInvoked.emit('devices');\n this.switchingTo = { ...this.switchingTo, [kind]: selection.DeviceID };\n this.cdr.markForCheck();\n try {\n if (kind === 'microphone') {\n await this.realtime.SwitchMicrophone(selection.DeviceID);\n } else {\n await this.realtime.SwitchCamera(selection.DeviceID);\n }\n } finally {\n if (this.switchingTo[kind] === selection.DeviceID) {\n this.switchingTo = { ...this.switchingTo, [kind]: null };\n }\n this.cdr.markForCheck();\n }\n }\n\n /** The microphone changed: the device menu follows it. */\n private onMicrophoneChanged(microphone: RealtimeMicrophoneState): void {\n this.microphone = microphone;\n this.refreshCallDevices();\n this.cdr.markForCheck();\n }\n\n /** Lists the call's microphones and its cameras for the device menu, as a new list only when one of them changed. */\n private refreshCallDevices(): void {\n const cameras = this.CaptureStates.Camera.Devices ?? [];\n const devices = [...this.microphone.Devices, ...cameras];\n const same = devices.length === this.CallDevices.length && devices.every((d, i) => d === this.CallDevices[i]);\n if (!same) {\n this.CallDevices = devices;\n }\n }\n\n /**\n * The user switched one of the agent's video sources on or off in the \"agent can see\" chip. The session\n * applies it (and remembers it per channel) and tells the agent.\n */\n public OnVideoSourceToggled(toggle: RealtimePerceptionToggle): void {\n this.realtime.SetVideoSourceEnabled(toggle.SourceID, toggle.Enabled);\n }\n\n /**\n * The user picked the video source the agent sees in the \"agent can see\" chip, or let the call choose again (`null`).\n * The session's arbiter applies it and tells the agent.\n */\n public OnVideoSourcePicked(sourceId: string | null): void {\n this.realtime.SelectVideoSource(sourceId);\n }\n\n /**\n * The user moved to another channel's tab (or to a tab that is not a channel). When the model can watch only one\n * video source, the channel the user is looking at is the one it sees.\n */\n public OnActiveChannelChange(channelKey: string | null): void {\n this.realtime.SetFocusedChannel(channelKey);\n }\n\n ngAfterViewChecked(): void {\n this.reportPresenterSlot();\n }\n\n /** Reports the agent's place in the call when the element changed (the chrome switched, or the call body changed). */\n private reportPresenterSlot(): void {\n const element = this.presenterSlotRef?.nativeElement ?? null;\n if (element === this.reportedPresenterSlot) {\n return;\n }\n this.reportedPresenterSlot = element;\n // The view was just checked and the stage binds the slot, so it hears about it in a fresh turn.\n queueMicrotask(() => {\n this.PresenterSlot = element;\n this.cdr.markForCheck();\n });\n }\n\n ngAfterViewInit(): void {\n this.viewReady = true;\n this.startResizeObserver();\n this.flushPendingChannelTabs();\n this.registerReviewBoardTab();\n this.registerReviewArtifactTabs();\n // Cues were already built by enterReview() when ReviewData was set; here we only need to\n // (re)register the recording tab now that the #recordingTpl ref exists. The storage media\n // player resolves the authenticated audio itself from the RecordingFileID.\n this.registerReviewRecordingTab();\n }\n\n // ── Declarative UI config: inputs → signals → resolved view-model ────────────\n\n /**\n * Writes one individually-bound UI input into {@link _uiInputs} and re-resolves the\n * view-model. `undefined` clears the slot (so the {@link UiConfig} bag / default applies).\n * Called by every dedicated `@Input()` setter.\n *\n * @param key the {@link RealtimeUiInputs} field to set\n * @param value the bound value, or `undefined` to clear the override\n */\n private setUiInput<K extends keyof RealtimeUiInputs>(key: K, value: RealtimeUiInputs[K] | undefined): void {\n if (value === undefined) {\n delete this._uiInputs[key];\n } else {\n this._uiInputs[key] = value;\n }\n this.recomputeUi();\n }\n\n /**\n * The effective consumer inputs: the {@link UiConfig} bag with the individually-bound\n * inputs layered ON TOP, so a dedicated `@Input()` always wins over its bag entry.\n */\n private get mergedUiInputs(): RealtimeUiInputs {\n return { ...(this._uiConfigBag ?? {}), ...this._uiInputs };\n }\n\n /**\n * Maps the runtime {@link RealtimeConnectionState} onto the resolver's\n * {@link RealtimeUiConnectionState}. `'closed'` (no live call) maps to `'idle'`; the\n * other states pass through 1:1.\n */\n private mapConnectionState(state: RealtimeConnectionState): RealtimeUiConnectionState {\n return state === 'closed' ? 'idle' : state;\n }\n\n /**\n * Builds the live {@link RealtimeUiSignals} the resolver consumes, reading current facts\n * from the disclosure model, the session/channel state, review mode, focus mode, and the\n * {@link ResizeObserver}-measured width. Pure read — no side effects.\n */\n private buildSignals(): RealtimeUiSignals {\n // Defensive: this can be reached before every dependency is wired (field-init / early\n // change-detection). Fall back to the dependency-free baseline rather than throw — the\n // next recompute, once everything exists, produces the real value.\n const disclosure = this.Disclosure;\n if (!disclosure) {\n return DEFAULT_REALTIME_UI_SIGNALS;\n }\n const reviewing = this.IsReviewing;\n return {\n ContainerWidthPx: this.containerWidthPx ?? 0,\n // Text intent = the user EXPLICITLY asked to see text this session — i.e. captions are on\n // (the captions toggle, the hero's \"Show the conversation\", RevealText(), and SetCaptions()\n // all route through ShowCaptions). NOT the disclosure ratchet: a power user still opens to\n // the calm orb until they ask for text, matching the historical ShowHero = !ShowCaptions.\n // While the agent's video presents, captions alone keep the hero (they run over the video);\n // only asking for the conversation opens the thread.\n TextRevealed: this.ShowCaptions && (this.conversationShown || !this.PresenterOnStage),\n DisclosureShowThread: disclosure.ShowThread,\n DisclosureShowComposer: disclosure.ShowComposer,\n DisclosureShowPanel: disclosure.ShowPanel,\n DisclosureShowGear: disclosure.ShowGear,\n // A surface to populate: the on-demand Details peek, or review (always has a surface).\n SurfacePanelEarned: this.DetailsPeek || reviewing,\n hasChannels: (this.realtime?.ActiveChannels ?? []).some(c => c.HasSurface()),\n HasActivity: (this.State?.Cards?.length ?? 0) > 0,\n DevMode: this.DevMode,\n IsReviewing: reviewing,\n channelFocus: this.ChannelFocusMode,\n ConnectionState: this.mapConnectionState(this.currentConnectionState)\n };\n }\n\n /**\n * Re-resolves {@link Ui} from the merged inputs + current signals and emits the chrome /\n * connection-state outputs when they actually change. Safe to call on any of the wired\n * change sources (input write, disclosure ratchet, connection flip, resize, channel set);\n * the resolver is pure so redundant calls are cheap. Always marks for check.\n */\n private recomputeUi(): void {\n const next = ResolveRealtimeUi(this.mergedUiInputs, this.buildSignals());\n const prevChrome = this._ui.chrome;\n this._ui = next;\n if (next.chrome !== prevChrome) {\n this.ChromeChanged.emit(next.chrome);\n }\n // The panel's area may have just hidden, or, while it waited for room, been hidden for another reason too.\n this.resetPanelCollapseUnlessWaitingForRoom();\n this.cdr.markForCheck();\n }\n\n /** Connection lifecycle changed: store it, re-resolve chrome, and surface the public output. */\n private onConnectionStateChanged(state: RealtimeConnectionState): void {\n if (state === this.currentConnectionState) {\n return;\n }\n this.currentConnectionState = state;\n this.ConnectionStateChanged.emit(this.mapConnectionState(state));\n this.recomputeUi();\n }\n\n // ── Container-width observation (drives the auto orb ↔ console graduation) ────\n\n /**\n * Starts observing the rendered overlay element's width so the resolver can graduate\n * `'auto'` chrome to a console when the host gives it room. Guards SSR / environments\n * without `ResizeObserver` (plain-node tests) — there the width simply stays 0 (an orb in\n * auto), which is the safe ambient default. Idempotent.\n */\n private startResizeObserver(): void {\n if (this.resizeObserver || typeof ResizeObserver !== 'function') {\n return;\n }\n const el = this.overlayElement() ?? (this.hostRef.nativeElement as HTMLElement);\n if (!el) {\n return;\n }\n // Seed an immediate measurement so the first resolve sees a real width. Deferred to a\n // microtask (same reasoning as OnPanelWideChanged above): ngAfterViewInit runs inside the\n // SAME change-detection pass that already checked bindings derived from Ui (e.g. the\n // template's `@if (ShowPanelArea)` and `[Compact]`) using the field-initializer's width-0\n // baseline. Recomputing synchronously here can flip chrome orb→console mid-pass and trip\n // ExpressionChangedAfterItHasBeenCheckedError (NG0100). Landing the seed measurement in a\n // fresh microtask lets it recompute in its own CD cycle instead.\n Promise.resolve().then(() => {\n this.applyContainerWidth(el.getBoundingClientRect ? el.getBoundingClientRect().width : 0);\n });\n this.resizeObserver = new ResizeObserver(entries => {\n const width = entries[0]?.contentRect?.width ?? 0;\n this.ngZone.run(() => Promise.resolve().then(() => this.applyContainerWidth(width)));\n });\n this.resizeObserver.observe(el);\n }\n\n /** Adopts a new measured width and re-resolves only when it actually changed. */\n private applyContainerWidth(width: number): void {\n const rounded = Math.round(width);\n if (rounded === this.containerWidthPx) {\n return;\n }\n this.containerWidthPx = rounded;\n this.recomputeUi();\n }\n\n /** Disconnects the container-width observer. */\n private stopResizeObserver(): void {\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n }\n\n // ── Surface-panel sizing (flex layout + pointer-drag handle; width persisted per-user) ──\n //\n // The panel width is a PLAIN FIELD rendered via [style.width.px] — there is no split\n // library with its own internal size state to fight. The resize handle uses the same\n // mechanics as ui-components' slide-panel (`MjSlidePanelComponent`): mousedown →\n // document mousemove/mouseup registered OUTSIDE Angular, live clamp while dragging,\n // adopt + persist on release. A bare CLICK cannot move the panel by construction\n // (width follows the pointer delta) and the click-vs-drag guard keeps it from being\n // adopted or persisted.\n\n /**\n * Whether the surface panel is collapsed to its slim strip, as the panel reports it. A panel created again starts this\n * way (the overlay binds the panel's `Collapsed`). Back to `false` while the panel's area is hidden for any reason but\n * room, so the panel comes back expanded after Details, a channel on the stage or a review turning into a live call,\n * and as the user left it when only the call's width hid it.\n */\n public PanelCollapsed = false;\n /**\n * Wide tier active (a content tab is focused) — drives the DEFAULT width only. The panel reports it when it flips; a\n * panel created again also sets it from the tab it lands on.\n */\n public PanelWide = false;\n /** The user's explicit dragged width (persisted); null = follow the default tiers. */\n private userPanelWidth: number | null = null;\n /** Current expanded panel width in px (rendered as the panel's inline width). */\n public PanelWidthPx = SURFACE_PANEL_DEFAULT_WIDTH;\n /** True while the resize handle is mid-drag (brand-tints the handle). */\n public IsPanelResizing = false;\n private panelResizeStartX = 0;\n private panelResizeStartWidth = 0;\n private boundPanelResizeMove = this.onPanelResizeMove.bind(this);\n private boundPanelResizeEnd = this.onPanelResizeEnd.bind(this);\n private hostRef = inject(ElementRef);\n private ngZone = inject(NgZone);\n\n /** The panel's rendered width: slim strip when collapsed, otherwise the current width. */\n public get PanelAreaSize(): number {\n return this.PanelCollapsed ? SURFACE_PANEL_COLLAPSED_WIDTH : this.PanelWidthPx;\n }\n\n /**\n * Resizing is meaningless while collapsed or when the surface fills (focus mode), and a\n * host may hard-disable it via `[AllowResize]=\"false\"` — in review the resolver's\n * `allowResize` is false (no live surface to resize), so this also reads the host flag\n * directly (defaulting to the historical `true`) rather than the resolved value, keeping\n * drag available in review exactly as before.\n */\n public get PanelResizeDisabled(): boolean {\n const hostAllows = this.mergedUiInputs.allowResize ?? DEFAULT_REALTIME_UI_INPUTS.allowResize;\n return this.PanelCollapsed || this.ChannelFocusMode || !hostAllows;\n }\n\n public OnPanelCollapsedChange(collapsed: boolean): void {\n this.PanelCollapsed = collapsed;\n this.cdr.markForCheck();\n }\n\n /**\n * Resets {@link PanelCollapsed} while the panel's area is hidden for any reason but room. Details, a channel taking the\n * stage and a reviewed session turning into a live call hide the panel on purpose, and what brings it back asks to see\n * it, so it comes back expanded (#5387). A call that only got too narrow asked for nothing, so the panel comes back as\n * the user left it (#5433). Runs when the panel goes away and on every re-resolve, so a panel that waits for room and\n * is then hidden on purpose (Details closed meanwhile) comes back expanded too. No binding reads PanelCollapsed while\n * the area is hidden, so a change here trips no NG0100 check.\n */\n private resetPanelCollapseUnlessWaitingForRoom(): void {\n if (!this.ShowPanelArea && !this._ui.SurfacePanelWaitsForRoom) {\n this.PanelCollapsed = false;\n }\n }\n\n /** Wide-tier flips only move the DEFAULT width — an explicit user width always wins. */\n public OnPanelWideChanged(wide: boolean): void {\n this.PanelWide = wide;\n if (this.userPanelWidth === null) {\n // This can fire synchronously from the surface-tabs child during the FIRST change-detection\n // pass, while hostWidth() transitions 0 → real across that same pass — setting the bound width\n // inline then trips ExpressionChangedAfterItHasBeenCheckedError (380 → 308). Defer to a\n // microtask so the recompute lands in a fresh CD cycle. (Drag/reset handlers stay synchronous —\n // those run on real user events, not during CD.)\n Promise.resolve().then(() => {\n if (this.userPanelWidth === null) {\n this.PanelWidthPx = DefaultSurfacePanelWidth(this.PanelWide, this.hostWidth());\n this.cdr.markForCheck();\n }\n });\n return;\n }\n this.cdr.markForCheck();\n }\n\n /** Mousedown on the resize handle: capture the start state and track the pointer document-wide. */\n public OnPanelResizeStart(event: MouseEvent): void {\n if (this.PanelResizeDisabled) {\n return;\n }\n event.preventDefault();\n this.IsPanelResizing = true;\n this.panelResizeStartX = event.clientX;\n this.panelResizeStartWidth = this.PanelWidthPx;\n document.body.style.cursor = 'col-resize';\n document.body.style.userSelect = 'none';\n this.ngZone.runOutsideAngular(() => {\n document.addEventListener('mousemove', this.boundPanelResizeMove);\n document.addEventListener('mouseup', this.boundPanelResizeEnd);\n });\n this.cdr.markForCheck();\n }\n\n /** Live drag: panel width follows the pointer delta, clamped to [min, 70% of the overlay]. */\n private onPanelResizeMove(event: MouseEvent): void {\n if (!this.IsPanelResizing) {\n return;\n }\n this.PanelWidthPx = SurfacePanelDragWidth(\n this.panelResizeStartWidth, this.panelResizeStartX, event.clientX, this.hostWidth()\n );\n this.ngZone.run(() => this.cdr.markForCheck());\n }\n\n /**\n * Release: a genuine DRAG adopts the width as the user's explicit preference and\n * persists it (debounced); a bare CLICK (movement under the tolerance) restores the\n * start width and persists nothing — the handle never snaps on a click.\n */\n private onPanelResizeEnd(event: MouseEvent): void {\n if (!this.IsPanelResizing) {\n return;\n }\n this.teardownPanelResize();\n let resizedTo: number | null = null;\n if (IsSurfacePanelDrag(this.panelResizeStartX, event.clientX)) {\n this.userPanelWidth = this.PanelWidthPx;\n this.persistPanelWidth(this.PanelWidthPx);\n resizedTo = this.PanelWidthPx;\n } else {\n this.PanelWidthPx = this.panelResizeStartWidth;\n }\n this.ngZone.run(() => {\n this.IsPanelResizing = false;\n // Surface the new width to the host only on a genuine drag (not a bare click).\n if (resizedTo !== null) {\n this.SurfacePanelResized.emit(resizedTo);\n }\n this.cdr.markForCheck();\n });\n }\n\n /** Double-click the handle: back to the default tier width; persist the reset. */\n public OnPanelResizeReset(): void {\n this.userPanelWidth = null;\n this.PanelWidthPx = DefaultSurfacePanelWidth(this.PanelWide, this.hostWidth());\n this.persistPanelWidth(null);\n this.cdr.markForCheck();\n }\n\n /** Removes the document-wide drag listeners and restores the body cursor/selection. */\n private teardownPanelResize(): void {\n document.removeEventListener('mousemove', this.boundPanelResizeMove);\n document.removeEventListener('mouseup', this.boundPanelResizeEnd);\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n }\n\n /**\n * The overlay's measurable width for clamping. The component host is\n * `display: contents` (zero rect) — measure the rendered `.call-overlay` div instead.\n */\n private hostWidth(): number {\n const host = this.hostRef.nativeElement as HTMLElement;\n const el = (host.firstElementChild as HTMLElement | null) ?? host;\n return el.getBoundingClientRect ? el.getBoundingClientRect().width : 0;\n }\n\n /** Reads the persisted width once per overlay instance (no-op when the engine isn't configured). */\n private loadPanelWidthPref(): void {\n try {\n const pref = ParseSurfacePanelPref(UserInfoEngine.Instance.GetSetting(SURFACE_PANEL_PREF_KEY));\n if (pref) {\n this.userPanelWidth = pref.Width;\n // hostWidth() is 0 before first layout — the clamp then enforces only the\n // minimum, and the 70% cap re-applies on the next real drag.\n this.PanelWidthPx = ClampSurfacePanelWidth(pref.Width, this.hostWidth());\n this.cdr.markForCheck();\n }\n } catch {\n // UserInfoEngine not configured (plain-node tests / early bootstrap) — default tiers apply.\n }\n }\n\n /** Persists the width preference server-side (debounced); reset serializes {\"width\":null}. */\n private persistPanelWidth(width: number | null): void {\n try {\n UserInfoEngine.Instance.SetSettingDebounced(SURFACE_PANEL_PREF_KEY, SerializeSurfacePanelPref(width));\n } catch {\n // engine unavailable — width still applies for this session\n }\n }\n\n // ── Progressive disclosure (the console that grows with you) ────────────────\n\n /**\n * True while the PURE-AUDIO hero (the orb) owns the main column. Now reads from the\n * resolved view-model ({@link Ui}): the resolver decides hero-vs-thread from the\n * effective chrome + text intent + review, so host inputs (`[Chrome]`,\n * `[AllowTextReveal]`, the breakpoint) gate it. Review still always shows the thread.\n */\n public get ShowHero(): boolean {\n return this._ui.showHero;\n }\n\n /**\n * Whether the surface-panel area renders. Driven by the resolved {@link Ui.showSurfacePanel}\n * (console + earned + host's `[ShowSurfacePanel]`) OR review mode, which always carries the\n * panel. The Details toggle still earns the panel on demand (it flips `surfacePanelEarned`).\n */\n public get ShowPanelArea(): boolean {\n return this._ui.showSurfacePanel || this.IsReviewing;\n }\n\n /** The Details (tabs) toggle is offered while live — it's the panel's one door. */\n public get ShowDetailsControl(): boolean {\n return !this.IsReviewing;\n }\n\n /**\n * Whether the active-channels strip renders. Preserves the historical disclosure gate\n * (level 2+, {@link RealtimeDisclosureModel.ShowComposer}) AND honours the host's\n * `[ShowChannels]` input + the resolver's focus rule: a host that sets `[ShowChannels]`\n * false hard-disables the strip, and channel-focus mode hides it. The strip component\n * itself self-hides when no channels are active, so this stays decluttered.\n */\n public get ChannelStripVisible(): boolean {\n // Reads the RESOLVED Ui.showChannelStrip flag — which already ANDs the host's\n // [ShowChannels] input, an active channel, console chrome, and the no-focus rule.\n // In orb/compact chrome it is false, so the overlay never shows the \"CHANNELS · Voice\"\n // strip (the lean Calm-Orb surface). The strip component itself still self-hides when\n // no channels are active, keeping the console decluttered too.\n return this._ui.showChannelStrip;\n }\n\n /**\n * Whether the surface panel's Activity tab should be shown. Reads the resolved\n * {@link Ui.showActivityTab} (host's `[ShowActivityRail]` AND activity/review AND console)\n * OR review mode — a past session's activity is always relevant even before the resolver's\n * console gate would otherwise allow it.\n */\n public get ShowActivityTab(): boolean {\n return this._ui.showActivityTab || this.IsReviewing;\n }\n\n /** Reads the persisted disclosure milestones (tolerant; defaults to day one). */\n private loadDisclosurePref(): void {\n try {\n this.Disclosure.Load(UserInfoEngine.Instance.GetSetting(REALTIME_UX_PREF_KEY));\n } catch {\n // UserInfoEngine not configured (plain-node tests / early bootstrap) — day-one defaults.\n this.Disclosure.Load(null);\n }\n }\n\n /** Reads the persisted text-vs-orb preference (tolerant; default = voice-first OFF). */\n private loadCaptionsPref(): void {\n try {\n this.ShowCaptions = UserInfoEngine.Instance.GetSetting(RealtimeSessionOverlayComponent.captionsPrefKey) === 'true';\n } catch {\n // UserInfoEngine not configured — voice-first default applies.\n }\n }\n\n /** Persists the text-vs-orb preference (debounced, best-effort). */\n private persistCaptionsPref(): void {\n try {\n UserInfoEngine.Instance.SetSettingDebounced(RealtimeSessionOverlayComponent.captionsPrefKey, String(this.ShowCaptions));\n } catch {\n // engine unavailable — the preference still applies for this session\n }\n }\n\n /** Persists the disclosure milestones server-side (debounced, best-effort). */\n private persistDisclosure(serialized: string): void {\n try {\n UserInfoEngine.Instance.SetSettingDebounced(REALTIME_UX_PREF_KEY, serialized);\n } catch {\n // engine unavailable — the ratchet still applies for this browser session\n }\n }\n\n /**\n * Merged-state change: re-render only. DELIBERATELY no disclosure raise — per product\n * direction, content never flips the console open: a running delegation is narrated\n * aloud, a finished artifact lands as a GLOWING (unfocused) tab, and the ONLY thing\n * that auto-reveals is a channel's first agent activity (the whiteboard demands eyes).\n * A pure-audio user stays in pure audio until THEY ask for more.\n */\n private onSessionStateChanged(): void {\n // State.Cards drives the resolver's hasActivity signal — re-resolve (also marks for check).\n this.recomputeUi();\n }\n\n /**\n * The agent ACTED on a channel (a tool call routed to its local executor — e.g. the\n * first whiteboard write). THE ONE AUTO-REVEAL: the surface panel opens (as a peek —\n * the left column stays exactly as it was, pure audio included) with the channel's tab\n * focused and flashed, exactly once per channel — so the user discovers the board the\n * moment it comes alive. Disclosure levels are NOT raised: no text, no composer, no\n * extra chrome — just the board.\n */\n private onChannelActivity(plugin: BaseRealtimeChannelClient): void {\n if (this.IsReviewing || this.revealedChannelKeys.has(plugin.ChannelName)) {\n return;\n }\n this.revealedChannelKeys.add(plugin.ChannelName);\n if (plugin.ShowsAgentVideo) {\n this.revealPresenter(plugin);\n return;\n }\n this.DetailsPeek = true; // the panel shows via the same on-demand mechanism Details uses\n // FIRST USE: a non-whiteboard channel was tab-less until now — register its tab\n // SYNCHRONOUSLY (before the reveal/focus below) so the channel exists to be revealed.\n // The whiteboard already has its tab from session start; re-registering is idempotent.\n if (plugin.HasSurface()) {\n this.registerPluginChannelTab(plugin);\n }\n if (this.surfaceTabs) {\n // Stream handler (a tool call), not a change-detection pass — reveal synchronously\n // so the board is the visible tab the instant the agent's first stroke lands. The\n // microtask-deferred RegisterChannelTab above is ordered before this RevealChannel,\n // so the tab is in place when the focus lands.\n this.surfaceTabs.RevealChannel(plugin.ChannelName);\n } else {\n // Panel not rendered yet (the peek just created it) — reveal once it exists.\n this.pendingRevealKey = plugin.ChannelName;\n }\n // DetailsPeek flipped — surfacePanelEarned changed; re-resolve (marks for check).\n this.recomputeUi();\n }\n\n /**\n * The agent's video arrived: its channel's surface goes where its row places it (the stage is the agent's place in the\n * call) and gets its tab, where it can be moved from, without opening the panel: the video shows in the call itself.\n */\n private revealPresenter(plugin: BaseRealtimeChannelClient): void {\n if (plugin.HasSurface()) {\n this.registerPluginChannelTab(plugin);\n }\n this.recomputeUi();\n }\n\n /** Active$ edges: session start resets the volatile level; session end ratchets + persists. */\n private onActiveChanged(active: boolean): void {\n if (active && !this.prevActive) {\n this.Disclosure.BeginSession();\n this.DetailsPeek = false;\n this.ComposerOpen = false; // typing is opt-in per session (voice-first)\n this.revealedChannelKeys.clear();\n this.pendingRevealKey = null;\n this.startAudioVisualLoop();\n } else if (!active && this.prevActive) {\n this.persistDisclosure(this.Disclosure.RatchetOnSessionEnd());\n this.stopAudioVisualLoop();\n }\n this.prevActive = active;\n this.cdr.markForCheck();\n }\n\n // ── Audio-reactive visuals (the orb that vibrates like a speaker cone) ──────\n //\n // A requestAnimationFrame loop OUTSIDE Angular samples the client's audio meters\n // (RealtimeSessionService.GetAudioActivity → driver AnalyserNodes), runs the frame through\n // the smoothing state machine, and writes CSS custom properties + data attributes\n // straight onto the rendered overlay element — zero change detection per frame. CSS\n // gates on [data-audio-live]: with real metering the orb/EQ follow the waveform; when\n // the driver attached no meters the attribute stays 'false' and the turn-state-driven\n // keyframe animations keep working unchanged.\n\n /** Per-frame smoothing state (attack/decay envelopes + direction hysteresis). */\n private readonly audioSmoother = new RealtimeAudioVisualSmoother();\n private audioRafHandle: number | null = null;\n /** Last attribute values written (attributes are only touched on change). */\n private lastAudioLive: boolean | null = null;\n private lastDirection: RealtimeDirection | null = null;\n\n /** Starts the sampling loop (idempotent). Runs outside Angular — no CD per frame. */\n private startAudioVisualLoop(): void {\n if (this.audioRafHandle !== null || typeof requestAnimationFrame !== 'function') {\n return;\n }\n this.audioSmoother.Reset();\n this.ngZone.runOutsideAngular(() => {\n const tick = (): void => {\n this.audioRafHandle = requestAnimationFrame(tick);\n if (this.Hidden) {\n return; // minimized — skip the work, keep the loop armed\n }\n const frame = this.audioSmoother.Next(this.realtime.GetAudioActivity(), performance.now());\n this.applyAudioVisualFrame(frame);\n };\n this.audioRafHandle = requestAnimationFrame(tick);\n });\n }\n\n /** Stops the loop and returns the overlay to turn-state-driven animation. */\n private stopAudioVisualLoop(): void {\n if (this.audioRafHandle !== null) {\n cancelAnimationFrame(this.audioRafHandle);\n this.audioRafHandle = null;\n }\n this.audioSmoother.Reset();\n this.lastAudioLive = null;\n this.lastDirection = null;\n this.overlayElement()?.setAttribute('data-audio-live', 'false');\n }\n\n /** The rendered `.call-overlay` element (the :host is display:contents). */\n private overlayElement(): HTMLElement | null {\n const host = this.hostRef.nativeElement as HTMLElement;\n return (host.firstElementChild as HTMLElement | null) ?? null;\n }\n\n /** Writes one smoothed frame as CSS vars/attributes (attributes only on change). */\n private applyAudioVisualFrame(frame: RealtimeAudioVisualFrame | null): void {\n const el = this.overlayElement();\n if (!el) {\n return;\n }\n const live = frame !== null;\n if (live !== this.lastAudioLive) {\n this.lastAudioLive = live;\n el.setAttribute('data-audio-live', String(live));\n }\n if (!frame) {\n return;\n }\n el.style.setProperty('--voice-out', frame.OutputLevel.toFixed(3));\n el.style.setProperty('--voice-in', frame.InputLevel.toFixed(3));\n for (let i = 0; i < frame.Bins.length; i++) {\n el.style.setProperty(`--eq-${i + 1}`, frame.Bins[i].toFixed(3));\n }\n if (frame.Direction !== this.lastDirection) {\n this.lastDirection = frame.Direction;\n el.setAttribute('data-voice-dir', frame.Direction);\n }\n }\n\n /** The strip's Details control: peek at (or hide) the surface panel on demand. */\n public OnDetailsToggled(): void {\n this.DetailsPeek = !this.DetailsPeek;\n if (this.DetailsPeek) {\n // Land on the marquee surface (channels lead the strip; Activity is pinned last).\n setTimeout(() => this.surfaceTabs?.FocusFirstTab());\n }\n this.ControlInvoked.emit('surface');\n // DetailsPeek drives surfacePanelEarned — re-resolve (marks for check).\n this.recomputeUi();\n }\n\n /**\n * The gear popover picked an interface density — apply + persist + emit. `Simple` IS the\n * \"pure audio\" surface (the standalone headphones control was folded into the gear here): it\n * returns to the orb-only view AND makes it stick across refresh/next call, so picking it also\n * closes any open Details peek so the surface is genuinely orb-only — matching the old app-bar\n * \"Pure audio\" button exactly. In-session reveals (\"Show the conversation\", T-to-type, Details)\n * stay available and ephemeral; switching density back to Standard/Pro/Auto restores the console.\n */\n public OnDensityChanged(density: RealtimeUxDensity): void {\n this.Disclosure.SetDensity(density);\n this.persistDisclosure(SerializeUxMilestones(this.Disclosure.Milestones));\n if (density === 'simple') {\n this.DetailsPeek = false; // Simple = pure audio: collapse the surface peek back to the bare orb.\n }\n this.DensityChanged.emit(density);\n this.ControlInvoked.emit('density');\n // Density (and possibly DetailsPeek) changed — re-resolve (marks for check).\n this.recomputeUi();\n }\n\n /** The hero's \"Show the conversation\" affordance — turns the text preference on, and opens the thread even over the agent's video. */\n public OnTextReveal(): void {\n this.conversationShown = true;\n this.OnCaptionsToggled(true);\n this.TextRevealed.emit();\n this.ControlInvoked.emit('reveal-text');\n }\n\n /** App-bar Minimize: hide the call view (CSS) — the call stays fully live. */\n public OnMinimize(): void {\n this.realtime.SetMinimized(true);\n this.Minimized.emit();\n this.ControlInvoked.emit('minimize');\n }\n\n /** App-bar / strip End: tear the session down, then notify the host. */\n public async OnEndCall(): Promise<void> {\n this.ControlInvoked.emit('end');\n await this.realtime.EndRealtimeSession();\n this.Ended.emit();\n }\n\n /** Maps the realtime state onto the hero orb's `data-state` (active turn-states only). */\n public HeroOrbState(state: RealtimeConnectionState): RealtimeAgentOrbState {\n return AgentOrbStateFor(state);\n }\n\n /**\n * Why the call ended, when its client said so (a relayed call that reached its time limit): the label the banner and the\n * hero show in the `'error'` state in place of \"Connection error\"; `null` otherwise.\n */\n public get CallEndLabel(): string | null {\n return DescribeCallEnd(this.realtime.LastSessionError)?.Label ?? null;\n }\n\n /** Short first-person status line for the pure-audio hero. */\n public HeroStateLabel(state: RealtimeConnectionState): string {\n switch (state) {\n case 'speaking': return `${this.AgentName} is speaking…`;\n case 'thinking': return `${this.AgentName} is working…`;\n case 'listening': return 'Listening';\n case 'connecting': return 'Connecting…';\n case 'error': return this.CallEndLabel ?? 'Connection error';\n default: return 'On call';\n }\n }\n\n /**\n * TYPE-TO-COMPOSE: during a live call, pressing any single printable character (with nothing\n * focused) reveals the composer, raises disclosure to the engaged level, AND seeds that very\n * character into the draft — the user just starts typing and their first key is captured (the\n * old dedicated \"T\" key is gone; \"t\"/\"T\" now types like any other letter, and the visible\n * \"press T to type\" hint was removed in favour of this natural behaviour). Ignored while\n * review/minimized/inactive, with Ctrl/Cmd/Alt modifiers (don't hijack shortcuts), for\n * non-printable named keys (Enter/Tab/Arrow/Escape/F-keys → `key.length > 1`), for a bare\n * Space (ambiguous — no message starts with a space), or when an editable element / a\n * keyboard-capturing surface (the remote-browser canvas) already holds focus.\n */\n @HostListener('document:keydown', ['$event'])\n public OnDocumentKeydown(event: KeyboardEvent): void {\n if (this.Hidden || this.IsReviewing || !this.realtime.IsActive) {\n return;\n }\n if (event.metaKey || event.ctrlKey || event.altKey) {\n return;\n }\n if (event.key.length !== 1 || event.key === ' ') {\n return;\n }\n if (this.isEditableTarget(event.target) || this.isKeyboardCapturingSurfaceFocused()) {\n return;\n }\n event.preventDefault();\n const typedChar = event.key;\n this.OnComposerOpenChanged(true);\n // The dock may have just been created — seed the typed character + focus after this CD pass.\n setTimeout(() => this.composer?.AppendAndFocus(typedChar));\n }\n\n /**\n * True when the event target is a native text-editing element (an input, textarea, or contentEditable),\n * where a bare letter should type into that element — not trigger type-to-compose.\n *\n * @param eventTarget The keydown event's target.\n * @returns Whether the target is an editable element.\n */\n private isEditableTarget(eventTarget: EventTarget | null): boolean {\n const target = eventTarget as HTMLElement | null;\n return !!target && (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable);\n }\n\n /**\n * True when a surface that opts into capturing keyboard input currently holds focus — notably the Remote\n * Browser live canvas, which marks itself with `data-mj-capture-keys` while the user is driving it. When it\n * has focus, the overlay's global shortcuts (T-to-type) must stand down so the user's keystrokes land in the\n * remote browser, not the local composer. Decoupled by an attribute contract so the overlay needs no direct\n * reference to the surface component.\n *\n * @returns Whether a keyboard-capturing surface is focused.\n */\n private isKeyboardCapturingSurfaceFocused(): boolean {\n const active = (typeof document !== 'undefined' ? document.activeElement : null) as HTMLElement | null;\n return !!active && active.hasAttribute('data-mj-capture-keys');\n }\n\n /**\n * The composer dock opened (strip Type control / type-to-compose keystroke) or closed (the\n * dock's hide control). Opening raises the 'engaged' milestone for the cross-session ratchet —\n * but the dock itself stays a per-session, user-owned toggle either way.\n */\n public OnComposerOpenChanged(open: boolean): void {\n this.ComposerOpen = open;\n if (open) {\n this.Disclosure.Raise('engaged'); // emits Changed$ → recomputeUi()\n this.ControlInvoked.emit('type');\n setTimeout(() => this.composer?.FocusInput());\n }\n this.cdr.markForCheck();\n }\n\n ngOnDestroy(): void {\n this.stopAudioVisualLoop();\n this.stopResizeObserver();\n this.clearAvatarNoticeTimer();\n if (this.IsPanelResizing) {\n this.teardownPanelResize();\n this.IsPanelResizing = false;\n }\n for (const sub of this.subs) {\n sub.unsubscribe();\n }\n this.subs = [];\n this.State.Detach();\n }\n\n /**\n * Registers (or updates) an INTERACTIVE-CHANNEL tab on the surface panel. The overlay\n * calls it for every registry-resolved plugin; hosts may also call it for bespoke\n * template-based panes. Until a registration supplies a plugin / template, the tab\n * renders the \"coming online…\" placeholder (re-register the same `Key` to upgrade).\n * Safe to call before the panel has rendered — registrations are queued and flushed.\n */\n public RegisterChannelTab(registration: RealtimeChannelTabRegistration): void {\n if (this.surfaceTabs) {\n this.surfaceTabs.RegisterChannelTab(registration);\n } else {\n this.pendingChannelTabs.push(registration);\n }\n }\n\n /**\n * A done delegation card / rail entry asked to view a produced artifact's tab — an\n * EXPLICIT user request, so it may open the (otherwise Details-controlled) panel.\n */\n public OnOpenArtifactRequested(artifact: ParsedDelegationArtifact): void {\n if (this.surfaceTabs) {\n this.surfaceTabs.FocusArtifact(artifact);\n return;\n }\n // Panel hidden — open it (Details mechanism) and focus once it exists.\n this.DetailsPeek = true;\n this.cdr.markForCheck();\n setTimeout(() => this.surfaceTabs?.FocusArtifact(artifact));\n }\n\n /**\n * Registers a surface tab per active channel plugin THAT HAS A SURFACE — but ONLY for\n * channels already in play: the WHITEBOARD tabs immediately (a user may be the first to\n * draw), every OTHER channel stays tab-less until the agent first USES it (its first\n * {@link onChannelActivity}). This keeps the strip decluttered to surfaces actually in\n * play instead of pre-listing every registry-resolved channel.\n *\n * Server-only channels ({@link BaseRealtimeChannelClient.HasSurface} === `false`) render no\n * tab — their tools + perception are wired by the session service regardless.\n */\n private registerChannelTabs(channels: BaseRealtimeChannelClient[]): void {\n this.cleanupStaleReviewBoardTab(channels);\n for (const plugin of channels) {\n if (!plugin.HasSurface()) {\n continue; // server-only channel — no surface to tab.\n }\n if (!ShouldRegisterChannelTabUpFront(plugin.ChannelName, this.realtime.HasChannelBeenUsed(plugin.ChannelName))) {\n continue; // not the whiteboard and not used yet — it earns its tab on first activity.\n }\n this.registerPluginChannelTab(plugin);\n }\n this.cdr.markForCheck();\n }\n\n /**\n * The session's channel set changed: surfaces whose channel left are dropped (focus ends with a surface that leaves\n * the stage this way, while the user's move stays saved) and the channels in play get their tabs.\n */\n private onActiveChannelsChanged(channels: BaseRealtimeChannelClient[]): void {\n this.SurfaceStage.KeepOnly(channels);\n this.registerChannelTabs(channels);\n this.recomputeUi();\n }\n\n // ── Moving surfaces: \"Move to…\", saved per user ────────────────────────────\n\n /** The user moved a channel's surface (\"Move to…\", \"Bring it here\"). */\n public OnMoveRequested(move: MediaMoveRequest): void {\n this.moveSurface(move);\n }\n\n /** The user put every surface back where its channel places it (and every picture-in-picture box back in its corner). */\n public OnResetLayout(): void {\n this.SurfaceStage.ResetLayout();\n this.PipRects = new Map();\n this.layoutPrefs.SaveMoves(this.SurfaceStage.Moves);\n this.layoutPrefs.SavePipRects(this.PipRects);\n this.recomputeUi();\n }\n\n /** Where the user put each picture-in-picture box, by channel key, as fractions of the stage. */\n public PipRects: ReadonlyMap<string, MediaPipRect> = new Map();\n\n /** The user's saved layout of the call's surfaces, per user, under the call's own keys. */\n private readonly layoutPrefs = new MediaLayoutPrefs(() => UserInfoEngine.Instance, {\n Moves: SURFACE_PLACEMENT_PREF_KEY,\n PipRects: SURFACE_PIP_PREF_KEY,\n });\n\n /** The user moved or resized a picture-in-picture box: keep it and save it. */\n public OnPipRectChange(change: MediaStagePipRectChange): void {\n this.PipRects = RecordPipRect(this.PipRects, change.Key, change.Rect);\n this.layoutPrefs.SavePipRects(this.PipRects);\n }\n\n /** Moves a surface, saves the layout, and re-resolves the UI (a surface on the stage is the focus layout). */\n private moveSurface(move: MediaMoveRequest): void {\n if (!this.SurfaceStage.Move(move.Key, move.Placement)) {\n return;\n }\n this.layoutPrefs.SaveMoves(this.SurfaceStage.Moves);\n this.recomputeUi();\n }\n\n /**\n * Starts from the user's saved layout and picture-in-picture boxes. While `UserInfoEngine` is not configured (plain\n * node tests, early bootstrap), nothing is saved and every surface starts where its channel places it.\n */\n private loadPlacementPref(): void {\n this.SurfaceStage.LoadMoves(this.layoutPrefs.LoadMoves());\n this.PipRects = this.layoutPrefs.LoadPipRects();\n }\n\n /** Registers (or upgrades) one channel plugin's surface tab on the panel, and its surface on the stage. */\n private registerPluginChannelTab(plugin: BaseRealtimeChannelClient): void {\n this.SurfaceStage.Register(plugin);\n this.RegisterChannelTab({\n Key: plugin.ChannelName,\n Title: plugin.TabTitle,\n Icon: plugin.TabIcon,\n Color: plugin.TabColor,\n Plugin: plugin\n });\n }\n\n /**\n * REVIEW→LIVE continuation edge: when the resumed live session resolves its channel set\n * WITHOUT a Whiteboard channel, the review-registered read-only board tab is now a dead\n * surface — remove it (Activity regains focus if it was active). When the set HAS a\n * Whiteboard channel, the plugin registration above upgrades the same tab key in place,\n * so the review flag is simply released. Review ARTIFACT tabs are deliberately kept —\n * they are wanted carryover into the live session.\n */\n private cleanupStaleReviewBoardTab(channels: BaseRealtimeChannelClient[]): void {\n if (!this.reviewWhiteboardTabRegistered) {\n return;\n }\n if (ShouldRemoveReviewWhiteboardTab(this.realtime.IsActive, this.reviewWhiteboardTabRegistered, channels)) {\n this.surfaceTabs?.RemoveTab('Whiteboard');\n // Also drop a still-queued review registration (panel not rendered yet — rare but possible).\n this.pendingChannelTabs = this.pendingChannelTabs.filter(r => !(r.Key === 'Whiteboard' && r.Content));\n this.reviewWhiteboardTabRegistered = false;\n } else if (channels.some(c => c.ChannelName === 'Whiteboard')) {\n this.reviewWhiteboardTabRegistered = false; // live plugin owns the tab now (upgraded in place)\n }\n }\n\n /** Forwards channel registrations that arrived before the panel existed. */\n private flushPendingChannelTabs(): void {\n if (this.surfaceTabs && this.pendingChannelTabs.length > 0) {\n for (const reg of this.pendingChannelTabs) {\n this.surfaceTabs.RegisterChannelTab(reg);\n }\n this.pendingChannelTabs = [];\n }\n }\n\n /**\n * The captions toggle = the persisted text-vs-orb switch: on → the thread renders\n * (raising the text disclosure milestone); off → the orb hero owns the screen again,\n * at any level. Persisted per-user so the choice survives refresh and devices.\n */\n public OnCaptionsToggled(on: boolean): void {\n this.ShowCaptions = on;\n if (on) {\n this.Disclosure.Raise('text'); // emits Changed$ → recomputeUi()\n } else {\n this.conversationShown = false;\n }\n this.persistCaptionsPref();\n this.ControlInvoked.emit('captions');\n // ShowCaptions feeds the resolver's `textRevealed` signal (buildSignals), so BOTH directions must\n // re-resolve the view-model. Turning ON already recomputes via Disclosure.Raise → Changed$, but\n // turning OFF raises nothing — a bare markForCheck() would re-render against a STALE _ui (still\n // showThread=true / showHero=false), so the hero orb wouldn't return until the next unrelated\n // interaction recomputed. recomputeUi() rebuilds _ui from the current ShowCaptions and marks for\n // check itself; it's pure/idempotent, so the redundant call in the ON case is harmless.\n this.recomputeUi();\n }\n\n /** Reflect the gear toggle from the controls into the dev affordances. */\n public OnDevModeToggled(on: boolean): void {\n this.DevMode = on;\n this.ControlInvoked.emit('gear');\n // devMode drives the resolver's showDevLinks signal — re-resolve (marks for check).\n this.recomputeUi();\n }\n\n /** A dev link asked to open a delegated agent run record. */\n public OnOpenRunRequested(runId: string): void {\n this.requestNavigate('MJ: AI Agent Runs', runId);\n }\n\n /** The banner's dev link asked to open the live agent session record. */\n public OnOpenSessionRequested(sessionId: string): void {\n this.requestNavigate('MJ: AI Agent Sessions', sessionId);\n }\n\n // ── Session review mode ────────────────────────────────────────────────────\n\n /** Review banner convenience accessors (null-safe against the review data). */\n public get ReviewStartedAt(): Date | null {\n return this._reviewData?.StartedAt ?? null;\n }\n public get ReviewClosedAt(): Date | null {\n return this._reviewData?.ClosedAt ?? null;\n }\n public get ReviewCloseReason(): string | null {\n return this._reviewData?.CloseReason ?? null;\n }\n\n /** The reviewed session record's id — feeds the banner's dev \"Open session\" link. */\n public get ReviewSessionID(): string | null {\n return this._reviewData?.SessionID ?? null;\n }\n\n /**\n * Review controls: resume the reviewed session as a NEW live call (host handles the\n * start). Flags the upcoming ReviewData→null transition as a CONTINUATION so the\n * historical thread is kept (divider appended) instead of cleared.\n */\n public OnStartLive(): void {\n const review = this._reviewData;\n if (!review || !this.AllowStartLive) {\n return;\n }\n this.pendingLiveContinuation = true;\n this.StartLiveRequested.emit({\n TargetAgentId: review.TargetAgentID,\n ConversationId: review.ConversationID,\n LastSessionId: review.SessionID\n });\n }\n\n /** Review controls: close the review (host clears its review state). */\n public OnReviewClose(): void {\n this.ReviewClosed.emit();\n }\n\n /**\n * Enters review: replaces the shared state's thread with the historical items (all\n * chain legs, dividers between legs), names the cards after the reviewed agent,\n * rehydrates the saved whiteboard (when any), and registers the chain's history\n * ARTIFACTS as unfocused surface tabs.\n */\n private enterReview(review: RealtimeSessionReview): void {\n this.State.AgentName = review.AgentName;\n this.State.LoadHistoricalItems(BuildReviewThreadItems(review));\n this.ReviewWhiteboard = this.parseReviewWhiteboard(review);\n this.reviewArtifacts = review.Artifacts ?? [];\n this.ReviewCues = this.buildReviewCues(review);\n if (this.viewReady) {\n // Let this CD pass create/refresh the surface panel before registering the tabs.\n // ngZone.run is REQUIRED: review often opens through the deep-link/query-param\n // path (a plain RxJS stream outside Angular's zone) — without re-entering the\n // zone, the registration's markForCheck never gets a change-detection pass and\n // the Whiteboard tab stays invisible until the user's next click.\n setTimeout(() => this.ngZone.run(() => {\n this.registerReviewBoardTab();\n this.registerReviewArtifactTabs();\n this.registerReviewRecordingTab();\n }), 0);\n }\n // isReviewing flipped on — review always wants the console (marks for check).\n this.recomputeUi();\n }\n\n /**\n * Builds time-aligned {@link MediaTranscriptCue}s from the reviewed session's turns, for the\n * storage media player's transcript panel. Skips turns with no text; derives each cue's start from\n * `UtteranceStartMs`, falling back to (turn-created − recording-start) ms, else 0. Sorts by start.\n */\n private buildReviewCues(review: RealtimeSessionReview): MediaTranscriptCue[] {\n const startedAt = review.RecordingStartedAt;\n const cues: MediaTranscriptCue[] = [];\n (review.Turns ?? []).forEach((turn, index) => {\n const text = (turn.Text ?? turn.Message ?? '').trim();\n if (text.length === 0) {\n return;\n }\n cues.push({\n Id: turn.ID || `turn-${index}`,\n StartMs: this.reviewCueStartMs(turn, startedAt),\n EndMs: turn.UtteranceEndMs ?? undefined,\n SpeakerLabel: turn.Role === 'User' ? 'You' : review.AgentName,\n Text: text\n });\n });\n cues.sort((a, b) => a.StartMs - b.StartMs);\n return cues;\n }\n\n /** A review turn's media-relative start (ms): precise offset, else derived from t0, else 0. */\n private reviewCueStartMs(turn: RealtimeSessionReviewTurn, startedAt: Date | null): number {\n if (turn.UtteranceStartMs != null) {\n return turn.UtteranceStartMs;\n }\n if (startedAt && turn.__mj_CreatedAt) {\n return Math.max(0, turn.__mj_CreatedAt.getTime() - startedAt.getTime());\n }\n return 0;\n }\n\n /**\n * Leaves review. Two distinct exits:\n * - REVIEW→LIVE CONTINUATION ({@link OnStartLive} was clicked): KEEP the historical\n * thread and append the \"Resumed live session\" divider so the new live items read\n * as a new section of the same conversation. Artifact tabs are left in place — the\n * chain's artifacts carry into the live session.\n * - plain CLOSE: clear everything so the conversation view returns clean.\n */\n private exitReview(): void {\n this.ReviewWhiteboard = null;\n this.ReviewCues = [];\n if (this.reviewRecordingTabRegistered) {\n this.surfaceTabs?.RemoveTab('Recording');\n this.pendingChannelTabs = this.pendingChannelTabs.filter(r => r.Key !== 'Recording');\n this.reviewRecordingTabRegistered = false;\n }\n if (this.pendingLiveContinuation) {\n this.pendingLiveContinuation = false;\n this.State.StartLiveContinuation();\n } else {\n this.reviewArtifacts = [];\n this.State.Clear();\n }\n // isReviewing flipped off — re-resolve the chrome/gates (marks for check).\n this.recomputeUi();\n }\n\n /**\n * Surfaces the reviewed chain's history artifacts inside the Activity tab. In the redesign\n * there are no per-artifact tabs — the artifacts ride the {@link ReviewArtifacts} input into\n * the rail's \"Session artifacts\" group, so this only needs to ensure the Activity tab is\n * shown (it carries the carryover artifacts). Idempotent; no-op without any review artifacts.\n */\n private registerReviewArtifactTabs(): void {\n if (!this.surfaceTabs || this.reviewArtifacts.length === 0) {\n return;\n }\n // Show the Activity tab (where the carryover artifacts now live); RegisterArtifactTab\n // flips the gate on without opening any tab of its own.\n this.surfaceTabs.RegisterArtifactTab(this.reviewArtifacts[0], false);\n this.cdr.markForCheck();\n }\n\n /**\n * Rehydrates the reviewed session's saved Whiteboard channel state. TOLERANT: a missing\n * or malformed state returns null — review simply shows no whiteboard tab.\n */\n private parseReviewWhiteboard(review: RealtimeSessionReview): WhiteboardState | null {\n const channel = review.ChannelStates.find(c => c.ChannelName.toLowerCase() === 'whiteboard');\n if (!channel?.StateJson) {\n return null;\n }\n try {\n return WhiteboardState.FromJSON(channel.StateJson);\n } catch {\n console.warn('[RealtimeSessionReview] Saved whiteboard state was malformed — skipping the board tab.');\n return null;\n }\n }\n\n /**\n * Registers the read-only review whiteboard tab (no-op without a board / template) —\n * FOCUSED: the session's channel surface is what the reviewer came to see; the\n * Activity rail stays available but is never the default focus.\n */\n private registerReviewBoardTab(): void {\n if (!this.ReviewWhiteboard || !this.reviewBoardTpl) {\n return;\n }\n this.RegisterChannelTab({\n Key: 'Whiteboard',\n Title: 'Whiteboard',\n Icon: 'fa-solid fa-chalkboard',\n Content: this.reviewBoardTpl,\n Focus: true\n });\n this.reviewWhiteboardTabRegistered = true;\n this.cdr.markForCheck();\n }\n\n /**\n * Registers the read-only review RECORDING tab (the time-aligned storage media player) — ONLY when\n * the reviewed session carried a `RecordingFileID`. Idempotent (re-registering the same key updates\n * it in place). The player resolves the authenticated audio itself from the `RecordingFileID` and\n * shows its own no-access / loading states; the click-to-seek transcript is usable immediately.\n * NOT focused — the channel surface / Activity rail keeps the default focus.\n */\n private registerReviewRecordingTab(): void {\n if (!this._reviewData?.RecordingFileID || !this.recordingTpl) {\n return;\n }\n this.RegisterChannelTab({\n Key: 'Recording',\n Title: 'Recording',\n Icon: 'fa-solid fa-circle-play',\n Content: this.recordingTpl\n });\n this.reviewRecordingTabRegistered = true;\n this.cdr.markForCheck();\n }\n\n /**\n * A working delegation card's ✕ asked to cancel that delegated run — EXPLICIT user\n * intent (barge-in never cancels work, by deliberate policy). The service calls the\n * server cancel channel and flips the card to a failed \"Cancelled by user\" result.\n */\n public OnCancelDelegation(callId: string): void {\n void this.realtime.CancelDelegation(callId);\n }\n\n /** Minimizes the live call (it stays running) and asks the host to open the record. */\n private requestNavigate(entityName: string, recordId: string): void {\n this.realtime.SetMinimized(true);\n this.NavigateRequest.emit({ EntityName: entityName, RecordID: recordId });\n }\n\n // ── Focus layout + pill ────────────────────────────────────────────────────\n\n /**\n * A channel asked for the focus layout via its host context (the whiteboard's \"Move to stage\"): its surface moves to\n * the stage, or, when released, back where its channel places it.\n */\n private onChannelFocus(channel: BaseRealtimeChannelClient, focused: boolean): void {\n const key = channel.ChannelName;\n if (focused) {\n this.moveSurface({ Key: key, Placement: 'stage' });\n } else if (this.SurfaceStage.StageKey === key) {\n this.moveSurface({ Key: key, Placement: this.SurfaceStage.OffStagePlacement(key) });\n }\n }\n\n /** Focus pill: toggle the mic mute (routes through the overlay's single mute path). */\n public OnFocusPillMute(): void {\n this.ToggleMute();\n }\n\n /** Focus pill: leave focus mode: the surface on the stage goes back where its channel places it (show the thread column again). */\n public OnFocusPillExit(): void {\n const key = this.SurfaceStage.StageKey;\n // Route through the channel on the stage so ITS surface toggle stays in sync — it may\n // re-emit SetFocusMode(false) → onChannelFocus. Move it here too (idempotent), covering\n // channels that don't.\n this.StagePlugin?.RequestFocusExit();\n if (key) {\n this.moveSurface({ Key: key, Placement: this.SurfaceStage.OffStagePlacement(key) });\n }\n }\n\n /** Focus pill: end the call (mirrors the controls row's End button). */\n public async OnFocusPillEnd(): Promise<void> {\n await this.realtime.EndRealtimeSession();\n this.Ended.emit();\n }\n\n /** Short status line for the focus pill (first person — the co-agent owns the work). */\n public FocusStateLabel(state: RealtimeConnectionState): string {\n switch (state) {\n case 'speaking': return `${this.AgentName} is speaking…`;\n case 'thinking': return `${this.AgentName} is working…`;\n case 'listening': return 'Listening';\n case 'connecting': return 'Connecting…';\n default: return '';\n }\n }\n\n /**\n * The composer dock toggled the mic. Syncs the overlay's single {@link Muted} source (and\n * the focus pill) and surfaces the {@link MuteChanged} / {@link ControlInvoked} outputs.\n */\n public OnComposerMuteChanged(muted: boolean): void {\n if (muted !== this.Muted) {\n this.Muted = muted;\n this.FocusPillMuted = muted;\n this.cdr.markForCheck();\n }\n this.MuteChanged.emit(muted);\n this.ControlInvoked.emit('mute');\n }\n\n // ── Imperative API — drive the surface from a host via @ViewChild ────────────\n //\n // Each method maps to an existing internal handler/service so behaviour matches the\n // user clicking the corresponding control. See the package README's \"Methods\" table.\n\n /**\n * Override the chrome at runtime (equivalent to binding `[Chrome]`). Pass `'auto'` to\n * return to the size/intent-driven default.\n *\n * @param mode the chrome to force.\n * @example `voice.SetChrome('console');`\n */\n public SetChrome(mode: RealtimeChromeMode): void {\n this.setUiInput('chrome', mode);\n }\n\n /**\n * Reveal the transcript programmatically — the imperative twin of the orb's \"Show the\n * conversation\" affordance. Raises the text disclosure level, turns captions on, and\n * emits {@link TextRevealed}.\n */\n public RevealText(): void {\n this.OnTextReveal();\n }\n\n /**\n * Set the mic mute to an explicit state (no-op when already there). Drives the session\n * service, syncs every mute affordance, and emits {@link MuteChanged}.\n *\n * @param muted the desired muted state.\n */\n public SetMuted(muted: boolean): void {\n if (muted === this.Muted) {\n return;\n }\n this.ToggleMute();\n }\n\n /**\n * Toggle the mic mute. Drives the session service, syncs the overlay's {@link Muted}\n * source + the composer/focus-pill affordances, and emits {@link MuteChanged} +\n * {@link ControlInvoked}.\n */\n public ToggleMute(): void {\n this.Muted = this.realtime.ToggleMute();\n this.FocusPillMuted = this.Muted;\n this.MuteChanged.emit(this.Muted);\n this.ControlInvoked.emit('mute');\n this.cdr.markForCheck();\n }\n\n /**\n * Set captions (the text-vs-orb preference) to an explicit state. Persisted per-user;\n * turning them on also raises the text disclosure level.\n *\n * @param on whether captions/text should be shown.\n */\n public SetCaptions(on: boolean): void {\n if (on === this.ShowCaptions) {\n return;\n }\n this.OnCaptionsToggled(on);\n }\n\n /** Toggle captions (the text-vs-orb preference). */\n public ToggleCaptions(): void {\n this.OnCaptionsToggled(!this.ShowCaptions);\n }\n\n /**\n * Set the UX interface density (the gear's escape hatch). Applied + persisted immediately;\n * emits {@link DensityChanged}.\n *\n * @param density the density to apply.\n */\n public SetDensity(density: RealtimeUxDensity): void {\n this.OnDensityChanged(density);\n }\n\n /**\n * Open the surface panel (the on-demand Details peek), optionally focusing a specific\n * channel's tab. Equivalent to the strip's Details control plus a channel reveal.\n *\n * @param channelId when supplied, the channel tab to reveal once the panel is shown.\n */\n public OpenSurfacePanel(channelId?: string): void {\n if (!this.DetailsPeek) {\n this.DetailsPeek = true;\n this.ControlInvoked.emit('surface');\n this.recomputeUi();\n }\n setTimeout(() => {\n if (channelId) {\n this.surfaceTabs?.RevealChannel(channelId);\n } else {\n this.surfaceTabs?.FocusFirstTab();\n }\n });\n }\n\n /** Collapse the surface panel (hide the Details peek). No-op in review (always shown). */\n public CollapseSurfacePanel(): void {\n if (this.IsReviewing || !this.DetailsPeek) {\n return;\n }\n this.DetailsPeek = false;\n this.ControlInvoked.emit('surface');\n this.recomputeUi();\n }\n\n /** Minimize the call (it stays live) — the imperative twin of the app-bar Minimize. */\n public Minimize(): void {\n this.OnMinimize();\n }\n\n /** End the session (tear down the call) — the imperative twin of the End control. */\n public EndSession(): void {\n void this.OnEndCall();\n }\n}\n\n/** Whether a capture is on or on its way, as the composer's buttons show it. */\nfunction isCapturing(capture: RealtimeCaptureState): boolean {\n return capture.Status === 'on' || capture.Status === 'starting';\n}\n","@if (ConnectionState$ | async; as state) {\n <div class=\"call-overlay\"\n [class.call-overlay--hidden]=\"Hidden\"\n [class.call-overlay--review]=\"IsReviewing\"\n [class.board-focus]=\"ChannelFocusMode\"\n role=\"region\" [attr.aria-label]=\"IsReviewing ? 'Past session review' : 'Live voice session'\">\n\n <!-- PROGRESSIVE DISCLOSURE (the console that grows with you — Redesign A Progressive):\n level 0 is PURE AUDIO (the hero orb owns the main column; no thread, no composer;\n the strip's Details control peeks at the panels on demand); level 1 reveals the\n caption thread + captions control + type-to-type hint; level 2+ docks the composer\n and keeps the surface panel. CONTENT NEVER FLIPS THE CONSOLE OPEN: finished\n artifacts land as glowing unfocused tabs; the ONE auto-reveal is a channel's\n first agent activity (e.g. the first whiteboard write), which opens the panel as\n a peek with that tab focused — the left column stays exactly as it was.\n REVIEW always renders the full console. -->\n <div class=\"call-main\">\n <!-- The UNIFIED APP-BAR: identity + state + every session action (Redesign A). -->\n <mj-realtime-agent-banner\n [State]=\"state\"\n [Compact]=\"!IsReviewing && Ui.compact && Ui.chrome === 'orb'\"\n [HideState]=\"ShowHero && !PresenterOnStage\"\n [AgentName]=\"AgentName\"\n [ErrorLabel]=\"CallEndLabel\"\n [ModelName]=\"IsReviewing ? null : (ModelName$ | async)\"\n [DevMode]=\"DevMode\"\n [SessionID]=\"IsReviewing ? ReviewSessionID : SessionID\"\n [ReviewMode]=\"IsReviewing\"\n [ReviewStartedAt]=\"ReviewStartedAt\"\n [ReviewClosedAt]=\"ReviewClosedAt\"\n [ReviewCloseReason]=\"ReviewCloseReason\"\n [ShowGear]=\"!IsReviewing && Ui.showGear\"\n [ShowDensityPicker]=\"Ui.showDensityPicker\"\n [ShowMinimize]=\"!IsReviewing && Ui.showMinimize\"\n [ShowStartLive]=\"AllowStartLive\"\n [Density]=\"Disclosure.Milestones.Density\"\n (OpenSessionRequested)=\"OnOpenSessionRequested($event)\"\n (DevModeToggled)=\"OnDevModeToggled($event)\"\n (DensityChanged)=\"OnDensityChanged($event)\"\n (MinimizeRequested)=\"OnMinimize()\"\n (StartLiveRequested)=\"OnStartLive()\"\n (CloseRequested)=\"OnReviewClose()\">\n </mj-realtime-agent-banner>\n\n <!-- No microphone works: the call lost its microphone, so the agent hears nothing until the user picks one in the\n device menu. It stays for as long as that lasts, with no dismiss button, and goes once a microphone is on.\n Never in review. -->\n @if (MicrophoneNotice; as message) {\n <mj-alert class=\"call-microphone-notice\"\n Variant=\"warning\"\n Size=\"sm\"\n Icon=\"fa-solid fa-microphone-slash\"\n [Message]=\"message\">\n </mj-alert>\n }\n\n <!-- Why the call shows no avatar its agent asked for: once per call, from the moment it connects, until the user\n dismisses it or it hides itself after 10 s. Never in review. -->\n @if (AvatarNotice) {\n <mj-alert class=\"call-avatar-notice\"\n Variant=\"info\"\n Size=\"sm\"\n Icon=\"fa-solid fa-video-slash\"\n [Message]=\"AvatarNoticeMessage\"\n Dismissible\n (Dismissed)=\"OnAvatarNoticeDismissed()\">\n </mj-alert>\n }\n\n <!-- Ephemeral narration with no active working card to anchor to → under the banner -->\n @if (!IsReviewing && State.Narration && !State.ActiveCallId && Disclosure.ShowThread) {\n <div class=\"banner-live-note\" role=\"status\" aria-live=\"polite\">\n <i class=\"fa-solid fa-comment-dots\" aria-hidden=\"true\"></i>\n {{ State.Narration }}\n </div>\n }\n\n <!-- The agent's place above the thread in the console: the agent's video (the Avatar) lies over it while it presents.\n Outside the scrolling body, so it stays in view as the conversation grows. -->\n @if (!ShowHero) {\n <div class=\"call-presenter\" [class.call-presenter--on]=\"PresenterOnStage\" #presenterSlot></div>\n }\n\n <!-- While the call connects, the connecting screen takes the body, except from a hero the agent's video presents in:\n a resume on a new connection keeps that hero, so the video keeps its place and its last frame. -->\n <div class=\"call-body\" [class.call-body--hero]=\"ShowHero && !ShowConnectingScreen(state)\">\n @if (ShowConnectingScreen(state)) {\n <div class=\"call-connecting\">\n <mj-loading text=\"Connecting to the live session…\" size=\"medium\"></mj-loading>\n </div>\n } @else if (ShowHero) {\n <!-- PURE-AUDIO HERO (level 0): the orb IS the interface — it breathes with the\n audio inside expanding sound-wave rings; nothing to read, nothing to configure. -->\n <div class=\"hero\" [class.hero--presenting]=\"PresenterOnStage\" [attr.data-state]=\"state\" role=\"status\" aria-live=\"polite\">\n @if (!PresenterOnStage) {\n <mj-realtime-agent-orb class=\"hero__orb\" [State]=\"HeroOrbState(state)\"></mj-realtime-agent-orb>\n <div class=\"hero__eq\" aria-hidden=\"true\">\n <span></span><span></span><span></span><span></span><span></span>\n <span></span><span></span><span></span><span></span>\n </div>\n }\n <!-- The agent's place in the hero: the agent's video (the Avatar) lies over it while it presents. With\n captions on, the newest caption runs over the video's lower third, as subtitles do. Hidden from\n assistive technology: the conversation, a click away, is the accessible transcript, and this live\n region would read every word as it arrives. -->\n <div class=\"hero__presenter\" [class.hero__presenter--on]=\"PresenterOnStage\" #presenterSlot>\n @if (ShowAvatarCaptions && AvatarCaption; as caption) {\n <p class=\"hero__caption\" aria-hidden=\"true\">\n <span class=\"hero__caption-window\">\n <span class=\"hero__caption-lines\">\n @if (caption.Speaker) {\n <span class=\"hero__caption-speaker\">{{ caption.Speaker }}:</span>\n }\n {{ caption.Text }}\n </span>\n </span>\n </p>\n }\n </div>\n @if (!PresenterOnStage) {\n <div class=\"hero__name\">{{ AgentName }}</div>\n <div class=\"hero__sub\">{{ HeroStateLabel(state) }}</div>\n } @else {\n <!-- The agent's tile names it and says what it is doing; this live region still says it for screen readers. -->\n <span class=\"hero__sr\">{{ HeroStateLabel(state) }}</span>\n }\n @if (PresenterOnStage || !Ui.showCaptionsControl) {\n <button type=\"button\" class=\"hero__reveal\" (click)=\"OnTextReveal()\"\n title=\"Show the conversation as text\">\n <i class=\"fa-solid fa-closed-captioning\" aria-hidden=\"true\"></i>\n Show the conversation\n </button>\n }\n </div>\n } @else {\n <mj-realtime-session-thread\n [State]=\"State\"\n [AgentName]=\"AgentName\"\n [UserName]=\"CurrentUser?.Name || 'You'\"\n [ShowCaptions]=\"IsReviewing ? true : ShowCaptions\"\n [DevMode]=\"DevMode\"\n (OpenRunRequested)=\"OnOpenRunRequested($event)\"\n (OpenArtifactRequested)=\"OnOpenArtifactRequested($event)\"\n (CancelRequested)=\"OnCancelDelegation($event)\">\n </mj-realtime-session-thread>\n }\n </div>\n\n <!-- The call's controls along the foot of the column. The stage starts its picture-in-picture boxes clear of\n them, so a camera or a shared screen never opens over End call (#5408). Empty, so with no size, in review. -->\n <div class=\"call-controls\" #callControls>\n @if (!IsReviewing) {\n <!-- \"Agent can see\": what the agent is looking at, with a switch per source. Shown while the user\n captures camera/screen (or when [ShowPerceptionChip]=\"true\"). -->\n <mj-realtime-perception-chip [Sources]=\"VisibleVideoSources\"\n (SourceToggled)=\"OnVideoSourceToggled($event)\"\n (SourcePicked)=\"OnVideoSourcePicked($event)\">\n </mj-realtime-perception-chip>\n\n <!-- Active channels (earned with the console at level 2+, host-gated via [ShowChannels]).\n The strip component self-hides when there are no active channels. -->\n @if (ChannelStripVisible) {\n <mj-realtime-channel-strip></mj-realtime-channel-strip>\n }\n\n <!-- The BOTTOM DOCK: phone-call strip ⇄ fused minis+composer — the user's own\n two-way toggle (Type opens, hide closes), never level-forced. -->\n <mj-realtime-composer\n [Open]=\"ComposerOpen\"\n [Compact]=\"Ui.chrome === 'orb' || Ui.compact\"\n (OpenChanged)=\"OnComposerOpenChanged($event)\"\n [CaptionsOn]=\"ShowCaptions\"\n [IsMuted]=\"Muted\"\n [ShowCamera]=\"CaptureOffers.Camera\"\n [ShowShare]=\"CaptureOffers.Screen\"\n [CameraOn]=\"CameraOn\"\n [Sharing]=\"Sharing\"\n [SharePanels]=\"SharePanels\"\n [Devices]=\"CallDevices\"\n [SelectedMicrophoneID]=\"SelectedMicrophoneID\"\n [SelectedCameraID]=\"SelectedCameraID\"\n (CameraToggled)=\"OnCameraToggled($event)\"\n (ShareRequested)=\"OnShareRequested($event)\"\n (StopShareRequested)=\"OnStopShareRequested()\"\n (DeviceSelected)=\"OnDeviceSelected($event)\"\n [ShowDetails]=\"ShowDetailsControl\"\n [DetailsOn]=\"DetailsPeek\"\n (CaptionsToggled)=\"OnCaptionsToggled($event)\"\n (DetailsToggled)=\"OnDetailsToggled()\"\n (MuteChanged)=\"OnComposerMuteChanged($event)\"\n (EndRequested)=\"OnEndCall()\">\n </mj-realtime-composer>\n }\n </div>\n </div>\n\n <!-- RIGHT: TABBED SURFACE PANEL — disclosure-gated: it EXISTS once earned (level 2+,\n which the first delegation forces), peeked on demand via the strip's Details\n control, or always in review. Slides in from the right when it arrives — the\n panel's arrival IS the progress cue. -->\n @if (ShowPanelArea) {\n <!-- Resize handle (hidden while the panel is collapsed or a channel holds focus). -->\n @if (!PanelResizeDisabled) {\n <div class=\"call-resizer\"\n [class.call-resizer--active]=\"IsPanelResizing\"\n role=\"separator\" aria-orientation=\"vertical\"\n aria-label=\"Resize the surface panel (double-click to reset)\"\n title=\"Drag to resize • double-click to reset\"\n (mousedown)=\"OnPanelResizeStart($event)\"\n (dblclick)=\"OnPanelResizeReset()\"></div>\n }\n\n <div class=\"call-panel\" [style.width.px]=\"PanelAreaSize\">\n <mj-realtime-surface-tabs\n [State]=\"State\"\n [DevMode]=\"DevMode\"\n [CurrentUser]=\"CurrentUser\"\n [EnvironmentID]=\"EnvironmentID\"\n [ShowActivityTab]=\"ShowActivityTab\"\n [ExtraArtifacts]=\"ReviewArtifacts\"\n (OpenRunRequested)=\"OnOpenRunRequested($event)\"\n [Collapsed]=\"PanelCollapsed\"\n (CollapsedChange)=\"OnPanelCollapsedChange($event)\"\n (WideChanged)=\"OnPanelWideChanged($event)\"\n (ActiveChannelChange)=\"OnActiveChannelChange($event)\"\n (ChannelSlotChange)=\"OnChannelSlotChange($event)\"\n [SurfacePlacements]=\"SurfaceStage.Placements\"\n [AllowedPlacements]=\"SurfaceStage.AllowedPlacements\"\n (MoveRequested)=\"OnMoveRequested($event)\"\n (ResetLayoutRequested)=\"OnResetLayout()\">\n </mj-realtime-surface-tabs>\n </div>\n }\n\n <!-- THE STAGE: every channel surface lives here, in one layer over the overlay. A surface\n is created the first time it is seen, lies over its tab's slot while that tab is\n active, fills the overlay while its channel holds focus (or, for the agent's video,\n lies in the agent's place in the call), and otherwise waits out of sight — so\n collapsing the panel, switching tabs or entering focus never reloads it.\n The pane tells each channel when its surface goes out of sight, so it can pause.\n A channel that opts in (SurfaceShareable, such as the whiteboard) marks its frame as a panel the Share menu\n offers under \"This panel\" while it is on screen. A picture-in-picture box the user has not moved starts\n clear of the call's controls. -->\n <mj-media-stage class=\"call-stage\"\n [Surfaces]=\"SurfaceStage.Surfaces\"\n [TabSlot]=\"StageSlot?.Element ?? null\"\n [StageSlot]=\"StageSurfaceSlot\"\n [ActiveTabKey]=\"StageSlot?.Key ?? null\"\n [PipRects]=\"PipRects\"\n [PipKeepClear]=\"callControls\"\n (PipRectChange)=\"OnPipRectChange($event)\">\n <ng-template mjMediaStageSurface let-key let-visible=\"Visible\" let-placement=\"Placement\">\n @if (SurfaceStage.PluginFor(key); as plugin) {\n <div class=\"stage-frame\" role=\"region\" [attr.aria-label]=\"plugin.TabTitle\"\n [mjSharePanel]=\"plugin.SurfaceShareable ? plugin.TabTitle : null\" [mjSharePanelIcon]=\"plugin.TabIcon\">\n <mj-realtime-channel-pane [Plugin]=\"plugin\" [Visible]=\"visible\" [Placement]=\"placement\"></mj-realtime-channel-pane>\n <!-- A surface presenting the agent has no focus pill, so its \"Move to…\" menu rides on it. -->\n @if (placement === 'stage' && plugin.ShowsAgentVideo) {\n <mj-media-move-menu\n class=\"stage-presenter-move\"\n [Key]=\"key\"\n [Title]=\"plugin.TabTitle\"\n Placement=\"stage\"\n [Allowed]=\"SurfaceStage.AllowedFor(key)\"\n (MoveRequested)=\"OnMoveRequested($event)\"\n (ResetLayoutRequested)=\"OnResetLayout()\">\n </mj-media-move-menu>\n }\n </div>\n }\n </ng-template>\n <!-- A picture-in-picture box's bar carries the same \"Move to…\" menu. -->\n <ng-template mjMediaStagePipActions let-key>\n @if (SurfaceStage.PluginFor(key); as plugin) {\n <mj-media-move-menu\n [Key]=\"key\"\n [Title]=\"plugin.TabTitle\"\n Placement=\"pip\"\n [Allowed]=\"SurfaceStage.AllowedFor(key)\"\n (MoveRequested)=\"OnMoveRequested($event)\"\n (ResetLayoutRequested)=\"OnResetLayout()\">\n </mj-media-move-menu>\n }\n </ng-template>\n </mj-media-stage>\n\n <!-- FOCUS floating call pill: the main column is hidden, so the live call's\n identity + state + mute / show-thread / end controls ride over the surface. -->\n @if (!IsReviewing && ChannelFocusMode) {\n <div class=\"board-focus-pill\" role=\"status\" aria-label=\"Live call (board focus)\">\n <span class=\"board-focus-pill__orb\" [attr.data-state]=\"state\" aria-hidden=\"true\"></span>\n <span class=\"board-focus-pill__text\">\n <span class=\"board-focus-pill__name\">Voice for {{ AgentName }}</span>\n @if (FocusStateLabel(state); as label) {\n <span class=\"board-focus-pill__state\">{{ label }}</span>\n }\n </span>\n <button type=\"button\" class=\"board-focus-pill__btn\"\n [class.board-focus-pill__btn--active]=\"FocusPillMuted\"\n (click)=\"OnFocusPillMute()\"\n [title]=\"FocusPillMuted ? 'Unmute' : 'Mute'\"\n [attr.aria-label]=\"FocusPillMuted ? 'Unmute microphone' : 'Mute microphone'\">\n <i class=\"fa-solid\" [class.fa-microphone]=\"!FocusPillMuted\" [class.fa-microphone-slash]=\"FocusPillMuted\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" class=\"board-focus-pill__btn\"\n (click)=\"OnFocusPillExit()\"\n title=\"Show thread\" aria-label=\"Show the conversation thread\">\n <i class=\"fa-solid fa-table-columns\" aria-hidden=\"true\"></i>\n </button>\n @if (StagePlugin; as stagePlugin) {\n <mj-media-move-menu\n [Key]=\"stagePlugin.ChannelName\"\n [Title]=\"stagePlugin.TabTitle\"\n Placement=\"stage\"\n [Allowed]=\"SurfaceStage.AllowedFor(stagePlugin.ChannelName)\"\n (MoveRequested)=\"OnMoveRequested($event)\"\n (ResetLayoutRequested)=\"OnResetLayout()\">\n </mj-media-move-menu>\n }\n <button type=\"button\" class=\"board-focus-pill__btn board-focus-pill__btn--end\"\n (click)=\"OnFocusPillEnd()\"\n title=\"End call\" aria-label=\"End the call\">\n <i class=\"fa-solid fa-phone-slash\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n\n <!-- THE CAMERA CHECK: the first time the user turns the camera on in a call, they see it, and can pick another\n camera, before the agent does. Until they choose, the camera's own box says it is waiting. -->\n @if (CameraCheck; as camera) {\n <mj-realtime-camera-check-card\n [Camera]=\"camera\"\n [AgentName]=\"AgentName\"\n [Switch]=\"SwitchCheckedCamera\"\n (Confirmed)=\"OnCameraCheckConfirmed()\"\n (Declined)=\"OnCameraCheckDeclined()\">\n </mj-realtime-camera-check-card>\n }\n\n </div>\n}\n\n<!-- SESSION REVIEW whiteboard pane body: the reviewed session's saved board, rehydrated\n locally (WhiteboardState.FromJSON) and rendered READ-ONLY (pan/zoom only). Registered\n as a template-based channel tab ONLY when a parseable Whiteboard state exists. -->\n<ng-template #reviewBoardTpl>\n @if (ReviewWhiteboard; as board) {\n <!-- The board host positions itself absolutely — give it a filling, positioned frame. -->\n <div class=\"review-board-host\">\n <mj-realtime-whiteboard\n [State]=\"board\"\n [AgentName]=\"AgentName\"\n [ReadOnly]=\"true\">\n </mj-realtime-whiteboard>\n </div>\n }\n</ng-template>\n\n<!-- SESSION REVIEW recording pane body: the reviewed session's recorded audio synced to its\n transcript, replayed via the shared storage media player (click-to-seek transcript + playhead\n highlight). Registered as a template-based channel tab ONLY when the reviewed session carries a\n RecordingFileID; the player resolves the authenticated audio itself from that file id. -->\n<ng-template #recordingTpl>\n <div class=\"review-recording-host\">\n <mj-storage-media-player\n [FileID]=\"ReviewRecordingFileID\"\n [Transcript]=\"ReviewCues\"\n [Provider]=\"Provider\">\n </mj-storage-media-player>\n </div>\n</ng-template>\n"]}
|