@output.ai/core 0.0.9 → 0.0.10
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/README.md +12 -1
- package/package.json +5 -5
- package/src/configs.js +28 -6
- package/src/worker/index.js +2 -2
- package/src/worker/tracer/index.test.js +27 -39
package/README.md
CHANGED
|
@@ -126,5 +126,16 @@ To develop workflows you need the code, which will be called the worker, the API
|
|
|
126
126
|
After having the API and the engine running, to start the worker just run:
|
|
127
127
|
|
|
128
128
|
```js
|
|
129
|
-
`outputai`
|
|
129
|
+
`npm run outputai`
|
|
130
130
|
```
|
|
131
|
+
|
|
132
|
+
## Env variables
|
|
133
|
+
|
|
134
|
+
Necessary env variables to run the worker locally:
|
|
135
|
+
|
|
136
|
+
- `TEMPORAL_ADDRESS`: The temporal backend address, prefer the remote;
|
|
137
|
+
- `TEMPORAL_NAMESPACE`: The name of the namespace, if using remote, use: "output-staging.i0jzq";
|
|
138
|
+
- `TEMPORAL_API_KEY`: The API key to access remote temporal. If using local temporal, leave it blank;
|
|
139
|
+
- `CATALOG_ID`: The name of the local catalog, always set this. Use your email;
|
|
140
|
+
- `API_AUTH_KEY`: The API key to access the Framework API. Local can be blank, remote use the proper API Key;
|
|
141
|
+
- `TRACING_ENABLED`: A "stringbool" value indicating if traces should be generated or note;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@output.ai/core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.10",
|
|
4
4
|
"description": "The core module of the output framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
"url": "git+https://github.com/growthxai/flow-sdk"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@babel/generator": "7.
|
|
25
|
-
"@babel/parser": "7.
|
|
26
|
-
"@babel/traverse": "7.
|
|
27
|
-
"@babel/types": "7.
|
|
24
|
+
"@babel/generator": "7.28.3",
|
|
25
|
+
"@babel/parser": "7.28.4",
|
|
26
|
+
"@babel/traverse": "7.28.4",
|
|
27
|
+
"@babel/types": "7.28.4",
|
|
28
28
|
"@temporalio/worker": "1.13.0",
|
|
29
29
|
"@temporalio/workflow": "1.13.0",
|
|
30
30
|
"ajv": "8.17.1",
|
package/src/configs.js
CHANGED
|
@@ -1,17 +1,39 @@
|
|
|
1
|
+
import * as z from 'zod';
|
|
2
|
+
|
|
3
|
+
class InvalidEnvVarsErrors extends Error {}
|
|
4
|
+
|
|
5
|
+
const envVarSchema = z.object( {
|
|
6
|
+
TEMPORAL_ADDRESS: z.union( [
|
|
7
|
+
z.httpUrl(),
|
|
8
|
+
z.string().regex( /^[a-z0-9_-]+:\d{2,5}$/i ) // local docker container name like worker:7233
|
|
9
|
+
] ),
|
|
10
|
+
TEMPORAL_NAMESPACE: z.string().optional().default( 'default' ),
|
|
11
|
+
TEMPORAL_API_KEY: z.string().optional(),
|
|
12
|
+
CATALOG_ID: z.string().regex( /^[a-z0-9_.@-]+$/i ),
|
|
13
|
+
API_AUTH_KEY: z.string().optional(),
|
|
14
|
+
TRACING_ENABLED: z.stringbool().optional()
|
|
15
|
+
} );
|
|
16
|
+
|
|
17
|
+
const { data: safeEnvVar, error } = envVarSchema.safeParse( process.env );
|
|
18
|
+
if ( error ) {
|
|
19
|
+
throw new InvalidEnvVarsErrors( z.prettifyError( error ) );
|
|
20
|
+
}
|
|
21
|
+
|
|
1
22
|
export const worker = {
|
|
2
|
-
address:
|
|
3
|
-
apiKey:
|
|
23
|
+
address: safeEnvVar.TEMPORAL_ADDRESS,
|
|
24
|
+
apiKey: safeEnvVar.TEMPORAL_API_KEY,
|
|
4
25
|
executionTimeout: '1m',
|
|
5
26
|
maxActivities: 100,
|
|
6
27
|
maxWorkflows: 100,
|
|
7
|
-
namespace:
|
|
8
|
-
taskQueue:
|
|
28
|
+
namespace: safeEnvVar.TEMPORAL_NAMESPACE ?? 'default',
|
|
29
|
+
taskQueue: safeEnvVar.CATALOG_ID,
|
|
30
|
+
catalogId: safeEnvVar.CATALOG_ID
|
|
9
31
|
};
|
|
10
32
|
|
|
11
33
|
export const api = {
|
|
12
|
-
authKey:
|
|
34
|
+
authKey: safeEnvVar.API_AUTH_KEY
|
|
13
35
|
};
|
|
14
36
|
|
|
15
37
|
export const tracing = {
|
|
16
|
-
enabled:
|
|
38
|
+
enabled: safeEnvVar.TRACING_ENABLED
|
|
17
39
|
};
|
package/src/worker/index.js
CHANGED
|
@@ -15,7 +15,7 @@ const __dirname = dirname( fileURLToPath( import.meta.url ) );
|
|
|
15
15
|
// expose the coreTracker so other parts of the SDK can use it
|
|
16
16
|
setupGlobalTracer();
|
|
17
17
|
|
|
18
|
-
const { address, apiKey, maxActivities, maxWorkflows, namespace, taskQueue } = workerConfig;
|
|
18
|
+
const { address, apiKey, maxActivities, maxWorkflows, namespace, taskQueue, catalogId } = workerConfig;
|
|
19
19
|
|
|
20
20
|
// Get caller directory from command line arguments
|
|
21
21
|
const callerDir = process.argv[2];
|
|
@@ -75,7 +75,7 @@ const callerDir = process.argv[2];
|
|
|
75
75
|
console.log( '[Core]', 'Starting catalog workflow...' );
|
|
76
76
|
await new Client( { connection, namespace } ).workflow.start( 'catalog', {
|
|
77
77
|
taskQueue,
|
|
78
|
-
workflowId:
|
|
78
|
+
workflowId: catalogId, // use the name of the task queue as the catalog name, ensuring uniqueness
|
|
79
79
|
workflowIdConflictPolicy: WorkflowIdConflictPolicy.TERMINATE_EXISTING,
|
|
80
80
|
args: [ catalog ]
|
|
81
81
|
} );
|
|
@@ -6,12 +6,33 @@ import { THIS_LIB_NAME } from '#consts';
|
|
|
6
6
|
|
|
7
7
|
const createTempDir = () => mkdtempSync( join( tmpdir(), 'flow-sdk-trace-' ) );
|
|
8
8
|
|
|
9
|
+
// Single mocks (configured per-test by mutating the backing objects)
|
|
10
|
+
const mockConfig = { tracing: { enabled: false } };
|
|
11
|
+
vi.mock( '#configs', () => mockConfig );
|
|
12
|
+
|
|
13
|
+
const mockStorageData = {
|
|
14
|
+
activityId: 's1',
|
|
15
|
+
activityType: 'Step 1',
|
|
16
|
+
workflowId: 'wf1',
|
|
17
|
+
workflowType: 'prompt',
|
|
18
|
+
workflowPath: '/workflows/prompt.js',
|
|
19
|
+
parentWorkflowId: undefined,
|
|
20
|
+
rootWorkflowId: undefined,
|
|
21
|
+
rootWorkflowType: undefined
|
|
22
|
+
};
|
|
23
|
+
vi.mock( '../async_storage.js', () => ( {
|
|
24
|
+
Storage: { load: () => mockStorageData }
|
|
25
|
+
} ) );
|
|
26
|
+
|
|
27
|
+
vi.mock( './tracer_tree.js', () => ( { buildLogTree: vi.fn() } ) );
|
|
28
|
+
|
|
9
29
|
describe( 'tracer/index', () => {
|
|
10
30
|
beforeEach( () => {
|
|
11
31
|
vi.resetModules();
|
|
12
32
|
vi.clearAllMocks();
|
|
13
33
|
vi.useFakeTimers();
|
|
14
34
|
vi.setSystemTime( new Date( '2020-01-01T00:00:00.000Z' ) );
|
|
35
|
+
|
|
15
36
|
} );
|
|
16
37
|
|
|
17
38
|
afterEach( () => {
|
|
@@ -23,29 +44,14 @@ describe( 'tracer/index', () => {
|
|
|
23
44
|
const tmp = createTempDir();
|
|
24
45
|
process.argv[2] = tmp;
|
|
25
46
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
Storage: {
|
|
30
|
-
load: () => ( {
|
|
31
|
-
activityId: 's1',
|
|
32
|
-
activityType: 'Step 1',
|
|
33
|
-
workflowId: 'wf1',
|
|
34
|
-
workflowType: 'prompt',
|
|
35
|
-
workflowPath: '/workflows/prompt.js',
|
|
36
|
-
parentWorkflowId: undefined,
|
|
37
|
-
rootWorkflowId: undefined,
|
|
38
|
-
rootWorkflowType: undefined
|
|
39
|
-
} )
|
|
40
|
-
}
|
|
41
|
-
} ) );
|
|
42
|
-
vi.mock( './tracer_tree.js', () => ( { buildLogTree: vi.fn() } ) );
|
|
47
|
+
mockConfig.tracing.enabled = true;
|
|
48
|
+
|
|
49
|
+
const { buildLogTree } = await import( './tracer_tree.js' );
|
|
43
50
|
const { trace } = await import( './index.js' );
|
|
44
51
|
|
|
45
52
|
const input = { foo: 1 };
|
|
46
53
|
trace( { lib: THIS_LIB_NAME, event: 'workflow_start', input, output: null } );
|
|
47
54
|
|
|
48
|
-
const { buildLogTree } = await import( './tracer_tree.js' );
|
|
49
55
|
expect( buildLogTree ).toHaveBeenCalledTimes( 1 );
|
|
50
56
|
const logPath = buildLogTree.mock.calls[0][0];
|
|
51
57
|
|
|
@@ -67,7 +73,6 @@ describe( 'tracer/index', () => {
|
|
|
67
73
|
expect( typeof entry.timestamp ).toBe( 'number' );
|
|
68
74
|
|
|
69
75
|
rmSync( tmp, { recursive: true, force: true } );
|
|
70
|
-
process.env.TRACING_ENABLED = prevTracing;
|
|
71
76
|
process.argv[2] = originalArgv2;
|
|
72
77
|
} );
|
|
73
78
|
|
|
@@ -76,40 +81,23 @@ describe( 'tracer/index', () => {
|
|
|
76
81
|
const tmp = createTempDir();
|
|
77
82
|
process.argv[2] = tmp;
|
|
78
83
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
vi.mock( '../async_storage.js', () => ( {
|
|
82
|
-
Storage: {
|
|
83
|
-
load: () => ( {
|
|
84
|
-
activityId: 's1',
|
|
85
|
-
activityType: 'Step 1',
|
|
86
|
-
workflowId: 'wf1',
|
|
87
|
-
workflowType: 'prompt',
|
|
88
|
-
workflowPath: '/workflows/prompt.js'
|
|
89
|
-
} )
|
|
90
|
-
}
|
|
91
|
-
} ) );
|
|
92
|
-
vi.mock( './tracer_tree.js', () => ( { buildLogTree: vi.fn() } ) );
|
|
84
|
+
mockConfig.tracing.enabled = false;
|
|
85
|
+
const { buildLogTree } = await import( './tracer_tree.js' );
|
|
93
86
|
const { trace } = await import( './index.js' );
|
|
94
87
|
|
|
95
88
|
trace( { lib: THIS_LIB_NAME, event: 'workflow_start', input: {}, output: null } );
|
|
96
89
|
|
|
97
|
-
const { buildLogTree } = await import( './tracer_tree.js' );
|
|
98
90
|
expect( buildLogTree ).not.toHaveBeenCalled();
|
|
99
91
|
|
|
100
92
|
rmSync( tmp, { recursive: true, force: true } );
|
|
101
|
-
process.env.TRACING_ENABLED = prevTracing;
|
|
102
93
|
process.argv[2] = originalArgv2;
|
|
103
94
|
} );
|
|
104
95
|
|
|
105
96
|
it( 'setupGlobalTracer installs global symbol', async () => {
|
|
106
|
-
|
|
107
|
-
process.env.TRACING_ENABLED = 'false';
|
|
97
|
+
mockConfig.tracing.enabled = false;
|
|
108
98
|
const { setupGlobalTracer } = await import( './index.js' );
|
|
109
99
|
setupGlobalTracer();
|
|
110
100
|
const sym = Symbol.for( '__trace' );
|
|
111
101
|
expect( typeof globalThis[sym] ).toBe( 'function' );
|
|
112
|
-
process.env.TRACING_ENABLED = prevTracing;
|
|
113
102
|
} );
|
|
114
103
|
} );
|
|
115
|
-
|