griptape-ai / griptape

Modular Python framework for AI agents and workflows with chain-of-thought reasoning, tools, and memory.
https://www.griptape.ai
Apache License 2.0
1.9k stars 155 forks source link

Merge Config Does Not Reinitialize Non-Serializable Fields #826

Closed collindutter closed 3 weeks ago

collindutter commented 3 months ago

Describe the bug merge_config does the following:

  1. Call to_dict on the config.
  2. Recursive merge in the new config
  3. Return from_dict containing the merged config.

The problem is that to_dict throws away fields without serializable: True metadata such as OpenAiChatPromptDriver.api_key. Meaning if a non-serializable field is set before merge_config, it is lost on merge.

To Reproduce IMPORTANT: Ensure OPENAI_API_KEY is not set in environment. Run:

config = StructureConfig(
    prompt_driver=OpenAiChatPromptDriver(
        model="gpt-4o",
        api_key="VALID KEY",
    )
).merge_config(
    {
        "prompt_driver": {"stream": True},
    }
)

agent = Agent(config=config)

agent.run("hello")

Output:

openai.OpenAIError: The api_key client option must be set either by passing api_key to the client or by setting the OPENAI_API_KEY environment variable

Expected behavior merge_config should not throw away already set values.

collindutter commented 3 months ago

It seems like replacing self.to_dict with attrs.asdict(self) could be a solution, but this fails with:

Traceback (most recent call last):
  File "/Users/collindutter/Documents/griptape/griptape-playground/src/misc/config-issue.py", line 21, in <module>
    config = StructureConfig(
  File "/Users/collindutter/Documents/griptape/griptape/griptape/config/base_structure_config.py", line 36, in merge_config
    base_config = asdict(self)
  File "/Users/collindutter/Documents/griptape/griptape-playground/.venv/lib/python3.9/site-packages/attr/_next_gen.py", line 211, in asdict
    return _asdict(
  File "/Users/collindutter/Documents/griptape/griptape-playground/.venv/lib/python3.9/site-packages/attr/_funcs.py", line 65, in asdict
    rv[a.name] = asdict(
  File "/Users/collindutter/Documents/griptape/griptape-playground/.venv/lib/python3.9/site-packages/attr/_funcs.py", line 56, in asdict
    v = getattr(inst, a.name)
AttributeError: model

Probably an init=False problem.