veryfront 0.0.73 → 0.0.74

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 (43) hide show
  1. package/README.md +3 -0
  2. package/dist/ai/components.js +3 -3
  3. package/dist/ai/components.js.map +1 -1
  4. package/dist/ai/dev.js +130 -21
  5. package/dist/ai/dev.js.map +2 -2
  6. package/dist/ai/index.js +895 -418
  7. package/dist/ai/index.js.map +4 -4
  8. package/dist/ai/production.js +135 -38
  9. package/dist/ai/production.js.map +2 -2
  10. package/dist/ai/react.js +8 -7
  11. package/dist/ai/react.js.map +2 -2
  12. package/dist/ai/workflow.js +468 -110
  13. package/dist/ai/workflow.js.map +4 -4
  14. package/dist/components.js +8178 -1164
  15. package/dist/components.js.map +4 -4
  16. package/dist/config.js +377 -39
  17. package/dist/config.js.map +3 -3
  18. package/dist/context.d.ts +44 -0
  19. package/dist/context.js +52 -0
  20. package/dist/context.js.map +7 -0
  21. package/dist/data.js +176 -62
  22. package/dist/data.js.map +3 -3
  23. package/dist/fonts.d.ts +24 -0
  24. package/dist/fonts.js +45 -0
  25. package/dist/fonts.js.map +7 -0
  26. package/dist/head.d.ts +21 -0
  27. package/dist/head.js +34 -0
  28. package/dist/head.js.map +7 -0
  29. package/dist/index.js +8098 -1048
  30. package/dist/index.js.map +4 -4
  31. package/dist/oauth/handlers.js +6 -7
  32. package/dist/oauth/handlers.js.map +1 -1
  33. package/dist/oauth/index.js +6 -7
  34. package/dist/oauth/index.js.map +1 -1
  35. package/dist/oauth/providers.js +0 -3
  36. package/dist/oauth/providers.js.map +1 -1
  37. package/dist/oauth/token-store.js +6 -4
  38. package/dist/oauth/token-store.js.map +1 -1
  39. package/dist/router.d.ts +69 -0
  40. package/dist/router.js +61 -0
  41. package/dist/router.js.map +7 -0
  42. package/package.json +19 -2
  43. package/dist/cli.js +0 -107694
@@ -399,10 +399,12 @@ var isCloudflare = typeof globalThis !== "undefined" && "caches" in globalThis &
399
399
 
400
400
  // src/platform/compat/fs.ts
401
401
  var NodeFileSystem = class {
402
- fs = null;
403
- os = null;
404
- path = null;
405
- initialized = false;
402
+ constructor() {
403
+ this.fs = null;
404
+ this.os = null;
405
+ this.path = null;
406
+ this.initialized = false;
407
+ }
406
408
  async ensureInitialized() {
407
409
  if (this.initialized)
408
410
  return;
@@ -579,19 +581,69 @@ function getEnvironmentVariable(name) {
579
581
  }
580
582
  return void 0;
581
583
  }
584
+ function isProductionEnvironment() {
585
+ return getEnvironmentVariable("NODE_ENV") === "production";
586
+ }
582
587
 
583
588
  // src/core/utils/logger/logger.ts
584
589
  var cachedLogLevel;
590
+ var cachedLogFormat;
585
591
  function resolveLogLevel(force = false) {
586
592
  if (force || cachedLogLevel === void 0) {
587
593
  cachedLogLevel = getDefaultLevel();
588
594
  }
589
595
  return cachedLogLevel;
590
596
  }
591
- var ConsoleLogger = class {
592
- constructor(prefix, level = resolveLogLevel()) {
597
+ function resolveLogFormat(force = false) {
598
+ if (force || cachedLogFormat === void 0) {
599
+ cachedLogFormat = getDefaultFormat();
600
+ }
601
+ return cachedLogFormat;
602
+ }
603
+ function getDefaultFormat() {
604
+ const envFormat = getEnvironmentVariable("LOG_FORMAT");
605
+ if (envFormat === "json" || envFormat === "text") {
606
+ return envFormat;
607
+ }
608
+ return isProductionEnvironment() ? "json" : "text";
609
+ }
610
+ function serializeError(err) {
611
+ if (err instanceof Error) {
612
+ return {
613
+ name: err.name,
614
+ message: err.message,
615
+ stack: err.stack
616
+ };
617
+ }
618
+ if (err !== void 0 && err !== null) {
619
+ return {
620
+ name: "UnknownError",
621
+ message: String(err)
622
+ };
623
+ }
624
+ return void 0;
625
+ }
626
+ function extractContext(args) {
627
+ let context;
628
+ let error;
629
+ for (const arg of args) {
630
+ if (arg instanceof Error) {
631
+ error = serializeError(arg);
632
+ } else if (typeof arg === "object" && arg !== null && !Array.isArray(arg)) {
633
+ context = { ...context, ...arg };
634
+ }
635
+ }
636
+ return { context, error };
637
+ }
638
+ var ConsoleLogger = class _ConsoleLogger {
639
+ constructor(prefix, level = resolveLogLevel(), format = resolveLogFormat(), boundContext) {
593
640
  this.prefix = prefix;
594
641
  this.level = level;
642
+ this.format = format;
643
+ this.boundContext = {};
644
+ if (boundContext) {
645
+ this.boundContext = boundContext;
646
+ }
595
647
  }
596
648
  setLevel(level) {
597
649
  this.level = level;
@@ -599,36 +651,88 @@ var ConsoleLogger = class {
599
651
  getLevel() {
600
652
  return this.level;
601
653
  }
602
- debug(message, ...args) {
603
- if (this.level <= 0 /* DEBUG */) {
604
- console.debug(`[${this.prefix}] DEBUG: ${message}`, ...args);
654
+ setFormat(format) {
655
+ this.format = format;
656
+ }
657
+ getFormat() {
658
+ return this.format;
659
+ }
660
+ /**
661
+ * Create a child logger with additional bound context.
662
+ */
663
+ child(context) {
664
+ return new _ConsoleLogger(this.prefix, this.level, this.format, {
665
+ ...this.boundContext,
666
+ ...context
667
+ });
668
+ }
669
+ formatJson(level, message, args) {
670
+ const { context, error } = extractContext(args);
671
+ const entry = {
672
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
673
+ level,
674
+ service: this.prefix.toLowerCase(),
675
+ message
676
+ };
677
+ const mergedContext = { ...this.boundContext, ...context };
678
+ if (Object.keys(mergedContext).length > 0) {
679
+ if ("requestId" in mergedContext) {
680
+ entry.requestId = String(mergedContext.requestId);
681
+ delete mergedContext.requestId;
682
+ }
683
+ if ("traceId" in mergedContext) {
684
+ entry.traceId = String(mergedContext.traceId);
685
+ delete mergedContext.traceId;
686
+ }
687
+ if ("projectSlug" in mergedContext) {
688
+ entry.projectSlug = String(mergedContext.projectSlug);
689
+ delete mergedContext.projectSlug;
690
+ }
691
+ if ("durationMs" in mergedContext) {
692
+ entry.durationMs = Number(mergedContext.durationMs);
693
+ delete mergedContext.durationMs;
694
+ }
695
+ if (Object.keys(mergedContext).length > 0) {
696
+ entry.context = mergedContext;
697
+ }
698
+ }
699
+ if (error) {
700
+ entry.error = error;
605
701
  }
702
+ return JSON.stringify(entry);
606
703
  }
607
- info(message, ...args) {
608
- if (this.level <= 1 /* INFO */) {
609
- console.log(`[${this.prefix}] ${message}`, ...args);
704
+ log(level, logLevel, consoleFn, message, args) {
705
+ if (this.level > logLevel)
706
+ return;
707
+ if (this.format === "json") {
708
+ consoleFn(this.formatJson(level, message, args));
709
+ } else {
710
+ const prefix = level === "info" ? "" : ` ${level.toUpperCase()}:`;
711
+ consoleFn(`[${this.prefix}]${prefix} ${message}`, ...args);
610
712
  }
611
713
  }
714
+ debug(message, ...args) {
715
+ this.log("debug", 0 /* DEBUG */, console.debug, message, args);
716
+ }
717
+ info(message, ...args) {
718
+ this.log("info", 1 /* INFO */, console.log, message, args);
719
+ }
612
720
  warn(message, ...args) {
613
- if (this.level <= 2 /* WARN */) {
614
- console.warn(`[${this.prefix}] WARN: ${message}`, ...args);
615
- }
721
+ this.log("warn", 2 /* WARN */, console.warn, message, args);
616
722
  }
617
723
  error(message, ...args) {
618
- if (this.level <= 3 /* ERROR */) {
619
- console.error(`[${this.prefix}] ERROR: ${message}`, ...args);
620
- }
724
+ this.log("error", 3 /* ERROR */, console.error, message, args);
621
725
  }
622
726
  async time(label, fn) {
623
727
  const start = performance.now();
624
728
  try {
625
729
  const result = await fn();
626
- const end = performance.now();
627
- this.debug(`${label} completed in ${(end - start).toFixed(2)}ms`);
730
+ const durationMs = performance.now() - start;
731
+ this.debug(`${label} completed`, { durationMs: Math.round(durationMs) });
628
732
  return result;
629
733
  } catch (error) {
630
- const end = performance.now();
631
- this.error(`${label} failed after ${(end - start).toFixed(2)}ms`, error);
734
+ const durationMs = performance.now() - start;
735
+ this.error(`${label} failed`, { durationMs: Math.round(durationMs) }, error);
632
736
  throw error;
633
737
  }
634
738
  }
@@ -671,6 +775,7 @@ var serverLogger = createLogger("SERVER");
671
775
  var rendererLogger = createLogger("RENDERER");
672
776
  var bundlerLogger = createLogger("BUNDLER");
673
777
  var agentLogger = createLogger("AGENT");
778
+ var proxyLogger = createLogger("PROXY");
674
779
  var logger = createLogger("VERYFRONT");
675
780
 
676
781
  // src/core/utils/constants/cache.ts
@@ -696,7 +801,7 @@ var LRU_DEFAULT_MAX_SIZE_BYTES = 50 * 1024 * 1024;
696
801
  // deno.json
697
802
  var deno_default = {
698
803
  name: "veryfront",
699
- version: "0.0.73",
804
+ version: "0.0.74",
700
805
  nodeModulesDir: "auto",
701
806
  exclude: [
702
807
  "npm/",
@@ -781,12 +886,12 @@ var deno_default = {
781
886
  csstype: "https://esm.sh/csstype@3.2.3",
782
887
  "@types/react": "https://esm.sh/@types/react@18.3.27?deps=csstype@3.2.3",
783
888
  "@types/react-dom": "https://esm.sh/@types/react-dom@18.3.7?deps=csstype@3.2.3",
784
- react: "https://esm.sh/react@18.3.1",
785
- "react-dom": "https://esm.sh/react-dom@18.3.1",
786
- "react-dom/server": "https://esm.sh/react-dom@18.3.1/server",
787
- "react-dom/client": "https://esm.sh/react-dom@18.3.1/client",
788
- "react/jsx-runtime": "https://esm.sh/react@18.3.1/jsx-runtime",
789
- "react/jsx-dev-runtime": "https://esm.sh/react@18.3.1/jsx-dev-runtime",
889
+ react: "npm:react@18.3.1",
890
+ "react-dom": "npm:react-dom@18.3.1",
891
+ "react-dom/server": "npm:react-dom@18.3.1/server.node",
892
+ "react-dom/client": "npm:react-dom@18.3.1/client",
893
+ "react/jsx-runtime": "npm:react@18.3.1/jsx-runtime",
894
+ "react/jsx-dev-runtime": "npm:react@18.3.1/jsx-dev-runtime",
790
895
  "@mdx-js/mdx": "npm:@mdx-js/mdx@3.0.0",
791
896
  "@mdx-js/react": "npm:@mdx-js/react@3.0.0",
792
897
  "unist-util-visit": "npm:unist-util-visit@5.0.0",
@@ -796,27 +901,36 @@ var deno_default = {
796
901
  "remark-frontmatter": "npm:remark-frontmatter@5.0.0",
797
902
  "rehype-highlight": "npm:rehype-highlight@7.0.2",
798
903
  "rehype-slug": "npm:rehype-slug@6.0.0",
799
- esbuild: "https://deno.land/x/esbuild@v0.20.1/wasm.js",
800
- "esbuild/mod.js": "https://deno.land/x/esbuild@v0.20.1/mod.js",
904
+ esbuild: "npm:esbuild@0.20.2",
905
+ "esbuild/mod.js": "npm:esbuild@0.20.2",
801
906
  "es-module-lexer": "npm:es-module-lexer@1.5.0",
802
- zod: "npm:zod@3.23.8",
907
+ zod: "npm:zod@3.25.76",
803
908
  "mime-types": "npm:mime-types@2.1.35",
804
909
  mdast: "npm:@types/mdast@4.0.3",
805
910
  hast: "npm:@types/hast@3.0.3",
806
911
  unist: "npm:@types/unist@3.0.2",
807
912
  unified: "npm:unified@11.0.5",
808
- ai: "https://esm.sh/ai@5.0.76?deps=react@18.3.1,react-dom@18.3.1",
809
- "ai/react": "https://esm.sh/@ai-sdk/react@2.0.1?deps=react@18.3.1,react-dom@18.3.1",
810
- "@ai-sdk/react": "https://esm.sh/@ai-sdk/react@2.0.1?deps=react@18.3.1,react-dom@18.3.1",
913
+ ai: "npm:ai@5.0.76",
914
+ "ai/react": "npm:@ai-sdk/react@2.0.1",
915
+ "@ai-sdk/react": "npm:@ai-sdk/react@2.0.1",
811
916
  "@ai-sdk/openai": "https://esm.sh/@ai-sdk/openai@2.0.1",
812
917
  "@ai-sdk/anthropic": "https://esm.sh/@ai-sdk/anthropic@2.0.1",
813
918
  unocss: "https://esm.sh/unocss@0.59.0",
814
919
  "@unocss/core": "https://esm.sh/@unocss/core@0.59.0",
815
920
  "@unocss/preset-wind": "https://esm.sh/@unocss/preset-wind@0.59.0",
921
+ "next-themes": "npm:next-themes@0.3.0",
816
922
  redis: "npm:redis",
817
923
  pg: "npm:pg",
818
924
  "@opentelemetry/api": "npm:@opentelemetry/api@1",
819
- "@opentelemetry/core": "npm:@opentelemetry/core@1"
925
+ "@opentelemetry/core": "npm:@opentelemetry/core@1",
926
+ "@opentelemetry/sdk-trace-base": "npm:@opentelemetry/sdk-trace-base@1",
927
+ "@opentelemetry/exporter-trace-otlp-http": "npm:@opentelemetry/exporter-trace-otlp-http@0.57",
928
+ "@opentelemetry/resources": "npm:@opentelemetry/resources@1",
929
+ "@opentelemetry/semantic-conventions": "npm:@opentelemetry/semantic-conventions@1",
930
+ "@babel/parser": "npm:@babel/parser@7.26.3",
931
+ "@babel/traverse": "npm:@babel/traverse@7.26.3",
932
+ "@babel/generator": "npm:@babel/generator@7.26.3",
933
+ "@babel/types": "npm:@babel/types@7.26.3"
820
934
  },
821
935
  compilerOptions: {
822
936
  jsx: "react-jsx",
@@ -824,7 +938,7 @@ var deno_default = {
824
938
  strict: true,
825
939
  noImplicitAny: true,
826
940
  noUncheckedIndexedAccess: true,
827
- types: [],
941
+ types: ["npm:@types/react@18"],
828
942
  lib: [
829
943
  "deno.window",
830
944
  "dom",
@@ -839,9 +953,9 @@ var deno_default = {
839
953
  build: "deno compile --allow-all --output ../../bin/veryfront src/cli/main.ts",
840
954
  "build:npm": "deno run -A scripts/build-npm.ts",
841
955
  release: "deno run -A scripts/release.ts",
842
- test: "DENO_JOBS=1 deno test --parallel --fail-fast --allow-all --unstable-worker-options --unstable-net",
843
- "test:unit": "DENO_JOBS=1 deno test --parallel --allow-all --v8-flags=--max-old-space-size=8192 --ignore=tests --unstable-worker-options --unstable-net",
844
- "test:integration": "DENO_JOBS=1 deno test --parallel --fail-fast --allow-all tests --unstable-worker-options --unstable-net",
956
+ test: "VF_DISABLE_LRU_INTERVAL=1 DENO_JOBS=1 deno test --parallel --fail-fast --allow-all --unstable-worker-options --unstable-net",
957
+ "test:unit": "VF_DISABLE_LRU_INTERVAL=1 DENO_JOBS=1 deno test --parallel --allow-all --v8-flags=--max-old-space-size=8192 --ignore=tests,src/ai/workflow/__tests__ --unstable-worker-options --unstable-net",
958
+ "test:integration": "VF_DISABLE_LRU_INTERVAL=1 DENO_JOBS=1 deno test --parallel --fail-fast --allow-all tests --unstable-worker-options --unstable-net",
845
959
  "test:coverage": "rm -rf coverage && DENO_JOBS=1 deno test --parallel --fail-fast --allow-all --coverage=coverage --unstable-worker-options --unstable-net || exit 1",
846
960
  "test:coverage:unit": "rm -rf coverage && DENO_JOBS=1 deno test --parallel --fail-fast --allow-all --coverage=coverage --ignore=tests --unstable-worker-options --unstable-net || exit 1",
847
961
  "test:coverage:integration": "rm -rf coverage && DENO_JOBS=1 deno test --parallel --fail-fast --allow-all --coverage=coverage tests --unstable-worker-options --unstable-net || exit 1",
@@ -916,6 +1030,7 @@ function getEnv(key) {
916
1030
 
917
1031
  // src/core/utils/version.ts
918
1032
  var VERSION = getEnv("VERYFRONT_VERSION") || (typeof deno_default.version === "string" ? deno_default.version : "0.0.0");
1033
+ var SERVER_START_TIME = Date.now();
919
1034
 
920
1035
  // src/core/utils/constants/http.ts
921
1036
  var KB_IN_BYTES = 1024;
@@ -1020,9 +1135,11 @@ var VERYFRONT_PATHS = {
1020
1135
 
1021
1136
  // src/core/utils/bundle-manifest.ts
1022
1137
  var InMemoryBundleManifestStore = class {
1023
- metadata = /* @__PURE__ */ new Map();
1024
- code = /* @__PURE__ */ new Map();
1025
- sourceIndex = /* @__PURE__ */ new Map();
1138
+ constructor() {
1139
+ this.metadata = /* @__PURE__ */ new Map();
1140
+ this.code = /* @__PURE__ */ new Map();
1141
+ this.sourceIndex = /* @__PURE__ */ new Map();
1142
+ }
1026
1143
  getBundleMetadata(key) {
1027
1144
  const entry = this.metadata.get(key);
1028
1145
  if (!entry)
@@ -1113,11 +1230,11 @@ var InMemoryBundleManifestStore = class {
1113
1230
  };
1114
1231
  var manifestStore = new InMemoryBundleManifestStore();
1115
1232
 
1233
+ // src/core/utils/perf-timer.ts
1234
+ var enabled = typeof process !== "undefined" ? process.env?.VERYFRONT_PERF === "1" : typeof Deno !== "undefined" ? Deno.env.get("VERYFRONT_PERF") === "1" : false;
1235
+
1116
1236
  // src/ai/workflow/blob/local-storage.ts
1117
1237
  var LocalBlobStorage = class {
1118
- rootDir;
1119
- baseUrl;
1120
- fs;
1121
1238
  constructor(rootDir, baseUrl) {
1122
1239
  this.rootDir = rootDir;
1123
1240
  this.baseUrl = baseUrl;
@@ -1271,10 +1388,9 @@ Original error: ${error instanceof Error ? error.message : String(error)}`
1271
1388
  }
1272
1389
  }
1273
1390
  var S3BlobStorage = class {
1274
- client = null;
1275
- config;
1276
- initPromise = null;
1277
1391
  constructor(config) {
1392
+ this.client = null;
1393
+ this.initPromise = null;
1278
1394
  this.config = config;
1279
1395
  this.initPromise = this.initialize();
1280
1396
  }
@@ -1504,9 +1620,8 @@ var S3BlobStorage = class {
1504
1620
 
1505
1621
  // src/ai/workflow/blob/gcs-storage.ts
1506
1622
  var GCSBlobStorage = class {
1507
- config;
1508
- tokenCache = null;
1509
1623
  constructor(config) {
1624
+ this.tokenCache = null;
1510
1625
  this.config = config;
1511
1626
  try {
1512
1627
  JSON.parse(this.config.serviceAccountKey);
@@ -1794,13 +1909,12 @@ function hasEventSupport(backend) {
1794
1909
  // src/ai/workflow/backends/memory.ts
1795
1910
  var DEFAULT_MAX_QUEUE_SIZE = 1e4;
1796
1911
  var MemoryBackend = class {
1797
- runs = /* @__PURE__ */ new Map();
1798
- checkpoints = /* @__PURE__ */ new Map();
1799
- approvals = /* @__PURE__ */ new Map();
1800
- queue = [];
1801
- locks = /* @__PURE__ */ new Map();
1802
- config;
1803
1912
  constructor(config = {}) {
1913
+ this.runs = /* @__PURE__ */ new Map();
1914
+ this.checkpoints = /* @__PURE__ */ new Map();
1915
+ this.approvals = /* @__PURE__ */ new Map();
1916
+ this.queue = [];
1917
+ this.locks = /* @__PURE__ */ new Map();
1804
1918
  this.config = {
1805
1919
  prefix: "wf:",
1806
1920
  debug: false,
@@ -2357,11 +2471,10 @@ var DenoRedisAdapter = class {
2357
2471
  }
2358
2472
  };
2359
2473
  var RedisBackend = class {
2360
- client = null;
2361
- connectionPromise = null;
2362
- config;
2363
- initialized = false;
2364
2474
  constructor(config = {}) {
2475
+ this.client = null;
2476
+ this.connectionPromise = null;
2477
+ this.initialized = false;
2365
2478
  this.config = {
2366
2479
  prefix: "vf:workflow:",
2367
2480
  streamKey: "vf:workflow:stream",
@@ -2900,7 +3013,6 @@ var RedisBackend = class {
2900
3013
 
2901
3014
  // src/ai/workflow/executor/dag-executor.ts
2902
3015
  var DAGExecutor = class {
2903
- config;
2904
3016
  constructor(config) {
2905
3017
  this.config = {
2906
3018
  maxConcurrency: 10,
@@ -3043,9 +3155,16 @@ var DAGExecutor = class {
3043
3155
  context,
3044
3156
  nodeStates
3045
3157
  );
3158
+ case "loop":
3159
+ return await this.executeLoopNode(
3160
+ node,
3161
+ config,
3162
+ context,
3163
+ nodeStates
3164
+ );
3046
3165
  default:
3047
3166
  throw new Error(
3048
- `Unknown node type "${config.type}" for node "${node.id}". Valid types are: step, parallel, map, branch, wait, subWorkflow`
3167
+ `Unknown node type "${config.type}" for node "${node.id}". Valid types are: step, parallel, map, branch, wait, subWorkflow, loop`
3049
3168
  );
3050
3169
  }
3051
3170
  }
@@ -3203,6 +3322,155 @@ var DAGExecutor = class {
3203
3322
  waiting: result.waiting
3204
3323
  };
3205
3324
  }
3325
+ /**
3326
+ * Execute a loop node
3327
+ */
3328
+ async executeLoopNode(node, config, context, nodeStates) {
3329
+ const startTime = Date.now();
3330
+ const previousResults = [];
3331
+ let iteration = 0;
3332
+ let exitReason = "condition";
3333
+ let lastError;
3334
+ const existingLoopState = context[`${node.id}_loop_state`];
3335
+ if (existingLoopState) {
3336
+ iteration = existingLoopState.iteration;
3337
+ previousResults.push(...existingLoopState.previousResults);
3338
+ }
3339
+ while (iteration < config.maxIterations) {
3340
+ const loopContext = {
3341
+ iteration,
3342
+ totalIterations: iteration,
3343
+ previousResults: [...previousResults],
3344
+ isFirstIteration: iteration === 0,
3345
+ isLastAllowedIteration: iteration === config.maxIterations - 1
3346
+ };
3347
+ const shouldContinue = await config.while(context, loopContext);
3348
+ if (!shouldContinue) {
3349
+ exitReason = "condition";
3350
+ break;
3351
+ }
3352
+ const steps = typeof config.steps === "function" ? config.steps(context, loopContext) : config.steps;
3353
+ const result = await this.execute(steps, {
3354
+ id: `${node.id}_iter_${iteration}`,
3355
+ workflowId: "",
3356
+ status: "running",
3357
+ input: context.input,
3358
+ nodeStates: {},
3359
+ currentNodes: [],
3360
+ context: { ...context, _loop: loopContext },
3361
+ checkpoints: [],
3362
+ pendingApprovals: [],
3363
+ createdAt: /* @__PURE__ */ new Date()
3364
+ });
3365
+ if (result.waiting) {
3366
+ Object.assign(nodeStates, result.nodeStates);
3367
+ const state2 = {
3368
+ nodeId: node.id,
3369
+ status: "running",
3370
+ output: {
3371
+ iteration,
3372
+ waiting: true,
3373
+ previousResults
3374
+ },
3375
+ attempt: 1,
3376
+ startedAt: new Date(startTime)
3377
+ };
3378
+ return {
3379
+ state: state2,
3380
+ contextUpdates: {
3381
+ ...result.context,
3382
+ [`${node.id}_loop_state`]: { iteration, previousResults }
3383
+ },
3384
+ waiting: true
3385
+ };
3386
+ }
3387
+ if (result.error) {
3388
+ lastError = result.error;
3389
+ exitReason = "error";
3390
+ break;
3391
+ }
3392
+ previousResults.push(result.context);
3393
+ Object.assign(context, result.context);
3394
+ Object.assign(nodeStates, result.nodeStates);
3395
+ if (config.delay && iteration < config.maxIterations - 1) {
3396
+ const delayMs = typeof config.delay === "number" ? config.delay : this.parseDuration(config.delay);
3397
+ await this.sleep(delayMs);
3398
+ }
3399
+ iteration++;
3400
+ }
3401
+ if (iteration >= config.maxIterations && exitReason !== "condition") {
3402
+ exitReason = "maxIterations";
3403
+ }
3404
+ const finalLoopContext = {
3405
+ iteration,
3406
+ totalIterations: iteration,
3407
+ previousResults,
3408
+ isFirstIteration: false,
3409
+ isLastAllowedIteration: true
3410
+ };
3411
+ let completionUpdates = {};
3412
+ if (exitReason === "maxIterations" && config.onMaxIterations) {
3413
+ completionUpdates = await config.onMaxIterations(context, finalLoopContext);
3414
+ } else if (exitReason === "condition" && config.onComplete) {
3415
+ completionUpdates = await config.onComplete(context, finalLoopContext);
3416
+ }
3417
+ const output = {
3418
+ exitReason,
3419
+ iterations: iteration,
3420
+ previousResults,
3421
+ ...completionUpdates
3422
+ };
3423
+ const state = {
3424
+ nodeId: node.id,
3425
+ status: exitReason === "error" ? "failed" : "completed",
3426
+ output,
3427
+ error: lastError,
3428
+ attempt: 1,
3429
+ startedAt: new Date(startTime),
3430
+ completedAt: /* @__PURE__ */ new Date()
3431
+ };
3432
+ this.config.onNodeComplete?.(node.id, state);
3433
+ return {
3434
+ state,
3435
+ contextUpdates: {
3436
+ [node.id]: output,
3437
+ ...completionUpdates
3438
+ },
3439
+ waiting: false
3440
+ };
3441
+ }
3442
+ /**
3443
+ * Parse duration string to milliseconds
3444
+ */
3445
+ parseDuration(duration) {
3446
+ if (typeof duration === "number")
3447
+ return duration;
3448
+ const match = duration.match(/^(\d+)(ms|s|m|h|d)$/);
3449
+ if (!match)
3450
+ return 0;
3451
+ const value = parseInt(match[1], 10);
3452
+ const unit = match[2];
3453
+ switch (unit) {
3454
+ case "ms":
3455
+ return value;
3456
+ case "s":
3457
+ return value * 1e3;
3458
+ case "m":
3459
+ return value * 60 * 1e3;
3460
+ case "h":
3461
+ return value * 60 * 60 * 1e3;
3462
+ case "d":
3463
+ return value * 24 * 60 * 60 * 1e3;
3464
+ default:
3465
+ return 0;
3466
+ }
3467
+ }
3468
+ /**
3469
+ * Sleep for specified milliseconds
3470
+ */
3471
+ sleep(ms) {
3472
+ return new Promise((resolve) => setTimeout(resolve, ms));
3473
+ }
3206
3474
  /**
3207
3475
  * Execute a step node
3208
3476
  */
@@ -3442,7 +3710,6 @@ var DAGExecutor = class {
3442
3710
 
3443
3711
  // src/ai/workflow/executor/checkpoint-manager.ts
3444
3712
  var CheckpointManager = class {
3445
- config;
3446
3713
  constructor(config) {
3447
3714
  this.config = {
3448
3715
  debug: false,
@@ -3598,9 +3865,14 @@ var CheckpointManager = class {
3598
3865
  };
3599
3866
 
3600
3867
  // src/ai/workflow/executor/step-executor.ts
3868
+ var DEFAULT_RETRY = {
3869
+ maxAttempts: 1,
3870
+ backoff: "exponential",
3871
+ initialDelay: 1e3,
3872
+ maxDelay: 3e4
3873
+ };
3601
3874
  var DEFAULT_STEP_TIMEOUT_MS = 5 * 60 * 1e3;
3602
3875
  var StepExecutor = class {
3603
- config;
3604
3876
  constructor(config = {}) {
3605
3877
  this.config = {
3606
3878
  defaultTimeout: DEFAULT_STEP_TIMEOUT_MS,
@@ -3608,7 +3880,7 @@ var StepExecutor = class {
3608
3880
  };
3609
3881
  }
3610
3882
  /**
3611
- * Execute a step node
3883
+ * Execute a step node with retry support
3612
3884
  */
3613
3885
  async execute(node, context) {
3614
3886
  const startTime = Date.now();
@@ -3618,30 +3890,96 @@ var StepExecutor = class {
3618
3890
  `StepExecutor can only execute 'step' nodes, but node "${node.id}" has type '${config.type}'. This is likely a bug in the DAG executor routing.`
3619
3891
  );
3620
3892
  }
3621
- try {
3622
- const resolvedInput = await this.resolveInput(config.input, context);
3623
- this.config.onStepStart?.(node.id, resolvedInput);
3624
- const timeout = config.timeout ? parseDuration(config.timeout) : this.config.defaultTimeout;
3625
- const output = await this.executeWithTimeout(
3626
- () => this.executeStep(config, resolvedInput, context),
3627
- timeout,
3628
- node.id
3629
- );
3630
- this.config.onStepComplete?.(node.id, output);
3631
- return {
3632
- success: true,
3633
- output,
3634
- executionTime: Date.now() - startTime
3635
- };
3636
- } catch (error) {
3637
- const errorMessage = error instanceof Error ? error.message : String(error);
3638
- this.config.onStepError?.(node.id, error);
3639
- return {
3640
- success: false,
3641
- error: errorMessage,
3642
- executionTime: Date.now() - startTime
3643
- };
3893
+ const retryConfig = { ...DEFAULT_RETRY, ...config.retry };
3894
+ const maxAttempts = retryConfig.maxAttempts ?? 1;
3895
+ let lastError;
3896
+ let attempt = 0;
3897
+ while (attempt < maxAttempts) {
3898
+ attempt++;
3899
+ try {
3900
+ const resolvedInput = await this.resolveInput(config.input, context);
3901
+ this.config.onStepStart?.(node.id, resolvedInput);
3902
+ const timeout = config.timeout ? parseDuration(config.timeout) : this.config.defaultTimeout;
3903
+ const output = await this.executeWithTimeout(
3904
+ () => this.executeStep(config, resolvedInput, context),
3905
+ timeout,
3906
+ node.id
3907
+ );
3908
+ this.config.onStepComplete?.(node.id, output);
3909
+ return {
3910
+ success: true,
3911
+ output,
3912
+ executionTime: Date.now() - startTime
3913
+ };
3914
+ } catch (error) {
3915
+ lastError = error instanceof Error ? error : new Error(String(error));
3916
+ const shouldRetry = attempt < maxAttempts && this.isRetryableError(lastError, retryConfig);
3917
+ if (shouldRetry) {
3918
+ const delay2 = this.calculateRetryDelay(attempt, retryConfig);
3919
+ await this.sleep(delay2);
3920
+ continue;
3921
+ }
3922
+ this.config.onStepError?.(node.id, lastError);
3923
+ return {
3924
+ success: false,
3925
+ error: lastError.message,
3926
+ executionTime: Date.now() - startTime
3927
+ };
3928
+ }
3644
3929
  }
3930
+ return {
3931
+ success: false,
3932
+ error: lastError?.message ?? "Unknown error",
3933
+ executionTime: Date.now() - startTime
3934
+ };
3935
+ }
3936
+ /**
3937
+ * Check if error is retryable
3938
+ */
3939
+ isRetryableError(error, config) {
3940
+ if (config.retryIf) {
3941
+ return config.retryIf(error);
3942
+ }
3943
+ const retryablePatterns = [
3944
+ /timeout/i,
3945
+ /ECONNRESET/i,
3946
+ /ECONNREFUSED/i,
3947
+ /ETIMEDOUT/i,
3948
+ /rate limit/i,
3949
+ /429/,
3950
+ /503/,
3951
+ /502/
3952
+ ];
3953
+ return retryablePatterns.some((pattern) => pattern.test(error.message));
3954
+ }
3955
+ /**
3956
+ * Calculate retry delay based on backoff strategy
3957
+ */
3958
+ calculateRetryDelay(attempt, config) {
3959
+ const initialDelay = config.initialDelay ?? 1e3;
3960
+ const maxDelay = config.maxDelay ?? 3e4;
3961
+ let delay2;
3962
+ switch (config.backoff) {
3963
+ case "exponential":
3964
+ delay2 = initialDelay * Math.pow(2, attempt - 1);
3965
+ break;
3966
+ case "linear":
3967
+ delay2 = initialDelay * attempt;
3968
+ break;
3969
+ case "fixed":
3970
+ default:
3971
+ delay2 = initialDelay;
3972
+ break;
3973
+ }
3974
+ const jitter = delay2 * 0.1 * (Math.random() * 2 - 1);
3975
+ delay2 = Math.min(delay2 + jitter, maxDelay);
3976
+ return Math.floor(delay2);
3977
+ }
3978
+ /**
3979
+ * Sleep for specified milliseconds
3980
+ */
3981
+ sleep(ms) {
3982
+ return new Promise((resolve) => setTimeout(resolve, ms));
3645
3983
  }
3646
3984
  /**
3647
3985
  * Resolve step input from context
@@ -3822,15 +4160,8 @@ var StepExecutor = class {
3822
4160
 
3823
4161
  // src/ai/workflow/executor/workflow-executor.ts
3824
4162
  var WorkflowExecutor = class _WorkflowExecutor {
3825
- config;
3826
- stepExecutor;
3827
- checkpointManager;
3828
- dagExecutor;
3829
- workflows = /* @__PURE__ */ new Map();
3830
- blobResolver;
3831
- /** Default lock duration: 30 seconds */
3832
- static DEFAULT_LOCK_DURATION = 3e4;
3833
4163
  constructor(config) {
4164
+ this.workflows = /* @__PURE__ */ new Map();
3834
4165
  this.config = {
3835
4166
  maxConcurrency: 10,
3836
4167
  debug: false,
@@ -3866,6 +4197,10 @@ var WorkflowExecutor = class _WorkflowExecutor {
3866
4197
  };
3867
4198
  }
3868
4199
  }
4200
+ static {
4201
+ /** Default lock duration: 30 seconds */
4202
+ this.DEFAULT_LOCK_DURATION = 3e4;
4203
+ }
3869
4204
  /**
3870
4205
  * Register a workflow definition
3871
4206
  */
@@ -4220,10 +4555,8 @@ var WorkflowExecutor = class _WorkflowExecutor {
4220
4555
 
4221
4556
  // src/ai/workflow/runtime/approval-manager.ts
4222
4557
  var ApprovalManager = class {
4223
- config;
4224
- expirationTimer;
4225
- destroyed = false;
4226
4558
  constructor(config) {
4559
+ this.destroyed = false;
4227
4560
  this.config = {
4228
4561
  expirationCheckInterval: 6e4,
4229
4562
  // Check every minute
@@ -4450,7 +4783,9 @@ var ApprovalManager = class {
4450
4783
 
4451
4784
  // src/ai/workflow/runtime/agent-registry.ts
4452
4785
  var DefaultAgentRegistry = class {
4453
- agents = /* @__PURE__ */ new Map();
4786
+ constructor() {
4787
+ this.agents = /* @__PURE__ */ new Map();
4788
+ }
4454
4789
  /**
4455
4790
  * Register an agent
4456
4791
  */
@@ -4497,7 +4832,9 @@ var DefaultAgentRegistry = class {
4497
4832
  }
4498
4833
  };
4499
4834
  var DefaultToolRegistry = class {
4500
- tools = /* @__PURE__ */ new Map();
4835
+ constructor() {
4836
+ this.tools = /* @__PURE__ */ new Map();
4837
+ }
4501
4838
  /**
4502
4839
  * Register a tool
4503
4840
  */
@@ -4622,17 +4959,41 @@ function createMockTool(id, options = {}) {
4622
4959
 
4623
4960
  // src/ai/workflow/api/workflow-client.ts
4624
4961
  var WorkflowClient = class {
4625
- backend;
4626
- executor;
4627
- approvalManager;
4628
- debug;
4629
4962
  constructor(config = {}) {
4630
4963
  this.debug = config.debug ?? false;
4631
4964
  this.backend = config.backend ?? new MemoryBackend({ debug: this.debug });
4632
4965
  this.executor = new WorkflowExecutor({
4633
4966
  backend: this.backend,
4634
4967
  debug: this.debug,
4635
- ...config.executor
4968
+ ...config.executor,
4969
+ onWaiting: async (run, nodeId) => {
4970
+ const nodeState = run.nodeStates[nodeId];
4971
+ if (!nodeState?.input) {
4972
+ if (this.debug) {
4973
+ console.log(`[WorkflowClient] No wait config found for node: ${nodeId}`);
4974
+ }
4975
+ return;
4976
+ }
4977
+ const input = nodeState.input;
4978
+ if (input.type !== "approval") {
4979
+ return;
4980
+ }
4981
+ const waitConfig = {
4982
+ type: "wait",
4983
+ waitType: "approval",
4984
+ message: input.message,
4985
+ payload: input.payload
4986
+ };
4987
+ try {
4988
+ await this.approvalManager.createApproval(run, nodeId, waitConfig, run.context);
4989
+ if (this.debug) {
4990
+ console.log(`[WorkflowClient] Created approval for node: ${nodeId}`);
4991
+ }
4992
+ } catch (error) {
4993
+ console.error(`[WorkflowClient] Failed to create approval:`, error);
4994
+ }
4995
+ config.executor?.onWaiting?.(run, nodeId);
4996
+ }
4636
4997
  });
4637
4998
  this.approvalManager = new ApprovalManager({
4638
4999
  backend: this.backend,
@@ -4790,7 +5151,6 @@ function createWorkflowClient(config) {
4790
5151
 
4791
5152
  // src/ai/workflow/backends/temporal.ts
4792
5153
  var TemporalAdapter = class {
4793
- config;
4794
5154
  constructor(config = {}) {
4795
5155
  this.config = {
4796
5156
  address: "localhost:7233",
@@ -4851,7 +5211,6 @@ var TemporalAdapter = class {
4851
5211
 
4852
5212
  // src/ai/workflow/backends/inngest.ts
4853
5213
  var InngestAdapter = class {
4854
- config;
4855
5214
  constructor(config = {}) {
4856
5215
  this.config = {
4857
5216
  debug: false,
@@ -4909,7 +5268,6 @@ var InngestAdapter = class {
4909
5268
 
4910
5269
  // src/ai/workflow/backends/cloudflare.ts
4911
5270
  var CloudflareAdapter = class {
4912
- config;
4913
5271
  constructor(config = {}) {
4914
5272
  this.config = {
4915
5273
  durableObjectBinding: "WORKFLOW_DO",