Mixins / foldkit-mixins-ui

ChatMessage

namespace · packages/mixins-ui/src/chatMessage.ts:1

export * as ChatMessage from './chatMessage.js'

In the guides

Members

ChatMessage.ChatMessageAction

interface · packages/mixins-ui/src/chatMessage.ts:61

interface ChatMessageAction<Message> {
  readonly key: string
  readonly label: string
  readonly icon?: Html | undefined
  readonly onClick: Message
  readonly pressed?: boolean | undefined
  readonly disabled?: boolean | undefined
}

One thing a message offers: copy, edit, regenerate, a thumb up.

ChatMessage.ChatMessageFrom

type · packages/mixins-ui/src/chatMessage.ts:49

type ChatMessageFrom = 'user' | 'assistant' | 'system'

Who a message is from: the user's own, an assistant's (or another person's), or the system's.

ChatMessage.ChatMessageGroupSlots

const · packages/mixins-ui/src/chatMessage.ts:220

const ChatMessageGroupSlots: Slots.Contract<{
  readonly root: Slot.UnnamedSlot<
    Capability.Capability<
      'Container',
      readonly [
        Capability.Capability<
          'Interactive',
          readonly [Capability.Capability<'Base', readonly []>]
        >,
      ]
    >,
    readonly Slot.EventName[],
    readonly Slot.AttributeName[],
    readonly Slot.RequirementName[],
    boolean
  >
}>

A run of messages: each ChatMessageSlots message, the root only their frame.

ChatMessage.ChatMessageGroupView

interface · packages/mixins-ui/src/chatMessage.ts:231

interface ChatMessageGroupView<Message = never> {
  readonly items: ReadonlyArray<ChatMessageItem<Message>>
  readonly continues?:
    | ((
        previous: ChatMessageItem<Message>,
        next: ChatMessageItem<Message>,
      ) => boolean)
    | undefined
  readonly style?: NamedStyle<typeof ChatMessageGroupSlots> | undefined
  readonly messageStyle?: NamedStyle<typeof ChatMessageSlots> | undefined
  readonly mixins?: MixinList<Message> | undefined
}

Messages in order, those that follow one by the same sender drawn as continued.

ChatMessage.ChatMessageItem

type · packages/mixins-ui/src/chatMessage.ts:225

type ChatMessageItem<Message> = Omit<
  ChatMessageView<Message>,
  'style' | 'mixins' | 'continued'
> & {
  readonly key: string
}

A message of a group, keyed; the group decides whether it continues the one before.

ChatMessage.ChatMessageSlots

const · packages/mixins-ui/src/chatMessage.ts:21

const ChatMessageSlots: Slots.Contract<{ readonly root: Slot.UnnamedSlot<Capability.Capability<"Container", readonly [Capability.Capability<"Interactive", readonly [Capability.Capability<"Base", readonly []>]>]>, readonly Slot.EventName[], readonly Slot.AttributeName[], readonly Slot.RequirementName[], boolean>; readonly avatar: Slot.UnnamedSlot<Capability.Capability<"Container", readonly [Capability.Capability<"Interactive", readonly [Capability.Capability<"Base", readonly []>]>]>, readonly Slot.EventName[], readonly Slot.AttributeName[], readonly Slot.RequirementName[], boolean>; readonly main: Slot.UnnamedSlot<Capability.Capability<"Container", readonly [Capability.Capability<"Interactive", readonly [Capability.Capability<"Base", readonly []>]>]>, readonly Slot.EventName[], readonly Slot.AttributeName[], readonly Slot.RequirementName[], boolean>; readonly header: Slot.UnnamedSlot<Capability.Capability<"Container", readonly [Capability.Capability<"Interactive", readonly [Capability.Capability<"Base", readonly []>]>]>, readonly Slot.EventName[], readonly Slot.AttributeName[], readonly Slot.RequirementName[], boolean>; readonly author: Slot.UnnamedSlot<Capability.Capability<"Container", readonly [Capability.Capability<"Interactive", readonly [Capability.Capability<"Base", readonly []>]>]>, readonly Slot.EventName[], readonly Slot.AttributeName[], readonly Slot.RequirementName[], boolean>; readonly time: Slot.UnnamedSlot<Capability.Capability<"Container", readonly [Capability.Capability<"Interactive" …;

A chat message publishes its regions as slots; it owns no state, messages or bundles. Who sent it, when, what it says, whether it reached the server, and what can be done with it are the application's, passed in each draw; a streamed answer is the same message drawn again with more content.

The root carries data-from (user, assistant, system), which the recipe reads to set the user's messages at the end in a bubble, and data-continued, data-status and data-streaming for a style. A message still streaming is aria-busy, so a log around it announces the answer once it is whole rather than word by word. The body holds the content: plain text, or Markdown rendered to Html (foldkit-richtext- markdown's parse, then foldkit-richtext-dom's renderDocument), which the recipe's content: 'markdown' spaces as Prose.

ChatMessage.ChatMessageStatus

type · packages/mixins-ui/src/chatMessage.ts:52

type ChatMessageStatus = 'sending' | 'sent' | 'failed'

Where a message the user sent stands: on its way, received, or refused.

ChatMessage.ChatMessageTime

interface · packages/mixins-ui/src/chatMessage.ts:75

interface ChatMessageTime {
  readonly at: string
  readonly label: string
}

When a message was sent: at for the machine (datetime), label for the reader.

ChatMessage.ChatMessageView

interface · packages/mixins-ui/src/chatMessage.ts:85

interface ChatMessageView<Message = never> {
  readonly from: ChatMessageFrom
  readonly content: Html | string
  readonly author?: string | undefined
  readonly avatar?: Html | undefined
  readonly time?: ChatMessageTime | undefined
  readonly status?: ChatMessageStatus | undefined
  readonly statusLabel?: string | undefined
  readonly onRetry?: Message | undefined
  readonly retryLabel?: string | undefined
  readonly actions?: ReadonlyArray<ChatMessageAction<Message>> | undefined
  readonly actionsLabel?: string | undefined
  readonly pinActions?: boolean | undefined
  readonly streaming?: boolean | undefined
  readonly continued?: boolean | undefined
  readonly style?: NamedStyle<typeof ChatMessageSlots> | undefined
  readonly mixins?: MixinList<Message> | undefined
}

A message in one call: who sent it and when, what it says, where it stands, what it offers, a style for its slots, and mixins beside the style. No upstream component stands behind it.

ChatMessage.group

function · packages/mixins-ui/src/chatMessage.ts:254

function group<Message = never>(
  options: ChatMessageGroupView<Message>,
  h: HtmlBuilder<Message>,
): Html

ChatMessage.view

function · packages/mixins-ui/src/chatMessage.ts:214

function view<Message = never>(
  options: ChatMessageView<Message>,
  h: HtmlBuilder<Message>,
): Html