|
54 | 54 | "build_internal_strategy", |
55 | 55 | "build_testing_strategy", |
56 | 56 | "build_performance_strategy", |
| 57 | + "build_minimal_strategy", |
57 | 58 | ] |
58 | 59 |
|
59 | 60 | _logger = logging.getLogger(__name__) |
@@ -91,6 +92,7 @@ def __init__( |
91 | 92 | removable=False, |
92 | 93 | replaceable=False, |
93 | 94 | pure=True, |
| 95 | + provides=("context",), |
94 | 96 | ) |
95 | 97 | self._config = config |
96 | 98 | self._executor = executor |
@@ -129,6 +131,7 @@ def __init__(self, *, config: Any | None = None) -> None: |
129 | 131 | removable=True, |
130 | 132 | replaceable=True, |
131 | 133 | pure=True, |
| 134 | + requires=("context",), |
132 | 135 | ) |
133 | 136 | self._config = config |
134 | 137 | if config is not None: |
@@ -166,6 +169,7 @@ def __init__(self, *, registry: Any) -> None: |
166 | 169 | removable=False, |
167 | 170 | replaceable=False, |
168 | 171 | pure=True, |
| 172 | + provides=("module",), |
169 | 173 | ) |
170 | 174 | self._registry = registry |
171 | 175 |
|
@@ -196,6 +200,7 @@ def __init__(self, *, acl: Any | None = None) -> None: |
196 | 200 | removable=True, |
197 | 201 | replaceable=True, |
198 | 202 | pure=True, |
| 203 | + requires=("context", "module"), |
199 | 204 | ) |
200 | 205 | self._acl = acl |
201 | 206 |
|
@@ -236,6 +241,7 @@ def __init__( |
236 | 241 | removable=True, |
237 | 242 | replaceable=True, |
238 | 243 | pure=False, |
| 244 | + requires=("context", "module"), |
239 | 245 | ) |
240 | 246 | self._handler = handler |
241 | 247 | self._executor = executor |
@@ -404,6 +410,8 @@ def __init__(self) -> None: |
404 | 410 | removable=True, |
405 | 411 | replaceable=True, |
406 | 412 | pure=True, |
| 413 | + requires=("module",), |
| 414 | + provides=("validated_inputs",), |
407 | 415 | ) |
408 | 416 |
|
409 | 417 | async def execute(self, ctx: PipelineContext) -> StepResult: |
@@ -455,6 +463,8 @@ def __init__(self, *, config: Any | None = None) -> None: |
455 | 463 | removable=False, |
456 | 464 | replaceable=True, |
457 | 465 | pure=False, |
| 466 | + requires=("module",), |
| 467 | + provides=("output",), |
458 | 468 | ) |
459 | 469 | self._config = config |
460 | 470 | if config is not None: |
@@ -553,6 +563,8 @@ def __init__(self) -> None: |
553 | 563 | removable=True, |
554 | 564 | replaceable=True, |
555 | 565 | pure=True, |
| 566 | + requires=("module", "output"), |
| 567 | + provides=("validated_output",), |
556 | 568 | ) |
557 | 569 |
|
558 | 570 | async def execute(self, ctx: PipelineContext) -> StepResult: |
@@ -665,6 +677,7 @@ def __init__(self) -> None: |
665 | 677 | removable=False, |
666 | 678 | replaceable=False, |
667 | 679 | pure=True, |
| 680 | + requires=("output",), |
668 | 681 | ) |
669 | 682 |
|
670 | 683 | async def execute(self, ctx: PipelineContext) -> StepResult: |
@@ -777,3 +790,28 @@ def build_performance_strategy(**kwargs: Any) -> ExecutionStrategy: |
777 | 790 | s.remove("middleware_after") |
778 | 791 | object.__setattr__(s, "name", "performance") |
779 | 792 | return s |
| 793 | + |
| 794 | + |
| 795 | +def build_minimal_strategy(**kwargs: Any) -> ExecutionStrategy: |
| 796 | + """Build a minimal strategy: context → lookup → execute → return only. |
| 797 | +
|
| 798 | + Suitable for pre-validated internal hot paths where ACL, approval, |
| 799 | + middleware, and schema validation are unnecessary. Use with caution — |
| 800 | + no safety checks, no input/output validation, no middleware. |
| 801 | +
|
| 802 | + Args: |
| 803 | + **kwargs: Forwarded to build_standard_strategy(). |
| 804 | +
|
| 805 | + Returns: |
| 806 | + An ExecutionStrategy named "minimal" with 4 steps. |
| 807 | + """ |
| 808 | + s = build_standard_strategy(**kwargs) |
| 809 | + s.remove("call_chain_guard") |
| 810 | + s.remove("acl_check") |
| 811 | + s.remove("approval_gate") |
| 812 | + s.remove("middleware_before") |
| 813 | + s.remove("input_validation") |
| 814 | + s.remove("output_validation") |
| 815 | + s.remove("middleware_after") |
| 816 | + object.__setattr__(s, "name", "minimal") |
| 817 | + return s |
0 commit comments