diff --git a/python/packages/core/agent_framework/_workflows/_workflow.py b/python/packages/core/agent_framework/_workflows/_workflow.py index 58050eece9..fc26db8953 100644 --- a/python/packages/core/agent_framework/_workflows/_workflow.py +++ b/python/packages/core/agent_framework/_workflows/_workflow.py @@ -11,11 +11,11 @@ import logging import types import uuid from collections.abc import AsyncIterable, Awaitable, Callable, Mapping, Sequence -from typing import Any, Literal, overload +from typing import TYPE_CHECKING, Any, Literal, overload +from .._sessions import ContextProvider from .._types import ResponseStream from ..observability import OtelAttr, capture_exception, create_workflow_span -from ._agent import WorkflowAgent from ._checkpoint import CheckpointStorage from ._const import DEFAULT_MAX_ITERATIONS, GLOBAL_KWARGS_KEY, WORKFLOW_RUN_KWARGS_KEY from ._edge import ( @@ -35,6 +35,9 @@ from ._runner_context import RunnerContext from ._state import State from ._typing_utils import is_instance_of, try_coerce_to_type +if TYPE_CHECKING: + from ._agent import WorkflowAgent + logger = logging.getLogger(__name__) @@ -910,7 +913,14 @@ class Workflow(DictConvertible): return list(output_types) - def as_agent(self, name: str | None = None) -> WorkflowAgent: + def as_agent( + self, + name: str | None = None, + *, + description: str | None = None, + context_providers: Sequence[ContextProvider] | None = None, + **kwargs: Any, + ) -> WorkflowAgent: """Create a WorkflowAgent that wraps this workflow. The returned agent converts standard agent inputs (strings, Message, or lists of these) @@ -924,7 +934,10 @@ class Workflow(DictConvertible): initialization will fail with a ValueError. Args: - name: Optional name for the agent. If None, a default name will be generated. + name: Optional name for the agent. Defaults to workflow name. + description: Optional description of the agent. Defaults to workflow description. + context_providers: Optional sequence of context providers for the agent. + **kwargs: Additional keyword arguments passed to BaseAgent. Returns: A WorkflowAgent instance that wraps this workflow. @@ -935,4 +948,10 @@ class Workflow(DictConvertible): # Import here to avoid circular imports from ._agent import WorkflowAgent - return WorkflowAgent(workflow=self, name=name) + return WorkflowAgent( + workflow=self, + name=name if name is not None else self.name, + description=description if description is not None else self.description, + context_providers=context_providers, + **kwargs, + ) diff --git a/python/packages/core/tests/workflow/test_workflow_agent.py b/python/packages/core/tests/workflow/test_workflow_agent.py index 9c7a655d23..0101a6e8a5 100644 --- a/python/packages/core/tests/workflow/test_workflow_agent.py +++ b/python/packages/core/tests/workflow/test_workflow_agent.py @@ -313,6 +313,37 @@ class TestWorkflowAgent: assert isinstance(agent_no_name, WorkflowAgent) assert agent_no_name.workflow is workflow + def test_workflow_as_agent_with_description_and_context_providers(self) -> None: + """Test that Workflow.as_agent() forwards description and context_providers.""" + executor = SimpleExecutor(id="executor1", response_text="Response") + workflow = WorkflowBuilder(start_executor=executor).build() + + history_provider = InMemoryHistoryProvider() + agent = workflow.as_agent( + name="MyAgent", + description="A test agent", + context_providers=[history_provider], + ) + + assert isinstance(agent, WorkflowAgent) + assert agent.name == "MyAgent" + assert agent.description == "A test agent" + assert history_provider in agent.context_providers + + def test_workflow_as_agent_defaults_name_and_description_from_workflow(self) -> None: + """Test that as_agent() defaults name and description to the workflow's own values.""" + executor = SimpleExecutor(id="executor1", response_text="Response") + workflow = WorkflowBuilder( + start_executor=executor, + name="my-workflow", + description="Workflow description", + ).build() + + agent = workflow.as_agent() + + assert agent.name == "my-workflow" + assert agent.description == "Workflow description" + def test_workflow_as_agent_cannot_handle_agent_inputs(self) -> None: """Test that Workflow.as_agent() raises an error if the start executor cannot handle agent inputs."""