@plumbus/ai-bedrock 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,30 @@
1
+ # @plumbus/ai-bedrock
2
+
3
+ ## 0.1.0 — 2026-08-12 — initial release
4
+
5
+ ### Added
6
+
7
+ - **`createBedrockAdapter`** — Amazon Bedrock Runtime adapter for Plumbus AI: Converse / ConverseStream chat, Titan embeddings via `InvokeModel`, multi-turn tool use.
8
+ - **Package-owned pricing** — **production:** mount `pricingFilePath` / `AI_BEDROCK_PRICING_FILE` keyed by Bedrock family ids. **Dev:** optional auto-download from AWS Price List (best-effort id extraction + limited generative display inference — **not** a hardcoded forever model catalog). Attaches `cost` on complete / stream `done` / embed (Bedrock APIs return tokens only).
9
+ - **Optional peer of `@plumbus/core` `0.6.x`** — **runtime floor ≥ 0.6.16** (provider slot, env discovery, adapter `cost` preference, agent wiring v13). Wire via env (`AI_BEDROCK_REGION`) or `createAIService({ providers: { bedrock } })`.
10
+ - **Structured outputs (opt-in)** — `structuredOutputs: 'native'` forwards `responseSchema` as Converse `outputConfig.textFormat`. Default `'off'` keeps core's validate-and-repair loop, since `outputConfig` support is model-dependent.
11
+ - **Embeddings** — Titan *and* Cohere request/response shapes (`embeddingInputType`, default `search_document`), with bounded parallelism (`embedConcurrency`, default 4) and input order preserved.
12
+ - **Pricing tiers** — regional cache read/write SKUs (`cacheReadPerMTok` / `cacheWritePerMTok`) and global inference-profile SKUs (`globalInputPerMTok` / `globalOutputPerMTok`) are parsed and honored; all optional and additive to pricing file `version: 1`.
13
+ - **Agent instructions** — `instructions/framework.md`, `instructions/pricing.md` (Price List URLs, curl, normalize, ConfigMap, troubleshooting), `instructions/README.md`.
14
+ - **Concept docs** — `docs/ai/bedrock.md` (Runtime vs Mantle, IAM, tools/streaming, pricing, production checklist).
15
+ - **Live smoke** — `examples/ai-bedrock-smoke` (Mantle OpenAI-compatible vs Runtime IAM/bearer).
16
+
17
+ ### Notes
18
+
19
+ - ConverseStream sends the same `toolConfig` as Converse and accumulates partial tool-use JSON across content-block deltas.
20
+ - `toolChoice: 'none'` omits `toolConfig` (Bedrock has no true none); `'auto'` / unset omits just the `toolChoice` field, since support for it is model-dependent.
21
+ - A run of consecutive `tool` messages (parallel tool calls) is coalesced into a **single** Converse user turn carrying every `toolResult`, as the API requires.
22
+ - ConverseStream failures that arrive as stream **events** (`throttlingException`, `internalServerException`, `modelStreamErrorException`, `validationException`, `serviceUnavailableException`) emit a stream `error` event instead of a truncated `done`.
23
+ - Cache tokens are billed **additively**: Bedrock excludes `cacheReadInputTokens` / `cacheWriteInputTokens` from `inputTokens`, so they are added on top (approximate 0.1× read / 1.25× write multipliers) rather than carved out of it.
24
+ - Models with no known rate return **no `cost` field** (never `0`), so core falls back to `calculateModelCost` instead of recording unpriced spend as free.
25
+ - Pricing lookup falls back from `amazon.nova-lite-v1` to `amazon.nova-lite`, so both family-key shapes resolve. First-party Titan embedding rows are keyed from the `titanModel` offer attribute.
26
+ - Offer rows whose unit is not a token unit (`hour`, `image`, `1M TPM Hour`, …) are skipped rather than assumed to be per-1M-token prices, and the **lowest** standard-tier SKU wins so rates do not depend on JSON key order.
27
+ - `content_filtered` / `guardrail_intervened` map to `refusal` and `model_context_window_exceeded` to `length`, instead of falling through to `other`.
28
+ - `listModels` honors the `AIProviderAdapter` contract: warn once and return `[]` rather than throwing. Inference still fails loudly on a missing/invalid pricing file.
29
+ - Failed Price List downloads back off 5 minutes; TTL refreshes happen in the background while the previous rates keep serving.
30
+ - Do not confuse Bedrock **Runtime** (this package) with Bedrock **Mantle** (`createOpenAIAdapter` + Mantle base URL).
package/README.md ADDED
@@ -0,0 +1,161 @@
1
+ # @plumbus/ai-bedrock
2
+
3
+ > **Amazon Bedrock for [Plumbus](https://github.com/plumbus-framework/plumbus) AI.** Optional AWS SDK adapter for Converse chat, ConverseStream, Titan embeddings, and **package-owned USD cost** from the AWS Price List (or a mounted pricing file).
4
+
5
+ [![npm](https://img.shields.io/npm/v/@plumbus/ai-bedrock.svg)](https://www.npmjs.com/package/@plumbus/ai-bedrock)
6
+ [![license](https://img.shields.io/npm/l/@plumbus/ai-bedrock.svg)](https://github.com/plumbus-framework/plumbus/blob/main/LICENSE)
7
+ [![peer: @plumbus/core 0.6.x](https://img.shields.io/badge/peer-%40plumbus%2Fcore%200.6.x-blue)](https://www.npmjs.com/package/@plumbus/core)
8
+
9
+ ## What is this?
10
+
11
+ [Plumbus](https://github.com/plumbus-framework/plumbus) is an **AI-native, contract-driven TypeScript application framework**. Apps call `ctx.ai` / `definePrompt` against provider adapters registered on `createAIService`.
12
+
13
+ `@plumbus/ai-bedrock` is the **Amazon Bedrock Runtime adapter**. It wraps `@aws-sdk/client-bedrock-runtime` (Converse / ConverseStream / InvokeModel), maps Plumbus tool calling and usage into Bedrock shapes, and computes cost USD because Bedrock responses return **token counts only**.
14
+
15
+ If you only need Bedrock Mantle’s OpenAI-compatible HTTP API (`bedrock-mantle.*.api.aws`), use core’s `createOpenAIAdapter` with `OPENAI_BASE_URL` — that path does **not** use this package.
16
+
17
+ ## Why?
18
+
19
+ Bedrock needs the AWS SDK (SigV4 / IAM credential chain, Converse message shapes, InvokeModel embeddings). Shipping that inside `@plumbus/core` would:
20
+
21
+ - Pull AWS SDK weight into every app that never touches Bedrock
22
+ - Force core releases for every Bedrock SDK bump
23
+ - Mix IAM auth with the API-key OpenAI/Anthropic adapters
24
+
25
+ An opt-in peer keeps core lean while giving AWS shops a first-class `provider: 'bedrock'` path.
26
+
27
+ ## What you get
28
+
29
+ | Surface | What it does |
30
+ |---|---|
31
+ | `createBedrockAdapter()` | `AIProviderAdapter` for `createAIService({ providers: { bedrock } })`. |
32
+ | Converse / ConverseStream | Chat complete + stream with system, tools, named `toolChoice`, multi-turn tool results. |
33
+ | InvokeModel embeddings | Titan (default `amazon.titan-embed-text-v2:0`) and Cohere bodies; bounded concurrency, order preserved. |
34
+ | Structured outputs | Opt-in `structuredOutputs: 'native'` → Converse `outputConfig`; default uses core validate-and-repair. |
35
+ | Package-owned pricing | Auto-download AWS Price List by region, or `pricingFilePath` / `AI_BEDROCK_PRICING_FILE`. |
36
+ | `parseAwsOfferRates` / pricing helpers | Normalize offer JSON → mounted ConfigMap rates for k8s. |
37
+ | Env discovery (via core) | After install: `AI_BEDROCK_REGION`, `AI_BEDROCK_MODEL`, `AI_BEDROCK_PRICING_FILE`, … |
38
+
39
+ ## When to use this vs alternatives
40
+
41
+ | You want | Reach for |
42
+ |---|---|
43
+ | OpenAI / Anthropic HTTP APIs | Built-in adapters in `@plumbus/core` |
44
+ | Bedrock **Mantle** OpenAI-compatible endpoint | `createOpenAIAdapter` + `OPENAI_BASE_URL=https://bedrock-mantle.<region>.api.aws/v1` |
45
+ | Bedrock **Runtime** Converse + Titan embed + IAM/IRSA cost ledger | **`@plumbus/ai-bedrock`** (this package) |
46
+
47
+ ## Status
48
+
49
+ Optional peer of `@plumbus/core` (version-locked **`0.1.x`**; required peer `@plumbus/core` **`0.6.x`**). **Runtime floor:** `@plumbus/core` **≥ 0.6.16** (Bedrock provider slot, env discovery, adapter-supplied `cost`, agent wiring v13). Install alone is not enough until the adapter is registered (env discovery or `createBedrockAdapter`).
50
+
51
+ ## Install
52
+
53
+ ```bash
54
+ pnpm add @plumbus/ai-bedrock
55
+ ```
56
+
57
+ Peer (copy literally): `@plumbus/core` `0.6.x`. See `packages/plumbus-core/instructions/peer-dependencies.md`.
58
+
59
+ If agent wiring predates Bedrock instructions, refresh:
60
+
61
+ ```bash
62
+ plumbus init --patch --agent agents-md
63
+ plumbus doctor
64
+ ```
65
+
66
+ ## Quick start
67
+
68
+ ```typescript
69
+ import { createAIService } from '@plumbus/core';
70
+ import { createBedrockAdapter } from '@plumbus/ai-bedrock';
71
+
72
+ const ai = createAIService({
73
+ defaultProvider: 'bedrock',
74
+ providers: {
75
+ bedrock: createBedrockAdapter({
76
+ region: 'us-east-1',
77
+ // recommended in Kubernetes / locked-down networks:
78
+ // pricingFilePath: '/config/bedrock-pricing.json',
79
+ }),
80
+ },
81
+ });
82
+ ```
83
+
84
+ Or via env (after install):
85
+
86
+ ```bash
87
+ AI_DEFAULT_PROVIDER=bedrock
88
+ AI_BEDROCK_REGION=us-east-1
89
+ AI_BEDROCK_MODEL=anthropic.claude-sonnet-4-5-20250929-v1:0
90
+ AI_BEDROCK_EMBEDDING_MODEL=amazon.titan-embed-text-v2:0
91
+ # containers (recommended):
92
+ # AI_BEDROCK_PRICING_FILE=/config/bedrock-pricing.json
93
+ # optional: AI_BEDROCK_ENABLED=1 with AWS_REGION instead of AI_BEDROCK_REGION
94
+ # optional: AI_BEDROCK_REQUEST_TIMEOUT / AI_BEDROCK_PRICING_TTL_MS
95
+ ```
96
+
97
+ Then use the normal Plumbus AI surface:
98
+
99
+ ```typescript
100
+ // Chat / structured generate (prompt model.provider: 'bedrock')
101
+ await ctx.ai.generateWithUsage({ prompt: 'classifyTicket', input: { ticketText } });
102
+
103
+ // Tools — same as OpenAI/Anthropic; Converse toolConfig under the hood
104
+ import { runToolLoop } from '@plumbus/core';
105
+ await runToolLoop(ctx.ai, { prompt: 'assistant.turn', input: { userMessage }, tools, execute });
106
+
107
+ // Embeddings — wire adapter into createRAGPipeline({ provider: bedrock }), then:
108
+ await ctx.ai.retrieve({ query: 'refund policy' });
109
+ ```
110
+
111
+ **Auth (Runtime):** default AWS credential chain (env keys, shared config, IRSA, instance role). Optional `AWS_BEARER_TOKEN_BEDROCK` is honored by the AWS SDK when set. There is no separate “Bedrock API key” field on `createBedrockAdapter`.
112
+
113
+ ## Pricing (important)
114
+
115
+ Bedrock API responses include **token usage only**, not USD. This package loads rates and attaches `cost` for the ledger.
116
+
117
+ | Mode | When to use |
118
+ |------|-------------|
119
+ | **`pricingFilePath` / `AI_BEDROCK_PRICING_FILE`** | **Required for reliable production / k8s** — mount normalized JSON keyed by family ids |
120
+ | **Auto-download by `region`** | Local / best-effort only — AWS Price List has no stable modelId join; unkeyed models report **no cost** (field omitted, never `$0`) |
121
+
122
+ Do **not** alias Claude-on-Bedrock to core’s Anthropic `MODEL_PRICING` rows — regional Bedrock rates diverge. Do **not** expect this package to hardcode every future AWS model name.
123
+
124
+ Full curl, normalize script, ConfigMap sketch: **[instructions/pricing.md](./instructions/pricing.md)**.
125
+
126
+ ## Key gotchas
127
+
128
+ - **Runtime ≠ Mantle** — console `OPENAI_API_KEY` + Mantle base URL is OpenAI-compatible HTTP, not this package.
129
+ - **Model access** — Converse fails with `AccessDenied` until the account enables the model (and Anthropic use-case forms where required).
130
+ - **Embeddings** — Converse does not embed; use InvokeModel (Titan) via `createRAGPipeline({ provider })` + `ctx.ai.retrieve` / `ragPipeline.ingest`. There is no `ctx.ai.embed`. `plumbus rag ingest` does not auto-select Bedrock. Mantle typically has no embeddings.
131
+ - **Tools** — use `runToolLoop` / `generateWithUsage({ tools })`; do not call the Bedrock SDK. Stream accumulates partial tool JSON. Parallel tool results are coalesced into the single user turn Converse requires.
132
+ - **`toolChoice: 'none'`** — Bedrock has no true none; Plumbus omits `toolConfig` entirely. `'auto'` omits just the `toolChoice` field (model-dependent support).
133
+ - **Missing pricing file** — file mode throws on first call; auto-download failure warns, leaves cost unknown, and backs off 5 minutes before retrying.
134
+ - **Unmapped / unkeyed models** — inference works; **no `cost` field** is set until the pricing file has an explicit family-key row (auto-download is best-effort, not a complete AWS catalog). Core then falls back to its own catalog rather than recording the call as free.
135
+ - **IAM** — Converse itself requires `bedrock:InvokeModel`; do not scope that action to embedding models only.
136
+ - **Wiring** — after install, `plumbus init --patch` (core ≥ 0.6.16 / wiring v13) so agents see `instructions/`.
137
+
138
+ ## Documentation / Agent recipes
139
+
140
+ - **Concept docs:** [`docs/ai/bedrock.md`](../../docs/ai/bedrock.md) · [`docs/ai/ai-integration.md`](../../docs/ai/ai-integration.md)
141
+ - **Live smoke (monorepo):** [`examples/ai-bedrock-smoke`](../../examples/ai-bedrock-smoke)
142
+ - **Agent recipes** (after install, open these exact paths):
143
+ - `node_modules/@plumbus/ai-bedrock/instructions/README.md`
144
+ - `node_modules/@plumbus/ai-bedrock/instructions/framework.md`
145
+ - `node_modules/@plumbus/ai-bedrock/instructions/pricing.md`
146
+
147
+ ## The Plumbus ecosystem
148
+
149
+ `@plumbus/ai-bedrock` is one package in the Plumbus framework. For the full list of packages and when to use each, see the [Plumbus monorepo README](https://github.com/plumbus-framework/plumbus#packages).
150
+
151
+ ## Links
152
+
153
+ - **Plumbus framework** — [github.com/plumbus-framework/plumbus](https://github.com/plumbus-framework/plumbus)
154
+ - **Parent / peer** — [`@plumbus/core`](../plumbus-core/)
155
+ - **Full documentation** — [docs/](../../docs/) in the monorepo
156
+ - **Top-level README** — [`../../README.md`](../../README.md)
157
+ - **Issues** — [github.com/plumbus-framework/plumbus/issues](https://github.com/plumbus-framework/plumbus/issues)
158
+
159
+ ## License
160
+
161
+ MIT