yaml-flow 2.8.0 → 3.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.
Files changed (39) hide show
  1. package/README.md +168 -3
  2. package/dist/{constants-BEbO2_OK.d.ts → constants-B_ftYTTE.d.ts} +36 -6
  3. package/dist/{constants-BNjeIlZ8.d.cts → constants-CiyHX8L-.d.cts} +36 -6
  4. package/dist/continuous-event-graph/index.cjs +399 -42
  5. package/dist/continuous-event-graph/index.cjs.map +1 -1
  6. package/dist/continuous-event-graph/index.d.cts +124 -5
  7. package/dist/continuous-event-graph/index.d.ts +124 -5
  8. package/dist/continuous-event-graph/index.js +396 -43
  9. package/dist/continuous-event-graph/index.js.map +1 -1
  10. package/dist/event-graph/index.cjs +6784 -44
  11. package/dist/event-graph/index.cjs.map +1 -1
  12. package/dist/event-graph/index.d.cts +5 -5
  13. package/dist/event-graph/index.d.ts +5 -5
  14. package/dist/event-graph/index.js +6777 -43
  15. package/dist/event-graph/index.js.map +1 -1
  16. package/dist/index.cjs +946 -91
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +5 -5
  19. package/dist/index.d.ts +5 -5
  20. package/dist/index.js +938 -91
  21. package/dist/index.js.map +1 -1
  22. package/dist/inference/index.cjs +17 -8
  23. package/dist/inference/index.cjs.map +1 -1
  24. package/dist/inference/index.d.cts +2 -2
  25. package/dist/inference/index.d.ts +2 -2
  26. package/dist/inference/index.js +17 -8
  27. package/dist/inference/index.js.map +1 -1
  28. package/dist/step-machine/index.cjs +6600 -0
  29. package/dist/step-machine/index.cjs.map +1 -1
  30. package/dist/step-machine/index.d.cts +26 -1
  31. package/dist/step-machine/index.d.ts +26 -1
  32. package/dist/step-machine/index.js +6596 -1
  33. package/dist/step-machine/index.js.map +1 -1
  34. package/dist/{types-DAI_a2as.d.ts → types-BpWrH1sf.d.cts} +16 -7
  35. package/dist/{types-DAI_a2as.d.cts → types-BpWrH1sf.d.ts} +16 -7
  36. package/dist/{types-mS_pPftm.d.ts → types-BuEo3wVG.d.ts} +1 -1
  37. package/dist/{types-C2lOwquM.d.cts → types-CxJg9Jrt.d.cts} +1 -1
  38. package/package.json +1 -1
  39. package/schema/event-graph.schema.json +254 -0
package/dist/index.cjs CHANGED
@@ -1,7 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var child_process = require('child_process');
4
3
  var addFormats = require('ajv-formats');
4
+ var fs = require('fs');
5
+ var child_process = require('child_process');
5
6
 
6
7
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
8
 
@@ -3917,7 +3918,7 @@ var require_core = __commonJS({
3917
3918
  uriResolver
3918
3919
  };
3919
3920
  }
3920
- var Ajv2 = class {
3921
+ var Ajv4 = class {
3921
3922
  constructor(opts = {}) {
3922
3923
  this.schemas = {};
3923
3924
  this.refs = {};
@@ -4287,9 +4288,9 @@ var require_core = __commonJS({
4287
4288
  }
4288
4289
  }
4289
4290
  };
4290
- Ajv2.ValidationError = validation_error_1.default;
4291
- Ajv2.MissingRefError = ref_error_1.default;
4292
- exports$1.default = Ajv2;
4291
+ Ajv4.ValidationError = validation_error_1.default;
4292
+ Ajv4.MissingRefError = ref_error_1.default;
4293
+ exports$1.default = Ajv4;
4293
4294
  function checkOptions(checkOpts, options, msg, log = "error") {
4294
4295
  for (const key in checkOpts) {
4295
4296
  const opt = key;
@@ -6360,7 +6361,7 @@ var require_ajv = __commonJS({
6360
6361
  var draft7MetaSchema = require_json_schema_draft_07();
6361
6362
  var META_SUPPORT_DATA = ["/properties"];
6362
6363
  var META_SCHEMA_ID = "http://json-schema.org/draft-07/schema";
6363
- var Ajv2 = class extends core_1.default {
6364
+ var Ajv4 = class extends core_1.default {
6364
6365
  _addVocabularies() {
6365
6366
  super._addVocabularies();
6366
6367
  draft7_1.default.forEach((v) => this.addVocabulary(v));
@@ -6379,11 +6380,11 @@ var require_ajv = __commonJS({
6379
6380
  return this.opts.defaultMeta = super.defaultMeta() || (this.getSchema(META_SCHEMA_ID) ? META_SCHEMA_ID : void 0);
6380
6381
  }
6381
6382
  };
6382
- exports$1.Ajv = Ajv2;
6383
- module.exports = exports$1 = Ajv2;
6384
- module.exports.Ajv = Ajv2;
6383
+ exports$1.Ajv = Ajv4;
6384
+ module.exports = exports$1 = Ajv4;
6385
+ module.exports.Ajv = Ajv4;
6385
6386
  Object.defineProperty(exports$1, "__esModule", { value: true });
6386
- exports$1.default = Ajv2;
6387
+ exports$1.default = Ajv4;
6387
6388
  var validate_1 = require_validate();
6388
6389
  Object.defineProperty(exports$1, "KeywordCxt", { enumerable: true, get: function() {
6389
6390
  return validate_1.KeywordCxt;
@@ -6917,6 +6918,188 @@ async function loadStepFlow(source) {
6917
6918
  return flow;
6918
6919
  }
6919
6920
 
6921
+ // schema/flow.schema.json
6922
+ var flow_schema_default = {
6923
+ $schema: "http://json-schema.org/draft-07/schema#",
6924
+ $id: "https://github.com/yaml-flow/schema/flow.json",
6925
+ title: "YamlFlow Configuration",
6926
+ description: "Schema for yaml-flow workflow definitions",
6927
+ type: "object",
6928
+ required: ["settings", "steps", "terminal_states"],
6929
+ properties: {
6930
+ id: {
6931
+ type: "string",
6932
+ description: "Optional flow identifier"
6933
+ },
6934
+ settings: {
6935
+ type: "object",
6936
+ description: "Flow-level settings",
6937
+ required: ["start_step"],
6938
+ properties: {
6939
+ start_step: {
6940
+ type: "string",
6941
+ description: "Step to start execution from"
6942
+ },
6943
+ max_total_steps: {
6944
+ type: "integer",
6945
+ minimum: 1,
6946
+ default: 100,
6947
+ description: "Maximum steps before forced termination"
6948
+ },
6949
+ timeout_ms: {
6950
+ type: "integer",
6951
+ minimum: 0,
6952
+ description: "Flow timeout in milliseconds"
6953
+ }
6954
+ },
6955
+ additionalProperties: false
6956
+ },
6957
+ steps: {
6958
+ type: "object",
6959
+ description: "Step definitions",
6960
+ minProperties: 1,
6961
+ additionalProperties: {
6962
+ $ref: "#/definitions/step"
6963
+ }
6964
+ },
6965
+ terminal_states: {
6966
+ type: "object",
6967
+ description: "Terminal state definitions",
6968
+ minProperties: 1,
6969
+ additionalProperties: {
6970
+ $ref: "#/definitions/terminal_state"
6971
+ }
6972
+ }
6973
+ },
6974
+ additionalProperties: false,
6975
+ definitions: {
6976
+ step: {
6977
+ type: "object",
6978
+ description: "Individual step configuration",
6979
+ required: ["transitions"],
6980
+ properties: {
6981
+ description: {
6982
+ type: "string",
6983
+ description: "Human-readable description"
6984
+ },
6985
+ expects_data: {
6986
+ type: "array",
6987
+ items: { type: "string" },
6988
+ description: "Data keys this step expects as input"
6989
+ },
6990
+ produces_data: {
6991
+ type: "array",
6992
+ items: { type: "string" },
6993
+ description: "Data keys this step produces as output"
6994
+ },
6995
+ transitions: {
6996
+ type: "object",
6997
+ description: "Mapping of result -> next step name",
6998
+ additionalProperties: { type: "string" },
6999
+ minProperties: 1
7000
+ },
7001
+ retry: {
7002
+ $ref: "#/definitions/retry_config"
7003
+ },
7004
+ circuit_breaker: {
7005
+ $ref: "#/definitions/circuit_breaker_config"
7006
+ }
7007
+ },
7008
+ additionalProperties: false
7009
+ },
7010
+ terminal_state: {
7011
+ type: "object",
7012
+ description: "Terminal state configuration",
7013
+ required: ["return_intent"],
7014
+ properties: {
7015
+ description: {
7016
+ type: "string",
7017
+ description: "Human-readable description"
7018
+ },
7019
+ return_intent: {
7020
+ type: "string",
7021
+ description: "Intent/status to return (e.g., 'success', 'error')"
7022
+ },
7023
+ return_artifacts: {
7024
+ oneOf: [
7025
+ { type: "string" },
7026
+ { type: "array", items: { type: "string" } },
7027
+ { type: "boolean", const: false }
7028
+ ],
7029
+ description: "Data key(s) to include in result, or false to exclude"
7030
+ },
7031
+ expects_data: {
7032
+ type: "array",
7033
+ items: { type: "string" },
7034
+ description: "Data keys this terminal state expects"
7035
+ }
7036
+ },
7037
+ additionalProperties: false
7038
+ },
7039
+ retry_config: {
7040
+ type: "object",
7041
+ description: "Retry configuration for step failures",
7042
+ required: ["max_attempts"],
7043
+ properties: {
7044
+ max_attempts: {
7045
+ type: "integer",
7046
+ minimum: 1,
7047
+ description: "Maximum retry attempts"
7048
+ },
7049
+ delay_ms: {
7050
+ type: "integer",
7051
+ minimum: 0,
7052
+ description: "Delay between retries in ms"
7053
+ },
7054
+ backoff_multiplier: {
7055
+ type: "number",
7056
+ minimum: 1,
7057
+ description: "Backoff multiplier (e.g., 2 for exponential)"
7058
+ }
7059
+ },
7060
+ additionalProperties: false
7061
+ },
7062
+ circuit_breaker_config: {
7063
+ type: "object",
7064
+ description: "Circuit breaker configuration for loops",
7065
+ required: ["max_iterations", "on_open"],
7066
+ properties: {
7067
+ max_iterations: {
7068
+ type: "integer",
7069
+ minimum: 1,
7070
+ description: "Maximum iterations before circuit opens"
7071
+ },
7072
+ on_open: {
7073
+ type: "string",
7074
+ description: "Step to transition to when circuit opens"
7075
+ }
7076
+ },
7077
+ additionalProperties: false
7078
+ }
7079
+ }
7080
+ };
7081
+
7082
+ // src/step-machine/schema-validator.ts
7083
+ var import_ajv = __toESM(require_ajv());
7084
+ var _compiled = null;
7085
+ function getValidator() {
7086
+ if (_compiled) return _compiled;
7087
+ const ajv = new import_ajv.default({ allErrors: true });
7088
+ addFormats__default.default(ajv);
7089
+ _compiled = ajv.compile(flow_schema_default);
7090
+ return _compiled;
7091
+ }
7092
+ function validateFlowSchema(config) {
7093
+ const validate = getValidator();
7094
+ const valid = validate(config);
7095
+ if (valid) return { ok: true, errors: [] };
7096
+ const errors = (validate.errors ?? []).map((e) => {
7097
+ const path = e.instancePath || "/";
7098
+ return `${path}: ${e.message ?? "unknown error"}`;
7099
+ });
7100
+ return { ok: false, errors };
7101
+ }
7102
+
6920
7103
  // src/event-graph/constants.ts
6921
7104
  var TASK_STATUS = {
6922
7105
  NOT_STARTED: "not-started",
@@ -6993,15 +7176,14 @@ function isTaskCompleted(taskState) {
6993
7176
  function isTaskRunning(taskState) {
6994
7177
  return taskState?.status === TASK_STATUS.RUNNING;
6995
7178
  }
6996
- function isRepeatableTask(taskConfig) {
6997
- return taskConfig.repeatable === true || typeof taskConfig.repeatable === "object" && taskConfig.repeatable !== null;
7179
+ function getRefreshStrategy(taskConfig, graphSettings) {
7180
+ return taskConfig.refreshStrategy ?? graphSettings?.refreshStrategy ?? "data-changed";
6998
7181
  }
6999
- function getRepeatableMax(taskConfig) {
7000
- if (taskConfig.repeatable === true) return void 0;
7001
- if (typeof taskConfig.repeatable === "object" && taskConfig.repeatable !== null) {
7002
- return taskConfig.repeatable.max;
7003
- }
7004
- return void 0;
7182
+ function isRerunnable(taskConfig, graphSettings) {
7183
+ return getRefreshStrategy(taskConfig, graphSettings) !== "once";
7184
+ }
7185
+ function getMaxExecutions(taskConfig) {
7186
+ return taskConfig.maxExecutions;
7005
7187
  }
7006
7188
  function computeAvailableOutputs(graph, taskStates) {
7007
7189
  const outputs = /* @__PURE__ */ new Set();
@@ -7433,48 +7615,88 @@ function getCandidateTasks(graph, state) {
7433
7615
  const candidates = [];
7434
7616
  for (const [taskName, taskConfig] of Object.entries(graphTasks)) {
7435
7617
  const taskState = state.tasks[taskName];
7436
- if (!isRepeatableTask(taskConfig)) {
7437
- if (taskState?.status === TASK_STATUS.COMPLETED || taskState?.status === TASK_STATUS.RUNNING || isNonActiveTask(taskState)) {
7438
- continue;
7439
- }
7440
- } else {
7441
- if (taskState?.status === TASK_STATUS.RUNNING || isNonActiveTask(taskState)) {
7442
- continue;
7443
- }
7444
- const maxExec = getRepeatableMax(taskConfig);
7445
- if (maxExec !== void 0 && taskState && taskState.executionCount >= maxExec) {
7618
+ const strategy = getRefreshStrategy(taskConfig, graph.settings);
7619
+ const rerunnable = strategy !== "once";
7620
+ if (taskState?.status === TASK_STATUS.RUNNING || isNonActiveTask(taskState)) {
7621
+ continue;
7622
+ }
7623
+ const maxExec = getMaxExecutions(taskConfig);
7624
+ if (maxExec !== void 0 && taskState && taskState.executionCount >= maxExec) {
7625
+ continue;
7626
+ }
7627
+ if (taskConfig.circuit_breaker && taskState && taskState.executionCount >= taskConfig.circuit_breaker.max_executions) {
7628
+ continue;
7629
+ }
7630
+ if (!rerunnable) {
7631
+ if (taskState?.status === TASK_STATUS.COMPLETED) {
7446
7632
  continue;
7447
7633
  }
7448
- if (taskConfig.circuit_breaker) {
7449
- if (taskState && taskState.executionCount >= taskConfig.circuit_breaker.max_executions) {
7450
- continue;
7634
+ }
7635
+ if (rerunnable && taskState?.status === TASK_STATUS.COMPLETED) {
7636
+ const requires2 = getRequires(taskConfig);
7637
+ switch (strategy) {
7638
+ case "data-changed": {
7639
+ if (requires2.length > 0) {
7640
+ const hasChangedData = requires2.some((req) => {
7641
+ for (const [otherName, otherConfig] of Object.entries(graphTasks)) {
7642
+ if (getProvides(otherConfig).includes(req)) {
7643
+ const otherState = state.tasks[otherName];
7644
+ if (!otherState) continue;
7645
+ const consumed = taskState.lastConsumedHashes?.[req];
7646
+ if (otherState.lastDataHash == null) {
7647
+ return otherState.executionCount > taskState.lastEpoch;
7648
+ }
7649
+ return otherState.lastDataHash !== consumed;
7650
+ }
7651
+ }
7652
+ return false;
7653
+ });
7654
+ if (!hasChangedData) continue;
7655
+ } else {
7656
+ continue;
7657
+ }
7658
+ break;
7451
7659
  }
7452
- }
7453
- if (taskState?.status === TASK_STATUS.COMPLETED) {
7454
- const requires2 = getRequires(taskConfig);
7455
- if (requires2.length > 0) {
7456
- const hasRefreshedInputs = requires2.some((req) => {
7457
- for (const [otherName, otherConfig] of Object.entries(graphTasks)) {
7458
- if (getProvides(otherConfig).includes(req)) {
7459
- const otherState = state.tasks[otherName];
7460
- if (otherState && otherState.executionCount > taskState.lastEpoch) {
7461
- return true;
7660
+ case "epoch-changed": {
7661
+ if (requires2.length > 0) {
7662
+ const hasRefreshedInputs = requires2.some((req) => {
7663
+ for (const [otherName, otherConfig] of Object.entries(graphTasks)) {
7664
+ if (getProvides(otherConfig).includes(req)) {
7665
+ const otherState = state.tasks[otherName];
7666
+ if (otherState && otherState.executionCount > taskState.lastEpoch) {
7667
+ return true;
7668
+ }
7462
7669
  }
7463
7670
  }
7464
- }
7465
- return false;
7466
- });
7467
- if (!hasRefreshedInputs) continue;
7468
- } else {
7671
+ return false;
7672
+ });
7673
+ if (!hasRefreshedInputs) continue;
7674
+ } else {
7675
+ continue;
7676
+ }
7677
+ break;
7678
+ }
7679
+ case "time-based": {
7680
+ const interval = taskConfig.refreshInterval ?? 0;
7681
+ if (interval <= 0) continue;
7682
+ const completedAt = taskState.completedAt;
7683
+ if (!completedAt) continue;
7684
+ const elapsedSec = (Date.now() - Date.parse(completedAt)) / 1e3;
7685
+ if (elapsedSec < interval) continue;
7686
+ break;
7687
+ }
7688
+ case "manual": {
7469
7689
  continue;
7470
7690
  }
7691
+ default:
7692
+ continue;
7471
7693
  }
7472
7694
  }
7473
7695
  const requires = getRequires(taskConfig);
7474
7696
  if (!requires.every((req) => availableOutputs.includes(req))) {
7475
7697
  continue;
7476
7698
  }
7477
- if (!isRepeatableTask(taskConfig)) {
7699
+ if (!rerunnable) {
7478
7700
  const provides = getProvides(taskConfig);
7479
7701
  const allAlreadyAvailable = provides.length > 0 && provides.every((output) => availableOutputs.includes(output));
7480
7702
  if (allAlreadyAvailable) continue;
@@ -7558,7 +7780,7 @@ function applyTaskStart(state, taskName) {
7558
7780
  lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
7559
7781
  };
7560
7782
  }
7561
- function applyTaskCompletion(state, graph, taskName, result) {
7783
+ function applyTaskCompletion(state, graph, taskName, result, dataHash) {
7562
7784
  const existingTask = state.tasks[taskName] ?? createDefaultTaskState2();
7563
7785
  const taskConfig = graph.tasks[taskName];
7564
7786
  if (!taskConfig) {
@@ -7570,6 +7792,19 @@ function applyTaskCompletion(state, graph, taskName, result) {
7570
7792
  } else {
7571
7793
  outputTokens = getProvides(taskConfig);
7572
7794
  }
7795
+ const lastConsumedHashes = { ...existingTask.lastConsumedHashes };
7796
+ const requires = taskConfig.requires ?? [];
7797
+ for (const token of requires) {
7798
+ for (const [otherName, otherConfig] of Object.entries(graph.tasks)) {
7799
+ if (getProvides(otherConfig).includes(token)) {
7800
+ const otherState = state.tasks[otherName];
7801
+ if (otherState?.lastDataHash) {
7802
+ lastConsumedHashes[token] = otherState.lastDataHash;
7803
+ }
7804
+ break;
7805
+ }
7806
+ }
7807
+ }
7573
7808
  const updatedTask = {
7574
7809
  ...existingTask,
7575
7810
  status: "completed",
@@ -7577,11 +7812,10 @@ function applyTaskCompletion(state, graph, taskName, result) {
7577
7812
  lastUpdated: (/* @__PURE__ */ new Date()).toISOString(),
7578
7813
  executionCount: existingTask.executionCount + 1,
7579
7814
  lastEpoch: existingTask.executionCount + 1,
7815
+ lastDataHash: dataHash,
7816
+ lastConsumedHashes,
7580
7817
  error: void 0
7581
7818
  };
7582
- if (isRepeatableTask(taskConfig)) {
7583
- updatedTask.status = "not-started";
7584
- }
7585
7819
  const newOutputs = [.../* @__PURE__ */ new Set([...state.availableOutputs, ...outputTokens])];
7586
7820
  return {
7587
7821
  ...state,
@@ -7670,7 +7904,7 @@ function apply(state, event, graph) {
7670
7904
  case "task-started":
7671
7905
  return applyTaskStart(state, event.taskName);
7672
7906
  case "task-completed":
7673
- return applyTaskCompletion(state, graph, event.taskName, event.result);
7907
+ return applyTaskCompletion(state, graph, event.taskName, event.result, event.dataHash);
7674
7908
  case "task-failed":
7675
7909
  return applyTaskFailure(state, graph, event.taskName, event.error);
7676
7910
  case "task-progress":
@@ -8360,6 +8594,276 @@ function buildResult(issues) {
8360
8594
  };
8361
8595
  }
8362
8596
 
8597
+ // schema/event-graph.schema.json
8598
+ var event_graph_schema_default = {
8599
+ $schema: "http://json-schema.org/draft-07/schema#",
8600
+ $id: "https://github.com/yaml-flow/schema/event-graph.json",
8601
+ title: "Event Graph Configuration",
8602
+ description: "Schema for stateless event-graph (DAG) workflow definitions in yaml-flow",
8603
+ type: "object",
8604
+ required: ["settings", "tasks"],
8605
+ additionalProperties: false,
8606
+ properties: {
8607
+ id: {
8608
+ type: "string",
8609
+ description: "Optional graph identifier"
8610
+ },
8611
+ settings: {
8612
+ $ref: "#/definitions/settings"
8613
+ },
8614
+ tasks: {
8615
+ type: "object",
8616
+ description: "Task definitions keyed by name",
8617
+ minProperties: 1,
8618
+ additionalProperties: {
8619
+ $ref: "#/definitions/task"
8620
+ }
8621
+ }
8622
+ },
8623
+ definitions: {
8624
+ settings: {
8625
+ type: "object",
8626
+ required: ["completion"],
8627
+ properties: {
8628
+ completion: {
8629
+ type: "string",
8630
+ enum: [
8631
+ "all-tasks-done",
8632
+ "all-outputs-done",
8633
+ "only-resolved",
8634
+ "goal-reached",
8635
+ "manual"
8636
+ ],
8637
+ description: "Completion strategy"
8638
+ },
8639
+ conflict_strategy: {
8640
+ type: "string",
8641
+ enum: [
8642
+ "alphabetical",
8643
+ "priority-first",
8644
+ "duration-first",
8645
+ "cost-optimized",
8646
+ "resource-aware",
8647
+ "random-select",
8648
+ "user-choice",
8649
+ "parallel-all",
8650
+ "skip-conflicts",
8651
+ "round-robin"
8652
+ ],
8653
+ description: "Conflict resolution strategy"
8654
+ },
8655
+ execution_mode: {
8656
+ type: "string",
8657
+ enum: ["dependency-mode", "eligibility-mode"],
8658
+ description: "Execution mode"
8659
+ },
8660
+ goal: {
8661
+ type: "array",
8662
+ items: { type: "string" },
8663
+ minItems: 1,
8664
+ description: "Goal outputs \u2014 required when completion is 'goal-reached'"
8665
+ },
8666
+ max_iterations: {
8667
+ type: "integer",
8668
+ minimum: 1,
8669
+ description: "Max scheduler iterations (safety limit, default: 1000)"
8670
+ },
8671
+ timeout_ms: {
8672
+ type: "integer",
8673
+ minimum: 0,
8674
+ description: "Timeout in ms (declared for drivers, not enforced by pure engine)"
8675
+ },
8676
+ refreshStrategy: {
8677
+ $ref: "#/definitions/refresh_strategy",
8678
+ description: "Default refresh strategy for all tasks (default: 'data-changed')"
8679
+ }
8680
+ },
8681
+ additionalProperties: false,
8682
+ if: {
8683
+ properties: { completion: { const: "goal-reached" } }
8684
+ },
8685
+ then: {
8686
+ required: ["completion", "goal"]
8687
+ }
8688
+ },
8689
+ task: {
8690
+ type: "object",
8691
+ required: ["provides"],
8692
+ properties: {
8693
+ requires: {
8694
+ type: "array",
8695
+ items: { type: "string" },
8696
+ description: "Tokens this task needs to become eligible"
8697
+ },
8698
+ provides: {
8699
+ type: "array",
8700
+ items: { type: "string" },
8701
+ description: "Tokens this task produces on successful completion"
8702
+ },
8703
+ on: {
8704
+ type: "object",
8705
+ description: "Conditional provides based on handler result key",
8706
+ additionalProperties: {
8707
+ type: "array",
8708
+ items: { type: "string" }
8709
+ }
8710
+ },
8711
+ on_failure: {
8712
+ type: "array",
8713
+ items: { type: "string" },
8714
+ description: "Tokens to inject when this task fails"
8715
+ },
8716
+ method: {
8717
+ type: "string",
8718
+ description: "Task execution method (informational \u2014 driver concern)"
8719
+ },
8720
+ config: {
8721
+ type: "object",
8722
+ description: "Arbitrary task configuration (driver concern)"
8723
+ },
8724
+ priority: {
8725
+ type: "number",
8726
+ description: "Higher = preferred in conflict resolution"
8727
+ },
8728
+ estimatedDuration: {
8729
+ type: "number",
8730
+ minimum: 0,
8731
+ description: "Estimated duration in ms (used by duration-first strategy)"
8732
+ },
8733
+ estimatedCost: {
8734
+ type: "number",
8735
+ minimum: 0,
8736
+ description: "Estimated cost (used by cost-optimized strategy)"
8737
+ },
8738
+ estimatedResources: {
8739
+ type: "object",
8740
+ additionalProperties: { type: "number" },
8741
+ description: "Resource requirements (used by resource-aware strategy)"
8742
+ },
8743
+ retry: {
8744
+ $ref: "#/definitions/task_retry"
8745
+ },
8746
+ refreshStrategy: {
8747
+ $ref: "#/definitions/refresh_strategy",
8748
+ description: "Task-level refresh strategy (overrides settings default)"
8749
+ },
8750
+ refreshInterval: {
8751
+ type: "number",
8752
+ minimum: 0,
8753
+ description: "Interval in seconds for time-based refresh strategy"
8754
+ },
8755
+ maxExecutions: {
8756
+ type: "integer",
8757
+ minimum: 1,
8758
+ description: "Maximum number of times this task can execute"
8759
+ },
8760
+ circuit_breaker: {
8761
+ $ref: "#/definitions/task_circuit_breaker"
8762
+ },
8763
+ description: {
8764
+ type: "string",
8765
+ description: "Human-readable description"
8766
+ },
8767
+ inference: {
8768
+ $ref: "#/definitions/inference_hints"
8769
+ }
8770
+ },
8771
+ additionalProperties: false
8772
+ },
8773
+ task_retry: {
8774
+ type: "object",
8775
+ required: ["max_attempts"],
8776
+ properties: {
8777
+ max_attempts: {
8778
+ type: "integer",
8779
+ minimum: 1,
8780
+ description: "Maximum retry attempts"
8781
+ },
8782
+ delay_ms: {
8783
+ type: "integer",
8784
+ minimum: 0,
8785
+ description: "Delay between retries in ms"
8786
+ },
8787
+ backoff_multiplier: {
8788
+ type: "number",
8789
+ minimum: 1,
8790
+ description: "Backoff multiplier (e.g., 2 for exponential)"
8791
+ }
8792
+ },
8793
+ additionalProperties: false
8794
+ },
8795
+ refresh_strategy: {
8796
+ type: "string",
8797
+ enum: ["data-changed", "epoch-changed", "time-based", "manual", "once"],
8798
+ description: "Strategy for determining when a completed task should re-run"
8799
+ },
8800
+ task_circuit_breaker: {
8801
+ type: "object",
8802
+ required: ["max_executions", "on_break"],
8803
+ properties: {
8804
+ max_executions: {
8805
+ type: "integer",
8806
+ minimum: 1,
8807
+ description: "Max executions before breaker trips"
8808
+ },
8809
+ on_break: {
8810
+ type: "array",
8811
+ items: { type: "string" },
8812
+ minItems: 1,
8813
+ description: "Tokens to inject when breaker trips"
8814
+ }
8815
+ },
8816
+ additionalProperties: false
8817
+ },
8818
+ inference_hints: {
8819
+ type: "object",
8820
+ description: "LLM inference hints \u2014 opt-in metadata for AI-assisted completion detection",
8821
+ properties: {
8822
+ criteria: {
8823
+ type: "string",
8824
+ description: "Human-readable completion criteria"
8825
+ },
8826
+ keywords: {
8827
+ type: "array",
8828
+ items: { type: "string" },
8829
+ description: "Keywords to help the LLM understand the domain"
8830
+ },
8831
+ suggestedChecks: {
8832
+ type: "array",
8833
+ items: { type: "string" },
8834
+ description: "Suggested checks for verification"
8835
+ },
8836
+ autoDetectable: {
8837
+ type: "boolean",
8838
+ description: "Whether the LLM should attempt to auto-detect completion (default: false)"
8839
+ }
8840
+ },
8841
+ additionalProperties: false
8842
+ }
8843
+ }
8844
+ };
8845
+
8846
+ // src/event-graph/schema-validator.ts
8847
+ var import_ajv2 = __toESM(require_ajv());
8848
+ var _compiled2 = null;
8849
+ function getValidator2() {
8850
+ if (_compiled2) return _compiled2;
8851
+ const ajv = new import_ajv2.default({ allErrors: true });
8852
+ addFormats__default.default(ajv);
8853
+ _compiled2 = ajv.compile(event_graph_schema_default);
8854
+ return _compiled2;
8855
+ }
8856
+ function validateGraphSchema(config) {
8857
+ const validate = getValidator2();
8858
+ const valid = validate(config);
8859
+ if (valid) return { ok: true, errors: [] };
8860
+ const errors = (validate.errors ?? []).map((e) => {
8861
+ const path = e.instancePath || "/";
8862
+ return `${path}: ${e.message ?? "unknown error"}`;
8863
+ });
8864
+ return { ok: false, errors };
8865
+ }
8866
+
8363
8867
  // src/stores/localStorage.ts
8364
8868
  var LocalStorageStore = class {
8365
8869
  prefix;
@@ -8753,7 +9257,7 @@ function applyEvent(live, event) {
8753
9257
  newState = applyTaskStart(state, event.taskName);
8754
9258
  break;
8755
9259
  case "task-completed":
8756
- newState = applyTaskCompletion(state, config, event.taskName, event.result);
9260
+ newState = applyTaskCompletion(state, config, event.taskName, event.result, event.dataHash);
8757
9261
  break;
8758
9262
  case "task-failed":
8759
9263
  newState = applyTaskFailure(state, config, event.taskName, event.error);
@@ -8776,6 +9280,9 @@ function applyEvent(live, event) {
8776
9280
  }
8777
9281
  return { config, state: newState };
8778
9282
  }
9283
+ function applyEvents(live, events) {
9284
+ return events.reduce((current, event) => applyEvent(current, event), live);
9285
+ }
8779
9286
  function addNode(live, name, taskConfig) {
8780
9287
  if (live.config.tasks[name]) return live;
8781
9288
  return {
@@ -9020,38 +9527,84 @@ function schedule(live) {
9020
9527
  const blocked = [];
9021
9528
  for (const [taskName, taskConfig] of Object.entries(graphTasks)) {
9022
9529
  const taskState = state.tasks[taskName];
9023
- if (!isRepeatableTask(taskConfig)) {
9024
- if (taskState?.status === TASK_STATUS.COMPLETED || taskState?.status === TASK_STATUS.RUNNING || isNonActiveTask(taskState)) {
9025
- continue;
9026
- }
9027
- } else {
9028
- if (taskState?.status === TASK_STATUS.RUNNING || isNonActiveTask(taskState)) {
9029
- continue;
9030
- }
9031
- const maxExec = getRepeatableMax(taskConfig);
9032
- if (maxExec !== void 0 && taskState && taskState.executionCount >= maxExec) {
9033
- continue;
9034
- }
9035
- if (taskConfig.circuit_breaker && taskState && taskState.executionCount >= taskConfig.circuit_breaker.max_executions) {
9036
- continue;
9037
- }
9038
- if (taskState?.status === TASK_STATUS.COMPLETED) {
9039
- const requires2 = getRequires(taskConfig);
9040
- if (requires2.length > 0) {
9041
- const hasRefreshed = requires2.some((req) => {
9042
- for (const [otherName, otherConfig] of Object.entries(graphTasks)) {
9043
- if (getProvides(otherConfig).includes(req)) {
9044
- const otherState = state.tasks[otherName];
9045
- if (otherState && otherState.executionCount > taskState.lastEpoch) return true;
9530
+ const strategy = getRefreshStrategy(taskConfig, config.settings);
9531
+ const rerunnable = strategy !== "once";
9532
+ if (taskState?.status === TASK_STATUS.RUNNING || isNonActiveTask(taskState)) {
9533
+ continue;
9534
+ }
9535
+ const maxExec = getMaxExecutions(taskConfig);
9536
+ if (maxExec !== void 0 && taskState && taskState.executionCount >= maxExec) {
9537
+ continue;
9538
+ }
9539
+ if (taskConfig.circuit_breaker && taskState && taskState.executionCount >= taskConfig.circuit_breaker.max_executions) {
9540
+ continue;
9541
+ }
9542
+ if (!rerunnable && taskState?.status === TASK_STATUS.COMPLETED) {
9543
+ continue;
9544
+ }
9545
+ if (rerunnable && taskState?.status === TASK_STATUS.COMPLETED) {
9546
+ const requires2 = getRequires(taskConfig);
9547
+ let shouldSkip = false;
9548
+ switch (strategy) {
9549
+ case "data-changed": {
9550
+ if (requires2.length > 0) {
9551
+ const hasChangedData = requires2.some((req) => {
9552
+ for (const [otherName, otherConfig] of Object.entries(graphTasks)) {
9553
+ if (getProvides(otherConfig).includes(req)) {
9554
+ const otherState = state.tasks[otherName];
9555
+ if (!otherState) continue;
9556
+ const consumed = taskState.lastConsumedHashes?.[req];
9557
+ if (otherState.lastDataHash == null) {
9558
+ return otherState.executionCount > taskState.lastEpoch;
9559
+ }
9560
+ return otherState.lastDataHash !== consumed;
9561
+ }
9046
9562
  }
9047
- }
9048
- return false;
9049
- });
9050
- if (!hasRefreshed) continue;
9051
- } else {
9052
- continue;
9563
+ return false;
9564
+ });
9565
+ if (!hasChangedData) shouldSkip = true;
9566
+ } else {
9567
+ shouldSkip = true;
9568
+ }
9569
+ break;
9053
9570
  }
9571
+ case "epoch-changed": {
9572
+ if (requires2.length > 0) {
9573
+ const hasRefreshed = requires2.some((req) => {
9574
+ for (const [otherName, otherConfig] of Object.entries(graphTasks)) {
9575
+ if (getProvides(otherConfig).includes(req)) {
9576
+ const otherState = state.tasks[otherName];
9577
+ if (otherState && otherState.executionCount > taskState.lastEpoch) return true;
9578
+ }
9579
+ }
9580
+ return false;
9581
+ });
9582
+ if (!hasRefreshed) shouldSkip = true;
9583
+ } else {
9584
+ shouldSkip = true;
9585
+ }
9586
+ break;
9587
+ }
9588
+ case "time-based": {
9589
+ const interval = taskConfig.refreshInterval ?? 0;
9590
+ if (interval <= 0) {
9591
+ shouldSkip = true;
9592
+ break;
9593
+ }
9594
+ const completedAt = taskState.completedAt;
9595
+ if (!completedAt) {
9596
+ shouldSkip = true;
9597
+ break;
9598
+ }
9599
+ const elapsedSec = (Date.now() - Date.parse(completedAt)) / 1e3;
9600
+ if (elapsedSec < interval) shouldSkip = true;
9601
+ break;
9602
+ }
9603
+ case "manual":
9604
+ shouldSkip = true;
9605
+ break;
9054
9606
  }
9607
+ if (shouldSkip) continue;
9055
9608
  }
9056
9609
  const requires = getRequires(taskConfig);
9057
9610
  if (requires.length === 0) {
@@ -9446,6 +9999,300 @@ function getDownstream(live, nodeName) {
9446
9999
  }));
9447
10000
  return { nodeName, nodes, tokens: [...tokenSet] };
9448
10001
  }
10002
+ var MemoryJournal = class {
10003
+ buffer = [];
10004
+ append(event) {
10005
+ this.buffer.push(event);
10006
+ }
10007
+ drain() {
10008
+ const events = this.buffer;
10009
+ this.buffer = [];
10010
+ return events;
10011
+ }
10012
+ get size() {
10013
+ return this.buffer.length;
10014
+ }
10015
+ };
10016
+ var FileJournal = class {
10017
+ constructor(path) {
10018
+ this.path = path;
10019
+ if (!fs.existsSync(path)) {
10020
+ fs.writeFileSync(path, "", "utf-8");
10021
+ }
10022
+ }
10023
+ path;
10024
+ pending = 0;
10025
+ append(event) {
10026
+ fs.appendFileSync(this.path, JSON.stringify(event) + "\n", "utf-8");
10027
+ this.pending++;
10028
+ }
10029
+ drain() {
10030
+ const content = fs.readFileSync(this.path, "utf-8").trim();
10031
+ fs.writeFileSync(this.path, "", "utf-8");
10032
+ this.pending = 0;
10033
+ if (!content) return [];
10034
+ return content.split("\n").map((line) => JSON.parse(line));
10035
+ }
10036
+ get size() {
10037
+ try {
10038
+ const content = fs.readFileSync(this.path, "utf-8").trim();
10039
+ if (!content) return 0;
10040
+ return content.split("\n").length;
10041
+ } catch {
10042
+ return this.pending;
10043
+ }
10044
+ }
10045
+ };
10046
+
10047
+ // src/continuous-event-graph/reactive.ts
10048
+ function createReactiveGraph(config, options, executionId) {
10049
+ const {
10050
+ handlers: initialHandlers,
10051
+ maxDispatchRetries = 3,
10052
+ defaultTimeoutMs = 3e4,
10053
+ journal = new MemoryJournal(),
10054
+ onDispatchFailed,
10055
+ onAbandoned,
10056
+ onDrain
10057
+ } = options;
10058
+ let live = createLiveGraph(config, executionId);
10059
+ let disposed = false;
10060
+ const handlers = new Map(Object.entries(initialHandlers));
10061
+ const dispatched = /* @__PURE__ */ new Map();
10062
+ const timeoutTimers = /* @__PURE__ */ new Map();
10063
+ let draining = false;
10064
+ let drainQueued = false;
10065
+ function drain() {
10066
+ if (disposed) return;
10067
+ if (draining) {
10068
+ drainQueued = true;
10069
+ return;
10070
+ }
10071
+ draining = true;
10072
+ try {
10073
+ do {
10074
+ drainQueued = false;
10075
+ drainOnce();
10076
+ } while (drainQueued);
10077
+ } finally {
10078
+ draining = false;
10079
+ }
10080
+ }
10081
+ function drainOnce() {
10082
+ sweepTimeouts();
10083
+ const events = journal.drain();
10084
+ for (const event of events) {
10085
+ if (event.type === "task-completed" || event.type === "task-failed") {
10086
+ const taskName = event.taskName;
10087
+ dispatched.delete(taskName);
10088
+ clearTimeout(timeoutTimers.get(taskName));
10089
+ timeoutTimers.delete(taskName);
10090
+ }
10091
+ }
10092
+ if (events.length > 0) {
10093
+ live = applyEvents(live, events);
10094
+ }
10095
+ const result = schedule(live);
10096
+ if (onDrain && events.length > 0) {
10097
+ onDrain(events, live, result);
10098
+ }
10099
+ for (const taskName of result.eligible) {
10100
+ if (dispatched.has(taskName)) continue;
10101
+ dispatchTask(taskName);
10102
+ }
10103
+ for (const [taskName, entry] of dispatched) {
10104
+ if (entry.status === "retry-queued") {
10105
+ dispatchTask(taskName);
10106
+ }
10107
+ }
10108
+ }
10109
+ function dispatchTask(taskName) {
10110
+ const handler = handlers.get(taskName);
10111
+ if (!handler) {
10112
+ journal.append({
10113
+ type: "task-failed",
10114
+ taskName,
10115
+ error: `No handler registered for task "${taskName}"`,
10116
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
10117
+ });
10118
+ drainQueued = true;
10119
+ return;
10120
+ }
10121
+ const existing = dispatched.get(taskName);
10122
+ const attempt = existing ? existing.dispatchAttempts + 1 : 1;
10123
+ if (attempt > maxDispatchRetries) {
10124
+ dispatched.set(taskName, {
10125
+ status: "abandoned",
10126
+ dispatchedAt: existing?.dispatchedAt ?? Date.now(),
10127
+ dispatchAttempts: attempt - 1,
10128
+ lastError: existing?.lastError
10129
+ });
10130
+ onAbandoned?.(taskName);
10131
+ journal.append({
10132
+ type: "task-failed",
10133
+ taskName,
10134
+ error: `dispatch-abandoned: handler unreachable after ${attempt - 1} attempts${existing?.lastError ? ` (${existing.lastError})` : ""}`,
10135
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
10136
+ });
10137
+ drainQueued = true;
10138
+ return;
10139
+ }
10140
+ dispatched.set(taskName, {
10141
+ status: "initiated",
10142
+ dispatchedAt: Date.now(),
10143
+ dispatchAttempts: attempt
10144
+ });
10145
+ journal.append({
10146
+ type: "task-started",
10147
+ taskName,
10148
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
10149
+ });
10150
+ if (defaultTimeoutMs > 0) {
10151
+ const timer = setTimeout(() => {
10152
+ if (disposed) return;
10153
+ const entry = dispatched.get(taskName);
10154
+ if (entry?.status === "initiated") {
10155
+ dispatched.set(taskName, {
10156
+ ...entry,
10157
+ status: "timed-out"
10158
+ });
10159
+ dispatched.set(taskName, {
10160
+ ...entry,
10161
+ status: entry.dispatchAttempts >= maxDispatchRetries ? "abandoned" : "retry-queued"
10162
+ });
10163
+ if (entry.dispatchAttempts >= maxDispatchRetries) {
10164
+ onAbandoned?.(taskName);
10165
+ journal.append({
10166
+ type: "task-failed",
10167
+ taskName,
10168
+ error: `dispatch-timeout: no callback after ${defaultTimeoutMs}ms (${entry.dispatchAttempts} attempts)`,
10169
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
10170
+ });
10171
+ }
10172
+ drain();
10173
+ }
10174
+ }, defaultTimeoutMs);
10175
+ timeoutTimers.set(taskName, timer);
10176
+ }
10177
+ const ctx = {
10178
+ taskName,
10179
+ live,
10180
+ config: live.config.tasks[taskName]
10181
+ };
10182
+ try {
10183
+ const promise = handler(ctx);
10184
+ promise.then(
10185
+ (handlerResult) => {
10186
+ if (disposed) return;
10187
+ clearTimeout(timeoutTimers.get(taskName));
10188
+ timeoutTimers.delete(taskName);
10189
+ journal.append({
10190
+ type: "task-completed",
10191
+ taskName,
10192
+ result: handlerResult.result,
10193
+ data: handlerResult.data,
10194
+ dataHash: handlerResult.dataHash,
10195
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
10196
+ });
10197
+ drain();
10198
+ },
10199
+ (error) => {
10200
+ if (disposed) return;
10201
+ clearTimeout(timeoutTimers.get(taskName));
10202
+ timeoutTimers.delete(taskName);
10203
+ journal.append({
10204
+ type: "task-failed",
10205
+ taskName,
10206
+ error: error.message ?? String(error),
10207
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
10208
+ });
10209
+ drain();
10210
+ }
10211
+ );
10212
+ } catch (syncError) {
10213
+ const err = syncError instanceof Error ? syncError : new Error(String(syncError));
10214
+ dispatched.set(taskName, {
10215
+ status: "dispatch-failed",
10216
+ dispatchedAt: Date.now(),
10217
+ dispatchAttempts: attempt,
10218
+ lastError: err.message
10219
+ });
10220
+ onDispatchFailed?.(taskName, err, attempt);
10221
+ dispatched.set(taskName, {
10222
+ ...dispatched.get(taskName),
10223
+ status: "retry-queued"
10224
+ });
10225
+ drainQueued = true;
10226
+ }
10227
+ }
10228
+ function sweepTimeouts() {
10229
+ const now = Date.now();
10230
+ for (const [taskName, entry] of dispatched) {
10231
+ if (entry.status !== "initiated") continue;
10232
+ if (defaultTimeoutMs <= 0) continue;
10233
+ if (now - entry.dispatchedAt >= defaultTimeoutMs) {
10234
+ dispatched.set(taskName, {
10235
+ ...entry,
10236
+ status: entry.dispatchAttempts >= maxDispatchRetries ? "abandoned" : "retry-queued"
10237
+ });
10238
+ if (entry.dispatchAttempts >= maxDispatchRetries) {
10239
+ onAbandoned?.(taskName);
10240
+ journal.append({
10241
+ type: "task-failed",
10242
+ taskName,
10243
+ error: `dispatch-timeout: no callback after ${defaultTimeoutMs}ms (${entry.dispatchAttempts} attempts)`,
10244
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
10245
+ });
10246
+ }
10247
+ clearTimeout(timeoutTimers.get(taskName));
10248
+ timeoutTimers.delete(taskName);
10249
+ }
10250
+ }
10251
+ }
10252
+ return {
10253
+ push(event) {
10254
+ if (disposed) return;
10255
+ live = applyEvent(live, event);
10256
+ drain();
10257
+ },
10258
+ pushAll(events) {
10259
+ if (disposed) return;
10260
+ if (events.length === 0) return;
10261
+ live = applyEvents(live, events);
10262
+ drain();
10263
+ },
10264
+ addNode(name, taskConfig, handler) {
10265
+ if (disposed) return;
10266
+ live = addNode(live, name, taskConfig);
10267
+ handlers.set(name, handler);
10268
+ drain();
10269
+ },
10270
+ removeNode(name) {
10271
+ if (disposed) return;
10272
+ live = removeNode(live, name);
10273
+ handlers.delete(name);
10274
+ dispatched.delete(name);
10275
+ clearTimeout(timeoutTimers.get(name));
10276
+ timeoutTimers.delete(name);
10277
+ },
10278
+ getState() {
10279
+ return live;
10280
+ },
10281
+ getSchedule() {
10282
+ return schedule(live);
10283
+ },
10284
+ getDispatchState() {
10285
+ return dispatched;
10286
+ },
10287
+ dispose() {
10288
+ disposed = true;
10289
+ for (const timer of timeoutTimers.values()) {
10290
+ clearTimeout(timer);
10291
+ }
10292
+ timeoutTimers.clear();
10293
+ }
10294
+ };
10295
+ }
9449
10296
 
9450
10297
  // src/inference/core.ts
9451
10298
  var DEFAULT_THRESHOLD = 0.5;
@@ -10011,17 +10858,17 @@ var live_cards_schema_default = {
10011
10858
  };
10012
10859
 
10013
10860
  // src/card-compute/schema-validator.ts
10014
- var import_ajv = __toESM(require_ajv());
10015
- var _compiled = null;
10016
- function getValidator() {
10017
- if (_compiled) return _compiled;
10018
- const ajv = new import_ajv.default({ allErrors: true });
10861
+ var import_ajv3 = __toESM(require_ajv());
10862
+ var _compiled3 = null;
10863
+ function getValidator3() {
10864
+ if (_compiled3) return _compiled3;
10865
+ const ajv = new import_ajv3.default({ allErrors: true });
10019
10866
  addFormats__default.default(ajv);
10020
- _compiled = ajv.compile(live_cards_schema_default);
10021
- return _compiled;
10867
+ _compiled3 = ajv.compile(live_cards_schema_default);
10868
+ return _compiled3;
10022
10869
  }
10023
10870
  function validateLiveCardSchema(node) {
10024
- const validate = getValidator();
10871
+ const validate = getValidator3();
10025
10872
  const valid = validate(node);
10026
10873
  if (valid) return { ok: true, errors: [] };
10027
10874
  const errors = (validate.errors ?? []).map((e) => {
@@ -10484,9 +11331,11 @@ exports.CardCompute = CardCompute;
10484
11331
  exports.DEFAULTS = DEFAULTS;
10485
11332
  exports.EXECUTION_MODES = EXECUTION_MODES;
10486
11333
  exports.EXECUTION_STATUS = EXECUTION_STATUS;
11334
+ exports.FileJournal = FileJournal;
10487
11335
  exports.FileStore = FileStore;
10488
11336
  exports.FlowEngine = StepMachine;
10489
11337
  exports.LocalStorageStore = LocalStorageStore;
11338
+ exports.MemoryJournal = MemoryJournal;
10490
11339
  exports.MemoryStore = MemoryStore;
10491
11340
  exports.StepMachine = StepMachine;
10492
11341
  exports.TASK_STATUS = TASK_STATUS;
@@ -10497,6 +11346,7 @@ exports.addRequires = addRequires;
10497
11346
  exports.apply = apply;
10498
11347
  exports.applyAll = applyAll;
10499
11348
  exports.applyEvent = applyEvent;
11349
+ exports.applyEvents = applyEvents;
10500
11350
  exports.applyInferences = applyInferences;
10501
11351
  exports.applyStepResult = applyStepResult;
10502
11352
  exports.batch = batch;
@@ -10511,6 +11361,7 @@ exports.createHttpAdapter = createHttpAdapter;
10511
11361
  exports.createInitialExecutionState = createInitialExecutionState;
10512
11362
  exports.createInitialState = createInitialState;
10513
11363
  exports.createLiveGraph = createLiveGraph;
11364
+ exports.createReactiveGraph = createReactiveGraph;
10514
11365
  exports.createStepMachine = createStepMachine;
10515
11366
  exports.detectStuckState = detectStuckState;
10516
11367
  exports.disableNode = disableNode;
@@ -10523,8 +11374,10 @@ exports.flowToMermaid = flowToMermaid;
10523
11374
  exports.getAllTasks = getAllTasks;
10524
11375
  exports.getCandidateTasks = getCandidateTasks;
10525
11376
  exports.getDownstream = getDownstream;
11377
+ exports.getMaxExecutions = getMaxExecutions;
10526
11378
  exports.getNode = getNode;
10527
11379
  exports.getProvides = getProvides;
11380
+ exports.getRefreshStrategy = getRefreshStrategy;
10528
11381
  exports.getRequires = getRequires;
10529
11382
  exports.getTask = getTask;
10530
11383
  exports.getUnreachableNodes = getUnreachableNodes;
@@ -10538,7 +11391,7 @@ exports.injectTokens = injectTokens;
10538
11391
  exports.inspect = inspect;
10539
11392
  exports.isExecutionComplete = isExecutionComplete;
10540
11393
  exports.isNonActiveTask = isNonActiveTask;
10541
- exports.isRepeatableTask = isRepeatableTask;
11394
+ exports.isRerunnable = isRerunnable;
10542
11395
  exports.isTaskCompleted = isTaskCompleted;
10543
11396
  exports.isTaskRunning = isTaskRunning;
10544
11397
  exports.loadGraphConfig = loadGraphConfig;
@@ -10554,8 +11407,10 @@ exports.resolveVariables = resolveVariables;
10554
11407
  exports.restore = restore;
10555
11408
  exports.schedule = schedule;
10556
11409
  exports.snapshot = snapshot;
11410
+ exports.validateFlowSchema = validateFlowSchema;
10557
11411
  exports.validateGraph = validateGraph;
10558
11412
  exports.validateGraphConfig = validateGraphConfig;
11413
+ exports.validateGraphSchema = validateGraphSchema;
10559
11414
  exports.validateLiveCardSchema = validateLiveCardSchema;
10560
11415
  exports.validateStepFlowConfig = validateStepFlowConfig;
10561
11416
  //# sourceMappingURL=index.cjs.map