15 unstable releases (3 breaking)
Uses new Rust 2024
| new 0.4.3 | Dec 7, 2025 |
|---|---|
| 0.4.1 | Nov 19, 2025 |
| 0.3.4 | Nov 10, 2025 |
| 0.2.2 | Nov 3, 2025 |
| 0.1.5 | Oct 31, 2025 |
#376 in Database interfaces
503 downloads per month
Used in 22 crates
(6 directly)
76KB
2K
SLoC
Greentic Flow
Generic schema, loader, and intermediate representation for YGTC flows composed of self-describing component nodes.
Quickstart
use greentic_flow::{load_and_validate_bundle, resolve::resolve_parameters, loader, to_ir};
let yaml = std::fs::read_to_string("fixtures/weather_bot.ygtc")?;
let bundle = load_and_validate_bundle(&yaml, None)?;
println!("Bundle entry node: {}", bundle.entry);
let flow = loader::load_ygtc_from_str(&yaml, std::path::Path::new("schemas/ygtc.flow.schema.json"))?;
let ir = to_ir(flow)?;
let node = ir.nodes.get("forecast_weather").unwrap();
let resolved = resolve_parameters(&node.payload_expr, &ir.parameters, "nodes.forecast_weather")?;
# Ok::<_, greentic_flow::error::FlowError>(())
Design Highlights
- JSON Schema (
schemas/ygtc.flow.schema.json) enforces exactly one component key per node plus optional routing metadata. - Loader converts YAML documents to
FlowDoc, validates against the schema, extracts component metadata, and performs basic graph checks. - IR (
FlowIR) keeps nodes generic and serde-friendly so runtimes can post-process component payloads while exposingNodeKindclassification for adapters. NodeKind::Adapterrecognises node component strings shaped as<namespace>.<adapter>.<operation>and keeps the trailing segments joined so nested operations are preserved.resolve::resolve_parameterspre-resolves onlyparameters.*references, leaving other runtime bindings intact.startis optional; if omitted and aninnode exists, the loader defaultsstarttoin.
Adapter Registry Format
Adapter-backed nodes can be linted against an on-disk catalog that maps <namespace>.<adapter> pairs to the operations they expose. The registry is JSON by default, with optional TOML support via the toml feature.
{
"adapters": {
"messaging.telegram": ["sendMessage", "editMessage"],
"email.google": ["send", "draft.create"]
}
}
With the registry loaded, the adapter_resolvable rule reports any node whose component string cannot be found in the catalog.
Development
cargo fmt --checkcargo clippy -D warningscargo test
Fixtures under fixtures/ mirror common success and failure scenarios.
Run all CI-equivalent checks locally via:
LOCAL_CHECK_ONLINE=1 ci/local_check.sh
Toggles:
LOCAL_CHECK_ONLINE=1— enable networked checks (schema fetch, etc.)LOCAL_CHECK_STRICT=1— treat missing tools as immediate failures (default already fails required skips unlessLOCAL_CHECK_ALLOW_SKIP=1)LOCAL_CHECK_VERBOSE=1— echo each commandLOCAL_CHECK_ALLOW_SKIP=1— allow required CI steps to be skipped (not recommended)
CLI
Flow scaffolding
greentic-flow ships with a lightweight scaffolder for new .ygtc files:
cargo run --bin greentic-flow -- new flows/demo.ygtc --kind messaging
Flags of note:
--kind messaging|events|deploymentcontrols the template.--kind deploymentis just sugar fortype: eventsplus a first node that assumes access to thegreentic:deploy-plan@1.0.0world.--deploymentaliases--kind deployment.--pack-manifest <path>(or a localmanifest.yamlif no flag is provided) lets the tool peek at pack metadata. It will:- default
--kindtodeploymentwhen the pack declareskind: deployment, - append the new flow to the manifest's
flows:array (path stored relative to the manifest directory), and - emit informational hints (for example, when a deployment pack scaffolds a messaging flow anyway).
- default
--id,--description, and--forcecover the usual ergonomics.
Running the command writes a ready-to-edit .ygtc file and reports any hints.
Flow linting
Run cargo run --bin ygtc-lint -- <paths> to validate flows. Example:
cargo run --bin ygtc-lint -- fixtures --schema schemas/ygtc.flow.schema.json
To enable adapter linting, provide --registry:
cargo run --bin ygtc-lint -- \
--schema schemas/ygtc.flow.schema.json \
--registry tests/data/registry_ok.json \
tests/data/flow_ok.ygtc
For machine-readable CI, use --json; the command exits non-zero on any error and
prints the validated bundle plus diagnostics:
cargo run --quiet --bin ygtc-lint -- --json tests/data/flow_ok.ygtc
# { "ok": true, "bundle": { "id": "flow_ok", ... } }
Pipelines can also stream flows via stdin:
cat tests/data/flow_ok.ygtc | cargo run --quiet --bin ygtc-lint -- --json --stdin
And in CI you can assert the BLAKE3 hash is present:
ygtc-lint --json --stdin < flow.ygtc | jq -e '.ok and .hash_blake3 != null'
The CLI recursively walks any directories provided, only inspecting files with a .ygtc extension. Schema validation always runs; adapter checks are additive when a registry is supplied.
The shared flow schema is published from this repository at
https://raw.githubusercontent.com/greentic-ai/greentic-flow/refs/heads/master/schemas/ygtc.flow.schema.json
and matches the $id embedded in schemas/ygtc.flow.schema.json.
Config flows (convention)
A config flow is a regular flow whose kind may be component-config (or any other string) and whose final node emits a payload shaped as:
{ "node_id": "some_step", "node": { /* full node object with one component key plus routing */ } }
Tools like greentic-dev can execute these flows and splice the emitted node into another flow. The engine itself does not special-case config flows: node components such as questions (prompting for values) and template (rendering a JSON template) are handled like any other component.
For lightweight automation in this crate, config_flow::run_config_flow can execute simple config flows by seeding answers for questions fields and rendering the final template payload into { node_id, node }.
Deployment flows (events-based)
Deployment flows are standard type: events flows that operate on a
DeploymentPlan provided by hosting tooling. Use
greentic-flow new flows/deploy_stack.ygtc --kind deployment
to scaffold one quickly. The template creates a first node that highlights the
greentic:deploy-plan@1.0.0 world so the component can read the plan and emit
status updates. Node IDs and component kinds remain opaque strings; nothing in
this crate hard-codes provider-specific behaviour.
See docs/deployment-flows.md for a deeper dive
covering plan access, CLI helpers, and authoring guidelines.
A pack may declare kind: deployment in its manifest to signal that most of its
flows are deployment-oriented. The scaffolder simply treats that as a hint and
emits an informational message if you add a messaging flow to such a pack. Mixed
packs remain perfectly valid.
Environment
OTEL_EXPORTER_OTLP_ENDPOINT(defaulthttp://localhost:4317) targets your collector.RUST_LOGcontrols log verbosity; e.g.greentic_flow=info.OTEL_RESOURCE_ATTRIBUTES=deployment.environment=devtags spans with the active environment.
Maintenance Notes
- Keep shared primitives flowing through
greentic-typesandgreentic-interfaces. - Prefer zero-copy patterns and stay within safe Rust (
#![forbid(unsafe_code)]is enabled). - Update the adapter registry fixtures under
tests/data/when new adapters or operations are introduced.
Releases & Publishing
- Crate versions are sourced directly from each crate's
Cargo.toml. - Every push to
mastercompares the previous commit; if a crate version changed, a tag<crate-name>-v<semver>is created and pushed automatically. - The publish workflow runs on the tagged commit and attempts to publish all changed crates to crates.io using
katyo/publish-crates@v2. - Publishing is idempotent: if the version already exists on crates.io, the workflow succeeds without error.
Dependencies
~25–47MB
~744K SLoC