Skip to content

Commit

Permalink
Add Ability to use Drivers Configs as Context Managers for temporaril…
Browse files Browse the repository at this point in the history
…y setting the default Drivers.
  • Loading branch information
collindutter committed Sep 9, 2024
1 parent 5b56867 commit 6442f96
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Parameter `meta: dict` on `BaseEvent`.
- `AzureOpenAiTextToSpeechDriver`.
- Ability to use Drivers Configs as Context Managers for temporarily setting the default Drivers.

### Changed
- **BREAKING**: Drivers, Loaders, and Engines now raise exceptions rather than returning `ErrorArtifacts`.
Expand Down
15 changes: 14 additions & 1 deletion docs/griptape-framework/structures/configs.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,27 @@ search:

## Overview

Griptape exposes global configuration options to easily customize different parts of the framework.
Griptape exposes a global singleton, [Defaults](../../reference/griptape/configs/defaults.md), which can be used to access and modify the default configurations of the framework.

To update the default configurations, simply update the fields on the `Defaults` object.
Framework objects will be created with the currently set default configurations, but you can always override at the individual class level.

```python
--8<-- "docs/griptape-framework/structures/src/config_defaults.py"
```

### Drivers Configs

The [DriversConfig](../../reference/griptape/configs/drivers/drivers_config.md) class allows for the customization of Structures within Griptape, enabling specific settings such as Drivers to be defined for Tasks.

Griptape provides predefined [DriversConfig](../../reference/griptape/configs/drivers/drivers_config.md)'s for widely used services that provide APIs for most Driver types Griptape offers.

`DriversConfig`s can be used as a Python Context Manager using the `with` statement to temporarily change the default configurations for a block of code.

```python
--8<-- "docs/griptape-framework/structures/src/drivers_config_with.py"
```

#### OpenAI

The [OpenAI Driver config](../../reference/griptape/configs/drivers/openai_drivers_config.md) provides default Drivers for OpenAI's APIs. This is the default config for all Structures.
Expand Down
12 changes: 12 additions & 0 deletions docs/griptape-framework/structures/src/config_defaults.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from griptape.configs import Defaults
from griptape.configs.drivers import AnthropicDriversConfig, OpenAiDriversConfig
from griptape.drivers.prompt.anthropic_prompt_driver import AnthropicPromptDriver
from griptape.structures import Agent

Defaults.drivers_config = OpenAiDriversConfig() # Default
openai_agent = Agent()

Defaults.drivers_config = AnthropicDriversConfig()
anthropic_agent = Agent(
prompt_driver=AnthropicPromptDriver(model="claude-3-5-sonnet-20240620"), # Override the default prompt driver
)
31 changes: 31 additions & 0 deletions docs/griptape-framework/structures/src/drivers_config_with.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import schema

from griptape.configs.drivers import AnthropicDriversConfig, OpenAiDriversConfig
from griptape.drivers import AnthropicPromptDriver, OpenAiChatPromptDriver
from griptape.engines import JsonExtractionEngine
from griptape.structures import Agent
from griptape.tasks import ToolTask
from griptape.tools import ExtractionTool

with OpenAiDriversConfig(): # Agent will be created with OpenAi Drivers
openai_agent = Agent()

with AnthropicDriversConfig(): # Agent will be created with Anthropic Drivers
anthropic_agent = Agent(
tasks=[
ToolTask(
"Extract sentiment from this text: {{ args[0] }}",
prompt_driver=OpenAiChatPromptDriver(model="gpt-4o"), # Override this particular Task's prompt driver
tool=ExtractionTool(
extraction_engine=JsonExtractionEngine(
prompt_driver=AnthropicPromptDriver( # Override this particular Engine's prompt driver
model="claude-3-opus-20240229"
),
template_schema=schema.Schema({"sentiment": str}).json_schema("Output"),
),
),
)
]
)

anthropic_agent.run("Hello, I am happy!")
16 changes: 16 additions & 0 deletions griptape/configs/drivers/base_drivers_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,22 @@ class BaseDriversConfig(ABC, SerializableMixin):
default=None, kw_only=True, metadata={"serializable": True}, alias="audio_transcription_driver"
)

_old_drivers_config: BaseDriversConfig = field(default=None)

def __enter__(self) -> BaseDriversConfig:
from griptape.configs import Defaults

self._old_drivers_config = Defaults.drivers_config

Defaults.drivers_config = self

return self

def __exit__(self, type, value, traceback) -> None: # noqa: ANN001, A002
from griptape.configs import Defaults

Defaults.drivers_config = self._old_drivers_config

@lazy_property()
@abstractmethod
def prompt_driver(self) -> BasePromptDriver: ...
Expand Down
11 changes: 11 additions & 0 deletions tests/unit/configs/drivers/test_drivers_config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import pytest

from griptape.configs.drivers import DriversConfig
from tests.mocks.mock_drivers_config import MockDriversConfig


class TestDriversConfig:
Expand Down Expand Up @@ -41,6 +42,16 @@ def test_dot_update(self, config):

assert config.prompt_driver.max_tokens == 10

def test_context_manager(self):
from griptape.configs import Defaults

old_drivers_config = Defaults.drivers_config

with MockDriversConfig() as config:
assert Defaults.drivers_config == config

assert Defaults.drivers_config == old_drivers_config

@pytest.mark.skip_mock_config()
def test_lazy_init(self):
from griptape.configs import Defaults
Expand Down

0 comments on commit 6442f96

Please sign in to comment.