Skip to content
Salyro
Tool

Chat messages builder

Build a messages array as cards — roles, text, images, tool calls and results — and get it in OpenAI, Anthropic and Gemini formats, checked as you build.

What it does

Build a conversation as a list of message cards, each with its role — system, developer, user or assistant — and its parts: text, images, and tool calls with their results. Beside it, the request body is written live in the format you choose: OpenAI Chat Completions, OpenAI Responses, Anthropic Messages or Gemini generateContent. Copy it, or switch format and see what changes. Everything runs in your browser: nothing you type or upload is sent anywhere.

How it builds

One conversation, every format. The cards are one conversation in the site's shared model of a conversation, and each format is written by the same writers the LLM request converter uses. What a format cannot express is listed with the output — an image detail level in Messages, that a tool result is an error in Chat Completions — and so is what it writes differently, such as a system message in the middle of a conversation, which Messages and Gemini can only hold with the system prompt.

Checked as you build. The output is read by the Conversation linter's own engine every time it changes, and its findings are listed with the output, linked to the rules they come from. The table under the output shows, for every format at once, the linter's errors, its warnings and notes, and what did not carry over.

Tool calls are paired by construction. A tool call's result is part of the call, not a message of its own. So a result always answers its call, is always written right after it — in one user turn with the others in Messages, as tool messages in Chat Completions, as function_call_output items in Responses — and moving a message moves its calls' results with it. Call ids (call_1, call_2, …) are the builder's own and never reused. A call names its tool, so renaming a tool renames every call to it, and a tool that is called cannot be removed. Every conversation the builder can hold is written in every format with no Conversation linter error; the tests hold it to that on thousands of generated conversations. That is about pairing, not a promise that a provider accepts every conversation: what it may not is reported below.

What the builder reports itself.

  • Errors: a tool name that is not letters, digits, _ or - (the builder's own conservative rule), two tools with one name, parameters that are not a JSON object.
  • Warnings: arguments that are not a JSON object; an image with no https: address; and no user or assistant message with content — only system messages, or nothing — which makes Messages and Gemini write an empty messages / contents list, which a provider is unlikely to accept.
  • Notes: an empty message, which is left out of the output; and a tool call that follows neither a user message nor another call's results — first in the conversation, or right after an assistant message with no call. Gemini is understood to expect a function call right after a user turn or a function response. This is not verified against Google's own page, which could not be read, so it is a note, not a rule.

Tokens. The input is counted by the token counter's layer for the model you choose: exact for OpenAI models, a marked estimate for the others, and a floor when something — an image — cannot be counted.

Using it from the keyboard

Every control is a native button, field or menu. A card moves with its Move up and Move down buttons, or with Alt+↑ and Alt+↓ while one of its buttons or its heading has focus — never by dragging. Each move is announced, and focus stays on what you used: on the button, or on the other one when the message reaches the top or the bottom. Removing a message moves focus to the next one, or to Add message when none is left.

Images

An image is an https: address, or a file from your computer. A file is read in your browser and kept in this page only: it is written into the output as base64, and it is never in a link. A link that holds a conversation with such an image says the image is missing, and the output leaves it out until you add the file again. An image address is written as it is — so the provider will fetch it — and Gemini takes it as fileData, which it must be able to read.

Sharing

A share link holds your messages and tools, after the # of the address. Your browser never sends that part to a server, but anyone you give the link to can read it — so the link never holds a credential (each is replaced by a placeholder) or an uploaded image's bytes. Share settings only leaves the messages and tools out. Structure only keeps the roles, order, calls and images, with every text replaced and every address dropped.

What it does not know

  • It builds the conversation, not the rest of the request: beyond the model and the output limit, no sampling parameters, tool choice or response format.
  • It does not send the request, so it cannot tell whether the model will answer it well — only that the conversation is well formed.
  • A Gemini request takes its model in the address, not the body.
  • The Conversation linter's OpenAI and Gemini rules are heuristics until their documentation can be read; its Anthropic rules quote Anthropic's pages.
  • It does not write cURL or SDK code.
  • Credential detection is best-effort. A link replaces the keys it finds, including keys hidden or split by invisible characters in the common ways, but an input built on purpose to evade the detector can still get past it. Never paste a secret into a conversation you share.

FAQ

Why can I not put a tool result in a message of its own?

Because a result belongs to one call. Holding it in the call is what makes an orphan result, a result for the wrong call, or a result in the wrong place impossible — the mistakes the Conversation linter finds most often.

A link never carries image bytes. Add the file again; it stays in the page until you close it.

Which format does Salyro accept?

Salyro's own API speaks the OpenAI Chat Completions and Responses formats. The builder writes the providers' formats too, for calling them directly.

Sources

The formats are written by the site's formats core, and checked by the Conversation linter, whose rules' sources are recorded as Reference Data (conversation-rules.json) and listed in the public tools' data freshness report. The token counts come from the token layer, and the model list from the catalogue Salyro publishes.

Where the numbers come from

  • Model and pricing data is a snapshot of the catalogue Salyro itself uses, taken when this site was built.
  • Facts about models and providers that are not in that catalogue carry their own source and the date they were checked, and are shown as unknown where no reliable source exists.