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
23 changes: 23 additions & 0 deletions python/mypy_plugin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from typing import Callable
from mypy.plugin import Plugin, DynamicClassDefContext, SymbolTableNode
from mypy.nodes import SymbolTableNode

class CustomPlugin(Plugin):
def get_dynamic_class_hook(
self, fullname: str
) -> Callable[[DynamicClassDefContext], None] | None:

def hook(ctx: DynamicClassDefContext) -> None:
if "Component" in fullname:
# We need to generate mypy.nodes.TypeInfo
# to make mypy understand the type of the class
ctx.api.add_symbol_table_node(
fullname, SymbolTableNode(

)
)
return

def plugin(version: str):
# ignore version argument if the plugin works with all mypy versions.
return CustomPlugin
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
autogen\_core
=============


.. automodule:: autogen_core
:members:
:undoc-members:
:show-inheritance:
:member-order: bysource

.. For some reason the following isn't picked up by automodule above
.. autoclass:: autogen_core.ComponentType
ekzhu marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Component config\n",
"\n",
"AutoGen components are able to be declaratively configured in a generic fashion. This is to support configuration based experiences, such as AutoGen studio, but it is also useful for many other scenarios.\n",
"\n",
"The system that provides this is called \"component configuration\". In AutoGen, a component is simply something that can be created from a config object and itself can be dumped to a config object. In this way, you can define a component in code and then get the config object from it.\n",
"\n",
"This system is generic and allows for components defined outside of AutoGen itself (such as extensions) to be configured in the same way.\n",
"\n",
"## How does this differ from state?\n",
"\n",
"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.\n",
"\n",
"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.\n",
"\n",
"## Usage\n",
"\n",
"If you have a component in Python ad want to get the config for it, simply call {py:meth}`~autogen_core.ComponentConfig.dump_component` on it. The resulting object can be passed back into {py:meth}`~autogen_core.ComponentLoader.load_component` to get the component back.\n",
"\n",
"## Creating a component\n",
"\n",
"To add component functionality to a given class:\n",
"\n",
"1. Add a call to {py:meth}`~autogen_core.Component` in the class inheritance list.\n",
"2. Implment the {py:meth}`~autogen_core.ComponentConfigImpl._to_config` and {py:meth}`~autogen_core.ComponentConfigImpl._from_config` methods\n",
"\n",
"For example:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from __future__ import annotations\n",
"\n",
"from autogen_core import Component\n",
"from pydantic import BaseModel\n",
"\n",
"\n",
"class Config(BaseModel):\n",
" value: str\n",
"\n",
"\n",
"class MyComponent(Component[Config]):\n",
" component_type = \"custom\"\n",
" config_schema = Config\n",
"\n",
" def __init__(self, value: str):\n",
" self.value = value\n",
"\n",
" def _to_config(self) -> Config:\n",
" return Config(value=self.value)\n",
"\n",
" @classmethod\n",
" def _from_config(cls, config: Config) -> MyComponent:\n",
" return cls(value=config.value)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"## Secrets\n",
"\n",
"If a field of a config object is a secret value, it should be marked using [`SecretStr`](https://docs.pydantic.dev/latest/api/types/#pydantic.types.SecretStr), this will ensure that the value will not be dumped to the config object.\n",
"\n",
"For example:\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from pydantic import BaseModel, SecretStr\n",
"\n",
"\n",
"class ClientConfig(BaseModel):\n",
" endpoint: str\n",
" api_key: SecretStr"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.7"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ framework/logging
framework/telemetry
framework/command-line-code-executors
framework/distributed-agent-runtime
framework/component-config
```

```{toctree}
Expand Down
12 changes: 12 additions & 0 deletions python/packages/autogen-core/src/autogen_core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@
from ._base_agent import BaseAgent
from ._cancellation_token import CancellationToken
from ._closure_agent import ClosureAgent, ClosureContext
from ._component_config import (
Component,
ComponentConfigImpl,
ComponentLoader,
ComponentModel,
ComponentType,
)
from ._constants import (
EVENT_LOGGER_NAME as EVENT_LOGGER_NAME_ALIAS,
)
Expand Down Expand Up @@ -99,4 +106,9 @@
"ROOT_LOGGER_NAME",
"EVENT_LOGGER_NAME",
"TRACE_LOGGER_NAME",
"Component",
"ComponentLoader",
"ComponentConfigImpl",
"ComponentModel",
"ComponentType",
]
Loading
Loading