Skip to content

Commit b4a7f1e

Browse files
committed
Refactor InvokeModel and add Converse
1 parent bafa6bf commit b4a7f1e

File tree

8 files changed

+309
-118
lines changed

8 files changed

+309
-118
lines changed
Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,40 @@
11
plugins {
22
kotlin("jvm") version "2.1.10"
3-
id("org.jetbrains.kotlin.plugin.serialization") version "2.1.10"
4-
id("org.jlleitschuh.gradle.ktlint") version "11.3.1" apply true
3+
kotlin("plugin.serialization") version "2.1.10"
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+
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
3225
}
3326

34-
// Java and Kotlin configuration
3527
kotlin {
3628
jvmToolchain(21)
3729
}
3830

39-
java {
40-
toolchain {
41-
languageVersion = JavaLanguageVersion.of(21)
42-
}
43-
}
44-
4531
tasks.test {
4632
useJUnitPlatform()
4733
testLogging {
4834
events("passed", "skipped", "failed")
4935
}
50-
51-
// Define the test source set
52-
testClassesDirs += files("build/classes/kotlin/test")
53-
classpath += files("build/classes/kotlin/main", "build/resources/main")
5436
}
37+
38+
application {
39+
mainClass.set("com.example.bedrockruntime.InvokeModelKt")
40+
}

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

Lines changed: 0 additions & 67 deletions
This file was deleted.
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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+
* @throws RuntimeException if the model invocation fails
23+
*/
24+
suspend fun main() {
25+
converse().also { println(it) }
26+
}
27+
28+
suspend fun converse(): String {
29+
// Step 1: Create the Amazon Bedrock runtime client
30+
// The runtime client handles the communication with AI models on Amazon Bedrock
31+
BedrockRuntimeClient { region = "us-east-1" }.use { client ->
32+
33+
// Step 2: Specify which model to use
34+
// Available Amazon Nova models and their characteristics:
35+
// - Amazon Nova Micro: Text-only model optimized for lowest latency and cost
36+
// - Amazon Nova Lite: Fast, low-cost multimodal model for image, video, and text
37+
// - Amazon Nova Pro: Advanced multimodal model balancing accuracy, speed, and cost
38+
//
39+
// For the latest available models, see:
40+
// https://docs.aws.amazon.com/bedrock/latest/userguide/models-supported.html
41+
val modelId = "amazon.nova-lite-v1:0"
42+
43+
// Step 3: Create the message
44+
// The message includes the text prompt and specifies that it comes from the user
45+
val inputText = "Describe the purpose of a 'hello world' program in one line."
46+
val message = Message {
47+
role = ConversationRole.User
48+
content = listOf(ContentBlock.Text(inputText))
49+
}
50+
51+
// Step 4: Configure the request
52+
// Optional parameters to control the model's response:
53+
// - maxTokens: maximum number of tokens to generate
54+
// - temperature: randomness (max: 1.0, default: 0.7)
55+
// OR
56+
// - topP: diversity of word choice (max: 1.0, default: 0.9)
57+
// Note: Use either temperature OR topP, but not both
58+
val request = ConverseRequest {
59+
this.modelId = modelId
60+
messages = listOf(message)
61+
inferenceConfig {
62+
maxTokens = 500 // The maximum response length
63+
temperature = 0.5F // Using temperature for randomness control
64+
// topP = 0.8F // Alternative: use topP instead of temperature
65+
}
66+
}
67+
68+
// Step 5: Send and process the request
69+
// - Send the request to the model
70+
// - Extract and return the generated text
71+
runCatching {
72+
val response = client.converse(request)
73+
return response.output!!.asMessage().content.first().asText()
74+
75+
}.getOrElse { error ->
76+
error.message?.let { e -> System.err.println("ERROR: Can't invoke '$modelId'. Reason: $e") }
77+
throw RuntimeException("Failed to generate text with model $modelId", error)
78+
}
79+
}
80+
}
81+
// snippet-end:[bedrock-runtime.kotlin.Converse_AmazonNovaText]
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
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.titan.text
5+
6+
// snippet-start:[bedrock-runtime.kotlin.InvokeModel_AmazonTitanText]
7+
8+
import aws.sdk.kotlin.services.bedrockruntime.BedrockRuntimeClient
9+
import aws.sdk.kotlin.services.bedrockruntime.model.InvokeModelRequest
10+
import kotlinx.serialization.Serializable
11+
import kotlinx.serialization.json.Json
12+
13+
/**
14+
* This example demonstrates how to use the Amazon Titan foundation models to generate text.
15+
* It shows how to:
16+
* - Set up the Amazon Bedrock runtime client
17+
* - Create a request payload
18+
* - Configure and send a request
19+
* - Process the response
20+
*
21+
* @throws RuntimeException if the model invocation fails
22+
*/
23+
suspend fun main() {
24+
invokeModel().also { println(it) }
25+
}
26+
27+
// Initialize JSON parser with relaxed configuration
28+
private val json = Json { ignoreUnknownKeys = true }
29+
30+
suspend fun invokeModel(): String {
31+
// Step 1: Create the Amazon Bedrock runtime client
32+
// The runtime client handles the communication with AI models on Amazon Bedrock
33+
BedrockRuntimeClient { region = "us-east-1" }.use { client ->
34+
35+
// Step 2: Specify which model to use
36+
// Available Amazon Titan models and their characteristics:
37+
// - Titan Text Lite: Fast, cost-effective text generation
38+
// - Titan Text Express: Balanced performance and cost
39+
// - Titan Text Large: Advanced capabilities for complex tasks
40+
//
41+
// For the latest available models, see:
42+
// https://docs.aws.amazon.com/bedrock/latest/userguide/models-supported.html
43+
val modelId = "amazon.titan-text-lite-v1"
44+
45+
// Step 3: Create the request payload
46+
// Optional parameters to control the model's response:
47+
// - maxTokenCount: maximum number of tokens to generate
48+
// - temperature: randomness (max: 1.0, default: 0.7)
49+
// OR
50+
// - topP: diversity of word choice (max: 1.0, default: 0.9)
51+
// Note: Use either temperature OR topP, but not both
52+
//
53+
// For detailed parameter descriptions, see:
54+
// https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-titan-text.html
55+
val prompt = "Describe the purpose of a 'hello world' program in one line."
56+
val request = """
57+
{
58+
"inputText": "$prompt",
59+
"textGenerationConfig": {
60+
"maxTokenCount": 500,
61+
"temperature": 0.5
62+
}
63+
}
64+
""".trimIndent()
65+
66+
// Step 4: Send and process the request
67+
// - Send the request to the model
68+
// - Parse the JSON response
69+
// - Extract and return the generated text
70+
runCatching {
71+
// Send the request to the model
72+
val response = client.invokeModel(InvokeModelRequest {
73+
this.modelId = modelId
74+
body = request.toByteArray()
75+
})
76+
77+
// Convert the response bytes to a JSON string
78+
val jsonResponse = response.body.toString(Charsets.UTF_8)
79+
80+
// Parse the JSON into a Kotlin object
81+
val parsedResponse = json.decodeFromString<BedrockResponse>(jsonResponse)
82+
83+
// Extract and return the generated text
84+
return parsedResponse.results.firstOrNull()!!.outputText
85+
86+
}.getOrElse { error ->
87+
error.message?.let { msg ->
88+
System.err.println("ERROR: Can't invoke '$modelId'. Reason: $msg")
89+
}
90+
throw RuntimeException("Failed to generate text with model $modelId", error)
91+
}
92+
}
93+
}
94+
95+
@Serializable
96+
private data class BedrockResponse(val results: List<Result>)
97+
98+
@Serializable
99+
private data class Result(val outputText: String)
100+
101+
// snippet-end:[bedrock-runtime.kotlin.InvokeModel_AmazonTitanText]

kotlin/services/bedrock-runtime/src/test/kotlin/InvokeModelTest.kt

Lines changed: 0 additions & 24 deletions
This file was deleted.

0 commit comments

Comments
 (0)