Skip to content

Show what was extracted from V2 image uploads, index text-free images, and default image generation to 2025-04-01-preview - #1585

Merged
Paul Lizer (paullizer) merged 6 commits into
microsoft:paullizer-react-v2-uifrom
paullizer:paullizer-overexposed-image-processing
Sep 30, 2026
Merged

Paul Lizer (paullizer) merged 6 commits into
microsoft:paullizer-react-v2-uifrom
paullizer:paullizer-overexposed-image-processing

Conversation

@paullizer

Copy link
Copy Markdown
Contributor

Refs #1583

This brings the Development fix from #1584 into React V2 and adds the V2-only chat fixes for uploaded images. Version 0.261.210.

Why

Two nearly identical photos of an empty lab floor were uploaded. Neither has any real text.

  • The less overexposed photo worked only because Document Intelligence Layout misread a strip of floor tape as a page number (<!-- PageNumber="J" -->, confidence 0.18). That created a chunk for the vision description to ride on.
  • The overexposed photo got no chunk, no title, and nothing chat could use, even though its vision analysis succeeded.
  • A later upload returned a 404 because the vision model (gpt-5.6-luna) is hosted on a different AI connection, and ingestion always called the primary GPT endpoint.
  • In V2, opening the upload showed File content not found, a cited image showed only the picture, and the upload card did not match a generated image.

Folded from Development (#1584)

  • Images without OCR text are indexed from their vision description. A page that holds only Document Intelligence page-number or page-break annotations counts as no text. Chunks are embedded from the stored text, including the vision block. Failed or empty analyses are never indexed.
  • Content Understanding image analyzer fallback. A standalone image the document analyzer returns nothing for goes to the image analyzer before Document Intelligence Layout, for workspace and direct chat uploads. The analyzer's Summary field is now read, which also fixes Office-embedded images that were indexed as ![image](pages/1).
  • Vision analysis uses the AI connection that hosts the model. Ingestion, chat image uploads, and Test Vision Analysis resolve the model through find_enabled_model_endpoint_for_model_name / resolve_vision_model_endpoint, and fall back to the GPT connection otherwise.
  • Image generation API version defaults to 2025-04-01-preview. A saved 2024-12-01-preview or blank legacy value is upgraded when settings load. APIM versions are never changed.
  • CodeQL follow-up. Tests and docs only.

React V2 adjustments to the fold

  • The shared connection client helper keeps V2's order: it finds the model and runs require_model_capability before any Key Vault lookup, so metadata extraction behaves as before. Vision also checks image support against the resolved connection's model.
  • V2 refuses chunks that are too large for non-legacy embedding profiles. When only the appended vision block pushes a page over the budget, including a description-only chunk, the embedding input is cut to the budget and the stored text keeps the whole block.
  • Image connection profiles imported with 2024-12-01-preview are upgraded; APIM profiles are not. Unmigrated legacy direct Images settings with no version fall back to 2025-04-01-preview. An unmigrated APIM route keeps sending 2024-12-01-preview. The V2 admin field default and the docs are updated to match.

V2-only

  • /api/get_file_content for workspace-backed uploads returns the linked document's indexed chunks, read in that document's own scope through get_ordered_document_chunks. It also returns browser-safe details: engine and reason, vision analysis, title, summary, keywords, and status. There are explicit messages for processing, failed, and nothing-indexed files. Screening errors keep their public wording, and other failures return a fixed message. The new pure module functions_chat_upload_extraction.py shapes the response. The classic popup benefits too.
  • Upload card parity. The image is drawn at its own size, like a generated image. Hover or focus reveals Show sources, Message details, Open file preview, Use as reference and Edit. Show sources opens an inspector panel with the extraction, and Uploaded file shows the same content.
  • Cited images show What was extracted from this image (the cited passage) beneath the picture.

Tests

  • New: functional_tests/test_chat_upload_extraction_details.py. It covers response shaping, fallback to the stored vision analysis, processing, failed and absent wording, and the route helper's scope and error handling.
  • Folded and adapted for V2: test_image_description_indexing_without_ocr_text.py (9 passed). Its offline probe imports the real modules in normal and -O processes, and it adds V2 embedding-guard and capability-order cases. Also test_image_generation_api_version_default.py (21 passed), which adds connection-profile migration, persistence and APIM fallback cases.
  • ui_tests/test_v2_chat_image_uploads.py: 16 passed. It checks card sizing against a 320×200 image, hover reveal, the Sources panel, the file preview, processing and failed states, and the cited-image passage. test_v2_image_reference_generation.py and test_v2_image_editor.py also pass.
  • Related suites pass. The route policy suites, docs coverage and quality, and the BAC, XSS and swagger guardrails all pass.
  • Failures that also occur on the base commit b0ed6ea4a, checked in a clean worktree and unchanged by this PR:
    • test_backend_documents_swagger_integration (3)
    • test_v2_tabular_parity::test_the_confirmation_precedes_the_send
    • test_content_understanding_extraction_engine::test_settings_and_admin_surface_contract
    • test_model_vision_capability_resolution::test_the_catalog_overrules_the_name_heuristic
    • test_image_generation_model_compatibility (2)
    • 3 V2 admin parity/schema tests
    • test_image_generation_sdk_http::test_installed_sdk_matches_existing_application_requirement, which fails because the local openai SDK version differs.

Deploying

After deploying, re-upload or reprocess the overexposed image so it gets indexed.

Docs: V2 Chat Upload Extraction and Image Card Fix, Image Description Indexing Without OCR Text Fix, Image Generation API Version Default Fix, and release notes under v0.261.210.

…d card to generated images

A chat upload is stored as a workspace document, so its chat message has no text and
/api/get_file_content returned "File content not found" for every workspace-backed upload.
The route now returns the linked document's indexed chunks and the stored image analysis,
read in the document's own scope, with no storage or screening state in the response.

In V2 the uploaded image card is sized to the image like a generated image, its actions are
revealed on hover, and Show sources and the file preview show the extraction (engine, AI vision
analysis, metadata, indexed text). A cited image shows the cited passage beneath the picture.

Refs microsoft#1583

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

Folded from the Development fix (microsoft#1584) for microsoft#1583:
- An image whose OCR output is empty, or only a Document Intelligence page-number comment, is
  indexed from its AI vision description, and chunk embeddings are built from the stored text
  including the vision block.
- Standalone images fall back to the Content Understanding image analyzer, whose Summary field
  is now read, before Document Intelligence Layout.
- The vision model name resolves to the enabled AI connection that hosts it, for ingestion,
  chat image uploads and the admin vision test.

React V2 adjustments:
- The shared model-endpoint client helper keeps V2's order: find the model and re-check its
  chat capability before resolving Key Vault secrets. Metadata extraction behaves as before.
- Vision analysis re-checks image support on the resolved connection model, and the legacy
  path keeps its existing checks.
- A page that fits the embedding budget embeds its OCR text when the vision block would push
  it over, instead of being refused by the non-legacy embedding guard.
- The V2 admin help text and the Knowledge docs describe the new behavior.

(cherry picked from commit b91f9d5)

Refs microsoft#1583

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Folded from the Development fix (microsoft#1584): the image generation API version defaults to
2025-04-01-preview, the newest dated Azure OpenAI version and the one documented for gpt-image
models, and a saved 2024-12-01-preview (the previous default) or blank value is upgraded when
settings load. APIM versions are never changed.

React V2 adjustments:
- Image connection profiles imported with the previous default are upgraded the same way, and
  APIM profiles are left alone.
- Unmigrated legacy Images settings with no version fall back to 2025-04-01-preview.
- The V2 admin field default and the AI Models and image generation docs match.

(cherry picked from commit 4882390)

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…and image API version fixes

Refs microsoft#1583

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- An image whose only text is its vision description, or a page the appended description pushes
  past the embedding budget, now embeds the stored text cut to the budget instead of failing
  ingestion under a non-legacy embedding profile. The stored chunk keeps the whole description.
- A chat upload whose ingestion failed is reported as failed rather than still processing, in
  both the file content response and the V2 extraction panel.
- An unmigrated legacy APIM image route with no API version keeps sending 2024-12-01-preview;
  only the direct route falls back to 2025-04-01-preview.

Refs microsoft#1583

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Folded from Development: assert batch token usage in the no-vision case and add a fresh-process
probe that imports functions_content_understanding before functions_content. The fix doc
records the existing import cycle. Tests and docs only.

(cherry picked from commit 60365d5)

Refs microsoft#1583

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@paullizer
Paul Lizer (paullizer) merged commit 4f77838 into microsoft:paullizer-react-v2-ui Sep 30, 2026
10 checks passed
Paul Lizer (paullizer) added a commit that referenced this pull request Oct 1, 2026
Brings in #1585 (React V2 image indexing and upload fixes). The only
conflict was VERSION in config.py, kept at Phase 5's 0.261.212.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Paul Lizer (paullizer) added a commit that referenced this pull request Oct 1, 2026
#1585 took 0.261.210, so 3c moves up one. Mechanical: only version strings change.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Paul Lizer (paullizer) added a commit that referenced this pull request Oct 1, 2026
- Feature docs: the Ask AI tab, its thread, requests, rebase and change
  check, turn cards, failures, Draft with AI and accessibility
  (WORKFLOW_AI_ASSISTANT.md); the shared thread's opt-in options and the
  workflow limit (V2_SHARED_ASSIST_THREAD.md); AI-authored changes now
  coming from Ask AI and Draft with AI (WORKFLOW_EDITOR_CHANGE_TRACKING.md).
- Admin and guide: the setting now shows the tab and Draft with AI; a new
  "Ask AI to change a workflow" section and two troubleshooting rows.
- Release notes: v0.261.211 above #1585's v0.261.210, which is unchanged.
- test_v2_workflow_ask_ai.py: the four chat editors pass none of the
  shared thread's new options, and the client's instruction limit matches
  ASSIST_INSTRUCTION_MAX_LENGTH and is counted in code points.
- workflowAssist.ts: correct a comment about per-field Revert.

Refs #1548

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Paul Lizer (paullizer) added a commit that referenced this pull request Oct 1, 2026
Mechanical: #1585 took 0.261.210, so the sequence is now 3c .211,
Phase 5 .212 and phase 6a .213. Only phase 6a's own version references
change.

Part of #1546

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Paul Lizer (paullizer) added a commit that referenced this pull request Oct 1, 2026
Brings in #1585 (0.261.210). The only conflict was VERSION in config.py,
kept at phase 6a's 0.261.213. The settings hunks in functions_settings.py
and admin_settings_fields.py merged cleanly. The regenerated docs
inventory is unchanged.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Paul Lizer (paullizer) added a commit that referenced this pull request Oct 1, 2026
The closed exec namespace in test_v2_prompt_attachment_persistence.py
never received prepared_chat_image_references (added to chat_api by
#1585), so every chat-path boundary and the two composer-card tests
that reuse the harness died with a NameError.

- Seed the route's initial value next to the other chat_api locals in
  a shared _chat_namespace, plus the content-check names and the
  orchestration/shared-route names the boundaries now read (real pure
  functions with chat checks off; no production statements copied).
- Translate boundary NameErrors into a readable AssertionError naming
  the missing local.
- Add an AST drift check that compares the seed to chat_api's dict
  literal and fails with the added/dropped keys.
- Move the composer-card TypeScript dispatchPlan mock to planner
  contract 2 with a runnable step, which normalizePlan/isPlanRunnable
  now require.

Refs #1543

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Paul Lizer (paullizer) added a commit that referenced this pull request Oct 1, 2026
test_run_record_keeps_the_turn_and_question_ids execs the route's real
_validate_turn_memory_context and _persist_planned_turn in a hand-built
namespace. Since the image-reference work (#1585), _persist_planned_turn
calls image_reference_provenance_from_seeds() for the saved user message,
and the namespace never received it, so the test died with a NameError
(script 5/6; pytest 1 failed under the #1572 guard).

Inject the real helper from functions_orchestration_context through the
existing import_app_module stub seam. It is a pure function, and a turn
with no seeds yields [], so the asserted identifiers are unchanged.

Refs #1543

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant