@claushaas/ergon-engine 0.1.2
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/LICENSE +1 -0
- package/README.md +13 -0
- package/dist/defaults.d.ts +11 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/defaults.js +27 -0
- package/dist/defaults.js.map +1 -0
- package/dist/executors/agent.d.ts +12 -0
- package/dist/executors/agent.d.ts.map +1 -0
- package/dist/executors/agent.js +80 -0
- package/dist/executors/agent.js.map +1 -0
- package/dist/executors/artifact.d.ts +7 -0
- package/dist/executors/artifact.d.ts.map +1 -0
- package/dist/executors/artifact.js +148 -0
- package/dist/executors/artifact.js.map +1 -0
- package/dist/executors/condition.d.ts +7 -0
- package/dist/executors/condition.d.ts.map +1 -0
- package/dist/executors/condition.js +53 -0
- package/dist/executors/condition.js.map +1 -0
- package/dist/executors/exec.d.ts +32 -0
- package/dist/executors/exec.d.ts.map +1 -0
- package/dist/executors/exec.js +169 -0
- package/dist/executors/exec.js.map +1 -0
- package/dist/executors/index.d.ts +54 -0
- package/dist/executors/index.d.ts.map +1 -0
- package/dist/executors/index.js +49 -0
- package/dist/executors/index.js.map +1 -0
- package/dist/executors/manual.d.ts +7 -0
- package/dist/executors/manual.d.ts.map +1 -0
- package/dist/executors/manual.js +25 -0
- package/dist/executors/manual.js.map +1 -0
- package/dist/executors/notify.d.ts +48 -0
- package/dist/executors/notify.d.ts.map +1 -0
- package/dist/executors/notify.js +313 -0
- package/dist/executors/notify.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/runner.d.ts +11 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +1061 -0
- package/dist/runner.js.map +1 -0
- package/dist/templating/index.d.ts +43 -0
- package/dist/templating/index.d.ts.map +1 -0
- package/dist/templating/index.js +778 -0
- package/dist/templating/index.js.map +1 -0
- package/dist/worker.d.ts +26 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +320 -0
- package/dist/worker.js.map +1 -0
- package/dist/workflowIdentity.d.ts +3 -0
- package/dist/workflowIdentity.d.ts.map +1 -0
- package/dist/workflowIdentity.js +12 -0
- package/dist/workflowIdentity.js.map +1 -0
- package/package.json +44 -0
package/LICENSE
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
MIT
|
package/README.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type ProviderConfigMap } from '@claushaas/ergon-clients';
|
|
2
|
+
import { type ExecExecutorOptions } from './executors/exec.js';
|
|
3
|
+
import { ExecutorRegistry } from './executors/index.js';
|
|
4
|
+
import { type NotifyExecutorOptions } from './executors/notify.js';
|
|
5
|
+
export interface CreateDefaultExecutorRegistryOptions {
|
|
6
|
+
exec?: ExecExecutorOptions;
|
|
7
|
+
notify?: NotifyExecutorOptions;
|
|
8
|
+
providerConfigs?: ProviderConfigMap;
|
|
9
|
+
}
|
|
10
|
+
export declare function createDefaultExecutorRegistry(options?: CreateDefaultExecutorRegistryOptions): ExecutorRegistry;
|
|
11
|
+
//# sourceMappingURL=defaults.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../src/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,KAAK,iBAAiB,EACtB,MAAM,0BAA0B,CAAC;AAIlC,OAAO,EAAgB,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,OAAO,EAEN,KAAK,qBAAqB,EAC1B,MAAM,uBAAuB,CAAC;AAE/B,MAAM,WAAW,oCAAoC;IACpD,IAAI,CAAC,EAAE,mBAAmB,CAAC;IAC3B,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B,eAAe,CAAC,EAAE,iBAAiB,CAAC;CACpC;AAED,wBAAgB,6BAA6B,CAC5C,OAAO,GAAE,oCAAyC,GAChD,gBAAgB,CAoBlB"}
|
package/dist/defaults.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { createClientRegistry, } from '@claushaas/ergon-clients';
|
|
2
|
+
import { AgentExecutor } from './executors/agent.js';
|
|
3
|
+
import { ArtifactExecutor } from './executors/artifact.js';
|
|
4
|
+
import { ConditionExecutor } from './executors/condition.js';
|
|
5
|
+
import { ExecExecutor } from './executors/exec.js';
|
|
6
|
+
import { ExecutorRegistry } from './executors/index.js';
|
|
7
|
+
import { ManualExecutor } from './executors/manual.js';
|
|
8
|
+
import { NotifyExecutor, } from './executors/notify.js';
|
|
9
|
+
export function createDefaultExecutorRegistry(options = {}) {
|
|
10
|
+
const clientRegistry = createClientRegistry(options.providerConfigs);
|
|
11
|
+
return new ExecutorRegistry([
|
|
12
|
+
new AgentExecutor({
|
|
13
|
+
resolveClient(provider) {
|
|
14
|
+
return clientRegistry.get(provider);
|
|
15
|
+
},
|
|
16
|
+
}),
|
|
17
|
+
new ArtifactExecutor(),
|
|
18
|
+
new ConditionExecutor(),
|
|
19
|
+
new ExecExecutor(options.exec),
|
|
20
|
+
new ManualExecutor(),
|
|
21
|
+
new NotifyExecutor({
|
|
22
|
+
...options.notify,
|
|
23
|
+
openclaw: options.providerConfigs?.openclaw,
|
|
24
|
+
}),
|
|
25
|
+
]);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=defaults.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.js","sourceRoot":"","sources":["../src/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,oBAAoB,GAEpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAA4B,MAAM,qBAAqB,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EACN,cAAc,GAEd,MAAM,uBAAuB,CAAC;AAQ/B,MAAM,UAAU,6BAA6B,CAC5C,UAAgD,EAAE;IAElD,MAAM,cAAc,GAAG,oBAAoB,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IAErE,OAAO,IAAI,gBAAgB,CAAC;QAC3B,IAAI,aAAa,CAAC;YACjB,aAAa,CAAC,QAAQ;gBACrB,OAAO,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACrC,CAAC;SACD,CAAC;QACF,IAAI,gBAAgB,EAAE;QACtB,IAAI,iBAAiB,EAAE;QACvB,IAAI,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC;QAC9B,IAAI,cAAc,EAAE;QACpB,IAAI,cAAc,CAAC;YAClB,GAAG,OAAO,CAAC,MAAM;YACjB,QAAQ,EAAE,OAAO,CAAC,eAAe,EAAE,QAEvB;SACZ,CAAC;KACF,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AgentStepDefinition, ExecutionClient, Provider } from '@claushaas/ergon-shared';
|
|
2
|
+
import type { ExecutionContext, Executor, ExecutorResult } from './index.js';
|
|
3
|
+
export interface AgentExecutorOptions {
|
|
4
|
+
resolveClient: (provider: Provider) => ExecutionClient;
|
|
5
|
+
}
|
|
6
|
+
export declare class AgentExecutor implements Executor<AgentStepDefinition> {
|
|
7
|
+
readonly kind: "agent";
|
|
8
|
+
private readonly resolveClient;
|
|
9
|
+
constructor(options: AgentExecutorOptions);
|
|
10
|
+
execute(step: AgentStepDefinition, context: ExecutionContext): Promise<ExecutorResult>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/executors/agent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEX,mBAAmB,EAEnB,eAAe,EACf,QAAQ,EACR,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE7E,MAAM,WAAW,oBAAoB;IACpC,aAAa,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,eAAe,CAAC;CACvD;AAwCD,qBAAa,aAAc,YAAW,QAAQ,CAAC,mBAAmB,CAAC;IAClE,SAAgB,IAAI,EAAG,OAAO,CAAU;IACxC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAwC;gBAEnD,OAAO,EAAE,oBAAoB;IAInC,OAAO,CACnB,IAAI,EAAE,mBAAmB,EACzB,OAAO,EAAE,gBAAgB,GACvB,OAAO,CAAC,cAAc,CAAC;CA6C1B"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { renderStepRequestPayload } from '../templating/index.js';
|
|
2
|
+
function normalizeAgentArtifactName(step) {
|
|
3
|
+
if (step.output?.name) {
|
|
4
|
+
return step.output.name;
|
|
5
|
+
}
|
|
6
|
+
if (step.id === 'analyze') {
|
|
7
|
+
return 'analysis';
|
|
8
|
+
}
|
|
9
|
+
return step.id;
|
|
10
|
+
}
|
|
11
|
+
function tryParseJson(value) {
|
|
12
|
+
try {
|
|
13
|
+
return JSON.parse(value);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function normalizeAgentArtifactType(step, artifactName, parsedJson) {
|
|
20
|
+
if (step.output?.type) {
|
|
21
|
+
return step.output.type;
|
|
22
|
+
}
|
|
23
|
+
if (artifactName === 'analysis') {
|
|
24
|
+
return 'analysis';
|
|
25
|
+
}
|
|
26
|
+
if (artifactName === 'plan') {
|
|
27
|
+
return 'plan';
|
|
28
|
+
}
|
|
29
|
+
if (parsedJson !== undefined) {
|
|
30
|
+
return 'json';
|
|
31
|
+
}
|
|
32
|
+
return 'text';
|
|
33
|
+
}
|
|
34
|
+
export class AgentExecutor {
|
|
35
|
+
kind = 'agent';
|
|
36
|
+
resolveClient;
|
|
37
|
+
constructor(options) {
|
|
38
|
+
this.resolveClient = options.resolveClient;
|
|
39
|
+
}
|
|
40
|
+
async execute(step, context) {
|
|
41
|
+
const payload = renderStepRequestPayload(step, {
|
|
42
|
+
artifacts: context.artifacts,
|
|
43
|
+
inputs: context.inputs,
|
|
44
|
+
});
|
|
45
|
+
if (!payload.prompt) {
|
|
46
|
+
throw new Error(`Agent step "${step.id}" did not render a prompt`);
|
|
47
|
+
}
|
|
48
|
+
const client = this.resolveClient(step.provider);
|
|
49
|
+
const request = {
|
|
50
|
+
model: step.model,
|
|
51
|
+
prompt: payload.prompt,
|
|
52
|
+
provider: step.provider,
|
|
53
|
+
signal: context.signal,
|
|
54
|
+
};
|
|
55
|
+
const result = await client.run(request);
|
|
56
|
+
const parsedJson = tryParseJson(result.text);
|
|
57
|
+
const artifactName = normalizeAgentArtifactName(step);
|
|
58
|
+
const artifactValue = parsedJson ?? result.text;
|
|
59
|
+
const artifactType = normalizeAgentArtifactType(step, artifactName, parsedJson);
|
|
60
|
+
return {
|
|
61
|
+
artifacts: [
|
|
62
|
+
{
|
|
63
|
+
name: artifactName,
|
|
64
|
+
type: artifactType,
|
|
65
|
+
value: artifactValue,
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
outputs: {
|
|
69
|
+
artifact_name: artifactName,
|
|
70
|
+
attempt: context.run.attempt,
|
|
71
|
+
provider: step.provider,
|
|
72
|
+
request,
|
|
73
|
+
response: result.raw ?? result.text,
|
|
74
|
+
text: result.text,
|
|
75
|
+
},
|
|
76
|
+
status: 'succeeded',
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/executors/agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ArtifactStepDefinition } from '@claushaas/ergon-shared';
|
|
2
|
+
import type { ExecutionContext, Executor, ExecutorResult } from './index.js';
|
|
3
|
+
export declare class ArtifactExecutor implements Executor<ArtifactStepDefinition> {
|
|
4
|
+
readonly kind: "artifact";
|
|
5
|
+
execute(step: ArtifactStepDefinition, context: ExecutionContext): Promise<ExecutorResult>;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=artifact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifact.d.ts","sourceRoot":"","sources":["../../src/executors/artifact.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAuI7E,qBAAa,gBAAiB,YAAW,QAAQ,CAAC,sBAAsB,CAAC;IACxE,SAAgB,IAAI,EAAG,UAAU,CAAU;IAE9B,OAAO,CACnB,IAAI,EAAE,sBAAsB,EAC5B,OAAO,EAAE,gBAAgB,GACvB,OAAO,CAAC,cAAc,CAAC;CAwD1B"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
const RESERVED_ARTIFACT_KEYS = new Set([
|
|
2
|
+
'__proto__',
|
|
3
|
+
'constructor',
|
|
4
|
+
'prototype',
|
|
5
|
+
]);
|
|
6
|
+
function isRecord(value) {
|
|
7
|
+
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
8
|
+
}
|
|
9
|
+
function isReservedArtifactKey(key) {
|
|
10
|
+
return RESERVED_ARTIFACT_KEYS.has(key);
|
|
11
|
+
}
|
|
12
|
+
function assertSafeArtifactName(name, stepId) {
|
|
13
|
+
if (!name || isReservedArtifactKey(name)) {
|
|
14
|
+
throw new Error(`Artifact step "${stepId}" uses a reserved output name`);
|
|
15
|
+
}
|
|
16
|
+
return name;
|
|
17
|
+
}
|
|
18
|
+
function cloneArtifactValue(value) {
|
|
19
|
+
if (Array.isArray(value)) {
|
|
20
|
+
return [...value];
|
|
21
|
+
}
|
|
22
|
+
if (isRecord(value)) {
|
|
23
|
+
const copy = {};
|
|
24
|
+
for (const [key, entryValue] of Object.entries(value)) {
|
|
25
|
+
if (!isReservedArtifactKey(key)) {
|
|
26
|
+
copy[key] = entryValue;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return copy;
|
|
30
|
+
}
|
|
31
|
+
return value;
|
|
32
|
+
}
|
|
33
|
+
function getPathValue(source, path) {
|
|
34
|
+
const pathParts = path
|
|
35
|
+
.split('.')
|
|
36
|
+
.map((part) => part.trim())
|
|
37
|
+
.filter((part) => part.length > 0);
|
|
38
|
+
if (pathParts.length === 0) {
|
|
39
|
+
throw new Error('Artifact extract operation requires a non-empty field path');
|
|
40
|
+
}
|
|
41
|
+
let current = source;
|
|
42
|
+
for (const part of pathParts) {
|
|
43
|
+
if (!isRecord(current) ||
|
|
44
|
+
isReservedArtifactKey(part) ||
|
|
45
|
+
!Object.hasOwn(current, part)) {
|
|
46
|
+
throw new Error(`Artifact field "${path}" was not found`);
|
|
47
|
+
}
|
|
48
|
+
current = current[part];
|
|
49
|
+
}
|
|
50
|
+
return current;
|
|
51
|
+
}
|
|
52
|
+
function parseOperation(step) {
|
|
53
|
+
const [rawType, ...rawArgs] = step.operation.split(':');
|
|
54
|
+
const type = rawType?.trim();
|
|
55
|
+
const args = rawArgs.map((part) => part.trim());
|
|
56
|
+
switch (type) {
|
|
57
|
+
case 'copy':
|
|
58
|
+
return {
|
|
59
|
+
outputName: assertSafeArtifactName(args[0] || step.id, step.id),
|
|
60
|
+
type,
|
|
61
|
+
};
|
|
62
|
+
case 'rename':
|
|
63
|
+
if (!args[0]) {
|
|
64
|
+
throw new Error(`Artifact step "${step.id}" requires a target name for rename`);
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
outputName: assertSafeArtifactName(args[0], step.id),
|
|
68
|
+
type,
|
|
69
|
+
};
|
|
70
|
+
case 'extract':
|
|
71
|
+
if (!args[0]) {
|
|
72
|
+
throw new Error(`Artifact step "${step.id}" requires a field path for extract`);
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
extractPath: args[0],
|
|
76
|
+
outputName: assertSafeArtifactName(args[1] || step.id, step.id),
|
|
77
|
+
type,
|
|
78
|
+
};
|
|
79
|
+
case 'merge': {
|
|
80
|
+
const mergeInputs = args[0]
|
|
81
|
+
?.split(',')
|
|
82
|
+
.map((value) => value.trim())
|
|
83
|
+
.filter((value) => value.length > 0);
|
|
84
|
+
if (!mergeInputs || mergeInputs.length === 0) {
|
|
85
|
+
throw new Error(`Artifact step "${step.id}" requires at least one artifact for merge`);
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
mergeInputs,
|
|
89
|
+
outputName: assertSafeArtifactName(args[1] || step.id, step.id),
|
|
90
|
+
type,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
default:
|
|
94
|
+
throw new Error(`Artifact step "${step.id}" uses unsupported operation "${step.operation}"`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
export class ArtifactExecutor {
|
|
98
|
+
kind = 'artifact';
|
|
99
|
+
async execute(step, context) {
|
|
100
|
+
const operation = parseOperation(step);
|
|
101
|
+
const inputValue = context.getRequiredArtifact(step.input);
|
|
102
|
+
let value;
|
|
103
|
+
switch (operation.type) {
|
|
104
|
+
case 'copy':
|
|
105
|
+
case 'rename':
|
|
106
|
+
value = cloneArtifactValue(inputValue);
|
|
107
|
+
break;
|
|
108
|
+
case 'extract':
|
|
109
|
+
value = getPathValue(inputValue, operation.extractPath);
|
|
110
|
+
break;
|
|
111
|
+
case 'merge': {
|
|
112
|
+
if (!isRecord(inputValue)) {
|
|
113
|
+
throw new Error(`Artifact step "${step.id}" requires object input for merge`);
|
|
114
|
+
}
|
|
115
|
+
const merged = { ...inputValue };
|
|
116
|
+
for (const artifactName of operation.mergeInputs) {
|
|
117
|
+
const artifactValue = context.getRequiredArtifact(artifactName);
|
|
118
|
+
if (!isRecord(artifactValue)) {
|
|
119
|
+
throw new Error(`Artifact step "${step.id}" requires object artifact "${artifactName}" for merge`);
|
|
120
|
+
}
|
|
121
|
+
for (const [key, artifactEntryValue] of Object.entries(artifactValue)) {
|
|
122
|
+
if (!isReservedArtifactKey(key)) {
|
|
123
|
+
merged[key] = artifactEntryValue;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
value = merged;
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
artifacts: [
|
|
133
|
+
{
|
|
134
|
+
name: operation.outputName,
|
|
135
|
+
type: 'json',
|
|
136
|
+
value,
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
outputs: {
|
|
140
|
+
input: step.input,
|
|
141
|
+
name: operation.outputName,
|
|
142
|
+
operation: step.operation,
|
|
143
|
+
},
|
|
144
|
+
status: 'succeeded',
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=artifact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifact.js","sourceRoot":"","sources":["../../src/executors/artifact.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ConditionStepDefinition } from '@claushaas/ergon-shared';
|
|
2
|
+
import type { ExecutionContext, Executor, ExecutorResult } from './index.js';
|
|
3
|
+
export declare class ConditionExecutor implements Executor<ConditionStepDefinition> {
|
|
4
|
+
readonly kind: "condition";
|
|
5
|
+
execute(step: ConditionStepDefinition, context: ExecutionContext): Promise<ExecutorResult>;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=condition.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"condition.d.ts","sourceRoot":"","sources":["../../src/executors/condition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAEvE,OAAO,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAoC7E,qBAAa,iBAAkB,YAAW,QAAQ,CAAC,uBAAuB,CAAC;IAC1E,SAAgB,IAAI,EAAG,WAAW,CAAU;IAE/B,OAAO,CACnB,IAAI,EAAE,uBAAuB,EAC7B,OAAO,EAAE,gBAAgB,GACvB,OAAO,CAAC,cAAc,CAAC;CAe1B"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { interpolateTemplateString } from '../templating/index.js';
|
|
2
|
+
function coerceConditionValue(value) {
|
|
3
|
+
if (typeof value === 'boolean') {
|
|
4
|
+
return value;
|
|
5
|
+
}
|
|
6
|
+
if (typeof value === 'number') {
|
|
7
|
+
return value !== 0;
|
|
8
|
+
}
|
|
9
|
+
if (typeof value === 'string') {
|
|
10
|
+
const normalized = value.trim();
|
|
11
|
+
if (!normalized) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
if (normalized === 'true') {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
if (['false', 'null', 'undefined'].includes(normalized)) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
return coerceConditionValue(JSON.parse(normalized));
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
// A non-JSON string literal is treated as truthy by design.
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (Array.isArray(value)) {
|
|
29
|
+
return value.length > 0;
|
|
30
|
+
}
|
|
31
|
+
if (value && typeof value === 'object') {
|
|
32
|
+
return Object.keys(value).length > 0;
|
|
33
|
+
}
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
export class ConditionExecutor {
|
|
37
|
+
kind = 'condition';
|
|
38
|
+
async execute(step, context) {
|
|
39
|
+
const expression = interpolateTemplateString(step.expression, {
|
|
40
|
+
artifacts: context.artifacts,
|
|
41
|
+
inputs: context.inputs,
|
|
42
|
+
});
|
|
43
|
+
const passed = coerceConditionValue(expression);
|
|
44
|
+
return {
|
|
45
|
+
outputs: {
|
|
46
|
+
expression,
|
|
47
|
+
passed,
|
|
48
|
+
},
|
|
49
|
+
status: 'succeeded',
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=condition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"condition.js","sourceRoot":"","sources":["../../src/executors/condition.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAGnE,SAAS,oBAAoB,CAAC,KAAc;IAC3C,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;QAChC,OAAO,KAAK,CAAC;IACd,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,KAAK,KAAK,CAAC,CAAC;IACpB,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAChC,IAAI,CAAC,UAAU,EAAE,CAAC;YACjB,OAAO,KAAK,CAAC;QACd,CAAC;QACD,IAAI,UAAU,KAAK,MAAM,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAC;QACb,CAAC;QACD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACzD,OAAO,KAAK,CAAC;QACd,CAAC;QACD,IAAI,CAAC;YACJ,OAAO,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;QACrD,CAAC;QAAC,MAAM,CAAC;YACR,4DAA4D;YAC5D,OAAO,IAAI,CAAC;QACb,CAAC;IACF,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IACzB,CAAC;IACD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxC,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,MAAM,OAAO,iBAAiB;IACb,IAAI,GAAG,WAAoB,CAAC;IAErC,KAAK,CAAC,OAAO,CACnB,IAA6B,EAC7B,OAAyB;QAEzB,MAAM,UAAU,GAAG,yBAAyB,CAAC,IAAI,CAAC,UAAU,EAAE;YAC7D,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,MAAM,EAAE,OAAO,CAAC,MAAM;SACtB,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;QAEhD,OAAO;YACN,OAAO,EAAE;gBACR,UAAU;gBACV,MAAM;aACN;YACD,MAAM,EAAE,WAAW;SACnB,CAAC;IACH,CAAC;CACD"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { spawn as nodeSpawn } from 'node:child_process';
|
|
2
|
+
import { type ExecStepDefinition } from '@claushaas/ergon-shared';
|
|
3
|
+
import type { ExecutionContext, Executor, ExecutorResult } from './index.js';
|
|
4
|
+
export declare const DEFAULT_EXEC_MAX_OUTPUT_BYTES: number;
|
|
5
|
+
export interface ExecSpawnResult {
|
|
6
|
+
code: number | null;
|
|
7
|
+
signal: NodeJS.Signals | null;
|
|
8
|
+
stderr: string;
|
|
9
|
+
stdout: string;
|
|
10
|
+
}
|
|
11
|
+
export type ExecSpawn = (options: {
|
|
12
|
+
command: string;
|
|
13
|
+
cwd?: string;
|
|
14
|
+
env?: Record<string, string>;
|
|
15
|
+
signal?: AbortSignal;
|
|
16
|
+
}) => Promise<ExecSpawnResult>;
|
|
17
|
+
export interface ExecExecutorOptions {
|
|
18
|
+
spawn?: ExecSpawn;
|
|
19
|
+
}
|
|
20
|
+
export declare function defaultSpawn(options: {
|
|
21
|
+
command: string;
|
|
22
|
+
cwd?: string;
|
|
23
|
+
env?: Record<string, string>;
|
|
24
|
+
signal?: AbortSignal;
|
|
25
|
+
}, spawnImpl?: typeof nodeSpawn): Promise<ExecSpawnResult>;
|
|
26
|
+
export declare class ExecExecutor implements Executor<ExecStepDefinition> {
|
|
27
|
+
readonly kind: "exec";
|
|
28
|
+
private readonly spawn;
|
|
29
|
+
constructor(options?: ExecExecutorOptions);
|
|
30
|
+
execute(step: ExecStepDefinition, context: ExecutionContext): Promise<ExecutorResult>;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=exec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../src/executors/exec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAEN,KAAK,kBAAkB,EACvB,MAAM,yBAAyB,CAAC;AAKjC,OAAO,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE7E,eAAO,MAAM,6BAA6B,QAAc,CAAC;AAEzD,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,EAAE;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;AAE/B,MAAM,WAAW,mBAAmB;IACnC,KAAK,CAAC,EAAE,SAAS,CAAC;CAClB;AAsCD,wBAAsB,YAAY,CACjC,OAAO,EAAE;IACR,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB,EACD,SAAS,GAAE,OAAO,SAAqB,GACrC,OAAO,CAAC,eAAe,CAAC,CAwE1B;AAED,qBAAa,YAAa,YAAW,QAAQ,CAAC,kBAAkB,CAAC;IAChE,SAAgB,IAAI,EAAG,MAAM,CAAU;IACvC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAY;gBAEf,OAAO,GAAE,mBAAwB;IAIvC,OAAO,CACnB,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,gBAAgB,GACvB,OAAO,CAAC,cAAc,CAAC;CAiE1B"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { spawn as nodeSpawn } from 'node:child_process';
|
|
2
|
+
import { createChildProcessAbortController, } from '@claushaas/ergon-shared';
|
|
3
|
+
import { interpolateTemplateString, renderStepRequestPayload, } from '../templating/index.js';
|
|
4
|
+
export const DEFAULT_EXEC_MAX_OUTPUT_BYTES = 1024 * 1024;
|
|
5
|
+
const DEFAULT_EXEC_ENV_KEYS = [
|
|
6
|
+
'HOME',
|
|
7
|
+
'LANG',
|
|
8
|
+
'PATH',
|
|
9
|
+
'SHELL',
|
|
10
|
+
'SYSTEMROOT',
|
|
11
|
+
'TMPDIR',
|
|
12
|
+
];
|
|
13
|
+
function createOutputLimitError(stream) {
|
|
14
|
+
return new Error(`Exec command ${stream} exceeded ${DEFAULT_EXEC_MAX_OUTPUT_BYTES} bytes`);
|
|
15
|
+
}
|
|
16
|
+
function decodeOutput(chunks) {
|
|
17
|
+
return Buffer.concat(chunks).toString('utf8');
|
|
18
|
+
}
|
|
19
|
+
function normalizeChunk(chunk) {
|
|
20
|
+
return Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
21
|
+
}
|
|
22
|
+
function buildSpawnEnv(env) {
|
|
23
|
+
const inheritedEntries = DEFAULT_EXEC_ENV_KEYS.flatMap((key) => {
|
|
24
|
+
const value = process.env[key];
|
|
25
|
+
return typeof value === 'string' ? [[key, value]] : [];
|
|
26
|
+
});
|
|
27
|
+
return {
|
|
28
|
+
...Object.fromEntries(inheritedEntries),
|
|
29
|
+
...(env ?? {}),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export async function defaultSpawn(options, spawnImpl = nodeSpawn) {
|
|
33
|
+
return await new Promise((resolve, reject) => {
|
|
34
|
+
const child = spawnImpl('bash', ['-c', options.command], {
|
|
35
|
+
cwd: options.cwd,
|
|
36
|
+
env: buildSpawnEnv(options.env),
|
|
37
|
+
stdio: 'pipe',
|
|
38
|
+
});
|
|
39
|
+
const stdoutChunks = [];
|
|
40
|
+
const stderrChunks = [];
|
|
41
|
+
let stdoutBytes = 0;
|
|
42
|
+
let stderrBytes = 0;
|
|
43
|
+
let settled = false;
|
|
44
|
+
const { cleanupAbort, registerAbort } = createChildProcessAbortController({
|
|
45
|
+
abortMessage: 'Exec command aborted',
|
|
46
|
+
child,
|
|
47
|
+
isSettled: () => settled,
|
|
48
|
+
onAbort: reject,
|
|
49
|
+
setSettled: () => {
|
|
50
|
+
settled = true;
|
|
51
|
+
},
|
|
52
|
+
signal: options.signal,
|
|
53
|
+
});
|
|
54
|
+
const settle = (handler) => {
|
|
55
|
+
if (settled) {
|
|
56
|
+
cleanupAbort();
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
settled = true;
|
|
60
|
+
cleanupAbort();
|
|
61
|
+
return handler();
|
|
62
|
+
};
|
|
63
|
+
const fail = (error) => {
|
|
64
|
+
settle(() => {
|
|
65
|
+
child.kill('SIGTERM');
|
|
66
|
+
reject(error);
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
child.stdout.on('data', (chunk) => {
|
|
70
|
+
const normalized = normalizeChunk(chunk);
|
|
71
|
+
stdoutBytes += normalized.byteLength;
|
|
72
|
+
if (stdoutBytes > DEFAULT_EXEC_MAX_OUTPUT_BYTES) {
|
|
73
|
+
fail(createOutputLimitError('stdout'));
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
stdoutChunks.push(normalized);
|
|
77
|
+
});
|
|
78
|
+
child.stderr.on('data', (chunk) => {
|
|
79
|
+
const normalized = normalizeChunk(chunk);
|
|
80
|
+
stderrBytes += normalized.byteLength;
|
|
81
|
+
if (stderrBytes > DEFAULT_EXEC_MAX_OUTPUT_BYTES) {
|
|
82
|
+
fail(createOutputLimitError('stderr'));
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
stderrChunks.push(normalized);
|
|
86
|
+
});
|
|
87
|
+
child.on('error', fail);
|
|
88
|
+
child.on('close', (code, signal) => {
|
|
89
|
+
settle(() => resolve({
|
|
90
|
+
code,
|
|
91
|
+
signal,
|
|
92
|
+
stderr: decodeOutput(stderrChunks),
|
|
93
|
+
stdout: decodeOutput(stdoutChunks),
|
|
94
|
+
}));
|
|
95
|
+
});
|
|
96
|
+
if (registerAbort()) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
export class ExecExecutor {
|
|
102
|
+
kind = 'exec';
|
|
103
|
+
spawn;
|
|
104
|
+
constructor(options = {}) {
|
|
105
|
+
this.spawn = options.spawn ?? defaultSpawn;
|
|
106
|
+
}
|
|
107
|
+
async execute(step, context) {
|
|
108
|
+
const payload = renderStepRequestPayload(step, {
|
|
109
|
+
artifacts: context.artifacts,
|
|
110
|
+
inputs: context.inputs,
|
|
111
|
+
});
|
|
112
|
+
if (!payload.command) {
|
|
113
|
+
throw new Error(`Exec step "${step.id}" did not render a command`);
|
|
114
|
+
}
|
|
115
|
+
const cwd = step.cwd
|
|
116
|
+
? interpolateTemplateString(step.cwd, {
|
|
117
|
+
artifacts: context.artifacts,
|
|
118
|
+
inputs: context.inputs,
|
|
119
|
+
})
|
|
120
|
+
: undefined;
|
|
121
|
+
const env = step.env
|
|
122
|
+
? Object.fromEntries(Object.entries(step.env).map(([key, value]) => [
|
|
123
|
+
key,
|
|
124
|
+
interpolateTemplateString(value, {
|
|
125
|
+
artifacts: context.artifacts,
|
|
126
|
+
inputs: context.inputs,
|
|
127
|
+
}),
|
|
128
|
+
]))
|
|
129
|
+
: undefined;
|
|
130
|
+
const result = await this.spawn({
|
|
131
|
+
command: payload.command,
|
|
132
|
+
cwd,
|
|
133
|
+
env,
|
|
134
|
+
signal: context.signal,
|
|
135
|
+
});
|
|
136
|
+
const envKeys = env ? Object.keys(env).sort() : [];
|
|
137
|
+
const normalizedResult = {
|
|
138
|
+
code: result.code,
|
|
139
|
+
command: payload.command,
|
|
140
|
+
cwd,
|
|
141
|
+
envKeys,
|
|
142
|
+
signal: result.signal,
|
|
143
|
+
stderr: result.stderr,
|
|
144
|
+
stdout: result.stdout,
|
|
145
|
+
};
|
|
146
|
+
return {
|
|
147
|
+
artifacts: [
|
|
148
|
+
{
|
|
149
|
+
name: `${step.id}.stdout`,
|
|
150
|
+
type: 'text',
|
|
151
|
+
value: result.stdout,
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
name: `${step.id}.stderr`,
|
|
155
|
+
type: 'text',
|
|
156
|
+
value: result.stderr,
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
name: `${step.id}.result`,
|
|
160
|
+
type: 'json',
|
|
161
|
+
value: normalizedResult,
|
|
162
|
+
},
|
|
163
|
+
],
|
|
164
|
+
outputs: normalizedResult,
|
|
165
|
+
status: result.code === 0 ? 'succeeded' : 'failed',
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=exec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec.js","sourceRoot":"","sources":["../../src/executors/exec.ts"],"names":[],"mappings":"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"}
|