Skip to content
Salyro
Tool

Function-calling flow simulator

Define tools, script the calls and results, and see the exact request every provider is sent at each step — linted, compared and priced. No model runs.

What it does

Define your tools, then write a script of what happens, step by step:

  • The user says something.
  • The model calls tools — one, or several at once, in parallel — and each tool returns a result, or reports an error.
  • The model answers.

A user step, or an answer before the last step, needs text: a message with empty content may be rejected by the provider, so the simulator asks you to fill it in before it writes the requests.

For every step, the simulator shows the exact request each API is sent next — OpenAI Chat Completions, OpenAI Responses, Anthropic Messages and Gemini generateContent — side by side. No model is called and no tool runs: every call and every result is the one you wrote. Everything runs in your browser.

It is the tool-call sequence done right, before the Conversation Linter has to find it done wrong: each call with an id, each result answering its call, in the place each format expects it.

What you see at each step

  • Added by this step, in each format: the items the step added to the request's message list, with their role or type as the request writes it, and the call ids that pair each result with its call.
  • Differs between formats, or Same shape in every format, written at the top of every step. Parallel calls are where the formats differ most: the simulator shows each writer's own layout rather than describing it.
  • What the writer changed: the notes each format's writer reports when it writes something in a different form — a tool result sent as a block in a user turn, a result joined to the previous one in a single turn, a text result wrapped in an object.
  • The Conversation Linter's verdict on each request, with every finding. Every request the simulator writes passes the linter with no error; the tests hold every step of every example, in every format, to that.
  • The request itself, to copy.

How it builds the requests

The script is first written in the shapes of Salyro's own Chat Completions API — a tool is a ChatCompletionTool, a call a ChatCompletionMessageToolCall with its arguments as a JSON string — and read into the one conversation model the site's format tools share. Each format's request is then written by that format's writer, the same code the request converter uses. So what a request looks like is always the writer's answer, never a description of it.

Each call gets an id of its own (call_1, call_2…), and its result carries the same id in every format. For Messages, the results of parallel calls go back together in one user turn: Anthropic's parallel tool use guide calls separate user messages "Wrong", and the Conversation Linter warns about them.

Each request names a model of its own provider: the one you chose for its format, and otherwise the first model of that provider in the catalogue.

Tools and their schemas

A tool is a name, a description and its parameters as JSON Schema, with or without strict. Each schema is checked by the JSON Schema compatibility checker, for every provider, with what each provider's own documentation says it accepts — and unknown where that documentation could not be read. The arguments you write for a call are checked to be a JSON object, not against the schema.

What the calls cost

Every model turn in the script is one request. Each is priced by the shared cost engine the site's cost calculators use — the catalogue's price in force for the model you choose, computed exactly as Salyro's own engine computes it — and the running total adds them up. A model with no price is "not priced", never $0.

The tokens come from the tokens layer: exact for the OpenAI models whose tokenizer runs in the browser, an estimate for the rest. A request's input is the content of every message before the model's turn, plus the tool definitions where their count is documented; its output is the model's own message. The tokens a provider adds around each message are not counted, so every figure is a lower bound, and says so.

Sharing

A share link holds your tools and script, after the # of the address. Your browser never sends that part to a server, but anyone you give the link to can read it. To share the flow without its content, choose Structure only: tools become tool_1, tool_2…, their parameters keep only their structure with fields renamed, every message and result is replaced, and arguments keep only their shape. The shared script writes requests of the same shape.

What it does not know

  • It runs no model and no tool. Whether a model would make the calls you scripted is not something it can tell.
  • It shows each format's request, not each provider's response to it.
  • It does not check arguments against the tool's schema, and it covers function tools only — not a provider's hosted tools or MCP.
  • Costs are for the content it can count, at list prices; caching, batch discounts and the tokens providers add around messages are not included.

FAQ

Why does a parallel call look different in each format?

Because each API expects the results in a different place. Look at "Added by this step": the simulator shows exactly which items each format's request holds.

Why does each call get an id like call_1?

A result names the call it answers by id, in every format that has ids. Giving every call its own is what lets each result find its call; two calls with one id is something the Conversation Linter warns about.

Is this a model playground?

No. No model is called. It shows the requests your application would send for the flow you wrote.

Sources

Every request is written by the site's formats core. The linter's rules and their sources, and the schema rules each provider documents, are Reference Data with the provider page and the date it was read, listed in the public tools' data freshness report. Prices are the catalogue's, from each provider's own pricing page.

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.