Skip to content

Commit

Permalink
refactor(agent, forge): Move library code from autogpt to forge (#…
Browse files Browse the repository at this point in the history
…7106)

Moved from `autogpt` to `forge`:
- `autogpt.config`          -> `forge.config`
- `autogpt.processing`      -> `forge.content_processing`
- `autogpt.file_storage`    -> `forge.file_storage`
- `autogpt.logs`            -> `forge.logging`
- `autogpt.speech`          -> `forge.speech`
- `autogpt.agents.(base|components|protocols)`  -> `forge.agent.*`
- `autogpt.command_decorator`                   -> `forge.command.decorator`
- `autogpt.models.(command|command_parameter)`  -> `forge.command.(command|parameter)`
- `autogpt.(commands|components|features)`      -> `forge.components`
- `autogpt.core.utils.json_utils`           -> `forge.json.parsing`
- `autogpt.prompts.utils`                   -> `forge.llm.prompting.utils`
- `autogpt.core.prompting.(base|schema|utils)`    -> `forge.llm.prompting.*`
- `autogpt.core.resource.model_providers`   -> `forge.llm.providers`
- `autogpt.llm.providers.openai` + `autogpt.core.resource.model_providers.utils`
                                            -> `forge.llm.providers.utils`
- `autogpt.models.action_history:Action*`   -> `forge.models.action`
- `autogpt.core.configuration.schema`       -> `forge.models.config`
- `autogpt.core.utils.json_schema`          -> `forge.models.json_schema`
- `autogpt.core.resource.schema`            -> `forge.models.providers`
- `autogpt.models.utils`                    -> `forge.models.utils`
- `forge.sdk.(errors|utils)` + `autogpt.utils.(exceptions|file_operations_utils|validators)`
                        -> `forge.utils.(exceptions|file_operations|url_validator)`
- `autogpt.utils.utils` -> `forge.utils.const` + `forge.utils.yaml_validator`

Moved within `forge`:
- forge/prompts/* -> forge/llm/prompting/*

The rest are mostly import updates, and some sporadic removals and necessary updates (for example to fix circular deps):
- Changed `CommandOutput = Any` to remove coupling with `ContextItem` (no longer needed)
- Removed unused `Singleton` class
- Reluctantly moved `speech` to forge due to coupling (tts needs to be changed into component)
- Moved `function_specs_from_commands` and `core/resource/model_providers` to `llm/providers` (resources were a `core` thing and are no longer relevant)
- Keep tests in `autogpt` to reduce changes in this PR
- Removed unused memory-related code from tests
- Removed duplicated classes: `FancyConsoleFormatter`, `BelowLevelFilter`
- `prompt_settings.yaml` is in both `autogpt` and `forge` because for some reason doesn't work when placed in just one dir (need to be taken care of)
- Removed `config` param from `clean_input`, it wasn't used and caused circular dependency
- Renamed `BaseAgentActionProposal` to `ActionProposal`
- Updated `pyproject.toml` in `forge` and `autogpt`
- Moved `Action*` models from `forge/components/action_history/model.py` to `forge/models/action.py` as those are relevant to the entire agent and not just `EventHistoryComponent` + to reduce coupling
- Renamed `DEFAULT_ASK_COMMAND` to `ASK_COMMAND` and `DEFAULT_FINISH_COMMAND` to `FINISH_COMMAND`
- Renamed `AutoGptFormatter` to `ForgeFormatter` and moved to `forge`

Includes changes from PR #7148
---------

Co-authored-by: Reinier van der Leer <[email protected]>
  • Loading branch information
kcze and Pwuts committed May 15, 2024
1 parent 4f81246 commit e8d7dfa
Show file tree
Hide file tree
Showing 188 changed files with 2,053 additions and 1,207 deletions.
8 changes: 5 additions & 3 deletions autogpts/autogpt/agbenchmark_config/benchmarks.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
import sys
from pathlib import Path

from forge.config.ai_profile import AIProfile
from forge.config.config import ConfigBuilder
from forge.file_storage import FileStorageBackendName, get_storage
from forge.logging.config import configure_logging

from autogpt.agent_manager.agent_manager import AgentManager
from autogpt.agents.agent import Agent, AgentConfiguration, AgentSettings
from autogpt.app.main import _configure_llm_provider, run_interaction_loop
from autogpt.config import AIProfile, ConfigBuilder
from autogpt.file_storage import FileStorageBackendName, get_storage
from autogpt.logs.config import configure_logging

LOG_DIR = Path(__file__).parent / "logs"

Expand Down
9 changes: 6 additions & 3 deletions autogpts/autogpt/autogpt/agent_factory/configurators.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
from typing import Optional

from forge.config.ai_directives import AIDirectives
from forge.config.ai_profile import AIProfile
from forge.config.config import Config
from forge.file_storage.base import FileStorage
from forge.llm.providers import ChatModelProvider

from autogpt.agents.agent import Agent, AgentConfiguration, AgentSettings
from autogpt.config import AIDirectives, AIProfile, Config
from autogpt.core.resource.model_providers import ChatModelProvider
from autogpt.file_storage.base import FileStorage


def create_agent(
Expand Down
14 changes: 7 additions & 7 deletions autogpts/autogpt/autogpt/agent_factory/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@

from typing import TYPE_CHECKING

from autogpt.config.ai_directives import AIDirectives
from autogpt.file_storage.base import FileStorage

from .configurators import _configure_agent
from .profile_generator import generate_agent_profile_for_task
from forge.config.ai_directives import AIDirectives
from forge.file_storage.base import FileStorage

if TYPE_CHECKING:
from autogpt.agents.agent import Agent
from autogpt.config import Config
from autogpt.core.resource.model_providers.schema import ChatModelProvider
from forge.config.config import Config
from forge.llm.providers.schema import ChatModelProvider

from .configurators import _configure_agent
from .profile_generator import generate_agent_profile_for_task


async def generate_agent_for_task(
Expand Down
16 changes: 7 additions & 9 deletions autogpts/autogpt/autogpt/agent_factory/profile_generator.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
import json
import logging

from autogpt.config import AIDirectives, AIProfile, Config
from autogpt.core.configuration import SystemConfiguration, UserConfigurable
from autogpt.core.prompting import (
ChatPrompt,
LanguageModelClassification,
PromptStrategy,
)
from autogpt.core.resource.model_providers.schema import (
from forge.config.ai_directives import AIDirectives
from forge.config.ai_profile import AIProfile
from forge.config.config import Config
from forge.llm.prompting import ChatPrompt, LanguageModelClassification, PromptStrategy
from forge.llm.providers.schema import (
AssistantChatMessage,
ChatMessage,
ChatModelProvider,
CompletionModelFunction,
)
from autogpt.core.utils.json_schema import JSONSchema
from forge.models.config import SystemConfiguration, UserConfigurable
from forge.models.json_schema import JSONSchema

logger = logging.getLogger(__name__)

Expand Down
3 changes: 2 additions & 1 deletion autogpts/autogpt/autogpt/agent_manager/agent_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
import uuid
from pathlib import Path

from forge.file_storage.base import FileStorage

from autogpt.agents.agent import AgentSettings
from autogpt.file_storage.base import FileStorage


class AgentManager:
Expand Down
6 changes: 2 additions & 4 deletions autogpts/autogpt/autogpt/agents/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
from .agent import Agent, OneShotAgentActionProposal
from .base import BaseAgent, BaseAgentActionProposal
from .agent import Agent
from .prompt_strategies.one_shot import OneShotAgentActionProposal

__all__ = [
"BaseAgent",
"Agent",
"BaseAgentActionProposal",
"OneShotAgentActionProposal",
]
85 changes: 44 additions & 41 deletions autogpts/autogpt/autogpt/agents/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,66 +6,67 @@
from typing import TYPE_CHECKING, Optional

import sentry_sdk
from pydantic import Field

from autogpt.commands.execute_code import CodeExecutorComponent
from autogpt.commands.git_operations import GitOperationsComponent
from autogpt.commands.image_gen import ImageGeneratorComponent
from autogpt.commands.system import SystemComponent
from autogpt.commands.user_interaction import UserInteractionComponent
from autogpt.commands.web_search import WebSearchComponent
from autogpt.commands.web_selenium import WebSeleniumComponent
from autogpt.components.event_history import EventHistoryComponent
from autogpt.core.configuration import Configurable
from autogpt.core.prompting import ChatPrompt
from autogpt.core.resource.model_providers import (
from forge.agent.base import BaseAgent, BaseAgentConfiguration, BaseAgentSettings
from forge.agent.protocols import (
AfterExecute,
AfterParse,
CommandProvider,
DirectiveProvider,
MessageProvider,
)
from forge.command.command import Command, CommandOutput
from forge.components.action_history import (
ActionHistoryComponent,
EpisodicActionHistory,
)
from forge.components.code_executor.code_executor import CodeExecutorComponent
from forge.components.context.context import AgentContext, ContextComponent
from forge.components.file_manager import FileManagerComponent
from forge.components.git_operations import GitOperationsComponent
from forge.components.image_gen import ImageGeneratorComponent
from forge.components.system import SystemComponent
from forge.components.user_interaction import UserInteractionComponent
from forge.components.watchdog import WatchdogComponent
from forge.components.web import WebSearchComponent, WebSeleniumComponent
from forge.file_storage.base import FileStorage
from forge.llm.prompting.schema import ChatPrompt
from forge.llm.providers import (
AssistantFunctionCall,
ChatMessage,
ChatModelProvider,
ChatModelResponse,
)
from autogpt.core.runner.client_lib.logging.helpers import dump_prompt
from autogpt.file_storage.base import FileStorage
from autogpt.llm.providers.openai import function_specs_from_commands
from autogpt.logs.log_cycle import (
CURRENT_CONTEXT_FILE_NAME,
NEXT_ACTION_FILE_NAME,
USER_INPUT_FILE_NAME,
LogCycleHandler,
)
from autogpt.models.action_history import (
from forge.llm.providers.utils import function_specs_from_commands
from forge.models.action import (
ActionErrorResult,
ActionInterruptedByHuman,
ActionResult,
ActionSuccessResult,
EpisodicActionHistory,
)
from autogpt.models.command import Command, CommandOutput
from autogpt.utils.exceptions import (
from forge.models.config import Configurable
from forge.utils.exceptions import (
AgentException,
AgentTerminated,
CommandExecutionError,
UnknownCommandError,
)
from pydantic import Field

from autogpt.app.log_cycle import (
CURRENT_CONTEXT_FILE_NAME,
NEXT_ACTION_FILE_NAME,
USER_INPUT_FILE_NAME,
LogCycleHandler,
)
from autogpt.core.runner.client_lib.logging.helpers import dump_prompt

from .base import BaseAgent, BaseAgentConfiguration, BaseAgentSettings
from .features.agent_file_manager import FileManagerComponent
from .features.context import AgentContext, ContextComponent
from .features.watchdog import WatchdogComponent
from .prompt_strategies.one_shot import (
OneShotAgentActionProposal,
OneShotAgentPromptStrategy,
)
from .protocols import (
AfterExecute,
AfterParse,
CommandProvider,
DirectiveProvider,
MessageProvider,
)

if TYPE_CHECKING:
from autogpt.config import Config
from forge.config.config import Config

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -114,13 +115,13 @@ def __init__(

# Components
self.system = SystemComponent(legacy_config, settings.ai_profile)
self.history = EventHistoryComponent(
self.history = ActionHistoryComponent(
settings.history,
self.send_token_limit,
lambda x: self.llm_provider.count_tokens(x, self.llm.name),
legacy_config,
llm_provider,
)
).run_after(WatchdogComponent)
self.user_interaction = UserInteractionComponent(legacy_config)
self.file_manager = FileManagerComponent(settings, file_storage)
self.code_executor = CodeExecutorComponent(
Expand All @@ -135,7 +136,9 @@ def __init__(
self.web_search = WebSearchComponent(legacy_config)
self.web_selenium = WebSeleniumComponent(legacy_config, llm_provider, self.llm)
self.context = ContextComponent(self.file_manager.workspace, settings.context)
self.watchdog = WatchdogComponent(settings.config, settings.history)
self.watchdog = WatchdogComponent(settings.config, settings.history).run_after(
ContextComponent
)

self.created_at = datetime.now().strftime("%Y%m%d_%H%M%S")
"""Timestamp the agent was created; only used for structured debug logging."""
Expand Down
30 changes: 13 additions & 17 deletions autogpts/autogpt/autogpt/agents/prompt_strategies/one_shot.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,22 @@
from logging import Logger

import distro
from pydantic import Field

from autogpt.agents.base import BaseAgentActionProposal
from autogpt.config import AIDirectives, AIProfile
from autogpt.core.configuration.schema import SystemConfiguration, UserConfigurable
from autogpt.core.prompting import (
ChatPrompt,
LanguageModelClassification,
PromptStrategy,
)
from autogpt.core.resource.model_providers.schema import (
from forge.config.ai_directives import AIDirectives
from forge.config.ai_profile import AIProfile
from forge.json.parsing import extract_dict_from_json
from forge.llm.prompting import ChatPrompt, LanguageModelClassification, PromptStrategy
from forge.llm.prompting.utils import format_numbered_list
from forge.llm.providers.schema import (
AssistantChatMessage,
ChatMessage,
CompletionModelFunction,
)
from autogpt.core.utils.json_schema import JSONSchema
from autogpt.core.utils.json_utils import extract_dict_from_json
from autogpt.models.utils import ModelWithSummary
from autogpt.prompts.utils import format_numbered_list
from autogpt.utils.exceptions import InvalidAgentResponseError
from forge.models.action import ActionProposal
from forge.models.config import SystemConfiguration, UserConfigurable
from forge.models.json_schema import JSONSchema
from forge.models.utils import ModelWithSummary
from forge.utils.exceptions import InvalidAgentResponseError
from pydantic import Field

_RESPONSE_INTERFACE_NAME = "AssistantResponse"

Expand All @@ -46,7 +42,7 @@ def summary(self) -> str:
return self.text


class OneShotAgentActionProposal(BaseAgentActionProposal):
class OneShotAgentActionProposal(ActionProposal):
thoughts: AssistantThoughts


Expand Down
21 changes: 10 additions & 11 deletions autogpts/autogpt/autogpt/app/agent_protocol_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import RedirectResponse, StreamingResponse
from fastapi.staticfiles import StaticFiles
from forge.config.config import Config
from forge.file_storage import FileStorage
from forge.llm.providers import ChatModelProvider, ModelProviderBudget
from forge.models.action import ActionErrorResult, ActionSuccessResult
from forge.sdk.db import AgentDB
from forge.sdk.errors import NotFoundError
from forge.sdk.middlewares import AgentMiddleware
from forge.sdk.model import (
Artifact,
Expand All @@ -24,6 +27,8 @@
TaskStepsListResponse,
)
from forge.sdk.routes.agent_protocol import base_router
from forge.utils.const import ASK_COMMAND, FINISH_COMMAND
from forge.utils.exceptions import AgentFinished, NotFoundError
from hypercorn.asyncio import serve as hypercorn_serve
from hypercorn.config import Config as HypercornConfig
from sentry_sdk import set_user
Expand All @@ -32,12 +37,6 @@
from autogpt.agent_factory.generators import generate_agent_for_task
from autogpt.agent_manager import AgentManager
from autogpt.app.utils import is_port_free
from autogpt.config import Config
from autogpt.core.resource.model_providers import ChatModelProvider, ModelProviderBudget
from autogpt.file_storage import FileStorage
from autogpt.models.action_history import ActionErrorResult, ActionSuccessResult
from autogpt.utils.exceptions import AgentFinished
from autogpt.utils.utils import DEFAULT_ASK_COMMAND, DEFAULT_FINISH_COMMAND

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -226,7 +225,7 @@ async def execute_step(self, task_id: str, step_request: StepRequestBody) -> Ste
input=step_request,
is_last=(
last_proposal is not None
and last_proposal.use_tool.name == DEFAULT_FINISH_COMMAND
and last_proposal.use_tool.name == FINISH_COMMAND
and execute_approved
),
)
Expand All @@ -240,7 +239,7 @@ async def execute_step(self, task_id: str, step_request: StepRequestBody) -> Ste
)
)

if last_proposal.use_tool.name == DEFAULT_ASK_COMMAND:
if last_proposal.use_tool.name == ASK_COMMAND:
tool_result = ActionSuccessResult(outputs=user_input)
agent.event_history.register_result(tool_result)
elif execute_approved:
Expand Down Expand Up @@ -296,13 +295,13 @@ async def execute_step(self, task_id: str, step_request: StepRequestBody) -> Ste
+ ("\n\n" if "\n" in str(tool_result) else " ")
+ f"{tool_result}\n\n"
)
if last_proposal and last_proposal.use_tool.name != DEFAULT_ASK_COMMAND
if last_proposal and last_proposal.use_tool.name != ASK_COMMAND
else ""
)
output += f"{assistant_response.thoughts.speak}\n\n"
output += (
f"Next Command: {next_tool_to_use}"
if next_tool_to_use.name != DEFAULT_ASK_COMMAND
if next_tool_to_use.name != ASK_COMMAND
else next_tool_to_use.arguments["question"]
)

Expand Down
3 changes: 1 addition & 2 deletions autogpts/autogpt/autogpt/app/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
from typing import Optional

import click

from autogpt.logs.config import LogFormatName
from forge.logging.config import LogFormatName

from .telemetry import setup_telemetry

Expand Down

0 comments on commit e8d7dfa

Please sign in to comment.