Skip to content

Add experimental shared Documents abstractions - #7835

Merged
luisquintanilla merged 11 commits into
dotnet:mainfrom
luisquintanilla:luisquintanilla-document-extraction-planning
Nov 5, 2026
Merged

luisquintanilla merged 11 commits into
dotnet:mainfrom
luisquintanilla:luisquintanilla-document-extraction-planning

Conversation

@luisquintanilla

@luisquintanilla luisquintanilla commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Introduce a shared, provider-neutral document model that extraction engines, applications and ingestion pipelines can exchange without translating between competing element hierarchies.

The model lives in Microsoft.Extensions.Documents.Abstractions, under Microsoft.Extensions.Documents. Applications can construct it directly; an extraction client is not required.

var document = new ExtractionDocument("invoice:42");
var section = new ExtractionDocumentSection();
section.Elements.Add(
    new ExtractionDocumentTextElement(new TextContent("Total: $42.00")));
document.Sections.Add(section);

What the model provides

Area Design
Structure Ordered sections, text, images and tables, including addressed cells, spans and explicit empty anchors. Section/element collections use concrete List<T>.
Content Optional local AIContent, not an aggregate copy of descendants. Text nodes use TextContent.Text as their single authority. Image OCR/transcription and alternative description remain separate facts.
Source and layout Source-page identity, blank frames, optional original page numbers and ordered polygons with dimensions, units and coordinate origin. Unknown facts are not invented.
Native inspection Optional borrowed RawRepresentation for provider-specific inspection. It is excluded from default JSON, but that is not redaction or a durable raw-response archive.

How the PRs fit together

This PR owns the document model. #7588 adds extraction clients that return it. #7904 lets MEDI process it inside the retained IngestionDocument envelope, sharing the exact graph rather than replacing the ingestion root or copying the document.

This package does not provide extraction engines, rendering, ingestion orchestration or provider-operation tracking. Native objects are not implicitly disposed or deep-cloned; their usability depends on the real provider lifetime.

Suggested review focus

  1. Naming and package boundary: the current family is named ExtractionDocument*, while the package/namespace remain Documents. Naming and API approval are still review decisions.
  2. Content and structure: one authoritative text payload, useful table/image structure and clear local-content semantics without a second representation.
  3. Source and ownership: interpretable layout, explicit unknown/blank-page facts and a borrowed native escape hatch without promising durable provider responses.
Original PR description (preserved verbatim)

Why this change

Propose an independent, provider-neutral document exchange boundary shared by extraction engines and ingestion consumers. Applications can construct the model directly; it is not an OCR engine, editor, ingestion pipeline or rendering framework.

Simplified first-preview contract

Area Proposed boundary
Naming 14 ExtractionDocument* types in unchanged package Microsoft.Extensions.Documents.Abstractions / namespace Microsoft.Extensions.Documents. Naming/package/API approval remains a team decision.
Structure Ordered sections/text/images/tables, addressed cells/spans/explicit empty anchors. Optional local AIContent is not an aggregate copy of descendants.
Authoritative text Text nodes use only TextContent.Text; no competing general-element Text. Nonnull TextContent is enforced even through base-reference assignments; rejected mutations retain the old payload. Provider Markdown is preserved, not reinterpreted as promised plain text.
Image facts Image-only Text is genuine OCR/transcription. AlternativeText is independent description/caption. Original asset Source and current payload URI are distinct; neither is fetched by the model.
Interpretable layout Ordered polygon snapshots, coordinate units/origin/dimensions, nullable positive original numbers, multi-page references and explicit blank frames. SourcePages is an ordinary list; references do not implicitly register pages. Unknown facts are not invented.
Native escape hatch Optional document RawRepresentation works without content/sections and is excluded from default JSON. Native/opaque values remain borrowed, not implicitly disposed or deep-cloned; existing payload/source native inspection remains.
Bounded preview Remove SourceOutput, Artifact, RawContentStatus, operation registration and source-page operation links. No replacement graph in metadata. Heading levels are null or positive, with no arbitrary maximum ten.
Safety Retain table/grid/span validation, numerical source checks and null/cycle traversal safety. No public renderer, validator hierarchy, companion package or table-composition redesign.

This revision deliberately does not standardize original wire bytes, detached raw-response storage, capture status, per-operation identity or output provider/model metadata. Native inspection is subject to real provider lifetimes. JSON exclusion is not redaction.

Review map

Published head ee9ee634c9f1e649f409e0d2cf0efd9318437d90, tree c90ee4da7d7098f930329c7cbede3f6e1316ff46.

Executed acceptance and limits

Exact sealed-source Documents tests: 211 on each of net10/net9/net8/net472 = 844 passed, zero failed/skipped. Parent integration independently reproduced the sealed tree and reran all four targets, also 844 passed; these overlap, not additional distinct cases. Production covers net10/net9/net8/net462/netstandard2.0 with zero warnings/errors.

Actual ApiChief inventory changes 17→14 types and 89→71 members. Native delta retains the known string ApiStage parser defect; independent member comparison is not represented as a native-tool pass. Reduced counts retire tests of the intentionally deleted graph; structural/layout/lifetime/mutation coverage remains. All 40 legacy multiargument core text calls were reconciled; all 106 current calls explicitly name role arguments to avoid silent migration into the new second parameter.

Fresh immutable review version 10.10.0-review.20261102.1 is packed from public full core commit 0f69c5cd069e2a8bc53e5bc0021c6825b4d35726 / tree 102a40f1bfb67efc0746bad6b64faa08c65fe169. Actual nupkg-only parent acceptance passes 38 checks and all four runtime DLL hashes match canonical archives. Canonical receipt SHA256 bb66839bd51050f92ec5c342912827cdcc022363986aa80e21ef77252851fe4e.

See MEDI/bridge #7904 for its current ingestion-envelope reconciliation, owning acceptance and prerequisite integration gate; earlier migration receipts do not certify a later owning API revision. Toolkit passes512 canonical-package cases plus512 on each hosted Windows/Ubuntu platform in run41472886642. Those validate synthetic/offline boundaries, not live service certification. Old review packages remain unchanged. The canonical core candidate is not on a public package feed; Toolkit records its actual immutable public-source bootstrap.

Exact-head Azure build 1660145 completed/success: Ubuntu, Windows, coverage and aggregate checks all succeed; CLA succeeds. Its PR merge revision c514813dc45a902af9546c7163ecbcc56904367a has this published head as a parent. This check result is distinct from downstream prerequisite landing and API approval.

No merge, official release, API approval, demo migration, paid/live service request or repository-wide validation claim. Related design discussion: #7587. Experimental diagnostic: EXTEXP0019.

Microsoft Reviewers: Open in CodeFlow
Microsoft Reviewers: Open in CodeFlow

Introduce the provider-neutral Documents hierarchy, ownership and artifact lifetime contracts as a standalone prerequisite for document extraction. Include experimental diagnostic registration, API baseline, documentation and focused tests.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actions github-actions Bot added the area-ai Microsoft.Extensions.AI libraries label Oct 13, 2026
@luisquintanilla
luisquintanilla requested a balanced review from Copilot October 13, 2026 20:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Mutation, ownership rollback, disposal, and Markdown projection paths contain correctness issues that should be resolved before approval.

8 open findings
What changed in this PR

Adds experimental provider-neutral document abstractions for future extraction and ingestion integrations.

Changes:

  • Introduces document hierarchies, elements, tables, references, and owned artifacts.
  • Adds versioning, Markdown projection, ownership, and disposal behavior.
  • Registers EXTEXP0019 with API baselines, documentation, and tests.
File Description
Directory.Build.targets Suppresses the new experimental diagnostic internally.
docs/​list-of-diagnostics.md Documents EXTEXP0019.
src/​Shared/​DiagnosticIds/​DiagnosticIds.cs Registers the Documents diagnostic constant.
src/​Libraries/​Microsoft.Extensions.Documents.Abstractions/​README.md Documents scope, behavior, and usage.
src/​Libraries/​Microsoft.Extensions.Documents.Abstractions/​Microsoft.Extensions.Documents.Abstractions.json Defines the experimental API baseline.
src/​Libraries/​Microsoft.Extensions.Documents.Abstractions/​Microsoft.Extensions.Documents.Abstractions.csproj Configures the new library.
src/​Libraries/​Microsoft.Extensions.Documents.Abstractions/​Document.cs Implements document ownership, traversal, versioning, and disposal.
src/​Libraries/​Microsoft.Extensions.Documents.Abstractions/​DocumentElement.cs Implements the element hierarchy and collections.
src/​Libraries/​Microsoft.Extensions.Documents.Abstractions/​DocumentReferences.cs Adds references and owned artifacts.
src/​Libraries/​Microsoft.Extensions.Documents.Abstractions/​DocumentTable.cs Adds addressable tables and Markdown projection.
test/​Libraries/​Microsoft.Extensions.Documents.Abstractions.Tests/​Microsoft.Extensions.Documents.Abstractions.Tests.csproj Configures the test project.
test/​Libraries/​Microsoft.Extensions.Documents.Abstractions.Tests/​DocumentTests.cs Tests document lifecycle and hierarchy behavior.
test/​Libraries/​Microsoft.Extensions.Documents.Abstractions.Tests/​DocumentElementTests.cs Tests common element behavior.
test/​Libraries/​Microsoft.Extensions.Documents.Abstractions.Tests/​DocumentExtensionElementTests.cs Tests opaque extension elements.
test/​Libraries/​Microsoft.Extensions.Documents.Abstractions.Tests/​DocumentImageElementTests.cs Tests image elements.
test/​Libraries/​Microsoft.Extensions.Documents.Abstractions.Tests/​DocumentReferencesTests.cs Tests references and artifacts.
test/​Libraries/​Microsoft.Extensions.Documents.Abstractions.Tests/​DocumentSectionTests.cs Tests nested sections.
test/​Libraries/​Microsoft.Extensions.Documents.Abstractions.Tests/​DocumentTableCellCollectionTests.cs Tests table-cell ownership and mutation.
test/​Libraries/​Microsoft.Extensions.Documents.Abstractions.Tests/​DocumentTableCellTests.cs Tests cell addressing.
test/​Libraries/​Microsoft.Extensions.Documents.Abstractions.Tests/​DocumentTableElementTests.cs Tests table projection and dimensions.
test/​Libraries/​Microsoft.Extensions.Documents.Abstractions.Tests/​DocumentTextElementTests.cs Tests text kinds and header levels.

🧠 Review effort: Balanced


💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

luisquintanilla added a commit to luisquintanilla/extensions that referenced this pull request Oct 13, 2026
Recover the 23-file Extraction slice from 2d28dfd57712b55f941fbb1dbf41311eeaee8c8b, replacing obsolete semantic/geometry/options/usage/metadata/OTel contracts and their tests. Retain MEDE0001, forward-port all supported targets, fix artifact failure cleanup and cancellation, and validate the focused Documents/Extraction solution.

Temporary Documents prerequisite: ff1b5ac from PR dotnet#7835, imported unchanged as 4888286. Its four production files match canonical d35d5cb74695c4ba970d6ad198006b84354badc0. Reconcile after dotnet#7835 merges; no MEDI/provider bridge is included.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@dotnet-comment-bot

Copy link
Copy Markdown
Collaborator

‼️ Found issues ‼️

Project Coverage Type Expected Actual
Microsoft.Extensions.Diagnostics.Testing Line 99 98.65 🔻
Microsoft.Extensions.Telemetry Line 93 92.41 🔻
Microsoft.Extensions.AI.OpenAI Line 75 68.24 🔻
Microsoft.Extensions.AI.OpenAI Branch 75 57.54 🔻
Microsoft.Extensions.DataIngestion.MarkItDown Line 75 4.46 🔻
Microsoft.Extensions.DataIngestion.MarkItDown Branch 75 0 🔻
Microsoft.Extensions.Diagnostics.ResourceMonitoring Line 99 96.03 🔻
Microsoft.Extensions.Diagnostics.ResourceMonitoring Branch 99 92.76 🔻
Microsoft.Extensions.Diagnostics.ResourceMonitoring.Kubernetes Line 99 97.73 🔻
Microsoft.Extensions.ServiceDiscovery.Dns Line 75 71.61 🔻
Microsoft.Extensions.ServiceDiscovery Line 75 67.81 🔻
Microsoft.Extensions.ServiceDiscovery Branch 75 71.43 🔻
Microsoft.Extensions.ServiceDiscovery.Abstractions Line 75 42.11 🔻
Microsoft.Extensions.ServiceDiscovery.Abstractions Branch 75 42.86 🔻
Microsoft.Extensions.ServiceDiscovery.Yarp Line 75 73.85 🔻
Microsoft.Extensions.ServiceDiscovery.Yarp Branch 75 70 🔻
Microsoft.Extensions.VectorData.Abstractions Line 75 37.39 🔻
Microsoft.Extensions.VectorData.Abstractions Branch 75 22.73 🔻

🎉 Good job! The coverage increased 🎉
Update MinCodeCoverage in the project files.

Project Expected Actual
Microsoft.Extensions.Http.Diagnostics 94 95
Microsoft.Gen.BuildMetadata 97 100
Microsoft.Gen.MetadataExtractor 57 73
Microsoft.Gen.MetricsReports 67 69
Microsoft.Extensions.AI.Abstractions 82 86
Microsoft.Extensions.AI.Evaluation.NLP 0 78
Microsoft.Extensions.Caching.Hybrid 82 85
Microsoft.Extensions.DataIngestion 75 89
Microsoft.Extensions.DataIngestion.Markdig 75 90
Microsoft.Extensions.Documents.Abstractions 80 90
Microsoft.Extensions.Http.Resilience 97 100

Full code coverage report: https://dev.azure.com/dnceng-public/public/_build/results?buildId=1634013&view=codecoverage-tab

Add source frames, ordered polygon regions, reported confidence, structured annotations, merged and empty table cells, and operation-scoped break-glass output with explicit ownership. Include scoped regression tests, API baseline and documentation.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
luisquintanilla added a commit to luisquintanilla/extensions that referenced this pull request Oct 14, 2026
Import the shared Documents correction from canonical commit 37dad1a, keeping production, API baseline, documentation and regression tests identical. This remains the explicit temporary prerequisite for the existing Extraction PR.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
luisquintanilla added a commit to luisquintanilla/extensions that referenced this pull request Oct 14, 2026
Transfer source frames, annotations, confidence, merged and empty table cells, structured extension values and operation-scoped native/original output into shared Documents. Add isolated per-call overrides, default raw retention with opt-out enforcement, safe cleanup, regression tests and API documentation.

The shared Documents prerequisite is isolated in d830ad6, matching dotnet#7835 commit 37dad1a. The runtime README also removes the obsolete prerequisite SHA; existing local candidates predate that documentation-only follow-up.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@dotnet-comment-bot

Copy link
Copy Markdown
Collaborator

‼️ Found issues ‼️

Project Coverage Type Expected Actual
Microsoft.Extensions.Diagnostics.Testing Line 99 98.65 🔻
Microsoft.Extensions.Telemetry Line 93 92.71 🔻
Microsoft.Extensions.AI.OpenAI Line 75 68.24 🔻
Microsoft.Extensions.AI.OpenAI Branch 75 57.54 🔻
Microsoft.Extensions.DataIngestion.MarkItDown Line 75 4.46 🔻
Microsoft.Extensions.DataIngestion.MarkItDown Branch 75 0 🔻
Microsoft.Extensions.Diagnostics.ResourceMonitoring Line 99 96.03 🔻
Microsoft.Extensions.Diagnostics.ResourceMonitoring Branch 99 92.76 🔻
Microsoft.Extensions.Diagnostics.ResourceMonitoring.Kubernetes Line 99 97.73 🔻
Microsoft.Extensions.ServiceDiscovery.Dns Line 75 68.32 🔻
Microsoft.Extensions.ServiceDiscovery Line 75 67.36 🔻
Microsoft.Extensions.ServiceDiscovery Branch 75 71.43 🔻
Microsoft.Extensions.ServiceDiscovery.Abstractions Line 75 42.11 🔻
Microsoft.Extensions.ServiceDiscovery.Abstractions Branch 75 42.86 🔻
Microsoft.Extensions.ServiceDiscovery.Yarp Line 75 73.85 🔻
Microsoft.Extensions.ServiceDiscovery.Yarp Branch 75 70 🔻
Microsoft.Extensions.VectorData.Abstractions Line 75 37.39 🔻
Microsoft.Extensions.VectorData.Abstractions Branch 75 22.73 🔻

🎉 Good job! The coverage increased 🎉
Update MinCodeCoverage in the project files.

Project Expected Actual
Microsoft.Extensions.Http.Diagnostics 94 95
Microsoft.Gen.BuildMetadata 97 100
Microsoft.Gen.MetadataExtractor 57 73
Microsoft.Gen.MetricsReports 67 69
Microsoft.Extensions.AI.Abstractions 82 86
Microsoft.Extensions.AI.Evaluation.NLP 0 78
Microsoft.Extensions.Caching.Hybrid 82 85
Microsoft.Extensions.DataIngestion 75 89
Microsoft.Extensions.DataIngestion.Markdig 75 90
Microsoft.Extensions.Documents.Abstractions 80 94
Microsoft.Extensions.Http.Resilience 97 100

Full code coverage report: https://dev.azure.com/dnceng-public/public/_build/results?buildId=1635121&view=codecoverage-tab

Pin producer roles, literal contents, spans, source frames, raw ownership, and distinct stored/structural Markdown views without changing core behavior or APIs.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@dotnet-comment-bot

Copy link
Copy Markdown
Collaborator

‼️ Found issues ‼️

Project Coverage Type Expected Actual
Microsoft.Extensions.Diagnostics.Testing Line 99 98.65 🔻
Microsoft.Extensions.Telemetry Line 93 92.71 🔻
Microsoft.Extensions.AI.OpenAI Line 75 68.24 🔻
Microsoft.Extensions.AI.OpenAI Branch 75 57.54 🔻
Microsoft.Extensions.DataIngestion.MarkItDown Line 75 4.46 🔻
Microsoft.Extensions.DataIngestion.MarkItDown Branch 75 0 🔻
Microsoft.Extensions.Diagnostics.ResourceMonitoring Line 99 96.03 🔻
Microsoft.Extensions.Diagnostics.ResourceMonitoring Branch 99 92.76 🔻
Microsoft.Extensions.Diagnostics.ResourceMonitoring.Kubernetes Line 99 97.73 🔻
Microsoft.Extensions.ServiceDiscovery.Dns Line 75 71.61 🔻
Microsoft.Extensions.ServiceDiscovery Line 75 67.21 🔻
Microsoft.Extensions.ServiceDiscovery Branch 75 71.43 🔻
Microsoft.Extensions.ServiceDiscovery.Abstractions Line 75 42.11 🔻
Microsoft.Extensions.ServiceDiscovery.Abstractions Branch 75 42.86 🔻
Microsoft.Extensions.ServiceDiscovery.Yarp Line 75 73.85 🔻
Microsoft.Extensions.ServiceDiscovery.Yarp Branch 75 70 🔻
Microsoft.Extensions.VectorData.Abstractions Line 75 37.39 🔻
Microsoft.Extensions.VectorData.Abstractions Branch 75 22.73 🔻

🎉 Good job! The coverage increased 🎉
Update MinCodeCoverage in the project files.

Project Expected Actual
Microsoft.Extensions.Http.Diagnostics 94 95
Microsoft.Gen.BuildMetadata 97 100
Microsoft.Gen.MetadataExtractor 57 73
Microsoft.Gen.MetricsReports 67 69
Microsoft.Extensions.AI.Abstractions 82 86
Microsoft.Extensions.AI.Evaluation.NLP 0 78
Microsoft.Extensions.Caching.Hybrid 82 85
Microsoft.Extensions.DataIngestion 75 89
Microsoft.Extensions.DataIngestion.Markdig 75 90
Microsoft.Extensions.Documents.Abstractions 80 94
Microsoft.Extensions.Http.Resilience 97 100

Full code coverage report: https://dev.azure.com/dnceng-public/public/_build/results?buildId=1635677&view=codecoverage-tab

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Preserve cleanup failures and attachment ownership, enforce disposed mutation guards, and add registration and table coverage regressions.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep supplied provider-native objects inspectable when original response-content capture is disabled, and scope disabled status to content only. Add focused availability and borrowing regressions and regenerate the Documents API baseline.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@dotnet-comment-bot

Copy link
Copy Markdown
Collaborator

‼️ Found issues ‼️

Project Coverage Type Expected Actual
Microsoft.Extensions.Diagnostics.Testing Line 99 98.65 🔻
Microsoft.Extensions.Telemetry Line 93 92.75 🔻
Microsoft.Extensions.AI Line 89 88.4 🔻
Microsoft.Extensions.AI.OpenAI Line 75 68.24 🔻
Microsoft.Extensions.AI.OpenAI Branch 75 57.54 🔻
Microsoft.Extensions.DataIngestion.MarkItDown Line 75 4.46 🔻
Microsoft.Extensions.DataIngestion.MarkItDown Branch 75 0 🔻
Microsoft.Extensions.Diagnostics.ResourceMonitoring Line 99 96.07 🔻
Microsoft.Extensions.Diagnostics.ResourceMonitoring Branch 99 92.76 🔻
Microsoft.Extensions.Diagnostics.ResourceMonitoring.Kubernetes Line 99 97.73 🔻
Microsoft.Extensions.ServiceDiscovery.Abstractions Line 75 42.11 🔻
Microsoft.Extensions.ServiceDiscovery.Abstractions Branch 75 42.86 🔻
Microsoft.Extensions.ServiceDiscovery.Dns Line 75 71.61 🔻
Microsoft.Extensions.ServiceDiscovery Line 75 68.26 🔻
Microsoft.Extensions.ServiceDiscovery Branch 75 71.43 🔻
Microsoft.Extensions.ServiceDiscovery.Yarp Line 75 73.85 🔻
Microsoft.Extensions.ServiceDiscovery.Yarp Branch 75 70 🔻
Microsoft.Extensions.VectorData.Abstractions Line 75 37.39 🔻
Microsoft.Extensions.VectorData.Abstractions Branch 75 22.73 🔻

🎉 Good job! The coverage increased 🎉
Update MinCodeCoverage in the project files.

Project Expected Actual
Microsoft.Extensions.Http.Diagnostics 94 95
Microsoft.Gen.BuildMetadata 97 100
Microsoft.Gen.MetadataExtractor 57 73
Microsoft.Gen.MetricsReports 67 69
Microsoft.Extensions.AI.Abstractions 82 86
Microsoft.Extensions.AI.Evaluation.NLP 0 78
Microsoft.Extensions.Caching.Hybrid 82 85
Microsoft.Extensions.DataIngestion 75 89
Microsoft.Extensions.DataIngestion.Markdig 75 90
Microsoft.Extensions.Documents.Abstractions 80 95
Microsoft.Extensions.Http.Resilience 97 100

Full code coverage report: https://dev.azure.com/dnceng-public/public/_build/results?buildId=1649717&view=codecoverage-tab

luisquintanilla and others added 4 commits October 26, 2026 13:58
Replace generalized annotations and opaque evidence/page references with a typed page association and optional polygon. Keep native inspection and explicit resource ownership; internalize bookkeeping helpers.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep canonical content and typed source ownership while removing unused element bags, extension envelopes and redundant authoring helpers. Use optional text/cell roles and explicit supplied Markdown.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Remove core rendering, adopt the complete ExtractionDocument family, and migrate payload, hierarchy, source and byte-retention contracts and tests.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@luisquintanilla
luisquintanilla marked this pull request as ready for review November 1, 2026 21:24
@dotnet-comment-bot

Copy link
Copy Markdown
Collaborator

‼️ Found issues ‼️

Project Coverage Type Expected Actual
Microsoft.Extensions.Diagnostics.Testing Line 99 98.65 🔻
Microsoft.Extensions.Telemetry Line 93 92.75 🔻
Microsoft.Extensions.AI Line 89 88.4 🔻
Microsoft.Extensions.AI.OpenAI Line 75 68.24 🔻
Microsoft.Extensions.AI.OpenAI Branch 75 57.54 🔻
Microsoft.Extensions.DataIngestion.MarkItDown Line 75 4.46 🔻
Microsoft.Extensions.DataIngestion.MarkItDown Branch 75 0 🔻
Microsoft.Extensions.Diagnostics.ResourceMonitoring Line 99 96.07 🔻
Microsoft.Extensions.Diagnostics.ResourceMonitoring Branch 99 92.76 🔻
Microsoft.Extensions.Diagnostics.ResourceMonitoring.Kubernetes Line 99 97.73 🔻
Microsoft.Extensions.ServiceDiscovery.Dns Line 75 69.93 🔻
Microsoft.Extensions.ServiceDiscovery Line 75 68.11 🔻
Microsoft.Extensions.ServiceDiscovery Branch 75 71.43 🔻
Microsoft.Extensions.ServiceDiscovery.Abstractions Line 75 42.11 🔻
Microsoft.Extensions.ServiceDiscovery.Abstractions Branch 75 42.86 🔻
Microsoft.Extensions.ServiceDiscovery.Yarp Line 75 73.85 🔻
Microsoft.Extensions.ServiceDiscovery.Yarp Branch 75 70 🔻
Microsoft.Extensions.VectorData.Abstractions Line 75 37.39 🔻
Microsoft.Extensions.VectorData.Abstractions Branch 75 22.73 🔻

🎉 Good job! The coverage increased 🎉
Update MinCodeCoverage in the project files.

Project Expected Actual
Microsoft.Extensions.Http.Diagnostics 94 95
Microsoft.Gen.BuildMetadata 97 100
Microsoft.Gen.MetadataExtractor 57 73
Microsoft.Gen.MetricsReports 67 69
Microsoft.Extensions.AI.Abstractions 82 86
Microsoft.Extensions.AI.Evaluation.NLP 0 78
Microsoft.Extensions.Caching.Hybrid 82 84
Microsoft.Extensions.DataIngestion 75 89
Microsoft.Extensions.DataIngestion.Markdig 75 90
Microsoft.Extensions.Documents.Abstractions 80 98
Microsoft.Extensions.Http.Resilience 97 100

Full code coverage report: https://dev.azure.com/dnceng-public/public/_build/results?buildId=1658891&view=codecoverage-tab

Retain interpretable source layout and borrowed native inspection while removing the operation/artifact graph. Make TextContent authoritative and preserve image transcription and structural safety.

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

@luisquintanilla luisquintanilla left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@adamsitnik can I please get a review on this.

Thanks!

@dotnet-comment-bot

Copy link
Copy Markdown
Collaborator

‼️ Found issues ‼️

Project Coverage Type Expected Actual
Microsoft.Extensions.AI Line 89 87.21 🔻
Microsoft.Extensions.AI Branch 89 79.21 🔻
Microsoft.Extensions.AI.OpenAI Line 75 68.82 🔻
Microsoft.Extensions.AI.OpenAI Branch 75 60.26 🔻
Microsoft.Extensions.DataIngestion.MarkItDown Line 75 4.46 🔻
Microsoft.Extensions.DataIngestion.MarkItDown Branch 75 0.75 🔻
Microsoft.Extensions.Diagnostics.ResourceMonitoring Line 99 96.06 🔻
Microsoft.Extensions.Diagnostics.ResourceMonitoring Branch 99 92.28 🔻
Microsoft.Extensions.Diagnostics.ResourceMonitoring.Kubernetes Line 99 97.73 🔻
Microsoft.Extensions.Diagnostics.ResourceMonitoring.Kubernetes Branch 99 92.86 🔻
Microsoft.Extensions.Diagnostics.Testing Line 99 98.22 🔻
Microsoft.Extensions.Diagnostics.Testing Branch 99 93.71 🔻
Microsoft.Extensions.ServiceDiscovery Line 75 60.92 🔻
Microsoft.Extensions.ServiceDiscovery Branch 75 64.06 🔻
Microsoft.Extensions.ServiceDiscovery.Abstractions Line 75 41.14 🔻
Microsoft.Extensions.ServiceDiscovery.Abstractions Branch 75 45.1 🔻
Microsoft.Extensions.ServiceDiscovery.Dns Line 75 64.49 🔻
Microsoft.Extensions.ServiceDiscovery.Dns Branch 75 73.96 🔻
Microsoft.Extensions.ServiceDiscovery.Yarp Line 75 73.85 🔻
Microsoft.Extensions.ServiceDiscovery.Yarp Branch 75 60 🔻
Microsoft.Extensions.Telemetry Line 93 90.46 🔻
Microsoft.Extensions.Telemetry Branch 93 86.78 🔻
Microsoft.Extensions.VectorData.Abstractions Line 75 32.15 🔻
Microsoft.Extensions.VectorData.Abstractions Branch 75 26.31 🔻

🎉 Good job! The coverage increased 🎉
Update MinCodeCoverage in the project files.

Project Expected Actual
Microsoft.Extensions.AI.Evaluation.NLP 0 74
Microsoft.Extensions.DataIngestion 75 77
Microsoft.Extensions.DataIngestion.Markdig 75 88
Microsoft.Extensions.Documents.Abstractions 80 98
Microsoft.Extensions.Http.Resilience 97 99
Microsoft.Gen.MetadataExtractor 57 72
Microsoft.Gen.MetricsReports 67 69

Full code coverage report: https://dev.azure.com/dnceng-public/public/_build/results?buildId=1660145&view=codecoverage-tab

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

@tarekgh tarekgh left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM, thanks!

@dotnet-comment-bot

Copy link
Copy Markdown
Collaborator

‼️ Found issues ‼️

Project Coverage Type Expected Actual
Microsoft.Extensions.AI Line 89 87.81 🔻
Microsoft.Extensions.AI Branch 89 79.23 🔻
Microsoft.Extensions.AI.OpenAI Line 75 68.8 🔻
Microsoft.Extensions.AI.OpenAI Branch 75 60.3 🔻
Microsoft.Extensions.DataIngestion.MarkItDown Line 75 4.46 🔻
Microsoft.Extensions.DataIngestion.MarkItDown Branch 75 0.75 🔻
Microsoft.Extensions.Diagnostics.ResourceMonitoring Line 99 96.06 🔻
Microsoft.Extensions.Diagnostics.ResourceMonitoring Branch 99 92.28 🔻
Microsoft.Extensions.Diagnostics.ResourceMonitoring.Kubernetes Line 99 97.73 🔻
Microsoft.Extensions.Diagnostics.ResourceMonitoring.Kubernetes Branch 99 92.86 🔻
Microsoft.Extensions.Diagnostics.Testing Line 99 98.22 🔻
Microsoft.Extensions.Diagnostics.Testing Branch 99 93.66 🔻
Microsoft.Extensions.ServiceDiscovery Line 75 59.08 🔻
Microsoft.Extensions.ServiceDiscovery Branch 75 64.41 🔻
Microsoft.Extensions.ServiceDiscovery.Abstractions Line 75 41.14 🔻
Microsoft.Extensions.ServiceDiscovery.Abstractions Branch 75 45.1 🔻
Microsoft.Extensions.ServiceDiscovery.Dns Line 75 60.22 🔻
Microsoft.Extensions.ServiceDiscovery.Dns Branch 75 73.96 🔻
Microsoft.Extensions.ServiceDiscovery.Yarp Line 75 73.85 🔻
Microsoft.Extensions.ServiceDiscovery.Yarp Branch 75 60 🔻
Microsoft.Extensions.Telemetry Line 93 90.47 🔻
Microsoft.Extensions.Telemetry Branch 93 86.83 🔻
Microsoft.Extensions.VectorData.Abstractions Line 75 32.15 🔻
Microsoft.Extensions.VectorData.Abstractions Branch 75 26.31 🔻

🎉 Good job! The coverage increased 🎉
Update MinCodeCoverage in the project files.

Project Expected Actual
Microsoft.Extensions.AI.Evaluation.NLP 0 74
Microsoft.Extensions.DataIngestion 75 77
Microsoft.Extensions.DataIngestion.Markdig 75 88
Microsoft.Extensions.Documents.Abstractions 80 98
Microsoft.Extensions.Http.Resilience 97 99
Microsoft.Gen.MetadataExtractor 57 72
Microsoft.Gen.MetricsReports 67 69

Full code coverage report: https://dev.azure.com/dnceng-public/public/_build/results?buildId=1664674&view=codecoverage-tab

@luisquintanilla
luisquintanilla merged commit c3bb497 into dotnet:main Nov 5, 2026
5 checks passed
luisquintanilla added a commit that referenced this pull request Nov 5, 2026
…ns (#7588)

* Add IOcrClient OCR/document-extraction capability to Microsoft.Extensions.AI

Introduces IOcrClient as a provider-neutral OCR/document-parsing capability in
Microsoft.Extensions.AI.Abstractions, following the same abstraction + builder +
middleware + DI shape as the existing capability family (IChatClient,
ISpeechToTextClient, etc.).

Abstractions (Microsoft.Extensions.AI.Abstractions):
- IOcrClient, DelegatingOcrClient, OcrClientExtensions, OcrClientMetadata
- OcrOptions, OcrResult, OcrPage, OcrTable, OcrTableCell, OcrBlock,
  OcrBoundingRegion, OcrUsage, OcrProgress

Middleware + DI (Microsoft.Extensions.AI):
- OcrClientBuilder, AsBuilder, AddOcrClient/AddKeyedOcrClient
- LoggingOcrClient, OpenTelemetryOcrClient, ConfigureOptionsOcrClient and their
  builder extensions, mirroring the ISpeechToTextClient template

All public surface is marked [Experimental] under the MEAI001 (AIOcr) diagnostic id.
Includes unit tests for both libraries and updated API baselines.

* Add OcrImage type and OcrPage.Images for extracted figures

Adds an optional OcrImage sink so engines can return page images/figures when
OcrOptions.IncludeImages is requested. Every member is optional: document-native
engines (Mistral OCR inline images, Azure Document Intelligence figures) populate
Content with rendered bytes; a vision-LLM transcriber may populate only Caption.
One shape serves both provider archetypes.

* Add UriContent overload to OcrClientExtensions

Symmetric with the existing DataContent overload. Handles self-contained data:
URIs by delegating to the DataContent path and does no file/network IO. For file:
and remote URIs it throws NotSupportedException, leaving native URL passthrough
(Mistral document_url, Azure DI uriSource) as an explicit open design question.

* Rename IOcrClient.GetTextAsync to ExtractAsync

The method returns a rich OcrResult (markdown, tables, figures/images, blocks,
confidence, language), not plain text, so GetTextAsync was a misnomer. ExtractAsync
names the document-extraction operation accurately. Scoped to the Ocr/ types only;
ISpeechToTextClient.GetTextAsync is unrelated and unchanged.

Alternatives considered for maintainer discussion: GetDocumentAsync, AnalyzeAsync.

* Add OcrImage to IngestionDocumentImage reader mapping

* Add ExtractFromUriAsync opt-in remote downloader to IOcrClient extensions

* Finish GetTextAsync to ExtractAsync rename in OCR tests and API baselines

Complete the source rename across the OCR test suites in both
Microsoft.Extensions.AI.Abstractions.Tests and Microsoft.Extensions.AI.Tests, and
regenerate the two API baselines (which also reflect the round-2 members
ExtractFromUriAsync, OcrImage, and OcrPage.Images). Also fix pre-existing StyleCop/Sonar
violations in the OCR tests that were blocking the core test project from compiling.

* Fix net462 build: use buffered Stream.CopyToAsync overload in OCR test

Stream.CopyToAsync(Stream, CancellationToken) does not exist on net462/
netstandard2.0, so the 2-arg call failed to compile (CS1503) on the
net462 leg. Use the #if !NET conditional buffer-size overload, matching
the existing DataContent.cs convention.

* Shape OCR bounding geometry as points and 1-base page numbers

Introduce OcrPoint and OcrBoundingBox readonly record structs and retype
OcrBoundingRegion.Polygon as IReadOnlyList<OcrPoint> with a typed
OcrBoundingBox GetBounds() return. This makes odd or empty vertex lists
unrepresentable (fixing the GetBounds inverted-bounds edge case) and reads
self-documenting, while still carrying a rotation-skewed quadrilateral.

Rename OcrPage.Index (zero-based) to OcrPage.PageNumber (one-based) so it
correlates directly with OcrBoundingRegion.PageNumber, matching Azure
Document Intelligence, PdfPig, and human page conventions, and removing the
off-by-one adjustments providers had to make.

Update the internal OcrDocumentReader and the OCR tests, and regenerate the
Microsoft.Extensions.AI.Abstractions API baseline.

* Align IOcrClient surface with the MEAI family ahead of API review

Family-consistency changes surfaced by an API-review rehearsal against the
sibling abstractions (IChatClient, ISpeechToTextClient):

- Streaming: add IAsyncEnumerable<OcrResponseUpdate> via ExtractStreamingAsync
  (the unary/streaming/GetService triad, matching IChatClient) plus a
  ToOcrResult/ToOcrResultAsync reducer; retire IProgress<OcrProgress> and the
  OcrProgress type (progress folds onto OcrResponseUpdate).
- Unseal the OCR DTOs (OcrOptions, OcrResult, OcrPage, OcrBlock, OcrTable,
  OcrTableCell, OcrImage, OcrBoundingRegion, OcrUsage) to mirror the unsealed
  ChatResponse/ChatOptions family shape.
- Geometry units: add OcrPage.Width/Height and an OcrCoordinateUnit
  (ChatRole-style open struct: Pixel/Inch/Normalized) so bounding coordinates
  are interpretable across engines.
- Model OcrBlock.Kind and OcrTableCell.Kind as ChatRole-style open structs
  (OcrBlockKind, OcrTableCellKind) instead of raw strings.
- OcrBoundingRegion.GetBounds() now returns OcrBoundingBox? (null on empty
  polygon) instead of an ambiguous all-zero default.
- Remove the leaky OcrResult.OcrSource; document OcrTable.Cells as
  authoritative when non-null.
- Add <exception> docs to the AddOcrClient/AddKeyedOcrClient overloads.

Updates the middleware (Logging/OpenTelemetry/ConfigureOptions), the MEDI
OcrDocumentReader consumer, OCR tests, and both API baselines accordingly.

* Reshape OCR result model: reading-order elements, doc-level coordinates, usage tokens

Continue the IOcrClient reshape ahead of API review (#7587/#7588).

- Replace parallel OcrPage.Blocks/Tables/Images with a single reading-order
  Elements list over a new polymorphic OcrElement base (OcrBlock/OcrTable/OcrImage
  derive); consumers project with OfType<T>().
- Add optional nested OcrTableCell.Elements for structured cell content; keep the
  Content string as a flat-text convenience.
- Convert OcrCoordinateUnit to a closed enum and add Point; add an
  OcrCoordinateOrigin enum; move both to document level (OcrResult/OcrPageResult)
  and remove the per-page CoordinateUnit.
- Keep OcrBlockKind and OcrTableCellKind as open structs; add RowHeader and
  RowSection well-known cell kinds.
- Add nullable Input/Output/TotalTokenCount to OcrUsage for the vision-LLM path.
- Rename Markdown to Text on OcrPage/OcrResult; drop response ModelId,
  OcrPage.Confidence, and OcrOptions.IncludeImages; FromRectangle takes float.
- Keep ToOcrResult/ToOcrResultAsync reducers and the convenience overloads as
  extension methods, matching the MEAI ChatResponseExtensions precedent.
- Regenerate the ApiChief baselines for the reshaped surface.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 19ea13dd-f444-4942-b751-162711478580

* Move OCR coordinate frame per-page; add OcrPageDimensions (SPIKE-07/08)

SPIKE-07/08 primary-source verification refuted the round-1 assumption that a
document uses one uniform coordinate unit. Google Document AI models
Page.Dimension{width,height,unit} per page, and Azure DI's per-page
DocumentPage.Unit is "pixel" for image inputs and "inch" for PDF, so one
analyze call over a mixed batch returns different units on different pages.

- Group OcrPage.Width/Height into a new OcrPageDimensions readonly record
  struct (the extent; an atomic pair several engines bundle).
- Move CoordinateUnit + CoordinateOrigin from the document level (OcrResult,
  OcrPageResult) onto OcrPage; they are siblings to the dimensions extent,
  together describing the per-page coordinate system.
- Drop the reducer's last-non-null coordinate carry-forward: pages already
  carry their own unit/origin.
- Defer continuous page-rotation angle (Azure-family-only) to
  AdditionalProperties for v1; element rotation is already carried losslessly
  by the polygon OcrBoundingRegion.
- Update per-page tests and regenerate the ApiChief baseline (32 public types).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 19ea13dd-f444-4942-b751-162711478580

* Add per-cell geometry and OcrPage.RawRepresentation (SPIKE-06)

SPIKE-06 built an exhaustive 14-engine raw-output inventory to justify the
RawRepresentation/AdditionalProperties escape hatches, then a promote interview
resolved which recurring un-homed fields become first-class.

- Add BoundingRegion, Confidence, RawRepresentation, and AdditionalProperties to
  OcrTableCell, mirrored member-for-member from OcrElement. Five engines (Textract,
  Google Document AI, Azure DI, Adobe, Docling) emit per-cell geometry, and a cell
  has its own rectangle even when empty or padded. OcrTableCell deliberately does
  not derive from OcrElement (a cell is not a page-reading-order element) and no
  shared base type is extracted yet; mirroring the members keeps that a reversible
  way-station under [Experimental].
- Add [JsonIgnore] object? RawRepresentation to OcrPage. Every other node carries
  it; the page node was the lone exception. Because the page rides through
  ToOcrResult reduction, provider-native page data now survives into
  OcrResult.Pages, closing a silent per-page raw data-loss.
- Detected language is deferred (not promoted) to a standardized
  AdditionalProperties key rather than a lossy typed field.
- Add OCR tests for cell geometry round-trip and per-page raw survival; regenerate
  the ApiChief baseline (five additive members, no new types).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 19ea13dd-f444-4942-b751-162711478580

* Extract OCR into Microsoft.Extensions.DocumentExtraction peer library

Move the reshaped OCR surface out of Microsoft.Extensions.AI(.Abstractions)
into a standalone peer library, Microsoft.Extensions.DocumentExtraction,
mirroring VectorData / DataIngestion. OCR is document extraction rather than
an AI-branded concern, so it gets its own package + namespace
(Microsoft.Extensions.DocumentExtraction) with domain-noun naming
(Document*/DocumentExtraction*) instead of the MEAI-internal verb scheme.

- New Microsoft.Extensions.DocumentExtraction.Abstractions: the Document*
  model, IDocumentExtractionClient, DocumentExtractionResult/Options/
  ClientMetadata/PageResult, extensions, DelegatingDocumentExtractionClient.
- New Microsoft.Extensions.DocumentExtraction: builder + Logging/
  OpenTelemetry/ConfigureOptions delegating clients + DI/builder extensions,
  with self-contained internal telemetry helpers (no MEAI-core coupling).
- Remove the OCR types from Microsoft.Extensions.AI(.Abstractions) and shrink
  both API baselines accordingly (only OCR type-blocks removed; the manual
  params edits and JSONC comments are preserved byte-for-byte).
- Populate the two new Stage=normal baselines (peer precedent: VectorData
  ships a populated baseline for its [Experimental] surface).
- Repoint Microsoft.Extensions.DataIngestion's OcrDocumentReader onto
  DocumentExtraction.Abstractions.
- Add DiagnosticIds MEDE0001 for the new [Experimental] surface.
- Retarget all OCR tests to two new DocumentExtraction test projects.

Green across all five TFMs (netstandard2.0, net462, net8.0, net9.0,
net10.0); DocumentExtraction tests 31/31 + 29/29 on net8/9/10; the MEDI
OcrDocumentReader test stays green after the repoint.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 19ea13dd-f444-4942-b751-162711478580

* Fix CI: remove dangling TestOcrClient.cs <Compile> link

The OCR test helper moved to Microsoft.Extensions.DocumentExtraction.Abstractions.Tests
(TestDocumentExtractionClient.cs) during the extraction, but Microsoft.Extensions.AI.Tests.csproj
still linked the moved-away ..\Microsoft.Extensions.AI.Abstractions.Tests\TestOcrClient.cs,
causing error CS2001 (source file not found) on all TFMs in CI. No MEAI test references any
Ocr type, so the link is safe to delete.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 19ea13dd-f444-4942-b751-162711478580

* Add README.md for the DocumentExtraction packages

Every packable library in the repo ships a README.md (auto-included as PackageReadmeFile on
pack); the two new DocumentExtraction packages were missing theirs, so packing failed with
NU5019. Add READMEs mirroring the DataIngestion peers, describing the document-extraction
capability and the Abstractions-vs-core package split.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 19ea13dd-f444-4942-b751-162711478580

* Add experimental shared Documents abstractions

Introduce the provider-neutral Documents hierarchy, ownership and artifact lifetime contracts as a standalone prerequisite for document extraction. Include experimental diagnostic registration, API baseline, documentation and focused tests.

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

* Recover selected Extraction contract over shared Documents

Recover the 23-file Extraction slice from 2d28dfd57712b55f941fbb1dbf41311eeaee8c8b, replacing obsolete semantic/geometry/options/usage/metadata/OTel contracts and their tests. Retain MEDE0001, forward-port all supported targets, fix artifact failure cleanup and cancellation, and validate the focused Documents/Extraction solution.

Temporary Documents prerequisite: ff1b5ac from PR #7835, imported unchanged as 4888286. Its four production files match canonical d35d5cb74695c4ba970d6ad198006b84354badc0. Reconcile after #7835 merges; no MEDI/provider bridge is included.

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

* Exclude obsolete unrelated AI baseline whitespace

Keep the Extraction recovery diff limited to its own contracts and the explicit Documents prerequisite; drop the old PR's unrelated AI baseline newline-only change. Validated production source is unchanged.

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

* Sync Documents layout fidelity prerequisite from #7835

Import the shared Documents correction from canonical commit 37dad1a, keeping production, API baseline, documentation and regression tests identical. This remains the explicit temporary prerequisite for the existing Extraction PR.

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

* Preserve extraction layout, structured values and raw-output controls

Transfer source frames, annotations, confidence, merged and empty table cells, structured extension values and operation-scoped native/original output into shared Documents. Add isolated per-call overrides, default raw retention with opt-out enforcement, safe cleanup, regression tests and API documentation.

The shared Documents prerequisite is isolated in d830ad6, matching #7835 commit 37dad1a. The runtime README also removes the obsolete prerequisite SHA; existing local candidates predate that documentation-only follow-up.

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

* Fix extraction cleanup and per-build logging correctness

Preserve initiating extraction failures while attempting all eligible artifact cleanup; leave foreign-owned artifacts untouched. Resolve logging factories independently per pipeline build and document the existing shared-instance DI lifetime behavior with independent factory regressions.

Synchronize the already-verified canonical Documents prerequisite repairs and fidelity tests without changing public APIs, raw defaults, registration lifetimes, package placement, or table projection. Exact 18-path tree matches frozen tested tree 2d8def9. Fresh bounded validation: five production targets, zero build warnings/errors; 87 abstraction, 12 middleware, and 197 prerequisite cases per net10/net9/net8/net472 target, all passing.

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

* Separate native inspection from response-content capture

Keep supplied provider-native objects inspectable when original response-content capture is disabled, and scope disabled status to content only. Add focused availability and borrowing regressions and regenerate the Documents API baseline.

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

* Separate Extraction native inspection from optional response content

Default CaptureRawContent to false without gating native source or annotation objects. Reject retained body-policy violations while preserving existing ownership and cleanup. Regenerate the API baseline and document availability and non-redaction semantics.

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

* Preserve Extraction primary failures and verify raw-content policy

Cover capture defaults, native identity, exact opt-in body bytes, nested policy violations, ownership and cleanup across all supported test targets. Preserve enumeration errors and cancellation when artifact or enumerator cleanup also fails.

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

* Reduce Documents to typed content and source references

Replace generalized annotations and opaque evidence/page references with a typed page association and optional polygon. Keep native inspection and explicit resource ownership; internalize bookkeeping helpers.

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

* Reduce Extraction associations to typed sources and metadata snapshots

Align the reduced shared Documents prerequisite, replace generalized annotations and evidence with source references, and transfer provider-specific metadata snapshots without introducing normalized schemas. Preserve blank-page/source registration, independent native inspection, nested body-policy enforcement, ownership and primary-failure cleanup guarantees. Regenerate the real API baseline.

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

* Internalize Extraction result disposal bookkeeping

Keep disposal behavior public without exposing an unconsumed bookkeeping flag in the reduced contract. Regenerate the real API baseline.

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

* Migrate Extraction regressions to reduced source and metadata contract

Verify typed source ordering and snapshots, metadata transfer and borrowing, reduced public API, native access independent of content capture, recursive policy enforcement and existing cleanup guarantees across supported test targets.

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

* Migrate Documents regressions to reduced source references

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

* Keep reduced Extraction lifetime fixtures analyzer-clean

Use explicit fixture ownership and test-context task creation while preserving primary-error, cancellation and borrowed-native lifetime assertions. Leave pre-existing file-size style warnings outside this bounded correction.

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

* Simplify Documents to an exchange-first contract

Keep canonical content and typed source ownership while removing unused element bags, extension envelopes and redundant authoring helpers. Use optional text/cell roles and explicit supplied Markdown.

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

* Use a direct Documents exchange boundary for extraction

Compile-prerequisite snapshot, not final acceptance: return Task<Document> directly, remove public staging and finalization protocol, snapshot delegation options and log lifecycle without serializing payloads. Preserve caller input and returned document ownership, including cleanup when completion logging fails. Regenerate real API baselines and document independent Documents/Extraction/consumer composition. Final direct-contract regression validation follows separately.

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

* Validate direct document extraction and composition ownership

Replace retired staging-only regressions with direct canonical-document exchange, source-body/native lifetime, options snapshot, cancellation/error and middleware composition tests. Verify unreturned documents are released when completion logging fails and preserve primary errors on cleanup or failure logging. Actual four-target runners and integrated build pass; staging retirements and quality review are recorded in isolated session artifacts.

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

* Apply surgical document extraction API review corrections

Preserve the reviewed data model, remove structural rendering, and correct client lifetime and cleanup contracts.

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

* Simplify preview document and extraction contracts

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

* Replace extraction interface with an evolvable abstract client

Migrate composition and DI to the abstract client, preserve extraction and cleanup semantics, qualify logging failures, and remove the unused logging configuration callback.

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

* Sync accepted Documents prerequisite from locked public snapshot

Copy exactly six reviewed Documents source, API inventory, documentation and regression-test blobs from e08fe2e so Extraction provides one coherent public bootstrap source snapshot.

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

* Make extraction package READMEs consumer-focused

Document package selection, installation and practical extraction, logging and DI examples without development history or PR lifecycle guidance.

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

---------

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

Labels

area-ai Microsoft.Extensions.AI libraries

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants