Skip to content

Releases: zvictor/BrainyFlow

TypeScript Package v2.1.0

29 May 22:57
Compare
Choose a tag to compare

BrainyFlow TypeScript Package v2.1.0

Automatic Triggers Propagation

Since v2.0, Brainyflow propagates triggers from terminal nodes (i.e. nodes missing successors) to subsequent flows. This let you permeate an action from a node directly to outside of the parent flow, skipping the need to explicitly re-trigger the actions at the end of every flow execution.

This allows for more fluid and permeable flows, and effectively stops the parent flow from being a rigid barrier in the graph execution.
Think about it as "handing over unfinished tasks in a flow to the first node in the next flow".

It also means that you can preserve the concurrency of that execution path as you navigate into the next flow: the execution doesn’t end at the leaf node, it continues into the next flow.

Ignoring Implicit Triggers Propagation

In v2.1 we are stopping the propagation of Implicit Triggers - the default action that is automatically triggered when no .trigger() was explicitly called - to give users more control over trigger's propagation and avoid unexpected behavior.

Thus, this is the behaviour you can expect:

  1. If a terminal node does NOT explicitly call .trigger(), no action is propagated from that terminal node.
  2. If a terminal node calls .trigger(), then the parent flow propagates that action to its own sucessors - and any forking data passed is preserved.

Check https://brainy.gitbook.io/flow/core-abstraction/flow for more info!


Installation

npm install [email protected]
pnpm add [email protected]
yarn add [email protected]

NPM Package

📦 View on NPM

Python Package v2.1.0

29 May 22:59
Compare
Choose a tag to compare

BrainyFlow Python Package v2.1.0

Automatic Triggers Propagation

Since v2.0, Brainyflow propagates triggers from terminal nodes (i.e. nodes missing successors) to subsequent flows. This let you permeate an action from a node directly to outside of the parent flow, skipping the need to explicitly re-trigger the actions at the end of every flow execution.

This allows for more fluid and permeable flows, and effectively stops the parent flow from being a rigid barrier in the graph execution.
Think about it as "handing over unfinished tasks in a flow to the first node in the next flow".

It also means that you can preserve the concurrency of that execution path as you navigate into the next flow: the execution doesn’t end at the leaf node, it continues into the next flow.

Ignoring Implicit Triggers Propagation

In v2.1 we are stopping the propagation of Implicit Triggers - the default action that is automatically triggered when no .trigger() was explicitly called - to give users more control over trigger's propagation and avoid unexpected behavior.

Thus, this is the behaviour you can expect:

  1. If a terminal node does NOT explicitly call .trigger(), no action is propagated from that terminal node.
  2. If a terminal node calls .trigger(), then the parent flow propagates that action to its own sucessors - and any forking data passed is preserved.

Check https://brainy.gitbook.io/flow/core-abstraction/flow for more info!


Installation

pip install brainyflow==2.1.0

PyPI Package

🐍 View on PyPI

TypeScript Package v2.0.0

28 May 23:31
Compare
Choose a tag to compare

BrainyFlow TypeScript Package v2.0.0

NPM Package

📦 View on NPM

Major Changes

  • 7dc9291: # Major Refactor and Enhancement for TypeScript

    This release introduces significant improvements to Memory management, Flow execution, and overall type safety.

    Breaking Changes

    • Flow as Node - Trigger Propagation: When a sub-flow (acting as a node) has an internal node triggering an action for which the sub-flow has no defined successor, this action now correctly propagates as a trigger from the sub-flow node itself in the parent flow's ExecutionTree.
    • Simplified Generic Types: The generic type hints for Flow and Node have been simplified, removing the L (i.e. LocalMemory) type parameter and moving the ActionT to the end of the list as it is rarely used. The local memory type can be defined inside the Global by using the property .local. Before: Node[G, L, ActionT, PrepResultT, ExecResultT]; Now: Node[G, PrepResultT, ExecResultT, ActionT].
    • New License: Brainyflow is now licensed under the Mozilla Public License 2.0.

    Rarely used other than internally, but still breaking changes:

    • Memory Creation: Memory.create(global, local) static method is removed. To create a memory object, just pass a plain object to flow.run({ ... }) as you always did or call the createMemory(global, local) factory function instead. This aligns with a more functional approach for creating the proxied Memory objects.
    • Memory Type: Memory is now an exported type alias representing the complex proxied structure, not a class to be instantiated directly with new.
    • Flow Execution Result: Flow.run() now returns an ExecutionTree object, providing a structured representation of the flow's execution path, triggered actions, and sub-node results. This replaces the previous less-structured result. The ExecutionTree structure is:
      type ExecutionTree = {
        order: number
        type: string
        triggered: Record<Action, ExecutionTree[]> | null
      }
    • Node __nodeOrder: The __nodeOrder property on BaseNode is now consistently a number.

    Core Library Changes & New Features

    Memory Management (createMemory)

    • Proxy-Based Implementation: createMemory function now constructs Memory objects using nested proxies to manage global and local scopes, closely mirroring the advanced Python Memory behavior.
    • Deletion and Existence: The Memory proxy handler now supports deleteProperty (for delete memory.key) and has (for 'key' in memory), operating on both local and global stores appropriately. memory.local proxy also supports these for the local scope.
    • Type Safety: Memory type uses generics GlobalStore and LocalStore for better type inference. _isMemoryObject flag added for runtime type assertions if needed.

    Flow Execution & ExecutionTree

    • Flow.run(): Returns a detailed ExecutionTree.
    • Cycle Detection: Default maxVisits for Flow instances increased from 5 to 15. Error messages for cycle detection now include node class name and ID (e.g., Maximum cycle count (15) reached for TestNode#0).
    • Node __nodeOrder: Now consistently a number. The order field in ExecutionTree is also a number.

    Node Lifecycle and Error Handling

    • BaseNode.triggers: Changed from private to protected to allow manipulation in subclasses if necessary (e.g., for complex trigger logic in ParallelFlow tests).
    • NodeError: Remains an Error subtype with an optional retryCount.
    • Warnings:
      • The warning "Node won't run successors. Use Flow!" when run() is called on a BaseNode with successors has been removed to reduce noise. #20
      • Warning for an "orphan action" (action triggered with no successor) in get_next_nodes has been refined for better clarity: Flow ends for node {ClassName}#{node_order}: Action '{action}' not found in its defined successors [...].

    Developer Experience & Testing

    • Test Suite: Comprehensive updates to memory.test.ts and flow.test.ts to cover new Memory functionalities (including cloning, local proxy operations, deletion, existence checks) and the new ExecutionTree structure.
    • Mock Resetting: Improved mock handling in tests for better isolation, particularly for TestNode instances.
    • Type Generics: Enhanced use of generics in TestNode and BranchingNode for better type safety in tests.

    Bug Fixes

    • V8 Debugger Craskeeping structuredClone and Proxies: Resolved by ensuring structuredClone in memory.clone() operates on plain object representations of proxied data.
    • ExecutionTree Structure: Standardized and made more robust.
    • Type Inconsistencies: Addressed various type issues for a more stable and predictable API.

    This major update significantly enhances the capabilities and reliability of the TypeScript port, especially around state management and flow execution tracking.

1.0.0

Major Changes

  • Refactor: Introduce Memory, trigger mechanism; remove Batch classes and params

    This release introduces a major architectural refactor:

    • Replaced the dictionary-based shared store with a Memory class managing global and local state via proxy access.
    • Nodes now use this.trigger("action", forkingData) in post to control flow instead of returning action strings.
    • Removed the params mechanism (setParams). Context should be passed via Memory (global or local via forkingData).
    • Removed BatchNode, ParallelBatchNode, SequentialBatchFlow, ParallelBatchFlow. Batch processing is now achieved using standard Nodes within Flow or ParallelFlow (e.g., fan-out pattern).
    • Updated documentation and tests extensively to reflect these changes.

Python Package v2.0.0

28 May 23:23
Compare
Choose a tag to compare

BrainyFlow Python Package v2.0.0

Installation

pip install brainyflow

PyPI Package

🐍 View on PyPI

Major Changes

  • 10289fa: # Major Refactor and Enhancement Release (Python)

    This release introduces a significant overhaul of the Memory class, refines Flow execution and cycle detection, and improves overall type safety and developer experience.

    Breaking Changes

    • Flow as Node - Trigger Propagation: When a sub-flow (acting as a node) has an internal node triggering an action for which the sub-flow has no defined successor, this action now correctly propagates as a trigger from the sub-flow node itself in the parent flow's ExecutionTree.
    • Simplified Generic Type Hints: The generic type hints for Flow and Node have been simplified, removing the L (i.e. LocalMemory) type parameter and moving the ActionT to the end of the list as it is rarely used. Before: Node[G, L, ActionT, PrepResultT, ExecResultT]; Now: Node[G, PrepResultT, ExecResultT, ActionT].
    • NodeError: Changed from an Exception subclass to a Protocol (runtime_checkable). This affects how NodeError might be caught or checked, promoting structural typing and fixing the double-raising of the exception.
    • New License: Brainyflow is now licensed under the Mozilla Public License 2.0.

    Rarely used other than internally, but still breaking changes:

    • Memory Creation: The static method Memory.create(global_store, local_store=None) has been removed. To create Memory instances, just pass a dict to flow.run({ ... }) as you always did, or use the standard constructor: Memory(global_store, local_store=None).
    • Flow Execution Result (Flow.run()): The run() method of a Flow now returns an ExecutionTree (a TypedDict with order: int, type: str, triggered: Optional[Dict[Action, List[ExecutionTree]]]). This provides a structured log of the execution, replacing the previous, less defined dictionary structure. Code that previously traversed the run() result will need to be updated to work with the new ExecutionTree format.
    • Internal Node Order (_node_order): This is now consistently an integer.

    Core Library Changes & New Features

    Memory Management (Memory Class)

    • Enhanced Proxy Behavior:
      • memory.local now returns a dedicated LocalProxy instance, providing isolated attribute and item access (getattr, getitem, setattr, setitem, delattr, delitem, contains) that operates only on the local store.
      • The main Memory object's attribute/item access (memory.foo, memory['foo']) continues to prioritize local then global for reads.
      • Writes (memory.foo = 'bar', memory['foo'] = 'bar') now consistently write to the global store, removing the key from the local store first if it exists there.
    • Comprehensive Deletion Support:
      • del memory.attr and del memory[key] now delete the key from both global and local stores if present in either (delegating to _delete_from_stores).
      • del memory.local.attr and del memory.local[key] delete only from the local store.
    • Helper Functions: Internal _get_from_stores and _delete_from_stores utility functions have been added to centralize store access logic.
    • Cloning: memory.clone(forking_data=None) remains, ensuring deep copy of the local store and merging of forking_data. Global store is shared by reference.

    Flow Execution & Cycle Detection

    • Flow.run() and ExecutionTree: As mentioned in Breaking Changes, returns a structured ExecutionTree.
    • Default maxVisits: Increased from 5 to 15 in the Flow constructor for cycle detection.
    • Cycle Detection Error Message: Improved format to: Maximum cycle count ({max_visits}) reached for {ClassName}#{node_order}.

    Node Lifecycle and Error Handling

    • NodeError Protocol: Now a typing.Protocol for more flexible error handling. error.retry_count is added to exceptions during the retry mechanism in Node.exec_runner.
    • Warnings:
      • The warning "Node won't run successors. Use Flow!" when run() is called on a BaseNode with successors has been removed to reduce noise. #20
      • Warning for an "orphan action" (action triggered with no successor) in get_next_nodes has been refined for better clarity: Flow ends for node {ClassName}#{node_order}: Action '{action}' not found in its defined successors [...].

    Type Annotations & Developer Experience

    • Improved Type Hints: Extensive improvements to type annotations throughout the library using TypeVar, Generic, Protocol, TypeAlias, and TypedDict for better static analysis and developer understanding. All MyPy errors and inconsistencies addressed.
    • Test Suite Enhancements:
      • Tests for new Memory deletion features and LocalProxy behavior.
      • Updated assertions for the new ExecutionTree structure.
      • BaseNode._next_id is reset in test fixtures/setups for predictable node ordering in tests.
      • More robust mocking and assertions for flow execution paths.
    • Documentation:
      • Migration guide (migrating_from_pocketflow.md) updated with clearer steps for async, trigger usage, memory access, and the new batch processing pattern.
      • Core abstraction documentation (flow.md, design.md) updated to reflect changes (e.g., maxVisits, Memory creation).
      • "Contributors Wanted!" section added to README.md.

    Infrastructure Improvements

    • CI/CD: GitHub Actions workflow changeset-check.yml updated to use changesets/[email protected] and properly prepare the Python directory for changeset tooling.
    • .envrc: Added dotenv_if_exists.
    • .gitignore: Added python/README.md (if it's auto-generated and shouldn't be committed).

    This release significantly modernizes the Python BrainyFlow library, especially its state management capabilities and execution tracking, while enhancing type safety and the overall development experience.