Rename AIConfig to AIProfile

This commit is contained in:
Reinier van der Leer
2023-10-07 18:14:52 -07:00
parent 34f2229479
commit 0b709a4393
17 changed files with 214 additions and 221 deletions

View File

@@ -5,7 +5,7 @@ from pathlib import Path
from autogpt.agents.agent import Agent, AgentConfiguration, AgentSettings
from autogpt.app.main import _configure_openai_provider, run_interaction_loop
from autogpt.commands import COMMAND_CATEGORIES
from autogpt.config import AIConfig, ConfigBuilder
from autogpt.config import AIProfile, ConfigBuilder
from autogpt.logs.config import configure_logging
from autogpt.memory.vector import get_memory
from autogpt.models.command_registry import CommandRegistry
@@ -39,7 +39,7 @@ def bootstrap_agent(task: str, continuous_mode: bool) -> Agent:
command_registry = CommandRegistry.with_command_modules(COMMAND_CATEGORIES, config)
ai_config = AIConfig(
ai_profile = AIProfile(
ai_name="AutoGPT",
ai_role="a multi-purpose AI assistant.",
ai_goals=[task],
@@ -50,7 +50,7 @@ def bootstrap_agent(task: str, continuous_mode: bool) -> Agent:
agent_settings = AgentSettings(
name=Agent.default_settings.name,
description=Agent.default_settings.description,
ai_config=ai_config,
ai_profile=ai_profile,
config=AgentConfiguration(
fast_llm=config.fast_llm,
smart_llm=config.smart_llm,

View File

@@ -11,7 +11,7 @@ if TYPE_CHECKING:
from autogpt.memory.vector import VectorMemory
from autogpt.models.command_registry import CommandRegistry
from autogpt.config import AIConfig
from autogpt.config import AIProfile
from autogpt.core.configuration import Configurable
from autogpt.core.prompting import ChatPrompt
from autogpt.core.resource.model_providers import (
@@ -70,7 +70,7 @@ class Agent(
default_settings: AgentSettings = AgentSettings(
name="Agent",
description=__doc__,
ai_config=AIConfig(ai_name="AutoGPT"),
ai_profile=AIProfile(ai_name="AutoGPT"),
config=AgentConfiguration(),
prompt_config=OneShotAgentPromptStrategy.default_configuration,
history=BaseAgent.default_settings.history,
@@ -159,7 +159,7 @@ class Agent(
self.log_cycle_handler.log_count_within_cycle = 0
self.log_cycle_handler.log_cycle(
self.ai_config.ai_name,
self.ai_profile.ai_name,
self.created_at,
self.config.cycle_count,
prompt.raw(),
@@ -184,7 +184,7 @@ class Agent(
) = self.prompt_strategy.parse_response_content(llm_response.response)
self.log_cycle_handler.log_cycle(
self.ai_config.ai_name,
self.ai_profile.ai_name,
self.created_at,
self.config.cycle_count,
assistant_reply_dict,
@@ -212,7 +212,7 @@ class Agent(
if command_name == "human_feedback":
result = ActionInterruptedByHuman(feedback=user_input)
self.log_cycle_handler.log_cycle(
self.ai_config.ai_name,
self.ai_profile.ai_name,
self.created_at,
self.config.cycle_count,
user_input,

View File

@@ -18,7 +18,7 @@ if TYPE_CHECKING:
from autogpt.models.command_registry import CommandRegistry
from autogpt.agents.utils.prompt_scratchpad import PromptScratchpad
from autogpt.config.ai_config import AIConfig
from autogpt.config.ai_profile import AIProfile
from autogpt.config.ai_directives import AIDirectives
from autogpt.core.configuration import (
Configurable,
@@ -118,8 +118,8 @@ class BaseAgentConfiguration(SystemConfiguration):
class BaseAgentSettings(SystemSettings):
ai_config: AIConfig
"""The AIConfig or "personality" object associated with this agent."""
ai_profile: AIProfile = Field(default_factory=lambda: AIProfile(ai_name="AutoGPT"))
"""The AIProfile or "personality" of this agent."""
config: BaseAgentConfiguration
"""The configuration for this BaseAgent subsystem instance."""
@@ -137,7 +137,6 @@ class BaseAgent(Configurable[BaseAgentSettings], ABC):
default_settings = BaseAgentSettings(
name="BaseAgent",
description=__doc__,
ai_config=AIConfig(),
config=BaseAgentConfiguration(),
history=EpisodicActionHistory(),
)
@@ -150,7 +149,7 @@ class BaseAgent(Configurable[BaseAgentSettings], ABC):
command_registry: CommandRegistry,
legacy_config: Config,
):
self.ai_config = settings.ai_config
self.ai_profile = settings.ai_profile
self.ai_directives = AIDirectives.from_file(legacy_config.prompt_settings_file)
self.llm_provider = llm_provider
@@ -173,7 +172,7 @@ class BaseAgent(Configurable[BaseAgentSettings], ABC):
# Support multi-inheritance and mixins for subclasses
super(BaseAgent, self).__init__()
logger.debug(f"Created {__class__} '{self.ai_config.ai_name}'")
logger.debug(f"Created {__class__} '{self.ai_profile.ai_name}'")
@property
def llm(self) -> ChatModelInfo:
@@ -273,7 +272,7 @@ class BaseAgent(Configurable[BaseAgentSettings], ABC):
extra_commands += list(scratchpad.commands.values())
prompt = self.prompt_strategy.build_prompt(
ai_config=self.ai_config,
ai_profile=self.ai_profile,
ai_directives=ai_directives,
commands=get_openai_command_specs(
self.command_registry.list_available_commands(self)

View File

@@ -6,7 +6,7 @@ from datetime import datetime
from typing import TYPE_CHECKING, Literal, Optional
if TYPE_CHECKING:
from autogpt.config import AIConfig, Config
from autogpt.config import Config
from autogpt.llm.base import ChatModelResponse, ChatSequence
from autogpt.memory.vector import VectorMemory
from autogpt.models.command_registry import CommandRegistry
@@ -44,7 +44,6 @@ class PlanningAgent(ContextMixin, WorkspaceMixin, BaseAgent):
def __init__(
self,
ai_config: AIConfig,
command_registry: CommandRegistry,
memory: VectorMemory,
triggering_prompt: str,
@@ -52,7 +51,6 @@ class PlanningAgent(ContextMixin, WorkspaceMixin, BaseAgent):
cycle_budget: Optional[int] = None,
):
super().__init__(
ai_config=ai_config,
command_registry=command_registry,
config=config,
default_cycle_instruction=triggering_prompt,
@@ -223,14 +221,14 @@ class PlanningAgent(ContextMixin, WorkspaceMixin, BaseAgent):
self.log_cycle_handler.log_count_within_cycle = 0
self.log_cycle_handler.log_cycle(
self.ai_config.ai_name,
self.ai_profile.ai_name,
self.created_at,
self.cycle_count,
self.event_history.episodes,
"event_history.json",
)
self.log_cycle_handler.log_cycle(
self.ai_config.ai_name,
self.ai_profile.ai_name,
self.created_at,
self.cycle_count,
prompt.raw(),
@@ -249,7 +247,7 @@ class PlanningAgent(ContextMixin, WorkspaceMixin, BaseAgent):
if command_name == "human_feedback":
result = ActionInterruptedByHuman(feedback=user_input)
self.log_cycle_handler.log_cycle(
self.ai_config.ai_name,
self.ai_profile.ai_name,
self.created_at,
self.cycle_count,
user_input,
@@ -333,7 +331,7 @@ class PlanningAgent(ContextMixin, WorkspaceMixin, BaseAgent):
response = command_name, arguments, assistant_reply_dict
self.log_cycle_handler.log_cycle(
self.ai_config.ai_name,
self.ai_profile.ai_name,
self.created_at,
self.cycle_count,
assistant_reply_dict,

View File

@@ -13,7 +13,7 @@ if TYPE_CHECKING:
from autogpt.models.action_history import Episode
from autogpt.agents.utils.exceptions import InvalidAgentResponseError
from autogpt.config import AIConfig, AIDirectives
from autogpt.config import AIProfile, AIDirectives
from autogpt.core.configuration.schema import SystemConfiguration, UserConfigurable
from autogpt.core.prompting import (
ChatPrompt,
@@ -190,7 +190,7 @@ class OneShotAgentPromptStrategy(PromptStrategy):
def build_prompt(
self,
*,
ai_config: AIConfig,
ai_profile: AIProfile,
ai_directives: AIDirectives,
commands: list[CompletionModelFunction],
event_history: list[Episode],
@@ -213,7 +213,7 @@ class OneShotAgentPromptStrategy(PromptStrategy):
extra_messages = []
system_prompt = self.build_system_prompt(
ai_config=ai_config,
ai_profile=ai_profile,
ai_directives=ai_directives,
commands=commands,
include_os_info=include_os_info,
@@ -256,26 +256,26 @@ class OneShotAgentPromptStrategy(PromptStrategy):
def build_system_prompt(
self,
ai_config: AIConfig,
ai_profile: AIProfile,
ai_directives: AIDirectives,
commands: list[CompletionModelFunction],
include_os_info: bool,
) -> str:
system_prompt_parts = (
self._generate_intro_prompt(ai_config)
self._generate_intro_prompt(ai_profile)
+ (self._generate_os_info() if include_os_info else [])
+ [
self.config.body_template.format(
constraints=format_numbered_list(
ai_directives.constraints
+ self._generate_budget_constraint(ai_config.api_budget)
+ self._generate_budget_constraint(ai_profile.api_budget)
),
resources=format_numbered_list(ai_directives.resources),
commands=self._generate_commands_list(commands),
best_practices=format_numbered_list(ai_directives.best_practices),
)
]
+ self._generate_goals_info(ai_config.ai_goals)
+ self._generate_goals_info(ai_profile.ai_goals)
)
# Join non-empty parts together into paragraph format
@@ -349,14 +349,14 @@ class OneShotAgentPromptStrategy(PromptStrategy):
f"{response_format}"
)
def _generate_intro_prompt(self, ai_config: AIConfig) -> list[str]:
def _generate_intro_prompt(self, ai_profile: AIProfile) -> list[str]:
"""Generates the introduction part of the prompt.
Returns:
list[str]: A list of strings forming the introduction part of the prompt.
"""
return [
f"You are {ai_config.ai_name}, {ai_config.ai_role.rstrip('.')}.",
f"You are {ai_profile.ai_name}, {ai_profile.ai_role.rstrip('.')}.",
"Your decisions must always be made independently without seeking "
"user assistance. Play to your strengths as an LLM and pursue "
"simple strategies with no legal complications.",

View File

@@ -15,7 +15,7 @@ from autogpt.agents import AgentThoughts, CommandArgs, CommandName
from autogpt.agents.agent import Agent, AgentConfiguration, AgentSettings
from autogpt.agents.utils.exceptions import InvalidAgentResponseError
from autogpt.app.configurator import apply_overrides_to_config
from autogpt.app.setup import interactive_ai_config_setup
from autogpt.app.setup import interactive_ai_profile_setup
from autogpt.app.spinner import Spinner
from autogpt.app.utils import (
clean_input,
@@ -26,7 +26,7 @@ from autogpt.app.utils import (
)
from autogpt.commands import COMMAND_CATEGORIES
from autogpt.config import (
AIConfig,
AIProfile,
Config,
ConfigBuilder,
assert_config_has_openai_api_key,
@@ -137,7 +137,7 @@ async def run_auto_gpt(
# Create a CommandRegistry instance and scan default folder
command_registry = CommandRegistry.with_command_modules(COMMAND_CATEGORIES, config)
ai_config = await construct_main_ai_config(
ai_profile = await construct_main_ai_profile(
config,
llm_provider=llm_provider,
name=ai_name,
@@ -151,7 +151,7 @@ async def run_auto_gpt(
agent_settings = AgentSettings(
name=Agent.default_settings.name,
description=Agent.default_settings.description,
ai_config=ai_config,
ai_profile=ai_profile,
config=AgentConfiguration(
fast_llm=config.fast_llm,
smart_llm=config.smart_llm,
@@ -283,7 +283,7 @@ async def run_interaction_loop(
"""
# These contain both application config and agent config, so grab them here.
legacy_config = agent.legacy_config
ai_config = agent.ai_config
ai_profile = agent.ai_profile
logger = logging.getLogger(__name__)
cycle_budget = cycles_remaining = _get_cycle_budget(
@@ -350,7 +350,7 @@ async def run_interaction_loop(
###############
# Print the assistant's thoughts and the next command to the user.
update_user(
ai_config,
ai_profile,
command_name,
command_args,
assistant_reply_dict,
@@ -363,7 +363,7 @@ async def run_interaction_loop(
if cycles_remaining == 1: # Last cycle
user_feedback, user_input, new_cycles_remaining = await get_user_feedback(
legacy_config,
ai_config,
ai_profile,
)
if user_feedback == UserFeedback.AUTHORIZE:
@@ -428,7 +428,7 @@ async def run_interaction_loop(
def update_user(
ai_config: AIConfig,
ai_profile: AIProfile,
command_name: CommandName,
command_args: CommandArgs,
assistant_reply_dict: AgentThoughts,
@@ -438,7 +438,7 @@ def update_user(
Args:
config: The program's configuration.
ai_config: The AI's configuration.
ai_profile: The AI's personality/profile
command_name: The name of the command to execute.
command_args: The arguments for the command.
assistant_reply_dict: The assistant's reply.
@@ -446,7 +446,7 @@ def update_user(
logger = logging.getLogger(__name__)
print_assistant_thoughts(
ai_name=ai_config.ai_name,
ai_name=ai_profile.ai_name,
assistant_reply_json_valid=assistant_reply_dict,
speak_mode=speak_mode,
)
@@ -469,13 +469,13 @@ def update_user(
async def get_user_feedback(
config: Config,
ai_config: AIConfig,
ai_profile: AIProfile,
) -> tuple[UserFeedback, str, int | None]:
"""Gets the user's feedback on the assistant's reply.
Args:
config: The program's configuration.
ai_config: The AI's configuration.
ai_profile: The AI's configuration.
Returns:
A tuple of the user's feedback, the user's input, and the number of
@@ -490,7 +490,7 @@ async def get_user_feedback(
f"Enter '{config.authorise_key}' to authorise command, "
f"'{config.authorise_key} -N' to run N continuous commands, "
f"'{config.exit_key}' to exit program, or enter feedback for "
f"{ai_config.ai_name}..."
f"{ai_profile.ai_name}..."
)
user_feedback = None
@@ -530,13 +530,13 @@ async def get_user_feedback(
return user_feedback, user_input, new_cycles_remaining
async def construct_main_ai_config(
async def construct_main_ai_profile(
config: Config,
llm_provider: ChatModelProvider,
name: Optional[str] = None,
role: Optional[str] = None,
goals: tuple[str] = tuple(),
) -> AIConfig:
) -> AIProfile:
"""Construct the prompt for the AI to respond to
Returns:
@@ -544,48 +544,48 @@ async def construct_main_ai_config(
"""
logger = logging.getLogger(__name__)
ai_config = AIConfig.load(config.workdir / config.ai_settings_file)
ai_profile = AIProfile.load(config.ai_settings_file)
# Apply overrides
if name:
ai_config.ai_name = name
ai_profile.ai_name = name
if role:
ai_config.ai_role = role
ai_profile.ai_role = role
if goals:
ai_config.ai_goals = list(goals)
ai_profile.ai_goals = list(goals)
if (
all([name, role, goals])
or config.skip_reprompt
and all([ai_config.ai_name, ai_config.ai_role, ai_config.ai_goals])
and all([ai_profile.ai_name, ai_profile.ai_role, ai_profile.ai_goals])
):
print_attribute("Name :", ai_config.ai_name)
print_attribute("Role :", ai_config.ai_role)
print_attribute("Goals:", ai_config.ai_goals)
print_attribute("Name :", ai_profile.ai_name)
print_attribute("Role :", ai_profile.ai_role)
print_attribute("Goals:", ai_profile.ai_goals)
print_attribute(
"API Budget:",
"infinite" if ai_config.api_budget <= 0 else f"${ai_config.api_budget}",
"infinite" if ai_profile.api_budget <= 0 else f"${ai_profile.api_budget}",
)
elif all([ai_config.ai_name, ai_config.ai_role, ai_config.ai_goals]):
elif all([ai_profile.ai_name, ai_profile.ai_role, ai_profile.ai_goals]):
logger.info(
extra={"title": f"{Fore.GREEN}Welcome back!{Fore.RESET}"},
msg=f"Would you like me to return to being {ai_config.ai_name}?",
msg=f"Would you like me to return to being {ai_profile.ai_name}?",
)
should_continue = await clean_input(
config,
f"""Continue with the last settings?
Name: {ai_config.ai_name}
Role: {ai_config.ai_role}
Goals: {ai_config.ai_goals}
API Budget: {"infinite" if ai_config.api_budget <= 0 else f"${ai_config.api_budget}"}
Name: {ai_profile.ai_name}
Role: {ai_profile.ai_role}
Goals: {ai_profile.ai_goals}
API Budget: {"infinite" if ai_profile.api_budget <= 0 else f"${ai_profile.api_budget}"}
Continue ({config.authorise_key}/{config.exit_key}): """,
)
if should_continue.lower() == config.exit_key:
ai_config = AIConfig()
ai_profile = AIProfile()
if any([not ai_config.ai_name, not ai_config.ai_role, not ai_config.ai_goals]):
ai_config = await interactive_ai_config_setup(config, llm_provider)
ai_config.save(config.workdir / config.ai_settings_file)
if any([not ai_profile.ai_name, not ai_profile.ai_role, not ai_profile.ai_goals]):
ai_profile = await interactive_ai_profile_setup(config, llm_provider)
ai_profile.save(config.ai_settings_file)
if config.restrict_to_workspace:
logger.info(
@@ -595,22 +595,22 @@ Continue ({config.authorise_key}/{config.exit_key}): """,
)
# set the total api budget
api_manager = ApiManager()
api_manager.set_total_budget(ai_config.api_budget)
api_manager.set_total_budget(ai_profile.api_budget)
# Agent Created, print message
logger.info(
f"{Fore.LIGHTBLUE_EX}{ai_config.ai_name}{Fore.RESET} has been created with the following details:",
f"{Fore.LIGHTBLUE_EX}{ai_profile.ai_name}{Fore.RESET} has been created with the following details:",
extra={"preserve_color": True},
)
# Print the ai_config details
print_attribute("Name :", ai_config.ai_name)
print_attribute("Role :", ai_config.ai_role)
# Print the ai_profile details
print_attribute("Name :", ai_profile.ai_name)
print_attribute("Role :", ai_profile.ai_role)
print_attribute("Goals:", "")
for goal in ai_config.ai_goals:
for goal in ai_profile.ai_goals:
logger.info(f"- {goal}")
return ai_config
return ai_profile
def print_assistant_thoughts(

View File

@@ -8,7 +8,7 @@ from jinja2 import Template
from autogpt.app import utils
from autogpt.config import Config
from autogpt.config.ai_config import AIConfig
from autogpt.config.ai_profile import AIProfile
from autogpt.core.resource.model_providers import ChatMessage, ChatModelProvider
from autogpt.logs.helpers import user_friendly_output
from autogpt.prompts.default_prompts import (
@@ -20,19 +20,19 @@ from autogpt.prompts.default_prompts import (
logger = logging.getLogger(__name__)
async def interactive_ai_config_setup(
async def interactive_ai_profile_setup(
config: Config,
llm_provider: ChatModelProvider,
ai_config_template: Optional[AIConfig] = None,
) -> AIConfig:
ai_profile_template: Optional[AIProfile] = None,
) -> AIProfile:
"""Prompt the user for input
Params:
config (Config): The Config object
ai_config_template (AIConfig): The AIConfig object to use as a template
ai_profile_template (AIProfile): The AIProfile object to use as a template
Returns:
AIConfig: The AIConfig object tailored to the user's input
AIProfile: The AIProfile object tailored to the user's input
"""
# Construct the prompt
@@ -42,16 +42,16 @@ async def interactive_ai_config_setup(
title_color=Fore.GREEN,
)
ai_config_template_provided = ai_config_template is not None and any(
ai_profile_template_provided = ai_profile_template is not None and any(
[
ai_config_template.ai_goals,
ai_config_template.ai_name,
ai_config_template.ai_role,
ai_profile_template.ai_goals,
ai_profile_template.ai_name,
ai_profile_template.ai_role,
]
)
user_desire = ""
if not ai_config_template_provided:
if not ai_profile_template_provided:
# Get user desire if command line overrides have not been passed in
user_friendly_output(
title="Create an AI-Assistant:",
@@ -67,13 +67,13 @@ async def interactive_ai_config_setup(
user_desire = DEFAULT_USER_DESIRE_PROMPT # Default prompt
# If user desire contains "--manual" or we have overridden any of the AI configuration
if "--manual" in user_desire or ai_config_template_provided:
if "--manual" in user_desire or ai_profile_template_provided:
user_friendly_output(
"",
title="Manual Mode Selected",
title_color=Fore.GREEN,
)
return await generate_aiconfig_manual(config, ai_config_template)
return await generate_aiconfig_manual(config, ai_profile_template)
else:
try:
@@ -84,27 +84,27 @@ async def interactive_ai_config_setup(
message="Falling back to manual mode.",
title_color=Fore.RED,
)
logger.debug(f"Error during AIConfig generation: {e}")
logger.debug(f"Error during AIProfile generation: {e}")
return await generate_aiconfig_manual(config)
async def generate_aiconfig_manual(
config: Config, ai_config_template: Optional[AIConfig] = None
) -> AIConfig:
config: Config, ai_profile_template: Optional[AIProfile] = None
) -> AIProfile:
"""
Interactively create an AI configuration by prompting the user to provide the name, role, and goals of the AI.
This function guides the user through a series of prompts to collect the necessary information to create
an AIConfig object. The user will be asked to provide a name and role for the AI, as well as up to five
an AIProfile object. The user will be asked to provide a name and role for the AI, as well as up to five
goals. If the user does not provide a value for any of the fields, default values will be used.
Params:
config (Config): The Config object
ai_config_template (AIConfig): The AIConfig object to use as a template
ai_profile_template (AIProfile): The AIProfile object to use as a template
Returns:
AIConfig: An AIConfig object containing the user-defined or default AI name, role, and goals.
AIProfile: An AIProfile object containing the user-defined or default AI name, role, and goals.
"""
# Manual Setup Intro
@@ -115,8 +115,8 @@ async def generate_aiconfig_manual(
title_color=Fore.GREEN,
)
if ai_config_template and ai_config_template.ai_name:
ai_name = ai_config_template.ai_name
if ai_profile_template and ai_profile_template.ai_name:
ai_name = ai_profile_template.ai_name
else:
ai_name = ""
# Get AI Name from User
@@ -135,8 +135,8 @@ async def generate_aiconfig_manual(
title_color=Fore.LIGHTBLUE_EX,
)
if ai_config_template and ai_config_template.ai_role:
ai_role = ai_config_template.ai_role
if ai_profile_template and ai_profile_template.ai_role:
ai_role = ai_profile_template.ai_role
else:
# Get AI Role from User
user_friendly_output(
@@ -150,8 +150,8 @@ async def generate_aiconfig_manual(
ai_role = "an AI designed to autonomously develop and run businesses with the"
" sole goal of increasing your net worth."
if ai_config_template and ai_config_template.ai_goals:
ai_goals = ai_config_template.ai_goals
if ai_profile_template and ai_profile_template.ai_goals:
ai_goals = ai_profile_template.ai_goals
else:
# Enter up to 5 goals for the AI
user_friendly_output(
@@ -200,7 +200,7 @@ async def generate_aiconfig_manual(
)
api_budget = 0.0
return AIConfig(
return AIProfile(
ai_name=ai_name, ai_role=ai_role, ai_goals=ai_goals, api_budget=api_budget
)
@@ -209,15 +209,15 @@ async def generate_aiconfig_automatic(
user_prompt: str,
config: Config,
llm_provider: ChatModelProvider,
) -> AIConfig:
"""Generates an AIConfig object from the given string.
) -> AIProfile:
"""Generates an AIProfile object from the given string.
Returns:
AIConfig: The AIConfig object tailored to the user's input
AIProfile: The AIProfile object tailored to the user's input
"""
system_prompt = DEFAULT_SYSTEM_PROMPT_AICONFIG_AUTOMATIC
prompt_ai_config_automatic = Template(
prompt_ai_profile_automatic = Template(
DEFAULT_TASK_PROMPT_AICONFIG_AUTOMATIC
).render(user_prompt=user_prompt)
# Call LLM with the string as user input
@@ -225,7 +225,7 @@ async def generate_aiconfig_automatic(
await llm_provider.create_chat_completion(
[
ChatMessage.system(system_prompt),
ChatMessage.user(prompt_ai_config_automatic),
ChatMessage.user(prompt_ai_profile_automatic),
],
config.smart_llm,
)
@@ -248,6 +248,6 @@ async def generate_aiconfig_automatic(
ai_goals = re.findall(r"(?<=\n)-\s*(.*)", output)
api_budget = 0.0 # TODO: parse api budget using a regular expression
return AIConfig(
return AIProfile(
ai_name=ai_name, ai_role=ai_role, ai_goals=ai_goals, api_budget=api_budget
)

View File

@@ -28,6 +28,6 @@ from autogpt.core.utils.json_schema import JSONSchema
)
async def ask_user(question: str, agent: Agent) -> str:
resp = await clean_input(
agent.legacy_config, f"{agent.ai_config.ai_name} asks: '{question}': "
agent.legacy_config, f"{agent.ai_profile.ai_name} asks: '{question}': "
)
return f"The user's answer: '{resp}'"

View File

@@ -1,13 +1,13 @@
"""
This module contains the configuration classes for AutoGPT.
"""
from .ai_config import AIConfig
from .ai_profile import AIProfile
from .ai_directives import AIDirectives
from .config import Config, ConfigBuilder, assert_config_has_openai_api_key
__all__ = [
"assert_config_has_openai_api_key",
"AIConfig",
"AIProfile",
"AIDirectives",
"Config",
"ConfigBuilder",

View File

@@ -1,15 +1,12 @@
"""A module that contains the AIConfig class object that contains the configuration"""
from __future__ import annotations
from pathlib import Path
import yaml
from pydantic import BaseModel, Field
class AIConfig(BaseModel):
class AIProfile(BaseModel):
"""
A class object that contains the configuration information for the AI
Object to hold the AI's personality.
Attributes:
ai_name (str): The name of the AI.
@@ -24,7 +21,7 @@ class AIConfig(BaseModel):
api_budget: float = 0.0
@staticmethod
def load(ai_settings_file: str | Path) -> "AIConfig":
def load(ai_settings_file: str | Path) -> "AIProfile":
"""
Returns class object with parameters (ai_name, ai_role, ai_goals, api_budget)
loaded from yaml file if yaml file exists, else returns class with no parameters.
@@ -52,7 +49,7 @@ class AIConfig(BaseModel):
]
api_budget = config_params.get("api_budget", 0.0)
return AIConfig(
return AIProfile(
ai_name=ai_name, ai_role=ai_role, ai_goals=ai_goals, api_budget=api_budget
)

View File

@@ -6,7 +6,7 @@ from agent_protocol import StepHandler, StepResult
from autogpt.agents import Agent
from autogpt.app.main import UserFeedback
from autogpt.commands import COMMAND_CATEGORIES
from autogpt.config import AIConfig, ConfigBuilder
from autogpt.config import AIProfile, ConfigBuilder
from autogpt.logs.helpers import user_friendly_output
from autogpt.memory.vector import get_memory
from autogpt.models.command_registry import CommandRegistry
@@ -71,7 +71,7 @@ async def interaction_step(
return {
"config": agent.config,
"ai_config": agent.ai_config,
"ai_profile": agent.ai_profile,
"result": result,
"assistant_reply_dict": assistant_reply_dict,
"next_step_command_name": next_command_name,
@@ -89,16 +89,15 @@ def bootstrap_agent(task, continuous_mode) -> Agent:
config.memory_backend = "no_memory"
config.workspace_path = Workspace.init_workspace_directory(config)
config.file_logger_path = Workspace.build_file_logger_path(config.workspace_path)
ai_config = AIConfig(
ai_profile = AIProfile(
ai_name="AutoGPT",
ai_role="a multi-purpose AI assistant.",
ai_goals=[task],
)
ai_config.command_registry = command_registry
return Agent(
memory=get_memory(config),
command_registry=command_registry,
ai_config=ai_config,
ai_profile=ai_profile,
config=config,
triggering_prompt=DEFAULT_TRIGGERING_PROMPT,
)

View File

@@ -8,7 +8,7 @@ from pytest_mock import MockerFixture
from autogpt.agents.agent import Agent, AgentConfiguration, AgentSettings
from autogpt.app.main import _configure_openai_provider
from autogpt.config import AIConfig, Config, ConfigBuilder
from autogpt.config import AIProfile, Config, ConfigBuilder
from autogpt.core.resource.model_providers import ChatModelProvider, OpenAIProvider
from autogpt.llm.api_manager import ApiManager
from autogpt.logs.config import configure_logging
@@ -100,7 +100,7 @@ def llm_provider(config: Config) -> OpenAIProvider:
@pytest.fixture
def agent(config: Config, llm_provider: ChatModelProvider) -> Agent:
ai_config = AIConfig(
ai_profile = AIProfile(
ai_name="Base",
ai_role="A base AI",
ai_goals=[],
@@ -117,7 +117,7 @@ def agent(config: Config, llm_provider: ChatModelProvider) -> Agent:
agent_settings = AgentSettings(
name=Agent.default_settings.name,
description=Agent.default_settings.description,
ai_config=ai_config,
ai_profile=ai_profile,
config=AgentConfiguration(
fast_llm=config.fast_llm,
smart_llm=config.smart_llm,

View File

@@ -1,7 +1,7 @@
import pytest
from autogpt.agents.agent import Agent, AgentConfiguration, AgentSettings
from autogpt.config import AIConfig, Config
from autogpt.config import AIProfile, Config
from autogpt.memory.vector import get_memory
from autogpt.models.command_registry import CommandRegistry
@@ -22,7 +22,7 @@ def memory_json_file(config: Config):
def dummy_agent(config: Config, llm_provider, memory_json_file):
command_registry = CommandRegistry()
ai_config = AIConfig(
ai_profile = AIProfile(
ai_name="Dummy Agent",
ai_role="Dummy Role",
ai_goals=[
@@ -35,7 +35,7 @@ def dummy_agent(config: Config, llm_provider, memory_json_file):
agent_settings = AgentSettings(
name=Agent.default_settings.name,
description=Agent.default_settings.description,
ai_config=ai_config,
ai_profile=ai_profile,
config=AgentConfiguration(
fast_llm=config.fast_llm,
smart_llm=config.smart_llm,

View File

@@ -2,8 +2,8 @@ from unittest.mock import patch
import pytest
from autogpt.app.setup import generate_aiconfig_automatic, interactive_ai_config_setup
from autogpt.config.ai_config import AIConfig
from autogpt.app.setup import generate_aiconfig_automatic, interactive_ai_profile_setup
from autogpt.config.ai_profile import AIProfile
@pytest.mark.vcr
@@ -13,12 +13,12 @@ async def test_generate_aiconfig_automatic_default(
):
user_inputs = [""]
with patch("autogpt.app.utils.session.prompt", side_effect=user_inputs):
ai_config = await interactive_ai_config_setup(config, llm_provider)
ai_profile = await interactive_ai_profile_setup(config, llm_provider)
assert isinstance(ai_config, AIConfig)
assert ai_config.ai_name is not None
assert ai_config.ai_role is not None
assert 1 <= len(ai_config.ai_goals) <= 5
assert isinstance(ai_profile, AIProfile)
assert ai_profile.ai_name is not None
assert ai_profile.ai_role is not None
assert 1 <= len(ai_profile.ai_goals) <= 5
@pytest.mark.vcr
@@ -27,12 +27,12 @@ async def test_generate_aiconfig_automatic_typical(
patched_api_requestor, config, llm_provider
):
user_prompt = "Help me create a rock opera about cybernetic giraffes"
ai_config = await generate_aiconfig_automatic(user_prompt, config, llm_provider)
ai_profile = await generate_aiconfig_automatic(user_prompt, config, llm_provider)
assert isinstance(ai_config, AIConfig)
assert ai_config.ai_name is not None
assert ai_config.ai_role is not None
assert 1 <= len(ai_config.ai_goals) <= 5
assert isinstance(ai_profile, AIProfile)
assert ai_profile.ai_name is not None
assert ai_profile.ai_role is not None
assert 1 <= len(ai_profile.ai_goals) <= 5
@pytest.mark.vcr
@@ -50,12 +50,12 @@ async def test_generate_aiconfig_automatic_fallback(
"",
]
with patch("autogpt.app.utils.session.prompt", side_effect=user_inputs):
ai_config = await interactive_ai_config_setup(config, llm_provider)
ai_profile = await interactive_ai_profile_setup(config, llm_provider)
assert isinstance(ai_config, AIConfig)
assert ai_config.ai_name == "Chef-GPT"
assert ai_config.ai_role == "an AI designed to browse bake a cake."
assert ai_config.ai_goals == ["Purchase ingredients", "Bake a cake"]
assert isinstance(ai_profile, AIProfile)
assert ai_profile.ai_name == "Chef-GPT"
assert ai_profile.ai_role == "an AI designed to browse bake a cake."
assert ai_profile.ai_goals == ["Purchase ingredients", "Bake a cake"]
@pytest.mark.vcr
@@ -71,9 +71,9 @@ async def test_prompt_user_manual_mode(patched_api_requestor, config, llm_provid
"",
]
with patch("autogpt.app.utils.session.prompt", side_effect=user_inputs):
ai_config = await interactive_ai_config_setup(config, llm_provider)
ai_profile = await interactive_ai_profile_setup(config, llm_provider)
assert isinstance(ai_config, AIConfig)
assert ai_config.ai_name == "Chef-GPT"
assert ai_config.ai_role == "an AI designed to browse bake a cake."
assert ai_config.ai_goals == ["Purchase ingredients", "Bake a cake"]
assert isinstance(ai_profile, AIProfile)
assert ai_profile.ai_name == "Chef-GPT"
assert ai_profile.ai_role == "an AI designed to browse bake a cake."
assert ai_profile.ai_goals == ["Purchase ingredients", "Bake a cake"]

View File

@@ -1,70 +0,0 @@
from autogpt.config.ai_config import AIConfig
"""
Test cases for the AIConfig class, which handles loads the AI configuration
settings from a YAML file.
"""
def test_goals_are_always_lists_of_strings(tmp_path):
"""Test if the goals attribute is always a list of strings."""
yaml_content = """
ai_goals:
- Goal 1: Make a sandwich
- Goal 2, Eat the sandwich
- Goal 3 - Go to sleep
- "Goal 4: Wake up"
ai_name: McFamished
ai_role: A hungry AI
api_budget: 0.0
"""
ai_settings_file = tmp_path / "ai_settings.yaml"
ai_settings_file.write_text(yaml_content)
ai_config = AIConfig.load(ai_settings_file)
assert len(ai_config.ai_goals) == 4
assert ai_config.ai_goals[0] == "Goal 1: Make a sandwich"
assert ai_config.ai_goals[1] == "Goal 2, Eat the sandwich"
assert ai_config.ai_goals[2] == "Goal 3 - Go to sleep"
assert ai_config.ai_goals[3] == "Goal 4: Wake up"
ai_settings_file.write_text("")
ai_config.save(ai_settings_file)
yaml_content2 = """ai_goals:
- 'Goal 1: Make a sandwich'
- Goal 2, Eat the sandwich
- Goal 3 - Go to sleep
- 'Goal 4: Wake up'
ai_name: McFamished
ai_role: A hungry AI
api_budget: 0.0
"""
assert ai_settings_file.read_text() == yaml_content2
def test_ai_config_file_not_exists(workspace):
"""Test if file does not exist."""
ai_settings_file = workspace.get_path("ai_settings.yaml")
ai_config = AIConfig.load(str(ai_settings_file))
assert ai_config.ai_name == ""
assert ai_config.ai_role == ""
assert ai_config.ai_goals == []
assert ai_config.api_budget == 0.0
def test_ai_config_file_is_empty(workspace):
"""Test if file does not exist."""
ai_settings_file = workspace.get_path("ai_settings.yaml")
ai_settings_file.write_text("")
ai_config = AIConfig.load(str(ai_settings_file))
assert ai_config.ai_name == ""
assert ai_config.ai_role == ""
assert ai_config.ai_goals == []
assert ai_config.api_budget == 0.0

View File

@@ -0,0 +1,70 @@
from autogpt.config.ai_profile import AIProfile
"""
Test cases for the AIProfile class, which handles loads the AI configuration
settings from a YAML file.
"""
def test_goals_are_always_lists_of_strings(tmp_path):
"""Test if the goals attribute is always a list of strings."""
yaml_content = """
ai_goals:
- Goal 1: Make a sandwich
- Goal 2, Eat the sandwich
- Goal 3 - Go to sleep
- "Goal 4: Wake up"
ai_name: McFamished
ai_role: A hungry AI
api_budget: 0.0
"""
ai_settings_file = tmp_path / "ai_settings.yaml"
ai_settings_file.write_text(yaml_content)
ai_profile = AIProfile.load(ai_settings_file)
assert len(ai_profile.ai_goals) == 4
assert ai_profile.ai_goals[0] == "Goal 1: Make a sandwich"
assert ai_profile.ai_goals[1] == "Goal 2, Eat the sandwich"
assert ai_profile.ai_goals[2] == "Goal 3 - Go to sleep"
assert ai_profile.ai_goals[3] == "Goal 4: Wake up"
ai_settings_file.write_text("")
ai_profile.save(ai_settings_file)
yaml_content2 = """ai_goals:
- 'Goal 1: Make a sandwich'
- Goal 2, Eat the sandwich
- Goal 3 - Go to sleep
- 'Goal 4: Wake up'
ai_name: McFamished
ai_role: A hungry AI
api_budget: 0.0
"""
assert ai_settings_file.read_text() == yaml_content2
def test_ai_profile_file_not_exists(workspace):
"""Test if file does not exist."""
ai_settings_file = workspace.get_path("ai_settings.yaml")
ai_profile = AIProfile.load(str(ai_settings_file))
assert ai_profile.ai_name == ""
assert ai_profile.ai_role == ""
assert ai_profile.ai_goals == []
assert ai_profile.api_budget == 0.0
def test_ai_profile_file_is_empty(workspace):
"""Test if file does not exist."""
ai_settings_file = workspace.get_path("ai_settings.yaml")
ai_settings_file.write_text("")
ai_profile = AIProfile.load(str(ai_settings_file))
assert ai_profile.ai_name == ""
assert ai_profile.ai_role == ""
assert ai_profile.ai_goals == []
assert ai_profile.api_budget == 0.0

View File

@@ -42,21 +42,21 @@ def kubernetes_agent(
command_registry.import_commands("autogpt.app")
# Define all the settings of our challenged agent
ai_config = AIConfig(
ai_profile = AIProfile(
ai_name="Kubernetes",
ai_role="an autonomous agent that specializes in creating Kubernetes deployment templates.",
ai_goals=[
"Write a simple kubernetes deployment file and save it as a kube.yaml.",
],
)
ai_config.command_registry = command_registry
ai_profile.command_registry = command_registry
system_prompt = ai_config.construct_full_prompt()
system_prompt = ai_profile.construct_full_prompt()
agent_test_config.set_continuous_mode(False)
agent = Agent(
memory=memory_json_file,
command_registry=command_registry,
config=ai_config,
config=ai_profile,
next_action_count=0,
triggering_prompt=DEFAULT_TRIGGERING_PROMPT,
)