Skip to content
Open
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
2 changes: 1 addition & 1 deletion ChatApp/gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[versions]
agp = "9.3.1"
appfunctions = "1.0.0-alpha10"
appfunctions = "1.0.0-SNAPSHOT"
kotlin = "2.4.10"
coreKtx = "1.19.0"
junit = "4.13.2"
Expand Down
6 changes: 6 additions & 0 deletions ChatApp/settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
*/
pluginManagement {
repositories {
maven {
url = uri("https://androidx.dev/snapshots/builds/16181473/artifacts/repository")
}
google {
content {
includeGroupByRegex("com\\.android.*")
Expand All @@ -29,6 +32,9 @@ pluginManagement {
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
maven {
url = uri("https://androidx.dev/snapshots/builds/16181473/artifacts/repository")
}
google()
mavenCentral()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package com.example.chatapp.appfunctions

import android.app.PendingIntent
import android.content.ContentResolver
import android.content.Intent
import android.net.Uri
import androidx.annotation.RequiresApi
Expand All @@ -26,6 +27,7 @@ import androidx.appfunctions.AppFunctionInvalidArgumentException
import androidx.appfunctions.AppFunctionService
import androidx.appfunctions.AppFunctionServiceEntryPoint
import androidx.appfunctions.AppFunctionStringValueConstraint
import androidx.appfunctions.AppFunctionUriValueConstraint
import com.example.chatapp.data.CallManager
import com.example.chatapp.data.DisplayMessage
import com.example.chatapp.data.MessageRepository
Expand Down Expand Up @@ -184,6 +186,7 @@ abstract class BaseChatAppFunctionService : AppFunctionService() {
@AppFunction(isDescribedByKDoc = true)
suspend fun updateChatWallpaper(
chatId: String,
@AppFunctionUriValueConstraint(allowedSchemes = [ContentResolver.SCHEME_CONTENT])
wallpaperUri: Uri,
): Boolean {
val resolvedId =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ class GeminiToolConverter
is AppFunctionStringTypeMetadata ->
buildJsonObject {
put(KEY_TYPE, JsonPrimitive(VALUE_STRING))
if (isFileReferenceParameter(parameterName)) {
if (dataType.format == AppFunctionStringTypeMetadata.FORMAT_URI || dataType.format == "uri") {
put(KEY_FORMAT, JsonPrimitive(VALUE_FILE_REFERENCE))
}
val enumValues = dataType.enumValues
Expand Down Expand Up @@ -261,13 +261,6 @@ class GeminiToolConverter
}
}

private fun isFileReferenceParameter(parameterName: String?): Boolean {
if (parameterName == null) return false
if (parameterName in KNOWN_FILE_REFERENCE_PARAM_NAMES) return true
return parameterName.endsWith("Uri", ignoreCase = true) ||
parameterName.endsWith("Uris", ignoreCase = true)
}

companion object {
private const val TOOL_ID_SEPARATOR = "_"
private const val KEY_NAME = "name"
Expand All @@ -276,15 +269,6 @@ class GeminiToolConverter
private const val KEY_TYPE = "type"
private const val KEY_FORMAT = "format"
private const val VALUE_FILE_REFERENCE = "file_reference"
private val KNOWN_FILE_REFERENCE_PARAM_NAMES =
setOf(
"wallpaperUri",
"imageUri",
"attachmentUri",
"ringtoneUri",
"profilePictureUri",
"audioUri",
)
private const val VALUE_OBJECT = "object"
private const val KEY_PROPERTIES = "properties"
private const val KEY_REQUIRED = "required"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import androidx.appfunctions.metadata.AppFunctionMetadata
import androidx.appfunctions.metadata.AppFunctionObjectTypeMetadata
import androidx.appfunctions.metadata.AppFunctionParameterMetadata
import androidx.appfunctions.metadata.AppFunctionReferenceTypeMetadata
import androidx.appfunctions.metadata.AppFunctionStringTypeMetadata
import androidx.core.content.FileProvider
import com.example.appfunctions.agent.data.AgentInternalTools
import com.example.appfunctions.agent.data.LlmProviderName
Expand Down Expand Up @@ -549,8 +550,7 @@ class AgentOrchestrator
): Any {
return when (value) {
is String -> {
val shouldResolve =
isFileReferenceParameter(paramName) || isUriMetadata(dataType)
val shouldResolve = isUriMetadata(dataType)
if (shouldResolve && (
value.startsWith(
"http://",
Expand Down Expand Up @@ -661,16 +661,19 @@ class AgentOrchestrator
}
}

private fun isFileReferenceParameter(parameterName: String?): Boolean {
if (parameterName == null) return false
if (parameterName in KNOWN_FILE_REFERENCE_PARAM_NAMES) return true
return parameterName.endsWith("Uri", ignoreCase = true) ||
parameterName.endsWith("Uris", ignoreCase = true)
}

private fun isUriMetadata(dataType: AppFunctionDataTypeMetadata?): Boolean {
if (dataType == null) return false
if (dataType is AppFunctionObjectTypeMetadata && dataType.qualifiedName == "android.net.Uri") return true
if (dataType is AppFunctionObjectTypeMetadata && dataType.qualifiedName == "android.net.Uri") {
val innerProp = dataType.properties["uri"] as? AppFunctionStringTypeMetadata
val pattern = innerProp?.pattern
return pattern == null || pattern.contains("content") || innerProp?.format == AppFunctionStringTypeMetadata.FORMAT_URI
}
if (dataType is AppFunctionStringTypeMetadata) {
val pattern = dataType.pattern
return (pattern != null && pattern.contains("content")) ||
dataType.format == AppFunctionStringTypeMetadata.FORMAT_URI ||
dataType.format == "uri"
}
if (dataType is AppFunctionReferenceTypeMetadata && dataType.referenceDataType == "android.net.Uri") return true
return false
}
Expand Down Expand Up @@ -719,17 +722,4 @@ class AgentOrchestrator
}
}
}

companion object {
private val KNOWN_FILE_REFERENCE_PARAM_NAMES =
setOf(
"wallpaperUri",
"imageUri",
"attachmentUri",
"ringtoneUri",
"profilePictureUri",
"audioUri",
"voiceNoteUri",
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -410,12 +410,16 @@ class GeminiToolConverterTest {
}

@Test
fun convert_stringParameterEndingWithUri_injectsFileReferenceFormat() {
fun convert_stringParameterWithUriFormat_injectsFileReferenceFormat() {
val parameter =
AppFunctionParameterMetadata(
name = "wallpaperUri",
isRequired = true,
dataType = AppFunctionStringTypeMetadata(isNullable = false),
dataType =
AppFunctionStringTypeMetadata(
isNullable = false,
format = AppFunctionStringTypeMetadata.FORMAT_URI,
),
description = "A URI parameter",
)
val tool =
Expand Down
2 changes: 1 addition & 1 deletion agent/gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ mockk = "1.14.11"
ksp = "2.3.10"
hilt = "2.60.1"
androidxHiltNavigationCompose = "1.4.0"
appfunctions = "1.0.0-alpha10"
appfunctions = "1.0.0-SNAPSHOT"
datastore = "1.2.1"
screenshot = "0.0.1-alpha15"
coil = "2.7.0"
Expand Down
6 changes: 6 additions & 0 deletions agent/settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
*/
pluginManagement {
repositories {
maven {
url = uri("https://androidx.dev/snapshots/builds/16181473/artifacts/repository")
}
google {
content {
includeGroupByRegex("com\\.android.*")
Expand All @@ -30,6 +33,9 @@ pluginManagement {
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
maven {
url = uri("https://androidx.dev/snapshots/builds/16181473/artifacts/repository")
}
google()
mavenCentral()
}
Expand Down
Loading