Skip to content

Commit b524899

Browse files
authored
Kotlin: Amazon Nova text and image generation examples (#7257)
* Refactor InvokeModel and add Converse; add ConverseStream, and example for Nova Canvas
1 parent ab7e5c8 commit b524899

File tree

15 files changed

+550
-117
lines changed

15 files changed

+550
-117
lines changed

.doc_gen/metadata/bedrock-runtime_metadata.yaml

+16
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,14 @@ bedrock-runtime_Converse_AmazonNovaText:
108108
- description: Send a text message to Amazon Nova, using Bedrock's Converse API.
109109
snippet_tags:
110110
- javascript.v3.bedrock-runtime.Converse_AmazonNovaText
111+
Kotlin:
112+
versions:
113+
- sdk_version: 1
114+
github: kotlin/services/bedrock-runtime
115+
excerpts:
116+
- description: Send a text message to Amazon Nova, using Bedrock's Converse API.
117+
snippet_tags:
118+
- bedrock-runtime.kotlin.Converse_AmazonNovaText
111119
.NET:
112120
versions:
113121
- sdk_version: 3
@@ -439,6 +447,14 @@ bedrock-runtime_ConverseStream_AmazonNovaText:
439447
- description: Send a text message to Amazon Nova using Bedrock's Converse API and process the response stream in real-time.
440448
snippet_tags:
441449
- javascript.v3.bedrock-runtime.ConverseStream_AmazonNovaText
450+
Kotlin:
451+
versions:
452+
- sdk_version: 1
453+
github: kotlin/services/bedrock-runtime
454+
excerpts:
455+
- description: Send a text message to Amazon Nova using Bedrock's Converse API and process the response stream in real-time.
456+
snippet_tags:
457+
- bedrock-runtime.kotlin.ConverseStream_AmazonNovaText
442458
.NET:
443459
versions:
444460
- sdk_version: 3

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,4 @@ kotlin/services/**/build/
3636
kotlin/services/**/gradle/
3737
kotlin/services/**/gradlew
3838
kotlin/services/**/gradlew.bat
39+
kotlin/services/**/.kotlin/

kotlin/services/bedrock-runtime/README.md

+10-1
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,18 @@ For prerequisites, see the [README](../../README.md#Prerequisites) in the `kotli
3030
<!--custom.prerequisites.start-->
3131
> ⚠ You must request access to a model before you can use it. If you try to use the model (with the API or console) before you have requested access to it, you will receive an error message. For more information, see [Model access](https://docs.aws.amazon.com/bedrock/latest/userguide/model-access.html).
3232
<!--custom.prerequisites.end-->
33+
### Amazon Nova
34+
35+
- [Converse](src/main/kotlin/com/example/bedrockruntime/models/amazon/nova/text/Converse.kt#L6)
36+
- [ConverseStream](src/main/kotlin/com/example/bedrockruntime/models/amazon/nova/text/ConverseStream.kt#L6)
37+
38+
### Amazon Nova Canvas
39+
40+
- [InvokeModel](src/main/kotlin/com/example/bedrockruntime/models/amazon/nova/canvas/InvokeModel.kt#L6)
41+
3342
### Amazon Titan Text
3443

35-
- [InvokeModel](src/main/kotlin/com/example/bedrockruntime/InvokeModel.kt#L6)
44+
- [InvokeModel](src/main/kotlin/com/example/bedrockruntime/models/amazon/titan/text/InvokeModel.kt#L6)
3645

3746

3847
<!--custom.examples.start-->
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,41 @@
11
plugins {
22
kotlin("jvm") version "2.1.10"
33
id("org.jetbrains.kotlin.plugin.serialization") version "2.1.10"
4-
id("org.jlleitschuh.gradle.ktlint") version "11.3.1" apply true
4+
id("org.jlleitschuh.gradle.ktlint") version "12.1.1"
55
application
66
}
77

88
group = "com.example.bedrockruntime"
99
version = "1.0-SNAPSHOT"
1010

11+
val awsSdkVersion = "1.4.27"
12+
val junitVersion = "5.12.0"
13+
1114
repositories {
1215
mavenCentral()
1316
}
1417

15-
buildscript {
16-
repositories {
17-
maven("https://plugins.gradle.org/m2/")
18-
}
19-
dependencies {
20-
classpath("org.jlleitschuh.gradle:ktlint-gradle:11.3.1")
21-
}
22-
}
23-
2418
dependencies {
25-
implementation("aws.sdk.kotlin:bedrockruntime:1.4.11")
19+
implementation("aws.sdk.kotlin:bedrockruntime:$awsSdkVersion")
2620
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.8.0")
27-
testImplementation("org.junit.jupiter:junit-jupiter:5.11.4")
28-
}
2921

30-
application {
31-
mainClass.set("com.example.bedrockruntime.InvokeModelKt")
22+
testImplementation("org.junit.jupiter:junit-jupiter:$junitVersion")
23+
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1")
24+
testImplementation("org.jetbrains.kotlin:kotlin-reflect")
25+
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
3226
}
3327

34-
// Java and Kotlin configuration
3528
kotlin {
3629
jvmToolchain(21)
3730
}
3831

39-
java {
40-
toolchain {
41-
languageVersion = JavaLanguageVersion.of(21)
42-
}
43-
}
44-
4532
tasks.test {
4633
useJUnitPlatform()
4734
testLogging {
4835
events("passed", "skipped", "failed")
4936
}
37+
}
5038

51-
// Define the test source set
52-
testClassesDirs += files("build/classes/kotlin/test")
53-
classpath += files("build/classes/kotlin/main", "build/resources/main")
39+
application {
40+
mainClass.set("com.example.bedrockruntime.InvokeModelKt")
5441
}

kotlin/services/bedrock-runtime/src/main/kotlin/com/example/bedrockruntime/InvokeModel.kt

-67
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package com.example.bedrockruntime.libs
5+
6+
import java.io.ByteArrayInputStream
7+
import java.io.IOException
8+
import javax.imageio.ImageIO
9+
import javax.swing.ImageIcon
10+
import javax.swing.JFrame
11+
import javax.swing.JLabel
12+
13+
/**
14+
* Utility object for handling image-related operations.
15+
*/
16+
object ImageTools {
17+
/**
18+
* Displays a byte array as an image in a new window.
19+
*
20+
* Creates a new JFrame window that displays the image represented by the provided byte array.
21+
* The window will close the application when closed (EXIT_ON_CLOSE).
22+
*
23+
* @param imageData The image data as a byte array
24+
* @throws RuntimeException if there is an error reading the image data
25+
*/
26+
fun displayImage(imageData: ByteArray) {
27+
try {
28+
val image = ImageIO.read(ByteArrayInputStream(imageData))
29+
JFrame("Image").apply {
30+
defaultCloseOperation = JFrame.EXIT_ON_CLOSE
31+
contentPane.add(JLabel(ImageIcon(image)))
32+
pack()
33+
isVisible = true
34+
}
35+
} catch (e: IOException) {
36+
throw RuntimeException(e)
37+
}
38+
}
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package com.example.bedrockruntime.models.amazon.nova.canvas
5+
6+
// snippet-start:[bedrock-runtime.kotlin.InvokeModel_AmazonNovaImageGeneration]
7+
8+
import aws.sdk.kotlin.services.bedrockruntime.BedrockRuntimeClient
9+
import aws.sdk.kotlin.services.bedrockruntime.model.InvokeModelRequest
10+
import com.example.bedrockruntime.libs.ImageTools.displayImage
11+
import kotlinx.serialization.Serializable
12+
import kotlinx.serialization.json.Json
13+
import java.util.*
14+
15+
/**
16+
* This example demonstrates how to use Amazon Nova Canvas to generate images.
17+
* It shows how to:
18+
* - Set up the Amazon Bedrock runtime client
19+
* - Configure the image generation parameters
20+
* - Send a request to generate an image
21+
* - Process the response and display the generated image
22+
*/
23+
suspend fun main() {
24+
println("Generating image. This may take a few seconds...")
25+
val imageData = invokeModel()
26+
displayImage(imageData)
27+
}
28+
29+
// Data class for parsing the model's response
30+
@Serializable
31+
private data class Response(val images: List<String>)
32+
33+
// Configure JSON parser to ignore unknown fields in the response
34+
private val json = Json { ignoreUnknownKeys = true }
35+
36+
suspend fun invokeModel(): ByteArray {
37+
// Create and configure the Bedrock runtime client
38+
BedrockRuntimeClient { region = "us-east-1" }.use { client ->
39+
40+
// Specify the model ID. For the latest available models, see:
41+
// https://docs.aws.amazon.com/bedrock/latest/userguide/models-supported.html
42+
val modelId = "amazon.nova-canvas-v1:0"
43+
44+
// Configure the generation parameters and create the request
45+
// First, set the main parameters:
46+
// - prompt: Text description of the image to generate
47+
// - seed: Random number for reproducible generation (0 to 858,993,459)
48+
val prompt = "A stylized picture of a cute old steampunk robot"
49+
val seed = (0..858_993_459).random()
50+
51+
// Then, create the request using a template with the following structure:
52+
// - taskType: TEXT_IMAGE (specifies text-to-image generation)
53+
// - textToImageParams: Contains the text prompt
54+
// - imageGenerationConfig: Contains optional generation settings (seed, quality, etc.)
55+
// For a list of available request parameters, see:
56+
// https://docs.aws.amazon.com/nova/latest/userguide/image-gen-req-resp-structure.html
57+
val request = """
58+
{
59+
"taskType": "TEXT_IMAGE",
60+
"textToImageParams": {
61+
"text": "$prompt"
62+
},
63+
"imageGenerationConfig": {
64+
"seed": $seed,
65+
"quality": "standard"
66+
}
67+
}
68+
""".trimIndent()
69+
70+
// Send the request and process the model's response
71+
runCatching {
72+
// Send the request to the model
73+
val response = client.invokeModel(
74+
InvokeModelRequest {
75+
this.modelId = modelId
76+
body = request.toByteArray()
77+
},
78+
)
79+
80+
// Parse the response and extract the generated image
81+
val jsonResponse = response.body.toString(Charsets.UTF_8)
82+
val parsedResponse = json.decodeFromString<Response>(jsonResponse)
83+
84+
// Extract the generated image and return it as a byte array for better handling
85+
val base64Image = parsedResponse.images.first()
86+
return Base64.getDecoder().decode(base64Image)
87+
}.getOrElse { error ->
88+
System.err.println("ERROR: Can't invoke '$modelId'. Reason: ${error.message}")
89+
throw RuntimeException("Failed to generate image with model $modelId", error)
90+
}
91+
}
92+
}
93+
94+
// snippet-end:[bedrock-runtime.kotlin.InvokeModel_AmazonNovaImageGeneration]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package com.example.bedrockruntime.models.amazon.nova.text
5+
6+
// snippet-start:[bedrock-runtime.kotlin.Converse_AmazonNovaText]
7+
8+
import aws.sdk.kotlin.services.bedrockruntime.BedrockRuntimeClient
9+
import aws.sdk.kotlin.services.bedrockruntime.model.ContentBlock
10+
import aws.sdk.kotlin.services.bedrockruntime.model.ConversationRole
11+
import aws.sdk.kotlin.services.bedrockruntime.model.ConverseRequest
12+
import aws.sdk.kotlin.services.bedrockruntime.model.Message
13+
14+
/**
15+
* This example demonstrates how to use the Amazon Nova foundation models to generate text.
16+
* It shows how to:
17+
* - Set up the Amazon Bedrock runtime client
18+
* - Create a message
19+
* - Configure and send a request
20+
* - Process the response
21+
*/
22+
suspend fun main() {
23+
converse().also { println(it) }
24+
}
25+
26+
suspend fun converse(): String {
27+
// Create and configure the Bedrock runtime client
28+
BedrockRuntimeClient { region = "us-east-1" }.use { client ->
29+
30+
// Specify the model ID. For the latest available models, see:
31+
// https://docs.aws.amazon.com/bedrock/latest/userguide/models-supported.html
32+
val modelId = "amazon.nova-lite-v1:0"
33+
34+
// Create the message with the user's prompt
35+
val prompt = "Describe the purpose of a 'hello world' program in one line."
36+
val message = Message {
37+
role = ConversationRole.User
38+
content = listOf(ContentBlock.Text(prompt))
39+
}
40+
41+
// Configure the request with optional model parameters
42+
val request = ConverseRequest {
43+
this.modelId = modelId
44+
messages = listOf(message)
45+
inferenceConfig {
46+
maxTokens = 500 // Maximum response length
47+
temperature = 0.5F // Lower values: more focused output
48+
// topP = 0.8F // Alternative to temperature
49+
}
50+
}
51+
52+
// Send the request and process the model's response
53+
runCatching {
54+
val response = client.converse(request)
55+
return response.output!!.asMessage().content.first().asText()
56+
}.getOrElse { error ->
57+
error.message?.let { e -> System.err.println("ERROR: Can't invoke '$modelId'. Reason: $e") }
58+
throw RuntimeException("Failed to generate text with model $modelId", error)
59+
}
60+
}
61+
}
62+
// snippet-end:[bedrock-runtime.kotlin.Converse_AmazonNovaText]

0 commit comments

Comments
 (0)