Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drivers Config Context Manager #1162

Merged
merged 1 commit into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `AzureOpenAiTextToSpeechDriver`.
- Ability to use Event Listeners as Context Managers for temporarily setting the Event Bus listeners.
- `JsonSchemaRule` for instructing the LLM to output a JSON object that conforms to a schema.
- 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_config.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()
dylanholmes marked this conversation as resolved.
Show resolved Hide resolved
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()
dylanholmes marked this conversation as resolved.
Show resolved Hide resolved

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!")
21 changes: 20 additions & 1 deletion griptape/configs/drivers/base_drivers_config.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

from abc import ABC, abstractmethod
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Optional

from attrs import define, field

Expand Down Expand Up @@ -48,6 +48,25 @@ class BaseDriversConfig(ABC, SerializableMixin):
default=None, kw_only=True, metadata={"serializable": True}, alias="audio_transcription_driver"
)

_last_drivers_config: Optional[BaseDriversConfig] = field(default=None)

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

self._last_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

if self._last_drivers_config is not None:
Defaults.drivers_config = self._last_drivers_config

self._last_drivers_config = None

@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
Loading