Add AI Extensions API Design Proposal#32545
Conversation
This document outlines the API design proposal for integrating AI services into .NET MAUI applications using dependency injection. It includes various options for registration, usage scenarios, design questions, and recommendations for implementation.
|
/review -b feature/refactor-copilot-yml |
MauiBot
left a comment
There was a problem hiding this comment.
Expert Review — 5 findings
See inline comments for details.
|
|
||
| public async Task SendMessage(string text) | ||
| { | ||
| var response = await _chatClient.CompleteAsync(text); |
There was a problem hiding this comment.
[moderate] Public API Surface — This sample appears to target Microsoft.Extensions.AI.IChatClient, but the repository usage calls GetResponseAsync(...) and reads response.Text; there is no CompleteAsync usage in the AI source. The method also returns text from a Task-returning method. Please update the example to compile against the actual abstraction so this design doc does not steer implementers toward the wrong API shape.
| ```csharp | ||
| // Explicit per platform | ||
| services.AddAppleIntelligenceChatClient(); | ||
| services.AddMLKitChatClient(); |
There was a problem hiding this comment.
[moderate] Cross-Platform Consistency — AddMLKitChatClient()/MLKitChatClient and the Windows equivalents are presented as concrete platform registrations, but the current AI surface in this repo only contains the Apple Intelligence and Natural Language implementations (plus OpenAI sample wiring). Please mark the Android/Windows names as proposed placeholders or add design detail for the missing implementations; otherwise the API proposal implies platform parity that does not exist.
| **Recommendation: Last one wins** (standard DI behavior) | ||
| ```csharp | ||
| services.AddAI(); // Registers platform client | ||
| services.AddSingleton<IChatClient>(new MyCustomClient()); // Replaces it |
There was a problem hiding this comment.
[moderate] Handler Mapper and Property Patterns — AddSingleton<IChatClient>(...) does not actually replace an earlier descriptor; Microsoft DI returns the last registration for single-service resolution, but all registrations remain visible through IEnumerable<IChatClient> and to decoration patterns. If the intended behavior is replacement, the design should specify Replace/remove semantics; otherwise reword this to avoid implementers assuming the prior client is removed.
| builder.Services.AddAIChatClient(); | ||
|
|
||
| // Wrap with fallback client (future work) | ||
| builder.Services.Decorate<IChatClient>((inner, sp) => |
There was a problem hiding this comment.
[moderate] Build & MSBuild — IServiceCollection.Decorate<T> is not part of Microsoft.Extensions.DependencyInjection.Abstractions; it typically comes from Scrutor or a container-specific extension. Since the goals include working with Microsoft DI and third-party containers, either call out the extra dependency/container requirement or show a portable registration pattern for the fallback client.
| - Adds API surface area | ||
|
|
||
| 4. **What's the package structure?** | ||
| - Core extensions in `Microsoft.Maui.AI` |
There was a problem hiding this comment.
[major] Public API Surface — The recommended package/namespace is Microsoft.Maui.AI, but the existing repo package and root namespace are Microsoft.Maui.Essentials.AI. If this proposal intentionally renames/splits the package, it needs migration and compatibility guidance; otherwise the design should align with the existing package identity to avoid creating a parallel AI surface.
This comment has been minimized.
This comment has been minimized.
|
@mattleibow is this one ready? |
|
/review -b feature/enhanced-reviewer -p windows |
MauiBot
left a comment
There was a problem hiding this comment.
Expert Review — 5 findings
See inline comments for details.
|
|
||
| public async Task SendMessage(string text) | ||
| { | ||
| var response = await _chatClient.CompleteAsync(text); |
There was a problem hiding this comment.
[major] API correctness — This sample does not match Microsoft.Extensions.AI: IChatClient exposes GetResponseAsync/GetStreamingResponseAsync, not CompleteAsync, and ChatResponse exposes Text/Messages, not Message.Text. As written, the first ViewModel sample will not compile and would mislead future API docs. Use the current shape, e.g. var response = await _chatClient.GetResponseAsync(text); return response.Text;.
| ```csharp | ||
| // Explicit per platform | ||
| services.AddAppleIntelligenceChatClient(); | ||
| services.AddMLKitChatClient(); |
There was a problem hiding this comment.
[moderate] Platform/package accuracy — The explicit platform API lists Android/Windows local providers such as MLKitChatClient and WindowsAIChatClient as if they exist today, but the current src/AI package only contains Apple Intelligence chat and Natural Language embeddings; Android/Windows item groups are empty. Please mark these as future placeholders or define the actual provider availability/fallback behavior so the proposal does not imply local AI exists on all MAUI targets.
| ### 3. Multiple Registrations | ||
| **What happens if user calls `AddAI()` twice?** | ||
|
|
||
| **Recommendation: Last one wins** (standard DI behavior) |
There was a problem hiding this comment.
[major] DI semantics — “Last one wins” is only true when resolving a single service from default Microsoft DI; adding another IChatClient descriptor does not replace the previous one, and IEnumerable<IChatClient> or decorators will still see multiple registrations. For an idempotent AddAI API, the proposal should explicitly choose TryAdd, Replace/RemoveAll, or keyed/named clients and describe duplicate-call behavior.
| builder.Services.AddAIChatClient(); | ||
|
|
||
| // Wrap with fallback client (future work) | ||
| builder.Services.Decorate<IChatClient>((inner, sp) => |
There was a problem hiding this comment.
[major] Microsoft DI compatibility — IServiceCollection.Decorate is not provided by the default Microsoft.Extensions.DependencyInjection stack; it is a Scrutor-style extension. This conflicts with the stated goal of working with Microsoft DI out of the box. Please either show a default-DI-compatible wrapper registration or explicitly call out the required package.
| - Adds API surface area | ||
|
|
||
| 4. **What's the package structure?** | ||
| - Core extensions in `Microsoft.Maui.AI` |
There was a problem hiding this comment.
[major] Package/API consistency — The repo already has an AI package with PackageId/assembly name Microsoft.Maui.Essentials.AI and current Apple Intelligence types. Recommending a new Microsoft.Maui.AI package without explaining the relationship, migration, or split creates package identity ambiguity. Please align with the existing package or document the rename/split plan.
MauiBot
left a comment
There was a problem hiding this comment.
AI Review Summary
@mattleibow — new AI review results are available based on this last commit:
69bc805.
Add AI Extensions API Design Proposal To request a fresh review after new comments or commits, comment/review rerun.
Review Sessions — click to expand
Gate — Test Before & After Fix
Gate Result: ⚠️ SKIPPED
No tests were detected in this PR.
Recommendation: Add tests to verify the fix using the write-tests-agent.
Pre-Flight — Context & Validation
Issue: Unknown - GitHub CLI unauthenticated; linked issue could not be fetched
PR: #32545 - Adds docs/design/ai-extensions-api-design.md
Platforms Affected: Documentation/design only; proposed APIs discuss iOS, Mac Catalyst, macOS, Android, and Windows
Files Changed: 0 implementation, 0 test, 1 documentation/design
Key Findings
- Environment blocker:
gh pr view 32545failed because GitHub CLI is unauthenticated, so issue/PR narrative, comments, and review discussion were unavailable. - Local review branch
pr-review-32545contains PR #32545 as squashed commit6ea55fee66; the local diff adds one design document:docs/design/ai-extensions-api-design.md. - Gate was already completed separately and skipped because no tests were detected; no
gate/content.mdwas created or overwritten here. - Regression check was already completed separately and skipped because no implementation files were modified.
- The proposal conflicts with existing
src/AI/src/Essentials.AIpackage facts in several places:IChatClientAPI usage, DI registration semantics, package identity, platform-provider availability, and default Microsoft DI capabilities.
Code Review Summary
Verdict: NEEDS_CHANGES
Confidence: high
Errors: 2 | Warnings: 3 | Suggestions: 0
Key code review findings:
- ❌
docs/design/ai-extensions-api-design.md:54-57sample uses_chatClient.CompleteAsync(text)/response.Message.Text, which does not matchMicrosoft.Extensions.AI.IChatClientas implemented byAppleIntelligenceChatClient(GetResponseAsync/GetStreamingResponseAsyncreturningChatResponse). - ❌
docs/design/ai-extensions-api-design.md:345-354says “Last one wins” and “Replaces it”; Microsoft DI single-service resolution returns the last registration, but earlier descriptors remain and still appear inIEnumerable<IChatClient>unless explicitly removed orTryAdd*/Replaceis used. ⚠️ docs/design/ai-extensions-api-design.md:454-456and480-483recommendMicrosoft.Maui.AI, while the repo already contains the experimentalMicrosoft.Maui.Essentials.AIpackage with Apple implementations.⚠️ docs/design/ai-extensions-api-design.md:79-81and306-314present Android/Windows provider methods as equivalent concrete APIs, but existing docs say Android and Windows have no built-in providers yet.⚠️ docs/design/ai-extensions-api-design.md:429-440usesIServiceCollection.Decorate, which is not part of default Microsoft.Extensions.DependencyInjection.
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #32545 | Add initial DI extension-method design proposal for MAUI AI services | docs/design/ai-extensions-api-design.md |
Original PR; documentation-only |
Code Review — Deep Analysis
Code Review — PR #32545
Independent Assessment
What this changes: Adds a new design document proposing DI extension methods for MAUI AI service registration.
Inferred motivation: Establish an easy, progressive-disclosure API for registering local/on-device AI services in MauiProgram.cs.
Reconciliation with PR Narrative
gh is not authenticated, so I could not read the PR narrative. Review is based on the local squashed commit at HEAD on pr-review-32545.
Findings
❌ Error — Sample IChatClient usage does not match Microsoft.Extensions.AI
docs/design/ai-extensions-api-design.md:54-57
The sample uses:
var response = await _chatClient.CompleteAsync(text);
return response.Message.Text;The existing MAUI AI package uses Microsoft.Extensions.AI.IChatClient, whose primary API is GetResponseAsync(...) / GetStreamingResponseAsync(...), returning ChatResponse. This example is likely misleading for the very abstraction the document is proposing around.
❌ Error — “Last one wins / replaces it” is not accurate DI behavior
docs/design/ai-extensions-api-design.md:345-354
Microsoft DI returns the last registration for single-service resolution, but previous registrations remain in the service collection and still appear in IEnumerable<IChatClient>. Calling AddAI() twice would likely duplicate services unless the extension uses TryAdd*, Replace, or explicitly removes prior descriptors. The doc should distinguish “single resolution returns the last registration” from true replacement/idempotency.
⚠️ Warning — Package and namespace recommendation conflicts with existing MAUI AI package
docs/design/ai-extensions-api-design.md:454-456, 480-483
The document recommends Microsoft.Maui.AI, but the repository already contains Microsoft.Maui.Essentials.AI with AppleIntelligenceChatClient, NLEmbeddingGenerator, samples, tests, and package metadata. If this proposal intentionally renames or supersedes that package, it should say so and discuss migration/API compatibility; otherwise it should align with the existing package identity.
⚠️ Warning — Android/Windows provider examples imply capabilities not present today
docs/design/ai-extensions-api-design.md:79-81, 306-314
The doc proposes AddMLKitChatClient() and AddWindowsAIChatClient(), but the existing Essentials.AI README says Android and Windows currently have no built-in on-device providers. Also, “ML Kit chat client” is a questionable naming/API claim without explaining the underlying Android chat model provider. This should be framed as future/placeholder API, not as an equivalent platform implementation.
⚠️ Warning — Decorate<IChatClient> example is not available in default Microsoft DI
docs/design/ai-extensions-api-design.md:429-440
IServiceCollection.Decorate is not part of Microsoft.Extensions.DependencyInjection by default; it usually comes from Scrutor or a third-party container. Since the goals explicitly include working with Microsoft DI, this example should either avoid Decorate, mention the extra package/container requirement, or show a pure Microsoft DI-compatible wrapper registration.
Devil’s Advocate
This is a proposal document, so some placeholder names and future platform references are acceptable. However, several examples are presented as concrete MAUI/.NET patterns and conflict with existing repo APIs or Microsoft DI semantics. Those are likely to mislead implementation and review discussions if left uncorrected.
Inline findings JSON
[]Verdict: NEEDS_CHANGES
Confidence: high
Summary: The document is useful as a starting point, but it contains concrete API and DI inaccuracies that should be corrected before merging as design guidance. The main issues are misleading Microsoft.Extensions.AI usage, inaccurate DI replacement behavior, and inconsistency with the existing Microsoft.Maui.Essentials.AI package.
Fix — Analysis & Comparison
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| 1 | try-fix | Surgical documentation correction: keep the PR's structure and fix inaccurate IChatClient, Microsoft DI, package identity, provider availability, and Decorate guidance |
✅ PASS | 1 file | Best balance of correctness and usefulness; preserves the author's recommended Option 5 while removing misleading claims |
| 2 | try-fix | Provider-agnostic rewrite: add existing-package context and convert uncertain Android/Windows/package details into placeholders/open questions | ✅ PASS | 1 file | Safer against future staleness, but less concrete and slightly less useful as actionable design guidance |
| PR | PR #32545 | Add initial DI extension-method design proposal for MAUI AI services | 1 file | Original PR contains concrete API/DI/package claims that expert review found inaccurate |
Cross-Pollination
| Model | Round | New Ideas? | Details |
|---|---|---|---|
| maui-expert-reviewer | 1 | Yes | Identified concrete accuracy issues: IChatClient sample API mismatch, incorrect Microsoft DI replacement wording, package identity conflict with Microsoft.Maui.Essentials.AI, unsupported Android/Windows provider implications, and Scrutor-only Decorate usage. These informed try-fix-1. |
| maui-expert-reviewer | 2 | Yes | Proposed a materially different provider-agnostic rewrite rather than surgical line fixes. This informed try-fix-2. |
Test Results
| # | Command | Result | Output |
|---|---|---|---|
| 1 | git diff --check HEAD |
✅ PASS | No output |
| 2 | git diff --check HEAD |
✅ PASS | No output |
Gate and regression checks were not re-run. The provided gate result remains ⚠️ SKIPPED — no tests detected in this PR; the existing regression-check artifact says no implementation files were modified.
Failure/Learning Summary
No candidate failed validation, so no failure output needed to be fed into a subsequent generation step. The expert-review loop still produced a second materially different approach to check whether a broader rewrite would be preferable to a surgical correction.
Selection
Exhausted: Yes — the meaningful alternatives for this documentation-only PR are (1) surgical correction while preserving the proposal structure, or (2) a broader provider-agnostic rewrite. Additional attempts would be minor wording variations of these two strategies.
Selected Fix: Candidate #1 — It fixes all expert-reviewed correctness issues while preserving the PR's concrete design value and the author's overall Option 5 recommendation. Candidate #2 is also valid, but it trades too much specificity for safety; it is best if maintainers want the design document to avoid concrete provider/package commitments until those decisions are finalized.
Report — Final Recommendation
Comparative Report - PR #32545
Candidates compared
| Rank | Candidate | Result | Assessment |
|---|---|---|---|
| 1 | pr-plus-reviewer |
Pass/usable; gate not re-run | Best candidate. It applies the expert review's concrete corrections while preserving the PR's useful design shape and Option 5 recommendation. |
| 2 | try-fix-1 |
Pass | Substantively equivalent to pr-plus-reviewer: a surgical documentation correction for the same API, provider, DI, decoration, and package-identity issues. Ranked just below because the requested reviewer-applied PR candidate captures the same fix as the direct expert-review outcome. |
| 3 | try-fix-2 |
Pass | Correct and safe, but less concrete. It rewrites the proposal to be provider-agnostic and converts uncertain details into open questions, which reduces risk of stale guidance but makes the design less immediately actionable. |
| 4 | pr |
Gate skipped; expert review found blocking doc accuracy issues | Raw PR is valuable as a starting point but should not win because it contains non-compiling IChatClient sample code, misleading Microsoft DI replacement wording, unsupported Android/Windows provider implications, default-DI-incompatible Decorate usage, and ambiguous package guidance. |
No candidate failed regression tests. The provided gate result for the PR remained skipped because no tests were detected, and no gate verification was re-run.
Winning candidate
Winner: pr-plus-reviewer
pr-plus-reviewer wins because it fixes every actionable expert-review finding without unnecessarily broadening the scope of the design document. It is tied in substance with try-fix-1, but it is the better final recommendation because it represents the PR fix plus reviewer feedback applied, rather than an independent alternative that would need to replace the PR wholesale.
Notes for author
The PR is documentation-only, so no automated tests were detected. The author should consider whether this design doc can be backed by API-shape validation later, but the immediate requirement is to correct the inaccurate examples and package/provider claims before merge.
Future Action — review latest findings
No alternative fix was selected for this run. Review the session findings and CI results before merging.
kubaflo
left a comment
There was a problem hiding this comment.
Could you please check the ai's suggestions?
This document outlines the API design proposal for integrating AI services into .NET MAUI applications using dependency injection. It includes various options for registration, usage scenarios, design questions, and recommendations for implementation.
This is related to #32544