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

Add component config support #4757

Merged
merged 11 commits into from
Dec 20, 2024
Merged

Add component config support #4757

merged 11 commits into from
Dec 20, 2024

Conversation

jackgerrits
Copy link
Member

@jackgerrits jackgerrits commented Dec 19, 2024

Component config adds a generic way for classes to opt in to being declaratively specified.

For example:

from __future__ import annotations

from autogen_core import Component
from pydantic import BaseModel


class Config(BaseModel):
    value: str


class MyComponent(Component[Config]):
    component_type = "custom"
    config_schema = Config

    def __init__(self, value: str):
        self.value = value

    def _to_config(self) -> Config:
        return Config(value=self.value)

    @classmethod
    def _from_config(cls, config: Config) -> MyComponent:
        return cls(value=config.value)

An example component config json:

{
    "provider": "autogen_ext.models.openai._openai_client.AzureOpenAIChatCompletionClient",
    "component_type": "model",
    "version": 1,
    "description": null,
    "config": {
        "values": {
            "azure_deployment": "{your-azure-deployment}",
            "model": "gpt-4o",
            "api_version": "2024-06-01",
            "azure_endpoint": "https://{your-custom-endpoint}.openai.azure.com/",
            "azure_ad_token_provider": {
                "provider": "autogen_ext.models.openai._azure_token_provider.AzureTokenProvider",
                "component_type": "token_provider",
                "version": 1,
                "description": null,
                "config": {
                    "provider_kind": "DefaultAzureCredential",
                    "scopes": [
                        "https://cognitiveservices.azure.com/.default"
                    ]
                }
            }
        }
    }
}

Which is a dump of:

az_model_client = AzureOpenAIChatCompletionClient(
    azure_deployment="{your-azure-deployment}",
    model="gpt-4o",
    api_version="2024-06-01",
    azure_endpoint="https://{your-custom-endpoint}.openai.azure.com/",
    azure_ad_token_provider=AzureTokenProvider(DefaultAzureCredential(), "https://cognitiveservices.azure.com/.default"),
)

@ekzhu
Copy link
Collaborator

ekzhu commented Dec 19, 2024

    def _to_config(self) -> Config:
        return Config(value=self.value)

    @classmethod
    def _from_config(cls, config: Config) -> MyComponent:
        return cls(value=config.value)

This returns a Pydantic basemodel, but as we discussed earlier Component types might be an implementation detail.

@jackgerrits @victordibia let's discuss this so we have a coherent way across configs and states.

@jackgerrits
Copy link
Member Author

jackgerrits commented Dec 19, 2024

    def _to_config(self) -> Config:
        return Config(value=self.value)

    @classmethod
    def _from_config(cls, config: Config) -> MyComponent:
        return cls(value=config.value)

This returns a Pydantic basemodel, but as we discussed earlier Component types might be an implementation detail.

@jackgerrits @victordibia let's discuss this so we have a coherent way across configs and states.

_to_config returns a type with a lower bound of base model (as specified by the Component[T] generic. The value passed to the _from_config function is guaranteed to be a valid instance of that type by the framework.

These are only ever called as part of the framework so it is safe to use full types here

@jackgerrits
Copy link
Member Author

jackgerrits commented Dec 19, 2024

I think the distinction between config and state is an important one. I added a section in the docs about it with my take but I think we should talk more about it!

How does this differ from state?

This is a very important point to clarify. When we talk about serializing an object, we must include all data that makes that object itself. Including things like message history etc. When deserializing from serialized state, you must get back the exact same object. This is not the case with component configuration.

Component configuration should be thought of as the blueprint for an object, and can be stamped out many times to create many instances of the same configured object.

Copy link
Collaborator

@ekzhu ekzhu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created a separate PR for the ChatCompletionClient argument list: #4774

@jackgerrits jackgerrits merged commit dda208f into main Dec 20, 2024
48 checks passed
@jackgerrits jackgerrits deleted the component_impl branch December 20, 2024 18:14
@victordibia
Copy link
Collaborator

victordibia commented Jan 4, 2025

@jackgerrits
Pydantic is generally unhappy with any fields that start with model_ such as model_info, model_capabilties, I get a flurry of warnings ...

image https://github.com/microsoft/autogen/blob/7b02d9dbf5c9e10ed3f2062eb09732b60ed44eec/python/packages/autogen-ext/src/autogen_ext/models/openai/config/__init__.py#L35 image

Some solutions

  • avoid using any field with model_ (doesnt feel quite right as it will interfer with core behaviours especially in component loading)
  • Use the "hack here" ... , add model_config = ConfigDict(protected_namespaces=()) to the data class

@jackgerrits
Copy link
Member Author

jackgerrits commented Jan 4, 2025

Pydantic loosened their requirements of naming in 2.10, so we now require >=2.10 for pydantic to avoid these warnings. See this PR: #4811

The warnings all go away with that version, you might need to uv sync your environment

@victordibia
Copy link
Collaborator

Ah .. got it!
I just need to upgrade my pydantic version!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants