@agentuity/server 0.0.5 → 0.0.6

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 (82) hide show
  1. package/AGENTS.md +29 -96
  2. package/README.md +31 -196
  3. package/dist/config.d.ts +11 -0
  4. package/dist/config.d.ts.map +1 -0
  5. package/dist/config.js +13 -0
  6. package/dist/config.js.map +1 -0
  7. package/dist/index.d.ts +4 -5
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +4 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/server.d.ts +22 -0
  12. package/dist/server.d.ts.map +1 -0
  13. package/dist/server.js +107 -0
  14. package/dist/server.js.map +1 -0
  15. package/package.json +11 -32
  16. package/dist/_config.d.ts +0 -61
  17. package/dist/_config.d.ts.map +0 -1
  18. package/dist/_context.d.ts +0 -33
  19. package/dist/_context.d.ts.map +0 -1
  20. package/dist/_idle.d.ts +0 -7
  21. package/dist/_idle.d.ts.map +0 -1
  22. package/dist/_server.d.ts +0 -17
  23. package/dist/_server.d.ts.map +0 -1
  24. package/dist/_services.d.ts +0 -2
  25. package/dist/_services.d.ts.map +0 -1
  26. package/dist/_util.d.ts +0 -16
  27. package/dist/_util.d.ts.map +0 -1
  28. package/dist/_waituntil.d.ts +0 -20
  29. package/dist/_waituntil.d.ts.map +0 -1
  30. package/dist/agent.d.ts +0 -88
  31. package/dist/agent.d.ts.map +0 -1
  32. package/dist/app.d.ts +0 -24
  33. package/dist/app.d.ts.map +0 -1
  34. package/dist/logger/console.d.ts +0 -50
  35. package/dist/logger/console.d.ts.map +0 -1
  36. package/dist/logger/index.d.ts +0 -4
  37. package/dist/logger/index.d.ts.map +0 -1
  38. package/dist/logger/internal.d.ts +0 -79
  39. package/dist/logger/internal.d.ts.map +0 -1
  40. package/dist/logger/logger.d.ts +0 -41
  41. package/dist/logger/logger.d.ts.map +0 -1
  42. package/dist/logger/user.d.ts +0 -8
  43. package/dist/logger/user.d.ts.map +0 -1
  44. package/dist/logger/util.d.ts +0 -11
  45. package/dist/logger/util.d.ts.map +0 -1
  46. package/dist/otel/config.d.ts +0 -17
  47. package/dist/otel/config.d.ts.map +0 -1
  48. package/dist/otel/console.d.ts +0 -26
  49. package/dist/otel/console.d.ts.map +0 -1
  50. package/dist/otel/fetch.d.ts +0 -12
  51. package/dist/otel/fetch.d.ts.map +0 -1
  52. package/dist/otel/http.d.ts +0 -16
  53. package/dist/otel/http.d.ts.map +0 -1
  54. package/dist/otel/logger.d.ts +0 -36
  55. package/dist/otel/logger.d.ts.map +0 -1
  56. package/dist/otel/otel.d.ts +0 -58
  57. package/dist/otel/otel.d.ts.map +0 -1
  58. package/dist/router.d.ts +0 -37
  59. package/dist/router.d.ts.map +0 -1
  60. package/src/_config.ts +0 -101
  61. package/src/_context.ts +0 -88
  62. package/src/_idle.ts +0 -26
  63. package/src/_server.ts +0 -278
  64. package/src/_services.ts +0 -175
  65. package/src/_util.ts +0 -63
  66. package/src/_waituntil.ts +0 -246
  67. package/src/agent.ts +0 -287
  68. package/src/app.ts +0 -31
  69. package/src/index.ts +0 -5
  70. package/src/logger/console.ts +0 -111
  71. package/src/logger/index.ts +0 -3
  72. package/src/logger/internal.ts +0 -165
  73. package/src/logger/logger.ts +0 -44
  74. package/src/logger/user.ts +0 -11
  75. package/src/logger/util.ts +0 -80
  76. package/src/otel/config.ts +0 -81
  77. package/src/otel/console.ts +0 -56
  78. package/src/otel/fetch.ts +0 -103
  79. package/src/otel/http.ts +0 -51
  80. package/src/otel/logger.ts +0 -238
  81. package/src/otel/otel.ts +0 -317
  82. package/src/router.ts +0 -303
@@ -1,238 +0,0 @@
1
- import { format } from 'node:util';
2
- import { safeStringify } from '@agentuity/core';
3
- import * as LogsAPI from '@opentelemetry/api-logs';
4
- import type { Logger } from '../logger';
5
- import ConsoleLogger from '../logger/console';
6
- import { getAgentContext } from '../_context';
7
-
8
- /**
9
- * Reference to the original console object before patching
10
- */
11
- export const __originalConsole = Object.create(console); // save the original console before we patch it
12
-
13
- export class OtelLogger implements Logger {
14
- private readonly delegates: LogsAPI.Logger[];
15
- private readonly context: Record<string, unknown> | undefined;
16
- private readonly logger: ConsoleLogger | undefined;
17
-
18
- constructor(
19
- useConsole: boolean,
20
- delegates: LogsAPI.Logger | LogsAPI.Logger[],
21
- context?: Record<string, unknown> | undefined
22
- ) {
23
- this.delegates = Array.isArray(delegates) ? delegates : [delegates];
24
- this.context = context;
25
- this.logger = useConsole ? new ConsoleLogger(context, false) : undefined;
26
- }
27
-
28
- addDelegate(delegate: LogsAPI.Logger) {
29
- this.delegates.push(delegate);
30
- }
31
-
32
- private formatMessage(message: unknown) {
33
- if (typeof message === 'string') {
34
- return message;
35
- }
36
- try {
37
- return safeStringify(message);
38
- } catch {
39
- // Handle circular references or other unknown stringification errors
40
- return String(message);
41
- }
42
- }
43
-
44
- private getAttributes(): Record<string, unknown> | undefined {
45
- try {
46
- const actx = getAgentContext();
47
- const current = actx.current?.metadata;
48
- if (current) {
49
- const result: Record<string, unknown> = {
50
- ...(this.context ?? {}),
51
- };
52
- for (const [key, value] of Object.entries(current)) {
53
- if (value !== null && value !== undefined) {
54
- result[`@agentuity/${key}`] = value as unknown;
55
- }
56
- }
57
- return result;
58
- }
59
- } catch {
60
- /* fall through */
61
- }
62
- return this.context;
63
- }
64
-
65
- private emitToAll(severityNumber: LogsAPI.SeverityNumber, severityText: string, body: string) {
66
- const attributes = this.getAttributes();
67
-
68
- this.delegates.forEach((delegate) => {
69
- try {
70
- delegate.emit({
71
- severityNumber,
72
- severityText,
73
- body,
74
- attributes: attributes as LogsAPI.LogRecord['attributes'],
75
- });
76
- } catch (error) {
77
- // Log error to console if available, but don't fail the entire operation
78
- this.logger?.error('Failed to emit log to OTLP instance:', error);
79
- }
80
- });
81
- }
82
-
83
- debug(message: string, ...args: unknown[]) {
84
- this.logger?.debug(message, ...args);
85
- let body: string;
86
- try {
87
- body = format(this.formatMessage(message), ...args);
88
- } catch {
89
- // Fallback if format causes recursion
90
- body = `${this.formatMessage(message)} ${args.map((arg) => String(arg)).join(' ')}`;
91
- }
92
- this.emitToAll(LogsAPI.SeverityNumber.DEBUG, 'DEBUG', body);
93
- }
94
- info(message: string, ...args: unknown[]) {
95
- this.logger?.info(message, ...args);
96
- let body: string;
97
- try {
98
- body = format(this.formatMessage(message), ...args);
99
- } catch {
100
- // Fallback if format causes recursion
101
- body = `${this.formatMessage(message)} ${args.map((arg) => String(arg)).join(' ')}`;
102
- }
103
- this.emitToAll(LogsAPI.SeverityNumber.INFO, 'INFO', body);
104
- }
105
- warn(message: string, ...args: unknown[]) {
106
- this.logger?.warn(message, ...args);
107
- let body: string;
108
- try {
109
- body = format(this.formatMessage(message), ...args);
110
- } catch {
111
- // Fallback if format causes recursion
112
- body = `${this.formatMessage(message)} ${args.map((arg) => String(arg)).join(' ')}`;
113
- }
114
- this.emitToAll(LogsAPI.SeverityNumber.WARN, 'WARN', body);
115
- }
116
- error(message: string, ...args: unknown[]) {
117
- this.logger?.error(message, ...args);
118
- let body: string;
119
- try {
120
- body = format(this.formatMessage(message), ...args);
121
- } catch {
122
- // Fallback if format causes recursion
123
- body = `${this.formatMessage(message)} ${args.map((arg) => String(arg)).join(' ')}`;
124
- }
125
- this.emitToAll(LogsAPI.SeverityNumber.ERROR, 'ERROR', body);
126
- }
127
- child(opts: Record<string, unknown>) {
128
- return new OtelLogger(!!this.logger, this.delegates, {
129
- ...(this.context ?? {}),
130
- ...opts,
131
- });
132
- }
133
- }
134
-
135
- /**
136
- * Creates a logger that integrates with OpenTelemetry
137
- *
138
- * @param useConsole - Whether to also log to the console
139
- * @param context - Additional context to include with log records
140
- * @returns A logger instance
141
- */
142
- export function createLogger(useConsole: boolean, context?: Record<string, unknown>): Logger {
143
- const delegate = LogsAPI.logs.getLogger('default', undefined, {
144
- scopeAttributes: context as LogsAPI.LoggerOptions['scopeAttributes'],
145
- });
146
- return new OtelLogger(useConsole, [delegate], context);
147
- }
148
-
149
- /**
150
- * Patches the global console object to integrate with OpenTelemetry logging
151
- *
152
- * @param attributes - Attributes to include with all console log records
153
- */
154
- export function patchConsole(enabled: boolean, attributes: Record<string, unknown>) {
155
- if (!enabled) {
156
- return;
157
- }
158
- const _patch = { ...__originalConsole };
159
- const delegate = createLogger(true, attributes);
160
-
161
- // Patch individual console methods instead of reassigning the whole object
162
- _patch.log = (...args: unknown[]) => {
163
- delegate.info(args[0] as string, ...args.slice(1));
164
- };
165
- _patch.error = (...args: unknown[]) => {
166
- delegate.error(args[0] as string, ...args.slice(1));
167
- };
168
- _patch.warn = (...args: unknown[]) => {
169
- delegate.warn(args[0] as string, ...args.slice(1));
170
- };
171
- _patch.debug = (...args: unknown[]) => {
172
- delegate.debug(args[0] as string, ...args.slice(1));
173
- };
174
- _patch.info = (...args: unknown[]) => {
175
- delegate.info(args[0] as string, ...args.slice(1));
176
- };
177
- _patch.dir = (...args: unknown[]) => {
178
- let msg = '';
179
- if (args.length === 1) {
180
- msg = format(args[0]);
181
- } else if (args.length >= 2) {
182
- msg = format(args[0], args[1]);
183
- } else {
184
- msg = safeStringify(args);
185
- }
186
- delegate.debug(msg);
187
- };
188
- _patch.dirxml = (...args: unknown[]) => {
189
- delegate.debug('dirxml:', ...args);
190
- };
191
- _patch.table = (...args: unknown[]) => {
192
- delegate.debug('table:', ...args);
193
- };
194
- _patch.trace = (...args: unknown[]) => {
195
- delegate.debug(args[0] as string, ...args.slice(1));
196
- };
197
- _patch.group = (...args: unknown[]) => {
198
- delegate.debug('group:', ...args);
199
- };
200
- _patch.groupCollapsed = (...args: unknown[]) => {
201
- delegate.debug('groupCollapsed:', ...args);
202
- };
203
- _patch.groupEnd = () => {
204
- delegate.debug('groupEnd');
205
- };
206
- _patch.clear = () => {
207
- /* no-op */
208
- };
209
- _patch.count = (...args: unknown[]) => {
210
- delegate.debug('count:', ...args);
211
- };
212
- _patch.countReset = (...args: unknown[]) => {
213
- delegate.debug('countReset:', ...args);
214
- };
215
- _patch.assert = (condition?: boolean, ...args: unknown[]) => {
216
- if (!condition) {
217
- delegate.error('assertion failed:', ...args);
218
- }
219
- };
220
- _patch.time = (...args: unknown[]) => {
221
- delegate.debug('time:', ...args);
222
- };
223
- _patch.timeLog = (...args: unknown[]) => {
224
- delegate.debug('timeLog:', ...args);
225
- };
226
- _patch.timeEnd = (...args: unknown[]) => {
227
- delegate.debug('timeEnd:', ...args);
228
- };
229
- _patch.profile = (...args: unknown[]) => {
230
- delegate.debug('profile:', ...args);
231
- };
232
- _patch.profileEnd = (...args: unknown[]) => {
233
- delegate.debug('profileEnd:', ...args);
234
- };
235
-
236
- // eslint-disable-next-line no-global-assign
237
- console = globalThis.console = _patch;
238
- }
package/src/otel/otel.ts DELETED
@@ -1,317 +0,0 @@
1
- import type { SpanProcessor } from '@opentelemetry/sdk-trace-base';
2
- import opentelemetry, { type Meter, metrics, propagation, type Tracer } from '@opentelemetry/api';
3
- import * as LogsAPI from '@opentelemetry/api-logs';
4
- import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
5
- import {
6
- CompositePropagator,
7
- W3CBaggagePropagator,
8
- W3CTraceContextPropagator,
9
- } from '@opentelemetry/core';
10
- import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';
11
- import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';
12
- import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
13
- import { HostMetrics } from '@opentelemetry/host-metrics';
14
- import { CompressionAlgorithm } from '@opentelemetry/otlp-exporter-base';
15
- import { resourceFromAttributes } from '@opentelemetry/resources';
16
- import type { Resource } from '@opentelemetry/resources';
17
- import {
18
- BatchLogRecordProcessor,
19
- LoggerProvider,
20
- type LogRecordProcessor,
21
- SimpleLogRecordProcessor,
22
- } from '@opentelemetry/sdk-logs';
23
- import { MeterProvider, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
24
- import { NodeSDK } from '@opentelemetry/sdk-node';
25
- import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from '@opentelemetry/semantic-conventions';
26
- import { initialize } from '@traceloop/node-server-sdk';
27
- import type { Logger } from '../logger';
28
- import { ConsoleLogRecordExporter } from './console';
29
- import { instrumentFetch } from './fetch';
30
- import { createLogger, patchConsole } from './logger';
31
- import { getSDKVersion } from '../_config';
32
-
33
- /**
34
- * Configuration for OpenTelemetry initialization
35
- */
36
- export interface OtelConfig {
37
- url?: string;
38
- name: string;
39
- version: string;
40
- bearerToken?: string;
41
- orgId?: string;
42
- projectId?: string;
43
- deploymentId?: string;
44
- environment?: string;
45
- cliVersion?: string;
46
- devmode?: boolean;
47
- spanProcessors?: Array<SpanProcessor>;
48
- }
49
-
50
- /**
51
- * Response from OpenTelemetry initialization
52
- */
53
- export interface OtelResponse {
54
- tracer: Tracer;
55
- meter: Meter;
56
- logger: Logger;
57
- shutdown: () => Promise<void>;
58
- }
59
-
60
- const devmodeExportInterval = 1_000; // 1 second
61
- const productionExportInterval = 10_000; // 10 seconds
62
-
63
- export const createResource = (config: OtelConfig): Resource => {
64
- const { name, version, orgId, projectId, deploymentId, environment, devmode, cliVersion } =
65
- config;
66
-
67
- const sdkVersion = getSDKVersion();
68
-
69
- return resourceFromAttributes({
70
- [ATTR_SERVICE_NAME]: name,
71
- [ATTR_SERVICE_VERSION]: version,
72
- '@agentuity/orgId': orgId ?? 'unknown',
73
- '@agentuity/projectId': projectId ?? 'unknown',
74
- '@agentuity/deploymentId': deploymentId ?? 'unknown',
75
- '@agentuity/env': environment,
76
- '@agentuity/devmode': devmode,
77
- '@agentuity/sdkVersion': sdkVersion ?? 'unknown',
78
- '@agentuity/cliVersion': cliVersion ?? 'unknown',
79
- });
80
- };
81
-
82
- export const createAgentuityLoggerProvider = ({
83
- url,
84
- headers,
85
- resource,
86
- }: {
87
- url?: string;
88
- headers?: Record<string, string>;
89
- resource: Resource;
90
- }) => {
91
- let processor: LogRecordProcessor;
92
- let exporter: OTLPLogExporter | undefined;
93
-
94
- if (url) {
95
- exporter = new OTLPLogExporter({
96
- url: `${url}/v1/logs`,
97
- headers,
98
- compression: CompressionAlgorithm.GZIP,
99
- timeoutMillis: 10_000,
100
- });
101
- processor = new BatchLogRecordProcessor(exporter);
102
- } else {
103
- processor = new SimpleLogRecordProcessor(new ConsoleLogRecordExporter());
104
- }
105
- const provider = new LoggerProvider({
106
- resource,
107
- processors: [processor],
108
- });
109
- LogsAPI.logs.setGlobalLoggerProvider(provider);
110
-
111
- return {
112
- processor,
113
- provider,
114
- exporter,
115
- };
116
- };
117
-
118
- export const createUserLoggerProvider = ({
119
- url,
120
- headers,
121
- resource,
122
- }: {
123
- url: string;
124
- headers?: Record<string, string>;
125
- resource: Resource;
126
- }) => {
127
- const exporter = new OTLPLogExporter({
128
- url: `${url}/v1/logs`,
129
- headers,
130
- compression: CompressionAlgorithm.GZIP,
131
- timeoutMillis: 10_000,
132
- });
133
- const processor = new BatchLogRecordProcessor(exporter);
134
- const provider = new LoggerProvider({
135
- resource,
136
- processors: [processor],
137
- });
138
- return {
139
- provider,
140
- exporter,
141
- processor,
142
- };
143
- };
144
-
145
- /**
146
- * Registers and initializes OpenTelemetry with the specified configuration
147
- *
148
- * @param config - The configuration for OpenTelemetry
149
- * @returns An object containing the tracer, logger, and shutdown function
150
- */
151
- export function registerOtel(config: OtelConfig): OtelResponse {
152
- const {
153
- url,
154
- name,
155
- version,
156
- bearerToken,
157
- environment = 'development',
158
- orgId,
159
- projectId,
160
- deploymentId,
161
- devmode = false,
162
- } = config;
163
-
164
- let headers: Record<string, string> | undefined;
165
-
166
- if (bearerToken) {
167
- headers = {};
168
- headers.Authorization = `Bearer ${bearerToken}`;
169
- }
170
-
171
- const resource = createResource(config);
172
- const loggerProvider = createAgentuityLoggerProvider({
173
- url,
174
- headers,
175
- resource,
176
- });
177
- const attrs = {
178
- '@agentuity/orgId': orgId ?? 'unknown',
179
- '@agentuity/projectId': projectId ?? 'unknown',
180
- '@agentuity/deploymentId': deploymentId ?? 'unknown',
181
- '@agentuity/env': environment,
182
- '@agentuity/devmode': devmode,
183
- '@agentuity/language': 'javascript',
184
- };
185
- const logger = createLogger(!!url, attrs);
186
-
187
- // must do this after we have created the logger
188
- patchConsole(!!url, attrs);
189
-
190
- const traceExporter = url
191
- ? new OTLPTraceExporter({
192
- url: `${url}/v1/traces`,
193
- headers,
194
- keepAlive: true,
195
- })
196
- : undefined;
197
-
198
- const metricExporter = url
199
- ? new OTLPMetricExporter({
200
- url: `${url}/v1/metrics`,
201
- headers,
202
- keepAlive: true,
203
- })
204
- : undefined;
205
-
206
- // Create a separate metric reader for the NodeSDK
207
- const sdkMetricReader =
208
- url && metricExporter
209
- ? new PeriodicExportingMetricReader({
210
- exporter: metricExporter,
211
- exportTimeoutMillis: devmode ? devmodeExportInterval : productionExportInterval,
212
- exportIntervalMillis: devmode ? devmodeExportInterval : productionExportInterval,
213
- })
214
- : undefined;
215
-
216
- // Create a separate metric reader for the MeterProvider
217
- const hostMetricReader =
218
- url && metricExporter
219
- ? new PeriodicExportingMetricReader({
220
- exporter: metricExporter,
221
- exportTimeoutMillis: devmode ? devmodeExportInterval : productionExportInterval,
222
- exportIntervalMillis: devmode ? devmodeExportInterval : productionExportInterval,
223
- })
224
- : undefined;
225
-
226
- const meterProvider = hostMetricReader
227
- ? new MeterProvider({
228
- resource,
229
- readers: [hostMetricReader],
230
- })
231
- : undefined;
232
-
233
- if (meterProvider) {
234
- metrics.setGlobalMeterProvider(meterProvider);
235
- }
236
-
237
- const hostMetrics = meterProvider ? new HostMetrics({ meterProvider }) : undefined;
238
-
239
- let running = false;
240
- let instrumentationSDK: NodeSDK | undefined;
241
-
242
- if (url) {
243
- const propagator = new CompositePropagator({
244
- propagators: [new W3CTraceContextPropagator(), new W3CBaggagePropagator()],
245
- });
246
- propagation.setGlobalPropagator(propagator);
247
-
248
- instrumentFetch();
249
- instrumentationSDK = new NodeSDK({
250
- logRecordProcessor: loggerProvider.processor,
251
- traceExporter,
252
- metricReader: sdkMetricReader,
253
- instrumentations: [getNodeAutoInstrumentations()],
254
- resource,
255
- textMapPropagator: propagator,
256
- spanProcessors: config.spanProcessors,
257
- });
258
- instrumentationSDK.start();
259
- hostMetrics?.start();
260
-
261
- try {
262
- const projectName = config.projectId || '';
263
- const orgName = config.orgId || '';
264
- const appName = `${orgName}:${projectName}`;
265
-
266
- const traceloopHeaders: Record<string, string> = {};
267
- if (bearerToken) {
268
- traceloopHeaders.Authorization = `Bearer ${bearerToken}`;
269
- }
270
-
271
- initialize({
272
- appName,
273
- baseUrl: url,
274
- headers: traceloopHeaders,
275
- disableBatch: devmode,
276
- logLevel: 'error',
277
- tracingEnabled: false, // Disable traceloop's own tracing (equivalent to Python's telemetryEnabled: false)
278
- // Note: JavaScript SDK doesn't support resourceAttributes like Python
279
- });
280
- logger.debug(`Telemetry initialized with app_name: ${appName}`);
281
- logger.info('Telemetry configured successfully');
282
- } catch (error) {
283
- logger.warn('Telemetry not available, skipping automatic instrumentation', {
284
- error: error instanceof Error ? error.message : String(error),
285
- });
286
- }
287
- running = true;
288
- }
289
-
290
- const tracer = opentelemetry.trace.getTracer(name, version);
291
- const meter = metrics.getMeter(name, version);
292
-
293
- const shutdown = async () => {
294
- if (running) {
295
- running = false;
296
- logger.debug('shutting down OpenTelemetry');
297
- await loggerProvider.provider
298
- .forceFlush()
299
- .catch((e) => logger.warn('error in forceFlush of otel provider. %s', e));
300
- await loggerProvider.exporter
301
- ?.shutdown()
302
- .catch((e) => !devmode && logger.warn('error in shutdown of otel exporter. %s', e));
303
- await instrumentationSDK
304
- ?.shutdown()
305
- .catch(
306
- (e) => !devmode && logger.warn('error in shutdown of otel instrumentation. %s', e)
307
- );
308
- logger.debug('shut down OpenTelemetry');
309
- }
310
- };
311
-
312
- if (url) {
313
- logger.debug('connected to Agentuity Agent Cloud');
314
- }
315
-
316
- return { tracer, meter, logger, shutdown };
317
- }