@agentuity/telemetry 3.0.0-alpha.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 (87) hide show
  1. package/dist/console.d.ts +33 -0
  2. package/dist/console.d.ts.map +1 -0
  3. package/dist/console.js +86 -0
  4. package/dist/console.js.map +1 -0
  5. package/dist/exporters/index.d.ts +4 -0
  6. package/dist/exporters/index.d.ts.map +1 -0
  7. package/dist/exporters/index.js +4 -0
  8. package/dist/exporters/index.js.map +1 -0
  9. package/dist/exporters/jsonl-log-exporter.d.ts +36 -0
  10. package/dist/exporters/jsonl-log-exporter.d.ts.map +1 -0
  11. package/dist/exporters/jsonl-log-exporter.js +103 -0
  12. package/dist/exporters/jsonl-log-exporter.js.map +1 -0
  13. package/dist/exporters/jsonl-metric-exporter.d.ts +40 -0
  14. package/dist/exporters/jsonl-metric-exporter.d.ts.map +1 -0
  15. package/dist/exporters/jsonl-metric-exporter.js +104 -0
  16. package/dist/exporters/jsonl-metric-exporter.js.map +1 -0
  17. package/dist/exporters/jsonl-trace-exporter.d.ts +36 -0
  18. package/dist/exporters/jsonl-trace-exporter.d.ts.map +1 -0
  19. package/dist/exporters/jsonl-trace-exporter.js +111 -0
  20. package/dist/exporters/jsonl-trace-exporter.js.map +1 -0
  21. package/dist/fetch.d.ts +12 -0
  22. package/dist/fetch.d.ts.map +1 -0
  23. package/dist/fetch.js +82 -0
  24. package/dist/fetch.js.map +1 -0
  25. package/dist/globals.d.ts +9 -0
  26. package/dist/globals.d.ts.map +1 -0
  27. package/dist/globals.js +13 -0
  28. package/dist/globals.js.map +1 -0
  29. package/dist/http.d.ts +16 -0
  30. package/dist/http.d.ts.map +1 -0
  31. package/dist/http.js +44 -0
  32. package/dist/http.js.map +1 -0
  33. package/dist/index.d.ts +50 -0
  34. package/dist/index.d.ts.map +1 -0
  35. package/dist/index.js +62 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/logger/console.d.ts +69 -0
  38. package/dist/logger/console.d.ts.map +1 -0
  39. package/dist/logger/console.js +278 -0
  40. package/dist/logger/console.js.map +1 -0
  41. package/dist/logger/index.d.ts +4 -0
  42. package/dist/logger/index.d.ts.map +1 -0
  43. package/dist/logger/index.js +3 -0
  44. package/dist/logger/index.js.map +1 -0
  45. package/dist/logger/internal.d.ts +79 -0
  46. package/dist/logger/internal.d.ts.map +1 -0
  47. package/dist/logger/internal.js +133 -0
  48. package/dist/logger/internal.js.map +1 -0
  49. package/dist/logger/user.d.ts +8 -0
  50. package/dist/logger/user.d.ts.map +1 -0
  51. package/dist/logger/user.js +7 -0
  52. package/dist/logger/user.js.map +1 -0
  53. package/dist/logger/util.d.ts +11 -0
  54. package/dist/logger/util.d.ts.map +1 -0
  55. package/dist/logger/util.js +77 -0
  56. package/dist/logger/util.js.map +1 -0
  57. package/dist/logger.d.ts +40 -0
  58. package/dist/logger.d.ts.map +1 -0
  59. package/dist/logger.js +259 -0
  60. package/dist/logger.js.map +1 -0
  61. package/dist/telemetry.d.ts +71 -0
  62. package/dist/telemetry.d.ts.map +1 -0
  63. package/dist/telemetry.js +274 -0
  64. package/dist/telemetry.js.map +1 -0
  65. package/dist/tracestate.d.ts +44 -0
  66. package/dist/tracestate.d.ts.map +1 -0
  67. package/dist/tracestate.js +84 -0
  68. package/dist/tracestate.js.map +1 -0
  69. package/package.json +58 -0
  70. package/src/console.ts +91 -0
  71. package/src/exporters/README.md +217 -0
  72. package/src/exporters/index.ts +3 -0
  73. package/src/exporters/jsonl-log-exporter.ts +113 -0
  74. package/src/exporters/jsonl-metric-exporter.ts +120 -0
  75. package/src/exporters/jsonl-trace-exporter.ts +121 -0
  76. package/src/fetch.ts +105 -0
  77. package/src/globals.ts +18 -0
  78. package/src/http.ts +53 -0
  79. package/src/index.ts +82 -0
  80. package/src/logger/console.ts +322 -0
  81. package/src/logger/index.ts +3 -0
  82. package/src/logger/internal.ts +165 -0
  83. package/src/logger/user.ts +15 -0
  84. package/src/logger/util.ts +80 -0
  85. package/src/logger.ts +285 -0
  86. package/src/telemetry.ts +403 -0
  87. package/src/tracestate.ts +108 -0
@@ -0,0 +1,322 @@
1
+ import type { LogLevel, Logger } from '@agentuity/core';
2
+ import { __originalConsole } from '../logger';
3
+ import { formatMessage } from './util';
4
+
5
+ const BOLD = '\x1b[1m';
6
+ const RESET = '\x1b[0m';
7
+
8
+ // Helper to convert hex color to ANSI 24-bit color code
9
+ function hexToAnsi(hex: string): string {
10
+ const r = parseInt(hex.slice(1, 3), 16);
11
+ const g = parseInt(hex.slice(3, 5), 16);
12
+ const b = parseInt(hex.slice(5, 7), 16);
13
+ return `\x1b[38;2;${r};${g};${b}m`;
14
+ }
15
+
16
+ interface LogColors {
17
+ level: string;
18
+ message: string;
19
+ }
20
+
21
+ function shouldUseColors(): boolean {
22
+ // FORCE_COLOR overrides all checks (used when stdout is piped but we still want colors)
23
+ if (process.env.FORCE_COLOR === '1') {
24
+ return true;
25
+ }
26
+
27
+ // Check for NO_COLOR environment variable (any non-empty value disables colors)
28
+ if (process.env.NO_COLOR) {
29
+ return false;
30
+ }
31
+
32
+ // Check for TERM=dumb
33
+ if (process.env.TERM === 'dumb') {
34
+ return false;
35
+ }
36
+
37
+ // Check if stdout is a TTY
38
+ if (!process.stdout || typeof process.stdout.isTTY === 'undefined') {
39
+ return false;
40
+ }
41
+
42
+ if (process.stdout && typeof process.stdout.isTTY !== 'undefined' && !process.stdout.isTTY) {
43
+ return false;
44
+ }
45
+
46
+ return true;
47
+ }
48
+
49
+ type ColorScheme = 'light' | 'dark';
50
+
51
+ function getLogColors(scheme: ColorScheme): Record<LogLevel, LogColors> {
52
+ if (scheme === 'light') {
53
+ // Darker, high-contrast colors for light backgrounds
54
+ return {
55
+ trace: {
56
+ level: hexToAnsi('#008B8B') + BOLD, // Dark cyan
57
+ message: hexToAnsi('#4B4B4B'), // Dark gray
58
+ },
59
+ debug: {
60
+ level: hexToAnsi('#0000CD') + BOLD, // Medium blue
61
+ message: hexToAnsi('#006400'), // Dark green
62
+ },
63
+ info: {
64
+ level: hexToAnsi('#FF8C00') + BOLD, // Dark orange
65
+ message: hexToAnsi('#0066CC') + BOLD, // Strong blue
66
+ },
67
+ warn: {
68
+ level: hexToAnsi('#9400D3') + BOLD, // Dark violet
69
+ message: hexToAnsi('#8B008B'), // Dark magenta
70
+ },
71
+ error: {
72
+ level: hexToAnsi('#DC143C') + BOLD, // Crimson
73
+ message: hexToAnsi('#8B0000') + BOLD, // Dark red
74
+ },
75
+ };
76
+ }
77
+
78
+ // Dark mode colors (brighter for dark backgrounds)
79
+ return {
80
+ trace: {
81
+ level: hexToAnsi('#00FFFF') + BOLD, // Cyan
82
+ message: hexToAnsi('#A0A0A0'), // Light gray
83
+ },
84
+ debug: {
85
+ level: hexToAnsi('#5C9CFF') + BOLD, // Blue
86
+ message: hexToAnsi('#90EE90'), // Light green
87
+ },
88
+ info: {
89
+ level: hexToAnsi('#FFD700') + BOLD, // Gold/Yellow
90
+ message: hexToAnsi('#FFFFFF') + BOLD, // White
91
+ },
92
+ warn: {
93
+ level: hexToAnsi('#FF00FF') + BOLD, // Magenta
94
+ message: hexToAnsi('#FF00FF'), // Magenta
95
+ },
96
+ error: {
97
+ level: hexToAnsi('#FF4444') + BOLD, // Red
98
+ message: hexToAnsi('#FF4444'), // Red
99
+ },
100
+ };
101
+ }
102
+
103
+ // Detect color scheme from environment
104
+ function detectColorScheme(): ColorScheme {
105
+ const scheme = process.env.COLOR_SCHEME?.toLowerCase();
106
+ if (scheme === 'light' || scheme === 'dark') {
107
+ return scheme;
108
+ }
109
+ if (process.env.CI) {
110
+ return 'light';
111
+ }
112
+ return 'dark'; // Default to dark mode
113
+ }
114
+
115
+ const NOCOLORS = Object.freeze({ level: '', reset: '', message: '' });
116
+
117
+ /**
118
+ * Console implementation of the Logger interface
119
+ */
120
+ export default class ConsoleLogger implements Logger {
121
+ private context: Record<string, unknown>;
122
+ private formatContext: boolean;
123
+ private logLevel: LogLevel;
124
+ private colors: Record<LogLevel, LogColors>;
125
+ private detectedTraceLoopLog: boolean | undefined;
126
+ private useColors: boolean;
127
+
128
+ /**
129
+ * Creates a new console logger
130
+ *
131
+ * @param context - Initial context for the logger
132
+ */
133
+ constructor(
134
+ context: Record<string, unknown> = {},
135
+ formatContext = true,
136
+ logLevel: LogLevel = 'info'
137
+ ) {
138
+ this.context = context;
139
+ this.formatContext = formatContext;
140
+ this.logLevel = logLevel;
141
+ this.useColors = shouldUseColors();
142
+ this.colors = this.useColors
143
+ ? getLogColors(detectColorScheme())
144
+ : ({} as Record<LogLevel, LogColors>);
145
+ }
146
+
147
+ private shouldLog(level: LogLevel): boolean {
148
+ switch (this.logLevel) {
149
+ case 'trace':
150
+ return true;
151
+ case 'debug':
152
+ return level === 'debug' || level === 'info' || level === 'warn' || level === 'error';
153
+ case 'info':
154
+ return level === 'info' || level === 'warn' || level === 'error';
155
+ case 'warn':
156
+ return level === 'warn' || level === 'error';
157
+ case 'error':
158
+ return level === 'error';
159
+ }
160
+ return false;
161
+ }
162
+
163
+ /**
164
+ * Log a trace message (most verbose)
165
+ *
166
+ * @param message - The message to log
167
+ * @param args - Additional arguments to log
168
+ */
169
+ trace(message: unknown, ...args: unknown[]): void {
170
+ if (!this.shouldLog('trace')) {
171
+ return;
172
+ }
173
+ try {
174
+ const colors = this.useColors ? this.colors.trace : NOCOLORS;
175
+ const formattedMessage = formatMessage(this.formatContext, this.context, message, args);
176
+ __originalConsole.debug(
177
+ `${colors.level}[TRACE]${RESET} ${colors.message}${formattedMessage}${RESET}`
178
+ );
179
+ } catch (err) {
180
+ // Fallback to direct logging if formatting fails
181
+ const colors = this.colors.trace;
182
+ __originalConsole.debug(`${colors.level}[TRACE]${RESET} ${message}`, ...args);
183
+ __originalConsole.error('Error formatting log message:', err);
184
+ }
185
+ }
186
+
187
+ /**
188
+ * Log a debug message
189
+ *
190
+ * @param message - The message to log
191
+ * @param args - Additional arguments to log
192
+ */
193
+ debug(message: unknown, ...args: unknown[]): void {
194
+ if (!this.shouldLog('debug')) {
195
+ return;
196
+ }
197
+ try {
198
+ const colors = this.useColors ? this.colors.debug : NOCOLORS;
199
+ const formattedMessage = formatMessage(this.formatContext, this.context, message, args);
200
+ __originalConsole.debug(
201
+ `${colors.level}[DEBUG]${RESET} ${colors.message}${formattedMessage}${RESET}`
202
+ );
203
+ } catch (err) {
204
+ // Fallback to direct logging if formatting fails
205
+ const colors = this.colors.debug;
206
+ __originalConsole.debug(`${colors.level}[DEBUG]${RESET} ${message}`, ...args);
207
+ __originalConsole.error('Error formatting log message:', err);
208
+ }
209
+ }
210
+
211
+ /**
212
+ * Log an info message
213
+ *
214
+ * @param message - The message to log
215
+ * @param args - Additional arguments to log
216
+ */
217
+ info(message: unknown, ...args: unknown[]): void {
218
+ if (!this.shouldLog('info')) {
219
+ return;
220
+ }
221
+ // suppress the default traceloop message at info level
222
+ if (
223
+ !this.detectedTraceLoopLog &&
224
+ typeof message === 'string' &&
225
+ message.includes('Traceloop exporting traces to')
226
+ ) {
227
+ this.detectedTraceLoopLog = true;
228
+ if (this.shouldLog('debug')) {
229
+ this.debug(message, ...args);
230
+ }
231
+ return;
232
+ }
233
+ try {
234
+ const colors = this.useColors ? this.colors.info : NOCOLORS;
235
+ const formattedMessage = formatMessage(this.formatContext, this.context, message, args);
236
+ __originalConsole.info(
237
+ `${colors.level}[INFO]${RESET} ${colors.message}${formattedMessage}${RESET}`
238
+ );
239
+ } catch (err) {
240
+ // Fallback to direct logging if formatting fails
241
+ const colors = this.colors.info;
242
+ __originalConsole.info(`${colors.level}[INFO]${RESET} ${message}`, ...args);
243
+ __originalConsole.error('Error formatting log message:', err);
244
+ }
245
+ }
246
+
247
+ /**
248
+ * Log a warning message
249
+ *
250
+ * @param message - The message to log
251
+ * @param args - Additional arguments to log
252
+ */
253
+ warn(message: unknown, ...args: unknown[]): void {
254
+ if (!this.shouldLog('warn')) {
255
+ return;
256
+ }
257
+ try {
258
+ const colors = this.useColors ? this.colors.warn : NOCOLORS;
259
+ const formattedMessage = formatMessage(this.formatContext, this.context, message, args);
260
+ __originalConsole.warn(
261
+ `${colors.level}[WARN]${RESET} ${colors.message}${formattedMessage}${RESET}`
262
+ );
263
+ } catch (err) {
264
+ // Fallback to direct logging if formatting fails
265
+ const colors = this.colors.warn;
266
+ __originalConsole.warn(`${colors.level}[WARN]${RESET} ${message}`, ...args);
267
+ __originalConsole.error('Error formatting log message:', err);
268
+ }
269
+ }
270
+
271
+ /**
272
+ * Log an error message
273
+ *
274
+ * @param message - The message to log
275
+ * @param args - Additional arguments to log
276
+ */
277
+ error(message: unknown, ...args: unknown[]): void {
278
+ if (!this.shouldLog('error')) {
279
+ return;
280
+ }
281
+ try {
282
+ const colors = this.useColors ? this.colors.error : NOCOLORS;
283
+ const formattedMessage = formatMessage(this.formatContext, this.context, message, args);
284
+ __originalConsole.error(
285
+ `${colors.level}[ERROR]${RESET} ${colors.message}${formattedMessage}${RESET}`
286
+ );
287
+ } catch (err) {
288
+ // Fallback to direct logging if formatting fails
289
+ const colors = this.colors.error;
290
+ __originalConsole.error(`${colors.level}[ERROR]${RESET} ${message}`, ...args);
291
+ __originalConsole.error('Error formatting log message:', err);
292
+ }
293
+ }
294
+
295
+ /**
296
+ * Log a fatal error message and exit the process
297
+ *
298
+ * @param message - The message to log
299
+ * @param args - Additional arguments to log
300
+ */
301
+ fatal(message: unknown, ...args: unknown[]): never {
302
+ this.error(message, ...args);
303
+ process.exit(1);
304
+ }
305
+
306
+ /**
307
+ * Create a child logger with additional context
308
+ *
309
+ * @param opts - Additional context for the child logger
310
+ * @returns A new logger instance with the additional context
311
+ */
312
+ child(opts: Record<string, unknown>): Logger {
313
+ return new ConsoleLogger(
314
+ {
315
+ ...this.context,
316
+ ...opts,
317
+ },
318
+ this.formatContext,
319
+ this.logLevel
320
+ );
321
+ }
322
+ }
@@ -0,0 +1,3 @@
1
+ export { internal } from './internal';
2
+ export type { Logger } from '@agentuity/core';
3
+ export { logger } from './user';
@@ -0,0 +1,165 @@
1
+ import { formatMessage } from './util';
2
+
3
+ const cyan = '\x1b[1;96m';
4
+ const reset = '\x1b[0m';
5
+
6
+ /**
7
+ * Log levels for internal SDK logging
8
+ */
9
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent';
10
+
11
+ /**
12
+ * Internal logger configuration
13
+ */
14
+ interface InternalLoggerConfig {
15
+ level: LogLevel;
16
+ context?: Record<string, unknown>;
17
+ }
18
+
19
+ /**
20
+ * Simple internal logger that doesn't depend on other SDK modules
21
+ * This logger is only for SDK internal diagnostics and debugging
22
+ */
23
+ class InternalLogger {
24
+ private config: InternalLoggerConfig;
25
+
26
+ constructor() {
27
+ this.config = this.loadConfig();
28
+ }
29
+
30
+ /**
31
+ * Load configuration from environment variables
32
+ */
33
+ private loadConfig(): InternalLoggerConfig {
34
+ const envLevel = process.env.AGENTUITY_SDK_LOG_LEVEL?.toLowerCase();
35
+
36
+ // Validate log level
37
+ const validLevels: LogLevel[] = ['debug', 'info', 'warn', 'error', 'silent'];
38
+ const level = validLevels.includes(envLevel as LogLevel) ? (envLevel as LogLevel) : 'silent';
39
+
40
+ return {
41
+ level,
42
+ context: {
43
+ '@agentuity/source': 'sdk-internal',
44
+ '@agentuity/timestamp': new Date().toISOString(),
45
+ },
46
+ };
47
+ }
48
+
49
+ /**
50
+ * Check if a log level should be output based on current configuration
51
+ */
52
+ private shouldLog(level: LogLevel): boolean {
53
+ if (this.config.level === 'silent') return false;
54
+
55
+ const levelPriority = {
56
+ debug: 0,
57
+ info: 1,
58
+ warn: 2,
59
+ error: 3,
60
+ silent: 4,
61
+ };
62
+
63
+ return levelPriority[level] >= levelPriority[this.config.level];
64
+ }
65
+
66
+ /**
67
+ * Format a log message with context
68
+ */
69
+ private formatMessage(message: unknown, ...args: unknown[]): string {
70
+ const formattedMessage = formatMessage(false, this.config.context, message, args);
71
+ return `${cyan}[INTERNAL]${reset} ${formattedMessage}`;
72
+ }
73
+
74
+ /**
75
+ * Log a debug message
76
+ */
77
+ debug(message: unknown, ...args: unknown[]): void {
78
+ if (this.shouldLog('debug')) {
79
+ console.debug(this.formatMessage(message, ...args));
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Log an info message
85
+ */
86
+ info(message: unknown, ...args: unknown[]): void {
87
+ if (this.shouldLog('info')) {
88
+ console.info(this.formatMessage(message, ...args));
89
+ }
90
+ }
91
+
92
+ /**
93
+ * Log a warning message
94
+ */
95
+ warn(message: unknown, ...args: unknown[]): void {
96
+ if (this.shouldLog('warn')) {
97
+ console.warn(this.formatMessage(message, ...args));
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Log an error message
103
+ */
104
+ error(message: unknown, ...args: unknown[]): void {
105
+ if (this.shouldLog('error')) {
106
+ console.error(this.formatMessage(message, ...args));
107
+ }
108
+ }
109
+
110
+ /**
111
+ * Update configuration at runtime
112
+ */
113
+ updateConfig(config: Partial<InternalLoggerConfig>): void {
114
+ this.config = { ...this.config, ...config };
115
+ }
116
+
117
+ /**
118
+ * Get current configuration
119
+ */
120
+ getConfig(): InternalLoggerConfig {
121
+ return { ...this.config };
122
+ }
123
+
124
+ /**
125
+ * Check if logging is enabled
126
+ */
127
+ isEnabled(): boolean {
128
+ return this.config.level !== 'silent';
129
+ }
130
+
131
+ /**
132
+ * Create a child logger with additional context
133
+ */
134
+ child(context: Record<string, unknown>): InternalLogger {
135
+ const childLogger = new InternalLogger();
136
+ childLogger.updateConfig({
137
+ ...this.config,
138
+ context: {
139
+ ...this.config.context,
140
+ ...context,
141
+ },
142
+ });
143
+ return childLogger;
144
+ }
145
+ }
146
+
147
+ // Singleton instance - not exported
148
+ const internalLogger = new InternalLogger();
149
+
150
+ /**
151
+ * Internal logger for SDK use only
152
+ * This is NOT exported from the main SDK index
153
+ */
154
+ export const internal = {
155
+ debug: (message: unknown, ...args: unknown[]) => internalLogger.debug(message, ...args),
156
+ info: (message: unknown, ...args: unknown[]) => internalLogger.info(message, ...args),
157
+ warn: (message: unknown, ...args: unknown[]) => internalLogger.warn(message, ...args),
158
+ error: (message: unknown, ...args: unknown[]) => internalLogger.error(message, ...args),
159
+
160
+ // Utility methods
161
+ updateConfig: (config: Partial<InternalLoggerConfig>) => internalLogger.updateConfig(config),
162
+ getConfig: () => internalLogger.getConfig(),
163
+ isEnabled: () => internalLogger.isEnabled(),
164
+ child: (context: Record<string, unknown>) => internalLogger.child(context),
165
+ };
@@ -0,0 +1,15 @@
1
+ import { type ColorScheme, createLogger } from '@agentuity/server';
2
+ import type { LogLevel, Logger } from '@agentuity/core';
3
+
4
+ /**
5
+ * User-facing logger instance
6
+ * This is the logger that SDK consumers should use
7
+ */
8
+ export const logger: Logger = createLogger(
9
+ (process.env.AGENTUITY_LOG_LEVEL || 'info') as LogLevel,
10
+ false,
11
+ (process.env.COLOR_SCHEME ?? 'dark') as ColorScheme
12
+ );
13
+
14
+ // Re-export the Logger type for convenience
15
+ export type { Logger } from '@agentuity/core';
@@ -0,0 +1,80 @@
1
+ import { formatWithOptions, inspect } from 'node:util';
2
+ import { safeStringify } from '@agentuity/core';
3
+
4
+ export function buildContextString(context?: Record<string, unknown>): string {
5
+ if (context) {
6
+ const contextStr =
7
+ context && Object.keys(context).length > 0
8
+ ? Object.entries(context)
9
+ .map(([key, value]) => {
10
+ try {
11
+ return `${key}=${typeof value === 'object' ? safeStringify(value) : value}`;
12
+ } catch {
13
+ return `${key}=[object Object]`;
14
+ }
15
+ })
16
+ .join(' ')
17
+ : '';
18
+
19
+ return contextStr;
20
+ }
21
+ return '';
22
+ }
23
+
24
+ /**
25
+ * Formats a log message with context
26
+ *
27
+ * @param message - The message to format
28
+ * @param args - Additional arguments for formatting
29
+ * @returns The formatted message with context
30
+ * @private
31
+ */
32
+ export function formatMessage(
33
+ displayContext: boolean,
34
+ context: Record<string, unknown> | undefined,
35
+ message: unknown,
36
+ args: unknown[]
37
+ ): string {
38
+ // Format the context string
39
+ const contextStr = displayContext ? buildContextString(context) : null;
40
+
41
+ // Format the message based on its type
42
+ let _message: string;
43
+ if (typeof message === 'string') {
44
+ _message = message;
45
+ } else if (typeof message === 'number' || typeof message === 'boolean') {
46
+ _message = String(message);
47
+ } else if (message === null) {
48
+ _message = 'null';
49
+ } else if (message === undefined) {
50
+ _message = 'undefined';
51
+ } else {
52
+ // Use inspect for objects for better formatting
53
+ _message = inspect(message, { depth: null, colors: false });
54
+ }
55
+
56
+ // Format the message with args
57
+ let formattedMessage: string;
58
+ try {
59
+ // Only use format if we have arguments
60
+ if (args.length > 0) {
61
+ formattedMessage = formatWithOptions({ depth: null }, _message, ...args);
62
+ } else {
63
+ formattedMessage = _message;
64
+ }
65
+ } catch {
66
+ // If formatting fails, use a simple concatenation
67
+ formattedMessage = `${_message} ${args
68
+ .map((arg) => {
69
+ try {
70
+ return typeof arg === 'object' ? safeStringify(arg) : String(arg);
71
+ } catch {
72
+ return '[object Object]';
73
+ }
74
+ })
75
+ .join(' ')}`;
76
+ }
77
+
78
+ // Combine message with context
79
+ return `${formattedMessage}${contextStr ? ` [${contextStr}]` : ''}`;
80
+ }