Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ tasks.register("runDebugUnitTest") {
dependsOn(":instantsearch:testDebugUnitTest")
dependsOn(":instantsearch-insights:testDebugUnitTest")
dependsOn(":instantsearch-compose:testDebugUnitTest")
dependsOn(":instantsearch-agent:jvmTest")
dependsOn(":extensions:android-paging3:testDebugUnitTest")
dependsOn(":extensions:android-loading:testDebugUnitTest")
dependsOn(":extensions:coroutines-extensions:jvmTest")
Expand Down
3 changes: 3 additions & 0 deletions examples/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ dependencies {
implementation project(":extensions:android-paging3")
//implementation "com.algolia:instantsearch-android-loading:$instantsearch"
implementation project(":extensions:android-loading")
// Experimental, standalone agent SDK (versioned independently, 0.x).
implementation project(":instantsearch-agent")
implementation "com.algolia.instantsearch:voice:1.1.0"

implementation "androidx.fragment:fragment-ktx:1.5.4"
Expand Down Expand Up @@ -91,6 +93,7 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
'-Xopt-in=com.algolia.instantsearch.ExperimentalInstantSearch',
'-Xopt-in=androidx.compose.material.ExperimentalMaterialApi',
'-opt-in=kotlinx.serialization.InternalSerializationApi',
'-opt-in=com.algolia.instantsearch.agent.ExperimentalAgentStudioApi',
]
}
}
6 changes: 6 additions & 0 deletions examples/android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,12 @@
android:name=".showcase.compose.filter.facet.DynamicFacetShowcase"
android:parentActivityName=".showcase.compose.directory.ComposeDirectoryShowcase" />

<!-- Agent Studio (experimental) -->

<activity
android:name=".showcase.compose.agent.AgentStudioShowcase"
android:parentActivityName=".directory.DirectoryActivity" />

<!-- Showcase: shared -->

<activity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import com.algolia.instantsearch.examples.android.guides.compose.ComposeActivity
import com.algolia.instantsearch.examples.android.guides.gettingstarted.GettingStartedGuide
import com.algolia.instantsearch.examples.android.guides.insights.InsightsActivity
import com.algolia.instantsearch.examples.android.showcase.androidview.directory.AndroidViewDirectoryShowcase
import com.algolia.instantsearch.examples.android.showcase.compose.agent.AgentStudioShowcase
import com.algolia.instantsearch.examples.android.showcase.compose.directory.ComposeDirectoryShowcase
import com.algolia.search.helper.deserialize
import kotlin.reflect.KClass
Expand All @@ -36,6 +37,18 @@ val guides = mapOf(
"codex_voice_search" to VoiceSearchCodex::class,
)

/**
* Static entries that are not backed by the `mobile_demos` Algolia index.
* Appended after the index-driven showcases so they always render last.
*/
private val experimentalItems = listOf(
DirectoryItem.Header("Experimental"),
DirectoryItem.Item(
DirectoryHit(objectID = "experimental_agentic_experience", name = "Agentic Experience", type = "Experimental"),
AgentStudioShowcase::class,
),
)

internal fun directoryItems(response: SearchResponse, mappings: Map<String, KClass<out ComponentActivity>>) =
response.hits.deserialize(DirectoryHit.serializer())
.filter { mappings.containsKey(it.objectID) }
Expand All @@ -44,7 +57,7 @@ internal fun directoryItems(response: SearchResponse, mappings: Map<String, KCla
.flatMap { (key, value) ->
listOf(DirectoryItem.Header(key)) + value.map { DirectoryItem.Item(it, mappings.getValue(it.objectID)) }
.sortedBy { it.hit.objectID }
}
} + experimentalItems

internal fun Context.navigateTo(item: DirectoryItem.Item) {
val intent = Intent(this, item.dest.java).apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class DirectoryActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_directory)

connection += connector.connectView(SearchBoxViewAppCompat(findViewById(R.id.searchView)))

val adapter = DirectoryAdapter()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.algolia.instantsearch.examples.android.showcase.compose.agent

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.algolia.instantsearch.agent.chat.ChatStore
import com.algolia.instantsearch.agent.transport.AgentStudioTransport

/**
* Owns the [ChatStore] for the Agent Studio showcase.
*
* Reuses the same Agent Studio showcase config that ships with the InstantSearch
* web examples (`examples/js/showcase`), so the demo works out of the box.
* In a real app, pass a **search-only** API key — never an admin key.
*/
class AgentChatViewModel : ViewModel() {

val store: ChatStore = run {
val transport = AgentStudioTransport.fromCredentials(
appId = APP_ID,
apiKey = SEARCH_API_KEY,
agentId = AGENT_ID,
)
ChatStore(transport = transport, scope = viewModelScope)
}

fun send(text: String) = store.send(text)

fun stop() = store.stop()

override fun onCleared() {
super.onCleared()
store.stop()
}

private companion object {
const val APP_ID = "latency"
const val SEARCH_API_KEY = "6be0576ff61c053d5f9a3225e2a90f76"
const val AGENT_ID = "eedef238-5468-470d-bc37-f99fa741bd25"
}
}
Loading
Loading