v0.20.0
Release 0.20.0
This release wires a single ILogger through the engine, Python steps, and your own steps, and teaches the Mermaid renderer to break large pipelines into per-flow companion diagrams so the merged DAG stops becoming unreadable past three flows.
What's New
- Shared ILogger Across the Engine and Your Steps: The engine now writes its own progress logs (step start/end, flow scheduling, errors) through a
loggerFactory.CreateLogger("Flowthru")instance registered in DI, and your steps can opt into the same logger by declaringILoggeras a parameter on theirCreate()factory. The[FlowthruStep]source generator picks it up automatically as a service ref. The CLI-sideFlowthruActivityLoggershim that previously translatedActivitySourceevents into log lines has been removed — activities are now exclusively for OTel tracing, and logs come from the logger directly. Hosts that never calledAddLogging()keep working becauseAddFlowthrufalls back toNullLoggerFactory.- Iris, Spaceflights, and SimpleEffectsExample wired through ILogger: All three starter examples now demonstrate the shared-logger pattern end to end, so you can copy a step and see exactly where
ILoggerenters and how step-emitted logs interleave with engine logs at runtime.
- Iris, Spaceflights, and SimpleEffectsExample wired through ILogger: All three starter examples now demonstrate the shared-logger pattern end to end, so you can copy a step and see exactly where
- Python Steps Narrate Through the Same ILogger: Python step output is now bridged into the engine's
"Flowthru"-category logger so Python steps look the same as C# steps in your logs. The Python worker installs a logging handler at startup that emits eachloggingrecord as a structured JSON frame on stderr; the newStderrLineClassifierparses those frames, maps Python levels to .NETLogLevel(DEBUG→Debug … CRITICAL→Critical), and renders the message with the logger name as a bracketed prefix. Raw lines (print(),sys.stderr.write(), uncaught tracebacks) are classified too: defaults toLogInformation, and aTraceback (most recent call last):marker promotes the line toLogError. Output now interleaves with engine logs in real time rather than arriving in a post-step batch.
-
Mermaid Per-Flow Companion Diagrams: The Mermaid metadata provider can now emit a per-flow file alongside the merged DAG — one Mermaid block per Flow, with neighboring Flows collapsed to their boundary Items and Steps. This keeps individual flows legible in pipelines where the merged view has grown too dense to read. Configure it through the new
PerFlowOptionsonMermaidMetadataProviderBuilder:PerFlowMode.Auto(default): emit the per-flow file when the DAG has more than 3 flows.PerFlowMode.Enabled: always emit it, even for single-flow pipelines.PerFlowMode.Disabled: only the merged view.
A quick example from the DataEvaluation flow in the advanced example's
SpaceflightsEnhanced:
Bug Fixes
- Mermaid Rendering and Service Metadata: Several correctness issues in Mermaid output and in the service-level metadata surface have been resolved, and example READMEs were refreshed to reflect the corrected diagrams.
- Example Package Props: Iris, IrisFUnit, and SimpleEffectsExample were missing
Directory.Packages.propsentries that caused inconsistent restores when cloning the example as a starting point. Those are now in place. - Logging Conventions Post-Audit: A pass over the new logging code aligned message templates and category usage with the conventions in CONTRIBUTING, so engine-emitted logs stay structurally consistent with step-emitted ones.
Documentation
- Anatomy of a Flow and Core Architecture refresh: docs/explanation/anatomy-of-a-flow.md and docs/explanation/advanced/core-architecture.md were updated to match the new shared-logger model and current flow-scheduling terminology.
- CONTRIBUTING Split by Role: The contributor docs have been broken out per audience — examples/CONTRIBUTING.md for Flow and Catalog Developers, src/core/CONTRIBUTING.md, src/extensions/CONTRIBUTING.md, src/tools/CONTRIBUTING.md, and per-context test conventions in tests/core/CONTRIBUTING.md and tests/extensions/CONTRIBUTING.md. The root CONTRIBUTING.md keeps only the cross-cutting design rules.
- Example READMEs Rewritten and Templated: Every starter and advanced example README has been rewritten against a shared template and is now generated by
scripts/update-example-readmes.mjs, so the "what does this example demonstrate?" framing stays consistent across the catalog. Examples were also renamed to follow consistent naming conventions.
❤️ Thank You
- Spencer Elkington