fixed flow output section

This commit is contained in:
Brandon Hancock
2024-09-23 14:47:11 -04:00
parent 3939d432aa
commit 50055a814c
5 changed files with 206 additions and 52 deletions

View File

@@ -11,7 +11,6 @@ class PoemState(BaseModel):
poem: str = ""
class PoemFlow(Flow[PoemState]):
initial_state = PoemState
@start()
def generate_sentence_count(self):

View File

@@ -0,0 +1,52 @@
import asyncio
from crewai.flow.flow import Flow, listen, start
from litellm import completion
class ExampleFlow(Flow):
model = "gpt-4o-mini"
@start()
def generate_city(self):
print("Starting flow")
response = completion(
model=self.model,
messages=[
{
"role": "user",
"content": "Return the name of a random city in the world.",
},
],
)
random_city = response["choices"][0]["message"]["content"]
print(f"Random City: {random_city}")
return random_city
@listen(generate_city)
def generate_fun_fact(self, random_city):
response = completion(
model=self.model,
messages=[
{
"role": "user",
"content": f"Tell me a fun fact about {random_city}",
},
],
)
fun_fact = response["choices"][0]["message"]["content"]
return fun_fact
async def main():
flow = ExampleFlow()
result = await flow.kickoff()
print(f"Generated fun fact: {result}")
asyncio.run(main())

View File

@@ -2,7 +2,7 @@ import asyncio
import inspect
from typing import Any, Callable, Dict, Generic, List, Set, Type, TypeVar, Union
from pydantic import BaseModel, Field
from pydantic import BaseModel
T = TypeVar("T", bound=Union[BaseModel, Dict[str, Any]])
@@ -140,7 +140,7 @@ class Flow(Generic[T], metaclass=FlowMeta):
self._state = self._create_initial_state()
self._completed_methods: Set[str] = set()
self._pending_and_listeners: Dict[str, Set[str]] = {}
self._flow_output = FlowOutput()
self._method_outputs: List[Any] = [] # List to store all method outputs
for method_name in dir(self):
if callable(getattr(self, method_name)) and not method_name.startswith(
@@ -162,7 +162,12 @@ class Flow(Generic[T], metaclass=FlowMeta):
def state(self) -> T:
return self._state
async def kickoff(self):
@property
def method_outputs(self) -> List[Any]:
"""Returns the list of all outputs from executed methods."""
return self._method_outputs
async def kickoff(self) -> Any:
if not self._start_methods:
raise ValueError("No start method defined")
@@ -175,6 +180,12 @@ class Flow(Generic[T], metaclass=FlowMeta):
# Run all start methods concurrently
await asyncio.gather(*tasks)
# Return the final output (from the last executed method)
if self._method_outputs:
return self._method_outputs[-1]
else:
return None # Or raise an exception if no methods were executed
async def _execute_start_method(self, start_method: str):
result = await self._execute_method(self._methods[start_method])
await self._execute_listeners(start_method, result)
@@ -185,7 +196,7 @@ class Flow(Generic[T], metaclass=FlowMeta):
if asyncio.iscoroutinefunction(method)
else method(*args, **kwargs)
)
self._flow_output.add_method_output(result)
self._method_outputs.append(result) # Store the output
return result
async def _execute_listeners(self, trigger_method: str, result: Any):
@@ -239,28 +250,3 @@ class Flow(Generic[T], metaclass=FlowMeta):
import traceback
traceback.print_exc()
class FlowOutput(BaseModel):
state: Dict[str, Any] = Field(
default_factory=dict, description="Final state of the flow"
)
method_outputs: List[Any] = Field(
default_factory=list, description="List of outputs from all executed methods"
)
@property
def final_output(self) -> Any:
"""Get the output of the last executed method."""
return self.method_outputs[-1] if self.method_outputs else None
def add_method_output(self, output: Any):
"""Add a method output to the list and update the final method name."""
self.method_outputs.append(output)
def update_state(self, new_state: Dict[str, Any]):
"""Update the flow state."""
self.state.update(new_state)
class Config:
arbitrary_types_allowed = True

View File

@@ -0,0 +1,26 @@
import asyncio
from crewai.flow.flow import Flow, listen, start
class OutputExampleFlow(Flow):
@start()
async def first_method(self):
return "Output from first_method"
@listen(first_method)
async def second_method(self, first_output):
return f"Second method received: {first_output}"
async def main():
flow = OutputExampleFlow()
outputs = await flow.kickoff()
print("---- Flow Outputs ----")
print(outputs)
print(" FLOW STATE POST RUN")
print(flow.state)
asyncio.run(main())