Skip to content

Commit

Permalink
improve component config, add description support in dump_component (#…
Browse files Browse the repository at this point in the history
…5203)

<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

It is currently hard to add a description to a component (defaults to
None also) .. you have to call super.dump() modify and return. This PR
makes the experience better.

- allows you specify `component_description` and `component_label` as an
optional class var. label is an optional human readable name for the the
component.
- will use component_description if provided int he description field
when dumped if there is no description, will use the first line of class
docstring. Takes advantage of all the good practices we have in writing
good docstrings. label defaults to component type.
 

For example 

```python
model_client=OpenAIChatCompletionClient( model="gpt-4o-2024-08-06" )
config = model_client.dump_component()
print(config.model_dump_json())
```
Note the description field below is no longer None and there is a label
```python
{
  "provider": "autogen_ext.models.openai.OpenAIChatCompletionClient",
  "component_type": "model",
  "version": 1,
  "component_version": 1,
  "description": "Chat completion client for OpenAI hosted models.",
  "label": "OpenAIChatCompletionClient",
  "config": { "model": "gpt-4o-2024-08-06" }
}


```

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->
None, felt faster to fix.

## Checks

- [x] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [x] I've made sure all auto checks have passed.
  • Loading branch information
victordibia authored Jan 27, 2025
1 parent b441d5b commit 6359b6a
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ class ComponentModel(BaseModel):
description: str | None = None
"""Description of the component."""

label: str | None = None
"""Human readable label for the component. If missing the component assumes the class name of the provider."""

config: dict[str, Any]
"""The schema validated config field is passed to a given class's implmentation of :py:meth:`autogen_core.ComponentConfigImpl._from_config` to create a new instance of the component class."""

Expand Down Expand Up @@ -95,6 +98,10 @@ class ComponentToConfig(Generic[ToConfigT]):
"""The version of the component, if schema incompatibilities are introduced this should be updated."""
component_provider_override: ClassVar[str | None] = None
"""Override the provider string for the component. This should be used to prevent internal module names being a part of the module name."""
component_description: ClassVar[str | None] = None
"""A description of the component. If not provided, the docstring of the class will be used."""
component_label: ClassVar[str | None] = None
"""A human readable label for the component. If not provided, the component class name will be used."""

def _to_config(self) -> ToConfigT:
"""Dump the configuration that would be requite to create a new instance of a component matching the configuration of this instance.
Expand Down Expand Up @@ -132,13 +139,22 @@ def dump_component(self) -> ComponentModel:
if not hasattr(self, "component_type"):
raise AttributeError("component_type not defined")

description = self.component_description
if description is None and self.__class__.__doc__:
# use docstring as description
docstring = self.__class__.__doc__.strip()
for marker in ["\n\nArgs:", "\n\nParameters:", "\n\nAttributes:", "\n\n"]:
docstring = docstring.split(marker)[0]
description = docstring.strip()

obj_config = self._to_config().model_dump(exclude_none=True)
model = ComponentModel(
provider=provider,
component_type=self.component_type,
version=self.component_version,
component_version=self.component_version,
description=None,
description=description,
label=self.component_label or self.__class__.__name__,
config=obj_config,
)
return model
Expand Down
18 changes: 18 additions & 0 deletions python/packages/autogen-core/tests/test_component_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ def _from_config(cls, config: MyConfig) -> MyComponent:
return cls(info=config.info)


class ComponentWithDescription(MyComponent):
component_description = "Explicit description"
component_label = "Custom Component"


class ComponentWithDocstring(MyComponent):
"""A component using just docstring."""


def test_custom_component() -> None:
comp = MyComponent("test")
comp2 = MyComponent.load_component(comp.dump_component())
Expand Down Expand Up @@ -350,3 +359,12 @@ async def async_func(x: float, y: float, cancellation_token: CancellationToken)
cancelled_token.cancel()
with pytest.raises(Exception, match="Cancelled"):
await loaded_async.run_json({"x": 1.0, "y": 2.0}, cancelled_token)


@pytest.mark.asyncio
def test_component_descriptions() -> None:
"""Test different ways of setting component descriptions."""
assert MyComponent("test").dump_component().description is None
assert ComponentWithDocstring("test").dump_component().description == "A component using just docstring."
assert ComponentWithDescription("test").dump_component().description == "Explicit description"
assert ComponentWithDescription("test").dump_component().label == "Custom Component"

0 comments on commit 6359b6a

Please sign in to comment.