Merge pull request #25 from SZubarev/feature/amazon-bedrock

Added Amazon Bedrock provider
This commit is contained in:
2024-11-01 08:53:46 -04:00
committed by GitHub
7 changed files with 106 additions and 6 deletions
+1
View File
@@ -4,3 +4,4 @@ export GROQ_API_KEY=""
export OLLAMA_HOST_URL=""
export OPENAI_API_KEY=""
export XAI_API_KEY=""
export AMAZON_PROFILE_NAME=""
+7 -2
View File
@@ -24,10 +24,12 @@ To specify a specific provider or model, you can use the `llm_provider` and `llm
- [**Ollama**](https://ollama.com)
- [**OpenAI's GPT**](https://openai.com/gpt)
- [**xAI's Grok**](https://x.ai/)
- [**Amazon Bedrock**](https://aws.amazon.com/bedrock/)
If you want to see Simplemind support, additional providers or models, please send a pull request!
## Why SimpleMind?
- **Intuitive**: Built with Pythonic simplicity and readability in mind.
- **For Humans**: Emphasizes a human-friendly interface, just like `requests` for HTTP.
- **Open Source**: Simplemind is open source, and contributions are always welcome!
@@ -56,7 +58,6 @@ Next, import Simplemind and start using it:
import simplemind as sm
```
## Examples
Here are some examples of how to use Simplemind:
@@ -190,6 +191,7 @@ conversation.add_message(
text="Please write a poem about the moon",
)
```
```pycon
>>> conversation.send()
In the vast expanse where stars do play,
@@ -233,9 +235,10 @@ Simplemind uses [logfire](https://logfire.ai) for logging. To enable logging, ca
Please see the [examples](examples) directory for executable examples.
-------------------
---
## Contributing
We welcome contributions of all kinds. Feel free to open issues for bug reports or feature requests, and submit pull requests to make SimpleMind even better.
To get started:
@@ -246,7 +249,9 @@ To get started:
4. Submit a pull request.
## License
Simplemind is licensed under the Apache 2.0 License.
## Acknowledgements
Simplemind is inspired by the philosophy of "code for humans" and aims to make working with AI models accessible to all. Special thanks to the open-source community for their contributions and inspiration.
+2 -1
View File
@@ -7,5 +7,6 @@ from .groq import Groq
from .ollama import Ollama
from .openai import OpenAI
from .xai import XAI
from .amazon import Amazon
providers: List[Type[BaseProvider]] = [Anthropic, Gemini, Groq, OpenAI, Ollama, XAI]
providers: List[Type[BaseProvider]] = [Anthropic, Gemini, Groq, OpenAI, Ollama, XAI, Amazon]
+87
View File
@@ -0,0 +1,87 @@
from typing import Type, TypeVar
import instructor
import anthropic
from pydantic import BaseModel
from ._base import BaseProvider
from ..settings import settings
T = TypeVar("T", bound=BaseModel)
PROVIDER_NAME = "amazon"
DEFAULT_MODEL = "anthropic.claude-3-sonnet-20240229-v1:0"
DEFAULT_MAX_TOKENS = 5000
class Amazon(BaseProvider):
NAME = PROVIDER_NAME
DEFAULT_MODEL = DEFAULT_MODEL
def __init__(self, profile_name: str | None = None):
self.profile_name = profile_name or settings.AMAZON_PROFILE_NAME
@property
def client(self):
"""The AnthropicBedrock client."""
if not self.profile_name:
raise ValueError("Profile name is not provided")
return anthropic.AnthropicBedrock(aws_profile=self.profile_name)
@property
def structured_client(self):
"""A client patched with Instructor."""
return instructor.from_anthropic(self.client)
def send_conversation(self, conversation: "Conversation", **kwargs):
"""Send a conversation to the OpenAI API."""
from ..models import Message
messages = [
{"role": msg.role, "content": msg.text} for msg in conversation.messages
]
response = self.client.chat.completions.create(
model=conversation.llm_model or DEFAULT_MODEL, messages=messages, **kwargs
)
# Get the response content from the OpenAI response
assistant_message = response.choices[0].message
# Create and return a properly formatted Message instance
return Message(
role="assistant",
text=assistant_message.content or "",
raw=response,
llm_model=conversation.llm_model or DEFAULT_MODEL,
llm_provider=PROVIDER_NAME,
)
def structured_response(self, prompt, response_model: Type[T], *, llm_model: str | None = None, **kwargs) -> T:
# Ensure messages are provided in kwargs
messages = [
{"role": "user", "content": prompt},
]
response = self.structured_client.chat.completions.create(
messages=messages,
model=llm_model or self.DEFAULT_MODEL,
response_model=response_model,
max_tokens = DEFAULT_MAX_TOKENS,
**kwargs,
)
return response
def generate_text(self, prompt, *, llm_model, **kwargs):
messages = [
{"role": "user", "content": prompt},
]
response = self.client.messages.create(
model=llm_model or self.DEFAULT_MODEL,
messages=messages,
max_tokens=DEFAULT_MAX_TOKENS,
**kwargs,
)
return response.content[0].text
+1
View File
@@ -41,6 +41,7 @@ class LoggingConfig(BaseSettings):
class Settings(BaseSettings):
"""The class that holds all the API keys for the application."""
AMAZON_PROFILE_NAME: Optional[str] = Field("default", description="AWS Named Profile")
ANTHROPIC_API_KEY: Optional[SecretStr] = Field(
None, description="API key for Anthropic"
)
+5 -2
View File
@@ -1,7 +1,9 @@
from pydantic import BaseModel
import pytest
from simplemind.providers import Anthropic, Gemini, Groq, Ollama, OpenAI
from simplemind.providers import Anthropic, Gemini, OpenAI, Groq, Ollama, Amazon
from pydantic import BaseModel
class ResponseModel(BaseModel):
@@ -16,6 +18,7 @@ class ResponseModel(BaseModel):
OpenAI,
Groq,
Ollama,
Amazon
],
)
def test_generate_data(provider_cls):
+3 -1
View File
@@ -1,5 +1,6 @@
import pytest
from simplemind.providers import Anthropic, Gemini, Groq, Ollama, OpenAI
from simplemind.providers import Anthropic, Gemini, OpenAI, Groq, Ollama, Amazon
@pytest.mark.parametrize(
@@ -10,6 +11,7 @@ from simplemind.providers import Anthropic, Gemini, Groq, Ollama, OpenAI
OpenAI,
Groq,
Ollama,
Amazon,
],
)
def test_generate_text(provider_cls):