From 3891dde3f15232eb32c4ccdcdb0f9eff7c44fbeb Mon Sep 17 00:00:00 2001
From: cogwheel
Date: Sat, 22 Aug 2026 23:47:51 +0530
Subject: [PATCH] Add Apple on-device support and improve direct chats (#651)
* feat: add Apple model backends and context compaction
* Add Apple on-device and PCC direct providers
* dev: show all onboarding backends in debug builds
* Fix short response pin-to-top settlement
* Polish Direct Connections context settings
* Fix onboarding selection row spacing
* Address PR review feedback
* Harden context and native request bounds
* Strengthen compaction regression coverage
* Close final context and image review gaps
* Validate structured array bounds
---
PRIVACY_POLICY.md | 5 +-
README.md | 45 +-
.../cogwheel/conduit/ConduitPlatformApis.g.kt | 733 ++++-
docs/BUILDING.md | 11 +
ios/Flutter/Debug.xcconfig | 1 +
ios/Flutter/PccSdk.xcconfig | 15 +
ios/Flutter/Release.xcconfig | 1 +
ios/Runner.xcodeproj/project.pbxproj | 4 +
ios/Runner/AppDelegate.swift | 1 +
ios/Runner/ConduitPlatformApis.g.swift | 692 ++++-
ios/Runner/PccBridge.swift | 1097 ++++++++
ios/RunnerTests/RunnerTests.swift | 134 +
lib/core/persistence/persistence_keys.dart | 6 +
.../platform/conduit_platform_apis.g.dart | 2476 +++++++++--------
.../native_sheet_hydration_service.dart | 3 +
.../auth/views/backend_chooser_page.dart | 240 +-
.../chat/providers/chat_providers.dart | 285 +-
.../providers/reasoning_effort_provider.dart | 13 +
lib/features/chat/views/chat_page.dart | 18 +-
.../chat/widgets/model_selector_sheet.dart | 3 +
.../models/direct_connection_profile.dart | 45 +
.../direct_connection_providers.dart | 260 +-
.../services/apple_pcc_adapter.dart | 512 ++++
.../services/direct_chat_bridge.dart | 331 +++
.../services/direct_model_registry.dart | 12 +
.../views/direct_connections_page.dart | 325 ++-
lib/l10n/app_en.arb | 115 +-
lib/l10n/app_pl.arb | 115 +-
lib/shared/widgets/utility/utility_rows.dart | 1 -
pigeons/conduit_platform_apis.dart | 123 +
test/core/database/fts_perf_test.dart | 34 +-
test/core/database/support/large_fixture.dart | 4 +-
.../api_service_proxy_diagnostics_test.dart | 14 +-
.../streaming_helper_transport_test.dart | 17 +-
test/core/sync/read_path_acceptance_test.dart | 21 +-
.../backend_onboarding_adaptive_test.dart | 69 +-
.../views/support/adaptive_auth_harness.dart | 25 +
.../direct_send_history_links_test.dart | 126 +-
.../reasoning_effort_provider_test.dart | 21 +
.../views/chat_page_layout_metadata_test.dart | 12 +-
.../widgets/chat_timeline_viewport_test.dart | 13 +-
.../apple_pcc_adapter_test.dart | 235 ++
.../direct_adapters_test.dart | 2 +
.../direct_chat_bridge_test.dart | 202 ++
.../direct_connections_management_test.dart | 127 +
.../direct_providers_test.dart | 108 +
.../direct_registry_test.dart | 22 +
.../conversation_selection_provider_test.dart | 2 +-
.../widgets/utility_components_test.dart | 12 +-
49 files changed, 7195 insertions(+), 1493 deletions(-)
create mode 100644 ios/Flutter/PccSdk.xcconfig
create mode 100644 ios/Runner/PccBridge.swift
create mode 100644 lib/features/direct_connections/services/apple_pcc_adapter.dart
create mode 100644 test/features/direct_connections/apple_pcc_adapter_test.dart
diff --git a/PRIVACY_POLICY.md b/PRIVACY_POLICY.md
index 0cec81626..aada4f129 100644
--- a/PRIVACY_POLICY.md
+++ b/PRIVACY_POLICY.md
@@ -1,6 +1,6 @@
# Conduit Privacy Policy
-Effective date: 2026-07-11
+Effective date: 2026-08-21
Conduit is an open‑source mobile client for Open‑WebUI and directly connected AI providers. This app acts as a client to services you choose and configure. This policy describes how the app itself handles data on your device. Open WebUI servers and AI providers may collect, process, and store data under their own policies; please review their privacy terms separately.
@@ -19,6 +19,8 @@ Conduit is an open‑source mobile client for Open‑WebUI and directly connecte
- Local storage: preferences and credentials are stored on your device. Access tokens are stored using secure storage where available.
- Network transfer: when you interact with the app, your data is sent to the Open WebUI server or direct AI provider you selected. Direct model requests are not relayed through Open WebUI or any developer‑controlled server.
- Direct chat history: by default, a direct chat is also synchronized to your active Open WebUI server when you are signed in. You can instead keep direct chat history only on this device. Changing this setting applies to new chats and does not automatically upload existing on-device chats.
+- Apple On-Device: when you select Apple On-Device, model inference runs locally through Apple's Foundation Models framework. Prompt and response content is not sent to an AI provider by Conduit, though optional Open WebUI history synchronization remains a separate setting.
+- Apple Private Cloud Compute: when you select the Apple PCC provider, Conduit sends the conversation content and selected images needed for that request to Apple's Private Cloud Compute service. Conduit does not operate an intermediary server. If you enable on-device fallback, a PCC network failure may instead be retried with Apple's on-device model. Apple's processing and retention terms apply separately from Conduit's optional Open WebUI history synchronization.
## Permissions
Depending on how you use Conduit, the app may request:
@@ -54,4 +56,3 @@ We may update this policy to reflect improvements or legal requirements. Materia
## Contact
For questions or requests about this policy, please contact the app maintainer(s) through the project repository.
-
diff --git a/README.md b/README.md
index cd353688f..be407254f 100644
--- a/README.md
+++ b/README.md
@@ -74,7 +74,7 @@
- Connect ·
+ Connect ·
Screenshots ·
Features ·
Getting Started ·
@@ -103,7 +103,7 @@ works with or without an Open WebUI server at all.
Your chats live on your device first. Nothing routes through a backend the
maintainer operates.
-## Three ways to connect
+## Ways to connect
On first launch Conduit asks how you want to connect. Pick one, add the others
later, and skip any sign-in you don't need.
@@ -112,6 +112,8 @@ later, and skip any sign-in you don't need.
| --- | --- | --- |
| **Open WebUI** | Your self-hosted server | Full feature set: chats, folders, notes, channels, workspace, tools, web search, image generation |
| **Direct** | OpenAI-compatible, Ollama, OpenRouter | Talk straight to a provider or a model on your own machine. No Open WebUI account required |
+| **Apple On-Device** | Apple Intelligence | Run Apple's local model offline on eligible iOS 26 devices without an API key |
+| **Apple PCC** | Apple Private Cloud Compute | Use Apple's private cloud model on eligible iOS 27 devices without an API key |
| **Hermes** | Your self-hosted agent | An agent that runs tools, asks before sensitive steps, and works on a schedule |
**Direct connections** cover OpenAI-compatible endpoints (Chat Completions or
@@ -120,6 +122,20 @@ OpenRouter. Bring an API key, or skip it for a local endpoint that doesn't want
one. Direct connections you already configured in Open WebUI come along
automatically. Keys and custom headers stay in platform secure storage.
+**Apple On-Device** is an iOS-only Direct provider backed by Apple's local
+SystemLanguageModel. It requires iOS 26 and Apple Intelligence, works offline,
+and supports streaming, sampling controls, and JSON-schema responses with a 4K
+context window. Image input, reasoning controls, and tool calling are not
+available.
+
+**Apple Private Cloud Compute** is an iOS-only Direct provider. It uses Apple's
+Foundation Models framework, streams responses through the same chat path as
+other Direct models, and requires iOS 27, Apple Intelligence availability, and
+Apple's managed PCC entitlement. It supports image input, reasoning levels,
+sampling and output limits, JSON-schema responses, live quota/context status,
+and an optional on-device fallback for PCC network failures. Tool calling is
+not enabled.
+
**Hermes Agent** connects to your own Hermes server. You watch its tools work
live, approve sensitive steps before they run, and let scheduled agents run
while you sleep. Conversations and schedules get their own tab, and Conduit only
@@ -129,7 +145,7 @@ exposes the capabilities your server actually reports.
| Chat | Connect | Chats | Voice |
| --- | --- | --- | --- |
-| | | | |
+| | | | |
## What you get
@@ -219,6 +235,29 @@ then pick how you want to connect.
+
+Apple On-Device
+
+1. On an eligible iOS 26 device, launch Conduit and choose Apple On-Device.
+2. Conduit checks Apple Intelligence and local-model availability. No API key
+ or network connection is required.
+3. Start chatting. New Apple-only installations keep Direct history on the
+ device unless you later enable Open WebUI history.
+
+
+
+
+Apple Private Cloud Compute
+
+1. On an eligible iOS 27 device, launch Conduit and choose Apple Private Cloud
+ Compute.
+2. Conduit checks Apple Intelligence and PCC availability. No API key is
+ required.
+3. Start chatting. New PCC-only installations keep Direct history on the
+ device unless you later enable Open WebUI history.
+
+
+
Hermes Agent
diff --git a/android/app/src/main/kotlin/app/cogwheel/conduit/ConduitPlatformApis.g.kt b/android/app/src/main/kotlin/app/cogwheel/conduit/ConduitPlatformApis.g.kt
index 0409961ab..349180045 100644
--- a/android/app/src/main/kotlin/app/cogwheel/conduit/ConduitPlatformApis.g.kt
+++ b/android/app/src/main/kotlin/app/cogwheel/conduit/ConduitPlatformApis.g.kt
@@ -218,6 +218,56 @@ enum class PlatformNativePasteKind(val raw: Int) {
}
}
+enum class PlatformPccAvailability(val raw: Int) {
+ AVAILABLE(0),
+ UNAVAILABLE(1),
+ UNSUPPORTED(2);
+
+ companion object {
+ fun ofRaw(raw: Int): PlatformPccAvailability? {
+ return values().firstOrNull { it.raw == raw }
+ }
+ }
+}
+
+enum class PlatformAppleModel(val raw: Int) {
+ ON_DEVICE(0),
+ PRIVATE_CLOUD_COMPUTE(1);
+
+ companion object {
+ fun ofRaw(raw: Int): PlatformAppleModel? {
+ return values().firstOrNull { it.raw == raw }
+ }
+ }
+}
+
+enum class PlatformPccQuotaStatus(val raw: Int) {
+ BELOW_LIMIT(0),
+ APPROACHING_LIMIT(1),
+ LIMIT_REACHED(2),
+ UNKNOWN(3);
+
+ companion object {
+ fun ofRaw(raw: Int): PlatformPccQuotaStatus? {
+ return values().firstOrNull { it.raw == raw }
+ }
+ }
+}
+
+enum class PlatformPccEventKind(val raw: Int) {
+ CONTENT(0),
+ USAGE(1),
+ FALLBACK(2),
+ ERROR(3),
+ DONE(4);
+
+ companion object {
+ fun ofRaw(raw: Int): PlatformPccEventKind? {
+ return values().firstOrNull { it.raw == raw }
+ }
+ }
+}
+
enum class PlatformNativeSheetItemKind(val raw: Int) {
NAVIGATION(0),
TEXT_FIELD(1),
@@ -2541,6 +2591,303 @@ data class PlatformNativeSheetActionResult (
return "PlatformNativeSheetActionResult(actionId=$actionId, values=$values)"
}
}
+
+/** Generated class from Pigeon that represents data sent in messages. */
+data class PlatformPccStatus (
+ val availability: PlatformPccAvailability,
+ val quotaStatus: PlatformPccQuotaStatus,
+ val quotaLimitReached: Boolean,
+ val canIncreaseQuota: Boolean,
+ val message: String? = null,
+ val quotaResetAtMilliseconds: Long? = null,
+ val contextSize: Long? = null,
+ val supportsCurrentLocale: Boolean? = null
+)
+ {
+ companion object {
+ fun fromList(pigeonVar_list: List): PlatformPccStatus {
+ val availability = pigeonVar_list[0] as PlatformPccAvailability
+ val quotaStatus = pigeonVar_list[1] as PlatformPccQuotaStatus
+ val quotaLimitReached = pigeonVar_list[2] as Boolean
+ val canIncreaseQuota = pigeonVar_list[3] as Boolean
+ val message = pigeonVar_list[4] as String?
+ val quotaResetAtMilliseconds = pigeonVar_list[5] as Long?
+ val contextSize = pigeonVar_list[6] as Long?
+ val supportsCurrentLocale = pigeonVar_list[7] as Boolean?
+ return PlatformPccStatus(availability, quotaStatus, quotaLimitReached, canIncreaseQuota, message, quotaResetAtMilliseconds, contextSize, supportsCurrentLocale)
+ }
+ }
+ fun toList(): List {
+ return listOf(
+ availability,
+ quotaStatus,
+ quotaLimitReached,
+ canIncreaseQuota,
+ message,
+ quotaResetAtMilliseconds,
+ contextSize,
+ supportsCurrentLocale,
+ )
+ }
+ override fun equals(other: Any?): Boolean {
+ if (other == null || other.javaClass != javaClass) {
+ return false
+ }
+ if (this === other) {
+ return true
+ }
+ val other = other as PlatformPccStatus
+ return ConduitPlatformApisPigeonUtils.deepEquals(this.availability, other.availability) && ConduitPlatformApisPigeonUtils.deepEquals(this.quotaStatus, other.quotaStatus) && ConduitPlatformApisPigeonUtils.deepEquals(this.quotaLimitReached, other.quotaLimitReached) && ConduitPlatformApisPigeonUtils.deepEquals(this.canIncreaseQuota, other.canIncreaseQuota) && ConduitPlatformApisPigeonUtils.deepEquals(this.message, other.message) && ConduitPlatformApisPigeonUtils.deepEquals(this.quotaResetAtMilliseconds, other.quotaResetAtMilliseconds) && ConduitPlatformApisPigeonUtils.deepEquals(this.contextSize, other.contextSize) && ConduitPlatformApisPigeonUtils.deepEquals(this.supportsCurrentLocale, other.supportsCurrentLocale)
+ }
+
+ override fun hashCode(): Int {
+ var result = javaClass.hashCode()
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.availability)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.quotaStatus)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.quotaLimitReached)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.canIncreaseQuota)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.message)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.quotaResetAtMilliseconds)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.contextSize)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.supportsCurrentLocale)
+ return result
+ }
+ override fun toString(): String {
+ return "PlatformPccStatus(availability=$availability, quotaStatus=$quotaStatus, quotaLimitReached=$quotaLimitReached, canIncreaseQuota=$canIncreaseQuota, message=$message, quotaResetAtMilliseconds=$quotaResetAtMilliseconds, contextSize=$contextSize, supportsCurrentLocale=$supportsCurrentLocale)"
+ }
+}
+
+/** Generated class from Pigeon that represents data sent in messages. */
+data class PlatformPccImage (
+ val mimeType: String,
+ val bytes: ByteArray
+)
+ {
+ companion object {
+ fun fromList(pigeonVar_list: List): PlatformPccImage {
+ val mimeType = pigeonVar_list[0] as String
+ val bytes = pigeonVar_list[1] as ByteArray
+ return PlatformPccImage(mimeType, bytes)
+ }
+ }
+ fun toList(): List {
+ return listOf(
+ mimeType,
+ bytes,
+ )
+ }
+ override fun equals(other: Any?): Boolean {
+ if (other == null || other.javaClass != javaClass) {
+ return false
+ }
+ if (this === other) {
+ return true
+ }
+ val other = other as PlatformPccImage
+ return ConduitPlatformApisPigeonUtils.deepEquals(this.mimeType, other.mimeType) && ConduitPlatformApisPigeonUtils.deepEquals(this.bytes, other.bytes)
+ }
+
+ override fun hashCode(): Int {
+ var result = javaClass.hashCode()
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.mimeType)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.bytes)
+ return result
+ }
+ override fun toString(): String {
+ return "PlatformPccImage(mimeType=$mimeType, bytes=${bytes.contentToString()})"
+ }
+}
+
+/** Generated class from Pigeon that represents data sent in messages. */
+data class PlatformPccMessage (
+ val role: String,
+ val content: String,
+ val images: List
+)
+ {
+ companion object {
+ fun fromList(pigeonVar_list: List): PlatformPccMessage {
+ val role = pigeonVar_list[0] as String
+ val content = pigeonVar_list[1] as String
+ val images = pigeonVar_list[2] as List
+ return PlatformPccMessage(role, content, images)
+ }
+ }
+ fun toList(): List {
+ return listOf(
+ role,
+ content,
+ images,
+ )
+ }
+ override fun equals(other: Any?): Boolean {
+ if (other == null || other.javaClass != javaClass) {
+ return false
+ }
+ if (this === other) {
+ return true
+ }
+ val other = other as PlatformPccMessage
+ return ConduitPlatformApisPigeonUtils.deepEquals(this.role, other.role) && ConduitPlatformApisPigeonUtils.deepEquals(this.content, other.content) && ConduitPlatformApisPigeonUtils.deepEquals(this.images, other.images)
+ }
+
+ override fun hashCode(): Int {
+ var result = javaClass.hashCode()
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.role)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.content)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.images)
+ return result
+ }
+ override fun toString(): String {
+ return "PlatformPccMessage(role=$role, content=$content, images=$images)"
+ }
+}
+
+/** Generated class from Pigeon that represents data sent in messages. */
+data class PlatformPccCompletionRequest (
+ val runId: String,
+ val model: PlatformAppleModel,
+ val messages: List,
+ val allowOnDeviceFallback: Boolean,
+ val reasoningLevel: String? = null,
+ val temperature: Double? = null,
+ val maximumResponseTokens: Long? = null,
+ val topP: Double? = null,
+ val topK: Long? = null,
+ val seed: Long? = null,
+ val greedySampling: Boolean? = null,
+ val responseSchemaName: String? = null,
+ val responseSchemaJson: String? = null
+)
+ {
+ companion object {
+ fun fromList(pigeonVar_list: List): PlatformPccCompletionRequest {
+ val runId = pigeonVar_list[0] as String
+ val model = pigeonVar_list[1] as PlatformAppleModel
+ val messages = pigeonVar_list[2] as List
+ val allowOnDeviceFallback = pigeonVar_list[3] as Boolean
+ val reasoningLevel = pigeonVar_list[4] as String?
+ val temperature = pigeonVar_list[5] as Double?
+ val maximumResponseTokens = pigeonVar_list[6] as Long?
+ val topP = pigeonVar_list[7] as Double?
+ val topK = pigeonVar_list[8] as Long?
+ val seed = pigeonVar_list[9] as Long?
+ val greedySampling = pigeonVar_list[10] as Boolean?
+ val responseSchemaName = pigeonVar_list[11] as String?
+ val responseSchemaJson = pigeonVar_list[12] as String?
+ return PlatformPccCompletionRequest(runId, model, messages, allowOnDeviceFallback, reasoningLevel, temperature, maximumResponseTokens, topP, topK, seed, greedySampling, responseSchemaName, responseSchemaJson)
+ }
+ }
+ fun toList(): List {
+ return listOf(
+ runId,
+ model,
+ messages,
+ allowOnDeviceFallback,
+ reasoningLevel,
+ temperature,
+ maximumResponseTokens,
+ topP,
+ topK,
+ seed,
+ greedySampling,
+ responseSchemaName,
+ responseSchemaJson,
+ )
+ }
+ override fun equals(other: Any?): Boolean {
+ if (other == null || other.javaClass != javaClass) {
+ return false
+ }
+ if (this === other) {
+ return true
+ }
+ val other = other as PlatformPccCompletionRequest
+ return ConduitPlatformApisPigeonUtils.deepEquals(this.runId, other.runId) && ConduitPlatformApisPigeonUtils.deepEquals(this.model, other.model) && ConduitPlatformApisPigeonUtils.deepEquals(this.messages, other.messages) && ConduitPlatformApisPigeonUtils.deepEquals(this.allowOnDeviceFallback, other.allowOnDeviceFallback) && ConduitPlatformApisPigeonUtils.deepEquals(this.reasoningLevel, other.reasoningLevel) && ConduitPlatformApisPigeonUtils.deepEquals(this.temperature, other.temperature) && ConduitPlatformApisPigeonUtils.deepEquals(this.maximumResponseTokens, other.maximumResponseTokens) && ConduitPlatformApisPigeonUtils.deepEquals(this.topP, other.topP) && ConduitPlatformApisPigeonUtils.deepEquals(this.topK, other.topK) && ConduitPlatformApisPigeonUtils.deepEquals(this.seed, other.seed) && ConduitPlatformApisPigeonUtils.deepEquals(this.greedySampling, other.greedySampling) && ConduitPlatformApisPigeonUtils.deepEquals(this.responseSchemaName, other.responseSchemaName) && ConduitPlatformApisPigeonUtils.deepEquals(this.responseSchemaJson, other.responseSchemaJson)
+ }
+
+ override fun hashCode(): Int {
+ var result = javaClass.hashCode()
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.runId)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.model)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.messages)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.allowOnDeviceFallback)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.reasoningLevel)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.temperature)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.maximumResponseTokens)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.topP)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.topK)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.seed)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.greedySampling)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.responseSchemaName)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.responseSchemaJson)
+ return result
+ }
+ override fun toString(): String {
+ return "PlatformPccCompletionRequest(runId=$runId, model=$model, messages=$messages, allowOnDeviceFallback=$allowOnDeviceFallback, reasoningLevel=$reasoningLevel, temperature=$temperature, maximumResponseTokens=$maximumResponseTokens, topP=$topP, topK=$topK, seed=$seed, greedySampling=$greedySampling, responseSchemaName=$responseSchemaName, responseSchemaJson=$responseSchemaJson)"
+ }
+}
+
+/** Generated class from Pigeon that represents data sent in messages. */
+data class PlatformPccStreamEvent (
+ val runId: String,
+ val kind: PlatformPccEventKind,
+ val content: String? = null,
+ val inputTokenCount: Long? = null,
+ val outputTokenCount: Long? = null,
+ val reasoningTokenCount: Long? = null,
+ val totalTokenCount: Long? = null
+)
+ {
+ companion object {
+ fun fromList(pigeonVar_list: List): PlatformPccStreamEvent {
+ val runId = pigeonVar_list[0] as String
+ val kind = pigeonVar_list[1] as PlatformPccEventKind
+ val content = pigeonVar_list[2] as String?
+ val inputTokenCount = pigeonVar_list[3] as Long?
+ val outputTokenCount = pigeonVar_list[4] as Long?
+ val reasoningTokenCount = pigeonVar_list[5] as Long?
+ val totalTokenCount = pigeonVar_list[6] as Long?
+ return PlatformPccStreamEvent(runId, kind, content, inputTokenCount, outputTokenCount, reasoningTokenCount, totalTokenCount)
+ }
+ }
+ fun toList(): List {
+ return listOf(
+ runId,
+ kind,
+ content,
+ inputTokenCount,
+ outputTokenCount,
+ reasoningTokenCount,
+ totalTokenCount,
+ )
+ }
+ override fun equals(other: Any?): Boolean {
+ if (other == null || other.javaClass != javaClass) {
+ return false
+ }
+ if (this === other) {
+ return true
+ }
+ val other = other as PlatformPccStreamEvent
+ return ConduitPlatformApisPigeonUtils.deepEquals(this.runId, other.runId) && ConduitPlatformApisPigeonUtils.deepEquals(this.kind, other.kind) && ConduitPlatformApisPigeonUtils.deepEquals(this.content, other.content) && ConduitPlatformApisPigeonUtils.deepEquals(this.inputTokenCount, other.inputTokenCount) && ConduitPlatformApisPigeonUtils.deepEquals(this.outputTokenCount, other.outputTokenCount) && ConduitPlatformApisPigeonUtils.deepEquals(this.reasoningTokenCount, other.reasoningTokenCount) && ConduitPlatformApisPigeonUtils.deepEquals(this.totalTokenCount, other.totalTokenCount)
+ }
+
+ override fun hashCode(): Int {
+ var result = javaClass.hashCode()
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.runId)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.kind)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.content)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.inputTokenCount)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.outputTokenCount)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.reasoningTokenCount)
+ result = 31 * result + ConduitPlatformApisPigeonUtils.deepHash(this.totalTokenCount)
+ return result
+ }
+ override fun toString(): String {
+ return "PlatformPccStreamEvent(runId=$runId, kind=$kind, content=$content, inputTokenCount=$inputTokenCount, outputTokenCount=$outputTokenCount, reasoningTokenCount=$reasoningTokenCount, totalTokenCount=$totalTokenCount)"
+ }
+}
private open class ConduitPlatformApisPigeonCodec : StandardMessageCodec() {
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
return when (type) {
@@ -2556,219 +2903,264 @@ private open class ConduitPlatformApisPigeonCodec : StandardMessageCodec() {
}
131.toByte() -> {
return (readValue(buffer) as Long?)?.let {
- PlatformNativeSheetItemKind.ofRaw(it.toInt())
+ PlatformPccAvailability.ofRaw(it.toInt())
}
}
132.toByte() -> {
- return (readValue(buffer) as? List)?.let {
- PlatformBackgroundStreamLease.fromList(it)
+ return (readValue(buffer) as Long?)?.let {
+ PlatformAppleModel.ofRaw(it.toInt())
}
}
133.toByte() -> {
- return (readValue(buffer) as? List)?.let {
- PlatformBackgroundStartRequest.fromList(it)
+ return (readValue(buffer) as Long?)?.let {
+ PlatformPccQuotaStatus.ofRaw(it.toInt())
}
}
134.toByte() -> {
- return (readValue(buffer) as? List)?.let {
- PlatformBackgroundStopRequest.fromList(it)
+ return (readValue(buffer) as Long?)?.let {
+ PlatformPccEventKind.ofRaw(it.toInt())
}
}
135.toByte() -> {
- return (readValue(buffer) as? List)?.let {
- PlatformBackgroundKeepAliveRequest.fromList(it)
+ return (readValue(buffer) as Long?)?.let {
+ PlatformNativeSheetItemKind.ofRaw(it.toInt())
}
}
136.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformBackgroundAudioSessionOwnerRequest.fromList(it)
+ PlatformBackgroundStreamLease.fromList(it)
}
}
137.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformServiceFailureEvent.fromList(it)
+ PlatformBackgroundStartRequest.fromList(it)
}
}
138.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformTimeLimitWarningEvent.fromList(it)
+ PlatformBackgroundStopRequest.fromList(it)
}
}
139.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformStreamsSuspendingEvent.fromList(it)
+ PlatformBackgroundKeepAliveRequest.fromList(it)
}
}
140.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformBackgroundTaskExtendedEvent.fromList(it)
+ PlatformBackgroundAudioSessionOwnerRequest.fromList(it)
}
}
141.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformAppIntentImagePayload.fromList(it)
+ PlatformServiceFailureEvent.fromList(it)
}
}
142.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformAppIntentResponse.fromList(it)
+ PlatformTimeLimitWarningEvent.fromList(it)
}
}
143.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformNativePasteImageItem.fromList(it)
+ PlatformStreamsSuspendingEvent.fromList(it)
}
}
144.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformNativePastePayload.fromList(it)
+ PlatformBackgroundTaskExtendedEvent.fromList(it)
}
}
145.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformKeyboardAttachmentActionConfig.fromList(it)
+ PlatformAppIntentImagePayload.fromList(it)
}
}
146.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformKeyboardAttachmentConfig.fromList(it)
+ PlatformAppIntentResponse.fromList(it)
}
}
147.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformKeyboardAttachmentActionEvent.fromList(it)
+ PlatformNativePasteImageItem.fromList(it)
}
}
148.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformKeyboardAttachmentVisibilityEvent.fromList(it)
+ PlatformNativePastePayload.fromList(it)
}
}
149.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformRect.fromList(it)
+ PlatformKeyboardAttachmentActionConfig.fromList(it)
}
}
150.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformDropdownOption.fromList(it)
+ PlatformKeyboardAttachmentConfig.fromList(it)
}
}
151.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformDropdownRequest.fromList(it)
+ PlatformKeyboardAttachmentActionEvent.fromList(it)
}
}
152.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformNativeSheetOption.fromList(it)
+ PlatformKeyboardAttachmentVisibilityEvent.fromList(it)
}
}
153.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformNativeSheetTheme.fromList(it)
+ PlatformRect.fromList(it)
}
}
154.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformNativeSheetItem.fromList(it)
+ PlatformDropdownOption.fromList(it)
}
}
155.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformNativeSheetLink.fromList(it)
+ PlatformDropdownRequest.fromList(it)
}
}
156.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformNativeSheetSection.fromList(it)
+ PlatformNativeSheetOption.fromList(it)
}
}
157.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformNativeEditProfileSheetConfig.fromList(it)
+ PlatformNativeSheetTheme.fromList(it)
}
}
158.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformNativeProfileSheetUser.fromList(it)
+ PlatformNativeSheetItem.fromList(it)
}
}
159.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformNativeSheetDetail.fromList(it)
+ PlatformNativeSheetLink.fromList(it)
}
}
160.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformNativeProfileSheetConfig.fromList(it)
+ PlatformNativeSheetSection.fromList(it)
}
}
161.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformNativeSheetModelOption.fromList(it)
+ PlatformNativeEditProfileSheetConfig.fromList(it)
}
}
162.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformNativeSheetModelSelectorRequest.fromList(it)
+ PlatformNativeProfileSheetUser.fromList(it)
}
}
163.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformNativeSheetOptionsSelectorRequest.fromList(it)
+ PlatformNativeSheetDetail.fromList(it)
}
}
164.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformNativeSheetDatePickerRequest.fromList(it)
+ PlatformNativeProfileSheetConfig.fromList(it)
}
}
165.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformNativeSheetTextEditorRequest.fromList(it)
+ PlatformNativeSheetModelOption.fromList(it)
}
}
166.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformNativeSheetResultRequest.fromList(it)
+ PlatformNativeSheetModelSelectorRequest.fromList(it)
}
}
167.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformNativeSheetApplyDetailPatchRequest.fromList(it)
+ PlatformNativeSheetOptionsSelectorRequest.fromList(it)
}
}
168.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformNativeSheetControlChangedEvent.fromList(it)
+ PlatformNativeSheetDatePickerRequest.fromList(it)
}
}
169.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformNativeSheetDetailAppearedEvent.fromList(it)
+ PlatformNativeSheetTextEditorRequest.fromList(it)
}
}
170.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformNativeSheetModelPinToggledEvent.fromList(it)
+ PlatformNativeSheetResultRequest.fromList(it)
}
}
171.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformNativeSheetReasoningEffortChangedEvent.fromList(it)
+ PlatformNativeSheetApplyDetailPatchRequest.fromList(it)
}
}
172.toByte() -> {
return (readValue(buffer) as? List)?.let {
- PlatformNativeEditProfileCommittedEvent.fromList(it)
+ PlatformNativeSheetControlChangedEvent.fromList(it)
}
}
173.toByte() -> {
+ return (readValue(buffer) as? List)?.let {
+ PlatformNativeSheetDetailAppearedEvent.fromList(it)
+ }
+ }
+ 174.toByte() -> {
+ return (readValue(buffer) as? List)?.let {
+ PlatformNativeSheetModelPinToggledEvent.fromList(it)
+ }
+ }
+ 175.toByte() -> {
+ return (readValue(buffer) as? List)?.let {
+ PlatformNativeSheetReasoningEffortChangedEvent.fromList(it)
+ }
+ }
+ 176.toByte() -> {
+ return (readValue(buffer) as? List)?.let {
+ PlatformNativeEditProfileCommittedEvent.fromList(it)
+ }
+ }
+ 177.toByte() -> {
return (readValue(buffer) as? List)?.let {
PlatformNativeSheetActionResult.fromList(it)
}
}
+ 178.toByte() -> {
+ return (readValue(buffer) as? List)?.let {
+ PlatformPccStatus.fromList(it)
+ }
+ }
+ 179.toByte() -> {
+ return (readValue(buffer) as? List)?.let {
+ PlatformPccImage.fromList(it)
+ }
+ }
+ 180.toByte() -> {
+ return (readValue(buffer) as? List)?.let {
+ PlatformPccMessage.fromList(it)
+ }
+ }
+ 181.toByte() -> {
+ return (readValue(buffer) as? List)?.let {
+ PlatformPccCompletionRequest.fromList(it)
+ }
+ }
+ 182.toByte() -> {
+ return (readValue(buffer) as? List)?.let {
+ PlatformPccStreamEvent.fromList(it)
+ }
+ }
else -> super.readValueOfType(type, buffer)
}
}
@@ -2782,178 +3174,214 @@ private open class ConduitPlatformApisPigeonCodec : StandardMessageCodec() {
stream.write(130)
writeValue(stream, value.raw.toLong())
}
- is PlatformNativeSheetItemKind -> {
+ is PlatformPccAvailability -> {
stream.write(131)
writeValue(stream, value.raw.toLong())
}
- is PlatformBackgroundStreamLease -> {
+ is PlatformAppleModel -> {
stream.write(132)
- writeValue(stream, value.toList())
+ writeValue(stream, value.raw.toLong())
}
- is PlatformBackgroundStartRequest -> {
+ is PlatformPccQuotaStatus -> {
stream.write(133)
- writeValue(stream, value.toList())
+ writeValue(stream, value.raw.toLong())
}
- is PlatformBackgroundStopRequest -> {
+ is PlatformPccEventKind -> {
stream.write(134)
- writeValue(stream, value.toList())
+ writeValue(stream, value.raw.toLong())
}
- is PlatformBackgroundKeepAliveRequest -> {
+ is PlatformNativeSheetItemKind -> {
stream.write(135)
- writeValue(stream, value.toList())
+ writeValue(stream, value.raw.toLong())
}
- is PlatformBackgroundAudioSessionOwnerRequest -> {
+ is PlatformBackgroundStreamLease -> {
stream.write(136)
writeValue(stream, value.toList())
}
- is PlatformServiceFailureEvent -> {
+ is PlatformBackgroundStartRequest -> {
stream.write(137)
writeValue(stream, value.toList())
}
- is PlatformTimeLimitWarningEvent -> {
+ is PlatformBackgroundStopRequest -> {
stream.write(138)
writeValue(stream, value.toList())
}
- is PlatformStreamsSuspendingEvent -> {
+ is PlatformBackgroundKeepAliveRequest -> {
stream.write(139)
writeValue(stream, value.toList())
}
- is PlatformBackgroundTaskExtendedEvent -> {
+ is PlatformBackgroundAudioSessionOwnerRequest -> {
stream.write(140)
writeValue(stream, value.toList())
}
- is PlatformAppIntentImagePayload -> {
+ is PlatformServiceFailureEvent -> {
stream.write(141)
writeValue(stream, value.toList())
}
- is PlatformAppIntentResponse -> {
+ is PlatformTimeLimitWarningEvent -> {
stream.write(142)
writeValue(stream, value.toList())
}
- is PlatformNativePasteImageItem -> {
+ is PlatformStreamsSuspendingEvent -> {
stream.write(143)
writeValue(stream, value.toList())
}
- is PlatformNativePastePayload -> {
+ is PlatformBackgroundTaskExtendedEvent -> {
stream.write(144)
writeValue(stream, value.toList())
}
- is PlatformKeyboardAttachmentActionConfig -> {
+ is PlatformAppIntentImagePayload -> {
stream.write(145)
writeValue(stream, value.toList())
}
- is PlatformKeyboardAttachmentConfig -> {
+ is PlatformAppIntentResponse -> {
stream.write(146)
writeValue(stream, value.toList())
}
- is PlatformKeyboardAttachmentActionEvent -> {
+ is PlatformNativePasteImageItem -> {
stream.write(147)
writeValue(stream, value.toList())
}
- is PlatformKeyboardAttachmentVisibilityEvent -> {
+ is PlatformNativePastePayload -> {
stream.write(148)
writeValue(stream, value.toList())
}
- is PlatformRect -> {
+ is PlatformKeyboardAttachmentActionConfig -> {
stream.write(149)
writeValue(stream, value.toList())
}
- is PlatformDropdownOption -> {
+ is PlatformKeyboardAttachmentConfig -> {
stream.write(150)
writeValue(stream, value.toList())
}
- is PlatformDropdownRequest -> {
+ is PlatformKeyboardAttachmentActionEvent -> {
stream.write(151)
writeValue(stream, value.toList())
}
- is PlatformNativeSheetOption -> {
+ is PlatformKeyboardAttachmentVisibilityEvent -> {
stream.write(152)
writeValue(stream, value.toList())
}
- is PlatformNativeSheetTheme -> {
+ is PlatformRect -> {
stream.write(153)
writeValue(stream, value.toList())
}
- is PlatformNativeSheetItem -> {
+ is PlatformDropdownOption -> {
stream.write(154)
writeValue(stream, value.toList())
}
- is PlatformNativeSheetLink -> {
+ is PlatformDropdownRequest -> {
stream.write(155)
writeValue(stream, value.toList())
}
- is PlatformNativeSheetSection -> {
+ is PlatformNativeSheetOption -> {
stream.write(156)
writeValue(stream, value.toList())
}
- is PlatformNativeEditProfileSheetConfig -> {
+ is PlatformNativeSheetTheme -> {
stream.write(157)
writeValue(stream, value.toList())
}
- is PlatformNativeProfileSheetUser -> {
+ is PlatformNativeSheetItem -> {
stream.write(158)
writeValue(stream, value.toList())
}
- is PlatformNativeSheetDetail -> {
+ is PlatformNativeSheetLink -> {
stream.write(159)
writeValue(stream, value.toList())
}
- is PlatformNativeProfileSheetConfig -> {
+ is PlatformNativeSheetSection -> {
stream.write(160)
writeValue(stream, value.toList())
}
- is PlatformNativeSheetModelOption -> {
+ is PlatformNativeEditProfileSheetConfig -> {
stream.write(161)
writeValue(stream, value.toList())
}
- is PlatformNativeSheetModelSelectorRequest -> {
+ is PlatformNativeProfileSheetUser -> {
stream.write(162)
writeValue(stream, value.toList())
}
- is PlatformNativeSheetOptionsSelectorRequest -> {
+ is PlatformNativeSheetDetail -> {
stream.write(163)
writeValue(stream, value.toList())
}
- is PlatformNativeSheetDatePickerRequest -> {
+ is PlatformNativeProfileSheetConfig -> {
stream.write(164)
writeValue(stream, value.toList())
}
- is PlatformNativeSheetTextEditorRequest -> {
+ is PlatformNativeSheetModelOption -> {
stream.write(165)
writeValue(stream, value.toList())
}
- is PlatformNativeSheetResultRequest -> {
+ is PlatformNativeSheetModelSelectorRequest -> {
stream.write(166)
writeValue(stream, value.toList())
}
- is PlatformNativeSheetApplyDetailPatchRequest -> {
+ is PlatformNativeSheetOptionsSelectorRequest -> {
stream.write(167)
writeValue(stream, value.toList())
}
- is PlatformNativeSheetControlChangedEvent -> {
+ is PlatformNativeSheetDatePickerRequest -> {
stream.write(168)
writeValue(stream, value.toList())
}
- is PlatformNativeSheetDetailAppearedEvent -> {
+ is PlatformNativeSheetTextEditorRequest -> {
stream.write(169)
writeValue(stream, value.toList())
}
- is PlatformNativeSheetModelPinToggledEvent -> {
+ is PlatformNativeSheetResultRequest -> {
stream.write(170)
writeValue(stream, value.toList())
}
- is PlatformNativeSheetReasoningEffortChangedEvent -> {
+ is PlatformNativeSheetApplyDetailPatchRequest -> {
stream.write(171)
writeValue(stream, value.toList())
}
- is PlatformNativeEditProfileCommittedEvent -> {
+ is PlatformNativeSheetControlChangedEvent -> {
stream.write(172)
writeValue(stream, value.toList())
}
- is PlatformNativeSheetActionResult -> {
+ is PlatformNativeSheetDetailAppearedEvent -> {
stream.write(173)
writeValue(stream, value.toList())
}
+ is PlatformNativeSheetModelPinToggledEvent -> {
+ stream.write(174)
+ writeValue(stream, value.toList())
+ }
+ is PlatformNativeSheetReasoningEffortChangedEvent -> {
+ stream.write(175)
+ writeValue(stream, value.toList())
+ }
+ is PlatformNativeEditProfileCommittedEvent -> {
+ stream.write(176)
+ writeValue(stream, value.toList())
+ }
+ is PlatformNativeSheetActionResult -> {
+ stream.write(177)
+ writeValue(stream, value.toList())
+ }
+ is PlatformPccStatus -> {
+ stream.write(178)
+ writeValue(stream, value.toList())
+ }
+ is PlatformPccImage -> {
+ stream.write(179)
+ writeValue(stream, value.toList())
+ }
+ is PlatformPccMessage -> {
+ stream.write(180)
+ writeValue(stream, value.toList())
+ }
+ is PlatformPccCompletionRequest -> {
+ stream.write(181)
+ writeValue(stream, value.toList())
+ }
+ is PlatformPccStreamEvent -> {
+ stream.write(182)
+ writeValue(stream, value.toList())
+ }
else -> super.writeValue(stream, value)
}
}
@@ -4014,3 +4442,122 @@ class NativeSheetFlutterApi(private val binaryMessenger: BinaryMessenger, privat
}
}
}
+/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
+interface PccHostApi {
+ fun getStatus(model: PlatformAppleModel, callback: (Result) -> Unit)
+ fun showQuotaIncreaseSuggestion(callback: (Result) -> Unit)
+ fun start(request: PlatformPccCompletionRequest)
+ fun cancel(runId: String)
+
+ companion object {
+ /** The codec used by PccHostApi. */
+ val codec: MessageCodec by lazy {
+ ConduitPlatformApisPigeonCodec()
+ }
+ /** Sets up an instance of `PccHostApi` to handle messages through the `binaryMessenger`. */
+ @JvmOverloads
+ fun setUp(binaryMessenger: BinaryMessenger, api: PccHostApi?, messageChannelSuffix: String = "") {
+ val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
+ run {
+ val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.conduit.PccHostApi.getStatus$separatedMessageChannelSuffix", codec)
+ if (api != null) {
+ channel.setMessageHandler { message, reply ->
+ val args = message as List
+ val modelArg = args[0] as PlatformAppleModel
+ api.getStatus(modelArg) { result: Result ->
+ val error = result.exceptionOrNull()
+ if (error != null) {
+ reply.reply(ConduitPlatformApisPigeonUtils.wrapError(error))
+ } else {
+ val data = result.getOrNull()
+ reply.reply(ConduitPlatformApisPigeonUtils.wrapResult(data))
+ }
+ }
+ }
+ } else {
+ channel.setMessageHandler(null)
+ }
+ }
+ run {
+ val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.conduit.PccHostApi.showQuotaIncreaseSuggestion$separatedMessageChannelSuffix", codec)
+ if (api != null) {
+ channel.setMessageHandler { _, reply ->
+ api.showQuotaIncreaseSuggestion{ result: Result ->
+ val error = result.exceptionOrNull()
+ if (error != null) {
+ reply.reply(ConduitPlatformApisPigeonUtils.wrapError(error))
+ } else {
+ val data = result.getOrNull()
+ reply.reply(ConduitPlatformApisPigeonUtils.wrapResult(data))
+ }
+ }
+ }
+ } else {
+ channel.setMessageHandler(null)
+ }
+ }
+ run {
+ val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.conduit.PccHostApi.start$separatedMessageChannelSuffix", codec)
+ if (api != null) {
+ channel.setMessageHandler { message, reply ->
+ val args = message as List
+ val requestArg = args[0] as PlatformPccCompletionRequest
+ val wrapped: List = try {
+ api.start(requestArg)
+ listOf(null)
+ } catch (exception: Throwable) {
+ ConduitPlatformApisPigeonUtils.wrapError(exception)
+ }
+ reply.reply(wrapped)
+ }
+ } else {
+ channel.setMessageHandler(null)
+ }
+ }
+ run {
+ val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.conduit.PccHostApi.cancel$separatedMessageChannelSuffix", codec)
+ if (api != null) {
+ channel.setMessageHandler { message, reply ->
+ val args = message as List
+ val runIdArg = args[0] as String
+ val wrapped: List = try {
+ api.cancel(runIdArg)
+ listOf(null)
+ } catch (exception: Throwable) {
+ ConduitPlatformApisPigeonUtils.wrapError(exception)
+ }
+ reply.reply(wrapped)
+ }
+ } else {
+ channel.setMessageHandler(null)
+ }
+ }
+ }
+ }
+}
+/** Generated class from Pigeon that represents Flutter messages that can be called from Kotlin. */
+class PccFlutterApi(private val binaryMessenger: BinaryMessenger, private val messageChannelSuffix: String = "") {
+ companion object {
+ /** The codec used by PccFlutterApi. */
+ val codec: MessageCodec by lazy {
+ ConduitPlatformApisPigeonCodec()
+ }
+ }
+ fun onEvent(eventArg: PlatformPccStreamEvent, callback: (Result) -> Unit)
+{
+ val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
+ val channelName = "dev.flutter.pigeon.conduit.PccFlutterApi.onEvent$separatedMessageChannelSuffix"
+ val channel = BasicMessageChannel(binaryMessenger, channelName, codec)
+ channel.send(listOf(eventArg)) {
+ if (it is List<*>) {
+ if (it.size > 1) {
+ callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
+ } else {
+ callback(Result.success(Unit))
+ }
+ } else {
+ callback(Result.failure(ConduitPlatformApisPigeonUtils.createConnectionError(channelName)))
+ }
+ }
+ }
+}
diff --git a/docs/BUILDING.md b/docs/BUILDING.md
index c52bf47c8..06112ea93 100644
--- a/docs/BUILDING.md
+++ b/docs/BUILDING.md
@@ -15,6 +15,17 @@ instead.
| iOS | Xcode with an iOS 16.0+ deployment target |
| Backend | An Open WebUI instance, an OpenAI-compatible API, an Ollama endpoint, or a Hermes server |
+Apple On-Device requires Xcode 26 and an iOS 26 device that supports Apple
+Intelligence. It uses the local SystemLanguageModel with a 4K context window;
+image input, reasoning controls, and tool parameters are rejected.
+
+Apple Private Cloud Compute additionally requires Xcode 27, an iOS 27 device
+that supports Apple Intelligence, and Apple's managed PCC entitlement. The iOS
+build keeps PCC compiled out on older SDKs while retaining the iOS 16 deployment
+target. PCC accepts image data URLs and Direct generation parameters including
+`temperature`, `max_tokens`, `top_p`, `top_k`, `seed`, and OpenAI-style
+`response_format.json_schema`; tool parameters are rejected.
+
## Clone
```bash
diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig
index be9ca906c..4377cde43 100644
--- a/ios/Flutter/Debug.xcconfig
+++ b/ios/Flutter/Debug.xcconfig
@@ -1,5 +1,6 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"
+#include "PccSdk.xcconfig"
FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*] = $(inherited) "$(FLUTTER_ROOT)/bin/cache/artifacts/engine/ios/Flutter.xcframework/ios-arm64"
FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*] = $(inherited) "$(FLUTTER_ROOT)/bin/cache/artifacts/engine/ios/Flutter.xcframework/ios-arm64_x86_64-simulator"
diff --git a/ios/Flutter/PccSdk.xcconfig b/ios/Flutter/PccSdk.xcconfig
new file mode 100644
index 000000000..fba146b42
--- /dev/null
+++ b/ios/Flutter/PccSdk.xcconfig
@@ -0,0 +1,15 @@
+// SDK 27 introduces PrivateCloudComputeLanguageModel. Keep older SDKs on the
+// compile-safe path; unknown future SDK majors opt in automatically.
+CONDUIT_PCC_SDK_FLAG_180000 = CONDUIT_NO_PCC_SDK
+CONDUIT_PCC_SDK_FLAG_190000 = CONDUIT_NO_PCC_SDK
+CONDUIT_PCC_SDK_FLAG_200000 = CONDUIT_NO_PCC_SDK
+CONDUIT_PCC_SDK_FLAG_210000 = CONDUIT_NO_PCC_SDK
+CONDUIT_PCC_SDK_FLAG_220000 = CONDUIT_NO_PCC_SDK
+CONDUIT_PCC_SDK_FLAG_230000 = CONDUIT_NO_PCC_SDK
+CONDUIT_PCC_SDK_FLAG_240000 = CONDUIT_NO_PCC_SDK
+CONDUIT_PCC_SDK_FLAG_250000 = CONDUIT_NO_PCC_SDK
+CONDUIT_PCC_SDK_FLAG_260000 = CONDUIT_NO_PCC_SDK
+CONDUIT_PCC_SDK_FLAG = $(CONDUIT_PCC_SDK_FLAG_$(SDK_VERSION_MAJOR):default=CONDUIT_PCC_SDK)
+
+SWIFT_ACTIVE_COMPILATION_CONDITIONS[sdk=iphoneos*] = $(inherited) $(CONDUIT_PCC_SDK_FLAG)
+SWIFT_ACTIVE_COMPILATION_CONDITIONS[sdk=iphonesimulator*] = $(inherited) $(CONDUIT_PCC_SDK_FLAG)
diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig
index 0b0c53642..febd8ad94 100644
--- a/ios/Flutter/Release.xcconfig
+++ b/ios/Flutter/Release.xcconfig
@@ -1,5 +1,6 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
+#include "PccSdk.xcconfig"
FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*] = $(inherited) "$(FLUTTER_ROOT)/bin/cache/artifacts/engine/ios-release/Flutter.xcframework/ios-arm64"
FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*] = $(inherited) "$(FLUTTER_ROOT)/bin/cache/artifacts/engine/ios-release/Flutter.xcframework/ios-arm64_x86_64-simulator"
diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj
index 32d768add..3a31f1c3e 100644
--- a/ios/Runner.xcodeproj/project.pbxproj
+++ b/ios/Runner.xcodeproj/project.pbxproj
@@ -27,6 +27,7 @@
D2A0B2252F5E4D6C7B8A9012 /* ConduitCarPlaySceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A0B2232F5E4D6C7B8A9012 /* ConduitCarPlaySceneDelegate.swift */; };
D2A0B2262F5E4D6C7B8A9012 /* CarPlay.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2A0B2212F5E4D6C7B8A9012 /* CarPlay.framework */; };
D2A0B2312F5E4D6C7B8A9012 /* NativeShareEnvelopeStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A0B2302F5E4D6C7B8A9012 /* NativeShareEnvelopeStore.swift */; };
+ D2A0B2412F5E4D6C7B8A9012 /* PccBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A0B2402F5E4D6C7B8A9012 /* PccBridge.swift */; };
F15AFEC42EE5499D00A1FABB /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F15AFEC32EE5499D00A1FABB /* WidgetKit.framework */; };
F15AFEC62EE5499D00A1FABB /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F15AFEC52EE5499D00A1FABB /* SwiftUI.framework */; };
F15AFED12EE5499E00A1FABB /* ConduitWidgetExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = F15AFEC22EE5499D00A1FABB /* ConduitWidgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
@@ -118,6 +119,7 @@
D2A0B2222F5E4D6C7B8A9012 /* ConduitCarPlayBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConduitCarPlayBridge.swift; sourceTree = ""; };
D2A0B2232F5E4D6C7B8A9012 /* ConduitCarPlaySceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConduitCarPlaySceneDelegate.swift; sourceTree = ""; };
D2A0B2302F5E4D6C7B8A9012 /* NativeShareEnvelopeStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ../ShareExtension/NativeShareEnvelopeStore.swift; sourceTree = ""; };
+ D2A0B2402F5E4D6C7B8A9012 /* PccBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PccBridge.swift; sourceTree = ""; };
D2A0B3012F5E4D6C7B8A9012 /* ConduitWidget.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = ConduitWidget/ConduitWidget.xcconfig; sourceTree = ""; };
D2A0B3022F5E4D6C7B8A9012 /* ShareExtension.debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = ShareExtension/ShareExtension.debug.xcconfig; sourceTree = ""; };
D2A0B3032F5E4D6C7B8A9012 /* ShareExtension.release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = ShareExtension/ShareExtension.release.xcconfig; sourceTree = ""; };
@@ -335,6 +337,7 @@
D2A0B1E62F5E4D6C7B8A9012 /* NativeSheetUIFoundation.swift */,
D2A0B1F32F5E4D6C7B8A9012 /* NativeDropdownBridge.swift */,
D2A0B2032F5E4D6C7B8A9012 /* NativeSttBridge.swift */,
+ D2A0B2402F5E4D6C7B8A9012 /* PccBridge.swift */,
D2A0B2052F5E4D6C7B8A9012 /* ConduitSceneDelegate.swift */,
D2A0B2222F5E4D6C7B8A9012 /* ConduitCarPlayBridge.swift */,
D2A0B2232F5E4D6C7B8A9012 /* ConduitCarPlaySceneDelegate.swift */,
@@ -656,6 +659,7 @@
D2A0B1E42F5E4D6C7B8A9012 /* NativeSheetBridge.swift in Sources */,
D2A0B1E52F5E4D6C7B8A9012 /* NativeSheetUIFoundation.swift in Sources */,
D2A0B2042F5E4D6C7B8A9012 /* NativeSttBridge.swift in Sources */,
+ D2A0B2412F5E4D6C7B8A9012 /* PccBridge.swift in Sources */,
D2A0B1D42F5E4D6C7B8A9012 /* NativeKeyboardAttachmentBridge.swift in Sources */,
D2A0B1C42F5E4D6C7B8A9012 /* NativePasteBridge.swift in Sources */,
D2A0B2312F5E4D6C7B8A9012 /* NativeShareEnvelopeStore.swift in Sources */,
diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift
index 6c4c0a74e..1bc57e2d1 100644
--- a/ios/Runner/AppDelegate.swift
+++ b/ios/Runner/AppDelegate.swift
@@ -2443,6 +2443,7 @@ private func cookieIsPreferred(
NativeSheetBridge.shared.configure(messenger: messenger)
NativeDropdownBridge.shared.configure(messenger: messenger)
NativeSttBridge.shared.configure(messenger: messenger)
+ PccBridge.shared.configure(messenger: messenger)
VoiceAudioRouteBridge.shared.configure(messenger: messenger)
NativeIosTtsBridge.shared.configure(messenger: messenger)
backgroundStreamingHandler?.setup(messenger: messenger)
diff --git a/ios/Runner/ConduitPlatformApis.g.swift b/ios/Runner/ConduitPlatformApis.g.swift
index 452f2ba6d..d8c1a485c 100644
--- a/ios/Runner/ConduitPlatformApis.g.swift
+++ b/ios/Runner/ConduitPlatformApis.g.swift
@@ -199,6 +199,32 @@ enum PlatformNativePasteKind: Int, CaseIterable {
case unsupported = 2
}
+enum PlatformPccAvailability: Int, CaseIterable {
+ case available = 0
+ case unavailable = 1
+ case unsupported = 2
+}
+
+enum PlatformAppleModel: Int, CaseIterable {
+ case onDevice = 0
+ case privateCloudCompute = 1
+}
+
+enum PlatformPccQuotaStatus: Int, CaseIterable {
+ case belowLimit = 0
+ case approachingLimit = 1
+ case limitReached = 2
+ case unknown = 3
+}
+
+enum PlatformPccEventKind: Int, CaseIterable {
+ case content = 0
+ case usage = 1
+ case fallback = 2
+ case error = 3
+ case done = 4
+}
+
enum PlatformNativeSheetItemKind: Int, CaseIterable {
case navigation = 0
case textField = 1
@@ -2620,6 +2646,321 @@ struct PlatformNativeSheetActionResult: Hashable, CustomStringConvertible {
}
}
+/// Generated class from Pigeon that represents data sent in messages.
+struct PlatformPccStatus: Hashable, CustomStringConvertible {
+ var availability: PlatformPccAvailability
+ var quotaStatus: PlatformPccQuotaStatus
+ var quotaLimitReached: Bool
+ var canIncreaseQuota: Bool
+ var message: String? = nil
+ var quotaResetAtMilliseconds: Int64? = nil
+ var contextSize: Int64? = nil
+ var supportsCurrentLocale: Bool? = nil
+
+
+ // swift-format-ignore: AlwaysUseLowerCamelCase
+ static func fromList(_ pigeonVar_list: [Any?]) -> PlatformPccStatus? {
+ let availability = pigeonVar_list[0] as! PlatformPccAvailability
+ let quotaStatus = pigeonVar_list[1] as! PlatformPccQuotaStatus
+ let quotaLimitReached = pigeonVar_list[2] as! Bool
+ let canIncreaseQuota = pigeonVar_list[3] as! Bool
+ let message: String? = nilOrValue(pigeonVar_list[4])
+ let quotaResetAtMilliseconds: Int64? = nilOrValue(pigeonVar_list[5])
+ let contextSize: Int64? = nilOrValue(pigeonVar_list[6])
+ let supportsCurrentLocale: Bool? = nilOrValue(pigeonVar_list[7])
+
+ return PlatformPccStatus(
+ availability: availability,
+ quotaStatus: quotaStatus,
+ quotaLimitReached: quotaLimitReached,
+ canIncreaseQuota: canIncreaseQuota,
+ message: message,
+ quotaResetAtMilliseconds: quotaResetAtMilliseconds,
+ contextSize: contextSize,
+ supportsCurrentLocale: supportsCurrentLocale
+ )
+ }
+ func toList() -> [Any?] {
+ return [
+ availability,
+ quotaStatus,
+ quotaLimitReached,
+ canIncreaseQuota,
+ message,
+ quotaResetAtMilliseconds,
+ contextSize,
+ supportsCurrentLocale,
+ ]
+ }
+ static func == (lhs: PlatformPccStatus, rhs: PlatformPccStatus) -> Bool {
+ if Swift.type(of: lhs) != Swift.type(of: rhs) {
+ return false
+ }
+ return ConduitPlatformApisPigeonInternal.deepEquals(lhs.availability, rhs.availability) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.quotaStatus, rhs.quotaStatus) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.quotaLimitReached, rhs.quotaLimitReached) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.canIncreaseQuota, rhs.canIncreaseQuota) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.message, rhs.message) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.quotaResetAtMilliseconds, rhs.quotaResetAtMilliseconds) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.contextSize, rhs.contextSize) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.supportsCurrentLocale, rhs.supportsCurrentLocale)
+ }
+
+ func hash(into hasher: inout Hasher) {
+ hasher.combine("PlatformPccStatus")
+ ConduitPlatformApisPigeonInternal.deepHash(value: availability, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: quotaStatus, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: quotaLimitReached, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: canIncreaseQuota, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: message, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: quotaResetAtMilliseconds, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: contextSize, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: supportsCurrentLocale, hasher: &hasher)
+ }
+
+ public var description: String {
+ return "PlatformPccStatus(availability: \(String(describing: availability)), quotaStatus: \(String(describing: quotaStatus)), quotaLimitReached: \(String(describing: quotaLimitReached)), canIncreaseQuota: \(String(describing: canIncreaseQuota)), message: \(String(describing: message)), quotaResetAtMilliseconds: \(String(describing: quotaResetAtMilliseconds)), contextSize: \(String(describing: contextSize)), supportsCurrentLocale: \(String(describing: supportsCurrentLocale)))"
+ }
+}
+
+/// Generated class from Pigeon that represents data sent in messages.
+struct PlatformPccImage: Hashable, CustomStringConvertible {
+ var mimeType: String
+ var bytes: FlutterStandardTypedData
+
+
+ // swift-format-ignore: AlwaysUseLowerCamelCase
+ static func fromList(_ pigeonVar_list: [Any?]) -> PlatformPccImage? {
+ let mimeType = pigeonVar_list[0] as! String
+ let bytes = pigeonVar_list[1] as! FlutterStandardTypedData
+
+ return PlatformPccImage(
+ mimeType: mimeType,
+ bytes: bytes
+ )
+ }
+ func toList() -> [Any?] {
+ return [
+ mimeType,
+ bytes,
+ ]
+ }
+ static func == (lhs: PlatformPccImage, rhs: PlatformPccImage) -> Bool {
+ if Swift.type(of: lhs) != Swift.type(of: rhs) {
+ return false
+ }
+ return ConduitPlatformApisPigeonInternal.deepEquals(lhs.mimeType, rhs.mimeType) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.bytes, rhs.bytes)
+ }
+
+ func hash(into hasher: inout Hasher) {
+ hasher.combine("PlatformPccImage")
+ ConduitPlatformApisPigeonInternal.deepHash(value: mimeType, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: bytes, hasher: &hasher)
+ }
+
+ public var description: String {
+ return "PlatformPccImage(mimeType: \(String(describing: mimeType)), bytes: \(String(describing: bytes)))"
+ }
+}
+
+/// Generated class from Pigeon that represents data sent in messages.
+struct PlatformPccMessage: Hashable, CustomStringConvertible {
+ var role: String
+ var content: String
+ var images: [PlatformPccImage]
+
+
+ // swift-format-ignore: AlwaysUseLowerCamelCase
+ static func fromList(_ pigeonVar_list: [Any?]) -> PlatformPccMessage? {
+ let role = pigeonVar_list[0] as! String
+ let content = pigeonVar_list[1] as! String
+ let images = pigeonVar_list[2] as! [PlatformPccImage]
+
+ return PlatformPccMessage(
+ role: role,
+ content: content,
+ images: images
+ )
+ }
+ func toList() -> [Any?] {
+ return [
+ role,
+ content,
+ images,
+ ]
+ }
+ static func == (lhs: PlatformPccMessage, rhs: PlatformPccMessage) -> Bool {
+ if Swift.type(of: lhs) != Swift.type(of: rhs) {
+ return false
+ }
+ return ConduitPlatformApisPigeonInternal.deepEquals(lhs.role, rhs.role) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.content, rhs.content) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.images, rhs.images)
+ }
+
+ func hash(into hasher: inout Hasher) {
+ hasher.combine("PlatformPccMessage")
+ ConduitPlatformApisPigeonInternal.deepHash(value: role, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: content, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: images, hasher: &hasher)
+ }
+
+ public var description: String {
+ return "PlatformPccMessage(role: \(String(describing: role)), content: \(String(describing: content)), images: \(String(describing: images)))"
+ }
+}
+
+/// Generated class from Pigeon that represents data sent in messages.
+struct PlatformPccCompletionRequest: Hashable, CustomStringConvertible {
+ var runId: String
+ var model: PlatformAppleModel
+ var messages: [PlatformPccMessage]
+ var allowOnDeviceFallback: Bool
+ var reasoningLevel: String? = nil
+ var temperature: Double? = nil
+ var maximumResponseTokens: Int64? = nil
+ var topP: Double? = nil
+ var topK: Int64? = nil
+ var seed: Int64? = nil
+ var greedySampling: Bool? = nil
+ var responseSchemaName: String? = nil
+ var responseSchemaJson: String? = nil
+
+
+ // swift-format-ignore: AlwaysUseLowerCamelCase
+ static func fromList(_ pigeonVar_list: [Any?]) -> PlatformPccCompletionRequest? {
+ let runId = pigeonVar_list[0] as! String
+ let model = pigeonVar_list[1] as! PlatformAppleModel
+ let messages = pigeonVar_list[2] as! [PlatformPccMessage]
+ let allowOnDeviceFallback = pigeonVar_list[3] as! Bool
+ let reasoningLevel: String? = nilOrValue(pigeonVar_list[4])
+ let temperature: Double? = nilOrValue(pigeonVar_list[5])
+ let maximumResponseTokens: Int64? = nilOrValue(pigeonVar_list[6])
+ let topP: Double? = nilOrValue(pigeonVar_list[7])
+ let topK: Int64? = nilOrValue(pigeonVar_list[8])
+ let seed: Int64? = nilOrValue(pigeonVar_list[9])
+ let greedySampling: Bool? = nilOrValue(pigeonVar_list[10])
+ let responseSchemaName: String? = nilOrValue(pigeonVar_list[11])
+ let responseSchemaJson: String? = nilOrValue(pigeonVar_list[12])
+
+ return PlatformPccCompletionRequest(
+ runId: runId,
+ model: model,
+ messages: messages,
+ allowOnDeviceFallback: allowOnDeviceFallback,
+ reasoningLevel: reasoningLevel,
+ temperature: temperature,
+ maximumResponseTokens: maximumResponseTokens,
+ topP: topP,
+ topK: topK,
+ seed: seed,
+ greedySampling: greedySampling,
+ responseSchemaName: responseSchemaName,
+ responseSchemaJson: responseSchemaJson
+ )
+ }
+ func toList() -> [Any?] {
+ return [
+ runId,
+ model,
+ messages,
+ allowOnDeviceFallback,
+ reasoningLevel,
+ temperature,
+ maximumResponseTokens,
+ topP,
+ topK,
+ seed,
+ greedySampling,
+ responseSchemaName,
+ responseSchemaJson,
+ ]
+ }
+ static func == (lhs: PlatformPccCompletionRequest, rhs: PlatformPccCompletionRequest) -> Bool {
+ if Swift.type(of: lhs) != Swift.type(of: rhs) {
+ return false
+ }
+ return ConduitPlatformApisPigeonInternal.deepEquals(lhs.runId, rhs.runId) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.model, rhs.model) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.messages, rhs.messages) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.allowOnDeviceFallback, rhs.allowOnDeviceFallback) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.reasoningLevel, rhs.reasoningLevel) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.temperature, rhs.temperature) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.maximumResponseTokens, rhs.maximumResponseTokens) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.topP, rhs.topP) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.topK, rhs.topK) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.seed, rhs.seed) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.greedySampling, rhs.greedySampling) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.responseSchemaName, rhs.responseSchemaName) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.responseSchemaJson, rhs.responseSchemaJson)
+ }
+
+ func hash(into hasher: inout Hasher) {
+ hasher.combine("PlatformPccCompletionRequest")
+ ConduitPlatformApisPigeonInternal.deepHash(value: runId, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: model, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: messages, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: allowOnDeviceFallback, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: reasoningLevel, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: temperature, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: maximumResponseTokens, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: topP, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: topK, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: seed, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: greedySampling, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: responseSchemaName, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: responseSchemaJson, hasher: &hasher)
+ }
+
+ public var description: String {
+ return "PlatformPccCompletionRequest(runId: \(String(describing: runId)), model: \(String(describing: model)), messages: \(String(describing: messages)), allowOnDeviceFallback: \(String(describing: allowOnDeviceFallback)), reasoningLevel: \(String(describing: reasoningLevel)), temperature: \(String(describing: temperature)), maximumResponseTokens: \(String(describing: maximumResponseTokens)), topP: \(String(describing: topP)), topK: \(String(describing: topK)), seed: \(String(describing: seed)), greedySampling: \(String(describing: greedySampling)), responseSchemaName: \(String(describing: responseSchemaName)), responseSchemaJson: \(String(describing: responseSchemaJson)))"
+ }
+}
+
+/// Generated class from Pigeon that represents data sent in messages.
+struct PlatformPccStreamEvent: Hashable, CustomStringConvertible {
+ var runId: String
+ var kind: PlatformPccEventKind
+ var content: String? = nil
+ var inputTokenCount: Int64? = nil
+ var outputTokenCount: Int64? = nil
+ var reasoningTokenCount: Int64? = nil
+ var totalTokenCount: Int64? = nil
+
+
+ // swift-format-ignore: AlwaysUseLowerCamelCase
+ static func fromList(_ pigeonVar_list: [Any?]) -> PlatformPccStreamEvent? {
+ let runId = pigeonVar_list[0] as! String
+ let kind = pigeonVar_list[1] as! PlatformPccEventKind
+ let content: String? = nilOrValue(pigeonVar_list[2])
+ let inputTokenCount: Int64? = nilOrValue(pigeonVar_list[3])
+ let outputTokenCount: Int64? = nilOrValue(pigeonVar_list[4])
+ let reasoningTokenCount: Int64? = nilOrValue(pigeonVar_list[5])
+ let totalTokenCount: Int64? = nilOrValue(pigeonVar_list[6])
+
+ return PlatformPccStreamEvent(
+ runId: runId,
+ kind: kind,
+ content: content,
+ inputTokenCount: inputTokenCount,
+ outputTokenCount: outputTokenCount,
+ reasoningTokenCount: reasoningTokenCount,
+ totalTokenCount: totalTokenCount
+ )
+ }
+ func toList() -> [Any?] {
+ return [
+ runId,
+ kind,
+ content,
+ inputTokenCount,
+ outputTokenCount,
+ reasoningTokenCount,
+ totalTokenCount,
+ ]
+ }
+ static func == (lhs: PlatformPccStreamEvent, rhs: PlatformPccStreamEvent) -> Bool {
+ if Swift.type(of: lhs) != Swift.type(of: rhs) {
+ return false
+ }
+ return ConduitPlatformApisPigeonInternal.deepEquals(lhs.runId, rhs.runId) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.kind, rhs.kind) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.content, rhs.content) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.inputTokenCount, rhs.inputTokenCount) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.outputTokenCount, rhs.outputTokenCount) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.reasoningTokenCount, rhs.reasoningTokenCount) && ConduitPlatformApisPigeonInternal.deepEquals(lhs.totalTokenCount, rhs.totalTokenCount)
+ }
+
+ func hash(into hasher: inout Hasher) {
+ hasher.combine("PlatformPccStreamEvent")
+ ConduitPlatformApisPigeonInternal.deepHash(value: runId, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: kind, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: content, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: inputTokenCount, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: outputTokenCount, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: reasoningTokenCount, hasher: &hasher)
+ ConduitPlatformApisPigeonInternal.deepHash(value: totalTokenCount, hasher: &hasher)
+ }
+
+ public var description: String {
+ return "PlatformPccStreamEvent(runId: \(String(describing: runId)), kind: \(String(describing: kind)), content: \(String(describing: content)), inputTokenCount: \(String(describing: inputTokenCount)), outputTokenCount: \(String(describing: outputTokenCount)), reasoningTokenCount: \(String(describing: reasoningTokenCount)), totalTokenCount: \(String(describing: totalTokenCount)))"
+ }
+}
+
private class ConduitPlatformApisPigeonCodecReader: FlutterStandardReader {
override func readValue(ofType type: UInt8) -> Any? {
switch type {
@@ -2638,93 +2979,127 @@ private class ConduitPlatformApisPigeonCodecReader: FlutterStandardReader {
case 131:
let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?)
if let enumResultAsInt = enumResultAsInt {
- return PlatformNativeSheetItemKind(rawValue: enumResultAsInt)
+ return PlatformPccAvailability(rawValue: enumResultAsInt)
}
return nil
case 132:
- return PlatformBackgroundStreamLease.fromList(self.readValue() as! [Any?])
+ let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?)
+ if let enumResultAsInt = enumResultAsInt {
+ return PlatformAppleModel(rawValue: enumResultAsInt)
+ }
+ return nil
case 133:
- return PlatformBackgroundStartRequest.fromList(self.readValue() as! [Any?])
+ let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?)
+ if let enumResultAsInt = enumResultAsInt {
+ return PlatformPccQuotaStatus(rawValue: enumResultAsInt)
+ }
+ return nil
case 134:
- return PlatformBackgroundStopRequest.fromList(self.readValue() as! [Any?])
+ let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?)
+ if let enumResultAsInt = enumResultAsInt {
+ return PlatformPccEventKind(rawValue: enumResultAsInt)
+ }
+ return nil
case 135:
- return PlatformBackgroundKeepAliveRequest.fromList(self.readValue() as! [Any?])
+ let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?)
+ if let enumResultAsInt = enumResultAsInt {
+ return PlatformNativeSheetItemKind(rawValue: enumResultAsInt)
+ }
+ return nil
case 136:
- return PlatformBackgroundAudioSessionOwnerRequest.fromList(self.readValue() as! [Any?])
+ return PlatformBackgroundStreamLease.fromList(self.readValue() as! [Any?])
case 137:
- return PlatformServiceFailureEvent.fromList(self.readValue() as! [Any?])
+ return PlatformBackgroundStartRequest.fromList(self.readValue() as! [Any?])
case 138:
- return PlatformTimeLimitWarningEvent.fromList(self.readValue() as! [Any?])
+ return PlatformBackgroundStopRequest.fromList(self.readValue() as! [Any?])
case 139:
- return PlatformStreamsSuspendingEvent.fromList(self.readValue() as! [Any?])
+ return PlatformBackgroundKeepAliveRequest.fromList(self.readValue() as! [Any?])
case 140:
- return PlatformBackgroundTaskExtendedEvent.fromList(self.readValue() as! [Any?])
+ return PlatformBackgroundAudioSessionOwnerRequest.fromList(self.readValue() as! [Any?])
case 141:
- return PlatformAppIntentImagePayload.fromList(self.readValue() as! [Any?])
+ return PlatformServiceFailureEvent.fromList(self.readValue() as! [Any?])
case 142:
- return PlatformAppIntentResponse.fromList(self.readValue() as! [Any?])
+ return PlatformTimeLimitWarningEvent.fromList(self.readValue() as! [Any?])
case 143:
- return PlatformNativePasteImageItem.fromList(self.readValue() as! [Any?])
+ return PlatformStreamsSuspendingEvent.fromList(self.readValue() as! [Any?])
case 144:
- return PlatformNativePastePayload.fromList(self.readValue() as! [Any?])
+ return PlatformBackgroundTaskExtendedEvent.fromList(self.readValue() as! [Any?])
case 145:
- return PlatformKeyboardAttachmentActionConfig.fromList(self.readValue() as! [Any?])
+ return PlatformAppIntentImagePayload.fromList(self.readValue() as! [Any?])
case 146:
- return PlatformKeyboardAttachmentConfig.fromList(self.readValue() as! [Any?])
+ return PlatformAppIntentResponse.fromList(self.readValue() as! [Any?])
case 147:
- return PlatformKeyboardAttachmentActionEvent.fromList(self.readValue() as! [Any?])
+ return PlatformNativePasteImageItem.fromList(self.readValue() as! [Any?])
case 148:
- return PlatformKeyboardAttachmentVisibilityEvent.fromList(self.readValue() as! [Any?])
+ return PlatformNativePastePayload.fromList(self.readValue() as! [Any?])
case 149:
- return PlatformRect.fromList(self.readValue() as! [Any?])
+ return PlatformKeyboardAttachmentActionConfig.fromList(self.readValue() as! [Any?])
case 150:
- return PlatformDropdownOption.fromList(self.readValue() as! [Any?])
+ return PlatformKeyboardAttachmentConfig.fromList(self.readValue() as! [Any?])
case 151:
- return PlatformDropdownRequest.fromList(self.readValue() as! [Any?])
+ return PlatformKeyboardAttachmentActionEvent.fromList(self.readValue() as! [Any?])
case 152:
- return PlatformNativeSheetOption.fromList(self.readValue() as! [Any?])
+ return PlatformKeyboardAttachmentVisibilityEvent.fromList(self.readValue() as! [Any?])
case 153:
- return PlatformNativeSheetTheme.fromList(self.readValue() as! [Any?])
+ return PlatformRect.fromList(self.readValue() as! [Any?])
case 154:
- return PlatformNativeSheetItem.fromList(self.readValue() as! [Any?])
+ return PlatformDropdownOption.fromList(self.readValue() as! [Any?])
case 155:
- return PlatformNativeSheetLink.fromList(self.readValue() as! [Any?])
+ return PlatformDropdownRequest.fromList(self.readValue() as! [Any?])
case 156:
- return PlatformNativeSheetSection.fromList(self.readValue() as! [Any?])
+ return PlatformNativeSheetOption.fromList(self.readValue() as! [Any?])
case 157:
- return PlatformNativeEditProfileSheetConfig.fromList(self.readValue() as! [Any?])
+ return PlatformNativeSheetTheme.fromList(self.readValue() as! [Any?])
case 158:
- return PlatformNativeProfileSheetUser.fromList(self.readValue() as! [Any?])
+ return PlatformNativeSheetItem.fromList(self.readValue() as! [Any?])
case 159:
- return PlatformNativeSheetDetail.fromList(self.readValue() as! [Any?])
+ return PlatformNativeSheetLink.fromList(self.readValue() as! [Any?])
case 160:
- return PlatformNativeProfileSheetConfig.fromList(self.readValue() as! [Any?])
+ return PlatformNativeSheetSection.fromList(self.readValue() as! [Any?])
case 161:
- return PlatformNativeSheetModelOption.fromList(self.readValue() as! [Any?])
+ return PlatformNativeEditProfileSheetConfig.fromList(self.readValue() as! [Any?])
case 162:
- return PlatformNativeSheetModelSelectorRequest.fromList(self.readValue() as! [Any?])
+ return PlatformNativeProfileSheetUser.fromList(self.readValue() as! [Any?])
case 163:
- return PlatformNativeSheetOptionsSelectorRequest.fromList(self.readValue() as! [Any?])
+ return PlatformNativeSheetDetail.fromList(self.readValue() as! [Any?])
case 164:
- return PlatformNativeSheetDatePickerRequest.fromList(self.readValue() as! [Any?])
+ return PlatformNativeProfileSheetConfig.fromList(self.readValue() as! [Any?])
case 165:
- return PlatformNativeSheetTextEditorRequest.fromList(self.readValue() as! [Any?])
+ return PlatformNativeSheetModelOption.fromList(self.readValue() as! [Any?])
case 166:
- return PlatformNativeSheetResultRequest.fromList(self.readValue() as! [Any?])
+ return PlatformNativeSheetModelSelectorRequest.fromList(self.readValue() as! [Any?])
case 167:
- return PlatformNativeSheetApplyDetailPatchRequest.fromList(self.readValue() as! [Any?])
+ return PlatformNativeSheetOptionsSelectorRequest.fromList(self.readValue() as! [Any?])
case 168:
- return PlatformNativeSheetControlChangedEvent.fromList(self.readValue() as! [Any?])
+ return PlatformNativeSheetDatePickerRequest.fromList(self.readValue() as! [Any?])
case 169:
- return PlatformNativeSheetDetailAppearedEvent.fromList(self.readValue() as! [Any?])
+ return PlatformNativeSheetTextEditorRequest.fromList(self.readValue() as! [Any?])
case 170:
- return PlatformNativeSheetModelPinToggledEvent.fromList(self.readValue() as! [Any?])
+ return PlatformNativeSheetResultRequest.fromList(self.readValue() as! [Any?])
case 171:
- return PlatformNativeSheetReasoningEffortChangedEvent.fromList(self.readValue() as! [Any?])
+ return PlatformNativeSheetApplyDetailPatchRequest.fromList(self.readValue() as! [Any?])
case 172:
- return PlatformNativeEditProfileCommittedEvent.fromList(self.readValue() as! [Any?])
+ return PlatformNativeSheetControlChangedEvent.fromList(self.readValue() as! [Any?])
case 173:
+ return PlatformNativeSheetDetailAppearedEvent.fromList(self.readValue() as! [Any?])
+ case 174:
+ return PlatformNativeSheetModelPinToggledEvent.fromList(self.readValue() as! [Any?])
+ case 175:
+ return PlatformNativeSheetReasoningEffortChangedEvent.fromList(self.readValue() as! [Any?])
+ case 176:
+ return PlatformNativeEditProfileCommittedEvent.fromList(self.readValue() as! [Any?])
+ case 177:
return PlatformNativeSheetActionResult.fromList(self.readValue() as! [Any?])
+ case 178:
+ return PlatformPccStatus.fromList(self.readValue() as! [Any?])
+ case 179:
+ return PlatformPccImage.fromList(self.readValue() as! [Any?])
+ case 180:
+ return PlatformPccMessage.fromList(self.readValue() as! [Any?])
+ case 181:
+ return PlatformPccCompletionRequest.fromList(self.readValue() as! [Any?])
+ case 182:
+ return PlatformPccStreamEvent.fromList(self.readValue() as! [Any?])
default:
return super.readValue(ofType: type)
}
@@ -2739,135 +3114,162 @@ private class ConduitPlatformApisPigeonCodecWriter: FlutterStandardWriter {
} else if let value = value as? PlatformNativePasteKind {
super.writeByte(130)
super.writeValue(value.rawValue)
- } else if let value = value as? PlatformNativeSheetItemKind {
+ } else if let value = value as? PlatformPccAvailability {
super.writeByte(131)
super.writeValue(value.rawValue)
- } else if let value = value as? PlatformBackgroundStreamLease {
+ } else if let value = value as? PlatformAppleModel {
super.writeByte(132)
- super.writeValue(value.toList())
- } else if let value = value as? PlatformBackgroundStartRequest {
+ super.writeValue(value.rawValue)
+ } else if let value = value as? PlatformPccQuotaStatus {
super.writeByte(133)
- super.writeValue(value.toList())
- } else if let value = value as? PlatformBackgroundStopRequest {
+ super.writeValue(value.rawValue)
+ } else if let value = value as? PlatformPccEventKind {
super.writeByte(134)
- super.writeValue(value.toList())
- } else if let value = value as? PlatformBackgroundKeepAliveRequest {
+ super.writeValue(value.rawValue)
+ } else if let value = value as? PlatformNativeSheetItemKind {
super.writeByte(135)
- super.writeValue(value.toList())
- } else if let value = value as? PlatformBackgroundAudioSessionOwnerRequest {
+ super.writeValue(value.rawValue)
+ } else if let value = value as? PlatformBackgroundStreamLease {
super.writeByte(136)
super.writeValue(value.toList())
- } else if let value = value as? PlatformServiceFailureEvent {
+ } else if let value = value as? PlatformBackgroundStartRequest {
super.writeByte(137)
super.writeValue(value.toList())
- } else if let value = value as? PlatformTimeLimitWarningEvent {
+ } else if let value = value as? PlatformBackgroundStopRequest {
super.writeByte(138)
super.writeValue(value.toList())
- } else if let value = value as? PlatformStreamsSuspendingEvent {
+ } else if let value = value as? PlatformBackgroundKeepAliveRequest {
super.writeByte(139)
super.writeValue(value.toList())
- } else if let value = value as? PlatformBackgroundTaskExtendedEvent {
+ } else if let value = value as? PlatformBackgroundAudioSessionOwnerRequest {
super.writeByte(140)
super.writeValue(value.toList())
- } else if let value = value as? PlatformAppIntentImagePayload {
+ } else if let value = value as? PlatformServiceFailureEvent {
super.writeByte(141)
super.writeValue(value.toList())
- } else if let value = value as? PlatformAppIntentResponse {
+ } else if let value = value as? PlatformTimeLimitWarningEvent {
super.writeByte(142)
super.writeValue(value.toList())
- } else if let value = value as? PlatformNativePasteImageItem {
+ } else if let value = value as? PlatformStreamsSuspendingEvent {
super.writeByte(143)
super.writeValue(value.toList())
- } else if let value = value as? PlatformNativePastePayload {
+ } else if let value = value as? PlatformBackgroundTaskExtendedEvent {
super.writeByte(144)
super.writeValue(value.toList())
- } else if let value = value as? PlatformKeyboardAttachmentActionConfig {
+ } else if let value = value as? PlatformAppIntentImagePayload {
super.writeByte(145)
super.writeValue(value.toList())
- } else if let value = value as? PlatformKeyboardAttachmentConfig {
+ } else if let value = value as? PlatformAppIntentResponse {
super.writeByte(146)
super.writeValue(value.toList())
- } else if let value = value as? PlatformKeyboardAttachmentActionEvent {
+ } else if let value = value as? PlatformNativePasteImageItem {
super.writeByte(147)
super.writeValue(value.toList())
- } else if let value = value as? PlatformKeyboardAttachmentVisibilityEvent {
+ } else if let value = value as? PlatformNativePastePayload {
super.writeByte(148)
super.writeValue(value.toList())
- } else if let value = value as? PlatformRect {
+ } else if let value = value as? PlatformKeyboardAttachmentActionConfig {
super.writeByte(149)
super.writeValue(value.toList())
- } else if let value = value as? PlatformDropdownOption {
+ } else if let value = value as? PlatformKeyboardAttachmentConfig {
super.writeByte(150)
super.writeValue(value.toList())
- } else if let value = value as? PlatformDropdownRequest {
+ } else if let value = value as? PlatformKeyboardAttachmentActionEvent {
super.writeByte(151)
super.writeValue(value.toList())
- } else if let value = value as? PlatformNativeSheetOption {
+ } else if let value = value as? PlatformKeyboardAttachmentVisibilityEvent {
super.writeByte(152)
super.writeValue(value.toList())
- } else if let value = value as? PlatformNativeSheetTheme {
+ } else if let value = value as? PlatformRect {
super.writeByte(153)
super.writeValue(value.toList())
- } else if let value = value as? PlatformNativeSheetItem {
+ } else if let value = value as? PlatformDropdownOption {
super.writeByte(154)
super.writeValue(value.toList())
- } else if let value = value as? PlatformNativeSheetLink {
+ } else if let value = value as? PlatformDropdownRequest {
super.writeByte(155)
super.writeValue(value.toList())
- } else if let value = value as? PlatformNativeSheetSection {
+ } else if let value = value as? PlatformNativeSheetOption {
super.writeByte(156)
super.writeValue(value.toList())
- } else if let value = value as? PlatformNativeEditProfileSheetConfig {
+ } else if let value = value as? PlatformNativeSheetTheme {
super.writeByte(157)
super.writeValue(value.toList())
- } else if let value = value as? PlatformNativeProfileSheetUser {
+ } else if let value = value as? PlatformNativeSheetItem {
super.writeByte(158)
super.writeValue(value.toList())
- } else if let value = value as? PlatformNativeSheetDetail {
+ } else if let value = value as? PlatformNativeSheetLink {
super.writeByte(159)
super.writeValue(value.toList())
- } else if let value = value as? PlatformNativeProfileSheetConfig {
+ } else if let value = value as? PlatformNativeSheetSection {
super.writeByte(160)
super.writeValue(value.toList())
- } else if let value = value as? PlatformNativeSheetModelOption {
+ } else if let value = value as? PlatformNativeEditProfileSheetConfig {
super.writeByte(161)
super.writeValue(value.toList())
- } else if let value = value as? PlatformNativeSheetModelSelectorRequest {
+ } else if let value = value as? PlatformNativeProfileSheetUser {
super.writeByte(162)
super.writeValue(value.toList())
- } else if let value = value as? PlatformNativeSheetOptionsSelectorRequest {
+ } else if let value = value as? PlatformNativeSheetDetail {
super.writeByte(163)
super.writeValue(value.toList())
- } else if let value = value as? PlatformNativeSheetDatePickerRequest {
+ } else if let value = value as? PlatformNativeProfileSheetConfig {
super.writeByte(164)
super.writeValue(value.toList())
- } else if let value = value as? PlatformNativeSheetTextEditorRequest {
+ } else if let value = value as? PlatformNativeSheetModelOption {
super.writeByte(165)
super.writeValue(value.toList())
- } else if let value = value as? PlatformNativeSheetResultRequest {
+ } else if let value = value as? PlatformNativeSheetModelSelectorRequest {
super.writeByte(166)
super.writeValue(value.toList())
- } else if let value = value as? PlatformNativeSheetApplyDetailPatchRequest {
+ } else if let value = value as? PlatformNativeSheetOptionsSelectorRequest {
super.writeByte(167)
super.writeValue(value.toList())
- } else if let value = value as? PlatformNativeSheetControlChangedEvent {
+ } else if let value = value as? PlatformNativeSheetDatePickerRequest {
super.writeByte(168)
super.writeValue(value.toList())
- } else if let value = value as? PlatformNativeSheetDetailAppearedEvent {
+ } else if let value = value as? PlatformNativeSheetTextEditorRequest {
super.writeByte(169)
super.writeValue(value.toList())
- } else if let value = value as? PlatformNativeSheetModelPinToggledEvent {
+ } else if let value = value as? PlatformNativeSheetResultRequest {
super.writeByte(170)
super.writeValue(value.toList())
- } else if let value = value as? PlatformNativeSheetReasoningEffortChangedEvent {
+ } else if let value = value as? PlatformNativeSheetApplyDetailPatchRequest {
super.writeByte(171)
super.writeValue(value.toList())
- } else if let value = value as? PlatformNativeEditProfileCommittedEvent {
+ } else if let value = value as? PlatformNativeSheetControlChangedEvent {
super.writeByte(172)
super.writeValue(value.toList())
- } else if let value = value as? PlatformNativeSheetActionResult {
+ } else if let value = value as? PlatformNativeSheetDetailAppearedEvent {
super.writeByte(173)
super.writeValue(value.toList())
+ } else if let value = value as? PlatformNativeSheetModelPinToggledEvent {
+ super.writeByte(174)
+ super.writeValue(value.toList())
+ } else if let value = value as? PlatformNativeSheetReasoningEffortChangedEvent {
+ super.writeByte(175)
+ super.writeValue(value.toList())
+ } else if let value = value as? PlatformNativeEditProfileCommittedEvent {
+ super.writeByte(176)
+ super.writeValue(value.toList())
+ } else if let value = value as? PlatformNativeSheetActionResult {
+ super.writeByte(177)
+ super.writeValue(value.toList())
+ } else if let value = value as? PlatformPccStatus {
+ super.writeByte(178)
+ super.writeValue(value.toList())
+ } else if let value = value as? PlatformPccImage {
+ super.writeByte(179)
+ super.writeValue(value.toList())
+ } else if let value = value as? PlatformPccMessage {
+ super.writeByte(180)
+ super.writeValue(value.toList())
+ } else if let value = value as? PlatformPccCompletionRequest {
+ super.writeByte(181)
+ super.writeValue(value.toList())
+ } else if let value = value as? PlatformPccStreamEvent {
+ super.writeByte(182)
+ super.writeValue(value.toList())
} else {
super.writeValue(value)
}
@@ -3928,3 +4330,115 @@ class NativeSheetFlutterApi: NativeSheetFlutterApiProtocol {
}
}
}
+/// Generated protocol from Pigeon that represents a handler of messages from Flutter.
+protocol PccHostApi {
+ func getStatus(model: PlatformAppleModel, completion: @escaping (Result) -> Void)
+ func showQuotaIncreaseSuggestion(completion: @escaping (Result) -> Void)
+ func start(request: PlatformPccCompletionRequest) throws
+ func cancel(runId: String) throws
+}
+
+/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
+class PccHostApiSetup {
+ static var codec: FlutterStandardMessageCodec { ConduitPlatformApisPigeonCodec.shared }
+ /// Sets up an instance of `PccHostApi` to handle messages through the `binaryMessenger`.
+ static func setUp(binaryMessenger: FlutterBinaryMessenger, api: PccHostApi?, messageChannelSuffix: String = "") {
+ let channelSuffix = messageChannelSuffix.count > 0 ? ".\(messageChannelSuffix)" : ""
+ let getStatusChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.conduit.PccHostApi.getStatus\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
+ if let api = api {
+ getStatusChannel.setMessageHandler { message, reply in
+ let args = message as! [Any?]
+ let modelArg = args[0] as! PlatformAppleModel
+ api.getStatus(model: modelArg) { result in
+ switch result {
+ case .success(let res):
+ reply(wrapResult(res))
+ case .failure(let error):
+ reply(wrapError(error))
+ }
+ }
+ }
+ } else {
+ getStatusChannel.setMessageHandler(nil)
+ }
+ let showQuotaIncreaseSuggestionChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.conduit.PccHostApi.showQuotaIncreaseSuggestion\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
+ if let api = api {
+ showQuotaIncreaseSuggestionChannel.setMessageHandler { _, reply in
+ api.showQuotaIncreaseSuggestion { result in
+ switch result {
+ case .success(let res):
+ reply(wrapResult(res))
+ case .failure(let error):
+ reply(wrapError(error))
+ }
+ }
+ }
+ } else {
+ showQuotaIncreaseSuggestionChannel.setMessageHandler(nil)
+ }
+ let startChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.conduit.PccHostApi.start\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
+ if let api = api {
+ startChannel.setMessageHandler { message, reply in
+ let args = message as! [Any?]
+ let requestArg = args[0] as! PlatformPccCompletionRequest
+ do {
+ try api.start(request: requestArg)
+ reply(wrapResult(nil))
+ } catch {
+ reply(wrapError(error))
+ }
+ }
+ } else {
+ startChannel.setMessageHandler(nil)
+ }
+ let cancelChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.conduit.PccHostApi.cancel\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
+ if let api = api {
+ cancelChannel.setMessageHandler { message, reply in
+ let args = message as! [Any?]
+ let runIdArg = args[0] as! String
+ do {
+ try api.cancel(runId: runIdArg)
+ reply(wrapResult(nil))
+ } catch {
+ reply(wrapError(error))
+ }
+ }
+ } else {
+ cancelChannel.setMessageHandler(nil)
+ }
+ }
+}
+
+/// Generated protocol from Pigeon that represents Flutter messages that can be called from Swift.
+protocol PccFlutterApiProtocol {
+ func onEvent(event eventArg: PlatformPccStreamEvent, completion: @escaping (Result) -> Void)
+}
+class PccFlutterApi: PccFlutterApiProtocol {
+ private let binaryMessenger: FlutterBinaryMessenger
+ private let messageChannelSuffix: String
+ init(binaryMessenger: FlutterBinaryMessenger, messageChannelSuffix: String = "") {
+ self.binaryMessenger = binaryMessenger
+ self.messageChannelSuffix = messageChannelSuffix.count > 0 ? ".\(messageChannelSuffix)" : ""
+ }
+ var codec: ConduitPlatformApisPigeonCodec {
+ return ConduitPlatformApisPigeonCodec.shared
+ }
+ func onEvent(event eventArg: PlatformPccStreamEvent, completion: @escaping (Result) -> Void) {
+ let channelName: String = "dev.flutter.pigeon.conduit.PccFlutterApi.onEvent\(messageChannelSuffix)"
+ let channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger, codec: codec)
+ channel.sendMessage([eventArg] as [Any?]) { response in
+ guard let listResponse = response as? [Any?] else {
+ completion(.failure(createConnectionError(withChannelName: channelName)))
+ return
+ }
+ if listResponse.count > 1 {
+ let code: String = listResponse[0] as! String
+ let message: String? = nilOrValue(listResponse[1])
+ let details: String? = nilOrValue(listResponse[2])
+ completion(.failure(PigeonError(code: code, message: message, details: details)))
+ } else {
+ completion(.success(()))
+ }
+ }
+ }
+}
diff --git a/ios/Runner/PccBridge.swift b/ios/Runner/PccBridge.swift
new file mode 100644
index 000000000..f4445af8e
--- /dev/null
+++ b/ios/Runner/PccBridge.swift
@@ -0,0 +1,1097 @@
+import Flutter
+import Foundation
+import ImageIO
+
+#if canImport(FoundationModels)
+import FoundationModels
+#endif
+
+enum PccSnapshotDeltaError: Error {
+ case nonPrefixSnapshot
+}
+
+func pccSnapshotDelta(previous: String, snapshot: String) throws -> String {
+ guard snapshot.hasPrefix(previous) else {
+ throw PccSnapshotDeltaError.nonPrefixSnapshot
+ }
+ return String(snapshot.dropFirst(previous.count))
+}
+
+private let pccMaxImageDimension = 8_192
+private let pccMaxDecodedImageBytes = 64 * 1_024 * 1_024
+
+func pccDecodedImageBytes(
+ width: Int,
+ height: Int,
+ currentBytes: Int
+) -> Int? {
+ guard width > 0,
+ height > 0,
+ width <= pccMaxImageDimension,
+ height <= pccMaxImageDimension,
+ height <= (pccMaxDecodedImageBytes - currentBytes) / 4 / width
+ else {
+ return nil
+ }
+ return currentBytes + width * height * 4
+}
+
+func pccDecodedImageBytes(
+ bytesPerRow: Int,
+ height: Int,
+ currentBytes: Int
+) -> Int? {
+ guard bytesPerRow > 0,
+ height > 0,
+ currentBytes >= 0,
+ currentBytes <= pccMaxDecodedImageBytes,
+ height <= (pccMaxDecodedImageBytes - currentBytes) / bytesPerRow
+ else {
+ return nil
+ }
+ return currentBytes + bytesPerRow * height
+}
+
+func pccImageMetadataIsSafe(depth: Int, colorModel: String) -> Bool {
+ guard depth > 0, depth <= 8 else { return false }
+ return colorModel == kCGImagePropertyColorModelRGB as String ||
+ colorModel == kCGImagePropertyColorModelGray as String
+}
+
+private enum PccBridgeError: LocalizedError {
+ case invalidRequest
+ case invalidImage
+ case invalidSchema
+
+ var errorDescription: String? {
+ switch self {
+ case .invalidRequest:
+ "Apple Foundation Models request is invalid."
+ case .invalidImage:
+ "Apple Foundation Models received an invalid image."
+ case .invalidSchema:
+ "Apple Foundation Models received an unsupported response schema."
+ }
+ }
+}
+
+#if canImport(FoundationModels)
+@available(iOS 26.0, *)
+func pccGenerationOptions(
+ _ request: PlatformPccCompletionRequest
+) throws -> GenerationOptions {
+ if let temperature = request.temperature,
+ !(0 ... 1).contains(temperature)
+ {
+ throw PccBridgeError.invalidRequest
+ }
+ guard request.maximumResponseTokens.map({ $0 > 0 && $0 <= 32_768 }) ?? true,
+ request.topP.map({ $0 > 0 && $0 <= 1 }) ?? true,
+ request.topK.map({ $0 > 0 && $0 <= 100_000 }) ?? true,
+ request.seed.map({ $0 >= 0 }) ?? true
+ else {
+ throw PccBridgeError.invalidRequest
+ }
+ let selectedModes = [
+ request.greedySampling == true,
+ request.topP != nil,
+ request.topK != nil,
+ ].filter { $0 }.count
+ guard selectedModes <= 1 else { throw PccBridgeError.invalidRequest }
+
+ let seed = request.seed.map(UInt64.init)
+ let samplingMode: GenerationOptions.SamplingMode?
+ if request.greedySampling == true {
+ samplingMode = .greedy
+ } else if let topP = request.topP {
+ samplingMode = .random(probabilityThreshold: topP, seed: seed)
+ } else if let topK = request.topK {
+ samplingMode = .random(top: Int(topK), seed: seed)
+ } else {
+ samplingMode = nil
+ }
+#if CONDUIT_PCC_SDK
+ return GenerationOptions(
+ samplingMode: samplingMode,
+ temperature: request.temperature,
+ maximumResponseTokens: request.maximumResponseTokens.map(Int.init)
+ )
+#else
+ return GenerationOptions(
+ sampling: samplingMode,
+ temperature: request.temperature,
+ maximumResponseTokens: request.maximumResponseTokens.map(Int.init)
+ )
+#endif
+}
+
+@available(iOS 26.0, *)
+func pccGenerationSchema(json: String, name: String) throws -> GenerationSchema {
+ guard json.utf8.count <= 64 * 1024,
+ name.range(of: #"^[A-Za-z_][A-Za-z0-9_]{0,63}$"#,
+ options: .regularExpression) != nil,
+ let rootObject = try JSONSerialization.jsonObject(
+ with: Data(json.utf8)
+ ) as? [String: Any]
+ else {
+ throw PccBridgeError.invalidSchema
+ }
+
+ var objectIndex = 0
+ var propertyCount = 0
+ func build(_ raw: [String: Any], depth: Int) throws -> DynamicGenerationSchema {
+ guard depth <= 12 else { throw PccBridgeError.invalidSchema }
+ let type: String
+ if let rawType = raw["type"] {
+ guard let declaredType = rawType as? String else {
+ throw PccBridgeError.invalidSchema
+ }
+ type = declaredType
+ } else if raw["properties"] is [String: Any] {
+ type = "object"
+ } else {
+ throw PccBridgeError.invalidSchema
+ }
+ switch type {
+ case "object":
+ guard let rawProperties = raw["properties"] as? [String: Any],
+ rawProperties.count <= 128
+ else {
+ throw PccBridgeError.invalidSchema
+ }
+ propertyCount += rawProperties.count
+ guard propertyCount <= 256 else { throw PccBridgeError.invalidSchema }
+ let required: Set
+ if let rawRequired = raw["required"] {
+ guard let names = rawRequired as? [String],
+ Set(names).count == names.count
+ else {
+ throw PccBridgeError.invalidSchema
+ }
+ required = Set(names)
+ } else {
+ required = []
+ }
+ guard required.isSubset(of: Set(rawProperties.keys)) else {
+ throw PccBridgeError.invalidSchema
+ }
+ objectIndex += 1
+ let objectName = objectIndex == 1 ? name : "\(name)_\(objectIndex)"
+ let properties = try rawProperties.keys.sorted().map { propertyName in
+ guard propertyName.utf8.count <= 128,
+ let property = rawProperties[propertyName] as? [String: Any]
+ else {
+ throw PccBridgeError.invalidSchema
+ }
+ return DynamicGenerationSchema.Property(
+ name: propertyName,
+ description: property["description"] as? String,
+ schema: try build(property, depth: depth + 1),
+ isOptional: !required.contains(propertyName)
+ )
+ }
+ return DynamicGenerationSchema(
+ name: objectName,
+ description: raw["description"] as? String,
+ properties: properties
+ )
+ case "array":
+ guard let items = raw["items"] as? [String: Any] else {
+ throw PccBridgeError.invalidSchema
+ }
+ func nonnegativeInteger(_ key: String) throws -> Int? {
+ guard let value = raw[key] else { return nil }
+ guard let number = value as? NSNumber,
+ CFGetTypeID(number) != CFBooleanGetTypeID(),
+ let integer = value as? Int,
+ integer >= 0
+ else {
+ throw PccBridgeError.invalidSchema
+ }
+ return integer
+ }
+ let minimumElements = try nonnegativeInteger("minItems")
+ let maximumElements = try nonnegativeInteger("maxItems")
+ if let minimumElements,
+ let maximumElements,
+ maximumElements < minimumElements
+ {
+ throw PccBridgeError.invalidSchema
+ }
+ return DynamicGenerationSchema(
+ arrayOf: try build(items, depth: depth + 1),
+ minimumElements: minimumElements,
+ maximumElements: maximumElements
+ )
+ case "string":
+ if let rawEnum = raw["enum"] {
+ guard let values = rawEnum as? [String], !values.isEmpty else {
+ throw PccBridgeError.invalidSchema
+ }
+ return DynamicGenerationSchema(
+ type: String.self,
+ guides: [.anyOf(values)]
+ )
+ }
+ return DynamicGenerationSchema(type: String.self)
+ case "integer":
+ guard raw["minimum"] == nil, raw["maximum"] == nil else {
+ throw PccBridgeError.invalidSchema
+ }
+ return DynamicGenerationSchema(type: Int.self)
+ case "number":
+ guard raw["minimum"] == nil, raw["maximum"] == nil else {
+ throw PccBridgeError.invalidSchema
+ }
+ return DynamicGenerationSchema(type: Double.self)
+ case "boolean":
+ return DynamicGenerationSchema(type: Bool.self)
+ case "null":
+ throw PccBridgeError.invalidSchema
+ default:
+ throw PccBridgeError.invalidSchema
+ }
+ }
+
+ return try GenerationSchema(root: build(rootObject, depth: 0), dependencies: [])
+}
+#endif
+
+private final class PccTaskBox {
+ var task: Task?
+ var cancelled = false
+}
+
+private final class PccResponseState {
+ var emittedContent = false
+}
+
+final class PccBridge: PccHostApi {
+ static let shared = PccBridge()
+
+ private let lock = NSLock()
+ private var tasks: [String: PccTaskBox] = [:]
+ private var flutterApi: PccFlutterApi?
+
+ private init() {}
+
+ func configure(messenger: FlutterBinaryMessenger) {
+ flutterApi = PccFlutterApi(binaryMessenger: messenger)
+ PccHostApiSetup.setUp(binaryMessenger: messenger, api: self)
+ }
+
+ func getStatus(
+ model: PlatformAppleModel,
+ completion: @escaping (Result) -> Void
+ ) {
+ Task {
+ if model == .onDevice {
+#if canImport(FoundationModels)
+ if #available(iOS 26.0, *) {
+ completion(.success(onDeviceStatus()))
+ return
+ }
+#endif
+ completion(.success(Self.onDeviceUnsupportedStatus))
+ return
+ }
+#if CONDUIT_PCC_SDK
+ if #available(iOS 27.0, *) {
+ completion(.success(await liveStatus()))
+ return
+ }
+#endif
+ completion(.success(Self.pccUnsupportedStatus))
+ }
+ }
+
+ func showQuotaIncreaseSuggestion(
+ completion: @escaping (Result) -> Void
+ ) {
+ Task {
+#if CONDUIT_PCC_SDK
+ if #available(iOS 27.0, *) {
+ guard let suggestion = PrivateCloudComputeLanguageModel()
+ .quotaUsage.limitIncreaseSuggestion
+ else {
+ completion(.success(false))
+ return
+ }
+ await MainActor.run { suggestion.show() }
+ completion(.success(true))
+ return
+ }
+#endif
+ completion(.success(false))
+ }
+ }
+
+ func start(request: PlatformPccCompletionRequest) throws {
+ guard !request.runId.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty,
+ request.messages.last?.role == "user",
+ request.messages.last.map({
+ !$0.content.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ||
+ !$0.images.isEmpty
+ }) == true
+ else {
+ throw PccBridgeError.invalidRequest
+ }
+
+ let box = PccTaskBox()
+ lock.lock()
+ guard tasks[request.runId] == nil else {
+ lock.unlock()
+ throw PccBridgeError.invalidRequest
+ }
+ tasks[request.runId] = box
+ lock.unlock()
+
+ let task = Task { [weak self, box] in
+ guard let self else { return }
+ await self.perform(request, box: box)
+ }
+ lock.lock()
+ box.task = task
+ let wasCancelled = box.cancelled
+ lock.unlock()
+ if wasCancelled {
+ task.cancel()
+ }
+ }
+
+ func cancel(runId: String) throws {
+ lock.lock()
+ let box = tasks[runId]
+ box?.cancelled = true
+ let task = box?.task
+ lock.unlock()
+ task?.cancel()
+ }
+
+ private func perform(_ request: PlatformPccCompletionRequest, box: PccTaskBox) async {
+ defer { removeTask(request.runId, box: box) }
+ if request.model == .onDevice {
+#if canImport(FoundationModels)
+ if #available(iOS 26.0, *) {
+ await performOnDeviceRequest(request)
+ return
+ }
+#endif
+ await emitError(
+ runId: request.runId,
+ message: "Apple On-Device requires iOS 26 and an Apple Intelligence device."
+ )
+ return
+ }
+#if CONDUIT_PCC_SDK
+ if #available(iOS 27.0, *) {
+ await performAvailableRequest(request)
+ return
+ }
+#endif
+ await emitError(
+ runId: request.runId,
+ message: "Apple Private Cloud Compute requires iOS 27 and an eligible device."
+ )
+ }
+
+ private func removeTask(_ runId: String, box: PccTaskBox) {
+ lock.lock()
+ if tasks[runId] === box {
+ tasks.removeValue(forKey: runId)
+ }
+ lock.unlock()
+ }
+
+ private func emit(_ event: PlatformPccStreamEvent) async {
+ await MainActor.run { [weak self] in
+ self?.flutterApi?.onEvent(event: event) { _ in }
+ }
+ }
+
+ private func emitError(runId: String, message: String) async {
+ await emit(PlatformPccStreamEvent(
+ runId: runId,
+ kind: .error,
+ content: message
+ ))
+ }
+
+ private static let pccUnsupportedStatus = PlatformPccStatus(
+ availability: .unsupported,
+ quotaStatus: .unknown,
+ quotaLimitReached: false,
+ canIncreaseQuota: false,
+ message: "Apple Private Cloud Compute requires iOS 27 and an eligible device."
+ )
+
+ private static let onDeviceUnsupportedStatus = PlatformPccStatus(
+ availability: .unsupported,
+ quotaStatus: .unknown,
+ quotaLimitReached: false,
+ canIncreaseQuota: false,
+ message: "Apple On-Device requires iOS 26 and an Apple Intelligence device."
+ )
+}
+
+#if canImport(FoundationModels)
+@available(iOS 26.0, *)
+private struct OnDeviceSessionInput {
+ let transcript: Transcript
+ let prompt: Prompt
+ let generationOptions: GenerationOptions
+ let responseSchema: GenerationSchema?
+}
+
+@available(iOS 26.0, *)
+private extension PccBridge {
+ func onDeviceStatus() -> PlatformPccStatus {
+ let model = SystemLanguageModel.default
+ let message: String?
+ switch model.availability {
+ case .available:
+ message = nil
+ case .unavailable(.deviceNotEligible):
+ message = "This device does not support Apple Intelligence."
+ case .unavailable(.appleIntelligenceNotEnabled):
+ message = "Turn on Apple Intelligence to use Apple On-Device."
+ case .unavailable(.modelNotReady):
+ message = "The Apple on-device model is still downloading or not ready."
+ @unknown default:
+ message = "Apple On-Device is unavailable."
+ }
+ return PlatformPccStatus(
+ availability: model.isAvailable ? .available : .unavailable,
+ quotaStatus: .unknown,
+ quotaLimitReached: false,
+ canIncreaseQuota: false,
+ message: message,
+ contextSize: Int64(model.contextSize),
+ supportsCurrentLocale: model.supportsLocale(Locale.current)
+ )
+ }
+
+ func performOnDeviceRequest(_ request: PlatformPccCompletionRequest) async {
+ do {
+ let model = SystemLanguageModel.default
+ guard case .available = model.availability else {
+ await emitError(
+ runId: request.runId,
+ message: onDeviceStatus().message ?? "Apple On-Device is unavailable."
+ )
+ return
+ }
+ let input = try onDeviceSessionInput(request)
+ let session = LanguageModelSession(
+ model: model,
+ tools: [],
+ transcript: input.transcript
+ )
+ try await performOnDevice(
+ session: session,
+ input: input,
+ runId: request.runId
+ )
+ await emit(PlatformPccStreamEvent(runId: request.runId, kind: .done))
+ } catch is CancellationError {
+ await emit(PlatformPccStreamEvent(runId: request.runId, kind: .done))
+ } catch PccSnapshotDeltaError.nonPrefixSnapshot {
+ await emitError(
+ runId: request.runId,
+ message: "Apple On-Device returned an invalid response stream."
+ )
+ } catch {
+#if CONDUIT_PCC_SDK
+ if let error = error as? LanguageModelError {
+ await emitError(runId: request.runId, message: onDeviceMessage(for: error))
+ return
+ }
+#else
+ if let error = error as? LanguageModelSession.GenerationError {
+ await emitError(runId: request.runId, message: onDeviceMessage(for: error))
+ return
+ }
+#endif
+ if let error = error as? PccBridgeError {
+ await emitError(runId: request.runId, message: error.localizedDescription)
+ return
+ }
+ await emitError(runId: request.runId, message: "Apple On-Device request failed.")
+ }
+ }
+
+ func performOnDevice(
+ session: LanguageModelSession,
+ input: OnDeviceSessionInput,
+ runId: String
+ ) async throws {
+ if let schema = input.responseSchema {
+ let response = try await session.respond(
+ to: input.prompt,
+ schema: schema,
+ includeSchemaInPrompt: true,
+ options: input.generationOptions
+ )
+ try Task.checkCancellation()
+ await emit(PlatformPccStreamEvent(
+ runId: runId,
+ kind: .content,
+ content: response.content.jsonString
+ ))
+ return
+ }
+
+ var previous = ""
+ for try await snapshot in session.streamResponse(
+ to: input.prompt,
+ options: input.generationOptions
+ ) {
+ try Task.checkCancellation()
+ let content = snapshot.content
+ let delta = try pccSnapshotDelta(previous: previous, snapshot: content)
+ previous = content
+ if !delta.isEmpty {
+ await emit(PlatformPccStreamEvent(
+ runId: runId,
+ kind: .content,
+ content: delta
+ ))
+ }
+ }
+ }
+
+ func onDeviceSessionInput(
+ _ request: PlatformPccCompletionRequest
+ ) throws -> OnDeviceSessionInput {
+ guard request.reasoningLevel == nil,
+ request.messages.allSatisfy({ $0.images.isEmpty }),
+ let final = request.messages.last,
+ final.role == "user",
+ !final.content.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
+ else {
+ throw PccBridgeError.invalidRequest
+ }
+
+ var instructions: [String] = []
+ var entries: [Transcript.Entry] = []
+ for message in request.messages.dropLast() {
+ let content = message.content.trimmingCharacters(in: .whitespacesAndNewlines)
+ if content.isEmpty { continue }
+ let segment = Transcript.Segment.text(Transcript.TextSegment(content: content))
+ switch message.role {
+ case "system":
+ instructions.append(content)
+ case "user":
+ entries.append(.prompt(Transcript.Prompt(segments: [segment])))
+ case "assistant":
+ entries.append(.response(Transcript.Response(
+ assetIDs: [],
+ segments: [segment]
+ )))
+ default:
+ throw PccBridgeError.invalidRequest
+ }
+ }
+ if !instructions.isEmpty {
+ let segment = Transcript.Segment.text(
+ Transcript.TextSegment(content: instructions.joined(separator: "\n\n"))
+ )
+ entries.insert(.instructions(Transcript.Instructions(
+ segments: [segment],
+ toolDefinitions: []
+ )), at: 0)
+ }
+
+ let responseSchema: GenerationSchema?
+ switch (request.responseSchemaName, request.responseSchemaJson) {
+ case (nil, nil):
+ responseSchema = nil
+ case let (name?, json?):
+ responseSchema = try pccGenerationSchema(json: json, name: name)
+ default:
+ throw PccBridgeError.invalidSchema
+ }
+ return OnDeviceSessionInput(
+ transcript: Transcript(entries: entries),
+ prompt: Prompt(final.content),
+ generationOptions: try pccGenerationOptions(request),
+ responseSchema: responseSchema
+ )
+ }
+
+#if !CONDUIT_PCC_SDK
+ func onDeviceMessage(
+ for error: LanguageModelSession.GenerationError
+ ) -> String {
+ switch error {
+ case .exceededContextWindowSize:
+ return "This conversation exceeds the Apple On-Device context limit."
+ case .assetsUnavailable:
+ return "The Apple on-device model is not ready."
+ case .guardrailViolation:
+ return "Apple On-Device blocked this request for safety reasons."
+ case .unsupportedGuide, .unsupportedLanguageOrLocale:
+ return "Apple On-Device cannot process this request."
+ case .decodingFailure:
+ return "Apple On-Device returned an invalid response."
+ case .rateLimited, .concurrentRequests:
+ return "Apple On-Device is busy. Retry shortly."
+ case .refusal:
+ return "Apple On-Device declined this request."
+ @unknown default:
+ return "Apple On-Device request failed."
+ }
+ }
+#endif
+}
+#endif
+
+#if CONDUIT_PCC_SDK
+@available(iOS 27.0, *)
+private struct PccSessionInput {
+ let transcript: Transcript
+ let prompt: Prompt
+ let contextOptions: ContextOptions
+ let generationOptions: GenerationOptions
+ let responseSchema: GenerationSchema?
+}
+
+@available(iOS 27.0, *)
+private extension PccBridge {
+ func liveStatus() async -> PlatformPccStatus {
+ let model = PrivateCloudComputeLanguageModel()
+ let reset = model.quotaUsage.resetDate.map {
+ Int64($0.timeIntervalSince1970 * 1_000)
+ }
+ let quotaStatus: PlatformPccQuotaStatus = switch model.quotaUsage.status {
+ case .belowLimit(let info):
+ info.isApproachingLimit ? .approachingLimit : .belowLimit
+ case .limitReached:
+ .limitReached
+ @unknown default:
+ .unknown
+ }
+ let contextSize = try? await model.contextSize
+ let supportsCurrentLocale = try? await model.supportsLocale(Locale.current)
+ let canIncreaseQuota = model.quotaUsage.limitIncreaseSuggestion != nil
+ switch model.availability {
+ case .available:
+ let limitReached = model.quotaUsage.isLimitReached
+ return PlatformPccStatus(
+ availability: .available,
+ quotaStatus: quotaStatus,
+ quotaLimitReached: limitReached,
+ canIncreaseQuota: canIncreaseQuota,
+ message: limitReached
+ ? "The Apple Private Cloud Compute daily usage limit has been reached."
+ : nil,
+ quotaResetAtMilliseconds: reset,
+ contextSize: contextSize.map(Int64.init),
+ supportsCurrentLocale: supportsCurrentLocale
+ )
+ case .unavailable(.deviceNotEligible):
+ return PlatformPccStatus(
+ availability: .unavailable,
+ quotaStatus: quotaStatus,
+ quotaLimitReached: false,
+ canIncreaseQuota: canIncreaseQuota,
+ message: "This device is not eligible for Apple Private Cloud Compute."
+ )
+ case .unavailable(.systemNotReady):
+ return PlatformPccStatus(
+ availability: .unavailable,
+ quotaStatus: quotaStatus,
+ quotaLimitReached: false,
+ canIncreaseQuota: canIncreaseQuota,
+ message: "Apple Private Cloud Compute is not ready on this device."
+ )
+ @unknown default:
+ return PlatformPccStatus(
+ availability: .unavailable,
+ quotaStatus: quotaStatus,
+ quotaLimitReached: false,
+ canIncreaseQuota: canIncreaseQuota,
+ message: "Apple Private Cloud Compute is unavailable."
+ )
+ }
+ }
+
+ func performAvailableRequest(_ request: PlatformPccCompletionRequest) async {
+ let responseState = PccResponseState()
+ do {
+ let model = PrivateCloudComputeLanguageModel()
+ guard case .available = model.availability else {
+ let status = await liveStatus()
+ await emitError(
+ runId: request.runId,
+ message: status.message ?? "Apple Private Cloud Compute is unavailable."
+ )
+ return
+ }
+ guard !model.quotaUsage.isLimitReached else {
+ await emitError(
+ runId: request.runId,
+ message: "The Apple Private Cloud Compute daily usage limit has been reached."
+ )
+ return
+ }
+
+ let input = try sessionInput(request)
+ let session = LanguageModelSession(
+ model: model,
+ tools: [],
+ transcript: input.transcript
+ )
+ try await perform(
+ session: session,
+ input: input,
+ runId: request.runId,
+ responseState: responseState
+ )
+ await emit(PlatformPccStreamEvent(runId: request.runId, kind: .done))
+ } catch is CancellationError {
+ await emit(PlatformPccStreamEvent(runId: request.runId, kind: .done))
+ } catch PccSnapshotDeltaError.nonPrefixSnapshot {
+ await emitError(
+ runId: request.runId,
+ message: "Apple Private Cloud Compute returned an invalid response stream."
+ )
+ } catch let error as PrivateCloudComputeLanguageModel.Error {
+ if case .networkFailure = error,
+ !responseState.emittedContent,
+ request.allowOnDeviceFallback,
+ request.reasoningLevel == nil || request.reasoningLevel == "automatic",
+ request.messages.allSatisfy({ $0.images.isEmpty })
+ {
+ var fallbackRequest = request
+ fallbackRequest.reasoningLevel = nil
+ await performOnDeviceFallback(fallbackRequest)
+ } else {
+ await emitError(runId: request.runId, message: message(for: error))
+ }
+ } catch let error as LanguageModelError {
+ await emitError(runId: request.runId, message: message(for: error))
+ } catch let error as PccBridgeError {
+ await emitError(runId: request.runId, message: error.localizedDescription)
+ } catch {
+ await emitError(
+ runId: request.runId,
+ message: "Apple Private Cloud Compute request failed."
+ )
+ }
+ }
+
+ func performOnDeviceFallback(_ request: PlatformPccCompletionRequest) async {
+ do {
+ let model = SystemLanguageModel.default
+ guard case .available = model.availability else {
+ await emitError(
+ runId: request.runId,
+ message: "Apple Private Cloud Compute is offline and the on-device model is unavailable."
+ )
+ return
+ }
+ let input = try onDeviceSessionInput(request)
+ let session = LanguageModelSession(
+ model: model,
+ tools: [],
+ transcript: input.transcript
+ )
+ await emit(PlatformPccStreamEvent(
+ runId: request.runId,
+ kind: .fallback,
+ content: "on_device"
+ ))
+ try await performOnDevice(
+ session: session,
+ input: input,
+ runId: request.runId
+ )
+ await emit(PlatformPccStreamEvent(runId: request.runId, kind: .done))
+ } catch is CancellationError {
+ await emit(PlatformPccStreamEvent(runId: request.runId, kind: .done))
+ } catch let error as LanguageModelError {
+ await emitError(runId: request.runId, message: onDeviceMessage(for: error))
+ } catch let error as PccBridgeError {
+ await emitError(runId: request.runId, message: error.localizedDescription)
+ } catch {
+ await emitError(
+ runId: request.runId,
+ message: "Apple Private Cloud Compute is offline and the on-device fallback failed."
+ )
+ }
+ }
+
+ func perform(
+ session: LanguageModelSession,
+ input: PccSessionInput,
+ runId: String,
+ responseState: PccResponseState
+ ) async throws {
+ if let schema = input.responseSchema {
+ let response = try await session.respond(
+ to: input.prompt,
+ schema: schema,
+ options: input.generationOptions,
+ contextOptions: input.contextOptions
+ )
+ try Task.checkCancellation()
+ responseState.emittedContent = true
+ await emit(PlatformPccStreamEvent(
+ runId: runId,
+ kind: .content,
+ content: response.content.jsonString
+ ))
+ await emitUsage(response.usage, runId: runId)
+ return
+ }
+
+ var previous = ""
+ for try await snapshot in session.streamResponse(
+ to: input.prompt,
+ options: input.generationOptions,
+ contextOptions: input.contextOptions
+ ) {
+ try Task.checkCancellation()
+ let content = snapshot.content
+ let delta = try pccSnapshotDelta(previous: previous, snapshot: content)
+ previous = content
+ if !delta.isEmpty {
+ responseState.emittedContent = true
+ await emit(PlatformPccStreamEvent(
+ runId: runId,
+ kind: .content,
+ content: delta
+ ))
+ }
+ await emitUsage(snapshot.usage, runId: runId)
+ }
+ }
+
+ func emitUsage(_ usage: LanguageModelSession.Usage, runId: String) async {
+ await emit(PlatformPccStreamEvent(
+ runId: runId,
+ kind: .usage,
+ inputTokenCount: Int64(usage.input.totalTokenCount),
+ outputTokenCount: Int64(usage.output.totalTokenCount),
+ reasoningTokenCount: Int64(usage.output.reasoningTokenCount),
+ totalTokenCount: Int64(usage.totalTokenCount)
+ ))
+ }
+
+ func sessionInput(
+ _ request: PlatformPccCompletionRequest
+ ) throws -> PccSessionInput {
+ guard let final = request.messages.last,
+ final.role == "user",
+ (!final.content.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ||
+ !final.images.isEmpty)
+ else {
+ throw PccBridgeError.invalidRequest
+ }
+
+ var imageCount = 0
+ var imageBytes = 0
+ var decodedImageBytes = 0
+ func decodedImages(_ message: PlatformPccMessage) throws -> [CGImage] {
+ imageCount += message.images.count
+ imageBytes += message.images.reduce(0) { $0 + $1.bytes.data.count }
+ guard imageCount <= 4, imageBytes <= 20 * 1024 * 1024 else {
+ throw PccBridgeError.invalidImage
+ }
+ return try message.images.map { image in
+ guard image.mimeType.lowercased().hasPrefix("image/"),
+ !image.bytes.data.isEmpty,
+ let source = CGImageSourceCreateWithData(
+ image.bytes.data as CFData,
+ nil
+ ),
+ let properties = CGImageSourceCopyPropertiesAtIndex(
+ source,
+ 0,
+ nil
+ ) as NSDictionary?,
+ let width = (properties[kCGImagePropertyPixelWidth] as? NSNumber)?.intValue,
+ let height = (properties[kCGImagePropertyPixelHeight] as? NSNumber)?.intValue,
+ let depth = (properties[kCGImagePropertyDepth] as? NSNumber)?.intValue,
+ let colorModel = properties[kCGImagePropertyColorModel] as? String,
+ pccImageMetadataIsSafe(depth: depth, colorModel: colorModel),
+ pccDecodedImageBytes(
+ width: width,
+ height: height,
+ currentBytes: decodedImageBytes
+ ) != nil,
+ let cgImage = CGImageSourceCreateImageAtIndex(source, 0, nil),
+ cgImage.width == width,
+ cgImage.height == height,
+ let nextDecodedBytes = pccDecodedImageBytes(
+ bytesPerRow: cgImage.bytesPerRow,
+ height: cgImage.height,
+ currentBytes: decodedImageBytes
+ )
+ else {
+ throw PccBridgeError.invalidImage
+ }
+ decodedImageBytes = nextDecodedBytes
+ return cgImage
+ }
+ }
+
+ func segments(
+ for message: PlatformPccMessage,
+ labelPrefix: String
+ ) throws -> [Transcript.Segment] {
+ let content = message.content.trimmingCharacters(in: .whitespacesAndNewlines)
+ var segments: [Transcript.Segment] = []
+ if !content.isEmpty {
+ segments.append(.text(Transcript.TextSegment(content: content)))
+ }
+ for (index, image) in try decodedImages(message).enumerated() {
+ let attachment = Transcript.AttachmentSegment(
+ content: .image(Transcript.ImageAttachment(image)),
+ label: "\(labelPrefix)-\(index)"
+ )
+ segments.append(.attachment(attachment))
+ }
+ return segments
+ }
+
+ var instructions: [String] = []
+ var entries: [Transcript.Entry] = []
+ for (index, message) in request.messages.dropLast().enumerated() {
+ let content = message.content.trimmingCharacters(in: .whitespacesAndNewlines)
+ switch message.role {
+ case "system":
+ guard message.images.isEmpty else { throw PccBridgeError.invalidRequest }
+ if content.isEmpty { continue }
+ instructions.append(content)
+ case "user":
+ let value = try segments(for: message, labelPrefix: "history-\(index)")
+ if !value.isEmpty {
+ entries.append(.prompt(Transcript.Prompt(segments: value)))
+ }
+ case "assistant":
+ guard message.images.isEmpty else { throw PccBridgeError.invalidRequest }
+ if content.isEmpty { continue }
+ let segment = Transcript.Segment.text(Transcript.TextSegment(content: content))
+ entries.append(.response(Transcript.Response(
+ assetIDs: [],
+ segments: [segment]
+ )))
+ default:
+ throw PccBridgeError.invalidRequest
+ }
+ }
+ if !instructions.isEmpty {
+ let segment = Transcript.Segment.text(
+ Transcript.TextSegment(content: instructions.joined(separator: "\n\n"))
+ )
+ entries.insert(.instructions(Transcript.Instructions(
+ segments: [segment],
+ toolDefinitions: []
+ )), at: 0)
+ }
+
+ let finalImages = try decodedImages(final)
+ let finalContent = final.content
+ let prompt = Prompt {
+ if !finalContent.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
+ finalContent
+ }
+ for (index, image) in finalImages.enumerated() {
+ Attachment(image).label("prompt-\(index)")
+ }
+ }
+ let responseSchema: GenerationSchema?
+ switch (request.responseSchemaName, request.responseSchemaJson) {
+ case (nil, nil):
+ responseSchema = nil
+ case let (name?, json?):
+ responseSchema = try pccGenerationSchema(json: json, name: name)
+ default:
+ throw PccBridgeError.invalidSchema
+ }
+
+ return PccSessionInput(
+ transcript: Transcript(entries: entries),
+ prompt: prompt,
+ contextOptions: try contextOptions(
+ request.reasoningLevel,
+ includeSchema: responseSchema != nil
+ ),
+ generationOptions: try pccGenerationOptions(request),
+ responseSchema: responseSchema
+ )
+ }
+
+ func contextOptions(
+ _ reasoningLevel: String?,
+ includeSchema: Bool
+ ) throws -> ContextOptions {
+ let reasoning: ContextOptions.ReasoningLevel? = switch reasoningLevel {
+ case nil, "automatic": nil
+ case "light": .light
+ case "moderate": .moderate
+ case "deep": .deep
+ default: throw PccBridgeError.invalidRequest
+ }
+ return ContextOptions(
+ includeSchemaInPrompt: includeSchema ? true : nil,
+ reasoningLevel: reasoning
+ )
+ }
+
+ func message(for error: PrivateCloudComputeLanguageModel.Error) -> String {
+ switch error {
+ case .quotaLimitReached:
+ return "The Apple Private Cloud Compute daily usage limit has been reached."
+ case .networkFailure:
+ return "Apple Private Cloud Compute could not be reached. Check your connection and retry."
+ case .serviceUnavailable:
+ return "Apple Private Cloud Compute is temporarily unavailable."
+ @unknown default:
+ return "Apple Private Cloud Compute request failed."
+ }
+ }
+
+ func message(for error: LanguageModelError) -> String {
+ switch error {
+ case .contextSizeExceeded:
+ return "This conversation exceeds the Apple Private Cloud Compute context limit."
+ case .rateLimited:
+ return "Apple Private Cloud Compute is receiving too many requests. Retry shortly."
+ case .refusal:
+ return "Apple Private Cloud Compute declined this request."
+ case .timeout:
+ return "Apple Private Cloud Compute timed out."
+ case .guardrailViolation:
+ return "Apple Private Cloud Compute blocked this request for safety reasons."
+ case .unsupportedCapability, .unsupportedTranscriptContent,
+ .unsupportedGenerationGuide, .unsupportedLanguageOrLocale:
+ return "Apple Private Cloud Compute cannot process this request."
+ @unknown default:
+ return "Apple Private Cloud Compute request failed."
+ }
+ }
+
+ func onDeviceMessage(for error: LanguageModelError) -> String {
+ switch error {
+ case .contextSizeExceeded:
+ return "This conversation exceeds the Apple On-Device context limit."
+ case .rateLimited:
+ return "Apple On-Device is busy. Retry shortly."
+ case .refusal:
+ return "Apple On-Device declined this request."
+ case .timeout:
+ return "Apple On-Device timed out."
+ case .guardrailViolation:
+ return "Apple On-Device blocked this request for safety reasons."
+ case .unsupportedCapability, .unsupportedTranscriptContent,
+ .unsupportedGenerationGuide, .unsupportedLanguageOrLocale:
+ return "Apple On-Device cannot process this request."
+ @unknown default:
+ return "Apple On-Device request failed."
+ }
+ }
+}
+#endif
diff --git a/ios/RunnerTests/RunnerTests.swift b/ios/RunnerTests/RunnerTests.swift
index 44286432f..07872dab2 100644
--- a/ios/RunnerTests/RunnerTests.swift
+++ b/ios/RunnerTests/RunnerTests.swift
@@ -1,12 +1,146 @@
import AVFoundation
import Darwin
import Flutter
+import ImageIO
import UIKit
import XCTest
@testable import Runner
class RunnerTests: XCTestCase {
+ func testPccSnapshotDeltaEmitsOnlyNewContent() throws {
+ XCTAssertEqual(
+ try pccSnapshotDelta(previous: "Hello", snapshot: "Hello world"),
+ " world"
+ )
+ XCTAssertEqual(
+ try pccSnapshotDelta(previous: "Hello world", snapshot: "Hello world"),
+ ""
+ )
+ }
+
+ func testPccSnapshotDeltaRejectsRewrites() {
+ XCTAssertThrowsError(
+ try pccSnapshotDelta(previous: "Hello", snapshot: "Goodbye")
+ )
+ }
+
+ func testPccDecodedImageBytesRejectsUnsafeAllocations() {
+ XCTAssertEqual(
+ pccDecodedImageBytes(width: 2_048, height: 2_048, currentBytes: 0),
+ 16 * 1_024 * 1_024
+ )
+ XCTAssertNil(
+ pccDecodedImageBytes(width: 50_000, height: 50_000, currentBytes: 0)
+ )
+ XCTAssertNil(
+ pccDecodedImageBytes(width: 4_097, height: 4_097, currentBytes: 0)
+ )
+ XCTAssertNil(
+ pccDecodedImageBytes(
+ width: 2_048,
+ height: 2_048,
+ currentBytes: 60 * 1_024 * 1_024
+ )
+ )
+ XCTAssertEqual(
+ pccDecodedImageBytes(bytesPerRow: 8_192, height: 2_048, currentBytes: 0),
+ 16 * 1_024 * 1_024
+ )
+ XCTAssertNil(
+ pccDecodedImageBytes(bytesPerRow: 32_769, height: 2_048, currentBytes: 0)
+ )
+ XCTAssertTrue(pccImageMetadataIsSafe(
+ depth: 8,
+ colorModel: kCGImagePropertyColorModelRGB as String
+ ))
+ XCTAssertFalse(pccImageMetadataIsSafe(
+ depth: 16,
+ colorModel: kCGImagePropertyColorModelRGB as String
+ ))
+ XCTAssertFalse(pccImageMetadataIsSafe(
+ depth: 8,
+ colorModel: kCGImagePropertyColorModelCMYK as String
+ ))
+ }
+
+#if canImport(FoundationModels)
+ func testPccGenerationOptionsValidateNativeBoundary() throws {
+ guard #available(iOS 26.0, *) else { return }
+ let request = PlatformPccCompletionRequest(
+ runId: "options",
+ model: .onDevice,
+ messages: [],
+ allowOnDeviceFallback: false,
+ temperature: 0.4,
+ maximumResponseTokens: 512,
+ topP: 0.9,
+ seed: 42
+ )
+ let options = try pccGenerationOptions(request)
+ XCTAssertEqual(options.temperature, 0.4)
+ XCTAssertEqual(options.maximumResponseTokens, 512)
+
+ let invalid = PlatformPccCompletionRequest(
+ runId: "invalid",
+ model: .onDevice,
+ messages: [],
+ allowOnDeviceFallback: false,
+ topP: 0.9,
+ topK: 40
+ )
+ XCTAssertThrowsError(try pccGenerationOptions(invalid))
+ }
+
+ func testPccStructuredSchemaAcceptsBoundedJsonObject() throws {
+ guard #available(iOS 26.0, *) else { return }
+ XCTAssertNoThrow(try pccGenerationSchema(
+ json: #"{"type":"object","properties":{"answer":{"type":"string"}},"required":["answer"]}"#,
+ name: "Answer"
+ ))
+ XCTAssertThrowsError(try pccGenerationSchema(
+ json: #"{"type":"object","properties":{"value":{"type":"file"}}}"#,
+ name: "Unsupported"
+ ))
+ XCTAssertThrowsError(try pccGenerationSchema(
+ json: #"{"type":"object","properties":{},"required":["answer"]}"#,
+ name: "MissingRequiredProperty"
+ ))
+ XCTAssertThrowsError(try pccGenerationSchema(
+ json: #"{"type":"string","enum":[]}"#,
+ name: "EmptyEnum"
+ ))
+ XCTAssertThrowsError(try pccGenerationSchema(
+ json: #"{"type":"integer","minimum":0}"#,
+ name: "UnsupportedMinimum"
+ ))
+ XCTAssertThrowsError(try pccGenerationSchema(
+ json: #"{"type":"number","maximum":1}"#,
+ name: "UnsupportedMaximum"
+ ))
+ XCTAssertThrowsError(try pccGenerationSchema(
+ json: #"{"type":[],"properties":{}}"#,
+ name: "EmptyTypeArray"
+ ))
+ XCTAssertThrowsError(try pccGenerationSchema(
+ json: #"{"type":["string","null"]}"#,
+ name: "NullableType"
+ ))
+ XCTAssertThrowsError(try pccGenerationSchema(
+ json: #"{"type":"array","items":{"type":"string"},"minItems":"2"}"#,
+ name: "StringArrayBound"
+ ))
+ XCTAssertThrowsError(try pccGenerationSchema(
+ json: #"{"type":"array","items":{"type":"string"},"minItems":true}"#,
+ name: "BooleanArrayBound"
+ ))
+ XCTAssertThrowsError(try pccGenerationSchema(
+ json: #"{"type":"array","items":{"type":"string"},"minItems":2,"maxItems":1}"#,
+ name: "ReversedArrayBounds"
+ ))
+ }
+#endif
+
func testNativeDropdownCompletionIsExactlyOnce() {
var selections: [String?] = []
let completion = NativeDropdownCompletion { result in
diff --git a/lib/core/persistence/persistence_keys.dart b/lib/core/persistence/persistence_keys.dart
index 402697ef9..25bb6905d 100644
--- a/lib/core/persistence/persistence_keys.dart
+++ b/lib/core/persistence/persistence_keys.dart
@@ -93,6 +93,12 @@ final class PreferenceKeys {
static const String directConnectionsConfigured =
'direct_connections_configured_v1';
static const String directHistoryPolicy = 'direct_history_policy_v1';
+ static const String applePccEnabled = 'apple_pcc_enabled_v1';
+ static const String appleOnDeviceEnabled = 'apple_on_device_enabled_v1';
+ static const String applePccOnDeviceFallback =
+ 'apple_pcc_on_device_fallback_v1';
+ static const String directContextLengthOverrides =
+ 'direct_context_length_overrides_v1';
static const String reasoningEffortByModel = 'reasoning_effort_by_model_v1';
/// Prefix for the per-server account owner marker that guards reopening an
diff --git a/lib/core/platform/conduit_platform_apis.g.dart b/lib/core/platform/conduit_platform_apis.g.dart
index f9d84f883..f75108eba 100644
--- a/lib/core/platform/conduit_platform_apis.g.dart
+++ b/lib/core/platform/conduit_platform_apis.g.dart
@@ -10,9 +10,9 @@ import 'package:flutter/services.dart';
import 'package:meta/meta.dart' show immutable, protected, visibleForTesting;
Object? _extractReplyValueOrThrow(
- List