AI Assistant Multiple Documents: DocumentCoordinator
Example demonstrating AI chat for multiple documents analysis and interaction using DocumentCoordinator. You must also run the AI Assistant demo server on your Machine.
/* * Copyright © 2025-2026 PSPDFKit GmbH. All rights reserved. * * The PSPDFKit Sample applications are licensed with a modified BSD license. * Please see License for details. This notice may not be removed from this file. */
package com.pspdfkit.catalog.examples.kotlin
import android.content.Contextimport android.graphics.RectFimport android.net.Uriimport android.os.Bundleimport com.pspdfkit.catalog.Rimport com.pspdfkit.catalog.SdkExampleimport com.pspdfkit.catalog.SdkExample.Companion.WELCOME_DOCimport com.pspdfkit.catalog.examples.kotlin.AiAssistantComposeActivity.Companion.PREFERENCES_NAMEimport com.pspdfkit.catalog.examples.kotlin.AiAssistantComposeActivity.Companion.PREF_AI_IP_ADDRESSimport com.pspdfkit.catalog.tasks.ExtractAssetTask.extractAsyncimport com.pspdfkit.catalog.utils.JwtGeneratorimport com.pspdfkit.configuration.activity.PdfActivityConfigurationimport com.pspdfkit.ui.DocumentDescriptorimport com.pspdfkit.ui.PdfActivityimport com.pspdfkit.ui.PdfActivityIntentBuilderimport io.nutrient.domain.ai.AiAssistantimport io.nutrient.domain.ai.AiAssistantProviderimport io.reactivex.rxjava3.android.schedulers.AndroidSchedulersimport io.reactivex.rxjava3.core.Observableimport kotlinx.coroutines.CoroutineScopeimport kotlinx.coroutines.Dispatchersimport kotlinx.coroutines.launch
/** * Shows how to implement AI Assistant chat supporting multiple tabbed documents analysis and interaction. */class AiAssistantDocumentTabsExample(context: Context) : SdkExample(context, R.string.aiAssistantTabbedDocumentExampleTitle, R.string.aiAssistantTabbedDocumentExampleDescription) {
override fun launchExample(context: Context, configuration: PdfActivityConfiguration.Builder) { configuration.setAiAssistantEnabled(true)
Observable.fromIterable(AiAssistantDocumentTabsActivity.assetFiles) .flatMapSingle { assetName -> extractAsync(assetName, assetName, context, false, null) } .map { file -> DocumentDescriptor.fromUri(Uri.fromFile(file)) } .toList() .observeOn(AndroidSchedulers.mainThread()) .doOnSuccess { documentDescriptors -> launchExampleActivity(context, documentDescriptors, configuration) }.subscribe() }
private fun launchExampleActivity(context: Context, documentDescriptors: List<DocumentDescriptor>, configuration: PdfActivityConfiguration.Builder) { val intentBuilder = if (documentDescriptors.isEmpty()) { PdfActivityIntentBuilder.emptyActivity(context) } else { PdfActivityIntentBuilder.fromDocumentDescriptor(context, *documentDescriptors.toTypedArray()) } intentBuilder .configuration(configuration.build()) .activityClass(AiAssistantDocumentTabsActivity::class.java)
context.startActivity(intentBuilder.build()) }}
class AiAssistantDocumentTabsActivity : PdfActivity(), AiAssistantProvider {
var ipAddressValue = "" private val sessionId = AiAssistantDocumentTabsActivity::class.java.simpleName
companion object { val assetFiles = listOf("Classbook.pdf", WELCOME_DOC, "Aviation.pdf", "Annotations.pdf") }
var assistant: AiAssistant? = null
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val preferences = getSharedPreferences(PREFERENCES_NAME, MODE_PRIVATE) ipAddressValue = preferences.getString(PREF_AI_IP_ADDRESS, "") ?: "" assistant = getAiAssistant() CoroutineScope(Dispatchers.IO).launch { // ingesting the documents as soon as the activity is created assistant?.initialize(false) } }
fun getAiAssistantInstance() = com.pspdfkit.ai.createAiAssistant( context = this, documentsDescriptors = documentCoordinator.documents, serverUrl = "http://$ipAddressValue:4000", sessionId = sessionId, jwtToken = { documentIds -> JwtGenerator.generateJwtToken( this@AiAssistantDocumentTabsActivity, claims = mapOf( "document_ids" to documentIds, "session_ids" to listOf(sessionId), "request_limit" to mapOf( "requests" to 160, "time_period_s" to 1000 * 60 * 10 ) ) ) } )
override fun getAiAssistant(): AiAssistant { return assistant ?: getAiAssistantInstance().also { assistant = it } }
override fun navigateTo( documentRect: List<RectF>, pageIndex: Int, documentIndex: Int ) { val descriptor = documentCoordinator.getDocuments()[documentIndex] documentCoordinator.setVisibleDocument(descriptor) pdfFragment?.highlight(this@AiAssistantDocumentTabsActivity, documentRect, pageIndex) }}This code sample is an example that illustrates how to use our SDK. Please adapt it to your specific use case.