This guide walks you through creating your first TPipe application. Think of your first `Pipe` as connecting your main water line—once it's flowing, you can route it anywhere.
First Steps - Hello World with TPipe
💡 Tip: This guide walks you through creating your first TPipe application. Think of your first
Pipeas connecting your main water line—once it’s flowing, you can route it anywhere.
Prerequisites
- TPipe installed in your project (Installation Guide)
- JDK 24+ configured
- AWS credentials configured
Project Setup
build.gradle.kts
plugins {
kotlin("jvm") version "2.2.20"
kotlin("plugin.serialization") version "2.2.20"
application
}
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(24))
}
}
kotlin {
jvmToolchain(24)
compilerOptions {
jvmTarget.set(JvmTarget.JVM_24)
}
}
application {
mainClass.set("MainKt")
}
repositories {
mavenCentral()
}
dependencies {
implementation("com.TTT:TPipe:1.0.0")
implementation("com.TTT:TPipe-Bedrock:1.0.0")
implementation("org.jetbrains.kotlinx:kotlinx-io-core:0.8.0")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.0")
}
Hello World Examples
1. Basic Text Generation
Create src/main/kotlin/Main.kt:
import bedrockPipe.BedrockPipe
fun main() {
val pipe = BedrockPipe()
.setModel("anthropic.claude-3-haiku-20240307-v1:0")
.setRegion("us-west-2")
runBlocking {
val response = pipe.generateText("Hello, world!")
println(response)
}
}
2. Cross-Region Model with ARN Binding
Some models require cross-region ARN binding to connect:
import bedrockPipe.BedrockPipe
import env.bedrockEnv
import kotlinx.coroutines.runBlocking
fun main() {
// Required for cross-region models
bedrockEnv.bindInferenceProfile(
"anthropic.claude-3-5-sonnet-20241022-v2:0",
"arn:aws:bedrock:us-west-2:123456789012:inference-profile/my-profile"
)
val pipe = BedrockPipe()
.setModel("anthropic.claude-3-5-sonnet-20241022-v2:0")
.setRegion("us-east-1")
runBlocking {
val response = pipe.generateText("Hello from cross-region model!")
println(response)
}
}
3. Streaming Response
import bedrockPipe.BedrockPipe
import kotlinx.coroutines.runBlocking
fun main() {
val pipe = BedrockPipe()
.setModel("anthropic.claude-3-haiku-20240307-v1:0")
.setRegion("us-west-2")
.enableStreaming()
.setStreamingCallback { chunk ->
print(chunk)
}
runBlocking {
pipe.generateText("Summarize these system logs: [2026-03-31 10:15:02] ERROR: Connection timeout in module 'auth-service'. [2026-03-31 10:15:05] INFO: Retrying connection...")
println("\nDone!")
}
}
For advanced streaming features including multiple callbacks, error handling, and concurrent execution, see Streaming Callbacks.
4. Streaming with reasoning output
import bedrockPipe.BedrockPipe
import bedrockPipe.streamOutputToTerminal
import kotlinx.coroutines.runBlocking
fun main() {
val pipe = BedrockPipe()
.setModel("anthropic.claude-3-haiku-20240307-v1:0")
.setRegion("us-west-2")
streamOutputToTerminal(pipe)
runBlocking {
pipe.generateText("Explain how streaming output is routed through reasoning pipes.")
}
}
The helper above automatically enables streaming on the supplied [BedrockPipe] and any reasoning pipes it has been configured with, printing chunked tokens for both the primary response and any internal reasoning output.
If you are working with a Pipeline, use streamPipelineOutputToTerminal(pipeline) instead so every pipe already registered on the pipeline participates in streaming output.
Running Your Application
./gradlew run
Cross-Region ARN Binding
Models requiring ARN binding:
anthropic.claude-3-5-sonnet-20241022-v2:0anthropic.claude-3-5-haiku-20241022-v1:0amazon.nova-pro-v1:0
Use bedrockEnv.bindInferenceProfile(modelId, arnProfile) before creating the pipe.
Next Steps
Ready to dive deeper into TPipe? Continue with the core concepts:
→ Why TPipe? Architectural Deep Dive - The paradigm shift from libraries to substrates