@hexabot-ai/agentic 3.0.1-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.
- package/LICENSE.md +120 -0
- package/README.md +231 -0
- package/dist/cjs/action/abstract-action.js +141 -0
- package/dist/cjs/action/action.js +47 -0
- package/dist/cjs/action/action.types.js +7 -0
- package/dist/cjs/bindings/base-binding.js +278 -0
- package/dist/cjs/context.js +79 -0
- package/dist/cjs/dsl.types.js +318 -0
- package/dist/cjs/index.js +52 -0
- package/dist/cjs/runner-runtime-control.js +343 -0
- package/dist/cjs/step-executors/conditional-executor.js +63 -0
- package/dist/cjs/step-executors/loop-executor.js +187 -0
- package/dist/cjs/step-executors/parallel-executor.js +51 -0
- package/dist/cjs/step-executors/skip-helpers.js +29 -0
- package/dist/cjs/step-executors/task-executor.js +155 -0
- package/dist/cjs/step-executors/types.js +7 -0
- package/dist/cjs/suspension-rebuilder.js +301 -0
- package/dist/cjs/utils/deferred.js +17 -0
- package/dist/cjs/utils/naming.js +48 -0
- package/dist/cjs/utils/timeout.js +42 -0
- package/dist/cjs/utils/workflow-definition.js +102 -0
- package/dist/cjs/workflow-compiler.js +212 -0
- package/dist/cjs/workflow-event-emitter.js +40 -0
- package/dist/cjs/workflow-runner.js +448 -0
- package/dist/cjs/workflow-types.js +7 -0
- package/dist/cjs/workflow-values.js +99 -0
- package/dist/cjs/workflow.js +243 -0
- package/dist/esm/action/abstract-action.js +137 -0
- package/dist/esm/action/action.js +44 -0
- package/dist/esm/action/action.types.js +6 -0
- package/dist/esm/bindings/base-binding.js +273 -0
- package/dist/esm/context.js +75 -0
- package/dist/esm/dsl.types.js +309 -0
- package/dist/esm/index.js +16 -0
- package/dist/esm/runner-runtime-control.js +338 -0
- package/dist/esm/step-executors/conditional-executor.js +60 -0
- package/dist/esm/step-executors/loop-executor.js +182 -0
- package/dist/esm/step-executors/parallel-executor.js +48 -0
- package/dist/esm/step-executors/skip-helpers.js +25 -0
- package/dist/esm/step-executors/task-executor.js +152 -0
- package/dist/esm/step-executors/types.js +6 -0
- package/dist/esm/suspension-rebuilder.js +296 -0
- package/dist/esm/utils/deferred.js +14 -0
- package/dist/esm/utils/naming.js +42 -0
- package/dist/esm/utils/timeout.js +37 -0
- package/dist/esm/utils/workflow-definition.js +98 -0
- package/dist/esm/workflow-compiler.js +208 -0
- package/dist/esm/workflow-event-emitter.js +36 -0
- package/dist/esm/workflow-runner.js +444 -0
- package/dist/esm/workflow-types.js +6 -0
- package/dist/esm/workflow-values.js +89 -0
- package/dist/esm/workflow.js +236 -0
- package/dist/types/action/abstract-action.d.ts +54 -0
- package/dist/types/action/abstract-action.d.ts.map +1 -0
- package/dist/types/action/action.d.ts +23 -0
- package/dist/types/action/action.d.ts.map +1 -0
- package/dist/types/action/action.types.d.ts +55 -0
- package/dist/types/action/action.types.d.ts.map +1 -0
- package/dist/types/bindings/base-binding.d.ts +52 -0
- package/dist/types/bindings/base-binding.d.ts.map +1 -0
- package/dist/types/context.d.ts +105 -0
- package/dist/types/context.d.ts.map +1 -0
- package/dist/types/dsl.types.d.ts +220 -0
- package/dist/types/dsl.types.d.ts.map +1 -0
- package/dist/types/index.d.ts +18 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/runner-runtime-control.d.ts +64 -0
- package/dist/types/runner-runtime-control.d.ts.map +1 -0
- package/dist/types/step-executors/conditional-executor.d.ts +13 -0
- package/dist/types/step-executors/conditional-executor.d.ts.map +1 -0
- package/dist/types/step-executors/loop-executor.d.ts +33 -0
- package/dist/types/step-executors/loop-executor.d.ts.map +1 -0
- package/dist/types/step-executors/parallel-executor.d.ts +14 -0
- package/dist/types/step-executors/parallel-executor.d.ts.map +1 -0
- package/dist/types/step-executors/skip-helpers.d.ts +12 -0
- package/dist/types/step-executors/skip-helpers.d.ts.map +1 -0
- package/dist/types/step-executors/task-executor.d.ts +13 -0
- package/dist/types/step-executors/task-executor.d.ts.map +1 -0
- package/dist/types/step-executors/types.d.ts +24 -0
- package/dist/types/step-executors/types.d.ts.map +1 -0
- package/dist/types/suspension-rebuilder.d.ts +67 -0
- package/dist/types/suspension-rebuilder.d.ts.map +1 -0
- package/dist/types/utils/deferred.d.ts +7 -0
- package/dist/types/utils/deferred.d.ts.map +1 -0
- package/dist/types/utils/naming.d.ts +24 -0
- package/dist/types/utils/naming.d.ts.map +1 -0
- package/dist/types/utils/timeout.d.ts +17 -0
- package/dist/types/utils/timeout.d.ts.map +1 -0
- package/dist/types/utils/workflow-definition.d.ts +3 -0
- package/dist/types/utils/workflow-definition.d.ts.map +1 -0
- package/dist/types/workflow-compiler.d.ts +12 -0
- package/dist/types/workflow-compiler.d.ts.map +1 -0
- package/dist/types/workflow-event-emitter.d.ts +70 -0
- package/dist/types/workflow-event-emitter.d.ts.map +1 -0
- package/dist/types/workflow-runner.d.ts +179 -0
- package/dist/types/workflow-runner.d.ts.map +1 -0
- package/dist/types/workflow-types.d.ts +195 -0
- package/dist/types/workflow-types.d.ts.map +1 -0
- package/dist/types/workflow-values.d.ts +34 -0
- package/dist/types/workflow-values.d.ts.map +1 -0
- package/dist/types/workflow.d.ts +75 -0
- package/dist/types/workflow.d.ts.map +1 -0
- package/examples/defs-bindings-agent/actions/ai-agent.ts +110 -0
- package/examples/defs-bindings-agent/actions/caculate-score.ts +49 -0
- package/examples/defs-bindings-agent/actions/index.ts +15 -0
- package/examples/defs-bindings-agent/bindings.ts +20 -0
- package/examples/defs-bindings-agent/context.ts +32 -0
- package/examples/defs-bindings-agent/workflow.ts +67 -0
- package/examples/defs-bindings-agent/workflow.yml +28 -0
- package/examples/full/actions/await-user-input.ts +46 -0
- package/examples/full/actions/call-llm.ts +133 -0
- package/examples/full/actions/create-ticket.ts +46 -0
- package/examples/full/actions/decision-router.ts +83 -0
- package/examples/full/actions/get-calendar-events.ts +55 -0
- package/examples/full/actions/get-user-profile.ts +72 -0
- package/examples/full/actions/index.ts +33 -0
- package/examples/full/actions/query-memory.ts +45 -0
- package/examples/full/actions/search-web.ts +53 -0
- package/examples/full/actions/send-email.ts +50 -0
- package/examples/full/context.ts +41 -0
- package/examples/full/workflow.ts +75 -0
- package/examples/full/workflow.yml +359 -0
- package/examples/loop/actions/await-reply.ts +47 -0
- package/examples/loop/actions/index.ts +19 -0
- package/examples/loop/actions/send-text-message.ts +40 -0
- package/examples/loop/context.ts +32 -0
- package/examples/loop/workflow.ts +66 -0
- package/examples/loop/workflow.yml +66 -0
- package/examples/suspend-resume/actions/format-reply.ts +43 -0
- package/examples/suspend-resume/actions/index.ts +13 -0
- package/examples/suspend-resume/actions/wait-for-user.ts +51 -0
- package/examples/suspend-resume/context.ts +32 -0
- package/examples/suspend-resume/workflow.ts +79 -0
- package/examples/suspend-resume/workflow.yml +29 -0
- package/package.json +60 -0
- package/src/__tests__/parser.test.ts +95 -0
- package/src/__tests__/suspension-rebuilder.test.ts +361 -0
- package/src/__tests__/test-helpers.ts +36 -0
- package/src/__tests__/validation.test.ts +526 -0
- package/src/__tests__/workflow-compiler.test.ts +715 -0
- package/src/__tests__/workflow-definition-path.test.ts +381 -0
- package/src/__tests__/workflow-event-emitter.test.ts +50 -0
- package/src/__tests__/workflow-runner.test.ts +1397 -0
- package/src/__tests__/workflow-values.test.ts +132 -0
- package/src/__tests__/workflow.test.ts +320 -0
- package/src/action/__tests__/abstract-action-timing.test.ts +183 -0
- package/src/action/__tests__/action.test.ts +473 -0
- package/src/action/abstract-action.ts +215 -0
- package/src/action/action.ts +83 -0
- package/src/action/action.types.ts +93 -0
- package/src/bindings/base-binding.ts +508 -0
- package/src/context.ts +179 -0
- package/src/dsl.types.ts +473 -0
- package/src/index.ts +114 -0
- package/src/runner-runtime-control.ts +544 -0
- package/src/step-executors/conditional-executor.test.ts +192 -0
- package/src/step-executors/conditional-executor.ts +83 -0
- package/src/step-executors/loop-executor.test.ts +303 -0
- package/src/step-executors/loop-executor.ts +299 -0
- package/src/step-executors/parallel-executor.test.ts +182 -0
- package/src/step-executors/parallel-executor.ts +77 -0
- package/src/step-executors/skip-helpers.ts +68 -0
- package/src/step-executors/task-executor.test.ts +257 -0
- package/src/step-executors/task-executor.ts +248 -0
- package/src/step-executors/types.ts +70 -0
- package/src/suspension-rebuilder.ts +504 -0
- package/src/utils/deferred.ts +23 -0
- package/src/utils/naming.ts +55 -0
- package/src/utils/timeout.ts +48 -0
- package/src/utils/workflow-definition.ts +173 -0
- package/src/workflow-compiler.ts +317 -0
- package/src/workflow-event-emitter.ts +86 -0
- package/src/workflow-runner.ts +603 -0
- package/src/workflow-types.ts +207 -0
- package/src/workflow-values.ts +159 -0
- package/src/workflow.ts +387 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Hexabot — Fair Core License (FCL-1.0-ALv2)
|
|
3
|
+
* Copyright (c) 2025 Hexastack.
|
|
4
|
+
* Full terms: see LICENSE.md.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { Expression } from 'jsonata';
|
|
8
|
+
import type { ZodType } from 'zod';
|
|
9
|
+
|
|
10
|
+
import type { Action } from './action/action.types';
|
|
11
|
+
import type { CompiledTaskBindings } from './bindings/base-binding';
|
|
12
|
+
import type { BaseWorkflowContext, WorkflowSnapshot } from './context';
|
|
13
|
+
import type { Settings, TaskDefinition, WorkflowDefinition } from './dsl.types';
|
|
14
|
+
import { StepType, type StepInfo } from './workflow-event-emitter';
|
|
15
|
+
|
|
16
|
+
export type { CompiledTaskBindings } from './bindings/base-binding';
|
|
17
|
+
|
|
18
|
+
/** Value representation used by the runtime after compilation. */
|
|
19
|
+
export type CompiledValue =
|
|
20
|
+
| { kind: 'literal'; value: unknown }
|
|
21
|
+
| { kind: 'expression'; source: string; expression: Expression };
|
|
22
|
+
|
|
23
|
+
/** Map of variable names to compiled values. */
|
|
24
|
+
export type CompiledMapping = Record<string, CompiledValue>;
|
|
25
|
+
|
|
26
|
+
/** Fully resolved task with parsed settings and compiled IO mappings. */
|
|
27
|
+
export type CompiledTask = {
|
|
28
|
+
name: string;
|
|
29
|
+
definition: TaskDefinition;
|
|
30
|
+
actionName: string;
|
|
31
|
+
action: Action;
|
|
32
|
+
inputs: CompiledMapping;
|
|
33
|
+
settings: Settings;
|
|
34
|
+
bindings: CompiledTaskBindings;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/** Complete workflow ready for execution. */
|
|
38
|
+
export type CompiledWorkflow = {
|
|
39
|
+
definition: WorkflowDefinition;
|
|
40
|
+
tasks: Record<string, CompiledTask>;
|
|
41
|
+
flow: CompiledStep[];
|
|
42
|
+
outputMapping: CompiledMapping;
|
|
43
|
+
inputParser: ZodType<Record<string, unknown>>;
|
|
44
|
+
defaultSettings?: Settings;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/** Any executable step inside the compiled flow. */
|
|
48
|
+
export type CompiledStep = TaskStep | ParallelStep | ConditionalStep | LoopStep;
|
|
49
|
+
|
|
50
|
+
export type BaseStep = {
|
|
51
|
+
id: string;
|
|
52
|
+
label: string;
|
|
53
|
+
type: StepType;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/** Single task execution. */
|
|
57
|
+
export type TaskStep = BaseStep & {
|
|
58
|
+
type: StepType.Task;
|
|
59
|
+
taskName: string;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/** Runs nested steps with either wait-all or wait-any semantics. */
|
|
63
|
+
export type ParallelStep = BaseStep & {
|
|
64
|
+
type: StepType.Parallel;
|
|
65
|
+
description?: string;
|
|
66
|
+
strategy: 'wait_all' | 'wait_any';
|
|
67
|
+
steps: CompiledStep[];
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/** Conditional branch tree describing when to run a step list. */
|
|
71
|
+
export type ConditionalBranch = {
|
|
72
|
+
id: string;
|
|
73
|
+
condition?: CompiledValue;
|
|
74
|
+
steps: CompiledStep[];
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/** Conditional step with multiple branches. */
|
|
78
|
+
export type ConditionalStep = BaseStep & {
|
|
79
|
+
type: StepType.Conditional;
|
|
80
|
+
description?: string;
|
|
81
|
+
branches: ConditionalBranch[];
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
type BaseLoopStep = BaseStep & {
|
|
85
|
+
type: StepType.Loop;
|
|
86
|
+
name?: string;
|
|
87
|
+
description?: string;
|
|
88
|
+
accumulate?: { as: string; initial: unknown; merge: CompiledValue };
|
|
89
|
+
steps: CompiledStep[];
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
/** Loop over items with optional post-iteration break condition. */
|
|
93
|
+
export type ForEachLoopStep = BaseLoopStep & {
|
|
94
|
+
loopType: 'for_each';
|
|
95
|
+
forEach: { item: string; in: CompiledValue };
|
|
96
|
+
maxConcurrency?: number;
|
|
97
|
+
until?: CompiledValue;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/** Classic while-loop evaluated before each iteration. */
|
|
101
|
+
export type WhileLoopStep = BaseLoopStep & {
|
|
102
|
+
loopType: 'while';
|
|
103
|
+
while: CompiledValue;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export type LoopStep = ForEachLoopStep | WhileLoopStep;
|
|
107
|
+
|
|
108
|
+
/** Scope passed to value evaluators, reflecting the live runtime state. */
|
|
109
|
+
export type EvaluationScope = {
|
|
110
|
+
input: Record<string, unknown>;
|
|
111
|
+
context: Record<string, unknown>;
|
|
112
|
+
output: Record<string, unknown>;
|
|
113
|
+
iteration?: { item: unknown; index: number };
|
|
114
|
+
accumulator?: unknown;
|
|
115
|
+
result?: unknown;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
/** Minimal mutable state for the executor. */
|
|
119
|
+
export type ExecutionState = {
|
|
120
|
+
input: Record<string, unknown>;
|
|
121
|
+
output: Record<string, unknown>;
|
|
122
|
+
iteration?: { item: unknown; index: number };
|
|
123
|
+
accumulator?: unknown;
|
|
124
|
+
iterationStack: number[];
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
/** Encapsulates a suspended step and how to continue it. */
|
|
128
|
+
export type Suspension = {
|
|
129
|
+
step: StepInfo;
|
|
130
|
+
reason?: string;
|
|
131
|
+
data?: unknown;
|
|
132
|
+
stepExecId?: string;
|
|
133
|
+
suspendIndex?: number;
|
|
134
|
+
suspendKey?: string;
|
|
135
|
+
awaitResults?: Record<string, unknown>;
|
|
136
|
+
continue: (resumeData: unknown) => Promise<Suspension | void>;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
export type PersistedSuspension = {
|
|
140
|
+
stepId: string;
|
|
141
|
+
reason?: string | null;
|
|
142
|
+
data?: unknown;
|
|
143
|
+
stepExecId?: string;
|
|
144
|
+
suspendIndex?: number;
|
|
145
|
+
suspendKey?: string;
|
|
146
|
+
awaitResults?: Record<string, unknown>;
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
/** Result of starting a workflow run. */
|
|
150
|
+
export type StartResult =
|
|
151
|
+
| {
|
|
152
|
+
status: 'finished';
|
|
153
|
+
output: Record<string, unknown>;
|
|
154
|
+
snapshot: WorkflowSnapshot;
|
|
155
|
+
}
|
|
156
|
+
| {
|
|
157
|
+
status: 'suspended';
|
|
158
|
+
step: StepInfo;
|
|
159
|
+
reason?: string;
|
|
160
|
+
data?: unknown;
|
|
161
|
+
stepExecId?: string;
|
|
162
|
+
suspendIndex?: number;
|
|
163
|
+
suspendKey?: string;
|
|
164
|
+
awaitResults?: Record<string, unknown>;
|
|
165
|
+
snapshot: WorkflowSnapshot;
|
|
166
|
+
}
|
|
167
|
+
| { status: 'failed'; error: unknown; snapshot: WorkflowSnapshot };
|
|
168
|
+
|
|
169
|
+
/** Result of resuming a suspended workflow. */
|
|
170
|
+
export type ResumeResult =
|
|
171
|
+
| {
|
|
172
|
+
status: 'finished';
|
|
173
|
+
output: Record<string, unknown>;
|
|
174
|
+
snapshot: WorkflowSnapshot;
|
|
175
|
+
}
|
|
176
|
+
| {
|
|
177
|
+
status: 'suspended';
|
|
178
|
+
step: StepInfo;
|
|
179
|
+
reason?: string;
|
|
180
|
+
data?: unknown;
|
|
181
|
+
stepExecId?: string;
|
|
182
|
+
suspendIndex?: number;
|
|
183
|
+
suspendKey?: string;
|
|
184
|
+
awaitResults?: Record<string, unknown>;
|
|
185
|
+
snapshot: WorkflowSnapshot;
|
|
186
|
+
}
|
|
187
|
+
| { status: 'failed'; error: unknown; snapshot: WorkflowSnapshot };
|
|
188
|
+
|
|
189
|
+
/** Options that influence how the workflow runner behaves. */
|
|
190
|
+
export type WorkflowRunOptions = {
|
|
191
|
+
runId?: string;
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
export type WorkflowStartResult = StartResult;
|
|
195
|
+
|
|
196
|
+
export type WorkflowResumeResult = ResumeResult;
|
|
197
|
+
|
|
198
|
+
/** Arguments required to start a run. */
|
|
199
|
+
export type RunnerStartArgs = {
|
|
200
|
+
inputData: unknown;
|
|
201
|
+
context: BaseWorkflowContext;
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
/** Payload passed when resuming a suspended run. */
|
|
205
|
+
export type RunnerResumeArgs = {
|
|
206
|
+
resumeData?: unknown;
|
|
207
|
+
};
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Hexabot — Fair Core License (FCL-1.0-ALv2)
|
|
3
|
+
* Copyright (c) 2025 Hexastack.
|
|
4
|
+
* Full terms: see LICENSE.md.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { Expression, Focus } from 'jsonata';
|
|
8
|
+
import jsonata from 'jsonata';
|
|
9
|
+
|
|
10
|
+
import type { JsonValue, Settings } from './dsl.types';
|
|
11
|
+
import type {
|
|
12
|
+
CompiledMapping,
|
|
13
|
+
CompiledValue,
|
|
14
|
+
EvaluationScope,
|
|
15
|
+
} from './workflow-types';
|
|
16
|
+
|
|
17
|
+
export type JsonataFunctionImplementation = (
|
|
18
|
+
this: Focus,
|
|
19
|
+
...args: any[]
|
|
20
|
+
) => unknown;
|
|
21
|
+
|
|
22
|
+
export type JsonataFunctionConfig =
|
|
23
|
+
| JsonataFunctionImplementation
|
|
24
|
+
| {
|
|
25
|
+
implementation: JsonataFunctionImplementation;
|
|
26
|
+
signature?: string;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export type JsonataFunctionRegistry = Record<string, JsonataFunctionConfig>;
|
|
30
|
+
|
|
31
|
+
export type CompileValueOptions = {
|
|
32
|
+
jsonataFunctions?: JsonataFunctionRegistry;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/** Basic object guard that rejects arrays and null. */
|
|
36
|
+
const isPlainObject = (value: unknown): value is Record<string, unknown> =>
|
|
37
|
+
typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
38
|
+
const registerJsonataFunctions = (
|
|
39
|
+
expression: Expression,
|
|
40
|
+
registry?: JsonataFunctionRegistry,
|
|
41
|
+
) => {
|
|
42
|
+
if (!registry) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
for (const [name, config] of Object.entries(registry)) {
|
|
47
|
+
if (typeof config === 'function') {
|
|
48
|
+
expression.registerFunction(name, config);
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (config && typeof config.implementation === 'function') {
|
|
53
|
+
expression.registerFunction(
|
|
54
|
+
name,
|
|
55
|
+
config.implementation,
|
|
56
|
+
config.signature,
|
|
57
|
+
);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
throw new Error(`Invalid JSONata function config for "${name}"`);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Prepares a workflow value for evaluation.
|
|
67
|
+
* Strings prefixed with `=` are treated as JSONata expressions; everything else is a literal.
|
|
68
|
+
*/
|
|
69
|
+
export const compileValue = (
|
|
70
|
+
value: unknown,
|
|
71
|
+
options?: CompileValueOptions,
|
|
72
|
+
): CompiledValue => {
|
|
73
|
+
if (typeof value === 'string' && value.startsWith('=')) {
|
|
74
|
+
const expression = jsonata(value.slice(1));
|
|
75
|
+
registerJsonataFunctions(expression, options?.jsonataFunctions);
|
|
76
|
+
|
|
77
|
+
return { kind: 'expression', source: value, expression };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return { kind: 'literal', value };
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Evaluate a compiled value against the current workflow scope.
|
|
85
|
+
* Expressions are executed via JSONata with the scope exposed as variables; `context`
|
|
86
|
+
* represents the workflow context state, not the context instance itself.
|
|
87
|
+
*/
|
|
88
|
+
export const evaluateValue = async (
|
|
89
|
+
compiled: CompiledValue,
|
|
90
|
+
scope: EvaluationScope,
|
|
91
|
+
): Promise<unknown> => {
|
|
92
|
+
if (compiled.kind === 'literal') {
|
|
93
|
+
return compiled.value;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return compiled.expression.evaluate(
|
|
97
|
+
{},
|
|
98
|
+
{
|
|
99
|
+
input: scope.input,
|
|
100
|
+
context: scope.context,
|
|
101
|
+
output: scope.output,
|
|
102
|
+
iteration: scope.iteration,
|
|
103
|
+
accumulator: scope.accumulator,
|
|
104
|
+
result: scope.result,
|
|
105
|
+
},
|
|
106
|
+
);
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Evaluate all entries of a compiled mapping, returning a plain object.
|
|
111
|
+
* Missing mappings resolve to an empty object.
|
|
112
|
+
*/
|
|
113
|
+
export const evaluateMapping = async (
|
|
114
|
+
mapping: CompiledMapping | undefined,
|
|
115
|
+
scope: EvaluationScope,
|
|
116
|
+
): Promise<Record<string, unknown>> => {
|
|
117
|
+
if (!mapping) {
|
|
118
|
+
return {};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const result: Record<string, unknown> = {};
|
|
122
|
+
|
|
123
|
+
for (const [key, compiled] of Object.entries(mapping)) {
|
|
124
|
+
result[key] = await evaluateValue(compiled, scope);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return result;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Deep-merge workflow settings, preferring non-undefined overrides.
|
|
132
|
+
* Nested objects are merged recursively to preserve defaults.
|
|
133
|
+
*/
|
|
134
|
+
export const mergeSettings = (
|
|
135
|
+
base?: Partial<Settings>,
|
|
136
|
+
override?: Partial<Settings>,
|
|
137
|
+
): Partial<Settings> => {
|
|
138
|
+
const merged: Partial<Settings> = { ...(base ?? {}) };
|
|
139
|
+
|
|
140
|
+
if (!override) {
|
|
141
|
+
return merged;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
for (const key of Object.keys(override)) {
|
|
145
|
+
const value = override[key];
|
|
146
|
+
const previous = merged[key];
|
|
147
|
+
|
|
148
|
+
if (isPlainObject(previous) && isPlainObject(value)) {
|
|
149
|
+
merged[key] = mergeSettings(
|
|
150
|
+
previous as Partial<Settings>,
|
|
151
|
+
value as Partial<Settings>,
|
|
152
|
+
) as JsonValue;
|
|
153
|
+
} else if (value !== undefined) {
|
|
154
|
+
merged[key] = value;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return merged;
|
|
159
|
+
};
|