Member Junction
    Preparing search index...

    Component for displaying a single message in a conversation Follows the dynamic rendering pattern from skip-chat for optimal performance This component is created dynamically via ViewContainerRef.createComponent()

    Hierarchy (View Summary)

    Implements

    • OnInit
    • AfterViewInit
    • OnDestroy
    • OnChanges
    • DoCheck
    Index

    Constructors

    Properties

    afterResponseFormSubmitted AfterResponseFormSubmitted AgentRun AgentRunDurationFormatted AllMessages AllowMessageDelete AllowMessageEdit AllowPinning AllowStopRun Artifact? artifactActionPerformed ArtifactActionPerformed artifactClicked ArtifactClicked Artifacts artifactVersion? AssistantAvatarFailed AssistantDisplayName attachmentClicked AttachmentClicked Attachments beforeResponseFormSubmitted BeforeResponseFormSubmitted BeforeStopClicked CanFork Conversation CurrentUser deleteClicked DeleteClicked DetailTasks diagnosticRequested DiagnosticRequested editClicked EditClicked EditedText EditingChanged EditOpenElsewhere EditResendRequested ElapsedTimeFormatted ExpandedWorkflowStepIds ForkChips ForkMarkerText ForkOpenRequested ForkRail ForkRequested InFlightCount InPlaceRole IsAgentDetailsExpanded IsEditing IsLastMessage IsLatestTurn IsProcessing IsStopping IsStreaming IsSupportingArtifactsExpanded IsWorkflowStepsExpanded LivenessCheckRequested message messageEdited MessageEdited MessageExtraTemplate messagePinToggled MessagePinToggled openEntityRecord OpenEntityRecord OriginatingWorkflowTask PendingArtifacts PendingReplace Provider Ratings? ReadOnly RegenerateRequested ResendInPlaceRequested retryClicked RetryClicked scrollToMessageRequested ScrollToMessageRequested ShowAgentRunDetails ShowMessageRating ShowReactions StopRequested suggestedResponseSelected SuggestedResponseSelected taskGraphPanelRequested TaskGraphPanelRequested testFeedbackClicked TestFeedbackClicked UserAvatarMap WorkflowElapsedFormatted ContinueMessage ɵdir ɵfac

    Accessors

    _agentRunDurationFormatted _elapsedTimeFormatted actionableCommands ActionableCommands agentRun agentRunDuration AgentRunDuration agentRunStepCount AgentRunStepCount agentRunTotalCost AgentRunTotalCost agentRunTotalTokens AgentRunTotalTokens aiAgentInfo AiAgentInfo allMessages allowMessageDelete allowMessageEdit allowPinning artifact artifacts assistantAvatarFailed assistantAvatarUrl AssistantAvatarUrl assistantDisplayName attachments CanContinueStoppedRun CanEdit CanRegenerate CanStartFork CanStopRun conversation currentUser detailTasks displayArtifacts DisplayArtifacts displayMessage DisplayMessage editedText EditHint EditMode EditNote EditSaveIcon EditSaveLabel effectiveAssistantAvatarUrl EffectiveAssistantAvatarUrl elapsedTimeSinceLoad ElapsedTimeSinceLoad engineAgentInfo formattedGenerationTime FormattedGenerationTime HasActiveWorkflowTasks hasAgentDetailsPanelContent HasAgentDetailsPanelContent hasAgentRun HasAgentRun hasArtifact HasArtifact hasAttachments HasAttachments imageAttachments ImageAttachments isAgentDetailsExpanded isAgentRunActive IsAgentRunActive isAIMessage IsAIMessage isConversationManager IsConversationManager isConversationOwner IsConversationOwner isEditing isFirstMessageInConversation IsFirstMessageInConversation isInProgressAIMessage IsInProgressAIMessage isLastMessage isLastMessageInConversation IsLastMessageInConversation isMessageEdited IsMessageEdited isProcessing IsStoppedRun isSystemArtifact IsSystemArtifact isUserMessage IsUserMessage LivenessState messageClasses MessageClasses messageExtraTemplate messageSenderName MessageSenderName messageStatus MessageStatus pendingArtifactPlaceholders PendingArtifactPlaceholders pendingArtifacts PrimaryArtifact ProviderToUse ratings RegenerateTitle responseForm ResponseForm RunQueryToUse RunViewToUse showAgentRunDetails showMessageRating showReactions ShowsActionGroup ShowsFooter ShowsFooterRegenerate ShowsHeaderRegenerate StoppedLineText SupportingArtifacts timePillText TimePillText userAvatarIconClass UserAvatarIconClass userAvatarMap userAvatarUrl UserAvatarUrl WasStoppedByUser WorkflowCompletedStepCount WorkflowDurationDisplay WorkflowParentTask WorkflowParentTaskID WorkflowProgressPercent WorkflowSkippedStepCount WorkflowStatus WorkflowSteps WorkflowTitle

    Methods

    Constructors

    Properties

    afterResponseFormSubmitted: EventEmitter<AfterResponseFormSubmittedEventArgs> = ...

    Use AfterResponseFormSubmitted.

    The same emitter under the old binding name, so a template still binding (afterResponseFormSubmitted) keeps working. Must stay AFTER AfterResponseFormSubmitted: class fields initialise in order, and the other way round this captures undefined.

    AfterResponseFormSubmitted: EventEmitter<AfterResponseFormSubmittedEventArgs> = ...

    Fired AFTER the response form's values have been submitted. Carries the form id (using the message ID as a stable per-message identifier) and the submitted values map. Not fired when beforeResponseFormSubmitted was canceled.

    AgentRun: MJAIAgentRunEntityExtended | null = null
    AgentRunDurationFormatted: string = '0:00'
    AllowMessageDelete: boolean = true

    Allow deleting the user's own messages (the per-message delete button).

    AllowMessageEdit: boolean = true

    Allow editing the user's own messages (the per-message edit button).

    AllowPinning: boolean = true

    Allow pinning messages (the per-message pin button).

    AllowStopRun: boolean = true

    Whether the Stop control is offered on an in-progress agent reply, and the Continue control on a stopped one. A host can turn stopping off for a surface without making the conversation read-only. Default true.

    Artifact?: MJArtifactEntity
    artifactActionPerformed: EventEmitter<{ action: string; artifactId: string }> = ...

    Use ArtifactActionPerformed.

    The same emitter under the old binding name, so a template still binding (artifactActionPerformed) keeps working. Must stay AFTER ArtifactActionPerformed: class fields initialise in order, and the other way round this captures undefined.

    ArtifactActionPerformed: EventEmitter<{ action: string; artifactId: string }> = ...
    artifactClicked: EventEmitter<{ artifactId: string; versionId?: string }> = ...

    Use ArtifactClicked.

    The same emitter under the old binding name, so a template still binding (artifactClicked) keeps working. Must stay AFTER ArtifactClicked: class fields initialise in order, and the other way round this captures undefined.

    ArtifactClicked: EventEmitter<{ artifactId: string; versionId?: string }> = ...
    Artifacts: MessageArtifactRef[] = []

    All distinct artifacts attached to this message, each at its latest version. Preferred over the single artifact/artifactVersion inputs above (which are retained for backward compatibility and kept pointed at the first entry).

    artifactVersion?: MJArtifactVersionEntity
    AssistantAvatarFailed: boolean = false

    The last assistantAvatarUrl failed to load — fall back to the icon branch.

    AssistantDisplayName: string | null = null

    Host override for the AI message display name (white-label persona). Null = the agent record's name.

    attachmentClicked: EventEmitter<MessageAttachment> = ...

    Use AttachmentClicked.

    The same emitter under the old binding name, so a template still binding (attachmentClicked) keeps working. Must stay AFTER AttachmentClicked: class fields initialise in order, and the other way round this captures undefined.

    AttachmentClicked: EventEmitter<MessageAttachment> = ...
    Attachments: MessageAttachment[] = []
    beforeResponseFormSubmitted: EventEmitter<BeforeResponseFormSubmittedEventArgs> = ...

    Use BeforeResponseFormSubmitted.

    The same emitter under the old binding name, so a template still binding (beforeResponseFormSubmitted) keeps working. Must stay AFTER BeforeResponseFormSubmitted: class fields initialise in order, and the other way round this captures undefined.

    BeforeResponseFormSubmitted: EventEmitter<BeforeResponseFormSubmittedEventArgs> = ...

    Cancelable — fired BEFORE the response form's values are sent back as a new conversation message. Listeners may set event.Cancel = true to halt the submission (e.g., a validation pass that finds required fields unfilled). When canceled, the corresponding afterResponseFormSubmitted event is NOT fired and suggestedResponseSelected is NOT emitted. Follows MJ's established Before/After cancelable event pattern.

    BeforeStopClicked: EventEmitter<BeforeStopClickedEventArgs> = ...

    Fired BEFORE a stop is requested, when the person clicks Stop on this in-progress agent reply. Listeners may set event.Cancel = true to keep the run going; the control then stays available and nothing else happens. Carries the reply's detail id and the run id when the chat has seen the run row.

    CanFork: boolean = true

    True when the person may start forks; false hides "Fork from here", and Edit and Regenerate then work in place (EditMode, InPlaceRole). Set by the message list.

    Conversation: MJConversationEntity | null
    CurrentUser: UserInfo
    deleteClicked: EventEmitter<MJConversationDetailEntity> = ...

    Use DeleteClicked.

    The same emitter under the old binding name, so a template still binding (deleteClicked) keeps working. Must stay AFTER DeleteClicked: class fields initialise in order, and the other way round this captures undefined.

    DeleteClicked: EventEmitter<MJConversationDetailEntity> = ...
    DetailTasks: MJTaskEntity[] = []
    diagnosticRequested: EventEmitter<string> = ...

    Use DiagnosticRequested.

    The same emitter under the old binding name, so a template still binding (diagnosticRequested) keeps working. Must stay AFTER DiagnosticRequested: class fields initialise in order, and the other way round this captures undefined.

    DiagnosticRequested: EventEmitter<string> = ...
    editClicked: EventEmitter<MJConversationDetailEntity> = ...

    Use EditClicked.

    The same emitter under the old binding name, so a template still binding (editClicked) keeps working. Must stay AFTER EditClicked: class fields initialise in order, and the other way round this captures undefined.

    EditClicked: EventEmitter<MJConversationDetailEntity> = ...
    EditedText: string = ''
    EditingChanged: EventEmitter<boolean> = ...

    Emits true when this row's inline editor opens and false when it closes.

    EditOpenElsewhere: boolean = false

    True while another message of the view is being edited; this row's footer then hides. Set by the message list.

    EditResendRequested: EventEmitter<
        { Message: MJConversationDetailEntity; NewText: string },
    > = ...

    Emits the edited text of this message; the host saves it as a new fork.

    ElapsedTimeFormatted: string = '0:00'
    ExpandedWorkflowStepIds: Set<string> = ...
    ForkChips: readonly MessageForkChip[] = EMPTY_FORK_CHIPS

    The chips under this message: the forks placed under it and, on a fork's first own message, the fork's alternatives (an original chip and the other forks of the replaced message). Set by the message list.

    ForkMarkerText: string | null = null

    The fork marker shown under this row (the last inherited row of a fork view); null for none. Set by the message list.

    ForkOpenRequested: EventEmitter<ForkChipOpenRequest> = ...

    A chip was clicked: the host opens that fork, or for an original chip, its view at the replaced message.

    ForkRail: "Inherited" | "Own" | null = null

    The rail a fork view draws this row on: 'Inherited' (faded, dashed) or 'Own' (solid); null in Main. Set by the message list.

    ForkRequested: EventEmitter<MJConversationDetailEntity> = ...

    "Fork from here" was clicked.

    InFlightCount: number = 0

    How many agent replies are in flight in the open view. The per-reply Stop control is offered only above one: with a single run the composer's send slot is the stop control, so a pill here would be a second control for the same thing. With several runs the pill is the only way to say which one, and the composer stops them all.

    InPlaceRole: "User" | "Answer" | null = null

    The row's role in the latest turn when forking is off: its user message ('User') or its answer ('Answer'); null otherwise. Set by the message list.

    IsAgentDetailsExpanded: boolean = false
    IsEditing: boolean = false
    IsLastMessage: boolean = false
    IsLatestTurn: boolean = false

    True for the latest user message and the last message of the view; their actions show labels. Set by the message list.

    IsProcessing: boolean = false
    IsStopping: boolean = false

    True from the moment Stop was clicked until the message leaves In-Progress, so the button reads "Stopping…" and cannot be clicked twice while the server catches up. Falls back to false after STOP_RETRY_AFTER_MS if the run is still going, so a stop that did not take (the row write was refused, the owning process is gone) can be tried again.

    IsStreaming: boolean = false

    Set by the list while this in-progress bubble shows streamed reply text rather than a status line. Rendered as the streaming class, which the stylesheet uses to lift the status cap.

    IsSupportingArtifactsExpanded: boolean = ...

    Whether the Supporting Artifacts grid is expanded when a message has multiple artifacts. Defaults to false (collapsed) when unset and persists the user's global preference via UserInfoEngine.

    IsWorkflowStepsExpanded: boolean = true

    Whether the completed workflow step list is expanded (always expanded while Running).

    LivenessCheckRequested: EventEmitter<string> = ...

    Raised when this message's run has gone quiet long enough that the displayed state may be fiction (MJ #4222). The parent answers by re-reading durable state; if the run really is alive its heartbeat advances and the pill returns to 'live' on the next tick.

    messageEdited: EventEmitter<MJConversationDetailEntity> = ...

    Use MessageEdited.

    The same emitter under the old binding name, so a template still binding (messageEdited) keeps working. Must stay AFTER MessageEdited: class fields initialise in order, and the other way round this captures undefined.

    MessageEdited: EventEmitter<MJConversationDetailEntity> = ...
    MessageExtraTemplate: TemplateRef<unknown> | null = null

    Optional additive per-message slot template (forwarded from chat-area's mjChatSlot="messageExtra"). Rendered inside the bubble after the message content, before attachments. Receives the message as $implicit + a named message context binding. Null when no consumer template is projected.

    messagePinToggled: EventEmitter<MJConversationDetailEntity> = ...

    Use MessagePinToggled.

    The same emitter under the old binding name, so a template still binding (messagePinToggled) keeps working. Must stay AFTER MessagePinToggled: class fields initialise in order, and the other way round this captures undefined.

    MessagePinToggled: EventEmitter<MJConversationDetailEntity> = ...
    openEntityRecord: EventEmitter<
        { compositeKey: CompositeKey; entityName: string },
    > = ...

    Use OpenEntityRecord.

    The same emitter under the old binding name, so a template still binding (openEntityRecord) keeps working. Must stay AFTER OpenEntityRecord: class fields initialise in order, and the other way round this captures undefined.

    OpenEntityRecord: EventEmitter<
        { compositeKey: CompositeKey; entityName: string },
    > = ...
    OriginatingWorkflowTask: MJTaskEntity | null = null

    When this message is a bottom continuation reply (this.message.ParentID points to the originating workflow message), holds the root MJ: Tasks row for that workflow so the UI can render a relational Workflow Context Header without string-parsing.

    PendingArtifacts: readonly MessagePendingArtifactRef[] = []

    Artifacts attached to this message whose entity rows have not arrived yet.

    The parent knows these synchronously — the message-to-artifact map is already in memory — while loading each artifact and version row is not. Without them the message rendered as finished with nothing where the image belonged, then the card appeared unannounced seconds later, which reads as "generation failed" rather than "still loading".

    Set alongside, not instead of, artifacts: on a message that already shows a report and is still loading an image, both render at once. Entries whose artifact has since loaded are filtered out by pendingArtifactPlaceholders.

    PendingReplace: boolean = false

    True for the answer that "Save and resend" will replace while that edit is open; the row dims. Set by the message list.

    Provider: IMetadataProvider | null

    If specified, this provider will be used for communication and for all metadata purposes. By default, if not provided, the Metadata and RunView classes are used for this and the default GraphQLDataProvider is used which is connected to the same back-end MJAPI instance as the Metadata and RunView classes. If you want to have this component connect to a different MJAPI back-end, create an instance of a ProviderBase sub-class like GraphQLDataProvider/etc, and configure it as appropriate to connect to the MJAPI back-end you want to use, and then pass it in here.

    Ratings?: RatingJSON[]
    ReadOnly: boolean = false

    Hides the response form and actionable commands on this message.

    RegenerateRequested: EventEmitter<MJConversationDetailEntity> = ...

    Emits this AI reply when the user asks for a new one; the host regenerates it on a new branch.

    ResendInPlaceRequested: EventEmitter<MJConversationDetailEntity> = ...

    Asks the host to rerun this user message's turn in place, after "Save and resend" saved the new text.

    retryClicked: EventEmitter<MJConversationDetailEntity> = ...

    Use RegenerateRequested.

    The same emitter under the old binding name, so a template still binding (retryClicked) keeps working. Must stay AFTER RetryClicked: class fields initialise in order, and the other way round this captures undefined.

    RetryClicked: EventEmitter<MJConversationDetailEntity> = ...

    Use RegenerateRequested.

    The same emitter under the old binding name, so a template still binding (RetryClicked) keeps working. Must stay AFTER RegenerateRequested: class fields initialise in order, and the other way round this captures undefined.

    scrollToMessageRequested: EventEmitter<string> = ...

    Use ScrollToMessageRequested.

    ScrollToMessageRequested: EventEmitter<string> = ...

    Fired when the user clicks the Workflow Context Header chip to jump to the originating workflow message (message.ParentID). Allows the virtualized message list / chat area to materialize off-screen messages before scrolling and highlighting.

    ShowAgentRunDetails: boolean = true

    Show the per-message agent run-detail grid (run ID, step/token counts, $ cost).

    ShowMessageRating: boolean = true

    Show the per-message thumbs rating control on completed AI messages.

    ShowReactions: boolean = true

    Show the per-message reaction buttons (like / comment).

    StopRequested: EventEmitter<MJConversationDetailEntity> = ...

    Fired when a stop was requested and no BeforeStopClicked listener canceled it. Carries the reply's conversation detail; the host resolves the run behind it, stops it, and fires its AfterStopClicked with the outcome.

    suggestedResponseSelected: EventEmitter<{ customInput?: string; text: string }> = ...

    Use SuggestedResponseSelected.

    The same emitter under the old binding name, so a template still binding (suggestedResponseSelected) keeps working. Must stay AFTER SuggestedResponseSelected: class fields initialise in order, and the other way round this captures undefined.

    SuggestedResponseSelected: EventEmitter<{ customInput?: string; text: string }> = ...
    taskGraphPanelRequested: EventEmitter<
        {
            isRunning: boolean;
            parentTaskId: string;
            workflowName: string;
            workflowTitle: string;
        },
    > = ...

    Use TaskGraphPanelRequested.

    TaskGraphPanelRequested: EventEmitter<
        {
            isRunning: boolean;
            parentTaskId: string;
            workflowName: string;
            workflowTitle: string;
        },
    > = ...

    Fired when the user clicks the Task Graph button on the inline workflow card to view the visual <mj-task-graph-run-view> flowchart in the conversation's right-side panel.

    testFeedbackClicked: EventEmitter<MJConversationDetailEntity> = ...

    Use TestFeedbackClicked.

    The same emitter under the old binding name, so a template still binding (testFeedbackClicked) keeps working. Must stay AFTER TestFeedbackClicked: class fields initialise in order, and the other way round this captures undefined.

    TestFeedbackClicked: EventEmitter<MJConversationDetailEntity> = ...
    UserAvatarMap: Map<
        string,
        { iconClass: string
        | null; imageUrl: string | null },
    > = ...
    WorkflowElapsedFormatted: string = '0:00'
    ContinueMessage: "Continue where you left off" = 'Continue where you left off'

    The message the Continue control sends; the next turn then resumes the stopped run.

    "ɵdir": unknown
    "ɵfac": ɵɵFactoryDeclaration<BaseAngularComponent, never>

    Accessors

    • get HasAgentDetailsPanelContent(): boolean

      Whether the agent-run gear's expanded panel would actually render anything — used to gate the gear button itself so it doesn't appear as a dead control that opens an empty popup. The panel hosts, in order: the run-details section (only when showAgentRunDetails), associated tasks, and (non-last messages only) the delete / rating / pin overflow. With showAgentRunDetails=false and none of those enabled — a white-labeled end-user surface — the gear vanishes entirely instead of opening onto nothing.

      Each arm below mirrors the corresponding template condition EXACTLY; keep them in lockstep with message-item.component.html's .agent-details-panel block.

      Defaults leave it unchanged: with showAgentRunDetails=true (the default) this is unconditionally true, so the gear renders exactly as before — including the pre-existing window where agentRun hasn't loaded yet and the panel is briefly empty. That window is deliberately preserved (byte-identical defaults) rather than fixed here.

      Returns boolean

    • get ProviderToUse(): IMetadataProvider

      Returns either the default Metadata provider or the one specified in the Provider property, if it was specified

      Returns IMetadataProvider

    • get RunQueryToUse(): IRunQueryProvider

      Returns either the default RunQuery provider or the one specified in the Provider property, if it was specified

      Returns IRunQueryProvider

    • get RunViewToUse(): IRunViewProvider

      Returns either the default RunView provider or the one specified in the Provider property, if it was specified

      Returns IRunViewProvider

    • get TimePillText(): string | null

      Unified time pill text for all AI message states Returns the appropriate time display based on message state:

      • Temporary messages (in-progress): Live elapsed time
      • Active agent runs / active workflow task graphs: Live duration (updated every second)
      • Completed messages: Final generation time (including any child workflow task graph)
      • Failed messages: Time before failure

      Returns string | null

    Methods

    • A callback method that is invoked immediately after the default change detector has checked data-bound properties if at least one has changed, and before the view and content children are checked.

      Parameters

      • _changes: { [propName: string]: SimpleChange<any> }

      Returns void