Message Types

TypeScript type definitions for chat messages and threads used in the Intercom component.

Note: This documentation presents the essential fields developers need to work with the Deva SDK. Additional fields that are handled internally by the SDK are not shown here. The types shown reflect the most commonly used properties for building applications.


Message

Chat message with author and thread information.

Interface

type Message = {
  id: string;
  text: string;
  author_type: ChatMessageAuthor;
  persona: Persona;
  created_at: string;
  in_reply_to?: Message | null;
  thread_id: string;
  persona_id: string;
};

Fields

id: string

  • Unique message identifier

  • Used for referencing and replies

text: string

  • Message content

  • Supports plain text and markdown

author_type: ChatMessageAuthor

persona: Persona

  • Message sender's persona

  • Contains username, avatar, display_name

created_at: string

  • Message creation timestamp (ISO 8601)

  • Used for message ordering

in_reply_to: Message | null | undefined

  • Message being replied to

  • Recursive structure for threaded conversations

  • null for top-level messages

thread_id: string

  • ID of the chat thread

persona_id: string

  • ID of the message sender

Usage

function MessageDisplay({ message }: { message: Message }) {
  const isUser = message.author_type === "USER";

  return (
    <div className={isUser ? "message-user" : "message-bot"}>
      <img src={message.persona.avatar} alt={message.persona.username} />
      <div>
        <strong>{message.persona.display_name}</strong>
        <time>{new Date(message.created_at).toLocaleString()}</time>
      </div>
      <p>{message.text}</p>
      {message.in_reply_to && (
        <div className="reply-context">
          Replying to: {message.in_reply_to.text}
        </div>
      )}
    </div>
  );
}

Thread

Chat thread with member information.

Interface

type Thread = {
  id: string;
  title: string;
  members: Persona[];
  is_direct_message: boolean;
  created_at: string;
  updated_at: string;
};

Fields

id: string

  • Unique thread identifier

title: string

  • Thread display name

  • Auto-generated for DMs (e.g., "Alice, Bob")

members: Persona[]

  • Array of thread participants

  • Includes full persona information

is_direct_message: boolean

  • true for 1-on-1 chats

  • false for group threads

created_at: string

  • Thread creation timestamp (ISO 8601)

updated_at: string

  • Last modification timestamp (ISO 8601)

Usage

Used internally by the Intercom component:

const { data: thread } = useSWRFetcher<Thread>(
  `${url}/api/sdk/chat/dm/${username}`
);

if (!thread) return <Loading />;

<div>
  <h3>{thread.title}</h3>
  <div className="members">
    {thread.members.map(member => (
      <img key={member.id} src={member.avatar} alt={member.username} />
    ))}
  </div>
  {thread.is_direct_message && <span>Direct Message</span>}
</div>

PaginatedMessages

Paginated list of messages.

Interface

type PaginatedMessages = {
  items: Message[];
  total: number;
};

Fields

items: Message[]

  • Array of message objects

  • Ordered newest to oldest

  • Limited by pagination

total: number

  • Total message count in thread

  • Used for "load more" functionality

Usage

Used internally by the Intercom component:

const { data: messages } = useSWRFetcher<PaginatedMessages>(
  `${url}/api/sdk/chat/${threadId}/messages?skip=${skip}&limit=20`
);

{messages?.items.map(message => (
  <MessageBubble key={message.id} message={message} />
))}

{messages && messages.total > messages.items.length && (
  <button onClick={loadMore}>Load More ({messages.total} total)</button>
)}

ChatMessageAuthor

Enum for message author types.

Type

type ChatMessageAuthor = "USER" | "BOT" | "SYSTEM";

Values

"USER"

  • Message sent by human user

  • Regular chat messages

"BOT"

  • Message sent by AI deva

  • Deva responses in conversations

"SYSTEM"

  • System-generated message

  • Notifications and status updates

Usage

function MessageBubble({ message }: { message: Message }) {
  if (message.author_type === "SYSTEM") {
    return <SystemNotification>{message.text}</SystemNotification>;
  }

  const isUser = message.author_type === "USER";

  return (
    <div className={isUser ? "user-message" : "bot-message"}>
      {message.text}
    </div>
  );
}

PostChatInput

Input type for creating chat messages.

Interface

type PostChatInput = {
  text: string;
  thread_id: string;
  in_reply_to_id?: string;
};

Fields

text: string

  • Message content to send (required)

thread_id: string

  • ID of the thread to post in (required)

in_reply_to_id: string | undefined

  • ID of message being replied to (optional)

Usage

Used internally by the Intercom component:

const sendMessage = async (text: string, threadId: string) => {
  const input: PostChatInput = {
    text,
    thread_id: threadId
  };

  const message = await fetcher<Message>(
    `${url}/api/sdk/chat/${threadId}/messages`,
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${accessToken}`,
      },
      body: JSON.stringify(input),
    }
  );

  return message;
};

ChatLLMQueryStreamTypes

Stream event types for real-time message streaming.

Type

type ChatLLMQueryStreamTypes =
  | "content"
  | "response_message"
  | "completion"
  | "error"
  | "llm_response";

Event Types

"content"

  • Partial text chunk during streaming

  • Sent multiple times as text generates

  • Accumulate chunks client-side

"response_message"

  • Complete message object

  • Sent once at end of stream

  • Contains full persisted message

"completion"

  • Stream completed successfully

  • No data payload

"error"

  • Stream encountered error

  • Contains error message

"llm_response"

  • Internal LLM processing event

Usage

Used internally by the Intercom streaming hook:

fetchEventSource(streamUrl, {
  method: "POST",
  onmessage: (msg) => {
    const type = msg.event as ChatLLMQueryStreamTypes;

    if (type === "content") {
      const chunk = JSON.parse(msg.data);
      accumulatedContent += chunk;
      setStreamingMessage({ text: accumulatedContent });
    }

    if (type === "response_message") {
      const finalMessage = JSON.parse(msg.data) as Message;
      setMessage(finalMessage);
      setIsDone(true);
    }

    if (type === "error") {
      console.error("Stream error:", msg.data);
      setError(new Error(msg.data));
    }
  }
});

Type Relationships

Thread
├── id: string
├── title: string
├── members: Persona[]
└── is_direct_message: boolean

Message
├── id: string
├── text: string
├── author_type: ChatMessageAuthor ("USER" | "BOT" | "SYSTEM")
├── persona: Persona
├── thread_id: string
└── in_reply_to?: Message

PaginatedMessages
├── items: Message[]
└── total: number

PostChatInput
├── text: string
├── thread_id: string
└── in_reply_to_id?: string

ChatLLMQueryStreamTypes
├── "content" (streaming text chunks)
├── "response_message" (final message)
├── "completion" (stream complete)
├── "error" (stream failed)
└── "llm_response" (internal)

Import

import type {
  Message,
  Thread,
  PaginatedMessages,
  ChatMessageAuthor,
  PostChatInput,
  ChatLLMQueryStreamTypes
} from "@bitplanet/deva-sdk";

Last updated