Skip to content

Commit b22f7b6

Browse files
nshkrdotcomnshkrdotcom
authored andcommitted
Created rebuild docs
1 parent 2f6560f commit b22f7b6

24 files changed

+15854
-0
lines changed

docs/enhancements/llm_integration/error_recovery_and_repair_strategies.md

Lines changed: 529 additions & 0 deletions
Large diffs are not rendered by default.

docs/enhancements/llm_integration/iterative_refinement_system.md

Lines changed: 606 additions & 0 deletions
Large diffs are not rendered by default.

docs/enhancements/llm_integration/json_first_pipeline_architecture.md

Lines changed: 412 additions & 0 deletions
Large diffs are not rendered by default.

docs/enhancements/llm_integration/json_schema_generation_for_llm_constraints.md

Lines changed: 564 additions & 0 deletions
Large diffs are not rendered by default.

docs/enhancements/llm_integration/llm_structured_output_schemas.md

Lines changed: 487 additions & 0 deletions
Large diffs are not rendered by default.

docs/enhancements/llm_integration/validation_pipeline_for_llm_configs.md

Lines changed: 526 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
# Current State Management Analysis in Pipeline_ex
2+
3+
## Overview
4+
5+
Pipeline_ex currently uses a flexible but unstructured approach to state management, relying primarily on Elixir maps and custom modules. This document analyzes the current implementation and compares it with LangGraph's Pydantic-based approach.
6+
7+
## Current State Architecture
8+
9+
### 1. Core State Container: The Context Map
10+
11+
The execution context is a plain Elixir map containing:
12+
13+
```elixir
14+
%{
15+
# Core execution state
16+
workflow_name: String.t(),
17+
step_index: integer(),
18+
results: %{String.t() => any()},
19+
20+
# Variable management
21+
variable_state: %VariableEngine{},
22+
global_vars: %{String.t() => any()},
23+
24+
# Infrastructure
25+
workspace_dir: String.t(),
26+
output_dir: String.t(),
27+
checkpoint_dir: String.t(),
28+
29+
# Execution tracking
30+
execution_log: [map()],
31+
start_time: DateTime.t(),
32+
33+
# Configuration
34+
config: map(),
35+
debug_enabled: boolean()
36+
}
37+
```
38+
39+
### 2. Variable State Management
40+
41+
The `VariableEngine` provides a three-tier scoping system:
42+
43+
```elixir
44+
%Pipeline.State.VariableEngine{
45+
global: %{}, # Pipeline-wide
46+
session: %{}, # Session-scoped
47+
loop: %{}, # Loop-iteration scoped
48+
current_step: String.t() | nil,
49+
step_index: integer()
50+
}
51+
```
52+
53+
### 3. Result Storage
54+
55+
Results are stored in a `ResultManager`:
56+
57+
```elixir
58+
%Pipeline.ResultManager{
59+
results: %{String.t() => any()},
60+
metadata: %{
61+
created_at: DateTime.t(),
62+
last_updated: DateTime.t()
63+
}
64+
}
65+
```
66+
67+
## Comparison with LangGraph's Approach
68+
69+
### LangGraph State Management
70+
71+
LangGraph uses Pydantic models for state definition:
72+
73+
```python
74+
from typing import TypedDict, Annotated, Sequence
75+
from langchain_core.messages import BaseMessage
76+
import operator
77+
78+
class AgentState(TypedDict):
79+
messages: Annotated[Sequence[BaseMessage], operator.add]
80+
next_agent: str
81+
82+
# Type-safe access throughout the graph
83+
def agent_node(state: AgentState) -> AgentState:
84+
messages = state["messages"]
85+
# Type checking and validation built-in
86+
```
87+
88+
### Key Differences
89+
90+
| Feature | Pipeline_ex | LangGraph |
91+
|---------|------------|-----------|
92+
| **Type Safety** | Runtime maps, no compile-time guarantees | Pydantic models with full type validation |
93+
| **Schema Definition** | Implicit, scattered across modules | Explicit, centralized in TypedDict/BaseModel |
94+
| **Validation** | Manual, ad-hoc | Automatic via Pydantic |
95+
| **State Updates** | Direct map manipulation | Type-safe dictionary updates |
96+
| **Serialization** | Custom JSON encoding | Pydantic's built-in serialization |
97+
| **IDE Support** | Limited | Full autocomplete and type hints |
98+
| **State Migration** | Not supported | Pydantic's schema evolution |
99+
100+
## Strengths of Current Approach
101+
102+
1. **Flexibility**: Easy to add new fields without schema changes
103+
2. **Simplicity**: No complex type definitions required
104+
3. **Performance**: Direct map access is fast
105+
4. **Elixir-native**: Uses idiomatic Elixir patterns
106+
107+
## Weaknesses of Current Approach
108+
109+
1. **No Type Safety**: Errors only caught at runtime
110+
2. **No Schema Documentation**: State structure isn't self-documenting
111+
3. **Inconsistent Validation**: Each module handles validation differently
112+
4. **Limited IDE Support**: No autocomplete for state fields
113+
5. **Error-Prone**: Typos in field names cause runtime errors
114+
6. **No State Evolution**: Can't handle schema migrations
115+
116+
## Requirements for LangGraph-Style State
117+
118+
To achieve parity with LangGraph's state management, we need:
119+
120+
1. **Formal State Schemas**: Define state structure explicitly
121+
2. **Type Validation**: Validate state at boundaries
122+
3. **Reducer Functions**: Define how state updates are merged
123+
4. **Serialization Support**: Built-in JSON/YAML conversion
124+
5. **Schema Evolution**: Handle state migrations
125+
6. **Developer Experience**: IDE support and documentation
126+
127+
## Proposed Solution: Exdantic-Based State
128+
129+
Using Exdantic (our chosen validation library), we can achieve similar capabilities:
130+
131+
```elixir
132+
defmodule Pipeline.State.Schema do
133+
use Exdantic, define_struct: true
134+
135+
schema "Pipeline execution state" do
136+
field :messages, {:array, MessageSchema} do
137+
required()
138+
default([])
139+
metadata(reducer: :append)
140+
end
141+
142+
field :current_step, :string do
143+
optional()
144+
end
145+
146+
field :variables, {:map, :string, :any} do
147+
default(%{})
148+
metadata(reducer: :merge)
149+
end
150+
151+
field :results, {:map, :string, :any} do
152+
default(%{})
153+
metadata(reducer: :merge)
154+
end
155+
end
156+
157+
# Custom reducer definitions
158+
def reduce_field(:messages, old, new), do: old ++ new
159+
def reduce_field(:variables, old, new), do: Map.merge(old, new)
160+
def reduce_field(:results, old, new), do: Map.merge(old, new)
161+
end
162+
```
163+
164+
This would provide:
165+
- Type safety and validation
166+
- Self-documenting schemas
167+
- Built-in serialization
168+
- Custom reducer logic
169+
- Schema evolution support
170+
171+
## Migration Path
172+
173+
1. **Phase 1**: Define Exdantic schemas for current state
174+
2. **Phase 2**: Add validation at pipeline boundaries
175+
3. **Phase 3**: Migrate internal code to use schemas
176+
4. **Phase 4**: Add reducer-based state updates
177+
5. **Phase 5**: Implement state migration system
178+
179+
## Conclusion
180+
181+
While Pipeline_ex's current state management is functional and flexible, adopting a schema-based approach similar to LangGraph would provide significant benefits in terms of type safety, developer experience, and maintainability. The combination of Exdantic for schemas and a reducer-based update pattern would achieve feature parity with LangGraph while maintaining Elixir's strengths.

0 commit comments

Comments
 (0)