Cookbook
bedrock-bot
One-shot Claude prompt via AWS Bedrock (`@theokit/sdk` Adoption Roadmap #8; ADRs D286-D302).
bedrock-bot
One-shot Claude prompt via AWS Bedrock (@theokit/sdk Adoption Roadmap #8; ADRs D286-D302).
Setup
- Enable Bedrock model access in your AWS account: https://console.aws.amazon.com/bedrock/home → "Model access" → request Anthropic models.
- Generate a Bearer token (one of three paths):
- Short-term, AWS Console: IAM → Users → your user → "Security credentials" → "Bedrock API keys" → "Generate API key" (≤12h TTL).
- Long-term via CLI:
(only for exploration — AWS docs warn against long-term keys in prod).aws iam create-service-specific-credential --service-name bedrock.amazonaws.com - Auto-refresh via peer dep:
Then the SDK refreshes short-term tokens automatically (D287).pnpm add @aws/bedrock-token-generator
- Copy
.env.exampleto.envand fillAWS_BEARER_TOKEN_BEDROCK.
Run
cp .env.example .env
# fill AWS_BEARER_TOKEN_BEDROCK
pnpm install
pnpm run run # default question: "Qual é a capital do Brasil?"
pnpm run run "What's 2+2?" # custom questionModel IDs
Format: bedrock/{regionPrefix}.anthropic.{model}-v{N}:{rev}.
Examples:
bedrock/us.anthropic.claude-sonnet-4-5-v1:0— US-regionbedrock/eu.anthropic.claude-sonnet-4-5-v1:0— EU region (different inference profile)bedrock/global.anthropic.claude-opus-4-7-v1:0— cross-region routed
See AWS docs for the full list per region.
v1 limitations (documented)
- Non-streaming only (D302) — the full response arrives at once; chat UX with token-by-token rendering needs v1.x or the escape hatch via
@aws-sdk/client-bedrock-runtime. - Bearer auth only (D286) — no SigV4 in v1 (D298). Customers in IAM-role-only environments wait for v1.x.
- InvokeModel only (D289) — Converse API deferred. Preserves Anthropic prompt-caching + extended-thinking fields.
- Claude only — Llama / Cohere / Mistral via Bedrock Converse deferred (D296).
- Bearer auth doesn't cover Bedrock Agents / Knowledge Bases / Computer Use (D282-style escape hatch via
adapter.getApp()not yet wired here).
Code
/**
* AWS Bedrock demo (Adoption Roadmap #8; ADRs D286-D302).
*
* Sends a one-shot prompt to Claude on Bedrock and prints the reply.
* Uses Bearer auth (no SigV4). Non-streaming in v1 (D302).
*
* Run:
* cp .env.example .env # fill AWS_BEARER_TOKEN_BEDROCK
* pnpm install
* pnpm run run
*/
import { Agent } from "@theokit/sdk";
const token = process.env.AWS_BEARER_TOKEN_BEDROCK;
const modelId =
process.env.BEDROCK_MODEL ?? "bedrock/us.anthropic.claude-sonnet-4-5-v1:0";
if (token === undefined || token.length === 0) {
console.log(
"[bedrock] AWS_BEARER_TOKEN_BEDROCK not set — SDK will auto-generate " +
"via @aws/bedrock-token-generator + standard AWS credential chain.",
);
}
const agent = await Agent.create({
apiKey: token ?? "__bedrock_lazy_token__",
model: { id: modelId },
local: { cwd: process.cwd(), sandboxOptions: { enabled: false } as const },
name: "bedrock-bot",
systemPrompt: "You are a concise assistant. Reply in one short sentence.",
});
const question = process.argv[2] ?? "Qual é a capital do Brasil?";
console.log(`[bedrock] model=${modelId} question="${question}"`);
const run = await agent.send(question);
const result = await run.wait();
const errInfo = (result as { error?: { name?: string; message?: string; metadata?: unknown } }).error;
console.log(`[bedrock] status=${result.status} resultLen=${(result.result ?? "").length}`);
if (errInfo !== undefined) {
console.log(`[bedrock] error.name=${errInfo.name}`);
console.log(`[bedrock] error.message=${errInfo.message}`);
console.log(`[bedrock] error.metadata=${JSON.stringify(errInfo.metadata, null, 2)}`);
}
console.log(result.result ?? "(no reply)");
await agent.dispose();
Run
cd examples/bedrock-bot
cp .env.example .env # fill in keys
pnpm install
pnpm run run