how-to ~3 min
First Steps - Hello World with TPipe

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 Pipe as 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:0
  • anthropic.claude-3-5-haiku-20241022-v1:0
  • amazon.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