Skip to content

Commit 89de0d6

Browse files
authored
Update haiway
1 parent 0c74c32 commit 89de0d6

File tree

19 files changed

+120
-118
lines changed

19 files changed

+120
-118
lines changed

docs/getting-started/first-steps.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ class AppConfig(State):
3131
max_retries: int = 3
3232
```
3333

34-
State instances are immutable—use `.updated()` to create tweaked copies.
34+
State instances are immutable—use `.updating()` to create tweaked copies.
3535

3636
```python
3737
config = AppConfig(environment="staging")
38-
updated = config.updated(max_retries=5)
38+
updated = config.updating(max_retries=5)
3939
```
4040

4141
## Model your data

docs/getting-started/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Throughout the getting-started journey you will assemble:
3434
## Core Concepts
3535

3636
1. **State management** – mutable-looking, immutable-under-the-hood `State` classes represent
37-
configuration and runtime data. You update them with methods like `State.updated(...)` to keep
37+
configuration and runtime data. You update them with methods like `State.updating(...)` to keep
3838
histories, snapshots, and metrics consistent.
3939
1. **Context scoping**`ctx.scope(...)` activates a stack of `State` instances and disposables for
4040
a logical unit of work, ensuring structured concurrency and clean teardown.

docs/guides/AdvancedState.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ initial: Mutable = Mutable(
2929
value=42,
3030
)
3131
# update one of the fields by creating a copy
32-
updated: Mutable = initial.updated(identifier="post")
32+
updated: Mutable = initial.updating(identifier="post")
3333
# update initial state once more - this will be another copy
34-
final: Mutable = initial.updated(value=21)
34+
final: Mutable = initial.updating(value=21)
3535

3636
print("initial", initial)
3737
print("updated", updated)

docs/guides/BasicStageUsage.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ reliable pipelines with confidence.
99

1010
- **Stage** – an async callable that produces or transforms multimodal content.
1111
- **StageState** – an immutable snapshot holding context entries and the latest result. Always
12-
return `state.updated(...)` instead of mutating in place.
12+
return `state.updating(...)` instead of mutating in place.
1313
- **MultimodalContent** – container for text, images, artifacts, and resources used as model inputs
1414
or outputs.
1515
- **`ctx.scope(...)`** – binds providers, disposables, and logging/metrics for the lifetime of your
@@ -189,7 +189,7 @@ async def merge_results(
189189
) -> StageState:
190190
successful = [branch for branch in branches if isinstance(branch, StageState)]
191191
combined = MultimodalContent.of(*[state.result for state in successful])
192-
return successful[0].updated(result=combined)
192+
return successful[0].updating(result=combined)
193193

194194
concurrent_stage = Stage.concurrent(
195195
Stage.completion("Analyze aspect A."),
@@ -292,7 +292,7 @@ from draive import MultimodalContent, StageState, stage
292292
@stage
293293
async def custom_processor(*, state: StageState) -> StageState:
294294
processed = MultimodalContent.of(f"Processed: {state.result.as_string()}")
295-
return state.updated(result=processed)
295+
return state.updating(result=processed)
296296
```
297297

298298
Any async function decorated with `@stage` gains the same API as built-in stages and can be mixed

docs/guides/BasicUsage.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,10 @@ async with ctx.scope( # prepare the new context
7878
print("RESULT GPT 3.5 | temperature 0.4:", result)
7979

8080
# we can update the configuration to change any parameter for nested context
81-
with ctx.updated(
81+
with ctx.updating(
8282
# we are updating the current context value instead of making a new one
8383
# this allows to preserve other elements of the configuration
84-
ctx.state(OpenAIResponsesConfig).updated(
84+
ctx.state(OpenAIResponsesConfig).updating(
8585
model="gpt-5",
8686
),
8787
):
@@ -135,8 +135,8 @@ async with ctx.scope( # prepare the context and see the execution metrics repor
135135
text="Roses are red...",
136136
)
137137

138-
with ctx.updated(
139-
ctx.state(OpenAIResponsesConfig).updated(
138+
with ctx.updating(
139+
ctx.state(OpenAIResponsesConfig).updating(
140140
model="gpt-5",
141141
),
142142
):

docs/guides/Basics.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ properties and an appropriate `__init__` function will be generated as well. Add
1616
types come with built-in validation. Each object is automatically validated during the
1717
initialization ensuring proper types and values for each field. Both types are also immutable by
1818
default - you will receive linting and runtime errors when trying to mutate those. To make a
19-
mutation of an instance of either of those we can use a dedicated `updated` method which makes a
19+
mutation of an instance of either of those we can use a dedicated `updating` method which makes a
2020
copy on the fly and validates mutation as well. Let's have a look:
2121

2222
```python
@@ -32,7 +32,7 @@ basic_state: BasicState = BasicState(
3232
# )
3333

3434
# prepare an update
35-
updated_state: BasicState = basic_state.updated(
35+
updated_state: BasicState = basic_state.updating(
3636
value=21
3737
) # value of `identifier` field won't change
3838

@@ -150,7 +150,7 @@ def do_something_contextually() -> None:
150150
```
151151

152152
What will be the current state is defined by the context of the execution. We can change it locally
153-
by using another function from `ctx` called `updated` which allows us to update the state by copying
153+
by using another function from `ctx` called `updating` which allows us to update the state by copying
154154
the context and allowing to enter a new scope with it:
155155

156156
```python
@@ -160,7 +160,7 @@ async with ctx.scope("basics", basic_state):
160160
do_something_contextually()
161161

162162
# then we can update it locally
163-
with ctx.updated(basic_state.updated(identifier="updated")):
163+
with ctx.updating(basic_state.updating(identifier="updated")):
164164
print("Updated:")
165165
# and access its updated version
166166
do_something_contextually()

llms.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ load_env()
1111
```
1212

1313
## Core primitives
14-
- `State` (from haiway): immutable runtime config/resources. Update via `.updated(...)`.
14+
- `State` (from haiway): immutable runtime config/resources. Update via `.updating(...)`.
1515
- `ctx.scope(label, *state, disposables=(...), observability=...)`: structured async context that activates states and disposables; nests safely.
1616
- `Disposables`: async resources (e.g., `OpenAI()`, `QdrantClient()`) auto-cleaned on scope exit.
1717
- `DataModel`: immutable, validated data containers with `.json_schema()` / `.simplified_schema()` and `.to_str()`.
@@ -189,5 +189,5 @@ all_ok = all(r.passed for r in results)
189189
- Always run inside `ctx.scope`.
190190
- Keep public APIs strictly typed (no implicit `Any`).
191191
- Avoid blocking calls; everything I/O is async.
192-
- Mutate state via `.updated(...)`; states and data models are immutable by design.
192+
- Mutate state via `.updating(...)`; states and data models are immutable by design.
193193
- Use `MultimodalContent` for any model input/output that mixes text/media/tools; use `.to_str()` for safe logging (binary redacted).

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ build-backend = "uv_build"
55
[project]
66
name = "draive"
77
description = "Framework designed to simplify and accelerate the development of LLM-based applications."
8-
version = "0.98.0"
8+
version = "0.99.0"
99
readme = "README.md"
1010
maintainers = [
1111
{ name = "Kacper Kaliński", email = "[email protected]" },
@@ -24,7 +24,7 @@ classifiers = [
2424
"Topic :: Software Development :: Libraries :: Application Frameworks",
2525
]
2626
license = { file = "LICENSE" }
27-
dependencies = ["numpy~=2.3", "haiway~=0.42.0"]
27+
dependencies = ["numpy~=2.3", "haiway~=0.43.0"]
2828

2929
[project.urls]
3030
Homepage = "https://miquido.com"

src/draive/helpers/instruction_refinement.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ async def tree_initialization(
264264
)
265265

266266
# Setup initial state
267-
return state.updated(
267+
return state.updating(
268268
_RefinementState(
269269
root=root_node,
270270
nodes={root_node.identifier: root_node},
@@ -324,7 +324,7 @@ async def explore(
324324
}
325325

326326
# Update the refinement state with the updated nodes
327-
refinement_state = refinement_state.updated(nodes=updated_nodes)
327+
refinement_state = refinement_state.updating(nodes=updated_nodes)
328328

329329
# Log tree statistics
330330
total_nodes: int = len(refinement_state.nodes)
@@ -336,7 +336,7 @@ async def explore(
336336
f"{active_nodes} active, {pruned_count} pruned"
337337
)
338338

339-
return state.updated(refinement_state)
339+
return state.updating(refinement_state)
340340

341341
async def condition(
342342
*,
@@ -419,7 +419,7 @@ async def _explore_node[Parameters: DataModel](
419419
# Evaluate with focused suite
420420
ctx.log_info(f"Evaluating strategy '{strategy_name}'...")
421421
focused_evaluation: EvaluatorSuiteResult
422-
with ctx.updated(child_node.patched_instructions_repository):
422+
with ctx.updating(child_node.patched_instructions_repository):
423423
focused_evaluation = await evaluator_suite(focused_suite_cases)
424424

425425
# Check for performance drop
@@ -431,7 +431,7 @@ async def _explore_node[Parameters: DataModel](
431431
pruned: bool = performance_ratio < performance_drop_threshold
432432

433433
# update node with evaluation data
434-
children[child_node.identifier] = child_node.updated(
434+
children[child_node.identifier] = child_node.updating(
435435
focused_evaluation=focused_evaluation,
436436
pruned=pruned,
437437
)
@@ -656,14 +656,14 @@ async def tree_finalization(
656656
)
657657

658658
complete_evaluation: EvaluatorSuiteResult
659-
with ctx.updated(candidate_node.patched_instructions_repository):
659+
with ctx.updating(candidate_node.patched_instructions_repository):
660660
complete_evaluation = await evaluator_suite()
661661

662662
# Update node with full eval score
663-
updated_node: _RefinementTreeNode = candidate_node.updated(
663+
updated_node: _RefinementTreeNode = candidate_node.updating(
664664
complete_evaluation=complete_evaluation
665665
)
666-
refinement_state = refinement_state.updated(
666+
refinement_state = refinement_state.updating(
667667
nodes={
668668
**refinement_state.nodes,
669669
# update node in tree
@@ -688,7 +688,7 @@ async def tree_finalization(
688688
)
689689

690690
# Update result with best instructions and updated state
691-
return state.updated(
691+
return state.updating(
692692
refinement_state,
693693
result=MultimodalContent.of(
694694
TextContent.of(

src/draive/models/generative.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ async def _loop(
340340

341341
if not pending_tools:
342342
ctx.log_debug("...loop finished...")
343-
result: ModelOutput = generated.updated(
343+
result: ModelOutput = generated.updating(
344344
# replace generated with forced result
345345
blocks=(
346346
*result_extension,
@@ -384,7 +384,7 @@ async def _loop(
384384

385385
if tools_result: # tools direct result
386386
ctx.log_debug("...loop finished by tools...")
387-
result: ModelOutput = generated.updated(
387+
result: ModelOutput = generated.updating(
388388
# replace generated with forced result
389389
blocks=(
390390
*result_extension,
@@ -746,27 +746,27 @@ def _decoded( # noqa: PLR0911
746746
return result
747747

748748
case "text":
749-
return result.updated(blocks=(MultimodalContent.of(*result.content.texts()),))
749+
return result.updating(blocks=(MultimodalContent.of(*result.content.texts()),))
750750

751751
case "image":
752-
return result.updated(blocks=(MultimodalContent.of(*result.content.images()),))
752+
return result.updating(blocks=(MultimodalContent.of(*result.content.images()),))
753753

754754
case "audio":
755-
return result.updated(blocks=(MultimodalContent.of(*result.content.audio()),))
755+
return result.updating(blocks=(MultimodalContent.of(*result.content.audio()),))
756756

757757
case "video":
758-
return result.updated(blocks=(MultimodalContent.of(*result.content.video()),))
758+
return result.updating(blocks=(MultimodalContent.of(*result.content.video()),))
759759

760760
case selection if isinstance(selection, Collection) and not isinstance(selection, str):
761761
selected_parts: tuple[MultimodalContentPart, ...] = tuple(
762762
part
763763
for part in result.content.parts
764764
if _matches_modalities(part, allowed=set(selection))
765765
)
766-
return result.updated(blocks=(MultimodalContent.of(*selected_parts),))
766+
return result.updating(blocks=(MultimodalContent.of(*selected_parts),))
767767

768768
case "json":
769-
return result.updated(
769+
return result.updating(
770770
blocks=(
771771
MultimodalContent.of(
772772
ArtifactContent.of(
@@ -779,7 +779,7 @@ def _decoded( # noqa: PLR0911
779779

780780
case model:
781781
assert isinstance(model, type) # nosec: B101
782-
return result.updated(
782+
return result.updating(
783783
blocks=(
784784
MultimodalContent.of(
785785
ArtifactContent.of(

0 commit comments

Comments
 (0)