weakincentives 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.
Files changed (73) hide show
  1. weakincentives/__init__.py +67 -0
  2. weakincentives/adapters/__init__.py +37 -0
  3. weakincentives/adapters/_names.py +32 -0
  4. weakincentives/adapters/_provider_protocols.py +69 -0
  5. weakincentives/adapters/_tool_messages.py +80 -0
  6. weakincentives/adapters/core.py +102 -0
  7. weakincentives/adapters/litellm.py +254 -0
  8. weakincentives/adapters/openai.py +254 -0
  9. weakincentives/adapters/shared.py +1021 -0
  10. weakincentives/cli/__init__.py +23 -0
  11. weakincentives/cli/wink.py +58 -0
  12. weakincentives/dbc/__init__.py +412 -0
  13. weakincentives/deadlines.py +58 -0
  14. weakincentives/prompt/__init__.py +105 -0
  15. weakincentives/prompt/_generic_params_specializer.py +64 -0
  16. weakincentives/prompt/_normalization.py +48 -0
  17. weakincentives/prompt/_overrides_protocols.py +33 -0
  18. weakincentives/prompt/_types.py +34 -0
  19. weakincentives/prompt/chapter.py +146 -0
  20. weakincentives/prompt/composition.py +281 -0
  21. weakincentives/prompt/errors.py +57 -0
  22. weakincentives/prompt/markdown.py +108 -0
  23. weakincentives/prompt/overrides/__init__.py +59 -0
  24. weakincentives/prompt/overrides/_fs.py +164 -0
  25. weakincentives/prompt/overrides/inspection.py +141 -0
  26. weakincentives/prompt/overrides/local_store.py +275 -0
  27. weakincentives/prompt/overrides/validation.py +534 -0
  28. weakincentives/prompt/overrides/versioning.py +269 -0
  29. weakincentives/prompt/prompt.py +353 -0
  30. weakincentives/prompt/protocols.py +103 -0
  31. weakincentives/prompt/registry.py +375 -0
  32. weakincentives/prompt/rendering.py +288 -0
  33. weakincentives/prompt/response_format.py +60 -0
  34. weakincentives/prompt/section.py +166 -0
  35. weakincentives/prompt/structured_output.py +179 -0
  36. weakincentives/prompt/tool.py +397 -0
  37. weakincentives/prompt/tool_result.py +30 -0
  38. weakincentives/py.typed +0 -0
  39. weakincentives/runtime/__init__.py +82 -0
  40. weakincentives/runtime/events/__init__.py +126 -0
  41. weakincentives/runtime/events/_types.py +110 -0
  42. weakincentives/runtime/logging.py +284 -0
  43. weakincentives/runtime/session/__init__.py +46 -0
  44. weakincentives/runtime/session/_slice_types.py +24 -0
  45. weakincentives/runtime/session/_types.py +55 -0
  46. weakincentives/runtime/session/dataclasses.py +29 -0
  47. weakincentives/runtime/session/protocols.py +34 -0
  48. weakincentives/runtime/session/reducer_context.py +40 -0
  49. weakincentives/runtime/session/reducers.py +82 -0
  50. weakincentives/runtime/session/selectors.py +56 -0
  51. weakincentives/runtime/session/session.py +387 -0
  52. weakincentives/runtime/session/snapshots.py +310 -0
  53. weakincentives/serde/__init__.py +19 -0
  54. weakincentives/serde/_utils.py +240 -0
  55. weakincentives/serde/dataclass_serde.py +55 -0
  56. weakincentives/serde/dump.py +189 -0
  57. weakincentives/serde/parse.py +417 -0
  58. weakincentives/serde/schema.py +260 -0
  59. weakincentives/tools/__init__.py +154 -0
  60. weakincentives/tools/_context.py +38 -0
  61. weakincentives/tools/asteval.py +853 -0
  62. weakincentives/tools/errors.py +26 -0
  63. weakincentives/tools/planning.py +831 -0
  64. weakincentives/tools/podman.py +1655 -0
  65. weakincentives/tools/subagents.py +346 -0
  66. weakincentives/tools/vfs.py +1390 -0
  67. weakincentives/types/__init__.py +35 -0
  68. weakincentives/types/json.py +45 -0
  69. weakincentives-0.9.0.dist-info/METADATA +775 -0
  70. weakincentives-0.9.0.dist-info/RECORD +73 -0
  71. weakincentives-0.9.0.dist-info/WHEEL +4 -0
  72. weakincentives-0.9.0.dist-info/entry_points.txt +2 -0
  73. weakincentives-0.9.0.dist-info/licenses/LICENSE +201 -0
@@ -0,0 +1,23 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ """Command line interfaces for the weakincentives package."""
14
+
15
+ from __future__ import annotations
16
+
17
+ from . import wink
18
+
19
+ __all__ = ["wink"]
20
+
21
+
22
+ def __dir__() -> list[str]:
23
+ return sorted({*globals().keys(), *(__all__)})
@@ -0,0 +1,58 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ """Command line entry points for the ``wink`` executable."""
14
+
15
+ from __future__ import annotations
16
+
17
+ import argparse
18
+ from collections.abc import Sequence
19
+
20
+ from ..runtime.logging import configure_logging, get_logger
21
+
22
+
23
+ def main(argv: Sequence[str] | None = None) -> int:
24
+ """Run the wink CLI."""
25
+
26
+ parser = _build_parser()
27
+ args = parser.parse_args(list(argv) if argv is not None else None)
28
+
29
+ configure_logging(level=args.log_level, json_mode=args.json_logs)
30
+ logger = get_logger(__name__)
31
+
32
+ logger.info(
33
+ "wink CLI placeholder executed.",
34
+ event="wink.placeholder",
35
+ )
36
+
37
+ return 0
38
+
39
+
40
+ def _build_parser() -> argparse.ArgumentParser:
41
+ parser = argparse.ArgumentParser(
42
+ prog="wink",
43
+ description="Placeholder command line interface for future wink features.",
44
+ )
45
+ _ = parser.add_argument(
46
+ "--log-level",
47
+ choices=("CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG", "NOTSET"),
48
+ default=None,
49
+ help="Override the log level emitted by the CLI.",
50
+ )
51
+ _ = parser.add_argument(
52
+ "--json-logs",
53
+ action=argparse.BooleanOptionalAction,
54
+ default=True,
55
+ help="Emit structured JSON logs (disable with --no-json-logs).",
56
+ )
57
+
58
+ return parser
@@ -0,0 +1,412 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ """Design by contract utilities for :mod:`weakincentives`."""
14
+
15
+ from __future__ import annotations
16
+
17
+ import builtins
18
+ import copy
19
+ import logging
20
+ import os
21
+ from collections.abc import Callable, Iterator, Mapping, Sequence
22
+ from contextlib import ExitStack, contextmanager
23
+ from functools import wraps
24
+ from pathlib import Path
25
+ from typing import ParamSpec, TypeVar, cast
26
+
27
+ from ..types import ContractResult
28
+
29
+ P = ParamSpec("P")
30
+ Q = ParamSpec("Q")
31
+ R = TypeVar("R")
32
+ S = TypeVar("S")
33
+ T = TypeVar("T", bound=object)
34
+
35
+ ContractCallable = Callable[..., ContractResult | object]
36
+
37
+ _ENV_FLAG = "WEAKINCENTIVES_DBC"
38
+ _forced_state: bool | None = None
39
+
40
+
41
+ def _coerce_flag(value: str | None) -> bool:
42
+ if value is None:
43
+ return False
44
+ lowered = value.strip().lower()
45
+ return lowered not in {"", "0", "false", "off", "no"}
46
+
47
+
48
+ def dbc_active() -> bool:
49
+ """Return ``True`` when DbC checks should run."""
50
+
51
+ if _forced_state is not None:
52
+ return _forced_state
53
+ return _coerce_flag(os.getenv(_ENV_FLAG))
54
+
55
+
56
+ def _qualname(target: object) -> str:
57
+ return getattr(target, "__qualname__", repr(target))
58
+
59
+
60
+ def enable_dbc() -> None:
61
+ """Force DbC enforcement on."""
62
+
63
+ global _forced_state
64
+ _forced_state = True
65
+
66
+
67
+ def disable_dbc() -> None:
68
+ """Force DbC enforcement off."""
69
+
70
+ global _forced_state
71
+ _forced_state = False
72
+
73
+
74
+ @contextmanager
75
+ def dbc_enabled(active: bool = True) -> Iterator[None]:
76
+ """Temporarily set the DbC flag inside a ``with`` block."""
77
+
78
+ global _forced_state
79
+ previous = _forced_state
80
+ _forced_state = active
81
+ try:
82
+ yield
83
+ finally:
84
+ _forced_state = previous
85
+
86
+
87
+ def _normalize_contract_result(
88
+ result: ContractResult | object,
89
+ ) -> tuple[bool, str | None]:
90
+ if isinstance(result, tuple):
91
+ sequence_result = cast(Sequence[object], result)
92
+ if not sequence_result:
93
+ msg = "Contract callables must not return empty tuples"
94
+ raise TypeError(msg)
95
+ outcome = bool(sequence_result[0])
96
+ message = None if len(sequence_result) == 1 else str(sequence_result[1])
97
+ return outcome, message
98
+ if isinstance(result, bool):
99
+ return result, None
100
+ if result is None:
101
+ return False, None
102
+ return bool(result), None
103
+
104
+
105
+ def _contract_failure_message(
106
+ *,
107
+ kind: str,
108
+ func: Callable[..., object],
109
+ predicate: ContractCallable,
110
+ args: tuple[object, ...],
111
+ kwargs: Mapping[str, object],
112
+ detail: str | None,
113
+ ) -> str:
114
+ predicate_name = getattr(predicate, "__name__", repr(predicate))
115
+ base = (
116
+ f"{kind} contract for {_qualname(func)} failed via {predicate_name}."
117
+ f" Args={args!r} Kwargs={kwargs!r}"
118
+ )
119
+ if detail:
120
+ return f"{base} Details: {detail}"
121
+ return base
122
+
123
+
124
+ def _evaluate_contract(
125
+ *,
126
+ kind: str,
127
+ func: Callable[..., object],
128
+ predicate: ContractCallable,
129
+ args: tuple[object, ...],
130
+ kwargs: Mapping[str, object],
131
+ ) -> None:
132
+ try:
133
+ result = predicate(*args, **kwargs)
134
+ except AssertionError:
135
+ raise
136
+ except Exception as exc: # pragma: no cover - diagnostics are important
137
+ msg = (
138
+ f"{kind} contract for {_qualname(func)} raised {type(exc).__name__}: {exc}"
139
+ )
140
+ raise AssertionError(msg) from exc
141
+ outcome, detail = _normalize_contract_result(result)
142
+ if not outcome:
143
+ raise AssertionError(
144
+ _contract_failure_message(
145
+ kind=kind,
146
+ func=func,
147
+ predicate=predicate,
148
+ args=args,
149
+ kwargs=kwargs,
150
+ detail=detail,
151
+ )
152
+ )
153
+
154
+
155
+ def require(
156
+ *predicates: ContractCallable,
157
+ ) -> Callable[[Callable[P, R]], Callable[P, R]]:
158
+ """Validate preconditions before invoking the wrapped callable."""
159
+
160
+ if not predicates:
161
+ msg = "@require expects at least one predicate"
162
+ raise ValueError(msg)
163
+
164
+ def decorator(func: Callable[P, R]) -> Callable[P, R]:
165
+ @wraps(func)
166
+ def wrapped(*args: P.args, **kwargs: P.kwargs) -> R:
167
+ if dbc_active():
168
+ for predicate in predicates:
169
+ _evaluate_contract(
170
+ kind="require",
171
+ func=func,
172
+ predicate=predicate,
173
+ args=tuple(args),
174
+ kwargs=dict(kwargs),
175
+ )
176
+ return func(*args, **kwargs)
177
+
178
+ return wrapped
179
+
180
+ return decorator
181
+
182
+
183
+ def ensure(*predicates: ContractCallable) -> Callable[[Callable[P, R]], Callable[P, R]]:
184
+ """Validate postconditions once the callable returns or raises."""
185
+
186
+ if not predicates:
187
+ msg = "@ensure expects at least one predicate"
188
+ raise ValueError(msg)
189
+
190
+ def decorator(func: Callable[P, R]) -> Callable[P, R]:
191
+ @wraps(func)
192
+ def wrapped(*args: P.args, **kwargs: P.kwargs) -> R:
193
+ if not dbc_active():
194
+ return func(*args, **kwargs)
195
+
196
+ try:
197
+ result = func(*args, **kwargs)
198
+ except BaseException as exc:
199
+ for predicate in predicates:
200
+ _evaluate_contract(
201
+ kind="ensure",
202
+ func=func,
203
+ predicate=predicate,
204
+ args=tuple(args),
205
+ kwargs={**kwargs, "exception": exc},
206
+ )
207
+ raise
208
+
209
+ for predicate in predicates:
210
+ _evaluate_contract(
211
+ kind="ensure",
212
+ func=func,
213
+ predicate=predicate,
214
+ args=tuple(args),
215
+ kwargs={**kwargs, "result": result},
216
+ )
217
+ return result
218
+
219
+ return wrapped
220
+
221
+ return decorator
222
+
223
+
224
+ def skip_invariant(func: Callable[Q, S]) -> Callable[Q, S]: # noqa: UP047
225
+ """Mark a method so invariants are not evaluated around it."""
226
+
227
+ func.__dbc_skip_invariant__ = True # type: ignore[attr-defined]
228
+ return func
229
+
230
+
231
+ def _check_invariants(
232
+ predicates: tuple[ContractCallable, ...],
233
+ *,
234
+ instance: object,
235
+ func: Callable[..., object],
236
+ ) -> None:
237
+ for predicate in predicates:
238
+ _evaluate_contract(
239
+ kind="invariant",
240
+ func=func,
241
+ predicate=predicate,
242
+ args=(instance,),
243
+ kwargs={},
244
+ )
245
+
246
+
247
+ def invariant(*predicates: ContractCallable) -> Callable[[type[T]], type[T]]:
248
+ """Enforce invariants before and after public method calls."""
249
+
250
+ if not predicates:
251
+ msg = "@invariant expects at least one predicate"
252
+ raise ValueError(msg)
253
+
254
+ predicate_tuple = tuple(predicates)
255
+
256
+ def decorator(cls: type[T]) -> type[T]:
257
+ original_init = cls.__init__
258
+
259
+ @wraps(original_init)
260
+ def init_wrapper(self: T, *args: object, **kwargs: object) -> None:
261
+ original_init(self, *args, **kwargs)
262
+ if dbc_active():
263
+ _check_invariants(predicate_tuple, instance=self, func=original_init)
264
+
265
+ type.__setattr__(cls, "__init__", init_wrapper)
266
+
267
+ for attribute_name, attribute in list(cls.__dict__.items()):
268
+ if attribute_name.startswith("_"):
269
+ continue
270
+ if getattr(attribute, "__dbc_skip_invariant__", False):
271
+ continue
272
+ if isinstance(attribute, (staticmethod, classmethod)):
273
+ continue
274
+ if not callable(attribute):
275
+ continue
276
+
277
+ def make_wrapper(method: Callable[..., object]) -> Callable[..., object]:
278
+ @wraps(method)
279
+ def wrapper(self: T, *args: object, **kwargs: object) -> object:
280
+ if not dbc_active():
281
+ return method(self, *args, **kwargs)
282
+ _check_invariants(predicate_tuple, instance=self, func=method)
283
+ try:
284
+ return method(self, *args, **kwargs)
285
+ finally:
286
+ _check_invariants(predicate_tuple, instance=self, func=method)
287
+
288
+ return wrapper
289
+
290
+ setattr(cls, attribute_name, make_wrapper(attribute))
291
+
292
+ return cls
293
+
294
+ return decorator
295
+
296
+
297
+ _SNAPSHOT_SENTINEL = object()
298
+
299
+
300
+ def _snapshot(value: object) -> object:
301
+ try:
302
+ return copy.deepcopy(value)
303
+ except Exception:
304
+ return _SNAPSHOT_SENTINEL
305
+
306
+
307
+ def _compare_snapshots(
308
+ *,
309
+ func: Callable[..., object],
310
+ args: tuple[object, ...],
311
+ kwargs: Mapping[str, object],
312
+ snap_args: tuple[object, ...],
313
+ snap_kwargs: Mapping[str, object],
314
+ ) -> None:
315
+ for index, (original, snapshot) in enumerate(zip(args, snap_args, strict=False)):
316
+ if snapshot is _SNAPSHOT_SENTINEL:
317
+ continue
318
+ if original != snapshot:
319
+ msg = (
320
+ f"pure contract for {_qualname(func)} detected mutation of "
321
+ f"positional argument {index}"
322
+ )
323
+ raise AssertionError(msg)
324
+
325
+ for key, snapshot in snap_kwargs.items():
326
+ if snapshot is _SNAPSHOT_SENTINEL:
327
+ continue
328
+ if kwargs[key] != snapshot:
329
+ msg = (
330
+ f"pure contract for {_qualname(func)} detected mutation of "
331
+ f"keyword argument '{key}'"
332
+ )
333
+ raise AssertionError(msg)
334
+
335
+
336
+ def _pure_violation(func: Callable[..., object], target: str) -> Callable[..., object]:
337
+ def raiser(*args: object, **kwargs: object) -> object: # pragma: no cover - trivial
338
+ msg = f"pure contract for {_qualname(func)} forbids calling {target}"
339
+ raise AssertionError(msg)
340
+
341
+ return raiser
342
+
343
+
344
+ @contextmanager
345
+ def _pure_environment(func: Callable[..., object]) -> Iterator[None]:
346
+ with ExitStack() as stack:
347
+ stack.enter_context(
348
+ _patch(builtins, "open", _pure_violation(func, "builtins.open"))
349
+ )
350
+ stack.enter_context(
351
+ _patch(Path, "write_text", _pure_violation(func, "Path.write_text"))
352
+ )
353
+ stack.enter_context(
354
+ _patch(Path, "write_bytes", _pure_violation(func, "Path.write_bytes"))
355
+ )
356
+ stack.enter_context(
357
+ _patch(logging.Logger, "_log", _pure_violation(func, "logging"))
358
+ )
359
+ yield
360
+
361
+
362
+ @contextmanager
363
+ def _patch(
364
+ obj: object, attribute: str, replacement: Callable[..., object]
365
+ ) -> Iterator[None]:
366
+ original = getattr(obj, attribute)
367
+ setattr(obj, attribute, replacement)
368
+ try:
369
+ yield
370
+ finally:
371
+ setattr(obj, attribute, original)
372
+
373
+
374
+ def pure(func: Callable[P, R]) -> Callable[P, R]: # noqa: UP047
375
+ """Validate that the wrapped callable behaves like a pure function."""
376
+
377
+ @wraps(func)
378
+ def wrapped(*args: P.args, **kwargs: P.kwargs) -> R:
379
+ if not dbc_active():
380
+ return func(*args, **kwargs)
381
+
382
+ snapshot_args = tuple(_snapshot(arg) for arg in args)
383
+ snapshot_kwargs: dict[str, object] = {
384
+ key: _snapshot(value) for key, value in kwargs.items()
385
+ }
386
+
387
+ with _pure_environment(func):
388
+ result = func(*args, **kwargs)
389
+
390
+ _compare_snapshots(
391
+ func=func,
392
+ args=tuple(args),
393
+ kwargs=dict(kwargs),
394
+ snap_args=snapshot_args,
395
+ snap_kwargs=snapshot_kwargs,
396
+ )
397
+ return result
398
+
399
+ return wrapped
400
+
401
+
402
+ __all__ = [
403
+ "dbc_active",
404
+ "dbc_enabled",
405
+ "disable_dbc",
406
+ "enable_dbc",
407
+ "ensure",
408
+ "invariant",
409
+ "pure",
410
+ "require",
411
+ "skip_invariant",
412
+ ]
@@ -0,0 +1,58 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ """Deadline utilities for orchestrating prompt evaluations."""
14
+
15
+ from __future__ import annotations
16
+
17
+ from dataclasses import dataclass
18
+ from datetime import UTC, datetime, timedelta
19
+
20
+ __all__ = ["Deadline"]
21
+
22
+
23
+ def _utcnow() -> datetime:
24
+ """Return the current UTC timestamp."""
25
+
26
+ return datetime.now(UTC)
27
+
28
+
29
+ @dataclass(slots=True, frozen=True)
30
+ class Deadline:
31
+ """Immutable value object describing a wall-clock expiration."""
32
+
33
+ expires_at: datetime
34
+
35
+ def __post_init__(self) -> None:
36
+ expires_at = self.expires_at
37
+ if expires_at.tzinfo is None or expires_at.utcoffset() is None:
38
+ msg = "Deadline expires_at must be timezone-aware."
39
+ raise ValueError(msg)
40
+
41
+ now = _utcnow()
42
+ if expires_at <= now:
43
+ msg = "Deadline expires_at must be in the future."
44
+ raise ValueError(msg)
45
+
46
+ if expires_at - now < timedelta(seconds=1):
47
+ msg = "Deadline must be at least one second in the future."
48
+ raise ValueError(msg)
49
+
50
+ def remaining(self, *, now: datetime | None = None) -> timedelta:
51
+ """Return the remaining duration before expiration."""
52
+
53
+ current = now or _utcnow()
54
+ if current.tzinfo is None or current.utcoffset() is None:
55
+ msg = "Deadline remaining now must be timezone-aware."
56
+ raise ValueError(msg)
57
+
58
+ return self.expires_at - current
@@ -0,0 +1,105 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ """Prompt authoring primitives exposed by :mod:`weakincentives.prompt`."""
14
+
15
+ from __future__ import annotations
16
+
17
+ from ._types import SupportsDataclass, SupportsToolResult
18
+ from .chapter import Chapter, ChaptersExpansionPolicy
19
+ from .composition import (
20
+ DelegationParams,
21
+ DelegationPrompt,
22
+ DelegationSummarySection,
23
+ ParentPromptParams,
24
+ ParentPromptSection,
25
+ RecapParams,
26
+ RecapSection,
27
+ )
28
+ from .errors import (
29
+ PromptError,
30
+ PromptRenderError,
31
+ PromptValidationError,
32
+ SectionPath,
33
+ )
34
+ from .markdown import MarkdownSection
35
+ from .overrides import (
36
+ LocalPromptOverridesStore,
37
+ PromptDescriptor,
38
+ PromptLike,
39
+ PromptOverride,
40
+ PromptOverridesError,
41
+ PromptOverridesStore,
42
+ SectionDescriptor,
43
+ SectionOverride,
44
+ ToolDescriptor,
45
+ ToolOverride,
46
+ hash_json,
47
+ hash_text,
48
+ )
49
+ from .prompt import Prompt
50
+ from .protocols import (
51
+ PromptProtocol,
52
+ ProviderAdapterProtocol,
53
+ RenderedPromptProtocol,
54
+ )
55
+ from .section import Section
56
+ from .structured_output import (
57
+ OutputParseError,
58
+ StructuredOutputConfig,
59
+ parse_structured_output,
60
+ )
61
+ from .tool import Tool, ToolContext, ToolHandler
62
+ from .tool_result import ToolResult
63
+
64
+ __all__ = [
65
+ "Chapter",
66
+ "ChaptersExpansionPolicy",
67
+ "DelegationParams",
68
+ "DelegationPrompt",
69
+ "DelegationSummarySection",
70
+ "LocalPromptOverridesStore",
71
+ "MarkdownSection",
72
+ "OutputParseError",
73
+ "ParentPromptParams",
74
+ "ParentPromptSection",
75
+ "Prompt",
76
+ "PromptDescriptor",
77
+ "PromptError",
78
+ "PromptLike",
79
+ "PromptOverride",
80
+ "PromptOverridesError",
81
+ "PromptOverridesStore",
82
+ "PromptProtocol",
83
+ "PromptRenderError",
84
+ "PromptValidationError",
85
+ "ProviderAdapterProtocol",
86
+ "RecapParams",
87
+ "RecapSection",
88
+ "RenderedPromptProtocol",
89
+ "Section",
90
+ "SectionDescriptor",
91
+ "SectionOverride",
92
+ "SectionPath",
93
+ "StructuredOutputConfig",
94
+ "SupportsDataclass",
95
+ "SupportsToolResult",
96
+ "Tool",
97
+ "ToolContext",
98
+ "ToolDescriptor",
99
+ "ToolHandler",
100
+ "ToolOverride",
101
+ "ToolResult",
102
+ "hash_json",
103
+ "hash_text",
104
+ "parse_structured_output",
105
+ ]