Port types
A port has two independent axes. The first is the wire: whether the edge carries a trigger, a value or a token stream; those are hard rules, and an edge either connects or it does not. The second is the payload type: what the value actually is. The payload type is a soft signal. It tells the editor what to show, warns about a suspicious connection and enables coercion, but on its own it never forbids an edge.
The thirteen types
| Type | What it is | Example port |
|---|---|---|
any |
undeclared or unknown | the widget function’s output |
string |
text | text on the message node |
number |
floating-point number | — |
integer |
whole number | — |
boolean |
a flag | — |
object |
a structure: a JSON object; may carry a schema so the editor can expand its fields | the ai_agent output |
array |
a list of values | tasks_out on the agent plan node |
dataframe |
a table of rows and columns | the inputs and outputs of the df nodes |
message |
one chat message: role, text, attachments | the entry output, the ai_agent input |
messages |
a list of messages — the conversation | the chat_history output |
file |
a file reference: image, audio, document | the files input on exit |
bytes |
a binary payload | — |
binary |
a binary payload annotated with a MIME type | — |
A dash means no port in today’s catalog declares that type explicitly. Scalar types still
show up: when a port declares nothing, the primary output takes its type from the node’s
output schema, and everything else stays any. On the node reference pages the type of
each port is shown in the “Payload” column.
Compatibility
A pair of types counts as compatible — and the editor stays quiet — in these cases:
- either side is
any: nothing is known about that port; - the types are identical;
integerandnumberinterchange;string,messageandmessagesinterchange: a bare string becomes a message with the user role, and a message reads as its own text;filefeeds amessageormessagesinput — the file becomes an attachment;objectfeeds amessageormessagesinput — a computed object is coerced into a message just like a string;- the target is a
string: a template stringifies anything.
Everything else produces a port_type.mismatch warning naming both kinds. It is a warning:
such a graph can be saved and run, and when a converter exists for the pair, the message
suggests inserting a converter node.
Adapting a value
There are three kinds of adaptation, and they are not the same thing.
Implicit — the message family. String, message and list of messages convert into each
other on the spot, with nothing to configure: a message from entry
reads as plain text inside a template, and a string arrives at the message input of
ai_agent already wrapped as a user message.
Explicit — the convert node. It turns json, csv and
dataframe into one another; pick the source and target format in its configuration. The
csv ↔ json pair goes through dataframe. This is the only form of conversion visible
on the canvas: it becomes a graph step with its own timing and its own error.
Automatic — a flag on the edge. The engine can adapt a value to the target port’s type
by itself, but only when the edge explicitly carries coerce. It is absent by default and
the editor does not set it, so graphs drawn on the canvas rely on the first two forms. When
a conversion fails, the value travels on unchanged rather than failing the run.