cooklang-import 0.9.7

A tool for importing recipes into Cooklang format
Documentation
# Android SDK

Native Kotlin bindings for `cooklang-import` via UniFFI.

## Installation

### GitHub Packages (Maven)

1. Add the GitHub Packages repository to `settings.gradle.kts`:

```kotlin
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()

        maven {
            name = "GitHubPackages"
            url = uri("https://maven.pkg.github.com/cooklang/cooklang-import")
            credentials {
                username = project.findProperty("gpr.user") as String?
                    ?: System.getenv("GITHUB_ACTOR")
                password = project.findProperty("gpr.key") as String?
                    ?: System.getenv("GITHUB_TOKEN")
            }
        }
    }
}
```

2. Add the dependency to `build.gradle.kts`:

```kotlin
dependencies {
    implementation("org.cooklang:cooklang-import:0.8.6")
}
```

3. Configure credentials in `~/.gradle/gradle.properties`:

```properties
gpr.user=YOUR_GITHUB_USERNAME
gpr.key=YOUR_GITHUB_TOKEN
```

> **Note:** You need a GitHub personal access token with `read:packages` scope.

### Manual Installation

1. Download `cooklang-import-android.zip` from the [latest release]https://github.com/cooklang/cooklang-import/releases
2. Extract and copy the module to your project
3. Add to `settings.gradle.kts`:
   ```kotlin
   include(":cooklang-import-android")
   ```
4. Add dependency:
   ```kotlin
   implementation(project(":cooklang-import-android"))
   ```

## Usage

### Simple Import (Default LLM Settings)

Uses default LLM provider from environment variables (e.g., `OPENAI_API_KEY`).

```kotlin
import org.cooklang.import.*

suspend fun importRecipe(url: String): String {
    return simpleImport(url)
}
```

### Import with Custom LLM Configuration

```kotlin
suspend fun importWithLlm(url: String, apiKey: String): String {
    val config = FfiImportConfig(
        provider = FfiLlmProvider.ANTHROPIC,
        apiKey = apiKey,
        model = null,  // Uses default model
        timeoutSeconds = 30u,
        extractOnly = false
    )

    return importFromUrl(url, config)
}
```

### Extract Recipe Without Conversion (No LLM Required)

```kotlin
suspend fun extractOnly(url: String): String {
    val config = FfiImportConfig(
        provider = null,
        apiKey = null,
        model = null,
        timeoutSeconds = 30u,
        extractOnly = true
    )

    return importFromUrl(url, config)
    // Returns structured recipe data without Cooklang conversion
}
```

### Convert Plain Text

```kotlin
suspend fun convertText(text: String, apiKey: String): String {
    val config = FfiImportConfig(
        provider = FfiLlmProvider.OPENAI,
        apiKey = apiKey,
        model = "gpt-4.1-mini",
        timeoutSeconds = 30u,
        extractOnly = false
    )

    return importFromText(text, config)
}
```

## Jetpack Compose Example

```kotlin
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.launch
import org.cooklang.import.*

@Composable
fun RecipeImportScreen() {
    var url by remember { mutableStateOf("") }
    var result by remember { mutableStateOf("") }
    var isLoading by remember { mutableStateOf(false) }
    var error by remember { mutableStateOf<String?>(null) }

    val scope = rememberCoroutineScope()

    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp),
        verticalArrangement = Arrangement.spacedBy(16.dp)
    ) {
        OutlinedTextField(
            value = url,
            onValueChange = { url = it },
            label = { Text("Recipe URL") },
            modifier = Modifier.fillMaxWidth()
        )

        Button(
            onClick = {
                scope.launch {
                    isLoading = true
                    error = null
                    try {
                        result = simpleImport(url)
                    } catch (e: Exception) {
                        error = e.message
                    }
                    isLoading = false
                }
            },
            enabled = !isLoading && url.isNotBlank(),
            modifier = Modifier.fillMaxWidth()
        ) {
            if (isLoading) {
                CircularProgressIndicator(
                    modifier = Modifier.size(20.dp),
                    strokeWidth = 2.dp
                )
            } else {
                Text("Import Recipe")
            }
        }

        error?.let {
            Text(
                text = it,
                color = MaterialTheme.colorScheme.error
            )
        }

        Text(
            text = result,
            style = MaterialTheme.typography.bodyMedium,
            fontFamily = androidx.compose.ui.text.font.FontFamily.Monospace
        )
    }
}
```

## Available Providers

```kotlin
enum class FfiLlmProvider {
    OPENAI,       // Requires OPENAI_API_KEY or apiKey parameter
    ANTHROPIC,    // Requires ANTHROPIC_API_KEY or apiKey parameter
    GOOGLE,       // Requires GOOGLE_API_KEY or apiKey parameter
    AZURE_OPENAI, // Requires additional Azure configuration
    OLLAMA        // Local models via Ollama
}
```

## Error Handling

```kotlin
try {
    val result = simpleImport(url)
} catch (e: Exception) {
    println("Import failed: ${e.message}")
}
```

## ProGuard Rules

The library includes consumer rules automatically. If manual configuration is needed:

```proguard
-keep class org.cooklang.** { *; }
-keep class com.sun.jna.** { *; }
-keepclassmembers class * extends com.sun.jna.** { public *; }
```

## Building from Source

```bash
./scripts/build-android.sh
```

Output in `target/android/`:
- `cooklang-import-android/` - Android library module
- `jniLibs/` - Native libraries for all architectures
- `kotlin/` - Kotlin binding files

### Supported Architectures

- arm64-v8a (64-bit ARM)
- armeabi-v7a (32-bit ARM)
- x86_64 (64-bit x86)