Skip to content

Python: [Bug]: Generic Type Executor are not supported properly in workflows + Cannot send workflow payload to multiple executors #4534

@esttenorio

Description

@esttenorio

Description

I'm trying to build a workflow that looks like this

graph LR
     Input([Input Payload]) -->|TypeX| ExecutorA -->|TypeA|ExecutorB -->|TypeB|ExecutorC 
     Input -->|TypeX| ExecutorC
Loading

Since the input payload for a workflow cannot be send to multiple executors, created a start step to do so that works as an echo:

graph LR
     Input([Input Payload]) -->|TypeX| StartExecutor-->|TypeX| ExecutorA -->|TypeA|ExecutorB -->|TypeB|ExecutorC 
     StartExecutor-->|TypeX| ExecutorC
Loading

I tried creating an executor passing a generic and then assigning ctx[T] but on runtime the validation fails since it the edges validation validates directly against the generic and not the value.

I created a workaround to have a factory + assign manually th param values, this seems to work with the validation:

def create_echo_executor(id: str, message_type: Type) -> Executor:
    """
    Factory that creates a concrete EchoExecutor whose handler has explicit
    type annotations matching *message_type*, so agent_framework can resolve
    input/output types at class-definition time.

    Usage:
        echo = create_echo_executor("start", PageContent)
    """

    class _EchoExecutor(Executor):

        async def echo(self, message, ctx):
            if not isinstance(message, message_type):
                raise TypeError(
                    f"Expected message of type {message_type.__name__}, "
                    f"got {type(message).__name__}"
                )
            await ctx.send_message(message)
            await ctx.yield_output(message)
            return message

    # Set concrete type annotations BEFORE applying @handler
    _EchoExecutor.echo.__annotations__["message"] = message_type
    _EchoExecutor.echo.__annotations__["ctx"] = WorkflowContext[message_type]
    _EchoExecutor.echo.__annotations__["return"] = message_type
    _EchoExecutor.echo = handler(_EchoExecutor.echo)

    return _EchoExecutor(id=id)

So, it seems there are 2 issues:

  • Allow sending workflow input payload to multiple executors -> Ideally the EchoExecutor should be created like: myCustomEcho = EchoExecutor(id, MyCustomType) or similar.
  • Allow generic executor types to be piped properly without the __annotations__ workaround

Code Sample

from typing import Type
from agent_framework import (
    Executor,
    WorkflowContext,
    handler,
)


def create_echo_executor(id: str, message_type: Type) -> Executor:
    """
    Factory that creates a concrete EchoExecutor whose handler has explicit
    type annotations matching *message_type*, so agent_framework can resolve
    input/output types at class-definition time.

    Usage:
        echo = create_echo_executor("start", PageContent)
    """

    class _EchoExecutor(Executor):

        async def echo(self, message, ctx):
            if not isinstance(message, message_type):
                raise TypeError(
                    f"Expected message of type {message_type.__name__}, "
                    f"got {type(message).__name__}"
                )
            await ctx.send_message(message)
            await ctx.yield_output(message)
            return message

    # Set concrete type annotations BEFORE applying @handler
    _EchoExecutor.echo.__annotations__["message"] = message_type
    _EchoExecutor.echo.__annotations__["ctx"] = WorkflowContext[message_type]
    _EchoExecutor.echo.__annotations__["return"] = message_type
    _EchoExecutor.echo = handler(_EchoExecutor.echo)

    return _EchoExecutor(id=id)

Error Messages / Stack Traces

Package Versions

agent-framework-azure-ai==1.0.0rc3

Python Version

No response

Additional Context

No response

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingpythonworkflowsRelated to Workflows in agent-framework

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions