Message

In shortReference for the Message class and all content block types in the 10xGraph TypeScript client.

  • 10 min read
  • 10 sections
  • Updated
  • v0.9.2
  • Markdown

The Message class is the data model that 10xGraph uses to represent every message in a conversation — user inputs, assistant responses, tool calls, and tool results. It is defined in src/message.ts and exported from @10xscale/agentflow-client.


Import

TypeScript
import {
  Message,
  TextBlock,
  ImageBlock,
  AudioBlock,
  VideoBlock,
  DocumentBlock,
  DataBlock,
  ToolCallBlock,
  RemoteToolCallBlock,
  ToolResultBlock,
  ReasoningBlock,
  AnnotationBlock,
  ErrorBlock,
  MediaRef,
  AnnotationRef,
  TokenUsages,
} from '@10xscale/agentflow-client';

Message class

TypeScript
class Message {
  message_id: string | null;
  role: 'user' | 'assistant' | 'system' | 'tool';
  content: ContentBlock[];
  delta: boolean;
  tools_calls?: Record<string, any>[];
  timestamp: number;
  metadata: Record<string, any>;
  usages?: TokenUsages;
  raw?: Record<string, any>;

  constructor(
    role: 'user' | 'assistant' | 'system' | 'tool',
    content: ContentBlock[],
    message_id?: string | null
  );
}

Fields

Field Type Description
message_id string | null Server-assigned message ID. Use "0" or null when creating new messages — the server assigns the real ID.
role 'user' | 'assistant' | 'system' | 'tool' Who produced this message.
content ContentBlock[] Array of content blocks. A single message can have multiple blocks (e.g. text + image).
delta boolean true when this message is a streaming partial update rather than a final message. Set by the server.
tools_calls Record<string, any>[] Raw tool call array from the underlying LLM response. Populated by the server; do not set this manually.
timestamp number Unix timestamp in milliseconds when the message was created. Defaults to Date.now() at construction time.
metadata Record<string, any> Arbitrary key-value metadata you can attach to messages.
usages TokenUsages Token usage information returned by the LLM. Only present on assistant messages.
raw Record<string, any> The raw LLM response object, if the server passes it through. Useful for debugging.

Static factory methods

Message.text_message(content, role?, message_id?)

The most common way to create a message. Creates a Message with a single TextBlock.

TypeScript
const userMsg = Message.text_message('What is the capital of France?');
// role defaults to 'user'

const systemMsg = Message.text_message(
  'You are a helpful geography tutor.',
  'system'
);

Parameters:

Parameter Type Default Description
content string — The text content.
role 'user' | 'assistant' | 'system' | 'tool' 'user' The role for the message.
message_id string | null null Optional message ID. Use null to let the server assign one.

Message.tool_message(content, message_id?, meta?)

Creates a tool role message containing ToolResultBlock instances. Typically you do not create these manually — when you use remote tools the client creates them for you.

TypeScript
const toolResult = Message.tool_message([
  new ToolResultBlock({
    call_id: 'call_abc123',
    output: { result: 42 },
    status: 'completed',
    is_error: false,
  }),
]);

Message.withImage(text, imageUrl, role?)

Creates a user message containing a TextBlock followed by an ImageBlock. The image is referenced by URL, so pass either an http(s) URL the server can fetch or a data: URI with inline base64.

TypeScript
const msg = Message.withImage('Describe this', 'https://example.com/photo.jpg');
const inline = Message.withImage('Describe this', 'data:image/png;base64,iVBORw0...');

Parameters:

Parameter Type Default Description
text string — The prompt that accompanies the image.
imageUrl string — URL or data: URI. Stored as MediaRef with kind: 'url'.
role 'user' | 'assistant' | 'system' 'user' Role for the message. Note there is no 'tool' option here.

To attach an image you uploaded through client.uploadFile(), use Message.withFile() instead — it builds a file_id reference, which is what the server resolves at LLM-call time.

Message.withFile(text, fileId, mimeType?, role?)

Creates a message containing a TextBlock plus one media block referencing an uploaded file by id. The block type is picked from mimeType:

mimeType starts with Block created
image/ ImageBlock
audio/ AudioBlock
video/ VideoBlock
anything else, or omitted DocumentBlock
TypeScript
const upload = await client.uploadFile(pdfFile);
const msg = Message.withFile('Summarize this PDF', upload.data.file_id, 'application/pdf');

Parameters:

Parameter Type Default Description
text string — The prompt that accompanies the file.
fileId string — file_id from client.uploadFile() (response.data.file_id).
mimeType string undefined Used to select the block type and stored on the MediaRef. Omitting it produces a DocumentBlock.
role 'user' | 'assistant' | 'system' 'user' Role for the message.

Pass the real MIME type. Uploading a PNG and omitting mimeType produces a DocumentBlock, which is not what a vision model expects.

Message.multimodal(blocks, role?)

Creates a message from an arbitrary array of content blocks. Use it when the shape does not fit withImage or withFile: several images at once, an image between two pieces of text, or a mix of URL and file_id references.

TypeScript
const msg = Message.multimodal([
  new TextBlock('Which of these two rooms is brighter?'),
  new ImageBlock(new MediaRef('url', 'https://example.com/a.jpg')),
  new ImageBlock(new MediaRef('url', 'https://example.com/b.jpg')),
]);

Parameters:

Parameter Type Default Description
blocks ContentBlock[] — Blocks in the order the model should see them.
role 'user' | 'assistant' | 'system' 'user' Role for the message.

Instance methods

text()

Flattens the message’s content down to a single string. TextBlock blocks contribute their text; ToolResultBlock blocks contribute their output (stringified with JSON.stringify when it is not already a string). Every other block type contributes an empty string, so an image-only message returns ''.

TypeScript
const answer = result.messages.at(-1)?.text();

This is the method to use when rendering a reply, including for streaming deltas.

attach_media(media, as_type)

Appends one media block to an existing message’s content array, in place. Returns nothing.

TypeScript
const msg = Message.text_message('Compare these two charts');

msg.attach_media(new MediaRef('file_id', undefined, firstId, undefined, 'image/png'), 'image');
msg.attach_media(new MediaRef('file_id', undefined, secondId, undefined, 'image/png'), 'image');

Parameters:

Parameter Type Description
media MediaRef The reference to attach.
as_type 'image' | 'audio' | 'video' | 'document' Which block class to wrap it in. Any other value throws Unsupported media type: <value>.

The MediaRef constructor is positional — (kind, url, file_id, data_base64, mime_type, ...) — so a file_id reference needs undefined in the url slot. Assigning the fields by name is easier to read:

TypeScript
const media = new MediaRef('file_id');
media.file_id = upload.data.file_id;
media.mime_type = upload.data.mime_type;
msg.attach_media(media, 'image');

ContentBlock union type

The content field of a Message is an array of ContentBlock values. Each block has a type discriminant field. The full union is:

TypeScript
type ContentBlock =
  | TextBlock
  | ImageBlock
  | AudioBlock
  | VideoBlock
  | DocumentBlock
  | DataBlock
  | ToolCallBlock
  | RemoteToolCallBlock
  | ToolResultBlock
  | ReasoningBlock
  | AnnotationBlock
  | ErrorBlock;

Block types

TextBlock

Plain text content.

TypeScript
class TextBlock {
  type: 'text';
  text: string;
  annotations: AnnotationRef[];
}
TypeScript
const block = new TextBlock('Hello, world!');
Field Type Description
type 'text' Discriminant. Always 'text'.
text string The text content.
annotations AnnotationRef[] Optional citation or note annotations appended to this block.

ImageBlock

An image attached to a message.

TypeScript
class ImageBlock {
  type: 'image';
  media: MediaRef;
  alt_text?: string;
  bbox?: number[];
}
TypeScript
const block = new ImageBlock(
  new MediaRef('url', 'https://example.com/photo.jpg'),
  'A photo of a cat'
);
Field Type Description
type 'image' Discriminant.
media MediaRef Reference to the image data.
alt_text string Accessible alternative text.
bbox number[] Optional bounding box [x, y, w, h] within a parent image.

AudioBlock

An audio clip attached to a message.

TypeScript
class AudioBlock {
  type: 'audio';
  media: MediaRef;
  transcript?: string;
  sample_rate?: number;
  channels?: number;
}
Field Type Description
media MediaRef Reference to the audio data.
transcript string Optional pre-computed transcript of the audio.
sample_rate number Sample rate in Hz.
channels number Number of audio channels (1 = mono, 2 = stereo).

VideoBlock

A video clip attached to a message.

TypeScript
class VideoBlock {
  type: 'video';
  media: MediaRef;
  thumbnail?: MediaRef;
}

DocumentBlock

A document (PDF, DOCX, etc.) attached to a message.

TypeScript
class DocumentBlock {
  type: 'document';
  media: MediaRef;
  pages?: number[];
  excerpt?: string;
}
Field Type Description
pages number[] Which pages of the document are relevant (1-indexed).
excerpt string Optional extracted text excerpt from the document.

DataBlock

Raw binary or structured data encoded as base64 or referenced via MediaRef.

TypeScript
class DataBlock {
  type: 'data';
  mime_type: string;
  data_base64?: string;
  media?: MediaRef;
}

ToolCallBlock

Represents a tool/function call made by the assistant. Populated by the server; you typically do not create these manually.

TypeScript
class ToolCallBlock {
  type: 'tool_call';
  id: string;
  name: string;
  args: Record<string, any>;
  tool_type?: string;
}
Field Type Description
id string Unique ID for this tool call (used to match with ToolResultBlock.call_id).
name string Name of the tool to call.
args Record<string, any> Arguments to pass to the tool function.
tool_type string Optional tool type tag (e.g. 'mcp', 'function').

RemoteToolCallBlock

Like ToolCallBlock but specifically for tools that execute on the client side (browser). When the server needs the client to run a tool, it returns a message containing RemoteToolCallBlock entries. The client’s invoke() loop detects these, executes the registered handlers, and sends the results back.

TypeScript
class RemoteToolCallBlock {
  type: 'remote_tool_call';
  id: string;
  name: string;
  args: Record<string, any>;
  tool_type: string; // always 'remote'
}

You do not create these manually. They arrive from the server inside invoke() responses.


ToolResultBlock

The result of executing a tool call. When using remote tools the client creates these automatically. You only need to construct them manually if you are building custom tool-loop logic.

TypeScript
class ToolResultBlock {
  type: 'tool_result';
  call_id: string;
  output: any;
  is_error: boolean;
  status?: 'completed' | 'failed';
}

// Constructor takes an object:
new ToolResultBlock({
  call_id: 'call_abc123',
  output: { temperature: 22.5 },
  status: 'completed',
  is_error: false,
})
Field Type Description
call_id string Must match the id of the corresponding ToolCallBlock or RemoteToolCallBlock.
output any The return value of the tool function. Can be any JSON-serialisable value.
is_error boolean Set to true when the tool execution failed.
status 'completed' | 'failed' Status signal sent back to the server.

ReasoningBlock

Extended-thinking / chain-of-thought reasoning steps emitted by models that support it (e.g. Claude 3+).

TypeScript
class ReasoningBlock {
  type: 'reasoning';
  summary: string;
  details?: string[];
}
Field Type Description
summary string Short summary of the reasoning step.
details string[] Optional detailed reasoning steps.

AnnotationBlock

Citations or notes appended to message content.

TypeScript
class AnnotationBlock {
  type: 'annotation';
  kind: 'citation' | 'note';
  refs: AnnotationRef[];
  spans?: [number, number][];
}
Field Type Description
kind 'citation' | 'note' Whether this is a citation to a source or an inline note.
refs AnnotationRef[] List of sources or note references.
spans [number, number][] Character offset spans within TextBlock.text that this annotation covers.

ErrorBlock

Represents an error that occurred during graph execution, embedded in a message.

TypeScript
class ErrorBlock {
  type: 'error';
  message: string;
  code?: string;
  data?: Record<string, any>;
}

Helper types

MediaRef

A reference to a media file. Supports three kinds: an external URL, an uploaded file_id, or inline base64 data.

TypeScript
class MediaRef {
  kind: 'url' | 'file_id' | 'data';
  url?: string;               // when kind = 'url'
  file_id?: string;           // when kind = 'file_id'
  data_base64?: string;       // when kind = 'data'
  mime_type?: string;
  size_bytes?: number;
  sha256?: string;
  filename?: string;
  width?: number;
  height?: number;
  duration_ms?: number;
  page?: number;
}

Create a URL reference:

TypeScript
const media = new MediaRef('url', 'https://example.com/image.png');
media.mime_type = 'image/png';

Create a file_id reference (after uploading):

TypeScript
const uploaded = await client.uploadFile(file);
const media = new MediaRef('file_id');
media.file_id = uploaded.data.file_id;
media.mime_type = uploaded.data.mime_type;

AnnotationRef

A reference to a source or note target.

TypeScript
class AnnotationRef {
  url?: string;
  file_id?: string;
  page?: number;
  index?: number;
  title?: string;
}

TokenUsages

LLM token usage statistics attached to assistant messages.

TypeScript
class TokenUsages {
  completion_tokens: number;
  prompt_tokens: number;
  total_tokens: number;
  reasoning_tokens: number;
  cache_creation_input_tokens: number;
  cache_read_input_tokens: number;
  image_tokens?: number;
  audio_tokens?: number;
}

Complete example

TypeScript
import {
  Message,
  TextBlock,
  ImageBlock,
  MediaRef,
} from '@10xscale/agentflow-client';

// 1. Simple text message
const greeting = Message.text_message('Hello!');

// 2. Message with mixed text and image
const multimodal = new Message('user', [
  new TextBlock('What is in this image?'),
  new ImageBlock(
    new MediaRef('url', 'https://example.com/photo.jpg'),
    'A street photo'
  ),
]);

// 3. System prompt
const system = Message.text_message(
  'You are a helpful assistant. Be concise.',
  'system'
);

// 4. Send them to the agent
const result = await client.invoke([system, greeting]);
console.log(result.messages);

What you learned

  • Message has four roles: user, assistant, system, and tool.
  • content is always an array of typed ContentBlock objects.
  • Message.text_message() is the easiest way to create a plain text message.
  • RemoteToolCallBlock arrives from the server when a remote tool needs executing — the invoke() loop handles this automatically.
  • Use MediaRef with kind: 'file_id' to reference files you have uploaded via uploadFile().
  • Message.withImage(), Message.withFile(), and Message.multimodal() build multimodal messages without hand-assembling blocks; attach_media() adds one to a message you already have.
  • message.text() flattens content blocks to a string and is what you render for both final messages and streaming deltas.

Next step

See how-to/client/send-images-and-documents for the end-to-end upload-and-send flow, or reference/client/invoke to learn how to send messages and receive responses.

Last updated for v0.9.2Edit this page on GitHubReport an issue