@agentuity/runtime 0.1.24 → 0.1.26

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/src/otel/otel.ts CHANGED
@@ -24,7 +24,6 @@ import {
24
24
  import { MeterProvider, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
25
25
  import { NodeSDK } from '@opentelemetry/sdk-node';
26
26
  import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from '@opentelemetry/semantic-conventions';
27
- import { initialize } from '@traceloop/node-server-sdk';
28
27
  import type { Logger } from '../logger';
29
28
  import { ConsoleLogRecordExporter, DebugSpanExporter } from './console';
30
29
  import { instrumentFetch } from './fetch';
@@ -308,35 +307,8 @@ export function registerOtel(config: OtelConfig): OtelResponse {
308
307
  instrumentationSDK.start();
309
308
  hostMetrics?.start();
310
309
 
311
- try {
312
- const projectName = config.projectId || '';
313
- const orgId = config.orgId || '';
314
- const appName = `${orgId}:${projectName}`;
315
-
316
- const traceloopHeaders: Record<string, string> = {};
317
- if (bearerToken) {
318
- traceloopHeaders.Authorization = `Bearer ${bearerToken}`;
319
- }
320
-
321
- initialize({
322
- appName,
323
- baseUrl: url,
324
- headers: traceloopHeaders,
325
- disableBatch: devmode,
326
- propagator,
327
- silenceInitializationMessage: true,
328
- traceloopSyncEnabled: false,
329
- tracingEnabled: false, // Disable traceloop's own tracing (equivalent to Python's telemetryEnabled: false)
330
- // Note: JavaScript SDK doesn't support resourceAttributes like Python
331
- });
332
- logger.debug(`Telemetry initialized with app_name: ${appName}`);
333
- logger.debug('Telemetry configured successfully');
334
- logger.debug('Sending telemetry data to %s', url);
335
- } catch (error) {
336
- logger.warn('Telemetry not available, skipping automatic instrumentation', {
337
- error: error instanceof Error ? error.message : String(error),
338
- });
339
- }
310
+ logger.debug('Telemetry configured successfully');
311
+ logger.debug('Sending telemetry data to %s', url);
340
312
  running = true;
341
313
  }
342
314
 
@@ -13,6 +13,7 @@ import {
13
13
  type Logger,
14
14
  StructuredError,
15
15
  } from '@agentuity/core';
16
+ import { context, trace, SpanStatusCode } from '@opentelemetry/api';
16
17
  import { internal } from '../../logger/internal';
17
18
 
18
19
  const EvalRunResponseError = StructuredError('EvalRunResponseError');
@@ -37,6 +38,10 @@ export class HTTPEvalRunEventProvider implements EvalRunEventProvider {
37
38
  * @param event EvalRunStartEvent
38
39
  */
39
40
  async start(event: EvalRunStartEvent): Promise<void> {
41
+ const tracer = trace.getTracer('evalrun');
42
+ const currentContext = context.active();
43
+ const span = tracer.startSpan('Eval Start', {}, currentContext);
44
+
40
45
  const endpoint = '/evalrun/2025-03-17';
41
46
  const fullUrl = `${this.baseUrl}${endpoint}`;
42
47
 
@@ -57,18 +62,24 @@ export class HTTPEvalRunEventProvider implements EvalRunEventProvider {
57
62
  internal.info('[EVALRUN HTTP] ============================================');
58
63
 
59
64
  try {
60
- const resp = await this.apiClient.post(
61
- endpoint,
62
- payload,
63
- APIResponseSchemaNoData(),
64
- EvalRunStartEventDelayedSchema
65
+ const spanContext = trace.setSpan(currentContext, span);
66
+ const resp = await context.with(spanContext, () =>
67
+ this.apiClient.post(
68
+ endpoint,
69
+ payload,
70
+ APIResponseSchemaNoData(),
71
+ EvalRunStartEventDelayedSchema
72
+ )
65
73
  );
74
+
66
75
  if (resp.success) {
67
76
  this.logger.debug('[EVALRUN HTTP] Start event sent successfully: %s', event.id);
77
+ span.setStatus({ code: SpanStatusCode.OK });
68
78
  return;
69
79
  }
70
80
  const errorMsg = resp.message || 'Unknown error';
71
81
  this.logger.error('[EVALRUN HTTP] Start event failed: %s, error: %s', event.id, errorMsg);
82
+ span.setStatus({ code: SpanStatusCode.ERROR, message: errorMsg });
72
83
  throw new EvalRunResponseError({ message: errorMsg });
73
84
  } catch (error) {
74
85
  this.logger.error(
@@ -86,7 +97,14 @@ export class HTTPEvalRunEventProvider implements EvalRunEventProvider {
86
97
  JSON.stringify(error.issues, null, 2)
87
98
  );
88
99
  }
100
+ span.recordException(error as Error);
101
+ span.setStatus({
102
+ code: SpanStatusCode.ERROR,
103
+ message: error instanceof Error ? error.message : String(error),
104
+ });
89
105
  throw error;
106
+ } finally {
107
+ span.end();
90
108
  }
91
109
  }
92
110
 
@@ -96,6 +114,10 @@ export class HTTPEvalRunEventProvider implements EvalRunEventProvider {
96
114
  * @param event EvalRunCompleteEvent
97
115
  */
98
116
  async complete(event: EvalRunCompleteEvent): Promise<void> {
117
+ const tracer = trace.getTracer('evalrun');
118
+ const currentContext = context.active();
119
+ const span = tracer.startSpan('Eval End', {}, currentContext);
120
+
99
121
  const endpoint = '/evalrun/2025-03-17';
100
122
  const fullUrl = `${this.baseUrl}${endpoint}`;
101
123
  this.logger.debug('[EVALRUN HTTP] Sending eval run complete event: %s', event.id);
@@ -103,14 +125,19 @@ export class HTTPEvalRunEventProvider implements EvalRunEventProvider {
103
125
  this.logger.debug('[EVALRUN HTTP] Base URL: %s', this.baseUrl);
104
126
 
105
127
  try {
106
- const resp = await this.apiClient.put(
107
- endpoint,
108
- { ...event, timestamp: Date.now() },
109
- APIResponseSchemaNoData(),
110
- EvalRunCompleteEventDelayedSchema
128
+ const spanContext = trace.setSpan(currentContext, span);
129
+ const resp = await context.with(spanContext, () =>
130
+ this.apiClient.put(
131
+ endpoint,
132
+ { ...event, timestamp: Date.now() },
133
+ APIResponseSchemaNoData(),
134
+ EvalRunCompleteEventDelayedSchema
135
+ )
111
136
  );
137
+
112
138
  if (resp.success) {
113
139
  this.logger.debug('[EVALRUN HTTP] Complete event sent successfully: %s', event.id);
140
+ span.setStatus({ code: SpanStatusCode.OK });
114
141
  return;
115
142
  }
116
143
  const errorMsg = resp.message || 'Unknown error';
@@ -119,6 +146,7 @@ export class HTTPEvalRunEventProvider implements EvalRunEventProvider {
119
146
  event.id,
120
147
  errorMsg
121
148
  );
149
+ span.setStatus({ code: SpanStatusCode.ERROR, message: errorMsg });
122
150
  throw new EvalRunResponseError({ message: errorMsg });
123
151
  } catch (error) {
124
152
  this.logger.error(
@@ -126,7 +154,14 @@ export class HTTPEvalRunEventProvider implements EvalRunEventProvider {
126
154
  event.id,
127
155
  error instanceof Error ? error.message : String(error)
128
156
  );
157
+ span.recordException(error as Error);
158
+ span.setStatus({
159
+ code: SpanStatusCode.ERROR,
160
+ message: error instanceof Error ? error.message : String(error),
161
+ });
129
162
  throw error;
163
+ } finally {
164
+ span.end();
130
165
  }
131
166
  }
132
167
  }
@@ -8,6 +8,7 @@ import {
8
8
  type Logger,
9
9
  StructuredError,
10
10
  } from '@agentuity/core';
11
+ import { context, trace, SpanStatusCode } from '@opentelemetry/api';
11
12
  import { internal } from '../../logger/internal';
12
13
 
13
14
  const SessionResponseError = StructuredError('SessionResponseError');
@@ -54,22 +55,44 @@ export class HTTPSessionEventProvider implements SessionEventProvider {
54
55
  return;
55
56
  }
56
57
 
57
- internal.info('[session-http] sending start event: %s', event.id);
58
- this.logger.debug('Sending session start event: %s', event.id);
59
- const resp = await this.apiClient.post(
60
- '/session/2025-03-17',
61
- { ...event, timestamp: Date.now() },
62
- APIResponseSchemaNoData(),
63
- SessionStartEventDelayedSchema
64
- );
65
- if (resp.success) {
66
- internal.info('[session-http] start event sent successfully: %s', event.id);
67
- this.logger.debug('Session start event sent successfully: %s', event.id);
68
- this.startedSessions.add(event.id);
69
- return;
58
+ const tracer = trace.getTracer('session');
59
+ const currentContext = context.active();
60
+ const span = tracer.startSpan('Session Start', {}, currentContext);
61
+
62
+ try {
63
+ internal.info('[session-http] sending start event: %s', event.id);
64
+ this.logger.debug('Sending session start event: %s', event.id);
65
+
66
+ const spanContext = trace.setSpan(currentContext, span);
67
+ const resp = await context.with(spanContext, () =>
68
+ this.apiClient.post(
69
+ '/session/2025-03-17',
70
+ { ...event, timestamp: Date.now() },
71
+ APIResponseSchemaNoData(),
72
+ SessionStartEventDelayedSchema
73
+ )
74
+ );
75
+
76
+ if (resp.success) {
77
+ internal.info('[session-http] start event sent successfully: %s', event.id);
78
+ this.logger.debug('Session start event sent successfully: %s', event.id);
79
+ this.startedSessions.add(event.id);
80
+ span.setStatus({ code: SpanStatusCode.OK });
81
+ return;
82
+ }
83
+ internal.info('[session-http] start event failed: %s - %s', event.id, resp.message);
84
+ span.setStatus({ code: SpanStatusCode.ERROR, message: resp.message });
85
+ throw new SessionResponseError({ message: resp.message });
86
+ } catch (error) {
87
+ span.recordException(error as Error);
88
+ span.setStatus({
89
+ code: SpanStatusCode.ERROR,
90
+ message: error instanceof Error ? error.message : String(error),
91
+ });
92
+ throw error;
93
+ } finally {
94
+ span.end();
70
95
  }
71
- internal.info('[session-http] start event failed: %s - %s', event.id, resp.message);
72
- throw new SessionResponseError({ message: resp.message });
73
96
  }
74
97
 
75
98
  /**
@@ -91,24 +114,46 @@ export class HTTPSessionEventProvider implements SessionEventProvider {
91
114
  }
92
115
  this.startedSessions.delete(event.id);
93
116
 
94
- internal.info(
95
- '[session-http] sending complete event: %s, userData: %s',
96
- event.id,
97
- event.userData ? `${event.userData.length} bytes` : 'none'
98
- );
99
- this.logger.debug('Sending session complete event: %s', event.id);
100
- const resp = await this.apiClient.put(
101
- '/session/2025-03-17',
102
- { ...event, timestamp: Date.now() },
103
- APIResponseSchemaNoData(),
104
- SessionCompleteEventDelayedSchema
105
- );
106
- if (resp.success) {
107
- internal.info('[session-http] complete event sent successfully: %s', event.id);
108
- this.logger.debug('Session complete event sent successfully: %s', event.id);
109
- return;
117
+ const tracer = trace.getTracer('session');
118
+ const currentContext = context.active();
119
+ const span = tracer.startSpan('Session End', {}, currentContext);
120
+
121
+ try {
122
+ internal.info(
123
+ '[session-http] sending complete event: %s, userData: %s',
124
+ event.id,
125
+ event.userData ? `${event.userData.length} bytes` : 'none'
126
+ );
127
+ this.logger.debug('Sending session complete event: %s', event.id);
128
+
129
+ const spanContext = trace.setSpan(currentContext, span);
130
+ const resp = await context.with(spanContext, () =>
131
+ this.apiClient.put(
132
+ '/session/2025-03-17',
133
+ { ...event, timestamp: Date.now() },
134
+ APIResponseSchemaNoData(),
135
+ SessionCompleteEventDelayedSchema
136
+ )
137
+ );
138
+
139
+ if (resp.success) {
140
+ internal.info('[session-http] complete event sent successfully: %s', event.id);
141
+ this.logger.debug('Session complete event sent successfully: %s', event.id);
142
+ span.setStatus({ code: SpanStatusCode.OK });
143
+ return;
144
+ }
145
+ internal.info('[session-http] complete event failed: %s - %s', event.id, resp.message);
146
+ span.setStatus({ code: SpanStatusCode.ERROR, message: resp.message });
147
+ throw new SessionResponseError({ message: resp.message });
148
+ } catch (error) {
149
+ span.recordException(error as Error);
150
+ span.setStatus({
151
+ code: SpanStatusCode.ERROR,
152
+ message: error instanceof Error ? error.message : String(error),
153
+ });
154
+ throw error;
155
+ } finally {
156
+ span.end();
110
157
  }
111
- internal.info('[session-http] complete event failed: %s - %s', event.id, resp.message);
112
- throw new SessionResponseError({ message: resp.message });
113
158
  }
114
159
  }