@tangle-network/agent-core 0.2.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 (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +35 -0
  3. package/dist/auth/browser.d.ts +22 -0
  4. package/dist/auth/browser.d.ts.map +1 -0
  5. package/dist/auth/browser.js +43 -0
  6. package/dist/auth/browser.js.map +1 -0
  7. package/dist/auth/index.d.ts +430 -0
  8. package/dist/auth/index.d.ts.map +1 -0
  9. package/dist/auth/index.js +841 -0
  10. package/dist/auth/index.js.map +1 -0
  11. package/dist/computer-use/index.d.ts +122 -0
  12. package/dist/computer-use/index.d.ts.map +1 -0
  13. package/dist/computer-use/index.js +422 -0
  14. package/dist/computer-use/index.js.map +1 -0
  15. package/dist/errors-DJ6U6cHY.js +146 -0
  16. package/dist/errors-DJ6U6cHY.js.map +1 -0
  17. package/dist/events/index.d.ts +2 -0
  18. package/dist/events/index.js +2 -0
  19. package/dist/events-CUWh9qrv.js +263 -0
  20. package/dist/events-CUWh9qrv.js.map +1 -0
  21. package/dist/index-CFA8kgHJ.d.ts +352 -0
  22. package/dist/index-CFA8kgHJ.d.ts.map +1 -0
  23. package/dist/index-CtebBodu.d.ts +108 -0
  24. package/dist/index-CtebBodu.d.ts.map +1 -0
  25. package/dist/index-DiQX9bjq.d.ts +55 -0
  26. package/dist/index-DiQX9bjq.d.ts.map +1 -0
  27. package/dist/index-DlPznmKA.d.ts +158 -0
  28. package/dist/index-DlPznmKA.d.ts.map +1 -0
  29. package/dist/index-z2wPdzFb.d.ts +133 -0
  30. package/dist/index-z2wPdzFb.d.ts.map +1 -0
  31. package/dist/index.d.ts +565 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +822 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/resilience/index.d.ts +2 -0
  36. package/dist/resilience/index.js +2 -0
  37. package/dist/resilience-BQzDfw_C.js +221 -0
  38. package/dist/resilience-BQzDfw_C.js.map +1 -0
  39. package/dist/sse/index.d.ts +174 -0
  40. package/dist/sse/index.d.ts.map +1 -0
  41. package/dist/sse/index.js +303 -0
  42. package/dist/sse/index.js.map +1 -0
  43. package/dist/transport/index.d.ts +2 -0
  44. package/dist/transport/index.js +2 -0
  45. package/dist/transport-mKLoQep5.js +427 -0
  46. package/dist/transport-mKLoQep5.js.map +1 -0
  47. package/dist/types/index.d.ts +2 -0
  48. package/dist/types/index.js +2 -0
  49. package/dist/types-D5VLaol0.js +31 -0
  50. package/dist/types-D5VLaol0.js.map +1 -0
  51. package/dist/types-DC6OJ1um.js +331 -0
  52. package/dist/types-DC6OJ1um.js.map +1 -0
  53. package/dist/types-DiDSGM8K.d.ts +320 -0
  54. package/dist/types-DiDSGM8K.d.ts.map +1 -0
  55. package/package.json +132 -0
@@ -0,0 +1,427 @@
1
+ //#region src/transport/types.ts
2
+ /** Default reconnection config */
3
+ const DEFAULT_RECONNECTION_CONFIG = {
4
+ initialDelayMs: 1e3,
5
+ maxDelayMs: 3e4,
6
+ multiplier: 1.5,
7
+ jitter: .2,
8
+ maxAttempts: 10
9
+ };
10
+ //#endregion
11
+ //#region src/transport/connection-manager.ts
12
+ /**
13
+ * Connection Manager
14
+ *
15
+ * Manages reconnection logic with exponential backoff and jitter.
16
+ */
17
+ var ConnectionManager = class {
18
+ config;
19
+ attempt = 0;
20
+ aborted = false;
21
+ callbacks;
22
+ constructor(config = {}) {
23
+ this.config = {
24
+ initialDelayMs: config.initialDelayMs ?? DEFAULT_RECONNECTION_CONFIG.initialDelayMs,
25
+ maxDelayMs: config.maxDelayMs ?? DEFAULT_RECONNECTION_CONFIG.maxDelayMs,
26
+ multiplier: config.multiplier ?? DEFAULT_RECONNECTION_CONFIG.multiplier,
27
+ jitter: config.jitter ?? DEFAULT_RECONNECTION_CONFIG.jitter,
28
+ maxAttempts: config.maxAttempts ?? DEFAULT_RECONNECTION_CONFIG.maxAttempts
29
+ };
30
+ this.callbacks = {
31
+ onReconnecting: config.onReconnecting,
32
+ onReconnected: config.onReconnected,
33
+ onFailed: config.onFailed
34
+ };
35
+ }
36
+ /**
37
+ * Calculate delay for current attempt with exponential backoff and jitter.
38
+ */
39
+ calculateDelay() {
40
+ const exponentialDelay = this.config.initialDelayMs * this.config.multiplier ** (this.attempt - 1);
41
+ const cappedDelay = Math.min(exponentialDelay, this.config.maxDelayMs);
42
+ const jitterRange = cappedDelay * this.config.jitter;
43
+ const jitter = (Math.random() - .5) * 2 * jitterRange;
44
+ return Math.max(0, cappedDelay + jitter);
45
+ }
46
+ /**
47
+ * Wait for the calculated delay.
48
+ */
49
+ async wait() {
50
+ const delay = this.calculateDelay();
51
+ await new Promise((resolve) => setTimeout(resolve, delay));
52
+ }
53
+ /**
54
+ * Check if more reconnection attempts are allowed.
55
+ */
56
+ canRetry() {
57
+ if (this.aborted) return false;
58
+ if (this.config.maxAttempts === -1) return true;
59
+ return this.attempt < this.config.maxAttempts;
60
+ }
61
+ /**
62
+ * Get current attempt number.
63
+ */
64
+ getAttempt() {
65
+ return this.attempt;
66
+ }
67
+ /**
68
+ * Reset the connection manager state.
69
+ */
70
+ reset() {
71
+ this.attempt = 0;
72
+ this.aborted = false;
73
+ }
74
+ /**
75
+ * Abort any pending reconnection attempts.
76
+ */
77
+ abort() {
78
+ this.aborted = true;
79
+ }
80
+ /**
81
+ * Execute a reconnection attempt with the provided connect function.
82
+ * Returns true if connection succeeded, false if should retry.
83
+ */
84
+ async reconnect(connectFn) {
85
+ if (!this.canRetry()) {
86
+ const error = /* @__PURE__ */ new Error(`Max reconnection attempts (${this.config.maxAttempts}) exceeded`);
87
+ this.callbacks.onFailed?.(error);
88
+ return false;
89
+ }
90
+ this.attempt++;
91
+ this.callbacks.onReconnecting?.(this.attempt, this.config.maxAttempts);
92
+ await this.wait();
93
+ if (this.aborted) return false;
94
+ try {
95
+ await connectFn();
96
+ this.callbacks.onReconnected?.();
97
+ this.reset();
98
+ return true;
99
+ } catch {
100
+ return false;
101
+ }
102
+ }
103
+ /**
104
+ * Run reconnection loop until success or max attempts.
105
+ */
106
+ async runReconnectionLoop(connectFn) {
107
+ while (this.canRetry()) if (await this.reconnect(connectFn)) return true;
108
+ return false;
109
+ }
110
+ };
111
+ //#endregion
112
+ //#region src/transport/interface.ts
113
+ /**
114
+ * Base class for transport adapters with shared functionality.
115
+ * Handles event emission, metrics tracking, and connection state.
116
+ */
117
+ var BaseTransportAdapter = class {
118
+ _state = "disconnected";
119
+ _quality = "excellent";
120
+ config;
121
+ listeners = /* @__PURE__ */ new Map();
122
+ metrics = {
123
+ requestCount: 0,
124
+ failedRequests: 0,
125
+ avgLatencyMs: 0,
126
+ reconnectionAttempt: 0,
127
+ totalReconnections: 0,
128
+ missedHeartbeats: 0,
129
+ uptimeMs: 0
130
+ };
131
+ connectionStartTime;
132
+ latencySum = 0;
133
+ constructor(config) {
134
+ this.config = {
135
+ baseUrl: config.baseUrl.replace(/\/$/, ""),
136
+ headers: config.headers ?? {},
137
+ timeout: config.timeout ?? 3e4,
138
+ heartbeatIntervalMs: config.heartbeatIntervalMs ?? 3e4,
139
+ autoReconnect: config.autoReconnect ?? true,
140
+ reconnection: {
141
+ initialDelayMs: config.reconnection?.initialDelayMs ?? 1e3,
142
+ maxDelayMs: config.reconnection?.maxDelayMs ?? 3e4,
143
+ multiplier: config.reconnection?.multiplier ?? 1.5,
144
+ jitter: config.reconnection?.jitter ?? .2,
145
+ maxAttempts: config.reconnection?.maxAttempts ?? 10
146
+ }
147
+ };
148
+ }
149
+ get state() {
150
+ return this._state;
151
+ }
152
+ isConnected() {
153
+ return this._state === "connected";
154
+ }
155
+ on(event, listener) {
156
+ if (!this.listeners.has(event)) this.listeners.set(event, /* @__PURE__ */ new Set());
157
+ this.listeners.get(event)?.add(listener);
158
+ return () => this.listeners.get(event)?.delete(listener);
159
+ }
160
+ getMetrics() {
161
+ return {
162
+ ...this.metrics,
163
+ uptimeMs: this.connectionStartTime ? Date.now() - this.connectionStartTime : 0
164
+ };
165
+ }
166
+ getQuality() {
167
+ return this._quality;
168
+ }
169
+ emit(event, ...args) {
170
+ const listeners = this.listeners.get(event);
171
+ if (listeners) for (const listener of listeners) try {
172
+ listener(...args);
173
+ } catch (e) {
174
+ console.error(`Error in ${event} listener:`, e);
175
+ }
176
+ }
177
+ setState(state) {
178
+ if (this._state !== state) {
179
+ this._state = state;
180
+ if (state === "connected") {
181
+ this.connectionStartTime = Date.now();
182
+ this.metrics.reconnectionAttempt = 0;
183
+ }
184
+ this.emit("stateChange", state);
185
+ }
186
+ }
187
+ setQuality(quality) {
188
+ if (this._quality !== quality) {
189
+ this._quality = quality;
190
+ this.emit("qualityChange", quality);
191
+ }
192
+ }
193
+ recordRequest(durationMs, failed) {
194
+ this.metrics.requestCount++;
195
+ if (failed) this.metrics.failedRequests++;
196
+ this.latencySum += durationMs;
197
+ this.metrics.avgLatencyMs = this.latencySum / this.metrics.requestCount;
198
+ this.metrics.lastRequestAt = Date.now();
199
+ this.updateQuality();
200
+ }
201
+ recordReconnection() {
202
+ this.metrics.totalReconnections++;
203
+ this.emit("reconnected");
204
+ }
205
+ recordMissedHeartbeat() {
206
+ this.metrics.missedHeartbeats++;
207
+ this.updateQuality();
208
+ }
209
+ resetHeartbeatCounter() {
210
+ this.metrics.missedHeartbeats = 0;
211
+ this.updateQuality();
212
+ }
213
+ updateQuality() {
214
+ const failRate = this.metrics.requestCount > 0 ? this.metrics.failedRequests / this.metrics.requestCount : 0;
215
+ let quality;
216
+ if (this.metrics.missedHeartbeats >= 3 || failRate > .5 || this.metrics.avgLatencyMs > 5e3) quality = "poor";
217
+ else if (this.metrics.missedHeartbeats >= 2 || failRate > .2 || this.metrics.avgLatencyMs > 2e3) quality = "degraded";
218
+ else if (this.metrics.missedHeartbeats >= 1 || failRate > .1 || this.metrics.avgLatencyMs > 1e3) quality = "good";
219
+ else quality = "excellent";
220
+ this.setQuality(quality);
221
+ }
222
+ buildUrl(path) {
223
+ const cleanPath = path.startsWith("/") ? path : `/${path}`;
224
+ return `${this.config.baseUrl}${cleanPath}`;
225
+ }
226
+ buildHeaders(extra) {
227
+ return {
228
+ ...this.config.headers,
229
+ ...extra
230
+ };
231
+ }
232
+ };
233
+ //#endregion
234
+ //#region src/transport/mock.ts
235
+ /**
236
+ * Mock Transport Adapter
237
+ *
238
+ * A fully controllable transport adapter for testing.
239
+ * Allows mocking responses, simulating streams, and verifying requests.
240
+ */
241
+ /** Mock subscription for testing */
242
+ var MockSubscription = class {
243
+ streamId;
244
+ _state = "active";
245
+ eventCallbacks = /* @__PURE__ */ new Set();
246
+ errorCallbacks = /* @__PURE__ */ new Set();
247
+ reconnectCallbacks = /* @__PURE__ */ new Set();
248
+ events = [];
249
+ eventIndex = 0;
250
+ closed = false;
251
+ constructor(streamId, events = []) {
252
+ this.streamId = streamId;
253
+ this.events = events.map((e, i) => ({
254
+ id: e.id ?? `mock_${i}`,
255
+ event: e.event,
256
+ data: e.data
257
+ }));
258
+ }
259
+ get state() {
260
+ return this._state;
261
+ }
262
+ pause() {
263
+ if (this._state === "active") this._state = "paused";
264
+ }
265
+ resume() {
266
+ if (this._state === "paused") {
267
+ this._state = "active";
268
+ this.deliverPending();
269
+ }
270
+ }
271
+ close() {
272
+ this._state = "closed";
273
+ this.closed = true;
274
+ }
275
+ onEvent(callback) {
276
+ this.eventCallbacks.add(callback);
277
+ return () => this.eventCallbacks.delete(callback);
278
+ }
279
+ onError(callback) {
280
+ this.errorCallbacks.add(callback);
281
+ return () => this.errorCallbacks.delete(callback);
282
+ }
283
+ onReconnect(callback) {
284
+ this.reconnectCallbacks.add(callback);
285
+ return () => this.reconnectCallbacks.delete(callback);
286
+ }
287
+ async *[Symbol.asyncIterator]() {
288
+ while (!this.closed) if (this.eventIndex < this.events.length) if (this._state === "active") yield this.events[this.eventIndex++];
289
+ else await new Promise((r) => setTimeout(r, 10));
290
+ else await new Promise((r) => setTimeout(r, 10));
291
+ }
292
+ /** Push a new event to the stream (for testing) */
293
+ pushEvent(event) {
294
+ this.events.push(event);
295
+ if (this._state === "active") this.deliverPending();
296
+ }
297
+ /** Simulate an error (for testing) */
298
+ simulateError(error) {
299
+ for (const cb of this.errorCallbacks) cb(error);
300
+ }
301
+ /** Simulate reconnection (for testing) */
302
+ simulateReconnect(lastEventId) {
303
+ for (const cb of this.reconnectCallbacks) cb(lastEventId);
304
+ }
305
+ deliverPending() {
306
+ while (this.eventIndex < this.events.length && this._state === "active") {
307
+ const event = this.events[this.eventIndex++];
308
+ for (const cb of this.eventCallbacks) cb(event);
309
+ }
310
+ }
311
+ /** Start delivering events automatically */
312
+ startDelivery() {
313
+ this.deliverPending();
314
+ }
315
+ };
316
+ /**
317
+ * Mock transport adapter for testing.
318
+ * Provides full control over responses and streams.
319
+ */
320
+ var MockTransportAdapter = class extends BaseTransportAdapter {
321
+ responses = /* @__PURE__ */ new Map();
322
+ streams = /* @__PURE__ */ new Map();
323
+ subscriptions = /* @__PURE__ */ new Map();
324
+ requests = [];
325
+ constructor(config = {}) {
326
+ super({
327
+ baseUrl: config.baseUrl ?? "http://mock",
328
+ headers: config.headers,
329
+ timeout: config.timeout,
330
+ heartbeatIntervalMs: config.heartbeatIntervalMs,
331
+ autoReconnect: config.autoReconnect,
332
+ reconnection: config.reconnection
333
+ });
334
+ if (config.autoConnect !== false) this.setState("connected");
335
+ }
336
+ async connect() {
337
+ this.setState("connecting");
338
+ this.setState("connected");
339
+ }
340
+ async disconnect() {
341
+ this.setState("disconnected");
342
+ for (const sub of this.subscriptions.values()) sub.close();
343
+ this.subscriptions.clear();
344
+ }
345
+ async request(options) {
346
+ const start = Date.now();
347
+ this.requests.push({
348
+ method: options.method ?? "GET",
349
+ path: options.path,
350
+ body: options.body,
351
+ headers: options.headers,
352
+ timestamp: start
353
+ });
354
+ const key = `${options.method ?? "GET"}:${options.path}`;
355
+ const mock = this.responses.get(key) ?? this.responses.get(options.path);
356
+ if (mock?.delay) await new Promise((r) => setTimeout(r, mock.delay));
357
+ const duration = Date.now() - start;
358
+ if (mock?.error) {
359
+ this.recordRequest(duration, true);
360
+ throw mock.error;
361
+ }
362
+ this.recordRequest(duration, false);
363
+ return mock?.data ?? {};
364
+ }
365
+ subscribe(options) {
366
+ const streamId = `mock_${Date.now()}_${Math.random().toString(36).slice(2)}`;
367
+ const subscription = new MockSubscription(streamId, this.streams.get(options.path) ?? []);
368
+ this.subscriptions.set(streamId, subscription);
369
+ queueMicrotask(() => subscription.startDelivery());
370
+ return subscription;
371
+ }
372
+ /** Mock a response for a specific path */
373
+ mockResponse(path, response) {
374
+ this.responses.set(path, response);
375
+ }
376
+ /** Mock a response for a specific method and path */
377
+ mockMethodResponse(method, path, response) {
378
+ this.responses.set(`${method}:${path}`, response);
379
+ }
380
+ /** Mock a stream with events */
381
+ mockStream(path, events) {
382
+ this.streams.set(path, events);
383
+ }
384
+ /** Get a subscription by stream ID */
385
+ getSubscription(streamId) {
386
+ return this.subscriptions.get(streamId);
387
+ }
388
+ /** Get all active subscriptions */
389
+ getActiveSubscriptions() {
390
+ return Array.from(this.subscriptions.values()).filter((s) => s.state !== "closed");
391
+ }
392
+ /** Push an event to all subscriptions for a path */
393
+ pushEventToPath(_path, event) {
394
+ for (const sub of this.subscriptions.values()) sub.pushEvent(event);
395
+ }
396
+ /** Clear all recorded requests */
397
+ clearRequests() {
398
+ this.requests.length = 0;
399
+ }
400
+ /** Clear all mocked responses */
401
+ clearMocks() {
402
+ this.responses.clear();
403
+ this.streams.clear();
404
+ }
405
+ /** Get requests matching a path pattern */
406
+ getRequestsForPath(path) {
407
+ return this.requests.filter((r) => r.path === path);
408
+ }
409
+ /** Get the last request made */
410
+ getLastRequest() {
411
+ return this.requests[this.requests.length - 1];
412
+ }
413
+ /** Simulate connection failure */
414
+ simulateDisconnect() {
415
+ this.setState("disconnected");
416
+ this.emit("error", /* @__PURE__ */ new Error("Simulated disconnect"));
417
+ }
418
+ /** Simulate reconnection */
419
+ simulateReconnect() {
420
+ this.setState("connected");
421
+ this.recordReconnection();
422
+ }
423
+ };
424
+ //#endregion
425
+ export { DEFAULT_RECONNECTION_CONFIG as i, BaseTransportAdapter as n, ConnectionManager as r, MockTransportAdapter as t };
426
+
427
+ //# sourceMappingURL=transport-mKLoQep5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport-mKLoQep5.js","names":[],"sources":["../src/transport/types.ts","../src/transport/connection-manager.ts","../src/transport/interface.ts","../src/transport/mock.ts"],"sourcesContent":["/**\n * Transport Types\n *\n * Core type definitions for the transport layer abstraction.\n */\n\n/** Connection lifecycle states */\nexport type ConnectionState =\n | \"disconnected\"\n | \"connecting\"\n | \"connected\"\n | \"reconnecting\"\n | \"failed\";\n\n/** Connection quality levels for monitoring */\nexport type ConnectionQuality = \"excellent\" | \"good\" | \"degraded\" | \"poor\";\n\n/**\n * Transport mode for event delivery.\n *\n * - 'websocket': WebSocket via SessionGatewayClient (default, traditional server)\n * - 'sse': HTTP SSE (serverless/Cloudflare Workers)\n */\nexport type TransportMode = \"websocket\" | \"sse\";\n\n/** SSE event from server */\nexport interface SSEEvent {\n id?: string;\n event?: string;\n data: string;\n retry?: number;\n}\n\n/** Request options for HTTP calls */\nexport interface RequestOptions {\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\";\n path: string;\n body?: unknown;\n headers?: Record<string, string>;\n signal?: AbortSignal;\n timeout?: number;\n}\n\n/** Stream subscription options */\nexport interface StreamOptions {\n /** HTTP method (default: GET, use POST for streaming endpoints that accept a body) */\n method?: \"GET\" | \"POST\";\n path: string;\n /** Request body (for POST requests) */\n body?: unknown;\n headers?: Record<string, string>;\n /** Last event ID for resumption */\n lastEventId?: string;\n /** Reconnection configuration */\n reconnect?: ReconnectionConfig;\n /** Abort signal */\n signal?: AbortSignal;\n}\n\n/** Reconnection configuration with exponential backoff */\nexport interface ReconnectionConfig {\n /** Initial delay in milliseconds (default: 1000) */\n initialDelayMs?: number;\n /** Maximum delay in milliseconds (default: 30000) */\n maxDelayMs?: number;\n /** Backoff multiplier (default: 1.5) */\n multiplier?: number;\n /** Jitter factor 0-1 (default: 0.2) */\n jitter?: number;\n /** Maximum reconnection attempts (default: 10, -1 for infinite) */\n maxAttempts?: number;\n}\n\n/** Default reconnection config */\nexport const DEFAULT_RECONNECTION_CONFIG: Required<ReconnectionConfig> = {\n initialDelayMs: 1000,\n maxDelayMs: 30000,\n multiplier: 1.5,\n jitter: 0.2,\n maxAttempts: 10,\n};\n\n/** Transport quality metrics */\nexport interface TransportMetrics {\n /** Total requests made */\n requestCount: number;\n /** Failed requests */\n failedRequests: number;\n /** Average latency in ms */\n avgLatencyMs: number;\n /** Current reconnection attempt (0 if connected) */\n reconnectionAttempt: number;\n /** Total reconnection attempts since start */\n totalReconnections: number;\n /** Missed heartbeats in current connection */\n missedHeartbeats: number;\n /** Last successful request timestamp */\n lastRequestAt?: number;\n /** Connection uptime in ms */\n uptimeMs: number;\n}\n\n/** Transport event types */\nexport interface TransportEvents {\n /** Connection state changed */\n stateChange: (state: ConnectionState) => void;\n /** Error occurred */\n error: (error: Error) => void;\n /** Reconnecting with attempt count */\n reconnecting: (attempt: number, maxAttempts: number) => void;\n /** Successfully reconnected */\n reconnected: () => void;\n /** Quality changed */\n qualityChange: (quality: ConnectionQuality) => void;\n /** Heartbeat received */\n heartbeat: (timestamp: number) => void;\n}\n\n/** Base transport configuration */\nexport interface TransportConfig {\n /** Base URL for requests */\n baseUrl: string;\n /** Default headers for all requests */\n headers?: Record<string, string>;\n /** Request timeout in ms (default: 30000) */\n timeout?: number;\n /** Heartbeat interval in ms for quality monitoring (default: 30000) */\n heartbeatIntervalMs?: number;\n /** Enable automatic reconnection (default: true) */\n autoReconnect?: boolean;\n /** Reconnection config */\n reconnection?: ReconnectionConfig;\n}\n\n/** Subscription state */\nexport type SubscriptionState = \"active\" | \"paused\" | \"closed\";\n","/**\n * Connection Manager\n *\n * Manages reconnection logic with exponential backoff and jitter.\n */\n\nimport {\n DEFAULT_RECONNECTION_CONFIG,\n type ReconnectionConfig,\n} from \"./types.js\";\n\nexport interface ConnectionManagerConfig extends ReconnectionConfig {\n onReconnecting?: (attempt: number, maxAttempts: number) => void;\n onReconnected?: () => void;\n onFailed?: (error: Error) => void;\n}\n\nexport class ConnectionManager {\n private readonly config: Required<ReconnectionConfig>;\n private attempt = 0;\n private aborted = false;\n private readonly callbacks: {\n onReconnecting?: (attempt: number, maxAttempts: number) => void;\n onReconnected?: () => void;\n onFailed?: (error: Error) => void;\n };\n\n constructor(config: ConnectionManagerConfig = {}) {\n this.config = {\n initialDelayMs:\n config.initialDelayMs ?? DEFAULT_RECONNECTION_CONFIG.initialDelayMs,\n maxDelayMs: config.maxDelayMs ?? DEFAULT_RECONNECTION_CONFIG.maxDelayMs,\n multiplier: config.multiplier ?? DEFAULT_RECONNECTION_CONFIG.multiplier,\n jitter: config.jitter ?? DEFAULT_RECONNECTION_CONFIG.jitter,\n maxAttempts:\n config.maxAttempts ?? DEFAULT_RECONNECTION_CONFIG.maxAttempts,\n };\n this.callbacks = {\n onReconnecting: config.onReconnecting,\n onReconnected: config.onReconnected,\n onFailed: config.onFailed,\n };\n }\n\n /**\n * Calculate delay for current attempt with exponential backoff and jitter.\n */\n private calculateDelay(): number {\n const exponentialDelay =\n this.config.initialDelayMs * this.config.multiplier ** (this.attempt - 1);\n const cappedDelay = Math.min(exponentialDelay, this.config.maxDelayMs);\n const jitterRange = cappedDelay * this.config.jitter;\n const jitter = (Math.random() - 0.5) * 2 * jitterRange;\n return Math.max(0, cappedDelay + jitter);\n }\n\n /**\n * Wait for the calculated delay.\n */\n private async wait(): Promise<void> {\n const delay = this.calculateDelay();\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n\n /**\n * Check if more reconnection attempts are allowed.\n */\n canRetry(): boolean {\n if (this.aborted) return false;\n if (this.config.maxAttempts === -1) return true;\n return this.attempt < this.config.maxAttempts;\n }\n\n /**\n * Get current attempt number.\n */\n getAttempt(): number {\n return this.attempt;\n }\n\n /**\n * Reset the connection manager state.\n */\n reset(): void {\n this.attempt = 0;\n this.aborted = false;\n }\n\n /**\n * Abort any pending reconnection attempts.\n */\n abort(): void {\n this.aborted = true;\n }\n\n /**\n * Execute a reconnection attempt with the provided connect function.\n * Returns true if connection succeeded, false if should retry.\n */\n async reconnect(connectFn: () => Promise<void>): Promise<boolean> {\n if (!this.canRetry()) {\n const error = new Error(\n `Max reconnection attempts (${this.config.maxAttempts}) exceeded`,\n );\n this.callbacks.onFailed?.(error);\n return false;\n }\n\n this.attempt++;\n this.callbacks.onReconnecting?.(this.attempt, this.config.maxAttempts);\n\n await this.wait();\n\n if (this.aborted) {\n return false;\n }\n\n try {\n await connectFn();\n this.callbacks.onReconnected?.();\n this.reset();\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Run reconnection loop until success or max attempts.\n */\n async runReconnectionLoop(connectFn: () => Promise<void>): Promise<boolean> {\n while (this.canRetry()) {\n const success = await this.reconnect(connectFn);\n if (success) {\n return true;\n }\n }\n return false;\n }\n}\n","/**\n * Transport Adapter Interface\n *\n * The central abstraction for all transport implementations.\n * Provides HTTP requests and SSE stream subscriptions through a common API.\n */\n\nimport type {\n ConnectionQuality,\n ConnectionState,\n RequestOptions,\n SSEEvent,\n StreamOptions,\n SubscriptionState,\n TransportConfig,\n TransportEvents,\n TransportMetrics,\n} from \"./types.js\";\n\n/**\n * SSE Subscription handle for consuming server-sent events.\n * Supports pause/resume, async iteration, and event callbacks.\n */\nexport interface Subscription {\n /** Unique identifier for this subscription */\n readonly streamId: string;\n\n /** Current subscription state */\n readonly state: SubscriptionState;\n\n /** Pause event processing (events may still be buffered) */\n pause(): void;\n\n /** Resume event processing */\n resume(): void;\n\n /** Close the subscription and release resources */\n close(): void;\n\n /** Register callback for each event */\n onEvent(callback: (event: SSEEvent) => void): () => void;\n\n /** Register callback for errors */\n onError(callback: (error: Error) => void): () => void;\n\n /** Register callback for reconnection attempts */\n onReconnect(callback: (lastEventId: string | undefined) => void): () => void;\n\n /** Async iterator for event consumption */\n [Symbol.asyncIterator](): AsyncIterator<SSEEvent>;\n}\n\n/**\n * Transport Adapter - core abstraction for network communication.\n *\n * Implementations provide HTTP request/response and SSE streaming\n * with connection management, reconnection, and quality monitoring.\n */\nexport interface TransportAdapter {\n /** Current connection state */\n readonly state: ConnectionState;\n\n /** Connect to the server */\n connect(): Promise<void>;\n\n /** Disconnect from the server */\n disconnect(): Promise<void>;\n\n /** Check if currently connected */\n isConnected(): boolean;\n\n /**\n * Make an HTTP request.\n * Routes through the transport layer for connection management.\n */\n request<T>(options: RequestOptions): Promise<T>;\n\n /**\n * Subscribe to an SSE stream.\n * Handles reconnection and Last-Event-ID resumption.\n */\n subscribe(options: StreamOptions): Subscription;\n\n /** Register event listener, returns unsubscribe function */\n on<K extends keyof TransportEvents>(\n event: K,\n listener: TransportEvents[K],\n ): () => void;\n\n /** Get current transport metrics */\n getMetrics(): TransportMetrics;\n\n /** Get current connection quality */\n getQuality(): ConnectionQuality;\n}\n\n/**\n * Base class for transport adapters with shared functionality.\n * Handles event emission, metrics tracking, and connection state.\n */\nexport abstract class BaseTransportAdapter implements TransportAdapter {\n protected _state: ConnectionState = \"disconnected\";\n protected _quality: ConnectionQuality = \"excellent\";\n protected readonly config: Required<TransportConfig>;\n protected readonly listeners: Map<\n keyof TransportEvents,\n Set<(...args: never[]) => unknown>\n > = new Map();\n protected metrics: TransportMetrics = {\n requestCount: 0,\n failedRequests: 0,\n avgLatencyMs: 0,\n reconnectionAttempt: 0,\n totalReconnections: 0,\n missedHeartbeats: 0,\n uptimeMs: 0,\n };\n protected connectionStartTime?: number;\n private latencySum = 0;\n\n constructor(config: TransportConfig) {\n this.config = {\n baseUrl: config.baseUrl.replace(/\\/$/, \"\"),\n headers: config.headers ?? {},\n timeout: config.timeout ?? 30000,\n heartbeatIntervalMs: config.heartbeatIntervalMs ?? 30000,\n autoReconnect: config.autoReconnect ?? true,\n reconnection: {\n initialDelayMs: config.reconnection?.initialDelayMs ?? 1000,\n maxDelayMs: config.reconnection?.maxDelayMs ?? 30000,\n multiplier: config.reconnection?.multiplier ?? 1.5,\n jitter: config.reconnection?.jitter ?? 0.2,\n maxAttempts: config.reconnection?.maxAttempts ?? 10,\n },\n };\n }\n\n get state(): ConnectionState {\n return this._state;\n }\n\n abstract connect(): Promise<void>;\n abstract disconnect(): Promise<void>;\n abstract request<T>(options: RequestOptions): Promise<T>;\n abstract subscribe(options: StreamOptions): Subscription;\n\n isConnected(): boolean {\n return this._state === \"connected\";\n }\n\n on<K extends keyof TransportEvents>(\n event: K,\n listener: TransportEvents[K],\n ): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)?.add(listener);\n return () => this.listeners.get(event)?.delete(listener);\n }\n\n getMetrics(): TransportMetrics {\n return {\n ...this.metrics,\n uptimeMs: this.connectionStartTime\n ? Date.now() - this.connectionStartTime\n : 0,\n };\n }\n\n getQuality(): ConnectionQuality {\n return this._quality;\n }\n\n protected emit<K extends keyof TransportEvents>(\n event: K,\n ...args: Parameters<TransportEvents[K]>\n ): void {\n const listeners = this.listeners.get(event);\n if (listeners) {\n for (const listener of listeners) {\n try {\n (listener as (...args: unknown[]) => void)(...args);\n } catch (e) {\n console.error(`Error in ${event} listener:`, e);\n }\n }\n }\n }\n\n protected setState(state: ConnectionState): void {\n if (this._state !== state) {\n this._state = state;\n if (state === \"connected\") {\n this.connectionStartTime = Date.now();\n this.metrics.reconnectionAttempt = 0;\n }\n this.emit(\"stateChange\", state);\n }\n }\n\n protected setQuality(quality: ConnectionQuality): void {\n if (this._quality !== quality) {\n this._quality = quality;\n this.emit(\"qualityChange\", quality);\n }\n }\n\n protected recordRequest(durationMs: number, failed: boolean): void {\n this.metrics.requestCount++;\n if (failed) {\n this.metrics.failedRequests++;\n }\n this.latencySum += durationMs;\n this.metrics.avgLatencyMs = this.latencySum / this.metrics.requestCount;\n this.metrics.lastRequestAt = Date.now();\n this.updateQuality();\n }\n\n protected recordReconnection(): void {\n this.metrics.totalReconnections++;\n this.emit(\"reconnected\");\n }\n\n protected recordMissedHeartbeat(): void {\n this.metrics.missedHeartbeats++;\n this.updateQuality();\n }\n\n protected resetHeartbeatCounter(): void {\n this.metrics.missedHeartbeats = 0;\n this.updateQuality();\n }\n\n private updateQuality(): void {\n const failRate =\n this.metrics.requestCount > 0\n ? this.metrics.failedRequests / this.metrics.requestCount\n : 0;\n\n let quality: ConnectionQuality;\n if (\n this.metrics.missedHeartbeats >= 3 ||\n failRate > 0.5 ||\n this.metrics.avgLatencyMs > 5000\n ) {\n quality = \"poor\";\n } else if (\n this.metrics.missedHeartbeats >= 2 ||\n failRate > 0.2 ||\n this.metrics.avgLatencyMs > 2000\n ) {\n quality = \"degraded\";\n } else if (\n this.metrics.missedHeartbeats >= 1 ||\n failRate > 0.1 ||\n this.metrics.avgLatencyMs > 1000\n ) {\n quality = \"good\";\n } else {\n quality = \"excellent\";\n }\n\n this.setQuality(quality);\n }\n\n protected buildUrl(path: string): string {\n const cleanPath = path.startsWith(\"/\") ? path : `/${path}`;\n return `${this.config.baseUrl}${cleanPath}`;\n }\n\n protected buildHeaders(\n extra?: Record<string, string>,\n ): Record<string, string> {\n return {\n ...this.config.headers,\n ...extra,\n };\n }\n}\n","/**\n * Mock Transport Adapter\n *\n * A fully controllable transport adapter for testing.\n * Allows mocking responses, simulating streams, and verifying requests.\n */\n\nimport { BaseTransportAdapter, type Subscription } from \"./interface.js\";\nimport type {\n RequestOptions,\n SSEEvent,\n StreamOptions,\n SubscriptionState,\n TransportConfig,\n} from \"./types.js\";\n\n/** Recorded request for verification */\nexport interface RecordedRequest {\n method: string;\n path: string;\n body?: unknown;\n headers?: Record<string, string>;\n timestamp: number;\n}\n\n/** Mock response configuration */\nexport interface MockResponse<T = unknown> {\n status?: number;\n data?: T;\n error?: Error;\n delay?: number;\n}\n\n/** Mock stream event */\nexport interface MockStreamEvent {\n event?: string;\n data: string;\n id?: string;\n delay?: number;\n}\n\n/** Mock subscription for testing */\nclass MockSubscription implements Subscription {\n readonly streamId: string;\n private _state: SubscriptionState = \"active\";\n private eventCallbacks: Set<(event: SSEEvent) => void> = new Set();\n private errorCallbacks: Set<(error: Error) => void> = new Set();\n private reconnectCallbacks: Set<(lastEventId: string | undefined) => void> =\n new Set();\n private events: SSEEvent[] = [];\n private eventIndex = 0;\n private closed = false;\n\n constructor(streamId: string, events: MockStreamEvent[] = []) {\n this.streamId = streamId;\n this.events = events.map((e, i) => ({\n id: e.id ?? `mock_${i}`,\n event: e.event,\n data: e.data,\n }));\n }\n\n get state(): SubscriptionState {\n return this._state;\n }\n\n pause(): void {\n if (this._state === \"active\") {\n this._state = \"paused\";\n }\n }\n\n resume(): void {\n if (this._state === \"paused\") {\n this._state = \"active\";\n this.deliverPending();\n }\n }\n\n close(): void {\n this._state = \"closed\";\n this.closed = true;\n }\n\n onEvent(callback: (event: SSEEvent) => void): () => void {\n this.eventCallbacks.add(callback);\n return () => this.eventCallbacks.delete(callback);\n }\n\n onError(callback: (error: Error) => void): () => void {\n this.errorCallbacks.add(callback);\n return () => this.errorCallbacks.delete(callback);\n }\n\n onReconnect(callback: (lastEventId: string | undefined) => void): () => void {\n this.reconnectCallbacks.add(callback);\n return () => this.reconnectCallbacks.delete(callback);\n }\n\n async *[Symbol.asyncIterator](): AsyncIterator<SSEEvent> {\n while (!this.closed) {\n if (this.eventIndex < this.events.length) {\n if (this._state === \"active\") {\n yield this.events[this.eventIndex++];\n } else {\n await new Promise((r) => setTimeout(r, 10));\n }\n } else {\n await new Promise((r) => setTimeout(r, 10));\n }\n }\n }\n\n /** Push a new event to the stream (for testing) */\n pushEvent(event: SSEEvent): void {\n this.events.push(event);\n if (this._state === \"active\") {\n this.deliverPending();\n }\n }\n\n /** Simulate an error (for testing) */\n simulateError(error: Error): void {\n for (const cb of this.errorCallbacks) {\n cb(error);\n }\n }\n\n /** Simulate reconnection (for testing) */\n simulateReconnect(lastEventId?: string): void {\n for (const cb of this.reconnectCallbacks) {\n cb(lastEventId);\n }\n }\n\n private deliverPending(): void {\n while (this.eventIndex < this.events.length && this._state === \"active\") {\n const event = this.events[this.eventIndex++];\n for (const cb of this.eventCallbacks) {\n cb(event);\n }\n }\n }\n\n /** Start delivering events automatically */\n startDelivery(): void {\n this.deliverPending();\n }\n}\n\n/** Configuration for MockTransportAdapter */\nexport interface MockTransportConfig extends Partial<TransportConfig> {\n /** Auto-connect on creation (default: true) */\n autoConnect?: boolean;\n}\n\n/**\n * Mock transport adapter for testing.\n * Provides full control over responses and streams.\n */\nexport class MockTransportAdapter extends BaseTransportAdapter {\n private readonly responses = new Map<string, MockResponse>();\n private readonly streams = new Map<string, MockStreamEvent[]>();\n private readonly subscriptions = new Map<string, MockSubscription>();\n readonly requests: RecordedRequest[] = [];\n\n constructor(config: MockTransportConfig = {}) {\n super({\n baseUrl: config.baseUrl ?? \"http://mock\",\n headers: config.headers,\n timeout: config.timeout,\n heartbeatIntervalMs: config.heartbeatIntervalMs,\n autoReconnect: config.autoReconnect,\n reconnection: config.reconnection,\n });\n\n if (config.autoConnect !== false) {\n this.setState(\"connected\");\n }\n }\n\n async connect(): Promise<void> {\n this.setState(\"connecting\");\n this.setState(\"connected\");\n }\n\n async disconnect(): Promise<void> {\n this.setState(\"disconnected\");\n for (const sub of this.subscriptions.values()) {\n sub.close();\n }\n this.subscriptions.clear();\n }\n\n async request<T>(options: RequestOptions): Promise<T> {\n const start = Date.now();\n\n this.requests.push({\n method: options.method ?? \"GET\",\n path: options.path,\n body: options.body,\n headers: options.headers,\n timestamp: start,\n });\n\n const key = `${options.method ?? \"GET\"}:${options.path}`;\n const mock = this.responses.get(key) ?? this.responses.get(options.path);\n\n if (mock?.delay) {\n await new Promise((r) => setTimeout(r, mock.delay));\n }\n\n const duration = Date.now() - start;\n\n if (mock?.error) {\n this.recordRequest(duration, true);\n throw mock.error;\n }\n\n this.recordRequest(duration, false);\n return (mock?.data ?? {}) as T;\n }\n\n subscribe(options: StreamOptions): Subscription {\n const streamId = `mock_${Date.now()}_${Math.random().toString(36).slice(2)}`;\n const events = this.streams.get(options.path) ?? [];\n const subscription = new MockSubscription(streamId, events);\n this.subscriptions.set(streamId, subscription);\n\n // Start delivering events after a microtask\n queueMicrotask(() => subscription.startDelivery());\n\n return subscription;\n }\n\n // ========== Test Helpers ==========\n\n /** Mock a response for a specific path */\n mockResponse<T>(path: string, response: MockResponse<T>): void {\n this.responses.set(path, response);\n }\n\n /** Mock a response for a specific method and path */\n mockMethodResponse<T>(\n method: string,\n path: string,\n response: MockResponse<T>,\n ): void {\n this.responses.set(`${method}:${path}`, response);\n }\n\n /** Mock a stream with events */\n mockStream(path: string, events: MockStreamEvent[]): void {\n this.streams.set(path, events);\n }\n\n /** Get a subscription by stream ID */\n getSubscription(streamId: string): MockSubscription | undefined {\n return this.subscriptions.get(streamId);\n }\n\n /** Get all active subscriptions */\n getActiveSubscriptions(): MockSubscription[] {\n return Array.from(this.subscriptions.values()).filter(\n (s) => s.state !== \"closed\",\n );\n }\n\n /** Push an event to all subscriptions for a path */\n pushEventToPath(_path: string, event: SSEEvent): void {\n for (const sub of this.subscriptions.values()) {\n sub.pushEvent(event);\n }\n }\n\n /** Clear all recorded requests */\n clearRequests(): void {\n this.requests.length = 0;\n }\n\n /** Clear all mocked responses */\n clearMocks(): void {\n this.responses.clear();\n this.streams.clear();\n }\n\n /** Get requests matching a path pattern */\n getRequestsForPath(path: string): RecordedRequest[] {\n return this.requests.filter((r) => r.path === path);\n }\n\n /** Get the last request made */\n getLastRequest(): RecordedRequest | undefined {\n return this.requests[this.requests.length - 1];\n }\n\n /** Simulate connection failure */\n simulateDisconnect(): void {\n this.setState(\"disconnected\");\n this.emit(\"error\", new Error(\"Simulated disconnect\"));\n }\n\n /** Simulate reconnection */\n simulateReconnect(): void {\n this.setState(\"connected\");\n this.recordReconnection();\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { A as ToolStateCompleted, C as TerminalDataEvent, D as TextPart, E as TerminalResizeEvent, F as isReasoningPart, I as isSubtaskPart, L as isTextPart, M as ToolStatePending, N as ToolStateRunning, O as ToolPart, P as isFilePart, R as isToolPart, S as SubtaskPart, T as TerminalExitEvent, _ as ReplayEndEvent, a as DoneEvent, b as SessionUpdatedEvent, c as ExecutionCompletedEvent, d as FilePart, f as HeartbeatEvent, g as ReasoningPart, h as PartBase, i as ConnectionInitEvent, j as ToolStateError, k as ToolState, l as ExecutionFailedEvent, m as Part, n as AgentEventType, o as ErrorEvent, p as MessagePartUpdatedEvent, r as AgentEventTypeSchema, s as EventMetadata, t as AgentEvent, u as ExecutionStartedEvent, v as ReplayStartEvent, w as TerminalEvent, x as StatusEvent, y as ResultEvent } from "../index-z2wPdzFb.js";
2
+ export { AgentEvent, AgentEventType, AgentEventTypeSchema, ConnectionInitEvent, DoneEvent, ErrorEvent, EventMetadata, ExecutionCompletedEvent, ExecutionFailedEvent, ExecutionStartedEvent, FilePart, HeartbeatEvent, MessagePartUpdatedEvent, Part, PartBase, ReasoningPart, ReplayEndEvent, ReplayStartEvent, ResultEvent, SessionUpdatedEvent, StatusEvent, SubtaskPart, TerminalDataEvent, TerminalEvent, TerminalExitEvent, TerminalResizeEvent, TextPart, ToolPart, ToolState, ToolStateCompleted, ToolStateError, ToolStatePending, ToolStateRunning, isFilePart, isReasoningPart, isSubtaskPart, isTextPart, isToolPart };
@@ -0,0 +1,2 @@
1
+ import { a as isTextPart, i as isSubtaskPart, n as isFilePart, o as isToolPart, r as isReasoningPart, t as AgentEventTypeSchema } from "../types-D5VLaol0.js";
2
+ export { AgentEventTypeSchema, isFilePart, isReasoningPart, isSubtaskPart, isTextPart, isToolPart };
@@ -0,0 +1,31 @@
1
+ import { z } from "zod";
2
+ import { isFilePart, isReasoningPart, isSubtaskPart, isTextPart, isToolPart } from "@tangle-network/agent-interface";
3
+ //#region src/types/events.ts
4
+ /**
5
+ * Shared Event Types
6
+ *
7
+ * Type definitions for events across the SDK.
8
+ * Uses message.part.updated as the single canonical event for all content.
9
+ *
10
+ * Part types (TextPart, ToolPart, ReasoningPart, FilePart, ToolState)
11
+ * are re-exported from @tangle-network/agent-interface for consistency.
12
+ */
13
+ const AgentEventTypeSchema = z.enum([
14
+ "message.part.updated",
15
+ "status",
16
+ "error",
17
+ "heartbeat",
18
+ "connection.init",
19
+ "history.replay.start",
20
+ "history.replay.end",
21
+ "execution.started",
22
+ "execution.completed",
23
+ "execution.failed",
24
+ "session.updated",
25
+ "result",
26
+ "done"
27
+ ]);
28
+ //#endregion
29
+ export { isTextPart as a, isSubtaskPart as i, isFilePart as n, isToolPart as o, isReasoningPart as r, AgentEventTypeSchema as t };
30
+
31
+ //# sourceMappingURL=types-D5VLaol0.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-D5VLaol0.js","names":[],"sources":["../src/types/events.ts"],"sourcesContent":["/**\n * Shared Event Types\n *\n * Type definitions for events across the SDK.\n * Uses message.part.updated as the single canonical event for all content.\n *\n * Part types (TextPart, ToolPart, ReasoningPart, FilePart, ToolState)\n * are re-exported from @tangle-network/agent-interface for consistency.\n */\n\nimport { z } from \"zod\";\n\n// Re-export canonical Part types from agent-interface\nexport type {\n FilePart,\n Part,\n PartBase,\n ReasoningPart,\n SubtaskPart,\n TextPart,\n ToolPart,\n ToolState,\n ToolStateCompleted,\n ToolStateError,\n ToolStatePending,\n ToolStateRunning,\n} from \"@tangle-network/agent-interface\";\n\n// Re-export part type guards\nexport {\n isFilePart,\n isReasoningPart,\n isSubtaskPart,\n isTextPart,\n isToolPart,\n} from \"@tangle-network/agent-interface\";\n\n// Agent event types - message.part.updated is the primary content event\nexport const AgentEventTypeSchema = z.enum([\n \"message.part.updated\",\n \"status\",\n \"error\",\n \"heartbeat\",\n \"connection.init\",\n \"history.replay.start\",\n \"history.replay.end\",\n \"execution.started\",\n \"execution.completed\",\n \"execution.failed\",\n \"session.updated\",\n \"result\",\n \"done\",\n]);\n\nexport type AgentEventType = z.infer<typeof AgentEventTypeSchema>;\n\n// Base event metadata (agent-core specific - adds sequence tracking)\nexport interface EventMetadata {\n serverInstanceId: string;\n seq: number;\n prevSeq: number | null;\n sentAt: number;\n}\n\n// Import Part type for use in events\nimport type { Part } from \"@tangle-network/agent-interface\";\n\n// The primary content event - all text, tool, and reasoning updates\nexport interface MessagePartUpdatedEvent {\n type: \"message.part.updated\";\n part: Part;\n delta?: string; // Incremental text change for streaming\n _meta?: EventMetadata;\n}\n\n// Status event\nexport interface StatusEvent {\n type: \"status\";\n status: \"started\" | \"processing\" | \"completed\" | \"failed\";\n detail?: string;\n _meta?: EventMetadata;\n}\n\n// Error event\nexport interface ErrorEvent {\n type: \"error\";\n code?: string;\n message: string;\n details?: unknown;\n _meta?: EventMetadata;\n}\n\n// Heartbeat event\nexport interface HeartbeatEvent {\n type: \"heartbeat\";\n timestamp?: number;\n _meta?: EventMetadata;\n}\n\n// Connection events\nexport interface ConnectionInitEvent {\n type: \"connection.init\";\n serverInstanceId?: string;\n streamId?: string;\n initialSeq?: number;\n timestamp?: number;\n _meta?: EventMetadata;\n}\n\n// Replay events\nexport interface ReplayStartEvent {\n type: \"history.replay.start\";\n executionId?: string;\n sessionId?: string;\n totalEvents?: number;\n status?: string;\n}\n\nexport interface ReplayEndEvent {\n type: \"history.replay.end\";\n executionId?: string;\n totalEventsReplayed?: number;\n status?: string;\n continuing?: boolean;\n}\n\n// Execution lifecycle events\nexport interface ExecutionStartedEvent {\n type: \"execution.started\";\n executionId?: string;\n sessionId?: string;\n timestamp?: number;\n}\n\nexport interface ExecutionCompletedEvent {\n type: \"execution.completed\";\n executionId?: string;\n sessionId?: string;\n timestamp?: number;\n}\n\nexport interface ExecutionFailedEvent {\n type: \"execution.failed\";\n executionId?: string;\n sessionId?: string;\n error?: string;\n timestamp?: number;\n}\n\n// Session update event\nexport interface SessionUpdatedEvent {\n type: \"session.updated\";\n sessionId: string;\n title?: string;\n time?: { created?: number; updated?: number };\n}\n\n// Result event (final response)\nexport interface ResultEvent {\n type: \"result\";\n finalText?: string;\n toolInvocations?: unknown[];\n tokenUsage?: Record<string, unknown>;\n timing?: Record<string, unknown>;\n metadata?: Record<string, unknown>;\n}\n\n// Done event (stream complete)\nexport interface DoneEvent {\n type: \"done\";\n requestId?: string;\n}\n\n// Union of all agent events\nexport type AgentEvent =\n | MessagePartUpdatedEvent\n | StatusEvent\n | ErrorEvent\n | HeartbeatEvent\n | ConnectionInitEvent\n | ReplayStartEvent\n | ReplayEndEvent\n | ExecutionStartedEvent\n | ExecutionCompletedEvent\n | ExecutionFailedEvent\n | SessionUpdatedEvent\n | ResultEvent\n | DoneEvent;\n\n// Terminal event types\nexport interface TerminalDataEvent {\n type: \"terminal.data\";\n data: string;\n terminalId: string;\n}\n\nexport interface TerminalResizeEvent {\n type: \"terminal.resize\";\n cols: number;\n rows: number;\n terminalId: string;\n}\n\nexport interface TerminalExitEvent {\n type: \"terminal.exit\";\n exitCode: number;\n terminalId: string;\n}\n\nexport type TerminalEvent =\n | TerminalDataEvent\n | TerminalResizeEvent\n | TerminalExitEvent;\n"],"mappings":";;;;;;;;;;;;AAsCA,MAAa,uBAAuB,EAAE,KAAK;CACzC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC"}