Flows
What is a Flow?
Sección titulada «What is a Flow?»A Flow is a YAML orchestration graph for a digital worker. It says where a message, event, timer, webhook, or pub/sub payload enters, which component-backed steps run, and where the result goes next.
Flows are stored in .ygtc files. In day-to-day work you usually do not hand-author every node. The practical workflow is:
- Use
gtc wizardto create a bundle with providers, tenants, apps, and starter flows. - Use
greentic-flow wizardorgreentic-flow add-stepto add and update component-backed steps. - Use a coding agent to fetch the wizard schemas, fill the answer files, and run the CLI non-interactively.
- Use
greentic-flow doctorto validate the final flow and keep component resolve sidecars in sync.
Flow Shape
Sección titulada «Flow Shape»Modern Greentic flows use the YGTc v2 shape: nodes is a map, every node has one operation key, and routing declares where execution continues.
id: maintitle: Research Assistantdescription: Answer research questions from a chat message.type: messagingstart: answer_question
nodes: answer_question: component.exec: component: deep-research-analyst operation: answer question: "{{in.input.text}}" source_provider: webchat routing: - to: send_answer
send_answer: emit.response: messages: - type: text text: "{{prev.answer}}" routing: - out: trueThe important fields are:
| Field | Purpose |
|---|---|
id | Stable flow identifier. |
title / description | Human-readable summary for operators and tooling. |
type | Flow kind: messaging, webhook, timer, websocket, or pubsub. |
start | First node for the default entrypoint. |
entrypoints | Optional named entrypoints when one flow needs multiple starts. |
nodes | Named steps. Each step has one operation key plus optional routing, telemetry, retry, timeout, and metadata. |
A node is a single unit of work. The operation key determines what runs:
nodes: present_telco: component.exec: component: component-telco-present operation: present query: "{{in.input.text}}" metadata: "{{in.input.metadata}}" message: "{{in.input}}" source_provider: webchat routing: - to: respond_telcoCommon operation families include:
| Operation | Purpose |
|---|---|
component.exec | Call a WASM component operation. |
emit.response | Return one or more messages to the originating provider. |
template | Render a wizard/config fragment, often inside component dev flows. |
questions | Ask setup/config questions in component config flows. |
qa.process, mcp.exec, templating.handlebars | Component or adapter operations used by specific packs. |
Component-backed nodes normally come from component manifests and their dev_flows. For example, component-templates exposes a text operation and a config flow that can ask for the Handlebars text, output path, wrapping mode, and routing target. The CLI can use that contract to generate a valid node instead of making you remember the exact YAML shape.
Routing
Sección titulada «Routing»Routing is explicit and lives on each node:
routing: - to: send_responseTerminal routes finish the flow:
routing: - out: trueThe schema accepts explicit route arrays such as { to: next_node }, terminal output routes such as { out: true }, and reply routes such as { reply: true }. Prefer the forms produced by the wizard and demo bundles unless you are editing a flow by hand for a specific reason.
Conditional routing can be represented with route conditions:
routing: - to: approve_request condition: "prev.confidence >= 0.8" - to: escalate_request condition: "prev.confidence < 0.8"Inputs and Outputs
Sección titulada «Inputs and Outputs»Flows use template expressions to pass data between nodes:
| Expression | Meaning |
|---|---|
{{in}} | Current flow input envelope. |
{{in.input}} | Provider-specific inbound message or event payload. |
{{in.input.text}} | Common chat message text field. |
{{prev}} | Output from the previous node. |
{{prev.messages}} | Example output passed directly into emit.response. |
The Telco-X demo uses this pattern:
respond_telco: emit.response: messages: "{{prev.messages}}" routing: - out: trueThat keeps the presentation component responsible for producing provider-ready messages, while the flow only routes the output.
Messaging and Event Flows
Sección titulada «Messaging and Event Flows»Messaging flows usually start from chat extensions such as WebChat, Teams, Slack, Telegram, WhatsApp, Webex, or email. The deep research demo starts with an Adaptive Card menu, then routes either to a single research analyst or through a planner-and-analyst sequence:
id: maintitle: Deep Research Demodescription: Adaptive-card deep research flow with single-shot and agentic research modestype: messagingstart: main_menu
nodes: main_menu: component-adaptive-card.render: card_source: asset card_spec: asset_path: assets/cards/main_menu.json routing: - status: agentic to: research_planner - status: single_shot to: research_analyst - out: true
research_planner: component.exec: component: component-llm-openai operation: handle_message input: messages: - role: system content: "Turn the research goal into a focused plan." - role: user content: "{{entry.input.metadata.user_question}}" routing: - to: research_analyst
research_analyst: component.exec: component: component-llm-openai operation: handle_message input: messages: - role: system content: "Produce a concise final research report." - role: user content: "{{entry.input.metadata.user_question}}" routing: - to: show_final_report
show_final_report: component-adaptive-card.render: card_source: asset card_spec: asset_path: assets/cards/final_report.json routing: - out: trueEvent flows use the same graph model, but the entry payload comes from an event extension instead of a chat extension. Use webhook, timer, or pubsub as the flow type depending on the ingress.
Let the Wizard Build the Flow
Sección titulada «Let the Wizard Build the Flow»There are two wizard layers:
| Tool | Use it for |
|---|---|
gtc wizard | Creating the bundle: providers, tenants, apps, starter flows, assets, and setup scaffolding. |
greentic-flow wizard | Editing flows inside an existing pack or bundle through a declarative action plan. |
For a new bundle, start at the bundle level:
gtc wizard --answers deep-research-demo-create-answers.json --out ./deep-research-demoFor a flow inside an existing pack, let greentic-flow create or edit the .ygtc file:
greentic-flow new --flow flows/main.ygtc --id main --type messaging --name "Research Assistant"
greentic-flow add-step --flow flows/main.ygtc \ --node-id format_answer \ --component oci://ghcr.io/greenticai/components/templates:0.1.2 \ --operation text \ --mode config \ --routing-replyThe CLI handles the repetitive parts: node insertion, route rewiring, component manifest lookup, config-flow prompts, answer validation, and sidecar updates.
Coding Agent Workflow
Sección titulada «Coding Agent Workflow»Coding agents work best when they use the same schemas as the CLI instead of inventing YAML by hand.
Ask the agent to:
-
Inspect the existing flow and its sidecar.
-
Fetch the wizard plan schema:
Ventana de terminal greentic-flow wizard --schema -
Fetch the component answer schema for each component step:
Ventana de terminal greentic-flow component-schema oci://ghcr.io/greenticai/components/templates:0.1.2 --mode default -
Write a plan file with actions such as
add-flow,add-step,update-step, ordelete-step. -
Apply it non-interactively:
Ventana de terminal greentic-flow wizard ./my-pack --answers flow-plan.json -
Run validation:
Ventana de terminal greentic-flow doctor ./my-pack
This is the recommended path for larger changes. The agent can reason about the intent, but greentic-flow still performs the schema-aware mutations and catches invalid routing or missing answers.
Component Config Flows
Sección titulada «Component Config Flows»Components can ship dev_flows that describe how to create their own flow nodes. The component-templates pack includes:
id: ai.greentic.component-templates.customkind: component-configdescription: Auto-generated custom config for ai.greentic.component-templatesnodes: ask_config: questions: fields: - id: text prompt: Handlebars template used to render the reply type: string - id: output_path prompt: Dot path where the rendered string is stored type: string default: text - id: wrap prompt: Wrap output in an object when true; emit a raw string when false type: boolean default: true routing: - to: emit_configThat means a human, CI job, or coding agent can answer component-specific questions and let the component emit the correct component.exec node. This is why generated flows are safer than copying snippets from documentation.
Validation
Sección titulada «Validation»Validate flows before committing or packaging:
greentic-flow doctor flows/Useful related commands:
greentic-flow doctor --json flows/main.ygtcgreentic-flow answers --component ./component-templates --operation text --name templatesgreentic-flow doctor-answers --schema templates.schema.json --answers templates.example.jsongreentic-flow bind-component --flow flows/main.ygtc --step format_answer --component oci://ghcr.io/greenticai/components/templates:0.1.2 --writeBest Practices
Sección titulada «Best Practices»- Start with
gtc wizardor a demo bundle rather than a blank directory. - Use
greentic-flow wizardplans for multi-step changes. - Use
greentic-flow add-stepandupdate-stepfor component-backed nodes. - Keep node IDs stable and descriptive.
- Prefer component config flows and answer files over handwritten payloads.
- Commit
.ygtcfiles together with their.ygtc.resolve.jsonsidecars. - Use
--pinfor remote components when you need reproducible builds. - Run
greentic-flow doctorbefore packaging or deployment.
Next Steps
Sección titulada «Next Steps»- Packs - Package your flows for deployment
- Components - Create custom node types
- greentic-flow CLI - Command reference for flow tooling
- Flow Schema Reference - Complete YAML schema