Skip to content

Expose Apple Intelligence token usage through M.E.AI - #404

Merged
jfversluis merged 3 commits into
mainfrom
mattleibow-plan-apple-ai-metrics
Oct 9, 2026
Merged

jfversluis merged 3 commits into
mainfrom
mattleibow-plan-apple-ai-metrics

Conversation

@mattleibow

@mattleibow mattleibow commented Jul 24, 2026 •

Copy link
Copy Markdown
Member

Expose Apple Foundation Models' native OS 27 token usage through the standard Microsoft.Extensions.AI response surface.

Dependencies and native stack

This PR targets #623's mattleibow-apple-foundation-models-image-input branch, currently de5e19ba6c8e5f7cf0e920f6b19432f36f7b5808. It includes image input and its OS 26 rejection coverage, #630's trace-grouped diagnostics, and merged #629's model/streaming fixes and Xcode 27 build configuration.

Existing native stack 636 is preserved, including its merged lower member:

#629 → #630 → #623 → #404 → #631.

The broken session was recovered into a clean isolated worktree. This PR is published at d8515bdcedeca25615318cb17bc8dba9dba0caf7: both original usage commits are unchanged by range-diff, with one additional telemetry regression/documentation commit above the latest image-input tip. The dependent #631 branch is published at 287ee658fff7fdd6a1f520eb6c22c93231d6595c, exactly six unchanged Hybrid commits above this PR; all six range-diff entries are =. Both pushes used explicit compare-and-swap leases. Original stale worktrees were preserved, and no stack membership, PR bases, or draft states were changed.

Changes

  • Bridge native response usage into ChatResponse.Usage, including input, output, total, cached-input, and reasoning token counts.
  • Emit a final UsageContent update before streaming completion so standard response aggregation and built-in telemetry consume native usage normally, including the provider model ID.
  • Preserve inherited image conversion, response model IDs, and native tool callback execution context so tool diagnostics retain their originating chat trace.
  • Keep usage native-only: Xcode 27 or later is required to build the bridge, and Apple OS 27 or later is required for response usage. On OS 26 usage remains null; no reconstructed or estimated counts are added.
  • Extend reusable ChatClientUsageTestsBase<T> tests to capture real Activity and Meter output for Apple and the configured Azure OpenAI Responses client, in both single and streaming modes. Assert provider/request/response model tags, input/output and cached-input span counts, exact token histogram values, request duration, streaming timing measurements, and sensitive-data exclusions. Record observed measurements in test output and bound requests with cancellation.
  • Preserve both OpenAI opt-in flags without duplicate package references; document UsageDetails.Add accumulation and the exact pinned M.E.AI 10.4.1 telemetry mapping.

No provider-specific public usage API is introduced. The inherited diagnostics pipeline already consumes both ChatResponse.Usage and streaming UsageContent.

Live telemetry comparison on macOS 27

The earlier model-readiness blocker is cleared. A fresh native SystemLanguageModel.default.availability probe reports available, and both Apple usage requests successfully generated responses. These are real provider counts, not estimates or fake-client results.

The final 62-case device-test run captured:

Provider Mode Input Output Total Cached input Reasoning
Apple Intelligence Single 63 3 66 0 0
Apple Intelligence Streaming 63 3 66 0 0
Azure OpenAI, configured device-test deployment Single 15 3 18 0 0
Azure OpenAI, configured device-test deployment Streaming 15 2 17 0 0

The same synthetic one-word prompt was used. Counts are not expected to match across providers/tokenizers; the assertion is that each provider's response usage exactly matches its emitted standard telemetry.

Both providers emit gen_ai.operation.name, provider/request/response model tags, input/output usage tags, cached-input usage tags, gen_ai.client.token.usage histograms, and gen_ai.client.operation.duration. Fully consumed streams additionally emit time-to-first-chunk and time-per-output-chunk histograms. Sensitive prompt/response telemetry remains explicitly disabled.

Parity is not provider-specific identity: Apple does not invent Azure-only endpoint tags, response IDs, or finish reasons. Pinned M.E.AI 10.4.1 exposes total/reasoning counts on UsageDetails but does not emit separate built-in total/reasoning span tags or metrics.

Validation on the upgraded Mac

Default toolchain: macOS 27.0.1, Xcode 27.0 / Swift 6.4, .NET SDK and workloads 10.0.401.

  • Final Essentials.AI native/managed builds passed for net10.0-ios27.0, net10.0-maccatalyst27.0, and net10.0-macos27.0, with zero warnings/errors.
  • The separately identified Mac Catalyst 27 Chat Playground built with zero warnings/errors. Its exact process/package was verified through DevFlow; live Apple and configured Azure chat responses completed, and both diagnostics sidebars actually rendered standard model/input/output/cached token tags without captured prompt/response payloads. The temporary validation app was stopped; the user's existing playground was left untouched.
  • 62 native device checks passed, zero failed/skipped, verified by parsing the TRX, not merely a successful command exit. This includes all four live provider telemetry cases, single/streaming native tool trace correlation across awaits, honest response model IDs, live image inference, model-free image/validation/pre-cancellation coverage, and NLEmbeddingGenerator generation/similarity/metadata coverage.
  • 56 targeted Essentials.AI host checks passed for usage, streaming model IDs, and native callback context; 18 diagnostics host checks passed.
  • The recovered upper Add hybrid chat routing with standard leaf diagnostics #631 layer's full 234 Chat host checks passed, zero failed/skipped, including the existing diagnostics checks. Its six commits remain unchanged by range-diff.
  • The latest image-input parent separately verified its four OS 26 image-request rejection paths on an iOS 26.5 simulator. Native chat usage on OS 26 and the missing-vision-device path were not executed on this OS 27 vision-capable Mac.

The PR remains draft; no merge or ready-for-review action was requested.

@github-actions

This comment has been minimized.

1 similar comment
@github-actions

Copy link
Copy Markdown
Contributor

Expert Code Review — PR #404

Methodology: 2 independent reviewers (1 failed to complete — reduced coverage, no tiebreaker) with adversarial consensus.

Findings: 2 posted as inline comments (both 🟡 moderate). Both reached full 2/2 consensus.

  • 🟡 ApiDefinitions.cs — [Introduced ...26.0] availability annotation on UsageDetailsNative/Usage doesn't match the Swift #available(... 27.0) runtime gate; usage is always null on OS 26.
  • 🟡 ChatClientUsageTestsBase.cs — strict Input + Output == Total assertion is an unverified cross-provider invariant that can permanently fail CI if Apple's beta accounting differs.

Discarded (flagged by only 1 of 2 reviewers, no tiebreaker):

  • 🟢 Swift #available omits explicit macCatalyst 27.0 (relies on implicit iOS→Catalyst mapping).
  • 🟢 Usage-only trailing streaming update carries no ResponseId/MessageId/Role.
  • 🟡 IsUsageAvailable lacks an #elif MACOS branch, so macOS-native 27+ tests accept null and skip the positive usage assertion.
  • 🟢 No negative/sentinel clamp in FromNativeUsage for nint→long? token counts (one reviewer explicitly rated this a non-issue).

Test coverage: Good — the PR adds ChatClientUsageTestsBase (non-streaming + streaming), Apple/OpenAI usage subclasses, and StreamingResponseHandler completion unit tests covering the new usage path.

Backward compatibility: Complete(UsageDetails? usage = null) keeps existing callers source-compatible; OS 26 paths yield null usage and emit no UsageContent, preserving prior behavior.

CI status: PR mergeable_state is blocked at review time (pending required checks/approval).

Generated by Expert Code Review · 2 independent reviewers with adversarial consensus

Generated by Expert Code Review (auto) for #404 · 324.1 AIC · ⌖ 18.9 AIC · ⊞ 12.3K · ◷

@github-actions github-actions Bot 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.

Expert Code Review: 2 findings posted inline. See the lean summary comment for full details.

Generated by Expert Code Review (auto) for #404 · 324.1 AIC · ⌖ 18.9 AIC · ⊞ 12.3K

Comment thread src/AI/AppleNative/ApiDefinitions.cs
Comment thread src/AI/AppleNative/ApiDefinitions.cs
@mattleibow
mattleibow marked this pull request as draft July 24, 2026 23:58
@mattleibow
mattleibow force-pushed the mattleibow-plan-apple-ai-metrics branch from 433f9e2 to c6b4a19 Compare October 6, 2026 22:47
@mattleibow
mattleibow changed the base branch from main to mattleibow-chat-logging-sidebar October 6, 2026 22:48
@mattleibow
mattleibow force-pushed the mattleibow-plan-apple-ai-metrics branch from c6b4a19 to 74946b4 Compare October 7, 2026 08:49
@mattleibow
mattleibow changed the base branch from mattleibow-chat-logging-sidebar to mattleibow-apple-foundation-models-image-input October 7, 2026 08:58
@mattleibow
mattleibow added this pull request to stack #636 October 7, 2026 08:59
@mattleibow
mattleibow marked this pull request as ready for review October 7, 2026 09:14
@jfversluis
jfversluis force-pushed the mattleibow-plan-apple-ai-metrics branch from 74946b4 to 4aa189c Compare October 7, 2026 13:38
@mattleibow
mattleibow marked this pull request as draft October 7, 2026 13:43
@mattleibow
mattleibow force-pushed the mattleibow-plan-apple-ai-metrics branch 2 times, most recently from d8515bd to 0301fa3 Compare October 7, 2026 17:02
@jfversluis
jfversluis force-pushed the mattleibow-plan-apple-ai-metrics branch from 0301fa3 to 1dc0960 Compare October 7, 2026 19:24
Base automatically changed from mattleibow-apple-foundation-models-image-input to main October 7, 2026 20:59
mattleibow and others added 3 commits October 7, 2026 22:59
Map Xcode 27 Foundation Models usage into standard Microsoft.Extensions.AI responses and streaming updates. Add reusable provider usage tests for Apple and OpenAI compatibility.

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

Copilot-Session: 9dd6eab1-b5fd-4250-9d0c-49b901de09ca
Validate positive usage counts without assuming every provider defines total tokens as exactly input plus output.

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

Copilot-Session: 9dd6eab1-b5fd-4250-9d0c-49b901de09ca
Assert actual provider/model spans, cached-input tags, input/output token histograms, operation duration and streaming timings for both live providers. Preserve sensitive-data exclusions and document the pinned M.E.AI telemetry mapping.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: fb5d1926-9f89-4115-9a96-65cd7ee59e9c
@jfversluis
jfversluis force-pushed the mattleibow-plan-apple-ai-metrics branch from 1dc0960 to 7e6aa42 Compare October 7, 2026 20:59
@mattleibow
mattleibow marked this pull request as ready for review October 7, 2026 21:32
@jfversluis
jfversluis merged commit 4701c99 into main Oct 9, 2026
17 checks passed
@jfversluis
jfversluis deleted the mattleibow-plan-apple-ai-metrics branch October 9, 2026 13:21
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.

2 participants