veryfront 0.0.6 → 0.0.9

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.
@@ -0,0 +1,2 @@
1
+ // AI client type definitions
2
+ export * from 'ai';
@@ -0,0 +1,11 @@
1
+ // AI styled components type definitions
2
+ import type { ReactNode, HTMLAttributes } from 'react';
3
+ import type { UseChatHelpers } from '@ai-sdk/react';
4
+
5
+ export interface ChatProps extends Partial<UseChatHelpers> {
6
+ className?: string;
7
+ placeholder?: string;
8
+ welcomeMessage?: string;
9
+ }
10
+
11
+ export declare function Chat(props: ChatProps): JSX.Element;
@@ -0,0 +1,7 @@
1
+ // AI development utilities type definitions
2
+ export interface DevToolsConfig {
3
+ enabled?: boolean;
4
+ position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
5
+ }
6
+
7
+ export declare function AIDevTools(props: DevToolsConfig): JSX.Element | null;
@@ -0,0 +1,40 @@
1
+ // AI module type definitions
2
+ import type { z } from 'zod';
3
+
4
+ export interface AgentConfig {
5
+ model: string;
6
+ system?: string;
7
+ tools?: Record<string, boolean | object>;
8
+ memory?: {
9
+ type?: 'conversation' | 'summary' | 'buffer';
10
+ maxTokens?: number;
11
+ };
12
+ maxSteps?: number;
13
+ temperature?: number;
14
+ }
15
+
16
+ export interface ToolConfig<TInput = unknown, TOutput = unknown> {
17
+ description: string;
18
+ inputSchema: z.ZodType<TInput>;
19
+ execute: (input: TInput) => Promise<TOutput> | TOutput;
20
+ }
21
+
22
+ export interface ResourceConfig<TParams = unknown, TData = unknown> {
23
+ description: string;
24
+ paramsSchema?: z.ZodType<TParams>;
25
+ load: (params: TParams) => Promise<TData> | TData;
26
+ }
27
+
28
+ export declare function agent(config: AgentConfig): {
29
+ stream(options: { messages: Array<{ role: string; content: string }> }): {
30
+ toDataStreamResponse(): Response;
31
+ };
32
+ respond(request: Request): Promise<Response>;
33
+ };
34
+
35
+ export declare function tool<TInput, TOutput>(config: ToolConfig<TInput, TOutput>): ToolConfig<TInput, TOutput>;
36
+
37
+ export declare function resource<TParams, TData>(config: ResourceConfig<TParams, TData>): ResourceConfig<TParams, TData>;
38
+
39
+ // Re-export from ai-sdk
40
+ export * from 'ai';
package/dist/ai/index.js CHANGED
@@ -1675,7 +1675,7 @@ var BYTES_PER_MB = 1024 * 1024;
1675
1675
  // deno.json
1676
1676
  var deno_default = {
1677
1677
  name: "veryfront",
1678
- version: "0.0.6",
1678
+ version: "0.0.8",
1679
1679
  nodeModulesDir: "auto",
1680
1680
  workspace: [
1681
1681
  "./examples/async-worker-redis",
@@ -1804,6 +1804,7 @@ var deno_default = {
1804
1804
  dev: "deno run --allow-all --no-lock --unstable-net --unstable-worker-options src/cli/main.ts dev",
1805
1805
  build: "deno compile --allow-all --output ../../bin/veryfront src/cli/main.ts",
1806
1806
  "build:npm": "deno run -A scripts/build-npm.ts",
1807
+ release: "deno run -A scripts/release.ts",
1807
1808
  test: "DENO_JOBS=1 deno test --parallel --fail-fast --allow-all --unstable-worker-options --unstable-net",
1808
1809
  "test:unit": "DENO_JOBS=1 deno test --parallel --allow-all --v8-flags=--max-old-space-size=8192 --ignore=tests --unstable-worker-options --unstable-net",
1809
1810
  "test:integration": "DENO_JOBS=1 deno test --parallel --fail-fast --allow-all tests --unstable-worker-options --unstable-net",
@@ -3466,6 +3467,7 @@ var DEFAULT_CONFIG2 = {
3466
3467
  }
3467
3468
  };
3468
3469
  var configCacheByProject = /* @__PURE__ */ new Map();
3470
+ var cacheRevision = 0;
3469
3471
  function validateCorsConfig(userConfig) {
3470
3472
  if (!userConfig || typeof userConfig !== "object") {
3471
3473
  return;
@@ -3542,13 +3544,18 @@ var ConfigValidationError = class extends Error {
3542
3544
  };
3543
3545
  async function loadAndMergeConfig(configPath, projectDir) {
3544
3546
  try {
3545
- const configUrl = `file://${configPath}?t=${Date.now()}`;
3547
+ const configUrl = `file://${configPath}?t=${Date.now()}-${crypto.randomUUID()}`;
3546
3548
  const configModule = await import(configUrl);
3547
3549
  const userConfig = configModule.default || configModule;
3550
+ if (userConfig === null || typeof userConfig !== "object" || Array.isArray(userConfig)) {
3551
+ throw new ConfigValidationError(
3552
+ `Expected object, received ${userConfig === null ? "null" : typeof userConfig}`
3553
+ );
3554
+ }
3548
3555
  validateCorsConfig(userConfig);
3549
3556
  validateConfigShape(userConfig);
3550
3557
  const merged = mergeConfigs(userConfig);
3551
- configCacheByProject.set(projectDir, merged);
3558
+ configCacheByProject.set(projectDir, { revision: cacheRevision, config: merged });
3552
3559
  return merged;
3553
3560
  } catch (error) {
3554
3561
  if (error instanceof ConfigValidationError) {
@@ -3562,8 +3569,8 @@ async function loadAndMergeConfig(configPath, projectDir) {
3562
3569
  }
3563
3570
  async function getConfig(projectDir, adapter) {
3564
3571
  const cached = configCacheByProject.get(projectDir);
3565
- if (cached)
3566
- return cached;
3572
+ if (cached && cached.revision === cacheRevision)
3573
+ return cached.config;
3567
3574
  const configFiles = ["veryfront.config.js", "veryfront.config.ts", "veryfront.config.mjs"];
3568
3575
  for (const configFile of configFiles) {
3569
3576
  const configPath = join(projectDir, configFile);
@@ -3589,7 +3596,7 @@ async function getConfig(projectDir, adapter) {
3589
3596
  }
3590
3597
  }
3591
3598
  const defaultConfig = DEFAULT_CONFIG2;
3592
- configCacheByProject.set(projectDir, defaultConfig);
3599
+ configCacheByProject.set(projectDir, { revision: cacheRevision, config: defaultConfig });
3593
3600
  return defaultConfig;
3594
3601
  }
3595
3602
 
@@ -5921,20 +5928,172 @@ var DAGExecutor = class {
5921
5928
  return await this.executeStepNode(node, context);
5922
5929
  case "parallel":
5923
5930
  return await this.executeParallelNode(node, config, context, nodeStates);
5931
+ case "map":
5932
+ return await this.executeMapNode(node, config, context, nodeStates);
5924
5933
  case "branch":
5925
5934
  return await this.executeBranchNode(node, config, context, nodeStates);
5926
5935
  case "wait":
5927
5936
  return await this.executeWaitNode(node, config, context);
5928
5937
  case "subWorkflow":
5929
- throw new Error(
5930
- `Sub-workflow execution is not yet implemented for node "${node.id}". Workaround: Flatten your workflow by inlining the sub-workflow steps directly, or use the parallel() or branch() DSL helpers to compose workflows.`
5931
- );
5938
+ return await this.executeSubWorkflowNode(node, config, context, nodeStates);
5932
5939
  default:
5933
5940
  throw new Error(
5934
- `Unknown node type "${config.type}" for node "${node.id}". Valid types are: step, parallel, branch, wait, subWorkflow`
5941
+ `Unknown node type "${config.type}" for node "${node.id}". Valid types are: step, parallel, map, branch, wait, subWorkflow`
5935
5942
  );
5936
5943
  }
5937
5944
  }
5945
+ /**
5946
+ * Execute a map node (dynamic fan-out)
5947
+ */
5948
+ async executeMapNode(node, config, context, nodeStates) {
5949
+ const startTime = Date.now();
5950
+ const items = typeof config.items === "function" ? await config.items(context) : config.items;
5951
+ if (!Array.isArray(items)) {
5952
+ throw new Error(`Map node "${node.id}" items must be an array`);
5953
+ }
5954
+ if (items.length === 0) {
5955
+ const state = {
5956
+ nodeId: node.id,
5957
+ status: "completed",
5958
+ output: [],
5959
+ attempt: 1,
5960
+ startedAt: new Date(startTime),
5961
+ completedAt: /* @__PURE__ */ new Date()
5962
+ };
5963
+ return { state, contextUpdates: { [node.id]: [] }, waiting: false };
5964
+ }
5965
+ const childNodes = [];
5966
+ const isWorkflowDef = (p) => !!p.steps;
5967
+ for (let i = 0; i < items.length; i++) {
5968
+ const item = items[i];
5969
+ const childId = `${node.id}_${i}`;
5970
+ let childNode;
5971
+ if (isWorkflowDef(config.processor)) {
5972
+ childNode = {
5973
+ id: childId,
5974
+ config: {
5975
+ type: "subWorkflow",
5976
+ workflow: config.processor,
5977
+ input: item,
5978
+ retry: config.retry,
5979
+ checkpoint: false
5980
+ // Don't checkpoint individual map items by default
5981
+ }
5982
+ };
5983
+ } else {
5984
+ const processorConfig = { ...config.processor.config };
5985
+ if (processorConfig.type === "step") {
5986
+ processorConfig.input = item;
5987
+ }
5988
+ childNode = {
5989
+ id: childId,
5990
+ config: processorConfig
5991
+ };
5992
+ }
5993
+ childNodes.push(childNode);
5994
+ }
5995
+ const originalConcurrency = this.config.maxConcurrency;
5996
+ if (config.concurrency) {
5997
+ this.config.maxConcurrency = config.concurrency;
5998
+ }
5999
+ try {
6000
+ const result = await this.execute(childNodes, {
6001
+ id: `${node.id}_map`,
6002
+ workflowId: "",
6003
+ status: "running",
6004
+ input: context.input,
6005
+ nodeStates: {},
6006
+ // Start fresh for map iteration
6007
+ currentNodes: [],
6008
+ context: { ...context },
6009
+ // Pass copy of context so they can read global state
6010
+ checkpoints: [],
6011
+ pendingApprovals: [],
6012
+ createdAt: /* @__PURE__ */ new Date()
6013
+ });
6014
+ Object.assign(nodeStates, result.nodeStates);
6015
+ const outputs = childNodes.map((child) => {
6016
+ const childState = result.nodeStates[child.id];
6017
+ return childState?.output;
6018
+ });
6019
+ const state = {
6020
+ nodeId: node.id,
6021
+ status: result.completed ? "completed" : result.waiting ? "running" : "failed",
6022
+ output: outputs,
6023
+ error: result.error,
6024
+ attempt: 1,
6025
+ startedAt: new Date(startTime),
6026
+ completedAt: result.completed ? /* @__PURE__ */ new Date() : void 0
6027
+ };
6028
+ this.config.onNodeComplete?.(node.id, state);
6029
+ return {
6030
+ state,
6031
+ contextUpdates: result.completed ? { [node.id]: outputs } : {},
6032
+ waiting: result.waiting
6033
+ };
6034
+ } finally {
6035
+ this.config.maxConcurrency = originalConcurrency;
6036
+ }
6037
+ }
6038
+ /**
6039
+ * Execute a sub-workflow node
6040
+ */
6041
+ async executeSubWorkflowNode(node, config, context, nodeStates) {
6042
+ const startTime = Date.now();
6043
+ let workflowDef;
6044
+ if (typeof config.workflow === "string") {
6045
+ throw new Error("Resolving workflow by ID is not yet supported in this execution context. Pass the WorkflowDefinition object.");
6046
+ } else {
6047
+ workflowDef = config.workflow;
6048
+ }
6049
+ const input = typeof config.input === "function" ? await config.input(context) : config.input ?? context.input;
6050
+ let steps;
6051
+ if (typeof workflowDef.steps === "function") {
6052
+ steps = workflowDef.steps({
6053
+ input,
6054
+ context
6055
+ });
6056
+ } else {
6057
+ steps = workflowDef.steps;
6058
+ }
6059
+ const subRunId = `${node.id}_sub_${generateId()}`;
6060
+ const result = await this.execute(steps, {
6061
+ id: subRunId,
6062
+ workflowId: workflowDef.id,
6063
+ status: "running",
6064
+ input,
6065
+ nodeStates: {},
6066
+ currentNodes: [],
6067
+ context: {
6068
+ input
6069
+ // Subworkflow starts with fresh context scoped to its input
6070
+ // We do NOT inherit parent context to ensure isolation,
6071
+ // unless explicitly passed via input.
6072
+ },
6073
+ checkpoints: [],
6074
+ pendingApprovals: [],
6075
+ createdAt: /* @__PURE__ */ new Date()
6076
+ });
6077
+ let finalOutput = result.context;
6078
+ if (result.completed && config.output) {
6079
+ finalOutput = config.output(result.context);
6080
+ }
6081
+ const state = {
6082
+ nodeId: node.id,
6083
+ status: result.completed ? "completed" : result.waiting ? "running" : "failed",
6084
+ output: finalOutput,
6085
+ error: result.error,
6086
+ attempt: 1,
6087
+ startedAt: new Date(startTime),
6088
+ completedAt: result.completed ? /* @__PURE__ */ new Date() : void 0
6089
+ };
6090
+ this.config.onNodeComplete?.(node.id, state);
6091
+ return {
6092
+ state,
6093
+ contextUpdates: result.completed ? { [node.id]: finalOutput } : {},
6094
+ waiting: result.waiting
6095
+ };
6096
+ }
5938
6097
  /**
5939
6098
  * Execute a step node
5940
6099
  */
@@ -6745,9 +6904,12 @@ var WorkflowExecutor = class _WorkflowExecutor {
6745
6904
  if (Array.isArray(workflow2.steps)) {
6746
6905
  nodes = workflow2.steps;
6747
6906
  } else {
6907
+ if (!this.config.blobStorage) {
6908
+ }
6748
6909
  const builderContext = {
6749
6910
  input: context.input,
6750
- context
6911
+ context,
6912
+ blobStorage: this.config.blobStorage
6751
6913
  };
6752
6914
  nodes = workflow2.steps(builderContext);
6753
6915
  }