@nonoun/native-chat 0.3.0 → 0.5.1
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/dist/{chat-input-structured-element-Cpar3CeA.js → chat-input-structured-element-uXGIe-HI.js} +418 -131
- package/dist/chat-panel-element.d.ts +21 -0
- package/dist/chat-panel-element.d.ts.map +1 -1
- package/dist/feed/chat-feed-element.d.ts +19 -0
- package/dist/feed/chat-feed-element.d.ts.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/message/chat-message-element.d.ts +17 -1
- package/dist/message/chat-message-element.d.ts.map +1 -1
- package/dist/message/chat-messages-element.d.ts +1 -0
- package/dist/message/chat-messages-element.d.ts.map +1 -1
- package/dist/native-chat.css +90 -4
- package/dist/native-chat.js +147 -44
- package/dist/register.js +3 -3
- package/dist/stream/classify.d.ts +19 -0
- package/dist/stream/classify.d.ts.map +1 -0
- package/dist/stream/create-transport.d.ts +1 -1
- package/dist/stream/create-transport.d.ts.map +1 -1
- package/dist/stream/index.d.ts +3 -1
- package/dist/stream/index.d.ts.map +1 -1
- package/dist/stream/parse-ndjson.d.ts.map +1 -1
- package/dist/stream/parse-sse.d.ts.map +1 -1
- package/dist/stream/types.d.ts +20 -1
- package/dist/stream/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/native-chat.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { a as e, c as t, d as n, f as r, i,
|
|
1
|
+
import { a as e, c as t, d as n, f as r, g as i, h as a, i as o, l as s, m as c, n as l, o as u, p as d, r as f, s as p, t as m, u as h } from "./chat-input-structured-element-uXGIe-HI.js";
|
|
2
2
|
/**
|
|
3
3
|
* Parse a Server-Sent Events (SSE) response stream into ChatStreamChunk values.
|
|
4
4
|
*
|
|
5
5
|
* Reads `data:` lines from the response body, skips empty lines and comments,
|
|
6
6
|
* handles the `[DONE]` sentinel, and accumulates the full message across chunks.
|
|
7
7
|
*/
|
|
8
|
-
async function*
|
|
8
|
+
async function* g(e) {
|
|
9
9
|
let t = e.body.getReader(), n = new TextDecoder("utf-8"), r = "", i = "";
|
|
10
10
|
try {
|
|
11
11
|
for (;;) {
|
|
@@ -61,7 +61,8 @@ async function* m(e) {
|
|
|
61
61
|
fullMessage: i,
|
|
62
62
|
role: "assistant",
|
|
63
63
|
datetime: Date.now(),
|
|
64
|
-
done: !0
|
|
64
|
+
done: !0,
|
|
65
|
+
partial: !0
|
|
65
66
|
};
|
|
66
67
|
return;
|
|
67
68
|
} catch {}
|
|
@@ -71,7 +72,8 @@ async function* m(e) {
|
|
|
71
72
|
fullMessage: i,
|
|
72
73
|
role: "assistant",
|
|
73
74
|
datetime: Date.now(),
|
|
74
|
-
done: !0
|
|
75
|
+
done: !0,
|
|
76
|
+
partial: !0
|
|
75
77
|
});
|
|
76
78
|
} finally {
|
|
77
79
|
t.releaseLock();
|
|
@@ -83,7 +85,7 @@ async function* m(e) {
|
|
|
83
85
|
* Each non-empty line is parsed as a standalone JSON object.
|
|
84
86
|
* Accumulates the full message across chunks.
|
|
85
87
|
*/
|
|
86
|
-
async function*
|
|
88
|
+
async function* _(e) {
|
|
87
89
|
let t = e.body.getReader(), n = new TextDecoder("utf-8"), r = "", i = "";
|
|
88
90
|
try {
|
|
89
91
|
for (;;) {
|
|
@@ -121,7 +123,8 @@ async function* h(e) {
|
|
|
121
123
|
fullMessage: i,
|
|
122
124
|
role: "assistant",
|
|
123
125
|
datetime: Date.now(),
|
|
124
|
-
done: !0
|
|
126
|
+
done: !0,
|
|
127
|
+
partial: !0
|
|
125
128
|
};
|
|
126
129
|
return;
|
|
127
130
|
} catch {}
|
|
@@ -130,7 +133,8 @@ async function* h(e) {
|
|
|
130
133
|
fullMessage: i,
|
|
131
134
|
role: "assistant",
|
|
132
135
|
datetime: Date.now(),
|
|
133
|
-
done: !0
|
|
136
|
+
done: !0,
|
|
137
|
+
partial: !0
|
|
134
138
|
});
|
|
135
139
|
} finally {
|
|
136
140
|
t.releaseLock();
|
|
@@ -142,7 +146,7 @@ async function* h(e) {
|
|
|
142
146
|
* Reads the entire response body, parses as JSON, and yields one chunk
|
|
143
147
|
* with `done: true`.
|
|
144
148
|
*/
|
|
145
|
-
async function*
|
|
149
|
+
async function* v(e) {
|
|
146
150
|
let t = await e.json(), n = "";
|
|
147
151
|
typeof t.content == "string" ? n = t.content : typeof t.message == "string" ? n = t.message : typeof t.delta == "string" ? n = t.delta : Array.isArray(t.choices) && typeof t.choices[0]?.message?.content == "string" && (n = t.choices[0].message.content), yield {
|
|
148
152
|
delta: n,
|
|
@@ -153,9 +157,31 @@ async function* g(e) {
|
|
|
153
157
|
};
|
|
154
158
|
}
|
|
155
159
|
/**
|
|
160
|
+
* Classify how a stream ended based on the final chunk and optional error.
|
|
161
|
+
* - `complete` — explicit done signal received (e.g., `[DONE]` sentinel, `finish_reason`)
|
|
162
|
+
* - `partial` — stream ended without explicit completion (truncated)
|
|
163
|
+
* - `error` — an error occurred during streaming
|
|
164
|
+
* - `stopped` — consumer aborted the stream
|
|
165
|
+
*/
|
|
166
|
+
function y(e, t) {
|
|
167
|
+
return t ? t.name === "AbortError" ? "stopped" : "error" : e.partial ? "partial" : "complete";
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Classify an HTTP status code into a transport state.
|
|
171
|
+
*/
|
|
172
|
+
function b(e) {
|
|
173
|
+
return e === 401 || e === 403 ? "auth-required" : e === 429 ? "rate-limited" : "server-error";
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Calculate exponential backoff delay with jitter.
|
|
177
|
+
*/
|
|
178
|
+
function x(e, t = 1e3, n = 3e4) {
|
|
179
|
+
return Math.min(n, t * 2 ** e + Math.random() * 500);
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
156
182
|
* Detect the stream format from a Content-Type header value.
|
|
157
183
|
*/
|
|
158
|
-
function
|
|
184
|
+
function S(e) {
|
|
159
185
|
let t = e.toLowerCase();
|
|
160
186
|
return t.includes("text/event-stream") ? "sse" : t.includes("ndjson") || t.includes("x-ndjson") ? "ndjson" : "json";
|
|
161
187
|
}
|
|
@@ -163,48 +189,125 @@ function _(e) {
|
|
|
163
189
|
* Create an async generator that yields ChatStreamChunk values from a
|
|
164
190
|
* Response, auto-detecting the format from Content-Type when not specified.
|
|
165
191
|
*/
|
|
166
|
-
async function*
|
|
167
|
-
switch (t ??
|
|
192
|
+
async function* C(e, t) {
|
|
193
|
+
switch (t ?? S(e.headers.get("content-type") ?? "")) {
|
|
168
194
|
case "sse":
|
|
169
|
-
yield*
|
|
195
|
+
yield* g(e);
|
|
170
196
|
break;
|
|
171
197
|
case "ndjson":
|
|
172
|
-
yield*
|
|
198
|
+
yield* _(e);
|
|
173
199
|
break;
|
|
174
200
|
case "json":
|
|
175
|
-
yield*
|
|
201
|
+
yield* v(e);
|
|
176
202
|
break;
|
|
177
203
|
}
|
|
178
204
|
}
|
|
179
205
|
/**
|
|
180
206
|
* Create a reusable chat transport that sends requests and returns a
|
|
181
|
-
* streaming async generator.
|
|
207
|
+
* streaming async generator. Supports retry/backoff and transport state callbacks.
|
|
182
208
|
*/
|
|
183
|
-
function
|
|
184
|
-
|
|
185
|
-
|
|
209
|
+
function w(e) {
|
|
210
|
+
let t = (t) => {
|
|
211
|
+
e.onStateChange?.(t);
|
|
212
|
+
}, n = e.retry?.maxAttempts ?? 1, r = e.retry?.baseDelayMs ?? 1e3, i = e.retry?.maxDelayMs ?? 3e4;
|
|
213
|
+
return { async send(a) {
|
|
214
|
+
let o = {
|
|
186
215
|
"Content-Type": "application/json",
|
|
187
216
|
...e.headers
|
|
188
217
|
};
|
|
189
|
-
e.clientId && (
|
|
190
|
-
let
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
218
|
+
e.clientId && (o["X-Client-Id"] = e.clientId);
|
|
219
|
+
let s;
|
|
220
|
+
for (let c = 0; c < n; c++) {
|
|
221
|
+
t({
|
|
222
|
+
state: c === 0 ? "sending" : "retrying",
|
|
223
|
+
attempt: c,
|
|
224
|
+
maxAttempts: n
|
|
225
|
+
});
|
|
226
|
+
let l;
|
|
227
|
+
try {
|
|
228
|
+
l = await fetch(e.baseUrl, {
|
|
229
|
+
method: "POST",
|
|
230
|
+
headers: o,
|
|
231
|
+
body: JSON.stringify(a),
|
|
232
|
+
signal: e.signal
|
|
233
|
+
});
|
|
234
|
+
} catch (e) {
|
|
235
|
+
if (s = e instanceof Error ? e : Error(String(e)), t({
|
|
236
|
+
state: s.name === "TypeError" ? "offline" : "server-error",
|
|
237
|
+
error: s,
|
|
238
|
+
attempt: c,
|
|
239
|
+
maxAttempts: n
|
|
240
|
+
}), c + 1 < n) {
|
|
241
|
+
let e = x(c, r, i);
|
|
242
|
+
t({
|
|
243
|
+
state: "retrying",
|
|
244
|
+
retryInMs: e,
|
|
245
|
+
attempt: c + 1,
|
|
246
|
+
maxAttempts: n
|
|
247
|
+
}), await E(e);
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
if (!l.ok) {
|
|
253
|
+
let e = b(l.status);
|
|
254
|
+
s = /* @__PURE__ */ Error(`Chat transport error: ${l.status} ${l.statusText}`);
|
|
255
|
+
let a;
|
|
256
|
+
if (l.status === 429) {
|
|
257
|
+
let e = l.headers.get("Retry-After");
|
|
258
|
+
if (e) {
|
|
259
|
+
let t = Number(e);
|
|
260
|
+
a = Number.isFinite(t) ? t * 1e3 : Date.parse(e) - Date.now();
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
if (t({
|
|
264
|
+
state: e,
|
|
265
|
+
statusCode: l.status,
|
|
266
|
+
retryInMs: a,
|
|
267
|
+
error: s,
|
|
268
|
+
attempt: c,
|
|
269
|
+
maxAttempts: n
|
|
270
|
+
}), (l.status === 429 || l.status >= 500) && c + 1 < n) {
|
|
271
|
+
let e = a ?? x(c, r, i);
|
|
272
|
+
t({
|
|
273
|
+
state: "retrying",
|
|
274
|
+
retryInMs: e,
|
|
275
|
+
attempt: c + 1,
|
|
276
|
+
maxAttempts: n
|
|
277
|
+
}), await E(e);
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
break;
|
|
281
|
+
}
|
|
282
|
+
return t({ state: "streaming" }), T(C(l, e.format), t);
|
|
283
|
+
}
|
|
284
|
+
throw s ?? /* @__PURE__ */ Error("Chat transport failed");
|
|
198
285
|
} };
|
|
199
286
|
}
|
|
200
|
-
|
|
287
|
+
/**
|
|
288
|
+
* Wraps an async generator to emit `ready` state when the stream finishes.
|
|
289
|
+
*/
|
|
290
|
+
async function* T(e, t) {
|
|
291
|
+
try {
|
|
292
|
+
yield* e, t({ state: "ready" });
|
|
293
|
+
} catch (e) {
|
|
294
|
+
throw t({
|
|
295
|
+
state: "server-error",
|
|
296
|
+
error: e instanceof Error ? e : Error(String(e))
|
|
297
|
+
}), e;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
function E(e) {
|
|
301
|
+
return new Promise((t) => setTimeout(t, e));
|
|
302
|
+
}
|
|
303
|
+
const D = {
|
|
201
304
|
TRANSPORT: "native:chat-transport",
|
|
202
305
|
GENERATION_START: "native:generation-start",
|
|
203
306
|
GENERATION_COMPLETE: "native:generation-complete",
|
|
204
307
|
GENERATION_STOP: "native:generation-stop",
|
|
205
308
|
GENERATION_ERROR: "native:generation-error",
|
|
206
309
|
WARNING: "native:chat-warning"
|
|
207
|
-
},
|
|
310
|
+
}, O = [
|
|
208
311
|
"requestId",
|
|
209
312
|
"sessionId",
|
|
210
313
|
"conversationId",
|
|
@@ -217,7 +320,7 @@ const b = {
|
|
|
217
320
|
"attempt",
|
|
218
321
|
"maxAttempts",
|
|
219
322
|
"chunkIndex"
|
|
220
|
-
],
|
|
323
|
+
], k = [
|
|
221
324
|
"query",
|
|
222
325
|
"message",
|
|
223
326
|
"delta",
|
|
@@ -227,17 +330,17 @@ const b = {
|
|
|
227
330
|
"prompt",
|
|
228
331
|
"response"
|
|
229
332
|
];
|
|
230
|
-
var
|
|
333
|
+
var A = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g, j = /\b(?:\+?\d{1,3}[-.\s]?)?\(?\d{2,4}\)?[-.\s]?\d{3,4}[-.\s]?\d{3,4}\b/g, M = /\b(?:\d{4}[-\s]?){3}\d{4}\b/g;
|
|
231
334
|
/**
|
|
232
335
|
* Scrub common PII patterns from a string.
|
|
233
336
|
*
|
|
234
337
|
* Replaces email addresses, phone-like numbers, and credit-card-like
|
|
235
338
|
* number sequences with `[redacted]` placeholders.
|
|
236
339
|
*/
|
|
237
|
-
function
|
|
238
|
-
return e.replace(
|
|
340
|
+
function N(e) {
|
|
341
|
+
return e.replace(A, "[redacted:email]").replace(M, "[redacted:card]").replace(j, "[redacted:phone]");
|
|
239
342
|
}
|
|
240
|
-
var
|
|
343
|
+
var P = new Set(k);
|
|
241
344
|
/**
|
|
242
345
|
* Create a default redactor for the given telemetry level.
|
|
243
346
|
*
|
|
@@ -245,11 +348,11 @@ var D = new Set(S);
|
|
|
245
348
|
* `[redacted:Nchars]` indicating the original length.
|
|
246
349
|
* - **debug**: All fields pass through unmodified.
|
|
247
350
|
*/
|
|
248
|
-
function
|
|
351
|
+
function F(e) {
|
|
249
352
|
return e === "debug" ? (e) => e : (e) => {
|
|
250
353
|
if (!e.detail) return e;
|
|
251
354
|
let t = {};
|
|
252
|
-
for (let [n, r] of Object.entries(e.detail))
|
|
355
|
+
for (let [n, r] of Object.entries(e.detail)) P.has(n) && typeof r == "string" ? t[n] = `[redacted:${r.length}chars]` : t[n] = r;
|
|
253
356
|
return {
|
|
254
357
|
...e,
|
|
255
358
|
detail: t
|
|
@@ -260,15 +363,15 @@ function O(e) {
|
|
|
260
363
|
* Dispatches telemetry events as `CustomEvent` instances on a given
|
|
261
364
|
* `EventTarget`, applying a configurable redactor before emission.
|
|
262
365
|
*/
|
|
263
|
-
var
|
|
366
|
+
var I = class {
|
|
264
367
|
#e;
|
|
265
368
|
#t;
|
|
266
369
|
constructor(e, t = "minimal") {
|
|
267
|
-
this.#e = e, this.#t =
|
|
370
|
+
this.#e = e, this.#t = F(t);
|
|
268
371
|
}
|
|
269
372
|
/** Change the telemetry level, replacing the redactor. */
|
|
270
373
|
setLevel(e) {
|
|
271
|
-
this.#t =
|
|
374
|
+
this.#t = F(e);
|
|
272
375
|
}
|
|
273
376
|
/** Replace the redactor with a custom implementation. */
|
|
274
377
|
setRedactor(e) {
|
|
@@ -284,7 +387,7 @@ var k = class {
|
|
|
284
387
|
}
|
|
285
388
|
emitTransport(e, t, n) {
|
|
286
389
|
this.emit({
|
|
287
|
-
type:
|
|
390
|
+
type: D.TRANSPORT,
|
|
288
391
|
correlation: e,
|
|
289
392
|
detail: {
|
|
290
393
|
mode: t,
|
|
@@ -294,14 +397,14 @@ var k = class {
|
|
|
294
397
|
}
|
|
295
398
|
emitGenerationStart(e) {
|
|
296
399
|
this.emit({
|
|
297
|
-
type:
|
|
400
|
+
type: D.GENERATION_START,
|
|
298
401
|
correlation: e,
|
|
299
402
|
timing: { startedAt: Date.now() }
|
|
300
403
|
});
|
|
301
404
|
}
|
|
302
405
|
emitGenerationComplete(e, t) {
|
|
303
406
|
this.emit({
|
|
304
|
-
type:
|
|
407
|
+
type: D.GENERATION_COMPLETE,
|
|
305
408
|
correlation: e,
|
|
306
409
|
timing: {
|
|
307
410
|
completedAt: Date.now(),
|
|
@@ -311,7 +414,7 @@ var k = class {
|
|
|
311
414
|
}
|
|
312
415
|
emitWarning(e, t, n) {
|
|
313
416
|
this.emit({
|
|
314
|
-
type:
|
|
417
|
+
type: D.WARNING,
|
|
315
418
|
correlation: e,
|
|
316
419
|
detail: {
|
|
317
420
|
message: t,
|
|
@@ -320,4 +423,4 @@ var k = class {
|
|
|
320
423
|
});
|
|
321
424
|
}
|
|
322
425
|
};
|
|
323
|
-
export {
|
|
426
|
+
export { h as ACTION_REGISTRY, D as CHAT_EVENTS, d as NChatAvatar, c as NChatFeed, i as NChatInput, m as NChatInputStructured, n as NChatMessage, o as NChatMessageActivity, l as NChatMessageGenUI, f as NChatMessageSeed, e as NChatMessageText, s as NChatMessages, a as NChatPanel, r as ROLE_DEFAULTS, O as SAFE_FIELDS, k as SENSITIVE_FIELDS, I as TelemetryEmitter, x as backoffDelay, b as classifyHttpError, y as classifyStreamEnd, C as createChatStream, w as createChatTransport, F as createDefaultRedactor, S as detectFormat, v as parseJSON, _ as parseNDJSON, g as parseSSE, u as renderInline, p as renderMarkdown, t as sanitizeHtml, N as scrubPII };
|
package/dist/register.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as e, d as t,
|
|
1
|
+
import { a as e, d as t, g as n, h as r, i, l as a, m as o, n as s, p as c, r as l, t as u } from "./chat-input-structured-element-uXGIe-HI.js";
|
|
2
2
|
import { NButton as d, NCard as f, NDialog as p, NIcon as m, NTextarea as h, NToolbar as g, define as _, registerIcon as v } from "@nonoun/native-ui";
|
|
3
|
-
_("n-chat-input",
|
|
4
|
-
export {
|
|
3
|
+
_("n-chat-input", n), _("native-chat-panel", r), _("n-chat-feed", o), _("n-chat-avatar", c), _("n-chat-message", t), _("n-chat-messages", a), _("n-chat-message-text", e), _("n-chat-message-activity", i), _("n-chat-message-seed", l), _("n-chat-message-genui", s), _("n-chat-input-structured", u), _("n-textarea", h), _("n-button", d), _("n-icon", m), _("n-toolbar", g), _("n-dialog", p), _("n-card", f), v("chat-dots", "<svg viewBox=\"0 0 256 256\" fill=\"currentColor\"><path d=\"M116,128a12,12,0,1,1,12,12A12,12,0,0,1,116,128ZM84,140a12,12,0,1,0-12-12A12,12,0,0,0,84,140Zm88,0a12,12,0,1,0-12-12A12,12,0,0,0,172,140Zm60-76V192a16,16,0,0,1-16,16H83l-32.6,28.16-.09.07A15.89,15.89,0,0,1,40,240a16.13,16.13,0,0,1-6.8-1.52A15.85,15.85,0,0,1,24,224V64A16,16,0,0,1,40,48H216A16,16,0,0,1,232,64ZM40,224h0ZM216,64H40V224l34.77-30A8,8,0,0,1,80,192H216Z\"/></svg>"), v("user", "<svg viewBox=\"0 0 256 256\" fill=\"currentColor\"><path d=\"M230.92,212c-15.23-26.33-38.7-45.21-66.09-54.16a72,72,0,1,0-73.66,0C63.78,166.78,40.31,185.66,25.08,212a8,8,0,1,0,13.85,8C55.71,194.74,89.05,176,128,176s72.29,18.74,89.07,44a8,8,0,0,0,13.85-8ZM72,96a56,56,0,1,1,56,56A56.06,56.06,0,0,1,72,96Z\"/></svg>"), v("stop", "<svg viewBox=\"0 0 256 256\" fill=\"currentColor\"><path d=\"M200,40H56A16,16,0,0,0,40,56V200a16,16,0,0,0,16,16H200a16,16,0,0,0,16-16V56A16,16,0,0,0,200,40Zm0,160H56V56H200V200Z\"/></svg>"), v("arrow-counter-clockwise", "<svg viewBox=\"0 0 256 256\" fill=\"currentColor\"><path d=\"M224,128a96,96,0,0,1-94.71,96H128A95.38,95.38,0,0,1,62.1,197.8a8,8,0,0,1,11-11.63A80,80,0,1,0,71.43,71.39a3.07,3.07,0,0,1-.26.25L44.59,96H72a8,8,0,0,1,0,16H24a8,8,0,0,1-8-8V56a8,8,0,0,1,16,0V85.8L60.25,60A96,96,0,0,1,224,128Z\"/></svg>");
|
|
4
|
+
export { c as NChatAvatar, o as NChatFeed, n as NChatInput, u as NChatInputStructured, t as NChatMessage, i as NChatMessageActivity, s as NChatMessageGenUI, l as NChatMessageSeed, e as NChatMessageText, a as NChatMessages, r as NChatPanel };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ChatStreamChunk, TransportState } from './types.ts';
|
|
2
|
+
export type StreamEndReason = 'complete' | 'partial' | 'error' | 'stopped';
|
|
3
|
+
/**
|
|
4
|
+
* Classify how a stream ended based on the final chunk and optional error.
|
|
5
|
+
* - `complete` — explicit done signal received (e.g., `[DONE]` sentinel, `finish_reason`)
|
|
6
|
+
* - `partial` — stream ended without explicit completion (truncated)
|
|
7
|
+
* - `error` — an error occurred during streaming
|
|
8
|
+
* - `stopped` — consumer aborted the stream
|
|
9
|
+
*/
|
|
10
|
+
export declare function classifyStreamEnd(chunk: ChatStreamChunk, error?: Error): StreamEndReason;
|
|
11
|
+
/**
|
|
12
|
+
* Classify an HTTP status code into a transport state.
|
|
13
|
+
*/
|
|
14
|
+
export declare function classifyHttpError(status: number): TransportState;
|
|
15
|
+
/**
|
|
16
|
+
* Calculate exponential backoff delay with jitter.
|
|
17
|
+
*/
|
|
18
|
+
export declare function backoffDelay(attempt: number, base?: number, max?: number): number;
|
|
19
|
+
//# sourceMappingURL=classify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classify.d.ts","sourceRoot":"","sources":["../../src/stream/classify.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAElE,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAE3E;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,eAAe,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,eAAe,CAOxF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAKhE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,SAAO,EAAE,GAAG,SAAQ,GAAG,MAAM,CAE9E"}
|
|
@@ -13,7 +13,7 @@ export interface ChatTransport {
|
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
15
|
* Create a reusable chat transport that sends requests and returns a
|
|
16
|
-
* streaming async generator.
|
|
16
|
+
* streaming async generator. Supports retry/backoff and transport state callbacks.
|
|
17
17
|
*/
|
|
18
18
|
export declare function createChatTransport(options: ChatTransportOptions): ChatTransport;
|
|
19
19
|
//# sourceMappingURL=create-transport.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-transport.d.ts","sourceRoot":"","sources":["../../src/stream/create-transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,oBAAoB,
|
|
1
|
+
{"version":3,"file":"create-transport.d.ts","sourceRoot":"","sources":["../../src/stream/create-transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,oBAAoB,EAAmB,MAAM,YAAY,CAAC;AAMvG;;GAEG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,CAK9D;AAED;;;GAGG;AACH,wBAAuB,gBAAgB,CACrC,QAAQ,EAAE,QAAQ,EAClB,MAAM,CAAC,EAAE,YAAY,GACpB,cAAc,CAAC,eAAe,CAAC,CAejC;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC;CAC/D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,oBAAoB,GAC5B,aAAa,CAsGf"}
|
package/dist/stream/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
export type { ChatStreamChunk, StreamFormat, ChatTransportOptions, ChatStreamEvent, } from './types.ts';
|
|
1
|
+
export type { ChatStreamChunk, StreamFormat, ChatTransportOptions, ChatStreamEvent, TransportState, TransportStatus, TransportStateCallback, RetryOptions, } from './types.ts';
|
|
2
2
|
export { parseSSE } from './parse-sse.ts';
|
|
3
3
|
export { parseNDJSON } from './parse-ndjson.ts';
|
|
4
4
|
export { parseJSON } from './parse-json.ts';
|
|
5
5
|
export type { ChatTransport } from './create-transport.ts';
|
|
6
6
|
export { detectFormat, createChatStream, createChatTransport, } from './create-transport.ts';
|
|
7
|
+
export type { StreamEndReason } from './classify.ts';
|
|
8
|
+
export { classifyStreamEnd, classifyHttpError, backoffDelay } from './classify.ts';
|
|
7
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/stream/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,eAAe,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/stream/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,eAAe,EACf,cAAc,EACd,eAAe,EACf,sBAAsB,EACtB,YAAY,GACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,YAAY,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-ndjson.d.ts","sourceRoot":"","sources":["../../src/stream/parse-ndjson.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;;;GAKG;AACH,wBAAuB,WAAW,CAChC,QAAQ,EAAE,QAAQ,GACjB,cAAc,CAAC,eAAe,CAAC,
|
|
1
|
+
{"version":3,"file":"parse-ndjson.d.ts","sourceRoot":"","sources":["../../src/stream/parse-ndjson.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;;;GAKG;AACH,wBAAuB,WAAW,CAChC,QAAQ,EAAE,QAAQ,GACjB,cAAc,CAAC,eAAe,CAAC,CA2FjC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-sse.d.ts","sourceRoot":"","sources":["../../src/stream/parse-sse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;;;GAKG;AACH,wBAAuB,QAAQ,CAC7B,QAAQ,EAAE,QAAQ,GACjB,cAAc,CAAC,eAAe,CAAC,
|
|
1
|
+
{"version":3,"file":"parse-sse.d.ts","sourceRoot":"","sources":["../../src/stream/parse-sse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;;;GAKG;AACH,wBAAuB,QAAQ,CAC7B,QAAQ,EAAE,QAAQ,GACjB,cAAc,CAAC,eAAe,CAAC,CAmIjC"}
|
package/dist/stream/types.d.ts
CHANGED
|
@@ -4,17 +4,36 @@ export interface ChatStreamChunk {
|
|
|
4
4
|
role: 'assistant' | 'user';
|
|
5
5
|
datetime: number;
|
|
6
6
|
done: boolean;
|
|
7
|
+
/** True when stream ended without an explicit completion signal (e.g., no `[DONE]` sentinel). */
|
|
8
|
+
partial?: boolean;
|
|
7
9
|
}
|
|
8
10
|
export type StreamFormat = 'sse' | 'ndjson' | 'json';
|
|
11
|
+
export type TransportState = 'idle' | 'sending' | 'streaming' | 'retrying' | 'rate-limited' | 'auth-required' | 'server-error' | 'offline' | 'ready';
|
|
12
|
+
export interface TransportStatus {
|
|
13
|
+
state: TransportState;
|
|
14
|
+
statusCode?: number;
|
|
15
|
+
retryInMs?: number;
|
|
16
|
+
attempt?: number;
|
|
17
|
+
maxAttempts?: number;
|
|
18
|
+
error?: Error;
|
|
19
|
+
}
|
|
20
|
+
export type TransportStateCallback = (status: TransportStatus) => void;
|
|
21
|
+
export interface RetryOptions {
|
|
22
|
+
maxAttempts?: number;
|
|
23
|
+
baseDelayMs?: number;
|
|
24
|
+
maxDelayMs?: number;
|
|
25
|
+
}
|
|
9
26
|
export interface ChatTransportOptions {
|
|
10
27
|
baseUrl: string;
|
|
11
28
|
clientId?: string;
|
|
12
29
|
format?: StreamFormat;
|
|
13
30
|
headers?: Record<string, string>;
|
|
14
31
|
signal?: AbortSignal;
|
|
32
|
+
onStateChange?: TransportStateCallback;
|
|
33
|
+
retry?: RetryOptions;
|
|
15
34
|
}
|
|
16
35
|
export interface ChatStreamEvent {
|
|
17
|
-
type: 'start' | 'chunk' | 'complete' | 'error' | 'stop';
|
|
36
|
+
type: 'start' | 'chunk' | 'complete' | 'partial' | 'error' | 'stop';
|
|
18
37
|
chunk?: ChatStreamChunk;
|
|
19
38
|
error?: Error;
|
|
20
39
|
durationMs?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/stream/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,WAAW,GAAG,MAAM,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/stream/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,WAAW,GAAG,MAAM,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,iGAAiG;IACjG,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAIrD,MAAM,MAAM,cAAc,GACtB,MAAM,GACN,SAAS,GACT,WAAW,GACX,UAAU,GACV,cAAc,GACd,eAAe,GACf,cAAc,GACd,SAAS,GACT,OAAO,CAAC;AAEZ,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,cAAc,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,MAAM,MAAM,sBAAsB,GAAG,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;AAEvE,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,aAAa,CAAC,EAAE,sBAAsB,CAAC;IACvC,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;IACpE,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB"}
|