From dba6d23fc01ff636c05482fb4f304da5c2ba86a2 Mon Sep 17 00:00:00 2001 From: Charles Yao Date: Thu, 29 Oct 2026 19:53:47 -0700 Subject: [PATCH] fix(builder): retain native stream cleanup and align test inventories --- .github/scripts/builder-confirmed-tool-units.py | 11 ++++++----- api/services/dify_builder/attachment_extraction.py | 7 +++---- .../dify_builder/test_attachment_extraction.py | 5 ++++- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/.github/scripts/builder-confirmed-tool-units.py b/.github/scripts/builder-confirmed-tool-units.py index 5ccf75bbe2a..ae974ffee6a 100644 --- a/.github/scripts/builder-confirmed-tool-units.py +++ b/.github/scripts/builder-confirmed-tool-units.py @@ -1268,8 +1268,8 @@ a4_expected["tests.unit_tests.services.dify_builder.test_build_cognition"] = { "test_gap_system_separates_native_draft_coverage_from_runtime_admission": 1, "test_gap_system_treats_absent_named_candidates_as_unconfirmed_external_inventory": 1, "test_grounding_preserves_retrieval_config_without_dataset_assignment": 1, - "test_initial_plan_keeps_agent_catalogue_failure_distinct_from_no_agents": 1, - "test_initial_plan_uses_only_current_actor_eligible_published_agent_metadata": 2, + "test_initial_plan_defers_agent_catalogue_failure_and_discovery_distinguishes_empty": 2, + "test_initial_plan_defers_actor_eligible_published_agent_metadata_to_discovery": 2, "test_learn_from_build_degrades_on_boom": 1, "test_learn_from_build_degrades_to_generic": 1, "test_outline_keeps_original_goal_literals_and_metadata_in_user_message": 1, @@ -1283,7 +1283,7 @@ a4_expected["tests.unit_tests.services.dify_builder.test_build_cognition"] = { "test_planner_catalogue_includes_setup_tools_and_remains_capped": 1, "test_planner_describes_only_first_phase_nodes_to_the_model": 1, "test_planner_keeps_conditional_model_preference_separate_from_required_behavior": 1, - "test_planner_sees_relevant_installed_tools_including_delayed_setup_beyond_the_old_name_cap": 1, + "test_initial_plan_defers_installed_tools_and_discovery_ranks_delayed_setup_beyond_the_old_name_cap": 1, "test_propose_plan_v1_corrects_schema_once_with_full_source_and_same_provider_parameters": 1, "test_propose_plan_v1_does_not_retry_a_provider_failure": 1, "test_propose_plan_v1_preserves_valid_plan_strings_without_content_thresholds": 1, @@ -1549,6 +1549,7 @@ for module, functions in { "tests.unit_tests.services.dify_builder.test_code_risk_assessment": { "test_code_reasoner_uses_session_language_instead_of_old_goal_language": 1, "test_code_risk_language_is_bound_to_snapshot_without_translating_source": 1, + "test_code_risk_policy_denial_is_not_downgraded_to_simulation": 1, }, "tests.unit_tests.services.dify_builder.test_confirmed_full_run": { "test_closed_preparation_failure_is_not_reconciled_as_a_dispatched_run": 1, @@ -2218,8 +2219,8 @@ a4_expected["tests.unit_tests.core.dify_builder.test_handlers_build"] = { "test_run_test_routes_to_testdata_gate_when_no_input": 1, "test_run_test_skips_gate_when_input_prepared": 1, "test_run_test_still_asks_when_a_file_is_declared_among_other_variables": 1, - "test_submitting_requirements_goes_straight_to_resources": 1, - "test_submitting_requirements_progress_is_one_operation_with_monotonic_revisions": 1, + "test_submitting_requirements_prepares_plan_before_automatic_resource_stage": 1, + "test_submitting_requirements_progress_has_monotonic_revisions_for_each_committed_stage": 1, "test_test_and_repair_config_failure_still_routes_to_repair_gate": 1, "test_test_and_repair_defensive_mock_leaves_the_endpoint_for_the_form": 1, "test_test_and_repair_fail_routes_to_await_repair_with_staged_repair": 1, diff --git a/api/services/dify_builder/attachment_extraction.py b/api/services/dify_builder/attachment_extraction.py index 6fbd163d87f..d630f66f2b8 100644 --- a/api/services/dify_builder/attachment_extraction.py +++ b/api/services/dify_builder/attachment_extraction.py @@ -7,7 +7,7 @@ No parser follows links, performs OCR, writes derivatives or invokes providers. import hashlib import io import zipfile -from collections.abc import Iterable +from collections.abc import Generator, Iterable from dataclasses import dataclass from typing import Literal @@ -187,6 +187,5 @@ def extract_local_context( except Exception: return ExtractedContext("rejected", reason="malformed_file") finally: - close = getattr(chunks, "close", None) - if close is not None: - close() + if isinstance(chunks, Generator): + chunks.close() diff --git a/api/tests/unit_tests/services/dify_builder/test_attachment_extraction.py b/api/tests/unit_tests/services/dify_builder/test_attachment_extraction.py index ab707ed0af4..2139c25833c 100644 --- a/api/tests/unit_tests/services/dify_builder/test_attachment_extraction.py +++ b/api/tests/unit_tests/services/dify_builder/test_attachment_extraction.py @@ -31,7 +31,10 @@ def test_native_stream_stops_before_materializing_an_oversized_file() -> None: yield b"a" * (10 * 1024 * 1024 + 1) raise AssertionError("must not continue an oversized stream") - assert extract_local_context("txt", chunks()).reason == "byte_limit" + stream = chunks() + assert extract_local_context("txt", stream).reason == "byte_limit" + with pytest.raises(StopIteration): + next(stream) @pytest.mark.parametrize(