@independo/capacitor-inderun 1.1.0-dev.1 → 1.1.0-dev.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,253 @@
1
+ package app.independo.inderun.capacitor
2
+
3
+ import app.independo.inderun.core.ProviderCapabilitySnapshot
4
+ import app.independo.inderun.core.ProviderDescriptor
5
+ import app.independo.inderun.core.ProviderDynamicCapabilities
6
+ import org.junit.Assert.assertEquals
7
+ import org.junit.Assert.assertFalse
8
+ import org.junit.Assert.assertTrue
9
+ import org.junit.Test
10
+
11
+ class IndeRunSerializerCapabilitiesTest {
12
+
13
+ private fun snapshot(
14
+ providerId: String,
15
+ type: ProviderDescriptor.ProviderType,
16
+ transport: ProviderDescriptor.TransportType,
17
+ streamingStyle: ProviderDescriptor.StreamingStyle? = null,
18
+ streaming: Boolean,
19
+ cancel: ProviderDescriptor.CancelSemantics,
20
+ limits: ProviderDescriptor.ResourceLimits? = null,
21
+ privacy: ProviderDescriptor.PrivacyDescriptor? = null,
22
+ capabilities: ProviderDynamicCapabilities
23
+ ): ProviderCapabilitySnapshot = ProviderCapabilitySnapshot(
24
+ providerId = providerId,
25
+ descriptor = ProviderDescriptor(
26
+ id = providerId,
27
+ type = type,
28
+ transport = transport,
29
+ streamingStyle = streamingStyle,
30
+ supports = ProviderDescriptor.SupportsCapabilities(
31
+ run = true,
32
+ streaming = streaming,
33
+ realtime = false,
34
+ tools = false,
35
+ reasoningEvents = false,
36
+ structuredOutput = false,
37
+ multimodal = false
38
+ ),
39
+ cancel = cancel,
40
+ tasks = listOf("text_to_text"),
41
+ limits = limits,
42
+ privacy = privacy
43
+ ),
44
+ capabilities = capabilities
45
+ )
46
+
47
+ @Test
48
+ fun `encodeCapabilitySnapshots wraps the snapshots in a providers array`() {
49
+ val encoded = IndeRunSerializer.encodeCapabilitySnapshots(
50
+ listOf(
51
+ snapshot(
52
+ providerId = "openai",
53
+ type = ProviderDescriptor.ProviderType.cloud,
54
+ transport = ProviderDescriptor.TransportType.http,
55
+ streamingStyle = ProviderDescriptor.StreamingStyle.tokens,
56
+ streaming = true,
57
+ cancel = ProviderDescriptor.CancelSemantics.hard,
58
+ limits = ProviderDescriptor.ResourceLimits(
59
+ maxInputTokens = 128_000,
60
+ maxOutputTokens = 4_096
61
+ ),
62
+ privacy = ProviderDescriptor.PrivacyDescriptor(
63
+ dataLeavesDevice = true,
64
+ regions = listOf("us")
65
+ ),
66
+ capabilities = ProviderDynamicCapabilities(available = true)
67
+ )
68
+ )
69
+ )
70
+
71
+ val providers = encoded.getJSONArray("providers")
72
+ assertEquals(1, providers.length())
73
+
74
+ val provider = providers.getJSONObject(0)
75
+ assertEquals("openai", provider.getString("providerId"))
76
+
77
+ val descriptor = provider.getJSONObject("descriptor")
78
+ assertEquals("openai", descriptor.getString("id"))
79
+ assertEquals("cloud", descriptor.getString("type"))
80
+ assertEquals("http", descriptor.getString("transport"))
81
+ assertEquals("tokens", descriptor.getString("streamingStyle"))
82
+ assertEquals("hard", descriptor.getString("cancel"))
83
+ assertEquals(1, descriptor.getJSONArray("tasks").length())
84
+ assertEquals("text_to_text", descriptor.getJSONArray("tasks").getString(0))
85
+
86
+ val supports = descriptor.getJSONObject("supports")
87
+ assertTrue(supports.getBoolean("run"))
88
+ assertTrue(supports.getBoolean("streaming"))
89
+ assertFalse(supports.getBoolean("realtime"))
90
+ assertFalse(supports.getBoolean("tools"))
91
+ assertFalse(supports.getBoolean("reasoningEvents"))
92
+ assertFalse(supports.getBoolean("structuredOutput"))
93
+ assertFalse(supports.getBoolean("multimodal"))
94
+
95
+ val limits = descriptor.getJSONObject("limits")
96
+ assertEquals(128_000, limits.getInt("maxInputTokens"))
97
+ assertEquals(4_096, limits.getInt("maxOutputTokens"))
98
+ assertFalse(limits.has("maxImageBytes"))
99
+ assertFalse(limits.has("maxAudioSeconds"))
100
+
101
+ val privacy = descriptor.getJSONObject("privacy")
102
+ assertTrue(privacy.getBoolean("dataLeavesDevice"))
103
+ assertEquals("us", privacy.getJSONArray("regions").getString(0))
104
+
105
+ assertTrue(provider.getJSONObject("capabilities").getBoolean("available"))
106
+ }
107
+
108
+ /**
109
+ * `in_process` and `system_service` are the two descriptor constants a future upstream
110
+ * rename to camelCase would silently corrupt on the wire, because the TypeScript union
111
+ * in src/definitions.ts spells them out. Asserting the literals is the guard.
112
+ */
113
+ @Test
114
+ fun `encodeCapabilitySnapshots writes snake case transport constants verbatim`() {
115
+ val encoded = IndeRunSerializer.encodeCapabilitySnapshots(
116
+ listOf(
117
+ snapshot(
118
+ providerId = "local.onnx.genai.android",
119
+ type = ProviderDescriptor.ProviderType.local,
120
+ transport = ProviderDescriptor.TransportType.in_process,
121
+ streaming = false,
122
+ cancel = ProviderDescriptor.CancelSemantics.soft,
123
+ capabilities = ProviderDynamicCapabilities(
124
+ available = false,
125
+ reason = "No model package configured."
126
+ )
127
+ ),
128
+ snapshot(
129
+ providerId = "android.mlkit.genai",
130
+ type = ProviderDescriptor.ProviderType.local,
131
+ transport = ProviderDescriptor.TransportType.system_service,
132
+ streamingStyle = ProviderDescriptor.StreamingStyle.chunks,
133
+ streaming = true,
134
+ cancel = ProviderDescriptor.CancelSemantics.soft,
135
+ capabilities = ProviderDynamicCapabilities(available = true)
136
+ )
137
+ )
138
+ )
139
+
140
+ val providers = encoded.getJSONArray("providers")
141
+ assertEquals(
142
+ "in_process",
143
+ providers.getJSONObject(0).getJSONObject("descriptor").getString("transport")
144
+ )
145
+ assertEquals(
146
+ "system_service",
147
+ providers.getJSONObject(1).getJSONObject("descriptor").getString("transport")
148
+ )
149
+ assertEquals(
150
+ "chunks",
151
+ providers.getJSONObject(1).getJSONObject("descriptor").getString("streamingStyle")
152
+ )
153
+ }
154
+
155
+ /**
156
+ * Absence is the contract's "inherit the static declaration" state, so the nullable
157
+ * flags must not reach the wire as nulls — a null would be a third state no consumer
158
+ * has. Same for the optional descriptor sub-objects.
159
+ */
160
+ @Test
161
+ fun `encodeCapabilitySnapshots omits unset optional fields instead of writing null`() {
162
+ val encoded = IndeRunSerializer.encodeCapabilitySnapshots(
163
+ listOf(
164
+ snapshot(
165
+ providerId = "android.mlkit.genai",
166
+ type = ProviderDescriptor.ProviderType.local,
167
+ transport = ProviderDescriptor.TransportType.system_service,
168
+ streaming = true,
169
+ cancel = ProviderDescriptor.CancelSemantics.soft,
170
+ capabilities = ProviderDynamicCapabilities(available = true)
171
+ )
172
+ )
173
+ )
174
+
175
+ val provider = encoded.getJSONArray("providers").getJSONObject(0)
176
+ val descriptor = provider.getJSONObject("descriptor")
177
+ assertFalse(descriptor.has("streamingStyle"))
178
+ assertFalse(descriptor.has("limits"))
179
+ assertFalse(descriptor.has("privacy"))
180
+
181
+ val capabilities = provider.getJSONObject("capabilities")
182
+ assertFalse(capabilities.has("reason"))
183
+ assertFalse(capabilities.has("streamingAvailable"))
184
+ assertFalse(capabilities.has("streamingUnavailableReason"))
185
+ assertFalse(capabilities.has("cancellationAvailable"))
186
+ }
187
+
188
+ @Test
189
+ fun `encodeCapabilitySnapshots encodes streaming taken away at runtime`() {
190
+ val encoded = IndeRunSerializer.encodeCapabilitySnapshots(
191
+ listOf(
192
+ snapshot(
193
+ providerId = "openai",
194
+ type = ProviderDescriptor.ProviderType.cloud,
195
+ transport = ProviderDescriptor.TransportType.http,
196
+ streamingStyle = ProviderDescriptor.StreamingStyle.tokens,
197
+ streaming = true,
198
+ cancel = ProviderDescriptor.CancelSemantics.hard,
199
+ capabilities = ProviderDynamicCapabilities(
200
+ available = true,
201
+ streamingAvailable = false,
202
+ streamingUnavailableReason = "Host has no streaming HTTP client.",
203
+ cancellationAvailable = true
204
+ )
205
+ )
206
+ )
207
+ )
208
+
209
+ val capabilities = encoded.getJSONArray("providers")
210
+ .getJSONObject(0)
211
+ .getJSONObject("capabilities")
212
+ assertTrue(capabilities.getBoolean("available"))
213
+ assertFalse(capabilities.getBoolean("streamingAvailable"))
214
+ assertEquals(
215
+ "Host has no streaming HTTP client.",
216
+ capabilities.getString("streamingUnavailableReason")
217
+ )
218
+ assertTrue(capabilities.getBoolean("cancellationAvailable"))
219
+ }
220
+
221
+ @Test
222
+ fun `encodeCapabilitySnapshots encodes an empty registry as an empty array`() {
223
+ val encoded = IndeRunSerializer.encodeCapabilitySnapshots(emptyList())
224
+
225
+ assertTrue(encoded.has("providers"))
226
+ assertEquals(0, encoded.getJSONArray("providers").length())
227
+ }
228
+
229
+ /**
230
+ * Every enum constant of every descriptor enum maps to the wire spelling the
231
+ * TypeScript unions declare. Exhaustive by construction: `values()` grows when
232
+ * upstream adds a constant, and a renamed one fails here rather than in a demo.
233
+ */
234
+ @Test
235
+ fun `every descriptor enum constant maps to its declared wire value`() {
236
+ assertEquals(
237
+ listOf("local", "edge", "cloud"),
238
+ ProviderDescriptor.ProviderType.values().map { it.name }
239
+ )
240
+ assertEquals(
241
+ listOf("in_process", "system_service", "http", "sse", "realtime"),
242
+ ProviderDescriptor.TransportType.values().map { it.name }
243
+ )
244
+ assertEquals(
245
+ listOf("tokens", "chunks", "snapshots"),
246
+ ProviderDescriptor.StreamingStyle.values().map { it.name }
247
+ )
248
+ assertEquals(
249
+ listOf("hard", "soft", "none"),
250
+ ProviderDescriptor.CancelSemantics.values().map { it.name }
251
+ )
252
+ }
253
+ }
@@ -142,6 +142,29 @@ class IndeRunSerializerTest {
142
142
 
143
143
  // --- encodeError ---
144
144
 
145
+ /**
146
+ * `systemModel` and `onnx` are web-only bootstrap keys, like
147
+ * `allowDirectOpenAIEndpoint`. Android registers its own on-device provider, so it must
148
+ * ignore them rather than fail on the options object that carries them.
149
+ */
150
+ @Test
151
+ fun `parseConfigureOptions ignores the web-only provider bootstrap keys`() {
152
+ val options = IndeRunSerializer.parseConfigureOptions(
153
+ JSONObject(
154
+ """
155
+ {
156
+ "openAI": { "model": "gpt-5.2", "auth": "none" },
157
+ "systemModel": { "id": "local.system-model.web", "timeoutMs": 30000 },
158
+ "onnx": { "modelPackage": { "id": "demo", "format": "onnx" } }
159
+ }
160
+ """.trimIndent()
161
+ )
162
+ )
163
+
164
+ assertEquals("gpt-5.2", options.openAI?.model)
165
+ assertEquals("none", options.openAI?.auth)
166
+ }
167
+
145
168
  @Test
146
169
  fun `encodeError produces correct shape with required fields only`() {
147
170
  val encoded = IndeRunSerializer.encodeError(
@@ -177,4 +200,60 @@ class IndeRunSerializerTest {
177
200
  assertEquals(2000L, encoded.getLong("retryAfterMs"))
178
201
  assertEquals("run_abc", encoded.getString("runId"))
179
202
  }
203
+
204
+ /**
205
+ * A routing refusal carries its plan diagnostics on the error's `details`, and since
206
+ * inderun 0.3.0 it does so on iOS and Android too, not just on the web SDK. The shape
207
+ * is nested — a `rejectedProviders` array of objects, each with its own `reasons`
208
+ * array — and `encodeError` hands the whole map to `JSONObject(Map)`, which deep-wraps
209
+ * via `wrap()`. Nothing asserted that before; this is the data a provider-refusal UI
210
+ * actually reads, so a regression here would be invisible until a demo showed an empty
211
+ * table.
212
+ */
213
+ @Test
214
+ fun `encodeError preserves nested route-plan diagnostics in details`() {
215
+ val encoded = IndeRunSerializer.encodeError(
216
+ IndeRunError(
217
+ errorClass = IndeRunErrorClass.CapabilityMismatch,
218
+ message = "No eligible provider can stream this request.",
219
+ details = mapOf(
220
+ "failureCode" to "CapabilityMismatch",
221
+ "rejectedProviders" to listOf(
222
+ mapOf(
223
+ "providerId" to "android.mlkit.genai",
224
+ "reasons" to listOf(
225
+ mapOf(
226
+ "code" to "streaming_not_supported",
227
+ "message" to "Provider does not declare streaming."
228
+ )
229
+ )
230
+ ),
231
+ mapOf(
232
+ "providerId" to "openai",
233
+ "reasons" to listOf(
234
+ mapOf("code" to "privacy_constraint", "message" to "local_required forbids cloud.")
235
+ )
236
+ )
237
+ )
238
+ )
239
+ )
240
+ )
241
+
242
+ val details = encoded.getJSONObject("details")
243
+ assertEquals("CapabilityMismatch", details.getString("failureCode"))
244
+
245
+ val rejected = details.getJSONArray("rejectedProviders")
246
+ assertEquals(2, rejected.length())
247
+ assertEquals("android.mlkit.genai", rejected.getJSONObject(0).getString("providerId"))
248
+ assertEquals(
249
+ "streaming_not_supported",
250
+ rejected.getJSONObject(0).getJSONArray("reasons").getJSONObject(0).getString("code")
251
+ )
252
+ assertEquals("openai", rejected.getJSONObject(1).getString("providerId"))
253
+ assertEquals(
254
+ "privacy_constraint",
255
+ rejected.getJSONObject(1).getJSONArray("reasons").getJSONObject(0).getString("code")
256
+ )
257
+ }
258
+
180
259
  }
@@ -1,5 +1,5 @@
1
1
  import type { PluginListenerHandle } from "@capacitor/core";
2
- import type { IndeRunError, StreamEvent, StreamRunHandle, TaskRequest, TaskResult } from "@independo/inderun-contracts";
2
+ import type { IndeRunError, ModelPackage, StreamEvent, StreamRunHandle, TaskRequest, TaskResult } from "@independo/inderun-contracts";
3
3
  export interface OpenAIProviderBootstrapOptions {
4
4
  model: string;
5
5
  endpointUrl?: string;
@@ -7,8 +7,50 @@ export interface OpenAIProviderBootstrapOptions {
7
7
  authContextRef?: string;
8
8
  timeoutMs?: number;
9
9
  }
10
+ /**
11
+ * Bootstrap options for the browser-managed on-device provider (Chrome's Prompt API).
12
+ *
13
+ * **Web only**, and ignored on iOS and Android, which register their own on-device
14
+ * providers — Apple Foundation Models and ML Kit GenAI — from `configure()` regardless.
15
+ *
16
+ * The browser owns model availability, download and execution, so there is nothing to
17
+ * configure: registering it is the whole point, and it is what makes
18
+ * `constraints.privacy = "local_required"` routable in a browser. Mode 1 only — this
19
+ * provider does not stream, so a `local_required` *stream* on the web is still refused at
20
+ * routing time.
21
+ *
22
+ * The web SDK's `runtime` injection seam is deliberately not exposed: it is a function,
23
+ * and `configure()` has to survive a JSON bridge hop on native.
24
+ */
25
+ export interface SystemModelProviderBootstrapOptions {
26
+ id?: string;
27
+ timeoutMs?: number;
28
+ }
29
+ /**
30
+ * Bootstrap options for the Web ONNX Runtime provider, for a developer-supplied local
31
+ * model.
32
+ *
33
+ * **Web only**, like `systemModel`, and Mode 1 only.
34
+ *
35
+ * Two caveats worth knowing before reaching for this. The consumer has to install the
36
+ * optional `@huggingface/transformers` peer dependency — this bridge does not declare it —
37
+ * and supply real model weights, because the web SDK's `runtime` seam is a function and so
38
+ * cannot cross the JSON bridge hop: only the default Transformers.js runtime is reachable
39
+ * from here, never the fixture runtime the upstream demos use offline. A registered
40
+ * provider that cannot load turns a clean routing refusal into a provider error, so
41
+ * register it only when the weights are actually there.
42
+ */
43
+ export interface OnnxProviderBootstrapOptions {
44
+ id?: string;
45
+ modelPackage: ModelPackage;
46
+ timeoutMs?: number;
47
+ }
10
48
  export interface ConfigureOptions {
11
49
  openAI?: OpenAIProviderBootstrapOptions;
50
+ /** Web only; native registers its own on-device provider. */
51
+ systemModel?: SystemModelProviderBootstrapOptions;
52
+ /** Web only; native registers its own on-device provider. */
53
+ onnx?: OnnxProviderBootstrapOptions;
12
54
  allowDirectOpenAIEndpoint?: boolean;
13
55
  }
14
56
  /**
@@ -53,9 +95,88 @@ export interface StreamRun {
53
95
  events: AsyncIterable<StreamEvent>;
54
96
  cancel(reason?: string): void;
55
97
  }
98
+ /**
99
+ * A provider's static capability declaration.
100
+ *
101
+ * Declared here rather than imported, because — unlike `TaskRequest`, `StreamEvent` and
102
+ * the rest — this shape is *not* a generated contract. There is no schema for it in
103
+ * `@independo/inderun-contracts` and no validator; each SDK declares it independently
104
+ * (`core/provider.d.ts` in `@independo/inderun-web`, `IndeRunCore/Provider.swift`,
105
+ * `core/Provider.kt`), and this is the fourth copy. Importing it from
106
+ * `@independo/inderun-web` is not an option either: that would make the native
107
+ * platforms' plugin contract depend on the web SDK.
108
+ *
109
+ * The drift guard is in `web.ts`, which returns the web SDK's value into this type
110
+ * uncast — so `tsc` proves the shapes still match on every build, the same way the
111
+ * `StreamRun` mirror below is checked. See the upstream follow-up asking for a schema.
112
+ */
113
+ export interface ProviderDescriptor {
114
+ id: string;
115
+ type: "local" | "edge" | "cloud";
116
+ transport: "in_process" | "system_service" | "http" | "sse" | "realtime";
117
+ streamingStyle?: "tokens" | "chunks" | "snapshots";
118
+ supports: {
119
+ run: boolean;
120
+ streaming: boolean;
121
+ realtime: boolean;
122
+ tools: boolean;
123
+ reasoningEvents: boolean;
124
+ structuredOutput: boolean;
125
+ multimodal: boolean;
126
+ };
127
+ cancel: "hard" | "soft" | "none";
128
+ tasks: string[];
129
+ limits?: {
130
+ maxInputTokens?: number;
131
+ maxOutputTokens?: number;
132
+ maxImageBytes?: number;
133
+ maxAudioSeconds?: number;
134
+ };
135
+ privacy?: {
136
+ dataLeavesDevice: boolean;
137
+ regions?: string[];
138
+ };
139
+ }
140
+ /**
141
+ * A provider's live availability, as of the moment `checkCapabilities()` was called.
142
+ *
143
+ * `streamingAvailable` and `cancellationAvailable` are **absent**, not `null`, when the
144
+ * runtime has nothing to say: absence means *inherit the static declaration*
145
+ * (`descriptor.supports.streaming`, and `descriptor.cancel !== "none"`). Both native
146
+ * encoders omit the key rather than emitting null for exactly that reason.
147
+ */
148
+ export interface ProviderDynamicCapabilities {
149
+ available: boolean;
150
+ reason?: string;
151
+ streamingAvailable?: boolean;
152
+ streamingUnavailableReason?: string;
153
+ cancellationAvailable?: boolean;
154
+ }
155
+ /** One registered provider's identity, static declaration, and live availability. */
156
+ export interface ProviderCapabilitySnapshot {
157
+ providerId: string;
158
+ descriptor: ProviderDescriptor;
159
+ capabilities: ProviderDynamicCapabilities;
160
+ }
161
+ /**
162
+ * Envelope for `checkCapabilities()`. The array is wrapped because a Capacitor plugin
163
+ * method must resolve an object on both native platforms — `PluginCall.resolve(JSObject)`
164
+ * and `call.resolve([String: Any])` cannot carry a top-level array. `IndeRunCapacitor`
165
+ * and `createIndeRunCapacitor()` unwrap it, so app code sees the same
166
+ * `ProviderCapabilitySnapshot[]` the three platform SDKs return.
167
+ */
168
+ export interface CheckCapabilitiesResult {
169
+ providers: ProviderCapabilitySnapshot[];
170
+ }
56
171
  export interface IndeRunCapacitorPlugin {
57
172
  configure(options?: ConfigureOptions): Promise<void>;
58
173
  run(request: TaskRequest): Promise<TaskResult>;
174
+ /**
175
+ * Live snapshot of every registered provider, without executing a task. Availability
176
+ * changes between calls — a local model can unload, cloud credentials can expire — so
177
+ * do not cache it across a `run()` or `stream()`.
178
+ */
179
+ checkCapabilities(): Promise<CheckCapabilitiesResult>;
59
180
  /**
60
181
  * Unlike `run(request)`, which passes the request at the options root, this nests it
61
182
  * under `request` so the envelope can also carry `streamId`. Both native decode sites
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../src/definitions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EACX,eAAe,EACf,WAAW,EACX,UAAU,EACX,MAAM,8BAA8B,CAAC;AAEtC,MAAM,WAAW,8BAA8B;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAAC;IACjC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,8BAA8B,CAAC;IACxC,yBAAyB,CAAC,EAAE,OAAO,CAAC;CACrC;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,6FAA6F;AAC7F,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,WAAW,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,YAAY,CAAC;CACrB;AAED;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IACnC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,GAAG,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/C;;;;OAIG;IACH,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IACnE,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,WAAW,CACT,SAAS,EAAE,oBAAoB,EAC/B,YAAY,EAAE,CAAC,YAAY,EAAE,uBAAuB,KAAK,IAAI,GAC5D,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACjC,WAAW,CACT,SAAS,EAAE,oBAAoB,EAC/B,YAAY,EAAE,CAAC,YAAY,EAAE,uBAAuB,KAAK,IAAI,GAC5D,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACjC,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC"}
1
+ {"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../src/definitions.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,20 +1,23 @@
1
1
  import type { TaskRequest, TaskResult } from "@independo/inderun-contracts";
2
- import type { CancelStreamOptions, ConfigureOptions, IndeRunCapacitorPlugin as IndeRunCapacitorPluginContract, OpenAIProviderBootstrapOptions, StartStreamOptions, StreamErrorNotification, StreamEventNotification, StreamRun } from "./definitions.js";
2
+ import type { CancelStreamOptions, CheckCapabilitiesResult, ConfigureOptions, IndeRunCapacitorPlugin as IndeRunCapacitorPluginContract, OnnxProviderBootstrapOptions, OpenAIProviderBootstrapOptions, ProviderCapabilitySnapshot, ProviderDescriptor, ProviderDynamicCapabilities, StartStreamOptions, StreamErrorNotification, StreamEventNotification, StreamRun, SystemModelProviderBootstrapOptions } from "./definitions.js";
3
3
  /**
4
4
  * The plugin contract plus the ergonomic Mode 2 entry point. `stream()` is not a
5
5
  * plugin method — it is `startStream`, the event listeners, and `cancelStream`
6
6
  * reassembled into the same shape the platform SDKs return from `stream()`.
7
7
  */
8
- export interface IndeRunCapacitorApi extends IndeRunCapacitorPluginContract {
8
+ export interface IndeRunCapacitorApi extends Omit<IndeRunCapacitorPluginContract, "checkCapabilities"> {
9
9
  stream(request: TaskRequest): Promise<StreamRun>;
10
+ /** The plugin's `{ providers }` envelope, unwrapped to match the platform SDKs. */
11
+ checkCapabilities(): Promise<ProviderCapabilitySnapshot[]>;
10
12
  }
11
13
  export declare const IndeRunCapacitor: IndeRunCapacitorApi;
12
14
  export interface IndeRunCapacitorInstance {
13
15
  run(request: TaskRequest): Promise<TaskResult>;
14
16
  stream(request: TaskRequest): Promise<StreamRun>;
17
+ checkCapabilities(): Promise<ProviderCapabilitySnapshot[]>;
15
18
  }
16
19
  export declare function createIndeRunCapacitor(options?: ConfigureOptions): IndeRunCapacitorInstance;
17
20
  export { STREAM_ERROR_NAME, STREAM_EVENT_NAME } from "./streaming.js";
18
- export type { CancelStreamOptions, ConfigureOptions, IndeRunCapacitorPluginContract as IndeRunCapacitorPlugin, OpenAIProviderBootstrapOptions, StartStreamOptions, StreamErrorNotification, StreamEventNotification, StreamRun, TaskRequest, TaskResult };
21
+ export type { CancelStreamOptions, CheckCapabilitiesResult, ConfigureOptions, IndeRunCapacitorPluginContract as IndeRunCapacitorPlugin, OnnxProviderBootstrapOptions, OpenAIProviderBootstrapOptions, ProviderCapabilitySnapshot, ProviderDescriptor, ProviderDynamicCapabilities, StartStreamOptions, StreamErrorNotification, StreamEventNotification, StreamRun, SystemModelProviderBootstrapOptions, TaskRequest, TaskResult };
19
22
  export type * from "@independo/inderun-contracts";
20
23
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,WAAW,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAE7F,OAAO,KAAK,EACV,mBAAmB,EACnB,gBAAgB,EAChB,sBAAsB,IAAI,8BAA8B,EACxD,8BAA8B,EAC9B,kBAAkB,EAClB,uBAAuB,EACvB,uBAAuB,EACvB,SAAS,EACV,MAAM,kBAAkB,CAAC;AAQ1B;;;;GAIG;AACH,MAAM,WAAW,mBAAoB,SAAQ,8BAA8B;IACzE,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;CAClD;AAED,eAAO,MAAM,gBAAgB,EAAE,mBA4C9B,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACvC,GAAG,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/C,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;CAClD;AAED,wBAAgB,sBAAsB,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,wBAAwB,CAsB3F;AAED,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEtE,YAAY,EACV,mBAAmB,EACnB,gBAAgB,EAChB,8BAA8B,IAAI,sBAAsB,EACxD,8BAA8B,EAC9B,kBAAkB,EAClB,uBAAuB,EACvB,uBAAuB,EACvB,SAAS,EACT,WAAW,EACX,UAAU,EACX,CAAC;AAEF,mBAAmB,8BAA8B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,WAAW,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAE7F,OAAO,KAAK,EACV,mBAAmB,EACnB,uBAAuB,EACvB,gBAAgB,EAChB,sBAAsB,IAAI,8BAA8B,EACxD,4BAA4B,EAC5B,8BAA8B,EAC9B,0BAA0B,EAC1B,kBAAkB,EAClB,2BAA2B,EAC3B,kBAAkB,EAClB,uBAAuB,EACvB,uBAAuB,EACvB,SAAS,EACT,mCAAmC,EACpC,MAAM,kBAAkB,CAAC;AAQ1B;;;;GAIG;AACH,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAAC,8BAA8B,EAAE,mBAAmB,CAAC;IACpG,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IACjD,mFAAmF;IACnF,iBAAiB,IAAI,OAAO,CAAC,0BAA0B,EAAE,CAAC,CAAC;CAC5D;AAED,eAAO,MAAM,gBAAgB,EAAE,mBAqD9B,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACvC,GAAG,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/C,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IACjD,iBAAiB,IAAI,OAAO,CAAC,0BAA0B,EAAE,CAAC,CAAC;CAC5D;AAED,wBAAgB,sBAAsB,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,wBAAwB,CA4B3F;AAED,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEtE,YAAY,EACV,mBAAmB,EACnB,uBAAuB,EACvB,gBAAgB,EAChB,8BAA8B,IAAI,sBAAsB,EACxD,4BAA4B,EAC5B,8BAA8B,EAC9B,0BAA0B,EAC1B,kBAAkB,EAClB,2BAA2B,EAC3B,kBAAkB,EAClB,uBAAuB,EACvB,uBAAuB,EACvB,SAAS,EACT,mCAAmC,EACnC,WAAW,EACX,UAAU,EACX,CAAC;AAEF,mBAAmB,8BAA8B,CAAC"}
package/dist/index.js CHANGED
@@ -21,6 +21,15 @@ export const IndeRunCapacitor = {
21
21
  throw normalizePluginError(error);
22
22
  }
23
23
  },
24
+ async checkCapabilities() {
25
+ try {
26
+ const result = await IndeRunCapacitorNative.checkCapabilities();
27
+ return result.providers;
28
+ }
29
+ catch (error) {
30
+ throw normalizePluginError(error);
31
+ }
32
+ },
24
33
  async startStream(options) {
25
34
  try {
26
35
  return await IndeRunCapacitorNative.startStream(options);
@@ -62,6 +71,11 @@ export function createIndeRunCapacitor(options) {
62
71
  async stream(request) {
63
72
  await ensureConfigured();
64
73
  return IndeRunCapacitor.stream(request);
74
+ },
75
+ // Configures first: without a registry there are no providers to report on.
76
+ async checkCapabilities() {
77
+ await ensureConfigured();
78
+ return IndeRunCapacitor.checkCapabilities();
65
79
  }
66
80
  };
67
81
  }
package/dist/web.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { StreamRunHandle, TaskResult } from "@independo/inderun-contracts";
2
2
  import { WebPlugin } from "@capacitor/core";
3
- import type { CancelStreamOptions, ConfigureOptions, IndeRunCapacitorPlugin, StartStreamOptions } from "./definitions.js";
3
+ import type { CancelStreamOptions, CheckCapabilitiesResult, ConfigureOptions, IndeRunCapacitorPlugin, StartStreamOptions } from "./definitions.js";
4
4
  import type { TaskRequest } from "@independo/inderun-contracts";
5
5
  export declare class IndeRunWeb extends WebPlugin implements IndeRunCapacitorPlugin {
6
6
  private engine;
@@ -9,6 +9,7 @@ export declare class IndeRunWeb extends WebPlugin implements IndeRunCapacitorPlu
9
9
  private readonly pendingCancels;
10
10
  configure(options?: ConfigureOptions): Promise<void>;
11
11
  run(request: TaskRequest): Promise<TaskResult>;
12
+ checkCapabilities(): Promise<CheckCapabilitiesResult>;
12
13
  /**
13
14
  * The web path deliberately round-trips through `notifyListeners` rather than
14
15
  * handing the engine's `StreamRun` straight back.
package/dist/web.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAChF,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,KAAK,EACV,mBAAmB,EACnB,gBAAgB,EAChB,sBAAsB,EACtB,kBAAkB,EAEnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAIhE,qBAAa,UAAW,SAAQ,SAAU,YAAW,sBAAsB;IACzE,OAAO,CAAC,MAAM,CAAwB;IAItC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgC;IAC9D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqB;IACrD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAyC;IAElE,SAAS,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA6BzD;IAEK,GAAG,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAYnD;IAED;;;;;;;;OAQG;IACG,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,eAAe,CAAC,CA8BvE;IAEK,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiB9D;YAEa,IAAI;CAenB"}
1
+ {"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAChF,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,KAAK,EACV,mBAAmB,EACnB,uBAAuB,EACvB,gBAAgB,EAChB,sBAAsB,EACtB,kBAAkB,EAEnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAIhE,qBAAa,UAAW,SAAQ,SAAU,YAAW,sBAAsB;IACzE,OAAO,CAAC,MAAM,CAAwB;IAItC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgC;IAC9D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqB;IACrD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAyC;IAElE,SAAS,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkCzD;IAEK,GAAG,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAYnD;IAEK,iBAAiB,IAAI,OAAO,CAAC,uBAAuB,CAAC,CAe1D;IAED;;;;;;;;OAQG;IACG,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,eAAe,CAAC,CA8BvE;IAEK,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiB9D;YAEa,IAAI;CAenB"}