reducer replaces merge_strategy.

This commit is contained in:
lda
2026-05-17 16:23:51 +07:00 Verified
parent c5b43c7dbe
commit 86ffb17ec6
14 changed files with 348 additions and 91 deletions
+2 -2
View File
@@ -41,7 +41,7 @@ class AutoBindState(BaseModel):
class AppendState(BaseModel):
items: Annotated[list[str], state_field(merge_strategy="append")] = Field(
items: Annotated[list[str], state_field(reducer="wf.std.append")] = Field(
default_factory=list
)
@@ -54,7 +54,7 @@ class DefaultedState(BaseModel):
class NestedPersonState(BaseModel):
name: str
tags: Annotated[list[str], state_field(merge_strategy="append")] = Field(
tags: Annotated[list[str], state_field(reducer="wf.std.append")] = Field(
default_factory=list
)
+4 -4
View File
@@ -46,7 +46,7 @@ def test_builder_accepts_typeddict_for_json_schema_refs() -> None:
assert workflow.input_schema.properties["text"]["type"] == "string"
def test_state_basemodel_can_declare_merge_strategy_with_annotated_metadata() -> None:
def test_state_basemodel_can_declare_reducer_with_annotated_metadata() -> None:
builder = WorkflowBuilder(
name="state_metadata_demo",
input_schema=WorkflowInput,
@@ -58,7 +58,7 @@ def test_state_basemodel_can_declare_merge_strategy_with_annotated_metadata() ->
workflow = builder.compile()
assert workflow.state_schema.fields["items"].type == "array"
assert workflow.state_schema.fields["items"].merge_strategy == "append"
assert workflow.state_schema.fields["items"].reducer == "wf.std.append"
def test_state_basemodel_seeds_safe_initial_defaults() -> None:
@@ -96,5 +96,5 @@ def test_nested_state_basemodel_projects_parent_and_child_paths() -> None:
assert workflow.state_schema.fields["person"].type == "object"
assert workflow.state_schema.fields["person.name"].type == "string"
assert workflow.state_schema.fields["person.tags"].type == "array"
assert workflow.state_schema.fields["person"].merge_strategy == "replace"
assert workflow.state_schema.fields["person.tags"].merge_strategy == "append"
assert workflow.state_schema.fields["person"].reducer == "wf.std.replace"
assert workflow.state_schema.fields["person.tags"].reducer == "wf.std.append"
+19 -3
View File
@@ -4,9 +4,9 @@ from wf_core import SchemaRef, StateField, StateSchema, Workflow
from wf_core.runtime.ops.state import write_state_value
def test_exact_nested_state_path_uses_declared_merge_strategy() -> None:
def test_exact_nested_state_path_uses_declared_reducer() -> None:
workflow = _workflow(
fields={"person.tags": StateField(type="array", merge_strategy="append")}
fields={"person.tags": StateField(type="array", reducer="wf.std.append")}
)
state = {"person": {"tags": ["seed"]}}
@@ -17,7 +17,7 @@ def test_exact_nested_state_path_uses_declared_merge_strategy() -> None:
def test_parent_state_declaration_does_not_apply_to_nested_write() -> None:
workflow = _workflow(
fields={"person": StateField(type="object", merge_strategy="merge_object")}
fields={"person": StateField(type="object", reducer="wf.std.merge_object")}
)
state = {"person": {"tags": ["seed"]}}
@@ -35,6 +35,22 @@ def test_undeclared_nested_state_path_defaults_to_replace() -> None:
assert state["person"]["tags"] == ["next"]
def test_state_field_defaults_to_replace_reducer() -> None:
assert StateField(type="string").reducer == "wf.std.replace"
def test_unknown_state_reducer_fails_clearly() -> None:
workflow = _workflow(fields={"person.tags": StateField(type="array", reducer="x.nope")})
state = {"person": {"tags": ["seed"]}}
try:
write_state_value(workflow, state, "state.person.tags", ["next"])
except Exception as exc:
assert "unknown reducer 'x.nope'" in str(exc)
else:
raise AssertionError("expected unknown reducer to fail")
def _workflow(*, fields: dict[str, StateField]) -> Workflow:
return Workflow(
name="nested_state_paths",
+4 -2
View File
@@ -111,7 +111,7 @@ class UnsophisticatedPool(TypedDict):
class Storage(BaseModel):
"i NEED to do this?"
storage: Annotated[list[Entity], state_field(merge_strategy="append")] = Field(
storage: Annotated[list[Entity], state_field(reducer="wf.std.append")] = Field(
default_factory=list
) # add!
@@ -125,7 +125,9 @@ class PartialRates(SophisticatedRates, total=False):
class Rates(BaseModel):
rates: Annotated[PartialRates, state_field(merge_strategy="merge_object")] # or_!
rates: Annotated[
PartialRates, state_field(reducer="wf.std.merge_object")
] # or_!
class CurrentPools(BaseModel):