How to Integrate earendil π with Amazon Bedrock: Complete Implementation Guide
earendil π exposes Amazon Bedrock as a first-class LLM provider through automatic lazy registration in the packages/ai package, requiring only standard AWS credentials or a bearer token to begin routing requests.
The earendil-works/pi repository delivers a seamless way to integrate earendil π with Amazon Bedrock without manual provider configuration. The integration relies on an internal provider architecture that handles streaming, authentication, and request metadata automatically once credentials are supplied.
Architecture of the Bedrock Provider
The integration centers on packages/ai/src/providers/amazon-bedrock.ts, which implements the full Bedrock runtime API. This module is lazily loaded when running under the Bun runtime to keep the default Node.js bundle lightweight.
Core Components
| Component | Role | Source |
|---|---|---|
| Provider implementation | Implements the streaming Bedrock API using the AWS SDK (@aws-sdk/client-bedrock-runtime). Handles region/profile resolution, optional bearer-token auth, proxy support, and request-metadata tagging. |
packages/ai/src/providers/amazon-bedrock.ts |
| Provider options | BedrockOptions extends the generic StreamOptions and adds Bedrock-specific fields (region, profile, toolChoice, reasoning, thinkingBudgets, interleavedThinking, thinkingDisplay, requestMetadata, bearerToken). |
lines 53‑85 of amazon-bedrock.ts |
| Streaming entry point | streamBedrock is the StreamFunction that the rest of π calls. It builds the request payload, creates a BedrockRuntimeClient with the resolved configuration, and parses the streamed JSON events into AssistantMessageEventStream objects. |
lines 89‑124 of amazon-bedrock.ts |
| Lazy registration (Bun runtime) | register-bedrock.ts imports the provider module and registers it via setBedrockProviderModule. This file is only loaded when the CLI runs under Bun, keeping the default Node bundle lightweight. |
packages/coding-agent/src/bun/register-bedrock.ts |
| Provider lookup | model-resolver.ts maps the provider id ("amazon-bedrock") to a default model ID and registers the provider name for UI display. |
packages/coding-agent/src/core/model-resolver.ts |
| Display names | provider-display-names.ts maps the internal id to a human-readable label ("Amazon Bedrock") used by the /login UI and the interactive mode. |
packages/coding-agent/src/core/provider-display-names.ts |
| Credential detection | hasBedrockCredentials() checks for AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY (or a bearer token) and is used by the test harness to skip Bedrock tests when no credentials are present. |
packages/ai/test/bedrock-utils.ts |
Provider Implementation Details
The streamBedrock function in packages/ai/src/providers/amazon-bedrock.ts serves as the primary entry point for all Bedrock requests. It constructs a BedrockRuntimeClient with configuration resolved from environment variables and explicit options.
Configuration Resolution
The provider builds a BedrockRuntimeClientConfig object (lines 17‑34) that prioritizes explicit options over environment variables:
- Region: Explicit
options.region→AWS_REGIONenvironment variable → SDK defaults - Profile: Loaded from
options.profilefor credential resolution - Proxy:
NodeHttpHandlerconfigured whenHTTPS_PROXYorHTTP_PROXYis detected - Authentication: Bearer token support via
token/authSchemePreferencewhenAWS_BEARER_TOKEN_BEDROCKis set
Request Building and Streaming
The request payload construction (lines 88‑98) assembles a commandInput object containing:
modelId: The fully-qualified Bedrock model identifier- Converted messages and system prompts
- Inference configuration and tool configuration
- Optional
requestMetadatafor cost-allocation tagging - Model-specific fields like
thinkingBudgetsfor Claude models
The ConverseStreamCommand executes the request, and parseStreamingJson processes the response into AssistantMessageEventStream events including text, tool_call, thinking, usage, and stop signals.
Runtime Registration
The integration uses lazy loading to avoid bundling Bedrock-specific dependencies in Node.js environments. When running under Bun, packages/coding-agent/src/bun/register-bedrock.ts executes and calls setBedrockProviderModule(bedrockProviderModule), registering the compiled provider module with the internal registry.
At runtime, the generic getModel(providerId, modelId) function (exposed from @earendil-works/pi-ai) looks up the provider using the registry that includes the lazy-registered Bedrock module. This architecture means users need no manual registration code—merely installing π and providing credentials activates the integration.
Usage Examples
TypeScript API Integration
Import getModel from the AI package and specify "amazon-bedrock" as the provider ID:
import { getModel } from "@earendil-works/pi-ai";
const model = getModel(
"amazon-bedrock",
// Fully‑qualified Bedrock model identifier
"global.anthropic.claude-opus-4-6-v1"
);
// Use the model in a prompt
const response = await model.run({
messages: [{ role: "user", content: "Write a haiku about sunrise." }],
// optional Bedrock‑specific options
region: "us-east-1", // overrides AWS_REGION
thinkingDisplay: "summarized", // how Claude thinking is returned
requestMetadata: { project: "demo" } // cost‑allocation tags
});
console.log(response.content);
CLI with IAM Credentials
Export standard AWS environment variables and invoke the CLI:
export AWS_ACCESS_KEY_ID=AKIA...
export AWS_SECRET_ACCESS_KEY=...
export AWS_REGION=us-east-1 # optional, defaults to us-east-1
# Run π with the Bedrock provider
./pi -p "amazon-bedrock" -m "global.anthropic.claude-opus-4-6-v1" \
-t "Write a short poem about the sea."
Bearer Token Authentication
For environments using bearer tokens instead of IAM keys:
export AWS_BEARER_TOKEN_BEDROCK=eyJhbGciOi...
./pi -p amazon-bedrock -m "us.anthropic.claude-sonnet-4-5" \
"Explain quantum entanglement in plain English."
Environment Variables Reference
The following variables control the Bedrock integration behavior in packages/ai/src/providers/amazon-bedrock.ts (lines 36‑39, 44‑50, 78‑84):
| Variable | Purpose |
|---|---|
AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY |
Standard IAM credentials consumed by the AWS SDK |
AWS_REGION |
Default region when no explicit region option is provided |
AWS_PROFILE |
Named profile for credential resolution |
AWS_BEARER_TOKEN_BEDROCK |
Direct bearer-token authentication (requires bedrock:CallWithBearerToken permission) |
AWS_BEDROCK_SKIP_AUTH=1 |
Bypass AWS signing for unauthenticated endpoints |
AWS_BEDROCK_FORCE_HTTP1=1 |
Force HTTP/1.1 when custom endpoints reject HTTP/2 |
HTTPS_PROXY / HTTP_PROXY |
Proxy URLs translated into node-http agents via createHttpProxyAgentsForTarget |
Summary
- earendil π integrates Amazon Bedrock through the
packages/ai/src/providers/amazon-bedrock.tsprovider implementation - The provider supports both IAM credentials and bearer token authentication with automatic proxy detection
- Lazy registration via
packages/coding-agent/src/bun/register-bedrock.tskeeps Node.js bundles lightweight while enabling Bun runtime support - The
streamBedrockfunction handles request construction, streaming viaConverseStreamCommand, and event parsing intoAssistantMessageEventStreamobjects - Users configure the integration through standard AWS environment variables or explicit options in the TypeScript API, with no manual provider registration required
Frequently Asked Questions
What AWS credentials does earendil π require for Bedrock integration?
earendil π accepts standard IAM credentials via AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, or alternatively a bearer token through AWS_BEARER_TOKEN_BEDROCK. The credential detection logic in packages/ai/test/bedrock-utils.ts uses hasBedrockCredentials() to verify that at least one authentication method is present before attempting calls.
Does the Bedrock provider work in Node.js environments?
The Bedrock provider is lazily registered only when running under the Bun runtime via packages/coding-agent/src/bun/register-bedrock.ts. While the core provider code in packages/ai is runtime-agnostic, the automatic registration mechanism currently targets Bun specifically to maintain a lightweight default bundle for Node.js users.
How does earendil π handle Bedrock's streaming responses?
The streamBedrock function (lines 89‑124 of amazon-bedrock.ts) executes a ConverseStreamCommand and processes the response through parseStreamingJson, converting Bedrock's JSON events into standardized AssistantMessageEventStream objects that include text content, tool calls, thinking blocks, usage statistics, and stop signals.
Can I specify custom regions or endpoints for Bedrock?
Yes. The provider accepts a region option that overrides AWS_REGION, and supports custom endpoints through the endpoint field in the BedrockRuntimeClientConfig. Additionally, setting AWS_BEDROCK_FORCE_HTTP1=1 forces HTTP/1.1 for endpoints that do not support HTTP/2.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →