nighthawk-python 0.15.0__tar.gz → 0.16.0__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.
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/.github/workflows/ci.yml +14 -14
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/.github/workflows/docs.yml +26 -8
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/.github/workflows/publish.yml +1 -1
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/CHANGELOG.md +19 -1
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/PKG-INFO +1 -1
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/docs/design-drivers.md +19 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/docs/embedded-execution.md +60 -7
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/docs/executors.md +39 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/docs/for-coding-agents.md +5 -5
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/docs/natural-blocks.md +4 -3
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/docs/patterns.md +14 -13
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/docs/roadmap.md +1 -1
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/docs/runtime-configuration.md +161 -2
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/docs/specification.md +101 -59
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/docs/verification.md +14 -9
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/README.md +10 -12
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/inspection_study.py +10 -11
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/pyproject.toml +1 -1
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/composition.py +6 -2
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/configuration.py +5 -4
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/function_call.py +16 -4
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/oversight.py +6 -3
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/environment.py +50 -29
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/expression.py +1 -1
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/model_candidate.py +12 -4
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/preparation.py +1 -4
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/prompt.py +3 -17
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/runner.py +12 -17
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/scoping.py +13 -7
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/step_context.py +2 -5
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/step_executor.py +17 -11
- nighthawk_python-0.16.0/src/nighthawk/runtime/step_request.py +99 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/testing.py +25 -23
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/docs/test_coding_agent_examples.py +1 -1
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/docs/test_error_examples.py +1 -1
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/docs/test_readme_example.py +1 -1
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/docs/test_runtime_examples.py +3 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/integration/test_natural_composition.py +19 -17
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/lifecycle/test_embedded.py +8 -4
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/lifecycle/test_step_completion.py +1 -1
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/lifecycle/test_step_ledger.py +1 -1
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/natural/test_runtime_name_hygiene.py +7 -6
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/oversight/test_step_commit.py +9 -12
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/resilience/test_composition.py +2 -2
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/resilience/test_retry.py +1 -1
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_discovery.py +7 -7
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_embedded.py +37 -4
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_environment.py +32 -14
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_executor_contract.py +6 -1
- nighthawk_python-0.16.0/tests/runtime/test_explicit_sharing.py +317 -0
- nighthawk_python-0.16.0/tests/runtime/test_input_patterns.py +151 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_model_selection.py +2 -2
- nighthawk_python-0.16.0/tests/runtime/test_output_selection.py +135 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_preparation.py +1 -1
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_runner.py +10 -5
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_step_executor.py +5 -1
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_workflows.py +5 -5
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/support/executors.py +4 -3
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/test_testing.py +28 -26
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/uv.lock +36 -36
- nighthawk_python-0.15.0/src/nighthawk/runtime/step_request.py +0 -61
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/.claude/rules/docs.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/.claude/rules/evals.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/.claude/rules/promptfoo.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/.claude/rules/python.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/.claude/rules/src.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/.claude/rules/tests.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/.claude/settings.json +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/.claude/unset_envs.sh +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/.devcontainer/devcontainer-lock.json +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/.devcontainer/devcontainer.json +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/.devcontainer/postCreateCommand.sh +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/.github/dependabot.yml +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/.gitignore +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/.python-version +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/AGENTS.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/CLAUDE.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/CONTRIBUTING.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/LICENSE +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/README.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/docs/AGENTS.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/docs/api.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/docs/assets/nighthawk_logo-128x128.png +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/docs/coding-agent-backends.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/docs/index.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/docs/philosophy.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/docs/pydantic-ai-providers.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/docs/quickstart.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/AGENTS.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/coding_agents/evidence/20260914-guide-assessment.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/__init__.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/cases.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/evidence/20260908-tool-design-review.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/evidence/20260909-assessment.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/evidence/20260909-configurations.json +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/evidence/20260909-gpt56-assessment.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/evidence/20260909-gpt56-configurations.json +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/evidence/20260909-gpt56-guidance.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/evidence/20260909-gpt56-main.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/evidence/20260909-gpt56-selected-traces.json +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/evidence/20260909-gpt56-trials.csv +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/evidence/20260909-guidance.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/evidence/20260909-main.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/evidence/20260909-selected-traces.json +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/evidence/20260909-trials.csv +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/evidence/20260910-natural-composition.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/evidence/20260910-python-boundaries.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/evidence/20260911-ideal-state-audit.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/evidence/20260911-inspection-artifact-manifest.json +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/evidence/20260911-inspection-assessment.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/evidence/20260911-inspection-failure-traces.jsonl +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/evidence/20260911-inspection-study-protocol.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/evidence/20260911-inspection-trial-metrics.csv +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/prototype.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/report.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/model_tools/run.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/AGENTS.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/assertions/__init__.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/assertions/binding_value.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/assertions/outcome_kind.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/assertions/raise_message.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/evidence/2026-03-26-baseline-prompt-ab.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/evidence/2026-03-26-baseline-regression.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/evidence/2026-03-26-baseline-suffix-ab.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/evidence/2026-04-27-runtime-prompt-optimization.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/promptfooconfig-agents.yaml +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/promptfooconfig-luna-sanity.yaml +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/promptfooconfig-prompt-ab.yaml +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/promptfooconfig-suffix-ab.yaml +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/promptfooconfig.yaml +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/prompts/eval_coding_agent.txt +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/prompts/eval_default.txt +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/prompts/eval_legacy_default.txt +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/prompts/eval_mutation_aware.txt +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/prompts/eval_sequenced.txt +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/provider.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/research-result.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/test_cases/binding_operations.yaml +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/test_cases/edge_cases.yaml +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/test_cases/loop_outcomes.yaml +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/test_cases/loop_outcomes_ja.yaml +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/test_cases/multi_step.yaml +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/test_cases/null_handling.yaml +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/test_cases/outcome_kinds.yaml +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/evals/promptfoo/test_cases/tool_selection.yaml +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/mkdocs.yml +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/pyrightconfig.json +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/AGENTS.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/__init__.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/backends/__init__.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/backends/_text_fallback.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/backends/base.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/backends/claude_code_cli.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/backends/claude_code_sdk.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/backends/claude_code_settings.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/backends/codex.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/backends/mcp_boundary.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/backends/mcp_server.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/backends/process_management.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/backends/text_projection.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/backends/tool_bridge.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/backends/tool_transport.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/errors.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/identifier_path.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/json_renderer.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/lifecycle.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/natural/__init__.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/natural/_names.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/natural/blocks.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/natural/decorator.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/natural/definition.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/natural/transform.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/resilience/__init__.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/resilience/_budget.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/resilience/_circuit_breaker.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/resilience/_fallback.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/resilience/_retry.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/resilience/_timeout.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/resilience/_vote.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/__init__.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/_user_content.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/annotations.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/assignment.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/async_bridge.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/bindings.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/context.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/description.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/discovery.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/embedded.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/execution_reference.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/inspection.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/interruption.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/notifications.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/operation_contract.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/operations.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/step_contract.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/step_definition.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/step_result.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/runtime/tool_calls.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/tools/__init__.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/tools/_admission.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/tools/_ordering.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/tools/_tool_return_content.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/tools/assignment.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/tools/contracts.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/tools/declarations.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/tools/execution.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/tools/provided.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/src/nighthawk/ulid.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/AGENTS.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/README.md +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/__init__.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/backends/__init__.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/backends/test_base.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/backends/test_claude_code_cli.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/backends/test_claude_code_sdk.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/backends/test_codex.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/backends/test_mcp_boundary.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/backends/test_process_management.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/backends/test_text_fallback.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/backends/test_text_projection.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/backends/test_tool_bridge.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/backends/test_tool_transport.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/conftest.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/docs/__init__.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/docs/test_integrity.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/docs/test_links.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/docs/test_prompt_examples.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/evals/__init__.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/evals/model_tools/__init__.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/evals/model_tools/test_inspection_study.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/evals/model_tools/test_prototype.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/integration/__init__.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/integration/skip_helpers.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/integration/test_carry_pattern.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/integration/test_claude_code_cli.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/integration/test_claude_code_sdk.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/integration/test_codex.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/integration/test_openai.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/integration/test_openai_multimodal.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/lifecycle/__init__.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/lifecycle/test_notifications.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/natural/__init__.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/natural/test_block_ordering.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/natural/test_blocks.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/natural/test_decorator_globals.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/natural/test_deferred_annotations.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/natural/test_function_definition.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/natural/test_introspection.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/natural/test_lexical_contract.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/natural/test_methods.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/natural/test_traceback.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/natural/test_variadic_contracts.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/oversight/__init__.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/oversight/test_embedded_commit.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/oversight/test_return_expression.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/resilience/__init__.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/resilience/test_budget.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/resilience/test_circuit_breaker.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/resilience/test_fallback.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/resilience/test_timeout.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/resilience/test_vote.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/__init__.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_assignment.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_async_bridge.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_bindings.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_capabilities.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_context.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_description.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_expression.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_managed_model.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_model_candidate.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_model_operation_failures.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_operations.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_prompt_globals.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_prompt_multimodal.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_prompt_system.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_prompt_values.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_request_observation.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_scope_composition.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_scoping.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_step_contract.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_step_definition.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_tracing.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/runtime/test_usage_meter.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/support/__init__.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/support/codex.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/support/contexts.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/support/host_controls.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/support/prompts.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/support/tools.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/support/values.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/test_composition.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/test_configuration.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/test_function_call.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/test_json_renderer.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/test_public_api.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/tools/__init__.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/tools/test_admission.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/tools/test_assignment_async.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/tools/test_contracts.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/tools/test_coroutine_ownership.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/tools/test_declarations.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/tools/test_discovery_content.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/tools/test_execution.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/tools/test_ordering.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/tools/test_provided_async.py +0 -0
- {nighthawk_python-0.15.0 → nighthawk_python-0.16.0}/tests/tools/test_tool_return_content.py +0 -0
|
@@ -24,7 +24,7 @@ jobs:
|
|
|
24
24
|
persist-credentials: false
|
|
25
25
|
|
|
26
26
|
# setup-uv publishes no floating major tag since v8, so pin an exact release.
|
|
27
|
-
- uses: astral-sh/setup-uv@v10.0
|
|
27
|
+
- uses: astral-sh/setup-uv@v10.3.0
|
|
28
28
|
with:
|
|
29
29
|
python-version: "3.13"
|
|
30
30
|
# Same dependency set and cache key as "test (3.13)". Only that job
|
|
@@ -32,16 +32,16 @@ jobs:
|
|
|
32
32
|
save-cache: false
|
|
33
33
|
|
|
34
34
|
- name: Install dependencies
|
|
35
|
-
run: uv sync --all-extras --all-groups
|
|
35
|
+
run: uv sync --locked --all-extras --all-groups
|
|
36
36
|
|
|
37
37
|
- name: Format check
|
|
38
|
-
run: uv run ruff format --check .
|
|
38
|
+
run: uv run --no-sync ruff format --check .
|
|
39
39
|
|
|
40
40
|
- name: Lint
|
|
41
|
-
run: uv run ruff check .
|
|
41
|
+
run: uv run --no-sync ruff check .
|
|
42
42
|
|
|
43
43
|
- name: Type check
|
|
44
|
-
run: uv run pyright
|
|
44
|
+
run: uv run --no-sync pyright
|
|
45
45
|
|
|
46
46
|
test:
|
|
47
47
|
name: Test (Python ${{ matrix.python-version }})
|
|
@@ -49,23 +49,22 @@ jobs:
|
|
|
49
49
|
strategy:
|
|
50
50
|
fail-fast: false
|
|
51
51
|
matrix:
|
|
52
|
-
python-version: ["3.13", "3.14"]
|
|
53
|
-
continue-on-error: ${{ matrix.python-version != '3.13' }}
|
|
52
|
+
python-version: ["3.13", "3.14", "3.15"]
|
|
54
53
|
steps:
|
|
55
54
|
- uses: actions/checkout@v7
|
|
56
55
|
with:
|
|
57
56
|
persist-credentials: false
|
|
58
57
|
|
|
59
58
|
# Sole writer of the per-Python-version dependency cache.
|
|
60
|
-
- uses: astral-sh/setup-uv@v10.0
|
|
59
|
+
- uses: astral-sh/setup-uv@v10.3.0
|
|
61
60
|
with:
|
|
62
61
|
python-version: ${{ matrix.python-version }}
|
|
63
62
|
|
|
64
63
|
- name: Install dependencies
|
|
65
|
-
run: uv sync --all-extras --all-groups
|
|
64
|
+
run: uv sync --locked --all-extras --all-groups
|
|
66
65
|
|
|
67
66
|
- name: Run tests
|
|
68
|
-
run: uv run pytest -q
|
|
67
|
+
run: uv run --no-sync pytest -q
|
|
69
68
|
|
|
70
69
|
build:
|
|
71
70
|
name: Build distribution
|
|
@@ -78,7 +77,7 @@ jobs:
|
|
|
78
77
|
|
|
79
78
|
# Keep packaging and its fresh installation check independent of the
|
|
80
79
|
# source test job's dependency cache.
|
|
81
|
-
- uses: astral-sh/setup-uv@v10.0
|
|
80
|
+
- uses: astral-sh/setup-uv@v10.3.0
|
|
82
81
|
with:
|
|
83
82
|
enable-cache: false
|
|
84
83
|
|
|
@@ -87,14 +86,15 @@ jobs:
|
|
|
87
86
|
|
|
88
87
|
- name: Verify documented examples against the installed wheel
|
|
89
88
|
run: |
|
|
90
|
-
uv sync --all-groups
|
|
89
|
+
uv sync --locked --all-groups
|
|
91
90
|
uv venv "$RUNNER_TEMP/nighthawk-distribution"
|
|
92
91
|
uv pip install --python "$RUNNER_TEMP/nighthawk-distribution/bin/python" dist/*.whl
|
|
93
92
|
NIGHTHAWK_DISTRIBUTION_PYTHON="$RUNNER_TEMP/nighthawk-distribution/bin/python" \
|
|
94
|
-
uv run pytest -q tests/docs/test_runtime_examples.py
|
|
93
|
+
uv run --no-sync pytest -q tests/docs/test_runtime_examples.py
|
|
95
94
|
|
|
96
95
|
- name: Upload distribution artifacts
|
|
97
|
-
uses: actions/upload-artifact@
|
|
96
|
+
uses: actions/upload-artifact@v7
|
|
98
97
|
with:
|
|
99
98
|
name: python-package-distributions
|
|
100
99
|
path: dist/
|
|
100
|
+
if-no-files-found: error
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
name:
|
|
1
|
+
name: Build and deploy docs to GitHub Pages
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
4
|
push:
|
|
@@ -8,26 +8,38 @@ on:
|
|
|
8
8
|
- "src/nighthawk/**"
|
|
9
9
|
- "mkdocs.yml"
|
|
10
10
|
- "pyproject.toml"
|
|
11
|
+
- "uv.lock"
|
|
12
|
+
- ".python-version"
|
|
13
|
+
- ".github/workflows/docs.yml"
|
|
14
|
+
pull_request:
|
|
15
|
+
branches: [main]
|
|
16
|
+
paths:
|
|
17
|
+
- "docs/**"
|
|
18
|
+
- "src/nighthawk/**"
|
|
19
|
+
- "mkdocs.yml"
|
|
20
|
+
- "pyproject.toml"
|
|
21
|
+
- "uv.lock"
|
|
22
|
+
- ".python-version"
|
|
11
23
|
- ".github/workflows/docs.yml"
|
|
12
24
|
workflow_dispatch:
|
|
13
25
|
|
|
14
26
|
permissions:
|
|
15
27
|
contents: read
|
|
16
|
-
pages: write
|
|
17
|
-
id-token: write
|
|
18
28
|
|
|
19
29
|
concurrency:
|
|
20
|
-
group: pages
|
|
21
|
-
cancel-in-progress:
|
|
30
|
+
group: pages-${{ github.event_name == 'pull_request' && github.ref || 'deployment' }}
|
|
31
|
+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
22
32
|
|
|
23
33
|
jobs:
|
|
24
34
|
build:
|
|
25
35
|
runs-on: ubuntu-latest
|
|
26
36
|
steps:
|
|
27
37
|
- uses: actions/checkout@v7
|
|
38
|
+
with:
|
|
39
|
+
persist-credentials: false
|
|
28
40
|
|
|
29
41
|
# setup-uv publishes no floating major tag since v8, so pin an exact release.
|
|
30
|
-
- uses: astral-sh/setup-uv@v10.0
|
|
42
|
+
- uses: astral-sh/setup-uv@v10.3.0
|
|
31
43
|
with:
|
|
32
44
|
python-version: "3.13"
|
|
33
45
|
# The docs group is a subset of the cache "test (3.13)" saves under
|
|
@@ -35,18 +47,24 @@ jobs:
|
|
|
35
47
|
save-cache: false
|
|
36
48
|
|
|
37
49
|
- name: Install dependencies
|
|
38
|
-
|
|
50
|
+
# The default dev group supplies Ruff for API signature formatting.
|
|
51
|
+
run: uv sync --locked --group docs
|
|
39
52
|
|
|
40
53
|
- name: Build docs
|
|
41
|
-
run: uv run mkdocs build
|
|
54
|
+
run: uv run --no-sync mkdocs build
|
|
42
55
|
|
|
43
56
|
- uses: actions/upload-pages-artifact@v5
|
|
57
|
+
if: github.event_name != 'pull_request'
|
|
44
58
|
with:
|
|
45
59
|
path: site
|
|
46
60
|
|
|
47
61
|
deploy:
|
|
62
|
+
if: github.event_name != 'pull_request'
|
|
48
63
|
needs: build
|
|
49
64
|
runs-on: ubuntu-latest
|
|
65
|
+
permissions:
|
|
66
|
+
pages: write
|
|
67
|
+
id-token: write
|
|
50
68
|
environment:
|
|
51
69
|
name: github-pages
|
|
52
70
|
url: ${{ steps.deployment.outputs.page_url }}
|
|
@@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.16.0]
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Breaking: `StepCandidate` and testing responses distinguish omitted output selection (`UNSET`, select initialized declared outputs) from an explicit complete mapping (`{}`, no writes). Added `StepRequest.snapshot_output_bindings()` for explicit Python composition. `StepResponse` and response factories use `binding_name_to_value`; keyword-expanded output arguments are removed.
|
|
15
|
+
- Breaking: `Raise` rejects explicit nonempty output mappings in candidates and rewrites. Standard agent executors retain automatic output selection and final validation.
|
|
16
|
+
- Breaking: optional executor configuration and run identifiers use `UNSET`; invalid `None`, raw configuration dictionaries, and empty run identifiers fail at entry. Environment mappings reject `None`, and `StepExecutorConfiguration.model_settings` defaults to an empty dictionary.
|
|
17
|
+
- `function_call_scope` now supports omission or `UNSET` for inheritance, `None` for clearing, and validated handler replacement.
|
|
18
|
+
- Breaking: Natural functions no longer copy parent working values into their environment. Share values through Python arguments, globals, closures, or explicit `scope(task_references=...)`; ordinary Python helpers can select references from the active environment. Removed the `parent` name source and `parent_name_to_value` from `StepEnvironment` and test-call records.
|
|
19
|
+
- Documented explicit working-state snapshots, scoped reference replacement and clearing, and synchronous/asynchronous host sharing examples. Updated composition examples to declare their dependencies.
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- Falsey nonempty mappings and configuration objects retain their explicit values; invalid scope arguments fail before model resolution.
|
|
24
|
+
- Nested configuration and sharing scopes preserve the active step identity so child executions retain their parent-step correlation.
|
|
25
|
+
|
|
10
26
|
## [0.15.0]
|
|
11
27
|
|
|
12
28
|
### Added
|
|
@@ -43,6 +59,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
43
59
|
|
|
44
60
|
### Fixed
|
|
45
61
|
|
|
62
|
+
- Embedded step type annotations resolve explicit and scoped names on Python 3.14, including nested forward references and names that shadow builtins.
|
|
46
63
|
- Dynamic annotation validation uses explicit `TypeForm[object]` casts at Pydantic `TypeAdapter` boundaries, restoring type-checking compatibility with Pydantic 2.14 without changing runtime validation. Declared `typing-extensions` as a direct dependency.
|
|
47
64
|
- Error-handling guides distinguish Natural-selected exceptions, recoverable tool errors, and finalization failures. Published handlers are executed against deterministic runtime responses.
|
|
48
65
|
- Tests follow environment, prompt, executor, and model-selection ownership; scope tests use current composition terminology and avoid duplicate replacement checks or fixed instrumentation names.
|
|
@@ -347,7 +364,8 @@ Invalid initial results fail before oversight; use resilience retries to recover
|
|
|
347
364
|
- Step executor abstraction and provider integration foundation.
|
|
348
365
|
- Core documentation and project scaffolding.
|
|
349
366
|
|
|
350
|
-
[Unreleased]: https://github.com/kurusugawa-computer/nighthawk-python/compare/v0.
|
|
367
|
+
[Unreleased]: https://github.com/kurusugawa-computer/nighthawk-python/compare/v0.16.0...HEAD
|
|
368
|
+
[0.16.0]: https://github.com/kurusugawa-computer/nighthawk-python/compare/v0.15.0...v0.16.0
|
|
351
369
|
[0.15.0]: https://github.com/kurusugawa-computer/nighthawk-python/compare/v0.14.0...v0.15.0
|
|
352
370
|
[0.14.0]: https://github.com/kurusugawa-computer/nighthawk-python/compare/v0.13.0...v0.14.0
|
|
353
371
|
[0.13.0]: https://github.com/kurusugawa-computer/nighthawk-python/compare/v0.12.0...v0.13.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: nighthawk-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.16.0
|
|
4
4
|
Summary: A Python library where Python controls flow and LLMs or coding agents reason within constrained Natural blocks.
|
|
5
5
|
Project-URL: Repository, https://github.com/kurusugawa-computer/nighthawk-python
|
|
6
6
|
Project-URL: Documentation, https://kurusugawa-computer.github.io/nighthawk-python/
|
|
@@ -168,6 +168,25 @@ The expected benefit is less custom host integration for dynamic declarations an
|
|
|
168
168
|
Success requires correct per-invocation value contracts and completion records that reflect writeback failures.
|
|
169
169
|
Compare the effort and complexity of constructing and changing this integration with an ordinary Python implementation providing the same guarantees.
|
|
170
170
|
|
|
171
|
+
## Explicit sharing across nested Natural calls
|
|
172
|
+
|
|
173
|
+
**Status:** The name-resolution contract is covered by deterministic tests in `tests/runtime/test_explicit_sharing.py`, with executable synchronous and asynchronous [sharing examples](runtime-configuration.md#selecting-shared-values-with-python).
|
|
174
|
+
The originating evidence is one embedded conversation host's v0.15.0 reproduction; independent application evidence and model-quality improvements remain unevaluated.
|
|
175
|
+
|
|
176
|
+
The host calls reusable Natural functions from a step containing conversation input and temporary working values.
|
|
177
|
+
Automatically copying those working names into children creates dependencies beyond the child's arguments, Python lexical environment, and deliberately shared references.
|
|
178
|
+
A context builder can omit prompt content but cannot change preparation-time binding resolution or runtime name lookup.
|
|
179
|
+
Requiring host executors to reconstruct Core preparation would move execution complexity into applications.
|
|
180
|
+
|
|
181
|
+
Core therefore constructs each child's own Python environment and supplies only the active scope's explicit task references as additional names.
|
|
182
|
+
Applications select values using ordinary Python helpers and pass dictionaries through `scope(task_references=...)`; no inheritance mode or environment-construction callback is required.
|
|
183
|
+
Scopes preserve execution parentage and existing management contracts while replacing or clearing shared references.
|
|
184
|
+
This simplifies an existing execution semantic; it does not establish a general object-isolation facility.
|
|
185
|
+
|
|
186
|
+
The deterministic evidence covers absent parent bindings, preparation failures, real context construction, expression and discovery access, object identity, nested execution, and scoped asynchronous behavior.
|
|
187
|
+
It does not establish that separating names prevents repeated model calls or improves judgments.
|
|
188
|
+
Assess those hypotheses through application evaluations, including independent reuse and the effort needed to declare shared dependencies.
|
|
189
|
+
|
|
171
190
|
## Using Nighthawk to develop Nighthawk
|
|
172
191
|
|
|
173
192
|
**Status:** Conceptual application direction.
|
|
@@ -36,7 +36,10 @@ Caller locals, globals, closure cells, and inherited parent working state are no
|
|
|
36
36
|
Scoped configuration, execution identity, oversight, capabilities, and lifecycle retain their usual inheritance rules.
|
|
37
37
|
|
|
38
38
|
Called Python functions retain their own closures and globals.
|
|
39
|
-
Nested Natural functions use their own Python frames and the
|
|
39
|
+
Nested Natural functions use their own Python frames and the active scope's explicit task references.
|
|
40
|
+
The explicit namespace and later parent temporaries do not become implicit inputs to those functions or their descendants.
|
|
41
|
+
Pass values as arguments, or use a Python helper to select references for `nh.scope(task_references=...)` before calling the child.
|
|
42
|
+
See the [synchronous and asynchronous sharing examples](runtime-configuration.md#selecting-shared-values-with-python).
|
|
40
43
|
This selects an execution environment without isolating Python objects or restricting the authority of called functions.
|
|
41
44
|
|
|
42
45
|
Omitting an output annotation selects the ordinary initial-value inference rule.
|
|
@@ -52,10 +55,13 @@ It returns `None` or an awaitable completing that assignment.
|
|
|
52
55
|
Callbacks run sequentially in output declaration order; Core records a successful assignment only after its callback returns normally.
|
|
53
56
|
Both entry points accept synchronous or asynchronous writers; the synchronous entry point uses the ordinary bridge for awaitables.
|
|
54
57
|
|
|
55
|
-
|
|
56
|
-
Tracked working values take precedence over
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
When `StepCandidate.binding_name_to_value` is omitted or `nh.UNSET`, finalization selects initialized declared outputs.
|
|
59
|
+
Tracked working values take precedence over current Python values; uninitialized outputs and task-only references remain absent.
|
|
60
|
+
A supplied mapping selects exactly those outputs, including when it is empty; omitted names are neither supplemented nor validated for writeback.
|
|
61
|
+
Selected values must satisfy their output contracts before commit inspection.
|
|
62
|
+
Use `request.snapshot_output_bindings()` and ordinary Python dictionary composition to explicitly combine current output values with replacements.
|
|
63
|
+
An initial `Raise` selects no outputs and skips validation of pending working values.
|
|
64
|
+
Pairing `Raise` with an explicitly supplied nonempty output mapping is invalid for both `StepCandidate` and `Rewrite`.
|
|
59
65
|
A commit `Rewrite` with an explicitly supplied mapping replaces the selected outputs completely; rewriting to `{}` does not restore initial values.
|
|
60
66
|
|
|
61
67
|
These are separate facts:
|
|
@@ -71,6 +77,53 @@ An interrupted writer must finish its cancellation handling before control can r
|
|
|
71
77
|
If a writer mutates storage and then raises, Core cannot infer whether the assignment completed; that writer owns diagnosis and recovery for its partial effects.
|
|
72
78
|
This interface does not promise database transactions, rollback, retries, or durable storage.
|
|
73
79
|
|
|
80
|
+
This example uses the same executor with synchronous and asynchronous entry points to distinguish automatic, empty, explicit, and composed output selections.
|
|
81
|
+
|
|
82
|
+
<!-- runnable-example:output_selection -->
|
|
83
|
+
```py
|
|
84
|
+
import asyncio
|
|
85
|
+
|
|
86
|
+
import nighthawk as nh
|
|
87
|
+
from nighthawk.runtime import Pass, StepCandidate, StepDefinition, StepRequest, execute_step, execute_step_async
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class Executor:
|
|
91
|
+
def run_step(self, *, request: StepRequest) -> StepCandidate:
|
|
92
|
+
selection = request.processed_natural_program
|
|
93
|
+
if selection == "automatic":
|
|
94
|
+
return StepCandidate(outcome=Pass())
|
|
95
|
+
if selection == "empty":
|
|
96
|
+
return StepCandidate(outcome=Pass(), binding_name_to_value={})
|
|
97
|
+
if selection == "explicit":
|
|
98
|
+
return StepCandidate(outcome=Pass(), binding_name_to_value={"first": 7})
|
|
99
|
+
return StepCandidate(outcome=Pass(), binding_name_to_value={**request.snapshot_output_bindings(), "first": 7})
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
async def main() -> None:
|
|
103
|
+
selection_to_binding_name_to_value = {
|
|
104
|
+
"automatic": {"first": 1, "second": 2},
|
|
105
|
+
"empty": {},
|
|
106
|
+
"explicit": {"first": 7},
|
|
107
|
+
"composed": {"first": 7, "second": 2},
|
|
108
|
+
}
|
|
109
|
+
with nh.run(Executor()):
|
|
110
|
+
for asynchronous in (False, True):
|
|
111
|
+
for selection, expected_binding_name_to_value in selection_to_binding_name_to_value.items():
|
|
112
|
+
saved_name_to_value: dict[str, object] = {}
|
|
113
|
+
definition = StepDefinition(selection, output_binding_names=("first", "second"))
|
|
114
|
+
initial_name_to_value = {"first": 1, "second": 2}
|
|
115
|
+
if asynchronous:
|
|
116
|
+
await execute_step_async(definition, name_to_value=initial_name_to_value, write_binding=saved_name_to_value.__setitem__)
|
|
117
|
+
else:
|
|
118
|
+
execute_step(definition, name_to_value=initial_name_to_value, write_binding=saved_name_to_value.__setitem__)
|
|
119
|
+
assert saved_name_to_value == expected_binding_name_to_value
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
asyncio.run(main())
|
|
123
|
+
print("automatic=2; empty=0; explicit=1; composed=2; sync_and_async=True")
|
|
124
|
+
```
|
|
125
|
+
<!-- /runnable-example:output_selection -->
|
|
126
|
+
|
|
74
127
|
Terminal delivery happens after writeback or failure, with the usual `StepCompleted`, `StepRaised`, `StepFailed`, or `StepInterrupted` record.
|
|
75
128
|
Notification failure propagates without replaying execution or notification and without undoing completed writes.
|
|
76
129
|
The optional `source_location` labels the trusted program for diagnostics; its default is `<embedded>:0`.
|
|
@@ -107,7 +160,7 @@ definition = StepDefinition(
|
|
|
107
160
|
binding_name_to_type={"summary": str},
|
|
108
161
|
source_location="trusted_summary:1",
|
|
109
162
|
)
|
|
110
|
-
executor = ScriptedExecutor([pass_response(
|
|
163
|
+
executor = ScriptedExecutor([pass_response(binding_name_to_value={"summary": "The trial passed."})])
|
|
111
164
|
with nh.run(executor), nh.scope(lifecycle=StepLifecycle(finished)):
|
|
112
165
|
outcome = execute_step(definition, name_to_value=name_to_value, write_binding=name_to_value.__setitem__)
|
|
113
166
|
|
|
@@ -159,7 +212,7 @@ async def main() -> None:
|
|
|
159
212
|
binding_name_to_type={"selected": "Selection"},
|
|
160
213
|
source_location="trusted_selection:1",
|
|
161
214
|
)
|
|
162
|
-
executor = ScriptedExecutor([pass_response(
|
|
215
|
+
executor = ScriptedExecutor([pass_response(binding_name_to_value={"selected": {"label": "alpha"}})])
|
|
163
216
|
with nh.run(executor), nh.scope(lifecycle=StepLifecycle(finished)):
|
|
164
217
|
outcome = await execute_step_async(definition, name_to_value={"candidates": ["alpha", "beta"], "Selection": Selection}, write_binding=write)
|
|
165
218
|
assert outcome == Pass()
|
|
@@ -30,6 +30,9 @@ step_executor = nh.AgentStepExecutor.from_configuration(configuration=configurat
|
|
|
30
30
|
|
|
31
31
|
The `model` field accepts a `provider:model` identifier or a borrowed Pydantic AI `Model` instance whose client lifetime remains with the host.
|
|
32
32
|
The default model is `openai-responses:gpt-5.6-luna`.
|
|
33
|
+
`model_settings` defaults to an empty dictionary; `None` and `UNSET` are invalid field values.
|
|
34
|
+
Optional executor configuration arguments use omission or `nh.UNSET` to create a fresh default configuration.
|
|
35
|
+
An explicit configuration replaces the complete value; raw dictionaries and `None` are rejected before constructing an agent.
|
|
33
36
|
|
|
34
37
|
Use [Runtime configuration](runtime-configuration.md) to establish a run, select child models, or mix executors.
|
|
35
38
|
Host wrappers can support model selection through the [configuration resolution protocol](specification.md#model-declarations-and-observation).
|
|
@@ -49,6 +52,42 @@ executor = nh.AgentStepExecutor.from_agent(agent=agent)
|
|
|
49
52
|
|
|
50
53
|
For full control, implement `AsyncStepExecutor` directly. See [Specification Section 14.3](specification.md#143-custom-backends) for semantics and [API reference](api.md#runtime-executor-boundary) for the protocol.
|
|
51
54
|
|
|
55
|
+
## Output selection
|
|
56
|
+
|
|
57
|
+
Executors return `StepCandidate(outcome=..., binding_name_to_value=...)`.
|
|
58
|
+
The output mapping selects the complete set of values to validate and consider for writeback.
|
|
59
|
+
|
|
60
|
+
| Selection | Meaning |
|
|
61
|
+
|---|---|
|
|
62
|
+
| Omitted or `nh.UNSET` | Select initialized declared outputs from the working environment at finalization. |
|
|
63
|
+
| `{}` | Select no writes, even when declared outputs already have values. |
|
|
64
|
+
| `{"result": value}` | Select only `result`; do not supplement other initialized outputs. |
|
|
65
|
+
| `None` | Invalid. |
|
|
66
|
+
|
|
67
|
+
The standard agent executor omits the selection, so its tracked assignments and other initialized declared outputs receive final validation.
|
|
68
|
+
An explicit selection validates only its entries; output names must still be declared, and commit inspection still applies.
|
|
69
|
+
Neither an empty selection nor a later rejection undoes earlier calls or in-place object mutations.
|
|
70
|
+
`Raise` permits only omitted or empty output selections.
|
|
71
|
+
|
|
72
|
+
For an explicit combination of current outputs and replacements, use ordinary Python:
|
|
73
|
+
|
|
74
|
+
```py
|
|
75
|
+
from nighthawk.runtime import Pass, StepCandidate, StepRequest
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def select_result(request: StepRequest, result: object) -> StepCandidate:
|
|
79
|
+
return StepCandidate(
|
|
80
|
+
outcome=Pass(),
|
|
81
|
+
binding_name_to_value={**request.snapshot_output_bindings(), "result": result},
|
|
82
|
+
)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`snapshot_output_bindings()` returns a fresh dictionary in declaration order, preferring tracked assignments over current Python values, including live globals and cells.
|
|
86
|
+
Unbound outputs, temporaries, and task-only references are excluded.
|
|
87
|
+
The method preserves value identity and performs no validation or writes.
|
|
88
|
+
A snapshot fixes associations at the time it is taken; omission selects them later, during finalization.
|
|
89
|
+
`Rewrite` uses the same complete-mapping semantics after initial validation, with omission retaining the current commit field.
|
|
90
|
+
|
|
52
91
|
## Next steps
|
|
53
92
|
|
|
54
93
|
- **[Pydantic AI providers](pydantic-ai-providers.md)** -- Installation, model identifiers, credentials, and model settings for each Pydantic AI provider.
|
|
@@ -89,7 +89,7 @@ Read [Quickstart](https://kurusugawa-computer.github.io/nighthawk-python/quickst
|
|
|
89
89
|
- Use `deny` frontmatter to prohibit outcomes that would bypass required Python work. The template denies `return` to preserve the Python return path and denies the explicit `raise` outcome; runtime and helper failures can still raise.
|
|
90
90
|
- Denying outcomes does not require a fresh assignment. A permitted `pass` can retain an output's initial value. Use a deliberate default or an unbound annotated output, and validate the result before dependent work.
|
|
91
91
|
- Each block starts a fresh model interaction without implicit message history. Carry essential inputs and results through Python parameters and return values.
|
|
92
|
-
-
|
|
92
|
+
- Python lexical values and scoped task references supply context. Prefer explicit arguments for essential dependencies and `scope(task_references=...)` for intentionally shared policy. Parent working values are not copied into children. Child name rebinding stays local; explicitly shared mutable objects retain identity.
|
|
93
93
|
|
|
94
94
|
The type boundary may sit inside a function: accept text that needs interpretation, then commit a typed result before deterministic work begins.
|
|
95
95
|
Types constrain the result's shape and range; they do not prove that its meaning is correct.
|
|
@@ -189,8 +189,8 @@ def test_quote_batch_processes_each_message_and_uses_host_price():
|
|
|
189
189
|
messages = ["A dozen, please.", "Please send three."]
|
|
190
190
|
executor = ScriptedExecutor(
|
|
191
191
|
responses=[
|
|
192
|
-
pass_response(
|
|
193
|
-
pass_response(
|
|
192
|
+
pass_response(binding_name_to_value={"order": {"quantity": 12}}),
|
|
193
|
+
pass_response(binding_name_to_value={"order": {"quantity": 3}}),
|
|
194
194
|
],
|
|
195
195
|
)
|
|
196
196
|
with nh.run(executor):
|
|
@@ -199,14 +199,14 @@ def test_quote_batch_processes_each_message_and_uses_host_price():
|
|
|
199
199
|
|
|
200
200
|
|
|
201
201
|
def test_quote_batch_stops_when_quantity_is_unclear():
|
|
202
|
-
executor = ScriptedExecutor(responses=[pass_response(
|
|
202
|
+
executor = ScriptedExecutor(responses=[pass_response(binding_name_to_value={"order": {"quantity": None}})])
|
|
203
203
|
with nh.run(executor), pytest.raises(ValueError, match="Quantity needs clarification"):
|
|
204
204
|
quote_batch(["A few, please.", "Then three more."], unit_price_cents=250)
|
|
205
205
|
assert len(executor.calls) == 1
|
|
206
206
|
|
|
207
207
|
|
|
208
208
|
def test_quote_batch_rejects_invalid_model_output():
|
|
209
|
-
executor = ScriptedExecutor(responses=[pass_response(
|
|
209
|
+
executor = ScriptedExecutor(responses=[pass_response(binding_name_to_value={"order": {"quantity": 0}})])
|
|
210
210
|
with nh.run(executor), pytest.raises(nh.ExecutionError):
|
|
211
211
|
quote_batch(["One, please."], unit_price_cents=250)
|
|
212
212
|
```
|
|
@@ -81,7 +81,7 @@ Presentation is a view of accessible state, not its authority or a replacement f
|
|
|
81
81
|
|
|
82
82
|
Each Natural block performs one task with declared output bindings and one outcome.
|
|
83
83
|
There is no implicit model message history between blocks.
|
|
84
|
-
Python values
|
|
84
|
+
Python lexical values and explicitly scoped task references supply context to each fresh interaction (see [Patterns: cross-block composition](patterns.md#cross-block-composition)).
|
|
85
85
|
|
|
86
86
|
## Providing data to a block
|
|
87
87
|
|
|
@@ -150,7 +150,8 @@ An explicit output annotation determines its validation contract at block entry.
|
|
|
150
150
|
Without one, the runtime infers the initialized value's type, except for `None` and a plain `object()`; otherwise the output is unconstrained.
|
|
151
151
|
Annotate collections explicitly when element types matter: `findings: list[Finding] = []` retains its element contract, while `findings = []` selects only `list`.
|
|
152
152
|
An unresolved explicit annotation fails preparation instead of silently falling back to inference.
|
|
153
|
-
|
|
153
|
+
The standard executor selects all bound declared outputs for final validation even if the model never assigns them; an initial Raise discards pending outputs.
|
|
154
|
+
Custom executors may supply an explicit complete output selection; see [output selection](executors.md#output-selection).
|
|
154
155
|
Output contracts constrain values, not the factual correctness of a judgment.
|
|
155
156
|
See [binding contracts](specification.md#7-natural-dsl-bindings) for annotation acquisition and global/nonlocal writeback.
|
|
156
157
|
|
|
@@ -401,7 +402,7 @@ Function parameters and working locals are candidates for LOCALS, and explicit m
|
|
|
401
402
|
|
|
402
403
|
Keep fewer incidental locals alive when they do not help the judgment. A callable passed through a parameter retains its live callable metadata even when the parameter annotation is `object`, `Any`, or absent. Signature and documentation acquisition are best-effort and do not execute application properties or annotation expressions.
|
|
403
404
|
|
|
404
|
-
Use explicit parameters for essential inputs and independent reuse. Module globals and task
|
|
405
|
+
Use explicit parameters for essential inputs and independent reuse. Module globals and task references can supply shared capabilities and context. Parent working values are not copied into children; select values in ordinary Python and supply them through arguments or `nh.scope(task_references=...)`. These layers preserve their provenance and remain available beyond the initial presentation budget.
|
|
405
406
|
|
|
406
407
|
**Note:** Nighthawk also accepts native tools through `nh.scope(tools=[...])`, which exposes functions via the model's native tool-calling interface for the duration of the scope. This path is reserved for cases that need native tool calling, such as strict argument schemas or Pydantic AI tool features. Binding functions are preferred for all other uses because they incur no per-definition token overhead beyond a signature line in the prompt context. See [Runtime configuration](runtime-configuration.md#scoped-tools) and [Specification Section 8.3](specification.md#83-tools-available-to-the-llm).
|
|
407
408
|
|
|
@@ -257,7 +257,7 @@ async def classify_batch(texts: list[str]) -> list[str]:
|
|
|
257
257
|
```
|
|
258
258
|
|
|
259
259
|
Each concurrent Natural block has its own step context and no shared model message history.
|
|
260
|
-
|
|
260
|
+
Explicit Python references and host accounting can still be shared; `asyncio.gather` is appropriate when those shared values are safe for concurrent use.
|
|
261
261
|
Tasks capture their selected context when created, including model selection and function-call handlers; awaiting a task elsewhere does not replace that context.
|
|
262
262
|
|
|
263
263
|
### Async and sync interoperability
|
|
@@ -274,10 +274,10 @@ You can therefore use async binding functions through tools without changing a s
|
|
|
274
274
|
## Cross-block composition
|
|
275
275
|
|
|
276
276
|
Each Natural block starts a fresh model interaction ([one block, one task](natural-blocks.md#one-block-one-task)).
|
|
277
|
-
Use Python arguments and returned values for essential inputs and results,
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
The [environment contract](specification.md#813-
|
|
277
|
+
Use Python arguments and returned values for essential inputs and results, and scoped task references for deliberately shared context and capabilities.
|
|
278
|
+
Children do not receive a parent's working values automatically; explicitly shared objects remain live, while child name rebinding does not update the parent.
|
|
279
|
+
Hosts establish explicit inputs and execution scope for independent work that outlives a parent step.
|
|
280
|
+
The [environment contract](specification.md#813-shared-values-and-expression-lifetime) defines the precise boundaries.
|
|
281
281
|
|
|
282
282
|
### Python iteration with Natural judgment
|
|
283
283
|
|
|
@@ -317,7 +317,7 @@ async def summarize_and_assess(document: str) -> list[tuple[str, float]]:
|
|
|
317
317
|
### Natural selects follow-up assessments
|
|
318
318
|
|
|
319
319
|
Here the parent chooses which claims need review.
|
|
320
|
-
The child receives the document and claim
|
|
320
|
+
The child receives the document and claim as arguments, and the review policy through an explicit task-reference scope.
|
|
321
321
|
Call these ordinary Natural functions inside `nh.run(executor)`:
|
|
322
322
|
|
|
323
323
|
```python
|
|
@@ -342,18 +342,19 @@ async def assess_claim(document: str, claim: str) -> float:
|
|
|
342
342
|
async def review_claims(document: str, claims: list[str]) -> list[tuple[str, float]]:
|
|
343
343
|
review_guidance = "Check quantitative and causal claims against direct evidence."
|
|
344
344
|
assessments: list[tuple[str, float]] = []
|
|
345
|
-
""
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
345
|
+
with nh.scope(task_references={"review_guidance": review_guidance}):
|
|
346
|
+
"""natural
|
|
347
|
+
Use <review_guidance> to choose claims from <claims> that need closer review.
|
|
348
|
+
Call <assess_claim> with <document> and each selected claim, awaiting each result.
|
|
349
|
+
Store the selected claims and their returned scores in <:assessments>.
|
|
350
|
+
"""
|
|
350
351
|
return assessments
|
|
351
352
|
```
|
|
352
353
|
|
|
353
354
|
The parent step remains active until its chosen calls finish.
|
|
354
|
-
The policy does not need to pass through intermediate helper signatures, but `assess_claim`
|
|
355
|
+
The policy does not need to pass through intermediate helper signatures, but `assess_claim` has an explicit scoped dependency: calling it independently requires supplying `review_guidance` through task references.
|
|
355
356
|
Prefer an explicit policy parameter when independent reuse matters.
|
|
356
|
-
The [nested execution acceptance example](specification.md#144-nested-execution-acceptance-example) isolates
|
|
357
|
+
The [nested execution acceptance example](specification.md#144-nested-execution-acceptance-example) isolates explicit argument passing separately from this judgment task.
|
|
357
358
|
|
|
358
359
|
### The carry pattern
|
|
359
360
|
|
|
@@ -82,7 +82,7 @@ Explore explicit serialization of host data and correlation metadata for multi-p
|
|
|
82
82
|
|
|
83
83
|
### Async bridge ContextVar propagation
|
|
84
84
|
|
|
85
|
-
Investigate propagating selected context-variable rebindings back from bridge threads while preserving [
|
|
85
|
+
Investigate propagating selected context-variable rebindings back from bridge threads while preserving [shared-value and expression-lifetime boundaries](specification.md#813-shared-values-and-expression-lifetime).
|
|
86
86
|
|
|
87
87
|
## Implementation hardening
|
|
88
88
|
|