Skip to content
Closed
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
6 changes: 5 additions & 1 deletion arcade-java-example/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@ repositories {

dependencies {
implementation(project(":arcade-java"))

// Only needed for SpringBootExample
implementation(project(":arcade-spring-boot-starter"))
implementation("org.springframework.boot:spring-boot-starter:3.5.10")
}

tasks.withType<JavaCompile>().configureEach {
// Allow using more modern APIs, like `List.of` and `Map.of`, in examples.
options.release.set(9)
options.release.set(17)
}

application {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package dev.arcade.example;

import dev.arcade.client.ArcadeClient;
import dev.arcade.models.tools.ExecuteToolRequest;
import dev.arcade.models.tools.ExecuteToolResponse;
import dev.arcade.models.tools.ToolExecuteParams;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

/**
* Example of calling a tool using the Arcade Java SDK.
*/
@SpringBootApplication
public class SpringBootExample {

/**
* Starts the Spring Boot application.
* @param args All args are passed into the SpringApplication
*/
public static void main(String[] args) {
SpringApplication.run(SpringBootExample.class, args);
}

/**
* Injects an <code>ArcadeClient</code>, and returns an ApplicationRunner that makes a tool call.
* @param client Arcade Client is autoinjected if ARCADE_API_KEY, or equivalent application.properties var is set.
* @return Runs code on application start.
*/
@Bean
ApplicationRunner appRunner(ArcadeClient client) {
return args -> {
String userId = System.getenv("ARCADE_USER_ID"); // the Spotify tool require a userId
if (userId == null) {
throw new IllegalArgumentException("Missing ARCADE_USER_ID environment variable");
}

ToolExecuteParams params = ToolExecuteParams.builder()
.executeToolRequest(ExecuteToolRequest.builder()
.toolName("Spotify.ResumePlayback@1.0.2")
.userId(userId)
.build())
.build();
ExecuteToolResponse executeToolResponse = client.tools().execute(params);
executeToolResponse
.output()
.ifPresentOrElse(
output -> System.out.println("Tool output: " + output._value()),
() -> System.out.println("No output for this tool"));
};
}
}
34 changes: 34 additions & 0 deletions arcade-spring-boot-starter/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
id("arcade.kotlin")
id("java")
id("io.spring.dependency-management") version "1.1.7"
application
}

dependencies {
api(project(":arcade-java"))
implementation("org.springframework.boot:spring-boot-starter:3.5.10")
}

tasks.withType<JavaCompile>().configureEach {
// Allow using more modern APIs, like `List.of` and `Map.of`, in examples.
options.release.set(17)
}

tasks.withType<KotlinCompile> {
compilerOptions {
freeCompilerArgs = listOf(
"-Xjvm-default=all",
"-Xjdk-release=17",
// Suppress deprecation warnings because we may still reference and test deprecated members.
// TODO: Replace with `-Xsuppress-warning=DEPRECATION` once we use Kotlin compiler 2.1.0+.
"-nowarn",
)
jvmTarget.set(JvmTarget.JVM_17)
}
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package dev.arcade.springboot

import dev.arcade.client.ArcadeClient
import dev.arcade.client.okhttp.ArcadeOkHttpClient
import dev.arcade.core.ClientOptions
import org.springframework.boot.autoconfigure.AutoConfiguration
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.util.StringUtils

@AutoConfiguration
@EnableConfigurationProperties(ArcadeAutoConfiguration.Config::class)
open class ArcadeAutoConfiguration {

@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "arcade", name = ["api-key"])
open fun arcadeClient(config: Config): ArcadeClient {
val clientBuilder = ArcadeOkHttpClient.builder().fromEnv()

if (config.apiKey != null && StringUtils.hasText(config.apiKey)) {
clientBuilder.apiKey(config.apiKey)
}

if (config.baseUrl != null && StringUtils.hasText(config.baseUrl)) {
clientBuilder.baseUrl(config.baseUrl)
}

return clientBuilder.build()
}

@ConfigurationProperties(prefix = "arcade")
@JvmRecord
data class Config(
val apiKey: String? = System.getenv("ARCADE_API_KEY"),
val baseUrl: String? = ClientOptions.PRODUCTION_URL,
) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dev.arcade.springboot.ArcadeAutoConfiguration
3 changes: 2 additions & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ val projectNames = rootDir.listFiles()
file.listFiles()?.asSequence().orEmpty().any { it.name == "build.gradle.kts" }
}
.map { it.name }
.toList()
.toList() +
listOf("arcade-spring-boot-starter")
println("projects: $projectNames")
projectNames.forEach { include(it) }
Loading