@nonoun/native-chat 0.2.1 → 0.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.
Files changed (36) hide show
  1. package/dist/{chat-input-structured-element-CbDnI4zv.js → chat-input-structured-element-C80qP8yg.js} +265 -108
  2. package/dist/chat-panel-element.d.ts.map +1 -1
  3. package/dist/feed/chat-feed-element.d.ts +19 -0
  4. package/dist/feed/chat-feed-element.d.ts.map +1 -1
  5. package/dist/index.d.ts +6 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/message/chat-message-element.d.ts +14 -1
  8. package/dist/message/chat-message-element.d.ts.map +1 -1
  9. package/dist/native-chat.css +31 -1
  10. package/dist/native-chat.js +426 -2
  11. package/dist/register.js +3 -3
  12. package/dist/stream/classify.d.ts +19 -0
  13. package/dist/stream/classify.d.ts.map +1 -0
  14. package/dist/stream/create-transport.d.ts +19 -0
  15. package/dist/stream/create-transport.d.ts.map +1 -0
  16. package/dist/stream/index.d.ts +9 -0
  17. package/dist/stream/index.d.ts.map +1 -0
  18. package/dist/stream/parse-json.d.ts +9 -0
  19. package/dist/stream/parse-json.d.ts.map +1 -0
  20. package/dist/stream/parse-ndjson.d.ts +9 -0
  21. package/dist/stream/parse-ndjson.d.ts.map +1 -0
  22. package/dist/stream/parse-sse.d.ts +9 -0
  23. package/dist/stream/parse-sse.d.ts.map +1 -0
  24. package/dist/stream/types.d.ts +42 -0
  25. package/dist/stream/types.d.ts.map +1 -0
  26. package/dist/telemetry/emitter.d.ts +20 -0
  27. package/dist/telemetry/emitter.d.ts.map +1 -0
  28. package/dist/telemetry/events.d.ts +11 -0
  29. package/dist/telemetry/events.d.ts.map +1 -0
  30. package/dist/telemetry/index.d.ts +5 -0
  31. package/dist/telemetry/index.d.ts.map +1 -0
  32. package/dist/telemetry/redactor.d.ts +17 -0
  33. package/dist/telemetry/redactor.d.ts.map +1 -0
  34. package/dist/telemetry/types.d.ts +27 -0
  35. package/dist/telemetry/types.d.ts.map +1 -0
  36. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"chat-panel-element.d.ts","sourceRoot":"","sources":["../src/chat-panel-element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAU,MAAM,mBAAmB,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,qBAAa,UAAW,SAAQ,aAAa;;IAC3C,MAAM,CAAC,kBAAkB,WAAiC;IAa1D,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAepF,IAAI,QAAQ,IAAI,OAAO,CAAiC;IACxD,IAAI,QAAQ,CAAC,GAAG,EAAE,OAAO,EAGxB;IAED,IAAI,WAAW,IAAI,OAAO,CAAoC;IAC9D,IAAI,WAAW,CAAC,GAAG,EAAE,OAAO,EAG3B;IAID,KAAK,IAAI,IAAI;IA6Hb,QAAQ,IAAI,IAAI;CA6CjB"}
1
+ {"version":3,"file":"chat-panel-element.d.ts","sourceRoot":"","sources":["../src/chat-panel-element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAU,MAAM,mBAAmB,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,qBAAa,UAAW,SAAQ,aAAa;;IAC3C,MAAM,CAAC,kBAAkB,WAAiC;IAa1D,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAepF,IAAI,QAAQ,IAAI,OAAO,CAAiC;IACxD,IAAI,QAAQ,CAAC,GAAG,EAAE,OAAO,EAGxB;IAED,IAAI,WAAW,IAAI,OAAO,CAAoC;IAC9D,IAAI,WAAW,CAAC,GAAG,EAAE,OAAO,EAG3B;IAID,KAAK,IAAI,IAAI;IA4Hb,QAAQ,IAAI,IAAI;CA6CjB"}
@@ -12,8 +12,21 @@ import { NativeElement } from '@nonoun/native-ui';
12
12
  * </n-chat-feed>
13
13
  * ```
14
14
  *
15
+ * ### Virtualization (opt-in)
16
+ *
17
+ * ```html
18
+ * <n-chat-feed virtual virtual-item-height="80" virtual-overscan="8">
19
+ * </n-chat-feed>
20
+ * ```
21
+ *
22
+ * Set `items` and `itemRenderer` properties for programmatic data-driven rendering.
23
+ *
15
24
  * @attr {boolean} auto-scroll - Enable auto-scroll to bottom on new content (default: true)
25
+ * @attr {boolean} virtual - Enable virtual scroll windowing
26
+ * @attr {string} virtual-item-height - Estimated item height in px (default: 80)
27
+ * @attr {string} virtual-overscan - Number of extra items to render outside viewport (default: 5)
16
28
  * @fires native:feed-scroll - Fired when scroll pinned state changes
29
+ * @fires native:range-change - Fired when virtual scroll range changes
17
30
  */
18
31
  export declare class NChatFeed extends NativeElement {
19
32
  #private;
@@ -22,6 +35,12 @@ export declare class NChatFeed extends NativeElement {
22
35
  get isPinned(): boolean;
23
36
  /** Scroll to the bottom of the feed. */
24
37
  scrollToBottom(smooth?: boolean): void;
38
+ /** Data items for virtual rendering. */
39
+ get items(): unknown[];
40
+ set items(val: unknown[]);
41
+ /** Callback that creates an HTMLElement from a data item. */
42
+ get itemRenderer(): ((item: unknown, index: number) => HTMLElement) | null;
43
+ set itemRenderer(fn: ((item: unknown, index: number) => HTMLElement) | null);
25
44
  attributeChangedCallback(name: string, old: string | null, val: string | null): void;
26
45
  setup(): void;
27
46
  teardown(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"chat-feed-element.d.ts","sourceRoot":"","sources":["../../src/feed/chat-feed-element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAU,MAAM,mBAAmB,CAAC;AAI1D;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,SAAU,SAAQ,aAAa;;IAC1C,MAAM,CAAC,kBAAkB,WAAmB;;IAc5C,IAAI,QAAQ,IAAI,OAAO,CAAiC;IAExD,wCAAwC;IACxC,cAAc,CAAC,MAAM,UAAO,GAAG,IAAI;IAUnC,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAUpF,KAAK,IAAI,IAAI;IAsBb,QAAQ,IAAI,IAAI;CAuCjB"}
1
+ {"version":3,"file":"chat-feed-element.d.ts","sourceRoot":"","sources":["../../src/feed/chat-feed-element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAmC,MAAM,mBAAmB,CAAC;AAInF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBAAa,SAAU,SAAQ,aAAa;;IAC1C,MAAM,CAAC,kBAAkB,WAAuF;;IAoBhH,IAAI,QAAQ,IAAI,OAAO,CAAiC;IAExD,wCAAwC;IACxC,cAAc,CAAC,MAAM,UAAO,GAAG,IAAI;IAQnC,wCAAwC;IACxC,IAAI,KAAK,IAAI,OAAO,EAAE,CAA8B;IACpD,IAAI,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,EAKvB;IAED,6DAA6D;IAC7D,IAAI,YAAY,IAAI,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,WAAW,CAAC,GAAG,IAAI,CAA+B;IACzG,IAAI,YAAY,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,WAAW,CAAC,GAAG,IAAI,EAE1E;IAID,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IA0BpF,KAAK,IAAI,IAAI;IAiCb,QAAQ,IAAI,IAAI;CA6HjB"}
package/dist/index.d.ts CHANGED
@@ -4,8 +4,14 @@ export { NChatPanel } from './chat-panel-element.ts';
4
4
  export { NChatFeed } from './feed/index.ts';
5
5
  export { NChatAvatar } from './avatar/index.ts';
6
6
  export { NChatMessage, NChatMessages, NChatMessageText, NChatMessageActivity, NChatMessageSeed, NChatMessageGenUI, NChatInputStructured, } from './message/index.ts';
7
+ export type { ChatMessageActionDef } from './message/chat-message-element.ts';
8
+ export { ACTION_REGISTRY, ROLE_DEFAULTS } from './message/chat-message-element.ts';
7
9
  export type { SeedOption } from './message/chat-message-seed-element.ts';
8
10
  export type { StructuredOption } from './message/chat-input-structured-element.ts';
9
11
  export type { GenUINode } from './message/chat-message-genui-element.ts';
10
12
  export { renderMarkdown, renderInline, sanitizeHtml } from './message/chat-message-text-element.ts';
13
+ export type { ChatStreamChunk, StreamFormat, ChatTransportOptions, ChatStreamEvent, ChatTransport, TransportState, TransportStatus, TransportStateCallback, RetryOptions, StreamEndReason, } from './stream/index.ts';
14
+ export { parseSSE, parseNDJSON, parseJSON, detectFormat, createChatStream, createChatTransport, classifyStreamEnd, classifyHttpError, backoffDelay, } from './stream/index.ts';
15
+ export type { TelemetryCorrelation, TelemetryTiming, TelemetryRetry, TelemetryLevel, TelemetryEvent, TelemetryRedactor, } from './telemetry/index.ts';
16
+ export { CHAT_EVENTS, SAFE_FIELDS, SENSITIVE_FIELDS, scrubPII, createDefaultRedactor, TelemetryEmitter, } from './telemetry/index.ts';
11
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AAGvB,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAGrD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EACL,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EAAE,UAAU,EAAE,MAAM,wCAAwC,CAAC;AACzE,YAAY,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AACnF,YAAY,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AAGvB,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAGrD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EACL,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAGnF,YAAY,EAAE,UAAU,EAAE,MAAM,wCAAwC,CAAC;AACzE,YAAY,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AACnF,YAAY,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAC;AAGpG,YAAY,EACV,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,eAAe,EACf,aAAa,EACb,cAAc,EACd,eAAe,EACf,sBAAsB,EACtB,YAAY,EACZ,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,QAAQ,EACR,WAAW,EACX,SAAS,EACT,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,GACb,MAAM,mBAAmB,CAAC;AAG3B,YAAY,EACV,oBAAoB,EACpB,eAAe,EACf,cAAc,EACd,cAAc,EACd,cAAc,EACd,iBAAiB,GAClB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,QAAQ,EACR,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,sBAAsB,CAAC"}
@@ -1,4 +1,10 @@
1
1
  import { NativeElement } from '@nonoun/native-ui';
2
+ export interface ChatMessageActionDef {
3
+ label: string;
4
+ icon: string;
5
+ }
6
+ export declare const ACTION_REGISTRY: Record<string, ChatMessageActionDef>;
7
+ export declare const ROLE_DEFAULTS: Record<string, string[]>;
2
8
  /**
3
9
  * Individual chat message bubble.
4
10
  *
@@ -8,8 +14,11 @@ import { NativeElement } from '@nonoun/native-ui';
8
14
  * @attr {string} role - `user` | `assistant` | `system`
9
15
  * @attr {string} message-id - Unique message identifier
10
16
  * @attr {string} timestamp - Epoch milliseconds
11
- * @attr {string} status - `sending` | `sent` | `error` | `streaming`
17
+ * @attr {string} status - `sending` | `sent` | `error` | `streaming` | `partial`
18
+ * @attr {string} actions - Comma-separated action list, or `"none"` to suppress
19
+ * @attr {string} actions-style - `"label"` (default) | `"icon"` | `"icon-label"`
12
20
  * @fires native:message-action - Fired when an action button is clicked
21
+ * @fires native:continue-request - Fired when continue is requested for a partial message
13
22
  */
14
23
  export declare class NChatMessage extends NativeElement {
15
24
  #private;
@@ -21,6 +30,10 @@ export declare class NChatMessage extends NativeElement {
21
30
  get timestamp(): number;
22
31
  get status(): string;
23
32
  set status(val: string);
33
+ get actions(): string | null;
34
+ set actions(val: string | null);
35
+ get actionsStyle(): string;
36
+ set actionsStyle(val: string);
24
37
  attributeChangedCallback(name: string, old: string | null, val: string | null): void;
25
38
  setup(): void;
26
39
  teardown(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"chat-message-element.d.ts","sourceRoot":"","sources":["../../src/message/chat-message-element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAU,MAAM,mBAAmB,CAAC;AAE1D;;;;;;;;;;;GAWG;AACH,qBAAa,YAAa,SAAQ,aAAa;;IAC7C,MAAM,CAAC,kBAAkB,WAAiD;;IAc1E,IAAI,IAAI,IAAI,MAAM,CAA6B;IAC/C,IAAI,IAAI,CAAC,GAAG,EAAE,MAAM,EAGnB;IAED,IAAI,SAAS,IAAI,MAAM,CAAkD;IAEzE,IAAI,SAAS,IAAI,MAAM,CAAwD;IAE/E,IAAI,MAAM,IAAI,MAAM,CAA+B;IACnD,IAAI,MAAM,CAAC,GAAG,EAAE,MAAM,EAGrB;IAID,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAWpF,KAAK,IAAI,IAAI;IAeb,QAAQ,IAAI,IAAI;CAsDjB"}
1
+ {"version":3,"file":"chat-message-element.d.ts","sourceRoot":"","sources":["../../src/message/chat-message-element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAU,MAAM,mBAAmB,CAAC;AAI1D,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAOhE,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAGlD,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,qBAAa,YAAa,SAAQ,aAAa;;IAC7C,MAAM,CAAC,kBAAkB,WAA6E;;IAgBtG,IAAI,IAAI,IAAI,MAAM,CAA6B;IAC/C,IAAI,IAAI,CAAC,GAAG,EAAE,MAAM,EAGnB;IAED,IAAI,SAAS,IAAI,MAAM,CAAkD;IAEzE,IAAI,SAAS,IAAI,MAAM,CAAwD;IAE/E,IAAI,MAAM,IAAI,MAAM,CAA+B;IACnD,IAAI,MAAM,CAAC,GAAG,EAAE,MAAM,EAGrB;IAED,IAAI,OAAO,IAAI,MAAM,GAAG,IAAI,CAAgC;IAC5D,IAAI,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,EAO7B;IAED,IAAI,YAAY,IAAI,MAAM,CAAqC;IAC/D,IAAI,YAAY,CAAC,GAAG,EAAE,MAAM,EAG3B;IAID,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAapF,KAAK,IAAI,IAAI;IAkBb,QAAQ,IAAI,IAAI;CAoFjB"}
@@ -126,10 +126,16 @@
126
126
  gap: var(--n-chat-gap);
127
127
  flex: 1 1 0%;
128
128
  min-height: 0;
129
+ min-width: 0;
130
+ padding-block: calc(var(--n-space) * 4);
131
+ }
132
+
133
+ /* WHY: Opt-in scroll container — prevents layout conflicts when scroll
134
+ ownership belongs to a parent container. */
135
+ [scrollable]:where(n-chat-feed) {
129
136
  overflow-y: auto;
130
137
  scrollbar-width: thin;
131
138
  scroll-behavior: smooth;
132
- padding-block: calc(var(--n-space) * 4);
133
139
  }
134
140
 
135
141
  /* ── Date separator ── */
@@ -144,6 +150,19 @@
144
150
  user-select: none;
145
151
  }
146
152
 
153
+ /* ── Virtual scroll spacers ── */
154
+
155
+ :where(n-chat-feed) > :where(.n-chat-feed-virtual-container) {
156
+ display: flex;
157
+ flex-direction: column;
158
+ gap: var(--n-chat-gap);
159
+ }
160
+
161
+ :where(n-chat-feed) :where(.n-virtual-spacer-top),
162
+ :where(n-chat-feed) :where(.n-virtual-spacer-bottom) {
163
+ flex-shrink: 0;
164
+ }
165
+
147
166
  :where(n-chat-feed[hidden]) { display: none; }
148
167
 
149
168
  /* ══════════════════════════════════════════════════
@@ -156,6 +175,7 @@
156
175
  align-items: flex-start;
157
176
  gap: var(--n-chat-message-gap);
158
177
  align-self: flex-start;
178
+ min-width: 0;
159
179
  }
160
180
 
161
181
  /* User messages: right-aligned, avatar on right */
@@ -247,6 +267,11 @@
247
267
  border: 1px solid var(--n-border-danger);
248
268
  }
249
269
 
270
+ /* Partial status — stream ended without explicit completion */
271
+ [status="partial"]:where(n-chat-message) {
272
+ border-bottom: 2px dashed var(--n-border-muted);
273
+ }
274
+
250
275
  /* ── Message actions toolbar ── */
251
276
 
252
277
  :where(n-chat-message) > :where(.n-chat-message-actions) {
@@ -260,6 +285,11 @@
260
285
  opacity: 1;
261
286
  }
262
287
 
288
+ /* Partial status — always show actions (contains continue button) */
289
+ [status="partial"]:where(n-chat-message) > :where(.n-chat-message-actions) {
290
+ opacity: 1;
291
+ }
292
+
263
293
  :where(n-chat-message[hidden]) { display: none; }
264
294
 
265
295
  /* ══════════════════════════════════════════════════
@@ -1,2 +1,426 @@
1
- import { a as e, c as t, d as n, f as r, i, l as a, m as o, n as s, o as c, p as l, r as u, s as d, t as f, u as p } from "./chat-input-structured-element-CbDnI4zv.js";
2
- export { n as NChatAvatar, r as NChatFeed, o as NChatInput, f as NChatInputStructured, p as NChatMessage, i as NChatMessageActivity, s as NChatMessageGenUI, u as NChatMessageSeed, e as NChatMessageText, a as NChatMessages, l as NChatPanel, c as renderInline, d as renderMarkdown, t as sanitizeHtml };
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-C80qP8yg.js";
2
+ /**
3
+ * Parse a Server-Sent Events (SSE) response stream into ChatStreamChunk values.
4
+ *
5
+ * Reads `data:` lines from the response body, skips empty lines and comments,
6
+ * handles the `[DONE]` sentinel, and accumulates the full message across chunks.
7
+ */
8
+ async function* g(e) {
9
+ let t = e.body.getReader(), n = new TextDecoder("utf-8"), r = "", i = "";
10
+ try {
11
+ for (;;) {
12
+ let { done: e, value: a } = await t.read();
13
+ if (e) break;
14
+ r += n.decode(a, { stream: !0 });
15
+ let o = r.split("\n");
16
+ r = o.pop() ?? "";
17
+ for (let e of o) {
18
+ let t = e.trim();
19
+ if (t === "" || t.startsWith(":") || !t.startsWith("data:")) continue;
20
+ let n = t.slice(5).trim();
21
+ if (n === "[DONE]") {
22
+ yield {
23
+ delta: "",
24
+ fullMessage: i,
25
+ role: "assistant",
26
+ datetime: Date.now(),
27
+ done: !0
28
+ };
29
+ return;
30
+ }
31
+ let r;
32
+ try {
33
+ r = JSON.parse(n);
34
+ } catch {
35
+ continue;
36
+ }
37
+ let a = "";
38
+ if (typeof r.delta == "string") a = r.delta;
39
+ else if (Array.isArray(r.choices)) {
40
+ let e = r.choices[0];
41
+ typeof e?.delta?.content == "string" && (a = e.delta.content);
42
+ } else typeof r.content == "string" && (a = r.content);
43
+ i += a;
44
+ let o = r.done === !0 || Array.isArray(r.choices) && r.choices[0]?.finish_reason != null;
45
+ if (yield {
46
+ delta: a,
47
+ fullMessage: i,
48
+ role: "assistant",
49
+ datetime: Date.now(),
50
+ done: !!o
51
+ }, o) return;
52
+ }
53
+ }
54
+ let e = (r + n.decode()).trim();
55
+ if (e !== "" && e.startsWith("data:")) {
56
+ let t = e.slice(5).trim();
57
+ if (t !== "" && t !== "[DONE]") try {
58
+ let e = JSON.parse(t), n = "";
59
+ typeof e.delta == "string" ? n = e.delta : typeof e.content == "string" && (n = e.content), i += n, yield {
60
+ delta: n,
61
+ fullMessage: i,
62
+ role: "assistant",
63
+ datetime: Date.now(),
64
+ done: !0,
65
+ partial: !0
66
+ };
67
+ return;
68
+ } catch {}
69
+ }
70
+ i.length > 0 && (yield {
71
+ delta: "",
72
+ fullMessage: i,
73
+ role: "assistant",
74
+ datetime: Date.now(),
75
+ done: !0,
76
+ partial: !0
77
+ });
78
+ } finally {
79
+ t.releaseLock();
80
+ }
81
+ }
82
+ /**
83
+ * Parse a newline-delimited JSON (NDJSON) response stream into ChatStreamChunk values.
84
+ *
85
+ * Each non-empty line is parsed as a standalone JSON object.
86
+ * Accumulates the full message across chunks.
87
+ */
88
+ async function* _(e) {
89
+ let t = e.body.getReader(), n = new TextDecoder("utf-8"), r = "", i = "";
90
+ try {
91
+ for (;;) {
92
+ let { done: e, value: a } = await t.read();
93
+ if (e) break;
94
+ r += n.decode(a, { stream: !0 });
95
+ let o = r.split("\n");
96
+ r = o.pop() ?? "";
97
+ for (let e of o) {
98
+ let t = e.trim();
99
+ if (t === "") continue;
100
+ let n;
101
+ try {
102
+ n = JSON.parse(t);
103
+ } catch {
104
+ continue;
105
+ }
106
+ let r = "";
107
+ typeof n.delta == "string" ? r = n.delta : typeof n.content == "string" && (r = n.content), i += r;
108
+ let a = n.done === !0;
109
+ if (yield {
110
+ delta: r,
111
+ fullMessage: i,
112
+ role: "assistant",
113
+ datetime: Date.now(),
114
+ done: a
115
+ }, a) return;
116
+ }
117
+ }
118
+ let e = (r + n.decode()).trim();
119
+ if (e !== "") try {
120
+ let t = JSON.parse(e), n = "";
121
+ typeof t.delta == "string" ? n = t.delta : typeof t.content == "string" && (n = t.content), i += n, yield {
122
+ delta: n,
123
+ fullMessage: i,
124
+ role: "assistant",
125
+ datetime: Date.now(),
126
+ done: !0,
127
+ partial: !0
128
+ };
129
+ return;
130
+ } catch {}
131
+ i.length > 0 && (yield {
132
+ delta: "",
133
+ fullMessage: i,
134
+ role: "assistant",
135
+ datetime: Date.now(),
136
+ done: !0,
137
+ partial: !0
138
+ });
139
+ } finally {
140
+ t.releaseLock();
141
+ }
142
+ }
143
+ /**
144
+ * Parse a standard JSON response as a single ChatStreamChunk.
145
+ *
146
+ * Reads the entire response body, parses as JSON, and yields one chunk
147
+ * with `done: true`.
148
+ */
149
+ async function* v(e) {
150
+ let t = await e.json(), n = "";
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 {
152
+ delta: n,
153
+ fullMessage: n,
154
+ role: "assistant",
155
+ datetime: Date.now(),
156
+ done: !0
157
+ };
158
+ }
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
+ /**
182
+ * Detect the stream format from a Content-Type header value.
183
+ */
184
+ function S(e) {
185
+ let t = e.toLowerCase();
186
+ return t.includes("text/event-stream") ? "sse" : t.includes("ndjson") || t.includes("x-ndjson") ? "ndjson" : "json";
187
+ }
188
+ /**
189
+ * Create an async generator that yields ChatStreamChunk values from a
190
+ * Response, auto-detecting the format from Content-Type when not specified.
191
+ */
192
+ async function* C(e, t) {
193
+ switch (t ?? S(e.headers.get("content-type") ?? "")) {
194
+ case "sse":
195
+ yield* g(e);
196
+ break;
197
+ case "ndjson":
198
+ yield* _(e);
199
+ break;
200
+ case "json":
201
+ yield* v(e);
202
+ break;
203
+ }
204
+ }
205
+ /**
206
+ * Create a reusable chat transport that sends requests and returns a
207
+ * streaming async generator. Supports retry/backoff and transport state callbacks.
208
+ */
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 = {
215
+ "Content-Type": "application/json",
216
+ ...e.headers
217
+ };
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");
285
+ } };
286
+ }
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 = {
304
+ TRANSPORT: "native:chat-transport",
305
+ GENERATION_START: "native:generation-start",
306
+ GENERATION_COMPLETE: "native:generation-complete",
307
+ GENERATION_STOP: "native:generation-stop",
308
+ GENERATION_ERROR: "native:generation-error",
309
+ WARNING: "native:chat-warning"
310
+ }, O = [
311
+ "requestId",
312
+ "sessionId",
313
+ "conversationId",
314
+ "messageId",
315
+ "mode",
316
+ "contentType",
317
+ "durationMs",
318
+ "startedAt",
319
+ "completedAt",
320
+ "attempt",
321
+ "maxAttempts",
322
+ "chunkIndex"
323
+ ], k = [
324
+ "query",
325
+ "message",
326
+ "delta",
327
+ "fullMessage",
328
+ "body",
329
+ "content",
330
+ "prompt",
331
+ "response"
332
+ ];
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;
334
+ /**
335
+ * Scrub common PII patterns from a string.
336
+ *
337
+ * Replaces email addresses, phone-like numbers, and credit-card-like
338
+ * number sequences with `[redacted]` placeholders.
339
+ */
340
+ function N(e) {
341
+ return e.replace(A, "[redacted:email]").replace(M, "[redacted:card]").replace(j, "[redacted:phone]");
342
+ }
343
+ var P = new Set(k);
344
+ /**
345
+ * Create a default redactor for the given telemetry level.
346
+ *
347
+ * - **minimal**: Sensitive fields in `detail` are replaced with
348
+ * `[redacted:Nchars]` indicating the original length.
349
+ * - **debug**: All fields pass through unmodified.
350
+ */
351
+ function F(e) {
352
+ return e === "debug" ? (e) => e : (e) => {
353
+ if (!e.detail) return e;
354
+ let t = {};
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;
356
+ return {
357
+ ...e,
358
+ detail: t
359
+ };
360
+ };
361
+ }
362
+ /**
363
+ * Dispatches telemetry events as `CustomEvent` instances on a given
364
+ * `EventTarget`, applying a configurable redactor before emission.
365
+ */
366
+ var I = class {
367
+ #e;
368
+ #t;
369
+ constructor(e, t = "minimal") {
370
+ this.#e = e, this.#t = F(t);
371
+ }
372
+ /** Change the telemetry level, replacing the redactor. */
373
+ setLevel(e) {
374
+ this.#t = F(e);
375
+ }
376
+ /** Replace the redactor with a custom implementation. */
377
+ setRedactor(e) {
378
+ this.#t = e;
379
+ }
380
+ /** Apply the redactor and dispatch the event on the target. */
381
+ emit(e) {
382
+ let t = this.#t(e);
383
+ this.#e.dispatchEvent(new CustomEvent(t.type, {
384
+ detail: t,
385
+ bubbles: !0
386
+ }));
387
+ }
388
+ emitTransport(e, t, n) {
389
+ this.emit({
390
+ type: D.TRANSPORT,
391
+ correlation: e,
392
+ detail: {
393
+ mode: t,
394
+ contentType: n
395
+ }
396
+ });
397
+ }
398
+ emitGenerationStart(e) {
399
+ this.emit({
400
+ type: D.GENERATION_START,
401
+ correlation: e,
402
+ timing: { startedAt: Date.now() }
403
+ });
404
+ }
405
+ emitGenerationComplete(e, t) {
406
+ this.emit({
407
+ type: D.GENERATION_COMPLETE,
408
+ correlation: e,
409
+ timing: {
410
+ completedAt: Date.now(),
411
+ durationMs: t
412
+ }
413
+ });
414
+ }
415
+ emitWarning(e, t, n) {
416
+ this.emit({
417
+ type: D.WARNING,
418
+ correlation: e,
419
+ detail: {
420
+ message: t,
421
+ ...n
422
+ }
423
+ });
424
+ }
425
+ };
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, f as n, i as r, l as i, m as a, n as o, p as s, r as c, t as l, u } from "./chat-input-structured-element-CbDnI4zv.js";
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-C80qP8yg.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", a), _("native-chat-panel", s), _("n-chat-feed", n), _("n-chat-avatar", t), _("n-chat-message", u), _("n-chat-messages", i), _("n-chat-message-text", e), _("n-chat-message-activity", r), _("n-chat-message-seed", c), _("n-chat-message-genui", o), _("n-chat-input-structured", l), _("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 { t as NChatAvatar, n as NChatFeed, a as NChatInput, l as NChatInputStructured, u as NChatMessage, r as NChatMessageActivity, o as NChatMessageGenUI, c as NChatMessageSeed, e as NChatMessageText, i as NChatMessages, s as NChatPanel };
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"}
@@ -0,0 +1,19 @@
1
+ import type { ChatStreamChunk, StreamFormat, ChatTransportOptions } from './types.ts';
2
+ /**
3
+ * Detect the stream format from a Content-Type header value.
4
+ */
5
+ export declare function detectFormat(contentType: string): StreamFormat;
6
+ /**
7
+ * Create an async generator that yields ChatStreamChunk values from a
8
+ * Response, auto-detecting the format from Content-Type when not specified.
9
+ */
10
+ export declare function createChatStream(response: Response, format?: StreamFormat): AsyncGenerator<ChatStreamChunk>;
11
+ export interface ChatTransport {
12
+ send(body: unknown): Promise<AsyncGenerator<ChatStreamChunk>>;
13
+ }
14
+ /**
15
+ * Create a reusable chat transport that sends requests and returns a
16
+ * streaming async generator. Supports retry/backoff and transport state callbacks.
17
+ */
18
+ export declare function createChatTransport(options: ChatTransportOptions): ChatTransport;
19
+ //# sourceMappingURL=create-transport.d.ts.map
@@ -0,0 +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,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"}