Skip to content

chore: Dev merge to Main#301

Merged
Roopan-Microsoft merged 44 commits into
mainfrom
dev
Jun 25, 2026
Merged

chore: Dev merge to Main#301
Roopan-Microsoft merged 44 commits into
mainfrom
dev

Conversation

@ShreyasW-Microsoft

Copy link
Copy Markdown
Contributor

Purpose

This pull request includes several improvements and updates across the GitHub Actions workflows, infrastructure templates, Python dependencies, and code samples. The most significant changes are focused on improving security and maintainability in CI/CD workflows, updating dependency versions for compatibility, and enhancing the flexibility and correctness of the agent framework builder.

CI/CD Workflow Improvements:

  • Updated Docker build and deployment workflows to use ${{ vars.ACR_TEST_LOGIN_SERVER }} instead of secrets for referencing the Azure Container Registry, improving security and consistency across job-docker-build.yml, job-deploy-linux.yml, and job-deploy-windows.yml [1] [2] [3] [4] [5] [6] [7].
  • Refactored the Docker build workflow (job-docker-build.yml) to simplify triggers and permissions, removing unnecessary workflow inputs and adding workflow_dispatch as a trigger.
  • Improved the conditional logic for running the Docker build job in deploy-orchestrator.yml to ensure it only runs for manual dispatches with Docker builds enabled.
  • Modified the broken links checker workflow to explicitly exclude mailto: links and removed the deprecated --exclude-mail flag [1] [2].

Infrastructure and Dependency Updates:

  • Added missing dependencies in Bicep and ARM templates to ensure private endpoints are created in the correct order, preventing deployment failures (main.bicep, main_custom.bicep, main.json) [1] [2] [3].
  • Upgraded agent-framework to version 1.3.0 and azure-ai-projects to 2.1.0 for better compatibility and access to new features (pyproject.toml, requirements.txt) [1] [2].

Agent Framework Builder Enhancements:

  • Refactored AgentBuilder to support the new Agent class and related middleware types, added logic to handle reasoning models that do not support certain parameters, and improved model name resolution and parameter stripping [1] [2] [3] [4].

Documentation and Sample Code Improvements:

  • Updated code samples in codeSample.py to use the latest azure-ai-projects API, including new thread/message/run creation methods and improved error handling [1] [2].
  • Clarified documentation for local development and process framework setup, including updated instructions for dependency installation and workflow builder usage [1] [2] [3].

These changes collectively improve the robustness, maintainability, and clarity of the repository's workflows, infrastructure, and developer guidance.

Does this introduce a breaking change?

  • Yes
  • No

Golden Path Validation

  • I have tested the primary workflows (the "golden path") to ensure they function correctly without errors.

Deployment Validation

  • I have validated the deployment process successfully and all services are running as expected with this change.

What to Check

Verify that the following are valid

  • ...

Other Information

Prachig-Microsoft and others added 30 commits June 12, 2026 17:50
- Update agent-framework from 1.0.0b260107 to 1.3.0 in pyproject.toml
- Update azure-ai-projects from 1.0.0b12 to 2.1.0 in requirements.txt
- Migrate ChatAgent to Agent (client=, default_options=ChatOptions)
- Migrate agent_framework.azure to agent_framework.openai module paths
- Migrate ChatMessage to Message with Content.from_text()
- Migrate Role enum to string literals
- Migrate AgentRunContext to AgentContext
- Migrate WorkflowBuilder to new API (start_executor=, add_chain)
- Migrate event handling from isinstance checks to WorkflowEvent.type
- Migrate GroupChatBuilder to agent_framework.orchestrations module
- Migrate ContextProvider to before_run/after_run interface
- Remove ToolProtocol (use Any), AgentProtocol (use SupportsAgentRun)
- Define ManagerSelectionResponse locally (removed from framework)
- Update MCP tool files for Agent import
- Update all unit tests for new APIs (812 tests passing)
- Update docs/ProcessFrameworkGuide.md with new WorkflowBuilder example
- Update docs/LocalDevelopmentSetup.md prerelease note
- Regenerate uv.lock

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
AgentBuilder.with_context_providers() and with_middleware() accepted single
objects but passed them directly to Agent(), which expects Sequence types.
Now both methods auto-wrap single items into a list.

Also wrapped the call site in orchestrator_base.py for clarity.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The parent OpenAIChatClient._inner_get_response is a regular def that
returns ResponseStream (async iterable) when stream=True, or Awaitable
when stream=False. The override was async def, which always returned a
coroutine, breaking 'async for event in workflow.run(stream=True)'.

Refactored to:
- Regular def _inner_get_response dispatching stream vs non-stream
- _non_streaming_with_retry: async coroutine with retry + context-trim
- _streaming_with_retry: async generator with pre-first-chunk retry
- _maybe_trim_messages: shared context-trim helper

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…erator

The framework's BaseChatClient.get_response checks
isinstance(result, ResponseStream) for streaming responses. Our async
generator from _streaming_with_retry failed that check, causing the
framework to 'await' it — which fails with 'object async_generator
can't be used in await expression'.

Fix: for streaming, pass through to the parent's _inner_get_response
which returns a proper ResponseStream. Retry is preserved for
non-streaming calls. Removed unused _streaming_with_retry method.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- _trim_messages: keep at least 1 message (never pop to empty)
- _maybe_trim_messages: fall back to originals if trim produces empty
- _non_streaming_with_retry: re-raise if aggressive trim empties list
- _inner_get_response: log warning and use originals if messages empty

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Responses API requires the new v1 API endpoint. The old preview
version (2025-03-01-preview) does not support the /responses endpoint,
causing BadRequest 'API version not supported' errors at runtime.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…pletions API)

Adds a new AzureOpenAIChatClientWithRetry that wraps OpenAIChatCompletionClient

(the /chat/completions endpoint) with the same 429-retry and context-trimming

logic as the existing AzureOpenAIResponseClientWithRetry, then switches the

default client registered in AgentFrameworkHelper and the per-thread client in

OrchestratorBase to use it.

The /chat/completions endpoint works with the existing 2025-03-01-preview

Azure OpenAI API version, so the v1 API-version bump (commit 1d86176) is no

longer required and is reverted in the prior commit.

Mirrors the approach used in microsoft/content-processing-solution-accelerator#599.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…eter

OpenAIChatCompletionClient._inner_get_response is a SYNC method that returns

either Awaitable[ChatResponse] (stream=False) or ResponseStream (stream=True),

matching the OpenAIChatClient (Responses API) shape.

The previous implementation used async def without a stream parameter, which

caused the framework's streaming path to receive a coroutine instead of an

AsyncIterable, raising:

    'async for' requires an object with __aiter__ method, got coroutine

Mirror the existing AzureOpenAIResponseClientWithRetry pattern: sync _inner_get_response

that branches on stream and delegates non-streaming calls to _non_streaming_with_retry.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
OpenAI's Chat Completions endpoint validates the message `name` field against the pattern `^[^\s<|\\/>]+$`. Our agents have display names with whitespace (e.g. `Chief Architect`, `AKS Expert`), which caused a 400 BadRequest after switching the default client to `AzureOpenAIChatClientWithRetry`.

Add `_sanitize_author_name` / `_sanitize_author_names` helpers that replace runs of disallowed characters (whitespace, `<`, `|`, `\`, `/`, `>`) with a single underscore and strip leading/trailing underscores. Names that sanitize down to an empty string are dropped entirely so the field can be omitted from the request.

The sanitizer is applied inside `AzureOpenAIChatClientWithRetry._inner_get_response` after context trimming (and again after the trim-fallback retry inside `_non_streaming_with_retry`) so the wire format passes validation while in-memory `Message` objects keep their original display names for orchestration logic. Originals are never mutated — modified messages are shallow-copied before the name is rewritten.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The [AOAI_RETRY] empty messages list received warning fired on every
turn in group-chat orchestration when the same speaker was selected
twice in a row, flooding logs and giving the false impression of an
error.

This pattern is by design in agent-framework's GroupChatOrchestrator:
_broadcast_messages_to_participants excludes the source executor, so
when the orchestrator routes back to the same agent, its message
cache is empty. The framework already emits its own
"AgentExecutor ... Running agent with empty message cache" warning
for this case.

The actual API call is not empty -- the parent
OpenAIChatCompletionClient._prepare_options prepends the agent's
system instructions from options["instructions"] before sending. So
demoting our duplicate warning to DEBUG removes the noise without
hiding any real failure.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The agent_framework_orchestrations.GroupChatBuilder forces the Coordinator's response_format to AgentOrchestrationOutput (strict schema with fields next_speaker/reason/terminate). Our prompt asks for selected_participant/instruction/finish, but strict structured output overrides the prompt's field names.

Without aliases, ManagerSelectionResponse.model_validate() silently succeeded with all fields = None (extra=allow), which disabled:

  - The 3-strike loop-detection streak counter (line 1019-1054)

  - Coordinator-driven termination on finish=true (line 1065)

  - _agent_invoked_at[selected] elapsed-time tracking (line 1098)

Use Pydantic AliasChoices so the model accepts BOTH naming conventions, restoring anti-loop and termination logic.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Production still hits 400 BadRequest on messages[N].name even though _inner_get_response runs _sanitize_author_names on incoming Messages. The framework's _prepare_options/_prepare_messages_for_openai layer or agent-internal compaction can materialize messages with author_name set AFTER our early sanitization, leaving the dict 'name' field unsanitized on the wire.

Override _prepare_messages_for_openai (the parent method that builds the final OpenAI dict payload) to sanitize each dict's 'name' field as a last-mile pass. This is the single chokepoint guaranteed to be on every Chat Completions request, regardless of upstream message-construction path.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When Coordinator keeps picking the same agent A and A keeps running, A's
own completions were bumping _progress_counter. Loop detection compares
the counter snapshot taken at the previous identical Coordinator pick
against the current value; if it changed, the streak was reset to 1. So
the 3-strike threshold was never reached and the Coordinator->A->A
pattern ran until max_rounds.

Now we only treat a non-Coordinator completion as 'progress' when the
completing agent is different from the agent the Coordinator is
currently latching onto (_last_coordinator_selection[0]). A different
agent stepping in still resets the streak; A repeating itself does not.

Adds two regression tests covering both cases. Also updates an existing
termination test whose name described 'other agent makes progress' but
actually used the same agent, hard-coding the buggy semantics.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ute by capability

The Coordinator's valid_participants block was a bullet list of names only,
so the LLM had no per-agent capability signal. Combined with a Coordinator
prompt that names 'Chief Architect' frequently across phases 0/1/4/5/6,
the model latched onto Chief Architect repeatedly and the conversation
looped on the same agent.

This change populates agent_description on every Analysis participant
(Chief Architect, AKS Expert, and the platform experts in
platform_registry.json) and renders each description into the Coordinator's
valid_participants list. The descriptions are also passed through
AgentBuilder.create_agent_by_agentinfo's existing description= argument,
so the framework's Agent.description field is no longer always None.

Scope: Analysis step only. design/yaml/documentation orchestrators are
left for a follow-up after this change is validated in production.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Production run after the previous progress-counter fix (0da531f) STILL
showed Chief Architect picked 6+ consecutive times. Root cause: the
loop detection key was (agent, instruction_text). The LLM-driven
Coordinator varies its instruction on every pick ('list source blobs',
'read xyz.yaml', 'save analysis_result.md') while latching onto the
same agent — so every selection_key was unique, the streak reset to 1
on every pick, and the 3-strike threshold was never reached.

Change: track only the agent name (lower-cased). The progress counter
(now correct after 0da531f) already encodes 'no DIFFERENT agent ran in
between', so 3 consecutive picks of the same agent with no other-agent
progress is a strong, low-false-positive loop signal.

Adds a regression test that replays the production sequence (same agent,
three different instruction strings) and verifies forced termination
fires. The earlier tests for exact-match repeats and for B-resets-the-
streak continue to pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Production deployment of the agent-framework 1.3.0 upgrade surfaced a
crash chain: Analysis "succeeded" with a self-contradictory result
(result=True, is_hard_terminated=False, output=None), Design then
crashed at `task_param.output.process_id`. The root cause is the
ResultGenerator returning an empty shell when participants never
produced useful content.

Fixes:

* groupchat_orchestrator.run_stream now validates ResultGenerator output
  before constructing OrchestrationResult. If the result is not hard
  terminated but carries no `output` / `termination_output` payload, the
  orchestrator now reports success=False with a descriptive error. This
  is generic across all four step models (Analysis uses `output`;
  Design/Convert/Documentation use `termination_output`).
* All four step executors gained a defense-in-depth guard that raises a
  clear `<Step>Executor failed: produced no <X>Output. Reason: ...`
  exception when the same incoherent shape is observed. This stops the
  broken value at the boundary instead of propagating it downstream.
* groupchat_orchestrator silent `except Exception: pass` around
  Coordinator JSON parsing replaced with `logger.debug(... exc_info=...)`
  so loop-detection failures become visible during debugging instead of
  being swallowed.

Tests:

* Updated each executor's existing soft-completion test to provide a
  valid output (previous setup encoded the broken shape we now reject).
* Added a new guard test per executor asserting the new exception fires
  for the incoherent (success=True + output=None + not hard-terminated)
  shape.
* Full unit suite: 829 passed (was 825; +4 new guard tests).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Root cause of the "Runner did not converge after 100 iterations"
production failure (and the Chief-Architect-only loop that preceded it):
agent-framework 1.3.0 changed how AgentResponseUpdate is constructed.
`map_chat_to_agent_update` (_types.py:2825-2837) now only sets
`author_name` and leaves `agent_id` as None.

Our orchestrator was reading `event.agent_id` exclusively, so every
streaming update resolved to `agent_name=""`. That silently broke:

  * Loop detection (line 1080 `if agent_name == self.coordinator_name`
    never matched, so the streak counter never advanced and the 3x
    same-agent guard never fired). Production looped 100x on Chief
    Architect with zero detection.
  * Coordinator termination signal extraction (`finish=true`,
    `instruction=complete`, blocking instructions) - same gated block.
  * Manager-instruction parsing for the next participant.

The [MEMORY] logs continued to show real agent names ("Chief Architect")
because `SharedMemoryContextProvider` reads the name from the agent's
own context, not from the workflow event - which is why the regression
was invisible from logs alone.

Fix: in `_handle_agent_update`, prefer `event.author_name` (which IS
populated by 1.3.0's `map_chat_to_agent_update`) and fall back to
`agent_id` only when author_name is missing, for backwards compat with
older event shapes. Use `getattr` defensively so existing tests that
construct SimpleNamespace events without author_name still work.

Tests:

* test_handle_agent_update_resolves_coordinator_via_author_name_when_agent_id_is_none
  - asserts the identity resolution itself
* test_loop_detection_fires_on_3_consecutive_coordinator_selections_via_handle_agent_update
  - end-to-end through the production code path: 3 identical Coordinator
    selections via _handle_agent_update must trip _forced_termination
* Both tests verified to FAIL without the fix (intentionally reverted to
  confirm) and PASS with the fix
* Full suite: 831 passed (was 829, +2 regression tests)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…rounds for af 1.3.0

In agent-framework 1.3.0, `workflow.run(stream=True)` only yields
`WorkflowEvent` instances. `AgentResponseUpdate` is wrapped inside
`event.data` for `type=="output"` events. The two types are unrelated
(verified by MRO), so the previous `isinstance(event, AgentResponseUpdate)`
gate from the b260107 era was permanently dead in 1.3.0. As a result every
orchestrator-side safety guard inside that branch silently no-opped:

* per-agent loop detection
* Coordinator finish=true detection
* max_rounds enforcement
* streaming callback dispatch
* manager-instruction extraction

That is why production runs hit the framework's own 100-iteration runner
cap as `RuntimeError("Runner did not converge after 100 iterations")`
even after the recent identity-resolution patch (which only touched code
that never executed).

Three coordinated fixes:

1. Replace the dead `isinstance(event, AgentResponseUpdate)` gate with
   `isinstance(event, WorkflowEvent) and event.type == "output"` and
   inspect `event.data` / `event.executor_id` to distinguish per-
   participant streaming chunks (executor_id matches one of self.agents
   and data is AgentResponseUpdate) from the framework orchestrator's
   final output (list[Message] or custom result object).

2. Add `executor_id` parameter to `_handle_agent_update` so identity
   resolves from the WorkflowEvent wrapper's executor_id (always populated
   from `AgentExecutor.id` = the agent's name) first, then falls back
   to `event.author_name`, then legacy `event.agent_id`. Matches the
   approach already used by Content Processing Solution.

3. Pass `max_rounds=self.max_rounds` and `intermediate_outputs=True`
   to `GroupChatBuilder`:
   - `max_rounds` gives the framework itself a clean termination
     ceiling so even if our orchestrator-side guards miss, the workflow
     halts cleanly instead of crashing at the runner's 100-iteration cap.
   - `intermediate_outputs=True` is required for each participant's
     `yield_output(AgentResponseUpdate)` call to surface as a workflow
     `output` event. Without this, only the orchestrator's final yield
     reaches our streaming loop and the per-agent guards above never run.

Tests:
* Existing termination/loop-detection tests still pass (handler now has
  3-tier identity resolution with backward-compat for `author_name`).
* Added `test_handle_agent_update_prefers_executor_id_over_author_name`
  to lock in the new precedence.
* Added `test_handle_agent_update_strips_executor_id_prefix` to cover
  the `groupchat_agent:Coordinator` framework prefix.
* Full suite: 833 passed (was 831; +2 new tests).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
In agent-framework 1.3.0 the GroupChat orchestrator agent (Coordinator)
is invoked directly inside the framework's internal _invoke_agent_helper
(agent_framework_orchestrations/_group_chat.py:484) rather than through
an AgentExecutor. The Coordinator therefore never surfaces as a workflow
event, which makes our existing Coordinator-JSON-based loop detector in
_complete_agent_response permanently dead in 1.3.0.

Symptom in production: workflow loops with the Coordinator latched onto
the same participant (e.g., Chief Architect repeatedly asked to produce
an Evidence Pack that never satisfies the next reviewer). The loop runs
until the framework's max_rounds ceiling fires (~17 min at default 100)
instead of being caught early.

Fix:
* Track participant turn completions from WorkflowEvent.executor_completed,
  the one observable signal that does NOT depend on Coordinator visibility
  (participants ARE wrapped in AgentExecutor and so do emit these events).
* Force-terminate (hard_loop) after 3 consecutive completions of the same
  participant.
* Force-terminate (hard_timeout) when total participant completions reach
  max_rounds; independent of len(agent_responses) which only grows on
  agent switch and so can never reach max_rounds during a same-participant
  loop.
* Flush per-participant streaming buffer on each executor_completed so
  back-to-back same-agent turns produce one AgentResponse per turn instead
  of accumulating across turns.
* Move forced-termination break check to top of the streaming loop so any
  branch (timeout, participant loop, Coordinator finish=true) takes effect
  on the very next event rather than waiting for the next output event.

Adds 3 regression tests covering the streak trigger, the alternation
reset, and the round-budget enforcement. 836 tests pass (833 -> 836).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…p dead code

* Add a narrow logging.Filter on agent_framework._workflows._agent_executor
  that drops only the 'Running agent with empty message cache' message.
  This warning fires by design in GroupChat orchestration when the orchestrator
  routes back to the same speaker (broadcast cache is empty because
  _broadcast_messages_to_participants excludes the source executor). The
  framework's parent client prepends system instructions before the LLM call,
  so the API request still has content. Other warnings/errors from the same
  logger remain visible.

* Remove three lines of commented-out duplicate callback invocation in
  groupchat_orchestrator._complete_agent_response. The live callback handler
  is in the block directly above; the commented block was refactor debris.

No behavioural change. All 833 tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ee action

The --exclude-mail flag was removed in lychee v0.23.0. Replace with
equivalent --exclude pattern to fix CI failures on PRs touching .md files.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When the Coordinator signals finish=true, the streaming loop breaks before
the framework's final output event (carrying the conversation) arrives.
This left the conversation empty, causing ResultGenerator to produce
'nothing to summarize' and failing the step despite actual work being done.

Two fixes:
1. After the streaming loop, if conversation is empty but agent_responses
   exist, reconstruct the conversation from collected agent responses.
2. Sign-off validation now uses agent_responses when self._conversation
   is still empty, fixing vacuous validation during early termination.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…or_name)

_validate_sign_offs was using msg.content and msg.source which do not
exist on agent-framework 1.3.0 Message objects, causing runtime crashes.
Updated to use msg.text and msg.author_name. Updated corresponding test
mocks to use the new API attributes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
In agent-framework 1.3.0, GroupChatBuilder makes the Coordinator internal
to AgentBasedGroupChatOrchestrator - its responses never appear in the
streaming loop, making our coordinator-based loop detection dead code.

Additionally, _start_agent_if_needed silently returned when the same
agent was selected consecutively, preventing max_rounds from counting.

Fixes:
- Use response_id from AgentResponseUpdate to detect new invocations
  of the same agent (even when executor_id hasn't changed)
- Add participant-side loop detection: if same agent runs 5+
  consecutive times, force termination with descriptive message

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

github-actions Bot commented Jun 24, 2026

Copy link
Copy Markdown

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.288s ⏱️

Comment thread src/processor/src/libs/agent_framework/azure_openai_response_retry.py Dismissed
Comment thread src/processor/src/libs/agent_framework/groupchat_orchestrator.py Dismissed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR merges dev updates into main, centered on upgrading the processor to agent-framework==1.3.0 and refactoring the processor’s multi-agent orchestration, alongside CI/CD hardening (ACR vars), infrastructure dependency fixes for private endpoints, and documentation/sample updates.

Changes:

  • Upgrade agent-framework to 1.3.0 and refactor processor orchestration code/tests to the new Agent / WorkflowEvent / middleware/context-provider APIs.
  • Improve CI/CD workflow security and maintainability (use ${{ vars.ACR_TEST_LOGIN_SERVER }}, simplify reusable workflow invocation, update link checker excludes).
  • Fix infra private endpoint deployment ordering by adding missing dependencies / DNS zone deps.

Reviewed changes

Copilot reviewed 49 out of 50 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/processor/uv.lock Lockfile update for agent-framework 1.3.0 and new transitive deps.
src/processor/src/utils/logging_utils.py Adds narrow log filter to suppress known “empty message cache” warning noise.
src/processor/src/tests/unit/steps/test_migration_processor_run.py Updates workflow event tests to WorkflowEvent API and streaming changes.
src/processor/src/tests/unit/steps/documentation/test_documentation_executor.py Updates documentation step tests for termination output expectations + new guard test.
src/processor/src/tests/unit/steps/design/test_design_executor.py Updates design step tests for termination output expectations + new guard test.
src/processor/src/tests/unit/steps/convert/test_yaml_convert_executor.py Updates convert step tests for termination output expectations + new guard test.
src/processor/src/tests/unit/steps/analysis/test_analysis_executor.py Updates analysis step tests for new output model + new “missing output must raise” guard.
src/processor/src/tests/unit/libs/agent_framework/test_shared_memory_context_provider.py Updates shared memory context provider tests to before/after hooks + new Message shape.
src/processor/src/tests/unit/libs/agent_framework/test_middlewares_extras.py Updates middleware tests to new Message/Content API.
src/processor/src/tests/unit/libs/agent_framework/test_input_observer_middleware.py Updates input observer middleware test to new Message/Content API.
src/processor/src/tests/unit/libs/agent_framework/test_groupchat_orchestrator_termination.py Updates termination tests and adds regression coverage for 1.3.0 identity resolution.
src/processor/src/tests/unit/libs/agent_framework/test_groupchat_orchestrator_internals.py Refactors orchestrator internals tests for 1.3.0 event/message shapes; expands loop-breaker coverage.
src/processor/src/tests/unit/libs/agent_framework/test_azure_openai_response_retry_utils.py Adds author-name sanitization tests and retains trim/retry coverage.
src/processor/src/tests/unit/libs/agent_framework/test_agent_framework_helper.py Updates helper tests for new client constructors/params and removed client types.
src/processor/src/tests/unit/libs/agent_framework/test_agent_builder.py Updates builder tests for Agent + ChatOptions(default_options) changes and list-wrapping behavior.
src/processor/src/steps/migration_processor.py Migrates workflow execution to workflow.run(stream=True) and WorkflowEvent handling; updates builder usage.
src/processor/src/steps/documentation/workflow/documentation_executor.py Adds explicit failure when “soft success” has no termination output.
src/processor/src/steps/documentation/orchestration/documentation_orchestrator.py Removes ToolProtocol typing in favor of broader Any-based typing.
src/processor/src/steps/design/workflow/design_executor.py Adds explicit failure when “soft success” has no termination output.
src/processor/src/steps/design/orchestration/design_orchestrator.py Removes ToolProtocol typing in favor of broader Any-based typing.
src/processor/src/steps/convert/workflow/yaml_convert_executor.py Adds explicit failure when “soft success” has no termination output.
src/processor/src/steps/convert/orchestration/yaml_convert_orchestrator.py Removes ToolProtocol typing in favor of broader Any-based typing.
src/processor/src/steps/analysis/workflow/analysis_executor.py Adds explicit failure when “soft success” has no output payload.
src/processor/src/steps/analysis/orchestration/platform_registry.json Adds descriptions per platform expert to improve coordinator routing.
src/processor/src/steps/analysis/orchestration/analysis_orchestrator.py Includes agent descriptions in coordinator participant list and enriches AgentInfo metadata.
src/processor/src/libs/mcp_server/MCPMicrosoftDocs.py Updates examples to use Agent instead of ChatAgent.
src/processor/src/libs/mcp_server/MCPDatetimeTool.py Updates examples to use Agent instead of ChatAgent.
src/processor/src/libs/mcp_server/MCPBlobIOTool.py Updates examples to use Agent instead of ChatAgent.
src/processor/src/libs/base/orchestrator_base.py Refactors to new client types and agent creation API; updates context provider wiring.
src/processor/src/libs/agent_framework/shared_memory_context_provider.py Migrates context provider hooks to before_run/after_run with SessionContext.
src/processor/src/libs/agent_framework/middlewares.py Migrates middleware types and message mutation to Message/Content.
src/processor/src/libs/agent_framework/groupchat_orchestrator.py Major refactor for agent-framework 1.3.0 group chat orchestration, loop detection, and event streaming.
src/processor/src/libs/agent_framework/azure_openai_response_retry.py Adds chat-completions retry client + author name sanitization + updated trimming behavior.
src/processor/src/libs/agent_framework/agent_speaking_capture.py Updates middleware signature to new AgentContext.
src/processor/src/libs/agent_framework/agent_info.py Updates tools typing away from ToolProtocol.
src/processor/src/libs/agent_framework/agent_framework_helper.py Adds AzureOpenAIChatCompletionWithRetry client type; removes/blocks deprecated clients.
src/processor/src/libs/agent_framework/agent_builder.py Replaces ChatAgent builder with Agent builder using ChatOptions and reasoning-model param stripping.
src/processor/pyproject.toml Bumps agent-framework dependency to 1.3.0.
infra/vscode_web/requirements.txt Updates azure-ai-projects to 2.1.0.
infra/vscode_web/codeSample.py Updates sample to latest azure-ai-projects thread/message/run APIs and improved failure handling.
infra/main.json Adds additional private DNS zone dependencies for correct PE ordering.
infra/main.bicep Adds explicit dependsOn to AI Foundry private endpoint module.
infra/main_custom.bicep Adds explicit dependsOn to AI Foundry private endpoint module (custom variant).
docs/ProcessFrameworkGuide.md Updates docs for new WorkflowBuilder chaining and test command path.
docs/LocalDevelopmentSetup.md Clarifies prerelease install guidance (still requires --prerelease=allow for transitive deps).
.github/workflows/job-docker-build.yml Uses vars for ACR host, adds workflow_dispatch, and moves job gating to caller.
.github/workflows/job-deploy-windows.yml Switches ACR endpoint reference from secrets to vars.
.github/workflows/job-deploy-linux.yml Switches ACR endpoint reference from secrets to vars.
.github/workflows/deploy-orchestrator.yml Gates docker-build reusable workflow call via orchestrator inputs instead of passing removed inputs.
.github/workflows/broken-links-checker.yml Updates lychee args to exclude mailto: via regex and removes deprecated flag usage.

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

Comment thread src/processor/src/libs/agent_framework/groupchat_orchestrator.py
Comment thread src/processor/src/libs/agent_framework/groupchat_orchestrator.py
Comment thread src/processor/src/libs/agent_framework/groupchat_orchestrator.py
ShreyasW-Microsoft and others added 2 commits June 24, 2026 15:50
Pin agent-framework-orchestrations to the locked 1.0.0b260507 in the
processor_tests install step. The agent-framework-core[all] extra pulls
orchestrations in unpinned, so pip's fresh resolve grabbed the stable
1.0.0 which requires agent-framework-core>=1.9.0, conflicting with the
pinned agent-framework-core==1.3.0 and failing installation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
agent-framework 1.3.x requires Message.contents to hold Content objects,
not raw strings. _select_recent_messages and
_reconstruct_conversation_from_responses passed plain str values
(truncated text and AgentResponse.message), which fail pydantic
validation at runtime and can break downstream .text extraction in the
ResultGenerator and tool-usage backfill. Import Content and wrap both
call sites with Content.from_text, matching the pattern used across the
unit tests.

Addresses Copilot review comments on PR #301.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ShreyasW-Microsoft and others added 2 commits June 24, 2026 17:31
Move the agent-framework-orchestrations pin from the CI install step
into the package metadata so the constraint is expressed at the source
and applies to every install path (CI pip, local pip, and uv).

The agent-framework-core[all] extra pulls orchestrations in unpinned;
without a constraint a fresh resolve grabs the stable 1.0.0 which
requires agent-framework-core>=1.9.0 and conflicts with the pinned
agent-framework-core==1.3.0. Pin it to 1.0.0b260507 (already locked).

uv.lock updated minimally (orchestrations promoted to a direct dep;
no other packages changed) and verified with uv lock --locked. Reverts
the CI workaround in test.yml.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
fix(ci): resolve processor_tests dependency conflict
@github-actions

Copy link
Copy Markdown

Coverage

Tests Skipped Failures Errors Time
834 0 💤 0 ❌ 0 🔥 18.814s ⏱️

@ShreyasW-Microsoft

ShreyasW-Microsoft commented Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

@ShreyasW-Microsoft please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.

@microsoft-github-policy-service agree [company="{your company}"]

Options:

  • (default - no company specified) I have sole ownership of intellectual property rights to my Submissions and I am not making Submissions in the course of work for my employer.
@microsoft-github-policy-service agree
  • (when company given) I am making Submissions in the course of work for my employer (or my employer has intellectual property rights in my Submissions by contract or applicable law). I have permission from my employer to make Submissions and enter into this Agreement on behalf of my employer. By signing below, the defined term “You” includes me and my employer.
@microsoft-github-policy-service agree company="Microsoft"

Contributor License Agreement

Contribution License Agreement

This Contribution License Agreement (“Agreement”) is agreed to by the party signing below (“You”), and conveys certain license rights to Microsoft Corporation and its affiliates (“Microsoft”) for Your contributions to Microsoft open source projects. This Agreement is effective as of the latest signature date below.

  1. Definitions.
    “Code” means the computer software code, whether in human-readable or machine-executable form,
    that is delivered by You to Microsoft under this Agreement.
    “Project” means any of the projects owned or managed by Microsoft and offered under a license
    approved by the Open Source Initiative (www.opensource.org).
    “Submit” is the act of uploading, submitting, transmitting, or distributing code or other content to any
    Project, including but not limited to communication on electronic mailing lists, source code control
    systems, and issue tracking systems that are managed by, or on behalf of, the Project for the purpose of
    discussing and improving that Project, but excluding communication that is conspicuously marked or
    otherwise designated in writing by You as “Not a Submission.”
    “Submission” means the Code and any other copyrightable material Submitted by You, including any
    associated comments and documentation.
  2. Your Submission. You must agree to the terms of this Agreement before making a Submission to any
    Project. This Agreement covers any and all Submissions that You, now or in the future (except as
    described in Section 4 below), Submit to any Project.
  3. Originality of Work. You represent that each of Your Submissions is entirely Your original work.
    Should You wish to Submit materials that are not Your original work, You may Submit them separately
    to the Project if You (a) retain all copyright and license information that was in the materials as You
    received them, (b) in the description accompanying Your Submission, include the phrase “Submission
    containing materials of a third party:” followed by the names of the third party and any licenses or other
    restrictions of which You are aware, and (c) follow any other instructions in the Project’s written
    guidelines concerning Submissions.
  4. Your Employer. References to “employer” in this Agreement include Your employer or anyone else
    for whom You are acting in making Your Submission, e.g. as a contractor, vendor, or agent. If Your
    Submission is made in the course of Your work for an employer or Your employer has intellectual
    property rights in Your Submission by contract or applicable law, You must secure permission from Your
    employer to make the Submission before signing this Agreement. In that case, the term “You” in this
    Agreement will refer to You and the employer collectively. If You change employers in the future and
    desire to Submit additional Submissions for the new employer, then You agree to sign a new Agreement
    and secure permission from the new employer before Submitting those Submissions.
  5. Licenses.
  • Copyright License. You grant Microsoft, and those who receive the Submission directly or
    indirectly from Microsoft, a perpetual, worldwide, non-exclusive, royalty-free, irrevocable license in the
    Submission to reproduce, prepare derivative works of, publicly display, publicly perform, and distribute
    the Submission and such derivative works, and to sublicense any or all of the foregoing rights to third
    parties.
  • Patent License. You grant Microsoft, and those who receive the Submission directly or
    indirectly from Microsoft, a perpetual, worldwide, non-exclusive, royalty-free, irrevocable license under
    Your patent claims that are necessarily infringed by the Submission or the combination of the
    Submission with the Project to which it was Submitted to make, have made, use, offer to sell, sell and
    import or otherwise dispose of the Submission alone or with the Project.
  • Other Rights Reserved. Each party reserves all rights not expressly granted in this Agreement.
    No additional licenses or rights whatsoever (including, without limitation, any implied licenses) are
    granted by implication, exhaustion, estoppel or otherwise.
  1. Representations and Warranties. You represent that You are legally entitled to grant the above
    licenses. You represent that each of Your Submissions is entirely Your original work (except as You may
    have disclosed under Section 3). You represent that You have secured permission from Your employer to
    make the Submission in cases where Your Submission is made in the course of Your work for Your
    employer or Your employer has intellectual property rights in Your Submission by contract or applicable
    law. If You are signing this Agreement on behalf of Your employer, You represent and warrant that You
    have the necessary authority to bind the listed employer to the obligations contained in this Agreement.
    You are not expected to provide support for Your Submission, unless You choose to do so. UNLESS
    REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING, AND EXCEPT FOR THE WARRANTIES
    EXPRESSLY STATED IN SECTIONS 3, 4, AND 6, THE SUBMISSION PROVIDED UNDER THIS AGREEMENT IS
    PROVIDED WITHOUT WARRANTY OF ANY KIND, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY OF
    NONINFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
  2. Notice to Microsoft. You agree to notify Microsoft in writing of any facts or circumstances of which
    You later become aware that would make Your representations in this Agreement inaccurate in any
    respect.
  3. Information about Submissions. You agree that contributions to Projects and information about
    contributions may be maintained indefinitely and disclosed publicly, including Your name and other
    information that You submit with Your Submission.
  4. Governing Law/Jurisdiction. This Agreement is governed by the laws of the State of Washington, and
    the parties consent to exclusive jurisdiction and venue in the federal courts sitting in King County,
    Washington, unless no federal subject matter jurisdiction exists, in which case the parties consent to
    exclusive jurisdiction and venue in the Superior Court of King County, Washington. The parties waive all
    defenses of lack of personal jurisdiction and forum non-conveniens.
  5. Entire Agreement/Assignment. This Agreement is the entire agreement between the parties, and
    supersedes any and all prior agreements, understandings or communications, written or oral, between
    the parties relating to the subject matter hereof. This Agreement may be assigned by Microsoft.

@microsoft-github-policy-service agree company="Microsoft"

@Roopan-Microsoft Roopan-Microsoft merged commit a6a6dd0 into main Jun 25, 2026
20 checks passed
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 2.1.2 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

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.

7 participants