Releases: mdrideout/junjo
0.62.1
This patch release focuses on updates to the AI Chat example.
Changed
- Restored direct Gemini node usage across
examples/ai_chatworkflows instead of routing through provider abstractions. - Standardized Gemini model usage to
gemini-3-flash-previewfor text/schema generation andgemini-2.5-flash-imagefor image generation/editing flows. - Hardened Gemini schema request handling for empty/blocked responses and max-token edge cases.
- Updated
examples/ai_chat/README.mdand backend.env.exampleso Gemini is the default path with Grok as an optional experimentation path.
Junjo 0.62.0
Junjo 0.62.0
This release is primarily a cleanup and polish pass across existing features.
Junjo remains on its own version line at 0.62.0, independent of Junjo AI Studio versioning.
Highlights
- Modernized docs and examples, including telemetry and AI Studio terminology updates.
- Updated
examples/ai_chatto xAI Grok integration. - Tooling cleanup across the repo (Python pinning, Ruff updates, lockfile refresh).
- Internal Graphviz refactor in
Graphto improve maintainability while preserving behavior.
Removed / Simplified
- Removed deprecated pre-OpenTelemetry internals.
- Simplified OpenTelemetry usage in examples to lean on standard instrumentation.
Compatibility
- Mostly non-feature cleanup/polish.
- Consumers importing removed internal modules should migrate those imports.
0.61.1 - Package Metadata Update
- This release simply contains package metadata updates for where Junjo is published / distributed.
0.61.0 - Dependency Bumps For GRPC Connectivity / Retry Fixes
What's Changed
- Added flush() method to JunjoServerOtelExporter to allow block until all telemetry is exported
- Updated example application to call flush() to ensure delivery completes even when ingestion service starts late
- Bumped OpenTelemetry and gRPC dependencies to fix retry issues
- Improves retry of failed telemetry delivery
Fixes
- Fixes issue where if connectivity between Junjo library and gRPC ingestion service was disrupted, reconnection would not happen.
Full Changelog: 0.60.2...0.61.0
0.60.2 - Build Fix
A simple build fix.
0.60.1 - Build fixes and documentation updates
This release contains build fixes and documentation updates.
Full Changelog: 0.60.0...0.60.1
0.60.0 - Telemetry Schema Updates for Junjo Server
This Junjo client SDK release supports the telemetry schema in the latest version of Junjo Server.
If you are not using Junjo server, this release includes minor improvements, improved example code, and more documentation.
Updates
- Updated communication protocols for the latest version of Junjo Server
- Update Junjo Server to the latest version. See releases here.
- Junjo telemetry exporter will fail with older versions of Junjo Server 0.60.0
- No Junjo client implementation code changes are required
Junjo Server Upgrade (Required if using Junjo Server)
- New data architecture and ingestion protocol.
- Old telemetry data is not compatible.
- Delete existing database files, all existing telemetry data.
- New databases will be created automatically at startup of the new server.
- There is no upgrade path with the existing data.
Generated Release Notes
- Workflow updates by @mdrideout in #2
- Docs update by @mdrideout in #3
Full Changelog: 0.50.0...0.60.0
0.50.1 - Docs Update
A documentation update that explains how to use a lambda function for passing parameters to factory functions.
0.50.0 - GraphFactory Required Pattern
🚨 BREAKING CHANGE: graph Parameter Removed
This release introduces a breaking change to improve concurrency safety and ensure workflow isolation. The graph parameter in the Workflow and Subflow constructors has been removed and replaced with a mandatory graph_factory parameter.
Why this change was made
Previously, passing a Graph instance directly to a workflow could lead to stateful, shared graph instances across multiple workflow executions. This could cause unpredictable behavior in concurrent environments.
To ensure that every workflow execution is isolated and runs with a fresh, stateless graph, we now require a graph_factory. This is a callable (like a function) that returns a new Graph instance each time it's called. This change guarantees predictable behavior and prevents state conflicts.
How to Migrate
Updating your code is straightforward. Instead of creating your Graph instance and passing it in, you will now wrap your graph creation logic in a function and pass that function to the graph_factory parameter.
Before
# Instantiate the nodes
first_node = FirstNode()
# ... other nodes
# Create the workflow graph instance directly
workflow_graph = Graph(
source=first_node,
sink=final_node,
edges=[
# ... edges
]
)
# Create the workflow, passing the graph instance
sample_workflow = Workflow[SampleWorkflowState, SampleWorkflowStore](
name="Getting Started Example Workflow",
graph=workflow_graph, # <-- This parameter is now removed
store_factory=lambda: SampleWorkflowStore(
initial_state=SampleWorkflowState(items=["one", "two"])
)
)After
# Create a factory function that returns a new Graph instance
def create_graph() -> Graph:
"""
Factory function to create a new instance of the sample workflow graph.
This ensures that each workflow execution gets a fresh, isolated graph,
preventing state conflicts in concurrent environments.
"""
# Instantiate the nodes inside the factory
first_node = FirstNode()
# ... other nodes
# Return a new Graph instance
return Graph(
source=first_node,
sink=final_node,
edges=[
# ... edges
]
)
# Create the workflow, passing the factory function
sample_workflow = Workflow[SampleWorkflowState, SampleWorkflowStore](
name="Getting Started Example Workflow",
graph_factory=create_graph, # <-- Use the new graph_factory parameter
store_factory=lambda: SampleWorkflowStore(
initial_state=SampleWorkflowState(items=["one", "two"])
)
)✨ New & Improved API Documentation
To support this change, we've introduced two new protocols, GraphFactory and StoreFactory, which are now fully documented in our API reference. This will provide better type hinting and clarity for developers.
0.46.0 - Breaking Change: store_factory
Breaking Change
This release fixes a bug which caused Subflow instances to share a global store singleton. A new store_factory pattern has been implemented to guarantee every Workflow and Subflow execution utilizes a fresh isolated store and state.
The following illustrates the breaking change for Workflow and Subflow Store and State creation.
Workflow Example
The store is no longer instantiated and passed to the Workflow. We now use store_factory and a lambda to pass a callable to the Workflow that will instantiate the store at .execute().
You may still pass initial store values this way.
- # Create the store with initial state
- store = CreateContactStore(
- initial_state=CreateContactState(foo=bar)
- )
# Create the workflow
create_contact_workflow = Workflow[CreateContactState, CreateContactStore](
name="Create Contact Workflow",
graph=create_contact_graph,
- store=store,
+ store_factory=lambda: CreateContactStore(
+ initial_state=CreateContactState(foo=bar)
+ ),
hook_manager=HookManager(verbose_logging=True, open_telemetry=True),
)Subflow Example
The Subflow now follows an identical pattern. Use store_factory with a lambda function to instantiate the store and state.
# SubFlow Test - Test Running A SubFlow
sub_flow_test = TestSubFlow(
graph=test_sub_flow_graph,
- store=TestSubFlowStore(initial_state=TestSubFlowState())
+ store_factory=lambda: TestSubFlowStore(initial_state=TestSubFlowState())
)Full Changelog: 0.45.0...0.46.0