nighthawk-python 0.8.0__py3-none-any.whl → 0.9.0__py3-none-any.whl
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/__init__.py +0 -2
- nighthawk/configuration.py +0 -41
- nighthawk/runtime/scoping.py +42 -47
- {nighthawk_python-0.8.0.dist-info → nighthawk_python-0.9.0.dist-info}/METADATA +1 -1
- {nighthawk_python-0.8.0.dist-info → nighthawk_python-0.9.0.dist-info}/RECORD +7 -7
- {nighthawk_python-0.8.0.dist-info → nighthawk_python-0.9.0.dist-info}/WHEEL +0 -0
- {nighthawk_python-0.8.0.dist-info → nighthawk_python-0.9.0.dist-info}/licenses/LICENSE +0 -0
nighthawk/__init__.py
CHANGED
|
@@ -3,7 +3,6 @@ from __future__ import annotations
|
|
|
3
3
|
from .configuration import (
|
|
4
4
|
StepContextLimits,
|
|
5
5
|
StepExecutorConfiguration,
|
|
6
|
-
StepExecutorConfigurationPatch,
|
|
7
6
|
StepPromptTemplates,
|
|
8
7
|
)
|
|
9
8
|
from .errors import (
|
|
@@ -32,7 +31,6 @@ __all__ = [
|
|
|
32
31
|
"StepContextLimits",
|
|
33
32
|
"StepExecutor",
|
|
34
33
|
"StepExecutorConfiguration",
|
|
35
|
-
"StepExecutorConfigurationPatch",
|
|
36
34
|
"StepPromptTemplates",
|
|
37
35
|
"ToolEvaluationError",
|
|
38
36
|
"ToolRegistrationError",
|
nighthawk/configuration.py
CHANGED
|
@@ -160,44 +160,3 @@ class StepExecutorConfiguration(BaseModel):
|
|
|
160
160
|
return tiktoken.encoding_for_model(model_name)
|
|
161
161
|
except Exception:
|
|
162
162
|
return tiktoken.get_encoding("o200k_base")
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
class StepExecutorConfigurationPatch(BaseModel):
|
|
166
|
-
"""Partial override for StepExecutorConfiguration.
|
|
167
|
-
|
|
168
|
-
Non-None fields replace the corresponding fields in the target configuration.
|
|
169
|
-
|
|
170
|
-
Attributes:
|
|
171
|
-
model: Model identifier override.
|
|
172
|
-
model_settings: Model settings override. Accepts a dict or a
|
|
173
|
-
backend-specific BaseModel instance (auto-converted to dict).
|
|
174
|
-
prompts: Prompt templates override.
|
|
175
|
-
context_limits: Context limits override.
|
|
176
|
-
json_renderer_style: JSON renderer style override.
|
|
177
|
-
tokenizer_encoding: Tokenizer encoding override.
|
|
178
|
-
system_prompt_suffix_fragments: System prompt suffix fragments override.
|
|
179
|
-
user_prompt_suffix_fragments: User prompt suffix fragments override.
|
|
180
|
-
"""
|
|
181
|
-
|
|
182
|
-
model_config = ConfigDict(extra="forbid", frozen=True)
|
|
183
|
-
|
|
184
|
-
model: str | None = None
|
|
185
|
-
model_settings: dict[str, Any] | BaseModel | None = None
|
|
186
|
-
|
|
187
|
-
@field_validator("model_settings", mode="before")
|
|
188
|
-
@classmethod
|
|
189
|
-
def _normalize_model_settings(cls, value: Any) -> dict[str, Any] | None:
|
|
190
|
-
if isinstance(value, BaseModel):
|
|
191
|
-
return value.model_dump()
|
|
192
|
-
return value
|
|
193
|
-
|
|
194
|
-
prompts: StepPromptTemplates | None = None
|
|
195
|
-
context_limits: StepContextLimits | None = None
|
|
196
|
-
json_renderer_style: JsonRendererStyle | None = None
|
|
197
|
-
tokenizer_encoding: str | None = None
|
|
198
|
-
system_prompt_suffix_fragments: tuple[str, ...] | None = None
|
|
199
|
-
user_prompt_suffix_fragments: tuple[str, ...] | None = None
|
|
200
|
-
|
|
201
|
-
def apply_to(self, configuration: StepExecutorConfiguration) -> StepExecutorConfiguration:
|
|
202
|
-
"""Apply non-None fields to the given configuration and return a new copy."""
|
|
203
|
-
return configuration.model_copy(update=self.model_dump(exclude_none=True))
|
nighthawk/runtime/scoping.py
CHANGED
|
@@ -2,17 +2,17 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import importlib.metadata
|
|
4
4
|
import threading
|
|
5
|
-
from collections.abc import Iterator, Mapping
|
|
5
|
+
from collections.abc import Iterator, Mapping, Sequence
|
|
6
6
|
from contextlib import contextmanager
|
|
7
7
|
from contextvars import ContextVar
|
|
8
8
|
from copy import copy
|
|
9
9
|
from dataclasses import dataclass, replace
|
|
10
|
-
from typing import TYPE_CHECKING, Any
|
|
10
|
+
from typing import TYPE_CHECKING, Any, Literal
|
|
11
11
|
|
|
12
12
|
from opentelemetry.trace import Span, get_tracer_provider
|
|
13
13
|
from pydantic_ai.usage import RunUsage
|
|
14
14
|
|
|
15
|
-
from ..configuration import StepExecutorConfiguration
|
|
15
|
+
from ..configuration import StepExecutorConfiguration
|
|
16
16
|
from ..errors import NighthawkError
|
|
17
17
|
from ..tools.registry import tool_scope
|
|
18
18
|
from ..ulid import generate_ulid
|
|
@@ -295,24 +295,28 @@ def run(
|
|
|
295
295
|
@contextmanager
|
|
296
296
|
def scope(
|
|
297
297
|
*,
|
|
298
|
+
mode: Literal["inherit", "replace"] = "inherit",
|
|
298
299
|
step_executor_configuration: StepExecutorConfiguration | None = None,
|
|
299
|
-
step_executor_configuration_patch: StepExecutorConfigurationPatch | None = None,
|
|
300
300
|
step_executor: StepExecutor | None = None,
|
|
301
|
-
|
|
302
|
-
|
|
301
|
+
system_prompt_suffix_fragments: Sequence[str] | None = None,
|
|
302
|
+
user_prompt_suffix_fragments: Sequence[str] | None = None,
|
|
303
303
|
implicit_references: ImplicitReferenceNameToValue | None = None,
|
|
304
304
|
) -> Iterator[StepExecutor]:
|
|
305
|
-
"""Open a nested scope that can override the
|
|
305
|
+
"""Open a nested scope that can override the active execution context.
|
|
306
306
|
|
|
307
|
-
Must be called inside an active run context. Creates a new scope_id while inheriting the run_id from the parent context.
|
|
307
|
+
Must be called inside an active run context. Creates a new ``scope_id`` while inheriting the ``run_id`` from the parent context.
|
|
308
308
|
|
|
309
309
|
Args:
|
|
310
|
+
mode: Scope composition mode. ``"inherit"`` appends/merges values into the current scope. ``"replace"`` fully replaces provided list/dict values.
|
|
311
|
+
In both modes, ``None`` means no change.
|
|
310
312
|
step_executor_configuration: Full replacement configuration for the step executor.
|
|
311
|
-
step_executor_configuration_patch: Partial override applied on top of the current configuration.
|
|
312
313
|
step_executor: Replacement step executor for this scope.
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
314
|
+
system_prompt_suffix_fragments: Additional system prompt suffix fragments.
|
|
315
|
+
In ``mode="inherit"``, fragments are appended. In ``mode="replace"``, provided fragments fully replace the current fragments.
|
|
316
|
+
user_prompt_suffix_fragments: Additional user prompt suffix fragments.
|
|
317
|
+
In ``mode="inherit"``, fragments are appended. In ``mode="replace"``, provided fragments fully replace the current fragments.
|
|
318
|
+
implicit_references: Implicit global references for this scope.
|
|
319
|
+
In ``mode="inherit"``, values are merged with conflict checks. In ``mode="replace"``, provided mappings fully replace the current mapping.
|
|
316
320
|
|
|
317
321
|
Yields:
|
|
318
322
|
The step executor active within this scope.
|
|
@@ -321,9 +325,9 @@ def scope(
|
|
|
321
325
|
```python
|
|
322
326
|
with nighthawk.run(executor):
|
|
323
327
|
with nighthawk.scope(
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
328
|
+
mode="replace",
|
|
329
|
+
implicit_references={},
|
|
330
|
+
system_prompt_suffix_fragments=["Use concise answers."],
|
|
327
331
|
) as scoped_executor:
|
|
328
332
|
result = my_natural_function()
|
|
329
333
|
```
|
|
@@ -332,31 +336,13 @@ def scope(
|
|
|
332
336
|
current_execution_context = get_execution_context()
|
|
333
337
|
|
|
334
338
|
next_step_executor = current_step_executor
|
|
335
|
-
|
|
336
339
|
if step_executor is not None:
|
|
337
340
|
next_step_executor = step_executor
|
|
338
341
|
|
|
339
|
-
|
|
340
|
-
value is not None
|
|
341
|
-
for value in (
|
|
342
|
-
step_executor_configuration,
|
|
343
|
-
step_executor_configuration_patch,
|
|
344
|
-
)
|
|
345
|
-
)
|
|
346
|
-
|
|
347
|
-
if has_configuration_update:
|
|
348
|
-
current_agent_step_executor = _resolve_agent_step_executor(next_step_executor)
|
|
349
|
-
next_configuration = current_agent_step_executor.configuration
|
|
350
|
-
|
|
351
|
-
if step_executor_configuration is not None:
|
|
352
|
-
next_configuration = step_executor_configuration
|
|
353
|
-
|
|
354
|
-
if step_executor_configuration_patch is not None:
|
|
355
|
-
next_configuration = step_executor_configuration_patch.apply_to(next_configuration)
|
|
356
|
-
|
|
342
|
+
if step_executor_configuration is not None:
|
|
357
343
|
next_step_executor = _replace_step_executor_with_configuration(
|
|
358
344
|
next_step_executor,
|
|
359
|
-
configuration=
|
|
345
|
+
configuration=step_executor_configuration,
|
|
360
346
|
)
|
|
361
347
|
|
|
362
348
|
next_execution_context = replace(
|
|
@@ -364,27 +350,36 @@ def scope(
|
|
|
364
350
|
scope_id=generate_ulid(),
|
|
365
351
|
)
|
|
366
352
|
|
|
367
|
-
|
|
368
|
-
|
|
353
|
+
next_system_prompt_suffix_fragments = _system_prompt_suffix_fragments_var.get()
|
|
354
|
+
next_user_prompt_suffix_fragments = _user_prompt_suffix_fragments_var.get()
|
|
369
355
|
next_implicit_reference_name_to_value = _implicit_reference_name_to_value_var.get()
|
|
370
356
|
|
|
371
|
-
if
|
|
372
|
-
|
|
357
|
+
if system_prompt_suffix_fragments is not None:
|
|
358
|
+
if mode == "inherit":
|
|
359
|
+
next_system_prompt_suffix_fragments = (*next_system_prompt_suffix_fragments, *system_prompt_suffix_fragments)
|
|
360
|
+
else:
|
|
361
|
+
next_system_prompt_suffix_fragments = tuple(system_prompt_suffix_fragments)
|
|
373
362
|
|
|
374
|
-
if
|
|
375
|
-
|
|
363
|
+
if user_prompt_suffix_fragments is not None:
|
|
364
|
+
if mode == "inherit":
|
|
365
|
+
next_user_prompt_suffix_fragments = (*next_user_prompt_suffix_fragments, *user_prompt_suffix_fragments)
|
|
366
|
+
else:
|
|
367
|
+
next_user_prompt_suffix_fragments = tuple(user_prompt_suffix_fragments)
|
|
376
368
|
|
|
377
369
|
if implicit_references is not None:
|
|
378
|
-
|
|
379
|
-
next_implicit_reference_name_to_value
|
|
380
|
-
|
|
381
|
-
|
|
370
|
+
if mode == "inherit":
|
|
371
|
+
next_implicit_reference_name_to_value = _merge_implicit_reference_name_to_value_with_conflict_check(
|
|
372
|
+
next_implicit_reference_name_to_value,
|
|
373
|
+
implicit_references,
|
|
374
|
+
)
|
|
375
|
+
else:
|
|
376
|
+
next_implicit_reference_name_to_value = dict(implicit_references)
|
|
382
377
|
|
|
383
378
|
with tool_scope():
|
|
384
379
|
step_executor_token = _step_executor_var.set(next_step_executor)
|
|
385
380
|
execution_context_token = _execution_context_var.set(next_execution_context)
|
|
386
|
-
system_fragments_token = _system_prompt_suffix_fragments_var.set(
|
|
387
|
-
user_fragments_token = _user_prompt_suffix_fragments_var.set(
|
|
381
|
+
system_fragments_token = _system_prompt_suffix_fragments_var.set(next_system_prompt_suffix_fragments)
|
|
382
|
+
user_fragments_token = _user_prompt_suffix_fragments_var.set(next_user_prompt_suffix_fragments)
|
|
388
383
|
implicit_reference_name_to_value_token = _implicit_reference_name_to_value_var.set(next_implicit_reference_name_to_value)
|
|
389
384
|
try:
|
|
390
385
|
with span(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nighthawk-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.0
|
|
4
4
|
Summary: A Python library where Python controls flow and LLMs or coding agents reason within constrained Natural blocks.
|
|
5
5
|
Project-URL: Repository, https://github.com/kurusugawa-computer/nighthawk-python
|
|
6
6
|
Project-URL: Documentation, https://kurusugawa-computer.github.io/nighthawk-python/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
nighthawk/__init__.py,sha256=
|
|
2
|
-
nighthawk/configuration.py,sha256=
|
|
1
|
+
nighthawk/__init__.py,sha256=YqE9InkNzbW12v9Bh3qF4INLUHfJfmNT_hPqmE_kNb8,1308
|
|
2
|
+
nighthawk/configuration.py,sha256=1gtdLxcDMMnvz9t2fBZP-U-MHW54IHWmInSPiByTaGo,6286
|
|
3
3
|
nighthawk/errors.py,sha256=CSw_VfIoppCE2SdN2zMtVbMGu_wFwD628v8ZAVxeHIY,602
|
|
4
4
|
nighthawk/identifier_path.py,sha256=Io3VcT8BlxAASHQUSUclrRcCwnRKTtMDPSR1bpaDN6s,984
|
|
5
5
|
nighthawk/json_renderer.py,sha256=ixpUYTsVVKOp-iMdHldw7-6I3JxelXOQD8vK2KVXwbw,7640
|
|
@@ -29,7 +29,7 @@ nighthawk/runtime/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU
|
|
|
29
29
|
nighthawk/runtime/async_bridge.py,sha256=k1s7e5dJEMNZJd0xHqkqAY7VkE7tOBzJf6nAEJH_Xh0,1478
|
|
30
30
|
nighthawk/runtime/prompt.py,sha256=fod1f8wS2xKoc3RM44eB8wrKwPmap9K1gwLw4EzUSP4,22669
|
|
31
31
|
nighthawk/runtime/runner.py,sha256=saVkEeMkVfz1cm_AVaz8I23Y5OiWuWthqwv-z_4kwwY,23121
|
|
32
|
-
nighthawk/runtime/scoping.py,sha256=
|
|
32
|
+
nighthawk/runtime/scoping.py,sha256=oa3SqjxctFQtTTZNYFj-scvf5Q0_zaVtluh8V1h8pqE,14986
|
|
33
33
|
nighthawk/runtime/step_context.py,sha256=-MafRMUV9fo0IBTGnQfAF72IyQy90ZoUS9SK77OVgPc,5529
|
|
34
34
|
nighthawk/runtime/step_contract.py,sha256=2rbZpUBbmWGTogAksYerIAZfv2xgBgaNmidWxjJtfmY,6391
|
|
35
35
|
nighthawk/runtime/step_executor.py,sha256=Y4P7PuGzJT64FIwjhU2gABxoqHf6wPTXMiSFTSfkK6U,12847
|
|
@@ -40,7 +40,7 @@ nighthawk/tools/contracts.py,sha256=9bFj88GiRqwyUSfjhZxY3jhtQafdBP3RvDSz6-QCYPs,
|
|
|
40
40
|
nighthawk/tools/execution.py,sha256=e1uv09MWOkCoZ5uQu9myUXyhQzM_UziR9yE0raFYtQI,2740
|
|
41
41
|
nighthawk/tools/provided.py,sha256=gsZ7xcrNmEmwcvdkQi4YndTAIcfpwY1jTxpKJsYU4QQ,2079
|
|
42
42
|
nighthawk/tools/registry.py,sha256=wsZznwI2xPTflN6tfVE8je5keNVqBHHtTPd9bq0Cu7g,6425
|
|
43
|
-
nighthawk_python-0.
|
|
44
|
-
nighthawk_python-0.
|
|
45
|
-
nighthawk_python-0.
|
|
46
|
-
nighthawk_python-0.
|
|
43
|
+
nighthawk_python-0.9.0.dist-info/METADATA,sha256=DIyU5rb7e0BvfBfC7hbiw8vc8SIeDQRapJ1XTM0gDg0,6192
|
|
44
|
+
nighthawk_python-0.9.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
45
|
+
nighthawk_python-0.9.0.dist-info/licenses/LICENSE,sha256=R8tjrX79o5Pbi_l_aFPPWDbTZkmz4is0CxmzMMs3f0A,1076
|
|
46
|
+
nighthawk_python-0.9.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|