Skip to content

Expose AppFunctions for TMDB search and watchlist mutations#18

Open
odaridavid wants to merge 2 commits into
mainfrom
appfunctions-integration
Open

Expose AppFunctions for TMDB search and watchlist mutations#18
odaridavid wants to merge 2 commits into
mainfrom
appfunctions-integration

Conversation

@odaridavid

Copy link
Copy Markdown
Owner

Summary

  • Adds an Android 16+ AppFunctions surface so Gemini / Routines can search TMDB and mutate the on-device watchlist without opening the app.
  • Five functions: searchMovies, searchTvShows, listWatchlist, addToWatchlist, removeFromWatchlist. addToWatchlist is idempotent (it checks the current list before delegating to ToggleWatchlistUseCase, which would otherwise remove an existing entry).
  • All functions are wired to existing common use cases via Koin; KMP shape is preserved (only androidMain knows about AppFunctions).

Changes

  • gradle/libs.versions.toml: android-compileSdk 36→37; add androidx.appfunctions 1.0.0-alpha02 + three aliases.
  • composeApp/build.gradle.kts: deps on androidx.appfunctions{,-service}, kspAndroid compiler, ksp { arg("appfunctions:aggregateAppFunctions", "true") }.
  • composeApp/src/androidMain/res/xml/app_metadata.xml: capability + operational-pattern description for agents.
  • AndroidManifest.xml: <property android:name="android.app.appfunctions.app_metadata" .../>.
  • appfunctions/SmoovieAppFunctions.kt (new): five @AppFunction methods + SmoovieTitle / SmoovieSearchPage @AppFunctionSerializable types with inline KDoc per property.
  • PlatformModule.android.kt: Koin single for SmoovieAppFunctions.
  • SmoovieApplication: implements AppFunctionConfiguration.Provider, resolves the class via KoinPlatform.getKoin().

Notes

  • For alpha02: @AppFunction / AppFunctionConfiguration live under androidx.appfunctions.service, and isDescribedByKDoc = true (referenced in the official docs) was removed — KDoc is now always parsed.
  • MediaType is exposed as a String ("movie" / "tv") to match TMDB conventions and stay within @AppFunctionSerializable-supported types.
  • AGP 8.13.2 prints a non-fatal "tested up to compile SDK 36.1" warning against compileSdk = 37. Suppressible via android.suppressUnsupportedCompileSdk=37.0 in gradle.properties if noisy.

Test plan

  • ./gradlew :composeApp:compileDebugKotlinAndroid (green locally)
  • ./gradlew :composeApp:compileCommonMainKotlinMetadata + compileKotlinIosSimulatorArm64 (KMP didn't regress; green locally)
  • ./gradlew :composeApp:ktlintCheck (green locally)
  • Install debug build on an Android 16+ device with App Check debug token registered
  • adb shell cmd app_function list-app-functions | grep dev.odaridavid.smoovie — confirm all five functions register
  • adb shell cmd app_function execute-app-function --package dev.odaridavid.smoovie --function "<searchMovies id>" --parameters '{"query":"Dune","page":1}' — returns titles
  • Repeat for addToWatchlist with a tmdbId from the search; open the Watchlist tab — entry should appear
  • Repeat invocation of addToWatchlist with same tmdbId — no duplicate (idempotency)
  • removeFromWatchlist — entry disappears from the Watchlist tab
  • If on Android 17 with Gemini AppFunctions enabled: try a natural-language voice command like "add Dune Part Two to my Smoovie watchlist" — confirm the right function is matched

🤖 Generated with Claude Code

Wires Smoovie into the Android 16+ AppFunctions surface so system agents
(Gemini, Routines) can search TMDB and mutate the on-device watchlist
without opening the app.

- Bump compileSdk to 37; add androidx.appfunctions alpha02 + KSP compiler
- Register app_metadata.xml describing the function-discovery contract
- Implement SmoovieAppFunctions in androidMain wired to existing
  search/watchlist use cases via Koin; addToWatchlist is idempotent
- Make SmoovieApplication an AppFunctionConfiguration.Provider

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@odaridavid odaridavid self-assigned this May 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant