codeplain 0.3.11.dev21__tar.gz → 0.3.11.dev22__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/PKG-INFO +1 -1
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/codeplain_REST_api.py +32 -26
- codeplain-0.3.11.dev22/render_machine/actions/fix_unit_tests.py +79 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/render_machine/actions/run_unit_tests.py +0 -9
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/render_machine/render_context.py +0 -9
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/render_machine/render_types.py +0 -45
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_fix_unit_tests_conformance_context.py +25 -120
- codeplain-0.3.11.dev21/render_machine/actions/fix_unit_tests.py +0 -256
- codeplain-0.3.11.dev21/render_machine/agent_tools.py +0 -270
- codeplain-0.3.11.dev21/tests/test_agent_tools.py +0 -166
- codeplain-0.3.11.dev21/tests/test_fix_unit_tests_action.py +0 -239
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/.claude/settings.json +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/.flake8 +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/.github/dependabot.yml +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/.github/workflows/e2e.yml +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/.github/workflows/lint-and-test.yml +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/.github/workflows/lint-powershell.yml +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/.github/workflows/nofity-slack-on-main-merge.yml +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/.github/workflows/publish-dev-to-pypi.yml +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/.github/workflows/publish-install-script.yml +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/.github/workflows/publish-to-pypi.yml +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/.gitignore +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/.vscode/launch.json +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/.vscode/settings.json +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/CLAUDE.md +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/CONTRIBUTING.md +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/LICENSE +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/README.md +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/change_detection.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/cli_output/__init__.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/cli_output/dry_run.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/cli_output/render_summary.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/cli_output/status.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/concept_utils.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/config/__init__.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/config/system_config.yaml +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/conformance_fix_journal.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/diff_utils.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/docs/generate_cli.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/docs/plain2code_cli.md +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/docs/starting_a_plain_project_from_scratch.md +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/event_bus.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/examples/example_hello_world_golang/config.yaml +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/examples/example_hello_world_golang/harness_tests/hello_world_test.go +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/examples/example_hello_world_golang/hello_world_golang.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/examples/example_hello_world_golang/run.sh +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/examples/example_hello_world_python/config.yaml +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/examples/example_hello_world_python/harness_tests/hello_world_display/test_hello_world.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/examples/example_hello_world_python/hello_world_python.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/examples/example_hello_world_python/run.sh +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/examples/example_hello_world_react/config.yaml +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/e2e/hello_world.cy.ts +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/support/e2e.ts +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress.config.ts +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/examples/example_hello_world_react/harness_tests/hello_world_display/package.json +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/examples/example_hello_world_react/harness_tests/hello_world_display/tsconfig.json +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/examples/example_hello_world_react/hello_world_react.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/examples/example_hello_world_react/run.sh +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/examples/run.sh +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/file_utils.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/git_preflight.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/git_utils.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/install/bash/examples.sh +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/install/bash/install.sh +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/install/bash/walkthrough.sh +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/install/powershell/examples.ps1 +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/install/powershell/install.ps1 +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/install/powershell/walkthrough.ps1 +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/memory_management.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/metadata_utils.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/module_renderer.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/partial_rendering.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/path_resolution.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/plain2code.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/plain2code_arguments.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/plain2code_cli.md +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/plain2code_console.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/plain2code_events.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/plain2code_exceptions.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/plain2code_logger.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/plain2code_nodes.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/plain2code_read_config.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/plain2code_state.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/plain2code_telemetry.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/plain2code_utils.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/plain_file.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/plain_modules.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/plain_spec.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/pyproject.toml +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/pytest.ini +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/render_machine/__init__.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/render_machine/actions/analyze_specification_ambiguity.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/render_machine/actions/base_action.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/render_machine/actions/commit_conformance_tests_changes.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/render_machine/actions/commit_implementation_code_changes.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/render_machine/actions/create_dist.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/render_machine/actions/distill_conformance_test_memory.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/render_machine/actions/exit_with_error.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/render_machine/actions/finish_functional_requirement.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/render_machine/actions/fix_conformance_test.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/render_machine/actions/prepare_repositories.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/render_machine/actions/prepare_testing_environment.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/render_machine/actions/refactor_code.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/render_machine/actions/render_conformance_tests.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/render_machine/actions/render_functional_requirement.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/render_machine/actions/run_conformance_tests.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/render_machine/actions/summarize_conformance_tests.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/render_machine/code_renderer.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/render_machine/conformance_tests.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/render_machine/implementation_code_helpers.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/render_machine/render_utils.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/render_machine/state_machine_config.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/render_machine/states.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/render_machine/triggers.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/requirements.txt +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/resources/codeplain_overview.png +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/resources/plain_example.png +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/standard_template_library/golang-console-app-template.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/standard_template_library/python-console-app-template.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/standard_template_library/typescript-react-app-boilerplate.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/standard_template_library/typescript-react-app-template.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/system_config.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/test_scripts/run_conformance_tests_cypress.ps1 +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/test_scripts/run_conformance_tests_cypress.sh +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/test_scripts/run_conformance_tests_golang.ps1 +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/test_scripts/run_conformance_tests_golang.sh +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/test_scripts/run_conformance_tests_python.ps1 +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/test_scripts/run_conformance_tests_python.sh +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/test_scripts/run_unittests_flutter.ps1 +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/test_scripts/run_unittests_flutter.sh +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/test_scripts/run_unittests_golang.ps1 +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/test_scripts/run_unittests_golang.sh +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/test_scripts/run_unittests_python.ps1 +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/test_scripts/run_unittests_python.sh +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/test_scripts/run_unittests_react.ps1 +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/test_scripts/run_unittests_react.sh +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/__init__.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/conftest.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/acceptance_tests_warning/main_requiring_acceptance_tests.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/acceptance_tests_warning/required_with_acceptance_tests.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/imports/circular_imports_1.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/imports/circular_imports_2.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/imports/circular_imports_main.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/imports/diamond_import_1.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/imports/diamond_import_2.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/imports/diamond_import_common.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/imports/diamond_imports_main.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/imports/import_with_functionalities.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/imports/imports_module_with_functionalities.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/imports/non_existent_import.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/partial_rendering/pr_code_var.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/partial_rendering/pr_implement.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/partial_rendering/pr_leaf.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/partial_rendering/pr_middle.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/partial_rendering/pr_root.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/partial_rendering/pr_solo.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfile/add_new_task_modal_specification.yaml +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfile/duplicate_specification_heading.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfile/empty_functional_specs_section.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfile/invalid_specification_order.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfile/missing_non_functional_requirements.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfile/no_functional_specs_section.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfile/plain_source_with_absolute_link.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfile/plain_source_with_missing_link.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfile/plain_source_with_url_link.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfile/task_list_ui_specification.yaml +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfile/task_manager_with_reference_links.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfile/without_non_functional_requirement.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/concept_validation_acceptance_tests.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/concept_validation_acceptance_tests_nondefined.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/concept_validation_defined_nondefined.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/concept_validation_defined_nondefined_2.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/concept_validation_definition.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/concept_validation_noconcepts.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/concept_validation_nonconcept.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/concept_validation_nondefined.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/concept_validation_redefinition.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/concept_validation_several_concepts.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/concept_validation_valid.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/cyclic_definitions.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/exported_concepts.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/exported_concepts_base.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/exported_concepts_defaults_exported.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/exported_concepts_example.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/exported_concepts_imported_exported.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/exported_concepts_inherited_reexported.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/exported_concepts_malformed.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/exported_concepts_missing_definition.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/exported_concepts_missing_definition_example.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/exported_concepts_multiple_per_bullet.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/exported_concepts_multiple_per_bullet_undefined.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/exported_concepts_nested.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/exported_concepts_nested_example.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/exported_concepts_no_definitions.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/exported_concepts_not_declared.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/exported_concepts_not_declared_example.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/exported_concepts_transitive_example.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/exported_concepts_transitive_l1.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/exported_concepts_transitive_l2.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/plain_file_parser_with_comments.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/plain_file_with_comments_indented.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/regular_plain_source.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/required_concepts.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/required_concepts_defs.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/required_concepts_example.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/required_concepts_l1.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/required_concepts_l2.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/required_concepts_missing.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/required_concepts_module.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/required_concepts_partial.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/required_concepts_partial_duplicate.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/requires_without_definitions_example.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/topological_sort.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/plainfileparser/topological_sort_not_referenced.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/requires/circular_requires_main.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/requires/circular_requires_sub.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/requires/diamond_requires_1.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/requires/diamond_requires_2.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/requires/diamond_requires_common.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/requires/diamond_requires_main.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/requires/independent_requires_1.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/requires/independent_requires_2.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/requires/independent_requires_main.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/requires/non_existent_require.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/requires/normal_requires_1.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/requires/normal_requires_2.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/requires/normal_requires_common.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/requires/normal_requires_main.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/sample_base64_image.txt +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/simple.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/templates/block_level_include.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/templates/code_variables.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/templates/header.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/templates/implement.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/templates/implement_2.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/templates/template_include.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/data/templates/test_hardest_problem.plain +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/e2e/Dockerfile +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/e2e/conftest.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/e2e/test_hello_world_python.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/e2e/test_hello_world_python_windows.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_arg_provenance.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_change_detection.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_cli_output.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_conformance_fix_journal.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_console_log_styles.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_distill_conformance_test_memory.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_dry_run_link_validation.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_file_utils.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_folder_path_resolution.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_git_preflight.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_git_utils.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_headless_logging.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_imports.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_log_file_name_resolution.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_logging_config_path_resolution.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_partial_rendering.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_path_resolution.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_plain2code.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_plain2code_state.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_plain2code_utils.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_plain_modules.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_plainfile.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_plainfileparser.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_plainspec.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_prepare_repositories_layout.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_render_finished_report.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_requires.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_resolve_config_file.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_script_path_resolution.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_system_config.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_telemetry.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_tui_components.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_tui_usage.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_usage_summary.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tui/__init__.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tui/components.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tui/models.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tui/plain2code_tui.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tui/plain_module_render_choice_tui.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tui/spinner.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tui/state_handlers.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tui/styles.css +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tui/widget_helpers.py +0 -0
- {codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/usage_summary.py +0 -0
|
@@ -253,6 +253,38 @@ class CodeplainAPI:
|
|
|
253
253
|
|
|
254
254
|
return self.post_request(endpoint_url, headers, payload, run_state)
|
|
255
255
|
|
|
256
|
+
def fix_unittests_issue(
|
|
257
|
+
self,
|
|
258
|
+
frid,
|
|
259
|
+
plain_source_tree,
|
|
260
|
+
linked_resources,
|
|
261
|
+
existing_files_content,
|
|
262
|
+
module_name: str,
|
|
263
|
+
required_modules,
|
|
264
|
+
unittests_issue,
|
|
265
|
+
run_state: RunState,
|
|
266
|
+
conformance_tests_fixes: list[dict] | None = None,
|
|
267
|
+
):
|
|
268
|
+
endpoint_url = f"{self.api_url}/fix_unittests_issue"
|
|
269
|
+
headers = {"X-API-Key": self.api_key, "Content-Type": "application/json"}
|
|
270
|
+
|
|
271
|
+
payload = {
|
|
272
|
+
"frid": frid,
|
|
273
|
+
"plain_source_tree": plain_source_tree,
|
|
274
|
+
"linked_resources": linked_resources,
|
|
275
|
+
"existing_files_content": existing_files_content,
|
|
276
|
+
"module_name": module_name,
|
|
277
|
+
"required_modules": required_modules,
|
|
278
|
+
"unittests_issue": unittests_issue,
|
|
279
|
+
"unittest_batch_id": run_state.unittest_batch_id,
|
|
280
|
+
}
|
|
281
|
+
# Implementation code changes made by the conformance tests fixer right before this unit tests run;
|
|
282
|
+
# only sent when unit tests are processed inside the conformance tests phase.
|
|
283
|
+
if conformance_tests_fixes is not None:
|
|
284
|
+
payload["conformance_tests_fixes"] = conformance_tests_fixes
|
|
285
|
+
|
|
286
|
+
return self.post_request(endpoint_url, headers, payload, run_state)
|
|
287
|
+
|
|
256
288
|
def distill_conformance_test_memory(
|
|
257
289
|
self,
|
|
258
290
|
frid,
|
|
@@ -526,29 +558,3 @@ class CodeplainAPI:
|
|
|
526
558
|
}
|
|
527
559
|
|
|
528
560
|
return self.post_request(endpoint_url, headers, payload, run_state)
|
|
529
|
-
|
|
530
|
-
def agent_start(self, task_type: str, task_params: dict, frid: str, module_name: str, run_state: RunState):
|
|
531
|
-
"""Start a server-side agent session; returns the first turn (tool calls or completion)."""
|
|
532
|
-
endpoint_url = f"{self.api_url}/agent/start"
|
|
533
|
-
headers = {"X-API-Key": self.api_key, "Content-Type": "application/json"}
|
|
534
|
-
payload = {
|
|
535
|
-
"task_type": task_type,
|
|
536
|
-
"task_params": task_params,
|
|
537
|
-
"frid": frid,
|
|
538
|
-
"module_name": module_name,
|
|
539
|
-
}
|
|
540
|
-
return self.post_request(endpoint_url, headers, payload, run_state)
|
|
541
|
-
|
|
542
|
-
def agent_continue(
|
|
543
|
-
self, session_id: str, tool_results: list[dict], frid: str, module_name: str, run_state: RunState
|
|
544
|
-
):
|
|
545
|
-
"""Feed tool results into an agent session and run its next turn."""
|
|
546
|
-
endpoint_url = f"{self.api_url}/agent/continue"
|
|
547
|
-
headers = {"X-API-Key": self.api_key, "Content-Type": "application/json"}
|
|
548
|
-
payload = {
|
|
549
|
-
"session_id": session_id,
|
|
550
|
-
"tool_results": tool_results,
|
|
551
|
-
"frid": frid,
|
|
552
|
-
"module_name": module_name,
|
|
553
|
-
}
|
|
554
|
-
return self.post_request(endpoint_url, headers, payload, run_state)
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
import file_utils
|
|
4
|
+
import render_machine.render_utils as render_utils
|
|
5
|
+
from plain2code_console import console
|
|
6
|
+
from plain2code_exceptions import InternalClientError
|
|
7
|
+
from render_machine.actions.base_action import BaseAction
|
|
8
|
+
from render_machine.implementation_code_helpers import ImplementationCodeHelpers
|
|
9
|
+
from render_machine.render_context import RenderContext
|
|
10
|
+
|
|
11
|
+
MAX_ISSUE_LENGTH = 10000
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class FixUnitTests(BaseAction):
|
|
15
|
+
SUCCESSFUL_OUTCOME = "unit_tests_fix_generated"
|
|
16
|
+
|
|
17
|
+
def execute(self, render_context: RenderContext, previous_action_payload: Any | None):
|
|
18
|
+
if not previous_action_payload.get("previous_unittests_issue"):
|
|
19
|
+
raise InternalClientError(
|
|
20
|
+
"Internal client error: Previous action payload does not contain previous unit tests issue."
|
|
21
|
+
)
|
|
22
|
+
previous_unittests_issue = previous_action_payload["previous_unittests_issue"]
|
|
23
|
+
|
|
24
|
+
if previous_unittests_issue and len(previous_unittests_issue) > MAX_ISSUE_LENGTH:
|
|
25
|
+
console.debug(
|
|
26
|
+
f"Unit tests issue text is too long and will be smartly truncated to {MAX_ISSUE_LENGTH} characters."
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
existing_files, existing_files_content = ImplementationCodeHelpers.fetch_existing_files(
|
|
30
|
+
render_context.build_folder
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
render_utils.print_inputs(render_context, existing_files_content, "Files sent as input to unit tests fixing:")
|
|
34
|
+
|
|
35
|
+
conformance_tests_fixes = self._get_conformance_tests_fixes(render_context)
|
|
36
|
+
if conformance_tests_fixes:
|
|
37
|
+
console.info(
|
|
38
|
+
f"Unit tests are fixed while preserving {len(conformance_tests_fixes)} implementation code change(s) "
|
|
39
|
+
"made to fix the conformance tests."
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
response_files = render_context.codeplain_api.fix_unittests_issue(
|
|
43
|
+
render_context.frid_context.frid,
|
|
44
|
+
render_context.plain_source_tree,
|
|
45
|
+
render_context.frid_context.linked_resources,
|
|
46
|
+
existing_files_content,
|
|
47
|
+
render_context.module_name,
|
|
48
|
+
render_context.get_required_modules_functionalities(),
|
|
49
|
+
previous_unittests_issue,
|
|
50
|
+
run_state=render_context.run_state,
|
|
51
|
+
conformance_tests_fixes=conformance_tests_fixes,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
_, changed_files = file_utils.update_build_folder_with_rendered_files(
|
|
55
|
+
render_context.build_folder, existing_files, response_files
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
render_context.unit_tests_running_context.changed_files.update(changed_files)
|
|
59
|
+
|
|
60
|
+
console.print_files("Files fixed:", render_context.build_folder, response_files, style=console.OUTPUT_STYLE)
|
|
61
|
+
|
|
62
|
+
return self.SUCCESSFUL_OUTCOME, None
|
|
63
|
+
|
|
64
|
+
@staticmethod
|
|
65
|
+
def _get_conformance_tests_fixes(render_context: RenderContext) -> list[dict] | None:
|
|
66
|
+
"""Implementation code changes the conformance tests fixer made before these unit tests were run.
|
|
67
|
+
|
|
68
|
+
Only present when unit tests are processed inside the conformance tests phase - the implementation
|
|
69
|
+
and refactoring unit test passes have no conformance tests running context.
|
|
70
|
+
"""
|
|
71
|
+
conformance_tests_running_context = getattr(render_context, "conformance_tests_running_context", None)
|
|
72
|
+
if conformance_tests_running_context is None:
|
|
73
|
+
return None
|
|
74
|
+
|
|
75
|
+
implementation_code_fixes = getattr(conformance_tests_running_context, "implementation_code_fixes", None)
|
|
76
|
+
if not implementation_code_fixes:
|
|
77
|
+
return None
|
|
78
|
+
|
|
79
|
+
return list(implementation_code_fixes)
|
|
@@ -16,15 +16,6 @@ class RunUnitTests(BaseAction):
|
|
|
16
16
|
UNRECOVERABLE_ERROR_OUTCOME = "unrecoverable_error_occurred"
|
|
17
17
|
|
|
18
18
|
def execute(self, render_context: RenderContext, _previous_action_payload: Any | None):
|
|
19
|
-
context = render_context.unit_tests_running_context
|
|
20
|
-
if context.verified_passing:
|
|
21
|
-
# The fixing agent's own run passed and no file changed since; running again is redundant.
|
|
22
|
-
context.verified_passing = False
|
|
23
|
-
console.info("Unit tests already passed in the fixing agent's last run; not running them again.")
|
|
24
|
-
render_context.script_execution_history.latest_unit_test_output_path = context.verified_passing_log_path
|
|
25
|
-
render_context.script_execution_history.should_update_script_outputs = True
|
|
26
|
-
return self.SUCCESSFUL_OUTCOME, None
|
|
27
|
-
|
|
28
19
|
unittests_script = os.path.normpath(render_context.unittests_script)
|
|
29
20
|
|
|
30
21
|
console.info(
|
|
@@ -19,7 +19,6 @@ from render_machine.render_types import (
|
|
|
19
19
|
FridContext,
|
|
20
20
|
ScriptExecutionHistory,
|
|
21
21
|
TestExecutionPhase,
|
|
22
|
-
UnitTestsAgentSession,
|
|
23
22
|
UnitTestsRunningContext,
|
|
24
23
|
)
|
|
25
24
|
|
|
@@ -189,14 +188,6 @@ class RenderContext:
|
|
|
189
188
|
def should_run_conformance_tests(self) -> bool:
|
|
190
189
|
return self.conformance_tests_script is not None
|
|
191
190
|
|
|
192
|
-
@property
|
|
193
|
-
def unit_tests_agent_session(self) -> UnitTestsAgentSession:
|
|
194
|
-
"""The agent session fixing the unit tests: per unit-test loop, except during the conformance
|
|
195
|
-
phase, where one session spans every loop (see UnitTestsAgentSession)."""
|
|
196
|
-
if self.conformance_tests_running_context is not None:
|
|
197
|
-
return self.conformance_tests_running_context.unit_tests_agent_session
|
|
198
|
-
return self.unit_tests_running_context.agent_session
|
|
199
|
-
|
|
200
191
|
def start_unittests_processing(self):
|
|
201
192
|
self.unit_tests_running_context = UnitTestsRunningContext(fix_attempts=0)
|
|
202
193
|
self.run_state.increment_unittest_batch_id()
|
|
@@ -48,53 +48,10 @@ class FridContext:
|
|
|
48
48
|
refactoring_iteration: int = 0
|
|
49
49
|
|
|
50
50
|
|
|
51
|
-
@dataclass
|
|
52
|
-
class UnitTestsAgentSession:
|
|
53
|
-
"""Server-side agent session fixing a FRID's unit tests, and what it still has to be told.
|
|
54
|
-
|
|
55
|
-
Owned by the unit-tests running context (one session per unit-test loop) in the implementation
|
|
56
|
-
and refactoring phases, and by the conformance tests running context during the conformance
|
|
57
|
-
phase, so there one session spans every unit-test loop - the agent then sees that the
|
|
58
|
-
conformance tests fixer keeps changing the code it adjusts (see RenderContext.unit_tests_agent_session).
|
|
59
|
-
"""
|
|
60
|
-
|
|
61
|
-
session_id: Optional[str] = None
|
|
62
|
-
# The submit_fix call the agent ended its last attempt with, answered with the next test
|
|
63
|
-
# run's outcome, plus results of any tool calls made in the same turn as submit_fix.
|
|
64
|
-
pending_submit_call_id: Optional[str] = None
|
|
65
|
-
pending_tool_results: list[dict] = field(default_factory=list)
|
|
66
|
-
# Session abandoned without a submission (turn budget used up, LLM failure); the next session
|
|
67
|
-
# starts with a digest of what it tried.
|
|
68
|
-
previous_session_id: Optional[str] = None
|
|
69
|
-
# Full test logs the agent was pointed to; readable by read_file/grep although outside the
|
|
70
|
-
# build folder.
|
|
71
|
-
readable_log_paths: set[str] = field(default_factory=set)
|
|
72
|
-
# How many of the conformance tests fixes (ConformanceTestsRunningContext.implementation_code_fixes)
|
|
73
|
-
# the session has already been shown.
|
|
74
|
-
conformance_fixes_handed_off: int = 0
|
|
75
|
-
|
|
76
|
-
def reset(self) -> None:
|
|
77
|
-
"""Drop the session (keeping its id as the previous one) so the next failure starts a new one."""
|
|
78
|
-
self.previous_session_id = self.session_id
|
|
79
|
-
self.session_id, self.pending_submit_call_id, self.pending_tool_results = None, None, []
|
|
80
|
-
self.conformance_fixes_handed_off = 0
|
|
81
|
-
|
|
82
|
-
|
|
83
51
|
@dataclass
|
|
84
52
|
class UnitTestsRunningContext:
|
|
85
53
|
fix_attempts: int
|
|
86
54
|
changed_files: set[str] = field(default_factory=set)
|
|
87
|
-
# The agent session of this loop; used only outside the conformance phase.
|
|
88
|
-
agent_session: UnitTestsAgentSession = field(default_factory=UnitTestsAgentSession)
|
|
89
|
-
# Whether the agent already made a fix attempt in this loop. A session that is still open when
|
|
90
|
-
# a loop starts had its last fix accepted, which is what the agent is told.
|
|
91
|
-
agent_used_in_this_loop: bool = False
|
|
92
|
-
# Set when the agent's own run_unit_tests passed and no file changed since, so the harness
|
|
93
|
-
# can accept the fix without running the suite again.
|
|
94
|
-
verified_passing: bool = False
|
|
95
|
-
verified_passing_log_path: Optional[str] = None
|
|
96
|
-
# Results of read-only tool calls, keyed by call; cleared whenever a file changes.
|
|
97
|
-
tool_result_cache: dict[str, str] = field(default_factory=dict)
|
|
98
55
|
|
|
99
56
|
|
|
100
57
|
class ConformanceTestsRunningContext:
|
|
@@ -138,8 +95,6 @@ class ConformanceTestsRunningContext:
|
|
|
138
95
|
# order. Each entry is {"hypothesis": str | None, "approach": str | None, "code_diff": {file: diff}}.
|
|
139
96
|
# Handed to the unit tests fixer so it adjusts the unit tests instead of reverting these changes.
|
|
140
97
|
self.implementation_code_fixes: list[dict] = []
|
|
141
|
-
# The unit-test fixing agent session, shared by every unit-test loop of this conformance phase.
|
|
142
|
-
self.unit_tests_agent_session = UnitTestsAgentSession()
|
|
143
98
|
|
|
144
99
|
def get_conformance_tests_json(self, module_name: str) -> dict:
|
|
145
100
|
return self._conformance_tests_json[module_name]
|
{codeplain-0.3.11.dev21 → codeplain-0.3.11.dev22}/tests/test_fix_unit_tests_conformance_context.py
RENAMED
|
@@ -12,44 +12,25 @@ import pytest
|
|
|
12
12
|
|
|
13
13
|
import plain_spec
|
|
14
14
|
from memory_management import MemoryManager
|
|
15
|
+
from render_machine.actions import fix_unit_tests as fix_unit_tests_module
|
|
15
16
|
from render_machine.actions.fix_conformance_test import FixConformanceTest
|
|
16
17
|
from render_machine.actions.fix_unit_tests import FixUnitTests
|
|
17
18
|
from render_machine.implementation_code_helpers import ImplementationCodeHelpers
|
|
18
|
-
from render_machine.
|
|
19
|
-
from render_machine.render_types import ConformanceTestsRunningContext, ScriptExecutionHistory, UnitTestsRunningContext
|
|
19
|
+
from render_machine.render_types import ConformanceTestsRunningContext, UnitTestsRunningContext
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
class FakeCodeplainAPI:
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def __init__(self, conformance_fix_response=None):
|
|
23
|
+
def __init__(self, conformance_fix_response=None, unittests_fix_response=None):
|
|
26
24
|
self.conformance_fix_response = conformance_fix_response
|
|
27
|
-
self.
|
|
28
|
-
self.
|
|
25
|
+
self.unittests_fix_response = unittests_fix_response or {}
|
|
26
|
+
self.unittests_fix_calls = []
|
|
29
27
|
|
|
30
28
|
def fix_conformance_tests_issue(self, *args, **kwargs):
|
|
31
29
|
return self.conformance_fix_response
|
|
32
30
|
|
|
33
|
-
def
|
|
34
|
-
self.
|
|
35
|
-
self.
|
|
36
|
-
return self._submit(f"s{self.sessions_started}")
|
|
37
|
-
|
|
38
|
-
def agent_continue(self, session_id, tool_results, frid, module_name, run_state):
|
|
39
|
-
self.agent_calls.append(("continue", session_id, tool_results))
|
|
40
|
-
return self._submit(session_id)
|
|
41
|
-
|
|
42
|
-
def _submit(self, session_id):
|
|
43
|
-
call_id = f"submit-{len(self.agent_calls)}"
|
|
44
|
-
return {
|
|
45
|
-
"session_id": session_id,
|
|
46
|
-
"status": "tool_calls",
|
|
47
|
-
"calls": [{"id": call_id, "name": "submit_fix", "args": {"changes_made": "fixed"}}],
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
class FakeRenderContext(SimpleNamespace):
|
|
52
|
-
unit_tests_agent_session = RenderContext.unit_tests_agent_session
|
|
31
|
+
def fix_unittests_issue(self, *args, **kwargs):
|
|
32
|
+
self.unittests_fix_calls.append(kwargs)
|
|
33
|
+
return self.unittests_fix_response
|
|
53
34
|
|
|
54
35
|
|
|
55
36
|
class FakeConformanceTests:
|
|
@@ -78,11 +59,7 @@ def memory_folder():
|
|
|
78
59
|
def isolate_from_git_and_console(monkeypatch):
|
|
79
60
|
monkeypatch.setattr(ImplementationCodeHelpers, "get_code_diff", staticmethod(lambda *args: {}))
|
|
80
61
|
monkeypatch.setattr(plain_spec, "collect_linked_resources", lambda *args: None)
|
|
81
|
-
monkeypatch.setattr(
|
|
82
|
-
plain_spec,
|
|
83
|
-
"get_specifications_for_frid",
|
|
84
|
-
lambda tree, frid: ({plain_spec.FUNCTIONAL_REQUIREMENTS: ["- Add numbers."]}, None),
|
|
85
|
-
)
|
|
62
|
+
monkeypatch.setattr(fix_unit_tests_module.render_utils, "print_inputs", lambda *args: None)
|
|
86
63
|
|
|
87
64
|
|
|
88
65
|
def make_conformance_context():
|
|
@@ -99,7 +76,7 @@ def make_conformance_context():
|
|
|
99
76
|
|
|
100
77
|
|
|
101
78
|
def make_render_context(api, build_folder, memory_folder, conformance_tests_running_context):
|
|
102
|
-
return
|
|
79
|
+
return SimpleNamespace(
|
|
103
80
|
codeplain_api=api,
|
|
104
81
|
build_folder=build_folder,
|
|
105
82
|
memory_manager=MemoryManager(api, memory_folder),
|
|
@@ -109,11 +86,9 @@ def make_render_context(api, build_folder, memory_folder, conformance_tests_runn
|
|
|
109
86
|
plain_source_tree={},
|
|
110
87
|
module_name="mod",
|
|
111
88
|
required_modules=None,
|
|
112
|
-
frid_context=SimpleNamespace(frid="1", linked_resources={}
|
|
89
|
+
frid_context=SimpleNamespace(frid="1", linked_resources={}),
|
|
113
90
|
get_required_modules_functionalities=lambda: {},
|
|
114
91
|
run_state=SimpleNamespace(render_id="test-render-id", unittest_batch_id=1),
|
|
115
|
-
unittests_script=None,
|
|
116
|
-
script_execution_history=ScriptExecutionHistory(),
|
|
117
92
|
)
|
|
118
93
|
|
|
119
94
|
|
|
@@ -216,104 +191,34 @@ def test_implementation_fix_with_no_files_is_not_remembered(build_folder, memory
|
|
|
216
191
|
assert ctx.implementation_code_fixes == []
|
|
217
192
|
|
|
218
193
|
|
|
219
|
-
def run_unit_tests_fix(render_context
|
|
220
|
-
return FixUnitTests().execute(render_context, {"previous_unittests_issue":
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
def start_new_unit_test_loop(render_context):
|
|
224
|
-
"""What RenderContext.start_unittests_processing does when the unit tests are run again."""
|
|
225
|
-
render_context.unit_tests_running_context = UnitTestsRunningContext(fix_attempts=0)
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
def conformance_fix(number):
|
|
229
|
-
return {
|
|
230
|
-
"hypothesis": f"hypothesis {number}",
|
|
231
|
-
"approach": f"approach {number}",
|
|
232
|
-
"code_diff": {"app.py": f"+{number}"},
|
|
233
|
-
}
|
|
194
|
+
def run_unit_tests_fix(render_context):
|
|
195
|
+
return FixUnitTests().execute(render_context, {"previous_unittests_issue": "1 failed"})
|
|
234
196
|
|
|
235
197
|
|
|
236
|
-
def
|
|
237
|
-
api = FakeCodeplainAPI()
|
|
198
|
+
def test_unit_tests_fix_forwards_conformance_fixes(build_folder, memory_folder):
|
|
199
|
+
api = FakeCodeplainAPI(unittests_fix_response={"test_app.py": "def test_add(): pass\n"})
|
|
238
200
|
ctx = make_conformance_context()
|
|
239
|
-
ctx.implementation_code_fixes.append(
|
|
201
|
+
ctx.implementation_code_fixes.append(
|
|
202
|
+
{"hypothesis": "off by one", "approach": "add one", "code_diff": {"app.py": "+ return a + b + 1"}}
|
|
203
|
+
)
|
|
240
204
|
render_context = make_render_context(api, build_folder, memory_folder, ctx)
|
|
241
205
|
|
|
242
206
|
outcome, _ = run_unit_tests_fix(render_context)
|
|
243
207
|
|
|
244
208
|
assert outcome == FixUnitTests.SUCCESSFUL_OUTCOME
|
|
245
|
-
|
|
246
|
-
assert
|
|
247
|
-
assert task_params["conformance_tests_fixes"] == ctx.implementation_code_fixes
|
|
209
|
+
assert len(api.unittests_fix_calls) == 1
|
|
210
|
+
assert api.unittests_fix_calls[0]["conformance_tests_fixes"] == ctx.implementation_code_fixes
|
|
248
211
|
# The forwarded list is a copy, so later conformance fixes do not mutate what was sent.
|
|
249
|
-
assert
|
|
250
|
-
# The file the conformance fix changed is seeded although the FRID did not change it.
|
|
251
|
-
assert "app.py" in task_params["relevant_files"]
|
|
252
|
-
assert ctx.unit_tests_agent_session.session_id == "s1"
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
def test_next_unit_test_loop_of_conformance_phase_continues_the_session_with_only_new_fixes(
|
|
256
|
-
build_folder, memory_folder
|
|
257
|
-
):
|
|
258
|
-
api = FakeCodeplainAPI()
|
|
259
|
-
ctx = make_conformance_context()
|
|
260
|
-
ctx.implementation_code_fixes.append(conformance_fix(1))
|
|
261
|
-
render_context = make_render_context(api, build_folder, memory_folder, ctx)
|
|
262
|
-
run_unit_tests_fix(render_context)
|
|
263
|
-
|
|
264
|
-
# The fix was accepted; the conformance tests fixer changes the code again and the unit tests fail again.
|
|
265
|
-
ctx.implementation_code_fixes.append(conformance_fix(2))
|
|
266
|
-
start_new_unit_test_loop(render_context)
|
|
267
|
-
run_unit_tests_fix(render_context, issue="2 failed")
|
|
212
|
+
assert api.unittests_fix_calls[0]["conformance_tests_fixes"] is not ctx.implementation_code_fixes
|
|
268
213
|
|
|
269
|
-
assert api.sessions_started == 1
|
|
270
|
-
kind, session_id, tool_results = api.agent_calls[1]
|
|
271
|
-
assert (kind, session_id) == ("continue", "s1")
|
|
272
|
-
submit_answer = tool_results[-1]
|
|
273
|
-
assert submit_answer["call_id"] == "submit-1"
|
|
274
|
-
assert submit_answer["output"].startswith("Your fix was accepted: the unit tests passed.")
|
|
275
|
-
assert "Conformance Tests Fix below" in submit_answer["output"]
|
|
276
|
-
assert submit_answer["conformance_tests_fixes"] == [conformance_fix(2)]
|
|
277
|
-
assert submit_answer["test_output"] == "2 failed"
|
|
278
214
|
|
|
279
|
-
|
|
280
|
-
def test_retry_within_a_unit_test_loop_says_the_fix_did_not_work(build_folder, memory_folder):
|
|
281
|
-
api = FakeCodeplainAPI()
|
|
282
|
-
ctx = make_conformance_context()
|
|
283
|
-
ctx.implementation_code_fixes.append(conformance_fix(1))
|
|
284
|
-
render_context = make_render_context(api, build_folder, memory_folder, ctx)
|
|
285
|
-
run_unit_tests_fix(render_context)
|
|
286
|
-
|
|
287
|
-
run_unit_tests_fix(render_context, issue="still failing")
|
|
288
|
-
|
|
289
|
-
submit_answer = api.agent_calls[1][2][-1]
|
|
290
|
-
assert "still fail" in submit_answer["output"]
|
|
291
|
-
# Fix 1 was already shown to the session, so it is not sent again.
|
|
292
|
-
assert "conformance_tests_fixes" not in submit_answer
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
def test_new_conformance_phase_starts_a_new_session(build_folder, memory_folder):
|
|
296
|
-
api = FakeCodeplainAPI()
|
|
297
|
-
render_context = make_render_context(api, build_folder, memory_folder, make_conformance_context())
|
|
298
|
-
run_unit_tests_fix(render_context)
|
|
299
|
-
|
|
300
|
-
# E.g. the functionality is re-rendered from scratch: the conformance tests running context is recreated.
|
|
301
|
-
render_context.conformance_tests_running_context = make_conformance_context()
|
|
302
|
-
start_new_unit_test_loop(render_context)
|
|
303
|
-
run_unit_tests_fix(render_context)
|
|
304
|
-
|
|
305
|
-
assert [call[0] for call in api.agent_calls] == ["start", "start"]
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
def test_unit_tests_outside_conformance_phase_get_no_fixes_and_a_session_per_loop(build_folder, memory_folder):
|
|
215
|
+
def test_unit_tests_fix_outside_conformance_phase_sends_no_fixes(build_folder, memory_folder):
|
|
309
216
|
api = FakeCodeplainAPI()
|
|
310
217
|
render_context = make_render_context(api, build_folder, memory_folder, None)
|
|
311
|
-
|
|
312
|
-
start_new_unit_test_loop(render_context)
|
|
218
|
+
|
|
313
219
|
run_unit_tests_fix(render_context)
|
|
314
220
|
|
|
315
|
-
assert [
|
|
316
|
-
assert all("conformance_tests_fixes" not in call[1] for call in api.agent_calls)
|
|
221
|
+
assert api.unittests_fix_calls[0]["conformance_tests_fixes"] is None
|
|
317
222
|
|
|
318
223
|
|
|
319
224
|
def test_unit_tests_fix_in_conformance_phase_without_implementation_changes_sends_no_fixes(build_folder, memory_folder):
|
|
@@ -322,4 +227,4 @@ def test_unit_tests_fix_in_conformance_phase_without_implementation_changes_send
|
|
|
322
227
|
|
|
323
228
|
run_unit_tests_fix(render_context)
|
|
324
229
|
|
|
325
|
-
assert
|
|
230
|
+
assert api.unittests_fix_calls[0]["conformance_tests_fixes"] is None
|