68136ee081dbbee6983e6bb92a834f9ad30d20dc
1237 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
68136ee081 |
Python: Clean up dependency groups and compatibility (#7046)
* Python: Clean up dependency management Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2f7b1c89-f3ff-418d-ab4e-4f014fda308f * Python: Harden Mistral SDK import fallback Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2f7b1c89-f3ff-418d-ab4e-4f014fda308f |
||
|
|
87af313119 |
Python: [BREAKING]: Emit TOOL_CALL events for workflow participant tool calls in AG-UI (#7039)
* Python: emit participant tool calls in AG-UI workflows Decisions: - Pass function call, function result, and approval request content from streaming agent updates regardless of role. - Preserve the assistant-role gate for text and reuse the shared AG-UI content emitters without dual custom-event emission. Files changed: - packages/ag-ui/agent_framework_ag_ui/_workflow_run.py - packages/ag-ui/tests/ag_ui/test_workflow_run.py Verification: - uv run poe test -P ag-ui - uv run poe pyright -P ag-ui - uv run poe test-typing -P ag-ui - uv run poe syntax -P ag-ui -C Notes: - Existing workflow golden scenarios do not exercise participant tool calls, so no snapshot changed. - No blockers. * Python: guard participant tool call duplication Decisions: - Assert the workflow stream emits one TOOL_CALL_START when a streamed call is also present in final conversation history. - Keep production flow unchanged because latest-assistant final-response conversion prevents duplication. Files changed: - packages/ag-ui/tests/ag_ui/test_workflow_run.py Verification: - uv run pytest packages/ag-ui/tests/ag_ui/test_workflow_run.py -k 'participant_tool_call or repeat_tool_call' -q - uv run poe test -P ag-ui - uv run poe pyright -P ag-ui - uv run poe test-typing -P ag-ui - uv run poe syntax -P ag-ui -C - git diff --check Notes: - No blockers; no call-id guard was required. * Python: scope workflow tool content bypass to resumable tool calls - Exclude approval request content from the role bypass. Workflow approvals resume through request_info pending state, so an approval interrupt emitted from streamed content would have no pending request to resume against. - Admit mcp_server_tool_call and mcp_server_tool_result so provider-hosted MCP tool calls from workflow participants emit standard tool call events. - Add unit tests for MCP passthrough, approval exclusion, and mixed text-plus-tool content in non-assistant updates. |
||
|
|
9ac548ad15 |
Python: keep attachments close (#7038)
* Python: keep attachments close * Python: close attachment edge cases |
||
|
|
32a547a1a7 |
Python: bind AG-UI tool arguments to call IDs (#6342)
Co-authored-by: White-Mouse <15983334+White-Mouse@users.noreply.github.com> |
||
|
|
7464a59228 |
Python: Bump Python package versions for 1.11.0 release (#7035)
* Bump Python package versions for 1.11.0 release Bump the CHANGELOG-selected packages for the 1.11.0 release: core and the root package move to 1.11.0 for the new stable APIs, Foundry and OpenAI receive patch bumps, changed prerelease packages receive the 260709 stamp or next RC counter, and Monty joins the bump set for corrected published dependency metadata. No beta cohort bump was applied. Raise core floors conservatively on every package publishing this cycle and correct dependency floors exposed by lower-bound validation. Copilot-Session: ee33d338-c1fc-4182-9106-0345ccf26b8e * Fix Gemini streaming type suppression Move the targeted Pyright suppression to the SDK contents argument, where the google-genai invariant content-list alias produces the compatibility diagnostic, and remove the now-unnecessary member suppression. Copilot-Session: ee33d338-c1fc-4182-9106-0345ccf26b8e * Raise Monty core dependency floor Align Monty with the conservative release policy by requiring agent-framework-core 1.11.0 or later for the package version published in this cycle. Copilot-Session: ee33d338-c1fc-4182-9106-0345ccf26b8e |
||
|
|
01ec3b7bcf |
Fix AG-UI approval thread aliases (#6908)
Co-authored-by: godququ5-code <256881196+godququ5-code@users.noreply.github.com> |
||
|
|
ce96fd4b72 |
Python: Integrate message injection into harness agent (#7027)
* Integrate message injection into harness agent and sample console * Add agents.md update. * Address PR comments |
||
|
|
52237b8eff | Python: consolidate dependency updates (#7033) | ||
|
|
e6cc2c09af |
Python: Fix read_skill_resource instruction dropping .md extension (#7031)
The RESOURCE_INSTRUCTIONS example told the model to use eferences/FAQ instead of eferences/FAQ.md, contradicting the actual exact-match resource lookup (which lists and matches names including the extension). This caused read_skill_resource to fail with 'Resource not found'. Align the example with the .NET original. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
7440b1c376 | feat: enhance tool choice handling for required mode in _prepare_options (#7024) | ||
|
|
d43e52df69 |
Python: support mem0ai 2.x (#7004)
* Python: support mem0ai 2.x Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * updated lock * Address mem0 OSS application scope Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Use filters for mem0 platform add Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
fbaa346eec |
.NET: Python/.Net: Agent Harness blog post accompanying samples part 3 (#6741)
* Python/.Net: Agent Harness blog post accompanying samples part 3 * Delete inadvertently added files * Address PR feedback. * Rename files that are causing dotnet format failures * Address PR comment * Fix blog links |
||
|
|
9f4526a41e |
fix: parse structured response value from final message (#6383)
Signed-off-by: liuzemei <35027683+liuzemei@users.noreply.github.com> |
||
|
|
13fc425bf5 |
Python: docs: fix removed ChatAgent references in _clients.py docstrings (#6924)
* docs: fix removed ChatAgent references in _clients.py docstrings * docs: make _clients.py tool-support examples copy/paste-safe Import Agent in each tool-support protocol docstring example so copy/pasting no longer raises NameError, and define the shell executor (LocalShellTool) in the SupportsShellTool example. Addresses Copilot review feedback on #6924. Co-authored-by: Cursor <cursoragent@cursor.com> * docs: wrap SupportsShellTool example in async function `async with LocalShellTool()` is a SyntaxError at module level, so the copy/pasted snippet must live inside an async function to be valid. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Sumesh Bharathi Ramasamy <sumesh@iconicair.io> Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
5f9ac6b394 |
Python: bind policy-enforcement approvals to a single tool invocation (#6966)
* Bind policy-enforcement approvals to a single tool invocation PolicyEnforcementFunctionMiddleware retained approved call_ids in a set that was never cleared, so a reused call_id could re-authorize a later or different tool call without a fresh approval. It also accepted an approved response as long as the invocation metadata carried a pending call_id, without checking the response id or embedded function_call. Bind each approval to the exact invocation shown for review: call_id, function name, arguments, the security label (integrity/confidentiality), and the session. Validate that the approval response itself names the pending request (its id and embedded function_call), and consume the approval on first use. A reused call_id, a different function, changed arguments, an escalated label, a different session, or a mismatched approved response now all require a fresh approval. Adds regression tests covering each of those cases plus legitimate re-approval. * Require approval response identifiers to be present and match Make the policy-enforcement approval-response check reject a response that omits its id or embedded function_call.call_id: both must now be present and equal to the pending call_id, closing a None-identifier bypass. Adds a regression test. * Disclose all policy violations in a single approval request PolicyEnforcementFunctionMiddleware computed the approval decision once and reused it across the integrity and confidentiality checks, so a call that violated both policies produced an approval request describing only the untrusted-context violation and then silently waved the undisclosed confidentiality violation on replay. Detect every applicable violation up front and surface them together in a single approval request, so a granted approval waves only what it disclosed. The binding (call_id, function, arguments, security label, session) and consume-once behavior are unchanged. Adds a regression test covering a combined untrusted-context and confidentiality violation. * Bind policy approval to the disclosed violation set and fingerprint A pending policy approval was bound to the call body, security label, and session but not to the violations it disclosed. Because the violation set depends on the tool's policy metadata (max_allowed_confidentiality, accepts_untrusted), a replay could compute a different or larger set after that metadata changed and execute it under the old approval even though the user never reviewed that risk. Record the canonical disclosed violation fingerprint (type plus reason) in the pending record and require the replay to trip the same set, otherwise re-request approval disclosing the new set. Also require the approval response's approved flag to be a strict boolean True so a truthy non-boolean value is not treated as approval. Adds regression tests for a new violation appearing on replay, a same-type violation whose disclosed risk worsened, and a non-boolean approved flag. |
||
|
|
1aca7601b8 |
Python: Add hosting protocol helper surface (#6891)
* Add Python hosting protocol helper surface Introduce AgentFrameworkState and SessionStore for app-owned hosting routes, add Responses run conversion/rendering helpers, and update the local Responses sample to use native FastAPI routing with streaming support. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix CI failures, session continuity, and streaming model reporting - Fix constrained TargetT TypeVar in AgentFrameworkState: split __init__ into per-shape overloads (instance/sync factory/async factory/awaitable) since a bound TypeVar combined with one big Callable/Awaitable union parameter was unsolvable across pyright/pyrefly/ty/zuban. - Fix _FakeAgent test fixtures to structurally satisfy SupportsAgentRun (matching attribute types and overloaded run()), which the above surfaced. - Add SessionStore.put() to alias an additional session id to an already-resolved session, and use it in the local_responses sample to fix a real session-continuity bug: previous_response_id rotates every turn, so without aliasing the newly minted response id, turn 3+ of a conversation silently lost all prior history. Verified against a live Foundry model across a 3-turn conversation. - Fix responses_stream_events_from_run to report the real model instead of the "agent" fallback: AgentResponse.from_updates never carries a raw representation forward, so capture model from the individual streamed updates' raw representations instead. Verified live. - Add response_model=None to the sample's FastAPI route (it could not boot at all: FastAPI tried to build a Pydantic response model from the JSONResponse | StreamingResponse return annotation). - Map responses_to_run's ValueError to HTTP 400 instead of a 500. - Add HTTP round-trip integration tests (packages/hosting-responses) that exercise the same FastAPI + AgentFrameworkState + Responses helper wiring as the sample via httpx.ASGITransport, including a regression test for the session-continuity fix. - Add Workflow-target test coverage, SessionStore.put/reset_session tests, and TypeError-path coverage to packages/hosting/tests/hosting/test_state.py. - Extend call_server.py / call_server_af.py to a third conversation turn so they actually exercise the continuity chain (previous scripts stopped at turn 2, which would never have revealed the bug above). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Simplify session-continuity aliasing: fold put() into get() Per feedback: the growth of SessionStore was not the problem -- it's intentional, since OpenAI's previous_response_id is designed to let a caller continue (fork) from any earlier response, not just the latest one, so every response id has to stay independently resolvable. That part stays as-is. What was too complex was the call site: routes had to manually fetch a session and then conditionally alias it with a separate put() call. Folded that into a single get(session_id, alias=...) call instead: - SessionStore.get() gains an optional `alias` keyword that registers an additional id for the same session in the same call (no-op if alias is None or equal to session_id). Removed the separate put() method. - AgentFrameworkState.get_session() passes `alias` through. - local_responses sample and the HTTP round-trip integration tests now do `await state.get_session(lookup_id, alias=response_id)` instead of pulling the store out and orchestrating get()/put() by hand. - Documented that this in-memory SessionStore intentionally never evicts (by design, to support forking), and that a storage-backed replacement (Redis, a database, ...) is responsible for its own TTL/eviction policy. Verified against a live Foundry model across a 3-turn previous_response_id chain after the simplification. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Refine hosting state helpers Split the shared state surface into AgentState and WorkflowState, keep SessionStore and CheckpointStore as plain storage, and make state helpers responsible for get-or-create behavior. Update the Responses sample and HTTP round-trip tests to store the post-run session explicitly under the minted response id, and support WorkflowBuilder/orchestration-style builders via structural build() support. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix hosting state test protocol fakes Widen fake agents' get_session service_session_id parameter to match the SupportsAgentRun protocol under the Python 3.11 test typing checkers. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Simplify Responses stream helper naming Rename responses_stream_events_from_run to responses_stream_from_run across exports, tests, docs, and the local Responses sample to align with the generic <protocol>_stream_from_run helper convention. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add state-level storage setters Add AgentState.set_session and WorkflowState.set_checkpoint_storage so app code can pair get-or-create helpers with explicit post-run storage without reaching into the underlying stores. Update Responses docs, tests, and sample to use state.set_session. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Simplify WorkflowState checkpoint handling Remove CheckpointStore from WorkflowState so workflow checkpointing uses the existing CheckpointStorage abstraction directly. Keep WorkflowState focused on resolving workflow targets, including builders, and update hosting docs/tests accordingly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Rename Responses streaming run helper Rename responses_stream_from_run to responses_from_streaming_run across the hosting-responses exports, tests, docs, and local Responses sample. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Align Python hosting spec with protocol helpers Rewrite SPEC-002 to match the accepted helper-first hosting ADR and the implementation PR: AgentState, WorkflowState, SessionStore, Responses helpers, app-owned security/state responsibilities, and the minimal FastAPI Responses shape. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Remove old Python hosting channel implementation Remove the unreleased AgentFrameworkHost/channel implementation, the old hosting-telegram package, and old host/channel samples. Keep agent-framework-hosting focused on AgentState, WorkflowState, and SessionStore, and keep hosting-responses focused on helper-first Responses conversion. Update SPEC-002 to match the accepted helper-first ADR and the implementation surface. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Restore helper-first workflow sample Rebuild the local Responses workflow sample on the protocol-helper surface, add production-readiness cautions to the local hosting samples, and align file-backed workflow checkpoint/cursor storage under one sample storage root. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address hosting helper review feedback Handle streaming failures as terminal Responses SSE events, guard concurrent target/session initialization, and scope workflow sample checkpoint storage per continuation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Clarify Responses sample continuation behavior Document unknown conversation_id behavior in the agent sample and make the workflow sample explicitly reject conversation_id while continuing to use responses_session_id for previous_response_id. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Clarify Responses sample option policy Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
9a5312b278 |
Python: Add message injection middleware (#6998)
* Python: Add message injection middleware Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: Ignore informational tool calls for message injection Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: Preserve per-service history with message injection Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
978cfcd9e4 |
Python: Fix Foundry reasoning MCP compaction (#6907)
* Fix Foundry reasoning MCP compaction * Address reasoning MCP review feedback --------- Co-authored-by: godququ5-code <256881196+godququ5-code@users.noreply.github.com> Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com> |
||
|
|
7a73455e56 |
Python: normalize single Anthropic tools (#6903)
* Python: Normalize Anthropic single tools * Potential fix for pull request finding Thanks Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Python: Address Anthropic review feedback --------- Co-authored-by: VectorPeak <VectorPeak@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> |
||
|
|
1b4484829c |
Python: Add Python package release skill (#6356)
* Add Python package release skill * Address release skill review feedback * Address Python release skill review comments * Resolve Python release skill docs conflict |
||
|
|
346d3f0820 |
Python: Mark hosted tool calls informational-only (#6997)
* Python: Mark hosted tool calls informational-only Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: Address informational-only review feedback Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: Preserve approval responses in tool invocation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
9cc020e486 |
Python: Add AG-UI FastAPI SSE keepalive support (#6980)
* Python: Add AG-UI SSE keepalive endpoint option Key decisions: add keepalive_seconds as endpoint-owned FastAPI registration configuration with default 15, accept None as the explicit off switch, validate that non-None values are greater than zero during route registration, and keep agent/workflow runner constructors unchanged. Declare sse-starlette>=3.4.5,<4 as a direct AG-UI dependency without changing the existing StreamingResponse path in this slice. Files changed: packages/ag-ui/agent_framework_ag_ui/_endpoint.py adds validation and the public endpoint parameter; packages/ag-ui/tests/ag_ui/test_endpoint.py covers default, supported runner shapes, endpoint ownership, and invalid intervals; packages/ag-ui/pyproject.toml and uv.lock add the direct sse-starlette dependency metadata. Verification: uv run pytest focused keepalive endpoint tests -q; uv run poe test -P ag-ui; uv run poe syntax -P ag-ui -C; uv run poe pyright -P ag-ui; uv run poe validate-dependency-bounds-test -P ag-ui; git diff --check; git diff --cached --check. Also ran validate-dependency-bounds-project --mode both --package ag-ui --dependency sse-starlette; it completed but broadened the lower bound, so the issue-required >=3.4.5,<4 contract was restored and re-locked. Notes: uv run poe typing -P ag-ui and uv run poe check -P ag-ui currently fail in mypy before checking project files because .venv/lib/python3.13/site-packages/numpy/__init__.pyi uses type-statement syntax while the test mypy profile targets Python 3.11. Local issue file was moved to issues/done/ but not staged. * Python: Emit AG-UI SSE keepalive comments Key decisions: switch only enabled AG-UI FastAPI endpoint keepalive responses to EventSourceResponse, keep encoded AG-UI SSE frames as bytes on that path to avoid double encoding, and emit the fixed static SSE comment ': keepalive' while preserving existing SSE headers. Files changed: packages/ag-ui/agent_framework_ag_ui/_endpoint.py adds the EventSourceResponse enabled path and static comment factory; packages/ag-ui/tests/ag_ui/test_endpoint.py adds an endpoint test for a long output-silent gap, keepalive comments, headers, valid data frames, and no data: data: double encoding. Verification: uv run pytest packages/ag-ui/tests/ag_ui/test_endpoint.py::test_endpoint_keepalive_enabled_emits_static_comment_during_silent_gap -q; focused endpoint pytest selection; uv run poe test -P ag-ui; uv run poe syntax -P ag-ui -C; uv run poe pyright -P ag-ui; git diff --check; git diff --cached --check. Notes: uv run poe check -P ag-ui still fails in the test-typing mypy phase before project files are checked because .venv/lib/python3.13/site-packages/numpy/__init__.pyi uses type-statement syntax while the mypy test profile targets Python 3.11. Local PRD/Ralph/context artifacts were not staged. * Python: Preserve disabled AG-UI SSE keepalive behavior Key decisions: cover keepalive_seconds=None at the FastAPI endpoint seam and assert it preserves the legacy StreamingResponse SSE shape without emitting transport keepalive comments. Files changed: packages/ag-ui/tests/ag_ui/test_endpoint.py adds disabled keepalive endpoint coverage for headers, valid AG-UI data frames, no keepalive comments, and no data: data: double encoding. Verification: uv run pytest packages/ag-ui/tests/ag_ui/test_endpoint.py::test_endpoint_keepalive_disabled_preserves_streaming_response_shape packages/ag-ui/tests/ag_ui/test_endpoint.py::test_endpoint_keepalive_enabled_emits_static_comment_during_silent_gap -q; uv run poe test -P ag-ui; uv run poe syntax -P ag-ui -C; uv run poe pyright -P ag-ui; uv run poe test-typing -P ag-ui --checker pyright; git diff --check. Notes: no production code changes were needed because the endpoint already branches to the existing StreamingResponse path when keepalive_seconds=None. Local PRD/Ralph/context artifacts were not staged. * Python: Document AG-UI SSE keepalive behavior Key decisions: document keepalive_seconds at the FastAPI endpoint seam as a default-enabled transport keepalive with None as the off switch, and record that SSE keepalive emits comments without changing AG-UI events or adding protocol heartbeat events. Files changed: packages/ag-ui/agent_framework_ag_ui/_endpoint.py expands the public endpoint docstring; packages/ag-ui/AGENTS.md records endpoint-owned keepalive guidance; packages/ag-ui/tests/ag_ui/test_endpoint.py adds a public docstring regression. Verification: uv run pytest packages/ag-ui/tests/ag_ui/test_endpoint.py::test_add_endpoint_docstring_describes_keepalive_transport_behavior -q failed before the doc update; focused keepalive endpoint tests passed; uv run poe test -P ag-ui; uv run poe syntax -P ag-ui -C; uv run poe pyright -P ag-ui; uv run poe test-typing -P ag-ui --checker pyright; uv run python scripts/check_md_code_blocks.py packages/ag-ui/AGENTS.md; git diff --check. Notes: no standalone docs page was added. Local issue bookkeeping was moved to issues/done but not staged; local PRD and Ralph/context artifacts remain unstaged. * Python: Tighten AG-UI FastAPI dependency bound * Python: Defer AG-UI keepalive transport imports |
||
|
|
9ef8fadeac |
Python: Fix Bedrock non-ASCII escaping in JSON content blocks (#6628)
* Python: Fix Bedrock non-ASCII escaping in JSON content blocks The Bedrock Converse `json` content block was serialized with `json.dumps(json_value)`, whose default `ensure_ascii=True` escapes CJK/emoji/accented characters to `\uXXXX` and surfaces garbled text. Add `ensure_ascii=False` to match the sibling OpenAI client and the 16+ other call sites across the repo. Includes a regression test. Closes #6627 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Fix Bedrock test trailing whitespace --------- Co-authored-by: kimnamu <kimnamu@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com> Co-authored-by: Evan Mattson <evan.mattson@microsoft.com> |
||
|
|
23bfa49575 |
Python: Strip tools from Foundry agent request on the preview path (#6644)
The Foundry service rejects requests that include tool declarations when an agent is specified (HTTP 400 invalid_payload, "Not allowed when agent is specified."). RawFoundryAgentChatClient._prepare_options stripped tools, tool_choice, and parallel_tool_calls only on the non-preview path, so when allow_preview=True (where the agent identity is bound on the OpenAI client via get_openai_client(agent_name=...)) the tool fields were still sent and the call failed. This client always targets a pre-provisioned agent, so it must never send tool declarations. Drop the tool fields unconditionally and log a single warning when the caller supplied tools, noting they are used only for client-side function dispatch. The non-agent FoundryChatClient (model-based) is unaffected. Fixes #5130. Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com> |
||
|
|
c47f20d9a2 |
Python: fix: DevUI list[Message] input for declarative ToolAgent entry (#6533) (#6534)
* fix: DevUI list[Message] entry for declarative ToolAgent (#6533) When a declarative ToolAgent is created with default settings the entry JoinExecutor declares `input_types = [dict | str | list[Message] | ActionTrigger | ...]`. DevUI called `select_primary_input_type` which returned bare `Message` instead of `list[Message]`, then passed a single Message to the executor that expects a list — causing a "cannot handle message of type Message" runtime error. Changes: - Add `_is_list_message_type` helper (GenericAlias cannot be used with isinstance; get_origin/get_args required). - Add `_find_chat_message_type` that recursively searches union members and returns `list[Message]` in preference to bare `Message`. - `select_primary_input_type`: first-pass uses `_find_chat_message_type` so the declarative entry type is correctly returned as `list[Message]`. - `generate_input_schema`: returns `{"type":"string"}` for `list[Message]` so DevUI renders a plain text box. - Add `_looks_like_message_dict` heuristic (role present, type=="message", or exactly {"input":...}) to distinguish serialised Message payloads from structured workflow inputs without false positives. - `parse_input_for_type`: handle `list[Message]` target — wrap plain strings/Message objects, convert lists of dicts item-by-item, pass structured workflow inputs through unchanged. - Add 12 regression tests (57 total pass). * fix: resolve pyright unknown-type errors in parse_input_for_type --------- Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com> |
||
|
|
ab90300a71 |
Python: Prefer explicit AG-UI resume payloads (#6360)
* Prefer explicit AG-UI resume payloads * test: tighten AG-UI resume assertions --------- Co-authored-by: gezw <26155255+gezw@users.noreply.github.com> Co-authored-by: Evan Mattson <35585003+moonbox3@users.noreply.github.com> Co-authored-by: Evan Mattson <evan.mattson@microsoft.com> |
||
|
|
c64f8d9e86 |
Clarify service session ID scoping (#6993)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
0b49609176 |
Python: Add progressive MCP disclosure (#6850)
* Add progressive MCP disclosure Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address progressive MCP review feedback Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Document progressive MCP loader name collisions Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address progressive MCP review feedback Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix progressive MCP test typing Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Track progressive MCP warning feature id Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Document internal typing helper guidance Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix README stars badge link Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Support batch progressive MCP load unload Allow progressive MCP load_tool and unload_tool to accept either a single tool name or a list of tool names, applying successful changes in batches with per-tool model-visible results. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Evan Mattson <35585003+moonbox3@users.noreply.github.com> |
||
|
|
2aae66d063 |
Python: use writable runtime directory for Foundry Skills sample (#6606)
* fix: use writable skills download directory * fix: handle empty skills download directory override --------- Co-authored-by: malsabbagh05 <malsabbagh05@users.noreply.github.com> Co-authored-by: Tao Chen <taochen@microsoft.com> |
||
|
|
5adc038b16 |
Python: Add refresh_interval (TTL) to CachingSkillsSource (#6977)
* Python: Add refresh_interval (TTL) to CachingSkillsSource Port .NET's CachingAgentSkillsSourceOptions.RefreshInterval to the Python skills cache. Previously CachingSkillsSource cached a source's skill list indefinitely (only clearing on a failed fetch), so callers had no built-in way to periodically re-discover skills whose backing source changes at runtime (notably MCPSkillsSource over the network). CachingSkillsSource now accepts an optional refresh_interval (timedelta): a cached list older than the interval is treated as stale and re-fetched on the next call. When None (default) the cache never expires, so existing behavior is unchanged. Freshness is measured with a monotonic clock via a monkeypatchable _monotonic() helper. SkillsProvider.__init__ and from_paths expose a cache_refresh_interval kwarg threaded into the built-in cache. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: Address review feedback on CachingSkillsSource refresh_interval - from_paths: do not forward cache_refresh_interval when disable_caching=True, matching the docstring and avoiding a TypeError for legacy subclass __init__ signatures. - Correct docstring/AGENTS.md wording: a failed fetch does not update the cache (initial failure leaves it empty; a refresh failure keeps the prior list), rather than "resetting"/"leaving empty" in all cases. - Fix test typing: narrow provider._source via isinstance before accessing inner_source/_refresh_interval so ty/zuban/mypy/pyright all resolve them. - Add regression tests for disable_caching + interval and legacy-subclass paths. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: Do not forward cache_refresh_interval from from_paths into __init__ The refresh interval is already baked into the composed CachingSkillsSource that from_paths builds, and __init__ leaves a caller-supplied source un-wrapped, so forwarding cache_refresh_interval into cls(...) was a no-op for caching behavior while breaking legacy subclasses whose __init__ predates the kwarg (with caching enabled or disabled). Remove the forwarding entirely. Strengthen the regression test to cover the real break: a legacy subclass calling from_paths(paths, cache_refresh_interval=...) with caching enabled must not raise and the composed source still carries the interval. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: Drop _monotonic wrapper; call time.monotonic() directly Address review feedback: remove the _monotonic() helper that existed only to aid testing. CachingSkillsSource now calls time.monotonic() inline, and the refresh-interval tests monkeypatch time.monotonic directly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: Restore main's AGENTS.md sections lost in merge resolution The merge used 'checkout --ours' for AGENTS.md, which took the whole file from this branch and inadvertently reverted main's non-conflicting additions (the __init__.pyi tree entry and the 'Root Public API' section). Restore main's version and re-apply only the intended SkillsSource decorators change (refresh_interval docs + reworded cache-failure semantics). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
7f31bcc294 |
Python: Clear AG-UI queued approvals on cancel (#6947)
* Python: Add AG-UI approval state store Key decisions: introduce a bounded process-local server-side Approval State store for AG-UI agent approvals; scope pending approval validation by AG-UI thread id plus the endpoint's configured server-side scope when present; fail closed when approval-like resume decisions arrive without matching server-owned pending Approval State, covering replayed and wrong-scope attempts without requiring Thread Snapshot persistence. Files changed: packages/ag-ui/agent_framework_ag_ui/_approval_state.py adds the approval-only in-memory store and scoped thread-key helper; _agent.py owns the default store; _endpoint.py forwards the configured scope to approval handling independently of snapshot persistence; _agent_run.py keys pending approvals by scoped thread id and rejects approval resumes with missing state; tests/ag_ui/test_endpoint.py covers successful default resumes, replay failure, and wrong-scope failure without a snapshot store. Verification: uv run pytest focused approval resume tests -q; uv run poe test -P ag-ui; uv run poe syntax -P ag-ui -C; uv run poe pyright -P ag-ui; git diff --check; git diff --cached --check. uv run poe typing -P ag-ui and uv run poe check -P ag-ui currently stop in mypy before package checking on .venv/lib/python3.13/site-packages/numpy/__init__.pyi using Python 3.12 type-statement syntax under the configured Python 3.11 target. Notes: local issue/PRD planning artifacts were not staged. Follow-up slices still own already-approved sibling release, queued/auto-approved approval state preservation, replayable tool result persistence, synthetic-skip tightening, and final security/invariant coverage. * Python: Release AG-UI approved siblings on resume Key decisions: preserve core already-approved approval request groups inside AG-UI server-side Approval State for the visible approval interrupt; restore those siblings as server-generated approval responses only after the visible canonical resume passes server-owned validation; keep cancelled visible approvals fail-closed without executing or fabricating sibling results. Files changed: packages/ag-ui/agent_framework_ag_ui/_agent_run.py stores hidden already-approved sibling approval requests with pending approval entries and rehydrates them during resume; packages/ag-ui/tests/ag_ui/test_endpoint.py adds mixed approval-batch endpoint coverage for approved, rejected, and cancelled visible approvals. Verification: uv run pytest focused mixed approval sibling tests -q; uv run pytest neighboring approval endpoint tests -q; uv run poe syntax -P ag-ui -C; uv run poe pyright -P ag-ui; uv run poe test -P ag-ui; git diff --check; git diff --cached --check. uv run poe typing -P ag-ui and uv run poe check -P ag-ui pass pyright/pyrefly/ty/zuban for this change but still stop in mypy before package checking on .venv/lib/python3.13/site-packages/numpy/__init__.pyi using Python 3.12 type-statement syntax under the configured Python 3.11 target. Notes: local .ralph, PRD, and CONTEXT.md planning artifacts were not staged. Follow-up slices still own queued/auto-approved approval state preservation, replayable tool result persistence, synthetic-skip tightening, and final security/invariant coverage. * Python: Preserve AG-UI queued approval state Key decisions: persist only the core tool-approval state bag inside the AG-UI server-side Approval State Store, keyed by the scoped AG-UI approval thread id; restore that approval-only state into each per-run AgentSession before approval resolution; pop server-collected auto-approved responses into validated server-generated approval messages so they execute exactly like resumed approvals without trusting client state. Files changed: packages/ag-ui/agent_framework_ag_ui/_approval_state.py stores bounded tool approval state alongside pending approval entries; _agent.py passes the shared store into agent runs; _agent_run.py restores/saves tool approval state and drains collected auto-approved responses through existing pending-approval validation; packages/ag-ui/tests/ag_ui/test_endpoint.py covers queued approval surfacing and auto-approved response execution through SSE behavior. Verification: uv run pytest focused queued/auto approval endpoint tests -q; uv run pytest neighboring approval endpoint tests -q; uv run poe syntax -P ag-ui -C; uv run poe pyright -P ag-ui; uv run poe test -P ag-ui; git diff --check; git diff --cached --check. uv run poe check -P ag-ui still stops in mypy before package checking on .venv/lib/python3.13/site-packages/numpy/__init__.pyi using Python 3.12 type-statement syntax under the configured Python 3.11 target; syntax, pyright, pyrefly, ty, and zuban portions completed successfully before that failure. Notes: local .ralph, PRD, and CONTEXT.md planning artifacts were not staged. Follow-up slices still own replayable tool result persistence, synthetic-skip tightening, and final security/invariant coverage. * Python: Persist AG-UI approved tool results Key decisions: fold approval-resolved function_result messages into AG-UI Thread Snapshot history under their original tool call ids; strip server-generated canonical function_approvals resume controls from replayable snapshots; keep live TOOL_CALL_RESULT emission unchanged while preserving next-turn provider history validity. Files changed: packages/ag-ui/agent_framework_ag_ui/_agent_run.py adds snapshot merge helpers for approval-resolved tool results; packages/ag-ui/tests/ag_ui/test_endpoint.py covers mixed approval batch resume, hydration, and next-turn replay through observable endpoint behavior. Verification: uv run pytest focused replayable approval endpoint test -q; uv run pytest neighboring approval replay tests and test_approval_result_event.py -q; uv run poe syntax -P ag-ui -F; uv run poe syntax -P ag-ui -C; uv run poe pyright -P ag-ui; uv run poe test -P ag-ui; git diff --check; git diff --cached --check. uv run poe check -P ag-ui still stops in mypy before package checking on .venv/lib/python3.13/site-packages/numpy/__init__.pyi using Python 3.12 type-statement syntax under the configured Python 3.11 target; syntax, pyright, pyrefly, ty, and zuban portions completed successfully before that failure. Notes: local .ralph, PRD, and CONTEXT.md planning artifacts were not staged. Follow-up slices still own synthetic-skip tightening and final security/invariant coverage. * Python: Limit AG-UI synthetic skipped results Key decisions: treat server-owned Approval State, current approval resume decisions, and existing replayable tool results as non-abandoned tool calls for AG-UI sanitizer repair; keep the defensive skipped-result fallback for genuinely abandoned tool calls; reject client-injected tool results as insufficient to satisfy pending server-owned Approval State. Files changed: packages/ag-ui/agent_framework_ag_ui/_message_adapters.py adds protected tool-call context to synthetic skip injection; packages/ag-ui/agent_framework_ag_ui/_agent_run.py derives protected ids from pending approvals and stored approval-only state; packages/ag-ui/tests/ag_ui/test_message_adapters.py and test_endpoint.py cover protected pending calls, resume decisions, abandoned-call repair, and forged tool-result behavior. Verification: uv run pytest focused sanitizer red/green tests -q; uv run pytest focused pending-approval endpoint tests -q; uv run pytest package sanitizer plus neighboring approval endpoint tests -q; uv run poe syntax -P ag-ui -C; uv run poe pyright -P ag-ui; uv run poe test -P ag-ui; git diff --check; git diff --cached --check. uv run poe typing -P ag-ui passes pyright/pyrefly/ty/zuban but still stops in mypy before package checking on .venv/lib/python3.13/site-packages/numpy/__init__.pyi using Python 3.12 type-statement syntax under the configured Python 3.11 target. Notes: local .ralph, PRD, and CONTEXT.md planning artifacts were not staged. Follow-up slice still owns final AG-UI approval repair security and exact-once invariant coverage. * Python: Verify AG-UI approval invariants Key decisions: cover final AG-UI approval repair invariants at the FastAPI endpoint seam; treat wrong-thread resumes, client-supplied approval message spoofing, and client-injected approval state as non-executing fail-closed paths; assert exact-once replayable tool results for completed approval batches; document that Approval State is process-local and production authentication, authorization, and deployment/storage durability remain application responsibilities. Files changed: packages/ag-ui/tests/ag_ui/test_endpoint.py adds endpoint-observable security and exact-once coverage; packages/ag-ui/README.md documents Approval State production responsibilities. Verification: uv run pytest packages/ag-ui/tests/ag_ui/test_endpoint.py -q -k 'approval_resume_wrong_thread or approval_function_name_mismatch_message or approval_argument_mismatch_message or approval_client_fields_do_not_mutate or approval_resume_persists_replayable_tool_results'; uv run poe syntax -P ag-ui -F; uv run poe syntax -P ag-ui -C; uv run poe pyright -P ag-ui; uv run poe test -P ag-ui; uv run poe test-typing -P ag-ui --checker pyright; git diff --check; git diff --cached --check. Notes: local .ralph, PRD, and CONTEXT.md planning artifacts were not staged. This completes the final AG-UI approval repair security and invariant coverage slice. * Python: Clear AG-UI queued approvals on cancel * Python: Address AG-UI approval review feedback |
||
|
|
62456f044d |
Python: Fix web_search_options sent to Azure OpenAI Chat Completions API (issue #3629) (#6225)
* Fix: Skip web_search_options for Azure OpenAI Chat Completions API Azure OpenAI Chat Completions API does not support the web_search_options parameter. Sending it results in a 400 error: 'Unknown parameter: web_search_options'. This fix: - Stores the use_azure_client flag during initialization - In _prepare_tools_for_openai, skips web search tools when the client is Azure-based, logging a warning that guides users to the Responses API (OpenAIChatClient) for web search support on Azure Closes #3629 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: raise ValueError instead of silently ignoring web search on Azure Address review feedback: silent logger.warning was too easy to miss. Raising ValueError ensures callers know immediately that web search is incompatible with Azure Chat Completions and directs them to the Responses API alternative. - Changed logger.warning to ValueError in _prepare_tools_for_openai - Added test_prepare_tools_with_web_search_on_azure_raises - Added test_prepare_tools_with_web_search_on_openai_allowed * Fix Azure web search test regex --------- Co-authored-by: Autumn <Autumn@Autumns-MacBook-Air.local> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com> |
||
|
|
1249275997 |
Python: Remove experimental marker from Skills API (#6974)
* Python: Remove experimental marker from Skills API Promote the Skills feature from experimental to stable, mirroring .NET PR #6861. Removes the @experimental(SKILLS) decorators from the skills APIs and the SKILLS ExperimentalFeature enum member, updates tests and samples accordingly. MCP skills (MCP_SKILLS) remain experimental, matching the .NET change. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add experimental-stage assertions for MCP skills types Guard MCPSkill, MCPSkillResource, and MCPSkillsSource against accidental promotion by asserting their docstring warning block and __feature_stage__/__feature_id__ metadata remain experimental (MCP_SKILLS). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Remove redundant stable-stage test for Skills API Drop TestSkillsStableStage: asserting the absence of experimental markers on a released API is not meaningful, and the feature-stage decorator machinery is already covered by test_feature_stage.py. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
f280742c01 |
Python: Samples: deterministic action-boundary validation middleware (#5366) (#6528)
* Python: add ATR validation FunctionMiddleware sample (execution-boundary validation, #5366) Adds python/samples/02-agents/middleware/atr_validation_middleware.py: a FunctionMiddleware that validates tool arguments at the execution boundary and raises MiddlewareTermination before call_next() when they match an attack pattern, so the tool never runs. This is the deterministic, single-enforcement- point pattern named in #5366 and answers its open follow-up about a recommended validation-at-execution-boundary sample. The check is a small self-contained deny-list mirroring Agent Threat Rules (ATR) intent (prompt injection, exfiltration, credential access in tool args); a docstring notes how to swap in the full open ruleset via pyatr. No external dependency, so the sample stays import-clean. Updates the middleware README Files table. Signed-off-by: Adam Lin <adam@agentthreatrule.org> * Python: Samples: run the real ATR engine in atr_validation_middleware Address review on #6528: - Load and run the real ATR ruleset via pyatr (ATREngine + AgentEvent tool_call event) instead of re-implementing a regex deny-list; the built-in deny-list is now only a fallback when pyatr is not installed. - Add re.DOTALL (and a whole-text scan) to the fallback patterns so multiline injection payloads are not missed. - Move load_dotenv() into main() so importing the module has no side effects. - Route the middleware block/allow messages through a module logger instead of print(). - Include the matched ATR rule id in the log and in the MiddlewareTermination message for auditability. - Update the middleware README entry to match. * fix(samples): make ATR validation middleware pass ty/pyrefly typing CI Resolve the three type-checker errors flagged on the samples typing jobs (ty + pyrefly, reportMissingImports/reportAttributeAccessIssue via pyright): - pyatr is an optional, unstubbed runtime dependency that is not installed in the typing CI env; mark its imports with `# type: ignore` so the unresolved-import error is suppressed while keeping the graceful ImportError -> deny-list fallback intact. - Replace the function-attribute engine cache (`_detect_with_atr._engine`), which ty/pyrefly reject, with a clean `functools.lru_cache`-backed `_load_atr_engine()` loader. - Type the argument-scanning helpers to accept the real `FunctionInvocationContext.arguments` type (`BaseModel | Mapping[str, Any]`) and normalise a pydantic model via `model_dump()` before scanning, fixing the invalid-argument-type error. ty / pyrefly / pyright (samples config) / ruff check + format all clean on the file; runtime block/allow behaviour verified for both dict and BaseModel arguments. * Python: Samples: simplify ATR middleware to plain pyatr import Address review feedback (@eavanvalkenburg): now that the sample runs the real pyatr engine, drop the optional-import scaffolding. - Add a dependency header declaring pyatr (pip install pyatr). - Switch to a plain top-level `import pyatr` and remove the try/except ImportError fallback path. - Remove the regex deny-list (_FALLBACK_PATTERNS, _detect_with_fallback); keep 2-3 representative pattern shapes inline as a reference comment so readers still see the kind of rules ATR encodes. Detection is now a single straight-line engine call. - Keep the prior typing fixes: `# type: ignore` on the pyatr import (unstubbed, absent in the typing CI env), the functools.lru_cache engine loader, and the BaseModel | Mapping[str, Any] signatures. * fix: use PEP 723 inline script metadata for sample dependencies --------- Signed-off-by: Adam Lin <adam@agentthreatrule.org> Co-authored-by: eeee2345 <eeee2345@users.noreply.github.com> Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com> |
||
|
|
094d8d209a |
Python: Lazy load root agent_framework exports (#6962)
* Lazy load root agent_framework exports Move the root public API to lazy runtime exports backed by a typed stub, keep Runner deprecation handling in the owning workflow runner module, and document the maintenance pattern. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Tighten harness factory typing Add a private harness stub so create_harness_agent has a fully known public signature without depending on agent-framework-tools at runtime. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address lazy root export review comments Harden the circular import guard and add root export smoke tests covering representative lazy imports, star imports, and root stub export synchronization. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
783e8c4568 |
Python: skip NumPy stubs in mypy typing (#6969)
Mypy intentionally targets Python 3.10 for test typing, but NumPy 2.5 stubs include Python 3.12 type statement syntax. Skip following NumPy stubs so dependency maintenance can validate the repository tests without parsing NumPy internals. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
12b029858e |
Build(deps): consolidate Dependabot dependency updates (#6984)
* Consolidate Dependabot dependency updates * Restore method assignment suppression |
||
|
|
e26c8591ae |
Python: Fix response metadata construction (#6955)
* Python: Fix response metadata construction Propagate complete AgentResponse metadata through core response construction and provider finalization paths. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: Refine Ollama response metadata parsing Filter Ollama usage details to real token counts and only propagate streaming finish metadata from final chunks. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: Address response metadata review comments Accumulate Copilot non-streaming usage events and keep structured response value parsing lazy for provider hooks. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
7f551f057a |
Python: fix invalid options kwarg in workflow shared session sample (#6294)
* fix: use client_kwargs instead of invalid options kwarg in workflow sample Workflow.run() does not accept an options parameter. The store=False kwarg was silently ignored. Use client_kwargs to correctly forward it to the underlying chat client. Fixes #6293 * fix: use backend-neutral wording in client_kwargs comment --------- Co-authored-by: Benke Qu <bequ@microsoft.com> Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com> |
||
|
|
0661c69b78 |
fix(ag-ui): preserve streamed text message id (#6269)
Co-authored-by: cyphercodes <cyphercodes@users.noreply.github.com> Co-authored-by: Evan Mattson <35585003+moonbox3@users.noreply.github.com> |
||
|
|
2889475bce |
docs: add prerequisite commands for Python hosting samples (#5935)
Co-authored-by: Evan Mattson <35585003+moonbox3@users.noreply.github.com> |
||
|
|
339bbeb881 |
Fix DevUI deployment Dockerfile auth args (#6150)
Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com> |
||
|
|
5e0793542d |
Python (anthropic): Migrate structured outputs to GA output_config.format (#5884)
Bug
---
`RawAnthropicClient._prepare_options` forwards `response_format` as the
**deprecated** beta parameter `output_format={"type": "json_schema", "schema":
{...}}` plus the beta flag `structured-outputs-2025-11-13`. When the same
request also includes `tools`, Claude emits concatenated / malformed JSON —
e.g. three copies of the schema's empty default like
`{"matches":[]}{"matches":[]}{"matches":[]}` — instead of populating the
schema. Anthropic's GA shape — `output_config={"format": {"type":
"json_schema", "schema": {...}}}` — works correctly with tools.
Verified empirically on `agent-framework-anthropic` against
`claude-sonnet-4-6` for a structured-output workload that combined
`response_format` with a tool (`run_shell`); the deprecated path produced
the malformed concatenated output, the GA path did not.
Changes
-------
- Move `response_format` into `run_options["output_config"]["format"]` and
stop adding the `structured-outputs-2025-11-13` beta flag (the GA path
doesn't need it).
- Merge the format into any caller-supplied `output_config` so e.g.
`output_config["effort"]` (adaptive-thinking effort level) survives the
transformation.
- Drop the now-unused `STRUCTURED_OUTPUTS_BETA_FLAG` constant (private to
this module — no external callers).
- `_prepare_response_format` keeps the same `{"type": "json_schema",
"schema": ...}` return shape; the docstring is updated to point at the
GA target.
Test plan
---------
- `uv run pytest packages/anthropic/tests` → 130 passed.
- New tests:
- `test_prepare_options_uses_output_config_for_response_format` — the
GA `output_config.format` shape is emitted, the deprecated
`output_format` key is not, and the `structured-outputs-2025-11-13`
beta flag is not added.
- `test_prepare_options_preserves_caller_supplied_output_config_effort`
— a caller-supplied `output_config["effort"]` survives the merge.
- `test_prepare_options_no_response_format_omits_output_config` — no
`output_config` is added implicitly when `response_format` is absent.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
de39be9e58 |
Python: Improve error message when TypeVar is used in handler registration (#4553)
* Python: Improve error message when TypeVar is used in handler registration Fixes #4547. Adds early detection of unresolved TypeVar instances in: - @handler decorator (both explicit and introspected type paths) - @executor decorator (both explicit and introspected type paths) - WorkflowContext type argument validation (direct and union members) When a TypeVar is detected, a clear ValueError is raised with actionable guidance to use concrete types via @handler(input=ConcreteType, output=ConcreteType). * Address PR review: runtime-safe TypeVar detection and unit tests - Add shared is_typevar() helper in _typing_utils.py that safely detects TypeVar from both typing and typing_extensions modules - Replace all isinstance(x, TypeVar) calls with is_typevar() in _executor.py, _function_executor.py, and _workflow_context.py - Add 18 unit tests covering TypeVar validation for @handler, @executor, and WorkflowContext[T] (explicit params, introspection, union members) * Fix pyright error: add type annotation to _TYPEVAR_TYPES Pyright's reportUnknownVariableType flagged the inferred type as partially unknown. Adding an explicit `tuple[type, ...]` annotation resolves the strict-mode check. * Suppress pyright reportUnknownVariableType for _TYPEVAR_TYPES Pyright cannot infer the runtime type of TypeVar constructors, so the tuple elements resolve to type[Unknown]. A type annotation alone does not satisfy strict mode — add an inline suppression for this specific diagnostic since the unknown types are intentional (runtime TypeVar class detection). * Reject nested TypeVars in workflow annotations --------- Co-authored-by: Kranthi Kumar Manchikanti <kmanchikanti@microsoft.com> Co-authored-by: Evan Mattson <35585003+moonbox3@users.noreply.github.com> Co-authored-by: Evan Mattson <evan.mattson@microsoft.com> |
||
|
|
fb4be3bb1f |
Python: request reference source data in agentic search (#5095) (#5100)
Pass knowledge_source_params with include_reference_source_data=True for each resolved knowledge source on the KnowledgeBaseRetrievalRequest, so ref.source_data is populated when the source has source_data_fields configured. Uses SearchIndexKnowledgeSourceParams (azure-search-documents 12.0.0) and resolves real source names for both created and existing knowledge bases (avoids the prior 'None-source' name). Fixes #5095 Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> |
||
|
|
b31c8981a4 |
Python: Add multi-tenant hosting hosting security consideration to a2a sample (#6983)
* Add multi-tenant hosting hosting security consideration to a2a sample * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> |
||
|
|
96e009f87a |
Python: Forward skill_directories and disabled_skills to Copilot session (#6937)
GitHubCopilotAgent never forwarded the Copilot SDK's skill_directories (and disabled_skills) parameters to create_session/resume_session, so native Copilot CLI skills could not be configured through the agent. Add both as fields on GitHubCopilotOptions and forward them (with runtime-override and empty-list-clears-defaults semantics matching instruction_directories) in _create_session and _resume_session. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
07981847ed |
Add chat client Agent typing tests (#6950)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
81e425b44f |
Python: [BREAKING] Durable Task multi-workflow hosting and sub-workflows (#6696)
* feat(durabletask): add workflow naming helpers (multi-workflow phase 0)
Foundation for hosting multiple workflows (and later sub-workflows) on one
durable task host. Adds a host-agnostic naming module that derives the stable
durable names a hosted workflow registers under.
- New `_workflows/naming.py`:
- `workflow_orchestrator_name(name)` -> `dafx-{name}` (orchestration name,
aligned byte-for-byte with .NET `WorkflowNamingHelper`).
- `workflow_name_from_orchestrator(name)` -> reverse, `None` when not prefixed.
- `validate_workflow_name(name)` -> rejects empty / malformed / auto-generated
`WorkflowBuilder-<uuid>` names (validate-and-reject rather than silently
sanitize, since the name becomes a durable identity and an HTTP route segment).
- `is_auto_generated_workflow_name(name)`, `DURABLE_NAME_PREFIX`.
- Export the helpers from the package public API.
- Mark `WORKFLOW_ORCHESTRATOR_NAME` deprecated in favor of per-workflow names
(kept functional; the single-workflow path still uses it until phase 1).
- 39 unit tests covering round-trips and validation.
Design: docs/design/durabletask-multiworkflow-and-subworkflows.md
* feat(durabletask): host multiple workflows per worker with scoped names (phase 1)
Enables hosting more than one MAF workflow on a single standalone Durable Task
worker, and aligns both hosts on workflow-scoped durable names so two co-hosted
workflows that reuse an executor id cannot collide.
Naming (shared, host-agnostic):
- orchestration: dafx-{workflowName} (matches .NET; the name DT tooling surfaces)
- non-agent activity / agent entity: dafx-{workflowName}-{executorId} (scoped)
- New naming helpers workflow_scoped_executor_id / workflow_executor_activity_name.
Standalone worker (agent-framework-durabletask):
- configure_workflow is now additive: stores workflows keyed by Workflow.name,
rejects duplicate / auto-generated (WorkflowBuilder-<uuid>) / invalid names,
registers one orchestrator per workflow plus its scoped activities/entities.
- The shared orchestrator dispatches scoped names derived from workflow.name.
- New registered_workflow_names property.
Client (DurableWorkflowClient):
- Optional default workflow_name on the client; start/run/stream accept a per-call
workflow_name and target dafx-{name}.
- Opt-in ownership validation on status/HITL methods: when a workflow name is
resolvable, an instance whose orchestration name does not match is treated as
not-found (status -> None, pending -> [], send_hitl_response / await -> raise),
mirroring the Azure Functions route-scoping check.
Azure Functions host (agent-framework-azurefunctions):
- Registration now uses the same scoped names so the shared orchestrator's
dispatch matches (single workflow per app for now; flat workflow/* routes kept).
- Workflow name is validated up front; workflow agents register under the scoped
entity id; _is_workflow_orchestration scopes to dafx-{workflow.name}.
Samples + tests:
- Durable Task and Azure Functions workflow samples now name their workflow.
- Unit tests cover multi-workflow registration, name validation, client targeting,
and ownership; integration tests target the named workflows.
WORKFLOW_ORCHESTRATOR_NAME remains exported (deprecated). This is a hard switch:
in-flight single-workflow instances created before upgrade (under the old
workflow_orchestrator name) will not resume.
Design: docs/design/durabletask-multiworkflow-and-subworkflows.md
* feat(azurefunctions): host multiple workflows per app with per-workflow routes (phase 2)
Completes multi-workflow hosting on the Azure Functions host, building on the
shared scoped-naming foundation from the worker phase.
AgentFunctionApp:
- New `workflows=` parameter accepting a list (keyed by each `Workflow.name`) or a
name->Workflow mapping; the existing `workflow=` is a single-workflow alias.
Both may be combined. Duplicate names and mapping-key/name mismatches are rejected.
- Each workflow registers its own `dafx-{name}` orchestration, workflow-scoped
activities/entities, and per-workflow HTTP routes:
`workflow/{name}/run`, `workflow/{name}/status/{instanceId}`,
`workflow/{name}/respond/{instanceId}/{requestId}`. Routes are always
per-workflow (even for a single workflow) so callers don't change URLs as an app
grows from one workflow to many.
- Route ownership check is per-workflow (`_is_owned_orchestration(status, name)`):
a leaked instance id for another orchestration -- or another workflow -- is
treated as not-found, extending the route-scoping defense.
- `get_agent(context, name, workflow_name=...)` resolves a workflow agent under its
scoped id; bare `agents=` registration keeps the standalone surface. New
`workflows` introspection property; `.workflow` now returns the sole workflow
(or None when several are hosted).
- Removed the now-unused flat-URL helper `_build_status_url` (handlers inline
per-workflow URLs).
Samples + tests:
- Azure Functions workflow samples (09-12) name their workflow; integration tests
target the per-workflow routes.
- Unit tests cover multi-workflow registration, duplicate/mapping/auto-name
rejection, and per-workflow ownership.
Note: sample README / demo.http route docs are updated in the docs phase.
Design: docs/design/durabletask-multiworkflow-and-subworkflows.md
* feat(durabletask): sub-workflows via durable child orchestrations (phase 3)
Run WorkflowExecutor nodes as durable child orchestrations on both hosts.
- Protocol: add call_sub_orchestrator to WorkflowOrchestrationContext, implemented by the durabletask and Azure Functions adapters.
- Registration: planner classifies WorkflowExecutor as subworkflow_executors; collect_hosted_workflows walks nested workflows (parent first, deduped by name). Both hosts recursively register every nested workflow's orchestration/agents/activities once; only top-level workflows get HTTP routes. Names validated up front before any registration side effects.
- Orchestrator: dispatch WorkflowExecutor nodes via call_sub_orchestrator(dafx-{innerName}) with deterministic child instance ids ({instanceId}::{executorId}::{counter}), a trusted-input marker carrying nesting depth (bounded at 25), and outputs routed as messages (default) or parent outputs (allow_direct_output).
- Tests: registration/collect, orchestrator prepare/process/unwrap, recursive registration on both hosts. Sample: 11_subworkflow.
* feat(durabletask): sub-workflow HITL via qualified request ids (phase 4)
Surface a nested sub-workflow's human-in-the-loop request behind the top-level instance (B2 single addressing surface).
- Orchestrator records dispatched sub-workflow child instance ids in its custom status (subworkflows map) before suspending in task_all, so the read side can reach a child's pending request while the parent is paused.
- Read side (durabletask client get_pending_hitl_requests; AF status route) recurses into nested child statuses, qualifying each nested request id as {executorId}::{requestId} (accumulated for deeper nesting).
- Write side (durabletask client send_hitl_response; AF respond route) splits a qualified id on '::', resolves the owning child orchestration via the parent's subworkflows map, and raises the event on the leaf child with the bare request id. Unknown/inactive sub-workflow -> error/404.
- Shared SUBWORKFLOW_REQUEST_SEPARATOR ('::') in naming so both hosts and the client agree. respondUrl/respond always targets the top-level instance.
- Tests: TestSubworkflowHitl (durabletask client, 7), TestAgentFunctionAppSubworkflowHitl (AF, 7). Sample: 12_subworkflow_hitl (HITL pause inside an embedded sub-workflow).
* docs(durabletask): ADR + sample route docs for multi-workflow and sub-workflows (phase 5)
- Add ADR-0030 capturing the multi-workflow and sub-workflow hosting decisions (naming, scoped inner names, per-workflow routes, child-orchestration sub-workflows, hard-switch migration, B2 sub-workflow HITL, scoped agent addressing) with considered alternatives; mark the design doc as implemented and link the ADR.
- Update Azure Functions workflow samples (09-12) README/demo.http to the per-workflow route shape (workflow/{name}/run|status|respond) introduced in phase 2.
- Extend the durabletask sample catalog with the workflow hosting patterns (08-12), including the new 11_subworkflow and 12_subworkflow_hitl samples.
* fix(durabletask): harden sub-workflow hosting + add sub-workflow integration tests
Post-review hardening of the multi-workflow / sub-workflow durable hosting:
- Trust boundary: strip the reserved sub-workflow envelope key from untrusted
client input at both host boundaries (DurableWorkflowClient.start_workflow and
the AF start route) so a forged envelope cannot reach the trusted pickle path.
- Nested HITL addressing: qualify nested pending requests by (executorId, ordinal)
using a '~' separator (was '::', which collided with core's auto::N functional
request ids); the parent status subworkflows map is now a per-executor list so
multiple children dispatched in one superstep stay independently addressable.
- Reject two different workflow instances that share a name (the same instance
reused by sibling nodes is still deduped); validate executor ids (separator-free,
length-bounded) when hosting durably.
- Remove the arbitrary sub-workflow nesting depth cap: a WorkflowExecutor wraps a
concrete Workflow so the nesting tree is finite at build time, and the durable
instance-id length limit is the natural ceiling (matches .NET, which has none).
Tests/samples:
- New durabletask integration tests for sub-workflow composition (11) and nested
sub-workflow HITL (12); new no-agent AF sub-workflow HITL sample (13) + test.
- Exempt no-agent samples from the model-credential gate in both integration
conftests so the nested-HITL plumbing is covered deterministically.
- Update durabletask sample 12 docs to the new qualified-id format.
Validated: 484 unit tests; durabletask integration 08/09/11/12 and AF 12/13 pass
against the live emulators; pyright 0 errors; ruff clean.
* fix(durabletask): address PR review feedback on naming, typing, and docs
- Unquote df.DurableOrchestrationClient annotations so pyupgrade passes.
- Narrow the split_subworkflow_request_id result before unpacking in a naming test so the strict type checkers pass.
- Correct the durabletask sample catalog to the {executor}~{ordinal}~{requestId} qualified id format.
- Reword the Azure Functions sub-workflow sample intro so it does not imply a difference from a same-numbered sample.
- Drop internal shorthand (B2, phase labels) from code comments.
* fix(durabletask): reject case-insensitive workflow name collisions
The route ownership guard compares the durable orchestration name with casefold(), but registration kept raw names as distinct keys. Hosting 'Orders' and 'orders' therefore succeeded while either workflow's status/respond route could operate on the other's instances. Reject case-insensitive name collisions at registration (within a composition via collect_hosted_workflows, and across registration calls via the case-folded _registered_orchestrations map and the top-level guard in both hosts) so the case-folded ownership boundary stays real. Single names of any case remain valid; only collisions are rejected.
* docs(durabletask): remove multiworkflow/subworkflow ADR and design docs
Drop the ADR and design exploration documents and the dangling docstring reference to them.
* refactor(durabletask): simplify workflow client status parsing and drop deprecated orchestrator-name symbols
Extract a shared _parse_custom_status helper in DurableWorkflowClient to remove duplicated custom-status JSON parsing across three call sites.
Drop the now-unused single-workflow compatibility shims WORKFLOW_ORCHESTRATOR_NAME and WorkflowRegistrationPlan.orchestrator_name, replaced by per-workflow workflow_orchestrator_name(name).
* fix(core): drop WORKFLOW_ORCHESTRATOR_NAME from agent_framework.azure re-exports
The constant was removed from agent-framework-durabletask, but the core azure lazy-loading namespace still re-exported it, breaking pyright in packages/core. Remove it from both the runtime _IMPORTS map and the .pyi stub.
* fix(durabletask): atomic multi-workflow registration and bubble sub-workflow events
Make configure_workflow / AgentFunctionApp registration atomic: check every cross-call name collision before mutating any state, so a colliding nested sub-workflow no longer leaves a host partially configured (with the top-level name stuck in the registry). Applied to both the standalone worker and the Functions app.
Bubble sub-workflow intermediate events: a workflow run as a child orchestration now returns a SUBWORKFLOW_RESULT_KEY envelope carrying its outputs plus event timeline, and the parent re-tags the child's intermediate events with the WorkflowExecutor node id and republishes them, matching the in-process WorkflowExecutor contract. Top-level runs still return a bare outputs list.
Adds cross-registration atomicity tests on both hosts and unit tests for the result envelope and event bubbling. Resolves review threads on _worker.py, orchestrator.py, and test coverage.
* fix(azurefunctions): widen workflow orchestrator wrapper return type
The shared run_workflow_orchestrator now returns list | dict (the sub-workflow result envelope), so the azurefunctions _workflow.py wrapper that delegates to it must widen its Generator return annotation to match. Caught by the package-level pyright in CI (Package Checks), which type-checks the whole package, not just the files changed in the previous commit.
|
||
|
|
9c4cd07899 |
Python: Add SkillsSourceContext to SkillsSource.get_skills (#6895)
* Python: Add SkillsSourceContext to SkillsSource.get_skills Thread an invocation context (agent + optional session) through the skill source pipeline so sources and decorators can make context-aware decisions. - Add frozen, experimental SkillsSourceContext(agent, session). - Change SkillsSource.get_skills and all sources/decorators to accept and forward the context. - Make FilteringSkillsSource predicate context-aware: (skill, context) -> bool. - Add optional cache_isolation_key_selector to CachingSkillsSource for per-key cache isolation (None keeps the shared-bucket behavior). - Build the context in SkillsProvider from before_run agent/session. - Update foundry_hosting toolbox source, exports, tests, and docs. Python port of .NET PR #6797. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: Clarify skills source docstring examples Address PR review: docstring examples referenced `context` without constructing it. Add a `SkillsSourceContext` construction line (with a placeholder agent) to each source example and a note that the provider normally supplies it. Use `source_context` in the FilteringSkillsSource example to avoid clashing with the predicate's `context` parameter. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: Fix CI type errors and skill_filtering sample predicate Address CI failures from the SkillsSourceContext change: - Update the skill_filtering sample to the 2-arg predicate signature (skill, context); the old 1-arg lambda would fail at runtime. - Replace ad-hoc _StubAgent test stubs with the shared MockAgent / MockAgentSession from conftest so all type checkers (incl. ty) accept the SupportsAgentRun-typed agent. Add a small _NamedMockAgent subclass for tests needing distinct agent names, and drop now-unnecessary attr-defined ignores. - Use cast(SupportsAgentRun, ...) in foundry_hosting tests, which have no shared mock infrastructure. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: Make SkillsProvider caching safe-by-default; clarify context docstrings Address PR review comments: - Do not auto-wrap a caller-supplied SkillsSource in the provider's default CachingSkillsSource. A shared, unkeyed cache around a context-aware source replays the first invocation's skills for later SkillsSourceContexts, leaking skills across agents/tenants. Default caching now applies only to the built-in, context-independent file/in-memory leaf sources (Deduplicating(Caching(leaf))), matching the .NET provider. Callers who want caching on a custom pipeline compose CachingSkillsSource (optionally with a cache_isolation_key_selector) themselves. disable_caching now only affects the built-in leaves. Adds a leak-prevention test. - Reword the misleading "Unused by this source" context docstrings on the File/InMemory/MCP sources: the param is part of the get_skills contract; these sources just return the same skills regardless of context. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |