Skip to content

chore(deps): upgrade Graphon to 0.9.0 and adapt runtime contracts - #45356

Draft
WH-2099 wants to merge 5 commits into
mainfrom
chore/graphon-0.9.0
Draft

WH-2099 wants to merge 5 commits into
mainfrom
chore/graphon-0.9.0

Conversation

@WH-2099

@WH-2099 WH-2099 commented Nov 2, 2026 •

Copy link
Copy Markdown
Member

Summary

Fixes #45355.

Upgrade the API and standalone Agent package to Graphon 0.9.0 and adapt the host to its segment and engine contracts.
Both manifests, lockfiles, and installed environments use the reviewed commit 454cd1c1d9707fbd04634841c746c6487f97c791.

  • Accept secret variables in knowledge retrieval and dynamic Human Input email recipients, preserving secret tags and variable metadata during truncation.
  • Preserve ordinary JSON resembling files and existing fields in mixed arrays, draft values, pipeline outputs, and streaming responses; complete typed runtime snapshots retain actual File identity.
  • Refresh URLs for validated file variables and keep single node debugging within the admitted account's tenant through loading, execution, and persistence.
  • Bind pipeline worker file access to the admitted tenant and user, restoring the caller's scope afterward.
  • Extend failure cleanup to all started draft nodes and terminal persistence errors, preserving the original exception.
  • Disable unused frame observations in WorkflowEntry while retaining execution, container output commits, and pause/resume.
  • Update variable contracts and regression fixtures, and install Git in the Agent image's build stage for its frozen source dependency.

Dependencies

This draft depends on langgenius/graphon#382 and langgenius/graphon#383.
The integration fix covers JSON/File identity, nested serialization, templates over object arrays, cumulative tool call snapshots, unused stream retention, and frame observation copying.
Replace both temporary Git sources with the published package when it includes these fixes.
Historical mixed-array snapshots without file type metadata retain dictionaries as JSON.

Validation

  • All 12 changed API unit test files: 907 passed against the installed final Graphon pin.
  • Full Agent suite: 1,069 passed, 5 skipped against that pin.
  • API make lint and make type-check; Agent Ruff and pyrefly checks passed.
  • Both frozen dependency installs succeeded; independent verification matched all source references, installed commit metadata, and imported source bytes.
  • Graphon: 1,185 tests passed, just check, wheel/source distribution builds, and 29 documentation checks passed.
  • Independent reviews covered file permissions and serialization, execution lifecycle, persistence, runtime and model adapter contracts, packaging, tests, documentation, and naming; findings were fixed and rechecked.
  • Regression coverage exercises a real website crawl pipeline through engine execution, SQL output conversion, and response conversion after the execution scope exits.

Local tests used a valid NO_PROXY list and an ephemeral socksio dependency for the Agent test environment.
Live provider calls, complete Docker builds, database integration tests, and production concurrency were not run.

Screenshots

Not applicable: backend dependency and runtime integration changes.

Checklist

  • This change requires a documentation update, included: Dify Document — no public documentation change required.
  • I understand that this PR may be closed in case there was no previous discussion or issues. (This doesn't apply to typos!)
  • I've verified the change and added or updated tests where meaningful regression risk justifies coverage.
  • I've updated the documentation accordingly; affected local contracts and upstream Graphon documentation are current.
  • I ran make lint && make type-check (backend); frontend checks do not apply.

From Codex

@WH-2099 WH-2099 self-assigned this Nov 2, 2026
@github-actions github-actions Bot added the size:XL This PR changes 500-999 lines, ignoring generated files. label Nov 2, 2026
@github-actions

github-actions Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Pyrefly Type Coverage

Metric Base PR Delta
Type coverage 83.13% 83.14% +0.01%
Strict coverage 82.79% 82.79% +0.01%
Typed symbols 85,756 85,789 +33
Untyped symbols 17,471 17,471 0
Modules 4373 4373 0

@github-actions

github-actions Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Pyrefly Diff

base → PR
--- /tmp/pyrefly_base.txt	2026-11-03 08:15:58.589846616 +0000
+++ /tmp/pyrefly_pr.txt	2026-11-03 08:15:45.209703065 +0000
@@ -3629,7 +3629,7 @@
 ERROR Cannot index into `str` [bad-index]
    --> tests/unit_tests/core/app/apps/completion/test_generate_response_converter.py:175:16
 ERROR Class `PipelineRunner` has no class attribute `call_args` [missing-attribute]
-   --> tests/unit_tests/core/app/apps/pipeline/test_pipeline_generator.py:444:21
+   --> tests/unit_tests/core/app/apps/pipeline/test_pipeline_generator.py:450:21
 ERROR Object of class `Account` has no attribute `tenant_id` [missing-attribute]
    --> tests/unit_tests/core/app/apps/test_base_app_generator.py:609:9
 ERROR `list[str]` is not assignable to attribute `allowed_file_types` with type `Sequence[FileType] | None` [bad-assignment]
@@ -5375,13 +5375,13 @@
 ERROR Argument `dict[str, bool]` is not assignable to parameter `summary_index_setting` with type `SummaryIndexSettingDict | None` in function `core.workflow.nodes.knowledge_index.knowledge_index_node.KnowledgeIndexNode._invoke_knowledge_index` [bad-argument-type]
    --> tests/unit_tests/core/workflow/nodes/knowledge_index/test_knowledge_index_node.py:638:35
 ERROR `None` is not subscriptable [unsupported-operation]
-   --> tests/unit_tests/core/workflow/nodes/knowledge_retrieval/test_knowledge_retrieval_node.py:615:16
+   --> tests/unit_tests/core/workflow/nodes/knowledge_retrieval/test_knowledge_retrieval_node.py:641:16
 ERROR `None` is not subscriptable [unsupported-operation]
-   --> tests/unit_tests/core/workflow/nodes/knowledge_retrieval/test_knowledge_retrieval_node.py:616:27
+   --> tests/unit_tests/core/workflow/nodes/knowledge_retrieval/test_knowledge_retrieval_node.py:642:27
 ERROR `None` is not subscriptable [unsupported-operation]
-   --> tests/unit_tests/core/workflow/nodes/knowledge_retrieval/test_knowledge_retrieval_node.py:617:16
+   --> tests/unit_tests/core/workflow/nodes/knowledge_retrieval/test_knowledge_retrieval_node.py:643:16
 ERROR `None` is not subscriptable [unsupported-operation]
-   --> tests/unit_tests/core/workflow/nodes/knowledge_retrieval/test_knowledge_retrieval_node.py:618:16
+   --> tests/unit_tests/core/workflow/nodes/knowledge_retrieval/test_knowledge_retrieval_node.py:644:16
 ERROR Object of class `Span` has no attribute `events` [missing-attribute]
    --> tests/unit_tests/core/workflow/nodes/knowledge_retrieval/test_retrieval.py:174:42
 ERROR Missing argument `name` in function `core.workflow.nodes.trigger_webhook.entities.WebhookParameter.__init__` [missing-argument]
@@ -5549,39 +5549,39 @@
 ERROR Object of class `object` has no attribute `tool` [missing-attribute]
     --> tests/unit_tests/core/workflow/test_node_runtime.py:2252:16
 WARN Cannot instantiate `BaseNodeData` because it directly extends `ABC` or uses `ABCMeta` [direct-abstract-base-instantiation]
-    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1010:50
+    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1061:50
 ERROR `in` is not supported between `Literal['Maximum execution steps exceeded: 3 > 2']` and `None` [not-iterable]
-    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1067:20
+    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1118:20
 WARN Cannot instantiate `BaseNodeData` because it directly extends `ABC` or uses `ABCMeta` [direct-abstract-base-instantiation]
-    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1200:37
+    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1251:37
 ERROR Class member `EmptySplitKey.split` overrides parent class `UserString` in an inconsistent manner [bad-override]
-    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1632:21
+    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1683:21
 ERROR Class member `EmptySplitKey.split` overrides a member in a parent class but is missing an `@override` decorator [missing-override-decorator]
-    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1632:21
+    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1683:21
 ERROR `TestWorkflowEntryHelpersCases.TestMappingUserInputsBranches.test_rejects_invalid_node_variable_key.EmptySplitKey` is not assignable to dict key type `str` [bad-assignment]
-    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1637:39
+    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1688:39
 ERROR Argument `TestWorkflowEntryHelpersCases.TestWorkflowEntryNodeLayers.test_run_node_with_layers_reports_success.FakeNode` is not assignable to parameter `node` with type `Node[Unknown]` in function `core.workflow.workflow_entry.WorkflowEntry._run_node_with_layers` [bad-argument-type]
-    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1740:82
+    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1791:82
 ERROR Object of class `FunctionType` has no attribute `assert_called_once_with` [missing-attribute]
-    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1745:17
+    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1796:17
 ERROR Object of class `FunctionType` has no attribute `assert_called_once_with` [missing-attribute]
-    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1746:17
+    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1797:17
 ERROR Object of class `FunctionType` has no attribute `assert_called_once_with` [missing-attribute]
-    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1747:17
+    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1798:17
 ERROR Object of class `FunctionType` has no attribute `assert_called_once_with` [missing-attribute]
-    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1748:17
+    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1799:17
 ERROR Object of class `FunctionType` has no attribute `assert_called_once_with` [missing-attribute]
-    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1749:17
+    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1800:17
 ERROR Argument `TestWorkflowEntryHelpersCases.TestWorkflowEntryNodeLayers.test_run_node_with_layers_reports_errors.FakeNode` is not assignable to parameter `node` with type `Node[Unknown]` in function `core.workflow.workflow_entry.WorkflowEntry._run_node_with_layers` [bad-argument-type]
-    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1776:77
+    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1827:77
 ERROR Object of class `FunctionType` has no attribute `call_args` [missing-attribute]
-    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1779:24
+    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1830:24
 ERROR Object of class `FunctionType` has no attribute `call_args` [missing-attribute]
-    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1780:35
+    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1831:35
 ERROR Object of class `FunctionType` has no attribute `call_args` [missing-attribute]
-    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1781:24
+    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1832:24
 ERROR Object of class `FunctionType` has no attribute `call_args` [missing-attribute]
-    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1782:35
+    --> tests/unit_tests/core/workflow/test_workflow_entry.py:1833:35
 ERROR Object of class `object` has no attribute `append` [missing-attribute]
    --> tests/unit_tests/dev/test_generate_knowledge_fs_contract.py:121:13
 ERROR Cannot set item in `object` [unsupported-operation]
@@ -5655,7 +5655,7 @@
 ERROR Argument `str` is not assignable to parameter `indexing_status` with type `IndexingStatus | SQLCoreOperations[IndexingStatus]` in function `models.dataset.Document.__init__` [bad-argument-type]
    --> tests/unit_tests/fields/test_dataset_fields.py:299:25
 ERROR Cannot set item in `OrderedDict[str, bool | list[str] | str]` [unsupported-operation]
-   --> tests/unit_tests/fields/test_workflow_draft_variable_fields.py:142:47
+   --> tests/unit_tests/fields/test_workflow_draft_variable_fields.py:144:47
 ERROR Object of class `Subscription` has no attribute `_start_if_needed` [missing-attribute]
    --> tests/unit_tests/libs/broadcast_channel/redis/test_pubsub_channel.py:152:13
 ERROR Object of class `Subscription` has no attribute `_start_if_needed` [missing-attribute]
@@ -5941,19 +5941,19 @@
 ERROR Object of class `FromClause` has no attribute `create` [missing-attribute]
   --> tests/unit_tests/services/plugin/test_plugin_parameter_service.py:47:9
 ERROR Object of class `NoneType` has no attribute `marked_name` [missing-attribute]
-   --> tests/unit_tests/services/rag_pipeline/test_rag_pipeline.py:552:16
+   --> tests/unit_tests/services/rag_pipeline/test_rag_pipeline.py:618:16
 ERROR Object of class `NoneType` has no attribute `marked_comment` [missing-attribute]
-   --> tests/unit_tests/services/rag_pipeline/test_rag_pipeline.py:553:16
+   --> tests/unit_tests/services/rag_pipeline/test_rag_pipeline.py:619:16
 ERROR Object of class `NoneType` has no attribute `updated_by` [missing-attribute]
-   --> tests/unit_tests/services/rag_pipeline/test_rag_pipeline.py:555:16
+   --> tests/unit_tests/services/rag_pipeline/test_rag_pipeline.py:621:16
 ERROR Argument `dict[str, list[dict[str, dict[str, str | dict[str, str] | dict[str, int | str]]]]]` is not assignable to parameter `graph` with type `dict[str, object] | None` in function `_make_workflow` [bad-argument-type]
-   --> tests/unit_tests/services/rag_pipeline/test_rag_pipeline.py:669:71
+   --> tests/unit_tests/services/rag_pipeline/test_rag_pipeline.py:735:71
 ERROR Argument `() -> tuple[StartNode, Generator[object, Unknown]]` is not assignable to parameter `getter` with type `() -> tuple[Node[Unknown], Generator[CustomContainerRequest | IterationFrameRequest | LoopFrameRequest | NodeEvent]]` in function `services.rag_pipeline.rag_pipeline.RagPipelineService._handle_node_run_result` [bad-argument-type]
-    --> tests/unit_tests/services/rag_pipeline/test_rag_pipeline.py:1909:24
+    --> tests/unit_tests/services/rag_pipeline/test_rag_pipeline.py:1975:24
 ERROR Argument `() -> tuple[StartNode, Iterator[NodeRunFailedEvent]]` is not assignable to parameter `getter` with type `() -> tuple[Node[Unknown], Generator[CustomContainerRequest | IterationFrameRequest | LoopFrameRequest | NodeEvent]]` in function `services.rag_pipeline.rag_pipeline.RagPipelineService._handle_node_run_result` [bad-argument-type]
-    --> tests/unit_tests/services/rag_pipeline/test_rag_pipeline.py:1929:20
+    --> tests/unit_tests/services/rag_pipeline/test_rag_pipeline.py:1995:20
 ERROR Argument `() -> tuple[StartNode, Iterator[NodeRunFailedEvent]]` is not assignable to parameter `getter` with type `() -> tuple[Node[Unknown], Generator[CustomContainerRequest | IterationFrameRequest | LoopFrameRequest | NodeEvent]]` in function `services.rag_pipeline.rag_pipeline.RagPipelineService._handle_node_run_result` [bad-argument-type]
-    --> tests/unit_tests/services/rag_pipeline/test_rag_pipeline.py:1949:20
+    --> tests/unit_tests/services/rag_pipeline/test_rag_pipeline.py:2015:20
 ERROR Argument `Literal['']` is not assignable to parameter `plan` with type `CloudPlan` in function `RagPipelineTaskProxyTestDataFactory.create_mock_features` [bad-argument-type]
    --> tests/unit_tests/services/rag_pipeline/test_rag_pipeline_task_proxy.py:590:91
 ERROR Argument `None` is not assignable to parameter `plan` with type `CloudPlan` in function `RagPipelineTaskProxyTestDataFactory.create_mock_features` [bad-argument-type]
@@ -6259,11 +6259,13 @@
 ERROR `None` is not subscriptable [unsupported-operation]
     --> tests/unit_tests/services/test_workflow_persistence.py:1422:20
 ERROR `dict[str, str]` is not assignable to dict value type `list[Unknown] | str` [bad-assignment]
-   --> tests/unit_tests/services/test_workflow_service.py:239:30
+   --> tests/unit_tests/services/test_workflow_service.py:248:30
+ERROR Argument `Literal['array[any]']` is not assignable to parameter `value_type` with type `SQLCoreOperations[SegmentType] | SegmentType` in function `models.workflow.WorkflowDraftVariable.__init__` [bad-argument-type]
+    --> tests/unit_tests/services/test_workflow_service.py:3391:36
 ERROR Argument `Literal['invalid']` is not assignable to parameter `value` with type `AppMode | SQLCoreOperations[AppMode]` in function `sqlalchemy.orm.base.Mapped.__set__` [bad-argument-type]
-    --> tests/unit_tests/services/test_workflow_service.py:3945:24
+    --> tests/unit_tests/services/test_workflow_service.py:4034:24
 ERROR Argument `dict[str, str | dict[str, str]]` is not assignable to parameter `node_config` with type `NodeConfigDict` in function `services.workflow_service.WorkflowService._build_human_input_node_for_debugging` [bad-argument-type]
-    --> tests/unit_tests/services/test_workflow_service.py:3976:69
+    --> tests/unit_tests/services/test_workflow_service.py:4065:69
 ERROR Object of class `MCPToolProvider` has no attribute `provider_icon` [missing-attribute]
   --> tests/unit_tests/services/tools/test_tools_transform_service.py:82:9
 ERROR Object of class `MCPToolProvider` has no attribute `masked_server_url` [missing-attribute]

@github-actions github-actions Bot added the web This relates to changes on the web. label Nov 2, 2026
@codecov

codecov Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.42105% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.88%. Comparing base (a8631e5) to head (4799bd2).
⚠️ Report is 36 commits behind head on main.

Files with missing lines Patch % Lines
api/services/workflow_service.py 89.74% 4 Missing and 4 partials ⚠️
api/services/rag_pipeline/rag_pipeline.py 96.07% 1 Missing and 1 partial ⚠️

❌ Your project check has failed because the head coverage (85.88%) is below the adjusted base coverage (88.77%). You can increase the head coverage or adjust the Removed Code Behavior.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #45356      +/-   ##
==========================================
- Coverage   89.77%   85.88%   -3.90%     
==========================================
  Files        6239     6240       +1     
  Lines      390902   390955      +53     
  Branches    79285    79174     -111     
==========================================
- Hits       350934   335756   -15178     
- Misses      33870    49106   +15236     
+ Partials     6098     6093       -5     
Flag Coverage Δ
api 89.65% <93.42%> (+0.01%) ⬆️
cli 94.26% <ø> (ø)
dify-ui 92.54% <ø> (+0.15%) ⬆️
web 80.03% <ø> (-9.73%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions github-actions Bot added size:XXL This PR changes 1000+ lines, ignoring generated files. and removed size:XL This PR changes 500-999 lines, ignoring generated files. labels Nov 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL This PR changes 1000+ lines, ignoring generated files. web This relates to changes on the web.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

chore(deps): upgrade Graphon to 0.9.0 and adapt runtime contracts

1 participant