Skip to content

Commit d964f4d

Browse files
Address PR 88 review: self-contained reducer snippets + accurate shapes
- concat_flatten / merge_all doc snippets: add the missing `from typing import Annotated` / `from pydantic import Field` imports so each recipe is self-contained. - Reword the per-instance collection-shape sentence: a mapping per-instance value lands list[dict] (merge_all), not list[list[X]] — name the two non-flat shapes separately instead of lumping the mapping case under "list-of-lists". AGENTS.md regenerated from docs/agent/non-obvious-shapes.md.
1 parent aa79d6e commit d964f4d

2 files changed

Lines changed: 16 additions & 2 deletions

File tree

docs/agent/non-obvious-shapes.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,9 @@ The fix is the `concat_flatten` built-in reducer (proposal 0036) — the list-of
200200

201201
```python
202202
from typing import Annotated
203+
204+
from pydantic import Field
205+
203206
from openarmature.graph import State, concat_flatten
204207

205208
class PipelineState(State):
@@ -211,13 +214,17 @@ class PipelineState(State):
211214
The dict-shaped analog is `merge_all` (also proposal 0036): when each fan-out instance contributes a `dict[str, X]`, the parent's `target_field` receives `list[dict]`, which plain `merge` can't consume. `merge_all` folds the sequence of mappings into the prior with shallow last-write-wins per key:
212215

213216
```python
217+
from typing import Annotated
218+
219+
from pydantic import Field
220+
214221
from openarmature.graph import State, merge_all
215222

216223
class PipelineState(State):
217224
keyed_results: Annotated[dict[str, Result], merge_all] = Field(default_factory=dict)
218225
```
219226

220-
Single-record-per-instance fan-outs (`collect_field: str`, parent field `Annotated[list[X], append]`) don't hit this — the engine still wraps each instance's value as one element, but `append` flattens it correctly since each element is already an `X`. The list-of-lists shape only emerges when the per-instance value is itself a list (use `concat_flatten`) or a mapping (use `merge_all`).
227+
Single-record-per-instance fan-outs (`collect_field: str`, parent field `Annotated[list[X], append]`) don't hit this — the engine still wraps each instance's value as one element, but `append` flattens it correctly since each element is already an `X`. The two non-flat shapes emerge only when the per-instance value is itself a container: a `list[X]` per instance lands `list[list[X]]` (use `concat_flatten`), and a `dict[str, X]` per instance lands `list[dict]` (use `merge_all`).
221228

222229
If a parent field is populated by BOTH direct node writes AND fan-out collection, that's an architectural ambiguity worth fixing upstream — split into two fields, or pick one path.
223230

src/openarmature/AGENTS.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1062,6 +1062,9 @@ The fix is the `concat_flatten` built-in reducer (proposal 0036) — the list-of
10621062

10631063
```python
10641064
from typing import Annotated
1065+
1066+
from pydantic import Field
1067+
10651068
from openarmature.graph import State, concat_flatten
10661069

10671070
class PipelineState(State):
@@ -1073,13 +1076,17 @@ class PipelineState(State):
10731076
The dict-shaped analog is `merge_all` (also proposal 0036): when each fan-out instance contributes a `dict[str, X]`, the parent's `target_field` receives `list[dict]`, which plain `merge` can't consume. `merge_all` folds the sequence of mappings into the prior with shallow last-write-wins per key:
10741077

10751078
```python
1079+
from typing import Annotated
1080+
1081+
from pydantic import Field
1082+
10761083
from openarmature.graph import State, merge_all
10771084

10781085
class PipelineState(State):
10791086
keyed_results: Annotated[dict[str, Result], merge_all] = Field(default_factory=dict)
10801087
```
10811088

1082-
Single-record-per-instance fan-outs (`collect_field: str`, parent field `Annotated[list[X], append]`) don't hit this — the engine still wraps each instance's value as one element, but `append` flattens it correctly since each element is already an `X`. The list-of-lists shape only emerges when the per-instance value is itself a list (use `concat_flatten`) or a mapping (use `merge_all`).
1089+
Single-record-per-instance fan-outs (`collect_field: str`, parent field `Annotated[list[X], append]`) don't hit this — the engine still wraps each instance's value as one element, but `append` flattens it correctly since each element is already an `X`. The two non-flat shapes emerge only when the per-instance value is itself a container: a `list[X]` per instance lands `list[list[X]]` (use `concat_flatten`), and a `dict[str, X]` per instance lands `list[dict]` (use `merge_all`).
10831090

10841091
If a parent field is populated by BOTH direct node writes AND fan-out collection, that's an architectural ambiguity worth fixing upstream — split into two fields, or pick one path.
10851092

0 commit comments

Comments
 (0)