@providerprotocol/ai 0.0.35 → 0.0.36

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 (71) hide show
  1. package/README.md +17 -13
  2. package/dist/anthropic/index.d.ts +2 -2
  3. package/dist/anthropic/index.js +1 -1
  4. package/dist/cerebras/index.d.ts +2 -2
  5. package/dist/cerebras/index.js +1 -1
  6. package/dist/{chunk-7DXVRILR.js → chunk-2YXFLRQ6.js} +2 -2
  7. package/dist/chunk-2YXFLRQ6.js.map +1 -0
  8. package/dist/{chunk-HB4ZIH3T.js → chunk-4RX4VQCB.js} +2 -2
  9. package/dist/chunk-4RX4VQCB.js.map +1 -0
  10. package/dist/{chunk-ZI67WIQS.js → chunk-5IWHCXKN.js} +2 -2
  11. package/dist/chunk-5IWHCXKN.js.map +1 -0
  12. package/dist/{chunk-VOEWHQUB.js → chunk-CRP6Y7NF.js} +2 -2
  13. package/dist/chunk-CRP6Y7NF.js.map +1 -0
  14. package/dist/{chunk-3GWM5GR3.js → chunk-EPB3GQNL.js} +30 -65
  15. package/dist/chunk-EPB3GQNL.js.map +1 -0
  16. package/dist/{chunk-6S222DHN.js → chunk-RJGTRQ47.js} +20 -1
  17. package/dist/chunk-RJGTRQ47.js.map +1 -0
  18. package/dist/{embedding-CW6SaOOz.d.ts → embedding-BXA72PlJ.d.ts} +1 -1
  19. package/dist/google/index.d.ts +2 -2
  20. package/dist/google/index.js +1 -1
  21. package/dist/groq/index.d.ts +2 -2
  22. package/dist/groq/index.js +1 -1
  23. package/dist/http/index.d.ts +3 -3
  24. package/dist/{image-stream-C0ciACM2.d.ts → image-stream-CCgwB7ve.d.ts} +1 -1
  25. package/dist/index.d.ts +7 -7
  26. package/dist/index.js +1 -1
  27. package/dist/{llm-DwbUK7un.d.ts → llm-ByUFPcFH.d.ts} +1 -1
  28. package/dist/middleware/logging/index.d.ts +2 -2
  29. package/dist/middleware/parsed-object/index.d.ts +2 -2
  30. package/dist/middleware/parsed-object/index.js +1 -1
  31. package/dist/middleware/pubsub/index.d.ts +27 -34
  32. package/dist/middleware/pubsub/index.js +49 -119
  33. package/dist/middleware/pubsub/index.js.map +1 -1
  34. package/dist/middleware/pubsub/server/express/index.d.ts +24 -10
  35. package/dist/middleware/pubsub/server/express/index.js +2 -2
  36. package/dist/middleware/pubsub/server/fastify/index.d.ts +24 -10
  37. package/dist/middleware/pubsub/server/fastify/index.js +2 -2
  38. package/dist/middleware/pubsub/server/h3/index.d.ts +23 -9
  39. package/dist/middleware/pubsub/server/h3/index.js +2 -2
  40. package/dist/middleware/pubsub/server/index.d.ts +2 -2
  41. package/dist/middleware/pubsub/server/index.js +5 -5
  42. package/dist/middleware/pubsub/server/webapi/index.d.ts +23 -13
  43. package/dist/middleware/pubsub/server/webapi/index.js +2 -2
  44. package/dist/ollama/index.d.ts +2 -2
  45. package/dist/ollama/index.js +1 -1
  46. package/dist/openai/index.d.ts +2 -2
  47. package/dist/openai/index.js +1 -1
  48. package/dist/openrouter/index.d.ts +2 -2
  49. package/dist/openrouter/index.js +1 -1
  50. package/dist/proxy/index.d.ts +4 -4
  51. package/dist/proxy/index.js +1 -1
  52. package/dist/proxy/server/express/index.d.ts +4 -4
  53. package/dist/proxy/server/fastify/index.d.ts +4 -4
  54. package/dist/proxy/server/h3/index.d.ts +4 -4
  55. package/dist/proxy/server/index.d.ts +4 -4
  56. package/dist/proxy/server/webapi/index.d.ts +4 -4
  57. package/dist/responses/index.d.ts +2 -2
  58. package/dist/responses/index.js +1 -1
  59. package/dist/{retry-YayV42GV.d.ts → retry-BDMo4AVu.d.ts} +1 -1
  60. package/dist/{stream-CecfVCPO.d.ts → stream-S7nwQRqM.d.ts} +17 -6
  61. package/dist/types-CE4B7pno.d.ts +96 -0
  62. package/dist/xai/index.d.ts +2 -2
  63. package/dist/xai/index.js +1 -1
  64. package/package.json +1 -1
  65. package/dist/chunk-3GWM5GR3.js.map +0 -1
  66. package/dist/chunk-6S222DHN.js.map +0 -1
  67. package/dist/chunk-7DXVRILR.js.map +0 -1
  68. package/dist/chunk-HB4ZIH3T.js.map +0 -1
  69. package/dist/chunk-VOEWHQUB.js.map +0 -1
  70. package/dist/chunk-ZI67WIQS.js.map +0 -1
  71. package/dist/types-C8Gciizr.d.ts +0 -168
@@ -1,5 +1,5 @@
1
- import { P as PubSubAdapter } from '../../../../types-C8Gciizr.js';
2
- import '../../../../stream-CecfVCPO.js';
1
+ import { P as PubSubAdapter } from '../../../../types-CE4B7pno.js';
2
+ import '../../../../stream-S7nwQRqM.js';
3
3
 
4
4
  /**
5
5
  * @fileoverview Web API adapter for pub-sub stream resumption.
@@ -13,12 +13,10 @@ import '../../../../stream-CecfVCPO.js';
13
13
  /**
14
14
  * Creates a ReadableStream that replays buffered events and subscribes to live events.
15
15
  *
16
- * This utility handles the reconnection pattern for server routes:
17
- * 1. Replays all buffered events from the adapter
18
- * 2. If stream is already completed, closes immediately
19
- * 3. Otherwise, subscribes to live events until completion
20
- *
21
- * Works with any framework that supports web standard ReadableStream.
16
+ * Handles reconnection for Web API frameworks (Bun, Deno, Next.js, Cloudflare Workers):
17
+ * 1. Replays buffered events from the adapter
18
+ * 2. Subscribes to live events until completion signal
19
+ * 3. Closes when stream completes or client disconnects
22
20
  *
23
21
  * @param streamId - The stream ID to subscribe to
24
22
  * @param adapter - The pub-sub adapter instance
@@ -26,17 +24,29 @@ import '../../../../stream-CecfVCPO.js';
26
24
  *
27
25
  * @example
28
26
  * ```typescript
29
- * import { createSubscriberStream } from '@providerprotocol/ai/middleware/pubsub/server/webapi';
27
+ * import { llm } from '@providerprotocol/ai';
28
+ * import { anthropic } from '@providerprotocol/ai/anthropic';
29
+ * import { pubsubMiddleware, memoryAdapter } from '@providerprotocol/ai/middleware/pubsub';
30
+ * import { webapi } from '@providerprotocol/ai/middleware/pubsub/server';
31
+ *
32
+ * const adapter = memoryAdapter();
30
33
  *
31
- * // Next.js App Router
34
+ * // Next.js App Router / Bun.serve / Deno.serve
32
35
  * export async function POST(req: Request) {
33
- * const { streamId } = await req.json();
36
+ * const { input, conversationId } = await req.json();
37
+ *
38
+ * if (!await adapter.exists(conversationId)) {
39
+ * const model = llm({
40
+ * model: anthropic('claude-sonnet-4-20250514'),
41
+ * middleware: [pubsubMiddleware({ adapter, streamId: conversationId })],
42
+ * });
43
+ * model.stream(input).then(turn => saveToDatabase(conversationId, turn));
44
+ * }
34
45
  *
35
- * return new Response(createSubscriberStream(streamId, adapter), {
46
+ * return new Response(webapi.createSubscriberStream(conversationId, adapter), {
36
47
  * headers: {
37
48
  * 'Content-Type': 'text/event-stream',
38
49
  * 'Cache-Control': 'no-cache',
39
- * 'Connection': 'keep-alive',
40
50
  * },
41
51
  * });
42
52
  * }
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  createSubscriberStream,
3
3
  webapi
4
- } from "../../../../chunk-7DXVRILR.js";
5
- import "../../../../chunk-3GWM5GR3.js";
4
+ } from "../../../../chunk-2YXFLRQ6.js";
5
+ import "../../../../chunk-EPB3GQNL.js";
6
6
  import "../../../../chunk-ETBFOLQN.js";
7
7
  export {
8
8
  createSubscriberStream,
@@ -1,5 +1,5 @@
1
- import { d as Provider } from '../llm-DwbUK7un.js';
2
- import '../stream-CecfVCPO.js';
1
+ import { d as Provider } from '../llm-ByUFPcFH.js';
2
+ import '../stream-S7nwQRqM.js';
3
3
 
4
4
  /**
5
5
  * @fileoverview Type definitions for the Ollama provider.
@@ -27,7 +27,7 @@ import {
27
27
  import {
28
28
  StreamEventType,
29
29
  objectDelta
30
- } from "../chunk-6S222DHN.js";
30
+ } from "../chunk-RJGTRQ47.js";
31
31
 
32
32
  // src/providers/ollama/transform.ts
33
33
  function normalizeSystem(system) {
@@ -1,5 +1,5 @@
1
- import { d as Provider } from '../llm-DwbUK7un.js';
2
- import '../stream-CecfVCPO.js';
1
+ import { d as Provider } from '../llm-ByUFPcFH.js';
2
+ import '../stream-S7nwQRqM.js';
3
3
 
4
4
  /**
5
5
  * @fileoverview OpenAI Provider Type Definitions
@@ -34,7 +34,7 @@ import {
34
34
  import {
35
35
  StreamEventType,
36
36
  objectDelta
37
- } from "../chunk-6S222DHN.js";
37
+ } from "../chunk-RJGTRQ47.js";
38
38
 
39
39
  // src/providers/openai/transform.completions.ts
40
40
  function normalizeSystem(system) {
@@ -1,5 +1,5 @@
1
- import { d as Provider } from '../llm-DwbUK7un.js';
2
- import '../stream-CecfVCPO.js';
1
+ import { d as Provider } from '../llm-ByUFPcFH.js';
2
+ import '../stream-S7nwQRqM.js';
3
3
 
4
4
  /**
5
5
  * OpenRouter-specific types for the Unified Provider Protocol.
@@ -31,7 +31,7 @@ import {
31
31
  import {
32
32
  StreamEventType,
33
33
  objectDelta
34
- } from "../chunk-6S222DHN.js";
34
+ } from "../chunk-RJGTRQ47.js";
35
35
 
36
36
  // src/providers/openrouter/transform.completions.ts
37
37
  function isValidCacheControl(value) {
@@ -1,12 +1,12 @@
1
- import { d as Provider, g as ModelReference } from '../llm-DwbUK7un.js';
1
+ import { d as Provider, g as ModelReference } from '../llm-ByUFPcFH.js';
2
2
  export { AdapterOptions, ParsedBody, ProxyHandler, RequestMeta, server } from './server/index.js';
3
- import { M as Message, a as MessageJSON, T as Turn, b as TurnJSON, S as StreamEvent } from '../stream-CecfVCPO.js';
3
+ import { M as Message, a as MessageJSON, T as Turn, b as TurnJSON, S as StreamEvent } from '../stream-S7nwQRqM.js';
4
4
  export { ParsedEmbeddingRequest, ParsedImageRequest, ParsedRequest, bindTools, parseBody, parseEmbeddingBody, parseImageBody, toEmbeddingJSON, toError, toImageJSON, toImageSSE, toJSON, toSSE, webapi } from './server/webapi/index.js';
5
5
  export { express } from './server/express/index.js';
6
6
  export { fastify } from './server/fastify/index.js';
7
7
  export { h3 } from './server/h3/index.js';
8
- import '../embedding-CW6SaOOz.js';
9
- import '../image-stream-C0ciACM2.js';
8
+ import '../embedding-BXA72PlJ.js';
9
+ import '../image-stream-CCgwB7ve.js';
10
10
 
11
11
  /**
12
12
  * @fileoverview Proxy provider types.
@@ -62,7 +62,7 @@ import {
62
62
  import {
63
63
  StreamEventType,
64
64
  objectDelta
65
- } from "../chunk-6S222DHN.js";
65
+ } from "../chunk-RJGTRQ47.js";
66
66
 
67
67
  // src/providers/proxy/headers.ts
68
68
  function mergeHeaders(requestHeaders, defaultHeaders) {
@@ -1,7 +1,7 @@
1
- import { T as Turn, i as StreamResult } from '../../../stream-CecfVCPO.js';
2
- import { d as EmbeddingResult } from '../../../embedding-CW6SaOOz.js';
3
- import { N as ImageResult } from '../../../llm-DwbUK7un.js';
4
- import { I as ImageStreamLike } from '../../../image-stream-C0ciACM2.js';
1
+ import { T as Turn, i as StreamResult } from '../../../stream-S7nwQRqM.js';
2
+ import { d as EmbeddingResult } from '../../../embedding-BXA72PlJ.js';
3
+ import { N as ImageResult } from '../../../llm-ByUFPcFH.js';
4
+ import { I as ImageStreamLike } from '../../../image-stream-CCgwB7ve.js';
5
5
 
6
6
  /**
7
7
  * @fileoverview Express/Connect adapter for proxy server.
@@ -1,7 +1,7 @@
1
- import { T as Turn, i as StreamResult } from '../../../stream-CecfVCPO.js';
2
- import { d as EmbeddingResult } from '../../../embedding-CW6SaOOz.js';
3
- import { N as ImageResult } from '../../../llm-DwbUK7un.js';
4
- import { I as ImageStreamLike } from '../../../image-stream-C0ciACM2.js';
1
+ import { T as Turn, i as StreamResult } from '../../../stream-S7nwQRqM.js';
2
+ import { d as EmbeddingResult } from '../../../embedding-BXA72PlJ.js';
3
+ import { N as ImageResult } from '../../../llm-ByUFPcFH.js';
4
+ import { I as ImageStreamLike } from '../../../image-stream-CCgwB7ve.js';
5
5
 
6
6
  /**
7
7
  * @fileoverview Fastify adapter for proxy server.
@@ -1,7 +1,7 @@
1
- import { T as Turn, i as StreamResult } from '../../../stream-CecfVCPO.js';
2
- import { d as EmbeddingResult } from '../../../embedding-CW6SaOOz.js';
3
- import { N as ImageResult } from '../../../llm-DwbUK7un.js';
4
- import { I as ImageStreamLike } from '../../../image-stream-C0ciACM2.js';
1
+ import { T as Turn, i as StreamResult } from '../../../stream-S7nwQRqM.js';
2
+ import { d as EmbeddingResult } from '../../../embedding-BXA72PlJ.js';
3
+ import { N as ImageResult } from '../../../llm-ByUFPcFH.js';
4
+ import { I as ImageStreamLike } from '../../../image-stream-CCgwB7ve.js';
5
5
 
6
6
  /**
7
7
  * @fileoverview H3/Nitro/Nuxt adapter for proxy server.
@@ -6,10 +6,10 @@ import { sendJSON, sendEmbeddingJSON, sendImageJSON, streamSSE, streamImageSSE,
6
6
  export { express } from './express/index.js';
7
7
  import { parseBody, parseEmbeddingBody, parseImageBody, toJSON, toEmbeddingJSON, toImageJSON, toSSE, toImageSSE, toError, bindTools } from './webapi/index.js';
8
8
  export { ParsedEmbeddingRequest, ParsedImageRequest, ParsedRequest, webapi } from './webapi/index.js';
9
- import { M as Message, J as JSONSchema, H as ToolMetadata, T as Turn, i as StreamResult } from '../../stream-CecfVCPO.js';
10
- import '../../embedding-CW6SaOOz.js';
11
- import '../../llm-DwbUK7un.js';
12
- import '../../image-stream-C0ciACM2.js';
9
+ import { M as Message, J as JSONSchema, H as ToolMetadata, T as Turn, i as StreamResult } from '../../stream-S7nwQRqM.js';
10
+ import '../../embedding-BXA72PlJ.js';
11
+ import '../../llm-ByUFPcFH.js';
12
+ import '../../image-stream-CCgwB7ve.js';
13
13
 
14
14
  /**
15
15
  * @fileoverview Shared types for proxy server adapters.
@@ -1,7 +1,7 @@
1
- import { M as Message, J as JSONSchema, H as ToolMetadata, T as Turn, i as StreamResult, d as Tool } from '../../../stream-CecfVCPO.js';
2
- import { n as Image, E as EmbeddingInput, N as ImageResult } from '../../../llm-DwbUK7un.js';
3
- import { d as EmbeddingResult } from '../../../embedding-CW6SaOOz.js';
4
- import { I as ImageStreamLike } from '../../../image-stream-C0ciACM2.js';
1
+ import { M as Message, J as JSONSchema, H as ToolMetadata, T as Turn, i as StreamResult, d as Tool } from '../../../stream-S7nwQRqM.js';
2
+ import { n as Image, E as EmbeddingInput, N as ImageResult } from '../../../llm-ByUFPcFH.js';
3
+ import { d as EmbeddingResult } from '../../../embedding-BXA72PlJ.js';
4
+ import { I as ImageStreamLike } from '../../../image-stream-CCgwB7ve.js';
5
5
 
6
6
  /**
7
7
  * @fileoverview Media serialization utilities for proxy transport.
@@ -1,5 +1,5 @@
1
- import { d as Provider } from '../llm-DwbUK7un.js';
2
- import '../stream-CecfVCPO.js';
1
+ import { d as Provider } from '../llm-ByUFPcFH.js';
2
+ import '../stream-S7nwQRqM.js';
3
3
 
4
4
  /**
5
5
  * @fileoverview OpenResponses Provider Type Definitions
@@ -31,7 +31,7 @@ import {
31
31
  import {
32
32
  StreamEventType,
33
33
  objectDelta
34
- } from "../chunk-6S222DHN.js";
34
+ } from "../chunk-RJGTRQ47.js";
35
35
 
36
36
  // src/providers/responses/transform.ts
37
37
  function normalizeSystem(system) {
@@ -1,4 +1,4 @@
1
- import { K as KeyStrategy, b as ProviderConfig, e as Modality, R as RetryStrategy, U as UPPError } from './llm-DwbUK7un.js';
1
+ import { K as KeyStrategy, b as ProviderConfig, e as Modality, R as RetryStrategy, U as UPPError } from './llm-ByUFPcFH.js';
2
2
 
3
3
  /**
4
4
  * API key management strategies for load balancing and dynamic key selection.
@@ -1500,7 +1500,8 @@ interface StreamEvent {
1500
1500
  * Stream result - an async iterable that also provides the final turn.
1501
1501
  *
1502
1502
  * Allows consuming streaming events while also awaiting the complete
1503
- * Turn result after streaming finishes.
1503
+ * Turn result after streaming finishes. Implements `PromiseLike<Turn>`
1504
+ * for direct awaiting with automatic stream consumption.
1504
1505
  *
1505
1506
  * @typeParam TData - Type of the structured output data
1506
1507
  *
@@ -1510,19 +1511,22 @@ interface StreamEvent {
1510
1511
  *
1511
1512
  * const stream = instance.stream('Tell me a story');
1512
1513
  *
1513
- * // Consume streaming events
1514
+ * // Option 1: Consume streaming events manually
1514
1515
  * for await (const event of stream) {
1515
1516
  * if (event.type === StreamEventType.TextDelta) {
1516
1517
  * process.stdout.write(event.delta.text ?? '');
1517
1518
  * }
1518
1519
  * }
1519
- *
1520
- * // Get the complete turn after streaming
1521
1520
  * const turn = await stream.turn;
1522
- * console.log('\n\nTokens used:', turn.usage.totalTokens);
1521
+ *
1522
+ * // Option 2: Just await the turn (auto-drains the stream)
1523
+ * const turn = await instance.stream('Tell me a story');
1524
+ *
1525
+ * // Option 3: Fire-and-forget with callback
1526
+ * instance.stream('Tell me a story').then(turn => saveToDB(turn));
1523
1527
  * ```
1524
1528
  */
1525
- interface StreamResult<TData = unknown> extends AsyncIterable<StreamEvent> {
1529
+ interface StreamResult<TData = unknown> extends AsyncIterable<StreamEvent>, PromiseLike<Turn<TData>> {
1526
1530
  /**
1527
1531
  * Promise that resolves to the complete Turn after streaming finishes.
1528
1532
  * Rejects if the stream is aborted or terminated early.
@@ -1551,6 +1555,13 @@ interface StreamResult<TData = unknown> extends AsyncIterable<StreamEvent> {
1551
1555
  * turnPromise,
1552
1556
  * abortController
1553
1557
  * );
1558
+ *
1559
+ * // Can be awaited directly (auto-drains)
1560
+ * const turn = await stream;
1561
+ *
1562
+ * // Or iterated manually
1563
+ * for await (const event of stream) { ... }
1564
+ * const turn = await stream.turn;
1554
1565
  * ```
1555
1566
  */
1556
1567
  declare function createStreamResult<TData = unknown>(generator: AsyncGenerator<StreamEvent, void, unknown>, turnPromiseOrFactory: Promise<Turn<TData>> | (() => Promise<Turn<TData>>), abortController: AbortController): StreamResult<TData>;
@@ -0,0 +1,96 @@
1
+ import { S as StreamEvent } from './stream-S7nwQRqM.js';
2
+
3
+ /**
4
+ * @fileoverview Pub-sub middleware types for stream resumption.
5
+ *
6
+ * Defines interfaces for temporary stream storage, replay, and
7
+ * multi-client broadcast during active generation.
8
+ *
9
+ * @module middleware/pubsub/types
10
+ */
11
+
12
+ /**
13
+ * Stored stream state (in-flight only).
14
+ */
15
+ interface StoredStream {
16
+ readonly streamId: string;
17
+ readonly createdAt: number;
18
+ readonly events: readonly StreamEvent[];
19
+ }
20
+ /**
21
+ * Subscription callback for live events.
22
+ *
23
+ * @param event - Stream event payload
24
+ * @param cursor - Zero-based event index when adapter supports cursors
25
+ */
26
+ type SubscriptionCallback = (event: StreamEvent, cursor?: number) => void;
27
+ /**
28
+ * Completion callback when stream ends.
29
+ *
30
+ * Adapters should invoke this when {@link PubSubAdapter.remove} is called
31
+ * so subscriber streams can terminate before the stream is deleted.
32
+ */
33
+ type CompletionCallback = () => void;
34
+ /**
35
+ * Unsubscribe function returned by subscribe.
36
+ */
37
+ type Unsubscribe = () => void;
38
+ /**
39
+ * Storage adapter interface for pub-sub middleware.
40
+ *
41
+ * Stores in-flight streams only. Completed streams are removed immediately.
42
+ * Apps should persist completed conversations via `.then()` and serve from
43
+ * their own storage on reconnect.
44
+ */
45
+ interface PubSubAdapter {
46
+ /**
47
+ * Checks if a stream exists.
48
+ */
49
+ exists(streamId: string): Promise<boolean>;
50
+ /**
51
+ * Appends an event to the stream (creates lazily if needed).
52
+ */
53
+ append(streamId: string, event: StreamEvent): Promise<void>;
54
+ /**
55
+ * Fetches all events for replay.
56
+ */
57
+ getEvents(streamId: string): Promise<StreamEvent[]>;
58
+ /**
59
+ * Subscribes to live events (creates lazily if needed).
60
+ */
61
+ subscribe(streamId: string, onEvent: SubscriptionCallback, onComplete: CompletionCallback): Unsubscribe;
62
+ /**
63
+ * Publishes event to all subscribers.
64
+ */
65
+ publish(streamId: string, event: StreamEvent): void;
66
+ /**
67
+ * Notifies subscribers and removes stream from storage.
68
+ */
69
+ remove(streamId: string): Promise<void>;
70
+ }
71
+ /**
72
+ * Options for pub-sub middleware.
73
+ */
74
+ interface PubSubOptions {
75
+ /**
76
+ * Storage adapter instance.
77
+ * @default memoryAdapter()
78
+ */
79
+ adapter?: PubSubAdapter;
80
+ /**
81
+ * Stream identifier for pub-sub behavior.
82
+ */
83
+ streamId?: string;
84
+ }
85
+ /**
86
+ * Options for memory adapter.
87
+ */
88
+ interface MemoryAdapterOptions {
89
+ /**
90
+ * Max concurrent streams allowed. Throws if exceeded.
91
+ * @default 1000
92
+ */
93
+ maxStreams?: number;
94
+ }
95
+
96
+ export type { CompletionCallback as C, MemoryAdapterOptions as M, PubSubAdapter as P, StoredStream as S, Unsubscribe as U, PubSubOptions as a, SubscriptionCallback as b };
@@ -1,5 +1,5 @@
1
- import { d as Provider } from '../llm-DwbUK7un.js';
2
- import '../stream-CecfVCPO.js';
1
+ import { d as Provider } from '../llm-ByUFPcFH.js';
2
+ import '../stream-S7nwQRqM.js';
3
3
 
4
4
  /**
5
5
  * xAI Chat Completions API parameters (OpenAI-compatible).
package/dist/xai/index.js CHANGED
@@ -34,7 +34,7 @@ import {
34
34
  import {
35
35
  StreamEventType,
36
36
  objectDelta
37
- } from "../chunk-6S222DHN.js";
37
+ } from "../chunk-RJGTRQ47.js";
38
38
 
39
39
  // src/providers/xai/transform.completions.ts
40
40
  function normalizeSystem(system) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@providerprotocol/ai",
3
- "version": "0.0.35",
3
+ "version": "0.0.36",
4
4
  "description": "UPP: Unified Provider Protocol for AI inference",
5
5
  "license": "MIT",
6
6
  "homepage": "https://providerprotocol.org",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/middleware/pubsub/server/shared.ts"],"sourcesContent":["/**\n * @fileoverview Shared utilities for pub-sub server adapters.\n *\n * @module middleware/pubsub/server/shared\n * @internal\n */\n\nimport type { StreamEvent } from '../../../types/stream.ts';\nimport type { PubSubAdapter } from '../types.ts';\nimport { serializeStreamEvent } from '../../../stream/serialization.ts';\n\n/**\n * Writer interface for abstracting how data is written to responses.\n * @internal\n */\nexport interface StreamWriter {\n write(data: string): void;\n end(): void;\n}\n\n/**\n * Options for runSubscriberStream.\n * @internal\n */\nexport interface StreamOptions {\n signal?: AbortSignal;\n /** Max time to wait for stream creation (ms). @default 5000 */\n creationTimeout?: number;\n}\n\nconst DEFAULT_CREATION_TIMEOUT = 5000;\nconst CREATION_POLL_INTERVAL = 50;\n\n/**\n * Formats a stream event as an SSE data line.\n */\nexport function formatSSE(event: StreamEvent): string {\n const serialized = serializeStreamEvent(event);\n return `data: ${JSON.stringify(serialized)}\\n\\n`;\n}\n\n/**\n * Waits for a stream to be created, with timeout.\n * Returns true if stream exists, false if timed out.\n */\nasync function waitForStream(\n streamId: string,\n adapter: PubSubAdapter,\n timeout: number,\n signal?: AbortSignal\n): Promise<boolean> {\n const deadline = Date.now() + timeout;\n\n while (Date.now() < deadline) {\n if (signal?.aborted) return false;\n\n const exists = await adapter.exists(streamId);\n if (exists) return true;\n\n await new Promise((resolve) => setTimeout(resolve, CREATION_POLL_INTERVAL));\n }\n\n return false;\n}\n\n/**\n * Core subscriber stream logic shared across all adapters.\n *\n * Handles:\n * 1. Waiting for stream creation (with timeout)\n * 2. Subscribing to live events FIRST (to prevent event loss)\n * 3. Replaying buffered events\n * 4. Checking if already completed\n * 5. Processing live events until completion\n * 6. Final cleanup\n * 7. Client disconnect via AbortSignal\n *\n * @internal\n */\nexport async function runSubscriberStream(\n streamId: string,\n adapter: PubSubAdapter,\n writer: StreamWriter,\n options: StreamOptions = {}\n): Promise<void> {\n const { signal, creationTimeout = DEFAULT_CREATION_TIMEOUT } = options;\n\n // Early exit if already aborted\n if (signal?.aborted) {\n writer.end();\n return;\n }\n\n try {\n // 1. Wait for stream to be created (handles race with background generation)\n const streamExists = await waitForStream(streamId, adapter, creationTimeout, signal);\n\n if (signal?.aborted) {\n writer.end();\n return;\n }\n\n if (!streamExists) {\n writer.write(`data: ${JSON.stringify({ error: 'Stream not found' })}\\n\\n`);\n writer.end();\n return;\n }\n\n // 2. Subscribe FIRST to prevent event loss during replay\n // Any events emitted while we replay will queue up\n const queue: Array<{ event: StreamEvent; cursor: number | null }> = [];\n let resolveWait: (() => void) | null = null;\n let done = false;\n let lastSentCursor = -1;\n\n const unsubscribe = adapter.subscribe(streamId, (event: StreamEvent, cursor?: number) => {\n queue.push({ event, cursor: cursor ?? null });\n resolveWait?.();\n });\n\n // Handle client disconnect\n const onAbort = (): void => {\n done = true;\n resolveWait?.();\n };\n signal?.addEventListener('abort', onAbort);\n\n const drainQueue = (): void => {\n while (queue.length > 0 && !signal?.aborted) {\n const item = queue.shift();\n if (!item) {\n break;\n }\n const { event, cursor } = item;\n if (cursor !== null && cursor <= lastSentCursor) {\n continue;\n }\n writer.write(formatSSE(event));\n if (cursor !== null && cursor > lastSentCursor) {\n lastSentCursor = cursor;\n }\n }\n };\n\n const dropReplayDuplicates = (): void => {\n if (queue.length === 0) {\n return;\n }\n const filtered: Array<{ event: StreamEvent; cursor: number | null }> = [];\n for (const item of queue) {\n if (item.cursor !== null && item.cursor <= lastSentCursor) {\n continue;\n }\n filtered.push(item);\n }\n queue.length = 0;\n queue.push(...filtered);\n };\n\n const waitForNewEvents = (): Promise<void> => new Promise<void>((resolve) => {\n resolveWait = resolve;\n setTimeout(resolve, 500);\n });\n\n try {\n // 3. Replay buffered events (subscription is already active)\n const events = await adapter.getEvents(streamId);\n\n if (!events) {\n writer.write(`data: ${JSON.stringify({ error: 'Stream not found' })}\\n\\n`);\n writer.end();\n return;\n }\n\n for (const event of events) {\n if (signal?.aborted) break;\n writer.write(formatSSE(event));\n }\n\n lastSentCursor = events.length - 1;\n\n // Drop queued events that are already included in the replay (cursor-aware)\n dropReplayDuplicates();\n\n // Check abort after replay\n if (signal?.aborted) {\n writer.end();\n return;\n }\n\n // 4. Check if already completed\n const completed = await adapter.isCompleted(streamId).catch(() => false);\n if (completed) {\n // Drain any queued events first (these are post-replay events)\n drainQueue();\n writer.write('data: [DONE]\\n\\n');\n writer.end();\n return;\n }\n\n // 5. Process live events until completion\n while (!done) {\n // Check abort\n if (signal?.aborted) break;\n\n // Drain queue (all events here are post-replay, no duplicates)\n drainQueue();\n\n // Check abort again\n if (signal?.aborted) break;\n\n // Check completion\n const isComplete = await adapter.isCompleted(streamId).catch(() => false);\n if (isComplete) {\n done = true;\n break;\n }\n\n // Wait for new events\n await waitForNewEvents();\n resolveWait = null;\n }\n\n // Final drain (only if not aborted)\n if (!signal?.aborted) {\n drainQueue();\n }\n } finally {\n signal?.removeEventListener('abort', onAbort);\n unsubscribe();\n }\n\n // Only send DONE if not aborted\n if (!signal?.aborted) {\n writer.write('data: [DONE]\\n\\n');\n }\n writer.end();\n } catch (error) {\n // Don't send error if client disconnected\n if (!signal?.aborted) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n writer.write(`data: ${JSON.stringify({ error: errorMsg })}\\n\\n`);\n }\n writer.end();\n }\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/types/stream.ts"],"sourcesContent":["/**\n * @fileoverview Streaming types for real-time LLM responses.\n *\n * Defines the event types and interfaces for streaming LLM inference,\n * including text deltas, tool call deltas, and control events.\n *\n * @module types/stream\n */\n\nimport type { Turn } from './turn.ts';\n\n/**\n * Stream event type constants.\n *\n * Use these constants instead of raw strings for type-safe event handling:\n *\n * @example\n * ```typescript\n * import { StreamEventType } from 'upp';\n *\n * for await (const event of stream) {\n * if (event.type === StreamEventType.TextDelta) {\n * process.stdout.write(event.delta.text ?? '');\n * }\n * }\n * ```\n */\nexport const StreamEventType = {\n /** Incremental text output */\n TextDelta: 'text_delta',\n /** Incremental reasoning/thinking output */\n ReasoningDelta: 'reasoning_delta',\n /** Incremental image data */\n ImageDelta: 'image_delta',\n /** Incremental audio data */\n AudioDelta: 'audio_delta',\n /** Incremental video data */\n VideoDelta: 'video_delta',\n /** Incremental tool call data (arguments being streamed) */\n ToolCallDelta: 'tool_call_delta',\n /** Incremental structured object data (for structured output responses) */\n ObjectDelta: 'object_delta',\n /** Tool execution has started (may be emitted after completion in some implementations) */\n ToolExecutionStart: 'tool_execution_start',\n /** Tool execution has completed */\n ToolExecutionEnd: 'tool_execution_end',\n /** Beginning of a message */\n MessageStart: 'message_start',\n /** End of a message */\n MessageStop: 'message_stop',\n /** Beginning of a content block */\n ContentBlockStart: 'content_block_start',\n /** End of a content block */\n ContentBlockStop: 'content_block_stop',\n} as const;\n\n/**\n * Stream event type discriminator union.\n *\n * This type is derived from {@link StreamEventType} constants. Use `StreamEventType.TextDelta`\n * for constants or `type MyType = StreamEventType` for type annotations.\n */\nexport type StreamEventType = (typeof StreamEventType)[keyof typeof StreamEventType];\n\n/**\n * Event delta data payload.\n *\n * Contains the type-specific data for a streaming event.\n * Different fields are populated depending on the event type:\n *\n * | Event Type | Fields |\n * |------------|--------|\n * | `text_delta` | `text` |\n * | `reasoning_delta` | `text` |\n * | `object_delta` | `text` |\n * | `image_delta` | `data` |\n * | `audio_delta` | `data` |\n * | `video_delta` | `data` |\n * | `tool_call_delta` | `toolCallId`, `toolName`, `argumentsJson` |\n * | `tool_execution_start` | `toolCallId`, `toolName`, `timestamp` |\n * | `tool_execution_end` | `toolCallId`, `toolName`, `result`, `isError`, `timestamp` |\n * | `message_start` | (none) |\n * | `message_stop` | (none) |\n * | `content_block_start` | (none) |\n * | `content_block_stop` | (none) |\n */\nexport interface EventDelta {\n /** Incremental text content (text_delta, reasoning_delta, object_delta) */\n text?: string;\n\n /** Incremental binary data (image_delta, audio_delta, video_delta) */\n data?: Uint8Array;\n\n /** Tool call identifier (tool_call_delta, tool_execution_start/end) */\n toolCallId?: string;\n\n /** Tool name (tool_call_delta, tool_execution_start/end) */\n toolName?: string;\n\n /** Incremental JSON arguments string (tool_call_delta) */\n argumentsJson?: string;\n\n /** Tool execution result (tool_execution_end) */\n result?: unknown;\n\n /** Whether tool execution resulted in an error (tool_execution_end) */\n isError?: boolean;\n\n /** Timestamp in milliseconds (tool_execution_start/end) */\n timestamp?: number;\n}\n\n/**\n * A single streaming event from the LLM.\n *\n * Events are emitted in order as the model generates output,\n * allowing for real-time display of responses.\n *\n * @example\n * ```typescript\n * import { StreamEventType } from 'upp';\n *\n * for await (const event of stream) {\n * if (event.type === StreamEventType.TextDelta) {\n * process.stdout.write(event.delta.text ?? '');\n * } else if (event.type === StreamEventType.ToolCallDelta) {\n * console.log('Tool:', event.delta.toolName);\n * }\n * }\n * ```\n */\nexport interface StreamEvent {\n /** Event type discriminator */\n type: StreamEventType;\n\n /** Index of the content block this event belongs to */\n index: number;\n\n /** Event-specific data payload */\n delta: EventDelta;\n}\n\n/**\n * Stream result - an async iterable that also provides the final turn.\n *\n * Allows consuming streaming events while also awaiting the complete\n * Turn result after streaming finishes.\n *\n * @typeParam TData - Type of the structured output data\n *\n * @example\n * ```typescript\n * import { StreamEventType } from 'upp';\n *\n * const stream = instance.stream('Tell me a story');\n *\n * // Consume streaming events\n * for await (const event of stream) {\n * if (event.type === StreamEventType.TextDelta) {\n * process.stdout.write(event.delta.text ?? '');\n * }\n * }\n *\n * // Get the complete turn after streaming\n * const turn = await stream.turn;\n * console.log('\\n\\nTokens used:', turn.usage.totalTokens);\n * ```\n */\nexport interface StreamResult<TData = unknown>\n extends AsyncIterable<StreamEvent> {\n /**\n * Promise that resolves to the complete Turn after streaming finishes.\n * Rejects if the stream is aborted or terminated early.\n */\n readonly turn: Promise<Turn<TData>>;\n\n /**\n * Aborts the stream, stopping further events and cancelling the request.\n * This will cause {@link StreamResult.turn} to reject.\n */\n abort(): void;\n}\n\n/**\n * Creates a StreamResult from an async generator and completion promise.\n *\n * @typeParam TData - Type of the structured output data\n * @param generator - Async generator that yields stream events\n * @param turnPromiseOrFactory - Promise or factory that resolves to the complete Turn\n * @param abortController - Controller for aborting the stream\n * @returns A StreamResult that can be iterated and awaited\n *\n * @example\n * ```typescript\n * const abortController = new AbortController();\n * const stream = createStreamResult(\n * eventGenerator(),\n * turnPromise,\n * abortController\n * );\n * ```\n */\nexport function createStreamResult<TData = unknown>(\n generator: AsyncGenerator<StreamEvent, void, unknown>,\n turnPromiseOrFactory: Promise<Turn<TData>> | (() => Promise<Turn<TData>>),\n abortController: AbortController\n): StreamResult<TData> {\n let cachedTurn: Promise<Turn<TData>> | null = null;\n\n const getTurn = (): Promise<Turn<TData>> => {\n // Lazily build the turn promise to avoid work (or rejections) when unused.\n if (typeof turnPromiseOrFactory === 'function') {\n if (!cachedTurn) {\n cachedTurn = turnPromiseOrFactory();\n }\n return cachedTurn;\n }\n\n return turnPromiseOrFactory;\n };\n\n return {\n [Symbol.asyncIterator]() {\n return generator;\n },\n get turn() {\n return getTurn();\n },\n abort() {\n abortController.abort();\n },\n };\n}\n\n/**\n * Creates a text delta stream event.\n *\n * @param text - The incremental text content\n * @param index - Content block index (default: 0)\n * @returns A text_delta StreamEvent\n */\nexport function textDelta(text: string, index = 0): StreamEvent {\n return {\n type: StreamEventType.TextDelta,\n index,\n delta: { text },\n };\n}\n\n/**\n * Creates a tool call delta stream event.\n *\n * @param toolCallId - Unique identifier for the tool call\n * @param toolName - Name of the tool being called\n * @param argumentsJson - Incremental JSON arguments string\n * @param index - Content block index (default: 0)\n * @returns A tool_call_delta StreamEvent\n */\nexport function toolCallDelta(\n toolCallId: string,\n toolName: string,\n argumentsJson: string,\n index = 0\n): StreamEvent {\n return {\n type: StreamEventType.ToolCallDelta,\n index,\n delta: { toolCallId, toolName, argumentsJson },\n };\n}\n\n/**\n * Creates an object delta stream event for structured output responses.\n *\n * @param text - The incremental text content\n * @param index - Content block index (default: 0)\n * @returns An object_delta StreamEvent\n */\nexport function objectDelta(text: string, index = 0): StreamEvent {\n return {\n type: StreamEventType.ObjectDelta,\n index,\n delta: { text },\n };\n}\n\n/**\n * Creates a message start stream event.\n *\n * @returns A message_start StreamEvent\n */\nexport function messageStart(): StreamEvent {\n return {\n type: StreamEventType.MessageStart,\n index: 0,\n delta: {},\n };\n}\n\n/**\n * Creates a message stop stream event.\n *\n * @returns A message_stop StreamEvent\n */\nexport function messageStop(): StreamEvent {\n return {\n type: StreamEventType.MessageStop,\n index: 0,\n delta: {},\n };\n}\n\n/**\n * Creates a content block start stream event.\n *\n * @param index - The content block index starting\n * @returns A content_block_start StreamEvent\n */\nexport function contentBlockStart(index: number): StreamEvent {\n return {\n type: StreamEventType.ContentBlockStart,\n index,\n delta: {},\n };\n}\n\n/**\n * Creates a content block stop stream event.\n *\n * @param index - The content block index stopping\n * @returns A content_block_stop StreamEvent\n */\nexport function contentBlockStop(index: number): StreamEvent {\n return {\n type: StreamEventType.ContentBlockStop,\n index,\n delta: {},\n };\n}\n\n/**\n * Creates a tool execution start stream event.\n *\n * @param toolCallId - Unique identifier for the tool call\n * @param toolName - Name of the tool being executed\n * @param timestamp - Start timestamp in milliseconds\n * @param index - Content block index (default: 0)\n * @returns A tool_execution_start StreamEvent\n */\nexport function toolExecutionStart(\n toolCallId: string,\n toolName: string,\n timestamp: number,\n index = 0\n): StreamEvent {\n return {\n type: StreamEventType.ToolExecutionStart,\n index,\n delta: { toolCallId, toolName, timestamp },\n };\n}\n\n/**\n * Creates a tool execution end stream event.\n *\n * @param toolCallId - Unique identifier for the tool call\n * @param toolName - Name of the tool that was executed\n * @param result - The result from the tool execution\n * @param isError - Whether the execution resulted in an error\n * @param timestamp - End timestamp in milliseconds\n * @param index - Content block index (default: 0)\n * @returns A tool_execution_end StreamEvent\n */\nexport function toolExecutionEnd(\n toolCallId: string,\n toolName: string,\n result: unknown,\n isError: boolean,\n timestamp: number,\n index = 0\n): StreamEvent {\n return {\n type: StreamEventType.ToolExecutionEnd,\n index,\n delta: { toolCallId, toolName, result, isError, timestamp },\n };\n}\n"],"mappings":";AA2BO,IAAM,kBAAkB;AAAA;AAAA,EAE7B,WAAW;AAAA;AAAA,EAEX,gBAAgB;AAAA;AAAA,EAEhB,YAAY;AAAA;AAAA,EAEZ,YAAY;AAAA;AAAA,EAEZ,YAAY;AAAA;AAAA,EAEZ,eAAe;AAAA;AAAA,EAEf,aAAa;AAAA;AAAA,EAEb,oBAAoB;AAAA;AAAA,EAEpB,kBAAkB;AAAA;AAAA,EAElB,cAAc;AAAA;AAAA,EAEd,aAAa;AAAA;AAAA,EAEb,mBAAmB;AAAA;AAAA,EAEnB,kBAAkB;AACpB;AAoJO,SAAS,mBACd,WACA,sBACA,iBACqB;AACrB,MAAI,aAA0C;AAE9C,QAAM,UAAU,MAA4B;AAE1C,QAAI,OAAO,yBAAyB,YAAY;AAC9C,UAAI,CAAC,YAAY;AACf,qBAAa,qBAAqB;AAAA,MACpC;AACA,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,CAAC,OAAO,aAAa,IAAI;AACvB,aAAO;AAAA,IACT;AAAA,IACA,IAAI,OAAO;AACT,aAAO,QAAQ;AAAA,IACjB;AAAA,IACA,QAAQ;AACN,sBAAgB,MAAM;AAAA,IACxB;AAAA,EACF;AACF;AASO,SAAS,UAAU,MAAc,QAAQ,GAAgB;AAC9D,SAAO;AAAA,IACL,MAAM,gBAAgB;AAAA,IACtB;AAAA,IACA,OAAO,EAAE,KAAK;AAAA,EAChB;AACF;AAWO,SAAS,cACd,YACA,UACA,eACA,QAAQ,GACK;AACb,SAAO;AAAA,IACL,MAAM,gBAAgB;AAAA,IACtB;AAAA,IACA,OAAO,EAAE,YAAY,UAAU,cAAc;AAAA,EAC/C;AACF;AASO,SAAS,YAAY,MAAc,QAAQ,GAAgB;AAChE,SAAO;AAAA,IACL,MAAM,gBAAgB;AAAA,IACtB;AAAA,IACA,OAAO,EAAE,KAAK;AAAA,EAChB;AACF;AAOO,SAAS,eAA4B;AAC1C,SAAO;AAAA,IACL,MAAM,gBAAgB;AAAA,IACtB,OAAO;AAAA,IACP,OAAO,CAAC;AAAA,EACV;AACF;AAOO,SAAS,cAA2B;AACzC,SAAO;AAAA,IACL,MAAM,gBAAgB;AAAA,IACtB,OAAO;AAAA,IACP,OAAO,CAAC;AAAA,EACV;AACF;AAQO,SAAS,kBAAkB,OAA4B;AAC5D,SAAO;AAAA,IACL,MAAM,gBAAgB;AAAA,IACtB;AAAA,IACA,OAAO,CAAC;AAAA,EACV;AACF;AAQO,SAAS,iBAAiB,OAA4B;AAC3D,SAAO;AAAA,IACL,MAAM,gBAAgB;AAAA,IACtB;AAAA,IACA,OAAO,CAAC;AAAA,EACV;AACF;AAWO,SAAS,mBACd,YACA,UACA,WACA,QAAQ,GACK;AACb,SAAO;AAAA,IACL,MAAM,gBAAgB;AAAA,IACtB;AAAA,IACA,OAAO,EAAE,YAAY,UAAU,UAAU;AAAA,EAC3C;AACF;AAaO,SAAS,iBACd,YACA,UACA,QACA,SACA,WACA,QAAQ,GACK;AACb,SAAO;AAAA,IACL,MAAM,gBAAgB;AAAA,IACtB;AAAA,IACA,OAAO,EAAE,YAAY,UAAU,QAAQ,SAAS,UAAU;AAAA,EAC5D;AACF;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/middleware/pubsub/server/webapi.ts"],"sourcesContent":["/**\n * @fileoverview Web API adapter for pub-sub stream resumption.\n *\n * Provides utilities for Web API native frameworks (Bun, Deno, Next.js App Router,\n * Cloudflare Workers) to handle stream reconnections.\n *\n * @module middleware/pubsub/server/webapi\n */\n\nimport type { PubSubAdapter } from '../types.ts';\nimport { runSubscriberStream } from './shared.ts';\n\n/**\n * Creates a ReadableStream that replays buffered events and subscribes to live events.\n *\n * This utility handles the reconnection pattern for server routes:\n * 1. Replays all buffered events from the adapter\n * 2. If stream is already completed, closes immediately\n * 3. Otherwise, subscribes to live events until completion\n *\n * Works with any framework that supports web standard ReadableStream.\n *\n * @param streamId - The stream ID to subscribe to\n * @param adapter - The pub-sub adapter instance\n * @returns A ReadableStream of SSE-formatted data\n *\n * @example\n * ```typescript\n * import { createSubscriberStream } from '@providerprotocol/ai/middleware/pubsub/server/webapi';\n *\n * // Next.js App Router\n * export async function POST(req: Request) {\n * const { streamId } = await req.json();\n *\n * return new Response(createSubscriberStream(streamId, adapter), {\n * headers: {\n * 'Content-Type': 'text/event-stream',\n * 'Cache-Control': 'no-cache',\n * 'Connection': 'keep-alive',\n * },\n * });\n * }\n * ```\n */\nexport function createSubscriberStream(\n streamId: string,\n adapter: PubSubAdapter\n): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n const abortController = new AbortController();\n let closed = false;\n\n return new ReadableStream({\n async start(controller) {\n await runSubscriberStream(\n streamId,\n adapter,\n {\n write: (data: string) => {\n if (closed) {\n return;\n }\n controller.enqueue(encoder.encode(data));\n },\n end: () => {\n if (closed) {\n return;\n }\n closed = true;\n try {\n controller.close();\n } catch {\n // Ignore close errors after cancellation\n }\n },\n },\n { signal: abortController.signal }\n );\n },\n cancel() {\n abortController.abort();\n },\n });\n}\n\n/**\n * Web API adapter namespace for pub-sub server utilities.\n */\nexport const webapi = {\n createSubscriberStream,\n};\n"],"mappings":";;;;;AA4CO,SAAS,uBACd,UACA,SAC4B;AAC5B,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,kBAAkB,IAAI,gBAAgB;AAC5C,MAAI,SAAS;AAEb,SAAO,IAAI,eAAe;AAAA,IACxB,MAAM,MAAM,YAAY;AACtB,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,UACE,OAAO,CAAC,SAAiB;AACvB,gBAAI,QAAQ;AACV;AAAA,YACF;AACA,uBAAW,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,UACzC;AAAA,UACA,KAAK,MAAM;AACT,gBAAI,QAAQ;AACV;AAAA,YACF;AACA,qBAAS;AACT,gBAAI;AACF,yBAAW,MAAM;AAAA,YACnB,QAAQ;AAAA,YAER;AAAA,UACF;AAAA,QACF;AAAA,QACA,EAAE,QAAQ,gBAAgB,OAAO;AAAA,MACnC;AAAA,IACF;AAAA,IACA,SAAS;AACP,sBAAgB,MAAM;AAAA,IACxB;AAAA,EACF,CAAC;AACH;AAKO,IAAM,SAAS;AAAA,EACpB;AACF;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/middleware/pubsub/server/h3.ts"],"sourcesContent":["/**\n * @fileoverview H3/Nitro/Nuxt adapter for pub-sub stream resumption.\n *\n * Provides utilities for H3-based servers (Nuxt, Nitro, or standalone H3)\n * to handle stream reconnections.\n *\n * @module middleware/pubsub/server/h3\n */\n\nimport type { PubSubAdapter } from '../types.ts';\nimport { runSubscriberStream } from './shared.ts';\n\n/**\n * H3 Event interface (minimal type to avoid dependency).\n */\ninterface H3Event {\n node: {\n res: {\n setHeader(name: string, value: string): void;\n write(chunk: string): boolean;\n end(): void;\n on(event: 'close', listener: () => void): void;\n };\n };\n}\n\n/**\n * Stream buffered and live events to an H3 event response.\n *\n * This utility handles the reconnection pattern for H3/Nuxt routes:\n * 1. Replays all buffered events from the adapter\n * 2. If stream is already completed, ends immediately\n * 3. Otherwise, subscribes to live events until completion\n *\n * @param streamId - The stream ID to subscribe to\n * @param adapter - The pub-sub adapter instance\n * @param event - H3 event object\n *\n * @example\n * ```typescript\n * import { streamSubscriber } from '@providerprotocol/ai/middleware/pubsub/server/h3';\n *\n * export default defineEventHandler(async (event) => {\n * const { streamId } = await readBody(event);\n * return streamSubscriber(streamId, adapter, event);\n * });\n * ```\n */\nexport async function streamSubscriber(\n streamId: string,\n adapter: PubSubAdapter,\n event: H3Event\n): Promise<void> {\n const res = event.node.res;\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n\n const abortController = new AbortController();\n res.on('close', () => abortController.abort());\n\n await runSubscriberStream(\n streamId,\n adapter,\n {\n write: (data: string) => res.write(data),\n end: () => res.end(),\n },\n { signal: abortController.signal }\n );\n}\n\n/**\n * H3 adapter namespace for pub-sub server utilities.\n */\nexport const h3 = {\n streamSubscriber,\n};\n"],"mappings":";;;;;AAgDA,eAAsB,iBACpB,UACA,SACA,OACe;AACf,QAAM,MAAM,MAAM,KAAK;AACvB,MAAI,UAAU,gBAAgB,mBAAmB;AACjD,MAAI,UAAU,iBAAiB,UAAU;AACzC,MAAI,UAAU,cAAc,YAAY;AAExC,QAAM,kBAAkB,IAAI,gBAAgB;AAC5C,MAAI,GAAG,SAAS,MAAM,gBAAgB,MAAM,CAAC;AAE7C,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,MACE,OAAO,CAAC,SAAiB,IAAI,MAAM,IAAI;AAAA,MACvC,KAAK,MAAM,IAAI,IAAI;AAAA,IACrB;AAAA,IACA,EAAE,QAAQ,gBAAgB,OAAO;AAAA,EACnC;AACF;AAKO,IAAM,KAAK;AAAA,EAChB;AACF;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/middleware/pubsub/server/fastify.ts"],"sourcesContent":["/**\n * @fileoverview Fastify adapter for pub-sub stream resumption.\n *\n * Provides utilities for Fastify servers to handle stream reconnections.\n *\n * @module middleware/pubsub/server/fastify\n */\n\nimport type { PubSubAdapter } from '../types.ts';\nimport { runSubscriberStream } from './shared.ts';\n\n/**\n * Fastify Reply interface (minimal type to avoid dependency).\n */\ninterface FastifyReply {\n raw: {\n setHeader(name: string, value: string): void;\n write(chunk: string): boolean;\n end(): void;\n on(event: 'close', listener: () => void): void;\n };\n}\n\n/**\n * Stream buffered and live events to a Fastify reply.\n *\n * This utility handles the reconnection pattern for Fastify routes:\n * 1. Replays all buffered events from the adapter\n * 2. If stream is already completed, ends immediately\n * 3. Otherwise, subscribes to live events until completion\n *\n * @param streamId - The stream ID to subscribe to\n * @param adapter - The pub-sub adapter instance\n * @param reply - Fastify reply object\n *\n * @example\n * ```typescript\n * import { streamSubscriber } from '@providerprotocol/ai/middleware/pubsub/server/fastify';\n *\n * app.post('/api/ai/reconnect', async (request, reply) => {\n * const { streamId } = request.body;\n * return streamSubscriber(streamId, adapter, reply);\n * });\n * ```\n */\nexport async function streamSubscriber(\n streamId: string,\n adapter: PubSubAdapter,\n reply: FastifyReply\n): Promise<void> {\n const res = reply.raw;\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n\n const abortController = new AbortController();\n res.on('close', () => abortController.abort());\n\n await runSubscriberStream(\n streamId,\n adapter,\n {\n write: (data: string) => res.write(data),\n end: () => res.end(),\n },\n { signal: abortController.signal }\n );\n}\n\n/**\n * Fastify adapter namespace for pub-sub server utilities.\n */\nexport const fastify = {\n streamSubscriber,\n};\n"],"mappings":";;;;;AA6CA,eAAsB,iBACpB,UACA,SACA,OACe;AACf,QAAM,MAAM,MAAM;AAClB,MAAI,UAAU,gBAAgB,mBAAmB;AACjD,MAAI,UAAU,iBAAiB,UAAU;AACzC,MAAI,UAAU,cAAc,YAAY;AAExC,QAAM,kBAAkB,IAAI,gBAAgB;AAC5C,MAAI,GAAG,SAAS,MAAM,gBAAgB,MAAM,CAAC;AAE7C,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,MACE,OAAO,CAAC,SAAiB,IAAI,MAAM,IAAI;AAAA,MACvC,KAAK,MAAM,IAAI,IAAI;AAAA,IACrB;AAAA,IACA,EAAE,QAAQ,gBAAgB,OAAO;AAAA,EACnC;AACF;AAKO,IAAM,UAAU;AAAA,EACrB;AACF;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/middleware/pubsub/server/express.ts"],"sourcesContent":["/**\n * @fileoverview Express/Connect adapter for pub-sub stream resumption.\n *\n * Provides utilities for Express.js or Connect-based servers\n * to handle stream reconnections.\n *\n * @module middleware/pubsub/server/express\n */\n\nimport type { PubSubAdapter } from '../types.ts';\nimport { runSubscriberStream } from './shared.ts';\n\n/**\n * Express Response interface (minimal type to avoid dependency).\n */\ninterface ExpressResponse {\n setHeader(name: string, value: string): void;\n write(chunk: string): boolean;\n end(): void;\n on(event: 'close', listener: () => void): void;\n}\n\n/**\n * Stream buffered and live events to an Express response.\n *\n * This utility handles the reconnection pattern for Express routes:\n * 1. Replays all buffered events from the adapter\n * 2. If stream is already completed, ends immediately\n * 3. Otherwise, subscribes to live events until completion\n *\n * @param streamId - The stream ID to subscribe to\n * @param adapter - The pub-sub adapter instance\n * @param res - Express response object\n *\n * @example\n * ```typescript\n * import { streamSubscriber } from '@providerprotocol/ai/middleware/pubsub/server/express';\n *\n * app.post('/api/ai/reconnect', async (req, res) => {\n * const { streamId } = req.body;\n * streamSubscriber(streamId, adapter, res);\n * });\n * ```\n */\nexport async function streamSubscriber(\n streamId: string,\n adapter: PubSubAdapter,\n res: ExpressResponse\n): Promise<void> {\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n\n const abortController = new AbortController();\n res.on('close', () => abortController.abort());\n\n await runSubscriberStream(\n streamId,\n adapter,\n {\n write: (data: string) => res.write(data),\n end: () => res.end(),\n },\n { signal: abortController.signal }\n );\n}\n\n/**\n * Express adapter namespace for pub-sub server utilities.\n */\nexport const express = {\n streamSubscriber,\n};\n"],"mappings":";;;;;AA4CA,eAAsB,iBACpB,UACA,SACA,KACe;AACf,MAAI,UAAU,gBAAgB,mBAAmB;AACjD,MAAI,UAAU,iBAAiB,UAAU;AACzC,MAAI,UAAU,cAAc,YAAY;AAExC,QAAM,kBAAkB,IAAI,gBAAgB;AAC5C,MAAI,GAAG,SAAS,MAAM,gBAAgB,MAAM,CAAC;AAE7C,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,MACE,OAAO,CAAC,SAAiB,IAAI,MAAM,IAAI;AAAA,MACvC,KAAK,MAAM,IAAI,IAAI;AAAA,IACrB;AAAA,IACA,EAAE,QAAQ,gBAAgB,OAAO;AAAA,EACnC;AACF;AAKO,IAAM,UAAU;AAAA,EACrB;AACF;","names":[]}