Repository navigation
chore(release): prepare v0.7.0 #234
Description
Summary
Prepare Graphon v0.7.0 for release and give downstream integrators one place to review the complete change set and required migrations.
This issue complements #222, which only updated the package version metadata.
Release scope
- Previous release: v0.6.0
- Target release: v0.7.0
- Commit range: v0.6.0...11e2dee
- Current cutoff:
origin/mainat11e2dee8cbd6dc2e6bf1c2059d9bbf4d0437ebe5on 2026-07-29 - Commits in range: 16
- Version metadata:
pyproject.tomlanduv.lockare already set to0.7.0 - Release tag:
v0.7.0has not been created
If main changes before tagging, refresh the cutoff, compare link, and commit list below.
Breaking changes and downstream adaptation
1. Canonical ModelType values are now required
ModelType no longer accepts legacy provider-native aliases. Constructing the enum with one of the removed aliases now raises ValueError.
| Removed input | Required v0.7.0 input |
|---|---|
text-generation |
llm |
embeddings |
text-embedding |
reranking |
rerank |
The canonical values speech2text, moderation, and tts are unchanged. Outbound provider conversion through ModelType.to_origin_model_type() is also unchanged.
Downstream work:
- Migrate persisted JSON, database fields, environment/config values, DSL adapters, and API payloads before passing them to
ModelType. - Update validation schemas and fixtures to accept only Graphon canonical values.
- Keep provider-native values only at the provider boundary; use
to_origin_model_type()instead of maintaining a second mapping. - Search downstream repositories for
text-generation,embeddings, andreranking, distinguishing model-type values from unrelated provider payload fields. - Add a startup or migration check so stale persisted values fail before workflow execution.
2. VariablePool.convert_template() moved to a module helper
The squash commit subject omitted the breaking marker, but the PR title included ! and the method was removed from VariablePool.
Before v0.7.0:
rendered = variable_pool.convert_template(template)
From v0.7.0:
from graphon.variables.template_resolution import convert_template
rendered = convert_template(variable_pool, template)
Downstream work:
- Replace every call to
VariablePool.convert_template(template)withconvert_template(pool, template). - Import the helper from
graphon.variables.template_resolution; it is not re-exported fromgraphon.variables. - Update mocks and adapters to expose only
get(selector). The helper accepts any read-only lookup object with that method, so callers no longer need to downcast to the concrete mutableVariablePool. - Preserve existing handling of the returned
SegmentGroup, including use of.textwhere callers expect rendered text.
3. Loop and Iteration execution moved to resumable engine frames
Loop and Iteration no longer create nested child GraphEngine instances inside their node execution. They suspend their parent node, run child work as engine-managed frames, and resume the parent with a typed container result.
Execution entry and event consumers
- Run complete workflows through
GraphEngine.run()orgraphon.dsl.loads(...).run(). - Do not invoke Loop/Iteration private execution paths directly.
- Do not treat direct
Node.run()as a standalone execution API. The engine now binds execution identity before running a node. - Continue consuming graph events as the execution record. Child events carry
in_loop_idorin_iteration_idplus frame/index metadata; the parent container node emits the public container lifecycle events. - Audit code that assumed each Loop/Iteration created a distinct child engine or occupied a worker for its full lifetime.
Custom ready queues
The protocol moved from ReadyQueueProtocol to ReadyQueue, and queue items changed from node-id strings to a discriminated ReadyTask union:
StartTask(frame_id, node_id)starts work in a frame.ResumeTask(invocation_id, result)resumes a suspended container node.
Custom queue implementations must:
- Update imports from
graphon.runtime.ready_queue.ReadyQueueProtocoltographon.runtime.ready_queue.ReadyQueue. - Accept and return both task variants from
put()andget(). - Implement
task_done(),qsize(),drain(),dumps(), andloads().empty()is no longer part of the protocol. - Preserve task order, discriminator data, frame ids, invocation ids, and resume results during serialization.
- Preserve deferred tasks as well as the active queue during pause/resume.
- Quiesce producers and consumers while serializing or restoring if the backend cannot provide an atomic snapshot.
- Add migration support for any stored v1 queue payloads. The built-in
InMemoryReadyQueueupgrades v1 node-id items to root-frameStartTaskitems, but custom backends must implement equivalent behavior themselves.
Runtime snapshots and resume
GraphRuntimeState.dumps() now emits snapshot version 2.0 with graph execution state, active and deferred ready tasks, container invocations, child frames, and frame-local node/edge state.
Downstream work:
- Treat snapshots as opaque Graphon data instead of parsing or editing their JSON fields directly.
- Restore by creating a new state with
GraphRuntimeState.from_snapshot(snapshot, ready_queue_factory=...); the old instance methodloads()is removed. - Pass a JSON string to
from_snapshot(). Callers that retained snapshots as mappings must serialize them first. - Rebuild the engine with the same graph definition. Graph definitions are intentionally not embedded in runtime snapshots.
- Ensure the ready-queue factory returns the downstream queue implementation required for both active and deferred task restoration.
- Expect new snapshots to be version 2.0. The built-in loader retains read compatibility for Graphon v1.0 runtime, graph-execution, and in-memory queue snapshots, but custom snapshot parsers and queue backends still need explicit v2 support.
- After a successful v1 restore, reserialize and persist the v2 snapshot rather than continuing to depend on the legacy shape.
Custom node factories
Factories that can materialize nodes inside Loop/Iteration frames must implement:
with_runtime_state(graph_runtime_state) -> NodeFactory
The returned factory must preserve graph configuration and dependencies while binding newly created child-frame nodes to the supplied runtime state. The built-in SlimDslNodeFactory uses a dataclass replacement for this.
Downstream work:
- Add
with_runtime_state()to custom factories used with container graphs. - Verify every node created for a frame receives exactly that frame's
GraphRuntimeState. - Retain the original graph definition and factory on the root
Graph, because frame restoration uses both to rebuild child frames.
Node execution identity and domain integrations
GraphExecution.node_executionsis now keyed by(frame_id, node_id), not onlynode_id.GraphExecution.get_or_create_node_execution()now requires keyword argumentsframe_idandnode_id.NodeExecution.execution_idis required at construction.NodeExecutionno longer owns node state/error transitions or the methodsmark_started(),mark_taken(),mark_failed(), andmark_skipped().Node.ensure_execution_id()is removed; the engine binds the id throughNode.bind_execution_id().
Downstream code that directly orchestrates nodes should preferably move to GraphEngine. If a custom runner must remain, it must allocate or restore the frame-scoped NodeExecution, bind its id to the node, and only then invoke the node.
Removed child-engine and internal APIs
The old execution path removed these imports or concepts:
ExecutionCoordinator: use the publicGraphEnginelifecycle instead of coordinating workers directly.create_ready_queue_from_state: restore throughGraphRuntimeState.from_snapshot(..., ready_queue_factory=...), or instantiate the selected queue and call itsloads().LLMUsageTrackingMixin: record usage throughGraphRuntimeState.add_llm_usage().- Legacy Iteration exception classes: observe node/graph failure events or implement container-handler result/error handling instead of catching child-engine exceptions.
- Child-engine builder methods and
ChildEngineErrorsubclasses: use engine-managed frames andContainerHandlerimplementations. - Direct imports of dispatcher, worker, coordinator, and old container internals: keep integration at
GraphEngine,ReadyQueue,GraphRuntimeState, graph events, node factories, andContainerHandlerboundaries.
Custom container types
Custom container integrations should provide a ContainerHandlerFactory to GraphEngine. A handler owns child-frame creation/restoration, scheduling, aggregation, failure recording, and terminal result construction; the parent node still owns its public lifecycle events.
Additional compatibility-sensitive changes
These commits were not marked as breaking, but downstream implementations should still be audited.
TTS voice results are now structured
Custom TTSModelRuntime.get_tts_model_voices() implementations must return list[TTSModelVoice], where every item has string name and value fields, instead of returning list[str].
Example:
[{"name": "Nova", "value": "nova"}]
Update provider adapters, API schemas, UI option mapping, fixtures, and type stubs accordingly.
Sensitive values are masked in logs and live serialization
SecretVariable values, including secrets nested in SegmentGroup, are masked in run-log serialization and live stream payloads. HTTP request logs also mask secrets in URLs, query parameters, headers, and request bodies. The actual outbound request remains unchanged.
Downstream work:
- Do not expect raw secret values in run logs, SSE payloads, snapshots derived from log serialization, or HTTP request logs.
- Remove any parser, test, or support workflow that compares logged secrets with plaintext.
- Read real values only from authorized runtime inputs, never by attempting to reverse or bypass the log mask.
- Update snapshot/golden tests to assert masking while separately asserting that outbound requests retain the original value.
Complete commit list
Chronological order from v0.6.0 through the current release cutoff:
| # | Date | Commit | Pull request | Change | Compatibility |
|---|---|---|---|---|---|
| 1 | 2026-07-04 | e22dfa0 | #201 | chore(deps): bump the uv group with 3 updates | Dependency update |
| 2 | 2026-07-06 | 41a3feb | #203 | feat(document-extractor): support OpenDocument text files | Additive |
| 3 | 2026-07-07 | c5293d0 | #207 | refactor(model-runtime)!: remove legacy model type aliases | Breaking |
| 4 | 2026-07-07 | d554cb7 | #205 | refactor(variables): extract template resolution helper | Breaking API; commit subject omitted ! |
| 5 | 2026-07-07 | 7efee90 | #209 | fix(model-runtime): type TTS model voices | Structured return value |
| 6 | 2026-07-08 | b10cc41 | #211 | chore(deps): bump the uv group with 5 updates | Dependency update |
| 7 | 2026-07-08 | e86beec | #210 | chore(deps): bump setup-uv from 8.2.0 to 8.3.1 | CI-only |
| 8 | 2026-07-17 | 0f6f0c7 | #219 | fix(document-extractor): add configurable timeout to Unstructured API client | Additive configuration |
| 9 | 2026-07-17 | 96f3983 | #223 | chore(release): bump version to 0.7.0 | Release metadata |
| 10 | 2026-07-20 | ea76ded | #215 | chore(deps): bump setup-uv from 8.3.1 to 8.3.2 | CI-only |
| 11 | 2026-07-20 | 3564a95 | #224 | chore(deps): update uv group and Ruff suppressions | Tooling/dependencies |
| 12 | 2026-07-21 | b187ce7 | #217 | feat: mask secrets in run-log serialization and HTTP request logs | Observable log behavior |
| 13 | 2026-07-27 | d0e89ae | #228 | chore(deps): bump the github-actions group with 2 updates | CI-only |
| 14 | 2026-07-27 | be7cf7b | #229 | chore(deps): bump json-repair from 0.61.6 to 0.61.7 | Dependency update |
| 15 | 2026-07-28 | c3870df | #197 | feat(engine)!: run containers as resumable engine frames | Breaking |
| 16 | 2026-07-29 | 11e2dee | #233 | fix(runtime): support gevent-patched ready queues | Runtime compatibility fix |
Downstream sign-off checklist
- Stored and incoming model-type values use canonical Graphon names.
- All
VariablePool.convert_template()calls are migrated. - Custom ready queues support frame-aware start/resume tasks, draining, serialization, and v1-to-v2 migration.
- Runtime snapshot persistence uses
GraphRuntimeState.from_snapshot()and accepts v2 data. - Custom node factories used by container graphs implement
with_runtime_state(). - Direct node/domain integrations use frame-scoped execution ids or move to
GraphEngine. - Imports of removed child-engine and execution internals are replaced.
- Custom TTS runtimes return structured voice objects.
- Log/SSE consumers and golden tests expect masked secrets.
Release checklist
- Version metadata is
0.7.0. - Current
v0.6.0..origin/mainrange and breaking changes are documented. - Fix the remaining legacy Ruff suppression comments introduced after the Ruff 0.15.22 migration so
just checkpasses on the finalmain. - Refresh this issue if additional commits land before the release cutoff.
- Run
just test,just check, andjust buildon the final commit. - Confirm downstream migration owners have reviewed the breaking-change sections.
- Create
v0.7.0from a commit reachable frommain. - Push the tag to trigger the release workflow.
- Verify TestPyPI publication and approve the protected PyPI environment.
- Verify the PyPI package and published GitHub release.
Activity