@q1k-oss/btree-workflows 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) hide show
  1. package/README.md +13 -13
  2. package/dist/index.cjs +5011 -0
  3. package/dist/index.d.cts +3320 -0
  4. package/dist/index.d.ts +3320 -0
  5. package/dist/index.js +4879 -0
  6. package/package.json +33 -3
  7. package/.claude/settings.local.json +0 -31
  8. package/CLAUDE.md +0 -181
  9. package/behaviour-tree-workflows-landing/index.html +0 -16
  10. package/behaviour-tree-workflows-landing/package-lock.json +0 -2074
  11. package/behaviour-tree-workflows-landing/package.json +0 -31
  12. package/behaviour-tree-workflows-landing/public/favicon.svg +0 -17
  13. package/behaviour-tree-workflows-landing/src/App.css +0 -103
  14. package/behaviour-tree-workflows-landing/src/App.tsx +0 -176
  15. package/behaviour-tree-workflows-landing/src/components/BlackboardInspector.css +0 -89
  16. package/behaviour-tree-workflows-landing/src/components/BlackboardInspector.tsx +0 -64
  17. package/behaviour-tree-workflows-landing/src/components/ExampleSelector.css +0 -64
  18. package/behaviour-tree-workflows-landing/src/components/ExampleSelector.tsx +0 -34
  19. package/behaviour-tree-workflows-landing/src/components/ExecutionLog.css +0 -107
  20. package/behaviour-tree-workflows-landing/src/components/ExecutionLog.tsx +0 -85
  21. package/behaviour-tree-workflows-landing/src/components/Header.css +0 -50
  22. package/behaviour-tree-workflows-landing/src/components/Header.tsx +0 -26
  23. package/behaviour-tree-workflows-landing/src/components/StatusBadge.css +0 -45
  24. package/behaviour-tree-workflows-landing/src/components/StatusBadge.tsx +0 -15
  25. package/behaviour-tree-workflows-landing/src/components/Toolbar.css +0 -74
  26. package/behaviour-tree-workflows-landing/src/components/Toolbar.tsx +0 -53
  27. package/behaviour-tree-workflows-landing/src/components/TreeVisualizer.css +0 -67
  28. package/behaviour-tree-workflows-landing/src/components/TreeVisualizer.tsx +0 -192
  29. package/behaviour-tree-workflows-landing/src/components/YamlEditor.css +0 -18
  30. package/behaviour-tree-workflows-landing/src/components/YamlEditor.tsx +0 -96
  31. package/behaviour-tree-workflows-landing/src/lib/count-nodes.ts +0 -11
  32. package/behaviour-tree-workflows-landing/src/lib/execution-engine.ts +0 -96
  33. package/behaviour-tree-workflows-landing/src/lib/tree-layout.ts +0 -136
  34. package/behaviour-tree-workflows-landing/src/lib/yaml-examples.ts +0 -549
  35. package/behaviour-tree-workflows-landing/src/main.tsx +0 -9
  36. package/behaviour-tree-workflows-landing/src/stubs/activepieces.ts +0 -18
  37. package/behaviour-tree-workflows-landing/src/stubs/fs.ts +0 -24
  38. package/behaviour-tree-workflows-landing/src/stubs/path.ts +0 -16
  39. package/behaviour-tree-workflows-landing/src/stubs/temporal-activity.ts +0 -6
  40. package/behaviour-tree-workflows-landing/src/stubs/temporal-workflow.ts +0 -22
  41. package/behaviour-tree-workflows-landing/tsconfig.json +0 -25
  42. package/behaviour-tree-workflows-landing/vite.config.ts +0 -40
  43. package/demo-google-sheets.ts +0 -181
  44. package/demo-runtime-variables.ts +0 -174
  45. package/demo-template.ts +0 -208
  46. package/docs/ARCHITECTURE_SUMMARY.md +0 -613
  47. package/docs/NODE_REFERENCE.md +0 -504
  48. package/docs/README.md +0 -53
  49. package/docs/custom-nodes-architecture.md +0 -826
  50. package/docs/observability.md +0 -175
  51. package/docs/yaml-specification.md +0 -990
  52. package/examples/temporal/README.md +0 -117
  53. package/examples/temporal/activities.ts +0 -373
  54. package/examples/temporal/client.ts +0 -115
  55. package/examples/temporal/python-worker/activities.py +0 -339
  56. package/examples/temporal/python-worker/requirements.txt +0 -12
  57. package/examples/temporal/python-worker/worker.py +0 -106
  58. package/examples/temporal/worker.ts +0 -66
  59. package/examples/temporal/workflows.ts +0 -6
  60. package/examples/temporal/yaml-workflow-loader.ts +0 -105
  61. package/examples/yaml-test.ts +0 -97
  62. package/examples/yaml-workflows/01-simple-sequence.yaml +0 -25
  63. package/examples/yaml-workflows/02-parallel-timeout.yaml +0 -45
  64. package/examples/yaml-workflows/03-ecommerce-checkout.yaml +0 -94
  65. package/examples/yaml-workflows/04-ai-agent-workflow.yaml +0 -346
  66. package/examples/yaml-workflows/05-order-processing.yaml +0 -146
  67. package/examples/yaml-workflows/06-activity-test.yaml +0 -71
  68. package/examples/yaml-workflows/07-activity-simple-test.yaml +0 -43
  69. package/examples/yaml-workflows/08-file-processing.yaml +0 -141
  70. package/examples/yaml-workflows/09-http-request.yaml +0 -137
  71. package/examples/yaml-workflows/README.md +0 -211
  72. package/src/actions/code-execution.schema.ts +0 -27
  73. package/src/actions/code-execution.ts +0 -218
  74. package/src/actions/generate-file.test.ts +0 -516
  75. package/src/actions/generate-file.ts +0 -166
  76. package/src/actions/http-request.test.ts +0 -784
  77. package/src/actions/http-request.ts +0 -228
  78. package/src/actions/index.ts +0 -20
  79. package/src/actions/parse-file.test.ts +0 -448
  80. package/src/actions/parse-file.ts +0 -139
  81. package/src/actions/python-script.test.ts +0 -439
  82. package/src/actions/python-script.ts +0 -154
  83. package/src/base-node.test.ts +0 -511
  84. package/src/base-node.ts +0 -605
  85. package/src/behavior-tree.test.ts +0 -431
  86. package/src/behavior-tree.ts +0 -283
  87. package/src/blackboard.test.ts +0 -222
  88. package/src/blackboard.ts +0 -192
  89. package/src/composites/conditional.schema.ts +0 -19
  90. package/src/composites/conditional.test.ts +0 -309
  91. package/src/composites/conditional.ts +0 -129
  92. package/src/composites/for-each.schema.ts +0 -23
  93. package/src/composites/for-each.test.ts +0 -254
  94. package/src/composites/for-each.ts +0 -132
  95. package/src/composites/index.ts +0 -15
  96. package/src/composites/memory-sequence.schema.ts +0 -19
  97. package/src/composites/memory-sequence.test.ts +0 -223
  98. package/src/composites/memory-sequence.ts +0 -98
  99. package/src/composites/parallel.schema.ts +0 -28
  100. package/src/composites/parallel.test.ts +0 -502
  101. package/src/composites/parallel.ts +0 -157
  102. package/src/composites/reactive-sequence.schema.ts +0 -19
  103. package/src/composites/reactive-sequence.test.ts +0 -170
  104. package/src/composites/reactive-sequence.ts +0 -85
  105. package/src/composites/recovery.schema.ts +0 -19
  106. package/src/composites/recovery.test.ts +0 -366
  107. package/src/composites/recovery.ts +0 -90
  108. package/src/composites/selector.schema.ts +0 -19
  109. package/src/composites/selector.test.ts +0 -387
  110. package/src/composites/selector.ts +0 -85
  111. package/src/composites/sequence.schema.ts +0 -19
  112. package/src/composites/sequence.test.ts +0 -337
  113. package/src/composites/sequence.ts +0 -72
  114. package/src/composites/sub-tree.schema.ts +0 -21
  115. package/src/composites/sub-tree.test.ts +0 -893
  116. package/src/composites/sub-tree.ts +0 -177
  117. package/src/composites/while.schema.ts +0 -24
  118. package/src/composites/while.test.ts +0 -381
  119. package/src/composites/while.ts +0 -149
  120. package/src/data-store/index.ts +0 -10
  121. package/src/data-store/memory-store.ts +0 -161
  122. package/src/data-store/types.ts +0 -94
  123. package/src/debug/breakpoint.test.ts +0 -47
  124. package/src/debug/breakpoint.ts +0 -30
  125. package/src/debug/index.ts +0 -17
  126. package/src/debug/resume-point.test.ts +0 -49
  127. package/src/debug/resume-point.ts +0 -29
  128. package/src/decorators/delay.schema.ts +0 -21
  129. package/src/decorators/delay.test.ts +0 -261
  130. package/src/decorators/delay.ts +0 -140
  131. package/src/decorators/force-result.schema.ts +0 -32
  132. package/src/decorators/force-result.test.ts +0 -133
  133. package/src/decorators/force-result.ts +0 -63
  134. package/src/decorators/index.ts +0 -13
  135. package/src/decorators/invert.schema.ts +0 -19
  136. package/src/decorators/invert.test.ts +0 -135
  137. package/src/decorators/invert.ts +0 -42
  138. package/src/decorators/keep-running.schema.ts +0 -20
  139. package/src/decorators/keep-running.test.ts +0 -105
  140. package/src/decorators/keep-running.ts +0 -49
  141. package/src/decorators/precondition.schema.ts +0 -19
  142. package/src/decorators/precondition.test.ts +0 -351
  143. package/src/decorators/precondition.ts +0 -139
  144. package/src/decorators/repeat.schema.ts +0 -21
  145. package/src/decorators/repeat.test.ts +0 -187
  146. package/src/decorators/repeat.ts +0 -94
  147. package/src/decorators/run-once.schema.ts +0 -19
  148. package/src/decorators/run-once.test.ts +0 -140
  149. package/src/decorators/run-once.ts +0 -61
  150. package/src/decorators/soft-assert.schema.ts +0 -19
  151. package/src/decorators/soft-assert.test.ts +0 -107
  152. package/src/decorators/soft-assert.ts +0 -68
  153. package/src/decorators/timeout.schema.ts +0 -21
  154. package/src/decorators/timeout.test.ts +0 -274
  155. package/src/decorators/timeout.ts +0 -159
  156. package/src/errors.test.ts +0 -63
  157. package/src/errors.ts +0 -34
  158. package/src/events.test.ts +0 -347
  159. package/src/events.ts +0 -183
  160. package/src/index.ts +0 -80
  161. package/src/integrations/index.ts +0 -30
  162. package/src/integrations/integration-action.test.ts +0 -571
  163. package/src/integrations/integration-action.ts +0 -233
  164. package/src/integrations/piece-executor.ts +0 -320
  165. package/src/observability/execution-tracker.ts +0 -320
  166. package/src/observability/index.ts +0 -23
  167. package/src/observability/sinks.ts +0 -138
  168. package/src/observability/types.ts +0 -130
  169. package/src/registry-utils.ts +0 -147
  170. package/src/registry.test.ts +0 -466
  171. package/src/registry.ts +0 -334
  172. package/src/schemas/base.schema.ts +0 -104
  173. package/src/schemas/index.ts +0 -223
  174. package/src/schemas/integration.test.ts +0 -238
  175. package/src/schemas/tree-definition.schema.ts +0 -170
  176. package/src/schemas/validation.test.ts +0 -146
  177. package/src/schemas/validation.ts +0 -122
  178. package/src/scripting/index.ts +0 -22
  179. package/src/templates/template-loader.test.ts +0 -281
  180. package/src/templates/template-loader.ts +0 -152
  181. package/src/temporal-integration.test.ts +0 -213
  182. package/src/test-nodes.ts +0 -259
  183. package/src/types.ts +0 -503
  184. package/src/utilities/index.ts +0 -17
  185. package/src/utilities/log-message.test.ts +0 -275
  186. package/src/utilities/log-message.ts +0 -134
  187. package/src/utilities/regex-extract.test.ts +0 -138
  188. package/src/utilities/regex-extract.ts +0 -108
  189. package/src/utilities/variable-resolver.test.ts +0 -416
  190. package/src/utilities/variable-resolver.ts +0 -318
  191. package/src/utils/error-handler.test.ts +0 -117
  192. package/src/utils/error-handler.ts +0 -48
  193. package/src/utils/signal-check.test.ts +0 -234
  194. package/src/utils/signal-check.ts +0 -140
  195. package/src/yaml/errors.ts +0 -143
  196. package/src/yaml/index.ts +0 -30
  197. package/src/yaml/loader.ts +0 -39
  198. package/src/yaml/parser.ts +0 -286
  199. package/src/yaml/validation/semantic-validator.ts +0 -196
  200. package/templates/google-sheets/insert-row.yaml +0 -76
  201. package/templates/notification-sender.yaml +0 -33
  202. package/templates/order-validation.yaml +0 -44
  203. package/tsconfig.json +0 -24
  204. package/vitest.config.ts +0 -25
  205. package/workflows/order-processor.yaml +0 -59
  206. package/workflows/process-order-workflow.yaml +0 -142
@@ -1,149 +0,0 @@
1
- /**
2
- * While node - Loop while condition is true
3
- */
4
-
5
- import { CompositeNode } from "../base-node.js";
6
- import { ConfigurationError } from "../errors.js";
7
- import {
8
- type TemporalContext,
9
- type NodeConfiguration,
10
- NodeStatus,
11
- type TreeNode,
12
- } from "../types.js";
13
- import { checkSignal } from "../utils/signal-check.js";
14
-
15
- export interface WhileConfiguration extends NodeConfiguration {
16
- maxIterations?: number; // Safety limit
17
- }
18
-
19
- /**
20
- * While loops while the condition returns SUCCESS.
21
- * Structure:
22
- * - First child = condition
23
- * - Second child = body
24
- */
25
- export class While extends CompositeNode {
26
- private maxIterations: number;
27
- private currentIteration: number = 0;
28
- private condition?: TreeNode;
29
- private body?: TreeNode;
30
- private bodyStarted: boolean = false;
31
-
32
- constructor(config: WhileConfiguration) {
33
- super(config);
34
- this.maxIterations = config.maxIterations ?? 1000;
35
- }
36
-
37
- addChild(child: TreeNode): void {
38
- if (!this.condition) {
39
- this.condition = child;
40
- this._children.push(child);
41
- child.parent = this;
42
- } else if (!this.body) {
43
- this.body = child;
44
- this._children.push(child);
45
- child.parent = this;
46
- } else {
47
- throw new ConfigurationError(
48
- "While can have maximum 2 children (condition, body)",
49
- );
50
- }
51
- }
52
-
53
- async executeTick(context: TemporalContext): Promise<NodeStatus> {
54
- if (!this.condition) {
55
- throw new ConfigurationError("While requires a condition child");
56
- }
57
- if (!this.body) {
58
- throw new ConfigurationError("While requires a body child");
59
- }
60
-
61
- this.log(
62
- `Starting while loop (iteration ${this.currentIteration}/${this.maxIterations})`,
63
- );
64
-
65
- // Loop while condition is SUCCESS
66
- while (this.currentIteration < this.maxIterations) {
67
- // Check for cancellation before each iteration
68
- checkSignal(context.signal);
69
-
70
- // Only check condition if body hasn't started for this iteration
71
- if (!this.bodyStarted) {
72
- // Evaluate condition
73
- this.log(`Evaluating condition (iteration ${this.currentIteration})`);
74
- const conditionStatus = await this.condition.tick(context);
75
-
76
- if (conditionStatus === NodeStatus.RUNNING) {
77
- this.log("Condition is running");
78
- this._status = NodeStatus.RUNNING;
79
- return NodeStatus.RUNNING;
80
- }
81
-
82
- if (conditionStatus === NodeStatus.FAILURE) {
83
- this.log("Condition failed - exiting loop");
84
- this._status = NodeStatus.SUCCESS;
85
- this.currentIteration = 0;
86
- this.bodyStarted = false;
87
- return NodeStatus.SUCCESS;
88
- }
89
-
90
- // Condition succeeded, mark body as started
91
- this.bodyStarted = true;
92
- } else {
93
- this.log(
94
- `Body already started for iteration ${this.currentIteration} - continuing execution`,
95
- );
96
- }
97
-
98
- // Execute body
99
- this.log(`Executing body (iteration ${this.currentIteration})`);
100
- const bodyStatus = await this.body.tick(context);
101
-
102
- switch (bodyStatus) {
103
- case NodeStatus.SUCCESS:
104
- this.log("Body succeeded - continuing loop");
105
- this.currentIteration++;
106
- this.bodyStarted = false; // Reset for next iteration
107
- this.condition.reset(); // Reset for next iteration
108
- this.body.reset();
109
- break;
110
-
111
- case NodeStatus.FAILURE:
112
- this.log("Body failed - While fails");
113
- this._status = NodeStatus.FAILURE;
114
- this.currentIteration = 0;
115
- this.bodyStarted = false;
116
- return NodeStatus.FAILURE;
117
-
118
- case NodeStatus.RUNNING:
119
- this.log("Body is running");
120
- this._status = NodeStatus.RUNNING;
121
- return NodeStatus.RUNNING;
122
-
123
- default:
124
- throw new Error(`Unexpected status from body: ${bodyStatus}`);
125
- }
126
- }
127
-
128
- // Max iterations reached
129
- this.log(`Max iterations (${this.maxIterations}) reached`);
130
- this._status = NodeStatus.FAILURE;
131
- this.currentIteration = 0;
132
- this.bodyStarted = false;
133
- return NodeStatus.FAILURE;
134
- }
135
-
136
- protected onReset(): void {
137
- super.onReset();
138
- this.log("Resetting - clearing body started flag");
139
- this.currentIteration = 0;
140
- this.bodyStarted = false;
141
- }
142
-
143
- protected onHalt(): void {
144
- super.onHalt();
145
- this.log("Halting - clearing body started flag");
146
- this.currentIteration = 0;
147
- this.bodyStarted = false;
148
- }
149
- }
@@ -1,10 +0,0 @@
1
- /**
2
- * DataStore module exports
3
- *
4
- * Provides interfaces and implementations for large data storage
5
- * outside workflow execution context.
6
- */
7
-
8
- export type { DataStore, DataRef, PutOptions } from "./types.js";
9
- export { isDataRef } from "./types.js";
10
- export { MemoryDataStore } from "./memory-store.js";
@@ -1,161 +0,0 @@
1
- /**
2
- * In-Memory DataStore Implementation
3
- *
4
- * Simple in-memory storage for testing and development.
5
- * Data is lost when the process terminates.
6
- *
7
- * Features:
8
- * - TTL support with automatic cleanup
9
- * - Size tracking
10
- * - Thread-safe for single Node.js process
11
- */
12
-
13
- import type { DataStore, DataRef, PutOptions } from "./types.js";
14
-
15
- interface StoredEntry {
16
- data: unknown;
17
- sizeBytes: number;
18
- expiresAt?: number;
19
- }
20
-
21
- /**
22
- * In-memory DataStore implementation
23
- * Suitable for tests and local development
24
- */
25
- export class MemoryDataStore implements DataStore {
26
- private storage = new Map<string, StoredEntry>();
27
- private cleanupInterval: ReturnType<typeof setInterval> | null = null;
28
-
29
- constructor(options?: { cleanupIntervalMs?: number }) {
30
- // Start periodic cleanup for expired entries
31
- const cleanupMs = options?.cleanupIntervalMs ?? 60000; // 1 minute default
32
- if (cleanupMs > 0) {
33
- this.cleanupInterval = setInterval(() => this.cleanup(), cleanupMs);
34
- // Don't prevent process exit
35
- if (this.cleanupInterval.unref) {
36
- this.cleanupInterval.unref();
37
- }
38
- }
39
- }
40
-
41
- async put(key: string, data: unknown, options?: PutOptions): Promise<DataRef> {
42
- const serialized = JSON.stringify(data);
43
- const sizeBytes = Buffer.byteLength(serialized, "utf8");
44
-
45
- const entry: StoredEntry = {
46
- data,
47
- sizeBytes,
48
- };
49
-
50
- if (options?.ttlSeconds) {
51
- entry.expiresAt = Date.now() + options.ttlSeconds * 1000;
52
- }
53
-
54
- this.storage.set(key, entry);
55
-
56
- return {
57
- store: "memory",
58
- key,
59
- sizeBytes,
60
- expiresAt: entry.expiresAt,
61
- };
62
- }
63
-
64
- async get(ref: DataRef): Promise<unknown> {
65
- if (ref.store !== "memory") {
66
- throw new Error(`MemoryDataStore cannot retrieve from store: ${ref.store}`);
67
- }
68
-
69
- const entry = this.storage.get(ref.key);
70
-
71
- if (!entry) {
72
- throw new Error(`Data not found for key: ${ref.key}`);
73
- }
74
-
75
- // Check expiration
76
- if (entry.expiresAt && Date.now() > entry.expiresAt) {
77
- this.storage.delete(ref.key);
78
- throw new Error(`Data expired for key: ${ref.key}`);
79
- }
80
-
81
- // Return a deep clone to prevent accidental mutation
82
- return structuredClone(entry.data);
83
- }
84
-
85
- async delete(ref: DataRef): Promise<void> {
86
- if (ref.store !== "memory") {
87
- throw new Error(`MemoryDataStore cannot delete from store: ${ref.store}`);
88
- }
89
-
90
- this.storage.delete(ref.key);
91
- }
92
-
93
- async exists(ref: DataRef): Promise<boolean> {
94
- if (ref.store !== "memory") {
95
- return false;
96
- }
97
-
98
- const entry = this.storage.get(ref.key);
99
-
100
- if (!entry) {
101
- return false;
102
- }
103
-
104
- // Check expiration
105
- if (entry.expiresAt && Date.now() > entry.expiresAt) {
106
- this.storage.delete(ref.key);
107
- return false;
108
- }
109
-
110
- return true;
111
- }
112
-
113
- /**
114
- * Clear all stored data
115
- * Useful for test cleanup
116
- */
117
- clear(): void {
118
- this.storage.clear();
119
- }
120
-
121
- /**
122
- * Get the number of stored entries
123
- */
124
- size(): number {
125
- return this.storage.size;
126
- }
127
-
128
- /**
129
- * Get total bytes stored
130
- */
131
- totalBytes(): number {
132
- let total = 0;
133
- for (const entry of this.storage.values()) {
134
- total += entry.sizeBytes;
135
- }
136
- return total;
137
- }
138
-
139
- /**
140
- * Stop the cleanup interval
141
- * Call this when done with the store to prevent memory leaks in tests
142
- */
143
- dispose(): void {
144
- if (this.cleanupInterval) {
145
- clearInterval(this.cleanupInterval);
146
- this.cleanupInterval = null;
147
- }
148
- }
149
-
150
- /**
151
- * Remove expired entries
152
- */
153
- private cleanup(): void {
154
- const now = Date.now();
155
- for (const [key, entry] of this.storage.entries()) {
156
- if (entry.expiresAt && now > entry.expiresAt) {
157
- this.storage.delete(key);
158
- }
159
- }
160
- }
161
- }
@@ -1,94 +0,0 @@
1
- /**
2
- * DataStore Interface
3
- *
4
- * Provides an abstraction for storing and retrieving large data payloads
5
- * outside the workflow execution context. This keeps the Temporal workflow
6
- * history lean while allowing workflows to process large datasets.
7
- *
8
- * Implementations:
9
- * - MemoryDataStore: In-memory storage for tests
10
- * - GCSDataStore: Google Cloud Storage for production (in controlplane)
11
- * - RedisDataStore: Redis storage for caching (future)
12
- */
13
-
14
- /**
15
- * Reference to data stored in a DataStore
16
- * This lightweight reference can be passed through workflows/activities
17
- */
18
- export interface DataRef {
19
- /** Storage backend identifier */
20
- store: "gcs" | "s3" | "redis" | "memory";
21
- /** Unique key for retrieving the data */
22
- key: string;
23
- /** Size of stored data in bytes (for monitoring/optimization) */
24
- sizeBytes?: number;
25
- /** Unix timestamp when data expires (optional TTL) */
26
- expiresAt?: number;
27
- }
28
-
29
- /**
30
- * Options for storing data
31
- */
32
- export interface PutOptions {
33
- /** Time-to-live in seconds (data auto-deleted after expiry) */
34
- ttlSeconds?: number;
35
- /** Content type hint for serialization */
36
- contentType?: "json" | "csv" | "binary";
37
- /** Associated workflow ID for grouping/cleanup */
38
- workflowId?: string;
39
- }
40
-
41
- /**
42
- * DataStore interface for storing and retrieving large payloads
43
- */
44
- export interface DataStore {
45
- /**
46
- * Store data and return a reference
47
- * @param key - Unique identifier for the data
48
- * @param data - Data to store (will be JSON serialized)
49
- * @param options - Storage options (TTL, content type, etc.)
50
- * @returns Reference to the stored data
51
- */
52
- put(key: string, data: unknown, options?: PutOptions): Promise<DataRef>;
53
-
54
- /**
55
- * Retrieve data by reference
56
- * @param ref - Reference returned from put()
57
- * @returns The stored data (JSON deserialized)
58
- * @throws Error if data not found or expired
59
- */
60
- get(ref: DataRef): Promise<unknown>;
61
-
62
- /**
63
- * Delete data by reference
64
- * @param ref - Reference to delete
65
- */
66
- delete(ref: DataRef): Promise<void>;
67
-
68
- /**
69
- * Check if data exists
70
- * @param ref - Reference to check
71
- * @returns true if data exists and hasn't expired
72
- */
73
- exists(ref: DataRef): Promise<boolean>;
74
- }
75
-
76
- /**
77
- * Type guard to check if a value is a DataRef
78
- * @param value - Value to check
79
- * @returns true if value is a DataRef
80
- */
81
- export function isDataRef(value: unknown): value is DataRef {
82
- if (typeof value !== "object" || value === null) {
83
- return false;
84
- }
85
-
86
- const obj = value as Record<string, unknown>;
87
-
88
- return (
89
- typeof obj.store === "string" &&
90
- ["gcs", "s3", "redis", "memory"].includes(obj.store) &&
91
- typeof obj.key === "string" &&
92
- obj.key.length > 0
93
- );
94
- }
@@ -1,47 +0,0 @@
1
- /**
2
- * Tests for Breakpoint node
3
- */
4
-
5
- import { describe, expect, it } from "vitest";
6
- import { ScopedBlackboard } from "../blackboard.js";
7
- import { Registry } from "../registry.js";
8
- import { NodeStatus, type TemporalContext } from "../types.js";
9
- import { Breakpoint } from "./breakpoint.js";
10
-
11
- describe("Breakpoint", () => {
12
- const createContext = (): TemporalContext => ({
13
- blackboard: new ScopedBlackboard(),
14
- treeRegistry: new Registry(),
15
- signal: new AbortController().signal,
16
- timestamp: Date.now(),
17
- });
18
-
19
- it("should return RUNNING to signal pause", async () => {
20
- const node = new Breakpoint({ id: "test-break" });
21
- const context = createContext();
22
-
23
- const result = await node.tick(context);
24
-
25
- expect(result).toBe(NodeStatus.RUNNING);
26
- expect(node.status()).toBe(NodeStatus.RUNNING);
27
- });
28
-
29
- it("should store the breakpointId", () => {
30
- const node = new Breakpoint({ id: "my-breakpoint" });
31
-
32
- expect(node.breakpointId).toBe("my-breakpoint");
33
- expect(node.id).toBe("breakpoint-my-breakpoint");
34
- });
35
-
36
- it("should consistently return RUNNING", async () => {
37
- const node = new Breakpoint({ id: "pause-here" });
38
- const context = createContext();
39
-
40
- // Execute multiple times - should always return RUNNING
41
- const result1 = await node.tick(context);
42
- const result2 = await node.tick(context);
43
-
44
- expect(result1).toBe(NodeStatus.RUNNING);
45
- expect(result2).toBe(NodeStatus.RUNNING);
46
- });
47
- });
@@ -1,30 +0,0 @@
1
- /**
2
- * Breakpoint - Pauses execution without failure
3
- * Returns RUNNING to signal pause (not FAILURE)
4
- */
5
-
6
- import { ActionNode } from "../base-node.js";
7
- import { type TemporalContext, NodeStatus } from "../types.js";
8
-
9
- export interface BreakpointConfig {
10
- id: string;
11
- }
12
-
13
- /**
14
- * Breakpoint pauses execution without marking it as a failure.
15
- * Returns RUNNING to signal that execution should pause here.
16
- * The session can then be resumed from this point.
17
- */
18
- export class Breakpoint extends ActionNode {
19
- readonly breakpointId: string;
20
-
21
- constructor(config: BreakpointConfig) {
22
- super({ id: `breakpoint-${config.id}` });
23
- this.breakpointId = config.id;
24
- }
25
-
26
- async executeTick(_context: TemporalContext): Promise<NodeStatus> {
27
- this._status = NodeStatus.RUNNING;
28
- return NodeStatus.RUNNING;
29
- }
30
- }
@@ -1,17 +0,0 @@
1
- /**
2
- * Debug nodes for behavior tree debugging and resume functionality
3
- */
4
-
5
- // Breakpoint is not exported - it's still in development
6
- // The current implementation causes infinite loops with tickWhileRunning
7
- // See docs/backlog/DEBUG_MODE.md for the full implementation plan
8
- // export {
9
- // Breakpoint,
10
- // BreakpointSchema,
11
- // type BreakpointConfig,
12
- // } from "./breakpoint.js";
13
-
14
- export {
15
- ResumePoint,
16
- type ResumePointConfig,
17
- } from "./resume-point.js";
@@ -1,49 +0,0 @@
1
- /**
2
- * Tests for ResumePoint node
3
- */
4
-
5
- import { describe, expect, it } from "vitest";
6
- import { ScopedBlackboard } from "../blackboard.js";
7
- import { Registry } from "../registry.js";
8
- import { NodeStatus, type TemporalContext } from "../types.js";
9
- import { ResumePoint } from "./resume-point.js";
10
-
11
- describe("ResumePoint", () => {
12
- const createContext = (): TemporalContext => ({
13
- blackboard: new ScopedBlackboard(),
14
- treeRegistry: new Registry(),
15
- signal: new AbortController().signal,
16
- timestamp: Date.now(),
17
- });
18
-
19
- it("should always return SUCCESS", async () => {
20
- const node = new ResumePoint({ id: "test-resume" });
21
- const context = createContext();
22
-
23
- const result = await node.tick(context);
24
-
25
- expect(result).toBe(NodeStatus.SUCCESS);
26
- expect(node.status()).toBe(NodeStatus.SUCCESS);
27
- });
28
-
29
- it("should store the resumePointId", () => {
30
- const node = new ResumePoint({ id: "my-custom-id" });
31
-
32
- expect(node.resumePointId).toBe("my-custom-id");
33
- expect(node.id).toBe("resume-point-my-custom-id");
34
- });
35
-
36
- it("should not affect tree execution flow", async () => {
37
- const node = new ResumePoint({ id: "marker" });
38
- const context = createContext();
39
-
40
- // Execute multiple times - should always succeed
41
- const result1 = await node.tick(context);
42
- const result2 = await node.tick(context);
43
- const result3 = await node.tick(context);
44
-
45
- expect(result1).toBe(NodeStatus.SUCCESS);
46
- expect(result2).toBe(NodeStatus.SUCCESS);
47
- expect(result3).toBe(NodeStatus.SUCCESS);
48
- });
49
- });
@@ -1,29 +0,0 @@
1
- /**
2
- * ResumePoint - Marker node for resume location
3
- * Always returns SUCCESS, used purely as a findable marker for LLM-based resume
4
- */
5
-
6
- import { ActionNode } from "../base-node.js";
7
- import { type TemporalContext, NodeStatus } from "../types.js";
8
-
9
- export interface ResumePointConfig {
10
- id: string;
11
- }
12
-
13
- /**
14
- * ResumePoint is a marker node that LLM agents can insert to indicate
15
- * where execution should resume from. It always returns SUCCESS.
16
- */
17
- export class ResumePoint extends ActionNode {
18
- readonly resumePointId: string;
19
-
20
- constructor(config: ResumePointConfig) {
21
- super({ id: `resume-point-${config.id}` });
22
- this.resumePointId = config.id;
23
- }
24
-
25
- async executeTick(_context: TemporalContext): Promise<NodeStatus> {
26
- this._status = NodeStatus.SUCCESS;
27
- return NodeStatus.SUCCESS;
28
- }
29
- }
@@ -1,21 +0,0 @@
1
- /**
2
- * Delay decorator configuration schema
3
- */
4
-
5
- import { z } from "zod";
6
- import { createNodeSchema, validations } from "../schemas/base.schema.js";
7
-
8
- /**
9
- * Schema for Delay decorator configuration
10
- * Validates that delayMs is non-negative (can be 0)
11
- */
12
- export const delayConfigurationSchema = createNodeSchema("Delay", {
13
- delayMs: validations.nonNegativeNumber("delayMs"),
14
- });
15
-
16
- /**
17
- * Validated Delay configuration type
18
- */
19
- export type ValidatedDelayConfiguration = z.infer<
20
- typeof delayConfigurationSchema
21
- >;