nighthawk-python 0.4.0__tar.gz → 0.5.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.
Files changed (141) hide show
  1. nighthawk_python-0.5.0/.claude/rules/docs.md +106 -0
  2. nighthawk_python-0.5.0/.claude/rules/promptfoo.md +137 -0
  3. nighthawk_python-0.5.0/.claude/rules/tests.md +27 -0
  4. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/.devcontainer/litellm-config.yaml +1 -1
  5. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/.gitignore +6 -0
  6. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/AGENTS.md +3 -3
  7. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/CHANGELOG.md +25 -1
  8. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/CONTRIBUTING.md +43 -1
  9. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/PKG-INFO +27 -15
  10. nighthawk_python-0.5.0/README.md +74 -0
  11. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/docs/coding-agent-backends.md +34 -8
  12. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/docs/design.md +30 -39
  13. nighthawk_python-0.5.0/docs/for-coding-agents.md +254 -0
  14. nighthawk_python-0.5.0/docs/index.md +31 -0
  15. nighthawk_python-0.5.0/docs/philosophy.md +167 -0
  16. nighthawk_python-0.5.0/docs/practices.md +470 -0
  17. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/docs/providers.md +23 -29
  18. nighthawk_python-0.5.0/docs/quickstart.md +115 -0
  19. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/docs/roadmap.md +4 -5
  20. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/docs/tutorial.md +54 -342
  21. nighthawk_python-0.5.0/evals/promptfoo/assertions/binding_value.py +56 -0
  22. nighthawk_python-0.5.0/evals/promptfoo/assertions/outcome_kind.py +49 -0
  23. nighthawk_python-0.5.0/evals/promptfoo/assertions/raise_message.py +62 -0
  24. nighthawk_python-0.5.0/evals/promptfoo/evidence/2026-03-26-baseline-prompt-ab.md +32 -0
  25. nighthawk_python-0.5.0/evals/promptfoo/evidence/2026-03-26-baseline-regression.md +28 -0
  26. nighthawk_python-0.5.0/evals/promptfoo/evidence/2026-03-26-baseline-suffix-ab.md +37 -0
  27. nighthawk_python-0.5.0/evals/promptfoo/promptfooconfig-agents.yaml +44 -0
  28. nighthawk_python-0.5.0/evals/promptfoo/promptfooconfig-prompt-ab.yaml +63 -0
  29. nighthawk_python-0.5.0/evals/promptfoo/promptfooconfig-suffix-ab.yaml +63 -0
  30. nighthawk_python-0.5.0/evals/promptfoo/promptfooconfig.yaml +58 -0
  31. nighthawk_python-0.5.0/evals/promptfoo/prompts/eval_coding_agent.txt +8 -0
  32. nighthawk_python-0.5.0/evals/promptfoo/prompts/eval_default.txt +25 -0
  33. nighthawk_python-0.5.0/evals/promptfoo/prompts/eval_mutation_aware.txt +24 -0
  34. nighthawk_python-0.5.0/evals/promptfoo/prompts/eval_sequenced.txt +24 -0
  35. nighthawk_python-0.5.0/evals/promptfoo/provider.py +474 -0
  36. nighthawk_python-0.5.0/evals/promptfoo/research-result.md +569 -0
  37. nighthawk_python-0.5.0/evals/promptfoo/test_cases/binding_operations.yaml +141 -0
  38. nighthawk_python-0.5.0/evals/promptfoo/test_cases/edge_cases.yaml +117 -0
  39. nighthawk_python-0.5.0/evals/promptfoo/test_cases/loop_outcomes.yaml +77 -0
  40. nighthawk_python-0.5.0/evals/promptfoo/test_cases/multi_step.yaml +66 -0
  41. nighthawk_python-0.5.0/evals/promptfoo/test_cases/null_handling.yaml +35 -0
  42. nighthawk_python-0.5.0/evals/promptfoo/test_cases/outcome_kinds.yaml +151 -0
  43. nighthawk_python-0.5.0/evals/promptfoo/test_cases/tool_selection.yaml +287 -0
  44. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/mkdocs.yml +3 -1
  45. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/pyproject.toml +1 -1
  46. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/backends/claude_code_cli.py +1 -1
  47. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/backends/claude_code_sdk.py +1 -1
  48. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/configuration.py +10 -6
  49. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/runtime/runner.py +30 -23
  50. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/runtime/step_context.py +1 -1
  51. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/runtime/step_contract.py +16 -31
  52. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/testing.py +9 -4
  53. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/tools/assignment.py +1 -1
  54. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/tools/provided.py +2 -19
  55. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/conftest.py +0 -13
  56. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/execution/test_execution_outcome_prompt_fragment.py +12 -13
  57. nighthawk_python-0.5.0/tests/execution/test_infer_binding_types.py +91 -0
  58. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/execution/test_runtime.py +35 -13
  59. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/integration/skip_helpers.py +7 -10
  60. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/integration/test_carry_pattern.py +3 -3
  61. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/integration/test_claude_code_cli_integration.py +1 -1
  62. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/integration/test_codex_integration.py +2 -2
  63. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/integration/test_llm_integration.py +8 -71
  64. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/public/test_public_api.py +8 -8
  65. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/test_testing.py +1 -1
  66. nighthawk_python-0.5.0/tests/tools/__init__.py +0 -0
  67. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/tools/test_registry.py +0 -1
  68. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/uv.lock +100 -99
  69. nighthawk_python-0.4.0/.claude/rules/docs.md +0 -108
  70. nighthawk_python-0.4.0/README.md +0 -62
  71. nighthawk_python-0.4.0/docs/for-coding-agents.md +0 -365
  72. nighthawk_python-0.4.0/docs/index.md +0 -134
  73. nighthawk_python-0.4.0/docs/quickstart.md +0 -110
  74. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/.claude/rules/coding.md +0 -0
  75. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/.claude/settings.json +0 -0
  76. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/.claude/unset_envs.sh +0 -0
  77. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/.devcontainer/Dockerfile.devcontainer +0 -0
  78. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/.devcontainer/Dockerfile.litellm +0 -0
  79. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/.devcontainer/devcontainer.json +0 -0
  80. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/.devcontainer/docker-compose.yaml +0 -0
  81. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/.github/dependabot.yml +0 -0
  82. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/.github/workflows/ci.yml +0 -0
  83. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/.github/workflows/docs.yml +0 -0
  84. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/.github/workflows/publish.yml +0 -0
  85. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/.python-version +0 -0
  86. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/CLAUDE.md +0 -0
  87. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/LICENSE +0 -0
  88. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/docs/api.md +0 -0
  89. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/docs/assets/nighthawk_logo-128x128.png +0 -0
  90. {nighthawk_python-0.4.0/src/nighthawk/backends → nighthawk_python-0.5.0/evals/promptfoo/assertions}/__init__.py +0 -0
  91. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/pyrightconfig.json +0 -0
  92. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/__init__.py +0 -0
  93. {nighthawk_python-0.4.0/src/nighthawk/natural → nighthawk_python-0.5.0/src/nighthawk/backends}/__init__.py +0 -0
  94. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/backends/base.py +0 -0
  95. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/backends/codex.py +0 -0
  96. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/backends/mcp_boundary.py +0 -0
  97. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/backends/mcp_server.py +0 -0
  98. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/backends/tool_bridge.py +0 -0
  99. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/errors.py +0 -0
  100. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/identifier_path.py +0 -0
  101. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/json_renderer.py +0 -0
  102. {nighthawk_python-0.4.0/src/nighthawk/runtime → nighthawk_python-0.5.0/src/nighthawk/natural}/__init__.py +0 -0
  103. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/natural/blocks.py +0 -0
  104. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/natural/decorator.py +0 -0
  105. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/natural/transform.py +0 -0
  106. {nighthawk_python-0.4.0/src/nighthawk/tools → nighthawk_python-0.5.0/src/nighthawk/runtime}/__init__.py +0 -0
  107. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/runtime/async_bridge.py +0 -0
  108. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/runtime/prompt.py +0 -0
  109. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/runtime/scoping.py +0 -0
  110. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/runtime/step_executor.py +0 -0
  111. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/runtime/tool_calls.py +0 -0
  112. {nighthawk_python-0.4.0/tests → nighthawk_python-0.5.0/src/nighthawk/tools}/__init__.py +0 -0
  113. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/tools/contracts.py +0 -0
  114. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/tools/execution.py +0 -0
  115. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/tools/registry.py +0 -0
  116. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/src/nighthawk/ulid.py +0 -0
  117. {nighthawk_python-0.4.0/tests/backends → nighthawk_python-0.5.0/tests}/__init__.py +0 -0
  118. {nighthawk_python-0.4.0/tests/docs → nighthawk_python-0.5.0/tests/backends}/__init__.py +0 -0
  119. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/backends/test_claude_code_cli.py +0 -0
  120. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/backends/test_claude_code_sdk.py +0 -0
  121. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/backends/test_codex.py +0 -0
  122. {nighthawk_python-0.4.0/tests/execution → nighthawk_python-0.5.0/tests/docs}/__init__.py +0 -0
  123. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/docs/test_coding_agent_examples.py +0 -0
  124. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/docs/test_prompt_examples.py +0 -0
  125. {nighthawk_python-0.4.0/tests/integration → nighthawk_python-0.5.0/tests/execution}/__init__.py +0 -0
  126. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/execution/prompt_test_helpers.py +0 -0
  127. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/execution/stub_executor.py +0 -0
  128. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/execution/test_globals_prompt.py +0 -0
  129. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/execution/test_natural_block_ordering.py +0 -0
  130. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/execution/test_natural_traceback.py +0 -0
  131. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/execution/test_variables_prompt.py +0 -0
  132. {nighthawk_python-0.4.0/tests/natural → nighthawk_python-0.5.0/tests/integration}/__init__.py +0 -0
  133. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/integration/test_claude_code_sdk_integration.py +0 -0
  134. {nighthawk_python-0.4.0/tests/public → nighthawk_python-0.5.0/tests/natural}/__init__.py +0 -0
  135. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/natural/test_blocks.py +0 -0
  136. {nighthawk_python-0.4.0/tests/tools → nighthawk_python-0.5.0/tests/public}/__init__.py +0 -0
  137. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/public/test_readme_example.py +0 -0
  138. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/test_renderer.py +0 -0
  139. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/tools/test_assignment_async.py +0 -0
  140. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/tools/test_contracts.py +0 -0
  141. {nighthawk_python-0.4.0 → nighthawk_python-0.5.0}/tests/tools/test_tool_boundary.py +0 -0
@@ -0,0 +1,106 @@
1
+ ---
2
+ paths:
3
+ - "docs/**/*.md"
4
+ ---
5
+
6
+ # Documentation rules
7
+
8
+ ## File roles and boundaries
9
+
10
+ Content belongs in exactly one file; cross-reference rather than duplicate. Exception: `for-coding-agents.md` condenses (distills) content from other files into actionable rules.
11
+
12
+ | File | Audience | Role | Scope boundary |
13
+ |---|---|---|---|
14
+ | `index.md` | First-time visitors | Project overview, motivation, workflow styles | What Nighthawk is and why. Brief positioning summary with link to `philosophy.md`. No API details, no how-to. |
15
+ | `philosophy.md` | Users evaluating Nighthawk | Deep positioning and design rationale | Workflow styles, comparison with workflow engines, tool exposure tradeoffs (MCP/CLI/binding functions), runtime evaluation rationale. Technical arguments with benchmarks. |
16
+ | `quickstart.md` | New users | Shortest path to running a Natural block | Setup, first example, credentials, troubleshooting. No deep explanations. |
17
+ | `tutorial.md` | Users learning the system | Build understanding from first principles | Bindings, functions and discoverability, control flow, composition, configuration, async. Assumes quickstart is done. Guidelines and testing are in `practices.md`. |
18
+ | `practices.md` | Users applying patterns | Practical patterns and guidelines | Writing guidelines, binding function design, testing and debugging, observability. Assumes tutorial is done. |
19
+ | `design.md` | Implementors and advanced users | Canonical specification (target behavior) | Full technical detail: syntax rules, state layers, prompt rendering, tool contracts, outcome schema, frontmatter. |
20
+ | `providers.md` | Users choosing and configuring models | Provider selection, Pydantic AI setup, custom backends | Provider categories, capability matrix, model identifiers, Pydantic AI model settings, step executor protocols. No coding-agent-backend-specific content. |
21
+ | `coding-agent-backends.md` | Users of Claude Code or Codex backends | Coding agent backend configuration and features | Backend-specific settings, skills, MCP tool exposure, working directory, project-scoped files. |
22
+ | `for-coding-agents.md` | Coding agents (LLMs) working on Nighthawk projects | Condensed development knowledge base | Nighthawk mental model, Natural block writing, binding function design, control flow, composition, testing, common mistakes. Not a human tutorial; an LLM reference. |
23
+ | `api.md` | Developers using the library | Auto-generated API reference (mkdocstrings) | Public API surface only. Content comes from source docstrings; do not hand-edit. |
24
+ | `roadmap.md` | Contributors and planners | Future directions | Ideas and desired directions only. Must not restate what is already implemented. |
25
+
26
+ ## Content routing (non-obvious cases)
27
+
28
+ Most content maps to exactly one file via the scope boundaries above. These cases involve splits or non-intuitive placement:
29
+
30
+ - **Credential setup** -> `quickstart.md` (`OPENAI_API_KEY` only), `providers.md` (Pydantic AI providers), `coding-agent-backends.md` (coding agent backends)
31
+ - **Error types** -> `design.md` (specification), `tutorial.md` (practical usage with examples)
32
+ - **Testing patterns** -> `practices.md` (patterns with examples), `for-coding-agents.md` (condensed rules)
33
+ - **Writing guidelines** -> `practices.md` (patterns with examples), `for-coding-agents.md` (condensed rules)
34
+ - **Observability** -> `practices.md` (practical setup), `design.md` (specification)
35
+ - **Conceptual impact of coding agent backends** (how they expand what Natural blocks can do) -> `philosophy.md` (positioning arguments), `index.md` (brief summary), `practices.md` (guidelines). Configuration details stay in `coding-agent-backends.md`.
36
+
37
+ ## Writing guidelines
38
+
39
+ ### General
40
+
41
+ - Cross-reference with relative links (e.g., `[Section 5](tutorial.md#5-cross-block-composition)`). Exception: `for-coding-agents.md` uses absolute URLs based on `site_url` from `mkdocs.yml`.
42
+ - File boundary delineation: `index.md` owns "why" (motivation, positioning); `tutorial.md` owns "how" (usage with examples); `practices.md` owns "how to do it well" (guidelines, patterns, testing); `design.md` owns "exact rules and edge cases" (specification).
43
+ - Maintain consistent terminology across files (e.g., "one task per block" everywhere, not "one judgment" in one file and "one task" in another).
44
+ - Keep code examples self-contained: understandable without surrounding prose.
45
+ - Built-in tool names (`nh_eval`, `nh_exec`, `nh_assign`) are implementation details. Only `design.md` may expose them; all other files describe behavior instead.
46
+ - `@nh.tool` is discouraged. `design.md` documents it as specification. `tutorial.md` may mention it with a "prefer binding functions" note. All other files (including `for-coding-agents.md`) must not reference it.
47
+ - The PyPI package name is `nighthawk-python`. Always use `nighthawk-python` in `pip install` commands and extras.
48
+ - Terminology: "task" refers to the structural unit a Natural block performs (contract: inputs, outputs, outcome). "judgment" refers to the cognitive act the LLM performs (classification, interpretation, generation). Use "one task per block", not "one judgment per block".
49
+
50
+ ### Per-file rules
51
+
52
+ **index.md**
53
+ - Documentation links list must stay in sync with `nav` entries in `mkdocs.yml`.
54
+ - Keep positioning sections as brief summary paragraphs linking to `philosophy.md`. Do not add detailed comparisons, benchmarks, or technical arguments here.
55
+
56
+ **philosophy.md**
57
+ - Owns all detailed positioning arguments: workflow styles, workflow engine comparison, tool exposure tradeoffs, runtime evaluation rationale.
58
+ - External references (benchmarks, blog posts) are acceptable. Prefer stable URLs; include enough inline context that the argument survives link rot.
59
+ - May reference `tutorial.md` and `coding-agent-backends.md` for cross-cutting concepts but must not duplicate how-to content.
60
+
61
+ **quickstart.md**
62
+ - Optimize for copy-paste. Keep troubleshooting to common first-run errors only.
63
+ - Includes both a Pydantic AI provider example and a coding agent backend (claude-code-cli) example.
64
+
65
+ **tutorial.md**
66
+ - One concept per section. Combine related ideas only when they share an example.
67
+ - `<!-- prompt-example:name -->` markers are test anchors verified by `tests/docs/test_prompt_examples.py`. Never modify content between markers without updating the test.
68
+ - Backend-agnostic in configuration: no backend-specific file layouts, credentials, or initialization variants; point to `providers.md` or `coding-agent-backends.md` instead. Conceptual references to what coding agent backends enable are acceptable as brief pointers.
69
+
70
+ **practices.md**
71
+ - Assumes the reader has completed the tutorial. No repetition of fundamentals.
72
+ - No `<!-- prompt-example:name -->` markers; all prompt examples remain in `tutorial.md`.
73
+ - Focus on practical application patterns, setup instructions, and decision frameworks.
74
+ - Cross-reference `tutorial.md` for concepts, `design.md` for specifications.
75
+
76
+ **design.md**
77
+ - The specification. If implementation diverges, prefer changing the implementation (Section 0.1).
78
+ - Precise, unambiguous language. No hedging for specified behavior.
79
+ - Keep section hierarchy stable; other docs link to anchors.
80
+
81
+ **providers.md**
82
+ - Capability matrix must clearly show which features require a coding agent backend.
83
+ - Concise, runnable setup snippets over narrative; link to `tutorial.md` for concepts.
84
+ - Custom backends: show `AgentStepExecutor.from_agent` snippet; link to `design.md` for protocol details.
85
+ - No credential details; delegate to Pydantic AI documentation.
86
+
87
+ **coding-agent-backends.md**
88
+ - Document shared capabilities once in a shared section; per-backend sections focus on differences.
89
+ - For CLI integrations, separate what Nighthawk configures from what is delegated to backend CLI rules.
90
+ - Include a settings field table per backend (type, default, description).
91
+ - Reference `providers.md` for the overall provider landscape and capability matrix; do not duplicate the matrix.
92
+
93
+ **for-coding-agents.md**
94
+ - The reader is a coding agent (LLM). Write for immediate applicability, not progressive learning. Include runnable code templates.
95
+ - Distill principles from tutorial.md, practices.md, design.md, and guidelines into actionable rules. Do not duplicate prose.
96
+ - Information flows from human-oriented docs to this file, never the reverse. All facts, patterns, and rules in this file must have a source in tutorial.md, practices.md, or design.md. Do not introduce new information here.
97
+ - Self-contained: readable without sibling files. All doc references use absolute URLs from `site_url` in `mkdocs.yml` (currently `https://kurusugawa-computer.github.io/nighthawk-python/`). Update URLs if `site_url` changes.
98
+ - Keep the "common mistakes" table current.
99
+ - Filter for coding-agent relevance: omit infrastructure concerns (scoped overrides, exception hierarchy beyond `ExecutionError`, observability) that don't affect writing Natural blocks or binding functions.
100
+
101
+ **api.md**
102
+ - Content from source docstrings; edit source code, not api.md. Hand-editing limited to `:::` directive structure.
103
+ - Use `members` filters in `:::` directives to avoid duplicate rendering when the same module appears in multiple sections.
104
+
105
+ **roadmap.md**
106
+ - Future-facing only. Remove items once implemented. No implementation details.
@@ -0,0 +1,137 @@
1
+ ---
2
+ paths:
3
+ - "evals/promptfoo/**"
4
+ ---
5
+
6
+ # Prompt evaluation (promptfoo)
7
+
8
+ ## Directory roles
9
+
10
+ | Directory | Purpose | Determinism | Cost |
11
+ |---|---|---|---|
12
+ | `evals/promptfoo/` | Prompt experimentation: system prompt variants, tool descriptions, suffix fragments, backend comparison | Non-deterministic; use `--repeat N` to measure stability. | API calls x N x providers. |
13
+ | `evals/promptfoo/outputs/` | Transient raw output (gitignored). Working files for in-progress analysis. | N/A | N/A |
14
+ | `evals/promptfoo/evidence/` | Committed eval evidence. Decision rationale for adopted/rejected variants. | N/A | N/A |
15
+
16
+ ## Prompt changes workflow
17
+
18
+ 1. Edit eval-layer prompts or provider config in `evals/promptfoo/`.
19
+ 2. Run eval: `eval $PFOO eval --filter-providers "<provider>" --no-cache`.
20
+ 3. Compare against previous eval in the promptfoo DB or JSON output.
21
+ 4. Once validated, port the change to the corresponding production code (see mapping below).
22
+ 5. Run `uv run pytest -q` to confirm no regressions.
23
+
24
+ **`--filter-providers` caveat**: The flag takes a regex pattern, not an exact label. A pattern like `"gpt-5.4-mini"` matches every provider whose label contains that substring (e.g. both `openai-responses` and `codex` labels). Use an anchored or label-specific pattern (e.g. `"^gpt-5.4-mini"`, `"codex:"`) to target a single provider.
25
+
26
+ ## Prompt variant cleanup (deletion timing and criteria)
27
+
28
+ - Delete rejected prompt variants immediately when any of the following is true:
29
+ - Deterministic regression (`N/N` failures across repeats, e.g. `--repeat 3`)
30
+ - Clear degradation versus baseline on primary metrics
31
+ - Temporary/scratch variants created for quick checks
32
+ - Keep a variant only if it has clear re-test value (e.g. flaky `1/N` behavior or meaningful metric trade-offs).
33
+ - Retention for kept variants is limited to `min(7 days, 2 experiment cycles)`.
34
+ - If not re-evaluated within this window, delete it.
35
+ - Run cleanup at three checkpoints:
36
+ 1. Right after each experiment run
37
+ 2. Before opening a PR
38
+ 3. Before merge (final sweep)
39
+ - Before deleting, record a short rejection reason in the corresponding `evals/promptfoo/evidence/` file; do not keep dead prompt files just for history.
40
+
41
+ ## Backend prerequisites
42
+
43
+ | Backend | Requirement |
44
+ |---|---|
45
+ | `openai-responses` | `OPENAI_API_KEY` environment variable. |
46
+ | `codex` | Pre-authenticated `codex` CLI (`codex login`) or `CODEX_API_KEY` environment variable. |
47
+ | `claude-code-cli` | Pre-authenticated `claude` CLI (`claude login`) or `ANTHROPIC_API_KEY` environment variable. |
48
+ | `claude-code-sdk` | `ANTHROPIC_API_KEY` environment variable. |
49
+
50
+ Evals that include a backend without its prerequisite will run but produce errors for that backend's test cases. Use `--filter-providers` to exclude unavailable backends.
51
+
52
+ ## Eval-to-production mapping
53
+
54
+ Eval prompts are experimental copies of production code. Keep them in sync; divergence means eval results do not predict production behavior.
55
+
56
+ | Eval file | Production counterpart |
57
+ |---|---|
58
+ | `evals/promptfoo/prompts/eval_default.txt` | `configuration.py:DEFAULT_STEP_SYSTEM_PROMPT_TEMPLATE` |
59
+ | `evals/promptfoo/prompts/eval_coding_agent.txt` | No single counterpart; coding agent backends receive this prompt via `system_prompt_file` config. |
60
+ | Suffix variants in `evals/promptfoo/provider.py` (`_build_suffix_*`) | `step_contract.py:build_step_system_prompt_suffix_fragment` |
61
+ | Tool presets in `evals/promptfoo/provider.py` (`_build_tool_preset`) | `tools/registry.py` + `tools/assignment.py` |
62
+
63
+ ## Eval evidence
64
+
65
+ ### When to save evidence
66
+
67
+ | Save | Do not save |
68
+ |---|---|
69
+ | Eval that decided adoption or rejection of a prompt/suffix/tool variant | In-progress trial runs during development |
70
+ | Regression baseline update | Single-test filter runs |
71
+ | Eval backing a change merged via PR | Transient output already in `outputs/` |
72
+
73
+ ### File path convention
74
+
75
+ ```
76
+ evals/promptfoo/evidence/{YYYY-MM-DD}-{experiment-slug}.md
77
+ ```
78
+
79
+ Examples: `2026-03-20-suffix-ab.md`, `2026-03-25-regression-v2.md`.
80
+
81
+ ### File format
82
+
83
+ ```markdown
84
+ ---
85
+ eval_id: <promptfoo eval ID>
86
+ config: <YAML config file used>
87
+ date: YYYY-MM-DD
88
+ decision: <one-line summary of what was adopted/rejected>
89
+ ---
90
+
91
+ ## Providers tested
92
+ - <provider label> (<variants if A/B>)
93
+
94
+ ## Results summary
95
+ | Variant | Pass | Fail | Error | Score | Latency |
96
+ |---------|------|------|-------|-------|---------|
97
+ | ... | | | | | |
98
+
99
+ ## Decision rationale
100
+ <Why the chosen variant was adopted.>
101
+
102
+ ## Rejected variants
103
+ - <variant>: <short rejection reason>
104
+ ```
105
+
106
+ ### Rules
107
+
108
+ - Only Markdown files (`*.md`) are committed under `evidence/`. Raw JSON stays in `outputs/` (gitignored).
109
+ - One file per experiment decision. If a follow-up eval revises a prior decision, create a new file; do not overwrite.
110
+ - Reference the `eval_id` so the full raw result can be retrieved from the promptfoo local DB (`promptfoo view`) or `-o` export if needed.
111
+
112
+ ## Eval interpretation
113
+
114
+ - **Exit code 100**: promptfoo returns exit code 100 when any test case fails. This is not a system error; it signals "some assertions did not pass". CI scripts and background runners should treat exit 100 as "check results" rather than "eval crashed".
115
+ - **OpenAI 500 errors**: Transient; ignore unless persistent across runs.
116
+ - **Codex CLI errors**: Codex backend is unstable; isolate with `--filter-providers`.
117
+ - **Codex binding-not-returned**: Codex may return `None` for write bindings that `openai-responses` handles correctly. This is a distinct failure mode from flaky LLM non-determinism; it typically indicates the coding-agent backend did not invoke the assignment tool.
118
+ - **Mutation vs filter ambiguity**: Natural language instructions like "remove negative numbers" can be interpreted as either in-place mutation or filter-to-new-list. LLMs inconsistently choose between these, producing flaky failures where the binding value is the original unmodified collection. This pattern recurs across providers and suffix variants.
119
+ - **1/N failures (flaky)**: Inherent LLM non-determinism. Use `--repeat 3` to distinguish from deterministic regressions.
120
+ - **Deterministic failures** (N/N across repeats): Require prompt or code fix before merging.
121
+
122
+ ## Baseline workflow
123
+
124
+ Run a full baseline when: (a) setting up the eval environment for the first time, (b) after a major production code change, or (c) when prior baselines are stale (> 2 weeks or across model version changes).
125
+
126
+ 1. Verify prerequisites for each backend (see Backend prerequisites above).
127
+ 2. Run all applicable configs in parallel with `--no-cache` and `-o outputs/baseline-{slug}.json`:
128
+ - `promptfooconfig.yaml` — regression across all available backends.
129
+ - `promptfooconfig-prompt-ab.yaml` — prompt/tool variant comparison.
130
+ - `promptfooconfig-suffix-ab.yaml` — suffix fragment comparison.
131
+ - `promptfooconfig-agents.yaml` — coding-agent backends (requires `codex` and `claude` CLIs).
132
+ 3. For backends without prerequisites, either skip the config or use `--filter-providers` to exclude unavailable providers.
133
+ 4. Create one evidence file per config under `evals/promptfoo/evidence/` with the `baseline-` slug prefix.
134
+
135
+ ## Commands
136
+
137
+ See `CONTRIBUTING.md` "Prompt evaluation with promptfoo" for eval commands, config files, directory layout, and flags.
@@ -0,0 +1,27 @@
1
+ ---
2
+ paths:
3
+ - "tests/**"
4
+ ---
5
+
6
+ # Testing (pytest)
7
+
8
+ ## Directory roles
9
+
10
+ | Directory | Purpose | Determinism | Cost |
11
+ |---|---|---|---|
12
+ | `tests/` | Pytest suite: unit tests (ScriptedExecutor) and integration tests (real LLM) | Unit: deterministic. Integration: non-deterministic but single-run. | Unit: free. Integration: API calls. |
13
+ | `src/nighthawk/testing.py` | Test utility API for deterministic Natural-function tests (`ScriptedExecutor`, `CallbackExecutor`, and response factories). | Deterministic. | Free. |
14
+
15
+ ## Workflow
16
+
17
+ ### Scope boundary (pytest vs promptfoo)
18
+
19
+ - Do not force prompt behavior validation into pytest-only checks.
20
+ - When prompt rendering, system prompt text, suffix generation, or tool-exposure behavior changes, follow `.claude/rules/promptfoo.md`.
21
+
22
+ ### Python code changes (tools, executor, contracts)
23
+
24
+ 1. Write or update unit tests in `tests/` first.
25
+ 2. Prefer helpers from `nighthawk.testing` (for example `ScriptedExecutor`, `CallbackExecutor`, `pass_response`, `return_response`) when avoiding live LLM calls.
26
+ 3. Run `uv run pytest -q`.
27
+ 4. If the change affects prompt rendering or tool behavior, follow `.claude/rules/promptfoo.md` and run the relevant eval subset.
@@ -30,7 +30,7 @@ model_list:
30
30
  additional_drop_params: ["context_management", "output_config"]
31
31
  - model_name: claude-haiku-*
32
32
  litellm_params:
33
- model: openai/gpt-5-mini
33
+ model: openai/gpt-5.4-mini
34
34
  api_key: os.environ/OPENAI_API_KEY
35
35
  additional_drop_params: ["context_management", "output_config"]
36
36
  litellm_settings:
@@ -3,6 +3,12 @@
3
3
  *.local.json
4
4
  .vscode/
5
5
 
6
+ # promptfoo evaluation outputs
7
+ evals/promptfoo/outputs/
8
+ evals/promptfoo/*.json
9
+ evals/promptfoo/*.html
10
+ evals/promptfoo/*.csv
11
+
6
12
  # Byte-compiled / optimized / DLL files
7
13
  __pycache__/
8
14
  *.py[codz]
@@ -51,13 +51,13 @@ Python 3.13+, `uv` for dependencies, `pytest` for tests. Prefer LSP-based toolin
51
51
  | `uv run python` | Investigate interactively |
52
52
  | `uv sync --all-extras --all-groups` | Install/sync dependencies |
53
53
  | `uv run ruff format .` | Format |
54
- | `uv run ruff check .` | Lint |
55
54
  | `uv run ruff check --fix .` | Auto-fix lint |
56
55
  | `uv run pyright` | Type check |
57
- | `uv run pytest` | Full test suite |
58
56
  | `uv run pytest -q` | Tests (quiet) |
59
- | `set -a; source .env; set +a; uv run pytest -q` | Integration tests |
57
+ | `NIGHTHAWK_RUN_INTEGRATION_TESTS=1 uv run pytest -q` | Integration tests |
60
58
 
61
59
  `uv` hardlinking warnings do not indicate failure. Suppress: `export UV_LINK_MODE=copy`.
62
60
 
63
61
  Environment: `OPENAI_API_KEY` (OpenAI), `CODEX_API_KEY` (Codex).
62
+
63
+ Promptfoo evaluation details (commands, configs, directory layout, flags): see `CONTRIBUTING.md` "Prompt evaluation with promptfoo".
@@ -7,6 +7,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.5.0]
11
+
12
+ ### Added
13
+ - `evals/promptfoo/` evaluation harness for system prompt optimization using [promptfoo](https://www.promptfoo.dev/): custom Python provider, reusable assertions, and prompt variant A/B comparison support. See `CONTRIBUTING.md` for usage.
14
+ - `docs/philosophy.md`: design philosophy and motivation behind Nighthawk.
15
+ - `docs/practices.md`: practical patterns and binding function design guidance (extracted from tutorial).
16
+
17
+ ### Changed
18
+ - Replaced `return_reference_path` with `return_expression` in step execution contract: return values are now specified as Python expressions evaluated against step locals/globals, consistent with `nh_eval`/`nh_assign` expression evaluation. This unblocks coding-agent backends (e.g. Claude Code CLI) that compute results via native tools without bridging values through `nh_assign`.
19
+ - `nh_assign` now infers binding types from initial values when no explicit annotation is provided, enabling type-mismatch retry for unannotated write bindings.
20
+ - Default `json_renderer_style` changed from `"strict"` to `"default"`, making truncation visible via `…` omission markers in prompt context and tool results.
21
+ - Merged `nh_exec` into `nh_eval`: `nh_eval` now handles expression evaluation, function calls, and in-place mutation. `nh_exec` is removed.
22
+ - Condensed system prompt: simplified tool selection guidance (single `nh_eval` tool), added execution order section, clarified tool result format.
23
+ - Condensed step execution contract (outcome prompt suffix) for reduced token usage.
24
+ - Improved `nh_assign` and `nh_eval` tool descriptions for LLM clarity.
25
+ - Restructured documentation: rewrote `index.md`, `tutorial.md`, `for-coding-agents.md`; cross-referenced specification and practice guides.
26
+ - Integration tests: replaced single `NIGHTHAWK_RUN_INTEGRATION_TESTS` gate with per-backend environment variables (`NIGHTHAWK_CODEX_INTEGRATION_TESTS`, `NIGHTHAWK_CLAUDE_SDK_INTEGRATION_TESTS`, `NIGHTHAWK_CLAUDE_CLI_INTEGRATION_TESTS`).
27
+
28
+ ### Removed
29
+ - `nh_exec` tool (functionality absorbed by `nh_eval`).
30
+ - Three redundant OpenAI integration tests from `test_llm_integration.py` (covered by promptfoo evaluation harness).
31
+ - `pytest_sessionstart` credential-check hook (replaced by per-backend skip helpers).
32
+
10
33
  ## [0.4.0] - 2026-03-20
11
34
 
12
35
  ### Added
@@ -57,7 +80,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
57
80
  - Step executor abstraction and provider integration foundation.
58
81
  - Core documentation and project scaffolding.
59
82
 
60
- [Unreleased]: https://github.com/kurusugawa-computer/nighthawk-python/compare/v0.4.0...HEAD
83
+ [Unreleased]: https://github.com/kurusugawa-computer/nighthawk-python/compare/v0.5.0...HEAD
84
+ [0.5.0]: https://github.com/kurusugawa-computer/nighthawk-python/compare/v0.4.0...v0.5.0
61
85
  [0.4.0]: https://github.com/kurusugawa-computer/nighthawk-python/compare/v0.3.1...v0.4.0
62
86
  [0.3.1]: https://github.com/kurusugawa-computer/nighthawk-python/compare/v0.3.0...v0.3.1
63
87
  [0.3.0]: https://github.com/kurusugawa-computer/nighthawk-python/compare/v0.2.0...v0.3.0
@@ -70,6 +70,48 @@ OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 uv run pytest -q tests/integra
70
70
 
71
71
  Traces appear in the otel-tui terminal UI in real time.
72
72
 
73
+ ### Prompt evaluation with promptfoo
74
+
75
+ System prompt, tool descriptions, and backend behavior are evaluated with [promptfoo](https://www.promptfoo.dev/). Requires Node.js (for `npx`). API keys must be loaded from `.env` first.
76
+
77
+ ```bash
78
+ set -a; source .env; set +a
79
+ PFOO="cd evals/promptfoo && PROMPTFOO_PYTHON=\"$(uv python find)\" npx promptfoo@latest"
80
+ ```
81
+
82
+ | Command | Purpose |
83
+ |---|---|
84
+ | `eval $PFOO eval` | Full regression (all backends, all tests) |
85
+ | `eval $PFOO eval -c promptfooconfig-prompt-ab.yaml` | Prompt A/B test (gpt-5.4-mini only) |
86
+ | `eval $PFOO eval -c promptfooconfig-agents.yaml` | Coding agent backends (reduced test set) |
87
+ | `eval $PFOO eval -c promptfooconfig.yaml --filter-pattern "P-BIND-001"` | Single test |
88
+ | `eval $PFOO eval -c promptfooconfig.yaml --filter-providers "claude-code-cli"` | Single backend |
89
+ | `eval $PFOO view` | Open results in browser |
90
+
91
+ #### Config files (`evals/promptfoo/`)
92
+
93
+ - `promptfooconfig.yaml` — Regression: winner prompt combo across openai-responses, claude-code-cli, and codex backends. All test cases.
94
+ - `promptfooconfig-prompt-ab.yaml` — A/B testing: 4 prompt/tool variants on gpt-5.4-mini. All test cases.
95
+ - `promptfooconfig-agents.yaml` — Coding agent only: claude-code-cli and codex with reduced test set.
96
+
97
+ #### Directory layout
98
+
99
+ - `provider.py` — Custom provider wrapping `AgentStepExecutor`. Handles tool preset installation, backend-specific model settings, and callable fixture resolution.
100
+ - `prompts/` — System prompt variants (`eval_default.txt`, `eval_sequenced.txt`, `eval_mutation_aware.txt`, `eval_coding_agent.txt`, etc.).
101
+ - `test_cases/` — YAML test suites: `binding_operations`, `tool_selection`, `outcome_kinds`, `edge_cases`, `loop_outcomes`, `multi_step`, `null_handling`, `tool_selection_core`.
102
+ - `assertions/` — Custom Python assertions: `binding_value.py`, `outcome_kind.py`, `raise_message.py`.
103
+
104
+ #### Adding tests
105
+
106
+ Each test case YAML entry needs: `description` (with `P-SLUG-NNN` Id), `vars` (natural_program, input_bindings, output_binding_names), and `assert` list. Callable bindings use `"__callable:<key>"` resolved from `_CALLABLE_FIXTURE_REGISTRY` in `provider.py`.
107
+
108
+ #### Useful flags
109
+
110
+ - `--no-cache` — Skip cache (required after changing provider.py or prompts).
111
+ - `--filter-pattern "<regex>"` — Run only matching test descriptions.
112
+ - `--filter-providers "<regex>"` — Run only matching provider labels.
113
+ - `-o <path>.json` — Write structured results to file for analysis.
114
+
73
115
  ### Environment variables
74
116
 
75
117
  - `OPENAI_API_KEY`: Required for OpenAI integration tests (also requires `pydantic-ai-slim[openai]`).
@@ -160,7 +202,7 @@ def run(
160
202
  Example:
161
203
  ```python
162
204
  executor = AgentStepExecutor.from_configuration(
163
- configuration=StepExecutorConfiguration(model="openai-responses:gpt-5-mini"),
205
+ configuration=StepExecutorConfiguration(model="openai-responses:gpt-5.4-mini"),
164
206
  )
165
207
  with nighthawk.run(executor):
166
208
  result = my_natural_function()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nighthawk-python
3
- Version: 0.4.0
3
+ Version: 0.5.0
4
4
  Summary: An experimental Python library that embeds Natural blocks inside Python functions and executes them using an LLM.
5
5
  Project-URL: Repository, https://github.com/kurusugawa-computer/nighthawk-python
6
6
  Project-URL: Documentation, https://kurusugawa-computer.github.io/nighthawk-python/
@@ -33,7 +33,7 @@ Requires-Dist: mcp>=1.26; extra == 'codex'
33
33
  Description-Content-Type: text/markdown
34
34
 
35
35
  [![PyPI](https://img.shields.io/pypi/v/nighthawk-python)](https://pypi.org/project/nighthawk-python)
36
- ![PyPI - Downloads](https://img.shields.io/pypi/dm/nighthawk-python)
36
+ [![PyPI Stats](https://img.shields.io/pypi/dm/nighthawk-python)](https://pypistats.org/packages/nighthawk-python)
37
37
  [![license](https://img.shields.io/github/license/kurusugawa-computer/nighthawk-python.svg)](https://github.com/kurusugawa-computer/nighthawk-python/blob/main/LICENSE)
38
38
  [![issue resolution](https://img.shields.io/github/issues-closed-raw/kurusugawa-computer/nighthawk-python)](https://github.com/kurusugawa-computer/nighthawk-python/issues)
39
39
 
@@ -43,25 +43,32 @@ Description-Content-Type: text/markdown
43
43
  <img src="https://github.com/kurusugawa-computer/nighthawk-python/raw/main/docs/assets/nighthawk_logo-128x128.png" alt="nighthawk-logo" width="128px" margin="10px"></img>
44
44
  </div>
45
45
 
46
- Nighthawk is an experimental Python library exploring a clear separation between **hard control** (Python code) for strict procedure and deterministic flow, and **soft reasoning** (an LLM) for semantic interpretation inside small embedded "Natural blocks". It is a compact reimplementation of the core ideas of [Nightjar](https://github.com/psg-mit/nightjarpy).
46
+ Nighthawk is an experimental Python library exploring a clear separation:
47
47
 
48
- ## Quickstart
48
+ - Use **hard control** (Python code) for strict procedure, verification, and deterministic flow.
49
+ - Use **soft reasoning** (an LLM or coding agent) for semantic interpretation inside small embedded "Natural blocks".
49
50
 
50
- Prerequisites: Python 3.13+
51
+ Python controls all flow; the LLM or coding agent is constrained to small Natural blocks with explicit input/output boundaries. The same mechanism handles lightweight LLM judgments ("classify this sentiment") and autonomous agent executions ("refactor this module and write tests"). See **[Philosophy](https://kurusugawa-computer.github.io/nighthawk-python/philosophy/)** for the full design rationale.
52
+
53
+ This repository is a compact reimplementation of the core ideas of [Nightjar](https://github.com/psg-mit/nightjarpy).
51
54
 
52
- Install Nighthawk and a provider:
55
+ ## Installation
56
+
57
+ Prerequisites: Python 3.13+
53
58
 
54
59
  ```bash
55
60
  pip install nighthawk-python pydantic-ai-slim[openai]
56
61
  ```
57
62
 
58
- Save as `quickstart.py`:
63
+ For other providers, see [Providers](https://kurusugawa-computer.github.io/nighthawk-python/providers/).
64
+
65
+ ## Example
59
66
 
60
67
  ```py
61
68
  import nighthawk as nh
62
69
 
63
70
  step_executor = nh.AgentStepExecutor.from_configuration(
64
- configuration=nh.StepExecutorConfiguration(model="openai-responses:gpt-5-mini")
71
+ configuration=nh.StepExecutorConfiguration(model="openai-responses:gpt-5.4-mini")
65
72
  )
66
73
 
67
74
  with nh.run(step_executor):
@@ -75,17 +82,22 @@ with nh.run(step_executor):
75
82
  return total
76
83
 
77
84
  print(calculate_total("three apples, a dozen eggs, and 5 oranges"))
85
+ # => 20
78
86
  ```
79
87
 
80
- Run with your API key:
88
+ See the **[Quickstart](https://kurusugawa-computer.github.io/nighthawk-python/quickstart/)** for setup details, credentials, and troubleshooting.
81
89
 
82
- ```bash
83
- export OPENAI_API_KEY=sk-xxxxxxxxx
84
- python quickstart.py
85
- # => 20
86
- ```
90
+ ## Documentation
87
91
 
88
- For backends, credentials, model identifiers, and detailed guidance, see the [documentation site](https://kurusugawa-computer.github.io/nighthawk-python/).
92
+ - **[Quickstart](https://kurusugawa-computer.github.io/nighthawk-python/quickstart/)** — Setup and first example.
93
+ - **[Tutorial](https://kurusugawa-computer.github.io/nighthawk-python/tutorial/)** — Learn from first principles.
94
+ - **[Practices](https://kurusugawa-computer.github.io/nighthawk-python/practices/)** — Guidelines, patterns, and testing.
95
+ - **[Providers](https://kurusugawa-computer.github.io/nighthawk-python/providers/)** — LLM providers and configuration.
96
+ - **[Coding agent backends](https://kurusugawa-computer.github.io/nighthawk-python/coding-agent-backends/)** — Claude Code and Codex integration.
97
+ - **[Philosophy](https://kurusugawa-computer.github.io/nighthawk-python/philosophy/)** — Design rationale and positioning.
98
+ - **[Design](https://kurusugawa-computer.github.io/nighthawk-python/design/)** — Canonical specification.
99
+ - **[API Reference](https://kurusugawa-computer.github.io/nighthawk-python/api/)** — Auto-generated API documentation.
100
+ - **[Roadmap](https://kurusugawa-computer.github.io/nighthawk-python/roadmap/)** — Future directions.
89
101
 
90
102
  ## Development & Contributing
91
103
 
@@ -0,0 +1,74 @@
1
+ [![PyPI](https://img.shields.io/pypi/v/nighthawk-python)](https://pypi.org/project/nighthawk-python)
2
+ [![PyPI Stats](https://img.shields.io/pypi/dm/nighthawk-python)](https://pypistats.org/packages/nighthawk-python)
3
+ [![license](https://img.shields.io/github/license/kurusugawa-computer/nighthawk-python.svg)](https://github.com/kurusugawa-computer/nighthawk-python/blob/main/LICENSE)
4
+ [![issue resolution](https://img.shields.io/github/issues-closed-raw/kurusugawa-computer/nighthawk-python)](https://github.com/kurusugawa-computer/nighthawk-python/issues)
5
+
6
+ # Nighthawk
7
+
8
+ <div align="center">
9
+ <img src="https://github.com/kurusugawa-computer/nighthawk-python/raw/main/docs/assets/nighthawk_logo-128x128.png" alt="nighthawk-logo" width="128px" margin="10px"></img>
10
+ </div>
11
+
12
+ Nighthawk is an experimental Python library exploring a clear separation:
13
+
14
+ - Use **hard control** (Python code) for strict procedure, verification, and deterministic flow.
15
+ - Use **soft reasoning** (an LLM or coding agent) for semantic interpretation inside small embedded "Natural blocks".
16
+
17
+ Python controls all flow; the LLM or coding agent is constrained to small Natural blocks with explicit input/output boundaries. The same mechanism handles lightweight LLM judgments ("classify this sentiment") and autonomous agent executions ("refactor this module and write tests"). See **[Philosophy](https://kurusugawa-computer.github.io/nighthawk-python/philosophy/)** for the full design rationale.
18
+
19
+ This repository is a compact reimplementation of the core ideas of [Nightjar](https://github.com/psg-mit/nightjarpy).
20
+
21
+ ## Installation
22
+
23
+ Prerequisites: Python 3.13+
24
+
25
+ ```bash
26
+ pip install nighthawk-python pydantic-ai-slim[openai]
27
+ ```
28
+
29
+ For other providers, see [Providers](https://kurusugawa-computer.github.io/nighthawk-python/providers/).
30
+
31
+ ## Example
32
+
33
+ ```py
34
+ import nighthawk as nh
35
+
36
+ step_executor = nh.AgentStepExecutor.from_configuration(
37
+ configuration=nh.StepExecutorConfiguration(model="openai-responses:gpt-5.4-mini")
38
+ )
39
+
40
+ with nh.run(step_executor):
41
+
42
+ @nh.natural_function
43
+ def calculate_total(items: str) -> int:
44
+ total = 0
45
+ """natural
46
+ Read <items> and set <:total> to the sum of all quantities mentioned.
47
+ """
48
+ return total
49
+
50
+ print(calculate_total("three apples, a dozen eggs, and 5 oranges"))
51
+ # => 20
52
+ ```
53
+
54
+ See the **[Quickstart](https://kurusugawa-computer.github.io/nighthawk-python/quickstart/)** for setup details, credentials, and troubleshooting.
55
+
56
+ ## Documentation
57
+
58
+ - **[Quickstart](https://kurusugawa-computer.github.io/nighthawk-python/quickstart/)** — Setup and first example.
59
+ - **[Tutorial](https://kurusugawa-computer.github.io/nighthawk-python/tutorial/)** — Learn from first principles.
60
+ - **[Practices](https://kurusugawa-computer.github.io/nighthawk-python/practices/)** — Guidelines, patterns, and testing.
61
+ - **[Providers](https://kurusugawa-computer.github.io/nighthawk-python/providers/)** — LLM providers and configuration.
62
+ - **[Coding agent backends](https://kurusugawa-computer.github.io/nighthawk-python/coding-agent-backends/)** — Claude Code and Codex integration.
63
+ - **[Philosophy](https://kurusugawa-computer.github.io/nighthawk-python/philosophy/)** — Design rationale and positioning.
64
+ - **[Design](https://kurusugawa-computer.github.io/nighthawk-python/design/)** — Canonical specification.
65
+ - **[API Reference](https://kurusugawa-computer.github.io/nighthawk-python/api/)** — Auto-generated API documentation.
66
+ - **[Roadmap](https://kurusugawa-computer.github.io/nighthawk-python/roadmap/)** — Future directions.
67
+
68
+ ## Development & Contributing
69
+
70
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for setup, development commands, and contribution guidelines.
71
+
72
+ ## References
73
+
74
+ - Nightjar (upstream concept): https://github.com/psg-mit/nightjarpy