llm-sse 0.4.8 → 0.4.9
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 +6 -0
- package/README.md +6 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,12 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.4.9] - 2026-06-29
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Documentation: replace em dashes with standard punctuation for consistent house style.
|
|
14
|
+
|
|
9
15
|
## [0.4.8] - 2026-06-29
|
|
10
16
|
|
|
11
17
|
### Changed
|
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
Security posture is tracked in [docs/security-posture.md](https://github.com/slegarraga/llm-sse/blob/main/docs/security-posture.md),
|
|
15
15
|
including CodeQL, OpenSSF Scorecard, Dependabot and branch rules.
|
|
16
16
|
|
|
17
|
-
Each provider streams differently. OpenAI sends `choices[].delta` chunks, Anthropic sends typed `content_block_*` / `message_*` events, Gemini sends `candidates[].content.parts
|
|
17
|
+
Each provider streams differently. OpenAI sends `choices[].delta` chunks, Anthropic sends typed `content_block_*` / `message_*` events, Gemini sends `candidates[].content.parts`, and the SSE framing, tool-call argument fragments and stop reasons are all shaped differently. `llm-sse` turns any of them into the same small set of events, so your streaming UI or agent loop stays provider-agnostic.
|
|
18
18
|
|
|
19
19
|
## Quickstart
|
|
20
20
|
|
|
@@ -112,11 +112,11 @@ for await (const event of parseOpenAIStream(res.body)) {
|
|
|
112
112
|
|
|
113
113
|
## Why
|
|
114
114
|
|
|
115
|
-
- **One event shape, three providers.** `text`, `tool_call_start`, `tool_call_delta`, `finish`, `error
|
|
115
|
+
- **One event shape, three providers.** `text`, `tool_call_start`, `tool_call_delta`, `finish`, `error`, the same whether the bytes came from OpenAI, Anthropic or Gemini.
|
|
116
116
|
- **Tool calls just accumulate.** Streamed JSON argument fragments carry an `index`; concatenate by index (or let `collectStream` do it) to get the full call.
|
|
117
117
|
- **Correct SSE framing.** Robust to chunk boundaries splitting a line or event mid-way, CRLF, multi-line `data:` fields, comments and keep-alives.
|
|
118
118
|
- **Fixture-backed provider coverage.** Public OpenAI, Anthropic and Gemini `.sse` fixtures exercise text, reasoning, tool-call arguments and finish reasons.
|
|
119
|
-
- **Bytes or strings.** Feed it a `fetch()` `ReadableStream<Uint8Array>`, a Node stream, or an async iterable of strings
|
|
119
|
+
- **Bytes or strings.** Feed it a `fetch()` `ReadableStream<Uint8Array>`, a Node stream, or an async iterable of strings. Multibyte UTF-8 split across chunks is handled.
|
|
120
120
|
- **Zero dependencies**, ESM + CJS, fully typed.
|
|
121
121
|
|
|
122
122
|
## Why not the provider SDK?
|
|
@@ -133,7 +133,7 @@ npm install llm-sse
|
|
|
133
133
|
|
|
134
134
|
### `parseOpenAIStream(source)` · `parseAnthropicStream(source)` · `parseGeminiStream(source)`
|
|
135
135
|
|
|
136
|
-
Each takes a `source` (`AsyncIterable<Uint8Array | string
|
|
136
|
+
Each takes a `source` (`AsyncIterable<Uint8Array | string>`, `fetch().body` satisfies this) and returns an `AsyncGenerator<StreamEvent>`.
|
|
137
137
|
|
|
138
138
|
> Gemini: use the SSE form of the streaming endpoint (`streamGenerateContent?alt=sse`).
|
|
139
139
|
|
|
@@ -165,12 +165,12 @@ Drains an event stream into a single message:
|
|
|
165
165
|
const { text, reasoning, toolCalls, finishReason } = await collectStream(
|
|
166
166
|
parseAnthropicStream(res.body),
|
|
167
167
|
);
|
|
168
|
-
// toolCalls: { index, id?, name?, arguments }[]
|
|
168
|
+
// toolCalls: { index, id?, name?, arguments }[], arguments is the joined JSON string
|
|
169
169
|
```
|
|
170
170
|
|
|
171
171
|
### `toAssistantMessage(collected)`
|
|
172
172
|
|
|
173
|
-
Turn a collected stream into a standard OpenAI-shape assistant message
|
|
173
|
+
Turn a collected stream into a standard OpenAI-shape assistant message, the format `llm-messages` treats as canonical, so a streamed response composes straight back into your history or into a different provider:
|
|
174
174
|
|
|
175
175
|
```ts
|
|
176
176
|
import { collectStream, toAssistantMessage } from 'llm-sse';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "llm-sse",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.9",
|
|
4
4
|
"description": "Parse streaming SSE responses from OpenAI, Anthropic, Gemini and OpenAI-compatible providers into one unified event format. Text, reasoning and tool-call deltas. Zero dependencies.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"openai",
|