autotel-cloudflare 2.1.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 (74) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +432 -0
  3. package/dist/actors.d.ts +248 -0
  4. package/dist/actors.js +1030 -0
  5. package/dist/actors.js.map +1 -0
  6. package/dist/agents.d.ts +219 -0
  7. package/dist/agents.js +276 -0
  8. package/dist/agents.js.map +1 -0
  9. package/dist/bindings.d.ts +40 -0
  10. package/dist/bindings.js +4 -0
  11. package/dist/bindings.js.map +1 -0
  12. package/dist/chunk-JDPN3HND.js +520 -0
  13. package/dist/chunk-JDPN3HND.js.map +1 -0
  14. package/dist/chunk-QXFYTHQF.js +298 -0
  15. package/dist/chunk-QXFYTHQF.js.map +1 -0
  16. package/dist/chunk-SKKRPS5K.js +50 -0
  17. package/dist/chunk-SKKRPS5K.js.map +1 -0
  18. package/dist/events.d.ts +1 -0
  19. package/dist/events.js +3 -0
  20. package/dist/events.js.map +1 -0
  21. package/dist/handlers.d.ts +121 -0
  22. package/dist/handlers.js +4 -0
  23. package/dist/handlers.js.map +1 -0
  24. package/dist/index.d.ts +144 -0
  25. package/dist/index.js +576 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/logger.d.ts +1 -0
  28. package/dist/logger.js +3 -0
  29. package/dist/logger.js.map +1 -0
  30. package/dist/sampling.d.ts +4 -0
  31. package/dist/sampling.js +3 -0
  32. package/dist/sampling.js.map +1 -0
  33. package/dist/testing.d.ts +1 -0
  34. package/dist/testing.js +3 -0
  35. package/dist/testing.js.map +1 -0
  36. package/package.json +107 -0
  37. package/src/actors/alarms.ts +225 -0
  38. package/src/actors/index.ts +36 -0
  39. package/src/actors/instrument-actor.test.ts +179 -0
  40. package/src/actors/instrument-actor.ts +574 -0
  41. package/src/actors/sockets.ts +217 -0
  42. package/src/actors/storage.ts +263 -0
  43. package/src/actors/traced-handler.ts +300 -0
  44. package/src/actors/types.ts +98 -0
  45. package/src/actors.ts +50 -0
  46. package/src/agents/index.ts +42 -0
  47. package/src/agents/otel-observability.test.ts +329 -0
  48. package/src/agents/otel-observability.ts +465 -0
  49. package/src/agents/types.ts +167 -0
  50. package/src/agents.ts +76 -0
  51. package/src/bindings/bindings.ts +621 -0
  52. package/src/bindings/common.ts +75 -0
  53. package/src/bindings/index.ts +12 -0
  54. package/src/bindings.ts +6 -0
  55. package/src/events.ts +6 -0
  56. package/src/global/cache.test.ts +292 -0
  57. package/src/global/cache.ts +164 -0
  58. package/src/global/fetch.test.ts +344 -0
  59. package/src/global/fetch.ts +134 -0
  60. package/src/global/index.ts +7 -0
  61. package/src/handlers/durable-objects.test.ts +524 -0
  62. package/src/handlers/durable-objects.ts +250 -0
  63. package/src/handlers/index.ts +6 -0
  64. package/src/handlers/workflows.ts +318 -0
  65. package/src/handlers.ts +6 -0
  66. package/src/index.ts +57 -0
  67. package/src/logger.ts +6 -0
  68. package/src/sampling.ts +6 -0
  69. package/src/testing.ts +6 -0
  70. package/src/wrappers/index.ts +8 -0
  71. package/src/wrappers/instrument.integration.test.ts +468 -0
  72. package/src/wrappers/instrument.ts +643 -0
  73. package/src/wrappers/wrap-do.ts +34 -0
  74. package/src/wrappers/wrap-module.ts +37 -0
@@ -0,0 +1,329 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import {
3
+ createOtelObservability,
4
+ createOtelObservabilityFromEnv,
5
+ OtelObservability,
6
+ } from './otel-observability';
7
+ import type { AgentObservabilityEvent, MCPObservabilityEvent } from './types';
8
+
9
+ // Helper to create mock events
10
+ function createRpcEvent(method: string, streaming = false): AgentObservabilityEvent {
11
+ return {
12
+ type: 'rpc',
13
+ id: `rpc-${Date.now()}`,
14
+ displayMessage: `RPC call: ${method}`,
15
+ payload: { method, streaming },
16
+ timestamp: Date.now(),
17
+ };
18
+ }
19
+
20
+ function createConnectEvent(connectionId: string): AgentObservabilityEvent {
21
+ return {
22
+ type: 'connect',
23
+ id: `connect-${Date.now()}`,
24
+ displayMessage: `Connection: ${connectionId}`,
25
+ payload: { connectionId },
26
+ timestamp: Date.now(),
27
+ };
28
+ }
29
+
30
+ function createScheduleEvent(
31
+ eventType: 'schedule:create' | 'schedule:execute' | 'schedule:cancel',
32
+ callback: string,
33
+ id: string,
34
+ ): AgentObservabilityEvent {
35
+ return {
36
+ type: eventType,
37
+ id: `schedule-${Date.now()}`,
38
+ displayMessage: `Schedule ${eventType}: ${callback}`,
39
+ payload: { callback, id },
40
+ timestamp: Date.now(),
41
+ };
42
+ }
43
+
44
+ function createMcpConnectEvent(
45
+ url: string,
46
+ transport: string,
47
+ state: string,
48
+ ): MCPObservabilityEvent {
49
+ return {
50
+ type: 'mcp:client:connect',
51
+ id: `mcp-${Date.now()}`,
52
+ displayMessage: `MCP connect: ${url}`,
53
+ payload: { url, transport, state },
54
+ timestamp: Date.now(),
55
+ };
56
+ }
57
+
58
+ describe('OtelObservability', () => {
59
+ beforeEach(() => {
60
+ vi.clearAllMocks();
61
+ });
62
+
63
+ describe('createOtelObservability', () => {
64
+ it('should create an OtelObservability instance', () => {
65
+ const obs = createOtelObservability({
66
+ service: { name: 'test-agent' },
67
+ exporter: { url: 'http://localhost:4318/v1/traces' },
68
+ });
69
+
70
+ expect(obs).toBeInstanceOf(OtelObservability);
71
+ });
72
+
73
+ it('should accept custom agent options', () => {
74
+ const obs = createOtelObservability({
75
+ service: { name: 'test-agent' },
76
+ exporter: { url: 'http://localhost:4318/v1/traces' },
77
+ agents: {
78
+ traceRpc: true,
79
+ traceSchedule: false,
80
+ traceMcp: true,
81
+ },
82
+ });
83
+
84
+ expect(obs).toBeInstanceOf(OtelObservability);
85
+ });
86
+ });
87
+
88
+ describe('createOtelObservabilityFromEnv', () => {
89
+ it('should create instance from environment variables', () => {
90
+ const env = {
91
+ OTEL_SERVICE_NAME: 'my-agent',
92
+ OTEL_EXPORTER_OTLP_ENDPOINT: 'https://api.honeycomb.io',
93
+ OTEL_EXPORTER_OTLP_HEADERS: 'x-honeycomb-team=test-key',
94
+ };
95
+
96
+ const obs = createOtelObservabilityFromEnv(env);
97
+
98
+ expect(obs).toBeInstanceOf(OtelObservability);
99
+ });
100
+
101
+ it('should use defaults when env vars not set', () => {
102
+ const obs = createOtelObservabilityFromEnv({});
103
+
104
+ expect(obs).toBeInstanceOf(OtelObservability);
105
+ });
106
+
107
+ it('should parse multiple headers', () => {
108
+ const env = {
109
+ OTEL_EXPORTER_OTLP_HEADERS: 'key1=value1,key2=value2,key3=value3',
110
+ };
111
+
112
+ const obs = createOtelObservabilityFromEnv(env);
113
+
114
+ expect(obs).toBeInstanceOf(OtelObservability);
115
+ });
116
+ });
117
+
118
+ describe('emit', () => {
119
+ it('should emit RPC events', () => {
120
+ const obs = createOtelObservability({
121
+ service: { name: 'test-agent' },
122
+ exporter: { url: 'http://localhost:4318/v1/traces' },
123
+ });
124
+
125
+ const event = createRpcEvent('doSomething', false);
126
+
127
+ // Should not throw
128
+ expect(() => obs.emit(event)).not.toThrow();
129
+ });
130
+
131
+ it('should emit connect events', () => {
132
+ const obs = createOtelObservability({
133
+ service: { name: 'test-agent' },
134
+ exporter: { url: 'http://localhost:4318/v1/traces' },
135
+ });
136
+
137
+ const event = createConnectEvent('conn-123');
138
+
139
+ expect(() => obs.emit(event)).not.toThrow();
140
+ });
141
+
142
+ it('should emit schedule events', () => {
143
+ const obs = createOtelObservability({
144
+ service: { name: 'test-agent' },
145
+ exporter: { url: 'http://localhost:4318/v1/traces' },
146
+ });
147
+
148
+ const event = createScheduleEvent('schedule:create', 'myCallback', 'schedule-123');
149
+
150
+ expect(() => obs.emit(event)).not.toThrow();
151
+ });
152
+
153
+ it('should emit MCP events', () => {
154
+ const obs = createOtelObservability({
155
+ service: { name: 'test-agent' },
156
+ exporter: { url: 'http://localhost:4318/v1/traces' },
157
+ });
158
+
159
+ const event = createMcpConnectEvent('http://mcp-server.local', 'stdio', 'connected');
160
+
161
+ expect(() => obs.emit(event)).not.toThrow();
162
+ });
163
+
164
+ it('should respect traceStateUpdates option', () => {
165
+ const obs = createOtelObservability({
166
+ service: { name: 'test-agent' },
167
+ exporter: { url: 'http://localhost:4318/v1/traces' },
168
+ agents: {
169
+ traceStateUpdates: false,
170
+ },
171
+ });
172
+
173
+ const event: AgentObservabilityEvent = {
174
+ type: 'state:update',
175
+ id: 'state-123',
176
+ displayMessage: 'State updated',
177
+ payload: {},
178
+ timestamp: Date.now(),
179
+ };
180
+
181
+ // Should not throw and should be a no-op due to traceStateUpdates: false
182
+ expect(() => obs.emit(event)).not.toThrow();
183
+ });
184
+
185
+ it('should use custom spanNameFormatter', () => {
186
+ const customFormatter = vi.fn((event) => `custom-${event.type}`);
187
+
188
+ const obs = createOtelObservability({
189
+ service: { name: 'test-agent' },
190
+ exporter: { url: 'http://localhost:4318/v1/traces' },
191
+ agents: {
192
+ spanNameFormatter: customFormatter,
193
+ },
194
+ });
195
+
196
+ const event = createRpcEvent('testMethod');
197
+ obs.emit(event);
198
+
199
+ expect(customFormatter).toHaveBeenCalledWith(event);
200
+ });
201
+
202
+ it('should use custom attributeExtractor', () => {
203
+ const customExtractor = vi.fn(() => ({ 'custom.attr': 'value' }));
204
+
205
+ const obs = createOtelObservability({
206
+ service: { name: 'test-agent' },
207
+ exporter: { url: 'http://localhost:4318/v1/traces' },
208
+ agents: {
209
+ attributeExtractor: customExtractor,
210
+ },
211
+ });
212
+
213
+ const event = createRpcEvent('testMethod');
214
+ obs.emit(event);
215
+
216
+ expect(customExtractor).toHaveBeenCalledWith(event);
217
+ });
218
+
219
+ it('should emit with DurableObjectState context', () => {
220
+ const obs = createOtelObservability({
221
+ service: { name: 'test-agent' },
222
+ exporter: { url: 'http://localhost:4318/v1/traces' },
223
+ });
224
+
225
+ const mockCtx = {
226
+ waitUntil: vi.fn(),
227
+ } as unknown as DurableObjectState;
228
+
229
+ const event = createRpcEvent('testMethod');
230
+
231
+ expect(() => obs.emit(event, mockCtx)).not.toThrow();
232
+ });
233
+ });
234
+
235
+ describe('event types', () => {
236
+ const obs = createOtelObservability({
237
+ service: { name: 'test-agent' },
238
+ exporter: { url: 'http://localhost:4318/v1/traces' },
239
+ });
240
+
241
+ it('should handle message:request events', () => {
242
+ const event: AgentObservabilityEvent = {
243
+ type: 'message:request',
244
+ id: 'msg-req-123',
245
+ displayMessage: 'Message request',
246
+ payload: {},
247
+ timestamp: Date.now(),
248
+ };
249
+
250
+ expect(() => obs.emit(event)).not.toThrow();
251
+ });
252
+
253
+ it('should handle message:response events', () => {
254
+ const event: AgentObservabilityEvent = {
255
+ type: 'message:response',
256
+ id: 'msg-res-123',
257
+ displayMessage: 'Message response',
258
+ payload: {},
259
+ timestamp: Date.now(),
260
+ };
261
+
262
+ expect(() => obs.emit(event)).not.toThrow();
263
+ });
264
+
265
+ it('should handle message:clear events', () => {
266
+ const event: AgentObservabilityEvent = {
267
+ type: 'message:clear',
268
+ id: 'msg-clr-123',
269
+ displayMessage: 'Messages cleared',
270
+ payload: {},
271
+ timestamp: Date.now(),
272
+ };
273
+
274
+ expect(() => obs.emit(event)).not.toThrow();
275
+ });
276
+
277
+ it('should handle destroy events', () => {
278
+ const event: AgentObservabilityEvent = {
279
+ type: 'destroy',
280
+ id: 'destroy-123',
281
+ displayMessage: 'Agent destroyed',
282
+ payload: {},
283
+ timestamp: Date.now(),
284
+ };
285
+
286
+ expect(() => obs.emit(event)).not.toThrow();
287
+ });
288
+
289
+ it('should handle mcp:client:preconnect events', () => {
290
+ const event: MCPObservabilityEvent = {
291
+ type: 'mcp:client:preconnect',
292
+ id: 'mcp-pre-123',
293
+ displayMessage: 'MCP preconnect',
294
+ payload: { serverId: 'server-1' },
295
+ timestamp: Date.now(),
296
+ };
297
+
298
+ expect(() => obs.emit(event)).not.toThrow();
299
+ });
300
+
301
+ it('should handle mcp:client:authorize events', () => {
302
+ const event: MCPObservabilityEvent = {
303
+ type: 'mcp:client:authorize',
304
+ id: 'mcp-auth-123',
305
+ displayMessage: 'MCP authorize',
306
+ payload: {
307
+ serverId: 'server-1',
308
+ authUrl: 'https://auth.example.com',
309
+ clientId: 'client-123',
310
+ },
311
+ timestamp: Date.now(),
312
+ };
313
+
314
+ expect(() => obs.emit(event)).not.toThrow();
315
+ });
316
+
317
+ it('should handle mcp:client:discover events', () => {
318
+ const event: MCPObservabilityEvent = {
319
+ type: 'mcp:client:discover',
320
+ id: 'mcp-disc-123',
321
+ displayMessage: 'MCP discover',
322
+ payload: {},
323
+ timestamp: Date.now(),
324
+ };
325
+
326
+ expect(() => obs.emit(event)).not.toThrow();
327
+ });
328
+ });
329
+ });