Graphs
A Graph in the TEN framework describes the data flow between extensions. It orchestrates how data moves from one extension to another, defining the participants and the flow of data between them. For example, you can route the output of a Speech-to-Text (STT) extension to a Large Language Model (LLM) extension for further processing.
The TEN framework supports four main types of data flows between extensions:
- Command
- Data
- Video Frame
- Audio Frame
By defining these data flows within a graph, you can create inter-extension communication and unidirectional data streams, particularly useful for handling audio and video data.
Graph types
There are two types of graphs in the TEN framework:
- Dynamic
- Predefined
| Dynamic | Predefined | |
|---|---|---|
| Graph starts | When the TEN app receives the start_graph command. | When the TEN app starts, or when the TEN app receives the start_graph command. |
| Graph content | Specified in the start_graph command. | Specified in the TEN app's properties. |
| Graph ID | A random UUID. | A random UUID |

For predefined graphs, there is an auto_start attribute that determines whether the predefined graph start automatically when the TEN app starts.
The singleton attribute determines if the predefined graph can create only one engine instance in the TEN app.
Graph ID and graph name
Each engine instance created from a graph definition in the TEN app has a unique UUID4 string identifier. This UUID4 string is called the graph ID.
You can assign a meaningful graph name to each predefined graph for easy reference. Use this name when specifying a particular predefined graph. When a predefined graph has the singleton attribute, only one graph instance can exist from this definition in the TEN app. The TEN runtime uses the graph name to identify this single instance.
Dynamic Graph
When the TEN app receives the start_graph command and creates a dynamic graph, it assigns a random UUID value as the ID of the newly started graph. Other clients can connect to this graph by obtaining this graph's ID.
Following is an example of a dynamic graph ID:
123e4567-e89b-12d3-a456-426614174000
Predefined Graph
Predefined graphs are very similar to dynamic graphs. The content of a dynamic graph is included in the start_graph command, while the content of a predefined graph is defined by the TEN app. Clients only need to specify the name of the predefined graph they want to start in the start_graph command.
Predefined graphs improve usability and protect information. They let clients use graphs without needing to know their detailed structure, either for simplicity or to restrict access to sensitive information.
Following is an example of a predefined graph name:
http-server
When a TEN app starts, predefined graphs that are set to auto-start are also initiated.
Graph Definition
Flexible and predefined graphs use the same definition format, as shown below:
Key points:
-
If there is only one app, you can omit the app field. If not, it must be specified. The TEN runtime uses
localhostas the default app value when the app field is not specified. -
The nodes field specifies the nodes within the graph, such as extensions, extension groups, etc.
-
Each node within the graph can only appear once in the nodes field. If it appears multiple times, the TEN framework throws an error, either during graph validation by the TEN manager or during graph validation by the TEN runtime.
-
Specify an extension group within the nodes field as follows.
The
propertyfield is optional. -
Specify an extension within the nodes field as follows.
The
propertyandaddonfields are optional.- If the
addonfield is present, it indicates that the extension is an instance generated by that addon. - If the
addonfield is not present, it indicates that the extension is not generated by an addon but is created by the corresponding extension group. In such cases, it is not necessary to explicitly define it in the nodes field. If you want to specify itspropertyfield, it must be explicitly defined in the nodes field.
- If the
-
The
connectionsfield specifies the connections between nodes within the graph.In each connection, the values for extension and extension group are strings representing the names of the corresponding nodes.
Following is a complete example:
Definition of predefined graphs
Place the complete graph definition under the predefined_graphs field in the app's properties. The predefined_graphs field also has its own attributes, such as name and auto_start.
Definition of the start_graph command
Place the complete graph definition above under the ten field in the start_graph command. The start_graph command also has its own attributes, such as type and seq_id.
The following is a complete definition of the start_graph command:
Specification for graph definition
-
Requirement for
nodesField: Thenodesarray is mandatory in a graph definition. Theconnectionsarray is optional but encouraged for defining inter-node communication. -
Validation of node
appfield: Never set theappfield tolocalhostunder any circumstances. In a single-app graph, do not specify theappURI. In a multi-app graph, the value of theappfield must match theten::urivalue defined in each app'sproperty.json. -
Node Uniqueness and Identification: Each node in the
nodesarray represents a specific extension instance within a group of an app, created by a specified addon. Therefore, each extension instance should be uniquely represented by a single node. A node must be uniquely identified by the combination ofapp,extension_group, andname. Multiple entries for the same extension instance are not allowed.cautionThe following example is invalid because it defines multiple nodes for the same extension instance:
-
Consistency of extension instance definition in connections: All extension instances referenced in the
connectionsfield, whether as a source or destination, must be explicitly defined in thenodesfield. Any instance not defined in thenodesarray causes validation errors.cautionThe following definition is invalid because the extension instance
ext_2is used in theconnectionsfield but is not defined in thenodesfield. -
Consolidation of Connection Definitions: Within the
connectionsarray, all messages related to the same source extension instance must be grouped within a single section. Splitting the information across multiple sections for the same source extension instance leads to inconsistencies and errors.cautionThe following example is incorrect because messages from
ext_1are divided into separate sections.The correct approach is to consolidate all messages for the same source extension instance into one section:
-
Consolidation of Destinations for Unique Messages: For each message within a specific type, such as
cmdordata, the destination extension instances must be grouped under a single entry for that message. Repeating the same message name with separate destinations leads to inconsistency and validation errors.cautionFor example, the following is incorrect due to separate entries for the message named
hello.The correct approach is to consolidate all destinations for the same message under a single entry:
However, messages with the same name can exist across different types, such as
cmdanddata, without causing conflicts.
For further examples, refer to the check graph command documentation within the TEN framework's tman.