@witqq/agent-sdk 0.6.1 → 0.7.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 (122) hide show
  1. package/README.md +433 -6
  2. package/dist/auth/index.cjs +188 -1
  3. package/dist/auth/index.cjs.map +1 -1
  4. package/dist/auth/index.d.cts +154 -138
  5. package/dist/auth/index.d.ts +154 -138
  6. package/dist/auth/index.js +188 -2
  7. package/dist/auth/index.js.map +1 -1
  8. package/dist/backends/claude.cjs +315 -21
  9. package/dist/backends/claude.cjs.map +1 -1
  10. package/dist/backends/claude.d.cts +2 -1
  11. package/dist/backends/claude.d.ts +2 -1
  12. package/dist/backends/claude.js +315 -21
  13. package/dist/backends/claude.js.map +1 -1
  14. package/dist/backends/copilot.cjs +132 -24
  15. package/dist/backends/copilot.cjs.map +1 -1
  16. package/dist/backends/copilot.d.cts +2 -1
  17. package/dist/backends/copilot.d.ts +2 -1
  18. package/dist/backends/copilot.js +132 -24
  19. package/dist/backends/copilot.js.map +1 -1
  20. package/dist/backends/vercel-ai.cjs +56 -17
  21. package/dist/backends/vercel-ai.cjs.map +1 -1
  22. package/dist/backends/vercel-ai.d.cts +1 -1
  23. package/dist/backends/vercel-ai.d.ts +1 -1
  24. package/dist/backends/vercel-ai.js +56 -17
  25. package/dist/backends/vercel-ai.js.map +1 -1
  26. package/dist/chat/accumulator.cjs +147 -0
  27. package/dist/chat/accumulator.cjs.map +1 -0
  28. package/dist/chat/accumulator.d.cts +61 -0
  29. package/dist/chat/accumulator.d.ts +61 -0
  30. package/dist/chat/accumulator.js +145 -0
  31. package/dist/chat/accumulator.js.map +1 -0
  32. package/dist/chat/backends.cjs +3534 -0
  33. package/dist/chat/backends.cjs.map +1 -0
  34. package/dist/chat/backends.d.cts +62 -0
  35. package/dist/chat/backends.d.ts +62 -0
  36. package/dist/chat/backends.js +3501 -0
  37. package/dist/chat/backends.js.map +1 -0
  38. package/dist/chat/context.cjs +230 -0
  39. package/dist/chat/context.cjs.map +1 -0
  40. package/dist/chat/context.d.cts +167 -0
  41. package/dist/chat/context.d.ts +167 -0
  42. package/dist/chat/context.js +227 -0
  43. package/dist/chat/context.js.map +1 -0
  44. package/dist/chat/core.cjs +282 -0
  45. package/dist/chat/core.cjs.map +1 -0
  46. package/dist/chat/core.d.cts +435 -0
  47. package/dist/chat/core.d.ts +435 -0
  48. package/dist/chat/core.js +261 -0
  49. package/dist/chat/core.js.map +1 -0
  50. package/dist/chat/errors.cjs +251 -0
  51. package/dist/chat/errors.cjs.map +1 -0
  52. package/dist/chat/errors.d.cts +122 -0
  53. package/dist/chat/errors.d.ts +122 -0
  54. package/dist/chat/errors.js +243 -0
  55. package/dist/chat/errors.js.map +1 -0
  56. package/dist/chat/events.cjs +203 -0
  57. package/dist/chat/events.cjs.map +1 -0
  58. package/dist/chat/events.d.cts +241 -0
  59. package/dist/chat/events.d.ts +241 -0
  60. package/dist/chat/events.js +196 -0
  61. package/dist/chat/events.js.map +1 -0
  62. package/dist/chat/index.cjs +5359 -0
  63. package/dist/chat/index.cjs.map +1 -0
  64. package/dist/chat/index.d.cts +52 -0
  65. package/dist/chat/index.d.ts +52 -0
  66. package/dist/chat/index.js +5296 -0
  67. package/dist/chat/index.js.map +1 -0
  68. package/dist/chat/react.cjs +2739 -0
  69. package/dist/chat/react.cjs.map +1 -0
  70. package/dist/chat/react.d.cts +619 -0
  71. package/dist/chat/react.d.ts +619 -0
  72. package/dist/chat/react.js +2714 -0
  73. package/dist/chat/react.js.map +1 -0
  74. package/dist/chat/runtime.cjs +1030 -0
  75. package/dist/chat/runtime.cjs.map +1 -0
  76. package/dist/chat/runtime.d.cts +118 -0
  77. package/dist/chat/runtime.d.ts +118 -0
  78. package/dist/chat/runtime.js +1028 -0
  79. package/dist/chat/runtime.js.map +1 -0
  80. package/dist/chat/server.cjs +643 -0
  81. package/dist/chat/server.cjs.map +1 -0
  82. package/dist/chat/server.d.cts +287 -0
  83. package/dist/chat/server.d.ts +287 -0
  84. package/dist/chat/server.js +617 -0
  85. package/dist/chat/server.js.map +1 -0
  86. package/dist/chat/sessions.cjs +398 -0
  87. package/dist/chat/sessions.cjs.map +1 -0
  88. package/dist/chat/sessions.d.cts +239 -0
  89. package/dist/chat/sessions.d.ts +239 -0
  90. package/dist/chat/sessions.js +394 -0
  91. package/dist/chat/sessions.js.map +1 -0
  92. package/dist/chat/state.cjs +177 -0
  93. package/dist/chat/state.cjs.map +1 -0
  94. package/dist/chat/state.d.cts +92 -0
  95. package/dist/chat/state.d.ts +92 -0
  96. package/dist/chat/state.js +167 -0
  97. package/dist/chat/state.js.map +1 -0
  98. package/dist/chat/storage.cjs +240 -0
  99. package/dist/chat/storage.cjs.map +1 -0
  100. package/dist/chat/storage.d.cts +191 -0
  101. package/dist/chat/storage.d.ts +191 -0
  102. package/dist/chat/storage.js +236 -0
  103. package/dist/chat/storage.js.map +1 -0
  104. package/dist/errors-BDLbNu9w.d.cts +13 -0
  105. package/dist/errors-BDLbNu9w.d.ts +13 -0
  106. package/dist/in-process-transport-C2oPTYs6.d.ts +223 -0
  107. package/dist/in-process-transport-DG-w5G6k.d.cts +223 -0
  108. package/dist/index.cjs +25 -13
  109. package/dist/index.cjs.map +1 -1
  110. package/dist/index.d.cts +32 -4
  111. package/dist/index.d.ts +32 -4
  112. package/dist/index.js +25 -13
  113. package/dist/index.js.map +1 -1
  114. package/dist/transport-D1OaUgRk.d.ts +67 -0
  115. package/dist/transport-DX1Nhm4N.d.cts +67 -0
  116. package/dist/types-Bh5AhqD-.d.ts +141 -0
  117. package/dist/types-CGF7AEX1.d.cts +141 -0
  118. package/dist/{types-BvwNzZCj.d.cts → types-CqvUAYxt.d.cts} +21 -3
  119. package/dist/{types-BvwNzZCj.d.ts → types-CqvUAYxt.d.ts} +21 -3
  120. package/dist/types-DLZzlJxt.d.ts +39 -0
  121. package/dist/types-tE0CXwBl.d.cts +39 -0
  122. package/package.json +149 -2
@@ -0,0 +1,241 @@
1
+ import { ChatEventType, ChatEvent } from './core.cjs';
2
+ import '../types-CqvUAYxt.cjs';
3
+ import 'zod';
4
+
5
+ /**
6
+ * @witqq/agent-sdk/chat/events
7
+ *
8
+ * Type-safe event emitter, chat event bus, and middleware pipeline.
9
+ * Generic TypedEventEmitter<EventMap> for arbitrary typed event maps.
10
+ * ChatEventBus specializing TypedEventEmitter for ChatEvent types.
11
+ * Middleware support for event interception, transformation, and suppression.
12
+ * Utility functions for filtering and mapping event streams.
13
+ */
14
+
15
+ /** Constraint for event maps: keys are strings, values are payloads */
16
+ type EventMap = Record<string, any>;
17
+ /** Listener callback for a specific event */
18
+ type Listener<T> = (payload: T) => void;
19
+ /** Unsubscribe function returned by on/once */
20
+ type Unsubscribe = () => void;
21
+ /**
22
+ * Generic type-safe event emitter parameterized by an EventMap.
23
+ *
24
+ * @typeParam T - Map of event names to payload types
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * type MyEvents = {
29
+ * message: string;
30
+ * count: number;
31
+ * done: void;
32
+ * };
33
+ * const emitter = new TypedEventEmitter<MyEvents>();
34
+ * emitter.on("message", (text) => console.log(text));
35
+ * emitter.emit("message", "hello");
36
+ * ```
37
+ */
38
+ declare class TypedEventEmitter<T extends EventMap> {
39
+ private readonly listeners;
40
+ /**
41
+ * Subscribe to an event.
42
+ * @param event - Event name
43
+ * @param listener - Callback receiving the event payload
44
+ * @returns Unsubscribe function
45
+ */
46
+ on<K extends keyof T>(event: K, listener: Listener<T[K]>): Unsubscribe;
47
+ /**
48
+ * Subscribe to an event, firing the listener at most once.
49
+ * @param event - Event name
50
+ * @param listener - Callback receiving the event payload
51
+ * @returns Unsubscribe function
52
+ */
53
+ once<K extends keyof T>(event: K, listener: Listener<T[K]>): Unsubscribe;
54
+ /**
55
+ * Remove a specific listener from an event.
56
+ * @param event - Event name
57
+ * @param listener - The listener to remove
58
+ */
59
+ off<K extends keyof T>(event: K, listener: Listener<T[K]>): void;
60
+ /**
61
+ * Emit an event, calling all registered listeners synchronously.
62
+ * @param event - Event name
63
+ * @param payload - Event payload
64
+ */
65
+ emit<K extends keyof T>(event: K, payload: T[K]): void;
66
+ /**
67
+ * Remove all listeners for a specific event, or all events if no event specified.
68
+ * @param event - Optional event name
69
+ */
70
+ removeAllListeners<K extends keyof T>(event?: K): void;
71
+ /**
72
+ * Get the number of listeners for a specific event.
73
+ * @param event - Event name
74
+ * @returns Number of listeners
75
+ */
76
+ listenerCount<K extends keyof T>(event: K): number;
77
+ /**
78
+ * Get all event names that have at least one listener.
79
+ * @returns Array of event names
80
+ */
81
+ eventNames(): Array<keyof T>;
82
+ }
83
+ /**
84
+ * Map of ChatEvent type strings to their corresponding ChatEvent payloads.
85
+ * Used to parameterize TypedEventEmitter for chat events.
86
+ */
87
+ type ChatEventMap = {
88
+ [K in ChatEventType]: Extract<ChatEvent, {
89
+ type: K;
90
+ }>;
91
+ };
92
+ /**
93
+ * Context passed to middleware functions.
94
+ * Contains the event and control methods for the middleware pipeline.
95
+ */
96
+ interface MiddlewareContext {
97
+ /** The current event (may be transformed by prior middleware) */
98
+ event: ChatEvent;
99
+ /** Call the next middleware in the chain, or deliver to listeners if last */
100
+ next: () => void;
101
+ /** Suppress the event — do not deliver to listeners or subsequent middleware */
102
+ suppress: () => void;
103
+ }
104
+ /**
105
+ * Middleware function for intercepting, transforming, or suppressing events.
106
+ *
107
+ * @param ctx - Middleware context with event, next(), and suppress()
108
+ *
109
+ * @example
110
+ * ```typescript
111
+ * // Logging middleware
112
+ * const logger: EventMiddleware = (ctx) => {
113
+ * console.log(`Event: ${ctx.event.type}`);
114
+ * ctx.next();
115
+ * };
116
+ *
117
+ * // Suppressing middleware
118
+ * const filter: EventMiddleware = (ctx) => {
119
+ * if (ctx.event.type === "heartbeat") {
120
+ * ctx.suppress();
121
+ * } else {
122
+ * ctx.next();
123
+ * }
124
+ * };
125
+ * ```
126
+ */
127
+ type EventMiddleware = (ctx: MiddlewareContext) => void;
128
+ /**
129
+ * Chat event bus: a typed event emitter specialized for ChatEvent types
130
+ * with middleware pipeline support.
131
+ *
132
+ * Events pass through the middleware pipeline before reaching listeners.
133
+ * Middleware can inspect, transform, or suppress events.
134
+ *
135
+ * @example
136
+ * ```typescript
137
+ * const bus = new ChatEventBus();
138
+ *
139
+ * // Add middleware
140
+ * bus.use((ctx) => {
141
+ * console.log(`[${ctx.event.type}]`);
142
+ * ctx.next();
143
+ * });
144
+ *
145
+ * // Listen for events
146
+ * bus.on("message:delta", (event) => {
147
+ * console.log(event.text);
148
+ * });
149
+ *
150
+ * // Emit events
151
+ * bus.emit("message:delta", { type: "message:delta", messageId: id, text: "hi" });
152
+ * ```
153
+ */
154
+ declare class ChatEventBus extends TypedEventEmitter<ChatEventMap> {
155
+ private readonly middlewares;
156
+ /**
157
+ * Register a middleware function. Middleware runs in registration order.
158
+ * @param middleware - Middleware function
159
+ * @returns Unsubscribe function to remove the middleware
160
+ */
161
+ use(middleware: EventMiddleware): Unsubscribe;
162
+ /**
163
+ * Emit a chat event through the middleware pipeline, then to listeners.
164
+ *
165
+ * @param event - ChatEvent type string
166
+ * @param payload - The full ChatEvent object
167
+ */
168
+ emit<K extends ChatEventType>(event: K, payload: ChatEventMap[K]): void;
169
+ /**
170
+ * Replace the event in the middleware context.
171
+ * Middleware should mutate ctx.event or create a new MiddlewareContext
172
+ * to transform events passing through the pipeline.
173
+ */
174
+ /**
175
+ * Remove all middleware functions.
176
+ */
177
+ clearMiddleware(): void;
178
+ /**
179
+ * Get the number of registered middleware functions.
180
+ * @returns Number of middleware
181
+ */
182
+ middlewareCount(): number;
183
+ }
184
+ /**
185
+ * Create a filter function that passes only events of specified types.
186
+ *
187
+ * @param types - Event types to allow through
188
+ * @returns Predicate function for filtering ChatEvents
189
+ *
190
+ * @example
191
+ * ```typescript
192
+ * const isTextEvent = eventFilter("message:start", "message:delta", "message:complete");
193
+ * const textEvents = allEvents.filter(isTextEvent);
194
+ * ```
195
+ */
196
+ declare function eventFilter(...types: ChatEventType[]): (event: ChatEvent) => boolean;
197
+ /**
198
+ * Filter an async iterable of ChatEvents to only specified types.
199
+ *
200
+ * @param source - Async iterable of ChatEvents
201
+ * @param types - Event types to keep
202
+ * @returns Async iterable of filtered ChatEvents
203
+ *
204
+ * @example
205
+ * ```typescript
206
+ * for await (const event of filterEvents(stream, "message:delta", "message:complete")) {
207
+ * // only message:delta and message:complete events
208
+ * }
209
+ * ```
210
+ */
211
+ declare function filterEvents(source: AsyncIterable<ChatEvent>, ...types: ChatEventType[]): AsyncIterable<ChatEvent>;
212
+ /**
213
+ * Map/transform events from an async iterable.
214
+ *
215
+ * @param source - Async iterable of ChatEvents
216
+ * @param transform - Function to transform each event (return null to skip)
217
+ * @returns Async iterable of transformed values
218
+ *
219
+ * @example
220
+ * ```typescript
221
+ * // Extract text from message:delta events
222
+ * const texts = mapEvents(stream, (event) =>
223
+ * event.type === "message:delta" ? event.text : null
224
+ * );
225
+ * ```
226
+ */
227
+ declare function mapEvents<R>(source: AsyncIterable<ChatEvent>, transform: (event: ChatEvent) => R | null): AsyncIterable<R>;
228
+ /**
229
+ * Collect text from message:delta events into a single string.
230
+ *
231
+ * @param source - Async iterable of ChatEvents
232
+ * @returns Complete text assembled from message:delta payloads
233
+ *
234
+ * @example
235
+ * ```typescript
236
+ * const fullText = await collectText(stream);
237
+ * ```
238
+ */
239
+ declare function collectText(source: AsyncIterable<ChatEvent>): Promise<string>;
240
+
241
+ export { ChatEventBus, type ChatEventMap, type EventMap, type EventMiddleware, type Listener, type MiddlewareContext, TypedEventEmitter, type Unsubscribe, collectText, eventFilter, filterEvents, mapEvents };
@@ -0,0 +1,241 @@
1
+ import { ChatEventType, ChatEvent } from './core.js';
2
+ import '../types-CqvUAYxt.js';
3
+ import 'zod';
4
+
5
+ /**
6
+ * @witqq/agent-sdk/chat/events
7
+ *
8
+ * Type-safe event emitter, chat event bus, and middleware pipeline.
9
+ * Generic TypedEventEmitter<EventMap> for arbitrary typed event maps.
10
+ * ChatEventBus specializing TypedEventEmitter for ChatEvent types.
11
+ * Middleware support for event interception, transformation, and suppression.
12
+ * Utility functions for filtering and mapping event streams.
13
+ */
14
+
15
+ /** Constraint for event maps: keys are strings, values are payloads */
16
+ type EventMap = Record<string, any>;
17
+ /** Listener callback for a specific event */
18
+ type Listener<T> = (payload: T) => void;
19
+ /** Unsubscribe function returned by on/once */
20
+ type Unsubscribe = () => void;
21
+ /**
22
+ * Generic type-safe event emitter parameterized by an EventMap.
23
+ *
24
+ * @typeParam T - Map of event names to payload types
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * type MyEvents = {
29
+ * message: string;
30
+ * count: number;
31
+ * done: void;
32
+ * };
33
+ * const emitter = new TypedEventEmitter<MyEvents>();
34
+ * emitter.on("message", (text) => console.log(text));
35
+ * emitter.emit("message", "hello");
36
+ * ```
37
+ */
38
+ declare class TypedEventEmitter<T extends EventMap> {
39
+ private readonly listeners;
40
+ /**
41
+ * Subscribe to an event.
42
+ * @param event - Event name
43
+ * @param listener - Callback receiving the event payload
44
+ * @returns Unsubscribe function
45
+ */
46
+ on<K extends keyof T>(event: K, listener: Listener<T[K]>): Unsubscribe;
47
+ /**
48
+ * Subscribe to an event, firing the listener at most once.
49
+ * @param event - Event name
50
+ * @param listener - Callback receiving the event payload
51
+ * @returns Unsubscribe function
52
+ */
53
+ once<K extends keyof T>(event: K, listener: Listener<T[K]>): Unsubscribe;
54
+ /**
55
+ * Remove a specific listener from an event.
56
+ * @param event - Event name
57
+ * @param listener - The listener to remove
58
+ */
59
+ off<K extends keyof T>(event: K, listener: Listener<T[K]>): void;
60
+ /**
61
+ * Emit an event, calling all registered listeners synchronously.
62
+ * @param event - Event name
63
+ * @param payload - Event payload
64
+ */
65
+ emit<K extends keyof T>(event: K, payload: T[K]): void;
66
+ /**
67
+ * Remove all listeners for a specific event, or all events if no event specified.
68
+ * @param event - Optional event name
69
+ */
70
+ removeAllListeners<K extends keyof T>(event?: K): void;
71
+ /**
72
+ * Get the number of listeners for a specific event.
73
+ * @param event - Event name
74
+ * @returns Number of listeners
75
+ */
76
+ listenerCount<K extends keyof T>(event: K): number;
77
+ /**
78
+ * Get all event names that have at least one listener.
79
+ * @returns Array of event names
80
+ */
81
+ eventNames(): Array<keyof T>;
82
+ }
83
+ /**
84
+ * Map of ChatEvent type strings to their corresponding ChatEvent payloads.
85
+ * Used to parameterize TypedEventEmitter for chat events.
86
+ */
87
+ type ChatEventMap = {
88
+ [K in ChatEventType]: Extract<ChatEvent, {
89
+ type: K;
90
+ }>;
91
+ };
92
+ /**
93
+ * Context passed to middleware functions.
94
+ * Contains the event and control methods for the middleware pipeline.
95
+ */
96
+ interface MiddlewareContext {
97
+ /** The current event (may be transformed by prior middleware) */
98
+ event: ChatEvent;
99
+ /** Call the next middleware in the chain, or deliver to listeners if last */
100
+ next: () => void;
101
+ /** Suppress the event — do not deliver to listeners or subsequent middleware */
102
+ suppress: () => void;
103
+ }
104
+ /**
105
+ * Middleware function for intercepting, transforming, or suppressing events.
106
+ *
107
+ * @param ctx - Middleware context with event, next(), and suppress()
108
+ *
109
+ * @example
110
+ * ```typescript
111
+ * // Logging middleware
112
+ * const logger: EventMiddleware = (ctx) => {
113
+ * console.log(`Event: ${ctx.event.type}`);
114
+ * ctx.next();
115
+ * };
116
+ *
117
+ * // Suppressing middleware
118
+ * const filter: EventMiddleware = (ctx) => {
119
+ * if (ctx.event.type === "heartbeat") {
120
+ * ctx.suppress();
121
+ * } else {
122
+ * ctx.next();
123
+ * }
124
+ * };
125
+ * ```
126
+ */
127
+ type EventMiddleware = (ctx: MiddlewareContext) => void;
128
+ /**
129
+ * Chat event bus: a typed event emitter specialized for ChatEvent types
130
+ * with middleware pipeline support.
131
+ *
132
+ * Events pass through the middleware pipeline before reaching listeners.
133
+ * Middleware can inspect, transform, or suppress events.
134
+ *
135
+ * @example
136
+ * ```typescript
137
+ * const bus = new ChatEventBus();
138
+ *
139
+ * // Add middleware
140
+ * bus.use((ctx) => {
141
+ * console.log(`[${ctx.event.type}]`);
142
+ * ctx.next();
143
+ * });
144
+ *
145
+ * // Listen for events
146
+ * bus.on("message:delta", (event) => {
147
+ * console.log(event.text);
148
+ * });
149
+ *
150
+ * // Emit events
151
+ * bus.emit("message:delta", { type: "message:delta", messageId: id, text: "hi" });
152
+ * ```
153
+ */
154
+ declare class ChatEventBus extends TypedEventEmitter<ChatEventMap> {
155
+ private readonly middlewares;
156
+ /**
157
+ * Register a middleware function. Middleware runs in registration order.
158
+ * @param middleware - Middleware function
159
+ * @returns Unsubscribe function to remove the middleware
160
+ */
161
+ use(middleware: EventMiddleware): Unsubscribe;
162
+ /**
163
+ * Emit a chat event through the middleware pipeline, then to listeners.
164
+ *
165
+ * @param event - ChatEvent type string
166
+ * @param payload - The full ChatEvent object
167
+ */
168
+ emit<K extends ChatEventType>(event: K, payload: ChatEventMap[K]): void;
169
+ /**
170
+ * Replace the event in the middleware context.
171
+ * Middleware should mutate ctx.event or create a new MiddlewareContext
172
+ * to transform events passing through the pipeline.
173
+ */
174
+ /**
175
+ * Remove all middleware functions.
176
+ */
177
+ clearMiddleware(): void;
178
+ /**
179
+ * Get the number of registered middleware functions.
180
+ * @returns Number of middleware
181
+ */
182
+ middlewareCount(): number;
183
+ }
184
+ /**
185
+ * Create a filter function that passes only events of specified types.
186
+ *
187
+ * @param types - Event types to allow through
188
+ * @returns Predicate function for filtering ChatEvents
189
+ *
190
+ * @example
191
+ * ```typescript
192
+ * const isTextEvent = eventFilter("message:start", "message:delta", "message:complete");
193
+ * const textEvents = allEvents.filter(isTextEvent);
194
+ * ```
195
+ */
196
+ declare function eventFilter(...types: ChatEventType[]): (event: ChatEvent) => boolean;
197
+ /**
198
+ * Filter an async iterable of ChatEvents to only specified types.
199
+ *
200
+ * @param source - Async iterable of ChatEvents
201
+ * @param types - Event types to keep
202
+ * @returns Async iterable of filtered ChatEvents
203
+ *
204
+ * @example
205
+ * ```typescript
206
+ * for await (const event of filterEvents(stream, "message:delta", "message:complete")) {
207
+ * // only message:delta and message:complete events
208
+ * }
209
+ * ```
210
+ */
211
+ declare function filterEvents(source: AsyncIterable<ChatEvent>, ...types: ChatEventType[]): AsyncIterable<ChatEvent>;
212
+ /**
213
+ * Map/transform events from an async iterable.
214
+ *
215
+ * @param source - Async iterable of ChatEvents
216
+ * @param transform - Function to transform each event (return null to skip)
217
+ * @returns Async iterable of transformed values
218
+ *
219
+ * @example
220
+ * ```typescript
221
+ * // Extract text from message:delta events
222
+ * const texts = mapEvents(stream, (event) =>
223
+ * event.type === "message:delta" ? event.text : null
224
+ * );
225
+ * ```
226
+ */
227
+ declare function mapEvents<R>(source: AsyncIterable<ChatEvent>, transform: (event: ChatEvent) => R | null): AsyncIterable<R>;
228
+ /**
229
+ * Collect text from message:delta events into a single string.
230
+ *
231
+ * @param source - Async iterable of ChatEvents
232
+ * @returns Complete text assembled from message:delta payloads
233
+ *
234
+ * @example
235
+ * ```typescript
236
+ * const fullText = await collectText(stream);
237
+ * ```
238
+ */
239
+ declare function collectText(source: AsyncIterable<ChatEvent>): Promise<string>;
240
+
241
+ export { ChatEventBus, type ChatEventMap, type EventMap, type EventMiddleware, type Listener, type MiddlewareContext, TypedEventEmitter, type Unsubscribe, collectText, eventFilter, filterEvents, mapEvents };
@@ -0,0 +1,196 @@
1
+ // src/chat/events.ts
2
+ var TypedEventEmitter = class {
3
+ listeners = /* @__PURE__ */ new Map();
4
+ /**
5
+ * Subscribe to an event.
6
+ * @param event - Event name
7
+ * @param listener - Callback receiving the event payload
8
+ * @returns Unsubscribe function
9
+ */
10
+ on(event, listener) {
11
+ let set = this.listeners.get(event);
12
+ if (!set) {
13
+ set = /* @__PURE__ */ new Set();
14
+ this.listeners.set(event, set);
15
+ }
16
+ const fn = listener;
17
+ set.add(fn);
18
+ return () => {
19
+ set.delete(fn);
20
+ if (set.size === 0) {
21
+ this.listeners.delete(event);
22
+ }
23
+ };
24
+ }
25
+ /**
26
+ * Subscribe to an event, firing the listener at most once.
27
+ * @param event - Event name
28
+ * @param listener - Callback receiving the event payload
29
+ * @returns Unsubscribe function
30
+ */
31
+ once(event, listener) {
32
+ const unsub = this.on(event, (payload) => {
33
+ unsub();
34
+ listener(payload);
35
+ });
36
+ return unsub;
37
+ }
38
+ /**
39
+ * Remove a specific listener from an event.
40
+ * @param event - Event name
41
+ * @param listener - The listener to remove
42
+ */
43
+ off(event, listener) {
44
+ const set = this.listeners.get(event);
45
+ if (!set) return;
46
+ set.delete(listener);
47
+ if (set.size === 0) {
48
+ this.listeners.delete(event);
49
+ }
50
+ }
51
+ /**
52
+ * Emit an event, calling all registered listeners synchronously.
53
+ * @param event - Event name
54
+ * @param payload - Event payload
55
+ */
56
+ emit(event, payload) {
57
+ const set = this.listeners.get(event);
58
+ if (!set) return;
59
+ for (const fn of [...set]) {
60
+ fn(payload);
61
+ }
62
+ }
63
+ /**
64
+ * Remove all listeners for a specific event, or all events if no event specified.
65
+ * @param event - Optional event name
66
+ */
67
+ removeAllListeners(event) {
68
+ if (event !== void 0) {
69
+ this.listeners.delete(event);
70
+ } else {
71
+ this.listeners.clear();
72
+ }
73
+ }
74
+ /**
75
+ * Get the number of listeners for a specific event.
76
+ * @param event - Event name
77
+ * @returns Number of listeners
78
+ */
79
+ listenerCount(event) {
80
+ const set = this.listeners.get(event);
81
+ return set ? set.size : 0;
82
+ }
83
+ /**
84
+ * Get all event names that have at least one listener.
85
+ * @returns Array of event names
86
+ */
87
+ eventNames() {
88
+ return [...this.listeners.keys()];
89
+ }
90
+ };
91
+ var ChatEventBus = class extends TypedEventEmitter {
92
+ middlewares = [];
93
+ /**
94
+ * Register a middleware function. Middleware runs in registration order.
95
+ * @param middleware - Middleware function
96
+ * @returns Unsubscribe function to remove the middleware
97
+ */
98
+ use(middleware) {
99
+ this.middlewares.push(middleware);
100
+ return () => {
101
+ const idx = this.middlewares.indexOf(middleware);
102
+ if (idx !== -1) {
103
+ this.middlewares.splice(idx, 1);
104
+ }
105
+ };
106
+ }
107
+ /**
108
+ * Emit a chat event through the middleware pipeline, then to listeners.
109
+ *
110
+ * @param event - ChatEvent type string
111
+ * @param payload - The full ChatEvent object
112
+ */
113
+ emit(event, payload) {
114
+ if (this.middlewares.length === 0) {
115
+ super.emit(event, payload);
116
+ return;
117
+ }
118
+ let suppressed = false;
119
+ let currentEvent = payload;
120
+ let index = 0;
121
+ const runNext = () => {
122
+ if (suppressed) return;
123
+ if (index >= this.middlewares.length) {
124
+ super.emit(
125
+ currentEvent.type,
126
+ currentEvent
127
+ );
128
+ return;
129
+ }
130
+ const mw = this.middlewares[index++];
131
+ const ctx = {
132
+ event: currentEvent,
133
+ next: () => {
134
+ currentEvent = ctx.event;
135
+ runNext();
136
+ },
137
+ suppress: () => {
138
+ suppressed = true;
139
+ }
140
+ };
141
+ mw(ctx);
142
+ };
143
+ runNext();
144
+ }
145
+ /**
146
+ * Replace the event in the middleware context.
147
+ * Middleware should mutate ctx.event or create a new MiddlewareContext
148
+ * to transform events passing through the pipeline.
149
+ */
150
+ /**
151
+ * Remove all middleware functions.
152
+ */
153
+ clearMiddleware() {
154
+ this.middlewares.length = 0;
155
+ }
156
+ /**
157
+ * Get the number of registered middleware functions.
158
+ * @returns Number of middleware
159
+ */
160
+ middlewareCount() {
161
+ return this.middlewares.length;
162
+ }
163
+ };
164
+ function eventFilter(...types) {
165
+ const allowed = new Set(types);
166
+ return (event) => allowed.has(event.type);
167
+ }
168
+ async function* filterEvents(source, ...types) {
169
+ const pred = eventFilter(...types);
170
+ for await (const event of source) {
171
+ if (pred(event)) {
172
+ yield event;
173
+ }
174
+ }
175
+ }
176
+ async function* mapEvents(source, transform) {
177
+ for await (const event of source) {
178
+ const result = transform(event);
179
+ if (result !== null) {
180
+ yield result;
181
+ }
182
+ }
183
+ }
184
+ async function collectText(source) {
185
+ const parts = [];
186
+ for await (const event of source) {
187
+ if (event.type === "message:delta") {
188
+ parts.push(event.text);
189
+ }
190
+ }
191
+ return parts.join("");
192
+ }
193
+
194
+ export { ChatEventBus, TypedEventEmitter, collectText, eventFilter, filterEvents, mapEvents };
195
+ //# sourceMappingURL=events.js.map
196
+ //# sourceMappingURL=events.js.map