main
2844 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
d9d3fb6252 | .NET: Update version for 1.19.0 release (#7814) dotnet-1.19.0 | ||
|
|
abe1f629a2 |
.NET: Add support for Resilient long-running and Steerable Foundry Hosted Agents (#7370)
* feat(foundry): add resilient background hosting Enable AgentServer recovery and steering through FoundryResponsesOptions. Persist AgentSession snapshots during long background turns while workflow checkpointing remains owned by the workflow runtime. * feat(foundry): complete resilient and steerable hosting * fix(foundry): address resilience review feedback * feat(foundry): align resilient workflow checkpoints * docs(foundry): update resilience review guidance |
||
|
|
7a2b8038cc |
[BREAKING] Python: Bump package versions for 1.15.0 release (#7812)
* Bump Python package versions for 1.15.0 release Prepare the CHANGELOG-selected Python packages for the 1.15.0 release. Root and core move to 1.15.0; changed stable extensions receive package-specific minor or patch bumps; changed beta packages receive the 260821 stamp; no beta cohort bump is applied. Core dependency floors use the conservative policy for co-released packages. Release validation also adds the six dependency required by the supported Azure Cosmos SDK floor and retains cross-platform-compatible development-tool pins. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 98e979bd-1d07-41fd-946d-00db8a93e248 * Remove hook-only formatting changes Keep the Python 1.15.0 release commit scoped to package metadata, release notes, dependency floors, and the lockfile. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 98e979bd-1d07-41fd-946d-00db8a93e248 * Minimize release lockfile changes Restore the upstream PyPI-backed lockfile and retain only package versions and dependency metadata changed by the Python 1.15.0 release. Also preserve the development-tool upgrades already present on main. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 98e979bd-1d07-41fd-946d-00db8a93e248 * Retain OpenAI core compatibility floor Keep agent-framework-openai 1.13.1 compatible with core 1.13 because its streaming tool-call index fix uses the existing additional_properties API and does not require core 1.15. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 98e979bd-1d07-41fd-946d-00db8a93e248 * Raise OpenAI version and core floor Bump agent-framework-openai to 1.14.0 and require core 1.15.0 so the new dependency requirement is signaled as a minor release. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 98e979bd-1d07-41fd-946d-00db8a93e248 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 98e979bd-1d07-41fd-946d-00db8a93e248python-1.15.0 |
||
|
|
65e8aff93b | Fix DevFlow review command whitespace handling (#7813) | ||
|
|
c6a0e90250 |
Python: correct MCP tool argument filtering documentation (#7801)
* Python: correct MCP tool argument filtering documentation The documentation for MCPTool's outbound argument filtering did not match its behavior. The comment on _prepare_call_kwargs stated that framework runtime kwargs are "stripped so it is never forwarded to the MCP server", and packages/core/AGENTS.md repeated the same claim. In practice, runtime kwargs (FunctionInvocationContext.kwargs, seeded from function_invocation_kwargs) are merged with the model-supplied arguments in _call_tool_with_runtime_kwargs before the filter runs, so provenance is no longer distinguishable at that point. The allowlist is built from the tool's declared inputSchema.properties as advertised by the server, plus names opted in through additional_tool_argument_names. A runtime kwarg is therefore forwarded whenever the server declares a property of the same name, without the model supplying it. Update the comments, docstrings and docs to describe the actual rule, and point each transport at its appropriate channel for values that should not become tool arguments (env for stdio, header_provider for streamable HTTP). Also narrow the docstring of test_call_tool_forwards_only_declared_arguments, which claimed more than it asserts (it covers undeclared names only), and add a companion test pinning the declared-name behavior so the documented rule stays verifiable. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: address review feedback on MCP argument filtering docs Corrects and tightens the documentation added in the previous commit. - header_provider does not withhold values from the outbound argument filter; it reads the runtime kwargs without consuming them. The earlier wording recommended it as a way to keep a value out of tool arguments, which is wrong. Replaced in four places with the pattern that does work: source the credential outside function_invocation_kwargs, for example by reading a ContextVar inside the provider, which still allows a different value per request. - Note the _meta key and the framework denylist as exceptions wherever the docs say server-declared names are forwarded. - Rework test_call_tool_forwards_runtime_kwargs_the_server_declares to invoke the generated FunctionTool with a FunctionInvocationContext, so it exercises the real runtime-kwargs path instead of calling call_tool directly. Verified by mutation: removing the merge in _call_tool_with_runtime_kwargs now fails the test. - Add a test covering the recommended ContextVar pattern. - Condense the transport docstring notes, which had grown into three near-duplicate blocks. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
7b7b9a128c |
Python: Foundry Hosted Agent Resiliency Support (#7670)
* Migrate FHA to responses==2.0.0b1 and add Foundry state store * Fix session id error * Fix tests * Improve tests * Fix copilot comments * Address comments * Revert sample changes * Address comments * Add ContextScopedStoreProvider * Fix type check * Fix type check * LRA on top of state store * Temp disable state store user isolation * Simulate shutdown * Remove sim shutdown * Add sample * refine resiliency sample * Add steerable conversation support * Revert uv.lock * Add last_checkpoint_id and checkpoint existence check * Tighted resilient-recovery states * Tests for tightened resilient-recovery states * Make cancellation effective even when the iterator is stuck * Add more tests and fix sample * Small adjustment after review * Fix typing * Fix typing * Close driver background task in case of exceptions raised in the consumer * Handle usage content * xfail an integration test due to a known gap * Fix formatting --------- Co-authored-by: Evan Mattson <35585003+moonbox3@users.noreply.github.com> |
||
|
|
eb8548e582 |
Docs: add Go to the main README (#7754)
* docs: add Go to main README * docs: address Go README review feedback * docs: refine Go support wording * docs: preserve focused contributor resources * docs: scope Go reference to separate repository * Apply batched suggestions from code review Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com> --------- Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com> |
||
|
|
ede605d868 |
.NET: Bump AgentMemory from 1.3.0 to 1.4.1 (#7639)
* Bump AgentMemory from 1.3.0 to 1.4.1 --- updated-dependencies: - dependency-name: AgentMemory dependency-version: 1.4.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> |
||
|
|
eccf47154f |
.NET: Fix ReasoningSummary passthrough in GitHub Copilot resume config (#6441)
* .NET: Fix ReasoningSummary passthrough in GitHub Copilot resume config CopyResumeSessionConfig hand-copies a subset of SessionConfigBase into a new ResumeSessionConfig instead of using Clone(). It was missing ReasoningSummary, so callers that set SessionConfig.ReasoningSummary got readable extended-thinking summaries on the first turn but had it silently dropped on every resumed turn. ContextTier (a sibling model/context knob passed alongside ReasoningEffort/ReasoningSummary) was missing too. Both are now copied, mirroring ReasoningEffort. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * .NET: Assert ReasoningSummary/ContextTier defaults in null-source resume test Addresses PR review: the null-source CopyResumeSessionConfig test now also asserts ReasoningSummary and ContextTier default to null, locking the intended default behavior of the newly copied properties. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com> |
||
|
|
6a58888f3a |
Python: Bump uv from 0.11.32 to 0.12.5 in /python (#7780)
* Bump uv from 0.11.32 to 0.12.5 in /python Bumps [uv](https://github.com/astral-sh/uv) from 0.11.32 to 0.12.5. - [Release notes](https://github.com/astral-sh/uv/releases) - [Changelog](https://github.com/astral-sh/uv/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/uv/compare/0.11.32...0.12.5) --- updated-dependencies: - dependency-name: uv dependency-version: 0.12.5 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Align lab uv pin to 0.12.5 and update uv.lock Co-authored-by: moonbox3 <35585003+moonbox3@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: moonbox3 <35585003+moonbox3@users.noreply.github.com> |
||
|
|
8f68f6be5d |
Bump Anthropic from 12.35.1 to 12.42.0 (#7778)
* Bump Anthropic from 12.35.1 to 12.42.0 --- updated-dependencies: - dependency-name: Anthropic dependency-version: 12.42.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Update Anthropic test clients for SDK interfaces Co-authored-by: rogerbarreto <19890735+rogerbarreto@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: rogerbarreto <19890735+rogerbarreto@users.noreply.github.com> |
||
|
|
59ecceba03 |
Python: A2UI (Agent-to-UI) support for the AG-UI adapter (#7423)
* Python: A2UI (Agent-to-UI) support for the AG-UI adapter Adds an in-package _a2ui module to agent-framework-ag-ui delivering progressive-streaming, error-recovery, and sub-agent-based A2UI surface generation, reusing the shared ag-ui-a2ui-toolkit. Includes example agents, a unit suite, and two bridge fixes (strip unanswered tool calls from replayed history; suppress the terminal MESSAGES_SNAPSHOT for A2UI runs to keep streamed order stable). Signed-off-by: ran <ran@copilotkit.ai> * Python: A2UI review feedback — declarative wiring, no agent swap Reworks A2UI so it no longer swaps the agent object mid-run, and fixes the issues that swap caused. - Drive A2UI through a dedicated runner used only for the stream call; keep the original agent bound so protected-state-key computation, approval resolution, and continuation serialization still read its real context_providers and client (no more provider-namespace or approval middleware loss). - Hand the forwarded AG-UI context to the runner directly instead of stamping it onto run-option additional_properties. That channel leaked the slice to the provider SDK on any run carrying AG-UI context, including non-A2UI runs where nothing stripped it back. Removes the stamp/strip/read helpers and the dead .NET-shaped path. - Suppress the terminal MESSAGES_SNAPSHOT off whether A2UI actually drove the run, not the literal tool names, so an unrelated user tool named "generate_a2ui" keeps its snapshot. - Fail loud with an install hint when A2UI is requested but the toolkit isn't installed, instead of advertising render_a2ui with no executor. - Include the agent's own default tools in the no-double-injection check so an already-wired agent doesn't crash on a duplicate tool name. - Execute ordinary developer tools called in the same turn as generate_a2ui (the declaration-only tool poisons the inner batch invocation), so a "look up data then render it" turn no longer skips the backend call. - Attribute nameless streaming argument deltas by the provider tool-call index so interleaved parallel calls don't cross-contaminate; the OpenAI chat client preserves that index on the content. Adds tests for the mixed-batch execution, index-based fragment attribution, and the default-tool duplicate check. Signed-off-by: ran <ran@copilotkit.ai> * Python: A2UI review round 2 — mixed-batch pipeline, client tools, snapshot - Mixed-batch (a tool called in the same turn as generate_a2ui): execute server tools through the agent's real function-invocation pipeline (client function_middleware + config), the same path approval-resume uses, instead of a direct tool.invoke() that bypassed middleware/context/session. - Look up mixed-batch tools across incoming AND the agent's own default tools, so a server tool wired only on the agent (no runtime tools=) still executes. - Leave declaration-only client tools (func=None) as user-input requests instead of synthesizing a local result, preserving the resumable client-tool flow. - Recognize a manually enable_a2ui()-wrapped agent when deciding to suppress the terminal MESSAGES_SNAPSHOT, so the ordering fix also covers that path. - Remove .NET-specific comments from the Python module. Adds tests: server-tool execution runs through middleware, default-tool execution, client declaration-only tool left as user-input. Signed-off-by: ran <ran@copilotkit.ai> * Python: A2UI review round 2 — fold context wrapper, typed runner Consolidates A2UI wiring into one owner, per review: - Fold the context-prepend (former AGUIContextAgent) into A2UIAgent, which now prepends the forwarded catalog + guidelines as a system message itself. Removes the extra agent type (matching the langgraph/strands adapters, which have no separate context agent). - Make A2UIAgent the typed runner interface: it carries the render tool(s) to strip (drop_tool_names) and is recognized via is_a2ui_runner(). plan_a2ui_injection now returns the runner (or None) instead of a bare dict, so no private plan keys leak into the host and the host no longer tracks activation separately — is_a2ui_runner() covers both the auto-injected and manual enable_a2ui() paths. Signed-off-by: ran <ran@copilotkit.ai> * Python: A2UI — bridge test for client tool + generate_a2ui in one turn End-to-end through run_agent_stream: a turn that calls a declaration-only client tool alongside generate_a2ui surfaces the client tool as a resumable frontend tool call (START/ARGS/END, no server-synthesized result) so the frontend executes and resumes it, the A2UI surface still renders, the run finishes, and no terminal MESSAGES_SNAPSHOT is emitted (manual enable_a2ui path). Confirms the mixed-batch client-tool contract on the AG-UI wire, not just at the agent level. Signed-off-by: ran <ran@copilotkit.ai> * Python: A2UI review round 3 — manual-path delegation, per-request context, facade - A2UIAgent delegates client / default_options / context_providers to the wrapped agent, so a manually enable_a2ui()-wrapped runner keeps the inner agent's configured tools, provider-owned state protection, and approval middleware that the auto-injected path already preserves. - Take the AG-UI context slice per run (a2ui_context kwarg the host passes each request) instead of only at construction, so a reused runner never serves stale catalog/guidelines. - Remove the deleted AGUIContextAgent from the package facade's __all__ and lazy exports (it no longer resolves) and drop the remaining doc references to it. Signed-off-by: ran <ran@copilotkit.ai> * Python: A2UI review round 3 — mixed-batch reuses the core invocation controls Reworks server-tool execution batched with generate_a2ui so it goes through the shared function-invocation owner faithfully instead of a partial re-implementation: - Pass the run's invocation session and the full function-middleware pipeline (static client middleware plus runtime middleware) into the execution. - Honor function_invocation_configuration["enabled"] and the shared per-request max_function_calls budget, tracked cumulatively across A2UI planner rounds, so a side-effecting tool cannot run once per round or run while invocation is disabled. - Preserve non-result control contents (e.g. a function_approval_request for an always_require tool) and the executor's termination signal instead of filtering to function_result, and surface them on the wire. - Stop the run instead of re-entering the planner whenever the turn carries calls it cannot safely replay — client tools awaiting the frontend, deferred/over-budget or approval-pending server tools, or a termination request — so an unanswered assistant tool_call is never replayed as unbalanced history. Tests: cumulative budget cap across rounds, invocation-disabled skip, approval request surfaced + run stops, and the bridge test now asserts the planner is not re-entered. Signed-off-by: ran <ran@copilotkit.ai> * Python: A2UI review round 4 — core batch executor, budget/iteration parity - Add a core-owned execute_function_call_batch() to agent_framework._tools that builds the function-middleware pipeline (static + runtime, normalizing bare objects and expanding MiddlewareBundles via categorize_middleware), normalizes config, threads the invocation session, and returns a structured result (results / control / should_terminate). A2UI's mixed-batch server execution now delegates to it instead of reproducing the pipeline/session/result handling, so a runtime `middleware=<bare>` or a bundle no longer raises or is silently skipped, and future core policy changes stay in one place. - Charge generate_a2ui against the per-request max_function_calls budget (each is a render-subagent invocation) and cap the planner rounds by max_iterations, so a generate-only planner can no longer run more render calls than the configured limits. Tests: generate-only planner honors the call budget and max_iterations; the mixed-batch budget test accounts for generate also charging. Signed-off-by: ran <ran@copilotkit.ai> * Python: A2UI review round 5 — force tools off on the final narration turn The final narration turn started a fresh inner_agent.run() with tools still enabled, so after the planner rounds/budget were spent it could execute another full batch of server/default tools and exceed max_function_calls / max_iterations. Set tool_choice="none" on that turn so it is a pure narration with no tool execution, matching the core loop's budget-exhausted final response. Test: the final narration turn's options carry tool_choice="none". Signed-off-by: ran <ran@copilotkit.ai> * Python: A2UI review round 5 — move the budget lifecycle into a core owner Add a core-owned FunctionCallBudget to agent_framework._tools that owns the per-request accounting the core loop enforces: the invocation toggle, the cumulative max_function_calls budget, the max_iterations round cap, and the tools-off final-response options. execute_function_call_batch now takes a budget and returns the deferred (unrun) calls. A2UIAgent's planner loop no longer reimplements any of this — it holds one budget object and asks it (rounds_remaining / take / exhausted / final_response_options), so server tools, generate_a2ui, the round cap, and the final tools-off turn all go through the single core owner. This removes the split that let the final turn start a fresh budget, and keeps mixed A2UI turns aligned with core policy changes. Tests: core budget primitive (take/exhausted/rounds/final-options); invocation disabled now runs no server tool AND no surface (matches the core loop). Signed-off-by: ran <ran@copilotkit.ai> * Python: A2UI review round 5 follow-up — keep budgeting local, narrate on budget exhaustion Per review, the core is not the place for a second budget abstraction: remove the FunctionCallBudget class from agent_framework._tools (execute_function_call_batch, which was the requested shared executor, stays). A2UIAgent honors the inner agent's function-invocation configuration locally again — the invocation toggle, the cumulative max_function_calls budget (charged by server tools and generate_a2ui), and the max_iterations round cap. Also fix the reported gap: when the call budget is exhausted (e.g. max_function_calls=1 spent on the first generate_a2ui), the run now breaks to the tools-off final narration turn instead of returning after the surface, so it produces a closing assistant response — matching the iteration-cap path and the core loop. Calls awaiting external resolution (client tools, deferred, approval, termination) still end the run without that final turn, since a follow-up run resumes them. Signed-off-by: ran <ran@copilotkit.ai> * Python: A2UI — feed the current surface to the budget-exhausted final narration On budget exhaustion the loop broke before appending this round's assistant tool_call(s) and results to history, so the tools-off final narration turn saw only the original user messages and could not narrate the generate_a2ui result it had just produced. Append the round's assistant/tool pair before breaking so the final turn receives it. The test now asserts the final turn's messages include the just-produced surface. Signed-off-by: ran <ran@copilotkit.ai> * Python: A2UI — keep batch execution in the adapter; fix CI typing Per review, don't add A2UI-specific abstractions to core: remove execute_function_call_batch / FunctionCallBatchExecution from agent_framework._tools. A2UIAgent's _execute_server_tools now runs the mixed batch inline using the framework's existing helpers (_try_execute_function_call_groups plus categorize_middleware for bare/bundle middleware normalization) with the run's session, config, and middleware — the same helpers the AG-UI approval path uses — so nothing adapter-specific lives in core. Also fix the CI typing check: annotate the A2UI test doubles and helpers so mypy, pyrefly, and ty pass over the test module (mixed-shape result tuples, a nullable envelope helper, and duck-typed fakes passed where protocols are expected). Signed-off-by: ran <ran@copilotkit.ai> * Python: A2UI — propagate MiddlewareFailure through the inline server-tool path; generic non-leaking error results; fix ty test typing - _execute_server_tools now re-raises MiddlewareFailure so a fail-closed authorization/guardrail abort stops the run instead of being folded into an error result that would still render a surface (matches the core loop). - Ordinary execution failures return core's generic 'Error: Function failed.' message; the raw exception text rides the non-model-visible exception field and is only exposed when include_detailed_errors is enabled, so credentials/ provider payloads/tenant data cannot leak to the model. - Add ty suppressions on the two duck-typed test constructors (ty does not honor mypy-style '# type: ignore[arg-type]') to clear the Test Typing Checks gate. - Cover both behaviors with tests (MiddlewareFailure aborts without rendering; tool error result is generic and non-leaking). --------- Signed-off-by: ran <ran@copilotkit.ai> Co-authored-by: Evan Mattson <35585003+moonbox3@users.noreply.github.com> |
||
|
|
a7fea02070 |
Python: Bump ruff from 0.16.0 to 0.16.3 in /python (#7781)
* Bump ruff from 0.16.0 to 0.16.3 in /python Bumps [ruff](https://github.com/astral-sh/ruff) from 0.16.0 to 0.16.3. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.16.0...0.16.3) --- updated-dependencies: - dependency-name: ruff dependency-version: 0.16.3 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * Align lab ruff pin to 0.16.3 and refresh uv.lock Co-authored-by: moonbox3 <35585003+moonbox3@users.noreply.github.com> * Revert unintended ruff rule-name rewrites in python/pyproject.toml Co-authored-by: moonbox3 <35585003+moonbox3@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: moonbox3 <35585003+moonbox3@users.noreply.github.com> |
||
|
|
a8b0704691 |
Python: Bump ty from 0.0.70 to 0.0.72 in /python (#7783)
* Bump ty from 0.0.70 to 0.0.72 in /python Bumps [ty](https://github.com/astral-sh/ty) from 0.0.70 to 0.0.72. - [Release notes](https://github.com/astral-sh/ty/releases) - [Changelog](https://github.com/astral-sh/ty/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ty/compare/0.0.70...0.0.72) --- updated-dependencies: - dependency-name: ty dependency-version: 0.0.72 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * Regenerate uv.lock for ty 0.0.72 bump Co-authored-by: moonbox3 <35585003+moonbox3@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: moonbox3 <35585003+moonbox3@users.noreply.github.com> |
||
|
|
d1dbce7138 |
Python: Bump mypy from 2.3.0 to 2.3.1 in /python (#7784)
* Bump mypy from 2.3.0 to 2.3.1 in /python Bumps [mypy](https://github.com/python/mypy) from 2.3.0 to 2.3.1. - [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md) - [Commits](https://github.com/python/mypy/compare/v2.3.0...v2.3.1) --- updated-dependencies: - dependency-name: mypy dependency-version: 2.3.1 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * Regenerate uv.lock for mypy 2.3.1 and align lab dev pin Co-authored-by: moonbox3 <35585003+moonbox3@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: moonbox3 <35585003+moonbox3@users.noreply.github.com> |
||
|
|
007a2d7a05 |
Python: FoundryEvals always emits arguments field for tool calls (#7734)
* Python: always emit arguments field for tool calls in AgentEvalConverter
FoundryEvals uploaded tool_call content items without an arguments
field when a tool call had no model-supplied arguments. Foundry's
tool-aware evaluators (task_adherence, tool_output_utilization,
tool_call_accuracy) require the arguments field to always be present,
so zero-argument tool calls caused evaluation to fail with
FAILED_EXECUTION. Default to an empty object instead of omitting the
field.
* Python: only default arguments to {} when None, not on falsy values
Addresses Copilot review feedback: a truthiness check would also
overwrite valid but falsy parsed arguments (e.g. 0, "", False) with
{}. Use an explicit None check so only missing arguments are defaulted.
|
||
|
|
24a383613b |
Python: feat: forward function_invocation_kwargs through DevUI to agent.run (#7779)
DevUI's /v1/responses endpoint builds agent.run() kwargs by hand and only
passed stream/session, so tools that read request-scoped values via
FunctionInvocationContext.kwargs (tenant id, auth token, user id)
silently received nothing when the agent was run through DevUI. The same
agent works correctly outside DevUI via agent.run(..., function_invocation_kwargs=...).
Forward function_invocation_kwargs from the request into agent.run() in
AgentFrameworkExecutor._execute_agent. Accepts both channels already used
on the request payload:
- extra_body.function_invocation_kwargs (the channel already used for
response_id / checkpoint_id)
- top-level extra field (AgentFrameworkRequest has ConfigDict(extra="allow"))
Top-level takes precedence when both are set. Non-dict / missing values
are silently ignored for backward compatibility. No frontend / model
changes.
Adds a parametrized regression test in test_execution.py covering all
three cases (extra_body, top-level, absent).
Fixes #7344
|
||
|
|
946ece61a1 |
Update flit-core requirement from <4.0,>=3.11 to >=3.11,<5.0 in /python (#7782)
Updates the requirements on [flit-core](https://github.com/pypa/flit) to permit the latest version. - [Changelog](https://github.com/pypa/flit/blob/main/doc/history.rst) - [Commits](https://github.com/pypa/flit/compare/3.11.0...4.0.2) --- updated-dependencies: - dependency-name: flit-core dependency-version: 4.0.2 dependency-type: direct:development ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
074d23d269 | Add moonbox3 as codeowner for Foundry hosting and local packages (#7804) | ||
|
|
4e754a636d |
[BREAKING] Python: Consolidate OTel GenAI Semantic Conventions versions (#7673)
* Consolidate OTel GenAI Semantic Conventions versions * Address comments * Refinement * Further constraint v1.26.0 attrs * Fix tests and typing * Address copilot comments * Fix tests * Fix typing * Fix typing * Rewording |
||
|
|
43b3ce6027 |
.NET: Add feature-usage bitmask (#7709)
* Add feature-usage User-Agent telemetr * Removed static keyword from irrelevant methods. * Update method names and fix CI test issue. * Revert irrelevant changes. * Address PR comments. * Fix CI issue from merge conflict resolution. |
||
|
|
1109cf778b |
Python: resolve release tags against real package directories (#7795)
* Make python-release tag handling more robust Pass the release tag through the step env block and reference it as a quoted shell variable, and validate the package name derived from the tag before using it as a directory path. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 73f2e039-3ff4-4a5a-a8f8-253b0bfa94f3 * Resolve release tags against real package directories Package names can contain hyphens and can use underscores where the tag uses hyphens, so splitting the tag on the first hyphen picked the wrong directory. Resolve the name against the actual packages/ listing instead, and handle the python-<version> workspace tag explicitly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 73f2e039-3ff4-4a5a-a8f8-253b0bfa94f3 * Require a real version component in release tags Selecting the workspace build on the absence of a hyphen meant a malformed tag such as python-devui built and uploaded the whole workspace. Match the suffix against the supported version formats instead, and reject tags that are neither shape. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 73f2e039-3ff4-4a5a-a8f8-253b0bfa94f3 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 73f2e039-3ff4-4a5a-a8f8-253b0bfa94f3 |
||
|
|
aeaabe5abf |
Python: fix MCP tool argument shadowing the remote tool name (#7799)
* Python: fix MCP tool argument shadowing the remote tool name The generated MCP function held the remote tool name as the default of a keyword-only parameter. Tool arguments are splatted into that function, so an argument named `_remote_tool_name` bound to the parameter instead of `**kwargs` and changed which remote tool was called. Move the remote tool name into a factory closure so it is no longer part of the generated function's signature, matching the prompt path which already binds the name positionally via `partial`. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4cb58e38-4af2-485d-b734-7d70972959f2 * Guard await_args before indexing in MCP regression test Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4cb58e38-4af2-485d-b734-7d70972959f2 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4cb58e38-4af2-485d-b734-7d70972959f2 |
||
|
|
96560bbf65 |
.NET: [BREAKING] Migrate MCP long-running task support to the 2026-07-28 Tasks extension (#7774)
* Migrate MCP long-running task support to the 2026-07-28 Tasks extension * Address PR comments. * Address PR comments. * Address PR comments |
||
|
|
ab0f7d5d08 |
.NET: Persist hosted agent state in Foundry (#7649)
* Point the AgentServer packages at the local preview drop The durable state-store API this branch is built on ships in Core beta.28, which is not on nuget.org yet. The local feed is a stopgap for developing against it and must be removed before this branch ships. * Keep hosted agent state on the platform instead of the container disk A hosted agent kept its sessions, and a hosted workflow its checkpoints, in files under the container's own directory. That state is lost when the container is replaced and cannot be read by another instance of the same agent, so a conversation could not survive a restart or be served by more than one instance. Both now go to the Foundry durable state store when the process runs in a Foundry container, and stay on disk everywhere else: - FoundryAgentSessionStore holds the agent sessions, partitioned by agent, conversation and end user. - FoundryJsonCheckpointStore holds the workflow checkpoints, one item per checkpoint plus a per-session index that keeps them in commit order. Retrieving a checkpoint deletes the rest of that session's checkpoints, which is the only point at which nothing can still reach them, and is what stops the index growing past the size the platform accepts for one item. A workflow agent is redirected to that checkpoint store when it is resolved for a request, so nothing changes in how a container registers one. An agent built with a checkpoint manager of its own is left alone and reported by the new foundry-workflow-checkpointing readiness check, because its state would go somewhere hosting does not manage. Workflow agents are recognised through a new WorkflowAgentMetadata returned by GetService, which still finds them behind middleware. * Keep the readiness probe from running the agent's providers The stored-output probe ran the registered agent with its chat client replaced, which still set the agent's chat history provider and context providers running. Those are the parts most likely to reach outside the container and to write state, so every readiness probe could make external calls and add its own empty turn to real conversations. The probe now runs a stand-in built from the agent's own options with both kinds of provider dropped. It keeps what decides the setting, the chat options and the raw request factory, and cannot see a decorator wrapped around the agent, which is accepted for a readiness check. * build: bump AgentServer preview packages Core beta.29 adds the shared local state-store fallback used by hosted sessions and workflow checkpoints. Align its Azure Core and System package dependencies to avoid assembly and downgrade conflicts. * feat(foundry): use AgentServer state fallback Use FoundryStateStore for sessions and workflow checkpoints in every environment. Core beta.29 selects Foundry Storage when hosted and a file-backed local store otherwise, so local runs exercise the production storage shape without requiring Azure credentials. Give the hosted workflow sample stable inner-agent identities so its checkpoints remain compatible after container replacement. * fix(hosting): harden durable state storage Use published AgentServer packages so CI no longer depends on a local package source. * build(hosting): scope AgentServer versions Keep public package versions on their consumers so unrelated projects retain the central versions from main. * build(hosting): use public AgentServer packages Remove project overrides and keep package selection in the central catalog now that the required public releases are available. * fix(hosting): preserve durable state identity Keep keyed and default aliases on one session partition. Reject unstable unnamed direct-store usage and preserve live checkpoint branches during pruning. * refactor(hosting): centralize hosted metadata Carry storage identity through a hosting-specific agent wrapper, keep unknown middleware non-blocking at readiness, and align StateStore constructor parameter order. * refactor(hosting): move session identity into store * docs(hosting): explain session identity resolution * fix(hosting): preserve protocol mismatch status Reject unsupported protocol requests before AgentServer wraps handler failures in ResilientTaskException and converts the intended 501 response into a generic 500. |
||
|
|
e6617c407a |
.NET: Add Azure Blob Storage session persistence (#1893)
* setup azurestorage proj * setup for azure blob as agentthreadstore * add azurite as dependency for dotnet tests * use services * rollback * azurite as a step * move and rename * renames / fixes * rename to unit tests * copilot changes * .NET: Modernize Azure Blob session storage Copilot-Session: 35e63850-1a85-4f7c-ac80-2274534c13b5 * .NET: Test hosted Blob session persistence Copilot-Session: 35e63850-1a85-4f7c-ac80-2274534c13b5 * .NET: Address Azure Blob storage review feedback Copilot-Session: 35e63850-1a85-4f7c-ac80-2274534c13b5 * .NET: Use default test target frameworks Copilot-Session: 35e63850-1a85-4f7c-ac80-2274534c13b5 --------- Co-authored-by: Roger Barreto <19890735+RogerBarreto@users.noreply.github.com> Copilot-Session: 35e63850-1a85-4f7c-ac80-2274534c13b5 |
||
|
|
cabb21a292 |
.NET: Clarify compaction provider and chat reducer choices (#7678)
* Document compaction provider and reducer choices * Clarify chat history provider example --------- Co-authored-by: Ravi Kiran Pagidi <236139898+ravikiranpagidi@users.noreply.github.com> |
||
|
|
ab6c4d2dc8 | Pin GitHub Actions to full-length commit SHAs (#7768) | ||
|
|
2054d62702 |
Python: fix(github-copilot): forward telemetry config to client (#7625)
* fix(github-copilot): forward telemetry config to client * Python: fix telemetry settings typing for github_copilot `load_settings` does not coerce dict-typed fields, so GITHUB_COPILOT_TELEMETRY and .env values reach the agent as plain strings. Declaring `GitHubCopilotSettings.telemetry` as `dict[str, Any]` therefore misstated the runtime contract and failed the test typing checks where a string is assigned. Widen the annotation to `dict[str, Any] | str | None` and fix the union arm resolution in `_check_override_type`: parameterized generics are not `type` instances, so they were dropped from the allowed set and a valid dict override was rejected at runtime. Arms without a runtime class, such as `Literal`, now skip validation instead of narrowing it incorrectly. Also drive the telemetry string tests through the documented environment variable path rather than mutating `_settings` directly, and cover the valid-JSON-but-not-an-object case. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 657d2953-4112-4a01-889b-c0c6863630c1 * Python: resolve settings override types through generic origins Python 3.10 reports parameterized generics such as `dict[str, Any]` as instances of `type`, so the union arm resolution kept the alias and `isinstance` raised `TypeError: isinstance() argument 2 cannot be a parameterized generic` on that interpreter. Resolve every annotation through `get_origin` first via a shared `_runtime_class` helper, which also removes the same latent failure for a non-union parameterized generic field, and return `None` for annotations such as `Literal[...]` that have no runtime class so validation is skipped rather than narrowed incorrectly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 657d2953-4112-4a01-889b-c0c6863630c1 --------- Co-authored-by: Giles Odigwe <gilesodigwe@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 657d2953-4112-4a01-889b-c0c6863630c1 |
||
|
|
ecc1430977 |
Python: defer turn-scoped after_run providers to the agent loop boundary (#7289)
* Python: defer turn-scoped after_run providers to the agent loop boundary Each AgentLoopMiddleware iteration is a full agent run, so CompactionProvider.after_run fired per iteration and rewrote persisted history mid-task (#7236). Providers can now opt into turn scope with after_run_once_per_turn; iterations defer them via a contextvar, and the loop fires them once at the boundary. CompactionProvider opts in; HistoryProvider keeps its incremental per-run persistence. * Python: key loop suppression to the looping agent and pass run options through Two review follow-ups: the contextvar now carries the agent instance so a nested agent.run() inside a loop iteration is not suppressed as if it were an iteration, and the boundary SessionContext forwards the original run options to turn-scoped providers. * fix(core): carry the loop-iteration stamp in run options, not a contextvar The contextvar marker leaked in two ways. Held across a streamed yield it bled into the caller's context, suppressing turn-scoped providers on an unrelated same-agent run while the stream was paused, and a reset from a different consuming task raised on the token. Keyed to the agent instance, it also swallowed the boundary flush of a nested loop on the same agent with its own session. Stamp the runs the loop drives through their options instead. Run options reach only the inner runs (they never enter the model request), a nested or concurrent run starts with fresh options and keeps its own turn, and there is no token to reset, so stream consumption is safe from any task. * Python: annotate custom option keys in the after_run provider test * fix: nosec the loop-iteration options key (bandit B105 false positive) * Python: fix: suppress the loop-token key lint with ruff: ignore * Python: fix: silence the two pyright private-usage flags the repo's own idiom covers --------- Co-authored-by: Giles Odigwe <79032838+giles17@users.noreply.github.com> Co-authored-by: Evan Mattson <35585003+moonbox3@users.noreply.github.com> |
||
|
|
f666102d0c |
Python: Harness blog part4 samples (#7698)
* Add harness blog post part 4 samples. * Add harness sample fixes for python * Point FileMemoryStore to home for hosted agents. * Python sample fixes for toolbox Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3a5efc79-5c78-40b8-a1c5-c0f84e0795e1 * Address PR comments * Python blog sample fixes * Address PR comments * Fix formatting --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3a5efc79-5c78-40b8-a1c5-c0f84e0795e1 |
||
|
|
26b28b4386 |
Python: Avoid unchanged AG-UI predictive state snapshots (#7766)
* Python: Avoid unchanged AG-UI predictive state snapshots Only emit the coalesced snapshot when predictive updates were actually pending or a deterministic state update was returned. Assisted-by: Codex <codex@openai.com> * Python: Exercise the predictive update path in snapshot tests Use the handler streaming API to create pending state and narrow snapshot events by their concrete type. Assisted-by: Codex <codex@openai.com> |
||
|
|
435201b71b |
Python: Fix A2A input handling in orchestrations (#7761)
* fix(a2a): reject empty invocations explicitly Key decisions: - Keep A2A continuation authority explicit; durable session task state only enriches diagnostics. - Raise AgentInvalidRequestException with participant and available task context instead of inventing input. - Leave AgentExecutor and Group Chat production contracts unchanged. Files changed: - packages/a2a/agent_framework_a2a/_agent.py - packages/a2a/tests/test_a2a_agent.py - packages/a2a/tests/test_a2a_group_chat.py Notes for next iteration: - No blockers. INPUT_REQUIRED pause/resume remains a separate task. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(a2a): pause group chat for remote input Key decisions: - Translate A2A INPUT_REQUIRED task content into the existing Content user-input-request contract. - Use the remote task ID as stable request correlation for streamed and finalized responses. - Reuse AgentExecutor request handling so caller input resumes the same task without a workflow-specific A2A path. Files changed: - packages/a2a/agent_framework_a2a/_agent.py - packages/a2a/tests/test_a2a_agent.py - packages/a2a/tests/test_a2a_group_chat.py Notes for next iteration: - Checkpoint restoration of pending A2A input is now unblocked. - The local issue file could not be moved because repository issue files are restricted by content exclusion policy. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(a2a): restore pending input from checkpoints Key decisions: - Keep normalized INPUT_REQUIRED content durable by excluding transport-only protobuf raw representations. - Restore through the existing AgentExecutor checkpoint and request-response path without a new schema or continuation API. - Cover file-backed restoration in streaming and non-streaming Group Chat runs, including unrelated-response rejection and exact task resumption. Files changed: - packages/a2a/agent_framework_a2a/_agent.py - packages/a2a/tests/test_a2a_group_chat.py Notes for next iteration: - The local issue file could not be moved because repository issue files are restricted by content exclusion policy. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * test(handoff): lock textless target context Key decisions: - Exercise the built Handoff workflow in streaming and non-streaming modes instead of bypassing routing, sessions, or termination. - Keep the slice test-only because current production already carries the initial task to a textless handoff target without synthetic user input. - Revisit the source to verify its handoff function call retains a matching result and user-turn termination sees only caller messages. Files changed: - packages/orchestrations/tests/test_handoff.py Notes for next iteration: - No production defect was reproduced. - The local issue file could not be moved because repository issue files are restricted by content exclusion policy. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * test(handoff): use resolved IDs in event assertions * fix(workflows): preserve A2A input request semantics * fix(workflows): preserve input request correlation * fix(a2a): deduplicate message-less input requests * fix(workflows): preserve specialized input requests * test(openai): use current web search model --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
d29e7be7fd |
.NET: Fix A2A streaming artifact updates (#7722)
* .NET: Fix A2A streaming artifact updates Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: d07945ad-4b76-48da-a499-a915c076cff9 * Flush buffered A2A artifacts on stream failure Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: d07945ad-4b76-48da-a499-a915c076cff9 * Aggregate A2A message streams incrementally Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: d07945ad-4b76-48da-a499-a915c076cff9 * Fix duplicate A2A message declaration Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: d07945ad-4b76-48da-a499-a915c076cff9 --------- Co-authored-by: SergeyMenshykh <SergeMenshikh@outlook.com> Copilot-Session: d07945ad-4b76-48da-a499-a915c076cff9 |
||
|
|
26b9200c21 |
Python: Preserve AG-UI tool message IDs across snapshots (#7510)
* fix(ag-ui): preserve streamed tool message IDs * fix(ag-ui): align approval and MCP tool message IDs * fix(ag-ui): ensure unique tool segment IDs * fix(ag-ui): keep tool and text snapshot IDs unique --------- Co-authored-by: Evan Mattson <evan.mattson@microsoft.com> |
||
|
|
e2938f4531 |
.NET: Remove AGUI history special cases (#7741)
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> |
||
|
|
b1377fad52 |
.NET: Suppress Swagger UI CodeQL alert in sample (#7764)
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1b565023-c86e-496f-a1a1-be59b4d89cb7 |
||
|
|
064751c5f3 |
.NET: Upgrade AG-UI SDK packages to 0.0.5 (#7742)
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 425c405b-1fd3-4ba6-b332-a195598374b4 |
||
|
|
10bf8d7d9e |
.NET: agent-hooks interception contract as a first-class experimental feature (#7564)
* feat(dotnet): agent-hooks interception contract as an experimental package Add Microsoft.Agents.AI.AgentHooks, implementing the AGENT-HOOKS-0.1 control contract on the framework's native decorator seams, mirroring the merged Python feature (#7515) in .NET idiom: - One public factory (CreateAIAgentWithAgentHooks, per-run and host-owned-session overloads) composes agent, chat and function seams as one indivisible unit; the seam decorators are internal, so partial installs are impossible by construction. - All eight interception points: input/output at the agent seam, pre/post_model_call below the function-invocation loop (every model service call bracketed individually), pre/post_tool_call via the function-invocation middleware seam, agent_startup/agent_shutdown bracketing each run. - Fail-closed enforcement throughout: transforms write back into the native messages/arguments/results or throw; rich content is preserved as AIContent objects; interceptor crashes surface as host_error denies; enforcement-layer failures halt the run through FunctionInvocationContext.Terminate (the loop's only loud escape). - Streaming is fully buffered per spec buffered_output semantics: a deny releases zero updates; transformed responses re-derive the released updates so egress never diverges from verdicted content. - Verdict-before-durability: end-of-run history and context-provider writes defer behind the output verdict via gating provider wrappers (flushed post-transform with verdicted-message substitution for streams, dropped on deny); per-service-call persistence sits above the chat seam and is covered by its own post_model_call verdict; per-run history-provider overrides in run options are wrapped too; nested guarded sub-agents persist inline at their own boundaries. - Opt-in dependency: ResponsibleAI.AgentHooks 0.1.0-alpha.4 (bundles native runtimes) referenced only by the new package; no existing framework source is modified. - 58 tests: deny-before-execution and transform write-back per seam, rich-content preservation, streaming ordering with zero egress on deny, error bracketing, concurrency isolation, host-owned sessions, evaluate_only, approval-seam lift, persistence gating, misuse fail-closed paths, and codec units. Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com> * fix(dotnet): close structural bypasses at the ChatClientAgent boundary Address both reviewers' probe-confirmed findings; the runtime enforcement held everywhere, every fix is at the structural boundary: - Gate the implicit default ChatHistoryProvider: with no provider configured, ChatClientAgent creates an InMemoryChatHistoryProvider the factory never saw, so denied output became durable session history and replayed to the model on the zero-config path (both stream modes). The factory now materializes and gates the default, setting the history-conflict flags to mimic implicit-default semantics for service-managed-history agents. - Wrap per-run provider overrides on BOTH dictionaries: base AgentRunOptions.AdditionalProperties is merged into the chat options with precedence, so a base-level override bypassed (and displaced) the wrapped ChatOptions-level entry. Plain AgentRunOptions is covered too, and the wrap is copy-on-write — the caller's options and dictionaries are never mutated. - Reject per-run ChatClientFactory on guarded agents (fail closed): it would replace the guarded chat pipeline and the tool-wrapping stage riding it, silently removing the chat and tool seams. - Reject a supplied client already containing a FunctionInvokingChatClient: it would execute tools below the chat seam, before any post_model_call verdict and outside the tool seam. - Run wire projections inside the guarded blocks at the chat and function seams: a poisoned value whose serialization throws now fails the run closed (function seam: host_error halt; chat seam: gated persistence refused before the failure propagates). - Suppress provider failure notifications once a run-level deny or halt stands, so the denied turn's request messages never reach provider code. - Document the deferred-OpenTelemetry observer channel (request-side spans capture pre-transform content under sensitive-data telemetry). - Rename the factory to AsAIAgentWithAgentHooks per repo convention. 10 new boundary regression tests mined from the review probes (default-provider durability in both stream modes with session-replay assertions, both override dictionaries incl. the displacement shape, plain-run-options override, copy-on-write, factory and supplied-FICC rejections, poisoned-projection fail-closed); 68 total, all green. Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com> * fix(dotnet): redact denied-run failure notifications for both provider kinds The deny/halt handling of provider failure notifications only covered the chat-history wrapper; a context provider still received the denied turn's request messages on its failure notification. Both gating wrappers now REDACT instead of suppress: the notification is forwarded with empty request messages and the original exception, preserving the documented failure-cleanup contract (providers releasing per-run resources on the failure signal keep working) while the denied turn's request messages never reach provider code. Regression tests assert both provider kinds receive the redacted notification (zero request messages) on a denied run and full notifications on ordinary, verdict-free failures. 70 tests total. Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com> * fix(dotnet): address Copilot review on the agent-hooks PR - Run options: always clone chat-typed run options (the framework's function-invocation middleware chains its per-run factory onto the instance it receives, so forwarding the caller's instance leaked that factory into it — reuse tripped the rejection, concurrent reuse raced), and recognize the framework middleware's own factory as legitimate: it wraps the guarded pipeline (tool rewriting), so outer function-middleware composition now works, while its chained factories are walked so a caller-supplied factory cannot ride in unnoticed. - Streaming: re-derived (transformed) updates preserve the response's ContinuationToken (ToAgentResponseUpdates does not project it), so transformed background streaming responses remain resumable; a message-less response releases a metadata-only update carrying it. - Codecs: transformed tool calls are validated for complete shape and uniqueness before reconciliation (non-empty string id and name, object-valued args, distinct ids) — malformed shapes fail closed instead of becoming invalid native calls. Deliberately stricter than the merged Python codec, which coerces added-call shapes. - Role defaulting in message write-backs is confirmed exact Python parity (user/assistant defaults per the merged codecs) and is now locked by tests rather than changed. - ADR 0035 records the seam order, persistence gating, fail-closed behavior, alternatives and known limitations. 14 new tests (options reuse, outer function-middleware composition, smuggled-factory rejection, continuation-token preservation, 8 malformed tool-call shapes, 2 role-default parity); 84 total, green. Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com> * feat(dotnet): project the per-call tool set on pre_model_call emissions Context providers can register additional tools during run preparation, after agent_startup has been emitted, so tools_registered is inherently a run-start snapshot and can be a partial view of the tools eventually offered to the model. - Emit the spec's optional pre_model_call tools field ({name, description?}) from the per-call effective ChatOptions.Tools — the completed set for each call, including provider-added tools. - Document tools_registered as the run-start snapshot on the agent seam (dynamic registrations surface per call and are bracketed by the tool seam when invoked). - Probe-confirm enforcement completeness for provider-added tools: they flow through the guarded pipeline's tool-wrapping stage, emit pre/post_tool_call, and a pre_tool_call deny blocks their invocation exactly like constructor-registered tools. Two new tests (bracketing + audit projections, deny-blocks); 86 total, green. Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com> * refactor(dotnet): one artifact per file; rewrap foreign gating wrappers Per review: - Split the three multi-type files (AgentHooksGatingProviders.cs, AgentHooksRunState.cs, AgentHooksWireCodecs.cs) into one type per file, file name matching the type name, per repo convention. No behavior changes; namespaces and access levels unchanged. - Close a validation asymmetry at the provider gate: the per-run override wrap skipped any gating wrapper, including one owned by a DIFFERENT agent-hooks installation — which runs inline under this run's state (its own gate is not covering here), so a denied run's history could persist straight through it. Overrides are now re-wrapped unless the wrapper belongs to this installation (reference-equal configuration). The provider seam's inline behavior for foreign/absent state is otherwise deliberate: inline is the safe direction there (content of unguarded or differently guarded runs is covered by its own verdicts or none), and throwing would break the legitimate double-wrap flush flow. One new regression test (foreign wrapper as per-run override on a denied run persists nothing); 87 total, green. Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com> * refactor(dotnet): accept params IEnumerable for agent-hooks interceptors Per review: the constructor only iterates the interceptors, so widen the parameter from params IInterceptor[] to the C# 13 params IEnumerable<IInterceptor>. The sequence is enumerated exactly once into the internal registration list (sequences may be single-enumeration); per-item null validation and the factory's at-least-one-interceptor check are unchanged, and an explicit null sequence now throws ArgumentNullException. Params-form call sites are source-compatible. Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com> * build(dotnet): ship Microsoft.Agents.AI.AgentHooks as a preview package Per maintainer review on the PR: - Add the project to agent-framework-release.slnf and import the shared packaging props so the package ships. Version follows the repo default for unmarked packages (preview suffix), matching the package's [Experimental] surface and alpha upstream dependency: 1.17.0-preview.<date>.1. - Package metadata: sibling-style title, fuller description, tags; shared icon and NUGET.md readme via the packaging props. Verified dotnet pack locally: ResponsibleAI.AgentHooks 0.1.0-alpha.4 flows as a normal dependency and the project references become 1.17.0 package dependencies. - Update ADR 0035: shipping as preview per maintainer decision replaces the build-only-pending-maturity stance. Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com> * build(dotnet): version the agent-hooks package as alpha Per maintainer review: the package's maturity marker follows the ResponsibleAI.AgentHooks dependency it is built on (alpha), rather than the repo's default preview suffix. Packs as 1.17.0-alpha.260804.1; ADR 0035 updated. Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com> * refactor(dotnet): group agent-hooks internals into Core and Codecs folders Per review: only the public surface (the factory extensions and options) stays at the project root; the internal seam decorators, run state and gating providers move to Core/, and the wire projection codecs to Codecs/. Pure file moves — namespaces stay flat per the core package's folder convention (ChatClient/, Memory/); no content changes. Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com> * docs(dotnet): clarify session scoping and name the sessionId argument Per review: - Name the AgentContextBuilder arguments at the run-state factory so the GUID reads as what it is (the per-run agent-hooks session id). - Document both branches of CreateRunState: session-scoped means the host owns the emitter/builder and the session boundaries (one session spanning runs, no agent_startup/agent_shutdown emitted by the agent); the default is one session per run with a fresh emitter, fresh sequence and isolated record trail, which is what keeps concurrent runs' emissions from interleaving. Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com> * fix(dotnet): harden agent-hooks factory and input projection per review - Input projection returns (payload, content, role) as one typed result so the emission site never re-reads payload properties by name: the both-fields-exist invariant holds by construction. (The previous reads were fail-closed even hypothetically — JsonObject's indexer yields null, and a null content is rejected by the SDK's envelope validation — but reading back what we just produced was needlessly fragile-looking.) - Reject UseProvidedChatClientAsIs on the factory: it signals a fully custom, do-not-touch client stack, which is incompatible with a factory whose job is to decorate the supplied client and rely on the agent's default pipeline above the chat seam. Honoring it would silently change where (and whether) the seams sit. - Log swallowed agent_shutdown emission failures (logger resolved the same way the agent resolves its own: services, then the chat client, then null) so incomplete session trails are trackable; OutOfMemoryException stays unswallowed. The swallow remains correct: the run's own outcome is already propagating and the trail closure is best-effort by contract. 89th test: UseProvidedChatClientAsIs rejection. Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com> * build(dotnet): attribute the Agent-Hooks protocol in the package identity Per review: - Title per suggestion: 'Microsoft Agent Framework - Responsible AI Agent-Hooks Protocol Support'; description names the protocol precisely (AGENT-HOOKS-0.1, maintained by the Responsible AI project at github.com/responsibleai/agent-hooks) so the package reads as protocol support, not a MAF-owned feature; tags aligned. - Drop the [Experimental] attributes: per repo convention the attribute gates unstable surface inside released packages (Harness, core), while pre-release packages (Valkey and Mcp at alpha, Mem0 and LocalCodeAct at preview) carry none — the version suffix is the maturity signal. - Drop the describing comment on the central package version entry. Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com> * refactor(dotnet): split agent-hooks test fixtures into Support files Per review: one type per file under Support/ (mock client, guards, recording providers, helpers), matching the src-side convention; pure mechanical split, flat namespace. Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com> --------- Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com> |
||
|
|
8be7c93063 |
Python: Preserve structured instructions when merging chat options (#7730)
* Python: Preserve structured instructions when merging chat options `instructions` is declared as `str` on `ChatOptions`, but chat clients may widen it to a provider-native structured form. Three merge paths combined it with an f-string, which coerced any non-string value to its `repr`, turning structured metadata into literal text before any client could see it: - `merge_chat_options` (`_types.py`) - `_merge_options` (`_agents.py`, agent defaults + per-run options) - provider-contributed instructions in `_prepare_session_and_messages` (`_agents.py`) The last of these is the reported case: once any context provider (for example `SkillsProvider`) contributes instructions, structured instructions were replaced by their `repr`, so the model received Python dict syntax as its system prompt and Anthropic prompt caching silently stopped working. Add a shared `_append_instructions` helper that concatenates strings as before and otherwise extends element-wise, always appending so the leading portion stays unchanged for providers that treat it as a stable, structure-sensitive prefix. A lone mapping is treated as a single element rather than iterated into its keys. On the Anthropic side, `_extract_structured_instructions` now normalizes bare strings into text blocks, since appended instructions arrive alongside caller-supplied blocks. Fixes #7700 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f428b149-a306-484a-b423-4e9de69f0b90 * Python: address review feedback on structured instructions fix Parameterize the Anthropic regression test over both the with- and without-SkillsProvider configurations so the structure-preserving behavior is asserted in the baseline case too. Normalize structured instructions in `_get_instructions_from_options` so telemetry records the instruction text for provider-native block shapes, extracting only `text` values to keep provider metadata out of spans. Use `cast` for the structured `default_options` in both regression tests so the test type checkers resolve the client options type correctly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f428b149-a306-484a-b423-4e9de69f0b90 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Evan Mattson <35585003+moonbox3@users.noreply.github.com> Copilot-Session: f428b149-a306-484a-b423-4e9de69f0b90 |
||
|
|
c527d61ac7 | Update Python codeowners (#7762) | ||
|
|
ec407cf56f |
Python: fix: preserve Agent additional_properties in HandoffBuilder clones (#7755)
HandoffAgentExecutor clones each participant agent to attach handoff tools, but the clone rebuilt the Agent without forwarding additional_properties, so middleware and integrations observing context.agent.additional_properties during handoff runs saw an empty dict while the original agent retained its configuration. Pass a deepcopy of the original agent's additional_properties into the clone so handoff-executed agents keep their configured metadata and the original agent stays untouched. Fixes #7750 |
||
|
|
0f583ec8a3 |
.NET: Migrate remaining Foundry hosted samples to source deployment (#7668)
* .NET: Migrate 6 hosted-agent samples to source (ZIP) deploy Extend the source (ZIP) deploy pattern established for Hosted-ChatClientAgent to Hosted-LocalTools, Hosted-Workflow-Simple, Hosted-TextRag, Hosted-Observability, Hosted-Files and Hosted-FoundryAgent. Each gains an azure.yaml (codeConfiguration/remote_build, ASPNETCORE_URLS, model env) and the canonical .agentignore, a self-contained csproj (single target, CPM opt-out, explicit published package versions, AgentFrameworkVersion), a Program.cs that drops the shared contributor scaffolding for DefaultAzureCredential, an updated .env.example and README, and drops the container-mode files (agent.yaml, agent.manifest.yaml, Dockerfile, Dockerfile.contributor). LocalTools, Workflow-Simple, TextRag, Observability and Files were verified deploying live via remote_build; Workflow-Simple returns a workflow runtime error at invoke that is unrelated to the deploy mode. * .NET: Migrate Hosted-Invocations-EchoAgent and Hosted-LocalCodeAct to source (ZIP) deploy EchoAgent (Invocations protocol) and LocalCodeAct migrated to the zip/code-deploy pattern (azure.yaml, .agentignore, self-contained csproj, README, container files removed). EchoAgent maps /readiness explicitly because the Invocations SDK does not auto-map it. Both verified live via remote_build on a Foundry project; LocalCodeAct's execute_code ran server-side (compute 21+21 -> 42). * .NET: Migrate remaining hosted-agent samples to source (ZIP) deploy Migrate Hosted-McpTools, Hosted-MemoryAgent, Hosted-AgentSkills, Hosted-AzureSearchRag, Hosted-Toolbox, Hosted-Toolbox-AuthPaths and Hosted-ToolboxMcpSkills to the zip/code-deploy pattern (azure.yaml with codeConfiguration + sample-specific env passthrough, canonical .agentignore, self-contained csproj, Program.cs dropping the shared contributor scaffolding for DefaultAzureCredential, updated .env.example and README, container files removed). Also restore the Hosted-Invocations-EchoAgent csproj filename the solution references. McpTools verified live via remote_build against the public Microsoft Learn MCP server; the memory/search/toolbox/skills samples build locally and deploy via remote_build but need their external resources (memory store, search index, toolbox connections, skills) provisioned to exercise end to end. * .NET: Migrate Hosted-Workflow-Handoff to source (ZIP) deploy Migrate the triage handoff workflow sample to the zip/code-deploy pattern (azure.yaml with codeConfiguration and Azure OpenAI env passthrough, canonical .agentignore, self-contained csproj using AgentFrameworkVersion for Foundry/Foundry.Hosting/Hosting, Program.cs dropping the shared contributor scaffolding for DefaultAzureCredential, updated .env.example and README, container files removed). Builds via remote_build; live needs an Azure OpenAI resource (AZURE_OPENAI_ENDPOINT/AZURE_OPENAI_DEPLOYMENT). * .NET: Copy Hosted-AgentSkills skills/ into build output The startup provisioning helper reads SKILL.md files from AppContext.BaseDirectory/skills, but the project did not copy the skills/ folder to the build/publish output, so at runtime the source directory did not exist and provisioning was silently skipped. Add a Content include (PreserveNewest), matching the resources/ pattern already used by Hosted-Files. * .NET: Suppress OPENAI001 in Hosted-Workflow-Handoff for standalone ZIP build The repo-wide Directory.Build.props suppresses OPENAI001, but that file does not travel in the code/ZIP deploy package. The standalone dotnet publish the Foundry code deploy runs then fails with error OPENAI001 on the experimental GetResponsesClient().AsIChatClient() call. Add OPENAI001 to the project NoWarn so the sample builds in the code-deploy pipeline, matching SimpleAgent.csproj. * .NET: Document live-verified idiosyncrasies in Foundry hosted sample READMEs Align every FoundryHostedAgents sample README with the documented azd flow and add the idiosyncrasies found while live-testing each sample on a Foundry project: - All samples: 'azd down' reports success but does not delete the hosted agent; document the explicit REST DELETE needed to remove it. - Hosted-Workflow-Handoff: it builds its own AzureOpenAIClient (data-plane), so the agent identity needs the 'Cognitive Services OpenAI User' role on the Azure OpenAI account. azd only grants 'Foundry User' on the project, so add a step to grant the data-plane role and explain the triage-step failure without it. - Hosted-Toolbox / Toolbox-AuthPaths / ToolboxMcpSkills: the toolbox must already exist and the agent identity must be able to read it; toolboxes with OAuth-gated tools return an oauth_consent_request and response.incomplete on first invoke. * .NET: Address Foundry hosted sample review feedback Make sample configuration reject blank azd substitutions and document every required environment value inside the scaffolded project flow. Separate the hosted endpoint name from the Foundry managed prompt-agent name, fix standalone MemoryAgent diagnostics, and complete the contributor local package feed for Hosting, LocalCodeAct, and MCP. Use azd for agent invocation and az rest for authenticated administration without exposing tokens. Add native MCP approval handling to the toolbox consent client and make its local path target the standard responses endpoint. Validated all changed samples locally, the contributor flow in PowerShell and Bash, and the supported live scenarios on the TAO cace project. * .NET: Fix advanced hosted sample project access Document and validate the Foundry User grant required by hosted version identities that access project data plane APIs. Add the Skills preview feature header and use a writable temporary directory for downloaded skills because source deployments mount the application directory read only. Update AgentSkills, MemoryAgent, FoundryAgent, and ToolboxMcpSkills deployment guides with the post deploy identity grant. All four scenarios passed live on the TAO cace project. |
||
|
|
9917bddc2b |
.NET: Update AG-UI samples for latest MAF + AG-UI SDK and align with docs (#7295)
* Simplify AG-UI Step04 human-in-the-loop sample to idiomatic pattern The Step04 sample previously wrapped both the server and client agents in custom ServerFunctionApproval*Agent middleware (~470 lines across two files) to marshal a bespoke approval protocol over AG-UI. This is no longer needed: MapAGUIServer natively emits the tool-approval interrupt when the model calls an ApprovalRequiredAIFunction, and AGUIChatClient natively transports the client's ToolApprovalResponseContent decision back to resume the run. Changes: - Server: map the ChatClientAgent directly with MapAGUIServer; remove the ServerFunctionApprovalAgent wrapper, the JsonOptions plumbing, and the ApprovalJsonContext registration. - Client: use the AGUIChatClient-backed agent directly; the existing loop already handles ToolApprovalRequestContent -> CreateResponse idiomatically. - Delete ServerFunctionApprovalServerAgent.cs and ServerFunctionApprovalClientAgent.cs. Verified end-to-end (approval request -> approve -> tool executes -> final response) against GitHub Models. Both projects build with 0 warnings. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: eeb2168d-2ecc-4f8d-9830-c287072eb7e1 * Update AG-UI Step04 README to describe native approval flow The Step04 human-in-the-loop sample no longer uses the custom ServerFunctionApprovalServerAgent / ServerFunctionApprovalClientAgent wrappers. Update the README so it describes the idiomatic native flow: the server maps a plain agent with MapAGUIServer and relies on ApprovalRequiredAIFunction to raise the approval interrupt, and the client handles ToolApprovalRequestContent and replies with ToolApprovalResponseContent. * Fix AG-UI Step04 README server port to match client default The Step04 client defaults to http://localhost:5100 (and the server launchSettings also uses 5100), but the README told users to run the server on port 8888, so the client could not reach it. Align the Step04 server run command to 5100. Other steps intentionally keep 8888 because their clients default to that port. * Update AG-UI .NET samples for latest MAF + AG-UI SDK and align with docs - Bump AGUI.* packages 0.0.3 to 0.0.4 (Directory.Packages.props) - Step01/02/03: drop AddHttpClient().AddLogging() server noise and simplify the client run-started output to match the getting-started doc (no thread plumbing) - Step04 (HITL): remove HTTP body logging and MEAI001 pragmas, give the approval tool an explicit name, and align the resume decision message with the doc - Step05 (state): replace the custom SharedStateAgent/StatefulAgent DataContent pattern (dropped by released AGUI.Server) with declarative AGUIStreamOptions.MapResultAsStateSnapshot plus a thin RecipeStateAgent that reads RunAgentInput.State, and align the Recipe models with the docs - Refresh README to the shipped API (MapAGUIServer, ApprovalRequiredAIFunction, declarative state) Verified: all 10 sample projects build; Step04 approval/resume and Step05 state snapshot round-trip run end-to-end against GitHub Models. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: eeb2168d-2ecc-4f8d-9830-c287072eb7e1 * Name the Step02 backend tool search_restaurants to match the docs Give the SearchRestaurants tool an explicit "search_restaurants" name so the client displays an accurate tool name (not a compiler-mangled local-function name) and stays aligned with the backend-tool-rendering doc. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: eeb2168d-2ecc-4f8d-9830-c287072eb7e1 * Add UTF-8 BOM to Step05 sample files to satisfy check-format The check-format CI job enforces the repository's utf-8-bom charset rule via dotnet format. The Step05 files added in this PR were saved without a BOM. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: eeb2168d-2ecc-4f8d-9830-c287072eb7e1 * Fix AG-UI sample conversation history Let AgentSession own prior messages so clients send only each new turn, and give the frontend location tool a stable protocol name. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Roger Barreto <19890735+RogerBarreto@users.noreply.github.com> Copilot-Session: eeb2168d-2ecc-4f8d-9830-c287072eb7e1 |
||
|
|
da11daebe5 |
Python: fix: prevent superlinear history growth by deduplicating messages in save_messages (#7242)
* fix: prevent superlinear history growth by deduplicating messages in save_messages * fix: address review feedback for history deduplication * fix: Prevent superlinear history growth by deduplicating messages * fix: add list[Message] type hints * fix(sessions): resolve deduplication churn and collapsing of identical message * fix(sessions): replace uuid/seen-set dedup with sequence aware filtering * fix: use forward-scan sequence alignment in filter_new_messages * fix(core): annotate new_msgs type to resolve pyright errors --------- Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com> Co-authored-by: Evan Mattson <35585003+moonbox3@users.noreply.github.com> |
||
|
|
e74ac4613c |
fix(python): coerce JSON workflow resume payloads (#7684)
AG-UI clients send plain JSON, but structured response types were only accepted as already-built instances, and core's coercion stopped at the outer object, letting raw dicts sit inside typed fields. Coercion now walks declared annotations and returns the input untouched whenever it cannot satisfy them. |
||
|
|
1f738cdeb7 |
.NET: Python: Clarify PR review comment resolution (#7746)
* Clarify PR review comment resolution * Sync PR review resolution guidance |
||
|
|
e6536fb459 |
Python: Align AG-UI run continuity (#7662)
* Python: Align AG-UI run continuity Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: aadad05d-2646-405f-8c62-a7a223abfc92 * Python: Refine AG-UI continuation ownership Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: aadad05d-2646-405f-8c62-a7a223abfc92 * Python: Persist AG-UI checkpoint ownership Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: aadad05d-2646-405f-8c62-a7a223abfc92 --------- Copilot-Session: aadad05d-2646-405f-8c62-a7a223abfc92 |
||
|
|
58da0cc253 |
Python: add MiddlewareFailure, a first-class fatal signal for function middleware (#7562)
* feat(core): first-class fatal signal (MiddlewareFailure) for function middleware The function-invocation loop converts every exception raised by function middleware into a tool-error result and keeps looping, so middleware that needs fail-closed semantics (enforcement layers, guardrails) had no loud escape: the agent-hooks feature simulated one by mutating shared run state, raising MiddlewareTermination, and re-raising the real failure two hops away at the run boundary. Introduce MiddlewareFailure (a MiddlewareException sibling of MiddlewareTermination) as the loop's explicit fail-closed escape: - _auto_invoke_function re-raises it (both the direct and the pipeline path) instead of absorbing it into a tool-error result; ordinary exceptions keep the absorb-and-continue contract. - A failing call fails the whole parallel batch: in-flight sibling tool tasks are cancelled and awaited before the failure propagates. - Every existing MiddlewareTermination absorb site (agent/chat pipelines, _execute_single_function_call, harness loop, purview) passes it through untouched by construction, and agent/chat middleware exceptions already propagate, so one exception type gives uniform fail-loud semantics across all three categories. Migrate the agent-hooks feature to the new signal: delete the _RunState.halted back-channel and its three run-boundary re-raise checks, drop the halted arm of the termination special case in the function middleware (the approval-request pass-through moves to the single approval check on the normal path), and fail partial installs loudly. Tool-seam host_error blocks keep surfacing as InterceptionBlocked at the run boundary via the exception cause chain (one deny surface at every seam, pinned by tests). Spec 004 gains the middleware-failure invariants and matrix rows. Closes #7522 Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com> * fix(core): harden tool-seam unwrap and pin review findings Review round follow-ups for the MiddlewareFailure feature: - Only agent-hooks' own tagged tool-seam halts (_ToolSeamBlockFailure) authorize re-raising the chained InterceptionBlocked at the run boundary; a third-party MiddlewareFailure with a crafted InterceptionBlocked cause now propagates as raised instead of laundering an attacker-shaped interception record into the feature's deny surface (regression test added, verified by mutation). - Document that middleware must not catch MiddlewareFailure (docstring and spec 004): swallowing it converts a fail-closed abort back into a running, possibly unguarded loop. - Pin the trailing termination re-raise in the agent-hooks function middleware: an inner short-circuit is bracketed and still propagates, skipping outer middleware post-code (test fails with the re-raise removed). Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com> * fix(core): acyclic tool-seam unwrap chain; document cooperative batch cancellation Address two automated-review findings on the MiddlewareFailure PR, both confirmed empirically: - _reraise_tool_seam_block created a two-object exception-chain cycle (block.__cause__ -> wrapper -> block) by re-raising the chained InterceptionBlocked `from` its transport wrapper. Detach the wrapper's back-links and re-raise bare, recording the wrapper as the block's __context__ — acyclic, both exceptions still visible in tracebacks. Regression test walks the chain and pins finiteness (verified to fail against the cyclic re-raise). - Batch cancellation is cooperative: a synchronous tool body already running in a worker thread (asyncio.to_thread) cannot be interrupted by task cancellation and may complete its side effects after the failure reached the caller; its result is discarded either way and propagation is not delayed behind it. Narrow the stated contract (MiddlewareFailure docstring, loop comment, spec 004) and pin it with a blocking-sync-sibling regression test. Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com> * fix(core): settle dangling calls on service-managed conversations on abort Address maintainer review on the MiddlewareFailure PR: - A MiddlewareFailure escaping a tool batch on a service-managed conversation left the hosted thread ending in unresolved function_call items: _update_continuation_state persists session.service_session_id when the model turn completes (before tool execution), and probe-verified the next run sends only the new user message against that conversation — OpenAI-style continuations reject such a request, so a routine policy abort left the session permanently stuck. Both loops now settle the thread before propagating: one error function_result per dangling call, submitted with tool_choice="none" in a single extra request whose response is discarded; a settlement failure never masks the abort, and runs without a service-managed conversation make no extra request. Pinned by three regression tests (non-streaming, streaming, and the no-conversation no-cost case); spec 004 and the MiddlewareFailure docstring updated. - Make the three tool-bracket escape tuples in the agent-hooks function middleware identical (MiddlewareTermination, MiddlewareFailure, CancelledError): a MiddlewareFailure raised inside the post/error-bracket emit bodies is unreachable today, but the uniform tuples remove the need to reason about why they would differ, and preserve the exact exception (including the private tool-seam tag) if the emitter ever surfaces one. Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com> * fix(core): advance settled continuation; settle approved-replay aborts Address maintainer review on the MiddlewareFailure settlement path, both probe-verified (branch rebased onto current main first): - Advance the persisted continuation to the settlement response. For response-ID continuations (OpenAI Responses store=True, where the response id is the continuation handle) the settlement response is the first endpoint whose chain includes the synthetic tool outputs; leaving session.service_session_id on the pre-settlement response made the settlement ineffective — the next run would continue from the still-unresolved turn. The settlement response now runs through _update_function_invocation_continuation_state (a no-op for stable conversation-object ids). Pinned by a regression test that fails with the advance removed. - Cover the approval-resolution phase: a MiddlewareFailure raised while an approved tool is replayed escapes loudly (probe-verified, already the case) but executed before the loops' settlement seams, leaving the original — already service-persisted — call unresolved. _resolve_approval_responses now takes a settle_dangling_calls callback invoked with the approved batch on abort; the settlement helper became a layer method taking explicit calls (approval-response wrappers unwrap to their underlying calls, hosted-tool approvals are left to their provider protocol) and carries its own best-effort containment. Pinned by deny-during- replay regression tests in both response modes, mutation-verified. Spec 004 invariants and matrix rows updated accordingly. Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com> --------- Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com> |
||
|
|
2213ef8493 |
Add es-metadata.yml for Engineering System inventory (#7740)
Registers the repository with Engineering System inventory via the InventoryAsCode provider, mapping it to its Service Tree service and routing compliance work items to the owning team. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 05291438-8e37-49d6-84b6-5ffb7814abb8 |