Skip to content

Commit bfeeb49

Browse files
committed
Release v0.3.1
1 parent 52eedd0 commit bfeeb49

7 files changed

Lines changed: 63 additions & 37 deletions

File tree

CHANGELOG.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

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+
1018
## [0.3.0] - 2026-03-18
1119

1220
### Added
@@ -41,7 +49,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4149
- Step executor abstraction and provider integration foundation.
4250
- Core documentation and project scaffolding.
4351

44-
[Unreleased]: https://github.com/kurusugawa-computer/nighthawk-python/compare/v0.3.0...HEAD
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
4554
[0.3.0]: https://github.com/kurusugawa-computer/nighthawk-python/compare/v0.2.0...v0.3.0
4655
[0.2.0]: https://github.com/kurusugawa-computer/nighthawk-python/compare/v0.1.0...v0.2.0
4756
[0.1.0]: https://github.com/kurusugawa-computer/nighthawk-python/tree/v0.1.0

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ def run(
148148
149149
Args:
150150
step_executor: The step executor to use for Natural block execution.
151-
run_id: Optional identifier for the run. If not provided, a UUID is
151+
run_id: Optional identifier for the run. If not provided, a ULID is
152152
generated automatically.
153153
154154
Yields:

pyproject.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "nighthawk-python"
3-
version = "0.3.0"
3+
version = "0.3.1"
44
description = "An experimental Python library that embeds Natural blocks inside Python functions and executes them using an LLM."
55
readme = "README.md"
66
requires-python = ">=3.13"
@@ -32,11 +32,12 @@ dependencies = [
3232
[project.urls]
3333
Repository = "https://github.com/kurusugawa-computer/nighthawk-python"
3434
Documentation = "https://kurusugawa-computer.github.io/nighthawk-python/"
35+
Changelog = "https://github.com/kurusugawa-computer/nighthawk-python/blob/main/CHANGELOG.md"
3536
"Bug Tracker" = "https://github.com/kurusugawa-computer/nighthawk-python/issues"
3637

3738
[project.optional-dependencies]
3839
claude-code-sdk = [
39-
"claude-agent-sdk>=0.1",
40+
"claude-agent-sdk==0.1.48",
4041
]
4142
claude-code-cli = [
4243
"mcp>=1.26",

src/nighthawk/runtime/scoping.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from __future__ import annotations
22

33
import importlib.metadata
4-
import uuid
54
from collections.abc import Iterator
65
from contextlib import contextmanager
76
from contextvars import ContextVar
@@ -13,6 +12,7 @@
1312
from ..configuration import StepExecutorConfiguration, StepExecutorConfigurationPatch
1413
from ..errors import NighthawkError
1514
from ..tools.registry import tool_scope
15+
from ..ulid import generate_ulid
1616

1717
if TYPE_CHECKING:
1818
from .step_executor import AgentStepExecutor, StepExecutor
@@ -53,9 +53,6 @@ def span(span_name: str, /, **attributes: Any) -> Iterator[Span]:
5353
yield current_span
5454

5555

56-
def _generate_id() -> str:
57-
return uuid.uuid4().hex
58-
5956

6057
_step_executor_var: ContextVar[StepExecutor | None] = ContextVar(
6158
"nighthawk_step_executor",
@@ -172,7 +169,7 @@ def run(
172169
173170
Args:
174171
step_executor: The step executor to use for Natural block execution.
175-
run_id: Optional identifier for the run. If not provided, a UUID is
172+
run_id: Optional identifier for the run. If not provided, a ULID is
176173
generated automatically.
177174
178175
Yields:
@@ -188,8 +185,8 @@ def run(
188185
```
189186
"""
190187
execution_context = ExecutionContext(
191-
run_id=run_id or _generate_id(),
192-
scope_id=_generate_id(),
188+
run_id=run_id or generate_ulid(),
189+
scope_id=generate_ulid(),
193190
)
194191

195192
with tool_scope():
@@ -282,7 +279,7 @@ def scope(
282279

283280
next_execution_context = replace(
284281
current_execution_context,
285-
scope_id=_generate_id(),
282+
scope_id=generate_ulid(),
286283
)
287284

288285
next_system_fragments = _system_prompt_suffix_fragments_var.get()

src/nighthawk/runtime/tool_calls.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
from __future__ import annotations
22

33
import json
4-
import uuid
54
from collections.abc import Awaitable, Callable, Iterator
65
from contextlib import contextmanager
76
from typing import Any
87

98
from pydantic_ai import RunContext
109
from pydantic_ai._instrumentation import InstrumentationNames
1110

11+
from ..ulid import generate_ulid
12+
1213

1314
def generate_tool_call_id() -> str:
14-
return str(uuid.uuid4())
15+
return generate_ulid()
1516

1617

1718
def _resolve_instrumentation_names(*, run_context: RunContext[Any]) -> InstrumentationNames:

src/nighthawk/ulid.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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)

uv.lock

Lines changed: 23 additions & 23 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)