diff --git a/autogpt/agent/agent_manager.py b/autogpt/agent/agent_manager.py index 1283fdaefbaf..17fb35d87841 100644 --- a/autogpt/agent/agent_manager.py +++ b/autogpt/agent/agent_manager.py @@ -4,9 +4,8 @@ from typing import List from autogpt.config.config import Config -from autogpt.llm import create_chat_completion +from autogpt.llm import Message, create_chat_completion from autogpt.singleton import Singleton -from autogpt.types.openai import Message class AgentManager(metaclass=Singleton): diff --git a/autogpt/llm/__init__.py b/autogpt/llm/__init__.py index 3a958285de06..2a6f0b8fe2d6 100644 --- a/autogpt/llm/__init__.py +++ b/autogpt/llm/__init__.py @@ -1,4 +1,13 @@ from autogpt.llm.api_manager import ApiManager +from autogpt.llm.base import ( + ChatModelInfo, + ChatModelResponse, + EmbeddingModelInfo, + EmbeddingModelResponse, + LLMResponse, + Message, + ModelInfo, +) from autogpt.llm.chat import chat_with_ai, create_chat_message, generate_context from autogpt.llm.llm_utils import ( call_ai_function, @@ -10,6 +19,13 @@ __all__ = [ "ApiManager", + "Message", + "ModelInfo", + "ChatModelInfo", + "EmbeddingModelInfo", + "LLMResponse", + "ChatModelResponse", + "EmbeddingModelResponse", "create_chat_message", "generate_context", "chat_with_ai", diff --git a/autogpt/llm/base.py b/autogpt/llm/base.py new file mode 100644 index 000000000000..722e0f0f1ed1 --- /dev/null +++ b/autogpt/llm/base.py @@ -0,0 +1,65 @@ +from dataclasses import dataclass, field +from typing import List, TypedDict + + +class Message(TypedDict): + """OpenAI Message object containing a role and the message content""" + + role: str + content: str + + +@dataclass +class ModelInfo: + """Struct for model information. + + Would be lovely to eventually get this directly from APIs, but needs to be scraped from + websites for now. + + """ + + name: str + prompt_token_cost: float + completion_token_cost: float + max_tokens: int + + +@dataclass +class ChatModelInfo(ModelInfo): + """Struct for chat model information.""" + + pass + + +@dataclass +class EmbeddingModelInfo(ModelInfo): + """Struct for embedding model information.""" + + embedding_dimensions: int + + +@dataclass +class LLMResponse: + """Standard response struct for a response from an LLM model.""" + + model_info: ModelInfo + prompt_tokens_used: int = 0 + completion_tokens_used: int = 0 + + +@dataclass +class EmbeddingModelResponse(LLMResponse): + """Standard response struct for a response from an embedding model.""" + + embedding: List[float] = field(default_factory=list) + + def __post_init__(self): + if self.completion_tokens_used: + raise ValueError("Embeddings should not have completion tokens used.") + + +@dataclass +class ChatModelResponse(LLMResponse): + """Standard response struct for a response from an LLM model.""" + + content: str = None diff --git a/autogpt/llm/chat.py b/autogpt/llm/chat.py index 119468c39f3e..e0f0226d1f16 100644 --- a/autogpt/llm/chat.py +++ b/autogpt/llm/chat.py @@ -5,13 +5,13 @@ from autogpt.config import Config from autogpt.llm.api_manager import ApiManager +from autogpt.llm.base import Message from autogpt.llm.llm_utils import create_chat_completion from autogpt.llm.token_counter import count_message_tokens from autogpt.logs import logger from autogpt.memory_management.store_memory import ( save_memory_trimmed_from_context_window, ) -from autogpt.types.openai import Message cfg = Config() diff --git a/autogpt/llm/llm_utils.py b/autogpt/llm/llm_utils.py index c1ba5fa5e0f5..9a2400c79478 100644 --- a/autogpt/llm/llm_utils.py +++ b/autogpt/llm/llm_utils.py @@ -10,8 +10,8 @@ from autogpt.config import Config from autogpt.llm.api_manager import ApiManager +from autogpt.llm.base import Message from autogpt.logs import logger -from autogpt.types.openai import Message def retry_openai_api( diff --git a/autogpt/llm/providers/__init__.py b/autogpt/llm/providers/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/autogpt/llm/providers/openai.py b/autogpt/llm/providers/openai.py new file mode 100644 index 000000000000..188d5cf75b46 --- /dev/null +++ b/autogpt/llm/providers/openai.py @@ -0,0 +1,37 @@ +from autogpt.llm.base import ChatModelInfo, EmbeddingModelInfo + +OPEN_AI_CHAT_MODELS = { + "gpt-3.5-turbo": ChatModelInfo( + name="gpt-3.5-turbo", + prompt_token_cost=0.002, + completion_token_cost=0.002, + max_tokens=4096, + ), + "gpt-4": ChatModelInfo( + name="gpt-4", + prompt_token_cost=0.03, + completion_token_cost=0.06, + max_tokens=8192, + ), + "gpt-4-32k": ChatModelInfo( + name="gpt-4-32k", + prompt_token_cost=0.06, + completion_token_cost=0.12, + max_tokens=32768, + ), +} + +OPEN_AI_EMBEDDING_MODELS = { + "text-embedding-ada-002": EmbeddingModelInfo( + name="text-embedding-ada-002", + prompt_token_cost=0.0004, + completion_token_cost=0.0, + max_tokens=8191, + embedding_dimensions=1536, + ), +} + +OPEN_AI_MODELS = { + **OPEN_AI_CHAT_MODELS, + **OPEN_AI_EMBEDDING_MODELS, +} diff --git a/autogpt/llm/token_counter.py b/autogpt/llm/token_counter.py index 2d50547b4ab6..5e13920ed8dd 100644 --- a/autogpt/llm/token_counter.py +++ b/autogpt/llm/token_counter.py @@ -5,8 +5,8 @@ import tiktoken +from autogpt.llm.base import Message from autogpt.logs import logger -from autogpt.types.openai import Message def count_message_tokens( diff --git a/autogpt/types/openai.py b/autogpt/types/openai.py deleted file mode 100644 index 2af85785b4f6..000000000000 --- a/autogpt/types/openai.py +++ /dev/null @@ -1,9 +0,0 @@ -"""Type helpers for working with the OpenAI library""" -from typing import TypedDict - - -class Message(TypedDict): - """OpenAI Message object containing a role and the message content""" - - role: str - content: str