Skip to content

Conversation

@moonbox3
Copy link
Contributor

Motivation and Context

  • Add optional input_type and output_type parameters to @handler and @executor decorators
  • Explicit types take precedence over introspection from function signatures
  • Support union types via both str | int and Union[str, int] syntax
  • Add normalize_type_to_list utility for converting union types to lists

Example

# Before: types inferred from annotations
@handler
async def handle(self, message: str, ctx: WorkflowContext[int]) -> None:
    pass

# After: explicit types (useful when annotation is Any or missing)
@handler(input_type=str | int, output_type=bool)
async def handle(self, message: Any, ctx: WorkflowContext) -> None:
    pass

Description

See above.

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • Is this a breaking change? If yes, add "[BREAKING]" prefix to the title of the PR.

Copilot AI review requested due to automatic review settings January 28, 2026 02:04
@markwallace-microsoft
Copy link
Member

markwallace-microsoft commented Jan 28, 2026

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/core/agent_framework/_workflows
   _executor.py1641193%210, 333, 335–336, 345, 372, 375, 483, 488, 498, 620
   _function_executor.py71592%99, 126, 132, 138, 155
   _typing_utils.py1262877%142, 166, 245, 247–248, 257, 259, 266, 268, 288, 290, 292, 297–304, 307–308, 310–314, 316
TOTAL16219240285% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
3494 221 💤 0 ❌ 0 🔥 1m 8s ⏱️

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request adds explicit input_type and output_type parameters to the @handler and @executor decorators in the Python workflow framework. These optional parameters allow developers to specify types explicitly instead of relying on type introspection from function signatures, with explicit types taking precedence over introspected types. The feature supports union types via both str | int and Union[str, int] syntax.

Changes:

  • Added normalize_type_to_list utility function to convert union types to lists
  • Enhanced @handler and @executor decorators with optional input_type and output_type parameters
  • Modified signature validation functions to support skipping message annotation when explicit types are provided
  • Added comprehensive test coverage for explicit type parameters
  • Updated sample code to demonstrate the new feature

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
python/packages/core/agent_framework/_workflows/_typing_utils.py Added normalize_type_to_list utility function for handling union types; changed logger import pattern
python/packages/core/agent_framework/_workflows/_executor.py Enhanced @handler decorator with input_type and output_type parameters; updated handler validation logic; refactored exception handling in _discover_handlers
python/packages/core/agent_framework/_workflows/_function_executor.py Enhanced @executor decorator and FunctionExecutor class with explicit type parameters; updated function validation logic
python/packages/core/tests/workflow/test_typing_utils.py Added comprehensive tests for normalize_type_to_list function covering single types, union types, and optional types
python/packages/core/tests/workflow/test_executor.py Added comprehensive test suite for @handler with explicit types, covering precedence, union types, and partial specifications
python/packages/core/tests/workflow/test_function_executor.py Added comprehensive test suite for @executor with explicit types, covering various edge cases and usage patterns
python/samples/getting_started/workflows/_start-here/step1_executors_and_edges.py Added documentation and example demonstrating explicit type parameters with a new ExclamationAdder executor

Comment on lines +6 to 9
from agent_framework import get_logger

logger = get_logger("agent_framework._workflows._typing_utils")

Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

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

The logger is defined but never used in this file. The original code removed import logging and added get_logger, but there are no calls to logger.debug(), logger.info(), etc. anywhere in this file. This adds unnecessary imports and creates an unused variable. Consider removing the logger import and variable definition, or keep the original import logging if it might be needed in the future.

Suggested change
from agent_framework import get_logger
logger = get_logger("agent_framework._workflows._typing_utils")

Copilot uses AI. Check for mistakes.
async def handle_custom(self, message: Any, ctx: WorkflowContext[str]) -> None:
...
"""
from ._typing_utils import normalize_type_to_list
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

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

The import of normalize_type_to_list is done locally inside the decorator function, while is_instance_of from the same module is imported at the top of the file (line 24). For consistency and clarity, both imports should be at the module level unless there's a specific reason for a local import (such as avoiding circular dependencies, which doesn't appear to be the case here). Consider moving this import to the top of the file alongside the other import from _typing_utils.

Copilot uses AI. Check for mistakes.
@moonbox3 moonbox3 self-assigned this Jan 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants