@outputai/core 0.8.2-next.7929835.0 → 0.8.2-next.89b6f8c.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@outputai/core",
3
- "version": "0.8.2-next.7929835.0",
3
+ "version": "0.8.2-next.89b6f8c.0",
4
4
  "description": "The core module of the output framework",
5
5
  "type": "module",
6
6
  "exports": {
@@ -7,4 +7,4 @@ export * from './step.js';
7
7
  export * from './evaluator.js';
8
8
  export * from './workflow.js';
9
9
  export * from './evaluation_result.js';
10
- export * as Logger from './logger.js';
10
+ export * from './logger.js';
@@ -10,7 +10,7 @@ import { step } from './step.js';
10
10
  import { workflow } from './workflow.js';
11
11
  import { executeInParallel } from './workflow_utils.js';
12
12
  import { sendHttpRequest, sendPostRequestAndAwaitWebhook } from './webhook.js';
13
- import * as Logger from './logger.js';
13
+ import { Logger } from './logger.js';
14
14
 
15
15
  export {
16
16
  evaluator,
@@ -1,53 +1,61 @@
1
- /**
2
- * Additional structured fields attached to a log record.
3
- */
4
- export type LogMetadata = Record<string, unknown>;
1
+ type Logger = {
2
+ /**
3
+ * Log an error (level 0)
4
+ * @param message Log message
5
+ * @param metadata Additional information to be displayed
6
+ */
7
+ error( message: string, metadata?: Record<string, unknown> ) : void,
5
8
 
6
- /**
7
- * Log an error (level 0)
8
- * @param message Log message
9
- * @param metadata Additional information to be displayed
10
- */
11
- export declare function error( message: string, metadata?: LogMetadata ) : void;
9
+ /**
10
+ * Log a warn (level 1)
11
+ * @param message Log message
12
+ * @param metadata Additional information to be displayed
13
+ */
14
+ warn( message: string, metadata?: Record<string, unknown> ) : void,
12
15
 
13
- /**
14
- * Log a warn (level 1)
15
- * @param message Log message
16
- * @param metadata Additional information to be displayed
17
- */
18
- export declare function warn( message: string, metadata?: LogMetadata ) : void;
16
+ /**
17
+ * Log an info (level 2)
18
+ * @param message Log message
19
+ * @param metadata Additional information to be displayed
20
+ */
21
+ info( message: string, metadata?: Record<string, unknown> ) : void,
19
22
 
20
- /**
21
- * Log an info (level 2)
22
- * @param message Log message
23
- * @param metadata Additional information to be displayed
24
- */
25
- export declare function info( message: string, metadata?: LogMetadata ) : void;
23
+ /**
24
+ * Log http (level 3)
25
+ * @param message Log message
26
+ * @param metadata Additional information to be displayed
27
+ */
28
+ http( message: string, metadata?: Record<string, unknown> ) : void,
26
29
 
27
- /**
28
- * Log http (level 3)
29
- * @param message Log message
30
- * @param metadata Additional information to be displayed
31
- */
32
- export declare function http( message: string, metadata?: LogMetadata ) : void;
30
+ /**
31
+ * Log verbose (level 4)
32
+ * @param message Log message
33
+ * @param metadata Additional information to be displayed
34
+ */
35
+ verbose( message: string, metadata?: Record<string, unknown> ) : void,
33
36
 
34
- /**
35
- * Log verbose (level 4)
36
- * @param message Log message
37
- * @param metadata Additional information to be displayed
38
- */
39
- export declare function verbose( message: string, metadata?: LogMetadata ) : void;
37
+ /**
38
+ * Log debug (level 5)
39
+ * @param message Log message
40
+ * @param metadata Additional information to be displayed
41
+ */
42
+ debug( message: string, metadata?: Record<string, unknown> ) : void,
40
43
 
41
- /**
42
- * Log debug (level 5)
43
- * @param message Log message
44
- * @param metadata Additional information to be displayed
45
- */
46
- export declare function debug( message: string, metadata?: LogMetadata ) : void;
44
+ /**
45
+ * Log silly (level 6)
46
+ * @param message Log message
47
+ * @param metadata Additional information to be displayed
48
+ */
49
+ silly( message: string, metadata?: Record<string, unknown> ) : void,
50
+
51
+ /**
52
+ * Creates a new Logger with a namespace value preset for all emitted logs.
53
+ * @param namespace
54
+ */
55
+ createLogger( namespace: string ) : Logger
56
+ };
47
57
 
48
58
  /**
49
- * Log silly (level 6)
50
- * @param message Log message
51
- * @param metadata Additional information to be displayed
59
+ * Logger tool. Can be used in activities or workflows. Logs together with the framework's own logs.
52
60
  */
53
- export declare function silly( message: string, metadata?: LogMetadata ) : void;
61
+ export declare const Logger : Logger;
@@ -9,7 +9,6 @@ const reservedMetadataFields = new Set( [
9
9
  'level',
10
10
  'message',
11
11
  'metadata',
12
- 'namespace',
13
12
  'splat',
14
13
  'stack',
15
14
  'timestamp',
@@ -26,6 +25,7 @@ const reservedMetadataFields = new Set( [
26
25
  // This is inoffensive and can be used outside workflow sandbox
27
26
  const sinks = proxySinks();
28
27
 
28
+ // Winston uses npm levels by default: https://github.com/winstonjs/winston#logging-levels
29
29
  // Convert npm log levels to console levels
30
30
  const levelToConsole = {
31
31
  error: 'error',
@@ -36,14 +36,17 @@ const levelToConsole = {
36
36
  debug: 'debug',
37
37
  silly: 'log'
38
38
  };
39
+ const levels = Object.keys( levelToConsole );
39
40
 
40
41
  /** Drops reserved keys from object */
41
42
  const removeReservedFields = obj => Object.fromEntries( Object.entries( obj ).filter( ( [ k ] ) => !reservedMetadataFields.has( k ) ) );
42
43
 
43
- const log = ( level, message, metadata ) => {
44
+ /** Dispatch the log message downstream */
45
+ const log = ( level, namespace, message, metadata ) => {
46
+ const baseMetadata = namespace ? { namespace } : {};
44
47
  const sanitized = {
45
48
  message: String( message ),
46
- ...( isPlainObject( metadata ) && { metadata: removeReservedFields( metadata ) } )
49
+ metadata: { ...baseMetadata, ...isPlainObject( metadata ) ? removeReservedFields( metadata ) : {} }
47
50
  };
48
51
 
49
52
  // When inside workflow, use sinks to send logs out
@@ -58,11 +61,13 @@ const log = ( level, message, metadata ) => {
58
61
  }
59
62
  };
60
63
 
61
- // Winston uses npm levels by default: https://github.com/winstonjs/winston#logging-levels
62
- export const error = log.bind( null, 'error' );
63
- export const warn = log.bind( null, 'warn' );
64
- export const info = log.bind( null, 'info' );
65
- export const http = log.bind( null, 'http' );
66
- export const verbose = log.bind( null, 'verbose' );
67
- export const debug = log.bind( null, 'debug' );
68
- export const silly = log.bind( null, 'silly' );
64
+ /** Creates a new logger. It uses the npm levels, and for each level, bind the log function */
65
+ const createLogger = namespace => ( {
66
+ ...Object.fromEntries( levels.map( l => [ l, log.bind( null, l, namespace ) ] ) ),
67
+ createLogger
68
+ } );
69
+
70
+ /** This is the default logger instance */
71
+ const logger = createLogger( null );
72
+
73
+ export { logger as Logger };
@@ -34,7 +34,7 @@ const consoleMethodsByLevel = {
34
34
  silly: 'log'
35
35
  };
36
36
 
37
- const loadLogger = async () => import( './logger.js' );
37
+ const loadLogger = async () => ( await import( './logger.js' ) ).Logger;
38
38
 
39
39
  describe( 'interface/logger', () => {
40
40
  beforeEach( () => {
@@ -135,4 +135,38 @@ describe( 'interface/logger', () => {
135
135
  expect( consoleMocks.log ).toHaveBeenCalledTimes( 3 );
136
136
  expect( workflowLogMock ).not.toHaveBeenCalled();
137
137
  } );
138
+
139
+ it( 'creates a logger with a default namespace for every level', async () => {
140
+ const logger = await loadLogger();
141
+ inWorkflowContextMock.mockReturnValue( true );
142
+
143
+ const namespacedLogger = logger.createLogger( 'Namespace' );
144
+ logLevels.forEach( level => {
145
+ namespacedLogger[level]( `${level} message`, { requestId: level } );
146
+ } );
147
+
148
+ logLevels.forEach( ( level, index ) => {
149
+ expect( workflowLogMock ).toHaveBeenNthCalledWith( index + 1, {
150
+ level,
151
+ message: `${level} message`,
152
+ metadata: {
153
+ namespace: 'Namespace',
154
+ requestId: level
155
+ }
156
+ } );
157
+ } );
158
+ } );
159
+
160
+ it( 'lets log metadata override the default namespace', async () => {
161
+ const logger = await loadLogger();
162
+ inWorkflowContextMock.mockReturnValue( true );
163
+
164
+ logger.createLogger( 'Default namespace' ).info( 'message', { namespace: 'Inline namespace' } );
165
+
166
+ expect( workflowLogMock ).toHaveBeenCalledWith( {
167
+ level: 'info',
168
+ message: 'message',
169
+ metadata: { namespace: 'Inline namespace' }
170
+ } );
171
+ } );
138
172
  } );