Skip to content

fix: Refactor code structure for improved readability and maintainability#253

Draft
Dhanushree-Microsoft wants to merge 8 commits into
devfrom
cm-upg-aiproj
Draft

fix: Refactor code structure for improved readability and maintainability#253
Dhanushree-Microsoft wants to merge 8 commits into
devfrom
cm-upg-aiproj

Conversation

@Dhanushree-Microsoft
Copy link
Copy Markdown
Contributor

Purpose

This pull request updates dependencies and refactors the agent builder and client helper code to align with the latest agent-framework library changes. The main focus is on supporting the new Agent class and handling the removal or renaming of several types and clients in agent-framework 1.3.0. The changes improve compatibility and future-proof the codebase.

Does this introduce a breaking change?

  • Yes
  • No

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 21, 2026

Coverage

Coverage Report •
FileStmtsMissCoverMissing
TOTAL309720893% 
report-only-changed-files is enabled. No files were changed during this commit :)

Tests Skipped Failures Errors Time
588 0 💤 0 ❌ 0 🔥 23.574s ⏱️

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 21, 2026

Coverage

Processor Coverage Report •
FileStmtsMissCoverMissing
src/processor/src/libs/agent_framework
   agent_builder.py1230100% 
   agent_framework_helper.py821186%84, 151, 175, 197, 220, 237, 371, 390, 411, 448–449
   agent_info.py240100% 
   agent_speaking_capture.py66493%206–207, 210, 212
   azure_openai_response_retry.py37114062%91, 201, 209, 231, 257, 267–269, 393, 400–403, 405–407, 413–415, 432, 453–454, 459–462, 465–468, 470–473, 475, 485–487, 489–492, 494–497, 499–503, 505, 513–515, 517, 540–545, 547–549, 555–556, 560–563, 567, 570, 578–579, 585–586, 591, 593, 614, 620–622, 626–627, 643–644, 646–649, 653, 656, 664–665, 671–673, 675–678, 680–691, 694, 701–702, 727–728, 735–736, 738, 742, 745–746, 750–751, 753–755, 763, 765–767, 769–771, 773–774, 784
   coordinator_selection_response.py60100% 
   groupchat_orchestrator.py5439083%130–131, 138–139, 144–145, 473, 476–480, 482, 484–485, 488, 491, 494, 496, 498–501, 508–509, 516–517, 524–525, 528–530, 532–533, 538–540, 543–544, 549, 552–554, 557–558, 563, 566, 572, 575, 579, 581–585, 589–590, 596, 599, 603, 608, 611, 622–623, 625, 627–628, 630, 640–641, 643, 736, 910, 929, 931, 933, 962, 1091, 1093, 1208, 1217, 1219, 1264–1265, 1268, 1289–1292, 1310
   middlewares.py820100% 
   shared_memory_context_provider.py1221190%111, 138, 219, 230, 234, 239, 282, 287, 310–312
src/processor/src/libs/base
   orchestrator_base.py1675070%65, 71, 74–77, 83–84, 86–87, 130, 141, 146, 151–152, 156, 164, 166, 168, 175–176, 183, 189, 191, 198, 202, 211, 215, 220, 222–223, 225, 324–326, 329, 335, 342–344, 371–373, 376, 383, 390–392, 443–444
src/processor/src/libs/mcp_server
   MCPBlobIOTool.py50100% 
   MCPDatetimeTool.py60100% 
   MCPMicrosoftDocs.py30100% 
src/processor/src/steps
   migration_processor.py2644084%88–89, 145–146, 160, 187, 222–223, 229–230, 234, 238, 309–312, 315–318, 322–323, 336–337, 395–396, 496–497, 547–548, 555–556, 594–595, 613–614, 678–679, 703, 732
src/processor/src/steps/analysis/orchestration
   analysis_orchestrator.py85890%46–47, 61, 65, 112, 115, 121, 123
src/processor/src/steps/convert/orchestration
   yaml_convert_orchestrator.py97594%64, 112, 115, 121, 123
src/processor/src/steps/design/orchestration
   design_orchestrator.py82989%42–43, 50, 54, 104, 107, 114–115, 117
src/processor/src/steps/documentation/orchestration
   documentation_orchestrator.py95693%69, 117, 120, 126–127, 129
TOTAL575473487% 

Tests Skipped Failures Errors Time
812 0 💤 0 ❌ 0 🔥 19.266s ⏱️

Copy link
Copy Markdown
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 updates the repo’s Python dependencies and refactors the processor’s agent/workflow integration to align with agent-framework 1.3.0 (notably the new Agent class and WorkflowEvent-based event model), along with corresponding test updates.

Changes:

  • Bump agent-framework (and related Azure SDK deps) and refresh lockfiles across components.
  • Migrate processor workflow/event handling from per-event classes to WorkflowEvent.type + new event fields (e.g., executor_id).
  • Refactor agent orchestration layers to use Agent/Message/FunctionTool (with compatibility fallbacks) and add a new CoordinatorSelectionResponse schema.

Reviewed changes

Copilot reviewed 29 out of 31 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/processor/uv.lock Updates dependency lockfile for processor, including agent-framework==1.3.0 and new extras.
src/processor/src/tests/unit/steps/test_migration_processor_run.py Updates unit tests to emit/expect the new WorkflowEvent API.
src/processor/src/tests/unit/libs/agent_framework/test_shared_memory_context_provider.py Adjusts assertions to tolerate API differences in returned context shape.
src/processor/src/tests/unit/libs/agent_framework/test_middlewares_extras.py Refactors tests to avoid hard dependency on agent_framework.ChatMessage/Role.
src/processor/src/tests/unit/libs/agent_framework/test_input_observer_middleware.py Updates middleware tests for role/message shape changes.
src/processor/src/tests/unit/libs/agent_framework/test_groupchat_orchestrator_internals.py Updates orchestrator internal tests for Message/role changes.
src/processor/src/tests/unit/libs/agent_framework/test_agent_framework_helper.py Updates tests to assert removed Azure clients raise NotImplementedError.
src/processor/src/tests/unit/libs/agent_framework/test_agent_builder.py Updates tests to patch the new Agent constructor usage.
src/processor/src/steps/migration_processor.py Migrates workflow streaming handling to WorkflowEvent.type and executor_id.
src/processor/src/steps/documentation/orchestration/documentation_orchestrator.py Updates MCP tool typing/imports to FunctionTool with fallbacks.
src/processor/src/steps/design/orchestration/design_orchestrator.py Updates MCP tool typing/imports to FunctionTool with fallbacks.
src/processor/src/steps/convert/orchestration/yaml_convert_orchestrator.py Updates MCP tool typing/imports to FunctionTool with fallbacks.
src/processor/src/steps/analysis/orchestration/analysis_orchestrator.py Updates MCP tool typing/imports to FunctionTool with fallbacks.
src/processor/src/libs/mcp_server/MCPMicrosoftDocs.py Updates docs/examples from ChatAgent to Agent.
src/processor/src/libs/mcp_server/MCPDatetimeTool.py Updates docs/examples from ChatAgent to Agent.
src/processor/src/libs/mcp_server/MCPBlobIOTool.py Updates docs/examples from ChatAgent to Agent.
src/processor/src/libs/base/orchestrator_base.py Refactors to Agent + new response format model; adds tool result compaction when available.
src/processor/src/libs/agent_framework/shared_memory_context_provider.py Updates typing/imports for Message/Context, adds default memory prompt, and compatibility fallbacks.
src/processor/src/libs/agent_framework/middlewares.py Refactors middleware typing/imports for new AgentContext/Message while supporting older shapes.
src/processor/src/libs/agent_framework/groupchat_orchestrator.py Refactors orchestrator integration to new agent-framework types and coordinator response model.
src/processor/src/libs/agent_framework/coordinator_selection_response.py Adds new Pydantic model replacing prior manager selection response.
src/processor/src/libs/agent_framework/azure_openai_response_retry.py Adds compatibility shim for removed AzureOpenAIResponsesClient.
src/processor/src/libs/agent_framework/agent_speaking_capture.py Updates middleware context type imports for new AgentContext.
src/processor/src/libs/agent_framework/agent_info.py Updates tool typing to FunctionTool with fallback.
src/processor/src/libs/agent_framework/agent_framework_helper.py Updates Azure client creation paths to reflect removed/renamed clients in 1.3.0.
src/processor/src/libs/agent_framework/agent_builder.py Refactors builder from ChatAgent to Agent and updates associated types.
src/processor/pyproject.toml Bumps agent-framework + Azure SDK versions for processor.
src/backend-api/uv.lock Updates backend-api lockfile to newer azure-ai-agents.
src/backend-api/pyproject.toml Bumps backend-api dependency azure-ai-agents.
infra/vscode_web/requirements.txt Bumps azure-ai-projects to 2.1.0 for vscode web infra.
infra/vscode_web/endpoint-requirements.txt Bumps azure-ai-projects to 2.1.0 for endpoint requirements.
Comments suppressed due to low confidence (3)

src/processor/src/libs/agent_framework/groupchat_orchestrator.py:208

  • participants is typed as Mapping | Sequence, but the implementation assigns it to self.agents (a dict) and later calls .items() on it. If a caller passes a sequence (allowed by the signature/docstring), this will fail at runtime. Either restrict the type to a mapping or normalize sequences into a {name: agent} mapping during initialization.
            process_id: Workflow/process identifier (used for tracing)
            participants: Mapping/sequence of pre-created agents (including the Coordinator)
            memory_client: Mem0 async memory client for multi-agent memory (may be None depending on runtime)

src/processor/src/libs/base/orchestrator_base.py:160

  • create_agents() is annotated to return list[Agent] but actually builds and returns a dict[str, Agent] (and callers treat self.agents as a mapping). This mismatch makes type checking misleading and can hide real bugs; update the return type (and self.agents attribute type) to dict[str, Agent] (or return a list consistently).
        workspace_context = (
            f"\n\n## WORKSPACE CONTEXT\n"
            f"- Process ID: {process_id}\n"
            f"- Container: processes\n"
            f"- Source folder: {process_id}/source\n"

src/processor/src/libs/agent_framework/groupchat_orchestrator.py:524

  • In the agent-framework 1.3.0 import path, WorkflowOutputEvent is aliased to WorkflowEvent, but the streaming loop later uses elif isinstance(event, WorkflowOutputEvent) to detect final output. If the workflow emits non-output WorkflowEvents (e.g., started/failed/executor_* like MigrationProcessor handles), this isinstance check will match them too and treat them as final output, potentially clobbering conversation with event.data (often None). Consider switching to a discriminant check (e.g., event.type == "output") rather than relying on isinstance when WorkflowEvent is the unified event type.
                            reason=(
                                f"Workflow exceeded max_rounds={self.max_rounds}; terminating to avoid infinite loop"
                            ),
                            termination_type="hard_timeout",
                        )

                    if self._forced_termination_requested:

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
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

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

Comments suppressed due to low confidence (1)

src/processor/src/libs/agent_framework/shared_memory_context_provider.py:312

  • _get_text checks message.content, but the rest of the updated codebase (and agent-framework 1.3.0 Message usage) appears to use message.contents (plural) for non-text content (e.g., tool call content items). If Message instances have contents but no content, this will fall back to str(message) and can produce poor/empty queries and stored memories. Update _get_text to also handle contents (and extract any text segments from it) before falling back to str(message).
    @staticmethod
    def _get_text(message: Message) -> str:
        """Extract text content from a Message."""
        if hasattr(message, "text") and message.text:
            return message.text
        if hasattr(message, "content"):
            return str(message.content) if message.content else ""
        return str(message) if message else ""

Comment thread src/processor/src/libs/agent_framework/groupchat_orchestrator.py Outdated
Comment thread src/processor/src/libs/base/orchestrator_base.py Outdated
Copy link
Copy Markdown
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

Copilot reviewed 29 out of 31 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (2)

src/processor/src/libs/agent_framework/azure_openai_response_retry.py:664

  • In _inner_get_streaming_response, super()._inner_get_response(..., stream=True, ...) is called without await and then treated as an async iterator via __aiter__(). If the parent implementation is an async def (coroutine) rather than an async generator, this will raise at runtime. Consider awaiting the parent call (and then iterating the returned stream) or delegating to the parent streaming method if one exists, so stream is guaranteed to be an AsyncIterable.
        for attempt_index in range(attempts):
            stream = super(
                AzureOpenAIResponseClientWithRetry, self
            )._inner_get_response(
                messages=effective_messages, options=effective_options, stream=True, **kwargs
            )

            iterator = stream.__aiter__()
            try:

src/processor/src/libs/agent_framework/shared_memory_context_provider.py:312

  • SharedMemoryContextProvider._get_text only checks message.text and message.content, but elsewhere in this PR the new framework Message is accessed via message.contents (plural). If the framework provides content primarily via contents (e.g., TextContent items) and text is empty, this will store/search with str(message) instead of the actual user/assistant text, reducing memory retrieval quality. Add support for message.contents (and extract textual parts) before falling back to str(message).
    @staticmethod
    def _get_text(message: Message) -> str:
        """Extract text content from a Message."""
        if hasattr(message, "text") and message.text:
            return message.text
        if hasattr(message, "content"):
            return str(message.content) if message.content else ""
        return str(message) if message else ""

Comment thread src/processor/src/libs/agent_framework/groupchat_orchestrator.py
@Prachig-Microsoft Prachig-Microsoft marked this pull request as draft May 22, 2026 06:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants