@independo/capacitor-inderun 0.2.0-dev.0

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,111 @@
1
+ package app.independo.inderun.capacitor
2
+
3
+ import app.independo.inderun.core.IndeRunException
4
+ import app.independo.inderun.core.ProviderRegistry
5
+ import app.independo.inderun.core.toIndeRunException
6
+ import app.independo.inderun.providers.mlkit.AndroidProviderRegistryFactory
7
+ import app.independo.inderun.providers.openai.DEFAULT_OPENAI_RESPONSES_ENDPOINT
8
+ import app.independo.inderun.providers.openai.OpenAIAuthMode
9
+ import app.independo.inderun.providers.openai.OpenAIProvider
10
+ import app.independo.inderun.providers.openai.OpenAIProviderOptions
11
+ import app.independo.inderun.sdk.IndeRun
12
+ import com.getcapacitor.Plugin
13
+ import com.getcapacitor.PluginCall
14
+ import com.getcapacitor.PluginMethod
15
+ import com.getcapacitor.annotation.CapacitorPlugin
16
+ import kotlinx.coroutines.CoroutineScope
17
+ import kotlinx.coroutines.Dispatchers
18
+ import kotlinx.coroutines.SupervisorJob
19
+ import kotlinx.coroutines.cancel
20
+ import kotlinx.coroutines.launch
21
+
22
+ @CapacitorPlugin(name = "IndeRunCapacitor")
23
+ class IndeRunCapacitorPlugin : Plugin() {
24
+ private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
25
+ private var configuredRegistry: ProviderRegistry? = null
26
+
27
+ @PluginMethod
28
+ fun configure(call: PluginCall) {
29
+ try {
30
+ val options = IndeRunSerializer.parseConfigureOptions(call.data)
31
+ configuredRegistry = createRegistry(options.openAI)
32
+ call.resolve()
33
+ } catch (error: IndeRunException) {
34
+ val contractError = error.toContractError()
35
+ call.reject(
36
+ contractError.message,
37
+ contractError.errorClass.rawValue,
38
+ null,
39
+ runCatching { IndeRunSerializer.encodeError(contractError) }.getOrNull()
40
+ )
41
+ } catch (error: Throwable) {
42
+ val normalized = toIndeRunException(error)
43
+ val contractError = normalized.toContractError()
44
+ call.reject(
45
+ contractError.message,
46
+ contractError.errorClass.rawValue,
47
+ null,
48
+ runCatching { IndeRunSerializer.encodeError(contractError) }.getOrNull()
49
+ )
50
+ }
51
+ }
52
+
53
+ @PluginMethod
54
+ fun run(call: PluginCall) {
55
+ val requestJson = call.data
56
+
57
+ scope.launch {
58
+ try {
59
+ val registry = configuredRegistry
60
+ ?: throw toIndeRunException(IllegalStateException("Capacitor IndeRun has not been configured. Configure providers before calling run(request)."))
61
+ val request = IndeRunSerializer.parseTaskRequest(requestJson)
62
+ // IndeRun is stateless; new per call is intentional — registry is cached after configure().
63
+ val result = IndeRun.initialize(context.applicationContext, registry).run(request)
64
+ call.resolve(IndeRunSerializer.encodeTaskResult(result))
65
+ } catch (error: IndeRunException) {
66
+ val contractError = error.toContractError()
67
+ call.reject(
68
+ contractError.message,
69
+ contractError.errorClass.rawValue,
70
+ null,
71
+ runCatching { IndeRunSerializer.encodeError(contractError) }.getOrNull()
72
+ )
73
+ } catch (error: Throwable) {
74
+ val normalized = toIndeRunException(error)
75
+ val contractError = normalized.toContractError()
76
+ call.reject(
77
+ contractError.message,
78
+ contractError.errorClass.rawValue,
79
+ null,
80
+ runCatching { IndeRunSerializer.encodeError(contractError) }.getOrNull()
81
+ )
82
+ }
83
+ }
84
+ }
85
+
86
+ override fun handleOnDestroy() {
87
+ scope.cancel()
88
+ super.handleOnDestroy()
89
+ }
90
+
91
+ private fun createRegistry(openAI: OpenAIProviderBootstrapOptions?): ProviderRegistry {
92
+ val registry = AndroidProviderRegistryFactory.makeDefaultRegistry(context.applicationContext)
93
+
94
+ if (openAI != null) {
95
+ registry.register(
96
+ OpenAIProvider(
97
+ OpenAIProviderOptions(
98
+ id = "openai",
99
+ model = openAI.model,
100
+ endpointUrl = openAI.endpointUrl ?: DEFAULT_OPENAI_RESPONSES_ENDPOINT,
101
+ auth = if (openAI.auth == "none") OpenAIAuthMode.none else OpenAIAuthMode.authContextRef,
102
+ authContextRef = openAI.authContextRef,
103
+ timeoutMs = openAI.timeoutMs
104
+ )
105
+ )
106
+ )
107
+ }
108
+
109
+ return registry
110
+ }
111
+ }
@@ -0,0 +1,263 @@
1
+ package app.independo.inderun.capacitor
2
+
3
+ import app.independo.inderun.contracts.Cloud
4
+ import app.independo.inderun.contracts.FinishReason
5
+ import app.independo.inderun.contracts.Generation
6
+ import app.independo.inderun.contracts.IndeRunError
7
+ import app.independo.inderun.contracts.IndeRunErrorClass
8
+ import app.independo.inderun.contracts.Message
9
+ import app.independo.inderun.contracts.MessageRole
10
+ import app.independo.inderun.contracts.OptimizeFor
11
+ import app.independo.inderun.contracts.OutputType
12
+ import app.independo.inderun.contracts.PrivacyEnum
13
+ import app.independo.inderun.contracts.SchemaVersion
14
+ import app.independo.inderun.contracts.TaskKind
15
+ import app.independo.inderun.contracts.TaskRequest
16
+ import app.independo.inderun.contracts.TaskRequestConstraints
17
+ import app.independo.inderun.contracts.TaskRequestPreferences
18
+ import app.independo.inderun.contracts.TaskRequestTask
19
+ import app.independo.inderun.contracts.TaskRequestTelemetry
20
+ import app.independo.inderun.contracts.TaskResult
21
+ import app.independo.inderun.contracts.TaskResultTelemetry
22
+ import app.independo.inderun.contracts.TelemetryLevel
23
+ import app.independo.inderun.contracts.Usage
24
+ import com.getcapacitor.JSArray
25
+ import com.getcapacitor.JSObject
26
+ import org.json.JSONArray
27
+ import org.json.JSONObject
28
+
29
+ data class OpenAIProviderBootstrapOptions(
30
+ val model: String,
31
+ val endpointUrl: String? = null,
32
+ val auth: String? = null,
33
+ val authContextRef: String? = null,
34
+ val timeoutMs: Long? = null
35
+ )
36
+
37
+ data class RunOptions(
38
+ val openAI: OpenAIProviderBootstrapOptions? = null
39
+ )
40
+
41
+ object IndeRunSerializer {
42
+ fun parseConfigureOptions(json: JSONObject): RunOptions {
43
+ return RunOptions(
44
+ openAI = json.optJSONObject("openAI")?.let(::parseOpenAIOptions)
45
+ )
46
+ }
47
+
48
+ fun parseTaskRequest(json: JSONObject): TaskRequest {
49
+ return TaskRequest(
50
+ authContextRef = json.optStringOrNull("authContextRef"),
51
+ constraints = json.optJSONObject("constraints")?.let(::parseConstraints),
52
+ generation = json.optJSONObject("generation")?.let(::parseGeneration),
53
+ messages = json.optJSONArray("messages")?.let(::parseMessages),
54
+ preferences = json.optJSONObject("preferences")?.let(::parsePreferences),
55
+ prompt = json.optStringOrNull("prompt"),
56
+ requestId = json.optStringOrNull("requestId"),
57
+ schemaVersion = parseSchemaVersion(json.getString("schemaVersion")),
58
+ task = parseTask(json.getJSONObject("task")),
59
+ telemetry = json.optJSONObject("telemetry")?.let(::parseTelemetry)
60
+ )
61
+ }
62
+
63
+ fun encodeTaskResult(result: TaskResult): JSObject {
64
+ return JSObject().apply {
65
+ put("schemaVersion", result.schemaVersion.rawValue)
66
+ put("runId", result.runId)
67
+ put("finishReason", result.finishReason.rawValue)
68
+ put(
69
+ "output",
70
+ JSObject()
71
+ .put("type", result.output.type.rawValue)
72
+ .put("text", result.output.text)
73
+ )
74
+ put(
75
+ "telemetry",
76
+ JSObject()
77
+ .put("providerUsed", result.telemetry.providerUsed)
78
+ .put("totalMs", result.telemetry.totalMs)
79
+ .apply {
80
+ result.telemetry.errorClass?.let { put("errorClass", it.rawValue) }
81
+ }
82
+ )
83
+ result.usage?.let { usage ->
84
+ put(
85
+ "usage",
86
+ JSObject().apply {
87
+ usage.inputTokens?.let { put("inputTokens", it) }
88
+ usage.outputTokens?.let { put("outputTokens", it) }
89
+ usage.totalTokens?.let { put("totalTokens", it) }
90
+ }
91
+ )
92
+ }
93
+ }
94
+ }
95
+
96
+ fun encodeError(error: IndeRunError): JSObject {
97
+ return JSObject().apply {
98
+ put("schemaVersion", error.schemaVersion.rawValue)
99
+ put("errorClass", error.errorClass.rawValue)
100
+ put("message", error.message)
101
+ error.providerId?.let { put("providerId", it) }
102
+ error.retryable?.let { put("retryable", it) }
103
+ error.retryAfterMs?.let { put("retryAfterMs", it) }
104
+ error.runId?.let { put("runId", it) }
105
+ error.details?.let { put("details", JSONObject(it)) }
106
+ }
107
+ }
108
+
109
+ private fun parseOpenAIOptions(json: JSONObject): OpenAIProviderBootstrapOptions {
110
+ return OpenAIProviderBootstrapOptions(
111
+ model = json.getString("model"),
112
+ endpointUrl = json.optStringOrNull("endpointUrl"),
113
+ auth = json.optStringOrNull("auth"),
114
+ authContextRef = json.optStringOrNull("authContextRef"),
115
+ timeoutMs = json.optLongOrNull("timeoutMs")
116
+ )
117
+ }
118
+
119
+ private fun parseConstraints(json: JSONObject): TaskRequestConstraints {
120
+ return TaskRequestConstraints(
121
+ cloud = json.optStringOrNull("cloud")?.let(::parseCloud),
122
+ privacy = json.optStringOrNull("privacy")?.let(::parsePrivacy),
123
+ timeoutMs = json.optLongOrNull("timeoutMs")
124
+ )
125
+ }
126
+
127
+ private fun parseGeneration(json: JSONObject): Generation {
128
+ return Generation(
129
+ maxOutputTokens = json.optLongOrNull("maxOutputTokens"),
130
+ seed = json.optLongOrNull("seed"),
131
+ stop = json.optJSONArray("stop")?.toStringList(),
132
+ temperature = json.optDoubleOrNull("temperature"),
133
+ topP = json.optDoubleOrNull("topP")
134
+ )
135
+ }
136
+
137
+ private fun parseMessages(json: JSONArray): List<Message> {
138
+ return buildList {
139
+ for (index in 0 until json.length()) {
140
+ val message = json.getJSONObject(index)
141
+ add(
142
+ Message(
143
+ role = parseRole(message.getString("role")),
144
+ content = message.getString("content")
145
+ )
146
+ )
147
+ }
148
+ }
149
+ }
150
+
151
+ private fun parsePreferences(json: JSONObject): TaskRequestPreferences {
152
+ return TaskRequestPreferences(
153
+ optimizeFor = json.optStringOrNull("optimizeFor")?.let(::parseOptimizeFor)
154
+ )
155
+ }
156
+
157
+ private fun parseTask(json: JSONObject): TaskRequestTask {
158
+ return TaskRequestTask(kind = parseTaskKind(json.getString("kind")))
159
+ }
160
+
161
+ private fun parseTelemetry(json: JSONObject): TaskRequestTelemetry {
162
+ return TaskRequestTelemetry(
163
+ consent = json.optBooleanOrNull("consent"),
164
+ level = json.optStringOrNull("level")?.let(::parseTelemetryLevel),
165
+ tags = json.optJSONObject("tags")?.toStringMap()
166
+ )
167
+ }
168
+
169
+ private fun parseSchemaVersion(value: String): SchemaVersion {
170
+ return when (value) {
171
+ "1.0" -> SchemaVersion.V1_0
172
+ else -> throw IllegalArgumentException("Unsupported schemaVersion '$value'.")
173
+ }
174
+ }
175
+
176
+ private fun parseCloud(value: String): Cloud {
177
+ return when (value) {
178
+ "allowed" -> Cloud.Allowed
179
+ "forbidden" -> Cloud.Forbidden
180
+ "required" -> Cloud.Required
181
+ else -> throw IllegalArgumentException("Unsupported cloud constraint '$value'.")
182
+ }
183
+ }
184
+
185
+ private fun parsePrivacy(value: String): PrivacyEnum {
186
+ return when (value) {
187
+ "local_required" -> PrivacyEnum.LocalRequired
188
+ "local_preferred" -> PrivacyEnum.LocalPreferred
189
+ "cloud_allowed" -> PrivacyEnum.CloudAllowed
190
+ "cloud_required" -> PrivacyEnum.CloudRequired
191
+ else -> throw IllegalArgumentException("Unsupported privacy constraint '$value'.")
192
+ }
193
+ }
194
+
195
+ private fun parseRole(value: String): MessageRole {
196
+ return when (value) {
197
+ "assistant" -> MessageRole.ASSISTANT
198
+ "system" -> MessageRole.SYSTEM
199
+ "user" -> MessageRole.USER
200
+ else -> throw IllegalArgumentException("Unsupported message role '$value'.")
201
+ }
202
+ }
203
+
204
+ private fun parseOptimizeFor(value: String): OptimizeFor {
205
+ return when (value) {
206
+ "balanced" -> OptimizeFor.Balanced
207
+ "cost" -> OptimizeFor.Cost
208
+ "latency" -> OptimizeFor.Latency
209
+ "privacy" -> OptimizeFor.Privacy
210
+ else -> throw IllegalArgumentException("Unsupported optimizeFor '$value'.")
211
+ }
212
+ }
213
+
214
+ private fun parseTaskKind(value: String): TaskKind {
215
+ return when (value) {
216
+ "text_to_text" -> TaskKind.TEXT_TO_TEXT
217
+ else -> throw IllegalArgumentException("Unsupported task kind '$value'.")
218
+ }
219
+ }
220
+
221
+ private fun parseTelemetryLevel(value: String): TelemetryLevel {
222
+ return when (value) {
223
+ "debug" -> TelemetryLevel.DEBUG
224
+ "minimal" -> TelemetryLevel.MINIMAL
225
+ "off" -> TelemetryLevel.OFF
226
+ else -> throw IllegalArgumentException("Unsupported telemetry level '$value'.")
227
+ }
228
+ }
229
+ }
230
+
231
+ private fun JSONObject.optStringOrNull(key: String): String? {
232
+ return if (has(key) && !isNull(key)) getString(key) else null
233
+ }
234
+
235
+ private fun JSONObject.optLongOrNull(key: String): Long? {
236
+ return if (has(key) && !isNull(key)) getLong(key) else null
237
+ }
238
+
239
+ private fun JSONObject.optDoubleOrNull(key: String): Double? {
240
+ return if (has(key) && !isNull(key)) getDouble(key) else null
241
+ }
242
+
243
+ private fun JSONObject.optBooleanOrNull(key: String): Boolean? {
244
+ return if (has(key) && !isNull(key)) getBoolean(key) else null
245
+ }
246
+
247
+ private fun JSONObject.toStringMap(): Map<String, String> {
248
+ val result = linkedMapOf<String, String>()
249
+ val keys = keys()
250
+ while (keys.hasNext()) {
251
+ val key = keys.next()
252
+ result[key] = getString(key)
253
+ }
254
+ return result
255
+ }
256
+
257
+ private fun JSONArray.toStringList(): List<String> {
258
+ return buildList {
259
+ for (index in 0 until length()) {
260
+ add(getString(index))
261
+ }
262
+ }
263
+ }
@@ -0,0 +1,180 @@
1
+ package app.independo.inderun.capacitor
2
+
3
+ import app.independo.inderun.contracts.FinishReason
4
+ import app.independo.inderun.contracts.IndeRunError
5
+ import app.independo.inderun.contracts.IndeRunErrorClass
6
+ import app.independo.inderun.contracts.Output
7
+ import app.independo.inderun.contracts.SchemaVersion
8
+ import app.independo.inderun.contracts.TaskRequest
9
+ import app.independo.inderun.contracts.TaskRequestTask
10
+ import app.independo.inderun.contracts.TaskResult
11
+ import app.independo.inderun.contracts.TaskResultTelemetry
12
+ import org.json.JSONObject
13
+ import org.junit.Assert.assertEquals
14
+ import org.junit.Assert.assertFalse
15
+ import org.junit.Assert.assertNull
16
+ import org.junit.Test
17
+
18
+ class IndeRunSerializerTest {
19
+ @Test
20
+ fun `parseRunOptions decodes canonical request fields`() {
21
+ val request = IndeRunSerializer.parseTaskRequest(
22
+ JSONObject(
23
+ """
24
+ {
25
+ "schemaVersion": "1.0",
26
+ "task": { "kind": "text_to_text" },
27
+ "prompt": "Hello",
28
+ "constraints": { "privacy": "cloud_required" }
29
+ }
30
+ """.trimIndent()
31
+ )
32
+ )
33
+ val options = IndeRunSerializer.parseConfigureOptions(
34
+ JSONObject(
35
+ """
36
+ {
37
+ "openAI": {
38
+ "model": "gpt-5.2",
39
+ "endpointUrl": "/api/inderun/openai-responses",
40
+ "auth": "none"
41
+ }
42
+ }
43
+ """.trimIndent()
44
+ )
45
+ )
46
+
47
+ assertEquals("Hello", request.prompt)
48
+ assertEquals("gpt-5.2", options.openAI?.model)
49
+ assertEquals("/api/inderun/openai-responses", options.openAI?.endpointUrl)
50
+ }
51
+
52
+ @Test
53
+ fun `encodeTaskResult preserves canonical task result shape`() {
54
+ val encoded = IndeRunSerializer.encodeTaskResult(
55
+ TaskResult(
56
+ finishReason = FinishReason.STOP,
57
+ output = Output(text = "Hi"),
58
+ runId = "run_123",
59
+ schemaVersion = SchemaVersion.V1_0,
60
+ telemetry = TaskResultTelemetry(providerUsed = "openai", totalMs = 12.0)
61
+ )
62
+ )
63
+
64
+ assertEquals("1.0", encoded.getString("schemaVersion"))
65
+ assertEquals("stop", encoded.getString("finishReason"))
66
+ assertEquals("Hi", encoded.getJSONObject("output").getString("text"))
67
+ assertEquals("openai", encoded.getJSONObject("telemetry").getString("providerUsed"))
68
+ }
69
+
70
+ // --- Unknown enum values throw ---
71
+
72
+ @Test(expected = IllegalArgumentException::class)
73
+ fun `parseTaskRequest throws on unknown schemaVersion`() {
74
+ IndeRunSerializer.parseTaskRequest(
75
+ JSONObject("""{"schemaVersion":"9.9","task":{"kind":"text_to_text"},"prompt":"Hello"}""")
76
+ )
77
+ }
78
+
79
+ @Test(expected = IllegalArgumentException::class)
80
+ fun `parseTaskRequest throws on unknown task kind`() {
81
+ IndeRunSerializer.parseTaskRequest(
82
+ JSONObject("""{"schemaVersion":"1.0","task":{"kind":"image_to_text"},"prompt":"Hello"}""")
83
+ )
84
+ }
85
+
86
+ @Test(expected = IllegalArgumentException::class)
87
+ fun `parseTaskRequest throws on unknown cloud constraint`() {
88
+ IndeRunSerializer.parseTaskRequest(
89
+ JSONObject("""{"schemaVersion":"1.0","task":{"kind":"text_to_text"},"prompt":"Hi","constraints":{"cloud":"maybe"}}""")
90
+ )
91
+ }
92
+
93
+ @Test(expected = IllegalArgumentException::class)
94
+ fun `parseTaskRequest throws on unknown privacy constraint`() {
95
+ IndeRunSerializer.parseTaskRequest(
96
+ JSONObject("""{"schemaVersion":"1.0","task":{"kind":"text_to_text"},"prompt":"Hi","constraints":{"privacy":"some_value"}}""")
97
+ )
98
+ }
99
+
100
+ @Test(expected = IllegalArgumentException::class)
101
+ fun `parseTaskRequest throws on unknown message role`() {
102
+ IndeRunSerializer.parseTaskRequest(
103
+ JSONObject("""{"schemaVersion":"1.0","task":{"kind":"text_to_text"},"prompt":"Hi","messages":[{"role":"moderator","content":"Hi"}]}""")
104
+ )
105
+ }
106
+
107
+ @Test(expected = IllegalArgumentException::class)
108
+ fun `parseTaskRequest throws on unknown optimizeFor`() {
109
+ IndeRunSerializer.parseTaskRequest(
110
+ JSONObject("""{"schemaVersion":"1.0","task":{"kind":"text_to_text"},"prompt":"Hi","preferences":{"optimizeFor":"turbo"}}""")
111
+ )
112
+ }
113
+
114
+ @Test(expected = IllegalArgumentException::class)
115
+ fun `parseTaskRequest throws on unknown telemetry level`() {
116
+ IndeRunSerializer.parseTaskRequest(
117
+ JSONObject("""{"schemaVersion":"1.0","task":{"kind":"text_to_text"},"prompt":"Hi","telemetry":{"level":"verbose"}}""")
118
+ )
119
+ }
120
+
121
+ // --- Absent optional fields ---
122
+
123
+ @Test
124
+ fun `parseTaskRequest accepts minimal request with all optionals absent`() {
125
+ val request = IndeRunSerializer.parseTaskRequest(
126
+ JSONObject("""{"schemaVersion":"1.0","task":{"kind":"text_to_text"},"prompt":"Hi"}""")
127
+ )
128
+ assertNull(request.authContextRef)
129
+ assertNull(request.constraints)
130
+ assertNull(request.generation)
131
+ assertNull(request.messages)
132
+ assertNull(request.preferences)
133
+ assertNull(request.requestId)
134
+ assertNull(request.telemetry)
135
+ }
136
+
137
+ @Test
138
+ fun `parseConfigureOptions accepts empty object`() {
139
+ val options = IndeRunSerializer.parseConfigureOptions(JSONObject("{}"))
140
+ assertNull(options.openAI)
141
+ }
142
+
143
+ // --- encodeError ---
144
+
145
+ @Test
146
+ fun `encodeError produces correct shape with required fields only`() {
147
+ val encoded = IndeRunSerializer.encodeError(
148
+ IndeRunError(
149
+ errorClass = IndeRunErrorClass.Unavailable,
150
+ message = "Not configured."
151
+ )
152
+ )
153
+ assertEquals("1.0", encoded.getString("schemaVersion"))
154
+ assertEquals("Unavailable", encoded.getString("errorClass"))
155
+ assertEquals("Not configured.", encoded.getString("message"))
156
+ assertFalse(encoded.has("providerId"))
157
+ assertFalse(encoded.has("retryable"))
158
+ assertFalse(encoded.has("retryAfterMs"))
159
+ assertFalse(encoded.has("runId"))
160
+ }
161
+
162
+ @Test
163
+ fun `encodeError includes all optional fields when set`() {
164
+ val encoded = IndeRunSerializer.encodeError(
165
+ IndeRunError(
166
+ errorClass = IndeRunErrorClass.RateLimited,
167
+ message = "Rate limit exceeded.",
168
+ providerId = "openai",
169
+ retryable = true,
170
+ retryAfterMs = 2000L,
171
+ runId = "run_abc"
172
+ )
173
+ )
174
+ assertEquals("RateLimited", encoded.getString("errorClass"))
175
+ assertEquals("openai", encoded.getString("providerId"))
176
+ assertEquals(true, encoded.getBoolean("retryable"))
177
+ assertEquals(2000L, encoded.getLong("retryAfterMs"))
178
+ assertEquals("run_abc", encoded.getString("runId"))
179
+ }
180
+ }
@@ -0,0 +1,17 @@
1
+ import type { TaskRequest, TaskResult } from "@independo/inderun-contracts";
2
+ export interface OpenAIProviderBootstrapOptions {
3
+ model: string;
4
+ endpointUrl?: string;
5
+ auth?: "authContextRef" | "none";
6
+ authContextRef?: string;
7
+ timeoutMs?: number;
8
+ }
9
+ export interface ConfigureOptions {
10
+ openAI?: OpenAIProviderBootstrapOptions;
11
+ allowDirectOpenAIEndpoint?: boolean;
12
+ }
13
+ export interface IndeRunCapacitorPlugin {
14
+ configure(options?: ConfigureOptions): Promise<void>;
15
+ run(request: TaskRequest): Promise<TaskResult>;
16
+ }
17
+ //# sourceMappingURL=definitions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../src/definitions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAE5E,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,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;CAChD"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ import { type TaskRequest, type TaskResult } from "@independo/inderun-contracts";
2
+ import type { ConfigureOptions, IndeRunCapacitorPlugin as IndeRunCapacitorPluginContract, OpenAIProviderBootstrapOptions } from "./definitions.js";
3
+ export declare const IndeRunCapacitor: IndeRunCapacitorPluginContract;
4
+ export interface IndeRunCapacitorInstance {
5
+ run(request: TaskRequest): Promise<TaskResult>;
6
+ }
7
+ export declare function createIndeRunCapacitor(options?: ConfigureOptions): IndeRunCapacitorInstance;
8
+ export type { ConfigureOptions, IndeRunCapacitorPluginContract as IndeRunCapacitorPlugin, OpenAIProviderBootstrapOptions, TaskRequest, TaskResult };
9
+ export type * from "@independo/inderun-contracts";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,UAAU,EAChB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EACV,gBAAgB,EAChB,sBAAsB,IAAI,8BAA8B,EACxD,8BAA8B,EAC/B,MAAM,kBAAkB,CAAC;AAuB1B,eAAO,MAAM,gBAAgB,EAAE,8BAgB9B,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACvC,GAAG,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CAChD;AAED,wBAAgB,sBAAsB,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,wBAAwB,CAiB3F;AAED,YAAY,EACV,gBAAgB,EAChB,8BAA8B,IAAI,sBAAsB,EACxD,8BAA8B,EAC9B,WAAW,EACX,UAAU,EACX,CAAC;AAEF,mBAAmB,8BAA8B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,51 @@
1
+ import { validateIndeRunError } from "@independo/inderun-contracts";
2
+ import { registerPlugin } from "@capacitor/core";
3
+ const IndeRunCapacitorNative = registerPlugin("IndeRunCapacitor", {
4
+ web: () => import("./web.js").then((module) => new module.IndeRunWeb())
5
+ });
6
+ function normalizePluginError(error) {
7
+ if (validateIndeRunError(error)) {
8
+ return error;
9
+ }
10
+ if (typeof error === "object" &&
11
+ error !== null &&
12
+ "data" in error &&
13
+ validateIndeRunError(error.data)) {
14
+ return error.data;
15
+ }
16
+ return error;
17
+ }
18
+ export const IndeRunCapacitor = {
19
+ async configure(options) {
20
+ try {
21
+ await IndeRunCapacitorNative.configure(options);
22
+ }
23
+ catch (error) {
24
+ throw normalizePluginError(error);
25
+ }
26
+ },
27
+ async run(request) {
28
+ try {
29
+ return await IndeRunCapacitorNative.run(request);
30
+ }
31
+ catch (error) {
32
+ throw normalizePluginError(error);
33
+ }
34
+ }
35
+ };
36
+ export function createIndeRunCapacitor(options) {
37
+ let configured = null;
38
+ function ensureConfigured() {
39
+ configured ??= IndeRunCapacitor.configure(options).catch((error) => {
40
+ configured = null;
41
+ throw error;
42
+ });
43
+ return configured;
44
+ }
45
+ return {
46
+ async run(request) {
47
+ await ensureConfigured();
48
+ return IndeRunCapacitor.run(request);
49
+ }
50
+ };
51
+ }
package/dist/web.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ import type { TaskResult } from "@independo/inderun-contracts";
2
+ import { WebPlugin } from "@capacitor/core";
3
+ import type { ConfigureOptions, IndeRunCapacitorPlugin } from "./definitions.js";
4
+ import type { TaskRequest } from "@independo/inderun-contracts";
5
+ export declare class IndeRunWeb extends WebPlugin implements IndeRunCapacitorPlugin {
6
+ private engine;
7
+ configure(options?: ConfigureOptions): Promise<void>;
8
+ run(request: TaskRequest): Promise<TaskResult>;
9
+ }
10
+ //# sourceMappingURL=web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AACjF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAGhE,qBAAa,UAAW,SAAQ,SAAU,YAAW,sBAAsB;IACzE,OAAO,CAAC,MAAM,CAAwB;IAEhC,SAAS,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IA+BpD,GAAG,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CAarD"}