autotel-cloudflare 2.18.18 → 2.19.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.
- package/dist/actors.d.ts +54 -89
- package/dist/actors.d.ts.map +1 -0
- package/dist/actors.js +990 -986
- package/dist/actors.js.map +1 -1
- package/dist/agents.d.ts +102 -128
- package/dist/agents.d.ts.map +1 -0
- package/dist/agents.js +275 -259
- package/dist/agents.js.map +1 -1
- package/dist/bindings-C10RI6Il.js +975 -0
- package/dist/bindings-C10RI6Il.js.map +1 -0
- package/dist/bindings-xEZcXo5r.d.ts +149 -0
- package/dist/bindings-xEZcXo5r.d.ts.map +1 -0
- package/dist/bindings.d.ts +2 -139
- package/dist/bindings.js +3 -4
- package/dist/common-DiWH6nmG.js +63 -0
- package/dist/common-DiWH6nmG.js.map +1 -0
- package/dist/events.d.ts +1 -1
- package/dist/events.js +3 -3
- package/dist/execution-logger-BxmgP8jF.js +65 -0
- package/dist/execution-logger-BxmgP8jF.js.map +1 -0
- package/dist/{logger-Cm_73k3-.d.ts → execution-logger-tgQmJeeU.d.ts} +9 -7
- package/dist/execution-logger-tgQmJeeU.d.ts.map +1 -0
- package/dist/handlers-CMg9l_T-.js +378 -0
- package/dist/handlers-CMg9l_T-.js.map +1 -0
- package/dist/handlers-C_VojUeA.d.ts +96 -0
- package/dist/handlers-C_VojUeA.d.ts.map +1 -0
- package/dist/handlers.d.ts +2 -112
- package/dist/handlers.js +3 -4
- package/dist/index.d.ts +20 -99
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +644 -600
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts +3 -3
- package/dist/logger.js +5 -4
- package/dist/parse-error.d.ts +2 -1
- package/dist/parse-error.js +3 -3
- package/dist/sampling.d.ts +1 -4
- package/dist/sampling.js +3 -3
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +3 -3
- package/package.json +6 -6
- package/src/bindings/ai.test.ts +1 -1
- package/src/bindings/ai.ts +3 -1
- package/dist/bindings.js.map +0 -1
- package/dist/chunk-KAUHT25H.js +0 -1084
- package/dist/chunk-KAUHT25H.js.map +0 -1
- package/dist/chunk-MIDMNKDC.js +0 -333
- package/dist/chunk-MIDMNKDC.js.map +0 -1
- package/dist/chunk-O4IYKWPJ.js +0 -55
- package/dist/chunk-O4IYKWPJ.js.map +0 -1
- package/dist/chunk-RVVMMPWN.js +0 -63
- package/dist/chunk-RVVMMPWN.js.map +0 -1
- package/dist/events.js.map +0 -1
- package/dist/handlers.js.map +0 -1
- package/dist/logger.js.map +0 -1
- package/dist/parse-error.js.map +0 -1
- package/dist/sampling.js.map +0 -1
- package/dist/testing.js.map +0 -1
package/dist/agents.js
CHANGED
|
@@ -1,281 +1,297 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { WorkerTracer, WorkerTracerProvider, createInitialiser } from "autotel-edge";
|
|
2
|
+
import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
|
|
3
|
+
import { resourceFromAttributes } from "@opentelemetry/resources";
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
//#region src/agents/otel-observability.ts
|
|
6
|
+
/**
|
|
7
|
+
* OpenTelemetry-based Observability implementation for Cloudflare Agents SDK
|
|
8
|
+
*
|
|
9
|
+
* Converts Agent events into OpenTelemetry spans for distributed tracing.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { Agent } from 'agents'
|
|
14
|
+
* import { createOtelObservability } from 'autotel-cloudflare/agents'
|
|
15
|
+
*
|
|
16
|
+
* class MyAgent extends Agent<Env> {
|
|
17
|
+
* observability = createOtelObservability({
|
|
18
|
+
* service: { name: 'my-agent' },
|
|
19
|
+
* exporter: { url: env.OTLP_ENDPOINT }
|
|
20
|
+
* })
|
|
21
|
+
*
|
|
22
|
+
* @callable()
|
|
23
|
+
* async doSomething() {
|
|
24
|
+
* // This RPC call will be automatically traced
|
|
25
|
+
* return 'done'
|
|
26
|
+
* }
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* Map of active spans keyed by event ID
|
|
32
|
+
* Used to correlate start/end events
|
|
33
|
+
*/
|
|
34
|
+
const activeSpans = /* @__PURE__ */ new Map();
|
|
35
|
+
/**
|
|
36
|
+
* Whether the provider has been initialized
|
|
37
|
+
*/
|
|
38
|
+
let providerInitialized = false;
|
|
39
|
+
/**
|
|
40
|
+
* Initialize the tracer provider for Agents
|
|
41
|
+
*/
|
|
8
42
|
function initProvider(config) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
tracer.setHeadSampler(config.sampling.headSampler);
|
|
24
|
-
providerInitialized = true;
|
|
43
|
+
if (providerInitialized) return;
|
|
44
|
+
const resource = resourceFromAttributes({
|
|
45
|
+
"service.name": config.service.name,
|
|
46
|
+
"service.version": config.service.version,
|
|
47
|
+
"service.namespace": config.service.namespace,
|
|
48
|
+
"cloud.provider": "cloudflare",
|
|
49
|
+
"cloud.platform": "cloudflare.workers",
|
|
50
|
+
"telemetry.sdk.name": "autotel-cloudflare",
|
|
51
|
+
"telemetry.sdk.language": "js",
|
|
52
|
+
"agent.framework": "cloudflare-agents"
|
|
53
|
+
});
|
|
54
|
+
new WorkerTracerProvider(config.spanProcessors, resource).register();
|
|
55
|
+
trace.getTracer("autotel-cloudflare/agents").setHeadSampler(config.sampling.headSampler);
|
|
56
|
+
providerInitialized = true;
|
|
25
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* Get default span name for an event
|
|
60
|
+
*/
|
|
26
61
|
function getDefaultSpanName(event) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return `agent.destroy`;
|
|
45
|
-
}
|
|
46
|
-
case "state:update": {
|
|
47
|
-
return `agent.state.update`;
|
|
48
|
-
}
|
|
49
|
-
case "message:request": {
|
|
50
|
-
return `agent.message.request`;
|
|
51
|
-
}
|
|
52
|
-
case "message:response": {
|
|
53
|
-
return `agent.message.response`;
|
|
54
|
-
}
|
|
55
|
-
case "message:clear": {
|
|
56
|
-
return `agent.message.clear`;
|
|
57
|
-
}
|
|
58
|
-
case "mcp:client:preconnect": {
|
|
59
|
-
return `mcp.preconnect ${event.payload.serverId}`;
|
|
60
|
-
}
|
|
61
|
-
case "mcp:client:connect": {
|
|
62
|
-
return `mcp.connect ${event.payload.url}`;
|
|
63
|
-
}
|
|
64
|
-
case "mcp:client:authorize": {
|
|
65
|
-
return `mcp.authorize ${event.payload.serverId}`;
|
|
66
|
-
}
|
|
67
|
-
case "mcp:client:discover": {
|
|
68
|
-
return `mcp.discover`;
|
|
69
|
-
}
|
|
70
|
-
default: {
|
|
71
|
-
return `agent.${event.type}`;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
62
|
+
switch (event.type) {
|
|
63
|
+
case "rpc": return `agent.rpc ${event.payload.method}`;
|
|
64
|
+
case "schedule:create": return `agent.schedule.create ${event.payload.callback}`;
|
|
65
|
+
case "schedule:execute": return `agent.schedule.execute ${event.payload.callback}`;
|
|
66
|
+
case "schedule:cancel": return `agent.schedule.cancel ${event.payload.callback}`;
|
|
67
|
+
case "connect": return `agent.connect`;
|
|
68
|
+
case "destroy": return `agent.destroy`;
|
|
69
|
+
case "state:update": return `agent.state.update`;
|
|
70
|
+
case "message:request": return `agent.message.request`;
|
|
71
|
+
case "message:response": return `agent.message.response`;
|
|
72
|
+
case "message:clear": return `agent.message.clear`;
|
|
73
|
+
case "mcp:client:preconnect": return `mcp.preconnect ${event.payload.serverId}`;
|
|
74
|
+
case "mcp:client:connect": return `mcp.connect ${event.payload.url}`;
|
|
75
|
+
case "mcp:client:authorize": return `mcp.authorize ${event.payload.serverId}`;
|
|
76
|
+
case "mcp:client:discover": return `mcp.discover`;
|
|
77
|
+
default: return `agent.${event.type}`;
|
|
78
|
+
}
|
|
74
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Get default attributes for an event
|
|
82
|
+
*/
|
|
75
83
|
function getDefaultAttributes(event) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
case "mcp:client:authorize": {
|
|
113
|
-
attrs["agent.mcp.server_id"] = event.payload.serverId;
|
|
114
|
-
attrs["agent.mcp.auth_url"] = event.payload.authUrl;
|
|
115
|
-
if (event.payload.clientId) {
|
|
116
|
-
attrs["agent.mcp.client_id"] = event.payload.clientId;
|
|
117
|
-
}
|
|
118
|
-
break;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
for (const [key, value] of Object.entries(event.payload)) {
|
|
122
|
-
if (attrs[`agent.${key}`] === void 0 && (typeof value === "string" || typeof value === "number" || typeof value === "boolean")) {
|
|
123
|
-
attrs[`agent.payload.${key}`] = value;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
return attrs;
|
|
84
|
+
const attrs = {
|
|
85
|
+
"agent.event.type": event.type,
|
|
86
|
+
"agent.event.id": event.id
|
|
87
|
+
};
|
|
88
|
+
switch (event.type) {
|
|
89
|
+
case "rpc":
|
|
90
|
+
attrs["agent.rpc.method"] = event.payload.method;
|
|
91
|
+
if (event.payload.streaming !== void 0) attrs["agent.rpc.streaming"] = event.payload.streaming;
|
|
92
|
+
break;
|
|
93
|
+
case "schedule:create":
|
|
94
|
+
case "schedule:execute":
|
|
95
|
+
case "schedule:cancel":
|
|
96
|
+
attrs["agent.schedule.callback"] = event.payload.callback;
|
|
97
|
+
attrs["agent.schedule.id"] = event.payload.id;
|
|
98
|
+
break;
|
|
99
|
+
case "connect":
|
|
100
|
+
attrs["agent.connection.id"] = event.payload.connectionId;
|
|
101
|
+
break;
|
|
102
|
+
case "mcp:client:preconnect":
|
|
103
|
+
attrs["agent.mcp.server_id"] = event.payload.serverId;
|
|
104
|
+
break;
|
|
105
|
+
case "mcp:client:connect":
|
|
106
|
+
attrs["agent.mcp.url"] = event.payload.url;
|
|
107
|
+
attrs["agent.mcp.transport"] = event.payload.transport;
|
|
108
|
+
attrs["agent.mcp.state"] = event.payload.state;
|
|
109
|
+
if (event.payload.error) attrs["agent.mcp.error"] = event.payload.error;
|
|
110
|
+
break;
|
|
111
|
+
case "mcp:client:authorize":
|
|
112
|
+
attrs["agent.mcp.server_id"] = event.payload.serverId;
|
|
113
|
+
attrs["agent.mcp.auth_url"] = event.payload.authUrl;
|
|
114
|
+
if (event.payload.clientId) attrs["agent.mcp.client_id"] = event.payload.clientId;
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
for (const [key, value] of Object.entries(event.payload)) if (attrs[`agent.${key}`] === void 0 && (typeof value === "string" || typeof value === "number" || typeof value === "boolean")) attrs[`agent.payload.${key}`] = value;
|
|
118
|
+
return attrs;
|
|
127
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Determine span kind based on event type
|
|
122
|
+
*/
|
|
128
123
|
function getSpanKind(event) {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
case "mcp:client:authorize":
|
|
139
|
-
case "mcp:client:discover": {
|
|
140
|
-
return SpanKind.CLIENT;
|
|
141
|
-
}
|
|
142
|
-
default: {
|
|
143
|
-
return SpanKind.INTERNAL;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
124
|
+
switch (event.type) {
|
|
125
|
+
case "rpc": return SpanKind.SERVER;
|
|
126
|
+
case "connect": return SpanKind.SERVER;
|
|
127
|
+
case "mcp:client:connect":
|
|
128
|
+
case "mcp:client:preconnect":
|
|
129
|
+
case "mcp:client:authorize":
|
|
130
|
+
case "mcp:client:discover": return SpanKind.CLIENT;
|
|
131
|
+
default: return SpanKind.INTERNAL;
|
|
132
|
+
}
|
|
146
133
|
}
|
|
134
|
+
/**
|
|
135
|
+
* Check if an event type should be traced based on options
|
|
136
|
+
*/
|
|
147
137
|
function shouldTraceEvent(event, options) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
175
|
-
case "message:request":
|
|
176
|
-
case "message:response":
|
|
177
|
-
case "message:clear": {
|
|
178
|
-
return opts.traceMessages ?? true;
|
|
179
|
-
}
|
|
180
|
-
case "connect":
|
|
181
|
-
case "destroy": {
|
|
182
|
-
return opts.traceLifecycle ?? true;
|
|
183
|
-
}
|
|
184
|
-
default: {
|
|
185
|
-
return true;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
138
|
+
const opts = {
|
|
139
|
+
traceRpc: true,
|
|
140
|
+
traceSchedule: true,
|
|
141
|
+
traceMcp: true,
|
|
142
|
+
traceStateUpdates: false,
|
|
143
|
+
traceMessages: true,
|
|
144
|
+
traceLifecycle: true,
|
|
145
|
+
...options
|
|
146
|
+
};
|
|
147
|
+
switch (event.type) {
|
|
148
|
+
case "rpc": return opts.traceRpc ?? true;
|
|
149
|
+
case "schedule:create":
|
|
150
|
+
case "schedule:execute":
|
|
151
|
+
case "schedule:cancel": return opts.traceSchedule ?? true;
|
|
152
|
+
case "mcp:client:preconnect":
|
|
153
|
+
case "mcp:client:connect":
|
|
154
|
+
case "mcp:client:authorize":
|
|
155
|
+
case "mcp:client:discover": return opts.traceMcp ?? true;
|
|
156
|
+
case "state:update": return opts.traceStateUpdates ?? false;
|
|
157
|
+
case "message:request":
|
|
158
|
+
case "message:response":
|
|
159
|
+
case "message:clear": return opts.traceMessages ?? true;
|
|
160
|
+
case "connect":
|
|
161
|
+
case "destroy": return opts.traceLifecycle ?? true;
|
|
162
|
+
default: return true;
|
|
163
|
+
}
|
|
188
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* Export spans asynchronously
|
|
167
|
+
*/
|
|
189
168
|
async function exportSpans(traceId, ctx) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
console.error("[autotel-cloudflare/agents] Failed to export spans:", error);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
169
|
+
const tracer = trace.getTracer("autotel-cloudflare/agents");
|
|
170
|
+
if (tracer instanceof WorkerTracer) try {
|
|
171
|
+
if (ctx && "scheduler" in ctx) {
|
|
172
|
+
const ctxWithScheduler = ctx;
|
|
173
|
+
if (ctxWithScheduler.scheduler) await ctxWithScheduler.scheduler.wait(1);
|
|
174
|
+
}
|
|
175
|
+
await tracer.forceFlush(traceId);
|
|
176
|
+
} catch (error) {
|
|
177
|
+
console.error("[autotel-cloudflare/agents] Failed to export spans:", error);
|
|
178
|
+
}
|
|
179
|
+
if (ctx && "waitUntil" in ctx) {}
|
|
204
180
|
}
|
|
181
|
+
/**
|
|
182
|
+
* OpenTelemetry-based Observability implementation
|
|
183
|
+
*
|
|
184
|
+
* Implements the Agents SDK Observability interface and converts
|
|
185
|
+
* events into OpenTelemetry spans.
|
|
186
|
+
*/
|
|
205
187
|
var OtelObservability = class {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
}
|
|
252
|
-
}
|
|
188
|
+
config;
|
|
189
|
+
options;
|
|
190
|
+
initialized = false;
|
|
191
|
+
constructor(config) {
|
|
192
|
+
const initialiser = createInitialiser(config);
|
|
193
|
+
this.config = initialiser({}, void 0);
|
|
194
|
+
this.options = config.agents ?? {};
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Initialize the tracer provider (called lazily on first emit)
|
|
198
|
+
*/
|
|
199
|
+
initialize() {
|
|
200
|
+
if (this.initialized) return;
|
|
201
|
+
initProvider(this.config);
|
|
202
|
+
this.initialized = true;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Emit an observability event
|
|
206
|
+
*
|
|
207
|
+
* Converts the event to an OpenTelemetry span based on the event type.
|
|
208
|
+
*/
|
|
209
|
+
emit(event, ctx) {
|
|
210
|
+
this.initialize();
|
|
211
|
+
if (!shouldTraceEvent(event, this.options)) return;
|
|
212
|
+
const tracer = trace.getTracer("autotel-cloudflare/agents");
|
|
213
|
+
const spanName = this.options.spanNameFormatter ? this.options.spanNameFormatter(event) : getDefaultSpanName(event);
|
|
214
|
+
const defaultAttrs = getDefaultAttributes(event);
|
|
215
|
+
const customAttrs = this.options.attributeExtractor ? this.options.attributeExtractor(event) : {};
|
|
216
|
+
const attributes = {
|
|
217
|
+
...defaultAttrs,
|
|
218
|
+
...customAttrs
|
|
219
|
+
};
|
|
220
|
+
const kind = getSpanKind(event);
|
|
221
|
+
const span = tracer.startSpan(spanName, {
|
|
222
|
+
kind,
|
|
223
|
+
attributes,
|
|
224
|
+
startTime: event.timestamp
|
|
225
|
+
});
|
|
226
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
227
|
+
span.end(event.timestamp + 1);
|
|
228
|
+
activeSpans.set(event.id, span);
|
|
229
|
+
const traceId = span.spanContext().traceId;
|
|
230
|
+
if (ctx && "waitUntil" in ctx && typeof ctx.waitUntil === "function") ctx.waitUntil(exportSpans(traceId, ctx));
|
|
231
|
+
else exportSpans(traceId, ctx);
|
|
232
|
+
}
|
|
253
233
|
};
|
|
234
|
+
/**
|
|
235
|
+
* Create an OtelObservability instance
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* ```typescript
|
|
239
|
+
* import { Agent } from 'agents'
|
|
240
|
+
* import { createOtelObservability } from 'autotel-cloudflare/agents'
|
|
241
|
+
*
|
|
242
|
+
* class MyAgent extends Agent<Env> {
|
|
243
|
+
* observability = createOtelObservability({
|
|
244
|
+
* service: { name: 'my-agent' },
|
|
245
|
+
* exporter: { url: env.OTLP_ENDPOINT }
|
|
246
|
+
* })
|
|
247
|
+
* }
|
|
248
|
+
* ```
|
|
249
|
+
*/
|
|
254
250
|
function createOtelObservability(config) {
|
|
255
|
-
|
|
251
|
+
return new OtelObservability(config);
|
|
256
252
|
}
|
|
253
|
+
/**
|
|
254
|
+
* Create an OtelObservability instance with environment-based config
|
|
255
|
+
*
|
|
256
|
+
* Use this when you need to access environment variables for configuration.
|
|
257
|
+
*
|
|
258
|
+
* @example
|
|
259
|
+
* ```typescript
|
|
260
|
+
* import { Agent } from 'agents'
|
|
261
|
+
* import { createOtelObservabilityFromEnv } from 'autotel-cloudflare/agents'
|
|
262
|
+
*
|
|
263
|
+
* class MyAgent extends Agent<Env> {
|
|
264
|
+
* observability?: OtelObservability
|
|
265
|
+
*
|
|
266
|
+
* constructor(state: DurableObjectState, env: Env) {
|
|
267
|
+
* super(state, env)
|
|
268
|
+
* this.observability = createOtelObservabilityFromEnv(env)
|
|
269
|
+
* }
|
|
270
|
+
* }
|
|
271
|
+
* ```
|
|
272
|
+
*/
|
|
257
273
|
function createOtelObservabilityFromEnv(env, options) {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
274
|
+
const endpoint = env.OTEL_EXPORTER_OTLP_ENDPOINT || void 0;
|
|
275
|
+
const serviceName = env.OTEL_SERVICE_NAME || "cloudflare-agent";
|
|
276
|
+
let headers;
|
|
277
|
+
const headersStr = env.OTEL_EXPORTER_OTLP_HEADERS;
|
|
278
|
+
if (headersStr) {
|
|
279
|
+
headers = {};
|
|
280
|
+
for (const pair of headersStr.split(",")) {
|
|
281
|
+
const [key, value] = pair.split("=");
|
|
282
|
+
if (key && value) headers[key.trim()] = value.trim();
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return createOtelObservability({
|
|
286
|
+
service: { name: serviceName },
|
|
287
|
+
exporter: {
|
|
288
|
+
url: endpoint || "http://localhost:4318/v1/traces",
|
|
289
|
+
headers
|
|
290
|
+
},
|
|
291
|
+
agents: options
|
|
292
|
+
});
|
|
277
293
|
}
|
|
278
294
|
|
|
295
|
+
//#endregion
|
|
279
296
|
export { OtelObservability, createOtelObservability, createOtelObservabilityFromEnv };
|
|
280
|
-
//# sourceMappingURL=agents.js.map
|
|
281
297
|
//# sourceMappingURL=agents.js.map
|
package/dist/agents.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/agents/otel-observability.ts"],"names":[],"mappings":"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","file":"agents.js","sourcesContent":["/**\n * OpenTelemetry-based Observability implementation for Cloudflare Agents SDK\n *\n * Converts Agent events into OpenTelemetry spans for distributed tracing.\n *\n * @example\n * ```typescript\n * import { Agent } from 'agents'\n * import { createOtelObservability } from 'autotel-cloudflare/agents'\n *\n * class MyAgent extends Agent<Env> {\n * observability = createOtelObservability({\n * service: { name: 'my-agent' },\n * exporter: { url: env.OTLP_ENDPOINT }\n * })\n *\n * @callable()\n * async doSomething() {\n * // This RPC call will be automatically traced\n * return 'done'\n * }\n * }\n * ```\n */\n\nimport {\n trace,\n SpanStatusCode,\n SpanKind,\n type Span,\n type Attributes,\n} from '@opentelemetry/api';\nimport { resourceFromAttributes } from '@opentelemetry/resources';\nimport {\n createInitialiser,\n WorkerTracerProvider,\n WorkerTracer,\n type ResolvedEdgeConfig,\n} from 'autotel-edge';\nimport type {\n Observability,\n ObservabilityEvent,\n OtelObservabilityConfig,\n AgentInstrumentationOptions,\n} from './types';\n\n/**\n * Map of active spans keyed by event ID\n * Used to correlate start/end events\n */\nconst activeSpans = new Map<string, Span>();\n\n/**\n * Whether the provider has been initialized\n */\nlet providerInitialized = false;\n\n/**\n * Initialize the tracer provider for Agents\n */\nfunction initProvider(config: ResolvedEdgeConfig): void {\n if (providerInitialized) return;\n\n // Create resource with agent-specific attributes\n const resource = resourceFromAttributes({\n 'service.name': config.service.name,\n 'service.version': config.service.version,\n 'service.namespace': config.service.namespace,\n 'cloud.provider': 'cloudflare',\n 'cloud.platform': 'cloudflare.workers',\n 'telemetry.sdk.name': 'autotel-cloudflare',\n 'telemetry.sdk.language': 'js',\n 'agent.framework': 'cloudflare-agents',\n });\n\n // Create and register provider\n const provider = new WorkerTracerProvider(config.spanProcessors, resource);\n provider.register();\n\n // Set head sampler on tracer\n const tracer = trace.getTracer('autotel-cloudflare/agents') as WorkerTracer;\n tracer.setHeadSampler(config.sampling.headSampler);\n\n providerInitialized = true;\n}\n\n/**\n * Get default span name for an event\n */\nfunction getDefaultSpanName(event: ObservabilityEvent): string {\n switch (event.type) {\n case 'rpc': {\n return `agent.rpc ${event.payload.method}`;\n }\n case 'schedule:create': {\n return `agent.schedule.create ${event.payload.callback}`;\n }\n case 'schedule:execute': {\n return `agent.schedule.execute ${event.payload.callback}`;\n }\n case 'schedule:cancel': {\n return `agent.schedule.cancel ${event.payload.callback}`;\n }\n case 'connect': {\n return `agent.connect`;\n }\n case 'destroy': {\n return `agent.destroy`;\n }\n case 'state:update': {\n return `agent.state.update`;\n }\n case 'message:request': {\n return `agent.message.request`;\n }\n case 'message:response': {\n return `agent.message.response`;\n }\n case 'message:clear': {\n return `agent.message.clear`;\n }\n case 'mcp:client:preconnect': {\n return `mcp.preconnect ${event.payload.serverId}`;\n }\n case 'mcp:client:connect': {\n return `mcp.connect ${event.payload.url}`;\n }\n case 'mcp:client:authorize': {\n return `mcp.authorize ${event.payload.serverId}`;\n }\n case 'mcp:client:discover': {\n return `mcp.discover`;\n }\n default: {\n return `agent.${(event as ObservabilityEvent).type}`;\n }\n }\n}\n\n/**\n * Get default attributes for an event\n */\nfunction getDefaultAttributes(event: ObservabilityEvent): Attributes {\n const attrs: Attributes = {\n 'agent.event.type': event.type,\n 'agent.event.id': event.id,\n };\n\n // Add type-specific attributes\n switch (event.type) {\n case 'rpc': {\n attrs['agent.rpc.method'] = event.payload.method;\n if (event.payload.streaming !== undefined) {\n attrs['agent.rpc.streaming'] = event.payload.streaming;\n }\n break;\n }\n\n case 'schedule:create':\n case 'schedule:execute':\n case 'schedule:cancel': {\n attrs['agent.schedule.callback'] = event.payload.callback;\n attrs['agent.schedule.id'] = event.payload.id;\n break;\n }\n\n case 'connect': {\n attrs['agent.connection.id'] = event.payload.connectionId;\n break;\n }\n\n case 'mcp:client:preconnect': {\n attrs['agent.mcp.server_id'] = event.payload.serverId;\n break;\n }\n\n case 'mcp:client:connect': {\n attrs['agent.mcp.url'] = event.payload.url;\n attrs['agent.mcp.transport'] = event.payload.transport;\n attrs['agent.mcp.state'] = event.payload.state;\n if (event.payload.error) {\n attrs['agent.mcp.error'] = event.payload.error;\n }\n break;\n }\n\n case 'mcp:client:authorize': {\n attrs['agent.mcp.server_id'] = event.payload.serverId;\n attrs['agent.mcp.auth_url'] = event.payload.authUrl;\n if (event.payload.clientId) {\n attrs['agent.mcp.client_id'] = event.payload.clientId;\n }\n break;\n }\n }\n\n // Add any additional payload properties as attributes\n for (const [key, value] of Object.entries(event.payload)) {\n if (\n attrs[`agent.${key}`] === undefined &&\n (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean')\n ) {\n attrs[`agent.payload.${key}`] = value;\n }\n }\n\n return attrs;\n}\n\n/**\n * Determine span kind based on event type\n */\nfunction getSpanKind(event: ObservabilityEvent): SpanKind {\n switch (event.type) {\n case 'rpc': {\n return SpanKind.SERVER;\n }\n case 'connect': {\n return SpanKind.SERVER;\n }\n case 'mcp:client:connect':\n case 'mcp:client:preconnect':\n case 'mcp:client:authorize':\n case 'mcp:client:discover': {\n return SpanKind.CLIENT;\n }\n default: {\n return SpanKind.INTERNAL;\n }\n }\n}\n\n/**\n * Check if an event type should be traced based on options\n */\nfunction shouldTraceEvent(\n event: ObservabilityEvent,\n options: AgentInstrumentationOptions,\n): boolean {\n const defaults: AgentInstrumentationOptions = {\n traceRpc: true,\n traceSchedule: true,\n traceMcp: true,\n traceStateUpdates: false,\n traceMessages: true,\n traceLifecycle: true,\n };\n\n const opts = { ...defaults, ...options };\n\n switch (event.type) {\n case 'rpc': {\n return opts.traceRpc ?? true;\n }\n\n case 'schedule:create':\n case 'schedule:execute':\n case 'schedule:cancel': {\n return opts.traceSchedule ?? true;\n }\n\n case 'mcp:client:preconnect':\n case 'mcp:client:connect':\n case 'mcp:client:authorize':\n case 'mcp:client:discover': {\n return opts.traceMcp ?? true;\n }\n\n case 'state:update': {\n return opts.traceStateUpdates ?? false;\n }\n\n case 'message:request':\n case 'message:response':\n case 'message:clear': {\n return opts.traceMessages ?? true;\n }\n\n case 'connect':\n case 'destroy': {\n return opts.traceLifecycle ?? true;\n }\n\n default: {\n return true;\n }\n }\n}\n\n/**\n * Export spans asynchronously\n */\nasync function exportSpans(\n traceId: string,\n ctx?: DurableObjectState | ExecutionContext,\n): Promise<void> {\n const tracer = trace.getTracer('autotel-cloudflare/agents');\n if (tracer instanceof WorkerTracer) {\n try {\n // scheduler is only available on ExecutionContext, not DurableObjectState\n if (ctx && 'scheduler' in ctx) {\n const ctxWithScheduler = ctx as ExecutionContext & { scheduler?: { wait(ms: number): Promise<void> } };\n if (ctxWithScheduler.scheduler) {\n await ctxWithScheduler.scheduler.wait(1);\n }\n }\n await tracer.forceFlush(traceId);\n } catch (error) {\n console.error('[autotel-cloudflare/agents] Failed to export spans:', error);\n }\n }\n\n // If we have a DurableObject context, use waitUntil for export\n if (ctx && 'waitUntil' in ctx) {\n // Already exported above, but could defer more work here\n }\n}\n\n/**\n * OpenTelemetry-based Observability implementation\n *\n * Implements the Agents SDK Observability interface and converts\n * events into OpenTelemetry spans.\n */\nexport class OtelObservability implements Observability {\n private config: ResolvedEdgeConfig;\n private options: AgentInstrumentationOptions;\n private initialized = false;\n\n constructor(config: OtelObservabilityConfig) {\n // Use createInitialiser to resolve the config\n const initialiser = createInitialiser(config);\n this.config = initialiser({}, undefined);\n this.options = config.agents ?? {};\n }\n\n /**\n * Initialize the tracer provider (called lazily on first emit)\n */\n private initialize(): void {\n if (this.initialized) return;\n initProvider(this.config);\n this.initialized = true;\n }\n\n /**\n * Emit an observability event\n *\n * Converts the event to an OpenTelemetry span based on the event type.\n */\n emit(event: ObservabilityEvent, ctx?: DurableObjectState): void {\n // Initialize provider on first emit\n this.initialize();\n\n // Check if this event type should be traced\n if (!shouldTraceEvent(event, this.options)) {\n return;\n }\n\n const tracer = trace.getTracer('autotel-cloudflare/agents');\n\n // Get span name (custom or default)\n const spanName = this.options.spanNameFormatter\n ? this.options.spanNameFormatter(event)\n : getDefaultSpanName(event);\n\n // Get attributes (custom + default)\n const defaultAttrs = getDefaultAttributes(event);\n const customAttrs = this.options.attributeExtractor\n ? this.options.attributeExtractor(event)\n : {};\n const attributes = { ...defaultAttrs, ...customAttrs };\n\n // Determine span kind\n const kind = getSpanKind(event);\n\n // Create span with event timestamp\n const span = tracer.startSpan(spanName, {\n kind,\n attributes,\n startTime: event.timestamp,\n });\n\n // For short-lived events, end immediately\n // For events that have duration (like RPC), we would ideally track start/end\n // But the Agents SDK emits single events, so we create point-in-time spans\n span.setStatus({ code: SpanStatusCode.OK });\n span.end(event.timestamp + 1); // End 1ms after start\n\n // Store span for potential correlation\n activeSpans.set(event.id, span);\n\n // Schedule span export\n const traceId = span.spanContext().traceId;\n if (ctx && 'waitUntil' in ctx && typeof (ctx as any).waitUntil === 'function') {\n (ctx as any).waitUntil(exportSpans(traceId, ctx));\n } else {\n // In environments without waitUntil, export synchronously-ish\n void exportSpans(traceId, ctx);\n }\n }\n}\n\n/**\n * Create an OtelObservability instance\n *\n * @example\n * ```typescript\n * import { Agent } from 'agents'\n * import { createOtelObservability } from 'autotel-cloudflare/agents'\n *\n * class MyAgent extends Agent<Env> {\n * observability = createOtelObservability({\n * service: { name: 'my-agent' },\n * exporter: { url: env.OTLP_ENDPOINT }\n * })\n * }\n * ```\n */\nexport function createOtelObservability(config: OtelObservabilityConfig): OtelObservability {\n return new OtelObservability(config);\n}\n\n/**\n * Create an OtelObservability instance with environment-based config\n *\n * Use this when you need to access environment variables for configuration.\n *\n * @example\n * ```typescript\n * import { Agent } from 'agents'\n * import { createOtelObservabilityFromEnv } from 'autotel-cloudflare/agents'\n *\n * class MyAgent extends Agent<Env> {\n * observability?: OtelObservability\n *\n * constructor(state: DurableObjectState, env: Env) {\n * super(state, env)\n * this.observability = createOtelObservabilityFromEnv(env)\n * }\n * }\n * ```\n */\nexport function createOtelObservabilityFromEnv(\n env: Record<string, unknown>,\n options?: AgentInstrumentationOptions,\n): OtelObservability {\n // Extract standard OTLP env vars\n const endpoint = (env.OTEL_EXPORTER_OTLP_ENDPOINT as string) || undefined;\n const serviceName = (env.OTEL_SERVICE_NAME as string) || 'cloudflare-agent';\n\n // Parse headers if present\n let headers: Record<string, string> | undefined;\n const headersStr = env.OTEL_EXPORTER_OTLP_HEADERS as string;\n if (headersStr) {\n headers = {};\n for (const pair of headersStr.split(',')) {\n const [key, value] = pair.split('=');\n if (key && value) {\n headers[key.trim()] = value.trim();\n }\n }\n }\n\n // If no endpoint is configured, use a default localhost endpoint\n // In production, users should set OTEL_EXPORTER_OTLP_ENDPOINT\n const exporterUrl = endpoint || 'http://localhost:4318/v1/traces';\n\n return createOtelObservability({\n service: { name: serviceName },\n exporter: { url: exporterUrl, headers },\n agents: options,\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agents.js","names":[],"sources":["../src/agents/otel-observability.ts"],"sourcesContent":["/**\n * OpenTelemetry-based Observability implementation for Cloudflare Agents SDK\n *\n * Converts Agent events into OpenTelemetry spans for distributed tracing.\n *\n * @example\n * ```typescript\n * import { Agent } from 'agents'\n * import { createOtelObservability } from 'autotel-cloudflare/agents'\n *\n * class MyAgent extends Agent<Env> {\n * observability = createOtelObservability({\n * service: { name: 'my-agent' },\n * exporter: { url: env.OTLP_ENDPOINT }\n * })\n *\n * @callable()\n * async doSomething() {\n * // This RPC call will be automatically traced\n * return 'done'\n * }\n * }\n * ```\n */\n\nimport {\n trace,\n SpanStatusCode,\n SpanKind,\n type Span,\n type Attributes,\n} from '@opentelemetry/api';\nimport { resourceFromAttributes } from '@opentelemetry/resources';\nimport {\n createInitialiser,\n WorkerTracerProvider,\n WorkerTracer,\n type ResolvedEdgeConfig,\n} from 'autotel-edge';\nimport type {\n Observability,\n ObservabilityEvent,\n OtelObservabilityConfig,\n AgentInstrumentationOptions,\n} from './types';\n\n/**\n * Map of active spans keyed by event ID\n * Used to correlate start/end events\n */\nconst activeSpans = new Map<string, Span>();\n\n/**\n * Whether the provider has been initialized\n */\nlet providerInitialized = false;\n\n/**\n * Initialize the tracer provider for Agents\n */\nfunction initProvider(config: ResolvedEdgeConfig): void {\n if (providerInitialized) return;\n\n // Create resource with agent-specific attributes\n const resource = resourceFromAttributes({\n 'service.name': config.service.name,\n 'service.version': config.service.version,\n 'service.namespace': config.service.namespace,\n 'cloud.provider': 'cloudflare',\n 'cloud.platform': 'cloudflare.workers',\n 'telemetry.sdk.name': 'autotel-cloudflare',\n 'telemetry.sdk.language': 'js',\n 'agent.framework': 'cloudflare-agents',\n });\n\n // Create and register provider\n const provider = new WorkerTracerProvider(config.spanProcessors, resource);\n provider.register();\n\n // Set head sampler on tracer\n const tracer = trace.getTracer('autotel-cloudflare/agents') as WorkerTracer;\n tracer.setHeadSampler(config.sampling.headSampler);\n\n providerInitialized = true;\n}\n\n/**\n * Get default span name for an event\n */\nfunction getDefaultSpanName(event: ObservabilityEvent): string {\n switch (event.type) {\n case 'rpc': {\n return `agent.rpc ${event.payload.method}`;\n }\n case 'schedule:create': {\n return `agent.schedule.create ${event.payload.callback}`;\n }\n case 'schedule:execute': {\n return `agent.schedule.execute ${event.payload.callback}`;\n }\n case 'schedule:cancel': {\n return `agent.schedule.cancel ${event.payload.callback}`;\n }\n case 'connect': {\n return `agent.connect`;\n }\n case 'destroy': {\n return `agent.destroy`;\n }\n case 'state:update': {\n return `agent.state.update`;\n }\n case 'message:request': {\n return `agent.message.request`;\n }\n case 'message:response': {\n return `agent.message.response`;\n }\n case 'message:clear': {\n return `agent.message.clear`;\n }\n case 'mcp:client:preconnect': {\n return `mcp.preconnect ${event.payload.serverId}`;\n }\n case 'mcp:client:connect': {\n return `mcp.connect ${event.payload.url}`;\n }\n case 'mcp:client:authorize': {\n return `mcp.authorize ${event.payload.serverId}`;\n }\n case 'mcp:client:discover': {\n return `mcp.discover`;\n }\n default: {\n return `agent.${(event as ObservabilityEvent).type}`;\n }\n }\n}\n\n/**\n * Get default attributes for an event\n */\nfunction getDefaultAttributes(event: ObservabilityEvent): Attributes {\n const attrs: Attributes = {\n 'agent.event.type': event.type,\n 'agent.event.id': event.id,\n };\n\n // Add type-specific attributes\n switch (event.type) {\n case 'rpc': {\n attrs['agent.rpc.method'] = event.payload.method;\n if (event.payload.streaming !== undefined) {\n attrs['agent.rpc.streaming'] = event.payload.streaming;\n }\n break;\n }\n\n case 'schedule:create':\n case 'schedule:execute':\n case 'schedule:cancel': {\n attrs['agent.schedule.callback'] = event.payload.callback;\n attrs['agent.schedule.id'] = event.payload.id;\n break;\n }\n\n case 'connect': {\n attrs['agent.connection.id'] = event.payload.connectionId;\n break;\n }\n\n case 'mcp:client:preconnect': {\n attrs['agent.mcp.server_id'] = event.payload.serverId;\n break;\n }\n\n case 'mcp:client:connect': {\n attrs['agent.mcp.url'] = event.payload.url;\n attrs['agent.mcp.transport'] = event.payload.transport;\n attrs['agent.mcp.state'] = event.payload.state;\n if (event.payload.error) {\n attrs['agent.mcp.error'] = event.payload.error;\n }\n break;\n }\n\n case 'mcp:client:authorize': {\n attrs['agent.mcp.server_id'] = event.payload.serverId;\n attrs['agent.mcp.auth_url'] = event.payload.authUrl;\n if (event.payload.clientId) {\n attrs['agent.mcp.client_id'] = event.payload.clientId;\n }\n break;\n }\n }\n\n // Add any additional payload properties as attributes\n for (const [key, value] of Object.entries(event.payload)) {\n if (\n attrs[`agent.${key}`] === undefined &&\n (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean')\n ) {\n attrs[`agent.payload.${key}`] = value;\n }\n }\n\n return attrs;\n}\n\n/**\n * Determine span kind based on event type\n */\nfunction getSpanKind(event: ObservabilityEvent): SpanKind {\n switch (event.type) {\n case 'rpc': {\n return SpanKind.SERVER;\n }\n case 'connect': {\n return SpanKind.SERVER;\n }\n case 'mcp:client:connect':\n case 'mcp:client:preconnect':\n case 'mcp:client:authorize':\n case 'mcp:client:discover': {\n return SpanKind.CLIENT;\n }\n default: {\n return SpanKind.INTERNAL;\n }\n }\n}\n\n/**\n * Check if an event type should be traced based on options\n */\nfunction shouldTraceEvent(\n event: ObservabilityEvent,\n options: AgentInstrumentationOptions,\n): boolean {\n const defaults: AgentInstrumentationOptions = {\n traceRpc: true,\n traceSchedule: true,\n traceMcp: true,\n traceStateUpdates: false,\n traceMessages: true,\n traceLifecycle: true,\n };\n\n const opts = { ...defaults, ...options };\n\n switch (event.type) {\n case 'rpc': {\n return opts.traceRpc ?? true;\n }\n\n case 'schedule:create':\n case 'schedule:execute':\n case 'schedule:cancel': {\n return opts.traceSchedule ?? true;\n }\n\n case 'mcp:client:preconnect':\n case 'mcp:client:connect':\n case 'mcp:client:authorize':\n case 'mcp:client:discover': {\n return opts.traceMcp ?? true;\n }\n\n case 'state:update': {\n return opts.traceStateUpdates ?? false;\n }\n\n case 'message:request':\n case 'message:response':\n case 'message:clear': {\n return opts.traceMessages ?? true;\n }\n\n case 'connect':\n case 'destroy': {\n return opts.traceLifecycle ?? true;\n }\n\n default: {\n return true;\n }\n }\n}\n\n/**\n * Export spans asynchronously\n */\nasync function exportSpans(\n traceId: string,\n ctx?: DurableObjectState | ExecutionContext,\n): Promise<void> {\n const tracer = trace.getTracer('autotel-cloudflare/agents');\n if (tracer instanceof WorkerTracer) {\n try {\n // scheduler is only available on ExecutionContext, not DurableObjectState\n if (ctx && 'scheduler' in ctx) {\n const ctxWithScheduler = ctx as ExecutionContext & { scheduler?: { wait(ms: number): Promise<void> } };\n if (ctxWithScheduler.scheduler) {\n await ctxWithScheduler.scheduler.wait(1);\n }\n }\n await tracer.forceFlush(traceId);\n } catch (error) {\n console.error('[autotel-cloudflare/agents] Failed to export spans:', error);\n }\n }\n\n // If we have a DurableObject context, use waitUntil for export\n if (ctx && 'waitUntil' in ctx) {\n // Already exported above, but could defer more work here\n }\n}\n\n/**\n * OpenTelemetry-based Observability implementation\n *\n * Implements the Agents SDK Observability interface and converts\n * events into OpenTelemetry spans.\n */\nexport class OtelObservability implements Observability {\n private config: ResolvedEdgeConfig;\n private options: AgentInstrumentationOptions;\n private initialized = false;\n\n constructor(config: OtelObservabilityConfig) {\n // Use createInitialiser to resolve the config\n const initialiser = createInitialiser(config);\n this.config = initialiser({}, undefined);\n this.options = config.agents ?? {};\n }\n\n /**\n * Initialize the tracer provider (called lazily on first emit)\n */\n private initialize(): void {\n if (this.initialized) return;\n initProvider(this.config);\n this.initialized = true;\n }\n\n /**\n * Emit an observability event\n *\n * Converts the event to an OpenTelemetry span based on the event type.\n */\n emit(event: ObservabilityEvent, ctx?: DurableObjectState): void {\n // Initialize provider on first emit\n this.initialize();\n\n // Check if this event type should be traced\n if (!shouldTraceEvent(event, this.options)) {\n return;\n }\n\n const tracer = trace.getTracer('autotel-cloudflare/agents');\n\n // Get span name (custom or default)\n const spanName = this.options.spanNameFormatter\n ? this.options.spanNameFormatter(event)\n : getDefaultSpanName(event);\n\n // Get attributes (custom + default)\n const defaultAttrs = getDefaultAttributes(event);\n const customAttrs = this.options.attributeExtractor\n ? this.options.attributeExtractor(event)\n : {};\n const attributes = { ...defaultAttrs, ...customAttrs };\n\n // Determine span kind\n const kind = getSpanKind(event);\n\n // Create span with event timestamp\n const span = tracer.startSpan(spanName, {\n kind,\n attributes,\n startTime: event.timestamp,\n });\n\n // For short-lived events, end immediately\n // For events that have duration (like RPC), we would ideally track start/end\n // But the Agents SDK emits single events, so we create point-in-time spans\n span.setStatus({ code: SpanStatusCode.OK });\n span.end(event.timestamp + 1); // End 1ms after start\n\n // Store span for potential correlation\n activeSpans.set(event.id, span);\n\n // Schedule span export\n const traceId = span.spanContext().traceId;\n if (ctx && 'waitUntil' in ctx && typeof (ctx as any).waitUntil === 'function') {\n (ctx as any).waitUntil(exportSpans(traceId, ctx));\n } else {\n // In environments without waitUntil, export synchronously-ish\n void exportSpans(traceId, ctx);\n }\n }\n}\n\n/**\n * Create an OtelObservability instance\n *\n * @example\n * ```typescript\n * import { Agent } from 'agents'\n * import { createOtelObservability } from 'autotel-cloudflare/agents'\n *\n * class MyAgent extends Agent<Env> {\n * observability = createOtelObservability({\n * service: { name: 'my-agent' },\n * exporter: { url: env.OTLP_ENDPOINT }\n * })\n * }\n * ```\n */\nexport function createOtelObservability(config: OtelObservabilityConfig): OtelObservability {\n return new OtelObservability(config);\n}\n\n/**\n * Create an OtelObservability instance with environment-based config\n *\n * Use this when you need to access environment variables for configuration.\n *\n * @example\n * ```typescript\n * import { Agent } from 'agents'\n * import { createOtelObservabilityFromEnv } from 'autotel-cloudflare/agents'\n *\n * class MyAgent extends Agent<Env> {\n * observability?: OtelObservability\n *\n * constructor(state: DurableObjectState, env: Env) {\n * super(state, env)\n * this.observability = createOtelObservabilityFromEnv(env)\n * }\n * }\n * ```\n */\nexport function createOtelObservabilityFromEnv(\n env: Record<string, unknown>,\n options?: AgentInstrumentationOptions,\n): OtelObservability {\n // Extract standard OTLP env vars\n const endpoint = (env.OTEL_EXPORTER_OTLP_ENDPOINT as string) || undefined;\n const serviceName = (env.OTEL_SERVICE_NAME as string) || 'cloudflare-agent';\n\n // Parse headers if present\n let headers: Record<string, string> | undefined;\n const headersStr = env.OTEL_EXPORTER_OTLP_HEADERS as string;\n if (headersStr) {\n headers = {};\n for (const pair of headersStr.split(',')) {\n const [key, value] = pair.split('=');\n if (key && value) {\n headers[key.trim()] = value.trim();\n }\n }\n }\n\n // If no endpoint is configured, use a default localhost endpoint\n // In production, users should set OTEL_EXPORTER_OTLP_ENDPOINT\n const exporterUrl = endpoint || 'http://localhost:4318/v1/traces';\n\n return createOtelObservability({\n service: { name: serviceName },\n exporter: { url: exporterUrl, headers },\n agents: options,\n });\n}\n"],"mappings":"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"}
|