fix: Refactor code structure for improved readability and maintainability#253
fix: Refactor code structure for improved readability and maintainability#253Dhanushree-Microsoft wants to merge 8 commits into
Conversation
There was a problem hiding this comment.
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 newCoordinatorSelectionResponseschema.
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
participantsis typed asMapping | Sequence, but the implementation assigns it toself.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 returnlist[Agent]but actually builds and returns adict[str, Agent](and callers treatself.agentsas a mapping). This mismatch makes type checking misleading and can hide real bugs; update the return type (andself.agentsattribute type) todict[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,
WorkflowOutputEventis aliased toWorkflowEvent, but the streaming loop later useselif isinstance(event, WorkflowOutputEvent)to detect final output. If the workflow emits non-outputWorkflowEvents (e.g., started/failed/executor_* likeMigrationProcessorhandles), thisisinstancecheck will match them too and treat them as final output, potentially clobberingconversationwithevent.data(often None). Consider switching to a discriminant check (e.g.,event.type == "output") rather than relying onisinstancewhenWorkflowEventis 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.
…proved telemetry and error reporting
There was a problem hiding this comment.
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_textchecksmessage.content, but the rest of the updated codebase (and agent-framework 1.3.0 Message usage) appears to usemessage.contents(plural) for non-text content (e.g., tool call content items). IfMessageinstances havecontentsbut nocontent, this will fall back tostr(message)and can produce poor/empty queries and stored memories. Update_get_textto also handlecontents(and extract any text segments from it) before falling back tostr(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 ""
…and OrchestratorBase
…eter support and backward compatibility
There was a problem hiding this comment.
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 withoutawaitand then treated as an async iterator via__aiter__(). If the parent implementation is anasync 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, sostreamis guaranteed to be anAsyncIterable.
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_textonly checksmessage.textandmessage.content, but elsewhere in this PR the new frameworkMessageis accessed viamessage.contents(plural). If the framework provides content primarily viacontents(e.g., TextContent items) andtextis empty, this will store/search withstr(message)instead of the actual user/assistant text, reducing memory retrieval quality. Add support formessage.contents(and extract textual parts) before falling back tostr(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 ""
Purpose
This pull request updates dependencies and refactors the agent builder and client helper code to align with the latest
agent-frameworklibrary changes. The main focus is on supporting the newAgentclass and handling the removal or renaming of several types and clients inagent-framework1.3.0. The changes improve compatibility and future-proof the codebase.Does this introduce a breaking change?