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;
  • integer and number interchange;
  • string, message and messages interchange: a bare string becomes a message with the user role, and a message reads as its own text;
  • file feeds a message or messages input — the file becomes an attachment;
  • object feeds a message or messages input — 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 csvjson 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.

What next