nighthawk-python 0.2.0__tar.gz → 0.3.1__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.2.0 → nighthawk_python-0.3.1}/.claude/rules/docs.md +2 -0
- nighthawk_python-0.3.1/.claude/settings.json +5 -0
- nighthawk_python-0.3.1/CHANGELOG.md +56 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/CONTRIBUTING.md +18 -1
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/PKG-INFO +3 -2
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/docs/for-coding-agents.md +3 -33
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/pyproject.toml +3 -2
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/runtime/scoping.py +29 -11
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/runtime/step_executor.py +11 -25
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/runtime/tool_calls.py +3 -2
- nighthawk_python-0.3.1/src/nighthawk/ulid.py +18 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/public/test_public_api.py +42 -1
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/uv.lock +23 -23
- nighthawk_python-0.2.0/CHANGELOG.md +0 -35
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/.claude/rules/coding.md +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/.claude/unset_envs.sh +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/.devcontainer/Dockerfile.devcontainer +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/.devcontainer/Dockerfile.litellm +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/.devcontainer/devcontainer.json +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/.devcontainer/docker-compose.yaml +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/.devcontainer/litellm-config.yaml +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/.github/dependabot.yml +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/.github/workflows/ci.yml +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/.github/workflows/docs.yml +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/.github/workflows/publish.yml +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/.gitignore +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/.python-version +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/AGENTS.md +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/CLAUDE.md +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/LICENSE +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/README.md +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/docs/api.md +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/docs/assets/nighthawk_logo-128x128.png +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/docs/coding-agent-backends.md +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/docs/design.md +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/docs/index.md +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/docs/providers.md +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/docs/quickstart.md +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/docs/roadmap.md +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/docs/tutorial.md +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/mkdocs.yml +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/pyrightconfig.json +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/__init__.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/backends/__init__.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/backends/base.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/backends/claude_code_cli.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/backends/claude_code_sdk.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/backends/codex.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/backends/mcp_boundary.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/backends/mcp_server.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/backends/tool_bridge.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/configuration.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/errors.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/identifier_path.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/json_renderer.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/natural/__init__.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/natural/blocks.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/natural/decorator.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/natural/transform.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/runtime/__init__.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/runtime/async_bridge.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/runtime/prompt.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/runtime/runner.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/runtime/step_context.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/runtime/step_contract.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/tools/__init__.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/tools/assignment.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/tools/contracts.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/tools/execution.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/tools/provided.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/src/nighthawk/tools/registry.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/__init__.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/backends/__init__.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/backends/test_claude_code_cli.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/backends/test_claude_code_sdk.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/backends/test_codex.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/conftest.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/docs/__init__.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/docs/test_prompt_examples.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/execution/__init__.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/execution/prompt_test_helpers.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/execution/stub_executor.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/execution/test_execution_outcome_prompt_fragment.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/execution/test_globals_prompt.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/execution/test_natural_block_ordering.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/execution/test_natural_traceback.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/execution/test_runtime.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/execution/test_variables_prompt.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/integration/__init__.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/integration/skip_helpers.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/integration/test_carry_pattern.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/integration/test_claude_code_cli_integration.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/integration/test_claude_code_sdk_integration.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/integration/test_codex_integration.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/integration/test_llm_integration.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/natural/__init__.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/natural/test_blocks.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/public/__init__.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/public/test_readme_example.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/test_renderer.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/tools/__init__.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/tools/test_assignment_async.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/tools/test_contracts.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/tools/test_registry.py +0 -0
- {nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/tools/test_tool_boundary.py +0 -0
|
@@ -91,6 +91,8 @@ Each file has a distinct audience and scope. Content belongs in exactly one file
|
|
|
91
91
|
- This file should be self-contained: a coding agent reading only this file should be able to write correct Nighthawk code without consulting other docs.
|
|
92
92
|
- This file is consumed standalone (`@docs/for-coding-agents.md` in CLAUDE.md/AGENTS.md, GitHub raw URL, etc.). Do not assume sibling files exist at relative paths.
|
|
93
93
|
- All external references to other docs use absolute URLs based on `site_url` from `mkdocs.yml` (currently `https://kurusugawa-computer.github.io/nighthawk-python/`). If `site_url` changes, update the URLs in this file.
|
|
94
|
+
- `@nh.tool` is deprecated. Do not add examples, recommendations, or references to `@nh.tool` in this file. Binding functions are the only recommended callable exposure mechanism.
|
|
95
|
+
- Filter content for coding-agent relevance. Omit infrastructure-level concerns (scoped overrides parameter lists, exception hierarchy beyond `ExecutionError`, observability/tracing) that do not affect how an agent writes Natural blocks or binding functions. Mention existence and link to Tutorial or Design for details.
|
|
94
96
|
|
|
95
97
|
### api.md specifics
|
|
96
98
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.3.1] - 2026-03-19
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- Internal ID generation now uses `ulid.generate_ulid()` (ULID,
|
|
14
|
+
26-character Crockford Base32, timestamp-sortable) in a dedicated
|
|
15
|
+
module, replacing the former `generate_id` embedded in
|
|
16
|
+
`runtime.scoping`.
|
|
17
|
+
|
|
18
|
+
## [0.3.0] - 2026-03-18
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
- `system_prompt_suffix_fragment_scope` and `user_prompt_suffix_fragment_scope` context managers for lightweight prompt fragment management without full scope overhead.
|
|
22
|
+
- OpenTelemetry tracer now reports `instrumenting_library_version`.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
- Simplified OpenTelemetry span hierarchy: removed implicit `nighthawk.scope` spans and `nighthawk.step_executor` spans. `nighthawk.scope` spans are now emitted only for explicit `nh.scope()` calls.
|
|
26
|
+
- `nighthawk.run` span no longer includes `scope.id` attribute; only `run.id` is emitted.
|
|
27
|
+
- Trimmed `for-coding-agents.md` for coding-agent relevance: removed deprecated `@nh.tool` references, condensed exception hierarchy, scoped overrides, and added debugging context to `StepContextLimits`.
|
|
28
|
+
|
|
29
|
+
## [0.2.0] - 2026-03-16
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
- Added compact step trace support for Natural block execution attempts:
|
|
33
|
+
- `StepTrace`
|
|
34
|
+
- `StepTraceError`
|
|
35
|
+
- `nighthawk.get_step_traces()`
|
|
36
|
+
|
|
37
|
+
### Changed
|
|
38
|
+
- Updated CI workflow setup (`setup-uv`) in project automation.
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
- License badge reference in README.
|
|
42
|
+
- Documentation formatting inconsistencies.
|
|
43
|
+
|
|
44
|
+
## [0.1.0] - 2026-03-13
|
|
45
|
+
|
|
46
|
+
### Added
|
|
47
|
+
- Initial public release of `nighthawk-python`.
|
|
48
|
+
- Natural DSL execution runtime with run/scope execution context model.
|
|
49
|
+
- Step executor abstraction and provider integration foundation.
|
|
50
|
+
- Core documentation and project scaffolding.
|
|
51
|
+
|
|
52
|
+
[Unreleased]: https://github.com/kurusugawa-computer/nighthawk-python/compare/v0.3.1...HEAD
|
|
53
|
+
[0.3.1]: https://github.com/kurusugawa-computer/nighthawk-python/compare/v0.3.0...v0.3.1
|
|
54
|
+
[0.3.0]: https://github.com/kurusugawa-computer/nighthawk-python/compare/v0.2.0...v0.3.0
|
|
55
|
+
[0.2.0]: https://github.com/kurusugawa-computer/nighthawk-python/compare/v0.1.0...v0.2.0
|
|
56
|
+
[0.1.0]: https://github.com/kurusugawa-computer/nighthawk-python/tree/v0.1.0
|
|
@@ -53,6 +53,23 @@ Then run with your `.env` loaded:
|
|
|
53
53
|
set -a; source .env; set +a; uv run pytest -q
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
+
### Trace inspection with otel-tui
|
|
57
|
+
|
|
58
|
+
Nighthawk emits OpenTelemetry traces for step execution. You can inspect them
|
|
59
|
+
locally using [otel-tui](https://github.com/ymtdzzz/otel-tui):
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
docker run --rm -it -p 4318:4318 --name otel-tui ymtdzzz/otel-tui:latest
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Then run integration tests with the collector endpoint:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 uv run pytest -q tests/integration/
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Traces appear in the otel-tui terminal UI in real time.
|
|
72
|
+
|
|
56
73
|
### Environment variables
|
|
57
74
|
|
|
58
75
|
- `OPENAI_API_KEY`: Required for OpenAI integration tests (also requires `pydantic-ai-slim[openai]`).
|
|
@@ -131,7 +148,7 @@ def run(
|
|
|
131
148
|
|
|
132
149
|
Args:
|
|
133
150
|
step_executor: The step executor to use for Natural block execution.
|
|
134
|
-
run_id: Optional identifier for the run. If not provided, a
|
|
151
|
+
run_id: Optional identifier for the run. If not provided, a ULID is
|
|
135
152
|
generated automatically.
|
|
136
153
|
|
|
137
154
|
Yields:
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nighthawk-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.1
|
|
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/
|
|
7
|
+
Project-URL: Changelog, https://github.com/kurusugawa-computer/nighthawk-python/blob/main/CHANGELOG.md
|
|
7
8
|
Project-URL: Bug Tracker, https://github.com/kurusugawa-computer/nighthawk-python/issues
|
|
8
9
|
Author-email: "Kurusugawa Computer Inc." <oss@kurusugawa.jp>
|
|
9
10
|
License-Expression: MIT
|
|
@@ -26,7 +27,7 @@ Requires-Dist: tiktoken>=0.12
|
|
|
26
27
|
Provides-Extra: claude-code-cli
|
|
27
28
|
Requires-Dist: mcp>=1.26; extra == 'claude-code-cli'
|
|
28
29
|
Provides-Extra: claude-code-sdk
|
|
29
|
-
Requires-Dist: claude-agent-sdk
|
|
30
|
+
Requires-Dist: claude-agent-sdk==0.1.48; extra == 'claude-code-sdk'
|
|
30
31
|
Provides-Extra: codex
|
|
31
32
|
Requires-Dist: mcp>=1.26; extra == 'codex'
|
|
32
33
|
Description-Content-Type: text/markdown
|
|
@@ -64,10 +64,6 @@ Each Natural block should make exactly one independent judgment. If a block make
|
|
|
64
64
|
|
|
65
65
|
Binding functions (local or module-level callables) are the preferred way to expose functions to the LLM. The LLM discovers them from the LOCALS/GLOBALS sections of the prompt, rendered as their signature with the first docstring line as `# intent:`.
|
|
66
66
|
|
|
67
|
-
### Prefer binding functions over `@nh.tool`
|
|
68
|
-
|
|
69
|
-
`@nh.tool` is reserved strictly for cases requiring `RunContext[StepContext]` access. Binding functions incur no per-definition token overhead beyond a signature line. Always use binding functions unless `RunContext` access is needed.
|
|
70
|
-
|
|
71
67
|
### Keep locals minimal
|
|
72
68
|
|
|
73
69
|
Module-level names that are stable across invocations (constants, classes, utility functions) should stay in GLOBALS via `<name>` read bindings. Reserve function parameters for data that genuinely varies per call.
|
|
@@ -156,11 +152,7 @@ except nh.ExecutionError as e:
|
|
|
156
152
|
print(f"Validation failed: {e}")
|
|
157
153
|
```
|
|
158
154
|
|
|
159
|
-
Custom exception types referenced in step locals or globals are available as raise targets.
|
|
160
|
-
|
|
161
|
-
### Exception hierarchy
|
|
162
|
-
|
|
163
|
-
All exceptions inherit from `NighthawkError`: `ExecutionError`, `NaturalParseError`, `ToolEvaluationError`, `ToolValidationError`, `ToolRegistrationError`.
|
|
155
|
+
Custom exception types referenced in step locals or globals are available as raise targets. Catch `nh.ExecutionError` for Natural block failures; all Nighthawk exceptions inherit from `nh.NighthawkError`.
|
|
164
156
|
|
|
165
157
|
## 6. Cross-block composition
|
|
166
158
|
|
|
@@ -221,30 +213,9 @@ with nh.run(step_executor):
|
|
|
221
213
|
result = my_natural_function(data)
|
|
222
214
|
```
|
|
223
215
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
Use `nh.scope()` to override execution settings within an existing run. Each scope generates a new `scope_id` while keeping the current `run_id`.
|
|
227
|
-
|
|
228
|
-
Parameters:
|
|
229
|
-
|
|
230
|
-
- `step_executor_configuration`: replace the entire configuration.
|
|
231
|
-
- `step_executor_configuration_patch`: partially override specific fields.
|
|
232
|
-
- `step_executor`: replace the step executor entirely.
|
|
233
|
-
- `system_prompt_suffix_fragment`: append text to the system prompt for the scope.
|
|
234
|
-
- `user_prompt_suffix_fragment`: append text to the user prompt for the scope.
|
|
235
|
-
|
|
236
|
-
```python
|
|
237
|
-
with nh.scope(
|
|
238
|
-
step_executor_configuration_patch=nh.StepExecutorConfigurationPatch(
|
|
239
|
-
model="openai-responses:gpt-5-mini",
|
|
240
|
-
),
|
|
241
|
-
):
|
|
242
|
-
expensive_analysis(data)
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
### Context limits
|
|
216
|
+
Use `nh.scope()` to override model, prompts, or context limits within an existing run. For details, see [Tutorial](https://kurusugawa-computer.github.io/nighthawk-python/tutorial/).
|
|
246
217
|
|
|
247
|
-
LOCALS and GLOBALS sections are bounded by `StepContextLimits`.
|
|
218
|
+
LOCALS and GLOBALS sections are bounded by `StepContextLimits`. When bindings are missing or truncated (`<snipped>`), adjust the limits:
|
|
248
219
|
|
|
249
220
|
```python
|
|
250
221
|
configuration = nh.StepExecutorConfiguration(
|
|
@@ -304,7 +275,6 @@ def judge_review(review_data: str | nh.JsonableValue) -> ReviewVerdict:
|
|
|
304
275
|
| Use `<:carry>` (write binding) for mutable context | Rebinding breaks the caller's reference | Use `<carry>` (read binding); mutate in-place |
|
|
305
276
|
| Put two independent judgments in one block | Non-deterministic, hard to test, unclear contract | Split into two blocks connected by Python |
|
|
306
277
|
| Use Natural for deterministic computation | Wastes latency/cost, adds non-determinism | Use Python |
|
|
307
|
-
| Use `@nh.tool` when a binding function suffices | Unnecessary per-definition token overhead | Use binding functions; reserve `@nh.tool` for `RunContext[StepContext]` access |
|
|
308
278
|
| Forget type annotations on write bindings | No validation or coercion at commit time | Always annotate `<:name>` bindings |
|
|
309
279
|
| Duplicate module-level constants as function parameters | Moves stable values from GLOBALS to LOCALS, wastes tokens | Reference via `<name>` read binding |
|
|
310
280
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "nighthawk-python"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.3.1"
|
|
4
4
|
description = "An experimental Python library that embeds Natural blocks inside Python functions and executes them using an LLM."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.13"
|
|
@@ -32,11 +32,12 @@ dependencies = [
|
|
|
32
32
|
[project.urls]
|
|
33
33
|
Repository = "https://github.com/kurusugawa-computer/nighthawk-python"
|
|
34
34
|
Documentation = "https://kurusugawa-computer.github.io/nighthawk-python/"
|
|
35
|
+
Changelog = "https://github.com/kurusugawa-computer/nighthawk-python/blob/main/CHANGELOG.md"
|
|
35
36
|
"Bug Tracker" = "https://github.com/kurusugawa-computer/nighthawk-python/issues"
|
|
36
37
|
|
|
37
38
|
[project.optional-dependencies]
|
|
38
39
|
claude-code-sdk = [
|
|
39
|
-
"claude-agent-sdk
|
|
40
|
+
"claude-agent-sdk==0.1.48",
|
|
40
41
|
]
|
|
41
42
|
claude-code-cli = [
|
|
42
43
|
"mcp>=1.26",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import importlib.metadata
|
|
4
4
|
from collections.abc import Iterator
|
|
5
5
|
from contextlib import contextmanager
|
|
6
6
|
from contextvars import ContextVar
|
|
@@ -12,6 +12,7 @@ from opentelemetry.trace import Span, get_tracer_provider
|
|
|
12
12
|
from ..configuration import StepExecutorConfiguration, StepExecutorConfigurationPatch
|
|
13
13
|
from ..errors import NighthawkError
|
|
14
14
|
from ..tools.registry import tool_scope
|
|
15
|
+
from ..ulid import generate_ulid
|
|
15
16
|
|
|
16
17
|
if TYPE_CHECKING:
|
|
17
18
|
from .step_executor import AgentStepExecutor, StepExecutor
|
|
@@ -36,7 +37,9 @@ STEP_ID = "step.id"
|
|
|
36
37
|
TOOL_CALL_ID = "tool_call.id"
|
|
37
38
|
|
|
38
39
|
|
|
39
|
-
|
|
40
|
+
_LIBRARY_VERSION = importlib.metadata.version("nighthawk-python")
|
|
41
|
+
|
|
42
|
+
_tracer = get_tracer_provider().get_tracer("nighthawk", _LIBRARY_VERSION)
|
|
40
43
|
|
|
41
44
|
|
|
42
45
|
@contextmanager
|
|
@@ -50,10 +53,6 @@ def span(span_name: str, /, **attributes: Any) -> Iterator[Span]:
|
|
|
50
53
|
yield current_span
|
|
51
54
|
|
|
52
55
|
|
|
53
|
-
def _generate_id() -> str:
|
|
54
|
-
return uuid.uuid4().hex
|
|
55
|
-
|
|
56
|
-
|
|
57
56
|
_step_executor_var: ContextVar[StepExecutor | None] = ContextVar(
|
|
58
57
|
"nighthawk_step_executor",
|
|
59
58
|
default=None,
|
|
@@ -108,6 +107,26 @@ def get_user_prompt_suffix_fragments() -> tuple[str, ...]:
|
|
|
108
107
|
return _user_prompt_suffix_fragments_var.get()
|
|
109
108
|
|
|
110
109
|
|
|
110
|
+
@contextmanager
|
|
111
|
+
def system_prompt_suffix_fragment_scope(fragment: str) -> Iterator[None]:
|
|
112
|
+
current = _system_prompt_suffix_fragments_var.get()
|
|
113
|
+
token = _system_prompt_suffix_fragments_var.set((*current, fragment))
|
|
114
|
+
try:
|
|
115
|
+
yield
|
|
116
|
+
finally:
|
|
117
|
+
_system_prompt_suffix_fragments_var.reset(token)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
@contextmanager
|
|
121
|
+
def user_prompt_suffix_fragment_scope(fragment: str) -> Iterator[None]:
|
|
122
|
+
current = _user_prompt_suffix_fragments_var.get()
|
|
123
|
+
token = _user_prompt_suffix_fragments_var.set((*current, fragment))
|
|
124
|
+
try:
|
|
125
|
+
yield
|
|
126
|
+
finally:
|
|
127
|
+
_user_prompt_suffix_fragments_var.reset(token)
|
|
128
|
+
|
|
129
|
+
|
|
111
130
|
def _resolve_agent_step_executor(step_executor: StepExecutor) -> AgentStepExecutor:
|
|
112
131
|
from .step_executor import AgentStepExecutor
|
|
113
132
|
|
|
@@ -149,7 +168,7 @@ def run(
|
|
|
149
168
|
|
|
150
169
|
Args:
|
|
151
170
|
step_executor: The step executor to use for Natural block execution.
|
|
152
|
-
run_id: Optional identifier for the run. If not provided, a
|
|
171
|
+
run_id: Optional identifier for the run. If not provided, a ULID is
|
|
153
172
|
generated automatically.
|
|
154
173
|
|
|
155
174
|
Yields:
|
|
@@ -165,8 +184,8 @@ def run(
|
|
|
165
184
|
```
|
|
166
185
|
"""
|
|
167
186
|
execution_context = ExecutionContext(
|
|
168
|
-
run_id=run_id or
|
|
169
|
-
scope_id=
|
|
187
|
+
run_id=run_id or generate_ulid(),
|
|
188
|
+
scope_id=generate_ulid(),
|
|
170
189
|
)
|
|
171
190
|
|
|
172
191
|
with tool_scope():
|
|
@@ -179,7 +198,6 @@ def run(
|
|
|
179
198
|
"nighthawk.run",
|
|
180
199
|
**{
|
|
181
200
|
RUN_ID: execution_context.run_id,
|
|
182
|
-
SCOPE_ID: execution_context.scope_id,
|
|
183
201
|
},
|
|
184
202
|
):
|
|
185
203
|
yield
|
|
@@ -260,7 +278,7 @@ def scope(
|
|
|
260
278
|
|
|
261
279
|
next_execution_context = replace(
|
|
262
280
|
current_execution_context,
|
|
263
|
-
scope_id=
|
|
281
|
+
scope_id=generate_ulid(),
|
|
264
282
|
)
|
|
265
283
|
|
|
266
284
|
next_system_fragments = _system_prompt_suffix_fragments_var.get()
|
|
@@ -13,13 +13,8 @@ from ..tools.registry import get_visible_tools
|
|
|
13
13
|
from .async_bridge import run_coroutine_synchronously
|
|
14
14
|
from .prompt import build_user_prompt, extract_references_and_program
|
|
15
15
|
from .scoping import (
|
|
16
|
-
RUN_ID,
|
|
17
|
-
SCOPE_ID,
|
|
18
|
-
STEP_ID,
|
|
19
|
-
get_execution_context,
|
|
20
16
|
get_system_prompt_suffix_fragments,
|
|
21
|
-
|
|
22
|
-
span,
|
|
17
|
+
system_prompt_suffix_fragment_scope,
|
|
23
18
|
)
|
|
24
19
|
from .step_context import (
|
|
25
20
|
_MISSING,
|
|
@@ -315,25 +310,16 @@ class AgentStepExecutor:
|
|
|
315
310
|
allowed_step_kinds=allowed_step_kinds,
|
|
316
311
|
)
|
|
317
312
|
|
|
318
|
-
with
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
),
|
|
329
|
-
step_context_scope(step_context),
|
|
330
|
-
):
|
|
331
|
-
result = await self._run_agent(
|
|
332
|
-
user_prompt=user_prompt,
|
|
333
|
-
step_context=step_context,
|
|
334
|
-
toolset=toolset,
|
|
335
|
-
structured_output_type=structured_output_type,
|
|
336
|
-
)
|
|
313
|
+
with (
|
|
314
|
+
system_prompt_suffix_fragment_scope(step_system_prompt_fragment),
|
|
315
|
+
step_context_scope(step_context),
|
|
316
|
+
):
|
|
317
|
+
result = await self._run_agent(
|
|
318
|
+
user_prompt=user_prompt,
|
|
319
|
+
step_context=step_context,
|
|
320
|
+
toolset=toolset,
|
|
321
|
+
structured_output_type=structured_output_type,
|
|
322
|
+
)
|
|
337
323
|
|
|
338
324
|
step_outcome = self._parse_agent_result(result)
|
|
339
325
|
bindings = self._extract_bindings(binding_names=binding_names, step_context=step_context)
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
|
-
import uuid
|
|
5
4
|
from collections.abc import Awaitable, Callable, Iterator
|
|
6
5
|
from contextlib import contextmanager
|
|
7
6
|
from typing import Any
|
|
@@ -9,9 +8,11 @@ from typing import Any
|
|
|
9
8
|
from pydantic_ai import RunContext
|
|
10
9
|
from pydantic_ai._instrumentation import InstrumentationNames
|
|
11
10
|
|
|
11
|
+
from ..ulid import generate_ulid
|
|
12
|
+
|
|
12
13
|
|
|
13
14
|
def generate_tool_call_id() -> str:
|
|
14
|
-
return
|
|
15
|
+
return generate_ulid()
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
def _resolve_instrumentation_names(*, run_context: RunContext[Any]) -> InstrumentationNames:
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import time
|
|
5
|
+
|
|
6
|
+
_CROCKFORD = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def generate_ulid() -> str:
|
|
10
|
+
"""Generate a ULID string (timestamp-based, sortable, 26 chars, Crockford Base32)."""
|
|
11
|
+
timestamp_ms = int(time.time() * 1000)
|
|
12
|
+
random_int = int.from_bytes(os.urandom(10))
|
|
13
|
+
chars: list[str] = []
|
|
14
|
+
for shift in (45, 40, 35, 30, 25, 20, 15, 10, 5, 0):
|
|
15
|
+
chars.append(_CROCKFORD[(timestamp_ms >> shift) & 0x1F])
|
|
16
|
+
for shift in (75, 70, 65, 60, 55, 50, 45, 40, 35, 30, 25, 20, 15, 10, 5, 0):
|
|
17
|
+
chars.append(_CROCKFORD[(random_int >> shift) & 0x1F])
|
|
18
|
+
return "".join(chars)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
import importlib.metadata
|
|
2
3
|
from collections.abc import Generator
|
|
3
4
|
|
|
4
5
|
import pytest
|
|
@@ -26,7 +27,7 @@ def step_span_exporter() -> Generator[InMemorySpanExporter, None, None]:
|
|
|
26
27
|
tracer_provider.add_span_processor(SimpleSpanProcessor(span_exporter))
|
|
27
28
|
|
|
28
29
|
previous_tracer_provider = runtime_scoping._tracer
|
|
29
|
-
runtime_scoping._tracer = tracer_provider.get_tracer("nighthawk")
|
|
30
|
+
runtime_scoping._tracer = tracer_provider.get_tracer("nighthawk", importlib.metadata.version("nighthawk-python"))
|
|
30
31
|
try:
|
|
31
32
|
yield span_exporter
|
|
32
33
|
finally:
|
|
@@ -428,3 +429,43 @@ def test_step_span_failure_event_structure_is_compact(step_span_exporter: InMemo
|
|
|
428
429
|
assert "exception" in exception_event_name_set
|
|
429
430
|
assert "nighthawk.step.failed" in exception_event_name_set
|
|
430
431
|
assert len(step_span.events) == 2
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
def test_run_span_has_only_run_id_attribute(step_span_exporter: InMemorySpanExporter) -> None:
|
|
435
|
+
with nh.run(StubExecutor(), run_id="attr-test"):
|
|
436
|
+
|
|
437
|
+
@nh.natural_function
|
|
438
|
+
def natural_value_function() -> int:
|
|
439
|
+
"""natural
|
|
440
|
+
<:result>
|
|
441
|
+
{"step_outcome": {"kind": "pass"}, "bindings": {"result": 42}}
|
|
442
|
+
"""
|
|
443
|
+
return result # noqa: F821 # pyright: ignore[reportUndefinedVariable]
|
|
444
|
+
|
|
445
|
+
assert natural_value_function() == 42
|
|
446
|
+
|
|
447
|
+
run_span_list = [s for s in step_span_exporter.get_finished_spans() if s.name == "nighthawk.run"]
|
|
448
|
+
assert len(run_span_list) == 1
|
|
449
|
+
run_span = run_span_list[0]
|
|
450
|
+
assert _require_attribute_key_set(run_span) == {"run.id"}
|
|
451
|
+
assert _require_attribute_value(run_span, "run.id") == "attr-test"
|
|
452
|
+
|
|
453
|
+
|
|
454
|
+
def test_no_implicit_scope_or_step_executor_spans(step_span_exporter: InMemorySpanExporter) -> None:
|
|
455
|
+
with nh.run(StubExecutor()):
|
|
456
|
+
|
|
457
|
+
@nh.natural_function
|
|
458
|
+
def natural_value_function() -> int:
|
|
459
|
+
"""natural
|
|
460
|
+
<:result>
|
|
461
|
+
{"step_outcome": {"kind": "pass"}, "bindings": {"result": 7}}
|
|
462
|
+
"""
|
|
463
|
+
return result # noqa: F821 # pyright: ignore[reportUndefinedVariable]
|
|
464
|
+
|
|
465
|
+
assert natural_value_function() == 7
|
|
466
|
+
|
|
467
|
+
span_name_set = {s.name for s in step_span_exporter.get_finished_spans()}
|
|
468
|
+
assert "nighthawk.scope" not in span_name_set
|
|
469
|
+
assert "nighthawk.step_executor" not in span_name_set
|
|
470
|
+
assert "nighthawk.run" in span_name_set
|
|
471
|
+
assert "nighthawk.step" in span_name_set
|
|
@@ -761,7 +761,7 @@ wheels = [
|
|
|
761
761
|
|
|
762
762
|
[[package]]
|
|
763
763
|
name = "nighthawk-python"
|
|
764
|
-
version = "0.
|
|
764
|
+
version = "0.3.1"
|
|
765
765
|
source = { editable = "." }
|
|
766
766
|
dependencies = [
|
|
767
767
|
{ name = "headson" },
|
|
@@ -799,7 +799,7 @@ docs = [
|
|
|
799
799
|
|
|
800
800
|
[package.metadata]
|
|
801
801
|
requires-dist = [
|
|
802
|
-
{ name = "claude-agent-sdk", marker = "extra == 'claude-code-sdk'", specifier = "
|
|
802
|
+
{ name = "claude-agent-sdk", marker = "extra == 'claude-code-sdk'", specifier = "==0.1.48" },
|
|
803
803
|
{ name = "headson", specifier = ">=0.16.1" },
|
|
804
804
|
{ name = "mcp", marker = "extra == 'claude-code-cli'", specifier = ">=1.26" },
|
|
805
805
|
{ name = "mcp", marker = "extra == 'codex'", specifier = ">=1.26" },
|
|
@@ -836,7 +836,7 @@ wheels = [
|
|
|
836
836
|
|
|
837
837
|
[[package]]
|
|
838
838
|
name = "openai"
|
|
839
|
-
version = "2.
|
|
839
|
+
version = "2.29.0"
|
|
840
840
|
source = { registry = "https://pypi.org/simple" }
|
|
841
841
|
dependencies = [
|
|
842
842
|
{ name = "anyio" },
|
|
@@ -848,9 +848,9 @@ dependencies = [
|
|
|
848
848
|
{ name = "tqdm" },
|
|
849
849
|
{ name = "typing-extensions" },
|
|
850
850
|
]
|
|
851
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
851
|
+
sdist = { url = "https://files.pythonhosted.org/packages/b4/15/203d537e58986b5673e7f232453a2a2f110f22757b15921cbdeea392e520/openai-2.29.0.tar.gz", hash = "sha256:32d09eb2f661b38d3edd7d7e1a2943d1633f572596febe64c0cd370c86d52bec", size = 671128, upload-time = "2026-03-17T17:53:49.599Z" }
|
|
852
852
|
wheels = [
|
|
853
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
853
|
+
{ url = "https://files.pythonhosted.org/packages/d0/b1/35b6f9c8cf9318e3dbb7146cc82dab4cf61182a8d5406fc9b50864362895/openai-2.29.0-py3-none-any.whl", hash = "sha256:b7c5de513c3286d17c5e29b92c4c98ceaf0d775244ac8159aeb1bddf840eb42a", size = 1141533, upload-time = "2026-03-17T17:53:47.348Z" },
|
|
854
854
|
]
|
|
855
855
|
|
|
856
856
|
[[package]]
|
|
@@ -997,17 +997,17 @@ wheels = [
|
|
|
997
997
|
|
|
998
998
|
[[package]]
|
|
999
999
|
name = "protobuf"
|
|
1000
|
-
version = "6.33.
|
|
1000
|
+
version = "6.33.6"
|
|
1001
1001
|
source = { registry = "https://pypi.org/simple" }
|
|
1002
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
1002
|
+
sdist = { url = "https://files.pythonhosted.org/packages/66/70/e908e9c5e52ef7c3a6c7902c9dfbb34c7e29c25d2f81ade3856445fd5c94/protobuf-6.33.6.tar.gz", hash = "sha256:a6768d25248312c297558af96a9f9c929e8c4cee0659cb07e780731095f38135", size = 444531, upload-time = "2026-03-18T19:05:00.988Z" }
|
|
1003
1003
|
wheels = [
|
|
1004
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1005
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1006
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1007
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1008
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1009
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1010
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1004
|
+
{ url = "https://files.pythonhosted.org/packages/fc/9f/2f509339e89cfa6f6a4c4ff50438db9ca488dec341f7e454adad60150b00/protobuf-6.33.6-cp310-abi3-win32.whl", hash = "sha256:7d29d9b65f8afef196f8334e80d6bc1d5d4adedb449971fefd3723824e6e77d3", size = 425739, upload-time = "2026-03-18T19:04:48.373Z" },
|
|
1005
|
+
{ url = "https://files.pythonhosted.org/packages/76/5d/683efcd4798e0030c1bab27374fd13a89f7c2515fb1f3123efdfaa5eab57/protobuf-6.33.6-cp310-abi3-win_amd64.whl", hash = "sha256:0cd27b587afca21b7cfa59a74dcbd48a50f0a6400cfb59391340ad729d91d326", size = 437089, upload-time = "2026-03-18T19:04:50.381Z" },
|
|
1006
|
+
{ url = "https://files.pythonhosted.org/packages/5c/01/a3c3ed5cd186f39e7880f8303cc51385a198a81469d53d0fdecf1f64d929/protobuf-6.33.6-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:9720e6961b251bde64edfdab7d500725a2af5280f3f4c87e57c0208376aa8c3a", size = 427737, upload-time = "2026-03-18T19:04:51.866Z" },
|
|
1007
|
+
{ url = "https://files.pythonhosted.org/packages/ee/90/b3c01fdec7d2f627b3a6884243ba328c1217ed2d978def5c12dc50d328a3/protobuf-6.33.6-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:e2afbae9b8e1825e3529f88d514754e094278bb95eadc0e199751cdd9a2e82a2", size = 324610, upload-time = "2026-03-18T19:04:53.096Z" },
|
|
1008
|
+
{ url = "https://files.pythonhosted.org/packages/9b/ca/25afc144934014700c52e05103c2421997482d561f3101ff352e1292fb81/protobuf-6.33.6-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:c96c37eec15086b79762ed265d59ab204dabc53056e3443e702d2681f4b39ce3", size = 339381, upload-time = "2026-03-18T19:04:54.616Z" },
|
|
1009
|
+
{ url = "https://files.pythonhosted.org/packages/16/92/d1e32e3e0d894fe00b15ce28ad4944ab692713f2e7f0a99787405e43533a/protobuf-6.33.6-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:e9db7e292e0ab79dd108d7f1a94fe31601ce1ee3f7b79e0692043423020b0593", size = 323436, upload-time = "2026-03-18T19:04:55.768Z" },
|
|
1010
|
+
{ url = "https://files.pythonhosted.org/packages/c4/72/02445137af02769918a93807b2b7890047c32bfb9f90371cbc12688819eb/protobuf-6.33.6-py3-none-any.whl", hash = "sha256:77179e006c476e69bf8e8ce866640091ec42e1beb80b213c3900006ecfba6901", size = 170656, upload-time = "2026-03-18T19:04:59.826Z" },
|
|
1011
1011
|
]
|
|
1012
1012
|
|
|
1013
1013
|
[[package]]
|
|
@@ -1036,7 +1036,7 @@ wheels = [
|
|
|
1036
1036
|
|
|
1037
1037
|
[[package]]
|
|
1038
1038
|
name = "pydantic-ai-slim"
|
|
1039
|
-
version = "1.
|
|
1039
|
+
version = "1.70.0"
|
|
1040
1040
|
source = { registry = "https://pypi.org/simple" }
|
|
1041
1041
|
dependencies = [
|
|
1042
1042
|
{ name = "genai-prices" },
|
|
@@ -1047,9 +1047,9 @@ dependencies = [
|
|
|
1047
1047
|
{ name = "pydantic-graph" },
|
|
1048
1048
|
{ name = "typing-inspection" },
|
|
1049
1049
|
]
|
|
1050
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
1050
|
+
sdist = { url = "https://files.pythonhosted.org/packages/ac/97/d57ee44976c349658ea7c645c5c2e1a26830e4b60fdeeee2669d4aaef6eb/pydantic_ai_slim-1.70.0.tar.gz", hash = "sha256:3df0c0e92f72c35e546d24795bce1f4d38f81da2d10addd2e9f255b2d2c83c91", size = 445474, upload-time = "2026-03-18T04:24:34.393Z" }
|
|
1051
1051
|
wheels = [
|
|
1052
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1052
|
+
{ url = "https://files.pythonhosted.org/packages/da/8c/8545d28d0b3a9957aa21393cfdab8280bb854362360b296cd486ed1713ec/pydantic_ai_slim-1.70.0-py3-none-any.whl", hash = "sha256:162907092a562b3160d9ef0418d317ec941c5c0e6dd6e0aa0dbb53b5a5cd3450", size = 576244, upload-time = "2026-03-18T04:24:27.301Z" },
|
|
1053
1053
|
]
|
|
1054
1054
|
|
|
1055
1055
|
[package.optional-dependencies]
|
|
@@ -1113,7 +1113,7 @@ wheels = [
|
|
|
1113
1113
|
|
|
1114
1114
|
[[package]]
|
|
1115
1115
|
name = "pydantic-graph"
|
|
1116
|
-
version = "1.
|
|
1116
|
+
version = "1.70.0"
|
|
1117
1117
|
source = { registry = "https://pypi.org/simple" }
|
|
1118
1118
|
dependencies = [
|
|
1119
1119
|
{ name = "httpx" },
|
|
@@ -1121,9 +1121,9 @@ dependencies = [
|
|
|
1121
1121
|
{ name = "pydantic" },
|
|
1122
1122
|
{ name = "typing-inspection" },
|
|
1123
1123
|
]
|
|
1124
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
1124
|
+
sdist = { url = "https://files.pythonhosted.org/packages/07/27/f7a71ca2a3705e7c24fd777959cf5515646cc5f23b5b16c886a2ed373340/pydantic_graph-1.70.0.tar.gz", hash = "sha256:3f76d9137369ef8748b0e8a6df1a08262118af20a32bc139d23e5c0509c6b711", size = 58578, upload-time = "2026-03-18T04:24:37.007Z" }
|
|
1125
1125
|
wheels = [
|
|
1126
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1126
|
+
{ url = "https://files.pythonhosted.org/packages/38/fd/19c42b60c37dfdbbf5b76c7b218e8309b43dac501f7aaf2025527ca05023/pydantic_graph-1.70.0-py3-none-any.whl", hash = "sha256:6083c1503a2587990ee1b8a15915106e3ddabc8f3f11fbc4a108a7d7496af4a5", size = 72351, upload-time = "2026-03-18T04:24:30.291Z" },
|
|
1127
1127
|
]
|
|
1128
1128
|
|
|
1129
1129
|
[[package]]
|
|
@@ -1532,15 +1532,15 @@ wheels = [
|
|
|
1532
1532
|
|
|
1533
1533
|
[[package]]
|
|
1534
1534
|
name = "sse-starlette"
|
|
1535
|
-
version = "3.3.
|
|
1535
|
+
version = "3.3.3"
|
|
1536
1536
|
source = { registry = "https://pypi.org/simple" }
|
|
1537
1537
|
dependencies = [
|
|
1538
1538
|
{ name = "anyio" },
|
|
1539
1539
|
{ name = "starlette" },
|
|
1540
1540
|
]
|
|
1541
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
1541
|
+
sdist = { url = "https://files.pythonhosted.org/packages/14/2f/9223c24f568bb7a0c03d751e609844dce0968f13b39a3f73fbb3a96cd27a/sse_starlette-3.3.3.tar.gz", hash = "sha256:72a95d7575fd5129bd0ae15275ac6432bb35ac542fdebb82889c24bb9f3f4049", size = 32420, upload-time = "2026-03-17T20:05:55.529Z" }
|
|
1542
1542
|
wheels = [
|
|
1543
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1543
|
+
{ url = "https://files.pythonhosted.org/packages/78/e2/b8cff57a67dddf9a464d7e943218e031617fb3ddc133aeeb0602ff5f6c85/sse_starlette-3.3.3-py3-none-any.whl", hash = "sha256:c5abb5082a1cc1c6294d89c5290c46b5f67808cfdb612b7ec27e8ba061c22e8d", size = 14329, upload-time = "2026-03-17T20:05:54.35Z" },
|
|
1544
1544
|
]
|
|
1545
1545
|
|
|
1546
1546
|
[[package]]
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to this project will be documented in this file.
|
|
4
|
-
|
|
5
|
-
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
-
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
-
|
|
8
|
-
## [Unreleased]
|
|
9
|
-
|
|
10
|
-
## [0.2.0] - 2026-03-16
|
|
11
|
-
|
|
12
|
-
### Added
|
|
13
|
-
- Added compact step trace support for Natural block execution attempts:
|
|
14
|
-
- `StepTrace`
|
|
15
|
-
- `StepTraceError`
|
|
16
|
-
- `nighthawk.get_step_traces()`
|
|
17
|
-
|
|
18
|
-
### Changed
|
|
19
|
-
- Updated CI workflow setup (`setup-uv`) in project automation.
|
|
20
|
-
|
|
21
|
-
### Fixed
|
|
22
|
-
- License badge reference in README.
|
|
23
|
-
- Documentation formatting inconsistencies.
|
|
24
|
-
|
|
25
|
-
## [0.1.0] - 2026-03-13
|
|
26
|
-
|
|
27
|
-
### Added
|
|
28
|
-
- Initial public release of `nighthawk-python`.
|
|
29
|
-
- Natural DSL execution runtime with run/scope execution context model.
|
|
30
|
-
- Step executor abstraction and provider integration foundation.
|
|
31
|
-
- Core documentation and project scaffolding.
|
|
32
|
-
|
|
33
|
-
[Unreleased]: https://github.com/kurusugawa-computer/nighthawk-python/compare/v0.2.0...HEAD
|
|
34
|
-
[0.2.0]: https://github.com/kurusugawa-computer/nighthawk-python/compare/v0.1.0...v0.2.0
|
|
35
|
-
[0.1.0]: https://github.com/kurusugawa-computer/nighthawk-python/tree/v0.1.0
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/execution/test_natural_block_ordering.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nighthawk_python-0.2.0 → nighthawk_python-0.3.1}/tests/integration/test_codex_integration.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|