Flow in BRX

Flow in BRX refers to how data moves through a BRX workflow, from inputs to outputs, through various BRKs and their dependencies. Understanding flow is essential for designing effective and efficient BRX applications.

Data Flow Basics

In BRX, data flows through a directed graph of BRKs, where each BRK:

  1. Receives inputs from the user or from parent BRKs
  2. Processes those inputs using LLMs or other tools
  3. Produces outputs that can be used by dependent BRKs
  4. Returns final results to the user

This flow of data enables complex workflows where each BRK contributes to the overall process.

Input Flow

Inputs to a BRK can come from several sources:

User Inputs

The most direct source of inputs is from the user:

// User provides inputs directly to the BRK
myBrk.input['user_query'] = 'How do I make a chocolate cake?';
myBrk.input['max_length'] = '500 words';

Dependency Outputs

BRKs can also receive inputs from the outputs of their dependencies:

┌─────────────┐
│ Recipe BRK  │
└─────┬───────┘

      │ Output: Recipe details

┌─────────────┐
│ Format BRK  │
└─────────────┘

In this example, the Format BRK receives the output of the Recipe BRK as an input.

Environment Variables

BRKs can access environment variables and configuration settings:

┌─────────────┐
│ Config      │ ──► API keys, settings, etc.
└─────┬───────┘


┌─────────────┐
│ API BRK     │
└─────────────┘

Processing Flow

Once a BRK receives its inputs, it processes them according to its configuration:

Prompt Processing

The most common processing flow involves sending a prompt to an LLM:

  1. The BRK constructs a prompt using its template and input values
  2. The prompt is sent to the LLM
  3. The LLM generates a response
  4. The response is processed and structured as needed

Tool Calling

BRKs can also call external tools as part of their processing:

  1. The BRK prepares data for the external tool
  2. The tool is called with the prepared data
  3. The tool returns a result
  4. The result is incorporated into the BRK’s output

Conditional Processing

BRKs can implement conditional processing flows:

┌─────────────┐
│ Router BRK  │
└─────┬───────┘

      ├─────► If condition A: BRK A

      ├─────► If condition B: BRK B

      └─────► If condition C: BRK C

Output Flow

After processing, BRKs produce outputs that flow to their dependents:

Direct Outputs

The simplest output flow is a direct output to the user:

const result = await brx.run(myBrk);
console.log(result[0].brxRes.output);

Dependency Chains

Outputs can flow through chains of dependencies:

┌─────────────┐
│ Extract BRK │
└─────┬───────┘

      │ Output: Extracted data

┌─────────────┐
│ Analyze BRK │
└─────┬───────┘

      │ Output: Analysis results

┌─────────────┐
│ Report BRK  │
└─────────────┘

Parallel Flows

Outputs can flow to multiple dependent BRKs in parallel:

              ┌─────────────┐
              │ Summary BRK │
              └─────────────┘


┌─────────────┼─────────────┐
│ Data BRK    │             │
└─────────────┘             │
              │             │
              ▼             │
              ┌─────────────┐
              │ Chart BRK   │
              └─────────────┘

Flow Control

BRX provides several mechanisms for controlling the flow of data:

Sequential Execution

By default, BRKs are executed in a sequence determined by their dependencies:

BRK A ──► BRK B ──► BRK C

BRK A is executed first, then BRK B, then BRK C.

Parallel Execution

Independent BRKs can be executed in parallel:

BRK A ──┐
        ├──► BRK C
BRK B ──┘

BRK A and BRK B are executed in parallel, and their outputs are combined for BRK C.

Conditional Execution

BRKs can implement conditional execution based on inputs or other factors:

// Conditional execution based on input
if (input.format === 'markdown') {
  // Execute Markdown BRK
  const result = await brx.run(markdownBrk);
} else {
  // Execute HTML BRK
  const result = await brx.run(htmlBrk);
}

Flow Patterns

Several common flow patterns are used in BRX applications:

Pipeline Pattern

The pipeline pattern is a linear sequence of BRKs, where each BRK processes the output of the previous one:

BRK A ──► BRK B ──► BRK C ──► BRK D

This pattern is useful for sequential processing steps, such as:

  1. Extract data from text
  2. Clean and normalize the data
  3. Analyze the data
  4. Generate a report

Fan-Out Pattern

The fan-out pattern involves a single BRK that feeds multiple dependent BRKs:

         ┌──► BRK B

BRK A ───┼──► BRK C

         └──► BRK D

This pattern is useful when you need to process the same data in multiple ways, such as:

  1. Extract data from text
  2. Generate a summary
  3. Create visualizations
  4. Translate to different languages

Fan-In Pattern

The fan-in pattern involves multiple BRKs that feed into a single dependent BRK:

BRK A ──┐

BRK B ──┼──► BRK D

BRK C ──┘

This pattern is useful when you need to combine data from multiple sources, such as:

  1. Collect data from multiple APIs
  2. Combine the data
  3. Generate a comprehensive report

Feedback Loop Pattern

The feedback loop pattern involves a BRK that feeds back into itself or an earlier BRK in the chain:

┌───────────────┐
│               │
│               ▼
BRK A ──► BRK B ──► BRK C

This pattern is useful for iterative refinement, such as:

  1. Generate an initial draft
  2. Evaluate the draft
  3. If not satisfactory, refine and repeat

Best Practices

Design for Clear Flow

  • Design your BRK dependencies to create a clear and logical flow of data
  • Avoid overly complex dependency graphs that are difficult to understand
  • Document the expected inputs and outputs of each BRK

Optimize Flow Efficiency

  • Minimize unnecessary data transfers between BRKs
  • Use parallel execution where appropriate to improve performance
  • Cache intermediate results to avoid redundant processing

Monitor and Debug Flow

  • Log the flow of data through your BRK workflow
  • Monitor execution times and resource usage
  • Use debugging tools to identify bottlenecks and issues

Handle Flow Errors

  • Implement error handling at each stage of the flow
  • Provide fallback options for critical paths
  • Design your flow to be resilient to failures

Example: Content Creation Workflow

Here’s an example of a content creation workflow that demonstrates various flow patterns:

┌─────────────┐
│ Topic BRK   │ ──► User provides a topic
└─────┬───────┘

      │ Output: Topic details

┌─────────────┐
│ Outline BRK │ ──► Generate an outline
└─────┬───────┘

      │ Output: Content outline

┌─────────────────────────────┐
│ Content Generation Router   │ ──► Route based on content type
└─────┬─────────┬─────────────┘
      │         │
      │         │ If video script
      │         ▼
      │   ┌─────────────┐
      │   │ Script BRK  │ ──► Generate video script
      │   └─────────────┘

      │ If blog post

┌─────────────┐
│ Blog BRK    │ ──► Generate blog post
└─────┬───────┘

      │ Output: Blog content

┌─────────────┐
│ Edit BRK    │ ──► Edit and refine content
└─────┬───────┘

      │ Output: Edited content

┌─────────────┐
│ Format BRK  │ ──► Format for publication
└─────────────┘

This workflow demonstrates:

  • Sequential flow (Topic → Outline)
  • Conditional flow (Content Generation Router)
  • Parallel paths (Blog vs. Script)
  • Pipeline pattern (Blog → Edit → Format)

By understanding and applying these flow concepts, you can design effective and efficient BRX workflows that meet your application’s needs.