@vaudience/aigentflow-flow-validator 0.22.0 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -433,7 +433,7 @@ function validateBasicStructure(flow, issues) {
433
433
  message: "Executor is required for each step",
434
434
  code: "missing_required_field",
435
435
  stepId: stepID,
436
- suggestion: "Specify an executor URL (e.g., 'function://demo/processor')"
436
+ suggestion: "Specify an executor URL (e.g., 'function://utils/log')"
437
437
  });
438
438
  } else if (executorText === null) {
439
439
  issues.error({
@@ -449,7 +449,7 @@ function validateBasicStructure(flow, issues) {
449
449
 
450
450
  // src/spec/aigentflow-spec.json
451
451
  var aigentflow_spec_default = {
452
- specVersion: "2.828.0",
452
+ specVersion: "2.831.0",
453
453
  inputSchemaVersion: 1,
454
454
  executorSchemes: [
455
455
  "a2a",
@@ -946,6 +946,46 @@ var aigentflow_spec_default = {
946
946
  stepFieldFormat: "steps.%s.query.%s",
947
947
  loopStepFieldFormat: "steps.%s.loop.steps.%s.query.%s"
948
948
  },
949
+ functionOperations: {
950
+ code: "unknown_function_operation",
951
+ scheme: "function",
952
+ messageFormat: "step %s uses function://%s, which is not a built-in function. Available: %s",
953
+ suggestionFormat: "Use one of the built-in function operations: %s. For custom logic use a script://, http:// or ai:// executor instead.",
954
+ operations: [
955
+ "binary-processor/validate-and-store",
956
+ "data/create",
957
+ "data/from-json",
958
+ "data/to-json",
959
+ "data/validate",
960
+ "demo/adult-processor",
961
+ "demo/calculator",
962
+ "demo/data-processor",
963
+ "demo/finalizer",
964
+ "demo/senior-processor",
965
+ "demo/youth-processor",
966
+ "document/finalize",
967
+ "document/prepare",
968
+ "json/validate",
969
+ "math/basic",
970
+ "math/calculate",
971
+ "math/sum",
972
+ "results-compiler/aggregate",
973
+ "system/info",
974
+ "text/analysis",
975
+ "text/count-characters",
976
+ "text/count-lines",
977
+ "text/count-occurrences",
978
+ "text/count-words",
979
+ "text/find-pattern",
980
+ "text/generate",
981
+ "text/replace-text",
982
+ "text/search",
983
+ "utils/datetime",
984
+ "utils/format-date",
985
+ "utils/log",
986
+ "utils/parse-date"
987
+ ]
988
+ },
949
989
  flowDataReservedKeys: {
950
990
  code: "flow_data_key_reserved",
951
991
  fieldFormat: "data.%s",
@@ -1980,9 +2020,51 @@ var TEMPLATE_DEFAULT_PIPED = {
1980
2020
  messageFormat: aigentflow_spec_default.templateDefaultPiped.messageFormat,
1981
2021
  suggestion: aigentflow_spec_default.templateDefaultPiped.suggestion
1982
2022
  };
2023
+ var FUNCTION_OPERATIONS = {
2024
+ code: aigentflow_spec_default.functionOperations.code,
2025
+ scheme: aigentflow_spec_default.functionOperations.scheme,
2026
+ messageFormat: aigentflow_spec_default.functionOperations.messageFormat,
2027
+ suggestionFormat: aigentflow_spec_default.functionOperations.suggestionFormat,
2028
+ operations: new Set(aigentflow_spec_default.functionOperations.operations),
2029
+ sorted: aigentflow_spec_default.functionOperations.operations
2030
+ };
1983
2031
 
1984
2032
  // src/validators/executors.ts
1985
2033
  var SCHEME_SEPARATOR = "://";
2034
+ var UNKNOWN_SCHEME_BASE = (scheme) => `Unknown executor scheme '${scheme}'. It may be valid in a newer AIgentFlow release, or it could be a typo.`;
2035
+ var DECIDE_SCHEME = "decide";
2036
+ var DECIDE_HINT = "Decision models run through ai://{provider}/decide (for example ai://openai/decide), not through a scheme of their own.";
2037
+ var MAX_SCHEME_EDIT_DISTANCE = 2;
2038
+ function editDistance(a, b) {
2039
+ let prev = Array.from({ length: b.length + 1 }, (_, j) => j);
2040
+ for (let i = 1; i <= a.length; i++) {
2041
+ const cur = [i];
2042
+ for (let j = 1; j <= b.length; j++) {
2043
+ cur[j] = Math.min(
2044
+ prev[j] + 1,
2045
+ cur[j - 1] + 1,
2046
+ prev[j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1)
2047
+ );
2048
+ }
2049
+ prev = cur;
2050
+ }
2051
+ return prev[b.length];
2052
+ }
2053
+ function unknownSchemeMessage(scheme) {
2054
+ const lower = scheme.toLowerCase();
2055
+ const base = UNKNOWN_SCHEME_BASE(scheme);
2056
+ if (lower === DECIDE_SCHEME) return `${base} ${DECIDE_HINT}`;
2057
+ let best;
2058
+ let bestDist = MAX_SCHEME_EDIT_DISTANCE + 1;
2059
+ for (const known of [...EXECUTOR_SCHEMES].sort()) {
2060
+ const d = editDistance(lower, known);
2061
+ if (d < bestDist) {
2062
+ best = known;
2063
+ bestDist = d;
2064
+ }
2065
+ }
2066
+ return best === void 0 ? base : `${base} Did you mean '${best}'?`;
2067
+ }
1986
2068
  function checkExecutor(executor, field, stepID, issues) {
1987
2069
  const sepIdx = executor.indexOf(SCHEME_SEPARATOR);
1988
2070
  const scheme = sepIdx > 0 ? executor.slice(0, sepIdx) : "";
@@ -2001,11 +2083,28 @@ function checkExecutor(executor, field, stepID, issues) {
2001
2083
  if (!EXECUTOR_SCHEMES.has(scheme.toLowerCase())) {
2002
2084
  issues.warn({
2003
2085
  field,
2004
- message: `Unknown executor scheme '${scheme}'. It may be valid in a newer AIgentFlow release, or it could be a typo.`,
2086
+ message: unknownSchemeMessage(scheme),
2005
2087
  code: "unknown_executor_scheme",
2006
2088
  stepId: stepID
2007
2089
  });
2090
+ return;
2008
2091
  }
2092
+ checkFunctionOperation(executor, field, stepID, templated, issues);
2093
+ }
2094
+ function checkFunctionOperation(executor, field, stepID, templated, issues) {
2095
+ if (templated) return;
2096
+ const m = EXECUTOR_URL_PATTERN.exec(executor);
2097
+ if (m === null || m[1] !== FUNCTION_OPERATIONS.scheme) return;
2098
+ const op = `${m[2]}/${m[3]}`;
2099
+ if (FUNCTION_OPERATIONS.operations.has(op)) return;
2100
+ const list = FUNCTION_OPERATIONS.sorted.join(", ");
2101
+ issues.error({
2102
+ field,
2103
+ message: FUNCTION_OPERATIONS.messageFormat.replace("%s", () => JSON.stringify(stepID)).replace("%s", () => op).replace("%s", () => list),
2104
+ code: FUNCTION_OPERATIONS.code,
2105
+ stepId: stepID,
2106
+ suggestion: FUNCTION_OPERATIONS.suggestionFormat.replace("%s", () => list)
2107
+ });
2009
2108
  }
2010
2109
  function validateExecutors(flow, issues) {
2011
2110
  const steps = flow.steps;