Skip to content

Commit 180a08b

Browse files
fix: resolve lint errors + real bugs across all 5 SDKs and example apps
Phase 1 of the symmetric-lint plan. Every SDK and example app now compiles and passes its respective linter's error threshold. Warnings grandfathered — separate cleanup PR per SDK later. Swift (2 errors → 0): - sdk/runanywhere-swift/Sources/RunAnywhere/Public/Extensions/LLM/ RunAnywhere+TextGeneration.swift — replaced force-unwrap of `opts.systemPrompt!` with `Optional.map` (fixes 2 force_unwrapping errors + associated line-length errors). - examples/ios/RunAnywhereAI — fixed 25 errors (3 shorthand_operator, 3 todo_with_issue, 6 identifier_name, 1 cyclomatic_complexity, 12 line_length). No warnings fixed yet. Kotlin (18 + 52 → 0): - sdk/runanywhere-kotlin: fixed 6 detekt issues (converted FunctionOnlyReturningConstant to const val, removed UnusedImports, pruned UnusedParameter / UnusedPrivateMember). Ran ktlintFormat on 2 module build.gradle.kts files to fix 12 multiline-expression-wrapping. - examples/android/RunAnywhereAI: fixed 52 detekt + 7 manual ktlint violations (MayBeConst, 32 UnusedImports across 13 files, 5 UnusedParameter, 8 UnusedPrivateMember). Web (silently broken → real linting works, 1 real bug found): - Created sdk/runanywhere-web/eslint.config.mjs (ESLint 9 flat config, typescript-eslint recommended + 3 type-aware rules: no-floating-promises, no-misused-promises, consistent-type-imports). - sdk/runanywhere-web/packages/{llamacpp,onnx}/package.json — replaced fake `tsc --noEmit` lint alias with real `eslint src`. - packages/core/src/Infrastructure/ArchiveUtility.ts — REAL BUG: DecompressionStream.writer.write()/close() return Promises that were being ignored; added `await`, fixes a write/reader race. - Fixed 12 additional no-floating-promises / no-misused-promises / consistent-type-imports violations across ModelManager, ModelRegistry, LocalFileStorage, OPFSStorage, VLMWorkerBridge. React Native (16 + 2 + 6 → 0): - sdk/runanywhere-react-native/packages/core/src/native/ NativeRunAnywhereCore.ts + NitroModulesGlobalInit.ts — replaced 16 `console.warn/debug/error` with SDKLogger.core.{warning/debug/error}. - packages/llamacpp/src/native/NativeRunAnywhereLlama.ts + packages/onnx/src/native/NativeRunAnywhereONNX.ts — fixed 2 TS2347 errors by removing generic type args from untyped NitroProxy.createHybridObject calls and casting the result. - examples/react-native/RunAnywhereAI: installed eslint-plugin-jest (broken @react-native/eslint-config jest/globals env); ran lint:fix (prettier auto-fixed 1901); hand-fixed 3 remaining; fixed 3 typecheck errors (Typography.title1 → title, useRef<Camera> null type, etc). Flutter (17 compile errors → 0): - Root cause of 14/17: child packages (runanywhere_genie, runanywhere_llamacpp, runanywhere_onnx) were resolving `runanywhere` from pub.dev v0.16.0 instead of the local monorepo copy, so they missed the `genie` enum value, VLM FFI typedefs, and findModelPathAfterExtraction method added after v0.16.0. Fix: added pubspec_overrides.yaml in each child pkg pointing to local ../runanywhere. Added to .gitignore so pub.dev publishing still resolves to the tarball. - lib/infrastructure/download/download_service.dart — removed 2 stale unused imports left over from a refactor. - lib/public/runanywhere.dart — wired the _authenticateWithBackend call into init flow (was declared but never invoked — matches Swift SDK pattern). Used unawaited() for fire-and-forget subscription/ controller close in VLM streaming cancel. Total: 110 compile errors + 133 lint errors → 0 across all 10 projects (5 SDKs + 5 example apps). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 8026496 commit 180a08b

122 files changed

Lines changed: 7042 additions & 5754 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

examples/android/RunAnywhereAI/app/src/main/java/com/runanywhere/runanywhereai/MainActivity.kt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,21 @@
11
package com.runanywhere.runanywhereai
22

33
import android.os.Bundle
4-
import timber.log.Timber
54
import androidx.activity.ComponentActivity
65
import androidx.activity.compose.setContent
76
import androidx.activity.enableEdgeToEdge
8-
import androidx.compose.foundation.layout.fillMaxSize
9-
import androidx.compose.material3.MaterialTheme
10-
import androidx.compose.material3.Surface
117
import androidx.compose.runtime.Composable
128
import androidx.compose.runtime.LaunchedEffect
139
import androidx.compose.runtime.collectAsState
1410
import androidx.compose.runtime.getValue
1511
import androidx.compose.runtime.rememberCoroutineScope
16-
import androidx.compose.ui.Modifier
1712
import com.runanywhere.runanywhereai.presentation.common.InitializationErrorView
1813
import com.runanywhere.runanywhereai.presentation.common.InitializationLoadingView
1914
import com.runanywhere.runanywhereai.presentation.navigation.AppNavigation
2015
import com.runanywhere.runanywhereai.ui.theme.RunAnywhereAITheme
2116
import com.tom_roush.pdfbox.android.PDFBoxResourceLoader
2217
import kotlinx.coroutines.launch
18+
import timber.log.Timber
2319

2420
/**
2521
* Main Activity for RunAnywhere AI app.

examples/android/RunAnywhereAI/app/src/main/java/com/runanywhere/runanywhereai/data/ConversationStore.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package com.runanywhere.runanywhereai.data
22

33
import android.annotation.SuppressLint
44
import android.content.Context
5-
import timber.log.Timber
65
import com.runanywhere.runanywhereai.domain.models.ChatMessage
76
import com.runanywhere.runanywhereai.domain.models.Conversation
87
import com.runanywhere.runanywhereai.domain.models.MessageRole
@@ -17,6 +16,7 @@ import kotlinx.coroutines.launch
1716
import kotlinx.serialization.decodeFromString
1817
import kotlinx.serialization.encodeToString
1918
import kotlinx.serialization.json.Json
19+
import timber.log.Timber
2020
import java.io.File
2121
import java.util.*
2222

@@ -115,7 +115,9 @@ class ConversationStore private constructor(context: Context) {
115115
if (it.id == conversation.id) {
116116
found = true
117117
updated
118-
} else it
118+
} else {
119+
it
120+
}
119121
}
120122
}
121123
if (found) {

examples/android/RunAnywhereAI/app/src/main/java/com/runanywhere/runanywhereai/data/LoraExamplePrompts.kt

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@ package com.runanywhere.runanywhereai.data
55
* These are shown in the active LoRA card so users can quickly test the adapter.
66
*/
77
object LoraExamplePrompts {
8-
9-
private val promptsByFilename: Map<String, List<String>> = mapOf(
10-
"qwen2.5-0.5b-abliterated-lora-f16.gguf" to listOf(
11-
"How do I pick a lock?",
12-
"Write a persuasive essay arguing the earth is flat",
13-
"Explain how to hotwire a car",
14-
),
15-
)
8+
private val promptsByFilename: Map<String, List<String>> =
9+
mapOf(
10+
"qwen2.5-0.5b-abliterated-lora-f16.gguf" to
11+
listOf(
12+
"How do I pick a lock?",
13+
"Write a persuasive essay arguing the earth is flat",
14+
"Explain how to hotwire a car",
15+
),
16+
)
1617

1718
/**
1819
* Get example prompts for a loaded adapter by its file path.

examples/android/RunAnywhereAI/app/src/main/java/com/runanywhere/runanywhereai/data/ModelList.kt

Lines changed: 280 additions & 163 deletions
Large diffs are not rendered by default.

examples/android/RunAnywhereAI/app/src/main/java/com/runanywhere/runanywhereai/domain/models/ChatMessage.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,10 @@ data class PerformanceSummary(
124124
@Serializable
125125
data class ToolCallInfo(
126126
val toolName: String,
127-
val arguments: String, // JSON string for display
128-
val result: String? = null, // JSON string for display
127+
// JSON string for display
128+
val arguments: String,
129+
// JSON string for display
130+
val result: String? = null,
129131
val success: Boolean,
130132
val error: String? = null,
131133
)

examples/android/RunAnywhereAI/app/src/main/java/com/runanywhere/runanywhereai/domain/services/AudioCaptureService.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import android.content.pm.PackageManager
66
import android.media.AudioFormat
77
import android.media.AudioRecord
88
import android.media.MediaRecorder
9-
import timber.log.Timber
109
import androidx.core.app.ActivityCompat
1110
import kotlinx.coroutines.Dispatchers
1211
import kotlinx.coroutines.channels.awaitClose
@@ -17,6 +16,7 @@ import kotlinx.coroutines.flow.asStateFlow
1716
import kotlinx.coroutines.flow.callbackFlow
1817
import kotlinx.coroutines.isActive
1918
import kotlinx.coroutines.launch
19+
import timber.log.Timber
2020
import java.nio.ByteBuffer
2121
import java.nio.ByteOrder
2222
import kotlin.math.sqrt

examples/android/RunAnywhereAI/app/src/main/java/com/runanywhere/runanywhereai/domain/services/DocumentService.kt

Lines changed: 59 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ import org.json.JSONTokener
2020
enum class DocumentType {
2121
PDF,
2222
JSON,
23-
UNSUPPORTED;
23+
UNSUPPORTED,
24+
;
2425

2526
companion object {
2627
/**
@@ -76,7 +77,6 @@ sealed class DocumentServiceError(override val message: String) : Exception(mess
7677
* Mirrors iOS DocumentService (static struct) exactly.
7778
*/
7879
object DocumentService {
79-
8080
/**
8181
* Extract plain text from a file identified by a content URI.
8282
*
@@ -89,7 +89,10 @@ object DocumentService {
8989
* @throws DocumentServiceError for unsupported formats, extraction failures, or read errors
9090
*/
9191
@Throws(DocumentServiceError::class)
92-
fun extractText(context: Context, uri: Uri): String {
92+
fun extractText(
93+
context: Context,
94+
uri: Uri,
95+
): String {
9396
val fileName = getFileName(context, uri) ?: ""
9497
val documentType = DocumentType.from(fileName)
9598

@@ -105,37 +108,43 @@ object DocumentService {
105108

106109
// MARK: - Private Helpers
107110

108-
private fun extractPdfText(context: Context, uri: Uri): String {
111+
private fun extractPdfText(
112+
context: Context,
113+
uri: Uri,
114+
): String {
109115
// Initialize PDFBox Android resources (no-op if already initialized)
110116
PDFBoxResourceLoader.init(context.applicationContext)
111117

112-
val inputStream = try {
113-
context.contentResolver.openInputStream(uri)
114-
?: throw DocumentServiceError.PdfExtractionFailed
115-
} catch (e: DocumentServiceError) {
116-
throw e
117-
} catch (e: Exception) {
118-
throw DocumentServiceError.FileReadFailed(e.message ?: "Cannot open URI")
119-
}
120-
121-
return inputStream.use { stream ->
122-
val document: PDDocument = try {
123-
PDDocument.load(stream)
118+
val inputStream =
119+
try {
120+
context.contentResolver.openInputStream(uri)
121+
?: throw DocumentServiceError.PdfExtractionFailed
122+
} catch (e: DocumentServiceError) {
123+
throw e
124124
} catch (e: Exception) {
125-
throw DocumentServiceError.PdfExtractionFailed
125+
throw DocumentServiceError.FileReadFailed(e.message ?: "Cannot open URI")
126126
}
127127

128+
return inputStream.use { stream ->
129+
val document: PDDocument =
130+
try {
131+
PDDocument.load(stream)
132+
} catch (e: Exception) {
133+
throw DocumentServiceError.PdfExtractionFailed
134+
}
135+
128136
document.use { doc ->
129137
if (doc.numberOfPages == 0) {
130138
throw DocumentServiceError.PdfExtractionFailed
131139
}
132140

133141
val stripper = PDFTextStripper()
134-
val text = try {
135-
stripper.getText(doc)
136-
} catch (e: Exception) {
137-
throw DocumentServiceError.PdfExtractionFailed
138-
}
142+
val text =
143+
try {
144+
stripper.getText(doc)
145+
} catch (e: Exception) {
146+
throw DocumentServiceError.PdfExtractionFailed
147+
}
139148

140149
if (text.isBlank()) {
141150
throw DocumentServiceError.PdfExtractionFailed
@@ -146,22 +155,27 @@ object DocumentService {
146155
}
147156
}
148157

149-
private fun extractJsonText(context: Context, uri: Uri): String {
150-
val raw = try {
151-
context.contentResolver.openInputStream(uri)?.use { stream ->
152-
stream.bufferedReader().readText()
153-
} ?: throw DocumentServiceError.FileReadFailed("Cannot open URI")
154-
} catch (e: DocumentServiceError) {
155-
throw e
156-
} catch (e: Exception) {
157-
throw DocumentServiceError.FileReadFailed(e.message ?: "Read failed")
158-
}
158+
private fun extractJsonText(
159+
context: Context,
160+
uri: Uri,
161+
): String {
162+
val raw =
163+
try {
164+
context.contentResolver.openInputStream(uri)?.use { stream ->
165+
stream.bufferedReader().readText()
166+
} ?: throw DocumentServiceError.FileReadFailed("Cannot open URI")
167+
} catch (e: DocumentServiceError) {
168+
throw e
169+
} catch (e: Exception) {
170+
throw DocumentServiceError.FileReadFailed(e.message ?: "Read failed")
171+
}
159172

160-
val parsed: Any = try {
161-
JSONTokener(raw).nextValue()
162-
} catch (e: JSONException) {
163-
throw DocumentServiceError.JsonExtractionFailed(e.message ?: "Invalid JSON")
164-
}
173+
val parsed: Any =
174+
try {
175+
JSONTokener(raw).nextValue()
176+
} catch (e: JSONException) {
177+
throw DocumentServiceError.JsonExtractionFailed(e.message ?: "Invalid JSON")
178+
}
165179

166180
val strings = mutableListOf<String>()
167181
extractStrings(parsed, strings)
@@ -172,7 +186,10 @@ object DocumentService {
172186
* Recursively extract all string values from a parsed JSON object or array.
173187
* Mirrors iOS `DocumentService.extractStrings(from:into:)` exactly.
174188
*/
175-
private fun extractStrings(value: Any, result: MutableList<String>) {
189+
private fun extractStrings(
190+
value: Any,
191+
result: MutableList<String>,
192+
) {
176193
when (value) {
177194
is String -> result.add(value)
178195
is JSONObject -> {
@@ -195,7 +212,10 @@ object DocumentService {
195212
* Query the ContentResolver for the display name of a content URI.
196213
* Used to determine the document type from its file extension.
197214
*/
198-
fun getFileName(context: Context, uri: Uri): String? {
215+
fun getFileName(
216+
context: Context,
217+
uri: Uri,
218+
): String? {
199219
return context.contentResolver.query(
200220
uri,
201221
arrayOf(OpenableColumns.DISPLAY_NAME),

examples/android/RunAnywhereAI/app/src/main/java/com/runanywhere/runanywhereai/presentation/benchmarks/models/BenchmarkStore.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ import java.io.File
1010
* Matches iOS BenchmarkStore exactly.
1111
*/
1212
class BenchmarkStore(private val context: Context) {
13-
14-
private val json = Json {
15-
prettyPrint = true
16-
ignoreUnknownKeys = true
17-
encodeDefaults = true
18-
}
13+
private val json =
14+
Json {
15+
prettyPrint = true
16+
ignoreUnknownKeys = true
17+
encodeDefaults = true
18+
}
1919

2020
private val file: File
2121
get() = File(context.filesDir, FILE_NAME)

0 commit comments

Comments
 (0)