Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions .github/workflows/build-project.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,22 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'

- name: Install Poetry
run: |
curl -sSL https://install.python-poetry.org | python3

- name: Poetry lock
run: poetry lock
- name: Install and configure Poetry
uses: snok/install-poetry@v1
with:
version: 1.8.3
virtualenvs-create: true
virtualenvs-in-project: true

- name: Install dependencies
run: poetry install
run: poetry lock && poetry install

- name: Run build
run: poetry build
82 changes: 31 additions & 51 deletions examples/agent_of_flo_ai.ipynb

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/hierarchical_blogging_team.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
job: From the documents provider by the researcher write a blog of 300 words with can be readily published, make in engaging and add reference links to original blogs
tools:
- name: TavilySearchResults
- name: Writing Team
- name: WritingTeam
supervisor:
name: supervisor
agents:
Expand Down
41 changes: 0 additions & 41 deletions examples/planned_blogging_team.py

This file was deleted.

2 changes: 1 addition & 1 deletion examples/tool_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,6 @@ def _run(
- name: printStateTool
"""

flo = Flo.build(session, simple_tool_agent)
flo = Flo.build(session, simple_tool_agent, log_level="ERROR")

print(flo.invoke("Testing ...."))
13 changes: 13 additions & 0 deletions features/flo_name.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Feature: While building a flo

Scenario Outline: Flo Name Validation
When use the name, <flo_name>
Then it should be <validity>

Examples: Flo Names
| flo_name | validity |
| CorrectName | True |
| Wrong Name | False |
| correct_name | True |
| correct-name | True |
| wrong/name | False |
15 changes: 15 additions & 0 deletions features/steps/flo_name_steps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from behave import given, when, then, step
from flo_ai.yaml.validators import raise_for_name_error

@when('use the name, {flo_name}')
def step_impl(context, flo_name):
isException = "False"
try:
raise_for_name_error(flo_name)
except Exception as e:
isException = "True"
context.isException = isException

@then('it should be {validity}')
def step_impl(context, validity):
assert context.isException != validity
22 changes: 18 additions & 4 deletions flo_ai/builders/yaml_builder.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,32 @@
from flo_ai.models.flo_team import FloTeam
from flo_ai.models.flo_agent import FloAgent
from flo_ai.yaml.config import (FloRoutedTeamConfig, TeamConfig, AgentConfig, FloAgentConfig)
from flo_ai.models.flo_executable import ExecutableFlo
from flo_ai.state.flo_session import FloSession
from flo_ai.router.flo_router_factory import FloRouterFactory
from flo_ai.factory.agent_factory import AgentFactory
from flo_ai.yaml.validators import raise_for_name_error, DuplicateStringError
from flo_ai.common.flo_logger import builder_logger

def build_supervised_team(session: FloSession) -> ExecutableFlo:
name_set = set()
flo_config = session.config
if isinstance(flo_config, FloRoutedTeamConfig):
team_config: TeamConfig = flo_config.team
team = parse_and_build_subteams(session, team_config)
team = parse_and_build_subteams(session, team_config, name_set)
return team
elif isinstance(flo_config, FloAgentConfig):
agent_config: AgentConfig = flo_config.agent
validate_names(name_set, agent_config.name)
agent = AgentFactory.create(session, agent_config)
return agent

def validate_team(name_set: set, team_config: TeamConfig):
validate_names(name_set, team_config.name)
[validate_names(name_set, agent.name) for agent in team_config.agents]

def parse_and_build_subteams(session: FloSession, team_config: TeamConfig) -> ExecutableFlo:
def parse_and_build_subteams(session: FloSession, team_config: TeamConfig, name_set = set()) -> ExecutableFlo:
flo_team = None
validate_team(name_set, team_config)
if team_config.agents:
members = [AgentFactory.create(session, agent) for agent in team_config.agents]
flo_team = FloTeam.Builder(team_config, members=members).build()
Expand All @@ -27,10 +35,16 @@ def parse_and_build_subteams(session: FloSession, team_config: TeamConfig) -> Ex
else:
flo_teams = []
for subteam in team_config.subteams:
flo_subteam = parse_and_build_subteams(session, subteam)
flo_subteam = parse_and_build_subteams(session, subteam, name_set)
flo_teams.append(flo_subteam)
flo_team = FloTeam.Builder(team_config, members=flo_teams).build()
router = FloRouterFactory.create(session, team_config, flo_team)
flo_routed_team = router.build_routed_team()
return flo_routed_team

def validate_names(name_set: set, name):
raise_for_name_error(name)
if name in name_set:
builder_logger.error(f"Duplicate name found: '{name}'")
raise DuplicateStringError(f"The name '{name}' is already in the set.")
name_set.add(name)
1 change: 1 addition & 0 deletions flo_ai/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def invoke(self, query, config = None) -> Iterator[Union[dict[str, Any], Any]]:

@staticmethod
def build(session: FloSession, yaml: str, log_level: str = "INFO"):
set_global_log_level(log_level)
builder_logger.info("Building Flo instance from YAML")
return Flo(session, to_supervised_team(yaml), log_level)

Expand Down
8 changes: 1 addition & 7 deletions flo_ai/helpers/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,4 @@
def random_str(length: int = 5):
letters = string.ascii_letters + string.digits
result_str = ''.join(random.choice(letters) for i in range(length))
return result_str

def randomize_name(name: str):
return "{}-{}".format(name, random_str(5))

def agent_name_from_randomized_name(name: str):
return name.split("-")[0]
return result_str
3 changes: 1 addition & 2 deletions flo_ai/models/flo_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from langchain_core.runnables import Runnable
from langchain_core.language_models import BaseLanguageModel
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from flo_ai.helpers.utils import randomize_name
from flo_ai.models.flo_executable import ExecutableFlo
from flo_ai.state.flo_session import FloSession
from typing import Union, Optional
Expand Down Expand Up @@ -33,7 +32,7 @@ def __init__(self,
handle_parsing_errors: bool = True) -> None:
prompt: Union[ChatPromptTemplate, str] = config.job

self.name: str = randomize_name(config.name)
self.name: str = config.name
self.llm = llm if llm is not None else session.llm
self.config = config
# TODO improve to add more context of what other agents are available
Expand Down
3 changes: 1 addition & 2 deletions flo_ai/models/flo_llm_agent.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from langchain_core.runnables import Runnable
from langchain_core.language_models import BaseLanguageModel
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from flo_ai.helpers.utils import randomize_name
from flo_ai.models.flo_executable import ExecutableFlo
from flo_ai.state.flo_session import FloSession
from typing import Union
Expand All @@ -25,7 +24,7 @@ def __init__(self,
llm: Union[BaseLanguageModel, None] = None) -> None:
prompt: Union[ChatPromptTemplate, str] = config.job

self.name: str = randomize_name(config.name)
self.name: str = config.name
self.llm = llm if llm is not None else session.llm
# TODO improve to add more context of what other agents are available
system_prompts = [("system", "You are a {}".format(config.role)), ("system", prompt)] if config.role is not None else [("system", prompt)]
Expand Down
157 changes: 0 additions & 157 deletions flo_ai/models/flo_planner.py

This file was deleted.

Loading