This is an Alpha version still in active development; its structure, interfaces, and functionality are changing frequently as the design evolves. Join the GitHub discussions to help shape it.

đź’¬ Discussion: [PROPOSAL] Message body structure
đź’¬ Discussion: [PROPOSAL] Communication structure
đź’¬ Discussion: Agentic components - citations, artifacts, CoT, etc.

This page describes the core “message body” structure used in ACP.

Introduction

A message body consists of a series of parts, which may be “text”, “image”, or “artifact”, like int this example:

[
  {
    "type": "text",
    "content": "This is a cute cat:"
  },
  {
    "type": "image",
    "contentUrl": "https://s3.example.com/12345678901234567890/image.png"
  },
  {
    "type": "text",
    "content": "Would you like me to send more images of cats?"
  },
  {
    "type": "artifact",
    "name": "/sources/1",
    "contentUrl": "https://example.com/cat-facts"
  }
]
  • "text" parts provide their content inline
  • "image" parts provide a contentUrl where the content can be retrieved
  • "artifact" parts either provide a contentUrl like images, or they can be inlined by defining content, contentType (MIME type), and contentEncoding (which may be "plain" or "base64")

Parts form a full message by interleaving textual content with images and artifacts (which may serve as attachments, sources, recorded tool calls, etc.).

Next we provide a more formal specification of this structure, accompanied by more examples.

MessageBody

MessageBody consists of parts, each representing either text, an image, or an artifact. Text parts contain inline content, while images reference external content via a URL. Artifacts can either reference external content via a URL or contain inline content with an encoding. Only artifacts have names.

A message is an ordered list of parts. Text and images typically represent the main content, while artifacts serve as attachments, metadata, or additional resources.

interface MessageBodyPart {
    type: "text" | "image" | "artifact";
} & ({
    type: "text";
    content: string;
} | {
    type: "image";
    contentUrl: string;
} | {
    type: "artifact";
    name: string;
} & ({
    contentUrl: string;
} | {
    content: string;
    contentType?: string;
    contentEncoding: "plain" | "base64";
}))

type MessageBody = MessageBodyPart[];

MessageBodySchema

MessageBodySchema defines the types of parts expected in a message. It is simply a list of supported types from the set ["text", "image", "artifact"]. A message is valid if all its parts are of a type listed in the schema.

type MessageBodySchema = ("text" | "image" | "artifact")[];

Examples

Chat agent

A simple chat agent that only supports text responses:

["text"]

Example message:

[
  {
    "type": "text",
    "content": "Hello, world!"
  }
]

Multi-modal chat agent

A chat agent that can send text and images:

["text", "image"]

Example message:

[
  {
    "type": "text",
    "content": "This is a cute cat:"
  },
  {
    "type": "image",
    "contentUrl": "https://s3.example.com/12345678901234567890/image.png"
  },
  {
    "type": "text",
    "content": "Nice, huh?"
  }
]

Software-writing agent

An agent that generates text responses along with downloadable files:

["text", "artifact"]

Example message:

[
  {
    "type": "text",
    "content": "I have created a hello world project in Python."
  },
  {
    "type": "artifact",
    "name": "/files/hello_world.py",
    "contentUrl": "https://s3.example.com/12345678901234567890/hello_world.py"
  }
]

Researcher agent

An agent that provides a detailed write-up with images and references:

["text", "image", "artifact"]

Example message:

[
  {
    "type": "text",
    "content": "Cats are known to be [cute](source:1) and [funny](source:2)."
  },
  {
    "type": "image",
    "contentUrl": "https://s3.example.com/12345678901234567890/cat.png"
  },
  {
    "type": "artifact",
    "name": "/sources/1",
    "contentUrl": "https://example.com/cat-facts"
  },
  {
    "type": "artifact",
    "name": "/sources/2",
    "content": "https://example.com/it-came-to-me-in-a-dream",
    "contentEncoding": "plain"
  }
]

Why keep it simple?

Many schema formats, such as JSON Schema, introduce unnecessary complexity. This proposal keeps the structure minimal while still covering most use cases efficiently.