Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance the behavior of the method that loads llm_config and add new tests #3321

Open
wants to merge 3 commits into
base: 0.2
Choose a base branch
from
Open
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
37 changes: 28 additions & 9 deletions autogen/agentchat/conversable_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,17 +254,36 @@ def __init__(
}

def _validate_llm_config(self, llm_config):
assert llm_config in (None, False) or isinstance(
llm_config, dict
), "llm_config must be a dict or False or None."
assert llm_config in (None, False) or isinstance(llm_config, dict), "llm_config must be a dict, False, or None."

if llm_config is None:
llm_config = self.DEFAULT_CONFIG
self.llm_config = self.DEFAULT_CONFIG if llm_config is None else llm_config
# TODO: more complete validity check
if self.llm_config in [{}, {"config_list": []}, {"config_list": [{"model": ""}]}]:
raise ValueError(
"When using OpenAI or Azure OpenAI endpoints, specify a non-empty 'model' either in 'llm_config' or in each config of 'config_list'."
)

self.llm_config = llm_config

if isinstance(self.llm_config, dict):
config_list = self.llm_config.get("config_list", [])
if not isinstance(config_list, list):
raise ValueError("llm_config: 'config_list' must be a list.")

# If config_list is empty, check if 'model' field is present in llm_config
if not config_list and "model" not in self.llm_config:
raise ValueError("llm_config: 'model' field is required in 'llm_config' or each 'config_list' entry.")

# When config_list is not empty, check each item in config_list
for config in config_list:
if not isinstance(config, dict):
raise ValueError("llm_config: 'config_list' must be a list of dictionaries.")
if "model" not in config or not config["model"]:
raise ValueError(
"llm_config: 'model' field is required for each item in 'config_list' and must not be empty."
)
if "api_key" in config and not isinstance(config["api_key"], str):
raise ValueError("llm_config: 'api_key' must be a string.")
if "tags" in config:
if not isinstance(config["tags"], list) or not all(isinstance(tag, str) for tag in config["tags"]):
raise ValueError("llm_config: 'tags' must be a list of strings.")

self.client = None if self.llm_config is False else OpenAIWrapper(**self.llm_config)

@staticmethod
Expand Down
40 changes: 37 additions & 3 deletions test/agentchat/test_conversable_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -831,22 +831,56 @@ def do_stuff(s: str) -> str:
return f"{s} done"


def test_register_for_llm_with_valid_configuration():
with pytest.MonkeyPatch.context() as mp:
mp.setenv("OPENAI_API_KEY", MOCK_OPEN_AI_API_KEY)

valid_config = {
"config_list": [
{"model": "gpt-4"},
{"model": "gpt-4", "api_key": MOCK_OPEN_AI_API_KEY, "tags": ["gpt4", "openai"]},
],
}
assistant = ConversableAgent(
name="assistant",
llm_config=valid_config,
)
assert assistant is not None
assert assistant.llm_config == valid_config


def test_register_for_llm_without_configuration():
with pytest.raises(
ValueError,
match="When using OpenAI or Azure OpenAI endpoints, specify a non-empty 'model' either in 'llm_config' or in each config of 'config_list'.",
match="llm_config: 'model' field is required in 'llm_config' or each 'config_list' entry.",
):
ConversableAgent(name="agent", llm_config={"config_list": []})


def test_register_for_llm_without_model_name():
with pytest.raises(
ValueError,
match="When using OpenAI or Azure OpenAI endpoints, specify a non-empty 'model' either in 'llm_config' or in each config of 'config_list'.",
match="llm_config: 'model' field is required for each item in 'config_list' and must not be empty.",
):
ConversableAgent(name="agent", llm_config={"config_list": [{"model": ""}]})


def test_register_for_llm_with_invalid_tags():
with pytest.raises(
ValueError,
match="llm_config: 'tags' must be a list of strings.",
):
ConversableAgent(name="agent", llm_config={"config_list": [{"model": "gpt-4", "tags": "invalid_tags"}]})


def test_register_for_llm_with_invalid_api_key():
with pytest.raises(
ValueError,
match="llm_config: 'api_key' must be a string.",
):
ConversableAgent(name="agent", llm_config={"config_list": [{"model": "gpt-4", "api_key": 1234}]})


def test_register_for_execution():
with pytest.MonkeyPatch.context() as mp:
mp.setenv("OPENAI_API_KEY", MOCK_OPEN_AI_API_KEY)
Expand Down Expand Up @@ -1413,7 +1447,7 @@ def test_http_client():

def test_adding_duplicate_function_warning():

config_base = [{"base_url": "http://0.0.0.0:8000", "api_key": "NULL"}]
config_base = [{"base_url": "http://0.0.0.0:8000", "api_key": "NULL", "model": "na"}]

agent = autogen.ConversableAgent(
"jtoy",
Expand Down
Loading