@outputai/core 0.8.2-next.2da7213.0 → 0.8.2-next.ad732b1.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 (58) hide show
  1. package/package.json +8 -4
  2. package/src/consts.js +5 -2
  3. package/src/interface/evaluator.js +1 -1
  4. package/src/interface/index.d.ts +7 -6
  5. package/src/interface/index.js +2 -0
  6. package/src/interface/logger.d.ts +53 -0
  7. package/src/interface/logger.js +68 -0
  8. package/src/interface/logger.spec.js +138 -0
  9. package/src/interface/step.js +1 -1
  10. package/src/interface/workflow.js +2 -1
  11. package/src/internal_activities/index.js +2 -1
  12. package/src/internal_utils/component.js +9 -0
  13. package/src/logger/development.js +1 -1
  14. package/src/logger/development.spec.js +18 -1
  15. package/src/logger/production.js +1 -1
  16. package/src/logger/production.spec.js +24 -5
  17. package/src/sdk/README.md +47 -0
  18. package/src/sdk/helpers/component_metadata.d.ts +17 -0
  19. package/src/sdk/helpers/component_metadata.js +6 -0
  20. package/src/sdk/helpers/component_metadata.spec.js +30 -0
  21. package/src/sdk/helpers/index.d.ts +11 -0
  22. package/src/sdk/helpers/index.js +2 -0
  23. package/src/sdk/helpers/path.d.ts +11 -0
  24. package/src/sdk/helpers/path.js +32 -0
  25. package/src/{utils/resolve_invocation_dir.spec.js → sdk/helpers/path.spec.js} +9 -9
  26. package/src/sdk/runtime/context.d.ts +30 -0
  27. package/src/sdk/runtime/context.js +15 -0
  28. package/src/{activity_integration → sdk/runtime}/context.spec.js +5 -5
  29. package/src/sdk/runtime/events.d.ts +15 -0
  30. package/src/sdk/runtime/events.js +18 -0
  31. package/src/{activity_integration → sdk/runtime}/events.spec.js +8 -9
  32. package/src/sdk/runtime/index.d.ts +12 -0
  33. package/src/sdk/runtime/index.js +3 -0
  34. package/src/sdk/runtime/tracing.d.ts +46 -0
  35. package/src/sdk/runtime/tracing.js +11 -0
  36. package/src/utils/index.d.ts +0 -32
  37. package/src/utils/index.js +0 -1
  38. package/src/utils/utils.js +0 -27
  39. package/src/worker/global_functions.js +20 -0
  40. package/src/worker/global_functions.spec.js +55 -0
  41. package/src/worker/index.js +3 -0
  42. package/src/worker/index.spec.js +7 -0
  43. package/src/worker/loader/tools.js +1 -1
  44. package/src/worker/loader/tools.spec.js +1 -1
  45. package/src/worker/log_hooks.js +14 -0
  46. package/src/worker/log_hooks.spec.js +83 -2
  47. package/src/worker/sinks.js +6 -0
  48. package/src/worker/sinks.spec.js +203 -0
  49. package/src/activity_integration/context.d.ts +0 -23
  50. package/src/activity_integration/context.js +0 -18
  51. package/src/activity_integration/event_id_integration.spec.js +0 -52
  52. package/src/activity_integration/events.d.ts +0 -10
  53. package/src/activity_integration/events.js +0 -15
  54. package/src/activity_integration/index.d.ts +0 -9
  55. package/src/activity_integration/index.js +0 -3
  56. package/src/activity_integration/tracing.d.ts +0 -40
  57. package/src/activity_integration/tracing.js +0 -48
  58. package/src/utils/resolve_invocation_dir.js +0 -34
@@ -6,8 +6,17 @@ import {
6
6
  WORKFLOW_CATALOG
7
7
  } from '#consts';
8
8
 
9
- const activityLogMock = vi.hoisted( () => ( { info: vi.fn(), error: vi.fn() } ) );
10
- const workflowLogMock = vi.hoisted( () => ( { info: vi.fn(), error: vi.fn() } ) );
9
+ const createLoggerMock = vi.hoisted( () => () => ( {
10
+ error: vi.fn(),
11
+ warn: vi.fn(),
12
+ info: vi.fn(),
13
+ http: vi.fn(),
14
+ verbose: vi.fn(),
15
+ debug: vi.fn(),
16
+ silly: vi.fn()
17
+ } ) );
18
+ const activityLogMock = vi.hoisted( () => createLoggerMock() );
19
+ const workflowLogMock = vi.hoisted( () => createLoggerMock() );
11
20
  const createChildLoggerMock = vi.hoisted( () =>
12
21
  vi.fn( name => ( name === 'Activity' ? activityLogMock : workflowLogMock ) )
13
22
  );
@@ -125,6 +134,44 @@ describe( 'log_hooks', () => {
125
134
 
126
135
  expect( activityLogMock.error ).not.toHaveBeenCalled();
127
136
  } );
137
+
138
+ it( 'ACTIVITY_LOG logs dynamic levels with metadata and serialized activity fields', () => {
139
+ onHandlers[BusEventType.ACTIVITY_LOG]( {
140
+ activityInfo,
141
+ level: 'debug',
142
+ message: 'activity detail',
143
+ metadata: {
144
+ custom: 'value',
145
+ workflowId: 'metadata-workflow-id'
146
+ }
147
+ } );
148
+
149
+ expect( activityLogMock.debug ).toHaveBeenCalledTimes( 1 );
150
+ expect( activityLogMock.debug ).toHaveBeenCalledWith( 'activity detail', {
151
+ custom: 'value',
152
+ activityId: 'act-1',
153
+ activityType: 'myWorkflow#myStep',
154
+ workflowId: 'wf-1',
155
+ workflowType: 'myWorkflow',
156
+ runId: 'run-1'
157
+ } );
158
+ } );
159
+
160
+ it( 'ACTIVITY_LOG accepts omitted metadata', () => {
161
+ onHandlers[BusEventType.ACTIVITY_LOG]( {
162
+ activityInfo,
163
+ level: 'info',
164
+ message: 'activity detail'
165
+ } );
166
+
167
+ expect( activityLogMock.info ).toHaveBeenCalledWith( 'activity detail', {
168
+ activityId: 'act-1',
169
+ activityType: 'myWorkflow#myStep',
170
+ workflowId: 'wf-1',
171
+ workflowType: 'myWorkflow',
172
+ runId: 'run-1'
173
+ } );
174
+ } );
128
175
  } );
129
176
 
130
177
  describe( 'workflow events', () => {
@@ -210,5 +257,39 @@ describe( 'log_hooks', () => {
210
257
 
211
258
  expect( workflowLogMock.error ).not.toHaveBeenCalled();
212
259
  } );
260
+
261
+ it( 'WORKFLOW_LOG logs dynamic levels with metadata and serialized workflow fields', () => {
262
+ onHandlers[BusEventType.WORKFLOW_LOG]( {
263
+ workflowDetails,
264
+ level: 'warn',
265
+ message: 'workflow detail',
266
+ metadata: {
267
+ custom: 'value',
268
+ runId: 'metadata-run-id'
269
+ }
270
+ } );
271
+
272
+ expect( workflowLogMock.warn ).toHaveBeenCalledTimes( 1 );
273
+ expect( workflowLogMock.warn ).toHaveBeenCalledWith( 'workflow detail', {
274
+ custom: 'value',
275
+ workflowId: 'wf-1',
276
+ workflowType: 'myWorkflow',
277
+ runId: 'run-1'
278
+ } );
279
+ } );
280
+
281
+ it( 'WORKFLOW_LOG accepts omitted metadata', () => {
282
+ onHandlers[BusEventType.WORKFLOW_LOG]( {
283
+ workflowDetails,
284
+ level: 'info',
285
+ message: 'workflow detail'
286
+ } );
287
+
288
+ expect( workflowLogMock.info ).toHaveBeenCalledWith( 'workflow detail', {
289
+ workflowId: 'wf-1',
290
+ workflowType: 'myWorkflow',
291
+ runId: 'run-1'
292
+ } );
293
+ } );
213
294
  } );
214
295
  } );
@@ -10,6 +10,12 @@ export const sinks = {
10
10
  * Workflow lifecycle sinks
11
11
  */
12
12
  workflow: {
13
+ log: {
14
+ fn: ( workflowInfo, { level, message, metadata } ) => {
15
+ messageBus.emit( BusEventType.WORKFLOW_LOG, { level, message, metadata, workflowDetails: createWorkflowDetails( workflowInfo ) } );
16
+ },
17
+ callDuringReplay: false
18
+ },
13
19
  start: {
14
20
  fn: ( workflowInfo, input ) => {
15
21
  const { runId, workflowType, memo: { traceInfo }, parent } = workflowInfo;
@@ -0,0 +1,203 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { BusEventType, ComponentType } from '#consts';
3
+
4
+ const messageBusMock = vi.hoisted( () => ( {
5
+ emit: vi.fn()
6
+ } ) );
7
+
8
+ const addEventStartMock = vi.hoisted( () => vi.fn() );
9
+ const addEventEndMock = vi.hoisted( () => vi.fn() );
10
+ const addEventErrorMock = vi.hoisted( () => vi.fn() );
11
+
12
+ const createWorkflowDetailsMock = vi.hoisted( () => vi.fn( workflowInfo => ( {
13
+ workflowId: workflowInfo.workflowId,
14
+ workflowType: workflowInfo.workflowType,
15
+ runId: workflowInfo.runId
16
+ } ) ) );
17
+
18
+ vi.mock( '#bus', () => ( { messageBus: messageBusMock } ) );
19
+ vi.mock( '#tracing', () => ( {
20
+ addEventStart: addEventStartMock,
21
+ addEventEnd: addEventEndMock,
22
+ addEventError: addEventErrorMock
23
+ } ) );
24
+ vi.mock( '#internal_utils/temporal_context', () => ( {
25
+ createWorkflowDetails: createWorkflowDetailsMock
26
+ } ) );
27
+
28
+ describe( 'worker/sinks', () => {
29
+ const workflowInfo = {
30
+ workflowId: 'wf-1',
31
+ workflowType: 'myWorkflow',
32
+ runId: 'run-1',
33
+ memo: {
34
+ traceInfo: { traceId: 'trace-1' }
35
+ },
36
+ parent: {
37
+ runId: 'parent-run-1'
38
+ }
39
+ };
40
+ const workflowDetails = {
41
+ workflowId: 'wf-1',
42
+ workflowType: 'myWorkflow',
43
+ runId: 'run-1'
44
+ };
45
+
46
+ beforeEach( () => {
47
+ vi.clearAllMocks();
48
+ } );
49
+
50
+ it( 'disables replay calls for side-effecting sinks', async () => {
51
+ const { sinks } = await import( './sinks.js' );
52
+
53
+ expect( sinks.workflow.start.callDuringReplay ).toBe( false );
54
+ expect( sinks.workflow.end.callDuringReplay ).toBe( false );
55
+ expect( sinks.workflow.error.callDuringReplay ).toBe( false );
56
+ expect( sinks.trace.start.callDuringReplay ).toBe( false );
57
+ expect( sinks.trace.end.callDuringReplay ).toBe( false );
58
+ expect( sinks.trace.error.callDuringReplay ).toBe( false );
59
+ } );
60
+
61
+ it( 'workflow.log emits workflow log events with metadata and workflow details', async () => {
62
+ const { sinks } = await import( './sinks.js' );
63
+ const metadata = { requestId: 'req-1' };
64
+
65
+ sinks.workflow.log.fn( workflowInfo, {
66
+ level: 'info',
67
+ message: 'workflow detail',
68
+ metadata
69
+ } );
70
+
71
+ expect( createWorkflowDetailsMock ).toHaveBeenCalledWith( workflowInfo );
72
+ expect( messageBusMock.emit ).toHaveBeenCalledWith( BusEventType.WORKFLOW_LOG, {
73
+ level: 'info',
74
+ message: 'workflow detail',
75
+ metadata,
76
+ workflowDetails
77
+ } );
78
+ } );
79
+
80
+ it( 'workflow.start emits workflow start events and trace start events', async () => {
81
+ const { sinks } = await import( './sinks.js' );
82
+ const input = { value: 'input' };
83
+
84
+ sinks.workflow.start.fn( workflowInfo, input );
85
+
86
+ expect( messageBusMock.emit ).toHaveBeenCalledWith( BusEventType.WORKFLOW_START, { workflowDetails } );
87
+ expect( addEventStartMock ).toHaveBeenCalledWith( {
88
+ id: 'run-1',
89
+ kind: ComponentType.WORKFLOW,
90
+ name: 'myWorkflow',
91
+ details: input,
92
+ parentId: 'parent-run-1',
93
+ traceInfo: { traceId: 'trace-1' }
94
+ } );
95
+ } );
96
+
97
+ it( 'workflow.start skips tracing when trace info is absent', async () => {
98
+ const { sinks } = await import( './sinks.js' );
99
+
100
+ sinks.workflow.start.fn( { ...workflowInfo, memo: {} }, { value: 'input' } );
101
+
102
+ expect( messageBusMock.emit ).toHaveBeenCalledWith( BusEventType.WORKFLOW_START, { workflowDetails } );
103
+ expect( addEventStartMock ).not.toHaveBeenCalled();
104
+ } );
105
+
106
+ it( 'workflow.end emits workflow end events and trace end events', async () => {
107
+ const { sinks } = await import( './sinks.js' );
108
+ const output = { value: 'output' };
109
+
110
+ sinks.workflow.end.fn( workflowInfo, output );
111
+
112
+ expect( messageBusMock.emit ).toHaveBeenCalledWith( BusEventType.WORKFLOW_END, { workflowDetails } );
113
+ expect( addEventEndMock ).toHaveBeenCalledWith( {
114
+ id: 'run-1',
115
+ details: output,
116
+ traceInfo: { traceId: 'trace-1' }
117
+ } );
118
+ } );
119
+
120
+ it( 'workflow.end skips tracing when trace info is absent', async () => {
121
+ const { sinks } = await import( './sinks.js' );
122
+
123
+ sinks.workflow.end.fn( { ...workflowInfo, memo: {} }, { value: 'output' } );
124
+
125
+ expect( messageBusMock.emit ).toHaveBeenCalledWith( BusEventType.WORKFLOW_END, { workflowDetails } );
126
+ expect( addEventEndMock ).not.toHaveBeenCalled();
127
+ } );
128
+
129
+ it( 'workflow.error emits workflow error events and trace error events', async () => {
130
+ const { sinks } = await import( './sinks.js' );
131
+ const error = new Error( 'workflow failed' );
132
+
133
+ sinks.workflow.error.fn( workflowInfo, error );
134
+
135
+ expect( messageBusMock.emit ).toHaveBeenCalledWith( BusEventType.WORKFLOW_ERROR, { workflowDetails, error } );
136
+ expect( addEventErrorMock ).toHaveBeenCalledWith( {
137
+ id: 'run-1',
138
+ details: error,
139
+ traceInfo: { traceId: 'trace-1' }
140
+ } );
141
+ } );
142
+
143
+ it( 'workflow.error skips tracing when trace info is absent', async () => {
144
+ const { sinks } = await import( './sinks.js' );
145
+ const error = new Error( 'workflow failed' );
146
+
147
+ sinks.workflow.error.fn( { ...workflowInfo, memo: {} }, error );
148
+
149
+ expect( messageBusMock.emit ).toHaveBeenCalledWith( BusEventType.WORKFLOW_ERROR, { workflowDetails, error } );
150
+ expect( addEventErrorMock ).not.toHaveBeenCalled();
151
+ } );
152
+
153
+ it( 'trace.start records trace start events with workflow parent context', async () => {
154
+ const { sinks } = await import( './sinks.js' );
155
+
156
+ sinks.trace.start.fn( workflowInfo, {
157
+ id: 'step-1',
158
+ kind: ComponentType.STEP,
159
+ name: 'myStep',
160
+ details: { input: true }
161
+ } );
162
+
163
+ expect( addEventStartMock ).toHaveBeenCalledWith( {
164
+ id: 'step-1',
165
+ kind: ComponentType.STEP,
166
+ name: 'myStep',
167
+ details: { input: true },
168
+ parentId: 'parent-run-1',
169
+ traceInfo: { traceId: 'trace-1' }
170
+ } );
171
+ } );
172
+
173
+ it( 'trace.end records trace end events', async () => {
174
+ const { sinks } = await import( './sinks.js' );
175
+
176
+ sinks.trace.end.fn( workflowInfo, {
177
+ id: 'step-1',
178
+ details: { output: true }
179
+ } );
180
+
181
+ expect( addEventEndMock ).toHaveBeenCalledWith( {
182
+ id: 'step-1',
183
+ details: { output: true },
184
+ traceInfo: { traceId: 'trace-1' }
185
+ } );
186
+ } );
187
+
188
+ it( 'trace.error records trace error events', async () => {
189
+ const { sinks } = await import( './sinks.js' );
190
+ const error = new Error( 'step failed' );
191
+
192
+ sinks.trace.error.fn( workflowInfo, {
193
+ id: 'step-1',
194
+ details: error
195
+ } );
196
+
197
+ expect( addEventErrorMock ).toHaveBeenCalledWith( {
198
+ id: 'step-1',
199
+ details: error,
200
+ traceInfo: { traceId: 'trace-1' }
201
+ } );
202
+ } );
203
+ } );
@@ -1,23 +0,0 @@
1
- import type { Info } from '@temporalio/activity';
2
- /**
3
- * Context returned by {@link getContext} when running inside a Temporal Activity (step or evaluator).
4
- */
5
- export type Context = {
6
- /** Temporal info about the current activity */
7
- activityInfo: Info,
8
- /** Path of the workflow file */
9
- workflowFilename: string
10
- };
11
-
12
- /**
13
- * Returns information about the current Temporal execution.
14
- *
15
- * Only available when called from within a step or evaluator (Temporal Activities) running in the Temporal runtime.
16
- *
17
- * @remarks
18
- * - Returns `null` when not called inside a Temporal Activity (steps/evaluators);
19
- * - Returns `null` when not called from within a running Temporal worker, like in unit tests environment;
20
- *
21
- * @returns The workflow context, or `null` if unavailable or incomplete.
22
- */
23
- export declare function getExecutionContext(): Context | null;
@@ -1,18 +0,0 @@
1
- import { Storage } from '#async_storage';
2
-
3
- /**
4
- * Returns information trapped on AsyncStorage about the workflow invoking an activity
5
- *
6
- * @returns {object}
7
- */
8
- export const getExecutionContext = () => {
9
- const ctx = Storage.load();
10
- if ( !ctx ) {
11
- return null;
12
- }
13
-
14
- return {
15
- workflowFilename: ctx.workflowFilename,
16
- activityInfo: ctx.activityInfo
17
- };
18
- };
@@ -1,52 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from 'vitest';
2
- import { messageBus } from '#bus';
3
- import { emitEvent } from './events.js';
4
-
5
- const UUID_V4_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
6
-
7
- describe( 'eventId integration', () => {
8
- beforeEach( () => {
9
- messageBus.removeAllListeners();
10
- } );
11
-
12
- it( 'stamps a UUID v4 eventId on every emit (end-to-end via messageBus)', () => {
13
- const handler = vi.fn();
14
- messageBus.on( 'external:cost:llm:request', handler );
15
-
16
- emitEvent( 'cost:llm:request', { modelId: 'gpt-4o' } );
17
-
18
- expect( handler ).toHaveBeenCalledWith( expect.objectContaining( {
19
- eventId: expect.stringMatching( UUID_V4_REGEX ),
20
- modelId: 'gpt-4o'
21
- } ) );
22
- } );
23
-
24
- it( 'cost:http:request and http:request for the same fetch get distinct eventIds', () => {
25
- const costHandler = vi.fn();
26
- const reqHandler = vi.fn();
27
- messageBus.on( 'external:cost:http:request', costHandler );
28
- messageBus.on( 'external:http:request', reqHandler );
29
-
30
- const sharedRequestId = 'req-xyz';
31
- emitEvent( 'cost:http:request', { requestId: sharedRequestId, url: 'https://x.test', cost: 1 } );
32
- emitEvent( 'http:request', { requestId: sharedRequestId, url: 'https://x.test', status: 200 } );
33
-
34
- const costEventId = costHandler.mock.calls[0][0].eventId;
35
- const reqEventId = reqHandler.mock.calls[0][0].eventId;
36
- expect( costEventId ).toMatch( UUID_V4_REGEX );
37
- expect( reqEventId ).toMatch( UUID_V4_REGEX );
38
- expect( costEventId ).not.toBe( reqEventId );
39
- } );
40
-
41
- it( 'honors a caller-supplied eventId end-to-end', () => {
42
- const handler = vi.fn();
43
- messageBus.on( 'external:custom:event', handler );
44
-
45
- emitEvent( 'custom:event', { eventId: 'fixed-id-123', payload: 'hi' } );
46
-
47
- expect( handler ).toHaveBeenCalledWith( expect.objectContaining( {
48
- eventId: 'fixed-id-123',
49
- payload: 'hi'
50
- } ) );
51
- } );
52
- } );
@@ -1,10 +0,0 @@
1
- /**
2
- * Emits a custom event on the in-process message bus.
3
- *
4
- * When called inside an Output activity context, the framework automatically
5
- * attaches `activityInfo`, `workflowDetails`, and `outputActivityKind` onto the emitted payload.
6
- *
7
- * @param eventName - The name of the event to emit
8
- * @param payload - An optional payload to send to the event
9
- */
10
- export declare function emitEvent( eventName: string, payload?: unknown ): void;
@@ -1,15 +0,0 @@
1
- import { messageBus } from '#bus';
2
- import { Storage } from '#async_storage';
3
-
4
- export const emitEvent = ( eventName, payload ) => {
5
- const ctx = Storage.load();
6
-
7
- messageBus.emit( `external:${eventName}`, {
8
- ...payload ?? {},
9
- ...( ctx && {
10
- activityInfo: ctx.activityInfo,
11
- workflowDetails: ctx.workflowDetails,
12
- outputActivityKind: ctx.outputActivityKind
13
- } )
14
- } );
15
- };
@@ -1,9 +0,0 @@
1
- /**
2
- * > [!WARNING]
3
- * > **Internal use only.** Not part of the public API; may change without notice.
4
- *
5
- * @packageDocumentation
6
- */
7
- export { getExecutionContext } from './context';
8
- export { emitEvent } from './events';
9
- export * as Tracing from './tracing';
@@ -1,3 +0,0 @@
1
- export { getExecutionContext } from './context.js';
2
- export { emitEvent } from './events.js';
3
- export * as Tracing from './tracing.js';
@@ -1,40 +0,0 @@
1
- import type { Attribute } from '#trace_attribute';
2
-
3
- export { Attribute } from '#trace_attribute';
4
- /**
5
- * Creates a new event.
6
- *
7
- * @param args
8
- * @param args.id - A unique id for the Event.
9
- * @param args.kind - The kind of Event, like HTTP, DiskWrite, DBOp, etc.
10
- * @param args.name - The human-friendly name of the Event: query, request, create.
11
- * @param args.details - Arbitrary data to add to this event, it will be used as the "input" field.
12
- */
13
- export declare function addEventStart( args: { id: string; kind: string; name: string; details: unknown } ): void;
14
-
15
- /**
16
- * Concludes an event.
17
- *
18
- * @param args
19
- * @param args.id - The id of the event to conclude.
20
- * @param args.details - Arbitrary data to add to this event, it will be used as the "output" field.
21
- */
22
- export declare function addEventEnd( args: { id: string; details: unknown } ): void;
23
-
24
- /**
25
- * Concludes an event with an error.
26
- *
27
- * @param args
28
- * @param args.id - The id of the event to conclude.
29
- * @param args.details - Arbitrary data to add to this event, it will be used as the "error" field.
30
- */
31
- export declare function addEventError( args: { id: string; details: unknown } ): void;
32
-
33
- /**
34
- * Adds an attribute to an event.
35
- *
36
- * @param args
37
- * @param args.eventId - The id of the event to attach the attribute to.
38
- * @param args.attribute - The attribute to attach to the event.
39
- */
40
- export declare function addEventAttribute( args: { eventId: string; attribute: Attribute.Instance } ): void;
@@ -1,48 +0,0 @@
1
- import { addEventActionWithContext, EventAction } from '#tracing';
2
-
3
- export { Attribute } from '#trace_attribute';
4
-
5
- /**
6
- * Creates a new event.
7
- *
8
- * @param {object} args
9
- * @param {string} args.id - A unique id for the Event.
10
- * @param {string} args.kind - The kind of Event, like HTTP, DiskWrite, DBOp, etc.
11
- * @param {string} args.name - The human-friendly name of the Event: query, request, create.
12
- * @param {object} args.details - Arbitrary data to add to this event, it will be used as the "input" field.
13
- * @returns {void}
14
- */
15
- export const addEventStart = ( { id, kind, name, details } ) =>
16
- addEventActionWithContext( EventAction.START, { kind, name, details, id } );
17
-
18
- /**
19
- * Concludes an event.
20
- *
21
- * @param {object} args
22
- * @param {string} args.id - The id of the event to conclude.
23
- * @param {object} args.details - Arbitrary data to add to this event, it will be used as the "output" field.
24
- * @returns {void}
25
- */
26
- export const addEventEnd = ( { id, details } ) => addEventActionWithContext( EventAction.END, { id, details } );
27
-
28
- /**
29
- * Concludes an event with an error.
30
- *
31
- * @param {object} args
32
- * @param {string} args.id - The id of the event to conclude.
33
- * @param {object} args.details - Arbitrary data to add to this event, it will be used as the "error" field.
34
- * @returns {void}
35
- */
36
- export const addEventError = ( { id, details } ) => addEventActionWithContext( EventAction.ERROR, { id, details } );
37
-
38
- /**
39
- * Adds an attribute to an event.
40
- *
41
- * @param {object} args
42
- * @param {string} args.eventId - The id of the event to attach the attribute to.
43
- * @param {string} args.name - The attribute name
44
- * @param {unknown} args.value - The attribute value
45
- * @returns {void}
46
- */
47
- export const addEventAttribute = ( { eventId, attribute } ) =>
48
- addEventActionWithContext( EventAction.ADD_ATTR, { id: eventId, details: attribute } );
@@ -1,34 +0,0 @@
1
- import * as stackTraceParser from 'stacktrace-parser';
2
-
3
- // OS separator, but in a deterministic way, allowing this to work in Temporal's sandbox
4
- // This avoids importing from node:path
5
- const SEP = new Error().stack.includes( '/' ) ? '/' : '\\';
6
-
7
- const transformSeparators = path => path.replaceAll( '/', SEP );
8
- const defaultIgnorePaths = [
9
- '/@outputai/core/',
10
- '/@outputai/llm/',
11
- '/@outputai/evals/',
12
- '/sdk/core/',
13
- '/sdk/llm/',
14
- '/sdk/evals/',
15
- 'node:internal/',
16
- 'evalmachine.',
17
- 'webpack/bootstrap'
18
- ];
19
-
20
- /**
21
- * Return the directory of the file invoking the code that called this function
22
- * Excludes some internal paths and the sdk itself
23
- */
24
- export default ( additionalIgnorePaths = [] ) => {
25
- const stack = new Error().stack;
26
- const lines = stackTraceParser.parse( stack );
27
- const ignorePaths = [ ...additionalIgnorePaths, ...defaultIgnorePaths ].map( transformSeparators );
28
-
29
- const frame = lines.find( l => !ignorePaths.some( p => l.file.includes( p ) ) );
30
- if ( !frame ) {
31
- throw new Error( `Invocation dir resolution via stack trace failed. Stack: ${stack}` );
32
- }
33
- return frame.file.replace( 'file://', '' ).split( SEP ).slice( 0, -1 ).join( SEP );
34
- };