agentic-workflow-architecture 1.0.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/README.md +163 -0
- package/dist/chunk-G4ESW2JI.mjs +2070 -0
- package/dist/chunk-IZHFAP46.mjs +989 -0
- package/dist/chunk-PWDGJYCP.mjs +1779 -0
- package/dist/chunk-RUER3A4B.mjs +2054 -0
- package/dist/chunk-ZECJMOMD.mjs +1973 -0
- package/dist/cli/index.d.mts +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +2465 -0
- package/dist/cli/index.mjs +498 -0
- package/dist/index.d.mts +5893 -0
- package/dist/index.d.ts +5893 -0
- package/dist/index.js +3070 -0
- package/dist/index.mjs +1039 -0
- package/package.json +81 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,3070 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
AccessDirection: () => AccessDirection,
|
|
34
|
+
AccessMode: () => AccessMode,
|
|
35
|
+
AccessRightQuery: () => AccessRightQuery,
|
|
36
|
+
AccessRightSchema: () => AccessRightSchema,
|
|
37
|
+
ActivityQuery: () => ActivityQuery,
|
|
38
|
+
ActivitySchema: () => ActivitySchema,
|
|
39
|
+
ActorType: () => ActorType,
|
|
40
|
+
AnalyticsSchema: () => AnalyticsSchema,
|
|
41
|
+
AnimationConfigSchema: () => AnimationConfigSchema,
|
|
42
|
+
AnimationEasing: () => AnimationEasing,
|
|
43
|
+
AutoLayoutConfigSchema: () => AutoLayoutConfigSchema,
|
|
44
|
+
CameraSettings2DSchema: () => CameraSettings2DSchema,
|
|
45
|
+
CameraSettings3DSchema: () => CameraSettings3DSchema,
|
|
46
|
+
CameraType: () => CameraType,
|
|
47
|
+
CheckpointManager: () => CheckpointManager,
|
|
48
|
+
CollectionSchema: () => CollectionSchema,
|
|
49
|
+
ColorSchema: () => ColorSchema,
|
|
50
|
+
ContextBindingQuery: () => ContextBindingQuery,
|
|
51
|
+
ContextBindingSchema: () => ContextBindingSchema,
|
|
52
|
+
ContextManager: () => ContextManager,
|
|
53
|
+
ContextQuery: () => ContextQuery,
|
|
54
|
+
ContextSchema: () => ContextSchema,
|
|
55
|
+
ContextType: () => ContextType,
|
|
56
|
+
ControlSchema: () => ControlSchema,
|
|
57
|
+
ControlType: () => ControlType,
|
|
58
|
+
CurveType: () => CurveType,
|
|
59
|
+
DEFAULT_RETRY_CONFIG: () => DEFAULT_RETRY_CONFIG,
|
|
60
|
+
DataObjectSchema: () => DataObjectSchema,
|
|
61
|
+
DateTimeTz: () => DateTimeTz,
|
|
62
|
+
DeadLetterQueue: () => DeadLetterQueue,
|
|
63
|
+
DecisionEvaluator: () => DecisionEvaluator,
|
|
64
|
+
DecisionNodeSchema: () => DecisionNodeSchema,
|
|
65
|
+
DecisionRuleSchema: () => DecisionRuleSchema,
|
|
66
|
+
DecisionTableSchema: () => DecisionTableSchema,
|
|
67
|
+
Duration: () => Duration,
|
|
68
|
+
EdgeRoutingSchema: () => EdgeRoutingSchema,
|
|
69
|
+
EdgeSchema: () => EdgeSchema,
|
|
70
|
+
EdgeStyleSchema: () => EdgeStyleSchema,
|
|
71
|
+
EndpointSchema: () => EndpointSchema,
|
|
72
|
+
Enforcement: () => Enforcement,
|
|
73
|
+
EventSchema: () => EventSchema,
|
|
74
|
+
FilePersistenceAdapter: () => FilePersistenceAdapter,
|
|
75
|
+
HitPolicy: () => HitPolicy,
|
|
76
|
+
HumanAgent: () => HumanAgent,
|
|
77
|
+
HumanTaskPriority: () => HumanTaskPriority,
|
|
78
|
+
HumanTaskSchema: () => HumanTaskSchema,
|
|
79
|
+
HumanTaskStatus: () => HumanTaskStatus,
|
|
80
|
+
InMemoryPersistenceAdapter: () => InMemoryPersistenceAdapter,
|
|
81
|
+
LaneOrientation: () => LaneOrientation,
|
|
82
|
+
LaneSchema: () => LaneSchema,
|
|
83
|
+
LayoutAlgorithm: () => LayoutAlgorithm,
|
|
84
|
+
LayoutDirection: () => LayoutDirection,
|
|
85
|
+
Lifecycle: () => Lifecycle,
|
|
86
|
+
MachineSchema: () => MachineSchema,
|
|
87
|
+
NodeMaterial3DSchema: () => NodeMaterial3DSchema,
|
|
88
|
+
NodePosition2DSchema: () => NodePosition2DSchema,
|
|
89
|
+
NodePosition3DSchema: () => NodePosition3DSchema,
|
|
90
|
+
NodeShape: () => NodeShape,
|
|
91
|
+
NodeStyle2DSchema: () => NodeStyle2DSchema,
|
|
92
|
+
NodeType: () => NodeType,
|
|
93
|
+
ParameterSchema: () => ParameterSchema,
|
|
94
|
+
Permission: () => Permission,
|
|
95
|
+
ProgramSchema: () => ProgramSchema,
|
|
96
|
+
QuaternionSchema: () => QuaternionSchema,
|
|
97
|
+
ResourceType: () => ResourceType,
|
|
98
|
+
RobotAgent: () => RobotAgent,
|
|
99
|
+
RoleSchema: () => RoleSchema,
|
|
100
|
+
SLASchema: () => SLASchema,
|
|
101
|
+
SkillBindingSchema: () => SkillBindingSchema,
|
|
102
|
+
SkillType: () => SkillType,
|
|
103
|
+
SyncPattern: () => SyncPattern,
|
|
104
|
+
SystemSchema: () => SystemSchema,
|
|
105
|
+
TableColumnSchema: () => TableColumnSchema,
|
|
106
|
+
ThemeConfigSchema: () => ThemeConfigSchema,
|
|
107
|
+
Token: () => Token,
|
|
108
|
+
ToolRequirementSchema: () => ToolRequirementSchema,
|
|
109
|
+
ToolRequirementType: () => ToolRequirementType,
|
|
110
|
+
UUID: () => UUID,
|
|
111
|
+
Vector2DSchema: () => Vector2DSchema,
|
|
112
|
+
Vector3DSchema: () => Vector3DSchema,
|
|
113
|
+
ViewType: () => ViewType,
|
|
114
|
+
Visibility: () => Visibility,
|
|
115
|
+
VisualizationConfigSchema: () => VisualizationConfigSchema,
|
|
116
|
+
VisualizationEngine: () => VisualizationEngine,
|
|
117
|
+
WasteCategory: () => WasteCategory,
|
|
118
|
+
WorkflowBuilder: () => WorkflowBuilder,
|
|
119
|
+
WorkflowEngine: () => WorkflowEngine,
|
|
120
|
+
WorkflowQuery: () => WorkflowQuery,
|
|
121
|
+
WorkflowSchema: () => WorkflowSchema,
|
|
122
|
+
calculate_retry_delay: () => calculate_retry_delay,
|
|
123
|
+
create_file_checkpoint_manager: () => create_file_checkpoint_manager,
|
|
124
|
+
create_retryable_executor: () => create_retryable_executor,
|
|
125
|
+
deserialize_token: () => deserialize_token,
|
|
126
|
+
evaluate_decision: () => evaluate_decision,
|
|
127
|
+
get_checkpoint_manager: () => get_checkpoint_manager,
|
|
128
|
+
get_dead_letter_queue: () => get_dead_letter_queue,
|
|
129
|
+
is_retryable_error: () => is_retryable_error,
|
|
130
|
+
parse_activity: () => parse_activity,
|
|
131
|
+
parse_context: () => parse_context,
|
|
132
|
+
parse_workflow: () => parse_workflow,
|
|
133
|
+
query: () => query,
|
|
134
|
+
serialize_token: () => serialize_token,
|
|
135
|
+
set_checkpoint_manager: () => set_checkpoint_manager,
|
|
136
|
+
set_dead_letter_queue: () => set_dead_letter_queue,
|
|
137
|
+
sleep: () => sleep,
|
|
138
|
+
validate_activity: () => validate_activity,
|
|
139
|
+
validate_context: () => validate_context,
|
|
140
|
+
validate_workflow: () => validate_workflow,
|
|
141
|
+
validate_workflow_integrity: () => validate_workflow_integrity,
|
|
142
|
+
with_retry: () => with_retry,
|
|
143
|
+
workflow: () => workflow
|
|
144
|
+
});
|
|
145
|
+
module.exports = __toCommonJS(index_exports);
|
|
146
|
+
|
|
147
|
+
// src/types/index.ts
|
|
148
|
+
var import_zod2 = require("zod");
|
|
149
|
+
|
|
150
|
+
// src/types/visualization.ts
|
|
151
|
+
var import_zod = require("zod");
|
|
152
|
+
var ViewType = import_zod.z.enum(["2d", "3d"]);
|
|
153
|
+
var LayoutAlgorithm = import_zod.z.enum(["dagre", "elk", "d3_hierarchy", "manual"]);
|
|
154
|
+
var LayoutDirection = import_zod.z.enum(["tb", "bt", "lr", "rl"]);
|
|
155
|
+
var LaneOrientation = import_zod.z.enum(["horizontal", "vertical"]);
|
|
156
|
+
var CurveType = import_zod.z.enum(["bezier", "step", "smoothstep", "straight"]);
|
|
157
|
+
var NodeShape = import_zod.z.enum(["rectangle", "rounded", "circle", "diamond", "hexagon", "cylinder", "cube", "sphere"]);
|
|
158
|
+
var CameraType = import_zod.z.enum(["arc_rotate", "free", "follow", "fly"]);
|
|
159
|
+
var AnimationEasing = import_zod.z.enum(["linear", "ease", "ease_in", "ease_out", "ease_in_out", "bounce", "elastic"]);
|
|
160
|
+
var VisualizationEngine = import_zod.z.enum(["reactflow", "babylonjs", "custom"]);
|
|
161
|
+
var Vector2DSchema = import_zod.z.object({
|
|
162
|
+
x: import_zod.z.number(),
|
|
163
|
+
y: import_zod.z.number()
|
|
164
|
+
});
|
|
165
|
+
var Vector3DSchema = import_zod.z.object({
|
|
166
|
+
x: import_zod.z.number(),
|
|
167
|
+
y: import_zod.z.number(),
|
|
168
|
+
z: import_zod.z.number()
|
|
169
|
+
});
|
|
170
|
+
var QuaternionSchema = import_zod.z.object({
|
|
171
|
+
x: import_zod.z.number(),
|
|
172
|
+
y: import_zod.z.number(),
|
|
173
|
+
z: import_zod.z.number(),
|
|
174
|
+
w: import_zod.z.number()
|
|
175
|
+
});
|
|
176
|
+
var ColorSchema = import_zod.z.string().regex(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$|^rgba?\(/);
|
|
177
|
+
var NodeStyle2DSchema = import_zod.z.object({
|
|
178
|
+
background_color: ColorSchema.optional(),
|
|
179
|
+
border_color: ColorSchema.optional(),
|
|
180
|
+
border_width: import_zod.z.number().optional(),
|
|
181
|
+
border_radius: import_zod.z.number().optional(),
|
|
182
|
+
opacity: import_zod.z.number().min(0).max(1).optional()
|
|
183
|
+
}).passthrough();
|
|
184
|
+
var NodeMaterial3DSchema = import_zod.z.object({
|
|
185
|
+
diffuse_color: ColorSchema.optional(),
|
|
186
|
+
emissive_color: ColorSchema.optional(),
|
|
187
|
+
alpha: import_zod.z.number().min(0).max(1).optional(),
|
|
188
|
+
metallic: import_zod.z.number().min(0).max(1).optional(),
|
|
189
|
+
roughness: import_zod.z.number().min(0).max(1).optional()
|
|
190
|
+
}).passthrough();
|
|
191
|
+
var NodePosition2DSchema = import_zod.z.object({
|
|
192
|
+
id: import_zod.z.string().uuid().optional(),
|
|
193
|
+
node_id: import_zod.z.string().uuid(),
|
|
194
|
+
node_type: import_zod.z.enum(["activity", "event", "decision"]),
|
|
195
|
+
position: Vector2DSchema,
|
|
196
|
+
width: import_zod.z.number().min(0).optional(),
|
|
197
|
+
height: import_zod.z.number().min(0).optional(),
|
|
198
|
+
z_index: import_zod.z.number().int().optional(),
|
|
199
|
+
shape: NodeShape.optional(),
|
|
200
|
+
style: NodeStyle2DSchema.optional(),
|
|
201
|
+
collapsed: import_zod.z.boolean().default(false)
|
|
202
|
+
});
|
|
203
|
+
var NodePosition3DSchema = import_zod.z.object({
|
|
204
|
+
id: import_zod.z.string().uuid().optional(),
|
|
205
|
+
node_id: import_zod.z.string().uuid(),
|
|
206
|
+
node_type: import_zod.z.enum(["activity", "event", "decision"]),
|
|
207
|
+
position: Vector3DSchema,
|
|
208
|
+
rotation: QuaternionSchema.optional(),
|
|
209
|
+
scale: Vector3DSchema.optional(),
|
|
210
|
+
shape: NodeShape.optional(),
|
|
211
|
+
material: NodeMaterial3DSchema.optional(),
|
|
212
|
+
visible: import_zod.z.boolean().default(true)
|
|
213
|
+
});
|
|
214
|
+
var EdgeStyleSchema = import_zod.z.object({
|
|
215
|
+
stroke_color: ColorSchema.optional(),
|
|
216
|
+
stroke_width: import_zod.z.number().optional(),
|
|
217
|
+
stroke_dasharray: import_zod.z.string().optional(),
|
|
218
|
+
marker_start: import_zod.z.string().optional(),
|
|
219
|
+
marker_end: import_zod.z.string().optional()
|
|
220
|
+
}).passthrough();
|
|
221
|
+
var EdgeRoutingSchema = import_zod.z.object({
|
|
222
|
+
id: import_zod.z.string().uuid().optional(),
|
|
223
|
+
edge_id: import_zod.z.string().uuid(),
|
|
224
|
+
curve_type: CurveType.default("bezier"),
|
|
225
|
+
control_points_2d: import_zod.z.array(Vector2DSchema).optional(),
|
|
226
|
+
control_points_3d: import_zod.z.array(Vector3DSchema).optional(),
|
|
227
|
+
animated: import_zod.z.boolean().default(false),
|
|
228
|
+
animation_speed: import_zod.z.number().min(0).optional(),
|
|
229
|
+
style: EdgeStyleSchema.optional()
|
|
230
|
+
});
|
|
231
|
+
var LaneSchema = import_zod.z.object({
|
|
232
|
+
id: import_zod.z.string().uuid(),
|
|
233
|
+
name: import_zod.z.string(),
|
|
234
|
+
label: import_zod.z.string().optional(),
|
|
235
|
+
description: import_zod.z.string().optional(),
|
|
236
|
+
orientation: LaneOrientation.default("horizontal"),
|
|
237
|
+
order_index: import_zod.z.number().int().optional(),
|
|
238
|
+
node_ids: import_zod.z.array(import_zod.z.string().uuid()).default([]),
|
|
239
|
+
role_id: import_zod.z.string().uuid().optional(),
|
|
240
|
+
organization_id: import_zod.z.string().uuid().optional(),
|
|
241
|
+
color: ColorSchema.optional(),
|
|
242
|
+
collapsed: import_zod.z.boolean().default(false)
|
|
243
|
+
});
|
|
244
|
+
var AutoLayoutConfigSchema = import_zod.z.object({
|
|
245
|
+
algorithm: LayoutAlgorithm.default("dagre"),
|
|
246
|
+
direction: LayoutDirection.default("lr"),
|
|
247
|
+
node_spacing: import_zod.z.number().min(0).default(50),
|
|
248
|
+
rank_spacing: import_zod.z.number().min(0).default(100),
|
|
249
|
+
edge_spacing: import_zod.z.number().min(0).default(10),
|
|
250
|
+
align: import_zod.z.enum(["ul", "ur", "dl", "dr"]).optional(),
|
|
251
|
+
elk_options: import_zod.z.record(import_zod.z.unknown()).optional(),
|
|
252
|
+
respect_lanes: import_zod.z.boolean().default(true)
|
|
253
|
+
});
|
|
254
|
+
var CameraSettings2DSchema = import_zod.z.object({
|
|
255
|
+
center: Vector2DSchema.optional(),
|
|
256
|
+
zoom: import_zod.z.number().min(0.1).max(10).default(1),
|
|
257
|
+
min_zoom: import_zod.z.number().min(0.1).default(0.1),
|
|
258
|
+
max_zoom: import_zod.z.number().max(10).default(4),
|
|
259
|
+
fit_view: import_zod.z.boolean().default(true),
|
|
260
|
+
fit_padding: import_zod.z.number().default(50)
|
|
261
|
+
});
|
|
262
|
+
var CameraSettings3DSchema = import_zod.z.object({
|
|
263
|
+
type: CameraType.default("arc_rotate"),
|
|
264
|
+
position: Vector3DSchema.optional(),
|
|
265
|
+
target: Vector3DSchema.optional(),
|
|
266
|
+
fov: import_zod.z.number().min(10).max(120).default(45),
|
|
267
|
+
near_clip: import_zod.z.number().min(0.01).default(0.1),
|
|
268
|
+
far_clip: import_zod.z.number().default(1e3),
|
|
269
|
+
alpha: import_zod.z.number().optional(),
|
|
270
|
+
beta: import_zod.z.number().optional(),
|
|
271
|
+
radius: import_zod.z.number().optional()
|
|
272
|
+
});
|
|
273
|
+
var AnimationConfigSchema = import_zod.z.object({
|
|
274
|
+
enabled: import_zod.z.boolean().default(true),
|
|
275
|
+
transition_duration: import_zod.z.number().int().min(0).default(300),
|
|
276
|
+
easing: AnimationEasing.default("ease_in_out"),
|
|
277
|
+
edge_flow_enabled: import_zod.z.boolean().default(false),
|
|
278
|
+
edge_flow_speed: import_zod.z.number().default(1),
|
|
279
|
+
highlight_active_path: import_zod.z.boolean().default(true),
|
|
280
|
+
playback_speed: import_zod.z.number().min(0.1).max(10).default(1)
|
|
281
|
+
});
|
|
282
|
+
var ThemeConfigSchema = import_zod.z.object({
|
|
283
|
+
background_color: ColorSchema.optional(),
|
|
284
|
+
grid_enabled: import_zod.z.boolean().default(true),
|
|
285
|
+
grid_size: import_zod.z.number().default(20),
|
|
286
|
+
grid_color: ColorSchema.optional(),
|
|
287
|
+
minimap_enabled: import_zod.z.boolean().default(true),
|
|
288
|
+
controls_enabled: import_zod.z.boolean().default(true)
|
|
289
|
+
}).passthrough();
|
|
290
|
+
var VisualizationConfigSchema = import_zod.z.object({
|
|
291
|
+
id: import_zod.z.string().uuid(),
|
|
292
|
+
workflow_id: import_zod.z.string().uuid(),
|
|
293
|
+
name: import_zod.z.string().optional(),
|
|
294
|
+
description: import_zod.z.string().optional(),
|
|
295
|
+
is_default: import_zod.z.boolean().default(false),
|
|
296
|
+
view_type: ViewType,
|
|
297
|
+
engine: VisualizationEngine.optional(),
|
|
298
|
+
auto_layout: AutoLayoutConfigSchema.optional(),
|
|
299
|
+
node_positions_2d: import_zod.z.array(NodePosition2DSchema).default([]),
|
|
300
|
+
node_positions_3d: import_zod.z.array(NodePosition3DSchema).default([]),
|
|
301
|
+
edge_routings: import_zod.z.array(EdgeRoutingSchema).default([]),
|
|
302
|
+
lanes: import_zod.z.array(LaneSchema).default([]),
|
|
303
|
+
camera_2d: CameraSettings2DSchema.optional(),
|
|
304
|
+
camera_3d: CameraSettings3DSchema.optional(),
|
|
305
|
+
animation: AnimationConfigSchema.optional(),
|
|
306
|
+
theme: ThemeConfigSchema.optional(),
|
|
307
|
+
metadata: import_zod.z.record(import_zod.z.unknown()).optional(),
|
|
308
|
+
created_at: import_zod.z.string().datetime().optional(),
|
|
309
|
+
updated_at: import_zod.z.string().datetime().optional()
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
// src/types/index.ts
|
|
313
|
+
var ActorType = import_zod2.z.enum(["human", "ai_agent", "robot", "application"]);
|
|
314
|
+
var AccessMode = import_zod2.z.enum(["read", "write", "read_write", "subscribe", "publish"]);
|
|
315
|
+
var SyncPattern = import_zod2.z.enum(["shared_state", "message_passing", "blackboard", "event_sourcing"]);
|
|
316
|
+
var ContextType = import_zod2.z.enum(["document", "data", "config", "state", "memory", "artifact"]);
|
|
317
|
+
var Visibility = import_zod2.z.enum(["private", "workflow", "collection", "global"]);
|
|
318
|
+
var Permission = import_zod2.z.enum(["read", "write", "execute", "admin", "delete", "create"]);
|
|
319
|
+
var ResourceType = import_zod2.z.enum(["system", "api", "database", "file", "service", "secret"]);
|
|
320
|
+
var AccessDirection = import_zod2.z.enum(["requires", "provisions"]);
|
|
321
|
+
var HitPolicy = import_zod2.z.enum(["unique", "first", "priority", "any", "collect", "rule_order"]);
|
|
322
|
+
var WasteCategory = import_zod2.z.enum([
|
|
323
|
+
"defects",
|
|
324
|
+
"overproduction",
|
|
325
|
+
"waiting",
|
|
326
|
+
"non_utilized_talent",
|
|
327
|
+
"transport",
|
|
328
|
+
"inventory",
|
|
329
|
+
"motion",
|
|
330
|
+
"extra_processing"
|
|
331
|
+
]);
|
|
332
|
+
var NodeType = import_zod2.z.enum(["activity", "event", "decision"]);
|
|
333
|
+
var ControlType = import_zod2.z.enum(["authorization", "validation", "audit", "compliance", "security", "rate_limit"]);
|
|
334
|
+
var Enforcement = import_zod2.z.enum(["mandatory", "advisory", "informational"]);
|
|
335
|
+
var Lifecycle = import_zod2.z.enum(["transient", "persistent", "cached"]);
|
|
336
|
+
var SkillType = import_zod2.z.enum(["ai_context", "human_competency"]);
|
|
337
|
+
var ToolRequirementType = import_zod2.z.enum(["mcp", "rest_api", "graphql", "grpc", "software_package", "hardware_interface"]);
|
|
338
|
+
var UUID = import_zod2.z.string().uuid();
|
|
339
|
+
var Duration = import_zod2.z.string().regex(/^P(?:\d+Y)?(?:\d+M)?(?:\d+W)?(?:\d+D)?(?:T(?:\d+H)?(?:\d+M)?(?:\d+(?:\.\d+)?S)?)?$/);
|
|
340
|
+
var DateTimeTz = import_zod2.z.string().datetime();
|
|
341
|
+
var SkillBindingSchema = import_zod2.z.object({
|
|
342
|
+
id: UUID,
|
|
343
|
+
name: import_zod2.z.string(),
|
|
344
|
+
type: SkillType,
|
|
345
|
+
description: import_zod2.z.string().optional(),
|
|
346
|
+
min_level: import_zod2.z.string().optional(),
|
|
347
|
+
reference: import_zod2.z.string().url().optional()
|
|
348
|
+
});
|
|
349
|
+
var ToolRequirementSchema = import_zod2.z.object({
|
|
350
|
+
id: UUID,
|
|
351
|
+
name: import_zod2.z.string(),
|
|
352
|
+
type: ToolRequirementType,
|
|
353
|
+
description: import_zod2.z.string().optional(),
|
|
354
|
+
version: import_zod2.z.string().optional(),
|
|
355
|
+
reference: import_zod2.z.string().url().optional()
|
|
356
|
+
});
|
|
357
|
+
var DataObjectSchema = import_zod2.z.object({
|
|
358
|
+
name: import_zod2.z.string(),
|
|
359
|
+
description: import_zod2.z.string().optional(),
|
|
360
|
+
schema: import_zod2.z.record(import_zod2.z.unknown()).optional(),
|
|
361
|
+
required: import_zod2.z.boolean().default(true)
|
|
362
|
+
});
|
|
363
|
+
var ParameterSchema = import_zod2.z.object({
|
|
364
|
+
name: import_zod2.z.string(),
|
|
365
|
+
type: import_zod2.z.string(),
|
|
366
|
+
required: import_zod2.z.boolean().default(true),
|
|
367
|
+
default: import_zod2.z.unknown().optional()
|
|
368
|
+
});
|
|
369
|
+
var ProgramSchema = import_zod2.z.object({
|
|
370
|
+
id: UUID,
|
|
371
|
+
name: import_zod2.z.string(),
|
|
372
|
+
language: import_zod2.z.enum(["python", "typescript", "javascript", "java", "sql", "mcp_tool", "rest_api", "graphql", "shell"]),
|
|
373
|
+
code: import_zod2.z.string().optional(),
|
|
374
|
+
code_uri: import_zod2.z.string().url().optional(),
|
|
375
|
+
parameters: import_zod2.z.array(ParameterSchema).default([]),
|
|
376
|
+
mcp_server: import_zod2.z.string().optional()
|
|
377
|
+
});
|
|
378
|
+
var ControlSchema = import_zod2.z.object({
|
|
379
|
+
id: UUID,
|
|
380
|
+
name: import_zod2.z.string(),
|
|
381
|
+
description: import_zod2.z.string().optional(),
|
|
382
|
+
type: ControlType,
|
|
383
|
+
expression: import_zod2.z.string().optional(),
|
|
384
|
+
enforcement: Enforcement
|
|
385
|
+
});
|
|
386
|
+
var ContextBindingSchema = import_zod2.z.object({
|
|
387
|
+
id: UUID.optional(),
|
|
388
|
+
context_id: UUID,
|
|
389
|
+
activity_id: UUID.optional(),
|
|
390
|
+
access_mode: AccessMode,
|
|
391
|
+
required: import_zod2.z.boolean().default(true),
|
|
392
|
+
transforms: import_zod2.z.object({
|
|
393
|
+
on_read: import_zod2.z.string().optional(),
|
|
394
|
+
on_write: import_zod2.z.string().optional()
|
|
395
|
+
}).optional()
|
|
396
|
+
});
|
|
397
|
+
var AccessRightSchema = import_zod2.z.object({
|
|
398
|
+
id: UUID,
|
|
399
|
+
name: import_zod2.z.string(),
|
|
400
|
+
description: import_zod2.z.string().optional(),
|
|
401
|
+
activity_id: UUID.optional(),
|
|
402
|
+
direction: AccessDirection,
|
|
403
|
+
resource_type: ResourceType,
|
|
404
|
+
resource_id: import_zod2.z.string().optional(),
|
|
405
|
+
permission: Permission,
|
|
406
|
+
scope: import_zod2.z.string().optional(),
|
|
407
|
+
conditions: import_zod2.z.record(import_zod2.z.unknown()).optional()
|
|
408
|
+
});
|
|
409
|
+
var ContextSchema = import_zod2.z.object({
|
|
410
|
+
id: UUID,
|
|
411
|
+
name: import_zod2.z.string(),
|
|
412
|
+
description: import_zod2.z.string().optional(),
|
|
413
|
+
type: ContextType,
|
|
414
|
+
schema: import_zod2.z.record(import_zod2.z.unknown()).optional(),
|
|
415
|
+
initial_value: import_zod2.z.unknown().optional(),
|
|
416
|
+
sync_pattern: SyncPattern,
|
|
417
|
+
visibility: Visibility.default("workflow"),
|
|
418
|
+
owner_workflow_id: UUID.optional(),
|
|
419
|
+
lifecycle: Lifecycle.default("persistent"),
|
|
420
|
+
ttl: Duration.optional()
|
|
421
|
+
});
|
|
422
|
+
var SLASchema = import_zod2.z.object({
|
|
423
|
+
id: UUID.optional(),
|
|
424
|
+
name: import_zod2.z.string().optional(),
|
|
425
|
+
target_time: Duration.optional(),
|
|
426
|
+
max_time: Duration.optional(),
|
|
427
|
+
escalation_policy: import_zod2.z.object({
|
|
428
|
+
warning_threshold: Duration.optional(),
|
|
429
|
+
warning_action: import_zod2.z.string().optional(),
|
|
430
|
+
breach_action: import_zod2.z.string().optional(),
|
|
431
|
+
notify_roles: import_zod2.z.array(UUID).optional()
|
|
432
|
+
}).optional(),
|
|
433
|
+
metrics: import_zod2.z.array(import_zod2.z.object({
|
|
434
|
+
name: import_zod2.z.string(),
|
|
435
|
+
target: import_zod2.z.number(),
|
|
436
|
+
unit: import_zod2.z.string().optional(),
|
|
437
|
+
comparison: import_zod2.z.enum(["lt", "lte", "eq", "gte", "gt"]).optional()
|
|
438
|
+
})).optional()
|
|
439
|
+
});
|
|
440
|
+
var AnalyticsSchema = import_zod2.z.object({
|
|
441
|
+
process_time: Duration.optional(),
|
|
442
|
+
cycle_time: Duration.optional(),
|
|
443
|
+
lead_time: Duration.optional(),
|
|
444
|
+
wait_time: Duration.optional(),
|
|
445
|
+
value_added: import_zod2.z.boolean().optional(),
|
|
446
|
+
waste_categories: import_zod2.z.array(WasteCategory).optional(),
|
|
447
|
+
cost: import_zod2.z.object({
|
|
448
|
+
amount: import_zod2.z.number(),
|
|
449
|
+
currency: import_zod2.z.string().length(3)
|
|
450
|
+
}).optional(),
|
|
451
|
+
resource_utilization: import_zod2.z.number().min(0).max(1).optional(),
|
|
452
|
+
error_rate: import_zod2.z.number().min(0).max(1).optional(),
|
|
453
|
+
throughput: import_zod2.z.object({
|
|
454
|
+
value: import_zod2.z.number(),
|
|
455
|
+
unit: import_zod2.z.string(),
|
|
456
|
+
period: Duration.optional()
|
|
457
|
+
}).optional(),
|
|
458
|
+
process_cycle_efficiency: import_zod2.z.number().min(0).max(1).optional()
|
|
459
|
+
});
|
|
460
|
+
var ActivitySchema = import_zod2.z.object({
|
|
461
|
+
id: UUID,
|
|
462
|
+
name: import_zod2.z.string(),
|
|
463
|
+
description: import_zod2.z.string().optional(),
|
|
464
|
+
role_id: UUID,
|
|
465
|
+
actor_type: ActorType,
|
|
466
|
+
system_id: UUID.optional(),
|
|
467
|
+
machine_id: UUID.optional(),
|
|
468
|
+
endpoint_id: UUID.optional(),
|
|
469
|
+
organization_id: UUID.optional(),
|
|
470
|
+
inputs: import_zod2.z.array(DataObjectSchema).default([]),
|
|
471
|
+
outputs: import_zod2.z.array(DataObjectSchema).default([]),
|
|
472
|
+
context_bindings: import_zod2.z.array(ContextBindingSchema).default([]),
|
|
473
|
+
access_rights: import_zod2.z.array(AccessRightSchema).default([]),
|
|
474
|
+
programs: import_zod2.z.array(ProgramSchema).default([]),
|
|
475
|
+
controls: import_zod2.z.array(ControlSchema).default([]),
|
|
476
|
+
sla: SLASchema.optional(),
|
|
477
|
+
analytics: AnalyticsSchema.optional(),
|
|
478
|
+
is_expandable: import_zod2.z.boolean().default(false),
|
|
479
|
+
expansion_workflow_id: UUID.optional(),
|
|
480
|
+
skills: import_zod2.z.array(SkillBindingSchema).default([]),
|
|
481
|
+
tool_requirements: import_zod2.z.array(ToolRequirementSchema).default([])
|
|
482
|
+
});
|
|
483
|
+
var EdgeSchema = import_zod2.z.object({
|
|
484
|
+
id: UUID,
|
|
485
|
+
source_id: UUID,
|
|
486
|
+
target_id: UUID,
|
|
487
|
+
source_type: NodeType.optional(),
|
|
488
|
+
target_type: NodeType.optional(),
|
|
489
|
+
condition: import_zod2.z.string().optional(),
|
|
490
|
+
label: import_zod2.z.string().optional(),
|
|
491
|
+
is_default: import_zod2.z.boolean().default(false),
|
|
492
|
+
skills: import_zod2.z.array(SkillBindingSchema).default([]),
|
|
493
|
+
tool_requirements: import_zod2.z.array(ToolRequirementSchema).default([])
|
|
494
|
+
});
|
|
495
|
+
var EventSchema = import_zod2.z.object({
|
|
496
|
+
id: UUID,
|
|
497
|
+
name: import_zod2.z.string(),
|
|
498
|
+
description: import_zod2.z.string().optional(),
|
|
499
|
+
event_type: import_zod2.z.string(),
|
|
500
|
+
event_definition: import_zod2.z.record(import_zod2.z.unknown()).optional()
|
|
501
|
+
});
|
|
502
|
+
var DecisionRuleSchema = import_zod2.z.object({
|
|
503
|
+
id: UUID.optional(),
|
|
504
|
+
description: import_zod2.z.string().optional(),
|
|
505
|
+
input_entries: import_zod2.z.array(import_zod2.z.string()),
|
|
506
|
+
output_entries: import_zod2.z.array(import_zod2.z.unknown()),
|
|
507
|
+
output_edge_id: UUID.optional()
|
|
508
|
+
});
|
|
509
|
+
var TableColumnSchema = import_zod2.z.object({
|
|
510
|
+
name: import_zod2.z.string(),
|
|
511
|
+
label: import_zod2.z.string().optional(),
|
|
512
|
+
type: import_zod2.z.enum(["string", "number", "boolean", "date", "datetime"]),
|
|
513
|
+
allowed_values: import_zod2.z.array(import_zod2.z.unknown()).optional()
|
|
514
|
+
});
|
|
515
|
+
var DecisionTableSchema = import_zod2.z.object({
|
|
516
|
+
hit_policy: HitPolicy,
|
|
517
|
+
inputs: import_zod2.z.array(TableColumnSchema).min(1),
|
|
518
|
+
outputs: import_zod2.z.array(TableColumnSchema).min(1),
|
|
519
|
+
rules: import_zod2.z.array(DecisionRuleSchema)
|
|
520
|
+
});
|
|
521
|
+
var DecisionNodeSchema = import_zod2.z.object({
|
|
522
|
+
id: UUID,
|
|
523
|
+
name: import_zod2.z.string(),
|
|
524
|
+
description: import_zod2.z.string().optional(),
|
|
525
|
+
decision_table: DecisionTableSchema,
|
|
526
|
+
default_output_edge_id: UUID.optional()
|
|
527
|
+
});
|
|
528
|
+
var WorkflowSchema = import_zod2.z.object({
|
|
529
|
+
id: UUID,
|
|
530
|
+
name: import_zod2.z.string(),
|
|
531
|
+
version: import_zod2.z.string().regex(/^\d+\.\d+\.\d+$/),
|
|
532
|
+
description: import_zod2.z.string().optional(),
|
|
533
|
+
owner_id: UUID.optional(),
|
|
534
|
+
organization_id: UUID.optional(),
|
|
535
|
+
parent_workflow_id: UUID.optional(),
|
|
536
|
+
expansion_activity_id: UUID.optional(),
|
|
537
|
+
activities: import_zod2.z.array(ActivitySchema),
|
|
538
|
+
edges: import_zod2.z.array(EdgeSchema),
|
|
539
|
+
events: import_zod2.z.array(EventSchema).default([]),
|
|
540
|
+
decision_nodes: import_zod2.z.array(DecisionNodeSchema).default([]),
|
|
541
|
+
contexts: import_zod2.z.array(ContextSchema).default([]),
|
|
542
|
+
sla: SLASchema.optional(),
|
|
543
|
+
analytics: AnalyticsSchema.optional(),
|
|
544
|
+
metadata: import_zod2.z.record(import_zod2.z.unknown()).optional(),
|
|
545
|
+
created_at: DateTimeTz.optional(),
|
|
546
|
+
updated_at: DateTimeTz.optional()
|
|
547
|
+
});
|
|
548
|
+
var CollectionSchema = import_zod2.z.object({
|
|
549
|
+
id: UUID,
|
|
550
|
+
name: import_zod2.z.string(),
|
|
551
|
+
description: import_zod2.z.string().optional(),
|
|
552
|
+
workflow_ids: import_zod2.z.array(UUID).default([]),
|
|
553
|
+
shared_contexts: import_zod2.z.array(ContextSchema).default([]),
|
|
554
|
+
owner_id: UUID.optional(),
|
|
555
|
+
organization_id: UUID.optional(),
|
|
556
|
+
tags: import_zod2.z.array(import_zod2.z.string()).default([]),
|
|
557
|
+
created_at: DateTimeTz.optional(),
|
|
558
|
+
updated_at: DateTimeTz.optional()
|
|
559
|
+
});
|
|
560
|
+
var RoleSchema = import_zod2.z.object({
|
|
561
|
+
id: UUID,
|
|
562
|
+
name: import_zod2.z.string(),
|
|
563
|
+
description: import_zod2.z.string().optional(),
|
|
564
|
+
actor_type: ActorType,
|
|
565
|
+
organization_id: UUID.optional(),
|
|
566
|
+
capabilities: import_zod2.z.array(import_zod2.z.string()).default([]),
|
|
567
|
+
is_embedded: import_zod2.z.boolean().default(false),
|
|
568
|
+
ai_model_config: import_zod2.z.object({
|
|
569
|
+
model_id: import_zod2.z.string().optional(),
|
|
570
|
+
temperature: import_zod2.z.number().min(0).max(2).optional(),
|
|
571
|
+
max_tokens: import_zod2.z.number().optional(),
|
|
572
|
+
system_prompt: import_zod2.z.string().optional()
|
|
573
|
+
}).optional(),
|
|
574
|
+
mcp_tools: import_zod2.z.array(import_zod2.z.object({
|
|
575
|
+
server_name: import_zod2.z.string(),
|
|
576
|
+
tool_name: import_zod2.z.string()
|
|
577
|
+
})).default([])
|
|
578
|
+
});
|
|
579
|
+
var SystemSchema = import_zod2.z.object({
|
|
580
|
+
id: UUID,
|
|
581
|
+
name: import_zod2.z.string(),
|
|
582
|
+
vendor: import_zod2.z.string().optional(),
|
|
583
|
+
version: import_zod2.z.string().optional(),
|
|
584
|
+
type: import_zod2.z.enum(["erp", "crm", "hrm", "scm", "custom", "saas", "database", "messaging", "storage"]),
|
|
585
|
+
description: import_zod2.z.string().optional(),
|
|
586
|
+
base_url: import_zod2.z.string().url().optional(),
|
|
587
|
+
auth_config: import_zod2.z.record(import_zod2.z.unknown()).optional()
|
|
588
|
+
});
|
|
589
|
+
var MachineSchema = import_zod2.z.object({
|
|
590
|
+
id: UUID,
|
|
591
|
+
name: import_zod2.z.string(),
|
|
592
|
+
type: import_zod2.z.enum(["robot", "sensor", "actuator", "printer", "scanner", "vehicle", "camera", "conveyor"]),
|
|
593
|
+
manufacturer: import_zod2.z.string().optional(),
|
|
594
|
+
model: import_zod2.z.string().optional(),
|
|
595
|
+
serial_number: import_zod2.z.string().optional(),
|
|
596
|
+
location: import_zod2.z.string().optional(),
|
|
597
|
+
protocol: import_zod2.z.enum(["mqtt", "opcua", "modbus", "http", "grpc", "ros"]).optional(),
|
|
598
|
+
connection_string: import_zod2.z.string().optional()
|
|
599
|
+
});
|
|
600
|
+
var EndpointSchema = import_zod2.z.object({
|
|
601
|
+
id: UUID,
|
|
602
|
+
name: import_zod2.z.string(),
|
|
603
|
+
url: import_zod2.z.string(),
|
|
604
|
+
method: import_zod2.z.enum(["GET", "POST", "PUT", "DELETE", "PATCH", "GRPC", "WEBSOCKET", "GRAPHQL"]).optional(),
|
|
605
|
+
auth_type: import_zod2.z.enum(["none", "api_key", "oauth2", "jwt", "basic", "mtls"]).optional(),
|
|
606
|
+
openapi_ref: import_zod2.z.string().optional(),
|
|
607
|
+
request_schema: import_zod2.z.record(import_zod2.z.unknown()).optional(),
|
|
608
|
+
response_schema: import_zod2.z.record(import_zod2.z.unknown()).optional()
|
|
609
|
+
});
|
|
610
|
+
var HumanTaskStatus = import_zod2.z.enum(["pending", "assigned", "in_progress", "completed", "rejected", "expired"]);
|
|
611
|
+
var HumanTaskPriority = import_zod2.z.enum(["low", "normal", "high", "critical"]);
|
|
612
|
+
var HumanTaskSchema = import_zod2.z.object({
|
|
613
|
+
id: UUID,
|
|
614
|
+
activity_id: UUID,
|
|
615
|
+
activity_name: import_zod2.z.string(),
|
|
616
|
+
token_id: UUID,
|
|
617
|
+
workflow_id: UUID,
|
|
618
|
+
status: HumanTaskStatus,
|
|
619
|
+
priority: HumanTaskPriority,
|
|
620
|
+
assignee_id: import_zod2.z.string().optional(),
|
|
621
|
+
role_id: UUID,
|
|
622
|
+
creator_id: import_zod2.z.string().optional(),
|
|
623
|
+
creator_type: ActorType.optional(),
|
|
624
|
+
assigner_id: import_zod2.z.string().optional(),
|
|
625
|
+
assigner_type: ActorType.optional(),
|
|
626
|
+
inputs: import_zod2.z.record(import_zod2.z.unknown()),
|
|
627
|
+
outputs: import_zod2.z.record(import_zod2.z.unknown()).optional(),
|
|
628
|
+
created_at: DateTimeTz,
|
|
629
|
+
updated_at: DateTimeTz,
|
|
630
|
+
due_at: DateTimeTz.optional(),
|
|
631
|
+
completed_at: DateTimeTz.optional(),
|
|
632
|
+
description: import_zod2.z.string().optional(),
|
|
633
|
+
form_schema: import_zod2.z.record(import_zod2.z.unknown()).optional(),
|
|
634
|
+
tags: import_zod2.z.array(import_zod2.z.string()).optional()
|
|
635
|
+
});
|
|
636
|
+
|
|
637
|
+
// src/runtime/token.ts
|
|
638
|
+
var import_uuid = require("uuid");
|
|
639
|
+
var Token = class {
|
|
640
|
+
id;
|
|
641
|
+
activityId;
|
|
642
|
+
status;
|
|
643
|
+
contextData;
|
|
644
|
+
history;
|
|
645
|
+
parentTokenId;
|
|
646
|
+
workflowId;
|
|
647
|
+
createdAt;
|
|
648
|
+
updatedAt;
|
|
649
|
+
constructor(activityId, initialData = {}, parentTokenId, workflowId) {
|
|
650
|
+
this.id = (0, import_uuid.v4)();
|
|
651
|
+
this.activityId = activityId;
|
|
652
|
+
this.status = "active";
|
|
653
|
+
this.contextData = { ...initialData };
|
|
654
|
+
this.history = [];
|
|
655
|
+
this.parentTokenId = parentTokenId;
|
|
656
|
+
this.workflowId = workflowId;
|
|
657
|
+
this.createdAt = /* @__PURE__ */ new Date();
|
|
658
|
+
this.updatedAt = /* @__PURE__ */ new Date();
|
|
659
|
+
this.addToHistory(activityId, "created");
|
|
660
|
+
}
|
|
661
|
+
move(nextActivityId, analytics) {
|
|
662
|
+
this.addToHistory(this.activityId, "exited", void 0, analytics);
|
|
663
|
+
this.activityId = nextActivityId;
|
|
664
|
+
this.status = "active";
|
|
665
|
+
this.updatedAt = /* @__PURE__ */ new Date();
|
|
666
|
+
this.addToHistory(nextActivityId, "entered");
|
|
667
|
+
}
|
|
668
|
+
updateStatus(status, analytics) {
|
|
669
|
+
this.status = status;
|
|
670
|
+
this.updatedAt = /* @__PURE__ */ new Date();
|
|
671
|
+
this.addToHistory(this.activityId, `status_change:${status}`, void 0, analytics);
|
|
672
|
+
}
|
|
673
|
+
setData(key, value) {
|
|
674
|
+
this.contextData[key] = value;
|
|
675
|
+
this.updatedAt = /* @__PURE__ */ new Date();
|
|
676
|
+
}
|
|
677
|
+
getData(key) {
|
|
678
|
+
return this.contextData[key];
|
|
679
|
+
}
|
|
680
|
+
mergeData(data) {
|
|
681
|
+
this.contextData = { ...this.contextData, ...data };
|
|
682
|
+
this.updatedAt = /* @__PURE__ */ new Date();
|
|
683
|
+
}
|
|
684
|
+
addToHistory(nodeId, action, metrics, analytics) {
|
|
685
|
+
this.history.push({
|
|
686
|
+
nodeId,
|
|
687
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
688
|
+
action,
|
|
689
|
+
metrics,
|
|
690
|
+
analytics
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
toJSON() {
|
|
694
|
+
return {
|
|
695
|
+
id: this.id,
|
|
696
|
+
activityId: this.activityId,
|
|
697
|
+
status: this.status,
|
|
698
|
+
contextData: this.contextData,
|
|
699
|
+
history: this.history,
|
|
700
|
+
parentTokenId: this.parentTokenId,
|
|
701
|
+
workflowId: this.workflowId,
|
|
702
|
+
createdAt: this.createdAt.toISOString(),
|
|
703
|
+
updatedAt: this.updatedAt.toISOString()
|
|
704
|
+
};
|
|
705
|
+
}
|
|
706
|
+
};
|
|
707
|
+
|
|
708
|
+
// src/runtime/context_manager.ts
|
|
709
|
+
var ContextManager = class {
|
|
710
|
+
contexts;
|
|
711
|
+
values;
|
|
712
|
+
constructor() {
|
|
713
|
+
this.contexts = /* @__PURE__ */ new Map();
|
|
714
|
+
this.values = /* @__PURE__ */ new Map();
|
|
715
|
+
}
|
|
716
|
+
register(context) {
|
|
717
|
+
this.contexts.set(context.id, context);
|
|
718
|
+
if (context.initial_value !== void 0) {
|
|
719
|
+
this.values.set(context.id, JSON.parse(JSON.stringify(context.initial_value)));
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
get(contextId) {
|
|
723
|
+
if (!this.contexts.has(contextId)) {
|
|
724
|
+
throw new Error(`Context with ID ${contextId} not found`);
|
|
725
|
+
}
|
|
726
|
+
return this.values.get(contextId);
|
|
727
|
+
}
|
|
728
|
+
set(contextId, value) {
|
|
729
|
+
if (!this.contexts.has(contextId)) {
|
|
730
|
+
throw new Error(`Context with ID ${contextId} not found`);
|
|
731
|
+
}
|
|
732
|
+
this.values.set(contextId, value);
|
|
733
|
+
}
|
|
734
|
+
update(contextId, partialValue) {
|
|
735
|
+
if (!this.contexts.has(contextId)) {
|
|
736
|
+
throw new Error(`Context with ID ${contextId} not found`);
|
|
737
|
+
}
|
|
738
|
+
const currentValue = this.values.get(contextId) || {};
|
|
739
|
+
if (typeof currentValue === "object" && currentValue !== null && !Array.isArray(currentValue)) {
|
|
740
|
+
this.values.set(contextId, { ...currentValue, ...partialValue });
|
|
741
|
+
} else {
|
|
742
|
+
this.values.set(contextId, partialValue);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
delete(contextId) {
|
|
746
|
+
if (!this.contexts.has(contextId)) {
|
|
747
|
+
throw new Error(`Context with ID ${contextId} not found`);
|
|
748
|
+
}
|
|
749
|
+
this.contexts.delete(contextId);
|
|
750
|
+
this.values.delete(contextId);
|
|
751
|
+
}
|
|
752
|
+
getContextDefinition(contextId) {
|
|
753
|
+
return this.contexts.get(contextId);
|
|
754
|
+
}
|
|
755
|
+
};
|
|
756
|
+
|
|
757
|
+
// src/validator/index.ts
|
|
758
|
+
function formatZodError(error) {
|
|
759
|
+
return error.errors.map((e) => ({
|
|
760
|
+
path: e.path.join("."),
|
|
761
|
+
message: e.message,
|
|
762
|
+
code: e.code
|
|
763
|
+
}));
|
|
764
|
+
}
|
|
765
|
+
function validate_workflow(data) {
|
|
766
|
+
const result = WorkflowSchema.safeParse(data);
|
|
767
|
+
if (result.success) {
|
|
768
|
+
return { valid: true, errors: [] };
|
|
769
|
+
}
|
|
770
|
+
return { valid: false, errors: formatZodError(result.error) };
|
|
771
|
+
}
|
|
772
|
+
function validate_activity(data) {
|
|
773
|
+
const result = ActivitySchema.safeParse(data);
|
|
774
|
+
if (result.success) {
|
|
775
|
+
return { valid: true, errors: [] };
|
|
776
|
+
}
|
|
777
|
+
return { valid: false, errors: formatZodError(result.error) };
|
|
778
|
+
}
|
|
779
|
+
function validate_context(data) {
|
|
780
|
+
const result = ContextSchema.safeParse(data);
|
|
781
|
+
if (result.success) {
|
|
782
|
+
return { valid: true, errors: [] };
|
|
783
|
+
}
|
|
784
|
+
return { valid: false, errors: formatZodError(result.error) };
|
|
785
|
+
}
|
|
786
|
+
function parse_workflow(data) {
|
|
787
|
+
return WorkflowSchema.parse(data);
|
|
788
|
+
}
|
|
789
|
+
function parse_activity(data) {
|
|
790
|
+
return ActivitySchema.parse(data);
|
|
791
|
+
}
|
|
792
|
+
function parse_context(data) {
|
|
793
|
+
return ContextSchema.parse(data);
|
|
794
|
+
}
|
|
795
|
+
function validate_workflow_integrity(workflow2) {
|
|
796
|
+
const errors = [];
|
|
797
|
+
const nodeIds = /* @__PURE__ */ new Set([
|
|
798
|
+
...workflow2.activities.map((a) => a.id),
|
|
799
|
+
...workflow2.events.map((e) => e.id),
|
|
800
|
+
...workflow2.decision_nodes.map((d) => d.id)
|
|
801
|
+
]);
|
|
802
|
+
for (const edge of workflow2.edges) {
|
|
803
|
+
if (!nodeIds.has(edge.source_id)) {
|
|
804
|
+
errors.push({
|
|
805
|
+
path: `edges[${edge.id}].source_id`,
|
|
806
|
+
message: `Source node '${edge.source_id}' not found`,
|
|
807
|
+
code: "invalid_reference"
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
if (!nodeIds.has(edge.target_id)) {
|
|
811
|
+
errors.push({
|
|
812
|
+
path: `edges[${edge.id}].target_id`,
|
|
813
|
+
message: `Target node '${edge.target_id}' not found`,
|
|
814
|
+
code: "invalid_reference"
|
|
815
|
+
});
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
const contextIds = new Set(workflow2.contexts.map((c) => c.id));
|
|
819
|
+
for (const activity of workflow2.activities) {
|
|
820
|
+
for (const binding of activity.context_bindings) {
|
|
821
|
+
if (!contextIds.has(binding.context_id)) {
|
|
822
|
+
errors.push({
|
|
823
|
+
path: `activities[${activity.id}].context_bindings`,
|
|
824
|
+
message: `Context '${binding.context_id}' not found`,
|
|
825
|
+
code: "invalid_reference"
|
|
826
|
+
});
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
return { valid: errors.length === 0, errors };
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
// src/runtime/actors/software_agent.ts
|
|
834
|
+
var SoftwareAgent = class {
|
|
835
|
+
async execute(activity, inputs) {
|
|
836
|
+
console.log(`[SoftwareAgent] Executing activity: ${activity.name} (${activity.id})`);
|
|
837
|
+
if (activity.programs && activity.programs.length > 0) {
|
|
838
|
+
for (const program of activity.programs) {
|
|
839
|
+
if (program.language === "rest_api") {
|
|
840
|
+
return this.executeRestApi(program, inputs);
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
return {
|
|
845
|
+
status: "success",
|
|
846
|
+
message: "Executed via SoftwareAgent",
|
|
847
|
+
...inputs
|
|
848
|
+
};
|
|
849
|
+
}
|
|
850
|
+
async executeRestApi(program, inputs) {
|
|
851
|
+
console.log(`[SoftwareAgent] Executing REST API: ${program.name}`);
|
|
852
|
+
return {
|
|
853
|
+
status: 200,
|
|
854
|
+
data: {
|
|
855
|
+
mock_response: "from_rest_api",
|
|
856
|
+
inputs_received: inputs
|
|
857
|
+
}
|
|
858
|
+
};
|
|
859
|
+
}
|
|
860
|
+
};
|
|
861
|
+
|
|
862
|
+
// src/runtime/actors/ai_agent.ts
|
|
863
|
+
var import_generative_ai = require("@google/generative-ai");
|
|
864
|
+
var AIAgent = class {
|
|
865
|
+
genAI;
|
|
866
|
+
model;
|
|
867
|
+
role;
|
|
868
|
+
constructor(apiKey, role) {
|
|
869
|
+
this.genAI = new import_generative_ai.GoogleGenerativeAI(apiKey);
|
|
870
|
+
this.model = this.genAI.getGenerativeModel({ model: "gemini-2.5-flash" });
|
|
871
|
+
this.role = role;
|
|
872
|
+
}
|
|
873
|
+
async execute(activity, inputs) {
|
|
874
|
+
console.log(`[AIAgent] Executing activity: ${activity.name} (${activity.id})`);
|
|
875
|
+
const systemPrompt = this.generateSystemPrompt(activity);
|
|
876
|
+
const userMessage = this.generateUserMessage(activity, inputs);
|
|
877
|
+
try {
|
|
878
|
+
const generationConfig = {
|
|
879
|
+
temperature: this.role?.ai_model_config?.temperature ?? 0.7,
|
|
880
|
+
maxOutputTokens: this.role?.ai_model_config?.max_tokens ?? 1024
|
|
881
|
+
};
|
|
882
|
+
const result = await this.model.generateContent({
|
|
883
|
+
contents: [
|
|
884
|
+
{ role: "user", parts: [{ text: systemPrompt + "\n\n" + userMessage }] }
|
|
885
|
+
]
|
|
886
|
+
// Note: System instructions are supported in newer API versions,
|
|
887
|
+
// but combining into prompt is a safe fallback for all client versions.
|
|
888
|
+
// If the client supports systemInstruction, we could use that.
|
|
889
|
+
// generationConfig: generationConfig
|
|
890
|
+
});
|
|
891
|
+
const responseText = result.response.text();
|
|
892
|
+
try {
|
|
893
|
+
const jsonMatch = responseText.match(/\{[\s\S]*\}/);
|
|
894
|
+
if (jsonMatch) {
|
|
895
|
+
return JSON.parse(jsonMatch[0]);
|
|
896
|
+
}
|
|
897
|
+
} catch (e) {
|
|
898
|
+
}
|
|
899
|
+
return {
|
|
900
|
+
output: responseText,
|
|
901
|
+
status: "complex_completed"
|
|
902
|
+
};
|
|
903
|
+
} catch (error) {
|
|
904
|
+
console.error("[AIAgent] Execution failed:", error);
|
|
905
|
+
throw new Error(`AIAgent execution failed: ${error.message}`);
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
generateSystemPrompt(activity) {
|
|
909
|
+
const lines = [];
|
|
910
|
+
if (this.role) {
|
|
911
|
+
lines.push(`You are a ${this.role.name}.`);
|
|
912
|
+
if (this.role.description) {
|
|
913
|
+
lines.push(this.role.description);
|
|
914
|
+
}
|
|
915
|
+
if (this.role.capabilities && this.role.capabilities.length > 0) {
|
|
916
|
+
lines.push(` Your capabilities are: ${this.role.capabilities.join(", ")}.`);
|
|
917
|
+
}
|
|
918
|
+
} else {
|
|
919
|
+
lines.push("You are an intelligent AI agent.");
|
|
920
|
+
}
|
|
921
|
+
lines.push(`
|
|
922
|
+
You are responding to a request to perform the activity: "${activity.name}".`);
|
|
923
|
+
if (activity.description) {
|
|
924
|
+
lines.push(`Description: ${activity.description}`);
|
|
925
|
+
}
|
|
926
|
+
lines.push("\nPlease provide your output in a structured JSON format if the activity implies structured data, otherwise provide a clear textual response.");
|
|
927
|
+
return lines.join("\n");
|
|
928
|
+
}
|
|
929
|
+
generateUserMessage(activity, inputs) {
|
|
930
|
+
const lines = [];
|
|
931
|
+
lines.push("## Input Context");
|
|
932
|
+
if (Object.keys(inputs).length > 0) {
|
|
933
|
+
lines.push(JSON.stringify(inputs, null, 2));
|
|
934
|
+
} else {
|
|
935
|
+
lines.push("No specific input data provided.");
|
|
936
|
+
}
|
|
937
|
+
if (activity.controls && activity.controls.length > 0) {
|
|
938
|
+
lines.push("\n## Controls & Constraints");
|
|
939
|
+
activity.controls.forEach((c) => {
|
|
940
|
+
lines.push(`- ${c.name}: ${c.description || ""} (${c.enforcement})`);
|
|
941
|
+
});
|
|
942
|
+
}
|
|
943
|
+
lines.push("\nBased on the above, please perform the activity and generate the output.");
|
|
944
|
+
return lines.join("\n");
|
|
945
|
+
}
|
|
946
|
+
};
|
|
947
|
+
|
|
948
|
+
// src/runtime/actors/robot_agent.ts
|
|
949
|
+
var RobotAgent = class {
|
|
950
|
+
config;
|
|
951
|
+
constructor(config = {}) {
|
|
952
|
+
this.config = {
|
|
953
|
+
simulation_mode: true,
|
|
954
|
+
// Default to simulation for safety
|
|
955
|
+
timeout_ms: 3e4,
|
|
956
|
+
...config
|
|
957
|
+
};
|
|
958
|
+
}
|
|
959
|
+
async execute(activity, inputs) {
|
|
960
|
+
console.log(`[RobotAgent] Executing activity: ${activity.name} (${activity.id})`);
|
|
961
|
+
const start_time = Date.now();
|
|
962
|
+
if (this.config.simulation_mode) {
|
|
963
|
+
return this.simulate_execution(activity, inputs, start_time);
|
|
964
|
+
}
|
|
965
|
+
return this.execute_robot_command(activity, inputs, start_time);
|
|
966
|
+
}
|
|
967
|
+
/**
|
|
968
|
+
* Simulate robot execution for testing/development
|
|
969
|
+
*/
|
|
970
|
+
async simulate_execution(activity, inputs, start_time) {
|
|
971
|
+
console.log("[RobotAgent] Running in SIMULATION mode");
|
|
972
|
+
const simulated_delay = Math.random() * 400 + 100;
|
|
973
|
+
await new Promise((resolve) => setTimeout(resolve, simulated_delay));
|
|
974
|
+
const execution_time_ms = Date.now() - start_time;
|
|
975
|
+
const activity_type = this.infer_robot_activity_type(activity);
|
|
976
|
+
switch (activity_type) {
|
|
977
|
+
case "pick":
|
|
978
|
+
return {
|
|
979
|
+
status: "completed",
|
|
980
|
+
action: "pick",
|
|
981
|
+
execution_time_ms,
|
|
982
|
+
result: {
|
|
983
|
+
item_picked: true,
|
|
984
|
+
position: { x: 100, y: 50, z: 0 },
|
|
985
|
+
gripper_state: "closed"
|
|
986
|
+
},
|
|
987
|
+
...inputs
|
|
988
|
+
};
|
|
989
|
+
case "place":
|
|
990
|
+
return {
|
|
991
|
+
status: "completed",
|
|
992
|
+
action: "place",
|
|
993
|
+
execution_time_ms,
|
|
994
|
+
result: {
|
|
995
|
+
item_placed: true,
|
|
996
|
+
position: { x: 200, y: 100, z: 0 },
|
|
997
|
+
gripper_state: "open"
|
|
998
|
+
},
|
|
999
|
+
...inputs
|
|
1000
|
+
};
|
|
1001
|
+
case "move":
|
|
1002
|
+
return {
|
|
1003
|
+
status: "completed",
|
|
1004
|
+
action: "move",
|
|
1005
|
+
execution_time_ms,
|
|
1006
|
+
result: {
|
|
1007
|
+
movement_complete: true,
|
|
1008
|
+
current_position: { x: 150, y: 75, z: 25 }
|
|
1009
|
+
},
|
|
1010
|
+
...inputs
|
|
1011
|
+
};
|
|
1012
|
+
case "scan":
|
|
1013
|
+
return {
|
|
1014
|
+
status: "completed",
|
|
1015
|
+
action: "scan",
|
|
1016
|
+
execution_time_ms,
|
|
1017
|
+
result: {
|
|
1018
|
+
scan_complete: true,
|
|
1019
|
+
barcode: `SIM-${Date.now()}`,
|
|
1020
|
+
item_detected: true
|
|
1021
|
+
},
|
|
1022
|
+
...inputs
|
|
1023
|
+
};
|
|
1024
|
+
case "assemble":
|
|
1025
|
+
return {
|
|
1026
|
+
status: "completed",
|
|
1027
|
+
action: "assemble",
|
|
1028
|
+
execution_time_ms,
|
|
1029
|
+
result: {
|
|
1030
|
+
assembly_complete: true,
|
|
1031
|
+
quality_check: "passed",
|
|
1032
|
+
torque_values: [2.5, 2.7, 2.6]
|
|
1033
|
+
},
|
|
1034
|
+
...inputs
|
|
1035
|
+
};
|
|
1036
|
+
default:
|
|
1037
|
+
return {
|
|
1038
|
+
status: "completed",
|
|
1039
|
+
action: "generic_robot_task",
|
|
1040
|
+
execution_time_ms,
|
|
1041
|
+
result: {
|
|
1042
|
+
task_complete: true
|
|
1043
|
+
},
|
|
1044
|
+
...inputs
|
|
1045
|
+
};
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
/**
|
|
1049
|
+
* Execute actual robot command (placeholder for real implementation)
|
|
1050
|
+
*/
|
|
1051
|
+
async execute_robot_command(activity, inputs, start_time) {
|
|
1052
|
+
throw new Error(
|
|
1053
|
+
`Real robot execution not yet implemented. Protocol: ${this.config.protocol}, Connection: ${this.config.connection_string}. Enable simulation_mode for testing.`
|
|
1054
|
+
);
|
|
1055
|
+
}
|
|
1056
|
+
/**
|
|
1057
|
+
* Infer robot activity type from activity name/description
|
|
1058
|
+
*/
|
|
1059
|
+
infer_robot_activity_type(activity) {
|
|
1060
|
+
const name_lower = activity.name.toLowerCase();
|
|
1061
|
+
const desc_lower = (activity.description || "").toLowerCase();
|
|
1062
|
+
const combined = `${name_lower} ${desc_lower}`;
|
|
1063
|
+
if (combined.includes("pick") || combined.includes("grab") || combined.includes("grasp")) {
|
|
1064
|
+
return "pick";
|
|
1065
|
+
}
|
|
1066
|
+
if (combined.includes("place") || combined.includes("drop") || combined.includes("release")) {
|
|
1067
|
+
return "place";
|
|
1068
|
+
}
|
|
1069
|
+
if (combined.includes("move") || combined.includes("transport") || combined.includes("transfer")) {
|
|
1070
|
+
return "move";
|
|
1071
|
+
}
|
|
1072
|
+
if (combined.includes("scan") || combined.includes("read") || combined.includes("identify")) {
|
|
1073
|
+
return "scan";
|
|
1074
|
+
}
|
|
1075
|
+
if (combined.includes("assemble") || combined.includes("attach") || combined.includes("mount")) {
|
|
1076
|
+
return "assemble";
|
|
1077
|
+
}
|
|
1078
|
+
return "generic";
|
|
1079
|
+
}
|
|
1080
|
+
};
|
|
1081
|
+
|
|
1082
|
+
// src/runtime/actors/human_agent.ts
|
|
1083
|
+
var import_uuid2 = require("uuid");
|
|
1084
|
+
|
|
1085
|
+
// src/runtime/persistence/db.ts
|
|
1086
|
+
var import_client = require("@prisma/client");
|
|
1087
|
+
var globalForPrisma = global;
|
|
1088
|
+
var db = globalForPrisma.prisma || new import_client.PrismaClient();
|
|
1089
|
+
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = db;
|
|
1090
|
+
|
|
1091
|
+
// src/runtime/services/task_service.ts
|
|
1092
|
+
var TaskService = class {
|
|
1093
|
+
/**
|
|
1094
|
+
* Map Prisma Task to Domain Task
|
|
1095
|
+
*/
|
|
1096
|
+
static mapToDomain(task) {
|
|
1097
|
+
return {
|
|
1098
|
+
...task,
|
|
1099
|
+
status: task.status,
|
|
1100
|
+
// Cast to enum
|
|
1101
|
+
priority: task.priority,
|
|
1102
|
+
// Cast to enum
|
|
1103
|
+
assignee_id: task.assignee_id || void 0,
|
|
1104
|
+
creator_id: task.creator_id || void 0,
|
|
1105
|
+
creator_type: task.creator_type || void 0,
|
|
1106
|
+
assigner_id: task.assigner_id || void 0,
|
|
1107
|
+
assigner_type: task.assigner_type || void 0,
|
|
1108
|
+
description: task.description || void 0,
|
|
1109
|
+
inputs: JSON.parse(task.inputs),
|
|
1110
|
+
outputs: task.outputs ? JSON.parse(task.outputs) : void 0,
|
|
1111
|
+
tags: task.tags ? JSON.parse(task.tags) : void 0,
|
|
1112
|
+
form_schema: task.form_schema ? JSON.parse(task.form_schema) : void 0,
|
|
1113
|
+
created_at: task.created_at.toISOString(),
|
|
1114
|
+
updated_at: task.updated_at.toISOString(),
|
|
1115
|
+
due_at: task.due_at?.toISOString(),
|
|
1116
|
+
completed_at: task.completed_at?.toISOString()
|
|
1117
|
+
};
|
|
1118
|
+
}
|
|
1119
|
+
/**
|
|
1120
|
+
* Create a new task
|
|
1121
|
+
*/
|
|
1122
|
+
static async create(data) {
|
|
1123
|
+
const task = await db.humanTask.create({
|
|
1124
|
+
data: {
|
|
1125
|
+
...data,
|
|
1126
|
+
inputs: JSON.stringify(data.inputs),
|
|
1127
|
+
outputs: data.outputs ? JSON.stringify(data.outputs) : void 0,
|
|
1128
|
+
tags: data.tags ? JSON.stringify(data.tags) : void 0,
|
|
1129
|
+
form_schema: data.form_schema ? JSON.stringify(data.form_schema) : void 0
|
|
1130
|
+
}
|
|
1131
|
+
});
|
|
1132
|
+
return this.mapToDomain(task);
|
|
1133
|
+
}
|
|
1134
|
+
/**
|
|
1135
|
+
* Get a task by ID
|
|
1136
|
+
*/
|
|
1137
|
+
static async get(id) {
|
|
1138
|
+
const task = await db.humanTask.findUnique({
|
|
1139
|
+
where: { id }
|
|
1140
|
+
});
|
|
1141
|
+
return task ? this.mapToDomain(task) : null;
|
|
1142
|
+
}
|
|
1143
|
+
/**
|
|
1144
|
+
* List tasks with optional filters
|
|
1145
|
+
*/
|
|
1146
|
+
static async list(filters) {
|
|
1147
|
+
const where = {};
|
|
1148
|
+
if (filters?.assignee_id) where.assignee_id = filters.assignee_id;
|
|
1149
|
+
if (filters?.role_id) where.role_id = filters.role_id;
|
|
1150
|
+
if (filters?.status) where.status = filters.status;
|
|
1151
|
+
if (filters?.workflow_id) where.workflow_id = filters.workflow_id;
|
|
1152
|
+
const tasks = await db.humanTask.findMany({
|
|
1153
|
+
where,
|
|
1154
|
+
orderBy: { created_at: "desc" }
|
|
1155
|
+
});
|
|
1156
|
+
return tasks.map(this.mapToDomain);
|
|
1157
|
+
}
|
|
1158
|
+
/**
|
|
1159
|
+
* Assign a task
|
|
1160
|
+
*/
|
|
1161
|
+
static async assign(id, assignee_id, assigner_id, assigner_type) {
|
|
1162
|
+
const task = await db.humanTask.update({
|
|
1163
|
+
where: { id },
|
|
1164
|
+
data: {
|
|
1165
|
+
assignee_id,
|
|
1166
|
+
assigner_id,
|
|
1167
|
+
assigner_type,
|
|
1168
|
+
status: "assigned",
|
|
1169
|
+
updated_at: /* @__PURE__ */ new Date()
|
|
1170
|
+
}
|
|
1171
|
+
});
|
|
1172
|
+
return this.mapToDomain(task);
|
|
1173
|
+
}
|
|
1174
|
+
/**
|
|
1175
|
+
* Start a task
|
|
1176
|
+
*/
|
|
1177
|
+
static async start(id) {
|
|
1178
|
+
const task = await db.humanTask.update({
|
|
1179
|
+
where: { id },
|
|
1180
|
+
data: {
|
|
1181
|
+
status: "in_progress",
|
|
1182
|
+
updated_at: /* @__PURE__ */ new Date()
|
|
1183
|
+
}
|
|
1184
|
+
});
|
|
1185
|
+
return this.mapToDomain(task);
|
|
1186
|
+
}
|
|
1187
|
+
/**
|
|
1188
|
+
* Complete a task
|
|
1189
|
+
*/
|
|
1190
|
+
static async complete(id, outputs) {
|
|
1191
|
+
const task = await db.humanTask.update({
|
|
1192
|
+
where: { id },
|
|
1193
|
+
data: {
|
|
1194
|
+
status: "completed",
|
|
1195
|
+
outputs: JSON.stringify(outputs),
|
|
1196
|
+
completed_at: /* @__PURE__ */ new Date(),
|
|
1197
|
+
updated_at: /* @__PURE__ */ new Date()
|
|
1198
|
+
}
|
|
1199
|
+
});
|
|
1200
|
+
return this.mapToDomain(task);
|
|
1201
|
+
}
|
|
1202
|
+
/**
|
|
1203
|
+
* Reject a task
|
|
1204
|
+
*/
|
|
1205
|
+
static async reject(id, reason) {
|
|
1206
|
+
const task = await db.humanTask.update({
|
|
1207
|
+
where: { id },
|
|
1208
|
+
data: {
|
|
1209
|
+
status: "rejected",
|
|
1210
|
+
outputs: reason ? JSON.stringify({ rejection_reason: reason }) : void 0,
|
|
1211
|
+
updated_at: /* @__PURE__ */ new Date()
|
|
1212
|
+
}
|
|
1213
|
+
});
|
|
1214
|
+
return this.mapToDomain(task);
|
|
1215
|
+
}
|
|
1216
|
+
/**
|
|
1217
|
+
* Get pending tasks by role (Sorted by Priority)
|
|
1218
|
+
*/
|
|
1219
|
+
static async get_pending_by_role(role_id) {
|
|
1220
|
+
const tasks = await db.humanTask.findMany({
|
|
1221
|
+
where: {
|
|
1222
|
+
role_id,
|
|
1223
|
+
status: "pending"
|
|
1224
|
+
}
|
|
1225
|
+
});
|
|
1226
|
+
const priorityOrder = {
|
|
1227
|
+
"critical": 0,
|
|
1228
|
+
"high": 1,
|
|
1229
|
+
"normal": 2,
|
|
1230
|
+
"low": 3
|
|
1231
|
+
};
|
|
1232
|
+
const sortedTasks = tasks.sort((a, b) => {
|
|
1233
|
+
const pA = priorityOrder[a.priority] ?? 2;
|
|
1234
|
+
const pB = priorityOrder[b.priority] ?? 2;
|
|
1235
|
+
if (pA !== pB) return pA - pB;
|
|
1236
|
+
return a.created_at.getTime() - b.created_at.getTime();
|
|
1237
|
+
});
|
|
1238
|
+
return sortedTasks.map(this.mapToDomain);
|
|
1239
|
+
}
|
|
1240
|
+
};
|
|
1241
|
+
|
|
1242
|
+
// src/runtime/actors/human_agent.ts
|
|
1243
|
+
var HumanAgent = class {
|
|
1244
|
+
wait_for_completion;
|
|
1245
|
+
default_priority;
|
|
1246
|
+
constructor(options = {}) {
|
|
1247
|
+
this.wait_for_completion = options.wait_for_completion ?? false;
|
|
1248
|
+
this.default_priority = options.default_priority ?? "normal";
|
|
1249
|
+
}
|
|
1250
|
+
async execute(activity, inputs) {
|
|
1251
|
+
console.log(`[HumanAgent] Creating persistent task for activity: ${activity.name} (${activity.id})`);
|
|
1252
|
+
const token_id = inputs._token_id || (0, import_uuid2.v4)();
|
|
1253
|
+
const workflow_id = inputs._workflow_id || (0, import_uuid2.v4)();
|
|
1254
|
+
let priority = this.default_priority;
|
|
1255
|
+
if (activity.sla?.escalation_policy) {
|
|
1256
|
+
priority = "high";
|
|
1257
|
+
}
|
|
1258
|
+
const task = await TaskService.create({
|
|
1259
|
+
activity_id: activity.id,
|
|
1260
|
+
activity_name: activity.name,
|
|
1261
|
+
token_id,
|
|
1262
|
+
workflow_id,
|
|
1263
|
+
priority,
|
|
1264
|
+
role_id: activity.role_id || "user",
|
|
1265
|
+
// Ensure role_id exists
|
|
1266
|
+
creator_id: inputs._last_actor_id || "system",
|
|
1267
|
+
creator_type: inputs._last_actor_type || "application",
|
|
1268
|
+
inputs,
|
|
1269
|
+
description: activity.description,
|
|
1270
|
+
due_at: this.calculate_due_date(activity) ? new Date(this.calculate_due_date(activity)) : void 0,
|
|
1271
|
+
tags: []
|
|
1272
|
+
});
|
|
1273
|
+
console.log(`[HumanAgent] Task created in DB: ${task.id}`);
|
|
1274
|
+
if (this.wait_for_completion) {
|
|
1275
|
+
console.log(`[HumanAgent] Waiting for task ${task.id} completion...`);
|
|
1276
|
+
const completed_task = await this.wait_for_task_completion(task.id);
|
|
1277
|
+
if (completed_task.status === "rejected") {
|
|
1278
|
+
const outputs2 = completed_task.outputs ? JSON.parse(completed_task.outputs) : {};
|
|
1279
|
+
throw new Error(`Human task rejected: ${outputs2.rejection_reason || "No reason provided"}`);
|
|
1280
|
+
}
|
|
1281
|
+
const outputs = completed_task.outputs ? JSON.parse(completed_task.outputs) : {};
|
|
1282
|
+
return {
|
|
1283
|
+
...inputs,
|
|
1284
|
+
...outputs,
|
|
1285
|
+
_human_task_id: task.id,
|
|
1286
|
+
_human_task_status: "completed"
|
|
1287
|
+
};
|
|
1288
|
+
}
|
|
1289
|
+
return {
|
|
1290
|
+
...inputs,
|
|
1291
|
+
_human_task_id: task.id,
|
|
1292
|
+
_human_task_status: "pending",
|
|
1293
|
+
_requires_human_action: true
|
|
1294
|
+
};
|
|
1295
|
+
}
|
|
1296
|
+
/**
|
|
1297
|
+
* Poll for task completion
|
|
1298
|
+
*/
|
|
1299
|
+
async wait_for_task_completion(task_id) {
|
|
1300
|
+
return new Promise((resolve) => {
|
|
1301
|
+
const check = async () => {
|
|
1302
|
+
const task = await TaskService.get(task_id);
|
|
1303
|
+
if (task && (task.status === "completed" || task.status === "rejected")) {
|
|
1304
|
+
resolve(task);
|
|
1305
|
+
} else {
|
|
1306
|
+
setTimeout(check, 2e3);
|
|
1307
|
+
}
|
|
1308
|
+
};
|
|
1309
|
+
check();
|
|
1310
|
+
});
|
|
1311
|
+
}
|
|
1312
|
+
/**
|
|
1313
|
+
* Calculate due date from activity SLA
|
|
1314
|
+
*/
|
|
1315
|
+
calculate_due_date(activity) {
|
|
1316
|
+
if (!activity.sla?.max_time) {
|
|
1317
|
+
return void 0;
|
|
1318
|
+
}
|
|
1319
|
+
const duration = activity.sla.max_time;
|
|
1320
|
+
const match = duration.match(/PT?(\d+)([HMSD])/);
|
|
1321
|
+
if (!match) return void 0;
|
|
1322
|
+
const [, value, unit] = match;
|
|
1323
|
+
const ms_multipliers = {
|
|
1324
|
+
"S": 1e3,
|
|
1325
|
+
"M": 60 * 1e3,
|
|
1326
|
+
"H": 60 * 60 * 1e3,
|
|
1327
|
+
"D": 24 * 60 * 60 * 1e3
|
|
1328
|
+
};
|
|
1329
|
+
const offset_ms = parseInt(value) * (ms_multipliers[unit] || 0);
|
|
1330
|
+
return new Date(Date.now() + offset_ms).toISOString();
|
|
1331
|
+
}
|
|
1332
|
+
};
|
|
1333
|
+
|
|
1334
|
+
// src/runtime/decision_evaluator.ts
|
|
1335
|
+
function evaluate_feel_expression(expression, value) {
|
|
1336
|
+
const expr = expression.trim();
|
|
1337
|
+
if (expr === "" || expr === "-" || expr === "*") {
|
|
1338
|
+
return true;
|
|
1339
|
+
}
|
|
1340
|
+
if (expr === "true") return value === true;
|
|
1341
|
+
if (expr === "false") return value === false;
|
|
1342
|
+
if (expr === "null") return value === null || value === void 0;
|
|
1343
|
+
if (expr === "not null") return value !== null && value !== void 0;
|
|
1344
|
+
if (expr.startsWith('"') && expr.endsWith('"') || expr.startsWith("'") && expr.endsWith("'")) {
|
|
1345
|
+
const literal = expr.slice(1, -1);
|
|
1346
|
+
return String(value) === literal;
|
|
1347
|
+
}
|
|
1348
|
+
const range_match = expr.match(/^([\[\(])([^.]+)\.\.([^.\])]+)([\]\)])$/);
|
|
1349
|
+
if (range_match) {
|
|
1350
|
+
const [, start_bracket, start_val, end_val, end_bracket] = range_match;
|
|
1351
|
+
const num_value = Number(value);
|
|
1352
|
+
const start_num = Number(start_val);
|
|
1353
|
+
const end_num = Number(end_val);
|
|
1354
|
+
if (isNaN(num_value)) return false;
|
|
1355
|
+
const start_inclusive = start_bracket === "[";
|
|
1356
|
+
const end_inclusive = end_bracket === "]";
|
|
1357
|
+
const above_start = start_inclusive ? num_value >= start_num : num_value > start_num;
|
|
1358
|
+
const below_end = end_inclusive ? num_value <= end_num : num_value < end_num;
|
|
1359
|
+
return above_start && below_end;
|
|
1360
|
+
}
|
|
1361
|
+
if (expr.startsWith(">=")) {
|
|
1362
|
+
return Number(value) >= Number(expr.slice(2).trim());
|
|
1363
|
+
}
|
|
1364
|
+
if (expr.startsWith("<=")) {
|
|
1365
|
+
return Number(value) <= Number(expr.slice(2).trim());
|
|
1366
|
+
}
|
|
1367
|
+
if (expr.startsWith("!=") || expr.startsWith("<>")) {
|
|
1368
|
+
const compare_val = expr.slice(2).trim();
|
|
1369
|
+
return String(value) !== compare_val && Number(value) !== Number(compare_val);
|
|
1370
|
+
}
|
|
1371
|
+
if (expr.startsWith("==")) {
|
|
1372
|
+
const compare_val = expr.slice(2).trim();
|
|
1373
|
+
return String(value) === compare_val || Number(value) === Number(compare_val);
|
|
1374
|
+
}
|
|
1375
|
+
if (expr.startsWith(">")) {
|
|
1376
|
+
return Number(value) > Number(expr.slice(1).trim());
|
|
1377
|
+
}
|
|
1378
|
+
if (expr.startsWith("<")) {
|
|
1379
|
+
return Number(value) < Number(expr.slice(1).trim());
|
|
1380
|
+
}
|
|
1381
|
+
if (expr.startsWith("=")) {
|
|
1382
|
+
const compare_val = expr.slice(1).trim();
|
|
1383
|
+
return String(value) === compare_val || Number(value) === Number(compare_val);
|
|
1384
|
+
}
|
|
1385
|
+
if (expr.toLowerCase().startsWith("in ") || expr.startsWith("in(")) {
|
|
1386
|
+
const list_match = expr.match(/in\s*\(([^)]+)\)/i);
|
|
1387
|
+
if (list_match) {
|
|
1388
|
+
const items = list_match[1].split(",").map((s) => s.trim().replace(/^["']|["']$/g, ""));
|
|
1389
|
+
return items.includes(String(value));
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
if (expr.toLowerCase().startsWith("not in ") || expr.toLowerCase().startsWith("not in(")) {
|
|
1393
|
+
const list_match = expr.match(/not\s+in\s*\(([^)]+)\)/i);
|
|
1394
|
+
if (list_match) {
|
|
1395
|
+
const items = list_match[1].split(",").map((s) => s.trim().replace(/^["']|["']$/g, ""));
|
|
1396
|
+
return !items.includes(String(value));
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
if (expr.toLowerCase().startsWith("contains(")) {
|
|
1400
|
+
const match = expr.match(/contains\s*\(\s*["']([^"']+)["']\s*\)/i);
|
|
1401
|
+
if (match) {
|
|
1402
|
+
return String(value).includes(match[1]);
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
if (expr.toLowerCase().startsWith("starts with ")) {
|
|
1406
|
+
const pattern = expr.slice(12).trim().replace(/^["']|["']$/g, "");
|
|
1407
|
+
return String(value).startsWith(pattern);
|
|
1408
|
+
}
|
|
1409
|
+
if (expr.toLowerCase().startsWith("ends with ")) {
|
|
1410
|
+
const pattern = expr.slice(10).trim().replace(/^["']|["']$/g, "");
|
|
1411
|
+
return String(value).endsWith(pattern);
|
|
1412
|
+
}
|
|
1413
|
+
if (expr.toLowerCase().startsWith("matches(")) {
|
|
1414
|
+
const match = expr.match(/matches\s*\(\s*["']([^"']+)["']\s*\)/i);
|
|
1415
|
+
if (match) {
|
|
1416
|
+
try {
|
|
1417
|
+
const regex = new RegExp(match[1]);
|
|
1418
|
+
return regex.test(String(value));
|
|
1419
|
+
} catch {
|
|
1420
|
+
return false;
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
const num_expr = Number(expr);
|
|
1425
|
+
if (!isNaN(num_expr)) {
|
|
1426
|
+
return Number(value) === num_expr;
|
|
1427
|
+
}
|
|
1428
|
+
return String(value) === expr;
|
|
1429
|
+
}
|
|
1430
|
+
function evaluate_rule(rule, table, context) {
|
|
1431
|
+
for (let i = 0; i < table.inputs.length; i++) {
|
|
1432
|
+
const input_col = table.inputs[i];
|
|
1433
|
+
const expression = rule.input_entries[i] || "-";
|
|
1434
|
+
const value = context[input_col.name];
|
|
1435
|
+
if (!evaluate_feel_expression(expression, value)) {
|
|
1436
|
+
return false;
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
return true;
|
|
1440
|
+
}
|
|
1441
|
+
function extract_outputs(rule, table) {
|
|
1442
|
+
const outputs = {};
|
|
1443
|
+
for (let i = 0; i < table.outputs.length; i++) {
|
|
1444
|
+
const output_col = table.outputs[i];
|
|
1445
|
+
outputs[output_col.name] = rule.output_entries[i];
|
|
1446
|
+
}
|
|
1447
|
+
return outputs;
|
|
1448
|
+
}
|
|
1449
|
+
function evaluate_decision(node, context) {
|
|
1450
|
+
const table = node.decision_table;
|
|
1451
|
+
const matched_rules = [];
|
|
1452
|
+
for (const rule of table.rules) {
|
|
1453
|
+
if (evaluate_rule(rule, table, context)) {
|
|
1454
|
+
matched_rules.push(rule);
|
|
1455
|
+
if (table.hit_policy === "first" || table.hit_policy === "unique") {
|
|
1456
|
+
break;
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1460
|
+
if (matched_rules.length === 0) {
|
|
1461
|
+
return {
|
|
1462
|
+
matched: false,
|
|
1463
|
+
output_edge_id: node.default_output_edge_id,
|
|
1464
|
+
outputs: {},
|
|
1465
|
+
matched_rules: []
|
|
1466
|
+
};
|
|
1467
|
+
}
|
|
1468
|
+
let result_outputs = {};
|
|
1469
|
+
let result_edge_id;
|
|
1470
|
+
switch (table.hit_policy) {
|
|
1471
|
+
case "unique":
|
|
1472
|
+
case "first":
|
|
1473
|
+
result_outputs = extract_outputs(matched_rules[0], table);
|
|
1474
|
+
result_edge_id = matched_rules[0].output_edge_id;
|
|
1475
|
+
break;
|
|
1476
|
+
case "any":
|
|
1477
|
+
result_outputs = extract_outputs(matched_rules[0], table);
|
|
1478
|
+
result_edge_id = matched_rules[0].output_edge_id;
|
|
1479
|
+
break;
|
|
1480
|
+
case "priority":
|
|
1481
|
+
result_outputs = extract_outputs(matched_rules[0], table);
|
|
1482
|
+
result_edge_id = matched_rules[0].output_edge_id;
|
|
1483
|
+
break;
|
|
1484
|
+
case "collect":
|
|
1485
|
+
for (const output_col of table.outputs) {
|
|
1486
|
+
result_outputs[output_col.name] = matched_rules.map(
|
|
1487
|
+
(r) => r.output_entries[table.outputs.indexOf(output_col)]
|
|
1488
|
+
);
|
|
1489
|
+
}
|
|
1490
|
+
result_edge_id = matched_rules[0].output_edge_id;
|
|
1491
|
+
break;
|
|
1492
|
+
case "rule_order":
|
|
1493
|
+
for (const output_col of table.outputs) {
|
|
1494
|
+
result_outputs[output_col.name] = matched_rules.map(
|
|
1495
|
+
(r) => r.output_entries[table.outputs.indexOf(output_col)]
|
|
1496
|
+
);
|
|
1497
|
+
}
|
|
1498
|
+
result_edge_id = matched_rules[0].output_edge_id;
|
|
1499
|
+
break;
|
|
1500
|
+
default:
|
|
1501
|
+
result_outputs = extract_outputs(matched_rules[0], table);
|
|
1502
|
+
result_edge_id = matched_rules[0].output_edge_id;
|
|
1503
|
+
}
|
|
1504
|
+
return {
|
|
1505
|
+
matched: true,
|
|
1506
|
+
output_edge_id: result_edge_id || node.default_output_edge_id,
|
|
1507
|
+
outputs: result_outputs,
|
|
1508
|
+
matched_rules
|
|
1509
|
+
};
|
|
1510
|
+
}
|
|
1511
|
+
var DecisionEvaluator = class {
|
|
1512
|
+
decision_nodes = /* @__PURE__ */ new Map();
|
|
1513
|
+
constructor(nodes) {
|
|
1514
|
+
if (nodes) {
|
|
1515
|
+
for (const node of nodes) {
|
|
1516
|
+
this.register(node);
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
/**
|
|
1521
|
+
* Register a decision node
|
|
1522
|
+
*/
|
|
1523
|
+
register(node) {
|
|
1524
|
+
this.decision_nodes.set(node.id, node);
|
|
1525
|
+
}
|
|
1526
|
+
/**
|
|
1527
|
+
* Get a decision node by ID
|
|
1528
|
+
*/
|
|
1529
|
+
get(node_id) {
|
|
1530
|
+
return this.decision_nodes.get(node_id);
|
|
1531
|
+
}
|
|
1532
|
+
/**
|
|
1533
|
+
* Evaluate a decision node by ID
|
|
1534
|
+
*/
|
|
1535
|
+
evaluate(node_id, context) {
|
|
1536
|
+
const node = this.decision_nodes.get(node_id);
|
|
1537
|
+
if (!node) {
|
|
1538
|
+
throw new Error(`Decision node not found: ${node_id}`);
|
|
1539
|
+
}
|
|
1540
|
+
return evaluate_decision(node, context);
|
|
1541
|
+
}
|
|
1542
|
+
/**
|
|
1543
|
+
* Get the next edge ID for a decision node given a context
|
|
1544
|
+
*/
|
|
1545
|
+
get_next_edge(node_id, context) {
|
|
1546
|
+
return this.evaluate(node_id, context).output_edge_id;
|
|
1547
|
+
}
|
|
1548
|
+
};
|
|
1549
|
+
|
|
1550
|
+
// src/runtime/duration_utils.ts
|
|
1551
|
+
function format_iso_duration(ms) {
|
|
1552
|
+
if (ms < 0) ms = 0;
|
|
1553
|
+
const seconds = ms / 1e3 % 60;
|
|
1554
|
+
const minutes = Math.floor(ms / (1e3 * 60) % 60);
|
|
1555
|
+
const hours = Math.floor(ms / (1e3 * 60 * 60) % 24);
|
|
1556
|
+
const days = Math.floor(ms / (1e3 * 60 * 60 * 24));
|
|
1557
|
+
let result = "P";
|
|
1558
|
+
if (days > 0) result += `${days}D`;
|
|
1559
|
+
result += "T";
|
|
1560
|
+
if (hours > 0) result += `${hours}H`;
|
|
1561
|
+
if (minutes > 0) result += `${minutes}M`;
|
|
1562
|
+
if (seconds > 0 || result === "PT") {
|
|
1563
|
+
result += `${seconds.toFixed(1)}S`;
|
|
1564
|
+
}
|
|
1565
|
+
return result;
|
|
1566
|
+
}
|
|
1567
|
+
function calculate_duration(start, end = /* @__PURE__ */ new Date()) {
|
|
1568
|
+
return format_iso_duration(end.getTime() - start.getTime());
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1571
|
+
// src/runtime/workflow_engine.ts
|
|
1572
|
+
var WorkflowEngine = class {
|
|
1573
|
+
workflow;
|
|
1574
|
+
tokens;
|
|
1575
|
+
contextManager;
|
|
1576
|
+
status;
|
|
1577
|
+
activityMap;
|
|
1578
|
+
edgeMap;
|
|
1579
|
+
// Source ID -> Edges
|
|
1580
|
+
decisionNodeMap;
|
|
1581
|
+
options;
|
|
1582
|
+
roleMap;
|
|
1583
|
+
decisionEvaluator;
|
|
1584
|
+
constructor(workflowDef, options = {}) {
|
|
1585
|
+
const validation = validate_workflow_integrity(workflowDef);
|
|
1586
|
+
if (!validation.valid) {
|
|
1587
|
+
throw new Error(`Invalid workflow definition: ${validation.errors.map((e) => e.message).join(", ")}`);
|
|
1588
|
+
}
|
|
1589
|
+
this.workflow = workflowDef;
|
|
1590
|
+
this.options = {
|
|
1591
|
+
...options,
|
|
1592
|
+
// Support legacy option name
|
|
1593
|
+
gemini_api_key: options.gemini_api_key || options.geminiApiKey
|
|
1594
|
+
};
|
|
1595
|
+
this.tokens = [];
|
|
1596
|
+
this.contextManager = new ContextManager();
|
|
1597
|
+
this.status = "idle";
|
|
1598
|
+
this.activityMap = /* @__PURE__ */ new Map();
|
|
1599
|
+
this.edgeMap = /* @__PURE__ */ new Map();
|
|
1600
|
+
this.decisionNodeMap = /* @__PURE__ */ new Map();
|
|
1601
|
+
this.roleMap = /* @__PURE__ */ new Map();
|
|
1602
|
+
this.decisionEvaluator = new DecisionEvaluator(workflowDef.decision_nodes);
|
|
1603
|
+
this.initializeMaps();
|
|
1604
|
+
this.initializeContexts();
|
|
1605
|
+
}
|
|
1606
|
+
initializeMaps() {
|
|
1607
|
+
for (const activity of this.workflow.activities) {
|
|
1608
|
+
this.activityMap.set(activity.id, activity);
|
|
1609
|
+
}
|
|
1610
|
+
for (const edge of this.workflow.edges) {
|
|
1611
|
+
if (!this.edgeMap.has(edge.source_id)) {
|
|
1612
|
+
this.edgeMap.set(edge.source_id, []);
|
|
1613
|
+
}
|
|
1614
|
+
this.edgeMap.get(edge.source_id)?.push(edge);
|
|
1615
|
+
}
|
|
1616
|
+
for (const decisionNode of this.workflow.decision_nodes) {
|
|
1617
|
+
this.decisionNodeMap.set(decisionNode.id, decisionNode);
|
|
1618
|
+
}
|
|
1619
|
+
if (this.options.roles) {
|
|
1620
|
+
for (const role of this.options.roles) {
|
|
1621
|
+
this.roleMap.set(role.id, role);
|
|
1622
|
+
}
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1625
|
+
initializeContexts() {
|
|
1626
|
+
for (const context of this.workflow.contexts) {
|
|
1627
|
+
this.contextManager.register(context);
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
log(message) {
|
|
1631
|
+
if (this.options.verbose) {
|
|
1632
|
+
console.log(`[WorkflowEngine] ${message}`);
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1635
|
+
async start(initialData = {}) {
|
|
1636
|
+
if (this.status === "running") {
|
|
1637
|
+
throw new Error("Workflow is already running");
|
|
1638
|
+
}
|
|
1639
|
+
if (this.workflow.activities.length === 0) {
|
|
1640
|
+
throw new Error("Workflow has no activities");
|
|
1641
|
+
}
|
|
1642
|
+
let startNodeId;
|
|
1643
|
+
const targetIds = new Set(this.workflow.edges.map((e) => e.target_id));
|
|
1644
|
+
const startActivities = this.workflow.activities.filter((a) => !targetIds.has(a.id));
|
|
1645
|
+
if (startActivities.length > 0) {
|
|
1646
|
+
startNodeId = startActivities[0].id;
|
|
1647
|
+
} else {
|
|
1648
|
+
startNodeId = this.workflow.activities[0].id;
|
|
1649
|
+
}
|
|
1650
|
+
const tokenData = {
|
|
1651
|
+
...initialData,
|
|
1652
|
+
_workflow_id: this.workflow.id,
|
|
1653
|
+
_workflow_name: this.workflow.name,
|
|
1654
|
+
_started_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1655
|
+
};
|
|
1656
|
+
const token = new Token(startNodeId, tokenData, void 0, this.workflow.id);
|
|
1657
|
+
this.tokens.push(token);
|
|
1658
|
+
this.status = "running";
|
|
1659
|
+
this.log(`Started workflow "${this.workflow.name}" with token ${token.id}`);
|
|
1660
|
+
return token.id;
|
|
1661
|
+
}
|
|
1662
|
+
async runStep() {
|
|
1663
|
+
if (this.status !== "running" && this.status !== "waiting_human") return;
|
|
1664
|
+
const activeTokens = this.tokens.filter((t) => t.status === "active");
|
|
1665
|
+
if (activeTokens.length === 0) {
|
|
1666
|
+
const waitingTokens = this.tokens.filter((t) => t.status === "waiting");
|
|
1667
|
+
if (waitingTokens.length > 0) {
|
|
1668
|
+
this.status = "waiting_human";
|
|
1669
|
+
return;
|
|
1670
|
+
}
|
|
1671
|
+
this.status = "completed";
|
|
1672
|
+
return;
|
|
1673
|
+
}
|
|
1674
|
+
for (const token of activeTokens) {
|
|
1675
|
+
await this.processToken(token);
|
|
1676
|
+
}
|
|
1677
|
+
const allDone = this.tokens.every(
|
|
1678
|
+
(t) => t.status === "completed" || t.status === "failed" || t.status === "cancelled"
|
|
1679
|
+
);
|
|
1680
|
+
if (allDone) {
|
|
1681
|
+
this.status = "completed";
|
|
1682
|
+
}
|
|
1683
|
+
}
|
|
1684
|
+
/**
|
|
1685
|
+
* Run workflow to completion (or until paused/failed)
|
|
1686
|
+
*/
|
|
1687
|
+
async run(maxSteps = 1e3) {
|
|
1688
|
+
let steps = 0;
|
|
1689
|
+
while (this.status === "running" && steps < maxSteps) {
|
|
1690
|
+
await this.runStep();
|
|
1691
|
+
steps++;
|
|
1692
|
+
}
|
|
1693
|
+
this.log(`Workflow completed after ${steps} steps with status: ${this.status}`);
|
|
1694
|
+
return this.status;
|
|
1695
|
+
}
|
|
1696
|
+
async processToken(token) {
|
|
1697
|
+
const currentNodeId = token.activityId;
|
|
1698
|
+
const decisionNode = this.decisionNodeMap.get(currentNodeId);
|
|
1699
|
+
if (decisionNode) {
|
|
1700
|
+
await this.processDecisionNode(token, decisionNode);
|
|
1701
|
+
return;
|
|
1702
|
+
}
|
|
1703
|
+
const activity = this.activityMap.get(currentNodeId);
|
|
1704
|
+
if (!activity) {
|
|
1705
|
+
this.log(`Activity not found: ${currentNodeId}`);
|
|
1706
|
+
token.updateStatus("failed");
|
|
1707
|
+
return;
|
|
1708
|
+
}
|
|
1709
|
+
const startTime = /* @__PURE__ */ new Date();
|
|
1710
|
+
try {
|
|
1711
|
+
const actor = this.createActor(activity);
|
|
1712
|
+
if (actor) {
|
|
1713
|
+
const inputs = {
|
|
1714
|
+
...token.contextData,
|
|
1715
|
+
_token_id: token.id,
|
|
1716
|
+
_workflow_id: this.workflow.id,
|
|
1717
|
+
_activity_id: activity.id,
|
|
1718
|
+
_activity_name: activity.name
|
|
1719
|
+
};
|
|
1720
|
+
this.log(`Executing activity "${activity.name}" with ${activity.actor_type} actor`);
|
|
1721
|
+
const output = await actor.execute(activity, inputs);
|
|
1722
|
+
const endTime = /* @__PURE__ */ new Date();
|
|
1723
|
+
const processTime = calculate_duration(startTime, endTime);
|
|
1724
|
+
const analytics = {
|
|
1725
|
+
process_time: processTime,
|
|
1726
|
+
cycle_time: processTime,
|
|
1727
|
+
lead_time: processTime,
|
|
1728
|
+
value_added: activity.analytics?.value_added ?? true,
|
|
1729
|
+
waste_categories: []
|
|
1730
|
+
};
|
|
1731
|
+
if (output._requires_human_action && this.options.wait_for_human_tasks) {
|
|
1732
|
+
analytics.waste_categories?.push("waiting");
|
|
1733
|
+
token.updateStatus("waiting", analytics);
|
|
1734
|
+
token.mergeData({
|
|
1735
|
+
...output,
|
|
1736
|
+
_waiting_since: endTime.toISOString()
|
|
1737
|
+
});
|
|
1738
|
+
this.log(`Token paused waiting for human task ${output._human_task_id}`);
|
|
1739
|
+
return;
|
|
1740
|
+
}
|
|
1741
|
+
token.mergeData({
|
|
1742
|
+
...output,
|
|
1743
|
+
_last_actor_id: activity.id,
|
|
1744
|
+
_last_actor_type: activity.actor_type
|
|
1745
|
+
});
|
|
1746
|
+
await this.advanceToken(token, currentNodeId, analytics);
|
|
1747
|
+
} else {
|
|
1748
|
+
await this.advanceToken(token, currentNodeId);
|
|
1749
|
+
}
|
|
1750
|
+
} catch (error) {
|
|
1751
|
+
const endTime = /* @__PURE__ */ new Date();
|
|
1752
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1753
|
+
const errorStack = error instanceof Error ? error.stack : void 0;
|
|
1754
|
+
console.error(`Error processing activity ${activity.name}:`, error);
|
|
1755
|
+
const analytics = {
|
|
1756
|
+
process_time: calculate_duration(startTime, endTime),
|
|
1757
|
+
waste_categories: ["defects"],
|
|
1758
|
+
error_rate: 1
|
|
1759
|
+
};
|
|
1760
|
+
token.updateStatus("failed", analytics);
|
|
1761
|
+
token.mergeData({ _error: errorMessage, _stack: errorStack });
|
|
1762
|
+
}
|
|
1763
|
+
}
|
|
1764
|
+
/**
|
|
1765
|
+
* Process a decision node
|
|
1766
|
+
*/
|
|
1767
|
+
async processDecisionNode(token, decision) {
|
|
1768
|
+
this.log(`Evaluating decision node "${decision.name}"`);
|
|
1769
|
+
const result = evaluate_decision(decision, token.contextData);
|
|
1770
|
+
this.log(`Decision result: matched=${result.matched}, outputs=${JSON.stringify(result.outputs)}`);
|
|
1771
|
+
token.mergeData({
|
|
1772
|
+
_decision_node_id: decision.id,
|
|
1773
|
+
_decision_matched: result.matched,
|
|
1774
|
+
_decision_outputs: result.outputs
|
|
1775
|
+
});
|
|
1776
|
+
if (result.output_edge_id) {
|
|
1777
|
+
token.move(this.getEdgeTarget(result.output_edge_id) || result.output_edge_id);
|
|
1778
|
+
} else {
|
|
1779
|
+
if (decision.default_output_edge_id) {
|
|
1780
|
+
token.move(this.getEdgeTarget(decision.default_output_edge_id) || decision.default_output_edge_id);
|
|
1781
|
+
} else {
|
|
1782
|
+
this.log(`No matching rule and no default edge for decision "${decision.name}"`);
|
|
1783
|
+
token.updateStatus("failed");
|
|
1784
|
+
token.mergeData({ _error: "No matching decision rule and no default path" });
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
/**
|
|
1789
|
+
* Get the target node ID for an edge ID
|
|
1790
|
+
*/
|
|
1791
|
+
getEdgeTarget(edgeId) {
|
|
1792
|
+
for (const edge of this.workflow.edges) {
|
|
1793
|
+
if (edge.id === edgeId) {
|
|
1794
|
+
return edge.target_id;
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
return void 0;
|
|
1798
|
+
}
|
|
1799
|
+
/**
|
|
1800
|
+
* Advance token to next node(s) based on outgoing edges
|
|
1801
|
+
*/
|
|
1802
|
+
async advanceToken(token, currentNodeId, analytics) {
|
|
1803
|
+
const outgoingEdges = this.edgeMap.get(currentNodeId) || [];
|
|
1804
|
+
if (outgoingEdges.length === 0) {
|
|
1805
|
+
token.updateStatus("completed", analytics);
|
|
1806
|
+
this.log(`Token ${token.id} completed (no outgoing edges)`);
|
|
1807
|
+
return;
|
|
1808
|
+
}
|
|
1809
|
+
const nextEdge = this.selectNextEdge(outgoingEdges, token.contextData);
|
|
1810
|
+
if (nextEdge) {
|
|
1811
|
+
token.move(nextEdge.target_id, analytics);
|
|
1812
|
+
this.log(`Token ${token.id} moved to ${nextEdge.target_id}`);
|
|
1813
|
+
} else {
|
|
1814
|
+
token.updateStatus("failed", analytics);
|
|
1815
|
+
token.mergeData({ _error: "No valid outgoing edge found" });
|
|
1816
|
+
}
|
|
1817
|
+
}
|
|
1818
|
+
/**
|
|
1819
|
+
* Select the next edge based on conditions
|
|
1820
|
+
*/
|
|
1821
|
+
selectNextEdge(edges, context) {
|
|
1822
|
+
for (const edge of edges) {
|
|
1823
|
+
if (edge.condition) {
|
|
1824
|
+
if (this.evaluateEdgeCondition(edge.condition, context)) {
|
|
1825
|
+
return edge;
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
const defaultEdge = edges.find((e) => e.is_default);
|
|
1830
|
+
if (defaultEdge) {
|
|
1831
|
+
return defaultEdge;
|
|
1832
|
+
}
|
|
1833
|
+
return edges[0];
|
|
1834
|
+
}
|
|
1835
|
+
/**
|
|
1836
|
+
* Evaluate a simple edge condition
|
|
1837
|
+
* Supports: property == value, property != value, property (truthy check)
|
|
1838
|
+
*/
|
|
1839
|
+
evaluateEdgeCondition(condition, context) {
|
|
1840
|
+
try {
|
|
1841
|
+
const eqMatch = condition.match(/^(\w+)\s*==\s*(.+)$/);
|
|
1842
|
+
if (eqMatch) {
|
|
1843
|
+
const [, prop, val] = eqMatch;
|
|
1844
|
+
const contextVal = context[prop];
|
|
1845
|
+
const compareVal = val.trim().replace(/^["']|["']$/g, "");
|
|
1846
|
+
return String(contextVal) === compareVal || contextVal === JSON.parse(val);
|
|
1847
|
+
}
|
|
1848
|
+
const neqMatch = condition.match(/^(\w+)\s*!=\s*(.+)$/);
|
|
1849
|
+
if (neqMatch) {
|
|
1850
|
+
const [, prop, val] = neqMatch;
|
|
1851
|
+
const contextVal = context[prop];
|
|
1852
|
+
const compareVal = val.trim().replace(/^["']|["']$/g, "");
|
|
1853
|
+
return String(contextVal) !== compareVal && contextVal !== JSON.parse(val);
|
|
1854
|
+
}
|
|
1855
|
+
const gtMatch = condition.match(/^(\w+)\s*>\s*(\d+(?:\.\d+)?)$/);
|
|
1856
|
+
if (gtMatch) {
|
|
1857
|
+
const [, prop, val] = gtMatch;
|
|
1858
|
+
return Number(context[prop]) > Number(val);
|
|
1859
|
+
}
|
|
1860
|
+
const ltMatch = condition.match(/^(\w+)\s*<\s*(\d+(?:\.\d+)?)$/);
|
|
1861
|
+
if (ltMatch) {
|
|
1862
|
+
const [, prop, val] = ltMatch;
|
|
1863
|
+
return Number(context[prop]) < Number(val);
|
|
1864
|
+
}
|
|
1865
|
+
if (/^\w+$/.test(condition)) {
|
|
1866
|
+
return Boolean(context[condition]);
|
|
1867
|
+
}
|
|
1868
|
+
return Boolean(context[condition]);
|
|
1869
|
+
} catch {
|
|
1870
|
+
return false;
|
|
1871
|
+
}
|
|
1872
|
+
}
|
|
1873
|
+
/**
|
|
1874
|
+
* Create the appropriate actor for an activity
|
|
1875
|
+
*/
|
|
1876
|
+
createActor(activity) {
|
|
1877
|
+
switch (activity.actor_type) {
|
|
1878
|
+
case "application":
|
|
1879
|
+
return new SoftwareAgent();
|
|
1880
|
+
case "ai_agent":
|
|
1881
|
+
if (!this.options.gemini_api_key) {
|
|
1882
|
+
throw new Error("Gemini API Key required for AI Agent. Set gemini_api_key in options.");
|
|
1883
|
+
}
|
|
1884
|
+
const role = this.roleMap.get(activity.role_id);
|
|
1885
|
+
return new AIAgent(this.options.gemini_api_key, role);
|
|
1886
|
+
case "robot":
|
|
1887
|
+
return new RobotAgent(this.options.robot_config);
|
|
1888
|
+
case "human":
|
|
1889
|
+
return new HumanAgent({
|
|
1890
|
+
wait_for_completion: false
|
|
1891
|
+
// Engine will handle waiting state
|
|
1892
|
+
});
|
|
1893
|
+
default:
|
|
1894
|
+
this.log(`Unknown actor type: ${activity.actor_type}`);
|
|
1895
|
+
return void 0;
|
|
1896
|
+
}
|
|
1897
|
+
}
|
|
1898
|
+
/**
|
|
1899
|
+
* Resume a token that was waiting for human input
|
|
1900
|
+
*/
|
|
1901
|
+
resumeToken(tokenId, output) {
|
|
1902
|
+
const token = this.tokens.find((t) => t.id === tokenId);
|
|
1903
|
+
if (!token || token.status !== "waiting") {
|
|
1904
|
+
return false;
|
|
1905
|
+
}
|
|
1906
|
+
const waitingSince = token.getData("_waiting_since");
|
|
1907
|
+
let analytics;
|
|
1908
|
+
if (waitingSince) {
|
|
1909
|
+
const waitTime = calculate_duration(new Date(waitingSince), /* @__PURE__ */ new Date());
|
|
1910
|
+
analytics = {
|
|
1911
|
+
wait_time: waitTime,
|
|
1912
|
+
waste_categories: ["waiting"]
|
|
1913
|
+
};
|
|
1914
|
+
}
|
|
1915
|
+
token.mergeData(output);
|
|
1916
|
+
token.updateStatus("active", analytics);
|
|
1917
|
+
if (this.status === "waiting_human") {
|
|
1918
|
+
this.status = "running";
|
|
1919
|
+
}
|
|
1920
|
+
return true;
|
|
1921
|
+
}
|
|
1922
|
+
getStatus() {
|
|
1923
|
+
return this.status;
|
|
1924
|
+
}
|
|
1925
|
+
getContext(contextId) {
|
|
1926
|
+
return this.contextManager.get(contextId);
|
|
1927
|
+
}
|
|
1928
|
+
getTokens() {
|
|
1929
|
+
return this.tokens;
|
|
1930
|
+
}
|
|
1931
|
+
getWorkflow() {
|
|
1932
|
+
return this.workflow;
|
|
1933
|
+
}
|
|
1934
|
+
};
|
|
1935
|
+
|
|
1936
|
+
// src/server/logger.ts
|
|
1937
|
+
var LOG_LEVEL_PRIORITY = {
|
|
1938
|
+
debug: 0,
|
|
1939
|
+
info: 1,
|
|
1940
|
+
warn: 2,
|
|
1941
|
+
error: 3
|
|
1942
|
+
};
|
|
1943
|
+
var LOG_LEVEL_COLORS = {
|
|
1944
|
+
debug: "\x1B[36m",
|
|
1945
|
+
// Cyan
|
|
1946
|
+
info: "\x1B[32m",
|
|
1947
|
+
// Green
|
|
1948
|
+
warn: "\x1B[33m",
|
|
1949
|
+
// Yellow
|
|
1950
|
+
error: "\x1B[31m"
|
|
1951
|
+
// Red
|
|
1952
|
+
};
|
|
1953
|
+
var RESET_COLOR = "\x1B[0m";
|
|
1954
|
+
var Logger = class _Logger {
|
|
1955
|
+
config;
|
|
1956
|
+
correlation_id;
|
|
1957
|
+
context = {};
|
|
1958
|
+
constructor(config = {}) {
|
|
1959
|
+
this.config = {
|
|
1960
|
+
level: config.level ?? "info",
|
|
1961
|
+
format: config.format ?? "json",
|
|
1962
|
+
timestamps: config.timestamps ?? true,
|
|
1963
|
+
output: config.output
|
|
1964
|
+
};
|
|
1965
|
+
}
|
|
1966
|
+
/**
|
|
1967
|
+
* Create a child logger with additional context
|
|
1968
|
+
*/
|
|
1969
|
+
child(context) {
|
|
1970
|
+
const child = new _Logger(this.config);
|
|
1971
|
+
child.context = { ...this.context, ...context };
|
|
1972
|
+
child.correlation_id = this.correlation_id;
|
|
1973
|
+
return child;
|
|
1974
|
+
}
|
|
1975
|
+
/**
|
|
1976
|
+
* Set correlation ID for request tracing
|
|
1977
|
+
*/
|
|
1978
|
+
set_correlation_id(id) {
|
|
1979
|
+
this.correlation_id = id;
|
|
1980
|
+
}
|
|
1981
|
+
/**
|
|
1982
|
+
* Get current correlation ID
|
|
1983
|
+
*/
|
|
1984
|
+
get_correlation_id() {
|
|
1985
|
+
return this.correlation_id;
|
|
1986
|
+
}
|
|
1987
|
+
/**
|
|
1988
|
+
* Generate new correlation ID
|
|
1989
|
+
*/
|
|
1990
|
+
generate_correlation_id() {
|
|
1991
|
+
this.correlation_id = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
1992
|
+
return this.correlation_id;
|
|
1993
|
+
}
|
|
1994
|
+
/**
|
|
1995
|
+
* Check if a log level should be output
|
|
1996
|
+
*/
|
|
1997
|
+
should_log(level) {
|
|
1998
|
+
return LOG_LEVEL_PRIORITY[level] >= LOG_LEVEL_PRIORITY[this.config.level];
|
|
1999
|
+
}
|
|
2000
|
+
/**
|
|
2001
|
+
* Format and output a log entry
|
|
2002
|
+
*/
|
|
2003
|
+
log(level, message, metadata) {
|
|
2004
|
+
if (!this.should_log(level)) return;
|
|
2005
|
+
const entry = {
|
|
2006
|
+
timestamp: this.config.timestamps ? (/* @__PURE__ */ new Date()).toISOString() : "",
|
|
2007
|
+
level,
|
|
2008
|
+
message,
|
|
2009
|
+
correlation_id: this.correlation_id,
|
|
2010
|
+
...this.context,
|
|
2011
|
+
metadata
|
|
2012
|
+
};
|
|
2013
|
+
if (this.config.output) {
|
|
2014
|
+
this.config.output(entry);
|
|
2015
|
+
return;
|
|
2016
|
+
}
|
|
2017
|
+
if (this.config.format === "json") {
|
|
2018
|
+
const clean_entry = Object.fromEntries(
|
|
2019
|
+
Object.entries(entry).filter(([_, v]) => v !== void 0 && v !== "")
|
|
2020
|
+
);
|
|
2021
|
+
console.log(JSON.stringify(clean_entry));
|
|
2022
|
+
} else {
|
|
2023
|
+
this.log_text(entry);
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
2026
|
+
/**
|
|
2027
|
+
* Human-readable text format
|
|
2028
|
+
*/
|
|
2029
|
+
log_text(entry) {
|
|
2030
|
+
const color = LOG_LEVEL_COLORS[entry.level];
|
|
2031
|
+
const parts = [];
|
|
2032
|
+
if (entry.timestamp) {
|
|
2033
|
+
parts.push(`[${entry.timestamp}]`);
|
|
2034
|
+
}
|
|
2035
|
+
parts.push(`${color}${entry.level.toUpperCase().padEnd(5)}${RESET_COLOR}`);
|
|
2036
|
+
if (entry.correlation_id) {
|
|
2037
|
+
parts.push(`[${entry.correlation_id}]`);
|
|
2038
|
+
}
|
|
2039
|
+
parts.push(entry.message);
|
|
2040
|
+
if (entry.metadata && Object.keys(entry.metadata).length > 0) {
|
|
2041
|
+
parts.push(JSON.stringify(entry.metadata));
|
|
2042
|
+
}
|
|
2043
|
+
console.log(parts.join(" "));
|
|
2044
|
+
if (entry.error?.stack) {
|
|
2045
|
+
console.log(entry.error.stack);
|
|
2046
|
+
}
|
|
2047
|
+
}
|
|
2048
|
+
// Log level methods
|
|
2049
|
+
debug(message, metadata) {
|
|
2050
|
+
this.log("debug", message, metadata);
|
|
2051
|
+
}
|
|
2052
|
+
info(message, metadata) {
|
|
2053
|
+
this.log("info", message, metadata);
|
|
2054
|
+
}
|
|
2055
|
+
warn(message, metadata) {
|
|
2056
|
+
this.log("warn", message, metadata);
|
|
2057
|
+
}
|
|
2058
|
+
error(message, error, metadata) {
|
|
2059
|
+
const error_info = error instanceof Error ? {
|
|
2060
|
+
message: error.message,
|
|
2061
|
+
stack: error.stack,
|
|
2062
|
+
code: error.code
|
|
2063
|
+
} : error ? { message: String(error) } : void 0;
|
|
2064
|
+
this.log("error", message, {
|
|
2065
|
+
...metadata,
|
|
2066
|
+
error: error_info
|
|
2067
|
+
});
|
|
2068
|
+
}
|
|
2069
|
+
/**
|
|
2070
|
+
* Log workflow event
|
|
2071
|
+
*/
|
|
2072
|
+
workflow(event, workflow_id, metadata) {
|
|
2073
|
+
this.info(`[Workflow] ${event}`, { workflow_id, ...metadata });
|
|
2074
|
+
}
|
|
2075
|
+
/**
|
|
2076
|
+
* Log activity event
|
|
2077
|
+
*/
|
|
2078
|
+
activity(event, activity_id, metadata) {
|
|
2079
|
+
this.info(`[Activity] ${event}`, { activity_id, ...metadata });
|
|
2080
|
+
}
|
|
2081
|
+
/**
|
|
2082
|
+
* Log with timing
|
|
2083
|
+
*/
|
|
2084
|
+
timed(label, fn) {
|
|
2085
|
+
const start = Date.now();
|
|
2086
|
+
try {
|
|
2087
|
+
const result = fn();
|
|
2088
|
+
this.debug(`${label} completed`, { duration_ms: Date.now() - start });
|
|
2089
|
+
return result;
|
|
2090
|
+
} catch (error) {
|
|
2091
|
+
this.error(`${label} failed`, error, { duration_ms: Date.now() - start });
|
|
2092
|
+
throw error;
|
|
2093
|
+
}
|
|
2094
|
+
}
|
|
2095
|
+
/**
|
|
2096
|
+
* Async version of timed
|
|
2097
|
+
*/
|
|
2098
|
+
async timed_async(label, fn) {
|
|
2099
|
+
const start = Date.now();
|
|
2100
|
+
try {
|
|
2101
|
+
const result = await fn();
|
|
2102
|
+
this.debug(`${label} completed`, { duration_ms: Date.now() - start });
|
|
2103
|
+
return result;
|
|
2104
|
+
} catch (error) {
|
|
2105
|
+
this.error(`${label} failed`, error, { duration_ms: Date.now() - start });
|
|
2106
|
+
throw error;
|
|
2107
|
+
}
|
|
2108
|
+
}
|
|
2109
|
+
};
|
|
2110
|
+
var global_logger;
|
|
2111
|
+
function get_logger() {
|
|
2112
|
+
if (!global_logger) {
|
|
2113
|
+
global_logger = new Logger({
|
|
2114
|
+
level: process.env.LOG_LEVEL || "info",
|
|
2115
|
+
format: process.env.LOG_FORMAT === "text" ? "text" : "json"
|
|
2116
|
+
});
|
|
2117
|
+
}
|
|
2118
|
+
return global_logger;
|
|
2119
|
+
}
|
|
2120
|
+
|
|
2121
|
+
// src/runtime/retry.ts
|
|
2122
|
+
var DEFAULT_RETRY_CONFIG = {
|
|
2123
|
+
max_retries: 3,
|
|
2124
|
+
initial_delay_ms: 1e3,
|
|
2125
|
+
max_delay_ms: 3e4,
|
|
2126
|
+
backoff_multiplier: 2,
|
|
2127
|
+
jitter: true,
|
|
2128
|
+
non_retryable_errors: [
|
|
2129
|
+
"VALIDATION_ERROR",
|
|
2130
|
+
"AUTHENTICATION_ERROR",
|
|
2131
|
+
"PERMISSION_DENIED",
|
|
2132
|
+
"NOT_FOUND"
|
|
2133
|
+
]
|
|
2134
|
+
};
|
|
2135
|
+
function calculate_retry_delay(config, attempt) {
|
|
2136
|
+
let delay = config.initial_delay_ms * Math.pow(config.backoff_multiplier, attempt);
|
|
2137
|
+
delay = Math.min(delay, config.max_delay_ms);
|
|
2138
|
+
if (config.jitter) {
|
|
2139
|
+
const jitter_range = delay * 0.25;
|
|
2140
|
+
delay += Math.random() * jitter_range * 2 - jitter_range;
|
|
2141
|
+
}
|
|
2142
|
+
return Math.round(delay);
|
|
2143
|
+
}
|
|
2144
|
+
function is_retryable_error(error, config) {
|
|
2145
|
+
const error_code = error.code;
|
|
2146
|
+
if (error_code && config.non_retryable_errors?.includes(error_code)) {
|
|
2147
|
+
return false;
|
|
2148
|
+
}
|
|
2149
|
+
const non_retryable_patterns = [
|
|
2150
|
+
/validation/i,
|
|
2151
|
+
/invalid/i,
|
|
2152
|
+
/unauthorized/i,
|
|
2153
|
+
/forbidden/i,
|
|
2154
|
+
/not found/i,
|
|
2155
|
+
/permission/i
|
|
2156
|
+
];
|
|
2157
|
+
for (const pattern of non_retryable_patterns) {
|
|
2158
|
+
if (pattern.test(error.message)) {
|
|
2159
|
+
return false;
|
|
2160
|
+
}
|
|
2161
|
+
}
|
|
2162
|
+
return true;
|
|
2163
|
+
}
|
|
2164
|
+
function sleep(ms) {
|
|
2165
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
2166
|
+
}
|
|
2167
|
+
async function with_retry(fn, config = {}, logger) {
|
|
2168
|
+
const full_config = { ...DEFAULT_RETRY_CONFIG, ...config };
|
|
2169
|
+
const log = logger || get_logger();
|
|
2170
|
+
let last_error;
|
|
2171
|
+
for (let attempt = 0; attempt <= full_config.max_retries; attempt++) {
|
|
2172
|
+
try {
|
|
2173
|
+
return await fn();
|
|
2174
|
+
} catch (error) {
|
|
2175
|
+
last_error = error instanceof Error ? error : new Error(String(error));
|
|
2176
|
+
if (attempt >= full_config.max_retries) {
|
|
2177
|
+
log.error(`All ${full_config.max_retries} retry attempts exhausted`, last_error, { attempt });
|
|
2178
|
+
throw last_error;
|
|
2179
|
+
}
|
|
2180
|
+
if (!is_retryable_error(last_error, full_config)) {
|
|
2181
|
+
log.warn("Error is not retryable", { error: last_error.message });
|
|
2182
|
+
throw last_error;
|
|
2183
|
+
}
|
|
2184
|
+
const delay = calculate_retry_delay(full_config, attempt);
|
|
2185
|
+
log.warn(`Retry attempt ${attempt + 1}/${full_config.max_retries} after ${delay}ms`, {
|
|
2186
|
+
error: last_error.message,
|
|
2187
|
+
attempt: attempt + 1,
|
|
2188
|
+
delay_ms: delay
|
|
2189
|
+
});
|
|
2190
|
+
await sleep(delay);
|
|
2191
|
+
}
|
|
2192
|
+
}
|
|
2193
|
+
throw last_error;
|
|
2194
|
+
}
|
|
2195
|
+
var DeadLetterQueue = class {
|
|
2196
|
+
entries = /* @__PURE__ */ new Map();
|
|
2197
|
+
logger;
|
|
2198
|
+
constructor(logger) {
|
|
2199
|
+
this.logger = logger || get_logger();
|
|
2200
|
+
}
|
|
2201
|
+
/**
|
|
2202
|
+
* Add a failed token to the dead letter queue
|
|
2203
|
+
*/
|
|
2204
|
+
add(token, workflow_id, activity_id, error, retry_state, metadata) {
|
|
2205
|
+
const entry = {
|
|
2206
|
+
id: token.id,
|
|
2207
|
+
token,
|
|
2208
|
+
workflow_id,
|
|
2209
|
+
activity_id,
|
|
2210
|
+
error: {
|
|
2211
|
+
message: error.message,
|
|
2212
|
+
stack: error.stack,
|
|
2213
|
+
code: error.code
|
|
2214
|
+
},
|
|
2215
|
+
retry_state,
|
|
2216
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2217
|
+
metadata
|
|
2218
|
+
};
|
|
2219
|
+
this.entries.set(token.id, entry);
|
|
2220
|
+
this.logger.error("Token added to dead letter queue", error, {
|
|
2221
|
+
token_id: token.id,
|
|
2222
|
+
workflow_id,
|
|
2223
|
+
activity_id,
|
|
2224
|
+
attempts: retry_state.attempt
|
|
2225
|
+
});
|
|
2226
|
+
return entry;
|
|
2227
|
+
}
|
|
2228
|
+
/**
|
|
2229
|
+
* Get an entry by token ID
|
|
2230
|
+
*/
|
|
2231
|
+
get(token_id) {
|
|
2232
|
+
return this.entries.get(token_id);
|
|
2233
|
+
}
|
|
2234
|
+
/**
|
|
2235
|
+
* List all entries
|
|
2236
|
+
*/
|
|
2237
|
+
list() {
|
|
2238
|
+
return Array.from(this.entries.values());
|
|
2239
|
+
}
|
|
2240
|
+
/**
|
|
2241
|
+
* List entries by workflow
|
|
2242
|
+
*/
|
|
2243
|
+
list_by_workflow(workflow_id) {
|
|
2244
|
+
return this.list().filter((e) => e.workflow_id === workflow_id);
|
|
2245
|
+
}
|
|
2246
|
+
/**
|
|
2247
|
+
* Remove an entry (e.g., after manual resolution)
|
|
2248
|
+
*/
|
|
2249
|
+
remove(token_id) {
|
|
2250
|
+
const removed = this.entries.delete(token_id);
|
|
2251
|
+
if (removed) {
|
|
2252
|
+
this.logger.info("Token removed from dead letter queue", { token_id });
|
|
2253
|
+
}
|
|
2254
|
+
return removed;
|
|
2255
|
+
}
|
|
2256
|
+
/**
|
|
2257
|
+
* Clear all entries
|
|
2258
|
+
*/
|
|
2259
|
+
clear() {
|
|
2260
|
+
const count = this.entries.size;
|
|
2261
|
+
this.entries.clear();
|
|
2262
|
+
this.logger.info("Dead letter queue cleared", { count });
|
|
2263
|
+
return count;
|
|
2264
|
+
}
|
|
2265
|
+
/**
|
|
2266
|
+
* Get queue statistics
|
|
2267
|
+
*/
|
|
2268
|
+
stats() {
|
|
2269
|
+
const by_workflow = {};
|
|
2270
|
+
for (const entry of this.entries.values()) {
|
|
2271
|
+
by_workflow[entry.workflow_id] = (by_workflow[entry.workflow_id] || 0) + 1;
|
|
2272
|
+
}
|
|
2273
|
+
return { total: this.entries.size, by_workflow };
|
|
2274
|
+
}
|
|
2275
|
+
};
|
|
2276
|
+
var global_dlq;
|
|
2277
|
+
function get_dead_letter_queue() {
|
|
2278
|
+
if (!global_dlq) {
|
|
2279
|
+
global_dlq = new DeadLetterQueue();
|
|
2280
|
+
}
|
|
2281
|
+
return global_dlq;
|
|
2282
|
+
}
|
|
2283
|
+
function set_dead_letter_queue(dlq) {
|
|
2284
|
+
global_dlq = dlq;
|
|
2285
|
+
}
|
|
2286
|
+
function create_retryable_executor(executor, config, on_retry) {
|
|
2287
|
+
return async () => {
|
|
2288
|
+
const full_config = { ...DEFAULT_RETRY_CONFIG, ...config };
|
|
2289
|
+
const logger = get_logger();
|
|
2290
|
+
let last_error;
|
|
2291
|
+
for (let attempt = 0; attempt <= full_config.max_retries; attempt++) {
|
|
2292
|
+
try {
|
|
2293
|
+
return await executor();
|
|
2294
|
+
} catch (error) {
|
|
2295
|
+
last_error = error instanceof Error ? error : new Error(String(error));
|
|
2296
|
+
if (attempt >= full_config.max_retries || !is_retryable_error(last_error, full_config)) {
|
|
2297
|
+
throw last_error;
|
|
2298
|
+
}
|
|
2299
|
+
if (on_retry) {
|
|
2300
|
+
on_retry(attempt + 1, last_error);
|
|
2301
|
+
}
|
|
2302
|
+
const delay = calculate_retry_delay(full_config, attempt);
|
|
2303
|
+
logger.debug(`Retry ${attempt + 1}/${full_config.max_retries}`, { delay_ms: delay });
|
|
2304
|
+
await sleep(delay);
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
throw last_error;
|
|
2308
|
+
};
|
|
2309
|
+
}
|
|
2310
|
+
|
|
2311
|
+
// src/runtime/persistence.ts
|
|
2312
|
+
var InMemoryPersistenceAdapter = class {
|
|
2313
|
+
storage = /* @__PURE__ */ new Map();
|
|
2314
|
+
async save(workflow_id, state) {
|
|
2315
|
+
this.storage.set(workflow_id, state);
|
|
2316
|
+
}
|
|
2317
|
+
async load(workflow_id) {
|
|
2318
|
+
return this.storage.get(workflow_id) || null;
|
|
2319
|
+
}
|
|
2320
|
+
async delete(workflow_id) {
|
|
2321
|
+
this.storage.delete(workflow_id);
|
|
2322
|
+
}
|
|
2323
|
+
async list() {
|
|
2324
|
+
return Array.from(this.storage.keys());
|
|
2325
|
+
}
|
|
2326
|
+
};
|
|
2327
|
+
var FilePersistenceAdapter = class {
|
|
2328
|
+
directory;
|
|
2329
|
+
fs = null;
|
|
2330
|
+
path = null;
|
|
2331
|
+
constructor(directory) {
|
|
2332
|
+
this.directory = directory;
|
|
2333
|
+
}
|
|
2334
|
+
async ensure_deps() {
|
|
2335
|
+
if (!this.fs) {
|
|
2336
|
+
this.fs = await import("fs/promises");
|
|
2337
|
+
this.path = await import("path");
|
|
2338
|
+
}
|
|
2339
|
+
}
|
|
2340
|
+
state_path(workflow_id) {
|
|
2341
|
+
return this.path.join(this.directory, `${workflow_id}.state.json`);
|
|
2342
|
+
}
|
|
2343
|
+
async save(workflow_id, state) {
|
|
2344
|
+
await this.ensure_deps();
|
|
2345
|
+
await this.fs.mkdir(this.directory, { recursive: true });
|
|
2346
|
+
await this.fs.writeFile(
|
|
2347
|
+
this.state_path(workflow_id),
|
|
2348
|
+
JSON.stringify(state, null, 2),
|
|
2349
|
+
"utf-8"
|
|
2350
|
+
);
|
|
2351
|
+
}
|
|
2352
|
+
async load(workflow_id) {
|
|
2353
|
+
await this.ensure_deps();
|
|
2354
|
+
try {
|
|
2355
|
+
const content = await this.fs.readFile(this.state_path(workflow_id), "utf-8");
|
|
2356
|
+
return JSON.parse(content);
|
|
2357
|
+
} catch (error) {
|
|
2358
|
+
if (error.code === "ENOENT") {
|
|
2359
|
+
return null;
|
|
2360
|
+
}
|
|
2361
|
+
throw error;
|
|
2362
|
+
}
|
|
2363
|
+
}
|
|
2364
|
+
async delete(workflow_id) {
|
|
2365
|
+
await this.ensure_deps();
|
|
2366
|
+
try {
|
|
2367
|
+
await this.fs.unlink(this.state_path(workflow_id));
|
|
2368
|
+
} catch (error) {
|
|
2369
|
+
if (error.code !== "ENOENT") {
|
|
2370
|
+
throw error;
|
|
2371
|
+
}
|
|
2372
|
+
}
|
|
2373
|
+
}
|
|
2374
|
+
async list() {
|
|
2375
|
+
await this.ensure_deps();
|
|
2376
|
+
try {
|
|
2377
|
+
const files = await this.fs.readdir(this.directory);
|
|
2378
|
+
return files.filter((f) => f.endsWith(".state.json")).map((f) => f.replace(".state.json", ""));
|
|
2379
|
+
} catch (error) {
|
|
2380
|
+
if (error.code === "ENOENT") {
|
|
2381
|
+
return [];
|
|
2382
|
+
}
|
|
2383
|
+
throw error;
|
|
2384
|
+
}
|
|
2385
|
+
}
|
|
2386
|
+
};
|
|
2387
|
+
function serialize_token(token) {
|
|
2388
|
+
return {
|
|
2389
|
+
id: token.id,
|
|
2390
|
+
activity_id: token.activityId,
|
|
2391
|
+
status: token.status,
|
|
2392
|
+
context_data: token.contextData,
|
|
2393
|
+
created_at: token.createdAt.toISOString(),
|
|
2394
|
+
updated_at: token.updatedAt.toISOString()
|
|
2395
|
+
};
|
|
2396
|
+
}
|
|
2397
|
+
function deserialize_token(data, workflow_id) {
|
|
2398
|
+
const token = new Token(
|
|
2399
|
+
data.activity_id,
|
|
2400
|
+
data.context_data,
|
|
2401
|
+
void 0,
|
|
2402
|
+
// parentTokenId
|
|
2403
|
+
workflow_id
|
|
2404
|
+
);
|
|
2405
|
+
token.id = data.id;
|
|
2406
|
+
token.updateStatus(data.status);
|
|
2407
|
+
return token;
|
|
2408
|
+
}
|
|
2409
|
+
var CheckpointManager = class {
|
|
2410
|
+
adapter;
|
|
2411
|
+
logger;
|
|
2412
|
+
auto_checkpoint_interval;
|
|
2413
|
+
constructor(adapter, logger) {
|
|
2414
|
+
this.adapter = adapter;
|
|
2415
|
+
this.logger = logger || get_logger();
|
|
2416
|
+
}
|
|
2417
|
+
/**
|
|
2418
|
+
* Create a checkpoint of the current workflow state
|
|
2419
|
+
*/
|
|
2420
|
+
async checkpoint(workflow2, engine_status, tokens, contexts, metadata) {
|
|
2421
|
+
const state = {
|
|
2422
|
+
version: "1.0",
|
|
2423
|
+
workflow_id: workflow2.id,
|
|
2424
|
+
workflow_name: workflow2.name,
|
|
2425
|
+
workflow_version: workflow2.version,
|
|
2426
|
+
engine_status,
|
|
2427
|
+
tokens: tokens.map(serialize_token),
|
|
2428
|
+
contexts,
|
|
2429
|
+
checkpoint_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2430
|
+
metadata
|
|
2431
|
+
};
|
|
2432
|
+
await this.adapter.save(workflow2.id, state);
|
|
2433
|
+
this.logger.info("Workflow checkpoint created", {
|
|
2434
|
+
workflow_id: workflow2.id,
|
|
2435
|
+
token_count: tokens.length,
|
|
2436
|
+
engine_status
|
|
2437
|
+
});
|
|
2438
|
+
return state;
|
|
2439
|
+
}
|
|
2440
|
+
/**
|
|
2441
|
+
* Load a workflow checkpoint
|
|
2442
|
+
*/
|
|
2443
|
+
async load(workflow_id) {
|
|
2444
|
+
const state = await this.adapter.load(workflow_id);
|
|
2445
|
+
if (state) {
|
|
2446
|
+
this.logger.info("Workflow checkpoint loaded", {
|
|
2447
|
+
workflow_id,
|
|
2448
|
+
checkpoint_at: state.checkpoint_at,
|
|
2449
|
+
token_count: state.tokens.length
|
|
2450
|
+
});
|
|
2451
|
+
}
|
|
2452
|
+
return state;
|
|
2453
|
+
}
|
|
2454
|
+
/**
|
|
2455
|
+
* Delete a workflow checkpoint
|
|
2456
|
+
*/
|
|
2457
|
+
async delete(workflow_id) {
|
|
2458
|
+
await this.adapter.delete(workflow_id);
|
|
2459
|
+
this.logger.info("Workflow checkpoint deleted", { workflow_id });
|
|
2460
|
+
}
|
|
2461
|
+
/**
|
|
2462
|
+
* List all checkpointed workflows
|
|
2463
|
+
*/
|
|
2464
|
+
async list() {
|
|
2465
|
+
return this.adapter.list();
|
|
2466
|
+
}
|
|
2467
|
+
/**
|
|
2468
|
+
* Restore tokens from a checkpoint
|
|
2469
|
+
*/
|
|
2470
|
+
restore_tokens(state) {
|
|
2471
|
+
return state.tokens.map((t) => deserialize_token(t, state.workflow_id));
|
|
2472
|
+
}
|
|
2473
|
+
/**
|
|
2474
|
+
* Enable auto-checkpointing at intervals
|
|
2475
|
+
*/
|
|
2476
|
+
enable_auto_checkpoint(interval_ms, get_state) {
|
|
2477
|
+
this.disable_auto_checkpoint();
|
|
2478
|
+
this.auto_checkpoint_interval = setInterval(async () => {
|
|
2479
|
+
try {
|
|
2480
|
+
const { workflow: workflow2, engine_status, tokens, contexts } = await get_state();
|
|
2481
|
+
if (engine_status === "running" || engine_status === "waiting_human") {
|
|
2482
|
+
await this.checkpoint(workflow2, engine_status, tokens, contexts);
|
|
2483
|
+
}
|
|
2484
|
+
} catch (error) {
|
|
2485
|
+
this.logger.error("Auto-checkpoint failed", error);
|
|
2486
|
+
}
|
|
2487
|
+
}, interval_ms);
|
|
2488
|
+
this.logger.info("Auto-checkpoint enabled", { interval_ms });
|
|
2489
|
+
}
|
|
2490
|
+
/**
|
|
2491
|
+
* Disable auto-checkpointing
|
|
2492
|
+
*/
|
|
2493
|
+
disable_auto_checkpoint() {
|
|
2494
|
+
if (this.auto_checkpoint_interval) {
|
|
2495
|
+
clearInterval(this.auto_checkpoint_interval);
|
|
2496
|
+
this.auto_checkpoint_interval = void 0;
|
|
2497
|
+
this.logger.info("Auto-checkpoint disabled");
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2500
|
+
};
|
|
2501
|
+
var global_checkpoint_manager;
|
|
2502
|
+
function get_checkpoint_manager() {
|
|
2503
|
+
if (!global_checkpoint_manager) {
|
|
2504
|
+
global_checkpoint_manager = new CheckpointManager(new InMemoryPersistenceAdapter());
|
|
2505
|
+
}
|
|
2506
|
+
return global_checkpoint_manager;
|
|
2507
|
+
}
|
|
2508
|
+
function set_checkpoint_manager(manager) {
|
|
2509
|
+
global_checkpoint_manager = manager;
|
|
2510
|
+
}
|
|
2511
|
+
function create_file_checkpoint_manager(directory, logger) {
|
|
2512
|
+
return new CheckpointManager(new FilePersistenceAdapter(directory), logger);
|
|
2513
|
+
}
|
|
2514
|
+
|
|
2515
|
+
// src/builder/index.ts
|
|
2516
|
+
var import_uuid3 = require("uuid");
|
|
2517
|
+
var WorkflowBuilder = class {
|
|
2518
|
+
workflow;
|
|
2519
|
+
activityMap = /* @__PURE__ */ new Map();
|
|
2520
|
+
contextMap = /* @__PURE__ */ new Map();
|
|
2521
|
+
constructor(name, version = "1.0.0") {
|
|
2522
|
+
this.workflow = {
|
|
2523
|
+
id: (0, import_uuid3.v4)(),
|
|
2524
|
+
name,
|
|
2525
|
+
version,
|
|
2526
|
+
activities: [],
|
|
2527
|
+
edges: [],
|
|
2528
|
+
events: [],
|
|
2529
|
+
decision_nodes: [],
|
|
2530
|
+
contexts: [],
|
|
2531
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2532
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
2533
|
+
};
|
|
2534
|
+
}
|
|
2535
|
+
/**
|
|
2536
|
+
* Set workflow description
|
|
2537
|
+
*/
|
|
2538
|
+
description(description) {
|
|
2539
|
+
this.workflow.description = description;
|
|
2540
|
+
return this;
|
|
2541
|
+
}
|
|
2542
|
+
/**
|
|
2543
|
+
* Set workflow owner
|
|
2544
|
+
*/
|
|
2545
|
+
owner(owner_id) {
|
|
2546
|
+
this.workflow.owner_id = owner_id;
|
|
2547
|
+
return this;
|
|
2548
|
+
}
|
|
2549
|
+
/**
|
|
2550
|
+
* Set owning organization
|
|
2551
|
+
*/
|
|
2552
|
+
organization(organization_id) {
|
|
2553
|
+
this.workflow.organization_id = organization_id;
|
|
2554
|
+
return this;
|
|
2555
|
+
}
|
|
2556
|
+
/**
|
|
2557
|
+
* Add a context for agent collaboration
|
|
2558
|
+
*/
|
|
2559
|
+
context(name, config) {
|
|
2560
|
+
const context = {
|
|
2561
|
+
id: (0, import_uuid3.v4)(),
|
|
2562
|
+
name,
|
|
2563
|
+
type: config.type,
|
|
2564
|
+
sync_pattern: config.sync_pattern,
|
|
2565
|
+
description: config.description,
|
|
2566
|
+
schema: config.schema,
|
|
2567
|
+
initial_value: config.initial_value,
|
|
2568
|
+
visibility: config.visibility || "workflow",
|
|
2569
|
+
owner_workflow_id: this.workflow.id,
|
|
2570
|
+
lifecycle: "persistent"
|
|
2571
|
+
};
|
|
2572
|
+
this.contextMap.set(name, context);
|
|
2573
|
+
this.workflow.contexts.push(context);
|
|
2574
|
+
return this;
|
|
2575
|
+
}
|
|
2576
|
+
/**
|
|
2577
|
+
* Add an activity to the workflow
|
|
2578
|
+
*/
|
|
2579
|
+
activity(name, config) {
|
|
2580
|
+
const activityId = (0, import_uuid3.v4)();
|
|
2581
|
+
const contextBindings = (config.contexts || []).map((ctx) => {
|
|
2582
|
+
const contextObj = this.contextMap.get(ctx.id);
|
|
2583
|
+
return {
|
|
2584
|
+
id: (0, import_uuid3.v4)(),
|
|
2585
|
+
context_id: contextObj?.id || ctx.id,
|
|
2586
|
+
activity_id: activityId,
|
|
2587
|
+
access_mode: ctx.access_mode,
|
|
2588
|
+
required: ctx.required ?? true
|
|
2589
|
+
};
|
|
2590
|
+
});
|
|
2591
|
+
const accessRights = (config.access_rights || []).map((ar) => ({
|
|
2592
|
+
id: (0, import_uuid3.v4)(),
|
|
2593
|
+
name: ar.name,
|
|
2594
|
+
activity_id: activityId,
|
|
2595
|
+
direction: ar.direction || "requires",
|
|
2596
|
+
resource_type: ar.resource_type,
|
|
2597
|
+
resource_id: ar.resource_id,
|
|
2598
|
+
permission: ar.permission,
|
|
2599
|
+
scope: ar.scope
|
|
2600
|
+
}));
|
|
2601
|
+
const activity = {
|
|
2602
|
+
id: activityId,
|
|
2603
|
+
name,
|
|
2604
|
+
description: config.description,
|
|
2605
|
+
role_id: config.role_id,
|
|
2606
|
+
actor_type: config.actor_type,
|
|
2607
|
+
system_id: config.system_id,
|
|
2608
|
+
machine_id: config.machine_id,
|
|
2609
|
+
endpoint_id: config.endpoint_id,
|
|
2610
|
+
organization_id: config.organization_id,
|
|
2611
|
+
inputs: [],
|
|
2612
|
+
outputs: [],
|
|
2613
|
+
context_bindings: contextBindings,
|
|
2614
|
+
access_rights: accessRights,
|
|
2615
|
+
programs: [],
|
|
2616
|
+
controls: [],
|
|
2617
|
+
sla: config.sla,
|
|
2618
|
+
analytics: config.analytics,
|
|
2619
|
+
is_expandable: false,
|
|
2620
|
+
skills: [],
|
|
2621
|
+
tool_requirements: []
|
|
2622
|
+
};
|
|
2623
|
+
this.activityMap.set(name, activity);
|
|
2624
|
+
this.workflow.activities.push(activity);
|
|
2625
|
+
return this;
|
|
2626
|
+
}
|
|
2627
|
+
/**
|
|
2628
|
+
* Add an edge between two activities
|
|
2629
|
+
*/
|
|
2630
|
+
edge(sourceName, targetName, options) {
|
|
2631
|
+
const source = this.activityMap.get(sourceName);
|
|
2632
|
+
const target = this.activityMap.get(targetName);
|
|
2633
|
+
if (!source) {
|
|
2634
|
+
throw new Error(`Source activity '${sourceName}' not found`);
|
|
2635
|
+
}
|
|
2636
|
+
if (!target) {
|
|
2637
|
+
throw new Error(`Target activity '${targetName}' not found`);
|
|
2638
|
+
}
|
|
2639
|
+
const edge = {
|
|
2640
|
+
id: (0, import_uuid3.v4)(),
|
|
2641
|
+
source_id: source.id,
|
|
2642
|
+
target_id: target.id,
|
|
2643
|
+
source_type: "activity",
|
|
2644
|
+
target_type: "activity",
|
|
2645
|
+
condition: options?.condition,
|
|
2646
|
+
label: options?.label,
|
|
2647
|
+
is_default: false,
|
|
2648
|
+
skills: [],
|
|
2649
|
+
tool_requirements: []
|
|
2650
|
+
};
|
|
2651
|
+
this.workflow.edges.push(edge);
|
|
2652
|
+
return this;
|
|
2653
|
+
}
|
|
2654
|
+
/**
|
|
2655
|
+
* Set workflow-level SLA
|
|
2656
|
+
*/
|
|
2657
|
+
sla(sla) {
|
|
2658
|
+
this.workflow.sla = sla;
|
|
2659
|
+
return this;
|
|
2660
|
+
}
|
|
2661
|
+
/**
|
|
2662
|
+
* Set workflow-level analytics
|
|
2663
|
+
*/
|
|
2664
|
+
analytics(analytics) {
|
|
2665
|
+
this.workflow.analytics = analytics;
|
|
2666
|
+
return this;
|
|
2667
|
+
}
|
|
2668
|
+
/**
|
|
2669
|
+
* Add metadata
|
|
2670
|
+
*/
|
|
2671
|
+
metadata(key, value) {
|
|
2672
|
+
if (!this.workflow.metadata) {
|
|
2673
|
+
this.workflow.metadata = {};
|
|
2674
|
+
}
|
|
2675
|
+
this.workflow.metadata[key] = value;
|
|
2676
|
+
return this;
|
|
2677
|
+
}
|
|
2678
|
+
/**
|
|
2679
|
+
* Build and return the workflow
|
|
2680
|
+
*/
|
|
2681
|
+
build() {
|
|
2682
|
+
this.workflow.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
2683
|
+
return this.workflow;
|
|
2684
|
+
}
|
|
2685
|
+
/**
|
|
2686
|
+
* Get activity by name
|
|
2687
|
+
*/
|
|
2688
|
+
getActivity(name) {
|
|
2689
|
+
return this.activityMap.get(name);
|
|
2690
|
+
}
|
|
2691
|
+
/**
|
|
2692
|
+
* Get context by name
|
|
2693
|
+
*/
|
|
2694
|
+
getContext(name) {
|
|
2695
|
+
return this.contextMap.get(name);
|
|
2696
|
+
}
|
|
2697
|
+
};
|
|
2698
|
+
function workflow(name, version) {
|
|
2699
|
+
return new WorkflowBuilder(name, version);
|
|
2700
|
+
}
|
|
2701
|
+
|
|
2702
|
+
// src/client/query.ts
|
|
2703
|
+
var WorkflowQuery = class {
|
|
2704
|
+
constructor(workflow2) {
|
|
2705
|
+
this.workflow = workflow2;
|
|
2706
|
+
}
|
|
2707
|
+
/**
|
|
2708
|
+
* Query activities
|
|
2709
|
+
*/
|
|
2710
|
+
activities() {
|
|
2711
|
+
return new ActivityQuery(this.workflow.activities);
|
|
2712
|
+
}
|
|
2713
|
+
/**
|
|
2714
|
+
* Query contexts
|
|
2715
|
+
*/
|
|
2716
|
+
contexts() {
|
|
2717
|
+
return new ContextQuery(this.workflow.contexts);
|
|
2718
|
+
}
|
|
2719
|
+
/**
|
|
2720
|
+
* Query all access rights across activities
|
|
2721
|
+
*/
|
|
2722
|
+
access_rights() {
|
|
2723
|
+
const allRights = this.workflow.activities.flatMap((a) => a.access_rights);
|
|
2724
|
+
return new AccessRightQuery(allRights);
|
|
2725
|
+
}
|
|
2726
|
+
/**
|
|
2727
|
+
* Query context bindings across activities
|
|
2728
|
+
*/
|
|
2729
|
+
context_bindings() {
|
|
2730
|
+
const allBindings = this.workflow.activities.flatMap((a) => a.context_bindings);
|
|
2731
|
+
return new ContextBindingQuery(allBindings);
|
|
2732
|
+
}
|
|
2733
|
+
};
|
|
2734
|
+
var ActivityQuery = class {
|
|
2735
|
+
constructor(activities) {
|
|
2736
|
+
this.activities = activities;
|
|
2737
|
+
}
|
|
2738
|
+
/**
|
|
2739
|
+
* Filter by actor type
|
|
2740
|
+
*/
|
|
2741
|
+
by_actor_type(type) {
|
|
2742
|
+
this.activities = this.activities.filter((a) => a.actor_type === type);
|
|
2743
|
+
return this;
|
|
2744
|
+
}
|
|
2745
|
+
/**
|
|
2746
|
+
* Filter by system
|
|
2747
|
+
*/
|
|
2748
|
+
by_system(system_id) {
|
|
2749
|
+
this.activities = this.activities.filter((a) => a.system_id === system_id);
|
|
2750
|
+
return this;
|
|
2751
|
+
}
|
|
2752
|
+
/**
|
|
2753
|
+
* Filter by role
|
|
2754
|
+
*/
|
|
2755
|
+
by_role(role_id) {
|
|
2756
|
+
this.activities = this.activities.filter((a) => a.role_id === role_id);
|
|
2757
|
+
return this;
|
|
2758
|
+
}
|
|
2759
|
+
/**
|
|
2760
|
+
* Filter activities that have access rights
|
|
2761
|
+
*/
|
|
2762
|
+
with_access_rights() {
|
|
2763
|
+
this.activities = this.activities.filter((a) => a.access_rights.length > 0);
|
|
2764
|
+
return this;
|
|
2765
|
+
}
|
|
2766
|
+
/**
|
|
2767
|
+
* Filter activities bound to a specific context
|
|
2768
|
+
*/
|
|
2769
|
+
bound_to_context(context_id) {
|
|
2770
|
+
this.activities = this.activities.filter(
|
|
2771
|
+
(a) => a.context_bindings.some((b) => b.context_id === context_id)
|
|
2772
|
+
);
|
|
2773
|
+
return this;
|
|
2774
|
+
}
|
|
2775
|
+
/**
|
|
2776
|
+
* Custom filter
|
|
2777
|
+
*/
|
|
2778
|
+
where(predicate) {
|
|
2779
|
+
this.activities = this.activities.filter(predicate);
|
|
2780
|
+
return this;
|
|
2781
|
+
}
|
|
2782
|
+
/**
|
|
2783
|
+
* Get first result
|
|
2784
|
+
*/
|
|
2785
|
+
first() {
|
|
2786
|
+
return this.activities[0];
|
|
2787
|
+
}
|
|
2788
|
+
/**
|
|
2789
|
+
* Get all results
|
|
2790
|
+
*/
|
|
2791
|
+
list() {
|
|
2792
|
+
return [...this.activities];
|
|
2793
|
+
}
|
|
2794
|
+
/**
|
|
2795
|
+
* Count results
|
|
2796
|
+
*/
|
|
2797
|
+
count() {
|
|
2798
|
+
return this.activities.length;
|
|
2799
|
+
}
|
|
2800
|
+
};
|
|
2801
|
+
var ContextQuery = class {
|
|
2802
|
+
constructor(contexts) {
|
|
2803
|
+
this.contexts = contexts;
|
|
2804
|
+
}
|
|
2805
|
+
/**
|
|
2806
|
+
* Filter by type
|
|
2807
|
+
*/
|
|
2808
|
+
by_type(type) {
|
|
2809
|
+
this.contexts = this.contexts.filter((c) => c.type === type);
|
|
2810
|
+
return this;
|
|
2811
|
+
}
|
|
2812
|
+
/**
|
|
2813
|
+
* Filter by sync pattern
|
|
2814
|
+
*/
|
|
2815
|
+
by_sync_pattern(pattern) {
|
|
2816
|
+
this.contexts = this.contexts.filter((c) => c.sync_pattern === pattern);
|
|
2817
|
+
return this;
|
|
2818
|
+
}
|
|
2819
|
+
/**
|
|
2820
|
+
* Filter by visibility
|
|
2821
|
+
*/
|
|
2822
|
+
by_visibility(visibility) {
|
|
2823
|
+
this.contexts = this.contexts.filter((c) => c.visibility === visibility);
|
|
2824
|
+
return this;
|
|
2825
|
+
}
|
|
2826
|
+
/**
|
|
2827
|
+
* Custom filter
|
|
2828
|
+
*/
|
|
2829
|
+
where(predicate) {
|
|
2830
|
+
this.contexts = this.contexts.filter(predicate);
|
|
2831
|
+
return this;
|
|
2832
|
+
}
|
|
2833
|
+
/**
|
|
2834
|
+
* Get first result
|
|
2835
|
+
*/
|
|
2836
|
+
first() {
|
|
2837
|
+
return this.contexts[0];
|
|
2838
|
+
}
|
|
2839
|
+
/**
|
|
2840
|
+
* Get all results
|
|
2841
|
+
*/
|
|
2842
|
+
list() {
|
|
2843
|
+
return [...this.contexts];
|
|
2844
|
+
}
|
|
2845
|
+
/**
|
|
2846
|
+
* Count results
|
|
2847
|
+
*/
|
|
2848
|
+
count() {
|
|
2849
|
+
return this.contexts.length;
|
|
2850
|
+
}
|
|
2851
|
+
};
|
|
2852
|
+
var AccessRightQuery = class {
|
|
2853
|
+
constructor(rights) {
|
|
2854
|
+
this.rights = rights;
|
|
2855
|
+
}
|
|
2856
|
+
/**
|
|
2857
|
+
* Filter by permission
|
|
2858
|
+
*/
|
|
2859
|
+
by_permission(permission) {
|
|
2860
|
+
this.rights = this.rights.filter((r) => r.permission === permission);
|
|
2861
|
+
return this;
|
|
2862
|
+
}
|
|
2863
|
+
/**
|
|
2864
|
+
* Filter by resource type
|
|
2865
|
+
*/
|
|
2866
|
+
by_resource_type(type) {
|
|
2867
|
+
this.rights = this.rights.filter((r) => r.resource_type === type);
|
|
2868
|
+
return this;
|
|
2869
|
+
}
|
|
2870
|
+
/**
|
|
2871
|
+
* Filter by direction (requires/provisions)
|
|
2872
|
+
*/
|
|
2873
|
+
by_direction(direction) {
|
|
2874
|
+
this.rights = this.rights.filter((r) => r.direction === direction);
|
|
2875
|
+
return this;
|
|
2876
|
+
}
|
|
2877
|
+
/**
|
|
2878
|
+
* Filter by resource ID
|
|
2879
|
+
*/
|
|
2880
|
+
by_resource_id(resource_id) {
|
|
2881
|
+
this.rights = this.rights.filter((r) => r.resource_id === resource_id);
|
|
2882
|
+
return this;
|
|
2883
|
+
}
|
|
2884
|
+
/**
|
|
2885
|
+
* Custom filter
|
|
2886
|
+
*/
|
|
2887
|
+
where(predicate) {
|
|
2888
|
+
this.rights = this.rights.filter(predicate);
|
|
2889
|
+
return this;
|
|
2890
|
+
}
|
|
2891
|
+
/**
|
|
2892
|
+
* Get first result
|
|
2893
|
+
*/
|
|
2894
|
+
first() {
|
|
2895
|
+
return this.rights[0];
|
|
2896
|
+
}
|
|
2897
|
+
/**
|
|
2898
|
+
* Get all results
|
|
2899
|
+
*/
|
|
2900
|
+
list() {
|
|
2901
|
+
return [...this.rights];
|
|
2902
|
+
}
|
|
2903
|
+
/**
|
|
2904
|
+
* Count results
|
|
2905
|
+
*/
|
|
2906
|
+
count() {
|
|
2907
|
+
return this.rights.length;
|
|
2908
|
+
}
|
|
2909
|
+
};
|
|
2910
|
+
var ContextBindingQuery = class {
|
|
2911
|
+
constructor(bindings) {
|
|
2912
|
+
this.bindings = bindings;
|
|
2913
|
+
}
|
|
2914
|
+
/**
|
|
2915
|
+
* Filter by access mode
|
|
2916
|
+
*/
|
|
2917
|
+
by_access_mode(mode) {
|
|
2918
|
+
this.bindings = this.bindings.filter((b) => b.access_mode === mode);
|
|
2919
|
+
return this;
|
|
2920
|
+
}
|
|
2921
|
+
/**
|
|
2922
|
+
* Filter by context
|
|
2923
|
+
*/
|
|
2924
|
+
by_context(context_id) {
|
|
2925
|
+
this.bindings = this.bindings.filter((b) => b.context_id === context_id);
|
|
2926
|
+
return this;
|
|
2927
|
+
}
|
|
2928
|
+
/**
|
|
2929
|
+
* Custom filter
|
|
2930
|
+
*/
|
|
2931
|
+
where(predicate) {
|
|
2932
|
+
this.bindings = this.bindings.filter(predicate);
|
|
2933
|
+
return this;
|
|
2934
|
+
}
|
|
2935
|
+
/**
|
|
2936
|
+
* Get first result
|
|
2937
|
+
*/
|
|
2938
|
+
first() {
|
|
2939
|
+
return this.bindings[0];
|
|
2940
|
+
}
|
|
2941
|
+
/**
|
|
2942
|
+
* Get all results
|
|
2943
|
+
*/
|
|
2944
|
+
list() {
|
|
2945
|
+
return [...this.bindings];
|
|
2946
|
+
}
|
|
2947
|
+
/**
|
|
2948
|
+
* Count results
|
|
2949
|
+
*/
|
|
2950
|
+
count() {
|
|
2951
|
+
return this.bindings.length;
|
|
2952
|
+
}
|
|
2953
|
+
};
|
|
2954
|
+
function query(workflow2) {
|
|
2955
|
+
return new WorkflowQuery(workflow2);
|
|
2956
|
+
}
|
|
2957
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
2958
|
+
0 && (module.exports = {
|
|
2959
|
+
AccessDirection,
|
|
2960
|
+
AccessMode,
|
|
2961
|
+
AccessRightQuery,
|
|
2962
|
+
AccessRightSchema,
|
|
2963
|
+
ActivityQuery,
|
|
2964
|
+
ActivitySchema,
|
|
2965
|
+
ActorType,
|
|
2966
|
+
AnalyticsSchema,
|
|
2967
|
+
AnimationConfigSchema,
|
|
2968
|
+
AnimationEasing,
|
|
2969
|
+
AutoLayoutConfigSchema,
|
|
2970
|
+
CameraSettings2DSchema,
|
|
2971
|
+
CameraSettings3DSchema,
|
|
2972
|
+
CameraType,
|
|
2973
|
+
CheckpointManager,
|
|
2974
|
+
CollectionSchema,
|
|
2975
|
+
ColorSchema,
|
|
2976
|
+
ContextBindingQuery,
|
|
2977
|
+
ContextBindingSchema,
|
|
2978
|
+
ContextManager,
|
|
2979
|
+
ContextQuery,
|
|
2980
|
+
ContextSchema,
|
|
2981
|
+
ContextType,
|
|
2982
|
+
ControlSchema,
|
|
2983
|
+
ControlType,
|
|
2984
|
+
CurveType,
|
|
2985
|
+
DEFAULT_RETRY_CONFIG,
|
|
2986
|
+
DataObjectSchema,
|
|
2987
|
+
DateTimeTz,
|
|
2988
|
+
DeadLetterQueue,
|
|
2989
|
+
DecisionEvaluator,
|
|
2990
|
+
DecisionNodeSchema,
|
|
2991
|
+
DecisionRuleSchema,
|
|
2992
|
+
DecisionTableSchema,
|
|
2993
|
+
Duration,
|
|
2994
|
+
EdgeRoutingSchema,
|
|
2995
|
+
EdgeSchema,
|
|
2996
|
+
EdgeStyleSchema,
|
|
2997
|
+
EndpointSchema,
|
|
2998
|
+
Enforcement,
|
|
2999
|
+
EventSchema,
|
|
3000
|
+
FilePersistenceAdapter,
|
|
3001
|
+
HitPolicy,
|
|
3002
|
+
HumanAgent,
|
|
3003
|
+
HumanTaskPriority,
|
|
3004
|
+
HumanTaskSchema,
|
|
3005
|
+
HumanTaskStatus,
|
|
3006
|
+
InMemoryPersistenceAdapter,
|
|
3007
|
+
LaneOrientation,
|
|
3008
|
+
LaneSchema,
|
|
3009
|
+
LayoutAlgorithm,
|
|
3010
|
+
LayoutDirection,
|
|
3011
|
+
Lifecycle,
|
|
3012
|
+
MachineSchema,
|
|
3013
|
+
NodeMaterial3DSchema,
|
|
3014
|
+
NodePosition2DSchema,
|
|
3015
|
+
NodePosition3DSchema,
|
|
3016
|
+
NodeShape,
|
|
3017
|
+
NodeStyle2DSchema,
|
|
3018
|
+
NodeType,
|
|
3019
|
+
ParameterSchema,
|
|
3020
|
+
Permission,
|
|
3021
|
+
ProgramSchema,
|
|
3022
|
+
QuaternionSchema,
|
|
3023
|
+
ResourceType,
|
|
3024
|
+
RobotAgent,
|
|
3025
|
+
RoleSchema,
|
|
3026
|
+
SLASchema,
|
|
3027
|
+
SkillBindingSchema,
|
|
3028
|
+
SkillType,
|
|
3029
|
+
SyncPattern,
|
|
3030
|
+
SystemSchema,
|
|
3031
|
+
TableColumnSchema,
|
|
3032
|
+
ThemeConfigSchema,
|
|
3033
|
+
Token,
|
|
3034
|
+
ToolRequirementSchema,
|
|
3035
|
+
ToolRequirementType,
|
|
3036
|
+
UUID,
|
|
3037
|
+
Vector2DSchema,
|
|
3038
|
+
Vector3DSchema,
|
|
3039
|
+
ViewType,
|
|
3040
|
+
Visibility,
|
|
3041
|
+
VisualizationConfigSchema,
|
|
3042
|
+
VisualizationEngine,
|
|
3043
|
+
WasteCategory,
|
|
3044
|
+
WorkflowBuilder,
|
|
3045
|
+
WorkflowEngine,
|
|
3046
|
+
WorkflowQuery,
|
|
3047
|
+
WorkflowSchema,
|
|
3048
|
+
calculate_retry_delay,
|
|
3049
|
+
create_file_checkpoint_manager,
|
|
3050
|
+
create_retryable_executor,
|
|
3051
|
+
deserialize_token,
|
|
3052
|
+
evaluate_decision,
|
|
3053
|
+
get_checkpoint_manager,
|
|
3054
|
+
get_dead_letter_queue,
|
|
3055
|
+
is_retryable_error,
|
|
3056
|
+
parse_activity,
|
|
3057
|
+
parse_context,
|
|
3058
|
+
parse_workflow,
|
|
3059
|
+
query,
|
|
3060
|
+
serialize_token,
|
|
3061
|
+
set_checkpoint_manager,
|
|
3062
|
+
set_dead_letter_queue,
|
|
3063
|
+
sleep,
|
|
3064
|
+
validate_activity,
|
|
3065
|
+
validate_context,
|
|
3066
|
+
validate_workflow,
|
|
3067
|
+
validate_workflow_integrity,
|
|
3068
|
+
with_retry,
|
|
3069
|
+
workflow
|
|
3070
|
+
});
|