1095 Commits

  • [Python] Add agent-framework-azure-ai-contentunderstanding package (#4829)
    * feat: add agent-framework-azure-contentunderstanding package
    
    Add Azure Content Understanding integration as a context provider for the
    Agent Framework. The package automatically analyzes file attachments
    (documents, images, audio, video) using Azure CU and injects structured
    results (markdown, fields) into the LLM context.
    
    Key features:
    - Multi-document session state with status tracking (pending/ready/failed)
    - Configurable timeout with async background fallback for large files
    - Output filtering via AnalysisSection enum
    - Auto-registered list_documents() and get_analyzed_document() tools
    - Supports all CU modalities: documents, images, audio, video
    - Content limits enforcement (pages, file size, duration)
    - Binary stripping of supported files from input messages
    
    Public API:
    - ContentUnderstandingContextProvider (main class)
    - AnalysisSection (output section selector enum)
    - ContentLimits (configurable limits dataclass)
    
    Tests: 46 unit tests, 91% coverage, all linting and type checks pass.
    
    * fix: update CU fixtures with real API data, fix test assertions
    
    - Replace synthetic fixtures with real CU API responses (sanitized)
    - Update test assertions to match real data (Contoso vs CONTOSO,
      TotalAmount vs InvoiceTotal, field values from real analysis)
    - Add --pre install note in README (preview package)
    - Document unenforced ContentLimits fields (max_pages, duration)
    
    * chore: add connector .gitignore, update uv.lock
    
    * refactor: rename to azure-ai-contentunderstanding, fix CI issues
    
    Align naming with Azure SDK convention and AF pattern:
    - Directory: azure-contentunderstanding -> azure-ai-contentunderstanding
    - PyPI: agent-framework-azure-contentunderstanding -> agent-framework-azure-ai-contentunderstanding
    - Module: agent_framework_azure_contentunderstanding -> agent_framework_azure_ai_contentunderstanding
    
    CI fixes:
    - Inline conftest helpers to avoid cross-package import collision in xdist
    - Remove PyPI badge and dead API reference link from README (package not published yet)
    
    * feat: add samples (document_qa, invoice_processing, multimodal_chat)
    
    - document_qa.py: Single PDF upload, CU context provider, follow-up Q&A
    - invoice_processing.py: Structured field extraction with prebuilt-invoice
    - multimodal_chat.py: Multi-file session with status tracking
    - Add ruff per-file-ignores for samples/ directory
    - Update README with samples section, env vars, and run instructions
    
    * feat: add remaining samples (devui_multimodal_agent, large_doc_file_search)
    
    - S3: devui_multimodal_agent/ — DevUI web UI with CU-powered file analysis
    - S4: large_doc_file_search.py — CU extraction + OpenAI vector store RAG
    - Update README and samples/README.md with all 5 samples
    
    * feat: add file_search integration for large document RAG
    
    Add FileSearchConfig — when provided, CU-extracted markdown is automatically
    uploaded to an OpenAI vector store and a file_search tool is registered on
    the context. This enables token-efficient RAG retrieval for large documents
    without users needing to manage vector stores manually.
    
    - FileSearchConfig dataclass (openai_client, vector_store_name)
    - Auto-create vector store, upload markdown, register file_search tool
    - Auto-cleanup on close()
    - When file_search is enabled, skip full content injection (use RAG instead)
    - Update large_doc_file_search sample to use the integration
    - 4 new tests (50 total, 90% coverage)
    
    * fix: add key-based auth support to all samples
    
    Follow established AF pattern: check for API key env var first,
    fall back to AzureCliCredential. Supports AZURE_OPENAI_API_KEY and
    AZURE_CONTENTUNDERSTANDING_API_KEY environment variables.
    
    * FEATURE(python): add analyzer auto-detection, file_search RAG, and lazy init
    
    _context_provider.py:
    - Make analyzer_id optional (default None) with auto-detection by media
      type prefix: audio->audioSearch, video->videoSearch, else documentSearch
    - Add _ensure_initialized() for lazy client creation in before_run()
    - Add FileSearchConfig-based vector store upload
    - Fix: background-completed docs in file_search mode now upload to vector
      store instead of injecting full markdown into context messages
    - Add _pending_uploads queue for deferred vector store uploads
    
    devui_file_search_agent/ (new sample):
    - DevUI agent combining CU extraction + OpenAI file_search RAG
    
    azure_responses_agent (existing sample fix):
    - Add AzureCliCredential support and AZURE_AI_PROJECT_ENDPOINT fallback
    
    Tests (19 new), Docs updated (AGENTS.md, README.md)
    
    * feat(cu): MIME sniffing, media-aware formatting, unified timeout, vector store expiration
    
    - Add three-layer MIME detection (fast path → filetype binary sniff → filename
      fallback) to handle unreliable upstream MIME types (e.g. mp4 sent as
      application/octet-stream). Adds filetype>=1.2,<2 dependency.
    - Media-aware output formatting: video shows duration/resolution + all fields
      as JSON; audio promotes Summary as prose; document unchanged.
    - Unified timeout for all media types (removed file_search special-case that
      waited indefinitely for video/audio). All files use max_wait with background
      polling fallback.
    - Vector store created with expires_after=1 day as crash safety net.
    - Add 8 MIME sniffing tests (TestMimeSniffing class).
    
    * fix: merge all CU content segments for video/audio analysis
    
    CU's prebuilt-videoSearch and prebuilt-audioSearch analyzers split long
    media files into multiple `contents[]` segments. Previously,
    `_extract_sections()` only read `contents[0]`, causing truncated
    duration, missing transcript, and incomplete fields for any video/audio
    longer than a single scene.
    
    Now iterates all segments and merges:
    - duration: global min(startTimeMs) → max(endTimeMs)
    - markdown: concatenated with `---` separators
    - fields: same-named fields collected into per-segment list
    - metadata (kind, resolution): taken from first segment
    
    Single-segment results (documents, short audio) are unaffected.
    
    Update test fixture to realistic 3-segment video structure and expand
    assertions to verify multi-segment merging. Add documentation for
    multi-segment processing and speaker diarization limitation.
    
    * refactor: improve CU context provider docs and remove ContentLimits
    
    - Improve class docstring: clarify endpoint (Azure AI Foundry URL with
      example), credential (AzureKeyCredential vs Entra ID), and analyzer_id
      (prebuilt/custom with auto-selection behavior and reference links)
    - Add SUPPORTED_MEDIA_TYPES comments explaining MIME-based matching
      behavior and add missing file types per CU service docs
    - Use namespaced logger to align with other packages
    - Remove ContentLimits and related code/tests
    - Rename DEFAULT_MAX_WAIT to DEFAULT_MAX_WAIT_SECONDS for clarity
    
    * feat: support user-provided vector store in FileSearchConfig
    
    - Add vector_store_id field to FileSearchConfig (None = auto-create)
    - Track _owns_vector_store to only delete auto-created stores on close()
    - Remove vector_store_name; use internal _DEFAULT_VECTOR_STORE_NAME
    - Add inline comments for private state fields
    - Document output_sections default in docstring
    - Update AGENTS.md, samples, and tests
    
    * fix: remove ContentLimits from README code block
    
    * refactor: create CU client in __init__ instead of __aenter__
    
    Follow Azure AI Search provider pattern: create the client eagerly in
    __init__, make __aenter__ a no-op. This ensures __aexit__/close() is
    always safe to call and eliminates the _ensure_initialized() workaround.
    
    * docs: add file_search param to class docstring
    
    * feat: introduce FileSearchBackend abstraction for cross-client support
    
    Replace direct OpenAI client usage with FileSearchBackend ABC:
    - OpenAIFileSearchBackend: for OpenAIChatClient (Responses API)
    - FoundryFileSearchBackend: for FoundryChatClient (Azure Foundry)
    - Shared base _OpenAICompatBackend for common vector store CRUD
    
    FileSearchConfig now takes a backend instead of openai_client.
    Factory methods from_openai() and from_foundry() for convenience.
    
    BREAKING: FileSearchConfig(openai_client=...) -> FileSearchConfig.from_openai(...)
    
    * refactor: FileSearchBackend abstraction + caller-owned vector store
    
    * fix: file_search reliability and sample improvements
    
    - Poll vector store indexing (create_and_poll) to ensure file_search
      returns results immediately after upload
    - Set status to failed when vector store upload fails
    - Skip get_analyzed_document tool in file_search mode to prevent
      LLM from bypassing RAG
    - Simplify sample auth: single credential, direct parameters
    - Use from_foundry backend for Foundry project endpoints
    
    * perf: set max_num_results=10 for file_search to reduce token usage
    
    * fix: move import to top of file (E402 lint)
    
    * chore: remove unused imports
    
    * fix: align azure-ai-contentunderstanding with MAF coding conventions
    
    - Add module-level docstrings to __init__.py and _context_provider.py
    - Use Self return type for __aenter__ (with typing_extensions fallback)
    - Use explicit typed params for __aexit__ signature
    - Add sync TokenCredential to AzureCredentialTypes union
    - Pass AGENT_FRAMEWORK_USER_AGENT to ContentUnderstandingClient
    - Remove unused ContentLimits from public API and tests
    - Fix FileSearchConfig tests to match refactored backend API
    - Fix lifecycle tests to match eager client initialization
    
    * refactor: improve CU context provider API surface and fix CI
    
    - Refactor _analyze_file to return DocumentEntry instead of mutating dict
    - Remove TokenCredential from AzureCredentialTypes (fixes mypy/pyright CI)
    - Remove OpenAIFileSearchBackend/FoundryFileSearchBackend from public API
      (internal to FileSearchConfig factory methods)
    - Remove DocumentStatus from public exports (implementation detail)
    - Update file_search comments to reflect backend-agnostic design
    - Add DocumentStatus enum, analysis/upload duration tracking
    - Add combined timeout for CU analysis + vector store upload
    
    * fix: improve file_search samples and move tool guidelines to context provider
    
    - Delete redundant devui_file_search_agent sample (duplicate of azure_openai variant)
    - Move tool usage guidelines from sample agent instructions into context provider
      (extend_instructions in step 6, applied automatically for all file_search users)
    - Fix file_search purpose: use from_foundry() for Azure OpenAI (purpose="assistants")
    - Add filename hint in upload instructions for targeted file_search queries
    - Reduce max_num_results from 10 to 3 in both devui samples
    - Simplify agent instructions in both samples (remove tool-specific guidance)
    
    * feat: improve source_id, integration tests, and content assertions
    
    - Rename DEFAULT_SOURCE_ID to "azure_ai_contentunderstanding" (matches
      azure_ai_search convention)
    - Improve source_id docstring to describe default value
    - Clarify _detect_and_strip_files docstring (CU-supported files)
    - Add invoice.pdf test fixture from Azure CU samples repo
    - Refactor integration tests to use invoice.pdf directly (assert instead
      of skip when fixture missing)
    - Add URI content test (Content.from_uri with external URL)
    - Add "CONTOSO LTD." content assertion to all integration tests
    - Use max_wait=None in integration tests (wait until complete)
    
    * feat: reject duplicate filenames, add integration tests and sample comments
    
    - Reject duplicate document keys in before_run (skip + warn LLM to rename)
    - Update _derive_doc_key docstring to document uniqueness constraint
    - Add unit tests for duplicate filename rejection (cross-turn and same-turn)
    - Add integration test for data URI content (from_uri with base64)
    - Add integration test for background analysis (max_wait timeout + resolve)
    - Add filename recommendation comments to all samples' Content.from_data()
    
    * chore: improve doc key derivation, comments, and README
    
    - Replace hash-based doc key with uuid4 for anonymous uploads (O(1), no payload traversal)
    - Remove hashlib import (no longer needed)
    - Add File Naming section to README (filename importance, duplicate rejection)
    - Improve inline comments (_derive_doc_key, _extract_binary, URL parsing)
    
    * test: strengthen _format_result assertions with exact expected strings
    
    - Replace loose 'in' checks with exact 'assert formatted == expected'
      for both multi-segment and single-segment format tests
    - Add object-type fields (ShippingAddress, Speakers) to test data
      to cover nested dict/list serialization
    - Add position-based ordering assertions to verify structural
      correctness (header -> markdown -> fields across segments)
    
    * refactor: move invoice.pdf to shared sample_assets directory
    
    - Move invoice.pdf from tests/cu/test_data/ to
      python/samples/shared/sample_assets/ as single source of truth
    - Add INVOICE_PDF_PATH constant in test_integration.py pointing
      to the shared location
    - Update document_qa.py, invoice_processing.py, large_doc_file_search.py
      to use invoice.pdf instead of sample.pdf
    
    * refactor: reorganize samples into numbered dirs and simplify auth
    
    - Move script samples into 01-get-started/ with numbered prefixes
      (01_document_qa, 02_multimodal_chat, 03_invoice_processing,
       04_large_doc_file_search)
    - Move devui samples into 02-devui/ with 01-multimodal_agent and
      02-file_search_agent/{azure_openai_backend,foundry_backend}
    - Move invoice.pdf to CU package-local samples/shared/sample_assets/
    - Replace kwargs dicts with direct constructor calls; support both
      API key (AZURE_OPENAI_API_KEY) and AzureCliCredential
    - Update README sample table with new paths
    
    * fix: resolve CI lint errors (D205, RUF001, E501)
    
    - Fix D205: single-line docstring summary for _detect_and_strip_files
    - Fix RUF001: replace EN DASH with HYPHEN-MINUS in segment headers
    - Fix E501: wrap long assertion lines in tests
    - Also includes samples reorg and auth simplification
    
    * refactor: overhaul samples — FoundryChatClient, sessions, remove get_analyzed_document
    
    Samples:
    - Switch all samples from deprecated AzureOpenAIResponsesClient to FoundryChatClient
    - Add 02_multi_turn_session.py showing AgentSession persistence across turns
    - Rewrite 03_multimodal_chat.py with real PDF + audio + video (parallel
      analysis), per-modality follow-ups, cross-document question, elapsed
      time, user prompts, and input token counts
    - Renumber: 02->03 multimodal, 03->04 invoice, 04->05 file_search
    
    Context provider:
    - Remove get_analyzed_document tool -- full content is in conversation
      history via InMemoryHistoryProvider, no retrieval tool needed
    - Remove follow-up turn instructions about tools
    - Only list_documents tool remains (for status queries)
    - Update README to reflect tool removal
    
    * feat: add 05_background_analysis sample and fix 04 session/max_wait
    
    - Add 05_background_analysis.py demonstrating non-blocking CU analysis
      with max_wait=1s, status tracking via list_documents(), and automatic
      background task resolution on subsequent turns
    - Fix 04_invoice_processing.py: add max_wait=None and AgentSession
    - Rename 05→06 large_doc_file_search
    - Update README sample table
    
    * docs: update README and fix sample 06
    
    README:
    - Switch Quick Start from AzureOpenAIResponsesClient to FoundryChatClient
    - Add AgentSession to Quick Start example
    - Fix status values: pending -> analyzing/uploading/ready/failed
    - Fix env var: AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME -> AZURE_OPENAI_DEPLOYMENT_NAME
    - Update samples section with new paths, link to samples/README.md
    - Update multi-segment description to reflect per-segment fields
    
    Sample 06:
    - Fix from_openai -> from_foundry for Azure endpoints
    - Add AgentSession and max_wait=None
    
    * docs: rewrite README — concise format, prerequisites, CU link
    
    * fix: resolve pyright errors in _format_result segment cast
    
    * docs: add numbered section comments and fresh sample output to all samples
    
    - Add numbered section comments (# 1. ..., # 2. ...) per SAMPLE_GUIDELINES
    - Re-run all 6 samples and update expected output with real results
    - Fix duplicate sample output blocks in 04 and 05
    - Update README code example to use public invoice URL
    
    * feat: add load_settings support for env var configuration
    
    - Make endpoint optional in constructor — auto-loads from
      AZURE_CONTENTUNDERSTANDING_ENDPOINT env var via load_settings()
    - Add ContentUnderstandingSettings TypedDict
    - Add env_file_path/env_file_encoding params for .env file support
    - Add 4 unit tests: env var loading, explicit override, missing
      endpoint error, missing credential error
    - Update README with env var auto-resolution docs
    - Follows framework convention used by all other packages
    
    * docs: polish README — fix duplicate env var, add Next steps, service limits link
    
    * chore: trim invoice fixture from 199K to 33 lines
    
    Keep only VendorName, InvoiceTotal, DueDate, InvoiceDate, InvoiceId
    fields and first 500 chars of markdown. Strip spans/source/coordinates.
    Reduces fixture from 6.6MB to 1.2KB.
    
    * feat: per-file analyzer_id override via additional_properties
    
    - Read analyzer_id from Content.additional_properties for per-file override
    - Resolution order: per-file > provider-level > auto-detect by media type
    - Update class docstring documenting filename and analyzer_id properties
    - Update sample 04 to demonstrate per-file override (prebuilt-invoice)
    - Add unit test for per-file analyzer override
    
    * Trim PDF test fixture and clarify unique filename requirement
    
    - Trim analyze_pdf_result.json from 4427 to 23 lines by removing
      pages, words, lines, paragraphs, sections, spans, and source
      fields that are not used by any unit test.
    - Add docstring note that filename must be unique within a session;
      duplicate filenames are rejected and the file will not be analyzed.
    
    * Update python/packages/azure-ai-contentunderstanding/agent_framework_azure_ai_contentunderstanding/_context_provider.py
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * Update python/packages/azure-ai-contentunderstanding/agent_framework_azure_ai_contentunderstanding/_context_provider.py
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * Update python/packages/azure-ai-contentunderstanding/samples/02-devui/02-file_search_agent/azure_openai_backend/agent.py
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * Update python/packages/azure-ai-contentunderstanding/samples/02-devui/01-multimodal_agent/agent.py
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * Update python/packages/azure-ai-contentunderstanding/samples/01-get-started/06_large_doc_file_search.py
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * Fix AGENTS.md to match implementation; remove unused variable in test helper
    
    AGENTS.md:
    - Remove _ensure_initialized() reference (client is created in __init__)
    - Fix multi-segment docs: segments kept as list, not merged into fields
    - Remove get_analyzed_document() reference (only list_documents registered)
    - Update sample names to match current directory structure
    
    test_context_provider.py:
    - Simplify _make_data_uri() — remove unused 'encoded' variable
    
    * Fix premature file_search instruction for background-completed docs
    
    - Change _resolve_pending_tasks() instruction from 'Use file_search'
      to 'being indexed' since the upload hasn't completed yet at that point.
    - Add LLM instruction on upload failure in step 1b so the agent can
      inform the user the document isn't searchable.
    
    * fix: wrap long line in devui agent instructions (E501)
    
    * Fix Copilot review: unused logger, stray code in README, await cancelled tasks
    
    - _file_search.py: Remove unused logger and logging import
    - 01-multimodal_agent/README.md: Remove accidentally pasted Python script
    - _context_provider.py close(): Await cancelled tasks before closing
      client to prevent 'Task destroyed but pending' warnings
    
    * Sanitize doc keys and fix duplicate filename re-injection
    
    - Add _sanitize_doc_key() to strip control characters, collapse
      whitespace, and cap length at 255 chars — prevents prompt injection
      via crafted filenames in extend_instructions() calls.
    - Track accepted doc_keys in step 3 so step 5 only injects content
      for files actually analyzed this turn, not pre-existing duplicates.
    - Soften duplicate upload instruction wording (remove IMPORTANT/caps).
    
    * fix: add type annotation to tasks_to_cancel for pyright
    
    * Move per-session mutable state to state dict for session isolation
    
    Previously _pending_tasks, _pending_uploads, and _uploaded_file_ids
    were stored on self, shared across all sessions. This caused
    cross-session leakage: Session A's background task results could be
    injected into Session B's context.
    
    Now these are stored in the per-session state dict. Global copies
    (_all_pending_tasks, _all_uploaded_file_ids) are kept on self only
    for best-effort cleanup in close().
    
    Add 2 new TestSessionIsolation tests verifying that background tasks
    and resolved content stay within their originating session.
    
    * Remove unused AnalysisSection enum values
    
    Only MARKDOWN and FIELDS are handled by _extract_sections().
    Remove FIELD_GROUNDING, TABLES, PARAGRAPHS, SECTIONS to avoid
    exposing dead options to users.
    
    * Recursively flatten object/array field values for cleaner LLM output
    
    - Use SDK .value property with recursive extraction for object/array fields
    - Object: AmountDue -> {Amount: 610, CurrencyCode: USD} (was raw SDK dict)
    - Array: LineItems -> list of flattened items (was raw SDK list)
    - Update invoice fixture with object/array fields from prebuilt-invoice
    - Add 3 unit tests for object, array, and nested object field extraction
    
    * Preserve sub-field confidence; compare full expected JSON in tests
    
    * Remove incorrect MIME aliases (audio/mp4, video/x-matroska)
    
    * feat: add AnalysisInput, content_range, warnings, and category support
    
    - Use SDK AnalysisInput model instead of raw body dict for begin_analyze
    - Forward content_range from additional_properties to CU (page/time ranges)
    - Extract CU warnings with code/message/target (ODataV4Format) into output
    - Include content-level category from classifier analyzers
    - Add 5 new tests: warnings, category, content_range forwarding
    - Fix pyright with explicit casts; fix en-dash lint (RUF002)
    
    * fix: falsy-0 bug in duration calc; improve test coverage
    
    - Fix start_time_ms=0 treated as falsy by 'or' short-circuit, use
      'is None' checks instead for duration and segment time extraction
    - Update warnings test to use RAI ContentFiltered codes
    - Enrich warnings extraction to include code/message/target (ODataV4Format)
    - Add multi-segment video category test with per-segment assertions
    
    * refactor: split _context_provider.py into focused modules
    
    - Extract _constants.py: SUPPORTED_MEDIA_TYPES, MIME_ALIASES, analyzer maps
    - Extract _detection.py: file detection, MIME sniffing, doc key derivation
    - Extract _extraction.py: result extraction, field flattening, LLM formatting
    - _context_provider.py delegates via thin wrappers (793 lines, was 1255)
    - Update test imports to use _constants.py for SUPPORTED_MEDIA_TYPES
    
    * docs: update AGENTS.md with DocumentStatus, FileSearchBackend, and _file_search.py
    
    * refactor: replace AnalysisSection enum with Literal type for simpler DX
    
    - Remove AnalysisSection(str, Enum) class, replace with Literal["markdown", "fields"] type alias
    - Users can now pass plain strings: output_sections=["markdown"] — no extra import needed
    - AnalysisSection type alias still exported for type annotation use
    - Update all samples, tests, and internal code to use string literals
    - Address PR review feedback (eavanvalkenburg)
    
    * refactor: replace asyncio.Task with continuation tokens for serializable state
    
    - Replace state["_pending_tasks"] (asyncio.Task — not serializable) with
      state["_pending_tokens"] (dict of continuation token strings) so the
      framework can persist session state to disk/storage
    - Resume pending analyses via Azure SDK continuation_token mechanism
    - Fix: resumed pollers have stale cached status (done() always False),
      use asyncio.wait_for(poller.result()) with 10s min timeout instead
    - Remove _background_poll(), _all_pending_tasks, and task cancellation
    - Address PR review feedback (eavanvalkenburg): state must be serializable
    
    * fix: resolve CI lint (RUF052) and mypy (call-overload) errors
    
    * feat: add structured output (Pydantic model) to invoice processing sample
    
    - Use response_format=InvoiceResult for schema-constrained LLM output
    - Use output_sections=["fields"] only (no markdown needed for structured output)
    - Add LowConfidenceField model with confidence values
    - Add comments about prebuilt-invoice extensive schema vs simplified model
    - Address PR review feedback (eavanvalkenburg): use structured response
    
    * fix: use FOUNDRY_PROJECT_ENDPOINT and FOUNDRY_MODEL env vars in all samples
    
    Replace AZURE_AI_PROJECT_ENDPOINT → FOUNDRY_PROJECT_ENDPOINT and
    AZURE_OPENAI_DEPLOYMENT_NAME → FOUNDRY_MODEL across all sample .py and
    README.md files. Address PR review feedback (eavanvalkenburg).
    
    * refactor: remove background_analysis sample, use FoundryChatClient in DevUI
    
    - Remove 05_background_analysis.py (per reviewer feedback — discuss max_wait
      design separately from samples)
    - Renumber 06_large_doc_file_search.py → 05_large_doc_file_search.py
    - Replace AzureOpenAIResponsesClient with FoundryChatClient in all DevUI samples
    - Replace client.as_agent() with Agent(client=client, ...) everywhere
    - Add max_wait comments explaining interactive vs batch usage
    - Update README.md and AGENTS.md
    - Address PR review feedback (eavanvalkenburg)
    
    * fix: vector_stores API moved from beta namespace in OpenAI SDK
    
    * docs: add comments about multi-file support and CU service limits in file_search sample
    
    * fix: broken markdown links after sample removal and renumbering
    
    * fix: migrate BaseContextProvider to ContextProvider (non-deprecated)
    
    * fix: Message(text=) -> Message(contents=[]) for API compatibility
    
    * Inline _constants.py into consuming modules
    
    Remove _constants.py and move constants to where they are used:
    - SUPPORTED_MEDIA_TYPES, MIME_ALIASES → _detection.py
    - MEDIA_TYPE_ANALYZER_MAP, DEFAULT_ANALYZER → _context_provider.py
    
    Addresses review feedback to reduce file count.
    
    * Mark package as alpha per package management skill
    
    - Version: 1.0.0b260401 → 1.0.0a260401
    - Classifier: Development Status 4 - Beta → 3 - Alpha
    - Add to PACKAGE_STATUS.md as alpha
    
    Follows the alpha package checklist from python-package-management skill.
    
    * Replace extend_instructions with extend_messages for status notifications
    
    Status/error/result notifications now use extend_messages (conversation
    context) instead of extend_instructions (system prompt). This avoids
    system prompt bloat and keeps behavioral directives separate from
    event notifications.
    
    - 11 extend_instructions calls → extend_messages (role='user')
    - 1 extend_instructions retained: tool usage guidelines (behavioral)
    - 6 test assertions updated to check context_messages
    
    All 84 unit tests + 5 live integration tests pass.
    
    * Fix lint: E402 import order, ISC004 implicit string concatenation
    
    - Move constants after all imports to fix E402
    - Wrap multi-line strings in parentheses inside contents=[] to fix ISC004
    
    * Fix lint: remove unused json import in invoice sample
    
    * Fix CI: apply ruff format + fix E501 line length after reformatting
    
    ruff format expands Message() calls to multi-line, pushing string
    indentation deeper. Break long strings to fit within 120 char limit
    after formatting. Also removes unused json import in sample.
    
    * Address review feedback: keyword-only args, accept pre-built client, remove wrappers
    
    - All __init__ args now keyword-only (matches FoundryChatClient pattern)
    - New 'client' param accepts pre-built ContentUnderstandingClient
    - core dep bound: >=1.0.0rc5 → >=1.0.0,<2
    - Self import moved after local imports
    - Removed 9 static method wrappers; callsites use module functions directly
    - Tests updated to import derive_doc_key and format_result directly
    
    * fix: remove duplicate ContentUnderstandingClient instantiation
    
    The client was being created twice — once inside the if/else block and
    again unconditionally after it. The second instantiation overwrote the
    pre-built client path and failed type checking when credential was None.
    
    * rename: azure-ai-contentunderstanding → azure-contentunderstanding
    
    Package: agent-framework-azure-ai-contentunderstanding → agent-framework-azure-contentunderstanding
    Module: agent_framework_azure_ai_contentunderstanding → agent_framework_azure_contentunderstanding
    Directory: packages/azure-ai-contentunderstanding → packages/azure-contentunderstanding
    
    Per agreement with PM and MAF team to drop 'AI' from the package name.
    
    * feat: add ContentUnderstanding re-export to agent_framework.foundry namespace
    
    Enables: from agent_framework.foundry import ContentUnderstandingContextProvider
    
    Exports: ContentUnderstandingContextProvider, FileSearchConfig,
    FileSearchBackend, AnalysisSection, DocumentStatus
    
    Updates all samples and README to use the foundry namespace import.
    
    * fix: add missing copyright headers to standalone sample scripts
    
    * chore: remove .vscode/settings.json and add to .gitignore
    
    * refactor: reuse FoundryChatClient.client for vector store ops in file_search sample
    
    Address review feedback from TaoChenOSU:
    - 05_large_doc_file_search.py: use client.client instead of manually
      constructing AsyncAzureOpenAI; remove openai dependency
    - azure_openai_backend/agent.py: import reorder only (AIProjectClient
      kept — required for sync vector store creation in DevUI)
    
    * fix: skip closing client when caller passes pre-built client
    
    When a ContentUnderstandingClient is passed via client=, the caller
    owns its lifecycle. Added _owns_client flag so close() only closes
    the client when we created it internally.
    
    ---------
    
    Co-authored-by: yungshinlin <yungshin@msn.com>
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
  • Python: bump package versions for 1.2.1 release (#5536)
    * Python: bump package versions for 1.2.1 release
    
    PATCH bump (1.2.0 -> 1.2.1) for the released cohort. The release window
    covers two PRs, no new public APIs:
    
    - agent-framework-core: prevent inner_exception from being lost in
      AgentFrameworkException (#5167)
    - samples: add requirements.txt and .env.example to the a2a/ hosting
      sample for pip-based setup (#5510)
    
    Per lockstep convention, all 21 beta packages stamp 1.0.0b260428 and all
    3 alpha packages stamp 1.0.0a260428, regardless of per-package code
    churn. Every non-core package floor on agent-framework-core is raised to
    >=1.2.1 to keep cohort signaling consistent. Date stamp reflects the
    local (Asia) cut date 2026-04-28.
    
    * Python: silence pyright unknown-type warnings in hosted-env detection
    
    `azure.ai.agentserver.core` is probed at runtime via `importlib.util.find_spec`
    and is not a declared dependency. The existing `# pyright: ignore[reportMissingImports]`
    suppresses the missing-import warning, but at `lowest-direct` resolution pyright
    still reports the imported symbol (`AgentConfig`) and its members (`from_env`,
    `is_hosted`) as unknown, breaking `validate-dependency-bounds-test` for
    `packages/core`.
    
    Extend the existing ignore to cover `reportUnknownVariableType` on the import
    and `reportUnknownMemberType` on the call site so the bounds check returns to
    green. Behavior is unchanged.
    
    Latent since #5455 (shipped in 1.2.0).
    
    * Python: raise agent-framework-gemini lower bound to google-genai>=1.65.0
    
    The Gemini chat client references several `google.genai.types` symbols
    (`FileSearch`, `ThinkingLevel`, `SearchTypes`, `McpServer`,
    `StreamableHttpTransport`, plus call-site keyword args `mcp_servers` and
    `search_types`) that are not present at the lower bound of `google-genai>=1.0.0`.
    At `lowest-direct` resolution this caused `validate-dependency-bounds-test` to
    fail for `packages/gemini` with eleven `reportAttributeAccessIssue` /
    `reportUnknownVariableType` errors.
    
    Walking the upstream `google.genai.types` API:
    - `GoogleMaps`, `AuthConfig`: present from 1.40.0
    - `FileSearch`: introduced in 1.49.0
    - `ThinkingLevel`: introduced in 1.55.0
    - `SearchTypes`, `McpServer`, `StreamableHttpTransport`: introduced in 1.65.0
    
    Bump the lower bound to 1.65.0 — the minimum version that exposes every symbol
    the package actually uses. Keep the `<2.0.0` upper cap unchanged. With this
    bump `validate-dependency-bounds-test` passes for both lower and upper
    resolution scenarios across all 27 workspace packages.
    
    Latent since #4847 (Gemini package introduction in 1.1.0); aggravated by
    subsequent feature additions that pulled in newer `types.*` symbols.
    
    * Python: add dependabot bumps to 1.2.1 CHANGELOG
    
    Catalog the 15 dependabot dependency updates that merged on `upstream/main`
    between python-1.2.0 and the 1.2.1 cut window under a new Changed section:
    
    - Workspace dev/runtime deps: `rich`, `prek`, `python-multipart`, `pyasn1`,
      `pytest` (ag-ui, devui, lab), `uv` (lab)
    - Frontend deps: `vite` (devui, chatkit), `postcss` (devui, chatkit, handoff),
      `picomatch` (devui, handoff)
    
    CHANGELOG-only — no source or pyproject.toml changes. PRs themselves merged
    upstream independently of this release branch and will be brought in via the
    PR merge.
  • Python: Bump prek from 0.3.8 to 0.3.9 in /python (#5228)
    * Bump prek from 0.3.8 to 0.3.9 in /python
    
    Bumps [prek](https://github.com/j178/prek) from 0.3.8 to 0.3.9.
    - [Release notes](https://github.com/j178/prek/releases)
    - [Changelog](https://github.com/j178/prek/blob/master/CHANGELOG.md)
    - [Commits](https://github.com/j178/prek/compare/v0.3.8...v0.3.9)
    
    ---
    updated-dependencies:
    - dependency-name: prek
      dependency-version: 0.3.9
      dependency-type: direct:development
      update-type: version-update:semver-patch
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    
    * Fix CI: bump prek to 0.3.9 in lab package and update uv.lock
    
    Agent-Logs-Url: https://github.com/microsoft/agent-framework/sessions/f17751e5-c5a8-4d42-9555-6bf708a2ef47
    
    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>
  • Bump vite in /python/samples/05-end-to-end/chatkit-integration/frontend (#5126)
    Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 7.1.12 to 7.3.2.
    - [Release notes](https://github.com/vitejs/vite/releases)
    - [Changelog](https://github.com/vitejs/vite/blob/v7.3.2/packages/vite/CHANGELOG.md)
    - [Commits](https://github.com/vitejs/vite/commits/v7.3.2/packages/vite)
    
    ---
    updated-dependencies:
    - dependency-name: vite
      dependency-version: 7.3.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>
  • Bump vite from 7.1.12 to 7.3.2 in /python/packages/devui/frontend (#5127)
    Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 7.1.12 to 7.3.2.
    - [Release notes](https://github.com/vitejs/vite/releases)
    - [Changelog](https://github.com/vitejs/vite/blob/v7.3.2/packages/vite/CHANGELOG.md)
    - [Commits](https://github.com/vitejs/vite/commits/v7.3.2/packages/vite)
    
    ---
    updated-dependencies:
    - dependency-name: vite
      dependency-version: 7.3.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>
  • Bump picomatch (#4936)
    Bumps [picomatch](https://github.com/micromatch/picomatch) from 4.0.3 to 4.0.4.
    - [Release notes](https://github.com/micromatch/picomatch/releases)
    - [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md)
    - [Commits](https://github.com/micromatch/picomatch/compare/4.0.3...4.0.4)
    
    ---
    updated-dependencies:
    - dependency-name: picomatch
      dependency-version: 4.0.4
      dependency-type: indirect
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Update rich requirement in /python (#5227)
    Updates the requirements on [rich](https://github.com/Textualize/rich) to permit the latest version.
    - [Release notes](https://github.com/Textualize/rich/releases)
    - [Changelog](https://github.com/Textualize/rich/blob/master/CHANGELOG.md)
    - [Commits](https://github.com/Textualize/rich/compare/v13.7.1...v15.0.0)
    
    ---
    updated-dependencies:
    - dependency-name: rich
      dependency-version: 15.0.0
      dependency-type: direct:development
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Bump python-multipart from 0.0.22 to 0.0.26 in /python (#5286)
    Bumps [python-multipart](https://github.com/Kludex/python-multipart) from 0.0.22 to 0.0.26.
    - [Release notes](https://github.com/Kludex/python-multipart/releases)
    - [Changelog](https://github.com/Kludex/python-multipart/blob/master/CHANGELOG.md)
    - [Commits](https://github.com/Kludex/python-multipart/compare/0.0.22...0.0.26)
    
    ---
    updated-dependencies:
    - dependency-name: python-multipart
      dependency-version: 0.0.26
      dependency-type: indirect
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Python: Bump uv from 0.11.3 to 0.11.6 in /python/packages/lab (#5469)
    * Bump uv from 0.11.3 to 0.11.6 in /python/packages/lab
    
    Bumps [uv](https://github.com/astral-sh/uv) from 0.11.3 to 0.11.6.
    - [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.3...0.11.6)
    
    ---
    updated-dependencies:
    - dependency-name: uv
      dependency-version: 0.11.6
      dependency-type: direct:development
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    
    * Fix CI: update uv from 0.11.3 to 0.11.6 in python/pyproject.toml and regenerate uv.lock
    
    Agent-Logs-Url: https://github.com/microsoft/agent-framework/sessions/a1a7c648-b26f-44e7-bace-d56ed8489053
    
    Co-authored-by: moonbox3 <35585003+moonbox3@users.noreply.github.com>
    
    * Fix code quality CI: update uv-pre-commit rev from 0.11.3 to 0.11.6 in .pre-commit-config.yaml
    
    Agent-Logs-Url: https://github.com/microsoft/agent-framework/sessions/cdfdd211-9f1e-4570-bc7c-86fd15240e91
    
    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>
  • Python: Bump pytest from 9.0.2 to 9.0.3 in /python/packages/lab (#5470)
    * Bump pytest from 9.0.2 to 9.0.3 in /python/packages/lab
    
    Bumps [pytest](https://github.com/pytest-dev/pytest) from 9.0.2 to 9.0.3.
    - [Release notes](https://github.com/pytest-dev/pytest/releases)
    - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
    - [Commits](https://github.com/pytest-dev/pytest/compare/9.0.2...9.0.3)
    
    ---
    updated-dependencies:
    - dependency-name: pytest
      dependency-version: 9.0.3
      dependency-type: direct:development
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    
    * Update pytest from 9.0.2 to 9.0.3 across all workspace packages
    
    Fix dependency conflict: agent-framework workspace packages were pinning
    pytest==9.0.2 while agent-framework-lab required pytest==9.0.3, causing
    uv dependency resolution to fail. Updated all pyproject.toml files and
    regenerated uv.lock to use pytest==9.0.3 consistently.
    
    Agent-Logs-Url: https://github.com/microsoft/agent-framework/sessions/d274f7c5-b5ed-4b18-8eab-4db3cfd9d1bf
    
    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>
  • Bump postcss from 8.5.6 to 8.5.10 in /python/packages/devui/frontend (#5484)
    Bumps [postcss](https://github.com/postcss/postcss) from 8.5.6 to 8.5.10.
    - [Release notes](https://github.com/postcss/postcss/releases)
    - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
    - [Commits](https://github.com/postcss/postcss/compare/8.5.6...8.5.10)
    
    ---
    updated-dependencies:
    - dependency-name: postcss
      dependency-version: 8.5.10
      dependency-type: indirect
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Bump postcss (#5491)
    Bumps [postcss](https://github.com/postcss/postcss) from 8.5.6 to 8.5.10.
    - [Release notes](https://github.com/postcss/postcss/releases)
    - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
    - [Commits](https://github.com/postcss/postcss/compare/8.5.6...8.5.10)
    
    ---
    updated-dependencies:
    - dependency-name: postcss
      dependency-version: 8.5.10
      dependency-type: indirect
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Bump postcss (#5527)
    Bumps [postcss](https://github.com/postcss/postcss) from 8.5.6 to 8.5.12.
    - [Release notes](https://github.com/postcss/postcss/releases)
    - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
    - [Commits](https://github.com/postcss/postcss/compare/8.5.6...8.5.12)
    
    ---
    updated-dependencies:
    - dependency-name: postcss
      dependency-version: 8.5.12
      dependency-type: indirect
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Bump picomatch in /python/packages/devui/frontend (#4921)
    Bumps  and [picomatch](https://github.com/micromatch/picomatch). These dependencies needed to be updated together.
    
    Updates `picomatch` from 4.0.3 to 4.0.4
    - [Release notes](https://github.com/micromatch/picomatch/releases)
    - [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md)
    - [Commits](https://github.com/micromatch/picomatch/compare/4.0.3...4.0.4)
    
    Updates `picomatch` from 2.3.1 to 2.3.2
    - [Release notes](https://github.com/micromatch/picomatch/releases)
    - [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md)
    - [Commits](https://github.com/micromatch/picomatch/compare/4.0.3...4.0.4)
    
    ---
    updated-dependencies:
    - dependency-name: picomatch
      dependency-version: 4.0.4
      dependency-type: indirect
    - dependency-name: picomatch
      dependency-version: 2.3.2
      dependency-type: indirect
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Python: Update hosting agent samples + fixes (#5485)
    * Update foundry hosting samples
    
    * Add file data type support
    
    * Fix file content and add more tests
    
    * Fix README
    
    * Address comments
    
    * Fix int tests
    
    * remove temp
  • Python: Add requirements.txt and .env.example to the a2a/ sample for pip-based setup (#5510)
    * Add requirements.txt and .env.example to a2a sample
    
    Beginners following the a2a/ sample had no pip-based install path:
    the directory lacked requirements.txt and .env.example, unlike every
    other 04-hosting/ sample.
    
    - Add requirements.txt with editable local package paths matching the
      pattern used in azure_functions/ and similar hosting samples
    - Add .env.example documenting FOUNDRY_PROJECT_ENDPOINT, FOUNDRY_MODEL,
      and A2A_AGENT_HOST
    - Update README Quick Start to cover both pip (.venv) and uv workflows
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: Add `requirements.txt` and `.env.example` to the `a2a/` sample for pip-based setup
    
    Fixes #5395
    
    * fix(a2a-sample): address PR review feedback for issue #5395
    
    - Remove 'from repo root' wording from Option B uv heading in README
      to avoid contradicting the 'run from this directory' instruction
    - Fix A2A_AGENT_HOST default in .env.example from 5001 to 5000 to match
      function-tools flow; add clarifying comments about port usage
    - Add note for pip users explaining they can replace 'uv run python'
      with 'python' once the virtual environment is activated
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address review feedback for #5395: Python: [Samples][Python] a2a/ sample missing requirements.txt — beginners cannot install dependencies
    
    ---------
    
    Co-authored-by: Copilot <copilot@github.com>
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: fix: prevent inner_exception from being lost in AgentFrameworkException (#5167)
    * fix: prevent inner_exception from being lost in AgentFrameworkException
    
    The __init__ method unconditionally called super().__init__() after
    the conditional call with inner_exception, effectively overwriting the
    exception args and losing the inner_exception reference.
    
    Add else branch so super().__init__() is only called once with the
    correct arguments.
    
    Fixes #5155
    
    Signed-off-by: bahtya <bahtyar153@qq.com>
    
    * test: add explicit tests for AgentFrameworkException inner_exception handling
    
    - test_exception_with_inner_exception: verifies args include inner exception
    - test_exception_without_inner_exception: verifies args only contain message
    - test_exception_inner_exception_none_explicit: verifies explicit None
    
    Covers both branches of the if/else in __init__.
    
    * fix: export AgentFrameworkException from package
    
    Bahtya
    
    ---------
    
    Signed-off-by: bahtya <bahtyar153@qq.com>
  • Python: Bump Python package versions for 1.2.0 release (#5468)
    * Bump Python package versions for 1.2.0 release
    
    Released tier bumps 1.1.1 -> 1.2.0 (core, openai, foundry, root) to
    reflect additive public APIs landed since 1.1.0: functional workflow API
    (#4238) and FunctionTool SKIP_PARSING sentinel (#5424). All beta packages
    stamped 1.0.0b260424, alpha packages 1.0.0a260424. All 26 non-core
    agent-framework-core floors raised to >=1.2.0,<2. CHANGELOG consolidates
    the never-tagged 1.1.1 entries with the post-merge additions into [1.2.0].
    
    * Update CHANGELOG footer links for 1.2.0
    
    Advance [Unreleased] comparison base from python-1.1.0 to python-1.2.0
    and add a [1.2.0] reference link comparing python-1.1.0...python-1.2.0
    so the heading links resolve correctly.
    
    * Fix CHANGELOG: restore [1.1.1] section and add proper [1.2.0]
    
    Previous commit incorrectly renamed the [1.1.1] header to [1.2.0], which
    wiped the historical 1.1.1 entries and wrongly attributed them to 1.2.0.
    This restores [1.1.1] to its origin/main content and adds a new [1.2.0]
    section above containing only the commits in python-1.1.1..HEAD:
    
    - #4238 functional workflow API
    - #5142 GitHub Copilot OpenTelemetry
    - #2403 A2A bridge support
    - #5070 oauth_consent_request events in Foundry clients
    - #5447 FoundryAgent hosted agent sessions
    - #5459 hosting server dependency upgrade + types
    - #5389 AG-UI reasoning/multimodal parsing fix
    - #5440 stop [TOOLBOXES] warning spam
    - #5455 user agent prefix fix
    
    Also corrects the [1.2.0] compare base to python-1.1.1 (not 1.1.0) and
    adds the missing [1.1.1] reference link.
  • Python: Surface oauth_consent_request events from Responses API in Foundry clients (#5070)
    * Fix Foundry clients not surfacing oauth_consent_request events (#5054)
    
    Override _parse_chunk_from_openai in both RawFoundryChatClient and
    RawFoundryAgentChatClient to intercept response.output_item.added
    events with item.type == 'oauth_consent_request'. The consent link
    is validated (HTTPS required) and converted to
    Content.from_oauth_consent_request, which the AG-UI layer already
    knows how to emit as a CUSTOM event.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review feedback for #5054 OAuth consent parsing
    
    - Extract shared helper (try_parse_oauth_consent_event) to avoid
      duplicated logic between RawFoundryChatClient and
      RawFoundryAgentChatClient
    - Use urllib.parse.urlparse() for HTTPS validation instead of
      case-sensitive startswith check
    - Sanitize log messages to avoid leaking consent_link tokens;
      log only item id
    - Add model=self.model to ChatResponseUpdate to match parent behavior
    - Add assertions on role, raw_representation, and model in happy-path
      tests
    - Add test for empty-string consent_link
    - Add test verifying non-oauth events delegate to super()
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Handle response.oauth_consent_requested top-level event (#5054)
    
    Add support for the top-level response.oauth_consent_requested stream
    event in addition to the response.output_item.added variant. The
    service may emit either form; handle both so the consent link is
    reliably surfaced.
    
    Extract _validate_consent_link helper within _oauth_helpers.py to
    reduce nesting.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address review feedback for #5054: Python: [Bug]: `FoundryAgent` (Responses API) Does Not Surface `oauth_consent_request` as a CUSTOM AG-UI Event
    
    * Address review feedback: defensive getattr and dedicated helper tests (#5054)
    
    - Use getattr(event, 'type', None) in try_parse_oauth_consent_event
      for defensive access against malformed events without a type attribute
    - Add test_oauth_helpers.py with unit tests for _validate_consent_link
      and try_parse_oauth_consent_event covering edge cases:
      - HTTPS URL with empty netloc (https:///path)
      - Warning log messages for rejected consent links
      - Event objects missing 'type' attribute
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address review feedback for #5054: Python: [Bug]: `FoundryAgent` (Responses API) Does Not Surface `oauth_consent_request` as a CUSTOM AG-UI Event
    
    * Fix mypy: match _parse_chunk_from_openai signature with superclass
    
    Add seen_reasoning_delta_item_ids parameter to _parse_chunk_from_openai
    overrides in both RawFoundryChatClient and RawFoundryAgentChatClient to
    match the updated superclass signature on main. Update super() calls and
    test assertions accordingly.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <copilot@github.com>
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    Co-authored-by: Evan Mattson <evan.mattson@microsoft.com>
  • Python: (core): Add functional workflow API (#4238)
    * Add functional workflow api
    
    * cleanup
    
    * More cleanup
    
    * address copilot feedback
    
    * Address PR feedbacK
    
    * updates
    
    * PR feedback
    
    * Address review comments on functional workflow samples
    
    - Swap 05/06 get-started samples: agent workflow first (motivates
      why workflows exist), simple text workflow second
    - Rename text_pipeline → text_workflow, poem_pipeline → poem_workflow
    - Add @step to agent workflow sample (05) to demonstrate caching
    - Switch agent samples to AzureOpenAIResponsesClient with Foundry
    - Remove .as_agent() from agent_integration.py to focus on the key
      difference between inline agent calls vs @step-cached calls
    - Add commented-out Agent.run example in hitl_review.py
    - Add clarifying comment in _functional.py that event streaming is
      buffered (not true per-token streaming)
    - Add naive_group_chat.py functional sample: round-robin group chat
      as a plain Python loop
    - Update READMEs to reflect new file names and group chat sample
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix pyright type errors
    
    * Address PR review comments on functional workflow API
    
    1. Allow request_info inside @step: Auto-inject RunContext into step
       functions that declare a RunContext parameter (by type or name 'ctx'),
       and expose get_run_context() for programmatic access.
    
    2. Handle None responses: Log a warning when a response value is None,
       and document the behavior in request_info docstring.
    
    3. Add executor_bypassed event type: Replace executor_invoked +
       executor_completed with a single executor_bypassed event when a step
       replays from cache, making cached vs live execution explicit.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add regression tests for PR review comments on functional workflow API
    
    The three review comments (request_info in @step, None response handling,
    executor_bypassed event type) were already addressed in 7da7db4e. This
    commit adds cross-cutting regression tests that exercise the interactions
    between these features:
    
    - HITL in step with caching: preceding step bypassed on resume
    - Full checkpoint lifecycle with HITL step (interrupt -> resume -> restore)
    - None response inside step-level request_info logs warning
    - WorkflowInterrupted from step does not emit executor_failed
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR #4238 review comments on functional workflow API
    
    Comment 1 (request_info in @step): Already supported. Added comment in
    StepWrapper.__call__ explaining why WorkflowInterrupted (BaseException)
    safely bypasses the except Exception handler.
    
    Comment 2 (None response): Added docstring to _get_response clarifying
    the (found, value) return tuple semantics and None handling.
    
    Comment 3 (bypass event type): executor_bypassed is already a dedicated
    event type in WorkflowEventType. Updated comment at the bypass site to
    make the deliberate event type choice explicit.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add experimental API warnings to functional workflow module
    
    Mark all public classes and decorators (workflow, step, RunContext,
    FunctionalWorkflow, StepWrapper, FunctionalWorkflowAgent) as
    experimental and subject to change or removal.
    
    * Address PR #4238 review comments from @eavanvalkenburg
    
    - RunContext docstring leads with purpose (opt-in handle for HITL,
      custom events, state) so readers importing it from the public surface
      understand its role before the mechanics (#2993513452).
    - Rename `06_first_functional_workflow.py` to
      `06_functional_workflow_basics.py`; the previous filename was
      confusing since it followed `05_functional_workflow_with_agents.py`
      (#2993531979).
    - Simplify `05_functional_workflow_with_agents.py` to call agents
      directly without a @step wrapper; the step-vs-no-step contrast lives
      in `03-workflows/functional/agent_integration.py`, keeping the
      get-started sample minimal (#2993525532).
    - Switch functional samples to `FoundryChatClient` for consistency with
      the rest of 01-get-started and 03-workflows (follow-up on #2876988570).
    - Use walrus in `hitl_review.py` final-state assertion (#2993572182).
    - Add expected-output block to `basic_streaming_pipeline.py` (#2993557609).
    - Clarify in `parallel_pipeline.py` that `@step` composes with
      `asyncio.gather` (#2993597282).
    - `naive_group_chat.py` threads `list[Message]` between turns instead
      of stringifying the transcript, preserving role/authorship (#2993583231).
    
    Drive-by: pre-commit hook sorts an unrelated import block in
    `samples/04-hosting/foundry-hosted-agents/responses/02_local_tools/main.py`.
    
    * Fix 10 functional-workflow API bugs from /ultrareview pass
    
    - bug_001: `ctx.request_info()` without an explicit `request_id` now derives
      a deterministic `auto::<index>` id from the call-counter, so HITL resume
      works correctly on the documented default path.  A uuid was regenerated on
      every replay, making resume impossible.
    
    - bug_002: `StepWrapper.__call__` no longer deepcopies arguments on the
      cache-hit replay branch.  The copy is only performed on the live-execution
      path (for the event log) and falls back to the original mapping if deepcopy
      fails, so steps whose args aren't deepcopyable (locks, sockets, sessions)
      can still resume from checkpoint.
    
    - bug_007: `_set_responses` now prunes each resolved `request_id` from
      `_pending_requests`, and the cache-hit branch in `request_info` does the
      same.  Previously, answered requests were re-serialized into every
      subsequent checkpoint and the final checkpoint falsely claimed pending
      requests even after the workflow completed.
    
    - bug_008: `_compute_signature_hash` now mixes the function's `co_code` and
      `co_names` into the checkpoint signature, so changes to the workflow body
      invalidate older checkpoints even when steps are accessed via module /
      class attributes (which `_discover_step_names` can't see statically).
      `RunContext._record_observed_step` records observed step names for
      diagnostics.
    
    - bug_010: `FunctionalWorkflow.run()` docstring corrected — says "at least
      one of message/responses/checkpoint_id" and explicitly notes `responses`
      may be combined with `checkpoint_id` (the validator already allowed this).
    
    - bug_013: `FunctionalWorkflowAgent` now surfaces `request_info` events as
      `FunctionApprovalRequestContent` items (mirroring graph `WorkflowAgent`),
      threads `responses=` and `checkpoint_id=` through to the underlying
      workflow, and exposes `pending_requests`.  Previously `.as_agent()`
      returned empty `AgentResponse` for HITL workflows — effectively unusable.
    
    - bug_014: `FunctionalWorkflow` now clears `_last_message`,
      `_last_step_cache`, and `_last_pending_request_ids` on clean completion.
      `run()` validates that `responses=` keys intersect the currently-pending
      request set (or raises with a clear error) instead of silently replaying
      against stale singleton state from a prior run.
    
    - bug_015: `FunctionalWorkflow.as_agent` signature now matches graph
      `Workflow.as_agent`: accepts `name`, `description`, `context_providers`,
      and `**kwargs`.  `FunctionalWorkflowAgent` stores the overrides.
    
    - bug_017: `RunContext.set_state` raises `ValueError` for underscore-
      prefixed keys (the framework's `_step_cache` / `_original_message` keys
      would silently clobber user state on checkpoint save and user
      underscore-prefixed state was dropped on restore).  Docstring documents
      the reserved prefix.
    
    - merged_bug_003: Workflow function arity is validated at decoration time.
      Multiple non-ctx parameters raise `ValueError` immediately (previously
      every arg past the first was silently dropped at call time).  Passing a
      non-None `message` to a ctx-only workflow raises `ValueError` instead of
      silently discarding the message.
    
    Test coverage: +18 regression tests covering every fix.  Full workflow
    suite now 766 passed, 1 skipped, 2 xfailed; full core suite 2338 passed.
    
    * Deslop functional.py fix commit
    
    - Remove dead instrumentation added in the prior commit that was never
      consumed: `RunContext._observed_step_names`,
      `RunContext._record_observed_step`, `FunctionalWorkflow._runtime_step_names`,
      and `FunctionalWorkflowAgent._extra_kwargs`.  The signature hash relies on
      `co_code` alone, which covers the attribute-access case without the
      collection-scaffolding.
    - Trim over-explanatory comments that restated what the code does or what
      it no longer does.  Keep only the comments that answer "why" for the
      non-obvious bits (deterministic id contract, defensive deepcopy, stale
      replay guard).
    - Compress the `_compute_signature_hash` and FunctionalWorkflow `__init__`
      block docstrings without losing the user-facing reasoning.
    
    Net -49 lines.  Regression lock preserved (766 passed, 1 skipped, 2 xfailed).
    
    * Fix functional workflow review feedback
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    Co-authored-by: Copilot <copilot@github.com>
  • Python: update FoundryAgent for hosted agent sessions (#5447)
    * fixes to FoundryAgent to connect to new hosted agents
    
    Co-authored-by: Copilot <copilot@github.com>
    
    * fix mypy
    
    Co-authored-by: Copilot <copilot@github.com>
    
    * Python: remove Foundry service session helpers
    
    Remove the public hosted-agent service session CRUD helpers from FoundryAgent and drop the related feature-stage inventory entry.
    
    Update the hosted-agent sample to create and delete service sessions directly through the preview AIProjectClient APIs, and tighten a few test harnesses surfaced by full workspace validation.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix from merge
    
    * fix hosted env detection
    
    Co-authored-by: Copilot <copilot@github.com>
    
    * reverted sample update
    
    * fix tests and code
    
    Co-authored-by: Copilot <copilot@github.com>
    
    * remove aenter
    
    * skipping some tests
    
    Co-authored-by: Copilot <copilot@github.com>
    
    ---------
    
    Co-authored-by: Copilot <copilot@github.com>
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Add OpenTelemetry integration for GitHubCopilotAgent (#5142)
    * Python: Add OpenTelemetry integration for GitHubCopilotAgent
    
    - Split GitHubCopilotAgent into RawGitHubCopilotAgent (core, no OTel) and
      GitHubCopilotAgent(AgentTelemetryLayer, RawGitHubCopilotAgent) with tracing
    - Add default_options property to expose model for span attributes
    - Export RawGitHubCopilotAgent from all public namespaces
    - Add github_copilot_with_observability.py sample and update README
    
    * Python: Fix OTEL_SERVICE_NAME default in GitHub Copilot README
    
    Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
    
    * Python: Add unit tests for RawGitHubCopilotAgent.default_options property
    
    * Python: Address review feedback on GitHubCopilotAgent OTel integration
    
    - Add middleware param to GitHubCopilotAgent.run() overloads so per-call
      middleware is explicitly forwarded through AgentTelemetryLayer
    - Remove github_copilot_with_observability.py sample per feedback; replace
      with inline snippet + link to observability samples in README
    
    * Python: Address review feedback on log_level and session kwargs typing
    
    - Add middleware param to RawGitHubCopilotAgent.run() overloads for interface
      compatibility with AgentTelemetryLayer
    - Fix import in README observability snippet to use agent_framework.github
    
    * Python: Add AgentMiddlewareLayer to GitHubCopilotAgent MRO
    
    Follow FoundryAgent pattern: AgentMiddlewareLayer runs outside the telemetry
    span so middleware execution time is not captured in traces. Overloads removed
    as AgentMiddlewareLayer.run() handles dispatch via MRO.
    
    * Python: Add explicit __init__ to GitHubCopilotAgent for auto-complete and docstrings
    
    * Python: Address review feedback on middleware warning and test assertions
    
    - Add assert "timeout" not in opts to test_default_options_includes_model_for_telemetry
      to document the intentional asymmetry where timeout is extracted into _settings
      and not returned in default_options.
    - Replace silent del middleware with a logged warning when per-run middleware is
      passed to RawGitHubCopilotAgent, making it clear that the GitHub Copilot SDK
      handles tool execution internally and chat/function middleware cannot be injected.
    
    * Python: Use Self for __aenter__ return type in RawGitHubCopilotAgent
    
    Address review feedback: use typing.Self (3.11+) / typing_extensions.Self
    (3.10) for __aenter__ so subclasses like GitHubCopilotAgent get the correct
    return type from async context manager usage.
    
    ---------
    
    Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
  • Python: feat: Add Agent Framework to A2A bridge support (#2403)
    * feat: Add Agent Framework to A2A bridge support
    
    - Implement A2A event adapter for converting agent messages to A2A protocol
    - Add A2A execution context for managing agent execution state
    - Implement A2A executor for running agents in A2A environment
    - Add comprehensive unit tests for event adapter, execution context, and executor
    - Update agent framework core A2A module exports and type stubs
    - Integrate thread management utilities for async execution
    - Add getting started sample for A2A agent framework integration
    - Update dependencies in uv.lock
    
    This integration enables agent framework agents to communicate and execute within the A2A (Agent to Agent) infrastructure.
    
    * fix: Update references from agent_thread_storage to _agent_thread_storage in A2A executor tests
    
    * Refactor A2A agent framework and improve code structure
    
    - Reordered imports in various files for consistency and clarity.
    - Updated `__all__` definitions to maintain a consistent order across modules.
    - Simplified method signatures by removing unnecessary line breaks.
    - Enhanced readability by adjusting formatting in several sections.
    - Removed redundant comments and example scenarios in the execution context.
    - Improved handling of agent messages in the event adapter.
    - Added type hints for better clarity and type checking.
    - Cleaned up test cases for better organization and readability.
    
    * fix: Lint fix new line added
    
    * test: Add unit tests for AgentThreadStorage and InMemoryAgentThreadStorage
    
    * refactor: Update type hints to use new syntax for Union and List
    
    * fix: Validate RequestContext for context_id and message before execution
    
    * Refactor tests and remove A2aExecutionContext references
    
    - Deleted the test file for A2aExecutionContext as it is no longer needed.
    - Updated A2aExecutor tests to remove dependencies on A2aExecutionContext and adjusted method calls accordingly.
    - Modified event adapter tests to use ChatMessage instead of AgentRunResponseUpdate.
    - Removed A2aExecutionContext from imports in agent_framework.a2a module and updated type hints accordingly.
    
    * Refactor A2AExecutor tests and remove event adapter
    
    - Updated test cases to use A2AExecutor instead of A2aExecutor for consistency.
    - Removed mock_event_adapter fixture and related tests as A2aEventAdapter is deprecated.
    - Consolidated event handling tests into TestA2AExecutorEventAdapter.
    - Adjusted imports in various files to reflect the removal of deprecated components.
    - Ensured all references to A2aExecutor are updated to A2AExecutor across the codebase.
    
    * refactor: Remove AgentThreadStorage and InMemoryAgentThreadStorage classes from threads and tests
    
    * feat: A2AExecutor to have its own override able save and get threads methods for persistent storage.
    
    * fix: linter bugs
    
    * removed unnecessary changes form core package
    
    * new line added
    
    * Refactor A2AExecutor tests and update imports
    
    - Consolidated mock agent fixtures in test_a2a_executor.py to simplify agent mocking.
    - Removed redundant tests related to thread storage and agent types, focusing on A2AExecutor's core functionality.
    - Updated test assertions to reflect changes in message handling with new Message and Content classes.
    - Enhanced integration tests to ensure compatibility with the new agent framework structure.
    - Added A2AExecutor to the module exports in __init__.py and __init__.pyi for better accessibility.
    
    * Update A2A documentation: enhance usage examples for A2AAgent and A2AExecutor
    
    * Updated uv lock
    
    * Fix metadata assertion in TestA2AExecutorHandleEvents and reorder load_dotenv call in agent_framework_to_a2a.py
    
    * Update agent card configuration: add default input and output modes, and fix agent creation method
    
    * Fix assertion for metadata in TestA2AExecutorHandleEvents
    
    * Fix formatting issues in TestA2AExecutorExecute and TestA2AExecutorIntegration
    
    * Enhance A2AExecutor documentation with examples and clarify agent execution process
    
    * Revert uv lock to main
    
    * Refactor A2AExecutor: Improve formatting and streamline constructor parameters
    
    * Apply suggestions from code review
    
    Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com>
    
    * Refactor A2AExecutor to use SupportsAgentRun and enhance logging; update agent framework sample for flight and hotel booking capabilities
    
    * Enhance A2AExecutor with streaming support and custom run arguments; update tests for initialization and execution scenarios
    
    * Enhance A2AExecutor event handling with streamed artifact tracking; update tests for new behavior
    
    * Refactor A2AExecutor to enforce type hints for stream and run_kwargs attributes
    
    * Refactor A2AExecutor and tests: replace AsyncMock with MagicMock for response stream handling; clean up imports in agent_framework_to_a2a.py
    
    * refactor: streamline imports and improve code readability across multiple files
    
    * feat: enhance A2AExecutor cancel method with context validation and fixed review comments
    
    * feat: implement get_uri_data utility function for extracting base64 data from data URIs and update references
    
    * fix: update import path for get_uri_data utility function in A2AExecutor and A2AAgent
    
    * fix: correct error message handling in A2AExecutor and update test assertions
    
    ---------
    
    Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com>
  • Python: Upgrade hosting server dependency and add more type support (#5459)
    * Upgrade hosting server dependency and add more type support
    
    * Comments
  • Python: Fix AG-UI reasoning role and multimodal media parsing to follow specification (#5389)
    * Fix AG-UI reasoning role and multimodal media value field parsing
    
    Fix two spec compliance issues in the AG-UI integration:
    
    1. ReasoningMessageStartEvent now uses role='reasoning' instead of
       role='assistant', matching the AG-UI specification for reasoning
       messages.
    
    2. _parse_multimodal_media_part now reads the 'value' field from source
       dicts (with fallback to 'data' for backward compatibility), matching
       the current AG-UI InputContentSource specification.
    
    Bump ag-ui-protocol dependency from ==0.1.13 to >=0.1.16,<0.2 to pick
    up the SDK fix that accepts role='reasoning' in ReasoningMessageStartEvent.
    
    Fix pre-existing pyright reportMissingImports errors for orjson in sample
    files, and fix import ordering in foundry-hosted-agents sample.
    
    Fixes #5340
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: Fix AG-UI reasoning role and multimodal media parsing to follow specification
    
    Fixes #5340
    
    * Remove unintended .maf-runtime-ready marker file
    
    Address PR review feedback: the .maf-runtime-ready file is not referenced anywhere in the repo and was left over from automation.
    
    Fixes #5340
    
    * Python: Fix duplicate AG-UI multimodal 'value' parsing in snapshot path
    
    The snapshot normalization path used a second copy of the multimodal source
    parsing logic that still read the deprecated 'data' field. When clients sent
    base64 media with source={"type": "base64", "value": ...}, the snapshot event
    emitted by the server dropped the payload, causing AG-UI-compatible clients
    to crash on ingest.
    
    Extract the shared source-field extraction into _extract_multimodal_source_fields
    so both _parse_multimodal_media_part and the snapshot _legacy_binary_part stay
    in sync with the AG-UI spec. Add snapshot-path regression tests covering
    value-only, value-preferred-over-data, and the legacy data-field fallback.
    
    Addresses review feedback on #5389 from @Rickyneer.
    
    ---------
    
    Co-authored-by: Copilot <copilot@github.com>
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Fix user agent prefix (#5455)
    * Fix hosting user agent missing
    
    * Fix other providers
    
    * Add more tests
    
    * comments
    
    * Fix tests
  • Python: (foundry): stop emitting [TOOLBOXES] warning for every FoundryChatClient call (#5440)
    * Python: Foundry: make response tool sanitizer internal, drop TOOLBOXES warning
    
    sanitize_foundry_response_tool runs on every tool passed to the Foundry
    Responses API, so its @experimental(TOOLBOXES) decorator was emitting a
    [TOOLBOXES] ExperimentalWarning for any FoundryChatClient call, even when
    no toolbox was involved. The function isn't in __all__ and has no external
    callers. Rename to _sanitize_foundry_response_tool and drop the decorator;
    the actual toolbox-facing public helpers remain gated.
    
    * Python: Foundry: silence pyright on intentional cross-module private import
  • Python: (chore): update changelog (#5438)
    * update changelog
    
    * Update python/CHANGELOG.md
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * Update python/CHANGELOG.md
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
  • Python: Hyperlight: thread-confine sandbox, skip parsing on host callbacks, schema/tool cleanup (#5424)
    * improved parsing of tool call results and tweaks
    
    * Address PR review: skip_parsing flag, broader registry close, comment fix
    
    - FunctionTool.invoke now takes a boolean skip_parsing flag instead of the
      SKIP_PARSING sentinel; the sentinel is still accepted as result_parser at
      construction time to opt out of parsing for every call. The two paths are
      equivalent.
    - _SandboxRegistry.close now invokes any sandbox close/shutdown hook on the
      entry's own worker thread (PyO3 unsendable), then shuts the worker down,
      then cleans up the per-entry temporary directories.
    - Clarified the _SandboxWorker.shutdown comment to describe the actual
      ThreadPoolExecutor.shutdown(wait=False, cancel_futures=False) semantics.
    - Hyperlight host callback uses skip_parsing=True (the new flag).
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Drop redundant 'is not SKIP_PARSING' guard that mypy 1.x flags
    
    After callable(configured_parser) the sentinel is already excluded; the extra
    identity check tripped mypy's non-overlapping identity warning.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fixed sandbox working on copy of tool
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Bump Python package versions for a release. (#5432)
    * Bump Python version for a release.
    
    * Revert lockstep bumps on unchanged connectors
    
    Per PR review: only connectors that changed (or whose published metadata
    changed) should get new versions. Keeps released tier at 1.1.1, a2a/ag-ui
    at 1.0.0b260422, foundry-hosting at 1.0.0a260422; reverts the 19 unchanged
    betas and 2 unchanged alphas to 1.0.0b260421/1.0.0a260421. Reverts all 26
    non-core agent-framework-core floors to >=1.1.0,<2 since no connector
    actually depends on a 1.1.1 API or bug fix.
    
    * Restore lockstep prerelease bumps and raise core floors to >=1.1.1
    
    Reverses the lean-revert: all beta packages stamped 1.0.0b260423 and alpha
    packages stamped 1.0.0a260423 (Asia date, matching release cut time). All
    26 non-core packages raise agent-framework-core lower bound from >=1.1.0,<2
    to >=1.1.1,<2 to signal the validated cohort for this release. CHANGELOG
    date updated to 2026-04-23.
  • Python: Flaky test report (#5342)
    * Add flaky test trend reporting to CI workflows
    
    Parse JUnit XML (pytest.xml) from each integration test job and
    aggregate results into a markdown trend report showing per-test
    pass/fail/skip status across the last 5 runs.
    
    Changes:
    - Add python/scripts/flaky_report/ package (JUnit XML parser + trend
      report generator following the sample_validation pattern)
    - Add upload-artifact steps to all 6 integration test jobs in both
      python-merge-tests.yml and python-integration-tests.yml
    - Add python-flaky-test-report aggregation job with history caching
    - Add --junitxml=pytest.xml to integration-tests.yml jobs (already
      present in merge-tests.yml)
    - Fix Cosmos job --junitxml path (use absolute path since uv run
      --directory changes cwd)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix flaky report: handle missing test results gracefully
    
    - Guard against missing reports directory in load_current_run()
    - Only run report job when at least one integration test job completed
      (skip when all jobs are skipped, e.g. on pull_request events)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review: fix provider names and if-expression precedence
    
    - Use explicit provider name mapping in _derive_provider() so OpenAI
      renders correctly instead of 'Openai'
    - Fix operator precedence in workflow if-expressions by wrapping
      success/failure checks in parentheses
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add File column and xfail detection to flaky test report
    
    - Add File column showing module name (e.g., test_openai_chat_client)
      to disambiguate tests with the same function name across files
    - Detect pytest xfail tests in JUnit XML (type=pytest.xfail) and
      show them with a distinct warning emoji instead of skip emoji
    - Update legend to include xfail explanation
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add Foundry embedding env vars to merge-tests workflow
    
    Sync the Foundry integration job in python-merge-tests.yml with
    python-integration-tests.yml by adding FOUNDRY_MODELS_ENDPOINT,
    FOUNDRY_MODELS_API_KEY, FOUNDRY_EMBEDDING_MODEL, and
    FOUNDRY_IMAGE_EMBEDDING_MODEL. Once the repo variables/secrets
    are configured, the embedding integration test will run in CI.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix File column showing class name instead of module name
    
    When a test is inside a class, pytest writes the classname as e.g.
    'pkg.test_file.TestClass'. The previous rsplit logic extracted
    'TestClass' instead of 'test_file'. Now detect uppercase-starting
    segments as class names and use the preceding segment instead.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review: UTC timestamps, XML error handling, summary fix, docstring
    
    - Use datetime.now(timezone.utc) for accurate UTC timestamps
    - Catch ET.ParseError per-file so corrupt XML doesn't crash the report
    - Remove separate 'error' key from summary (errors folded into 'failed')
    - Fix _short_name docstring to show actual dotted classname::name format
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Pass client thread_id as session_id when constructing AgentSession in AG-UI (#5384)
    * Pass thread_id as session_id when constructing AgentSession in AG-UI
    
    run_agent_stream() was constructing AgentSession without passing the
    client's thread_id as session_id, causing every request to receive a
    random UUID. This broke session continuity for HistoryProvider
    implementations that rely on session_id matching the client's thread_id.
    
    Pass session_id=thread_id in both the service-session and non-service
    code paths so the session identity is consistent with the AG-UI client.
    
    Fixes #5357
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add test for service_session with no thread_id edge case (#5357)
    
    When use_service_session=True but no thread_id/threadId is in the payload,
    verify session_id is a generated UUID and service_session_id is None.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <copilot@github.com>
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Propagate thread_id and forwarded_props through AG-UI to A2A context_id (#5383)
    * Propagate session.service_session_id as A2A context_id
    
    When A2AAgent is used behind the AG-UI protocol, the client thread_id is
    stored in session.service_session_id but was never forwarded as the A2A
    context_id. This broke session continuity across the AG-UI → A2A boundary.
    
    Add an optional context_id keyword argument to _prepare_message_for_a2a()
    and pass session.service_session_id from run(). The explicit
    message.additional_properties["context_id"] still takes precedence.
    
    Fixes #5345
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add integration tests for session context_id wiring in run() (#5345)
    
    - Enhance MockA2AClient.send_message to capture last_message for assertions
    - Add test_run_passes_session_service_session_id_as_context_id: verifies
      run() passes session.service_session_id through to A2A message context_id
    - Add test_run_message_context_id_takes_precedence_over_session: verifies
      explicit message context_id wins over session fallback
    - Update _prepare_message_for_a2a docstring to document context_id param
      and its precedence rules
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address review feedback for #5345: Python: [Bug]: Inconvenient passing of context_id / thread_id in A2A/AG-UI implementations
    
    ---------
    
    Co-authored-by: Copilot <copilot@github.com>
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: fix(foundry): reconcile toolbox hosted-tool payloads with Responses API (#5414)
    * fix(foundry): reconcile toolbox hosted-tool payloads with Responses API
    
    * docs(foundry): update create_sample_toolbox docstring to reflect all tools created
  • Python: Fix OpenAI Responses streaming to propagate created_at from final response.completed event (#5382)
    * Fix streaming response losing created_at from response.completed event (#5347)
    
    The streaming path in _parse_chunk_from_openai did not extract created_at
    from the response.completed event, unlike the non-streaming path in
    _parse_responses_response. This caused durabletask persistence warnings
    when created_at was None.
    
    Extract created_at in the response.completed case and pass it to the
    returned ChatResponseUpdate.
    
    Also fix pre-existing pyright errors for optional orjson import in sample
    files.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix orjson import suppression to use pyright instead of mypy (#5347)
    
    Replace `# type: ignore[import-not-found]` with
    `# pyright: ignore[reportMissingImports]` on optional orjson imports
    in conversation sample files, matching the repo's Pyright strict
    configuration.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <copilot@github.com>
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: fix: exclude null file_id from input_image payload to prevent 400 sch… (#5125)
    * fix: exclude null file_id from input_image payload to prevent 400 schema error (#5120)
    
    * test: add case for additional_properties present without file_id key
    
    ---------
    
    Co-authored-by: Sergey Borisov <sergey.borisov@dataimpact.io>
  • Python: Fix OpenAIEmbeddingClient to use AsyncOpenAI for /openai/v1 endpoints (#5137)
    * Fix OpenAIEmbeddingClient with /openai/v1 endpoint (#5068)
    
    When base_url ends with /openai/v1/ and a credential is provided,
    load_openai_service_settings was creating an AsyncAzureOpenAI client.
    The Azure SDK rewrites deployment-based endpoints (including /embeddings)
    by inserting /deployments/{model}/ into the URL, producing 404s on the
    OpenAI-compatible /openai/v1 endpoint.
    
    Use AsyncOpenAI instead of AsyncAzureOpenAI when the resolved base_url
    targets /openai/v1, converting the Azure token provider to an async
    api_key callable. The responses_mode path is unaffected because the
    Responses API (/responses) is not in the SDK's rewrite list.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: Fix OpenAIEmbeddingClient to use AsyncOpenAI for /openai/v1 endpoints
    
    Fixes #5068
    
    * Address review feedback: improve test coverage and remove unrelated changes
    
    - Revert unrelated formatting change in test_a2a_agent.py
    - Fix test_init_with_openai_v1_base_url_and_api_key_uses_openai_client to
      exercise the Azure settings path (via AZURE_OPENAI_BASE_URL env var)
      instead of the plain OpenAI path, covering the elif api_key branch
    - Add _ensure_async_token_provider unit tests for both sync and async
      token providers
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address review feedback for #5068: Python: [Bug]: `OpenAIEmbeddingClient` does not work with `/openai/v1` endpoint
    
    ---------
    
    Co-authored-by: MAF Dashboard Bot <maf-dashboard-bot@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>
  • Python: feat(evals): add ground_truth support for similarity evaluator (#5234)
    * feat(evals): add ground_truth support for similarity evaluator
    
    - Include expected_output as ground_truth in Foundry JSONL dataset rows
    - Add ground_truth to item schema and data mapping for similarity evaluator
    - Add expected_output parameter to evaluate_workflow
    - Add similarity Pattern 3 to evaluate_agent and evaluate_workflow samples
    - Add tests for ground_truth in dataset, schema, and evaluate_workflow
    
    * Apply suggestions from code review
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * fix: wrap long line to satisfy ruff E501
    
    ---------
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
  • Python: Add second approval-required tool (set_stop_loss) to concurrent_builder_tool_approval sample (#4875)
    * Add set_stop_loss tool to concurrent_builder_tool_approval sample
    
    Add a second approval-gated tool (set_stop_loss) to the concurrent workflow
    tool approval sample to demonstrate handling approval requests for different
    tools in the same concurrent workflow.
    
    Changes:
    - Add set_stop_loss(symbol, stop_price) with approval_mode='always_require'
    - Include new tool in both agents' tool lists
    - Update agent instructions and prompt to encourage stop-loss usage
    - Update docstring to reflect two approval-gated tools
    - Update sample output to show mixed approval requests
    
    Fixes #4874
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Print tool name and arguments in concurrent sample's process_event_stream (#4874)
    
    Align process_event_stream in concurrent_builder_tool_approval.py to print
    the tool name and arguments when collecting approval requests, matching the
    sample output comment and the sequential_builder_tool_approval.py pattern.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add None-guard for function_call access in tool approval sample (#4874)
    
    Add explicit None-checks before accessing function_call.name and
    function_call.arguments in concurrent_builder_tool_approval.py. The
    function_call field is typed Content | None, so direct attribute access
    without a guard could raise AttributeError and required type: ignore
    comments. The None-guard is consistent with the pattern used in
    _agent_run.py and removes the suppression comments.
    
    Also add a regression test verifying that function_call defaults to None
    and that the None-guard pattern is safe.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Apply same function_call None-guard to sibling tool-approval samples (#4874)
    
    Apply the same fix to sequential_builder_tool_approval.py and
    group_chat_builder_tool_approval.py, which had the identical pattern
    of accessing function_call.name/arguments without a None-guard.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <copilot@github.com>
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Bump versions for a release. Update CHANGELOG (#5385)
    * Bump versions for a release. Update CHANGELOG
    
    * Bump devui
  • Python: Foundry hosted agent V2 (#5379)
    * Python: Wrapper + Samples 1st (#5177)
    
    * Experiment
    
    * Update dependency and add non streaming
    
    * Add more samples
    
    * Rename samples
    
    * Add invocations
    
    * Comments 1
    
    * Comments 2
    
    * Comments 3
    
    * Improve README
    
    * Add local shell sample
    
    * WIP: Add eval and memory samples
    
    * Update user agent prefix
    
    * Update user agent prefix doc
    
    * Update dependency (#5215)
    
    * Add tests and more content types (#5235)
    
    * Add tests
    
    * fix tests and sample
    
    * Fix formatting
    
    * Remove function approval contents
    
    * Python: Refine samples and upgrade packages (#5261)
    
    * Refine samples and upgrade pacakges
    
    * Upgrade to a new package that fixes a bug
    
    * Update model env var
    
    * Move samples (#5281)
    
    * Python: Upgrade agentserver packages (#5284)
    
    * Upgrade agentserver packages
    
    * Fix new types
    
    * Python: Add special handling for workflows (#5298)
    
    * Add special handling for workflows
    
    * Address comments
    
    * Improve samples (#5372)
    
    * Python: Add more types (#5378)
    
    * Add more type supports
    
    * Upgrade packages
    
    * Remove TODOs in README
    
    * Fix README
    
    * Comments and mypy
    
    * User agent scoped
    
    * Fix README
    
    * Fix pre commit
    
    * Fix pre commit 2
    
    * Fix pre commit 3
    
    * Fix pre commit 4
    
    * Fix pre commit 5
    
    * Fix pre commit 6
    
    * Add azure-monitor-opentelemetry to dev deps
    
    Fixes Samples & Markdown CI failure. The PR's new transitive dep on
    azure-monitor-opentelemetry-exporter (via azure-ai-agentserver-core) makes
    pyright resolve the azure.monitor.opentelemetry namespace, flipping the
    check_md_code_blocks diagnostic for `configure_azure_monitor` from
    reportMissingImports (filtered) to reportAttributeAccessIssue (not filtered).
    Installing the umbrella azure-monitor-opentelemetry package in dev makes
    pyright resolve the symbol correctly, matching the install guidance the
    observability README already gives users.
    
    ---------
    
    Co-authored-by: Evan Mattson <evan.mattson@microsoft.com>
  • Python: Expose forwardedProps to agents and tools via session metadata (#5264)
    * Expose forwarded_props to agents and tools via session metadata (#5239)
    
    Include forwarded_props from AG-UI request input_data in session.metadata
    (agent runner) and function_invocation_kwargs (workflow runner) so that
    agents, tools, and workflow executors can access request-level metadata
    such as invocation source flags from CopilotKit.
    
    - Add forwarded_props to base_metadata in _agent_run.py when present
    - Add 'forwarded_props' to AG_UI_INTERNAL_METADATA_KEYS to filter it
      from LLM-bound client metadata
    - Extract forwarded_props in _workflow_run.py and pass via
      function_invocation_kwargs to workflow.run()
    - Accept both snake_case and camelCase keys (forwarded_props/forwardedProps)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix(ag-ui): pass stream=True as literal to satisfy pyright overload resolution (#5239)
    
    The previous fix passed stream=True via **kwargs dict, which prevented
    pyright from resolving the Workflow.run() overload to the streaming
    variant. Pass stream=True as an explicit keyword argument so pyright
    can correctly infer the ResponseStream return type.
    
    Also remove unused pytest import in test file.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: address PR review feedback for forwarded_props (#5239)
    
    - Use key-presence checks instead of truthiness for forwarded_props so
      empty dict {} is forwarded correctly
    - Gate function_invocation_kwargs on workflow.run() signature inspection
      to avoid TypeError for workflows without **kwargs
    - Change _build_safe_metadata to drop (with warning) keys whose
      serialized values exceed 512 chars instead of truncating into invalid
      JSON
    - Rewrite metadata tests to exercise _build_safe_metadata directly with
      JSON-decodability and truncation assertions
    - Add workflow tests for empty dict forwarded_props, stream=True
      assertion, and signature-gated kwarg dropping
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * test: add stream=True assertions to CapturingWorkflow tests (#5239)
    
    Guard against accidental removal of the explicit stream=True kwarg
    in all forwarded_props CapturingWorkflow test cases.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address review feedback for #5239: Python: Expose forwardedProps to agents and tools via session metadata
    
    ---------
    
    Co-authored-by: Copilot <copilot@github.com>
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Add support for Foundry Toolboxes (#5346)
    * Add support for the Foundry Toolbox in MAF
    
    Introduces a Foundry Toolbox integration: FoundryChatClient gains a
    get_toolbox() helper plus select_toolbox_tools(), normalize_tools in
    the core package flattens tool-collection wrappers (ToolboxVersionObject
    and generic iterables, while leaving Pydantic BaseModel instances
    alone), and the new agent_framework.foundry namespace re-exports the
    toolbox helpers. Ships with unit tests, a sample, and a design doc.
    
    azure-ai-projects is pinned to the public >=2.0.0,<3.0 range and the
    lockfile resolves from public PyPI. The toolbox test module skips when
    Toolbox* types are unavailable so CI stays green until the public 2.1.0
    SDK lands. OMC tooling directories (.omc/, .omx/) are gitignored.
    
    * Update to latest azure ai projects package
    
    * Improve sample
    
    * Rename ADR to 0025
    
    * Update ADR
    
    * Apply suggestion from @alliscode
    
    Co-authored-by: Ben Thomas <ben.thomas@microsoft.com>
    
    * Improve samples
    
    * Update test
    
    ---------
    
    Co-authored-by: Ben Thomas <ben.thomas@microsoft.com>
  • Python: Add search tool content for OpenAI responses (#5302)
    * Add OpenAI search tool content parsing
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix typing
    
    * simplified oai image test
    
    * same for azure
    
    * skip az responses api test
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Flatten hyperlight execute_code output (#5333)
    * small fix for hyperlight
    
    * improved sandbox dependency
  • Python: Fix CopilotStudioAgent to reuse conversation ID from existing session (#5299)
    * Fix CopilotStudioAgent to reuse existing conversation on session (#5285)
    
    CopilotStudioAgent unconditionally called _start_new_conversation() in both
    _run_impl and _run_stream_impl, ignoring any existing service_session_id on
    the session. Add a guard to only start a new conversation when there is no
    existing service_session_id, matching the pattern used by other agents.
    
    Also fix pre-existing pyright reportMissingImports errors for orjson in
    file_history_provider samples.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Revert out-of-scope sample file changes
    
    Remove unrelated orjson type-ignore comment changes from sample files
    that were outside the scope of the conversation-ID reuse fix.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <copilot@github.com>
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Add Hyperlight CodeAct package and docs (#5185)
    * initial work on code_mode
    
    * updated samples
    
    * updates to codeact
    
    * udpated codeact
    
    * Draft CodeAct ADR and sample updates
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * initial implementation and adr and feature
    
    * Python: Limit Hyperlight wasm backend to Python <3.14
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: Fix CI for Hyperlight CodeAct PR
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: Run Hyperlight integration when available
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: Address Hyperlight review feedback
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: Simplify Hyperlight file mount inputs
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: Accept Path host paths in Hyperlight mounts
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: Fix Hyperlight mount typing for CI
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * temp run integration test
    
    * Python: Strengthen Hyperlight real sandbox tests
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * added additional tests
    
    * Python: Simplify Hyperlight CodeAct API
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * set tests as non-integration
    
    * Retry Hyperlight allowed-domain registration
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Gate Hyperlight integration tests by runtime support
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix Hyperlight skip test on Python 3.14
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Delay Hyperlight runtime probe until test execution
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Relax Hyperlight Windows integration stdout assertion
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Scan Hyperlight output directory for artifacts
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Retry Hyperlight output artifact collection
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Harden Hyperlight integration output assertions
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Retry Hyperlight read-back check in integration test
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Simplify Hyperlight integration write assertion
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Avoid pathlib in Hyperlight integration sandbox
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Use socket network check in Hyperlight sandbox
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Replace blocked Azure AI Search blog link
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Clarify Hyperlight guest stdlib limits
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Use _socket in Hyperlight integration sandbox
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Handle Hyperlight mounted file paths
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Broaden Hyperlight sandbox path fallbacks
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Search Hyperlight guest mounts recursively
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Split Hyperlight mount coverage
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Split Hyperlight live network tests
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix Hyperlight file-write test on Windows
    
    Enable the sandbox filesystem by providing a workspace_root so
    /output is mounted. Remove os.path.exists assertion (unsupported
    in WASM guest) and fix Content data assertion to use .uri.
    Skip the network integration test on Windows where the WASM
    sandbox lacks the encodings.idna codec.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review: ADR intro, manual wiring sample, doc clarifications
    
    - Add CodeAct introduction section to ADR for unfamiliar readers
    - Clarify 'less runtime efficient' con with specific overhead description
    - Add note in Python impl doc clarifying ADR vs impl doc split
    - Explain why before_run hooks must be per-run (CRUD, concurrency, approval)
    - Rename code_interpreter variable to codeact in E2E sample
    - Add manual static wiring sample (codeact_manual_wiring.py)
    - Add 'when to use which pattern' guidance to samples README
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR #5185 review comments and add .NET CodeAct design doc
    
    - Fix async callback: _make_sandbox_callback returns sync wrapper with
      thread + asyncio.run() bridge (was broken with real Wasm FFI)
    - Fix stale output: clear output_dir before each sandbox.run() call
    - Fix blocking event loop: _run_code now async with asyncio.to_thread()
    - Revert _agents.py options['tools'] injection (unnecessary; provider
      uses context.extend_tools())
    - Revert SessionContext.options docstring back to read-only
    - Add real-sandbox test fixtures (shared/restored/fresh)
    - Add 8 new real-sandbox tests for callback round-trip, stale output,
      event loop non-blocking, basic execution, stdout/stderr, errors,
      snapshot/restore, and tool registration
    - Add comprehensive .NET HyperlightCodeActProvider design document
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Update hyperlight README with code snippets and remove Public API section
    
    Replace bare export list with Quick Start code examples covering the
    context provider, standalone tool, manual static wiring, and file
    mounts / network access patterns.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Feat: Add finish_reason support to AgentResponse and AgentResponseUpdate (#5211)
    * feat: add finish_reason support to AgentResponse and AgentResponseUpdate
    
    Add finish_reason field to AgentResponse and AgentResponseUpdate classes,
    propagate it through _process_update() and map_chat_to_agent_update(),
    and add comprehensive unit tests.
    
    Fixes #4622
    
    * feat: add finish_reason to AgentResponse and AgentResponseUpdate
    
    * style: add copyright header to test_finish_reason.py
    
    * docs: add finish_reason to AgentResponse and AgentResponseUpdate docstrings
    
    * refactor: move finish_reason tests into test_types.py per review feedback
    
    Move all finish_reason test cases from the separate test_finish_reason.py
    file into test_types.py as requested by eavanvalkenburg. Tests are placed
    in a new '# region finish_reason' section at the end of the file.
    
    * fix: use model instead of model_id in _process_update
    
    Address PR review feedback from @eavanvalkenburg — ChatResponse and
    ChatResponseUpdate both use 'model', not 'model_id'.
    
    * fix: resolve SIM102 lint error in _process_update
    
    Combine nested if statements for AgentResponse finish_reason check
    to satisfy ruff SIM102 rule, with line wrapping to stay under 120 chars.
    
    * fix: resolve pyright reportArgumentType in map_chat_to_agent_update
    
    Add type: ignore[arg-type] for FinishReason NewType widening when
    passing ChatResponseUpdate.finish_reason to AgentResponseUpdate.
    Matches existing patterns in the codebase (40+ similar ignores).
  • Python: Fix Gemini client support for Gemini API and Vertex AI (#5258)
    * Add Gemini and Vertex AI client support
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address Gemini PR review feedback
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * removed sample run readme part
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    Co-authored-by: Evan Mattson <35585003+moonbox3@users.noreply.github.com>