@q1k-oss/btree-workflows 0.0.1
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/.claude/settings.local.json +31 -0
- package/CLAUDE.md +181 -0
- package/LICENSE +21 -0
- package/README.md +920 -0
- package/behaviour-tree-workflows-landing/index.html +16 -0
- package/behaviour-tree-workflows-landing/package-lock.json +2074 -0
- package/behaviour-tree-workflows-landing/package.json +31 -0
- package/behaviour-tree-workflows-landing/public/favicon.svg +17 -0
- package/behaviour-tree-workflows-landing/src/App.css +103 -0
- package/behaviour-tree-workflows-landing/src/App.tsx +176 -0
- package/behaviour-tree-workflows-landing/src/components/BlackboardInspector.css +89 -0
- package/behaviour-tree-workflows-landing/src/components/BlackboardInspector.tsx +64 -0
- package/behaviour-tree-workflows-landing/src/components/ExampleSelector.css +64 -0
- package/behaviour-tree-workflows-landing/src/components/ExampleSelector.tsx +34 -0
- package/behaviour-tree-workflows-landing/src/components/ExecutionLog.css +107 -0
- package/behaviour-tree-workflows-landing/src/components/ExecutionLog.tsx +85 -0
- package/behaviour-tree-workflows-landing/src/components/Header.css +50 -0
- package/behaviour-tree-workflows-landing/src/components/Header.tsx +26 -0
- package/behaviour-tree-workflows-landing/src/components/StatusBadge.css +45 -0
- package/behaviour-tree-workflows-landing/src/components/StatusBadge.tsx +15 -0
- package/behaviour-tree-workflows-landing/src/components/Toolbar.css +74 -0
- package/behaviour-tree-workflows-landing/src/components/Toolbar.tsx +53 -0
- package/behaviour-tree-workflows-landing/src/components/TreeVisualizer.css +67 -0
- package/behaviour-tree-workflows-landing/src/components/TreeVisualizer.tsx +192 -0
- package/behaviour-tree-workflows-landing/src/components/YamlEditor.css +18 -0
- package/behaviour-tree-workflows-landing/src/components/YamlEditor.tsx +96 -0
- package/behaviour-tree-workflows-landing/src/lib/count-nodes.ts +11 -0
- package/behaviour-tree-workflows-landing/src/lib/execution-engine.ts +96 -0
- package/behaviour-tree-workflows-landing/src/lib/tree-layout.ts +136 -0
- package/behaviour-tree-workflows-landing/src/lib/yaml-examples.ts +549 -0
- package/behaviour-tree-workflows-landing/src/main.tsx +9 -0
- package/behaviour-tree-workflows-landing/src/stubs/activepieces.ts +18 -0
- package/behaviour-tree-workflows-landing/src/stubs/fs.ts +24 -0
- package/behaviour-tree-workflows-landing/src/stubs/path.ts +16 -0
- package/behaviour-tree-workflows-landing/src/stubs/temporal-activity.ts +6 -0
- package/behaviour-tree-workflows-landing/src/stubs/temporal-workflow.ts +22 -0
- package/behaviour-tree-workflows-landing/tsconfig.json +25 -0
- package/behaviour-tree-workflows-landing/vite.config.ts +40 -0
- package/demo-google-sheets.ts +181 -0
- package/demo-runtime-variables.ts +174 -0
- package/demo-template.ts +208 -0
- package/docs/ARCHITECTURE_SUMMARY.md +613 -0
- package/docs/NODE_REFERENCE.md +504 -0
- package/docs/README.md +53 -0
- package/docs/custom-nodes-architecture.md +826 -0
- package/docs/observability.md +175 -0
- package/docs/yaml-specification.md +990 -0
- package/examples/temporal/README.md +117 -0
- package/examples/temporal/activities.ts +373 -0
- package/examples/temporal/client.ts +115 -0
- package/examples/temporal/python-worker/activities.py +339 -0
- package/examples/temporal/python-worker/requirements.txt +12 -0
- package/examples/temporal/python-worker/worker.py +106 -0
- package/examples/temporal/worker.ts +66 -0
- package/examples/temporal/workflows.ts +6 -0
- package/examples/temporal/yaml-workflow-loader.ts +105 -0
- package/examples/yaml-test.ts +97 -0
- package/examples/yaml-workflows/01-simple-sequence.yaml +25 -0
- package/examples/yaml-workflows/02-parallel-timeout.yaml +45 -0
- package/examples/yaml-workflows/03-ecommerce-checkout.yaml +94 -0
- package/examples/yaml-workflows/04-ai-agent-workflow.yaml +346 -0
- package/examples/yaml-workflows/05-order-processing.yaml +146 -0
- package/examples/yaml-workflows/06-activity-test.yaml +71 -0
- package/examples/yaml-workflows/07-activity-simple-test.yaml +43 -0
- package/examples/yaml-workflows/08-file-processing.yaml +141 -0
- package/examples/yaml-workflows/09-http-request.yaml +137 -0
- package/examples/yaml-workflows/README.md +211 -0
- package/package.json +38 -0
- package/src/actions/code-execution.schema.ts +27 -0
- package/src/actions/code-execution.ts +218 -0
- package/src/actions/generate-file.test.ts +516 -0
- package/src/actions/generate-file.ts +166 -0
- package/src/actions/http-request.test.ts +784 -0
- package/src/actions/http-request.ts +228 -0
- package/src/actions/index.ts +20 -0
- package/src/actions/parse-file.test.ts +448 -0
- package/src/actions/parse-file.ts +139 -0
- package/src/actions/python-script.test.ts +439 -0
- package/src/actions/python-script.ts +154 -0
- package/src/base-node.test.ts +511 -0
- package/src/base-node.ts +605 -0
- package/src/behavior-tree.test.ts +431 -0
- package/src/behavior-tree.ts +283 -0
- package/src/blackboard.test.ts +222 -0
- package/src/blackboard.ts +192 -0
- package/src/composites/conditional.schema.ts +19 -0
- package/src/composites/conditional.test.ts +309 -0
- package/src/composites/conditional.ts +129 -0
- package/src/composites/for-each.schema.ts +23 -0
- package/src/composites/for-each.test.ts +254 -0
- package/src/composites/for-each.ts +132 -0
- package/src/composites/index.ts +15 -0
- package/src/composites/memory-sequence.schema.ts +19 -0
- package/src/composites/memory-sequence.test.ts +223 -0
- package/src/composites/memory-sequence.ts +98 -0
- package/src/composites/parallel.schema.ts +28 -0
- package/src/composites/parallel.test.ts +502 -0
- package/src/composites/parallel.ts +157 -0
- package/src/composites/reactive-sequence.schema.ts +19 -0
- package/src/composites/reactive-sequence.test.ts +170 -0
- package/src/composites/reactive-sequence.ts +85 -0
- package/src/composites/recovery.schema.ts +19 -0
- package/src/composites/recovery.test.ts +366 -0
- package/src/composites/recovery.ts +90 -0
- package/src/composites/selector.schema.ts +19 -0
- package/src/composites/selector.test.ts +387 -0
- package/src/composites/selector.ts +85 -0
- package/src/composites/sequence.schema.ts +19 -0
- package/src/composites/sequence.test.ts +337 -0
- package/src/composites/sequence.ts +72 -0
- package/src/composites/sub-tree.schema.ts +21 -0
- package/src/composites/sub-tree.test.ts +893 -0
- package/src/composites/sub-tree.ts +177 -0
- package/src/composites/while.schema.ts +24 -0
- package/src/composites/while.test.ts +381 -0
- package/src/composites/while.ts +149 -0
- package/src/data-store/index.ts +10 -0
- package/src/data-store/memory-store.ts +161 -0
- package/src/data-store/types.ts +94 -0
- package/src/debug/breakpoint.test.ts +47 -0
- package/src/debug/breakpoint.ts +30 -0
- package/src/debug/index.ts +17 -0
- package/src/debug/resume-point.test.ts +49 -0
- package/src/debug/resume-point.ts +29 -0
- package/src/decorators/delay.schema.ts +21 -0
- package/src/decorators/delay.test.ts +261 -0
- package/src/decorators/delay.ts +140 -0
- package/src/decorators/force-result.schema.ts +32 -0
- package/src/decorators/force-result.test.ts +133 -0
- package/src/decorators/force-result.ts +63 -0
- package/src/decorators/index.ts +13 -0
- package/src/decorators/invert.schema.ts +19 -0
- package/src/decorators/invert.test.ts +135 -0
- package/src/decorators/invert.ts +42 -0
- package/src/decorators/keep-running.schema.ts +20 -0
- package/src/decorators/keep-running.test.ts +105 -0
- package/src/decorators/keep-running.ts +49 -0
- package/src/decorators/precondition.schema.ts +19 -0
- package/src/decorators/precondition.test.ts +351 -0
- package/src/decorators/precondition.ts +139 -0
- package/src/decorators/repeat.schema.ts +21 -0
- package/src/decorators/repeat.test.ts +187 -0
- package/src/decorators/repeat.ts +94 -0
- package/src/decorators/run-once.schema.ts +19 -0
- package/src/decorators/run-once.test.ts +140 -0
- package/src/decorators/run-once.ts +61 -0
- package/src/decorators/soft-assert.schema.ts +19 -0
- package/src/decorators/soft-assert.test.ts +107 -0
- package/src/decorators/soft-assert.ts +68 -0
- package/src/decorators/timeout.schema.ts +21 -0
- package/src/decorators/timeout.test.ts +274 -0
- package/src/decorators/timeout.ts +159 -0
- package/src/errors.test.ts +63 -0
- package/src/errors.ts +34 -0
- package/src/events.test.ts +347 -0
- package/src/events.ts +183 -0
- package/src/index.ts +80 -0
- package/src/integrations/index.ts +30 -0
- package/src/integrations/integration-action.test.ts +571 -0
- package/src/integrations/integration-action.ts +233 -0
- package/src/integrations/piece-executor.ts +320 -0
- package/src/observability/execution-tracker.ts +320 -0
- package/src/observability/index.ts +23 -0
- package/src/observability/sinks.ts +138 -0
- package/src/observability/types.ts +130 -0
- package/src/registry-utils.ts +147 -0
- package/src/registry.test.ts +466 -0
- package/src/registry.ts +334 -0
- package/src/schemas/base.schema.ts +104 -0
- package/src/schemas/index.ts +223 -0
- package/src/schemas/integration.test.ts +238 -0
- package/src/schemas/tree-definition.schema.ts +170 -0
- package/src/schemas/validation.test.ts +146 -0
- package/src/schemas/validation.ts +122 -0
- package/src/scripting/index.ts +22 -0
- package/src/templates/template-loader.test.ts +281 -0
- package/src/templates/template-loader.ts +152 -0
- package/src/temporal-integration.test.ts +213 -0
- package/src/test-nodes.ts +259 -0
- package/src/types.ts +503 -0
- package/src/utilities/index.ts +17 -0
- package/src/utilities/log-message.test.ts +275 -0
- package/src/utilities/log-message.ts +134 -0
- package/src/utilities/regex-extract.test.ts +138 -0
- package/src/utilities/regex-extract.ts +108 -0
- package/src/utilities/variable-resolver.test.ts +416 -0
- package/src/utilities/variable-resolver.ts +318 -0
- package/src/utils/error-handler.test.ts +117 -0
- package/src/utils/error-handler.ts +48 -0
- package/src/utils/signal-check.test.ts +234 -0
- package/src/utils/signal-check.ts +140 -0
- package/src/yaml/errors.ts +143 -0
- package/src/yaml/index.ts +30 -0
- package/src/yaml/loader.ts +39 -0
- package/src/yaml/parser.ts +286 -0
- package/src/yaml/validation/semantic-validator.ts +196 -0
- package/templates/google-sheets/insert-row.yaml +76 -0
- package/templates/notification-sender.yaml +33 -0
- package/templates/order-validation.yaml +44 -0
- package/tsconfig.json +24 -0
- package/vitest.config.ts +25 -0
- package/workflows/order-processor.yaml +59 -0
- package/workflows/process-order-workflow.yaml +142 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple test nodes for demonstrating behavior tree functionality
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { ActionNode, ConditionNode } from "./base-node.js";
|
|
6
|
+
import {
|
|
7
|
+
type TemporalContext,
|
|
8
|
+
type NodeConfiguration,
|
|
9
|
+
NodeStatus,
|
|
10
|
+
} from "./types.js";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Simple action that prints a message and succeeds
|
|
14
|
+
*/
|
|
15
|
+
export class PrintAction extends ActionNode {
|
|
16
|
+
private message: string;
|
|
17
|
+
|
|
18
|
+
constructor(config: NodeConfiguration & { message?: string }) {
|
|
19
|
+
super(config);
|
|
20
|
+
this.message = config.message || "Hello from PrintAction!";
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async executeTick(context: TemporalContext): Promise<NodeStatus> {
|
|
24
|
+
this.log(`Executing: "${this.message}"`);
|
|
25
|
+
|
|
26
|
+
// Optionally store result in blackboard
|
|
27
|
+
if (this.config.outputKey && typeof this.config.outputKey === "string") {
|
|
28
|
+
context.blackboard.set(this.config.outputKey, this.message);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
this._status = NodeStatus.SUCCESS;
|
|
32
|
+
return NodeStatus.SUCCESS;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Action that waits for a specified duration
|
|
38
|
+
*/
|
|
39
|
+
export class WaitAction extends ActionNode {
|
|
40
|
+
private waitMs: number;
|
|
41
|
+
private startTime: number | null = null;
|
|
42
|
+
|
|
43
|
+
constructor(config: NodeConfiguration & { waitMs?: number }) {
|
|
44
|
+
super(config);
|
|
45
|
+
this.waitMs = config.waitMs || 1000;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async executeTick(_context: TemporalContext): Promise<NodeStatus> {
|
|
49
|
+
if (this.startTime === null) {
|
|
50
|
+
this.startTime = Date.now();
|
|
51
|
+
this.log(`Starting wait for ${this.waitMs}ms`);
|
|
52
|
+
this._status = NodeStatus.RUNNING;
|
|
53
|
+
return NodeStatus.RUNNING;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const elapsed = Date.now() - this.startTime;
|
|
57
|
+
|
|
58
|
+
if (elapsed < this.waitMs) {
|
|
59
|
+
this.log(`Waiting... ${this.waitMs - elapsed}ms remaining`);
|
|
60
|
+
this._status = NodeStatus.RUNNING;
|
|
61
|
+
return NodeStatus.RUNNING;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
this.log(`Wait completed after ${elapsed}ms`);
|
|
65
|
+
this.startTime = null;
|
|
66
|
+
this._status = NodeStatus.SUCCESS;
|
|
67
|
+
return NodeStatus.SUCCESS;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
protected onReset(): void {
|
|
71
|
+
this.startTime = null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
protected onHalt(): void {
|
|
75
|
+
this.startTime = null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Action that increments a counter in the blackboard
|
|
81
|
+
*/
|
|
82
|
+
export class CounterAction extends ActionNode {
|
|
83
|
+
private counterKey: string;
|
|
84
|
+
private increment: number;
|
|
85
|
+
|
|
86
|
+
constructor(
|
|
87
|
+
config: NodeConfiguration & { counterKey?: string; increment?: number },
|
|
88
|
+
) {
|
|
89
|
+
super(config);
|
|
90
|
+
this.counterKey = config.counterKey || "counter";
|
|
91
|
+
this.increment = config.increment || 1;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async executeTick(context: TemporalContext): Promise<NodeStatus> {
|
|
95
|
+
const currentValue =
|
|
96
|
+
(context.blackboard.get(this.counterKey) as number) || 0;
|
|
97
|
+
const newValue = currentValue + this.increment;
|
|
98
|
+
|
|
99
|
+
context.blackboard.set(this.counterKey, newValue);
|
|
100
|
+
this.log(
|
|
101
|
+
`Counter '${this.counterKey}' incremented from ${currentValue} to ${newValue}`,
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
this._status = NodeStatus.SUCCESS;
|
|
105
|
+
return NodeStatus.SUCCESS;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Action that can be configured to return any status
|
|
111
|
+
*/
|
|
112
|
+
export class MockAction extends ActionNode {
|
|
113
|
+
private returnStatus: NodeStatus;
|
|
114
|
+
private ticksBeforeComplete: number;
|
|
115
|
+
private currentTicks: number = 0;
|
|
116
|
+
|
|
117
|
+
constructor(
|
|
118
|
+
config: NodeConfiguration & {
|
|
119
|
+
returnStatus?: NodeStatus;
|
|
120
|
+
ticksBeforeComplete?: number;
|
|
121
|
+
},
|
|
122
|
+
) {
|
|
123
|
+
super(config);
|
|
124
|
+
this.returnStatus = config.returnStatus || NodeStatus.SUCCESS;
|
|
125
|
+
this.ticksBeforeComplete = config.ticksBeforeComplete || 1;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async executeTick(_context: TemporalContext): Promise<NodeStatus> {
|
|
129
|
+
this.currentTicks++;
|
|
130
|
+
|
|
131
|
+
if (this.currentTicks < this.ticksBeforeComplete) {
|
|
132
|
+
this.log(
|
|
133
|
+
`Running... (tick ${this.currentTicks}/${this.ticksBeforeComplete})`,
|
|
134
|
+
);
|
|
135
|
+
this._status = NodeStatus.RUNNING;
|
|
136
|
+
return NodeStatus.RUNNING;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
this.log(`Completing with status: ${this.returnStatus}`);
|
|
140
|
+
this.currentTicks = 0;
|
|
141
|
+
this._status = this.returnStatus;
|
|
142
|
+
return this.returnStatus;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
protected onReset(): void {
|
|
146
|
+
this.currentTicks = 0;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
protected onHalt(): void {
|
|
150
|
+
this.currentTicks = 0;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Condition that checks if a blackboard value meets a criteria
|
|
156
|
+
*/
|
|
157
|
+
export class CheckCondition extends ConditionNode {
|
|
158
|
+
private key: string;
|
|
159
|
+
private operator: "==" | "!=" | ">" | "<" | ">=" | "<=";
|
|
160
|
+
private value: unknown;
|
|
161
|
+
|
|
162
|
+
constructor(
|
|
163
|
+
config: NodeConfiguration & {
|
|
164
|
+
key: string;
|
|
165
|
+
operator?: string;
|
|
166
|
+
value: unknown;
|
|
167
|
+
},
|
|
168
|
+
) {
|
|
169
|
+
super(config);
|
|
170
|
+
this.key = config.key;
|
|
171
|
+
this.operator =
|
|
172
|
+
(config.operator as "==" | "!=" | ">" | "<" | ">=" | "<=") || "==";
|
|
173
|
+
this.value = config.value;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
async executeTick(context: TemporalContext): Promise<NodeStatus> {
|
|
177
|
+
const actualValue = context.blackboard.get(this.key);
|
|
178
|
+
let result = false;
|
|
179
|
+
|
|
180
|
+
switch (this.operator) {
|
|
181
|
+
case "==":
|
|
182
|
+
result = actualValue === this.value;
|
|
183
|
+
break;
|
|
184
|
+
case "!=":
|
|
185
|
+
result = actualValue !== this.value;
|
|
186
|
+
break;
|
|
187
|
+
case ">":
|
|
188
|
+
result = (actualValue as number) > (this.value as number);
|
|
189
|
+
break;
|
|
190
|
+
case "<":
|
|
191
|
+
result = (actualValue as number) < (this.value as number);
|
|
192
|
+
break;
|
|
193
|
+
case ">=":
|
|
194
|
+
result = (actualValue as number) >= (this.value as number);
|
|
195
|
+
break;
|
|
196
|
+
case "<=":
|
|
197
|
+
result = (actualValue as number) <= (this.value as number);
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
this.log(
|
|
202
|
+
`Checking: ${this.key} ${this.operator} ${this.value} => ${actualValue} ${this.operator} ${this.value} = ${result}`,
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
this._status = result ? NodeStatus.SUCCESS : NodeStatus.FAILURE;
|
|
206
|
+
return this._status;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Simple condition that always returns the configured status
|
|
212
|
+
*/
|
|
213
|
+
export class AlwaysCondition extends ConditionNode {
|
|
214
|
+
private returnStatus: NodeStatus;
|
|
215
|
+
|
|
216
|
+
constructor(config: NodeConfiguration & { returnStatus?: NodeStatus }) {
|
|
217
|
+
super(config);
|
|
218
|
+
this.returnStatus = config.returnStatus || NodeStatus.SUCCESS;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
async executeTick(_context: TemporalContext): Promise<NodeStatus> {
|
|
222
|
+
this.log(`Returning ${this.returnStatus}`);
|
|
223
|
+
this._status = this.returnStatus;
|
|
224
|
+
return this.returnStatus;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Simple test node that always succeeds
|
|
230
|
+
*/
|
|
231
|
+
export class SuccessNode extends ActionNode {
|
|
232
|
+
async executeTick(_context: TemporalContext): Promise<NodeStatus> {
|
|
233
|
+
this.log("Executing (SUCCESS)");
|
|
234
|
+
this._status = NodeStatus.SUCCESS;
|
|
235
|
+
return NodeStatus.SUCCESS;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Simple test node that always fails
|
|
241
|
+
*/
|
|
242
|
+
export class FailureNode extends ActionNode {
|
|
243
|
+
async executeTick(_context: TemporalContext): Promise<NodeStatus> {
|
|
244
|
+
this.log("Executing (FAILURE)");
|
|
245
|
+
this._status = NodeStatus.FAILURE;
|
|
246
|
+
return NodeStatus.FAILURE;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Simple test node that stays running
|
|
252
|
+
*/
|
|
253
|
+
export class RunningNode extends ActionNode {
|
|
254
|
+
async executeTick(_context: TemporalContext): Promise<NodeStatus> {
|
|
255
|
+
this.log("Executing (RUNNING)");
|
|
256
|
+
this._status = NodeStatus.RUNNING;
|
|
257
|
+
return NodeStatus.RUNNING;
|
|
258
|
+
}
|
|
259
|
+
}
|