From af01a712f53e07df23ede6bf053aac783b7b660b Mon Sep 17 00:00:00 2001 From: lreynaldoj Date: Tue, 17 Jun 2025 13:54:18 -0400 Subject: [PATCH 1/5] Add control flow examples and utility functions for Cue package - Introduced new examples for various control flows: branch, parallel, sequential, do-until, do-while, and foreach. - Created utility functions for block operations including math, parallel, branch, and loop blocks. - Implemented logging and monitoring utilities to track workflow execution and block status. - Enhanced the overall structure and organization of control flow examples for better clarity and usability. --- .../cue/src/examples/control-flows/branch.ts | 44 +++++++ .../examples/control-flows/loops/dountil.ts | 40 +++++++ .../examples/control-flows/loops/dowhile.ts | 40 +++++++ .../examples/control-flows/loops/foreach.ts | 37 ++++++ .../src/examples/control-flows/parallel.ts | 40 +++++++ .../src/examples/control-flows/sequential.ts | 40 +++++++ .../examples/control-flows/utils/blocks.ts | 112 ++++++++++++++++++ .../examples/control-flows/utils/logger.ts | 26 ++++ 8 files changed, 379 insertions(+) create mode 100644 packages/cue/src/examples/control-flows/branch.ts create mode 100644 packages/cue/src/examples/control-flows/loops/dountil.ts create mode 100644 packages/cue/src/examples/control-flows/loops/dowhile.ts create mode 100644 packages/cue/src/examples/control-flows/loops/foreach.ts create mode 100644 packages/cue/src/examples/control-flows/parallel.ts create mode 100644 packages/cue/src/examples/control-flows/sequential.ts create mode 100644 packages/cue/src/examples/control-flows/utils/blocks.ts create mode 100644 packages/cue/src/examples/control-flows/utils/logger.ts diff --git a/packages/cue/src/examples/control-flows/branch.ts b/packages/cue/src/examples/control-flows/branch.ts new file mode 100644 index 0000000..88d4f0f --- /dev/null +++ b/packages/cue/src/examples/control-flows/branch.ts @@ -0,0 +1,44 @@ +import { Cue } from '../../../src/cue'; +import { z } from 'zod'; +import { log, monitorCue } from './utils/logger'; +import { createBranchBlocks } from './utils/blocks'; + +// Create branch workflow +const createBranchWorkflow = () => { + const { greaterThanBlock, lessThanBlock } = createBranchBlocks(); + + const cue = Cue.createCue({ + id: 'branch-workflow', + inputSchema: z.number(), + outputSchema: z.string(), + }); + + // Create conditional branches + cue.branch([ + [async ({ inputData }) => inputData > 10, greaterThanBlock], + [async ({ inputData }) => inputData <= 10, lessThanBlock], + ]); + + return cue; +}; + +// Example usage +const main = async () => { + try { + const workflow = createBranchWorkflow(); + const unsubscribeMain = monitorCue(workflow); + + // Test with different numbers + const results = await Promise.all([ + workflow.start(5), // Should use lessThanBlock + workflow.start(15), // Should use greaterThanBlock + ]); + + log('Final results:', results); + unsubscribeMain(); + } catch (error) { + console.error('Error:', error); + } +}; + +main(); diff --git a/packages/cue/src/examples/control-flows/loops/dountil.ts b/packages/cue/src/examples/control-flows/loops/dountil.ts new file mode 100644 index 0000000..e36929a --- /dev/null +++ b/packages/cue/src/examples/control-flows/loops/dountil.ts @@ -0,0 +1,40 @@ +import { Cue } from '../../../../src/cue'; +import { z } from 'zod'; +import { log, monitorCue } from '../utils/logger'; +import { createLoopBlocks } from '../utils/blocks'; + +// Create do-until workflow +const createDoUntilWorkflow = () => { + const { counterBlock } = createLoopBlocks(); + + const cue = Cue.createCue({ + id: 'dountil-workflow', + inputSchema: z.number(), + outputSchema: z.number(), + }); + + // Execute block until condition becomes true + cue.dountil( + counterBlock, + async ({ inputData }) => inputData >= 5 // Stop when number reaches or exceeds 5 + ); + + return cue; +}; + +// Example usage +const main = async () => { + try { + const workflow = createDoUntilWorkflow(); + const unsubscribeMain = monitorCue(workflow); + + const result = await workflow.start(1); // Start from 1 + + log('Final result:', result); + unsubscribeMain(); + } catch (error) { + console.error('Error:', error); + } +}; + +main(); diff --git a/packages/cue/src/examples/control-flows/loops/dowhile.ts b/packages/cue/src/examples/control-flows/loops/dowhile.ts new file mode 100644 index 0000000..694e8ac --- /dev/null +++ b/packages/cue/src/examples/control-flows/loops/dowhile.ts @@ -0,0 +1,40 @@ +import { Cue } from '../../../../src/cue'; +import { z } from 'zod'; +import { log, monitorCue } from '../utils/logger'; +import { createLoopBlocks } from '../utils/blocks'; + +// Create do-while workflow +const createDoWhileWorkflow = () => { + const { counterBlock } = createLoopBlocks(); + + const cue = Cue.createCue({ + id: 'dowhile-workflow', + inputSchema: z.number(), + outputSchema: z.number(), + }); + + // Execute block while condition is true + cue.dowhile( + counterBlock, + async ({ inputData }) => inputData < 5 // Continue while number is less than 5 + ); + + return cue; +}; + +// Example usage +const main = async () => { + try { + const workflow = createDoWhileWorkflow(); + const unsubscribeMain = monitorCue(workflow); + + const result = await workflow.start(1); // Start from 1 + + log('Final result:', result); + unsubscribeMain(); + } catch (error) { + console.error('Error:', error); + } +}; + +main(); diff --git a/packages/cue/src/examples/control-flows/loops/foreach.ts b/packages/cue/src/examples/control-flows/loops/foreach.ts new file mode 100644 index 0000000..d271b0e --- /dev/null +++ b/packages/cue/src/examples/control-flows/loops/foreach.ts @@ -0,0 +1,37 @@ +import { Cue } from '../../../../src/cue'; +import { z } from 'zod'; +import { log, monitorCue } from '../utils/logger'; +import { createLoopBlocks } from '../utils/blocks'; + +// Create foreach workflow +const createForEachWorkflow = () => { + const { processItemBlock } = createLoopBlocks(); + + const cue = Cue.createCue({ + id: 'foreach-workflow', + inputSchema: z.array(z.number()), + outputSchema: z.array(z.number()), + }); + + // Process each item in the array + cue.foreach(processItemBlock); + + return cue; +}; + +// Example usage +const main = async () => { + try { + const workflow = createForEachWorkflow(); + const unsubscribeMain = monitorCue(workflow); + + const result = await workflow.start([1, 2, 3, 4, 5]); + + log('Final result:', result); + unsubscribeMain(); + } catch (error) { + console.error('Error:', error); + } +}; + +main(); diff --git a/packages/cue/src/examples/control-flows/parallel.ts b/packages/cue/src/examples/control-flows/parallel.ts new file mode 100644 index 0000000..67a6735 --- /dev/null +++ b/packages/cue/src/examples/control-flows/parallel.ts @@ -0,0 +1,40 @@ +import { Cue } from '../../../src/cue'; +import { z } from 'zod'; +import { log, monitorCue } from './utils/logger'; +import { createParallelBlocks } from './utils/blocks'; + +// Create parallel workflow +const createParallelWorkflow = () => { + const { squareBlock, cubeBlock } = createParallelBlocks(); + + const cue = Cue.createCue({ + id: 'parallel-workflow', + inputSchema: z.number(), + outputSchema: z.object({ + square: z.number(), + cube: z.number(), + }), + }); + + // Execute blocks in parallel + cue.parallel([squareBlock, cubeBlock]); + + return cue; +}; + +// Example usage +const main = async () => { + try { + const workflow = createParallelWorkflow(); + const unsubscribeMain = monitorCue(workflow); + + const result = await workflow.start(5); + + log('Final result:', result); + unsubscribeMain(); + } catch (error) { + console.error('Error:', error); + } +}; + +main(); diff --git a/packages/cue/src/examples/control-flows/sequential.ts b/packages/cue/src/examples/control-flows/sequential.ts new file mode 100644 index 0000000..3594b76 --- /dev/null +++ b/packages/cue/src/examples/control-flows/sequential.ts @@ -0,0 +1,40 @@ +import { Cue } from '../../../src/cue'; +import { z } from 'zod'; +import { log, monitorCue } from './utils/logger'; +import { createMathBlocks } from './utils/blocks'; + +// Create sequential workflow +const createSequentialWorkflow = () => { + const { addBlock, multiplyBlock } = createMathBlocks(); + + const cue = Cue.createCue({ + id: 'sequential-workflow', + inputSchema: z.object({ a: z.number(), b: z.number() }), + outputSchema: z.number(), + }); + + // Chain blocks sequentially + cue.then(addBlock).then(multiplyBlock); + + return cue; +}; + +// Example usage +const main = async () => { + try { + const workflow = createSequentialWorkflow(); + const unsubscribeMain = monitorCue(workflow); + + const result = await workflow.start({ + a: 5, + b: 3, + }); + + log('Final result:', result); + unsubscribeMain(); + } catch (error) { + console.error('Error:', error); + } +}; + +main(); diff --git a/packages/cue/src/examples/control-flows/utils/blocks.ts b/packages/cue/src/examples/control-flows/utils/blocks.ts new file mode 100644 index 0000000..2ac0f96 --- /dev/null +++ b/packages/cue/src/examples/control-flows/utils/blocks.ts @@ -0,0 +1,112 @@ +import { Cue } from '../../../../src/cue'; +import { z } from 'zod'; +import { log } from './logger'; + +// Basic math operations +export const createMathBlocks = () => { + const addBlock = Cue.createBlock({ + id: 'add', + inputSchema: z.object({ a: z.number(), b: z.number() }), + outputSchema: z.number(), + execute: async ({ inputData }) => { + const result = inputData.a + inputData.b; + log('Add block executed', { input: inputData, result }); + return result; + }, + }); + + const multiplyBlock = Cue.createBlock({ + id: 'multiply', + inputSchema: z.number(), + outputSchema: z.number(), + execute: async ({ inputData }) => { + const result = inputData * 2; + log('Multiply block executed', { input: inputData, result }); + + return result; + }, + }); + + return { addBlock, multiplyBlock }; +}; + +// Parallel operations +export const createParallelBlocks = () => { + const squareBlock = Cue.createBlock({ + id: 'square', + inputSchema: z.number(), + outputSchema: z.number(), + execute: async ({ inputData }) => { + const result = inputData * inputData; + log('Square block executed', { input: inputData, result }); + return result; + }, + }); + + const cubeBlock = Cue.createBlock({ + id: 'cube', + inputSchema: z.number(), + outputSchema: z.number(), + execute: async ({ inputData }) => { + const result = inputData * inputData * inputData; + log('Cube block executed', { input: inputData, result }); + return result; + }, + }); + + return { squareBlock, cubeBlock }; +}; + +// Branch operations +export const createBranchBlocks = () => { + const greaterThanBlock = Cue.createBlock({ + id: 'greater-than', + inputSchema: z.number(), + outputSchema: z.string(), + execute: async ({ inputData }) => { + const result = `Number ${inputData} is greater than 10`; + log('Greater than block executed', { input: inputData, result }); + return result; + }, + }); + + const lessThanBlock = Cue.createBlock({ + id: 'less-than', + inputSchema: z.number(), + outputSchema: z.string(), + execute: async ({ inputData }) => { + const result = `Number ${inputData} is less than or equal to 10`; + log('Less than block executed', { input: inputData, result }); + return result; + }, + }); + + return { greaterThanBlock, lessThanBlock }; +}; + +// Loop operations +export const createLoopBlocks = () => { + const counterBlock = Cue.createBlock({ + id: 'counter', + inputSchema: z.number(), + outputSchema: z.number(), + execute: async ({ inputData }) => { + const result = inputData + 1; + log('Counter block executed', { input: inputData, result }); + return result; + }, + }); + + const processItemBlock = Cue.createBlock({ + id: 'process-item', + inputSchema: z.number(), + outputSchema: z.number(), + execute: async ({ inputData }) => { + const result = inputData * 3; + log('Process item block executed', { input: inputData, result }); + return result; + }, + }); + + return { counterBlock, processItemBlock }; +}; diff --git a/packages/cue/src/examples/control-flows/utils/logger.ts b/packages/cue/src/examples/control-flows/utils/logger.ts new file mode 100644 index 0000000..9c7b71f --- /dev/null +++ b/packages/cue/src/examples/control-flows/utils/logger.ts @@ -0,0 +1,26 @@ +export const log = (message: string, data?: any) => { + console.log(`\n[${new Date().toISOString()}] ${message}`); + if (data) { + console.log(JSON.stringify(data, null, 2)); + } +}; + +export const monitorCue = (cue: any) => { + // Monitor overall Cue status + cue.watch((event: any) => { + log(`Cue Status Update: ${event.type}`, event.data); + }); + + // Monitor block results + const unsubscribe = cue.store.subscribe((state: any) => { + const lastLog = state.logs[state.logs.length - 1]; + if (lastLog?.logType === 'BlockStatusUpdate') { + log(`Block ${lastLog.blockId} Status: ${lastLog.blockStatus}`, { + result: lastLog.blockResult, + executionPath: state.executionPath, + }); + } + }); + + return unsubscribe; +}; From 65ddbe1c67f0b5b26524aa368a30161e26d314e5 Mon Sep 17 00:00:00 2001 From: lreynaldoj Date: Tue, 17 Jun 2025 14:00:52 -0400 Subject: [PATCH 2/5] Refactor control flow examples to define blocks directly in workflows - Removed utility functions for creating blocks and defined blocks directly within each control flow example (branch, parallel, sequential, do-until, do-while, foreach). - Enhanced clarity and maintainability by consolidating block definitions with their respective workflows. - Updated logging for block execution to ensure consistent output across examples. --- .../cue/src/examples/control-flows/branch.ts | 24 +++- .../examples/control-flows/loops/dountil.ts | 13 +- .../examples/control-flows/loops/dowhile.ts | 13 +- .../examples/control-flows/loops/foreach.ts | 13 +- .../src/examples/control-flows/parallel.ts | 24 +++- .../src/examples/control-flows/sequential.ts | 24 +++- .../examples/control-flows/utils/blocks.ts | 112 ------------------ 7 files changed, 99 insertions(+), 124 deletions(-) delete mode 100644 packages/cue/src/examples/control-flows/utils/blocks.ts diff --git a/packages/cue/src/examples/control-flows/branch.ts b/packages/cue/src/examples/control-flows/branch.ts index 88d4f0f..07bb5cc 100644 --- a/packages/cue/src/examples/control-flows/branch.ts +++ b/packages/cue/src/examples/control-flows/branch.ts @@ -1,11 +1,31 @@ import { Cue } from '../../../src/cue'; import { z } from 'zod'; import { log, monitorCue } from './utils/logger'; -import { createBranchBlocks } from './utils/blocks'; // Create branch workflow const createBranchWorkflow = () => { - const { greaterThanBlock, lessThanBlock } = createBranchBlocks(); + // Define blocks + const greaterThanBlock = Cue.createBlock({ + id: 'greater-than', + inputSchema: z.number(), + outputSchema: z.string(), + execute: async ({ inputData }) => { + const result = `Number ${inputData} is greater than 10`; + log('Greater than block executed', { input: inputData, result }); + return result; + }, + }); + + const lessThanBlock = Cue.createBlock({ + id: 'less-than', + inputSchema: z.number(), + outputSchema: z.string(), + execute: async ({ inputData }) => { + const result = `Number ${inputData} is less than or equal to 10`; + log('Less than block executed', { input: inputData, result }); + return result; + }, + }); const cue = Cue.createCue({ id: 'branch-workflow', diff --git a/packages/cue/src/examples/control-flows/loops/dountil.ts b/packages/cue/src/examples/control-flows/loops/dountil.ts index e36929a..bdedba9 100644 --- a/packages/cue/src/examples/control-flows/loops/dountil.ts +++ b/packages/cue/src/examples/control-flows/loops/dountil.ts @@ -1,11 +1,20 @@ import { Cue } from '../../../../src/cue'; import { z } from 'zod'; import { log, monitorCue } from '../utils/logger'; -import { createLoopBlocks } from '../utils/blocks'; // Create do-until workflow const createDoUntilWorkflow = () => { - const { counterBlock } = createLoopBlocks(); + // Define block + const counterBlock = Cue.createBlock({ + id: 'counter', + inputSchema: z.number(), + outputSchema: z.number(), + execute: async ({ inputData }) => { + const result = inputData + 1; + log('Counter block executed', { input: inputData, result }); + return result; + }, + }); const cue = Cue.createCue({ id: 'dountil-workflow', diff --git a/packages/cue/src/examples/control-flows/loops/dowhile.ts b/packages/cue/src/examples/control-flows/loops/dowhile.ts index 694e8ac..be3df28 100644 --- a/packages/cue/src/examples/control-flows/loops/dowhile.ts +++ b/packages/cue/src/examples/control-flows/loops/dowhile.ts @@ -1,11 +1,20 @@ import { Cue } from '../../../../src/cue'; import { z } from 'zod'; import { log, monitorCue } from '../utils/logger'; -import { createLoopBlocks } from '../utils/blocks'; // Create do-while workflow const createDoWhileWorkflow = () => { - const { counterBlock } = createLoopBlocks(); + // Define block + const counterBlock = Cue.createBlock({ + id: 'counter', + inputSchema: z.number(), + outputSchema: z.number(), + execute: async ({ inputData }) => { + const result = inputData + 1; + log('Counter block executed', { input: inputData, result }); + return result; + }, + }); const cue = Cue.createCue({ id: 'dowhile-workflow', diff --git a/packages/cue/src/examples/control-flows/loops/foreach.ts b/packages/cue/src/examples/control-flows/loops/foreach.ts index d271b0e..a50ee76 100644 --- a/packages/cue/src/examples/control-flows/loops/foreach.ts +++ b/packages/cue/src/examples/control-flows/loops/foreach.ts @@ -1,11 +1,20 @@ import { Cue } from '../../../../src/cue'; import { z } from 'zod'; import { log, monitorCue } from '../utils/logger'; -import { createLoopBlocks } from '../utils/blocks'; // Create foreach workflow const createForEachWorkflow = () => { - const { processItemBlock } = createLoopBlocks(); + // Define block + const processItemBlock = Cue.createBlock({ + id: 'process-item', + inputSchema: z.number(), + outputSchema: z.number(), + execute: async ({ inputData }) => { + const result = inputData * 3; + log('Process item block executed', { input: inputData, result }); + return result; + }, + }); const cue = Cue.createCue({ id: 'foreach-workflow', diff --git a/packages/cue/src/examples/control-flows/parallel.ts b/packages/cue/src/examples/control-flows/parallel.ts index 67a6735..0a696d2 100644 --- a/packages/cue/src/examples/control-flows/parallel.ts +++ b/packages/cue/src/examples/control-flows/parallel.ts @@ -1,11 +1,31 @@ import { Cue } from '../../../src/cue'; import { z } from 'zod'; import { log, monitorCue } from './utils/logger'; -import { createParallelBlocks } from './utils/blocks'; // Create parallel workflow const createParallelWorkflow = () => { - const { squareBlock, cubeBlock } = createParallelBlocks(); + // Define blocks + const squareBlock = Cue.createBlock({ + id: 'square', + inputSchema: z.number(), + outputSchema: z.number(), + execute: async ({ inputData }) => { + const result = inputData * inputData; + log('Square block executed', { input: inputData, result }); + return result; + }, + }); + + const cubeBlock = Cue.createBlock({ + id: 'cube', + inputSchema: z.number(), + outputSchema: z.number(), + execute: async ({ inputData }) => { + const result = inputData * inputData * inputData; + log('Cube block executed', { input: inputData, result }); + return result; + }, + }); const cue = Cue.createCue({ id: 'parallel-workflow', diff --git a/packages/cue/src/examples/control-flows/sequential.ts b/packages/cue/src/examples/control-flows/sequential.ts index 3594b76..05a29ca 100644 --- a/packages/cue/src/examples/control-flows/sequential.ts +++ b/packages/cue/src/examples/control-flows/sequential.ts @@ -1,11 +1,31 @@ import { Cue } from '../../../src/cue'; import { z } from 'zod'; import { log, monitorCue } from './utils/logger'; -import { createMathBlocks } from './utils/blocks'; // Create sequential workflow const createSequentialWorkflow = () => { - const { addBlock, multiplyBlock } = createMathBlocks(); + // Define blocks + const addBlock = Cue.createBlock({ + id: 'add', + inputSchema: z.object({ a: z.number(), b: z.number() }), + outputSchema: z.number(), + execute: async ({ inputData }) => { + const result = inputData.a + inputData.b; + log('Add block executed', { input: inputData, result }); + return result; + }, + }); + + const multiplyBlock = Cue.createBlock({ + id: 'multiply', + inputSchema: z.number(), + outputSchema: z.number(), + execute: async ({ inputData }) => { + const result = inputData * 2; + log('Multiply block executed', { input: inputData, result }); + return result; + }, + }); const cue = Cue.createCue({ id: 'sequential-workflow', diff --git a/packages/cue/src/examples/control-flows/utils/blocks.ts b/packages/cue/src/examples/control-flows/utils/blocks.ts deleted file mode 100644 index 2ac0f96..0000000 --- a/packages/cue/src/examples/control-flows/utils/blocks.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { Cue } from '../../../../src/cue'; -import { z } from 'zod'; -import { log } from './logger'; - -// Basic math operations -export const createMathBlocks = () => { - const addBlock = Cue.createBlock({ - id: 'add', - inputSchema: z.object({ a: z.number(), b: z.number() }), - outputSchema: z.number(), - execute: async ({ inputData }) => { - const result = inputData.a + inputData.b; - log('Add block executed', { input: inputData, result }); - return result; - }, - }); - - const multiplyBlock = Cue.createBlock({ - id: 'multiply', - inputSchema: z.number(), - outputSchema: z.number(), - execute: async ({ inputData }) => { - const result = inputData * 2; - log('Multiply block executed', { input: inputData, result }); - - return result; - }, - }); - - return { addBlock, multiplyBlock }; -}; - -// Parallel operations -export const createParallelBlocks = () => { - const squareBlock = Cue.createBlock({ - id: 'square', - inputSchema: z.number(), - outputSchema: z.number(), - execute: async ({ inputData }) => { - const result = inputData * inputData; - log('Square block executed', { input: inputData, result }); - return result; - }, - }); - - const cubeBlock = Cue.createBlock({ - id: 'cube', - inputSchema: z.number(), - outputSchema: z.number(), - execute: async ({ inputData }) => { - const result = inputData * inputData * inputData; - log('Cube block executed', { input: inputData, result }); - return result; - }, - }); - - return { squareBlock, cubeBlock }; -}; - -// Branch operations -export const createBranchBlocks = () => { - const greaterThanBlock = Cue.createBlock({ - id: 'greater-than', - inputSchema: z.number(), - outputSchema: z.string(), - execute: async ({ inputData }) => { - const result = `Number ${inputData} is greater than 10`; - log('Greater than block executed', { input: inputData, result }); - return result; - }, - }); - - const lessThanBlock = Cue.createBlock({ - id: 'less-than', - inputSchema: z.number(), - outputSchema: z.string(), - execute: async ({ inputData }) => { - const result = `Number ${inputData} is less than or equal to 10`; - log('Less than block executed', { input: inputData, result }); - return result; - }, - }); - - return { greaterThanBlock, lessThanBlock }; -}; - -// Loop operations -export const createLoopBlocks = () => { - const counterBlock = Cue.createBlock({ - id: 'counter', - inputSchema: z.number(), - outputSchema: z.number(), - execute: async ({ inputData }) => { - const result = inputData + 1; - log('Counter block executed', { input: inputData, result }); - return result; - }, - }); - - const processItemBlock = Cue.createBlock({ - id: 'process-item', - inputSchema: z.number(), - outputSchema: z.number(), - execute: async ({ inputData }) => { - const result = inputData * 3; - log('Process item block executed', { input: inputData, result }); - return result; - }, - }); - - return { counterBlock, processItemBlock }; -}; From e4e90011a6ef00aa0814d73eb67991bcbeff5dcb Mon Sep 17 00:00:00 2001 From: lreynaldoj Date: Tue, 17 Jun 2025 14:18:07 -0400 Subject: [PATCH 3/5] Add mapping workflow example to control flows - Introduced a new example demonstrating a mapping workflow using Cue, featuring multiply and add blocks. - Defined block execution logic directly within the workflow for improved clarity and maintainability. - Implemented logging for block execution to track input and output values during the workflow process. --- .../examples/control-flows/loops/mapping.ts | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 packages/cue/src/examples/control-flows/loops/mapping.ts diff --git a/packages/cue/src/examples/control-flows/loops/mapping.ts b/packages/cue/src/examples/control-flows/loops/mapping.ts new file mode 100644 index 0000000..3011550 --- /dev/null +++ b/packages/cue/src/examples/control-flows/loops/mapping.ts @@ -0,0 +1,82 @@ +import { Cue } from '../../../../src/cue'; +import { z } from 'zod'; +import { log, monitorCue } from '../utils/logger'; + +// Create mapping workflow +const createMappingWorkflow = () => { + // Define blocks + const multiplyBlock = Cue.createBlock({ + id: 'multiply', + inputSchema: z.number(), + outputSchema: z.object({ + original: z.number(), + multiplied: z.number(), + }), + execute: async ({ inputData }) => { + const result = { + original: inputData, + multiplied: inputData * 2, + }; + log('Multiply block executed', { input: inputData, result }); + return result; + }, + }); + + const addBlock = Cue.createBlock({ + id: 'add', + inputSchema: z.object({ + value: z.number(), + increment: z.number(), + }), + outputSchema: z.number(), + execute: async ({ inputData }) => { + const result = inputData.value + inputData.increment; + log('Add block executed', { input: inputData, result }); + return result; + }, + }); + + const cue = Cue.createCue({ + id: 'mapping-workflow', + inputSchema: z.number(), + outputSchema: z.number(), + }); + + // Chain blocks with mapping + cue + .then(multiplyBlock) + .map({ + value: { + block: multiplyBlock, + path: 'multiplied', + }, + increment: { + value: 5, + schema: z.number(), + }, + }) + .then(addBlock); + + return cue; +}; + +// Example usage +const main = async () => { + try { + const workflow = createMappingWorkflow(); + const unsubscribeMain = monitorCue(workflow); + + const result = await workflow.start(3); // Input: 3 + // Expected flow: + // 1. multiplyBlock: 3 -> { original: 3, multiplied: 6 } + // 2. map: { value: 6, increment: 5 } + // 3. addBlock: 6 + 5 -> 11 + + log('Final result:', result); + unsubscribeMain(); + } catch (error) { + console.error('Error:', error); + } +}; + +main(); From 5079c05c5c2fb78e11fa250ed44dedf7369a99da Mon Sep 17 00:00:00 2001 From: lreynaldoj Date: Tue, 17 Jun 2025 15:50:14 -0400 Subject: [PATCH 4/5] Add mapping workflow example to control flows - Introduced a new example demonstrating a mapping workflow using Cue, featuring multiply and add blocks. - Defined block execution logic directly within the workflow for improved clarity and maintainability. - Implemented logging for block execution to track input and output values during the workflow process. --- .../src/examples/control-flows/{loops/mapping.ts => map.ts} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename packages/cue/src/examples/control-flows/{loops/mapping.ts => map.ts} (95%) diff --git a/packages/cue/src/examples/control-flows/loops/mapping.ts b/packages/cue/src/examples/control-flows/map.ts similarity index 95% rename from packages/cue/src/examples/control-flows/loops/mapping.ts rename to packages/cue/src/examples/control-flows/map.ts index 3011550..5b7b2bc 100644 --- a/packages/cue/src/examples/control-flows/loops/mapping.ts +++ b/packages/cue/src/examples/control-flows/map.ts @@ -1,6 +1,6 @@ -import { Cue } from '../../../../src/cue'; +import { Cue } from '../../cue'; import { z } from 'zod'; -import { log, monitorCue } from '../utils/logger'; +import { log, monitorCue } from './utils/logger'; // Create mapping workflow const createMappingWorkflow = () => { From b00f8cedaa827e93d3a88d0261d06a8ed94b0ed7 Mon Sep 17 00:00:00 2001 From: lreynaldoj Date: Tue, 17 Jun 2025 16:18:37 -0400 Subject: [PATCH 5/5] Add suspend/resume workflow example to control flows - Introduced a new example demonstrating a suspend/resume workflow using Cue. - Defined a suspend block that can pause execution and resume after a delay. - Implemented logging to track workflow status and suspended step details. - Enhanced example usage to illustrate the workflow's functionality and error handling. --- .../examples/control-flows/suspend-resume.ts | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 packages/cue/src/examples/control-flows/suspend-resume.ts diff --git a/packages/cue/src/examples/control-flows/suspend-resume.ts b/packages/cue/src/examples/control-flows/suspend-resume.ts new file mode 100644 index 0000000..38093b1 --- /dev/null +++ b/packages/cue/src/examples/control-flows/suspend-resume.ts @@ -0,0 +1,94 @@ +import { Cue } from '../../cue'; +import { z } from 'zod'; +import { log, monitorCue } from './utils/logger'; + +// Create a simple suspend/resume workflow +const createSimpleWorkflow = () => { + // Simple block that can be suspended + const suspendBlock = Cue.createBlock({ + id: 'suspend', + inputSchema: z.object({ + value: z.number(), + }), + outputSchema: z.number(), + execute: async ({ inputData, suspend }) => { + log('Block suspending', { input: inputData }); + await suspend(inputData); + return inputData.value * 2; + }, + }); + + // Create the workflow + const cue = Cue.createCue({ + id: 'simple-workflow', + inputSchema: z.object({ + value: z.number(), + }), + outputSchema: z.number(), + }); + + // Add the block to the workflow + cue.then(suspendBlock); + + return cue; +}; + +// Example usage +const main = async () => { + try { + console.log('Starting workflow...'); + const workflow = createSimpleWorkflow(); + const unsubscribe = monitorCue(workflow); + + // Start workflow + const result = await workflow.start({ + value: 10, + }); + + console.log('Workflow started with result:', result); + + if (result.status === 'suspended' && result.steps.suspend) { + const suspendedStep = result.steps.suspend; + log('Workflow suspended', result); + console.log('--------------------------------'); + console.log('Suspended step info:', { + status: suspendedStep.status, + output: suspendedStep.output, + suspendedPath: suspendedStep.suspendedPath, + }); + console.log('--------------------------------'); + + // Resume after delay + setTimeout(async () => { + try { + console.log('--------------------------------Resuming workflow...'); + const resumeResult = await workflow.resume({ + block: 'suspend', + resumeData: suspendedStep.output, + }); + log('Workflow completed', resumeResult); + } catch (error: any) { + console.error('Resume error:', error); + if (error && typeof error === 'object') { + console.error('Error details:', { + name: error.name, + message: error.message, + stack: error.stack, + }); + } + } + }, 6000); + } + + // Keep the process alive + setTimeout(() => { + console.log('Cleaning up...'); + unsubscribe(); + }, 7000); + } catch (error) { + console.error('Error:', error); + } +}; + +// Execute main function +main().catch(console.error);