llm-stream-assemble 1.3.5 → 1.4.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/README.md +74 -13
- package/dist/adapters/bedrock.cjs +413 -0
- package/dist/adapters/bedrock.cjs.map +1 -0
- package/dist/adapters/bedrock.d.cts +15 -0
- package/dist/adapters/bedrock.d.ts +15 -0
- package/dist/adapters/bedrock.js +411 -0
- package/dist/adapters/bedrock.js.map +1 -0
- package/dist/index.cjs +349 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +349 -1
- package/dist/index.js.map +1 -1
- package/package.json +11 -2
package/README.md
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
# llm-stream-assemble
|
|
2
2
|
|
|
3
|
-

|
|
4
4
|

|
|
5
5
|

|
|
6
|
-

|
|
7
7
|
[](https://github.com/01laky/llm-stream-assemble/actions/workflows/ci.yml)
|
|
8
|
-

|
|
9
9
|
|
|
10
10
|
**One typed event model for every LLM stream** — text, tool calls, reasoning, JSON, usage, refusals, errors, and non-streaming responses.
|
|
11
11
|
|
|
12
|
-
> A zero-dependency TypeScript layer
|
|
12
|
+
> A zero-dependency TypeScript layer between raw LLM provider bytes and your app: six built-in adapters, thirteen host presets, and a single StreamEvent model for text, tools, reasoning, JSON, and lifecycle — from Ollama to Azure to Bedrock to Cloudflare Workers AI.
|
|
13
13
|
|
|
14
14
|
Turn provider SSE fragments into typed events — **not another `+=` loop**.
|
|
15
15
|
|
|
16
|
-
**Status:** Stable `1.
|
|
16
|
+
**Status:** Stable `1.4.0`. Six built-in adapters, thirteen OpenAI-compatible host presets (including **Azure OpenAI** and **Cloudflare Workers AI**), transforms, replay helpers, and examples are production-ready. Pin semver ranges as usual and review [CHANGELOG.md](./CHANGELOG.md) before major upgrades.
|
|
17
17
|
|
|
18
18
|
---
|
|
19
19
|
|
|
@@ -31,6 +31,7 @@ Turn provider SSE fragments into typed events — **not another `+=` loop**.
|
|
|
31
31
|
- [Documentation](#documentation)
|
|
32
32
|
- [How this compares](#how-this-compares)
|
|
33
33
|
- [Examples](#examples)
|
|
34
|
+
- [Integration cookbook](#integration-cookbook)
|
|
34
35
|
- [Usage guides](#usage-guides)
|
|
35
36
|
- [Transforms & replay](#transforms--replay)
|
|
36
37
|
- [Examples & proxy safety](#examples--proxy-safety)
|
|
@@ -137,13 +138,14 @@ Diagram sources: [`docs/img/`](./docs/img/) (Mermaid `.mmd` + committed SVG). Re
|
|
|
137
138
|
|
|
138
139
|
## Providers at a glance
|
|
139
140
|
|
|
140
|
-
| Adapter | Provider / API | Import
|
|
141
|
-
| --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
142
|
-
| `openaiChatAdapter()` | OpenAI Chat Completions | `llm-stream-assemble`
|
|
143
|
-
| `openaiCompatibleAdapter({ provider })` | Groq, DeepSeek, Mistral, Ollama, LM Studio, Together, Fireworks, OpenRouter, Perplexity, xAI, **Azure OpenAI**, **Cloudflare Workers AI**, generic | `llm-stream-assemble`
|
|
144
|
-
| `anthropicAdapter()` | Anthropic Messages | `llm-stream-assemble`
|
|
145
|
-
| `openaiResponsesAdapter()` | OpenAI Responses API | `llm-stream-assemble`
|
|
146
|
-
| `geminiAdapter()` | Google AI Gemini | `llm-stream-assemble` or `/adapters/gemini`
|
|
141
|
+
| Adapter | Provider / API | Import |
|
|
142
|
+
| --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- |
|
|
143
|
+
| `openaiChatAdapter()` | OpenAI Chat Completions | `llm-stream-assemble` |
|
|
144
|
+
| `openaiCompatibleAdapter({ provider })` | Groq, DeepSeek, Mistral, Ollama, LM Studio, Together, Fireworks, OpenRouter, Perplexity, xAI, **Azure OpenAI**, **Cloudflare Workers AI**, generic | `llm-stream-assemble` |
|
|
145
|
+
| `anthropicAdapter()` | Anthropic Messages | `llm-stream-assemble` |
|
|
146
|
+
| `openaiResponsesAdapter()` | OpenAI Responses API | `llm-stream-assemble` |
|
|
147
|
+
| `geminiAdapter()` | Google AI Gemini | `llm-stream-assemble` or `/adapters/gemini` |
|
|
148
|
+
| `bedrockAdapter()` | AWS Bedrock Converse / ConverseStream | `llm-stream-assemble` or `/adapters/bedrock` |
|
|
147
149
|
|
|
148
150
|
Full feature flags and quirks: [compatibility matrix](./docs/compatibility.md).
|
|
149
151
|
|
|
@@ -199,6 +201,7 @@ Pick an adapter in ~30 seconds:
|
|
|
199
201
|
- **OpenAI Responses API** → `openaiResponsesAdapter()`
|
|
200
202
|
- **Anthropic Messages** → `anthropicAdapter()`
|
|
201
203
|
- **Google Gemini** → `geminiAdapter()`
|
|
204
|
+
- **AWS Bedrock ConverseStream** → `bedrockAdapter()` (decoded JSON per event — see [Bedrock Usage](#bedrock-usage))
|
|
202
205
|
- **Groq, Ollama, Azure, Cloudflare, OpenRouter, …** → `openaiCompatibleAdapter({ provider })`
|
|
203
206
|
- **Non-streaming JSON body** → `assembleResponse(body, adapter)`
|
|
204
207
|
- **React chat UI / full agent framework** → not this package — see [comparison](./docs/comparison.md)
|
|
@@ -212,6 +215,7 @@ Pick an adapter in ~30 seconds:
|
|
|
212
215
|
- [Adapter author guide](./docs/adapter-guide.md)
|
|
213
216
|
- [Performance & runtime behavior](./docs/performance.md)
|
|
214
217
|
- [Edge-case showcase](./docs/edge-cases.md)
|
|
218
|
+
- [Integration cookbook](./docs/integration-cookbook.md)
|
|
215
219
|
- [How this compares](./docs/comparison.md)
|
|
216
220
|
- [FAQ](./docs/faq.md)
|
|
217
221
|
- [Architecture diagrams](./docs/img/README.md)
|
|
@@ -269,6 +273,10 @@ for await (const event of assembleStream(response.body!, adapter)) {
|
|
|
269
273
|
|
|
270
274
|
→ [`examples/node-fetch/gemini.ts`](./examples/node-fetch/gemini.ts) · Usage: [Gemini](#gemini-usage)
|
|
271
275
|
|
|
276
|
+
### AWS Bedrock
|
|
277
|
+
|
|
278
|
+
→ [`examples/node-fetch/bedrock.ts`](./examples/node-fetch/bedrock.ts) · Usage: [Bedrock](#bedrock-usage) · Decode helper: [`examples/bedrock/README.md`](./examples/bedrock/README.md)
|
|
279
|
+
|
|
272
280
|
### Streaming JSON (structured output)
|
|
273
281
|
|
|
274
282
|
```ts
|
|
@@ -299,13 +307,17 @@ Stream `text.delta` into your renderer — this library does **not** parse markd
|
|
|
299
307
|
|
|
300
308
|
→ [`examples/node-fetch/replay-fixture.ts`](./examples/node-fetch/replay-fixture.ts)
|
|
301
309
|
|
|
310
|
+
### Integration cookbook
|
|
311
|
+
|
|
312
|
+
Wire unified events into **Hono**, **Express**, **Cloudflare Workers**, **LiteLLM**, **Next.js App Router**, AI SDK mapping, and LangChain callbacks — [`examples/integrations/`](./examples/integrations/) · **[Full cookbook →](./docs/integration-cookbook.md)**
|
|
313
|
+
|
|
302
314
|
---
|
|
303
315
|
|
|
304
316
|
## Usage guides
|
|
305
317
|
|
|
306
318
|
### Core Usage
|
|
307
319
|
|
|
308
|
-
The core pipeline works with any adapter that emits `RawChunk[]`, including the built-in OpenAI Chat, OpenAI-compatible, Anthropic Messages, OpenAI Responses,
|
|
320
|
+
The core pipeline works with any adapter that emits `RawChunk[]`, including the built-in OpenAI Chat, OpenAI-compatible, Anthropic Messages, OpenAI Responses, Google Gemini, and AWS Bedrock adapters:
|
|
309
321
|
|
|
310
322
|
```ts
|
|
311
323
|
import { assembleFromPayloads, type StreamAdapter } from "llm-stream-assemble";
|
|
@@ -545,6 +557,54 @@ Subpath import: `import { geminiAdapter } from "llm-stream-assemble/adapters/gem
|
|
|
545
557
|
|
|
546
558
|
Vertex AI and the Interactions API are out of scope for this adapter; see [compatibility matrix](./docs/compatibility.md).
|
|
547
559
|
|
|
560
|
+
### Bedrock Usage
|
|
561
|
+
|
|
562
|
+
`bedrockAdapter()` parses **decoded** AWS Bedrock **ConverseStream** JSON events — one ConverseStream envelope object per `parseChunk` call. Create one adapter instance per request/stream.
|
|
563
|
+
|
|
564
|
+
Bedrock streaming responses are often `application/vnd.amazon.eventstream` (binary). **Decode EventStream bytes in your app, AWS SDK, or the example helper** before assembly — this library does not sign requests or parse binary framing.
|
|
565
|
+
|
|
566
|
+
```
|
|
567
|
+
Bedrock Runtime → EventStream bytes → [SDK or decode helper] → JSON strings
|
|
568
|
+
→ bedrockAdapter().parseChunk / assembleFromPayloads / assembleStream → StreamEvent[]
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
**Recommended path:** use `@aws-sdk/client-bedrock-runtime` `ConverseStreamCommand`, iterate the async stream, `JSON.stringify` each event object, and feed lines to `assembleFromPayloads`. See [`examples/bedrock/README.md`](./examples/bedrock/README.md) and [`examples/node-fetch/bedrock.ts`](./examples/node-fetch/bedrock.ts).
|
|
572
|
+
|
|
573
|
+
```ts
|
|
574
|
+
import { assembleFromPayloads, bedrockAdapter } from "llm-stream-assemble";
|
|
575
|
+
|
|
576
|
+
async function* decodedConverseEvents(sdkStream: AsyncIterable<Record<string, unknown>>) {
|
|
577
|
+
for await (const event of sdkStream) {
|
|
578
|
+
yield JSON.stringify(event);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
for await (const event of assembleFromPayloads(
|
|
583
|
+
decodedConverseEvents(converseStream),
|
|
584
|
+
bedrockAdapter({ modelFamily: "auto" }),
|
|
585
|
+
)) {
|
|
586
|
+
if (event.type === "text.delta") process.stdout.write(event.text);
|
|
587
|
+
if (event.type === "tool_call.done") console.log(event.name, event.args);
|
|
588
|
+
}
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
**`modelFamily`** hints which ConverseStream dialect to prefer when envelopes overlap:
|
|
592
|
+
|
|
593
|
+
| Value | When to use |
|
|
594
|
+
| --------------- | ----------------------------------------------------------------- |
|
|
595
|
+
| `"auto"` | Default — structural detection from payload shape |
|
|
596
|
+
| `"anthropic"` | Claude on Bedrock — reasoning deltas, Anthropic-style tool blocks |
|
|
597
|
+
| `"nova"` | Amazon Nova models |
|
|
598
|
+
| `"openai-like"` | Llama and other OpenAI-shaped delta fields |
|
|
599
|
+
|
|
600
|
+
Use `bedrockAdapter({ jsonMode: true })` when structured JSON text blocks should map to `json.*` instead of `text.*`. Guardrail interventions map to `finish` with `content_filter`; trace details remain in `metadata.raw`.
|
|
601
|
+
|
|
602
|
+
**Environment variables** for live smoke and examples: `AWS_REGION`, `BEDROCK_MODEL_ID`, plus standard AWS credential chain (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_PROFILE`, SSO). IAM and SigV4 signing stay outside this library.
|
|
603
|
+
|
|
604
|
+
Subpath import: `import { bedrockAdapter } from "llm-stream-assemble/adapters/bedrock"`.
|
|
605
|
+
|
|
606
|
+
Worker proxy recipe: [`examples/integrations/bedrock-worker-proxy.ts`](./examples/integrations/bedrock-worker-proxy.ts). EventStream decode helper (examples only): [`examples/bedrock/decode-event-stream.ts`](./examples/bedrock/decode-event-stream.ts).
|
|
607
|
+
|
|
548
608
|
---
|
|
549
609
|
|
|
550
610
|
## Transforms & replay
|
|
@@ -617,6 +677,7 @@ for await (const event of assembleFromFile(
|
|
|
617
677
|
| [`examples/node-fetch/xai.ts`](./examples/node-fetch/xai.ts) | xAI Grok streaming |
|
|
618
678
|
| [`examples/node-fetch/anthropic.ts`](./examples/node-fetch/anthropic.ts) | Anthropic Messages |
|
|
619
679
|
| [`examples/node-fetch/gemini.ts`](./examples/node-fetch/gemini.ts) | Google Gemini SSE |
|
|
680
|
+
| [`examples/node-fetch/bedrock.ts`](./examples/node-fetch/bedrock.ts) | AWS Bedrock ConverseStream (decoded JSON) |
|
|
620
681
|
| [`examples/node-fetch/replay-fixture.ts`](./examples/node-fetch/replay-fixture.ts) | Local fixture replay |
|
|
621
682
|
| [`examples/proxy-safety/`](./examples/proxy-safety/) | Proxy + browser client patterns |
|
|
622
683
|
|
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/adapters/utils.ts
|
|
4
|
+
function isRecord(value) {
|
|
5
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6
|
+
}
|
|
7
|
+
function asString(value) {
|
|
8
|
+
return typeof value === "string" ? value : void 0;
|
|
9
|
+
}
|
|
10
|
+
function asNumber(value) {
|
|
11
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
12
|
+
}
|
|
13
|
+
function optionalRawChunk(input) {
|
|
14
|
+
return Object.fromEntries(
|
|
15
|
+
Object.entries(input).filter(([, value]) => value !== void 0)
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
function prefixedAdapterError(feature, message) {
|
|
19
|
+
return adapterScopedError(feature, message);
|
|
20
|
+
}
|
|
21
|
+
function createStreamAdapter(config) {
|
|
22
|
+
return {
|
|
23
|
+
parseChunk(raw) {
|
|
24
|
+
return config.parser.parseChunk(raw);
|
|
25
|
+
},
|
|
26
|
+
parseResponse(body) {
|
|
27
|
+
return config.parseResponse(body, config.options);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function parseAdapterJSON(raw, feature) {
|
|
32
|
+
try {
|
|
33
|
+
return JSON.parse(raw);
|
|
34
|
+
} catch (error) {
|
|
35
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
36
|
+
throw prefixedAdapterError(feature, message);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// src/adapters/errors.ts
|
|
41
|
+
function libraryError(message) {
|
|
42
|
+
return new Error(`llm-stream-assemble: ${message}`);
|
|
43
|
+
}
|
|
44
|
+
function adapterScopedError(scope, message) {
|
|
45
|
+
return new Error(`llm-stream-assemble: ${scope}: ${message}`);
|
|
46
|
+
}
|
|
47
|
+
function providerErrorChunks(error, recoverable = false) {
|
|
48
|
+
return [
|
|
49
|
+
{ kind: "provider-error", error, recoverable },
|
|
50
|
+
{ kind: "finish", reason: "error" }
|
|
51
|
+
];
|
|
52
|
+
}
|
|
53
|
+
function providerErrorChunksFromPayload(errorPayload, scope, recoverable, fallbackMessage) {
|
|
54
|
+
const message = asString(errorPayload.message) ?? fallbackMessage;
|
|
55
|
+
const error = adapterScopedError(scope, message);
|
|
56
|
+
Object.defineProperty(error, "raw", {
|
|
57
|
+
value: errorPayload,
|
|
58
|
+
enumerable: false
|
|
59
|
+
});
|
|
60
|
+
return providerErrorChunks(error, recoverable);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// src/adapters/bedrock.ts
|
|
64
|
+
var EXCEPTION_KEYS = [
|
|
65
|
+
"internalServerException",
|
|
66
|
+
"modelStreamErrorException",
|
|
67
|
+
"validationException",
|
|
68
|
+
"throttlingException",
|
|
69
|
+
"serviceUnavailableException"
|
|
70
|
+
];
|
|
71
|
+
function bedrockAdapter(options = {}) {
|
|
72
|
+
const parser = new BedrockStreamParser(options);
|
|
73
|
+
return createStreamAdapter({
|
|
74
|
+
parser,
|
|
75
|
+
parseResponse,
|
|
76
|
+
options
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
var BedrockStreamParser = class {
|
|
80
|
+
constructor(options) {
|
|
81
|
+
this.options = options;
|
|
82
|
+
}
|
|
83
|
+
options;
|
|
84
|
+
messageStarted = false;
|
|
85
|
+
blocks = /* @__PURE__ */ new Map();
|
|
86
|
+
parseChunk(raw) {
|
|
87
|
+
const trimmed = raw.trim();
|
|
88
|
+
if (trimmed.length === 0 || trimmed === "[DONE]") return [];
|
|
89
|
+
const payload = parseAdapterJSON(trimmed, "bedrockAdapter.parseChunk");
|
|
90
|
+
if (!isRecord(payload)) {
|
|
91
|
+
throw libraryError("bedrockAdapter.parseChunk expected a JSON object");
|
|
92
|
+
}
|
|
93
|
+
for (const key of EXCEPTION_KEYS) {
|
|
94
|
+
const exception = payload[key];
|
|
95
|
+
if (isRecord(exception)) {
|
|
96
|
+
return providerErrorChunksFromPayload(
|
|
97
|
+
exception,
|
|
98
|
+
"bedrockAdapter.parseChunk",
|
|
99
|
+
false,
|
|
100
|
+
`Bedrock ${key}`
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (payload.messageStart !== void 0) {
|
|
105
|
+
return this.messageStartChunks(payload.messageStart);
|
|
106
|
+
}
|
|
107
|
+
if (payload.contentBlockStart !== void 0) {
|
|
108
|
+
return this.contentBlockStartChunks(payload.contentBlockStart);
|
|
109
|
+
}
|
|
110
|
+
if (payload.contentBlockDelta !== void 0) {
|
|
111
|
+
return this.contentBlockDeltaChunks(payload.contentBlockDelta);
|
|
112
|
+
}
|
|
113
|
+
if (payload.contentBlockStop !== void 0) {
|
|
114
|
+
return this.contentBlockStopChunks(payload.contentBlockStop);
|
|
115
|
+
}
|
|
116
|
+
if (payload.messageStop !== void 0) {
|
|
117
|
+
return this.messageStopChunks(payload.messageStop);
|
|
118
|
+
}
|
|
119
|
+
if (payload.metadata !== void 0) {
|
|
120
|
+
return this.metadataChunks(payload.metadata);
|
|
121
|
+
}
|
|
122
|
+
return optionalMetadataRaw(payload);
|
|
123
|
+
}
|
|
124
|
+
messageStartChunks(value) {
|
|
125
|
+
if (!isRecord(value)) return [];
|
|
126
|
+
if (this.messageStarted) return [];
|
|
127
|
+
this.messageStarted = true;
|
|
128
|
+
const role = asString(value.role);
|
|
129
|
+
return [
|
|
130
|
+
{ kind: "message-start" },
|
|
131
|
+
...role ? [
|
|
132
|
+
optionalRawChunk({
|
|
133
|
+
kind: "metadata",
|
|
134
|
+
raw: { role }
|
|
135
|
+
})
|
|
136
|
+
] : []
|
|
137
|
+
];
|
|
138
|
+
}
|
|
139
|
+
contentBlockStartChunks(value) {
|
|
140
|
+
if (!isRecord(value)) return [];
|
|
141
|
+
const blockIndex = asNumber(value.contentBlockIndex) ?? 0;
|
|
142
|
+
const start = isRecord(value.start) ? value.start : void 0;
|
|
143
|
+
const toolUse = start && isRecord(start.toolUse) ? start.toolUse : void 0;
|
|
144
|
+
if (!toolUse) return [];
|
|
145
|
+
const id = asString(toolUse.toolUseId) ?? `bedrock:${blockIndex}`;
|
|
146
|
+
const name = asString(toolUse.name) ?? "unknown";
|
|
147
|
+
this.blocks.set(blockIndex, {
|
|
148
|
+
id,
|
|
149
|
+
name,
|
|
150
|
+
index: blockIndex,
|
|
151
|
+
open: true,
|
|
152
|
+
lastArgsJson: ""
|
|
153
|
+
});
|
|
154
|
+
return [
|
|
155
|
+
optionalRawChunk({
|
|
156
|
+
kind: "tool-start",
|
|
157
|
+
id,
|
|
158
|
+
name,
|
|
159
|
+
index: blockIndex,
|
|
160
|
+
choiceIndex: 0
|
|
161
|
+
})
|
|
162
|
+
];
|
|
163
|
+
}
|
|
164
|
+
contentBlockDeltaChunks(value) {
|
|
165
|
+
if (!isRecord(value)) return [];
|
|
166
|
+
const blockIndex = asNumber(value.contentBlockIndex) ?? 0;
|
|
167
|
+
const delta = isRecord(value.delta) ? value.delta : void 0;
|
|
168
|
+
if (!delta) return [];
|
|
169
|
+
const chunks = [];
|
|
170
|
+
const text = asString(delta.text);
|
|
171
|
+
if (text !== void 0 && text.length > 0) {
|
|
172
|
+
if (this.options.jsonMode) {
|
|
173
|
+
chunks.push({ kind: "json-delta", delta: text });
|
|
174
|
+
} else {
|
|
175
|
+
chunks.push({ kind: "text-delta", text, choiceIndex: 0 });
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const reasoning = delta.reasoningContent;
|
|
179
|
+
const reasoningText = reasoningTextFromDelta(reasoning, this.options.modelFamily);
|
|
180
|
+
if (reasoningText) {
|
|
181
|
+
chunks.push({ kind: "reasoning-delta", text: reasoningText, variant: "detail" });
|
|
182
|
+
}
|
|
183
|
+
const toolUse = isRecord(delta.toolUse) ? delta.toolUse : void 0;
|
|
184
|
+
if (toolUse) {
|
|
185
|
+
chunks.push(...this.toolInputDelta(blockIndex, toolUse));
|
|
186
|
+
}
|
|
187
|
+
return chunks;
|
|
188
|
+
}
|
|
189
|
+
toolInputDelta(blockIndex, toolUse) {
|
|
190
|
+
const state = this.blocks.get(blockIndex);
|
|
191
|
+
if (!state) return [];
|
|
192
|
+
const input = toolUse.input;
|
|
193
|
+
let delta;
|
|
194
|
+
if (typeof input === "string") {
|
|
195
|
+
delta = incrementalArgsDelta(state, input);
|
|
196
|
+
} else if (isRecord(input)) {
|
|
197
|
+
delta = incrementalArgsDelta(state, JSON.stringify(input));
|
|
198
|
+
}
|
|
199
|
+
if (!delta) return [];
|
|
200
|
+
return [
|
|
201
|
+
optionalRawChunk({
|
|
202
|
+
kind: "tool-args-delta",
|
|
203
|
+
id: state.id,
|
|
204
|
+
delta,
|
|
205
|
+
index: state.index,
|
|
206
|
+
choiceIndex: 0
|
|
207
|
+
})
|
|
208
|
+
];
|
|
209
|
+
}
|
|
210
|
+
contentBlockStopChunks(value) {
|
|
211
|
+
if (!isRecord(value)) return [];
|
|
212
|
+
const blockIndex = asNumber(value.contentBlockIndex) ?? 0;
|
|
213
|
+
const state = this.blocks.get(blockIndex);
|
|
214
|
+
if (!state?.open) return [];
|
|
215
|
+
state.open = false;
|
|
216
|
+
return [
|
|
217
|
+
optionalRawChunk({
|
|
218
|
+
kind: "tool-done",
|
|
219
|
+
id: state.id,
|
|
220
|
+
index: state.index,
|
|
221
|
+
choiceIndex: 0
|
|
222
|
+
})
|
|
223
|
+
];
|
|
224
|
+
}
|
|
225
|
+
messageStopChunks(value) {
|
|
226
|
+
if (!isRecord(value)) return [];
|
|
227
|
+
const stopReason = asString(value.stopReason) ?? "unknown";
|
|
228
|
+
const additional = value.additionalModelResponseFields;
|
|
229
|
+
const chunks = [];
|
|
230
|
+
chunks.push(
|
|
231
|
+
optionalRawChunk({
|
|
232
|
+
kind: "metadata",
|
|
233
|
+
raw: {
|
|
234
|
+
stopReason,
|
|
235
|
+
...additional !== void 0 ? { additionalModelResponseFields: additional } : {}
|
|
236
|
+
}
|
|
237
|
+
})
|
|
238
|
+
);
|
|
239
|
+
chunks.push({ kind: "finish", reason: mapStopReason(stopReason), choiceIndex: 0 });
|
|
240
|
+
return chunks;
|
|
241
|
+
}
|
|
242
|
+
metadataChunks(value) {
|
|
243
|
+
if (!isRecord(value)) return [];
|
|
244
|
+
const chunks = [];
|
|
245
|
+
const usage = usageChunk(value.usage);
|
|
246
|
+
if (usage) chunks.push(usage);
|
|
247
|
+
const metrics = value.metrics;
|
|
248
|
+
const trace = value.trace;
|
|
249
|
+
if (metrics !== void 0 || trace !== void 0) {
|
|
250
|
+
chunks.push(
|
|
251
|
+
optionalRawChunk({
|
|
252
|
+
kind: "metadata",
|
|
253
|
+
raw: { metrics, trace }
|
|
254
|
+
})
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
return chunks;
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
function parseResponse(body, options) {
|
|
261
|
+
if (!isRecord(body)) {
|
|
262
|
+
throw libraryError("bedrockAdapter.parseResponse expected a Converse response object");
|
|
263
|
+
}
|
|
264
|
+
for (const key of EXCEPTION_KEYS) {
|
|
265
|
+
const exception = body[key];
|
|
266
|
+
if (isRecord(exception)) {
|
|
267
|
+
return providerErrorChunksFromPayload(
|
|
268
|
+
exception,
|
|
269
|
+
"bedrockAdapter.parseResponse",
|
|
270
|
+
false,
|
|
271
|
+
`Bedrock ${key}`
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
const chunks = [];
|
|
276
|
+
const output = isRecord(body.output) ? body.output : void 0;
|
|
277
|
+
const message = output && isRecord(output.message) ? output.message : void 0;
|
|
278
|
+
if (message) {
|
|
279
|
+
chunks.push({ kind: "message-start" });
|
|
280
|
+
const role = asString(message.role);
|
|
281
|
+
if (role) {
|
|
282
|
+
chunks.push(optionalRawChunk({ kind: "metadata", raw: { role } }));
|
|
283
|
+
}
|
|
284
|
+
const content = Array.isArray(message.content) ? message.content : [];
|
|
285
|
+
let blockIndex = 0;
|
|
286
|
+
for (const block of content) {
|
|
287
|
+
if (!isRecord(block)) continue;
|
|
288
|
+
const text = asString(block.text);
|
|
289
|
+
if (text !== void 0 && text.length > 0) {
|
|
290
|
+
if (options.jsonMode) {
|
|
291
|
+
chunks.push({ kind: "json-delta", delta: text });
|
|
292
|
+
} else {
|
|
293
|
+
chunks.push({ kind: "text-delta", text, choiceIndex: 0 });
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
const toolUse = isRecord(block.toolUse) ? block.toolUse : void 0;
|
|
297
|
+
if (toolUse) {
|
|
298
|
+
const id = asString(toolUse.toolUseId) ?? `bedrock:${blockIndex}`;
|
|
299
|
+
const name = asString(toolUse.name) ?? "unknown";
|
|
300
|
+
chunks.push(
|
|
301
|
+
optionalRawChunk({
|
|
302
|
+
kind: "tool-start",
|
|
303
|
+
id,
|
|
304
|
+
name,
|
|
305
|
+
index: blockIndex,
|
|
306
|
+
choiceIndex: 0
|
|
307
|
+
})
|
|
308
|
+
);
|
|
309
|
+
const input = toolUse.input;
|
|
310
|
+
if (input !== void 0) {
|
|
311
|
+
const argsJson = typeof input === "string" ? input : JSON.stringify(input);
|
|
312
|
+
if (argsJson.length > 0) {
|
|
313
|
+
chunks.push(
|
|
314
|
+
optionalRawChunk({
|
|
315
|
+
kind: "tool-args-delta",
|
|
316
|
+
id,
|
|
317
|
+
delta: argsJson,
|
|
318
|
+
index: blockIndex,
|
|
319
|
+
choiceIndex: 0
|
|
320
|
+
})
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
chunks.push(
|
|
325
|
+
optionalRawChunk({
|
|
326
|
+
kind: "tool-done",
|
|
327
|
+
id,
|
|
328
|
+
index: blockIndex,
|
|
329
|
+
choiceIndex: 0
|
|
330
|
+
})
|
|
331
|
+
);
|
|
332
|
+
}
|
|
333
|
+
blockIndex += 1;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
const usage = usageChunk(body.usage);
|
|
337
|
+
if (usage) chunks.push(usage);
|
|
338
|
+
const stopReason = asString(body.stopReason);
|
|
339
|
+
if (stopReason) {
|
|
340
|
+
chunks.push({ kind: "finish", reason: mapStopReason(stopReason), choiceIndex: 0 });
|
|
341
|
+
} else if (!chunks.some((chunk) => chunk.kind === "finish")) {
|
|
342
|
+
chunks.push({ kind: "finish", reason: "stop" });
|
|
343
|
+
}
|
|
344
|
+
return chunks;
|
|
345
|
+
}
|
|
346
|
+
function reasoningTextFromDelta(reasoning, modelFamily) {
|
|
347
|
+
if (reasoning === void 0) return void 0;
|
|
348
|
+
if (typeof reasoning === "string") return reasoning.length > 0 ? reasoning : void 0;
|
|
349
|
+
if (!isRecord(reasoning)) return void 0;
|
|
350
|
+
const text = asString(reasoning.text);
|
|
351
|
+
if (text !== void 0 && text.length > 0) return text;
|
|
352
|
+
if (modelFamily === "anthropic" || modelFamily === "auto") {
|
|
353
|
+
const thinking = asString(reasoning.thinking);
|
|
354
|
+
if (thinking !== void 0 && thinking.length > 0) return thinking;
|
|
355
|
+
}
|
|
356
|
+
return void 0;
|
|
357
|
+
}
|
|
358
|
+
function incrementalArgsDelta(state, nextInput) {
|
|
359
|
+
const prev = state.lastArgsJson;
|
|
360
|
+
if (nextInput === prev) return void 0;
|
|
361
|
+
let delta;
|
|
362
|
+
if (prev.length > 0 && nextInput.startsWith(prev)) {
|
|
363
|
+
delta = nextInput.slice(prev.length);
|
|
364
|
+
} else {
|
|
365
|
+
delta = nextInput;
|
|
366
|
+
}
|
|
367
|
+
state.lastArgsJson = nextInput;
|
|
368
|
+
return delta.length > 0 ? delta : void 0;
|
|
369
|
+
}
|
|
370
|
+
function mapStopReason(value) {
|
|
371
|
+
switch (value) {
|
|
372
|
+
case "end_turn":
|
|
373
|
+
case "stop_sequence":
|
|
374
|
+
return "stop";
|
|
375
|
+
case "tool_use":
|
|
376
|
+
return "tool_calls";
|
|
377
|
+
case "max_tokens":
|
|
378
|
+
return "length";
|
|
379
|
+
case "content_filtered":
|
|
380
|
+
case "guardrail_intervened":
|
|
381
|
+
return "content_filter";
|
|
382
|
+
default:
|
|
383
|
+
return "stop";
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
function usageChunk(value) {
|
|
387
|
+
if (!isRecord(value)) return void 0;
|
|
388
|
+
const inputTokens = asNumber(value.inputTokens) ?? asNumber(value.promptTokens) ?? asNumber(value.inputTokenCount);
|
|
389
|
+
const outputTokens = asNumber(value.outputTokens) ?? asNumber(value.completionTokens) ?? asNumber(value.outputTokenCount);
|
|
390
|
+
const totalTokens = asNumber(value.totalTokens) ?? asNumber(value.totalTokenCount);
|
|
391
|
+
if (inputTokens === void 0 && outputTokens === void 0 && totalTokens === void 0) {
|
|
392
|
+
return void 0;
|
|
393
|
+
}
|
|
394
|
+
return optionalRawChunk({
|
|
395
|
+
kind: "usage",
|
|
396
|
+
inputTokens,
|
|
397
|
+
outputTokens,
|
|
398
|
+
raw: { ...value, totalTokens }
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
function optionalMetadataRaw(payload) {
|
|
402
|
+
if (Object.keys(payload).length === 0) return [];
|
|
403
|
+
return [
|
|
404
|
+
optionalRawChunk({
|
|
405
|
+
kind: "metadata",
|
|
406
|
+
raw: payload
|
|
407
|
+
})
|
|
408
|
+
];
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
exports.bedrockAdapter = bedrockAdapter;
|
|
412
|
+
//# sourceMappingURL=bedrock.cjs.map
|
|
413
|
+
//# sourceMappingURL=bedrock.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/utils.ts","../../src/adapters/errors.ts","../../src/adapters/bedrock.ts"],"names":[],"mappings":"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","file":"bedrock.cjs","sourcesContent":["/** Internal adapter utilities. Not part of the public API. */\nimport type { RawChunk, StreamAdapter } from \"../core/types\";\nimport { adapterScopedError } from \"./errors\";\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport function asString(value: unknown): string | undefined {\n\treturn typeof value === \"string\" ? value : undefined;\n}\n\nexport function asNumber(value: unknown): number | undefined {\n\treturn typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\nexport function optionalRawChunk(input: Record<string, unknown>): RawChunk {\n\treturn Object.fromEntries(\n\t\tObject.entries(input).filter(([, value]) => value !== undefined),\n\t) as RawChunk;\n}\n\nexport function prefixedAdapterError(feature: string, message: string): Error {\n\treturn adapterScopedError(feature, message);\n}\n\nexport function createStreamAdapter<TOptions>(config: {\n\tparser: { parseChunk(raw: string): RawChunk[] };\n\tparseResponse: (body: unknown, options: TOptions) => RawChunk[];\n\toptions: TOptions;\n}): StreamAdapter {\n\treturn {\n\t\tparseChunk(raw) {\n\t\t\treturn config.parser.parseChunk(raw);\n\t\t},\n\t\tparseResponse(body) {\n\t\t\treturn config.parseResponse(body, config.options);\n\t\t},\n\t};\n}\n\nexport function parseAdapterJSON(raw: string, feature: string): unknown {\n\ttry {\n\t\treturn JSON.parse(raw) as unknown;\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tthrow prefixedAdapterError(feature, message);\n\t}\n}\n","/** Internal adapter error helpers. Not part of the public API. */\nimport type { RawChunk } from \"../core/types\";\nimport { asString } from \"./utils\";\n\nexport function libraryError(message: string): Error {\n\treturn new Error(`llm-stream-assemble: ${message}`);\n}\n\nexport function adapterScopedError(scope: string, message: string): Error {\n\treturn new Error(`llm-stream-assemble: ${scope}: ${message}`);\n}\n\nexport function providerErrorChunks(error: Error, recoverable = false): RawChunk[] {\n\treturn [\n\t\t{ kind: \"provider-error\", error, recoverable },\n\t\t{ kind: \"finish\", reason: \"error\" },\n\t];\n}\n\nexport function providerErrorChunksFromMessage(message: string, recoverable = false): RawChunk[] {\n\treturn providerErrorChunks(libraryError(message), recoverable);\n}\n\nexport function providerErrorChunksFromPayload(\n\terrorPayload: Record<string, unknown>,\n\tscope: string,\n\trecoverable: boolean,\n\tfallbackMessage: string,\n): RawChunk[] {\n\tconst message = asString(errorPayload.message) ?? fallbackMessage;\n\tconst error = adapterScopedError(scope, message);\n\tObject.defineProperty(error, \"raw\", {\n\t\tvalue: errorPayload,\n\t\tenumerable: false,\n\t});\n\treturn providerErrorChunks(error, recoverable);\n}\n","import type { FinishReason, RawChunk, StreamAdapter } from \"../core/types\";\nimport { libraryError, providerErrorChunksFromPayload } from \"./errors\";\nimport {\n\tasNumber,\n\tasString,\n\tcreateStreamAdapter,\n\tisRecord,\n\toptionalRawChunk,\n\tparseAdapterJSON,\n} from \"./utils\";\n\nexport type BedrockModelFamily = \"anthropic\" | \"openai-like\" | \"nova\" | \"auto\";\n\nexport interface BedrockAdapterOptions {\n\t/**\n\t * Hint which ConverseStream payload dialect to prefer when envelopes overlap.\n\t * \"auto\" uses structural detection (document heuristics in adapter-guide).\n\t */\n\tmodelFamily?: BedrockModelFamily;\n\t/** Map structured JSON text blocks to json-delta instead of text-delta. */\n\tjsonMode?: boolean;\n}\n\ninterface BlockToolState {\n\tid: string;\n\tname: string;\n\tindex: number;\n\topen: boolean;\n\tlastArgsJson: string;\n}\n\nconst EXCEPTION_KEYS = [\n\t\"internalServerException\",\n\t\"modelStreamErrorException\",\n\t\"validationException\",\n\t\"throttlingException\",\n\t\"serviceUnavailableException\",\n] as const;\n\nexport function bedrockAdapter(options: BedrockAdapterOptions = {}): StreamAdapter {\n\tconst parser = new BedrockStreamParser(options);\n\treturn createStreamAdapter({\n\t\tparser,\n\t\tparseResponse,\n\t\toptions,\n\t});\n}\n\nclass BedrockStreamParser {\n\tprivate messageStarted = false;\n\tprivate readonly blocks = new Map<number, BlockToolState>();\n\n\tconstructor(private readonly options: BedrockAdapterOptions) {}\n\n\tparseChunk(raw: string): RawChunk[] {\n\t\tconst trimmed = raw.trim();\n\t\tif (trimmed.length === 0 || trimmed === \"[DONE]\") return [];\n\n\t\tconst payload = parseAdapterJSON(trimmed, \"bedrockAdapter.parseChunk\");\n\t\tif (!isRecord(payload)) {\n\t\t\tthrow libraryError(\"bedrockAdapter.parseChunk expected a JSON object\");\n\t\t}\n\n\t\tfor (const key of EXCEPTION_KEYS) {\n\t\t\tconst exception = payload[key];\n\t\t\tif (isRecord(exception)) {\n\t\t\t\treturn providerErrorChunksFromPayload(\n\t\t\t\t\texception,\n\t\t\t\t\t\"bedrockAdapter.parseChunk\",\n\t\t\t\t\tfalse,\n\t\t\t\t\t`Bedrock ${key}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tif (payload.messageStart !== undefined) {\n\t\t\treturn this.messageStartChunks(payload.messageStart);\n\t\t}\n\t\tif (payload.contentBlockStart !== undefined) {\n\t\t\treturn this.contentBlockStartChunks(payload.contentBlockStart);\n\t\t}\n\t\tif (payload.contentBlockDelta !== undefined) {\n\t\t\treturn this.contentBlockDeltaChunks(payload.contentBlockDelta);\n\t\t}\n\t\tif (payload.contentBlockStop !== undefined) {\n\t\t\treturn this.contentBlockStopChunks(payload.contentBlockStop);\n\t\t}\n\t\tif (payload.messageStop !== undefined) {\n\t\t\treturn this.messageStopChunks(payload.messageStop);\n\t\t}\n\t\tif (payload.metadata !== undefined) {\n\t\t\treturn this.metadataChunks(payload.metadata);\n\t\t}\n\n\t\treturn optionalMetadataRaw(payload);\n\t}\n\n\tprivate messageStartChunks(value: unknown): RawChunk[] {\n\t\tif (!isRecord(value)) return [];\n\t\tif (this.messageStarted) return [];\n\t\tthis.messageStarted = true;\n\t\tconst role = asString(value.role);\n\t\treturn [\n\t\t\t{ kind: \"message-start\" },\n\t\t\t...(role\n\t\t\t\t? [\n\t\t\t\t\t\toptionalRawChunk({\n\t\t\t\t\t\t\tkind: \"metadata\",\n\t\t\t\t\t\t\traw: { role },\n\t\t\t\t\t\t}),\n\t\t\t\t\t]\n\t\t\t\t: []),\n\t\t];\n\t}\n\n\tprivate contentBlockStartChunks(value: unknown): RawChunk[] {\n\t\tif (!isRecord(value)) return [];\n\t\tconst blockIndex = asNumber(value.contentBlockIndex) ?? 0;\n\t\tconst start = isRecord(value.start) ? value.start : undefined;\n\t\tconst toolUse = start && isRecord(start.toolUse) ? start.toolUse : undefined;\n\t\tif (!toolUse) return [];\n\n\t\tconst id = asString(toolUse.toolUseId) ?? `bedrock:${blockIndex}`;\n\t\tconst name = asString(toolUse.name) ?? \"unknown\";\n\t\tthis.blocks.set(blockIndex, {\n\t\t\tid,\n\t\t\tname,\n\t\t\tindex: blockIndex,\n\t\t\topen: true,\n\t\t\tlastArgsJson: \"\",\n\t\t});\n\t\treturn [\n\t\t\toptionalRawChunk({\n\t\t\t\tkind: \"tool-start\",\n\t\t\t\tid,\n\t\t\t\tname,\n\t\t\t\tindex: blockIndex,\n\t\t\t\tchoiceIndex: 0,\n\t\t\t}),\n\t\t];\n\t}\n\n\tprivate contentBlockDeltaChunks(value: unknown): RawChunk[] {\n\t\tif (!isRecord(value)) return [];\n\t\tconst blockIndex = asNumber(value.contentBlockIndex) ?? 0;\n\t\tconst delta = isRecord(value.delta) ? value.delta : undefined;\n\t\tif (!delta) return [];\n\n\t\tconst chunks: RawChunk[] = [];\n\t\tconst text = asString(delta.text);\n\t\tif (text !== undefined && text.length > 0) {\n\t\t\tif (this.options.jsonMode) {\n\t\t\t\tchunks.push({ kind: \"json-delta\", delta: text });\n\t\t\t} else {\n\t\t\t\tchunks.push({ kind: \"text-delta\", text, choiceIndex: 0 });\n\t\t\t}\n\t\t}\n\n\t\tconst reasoning = delta.reasoningContent;\n\t\tconst reasoningText = reasoningTextFromDelta(reasoning, this.options.modelFamily);\n\t\tif (reasoningText) {\n\t\t\tchunks.push({ kind: \"reasoning-delta\", text: reasoningText, variant: \"detail\" });\n\t\t}\n\n\t\tconst toolUse = isRecord(delta.toolUse) ? delta.toolUse : undefined;\n\t\tif (toolUse) {\n\t\t\tchunks.push(...this.toolInputDelta(blockIndex, toolUse));\n\t\t}\n\n\t\treturn chunks;\n\t}\n\n\tprivate toolInputDelta(blockIndex: number, toolUse: Record<string, unknown>): RawChunk[] {\n\t\tconst state = this.blocks.get(blockIndex);\n\t\tif (!state) return [];\n\n\t\tconst input = toolUse.input;\n\t\tlet delta: string | undefined;\n\t\tif (typeof input === \"string\") {\n\t\t\tdelta = incrementalArgsDelta(state, input);\n\t\t} else if (isRecord(input)) {\n\t\t\tdelta = incrementalArgsDelta(state, JSON.stringify(input));\n\t\t}\n\t\tif (!delta) return [];\n\n\t\treturn [\n\t\t\toptionalRawChunk({\n\t\t\t\tkind: \"tool-args-delta\",\n\t\t\t\tid: state.id,\n\t\t\t\tdelta,\n\t\t\t\tindex: state.index,\n\t\t\t\tchoiceIndex: 0,\n\t\t\t}),\n\t\t];\n\t}\n\n\tprivate contentBlockStopChunks(value: unknown): RawChunk[] {\n\t\tif (!isRecord(value)) return [];\n\t\tconst blockIndex = asNumber(value.contentBlockIndex) ?? 0;\n\t\tconst state = this.blocks.get(blockIndex);\n\t\tif (!state?.open) return [];\n\n\t\tstate.open = false;\n\t\treturn [\n\t\t\toptionalRawChunk({\n\t\t\t\tkind: \"tool-done\",\n\t\t\t\tid: state.id,\n\t\t\t\tindex: state.index,\n\t\t\t\tchoiceIndex: 0,\n\t\t\t}),\n\t\t];\n\t}\n\n\tprivate messageStopChunks(value: unknown): RawChunk[] {\n\t\tif (!isRecord(value)) return [];\n\t\tconst stopReason = asString(value.stopReason) ?? \"unknown\";\n\t\tconst additional = value.additionalModelResponseFields;\n\t\tconst chunks: RawChunk[] = [];\n\t\tchunks.push(\n\t\t\toptionalRawChunk({\n\t\t\t\tkind: \"metadata\",\n\t\t\t\traw: {\n\t\t\t\t\tstopReason,\n\t\t\t\t\t...(additional !== undefined ? { additionalModelResponseFields: additional } : {}),\n\t\t\t\t},\n\t\t\t}),\n\t\t);\n\t\tchunks.push({ kind: \"finish\", reason: mapStopReason(stopReason), choiceIndex: 0 });\n\t\treturn chunks;\n\t}\n\n\tprivate metadataChunks(value: unknown): RawChunk[] {\n\t\tif (!isRecord(value)) return [];\n\t\tconst chunks: RawChunk[] = [];\n\n\t\tconst usage = usageChunk(value.usage);\n\t\tif (usage) chunks.push(usage);\n\n\t\tconst metrics = value.metrics;\n\t\tconst trace = value.trace;\n\t\tif (metrics !== undefined || trace !== undefined) {\n\t\t\tchunks.push(\n\t\t\t\toptionalRawChunk({\n\t\t\t\t\tkind: \"metadata\",\n\t\t\t\t\traw: { metrics, trace },\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\treturn chunks;\n\t}\n}\n\nfunction parseResponse(body: unknown, options: BedrockAdapterOptions): RawChunk[] {\n\tif (!isRecord(body)) {\n\t\tthrow libraryError(\"bedrockAdapter.parseResponse expected a Converse response object\");\n\t}\n\n\tfor (const key of EXCEPTION_KEYS) {\n\t\tconst exception = body[key];\n\t\tif (isRecord(exception)) {\n\t\t\treturn providerErrorChunksFromPayload(\n\t\t\t\texception,\n\t\t\t\t\"bedrockAdapter.parseResponse\",\n\t\t\t\tfalse,\n\t\t\t\t`Bedrock ${key}`,\n\t\t\t);\n\t\t}\n\t}\n\n\tconst parser = new BedrockStreamParser(options);\n\tconst chunks: RawChunk[] = [];\n\n\tconst output = isRecord(body.output) ? body.output : undefined;\n\tconst message = output && isRecord(output.message) ? output.message : undefined;\n\tif (message) {\n\t\tchunks.push({ kind: \"message-start\" });\n\t\tconst role = asString(message.role);\n\t\tif (role) {\n\t\t\tchunks.push(optionalRawChunk({ kind: \"metadata\", raw: { role } }));\n\t\t}\n\n\t\tconst content = Array.isArray(message.content) ? message.content : [];\n\t\tlet blockIndex = 0;\n\t\tfor (const block of content) {\n\t\t\tif (!isRecord(block)) continue;\n\t\t\tconst text = asString(block.text);\n\t\t\tif (text !== undefined && text.length > 0) {\n\t\t\t\tif (options.jsonMode) {\n\t\t\t\t\tchunks.push({ kind: \"json-delta\", delta: text });\n\t\t\t\t} else {\n\t\t\t\t\tchunks.push({ kind: \"text-delta\", text, choiceIndex: 0 });\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst toolUse = isRecord(block.toolUse) ? block.toolUse : undefined;\n\t\t\tif (toolUse) {\n\t\t\t\tconst id = asString(toolUse.toolUseId) ?? `bedrock:${blockIndex}`;\n\t\t\t\tconst name = asString(toolUse.name) ?? \"unknown\";\n\t\t\t\tchunks.push(\n\t\t\t\t\toptionalRawChunk({\n\t\t\t\t\t\tkind: \"tool-start\",\n\t\t\t\t\t\tid,\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tindex: blockIndex,\n\t\t\t\t\t\tchoiceIndex: 0,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tconst input = toolUse.input;\n\t\t\t\tif (input !== undefined) {\n\t\t\t\t\tconst argsJson = typeof input === \"string\" ? input : JSON.stringify(input);\n\t\t\t\t\tif (argsJson.length > 0) {\n\t\t\t\t\t\tchunks.push(\n\t\t\t\t\t\t\toptionalRawChunk({\n\t\t\t\t\t\t\t\tkind: \"tool-args-delta\",\n\t\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\t\tdelta: argsJson,\n\t\t\t\t\t\t\t\tindex: blockIndex,\n\t\t\t\t\t\t\t\tchoiceIndex: 0,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tchunks.push(\n\t\t\t\t\toptionalRawChunk({\n\t\t\t\t\t\tkind: \"tool-done\",\n\t\t\t\t\t\tid,\n\t\t\t\t\t\tindex: blockIndex,\n\t\t\t\t\t\tchoiceIndex: 0,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\tblockIndex += 1;\n\t\t}\n\t}\n\n\tconst usage = usageChunk(body.usage);\n\tif (usage) chunks.push(usage);\n\n\tconst stopReason = asString(body.stopReason);\n\tif (stopReason) {\n\t\tchunks.push({ kind: \"finish\", reason: mapStopReason(stopReason), choiceIndex: 0 });\n\t} else if (!chunks.some((chunk) => chunk.kind === \"finish\")) {\n\t\tchunks.push({ kind: \"finish\", reason: \"stop\" });\n\t}\n\n\t// Touch parser options for modelFamily-specific paths in stream mode parity.\n\tvoid parser;\n\n\treturn chunks;\n}\n\nfunction reasoningTextFromDelta(\n\treasoning: unknown,\n\tmodelFamily: BedrockModelFamily | undefined,\n): string | undefined {\n\tif (reasoning === undefined) return undefined;\n\tif (typeof reasoning === \"string\") return reasoning.length > 0 ? reasoning : undefined;\n\tif (!isRecord(reasoning)) return undefined;\n\n\tconst text = asString(reasoning.text);\n\tif (text !== undefined && text.length > 0) return text;\n\n\tif (modelFamily === \"anthropic\" || modelFamily === \"auto\") {\n\t\tconst thinking = asString(reasoning.thinking);\n\t\tif (thinking !== undefined && thinking.length > 0) return thinking;\n\t}\n\n\treturn undefined;\n}\n\nfunction incrementalArgsDelta(state: BlockToolState, nextInput: string): string | undefined {\n\tconst prev = state.lastArgsJson;\n\tif (nextInput === prev) return undefined;\n\tlet delta: string;\n\tif (prev.length > 0 && nextInput.startsWith(prev)) {\n\t\tdelta = nextInput.slice(prev.length);\n\t} else {\n\t\tdelta = nextInput;\n\t}\n\tstate.lastArgsJson = nextInput;\n\treturn delta.length > 0 ? delta : undefined;\n}\n\nfunction mapStopReason(value: string): FinishReason {\n\tswitch (value) {\n\t\tcase \"end_turn\":\n\t\tcase \"stop_sequence\":\n\t\t\treturn \"stop\";\n\t\tcase \"tool_use\":\n\t\t\treturn \"tool_calls\";\n\t\tcase \"max_tokens\":\n\t\t\treturn \"length\";\n\t\tcase \"content_filtered\":\n\t\tcase \"guardrail_intervened\":\n\t\t\treturn \"content_filter\";\n\t\tdefault:\n\t\t\treturn \"stop\";\n\t}\n}\n\nfunction usageChunk(value: unknown): RawChunk | undefined {\n\tif (!isRecord(value)) return undefined;\n\tconst inputTokens =\n\t\tasNumber(value.inputTokens) ?? asNumber(value.promptTokens) ?? asNumber(value.inputTokenCount);\n\tconst outputTokens =\n\t\tasNumber(value.outputTokens) ??\n\t\tasNumber(value.completionTokens) ??\n\t\tasNumber(value.outputTokenCount);\n\tconst totalTokens = asNumber(value.totalTokens) ?? asNumber(value.totalTokenCount);\n\tif (inputTokens === undefined && outputTokens === undefined && totalTokens === undefined) {\n\t\treturn undefined;\n\t}\n\treturn optionalRawChunk({\n\t\tkind: \"usage\",\n\t\tinputTokens,\n\t\toutputTokens,\n\t\traw: { ...value, totalTokens },\n\t});\n}\n\nfunction optionalMetadataRaw(payload: Record<string, unknown>): RawChunk[] {\n\tif (Object.keys(payload).length === 0) return [];\n\treturn [\n\t\toptionalRawChunk({\n\t\t\tkind: \"metadata\",\n\t\t\traw: payload,\n\t\t}),\n\t];\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { S as StreamAdapter } from '../types-CskRfrmD.cjs';
|
|
2
|
+
|
|
3
|
+
type BedrockModelFamily = "anthropic" | "openai-like" | "nova" | "auto";
|
|
4
|
+
interface BedrockAdapterOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Hint which ConverseStream payload dialect to prefer when envelopes overlap.
|
|
7
|
+
* "auto" uses structural detection (document heuristics in adapter-guide).
|
|
8
|
+
*/
|
|
9
|
+
modelFamily?: BedrockModelFamily;
|
|
10
|
+
/** Map structured JSON text blocks to json-delta instead of text-delta. */
|
|
11
|
+
jsonMode?: boolean;
|
|
12
|
+
}
|
|
13
|
+
declare function bedrockAdapter(options?: BedrockAdapterOptions): StreamAdapter;
|
|
14
|
+
|
|
15
|
+
export { type BedrockAdapterOptions, type BedrockModelFamily, bedrockAdapter };
|