npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

fluid-graph-ai

v1.0.0

Published

Dynamic, self-compiling DAG execution framework for AI agents.

Readme


🚀 What is FluidGraph?

FluidGraph.js is a TypeScript framework that eliminates the need to manually wire agent workflows. Unlike rigid graph frameworks (e.g., LangGraph) where you define every node and edge by hand, FluidGraph uses an LLM to dynamically compile a Directed Acyclic Graph (DAG) from a natural language goal and a set of available tools.

You describe what you want. FluidGraph figures out how.

Traditional Approach (LangGraph):
  Developer manually codes: A → B → C → D

FluidGraph Approach:
  Developer provides: Tools [A, B, C, D] + Goal "Do X"
  LLM compiles:       A → C → D  (skips B, it's not needed)

✨ Key Features

| Feature | Description | |---------|-------------| | 🧠 LLM-Powered Compilation | An LLM analyzes your goal and available tools, then generates the optimal execution graph automatically. | | 🔌 Multi-Provider | Works with Gemini, OpenAI, Anthropic, and any OpenAI-compatible API (Ollama, LM Studio, Together AI). | | 🔀 Dynamic DAG Generation | No manual node/edge wiring. The graph is compiled fresh for every request based on the goal. | | 📐 Topological Execution | Uses Kahn's algorithm to guarantee correct dependency ordering across the DAG. | | 🔄 Shared State Context | Nodes pass data through a shared ExecutionContext, enabling seamless data flow between steps. | | 🛡️ Cycle Detection | Built-in validation ensures the compiled graph is a true DAG (no infinite loops). | | 📝 Execution History | Full audit trail of every node execution for debugging and observability. |


📦 Installation

npm install fluidgraph

Or clone and install locally:

git clone https://github.com/your-org/fluidgraph.git
cd fluidgraph
npm install

⚡ Quick Start

1. Set up your API key

cp .env.example .env
# Edit .env and add your Gemini API key

Get your API key from Google AI Studio.

2. Pick your LLM provider

FluidGraph is model-agnostic. Use whichever provider you prefer:

import {
  GeminiProvider,
  OpenAIProvider,
  AnthropicProvider
} from 'fluidgraph';

// Google Gemini (default)
const provider = new GeminiProvider({ model: 'gemini-2.5-flash' });

// OpenAI
const provider = new OpenAIProvider({ model: 'gpt-4o' });

// Anthropic Claude
const provider = new AnthropicProvider({ model: 'claude-sonnet-4-20250514' });

// Any OpenAI-compatible API (Ollama, LM Studio, Together AI)
const provider = new OpenAIProvider({
  baseUrl: 'http://localhost:11434/v1',
  apiKey: 'ollama',
  model: 'llama3',
});

3. Define your tools

Each tool is a FluidNode with an id, name, description, and an async action function:

import { FluidNode } from 'fluidgraph';

const tools: FluidNode[] = [
  {
    id: 'fetch_data',
    name: 'Fetch Data',
    description: 'Fetches user data from the database. Outputs { userData: object }',
    action: async (state) => {
      const data = await db.getUser(state.userId);
      return { userData: data };
    }
  },
  {
    id: 'analyze',
    name: 'Analyze Engagement',
    description: 'Scores user engagement. Requires userData in state.',
    action: async (state) => {
      const score = calculateScore(state.userData);
      return { engagementScore: score };
    }
  },
  {
    id: 'notify',
    name: 'Send Notification',
    description: 'Sends a notification. Requires engagementScore in state.',
    action: async (state) => {
      await sendPush(state.engagementScore > 80 ? 'premium' : 'standard');
      return { notified: true };
    }
  }
];

4. Compile and execute

import { GraphCompiler, GraphExecutor } from 'fluidgraph';

const compiler = new GraphCompiler(provider); // pass any LLMProvider
const executor = new GraphExecutor(tools);

// Describe your goal in natural language
const goal = "Fetch user data, analyze their engagement, and send a notification.";

// The LLM dynamically compiles the optimal DAG
const graph = await compiler.compile(goal, tools);

// Execute the compiled graph
const result = await executor.execute(graph, { userId: '123' });

console.log(result.state);   // { userData: {...}, engagementScore: 92, notified: true }
console.log(result.history);  // ["Executing: Fetch Data", "Completed: Fetch Data", ...]

🏗️ Architecture

┌─────────────────────────────────────────────────────┐
│                    FluidGraph.js                    │
│                                                     │
│  ┌──────────────┐    ┌──────────────────────────┐   │
│  │  User Goal   │───▶│    GraphCompiler          │   │
│  │  (string)    │    │  ┌──────────────────────┐ │   │
│  └──────────────┘    │  │  LLM (Any)        │ │   │
│                      │  │  Generates DAG JSON   │ │   │
│  ┌──────────────┐    │  └──────────────────────┘ │   │
│  │  Tool List   │───▶│                            │   │
│  │  (FluidNode) │    └─────────┬────────────────┘   │
│  └──────────────┘              │                     │
│                                ▼                     │
│                      ┌──────────────────────────┐   │
│                      │    FluidGraphDef (JSON)   │   │
│                      │  { nodes: [], edges: [] } │   │
│                      └─────────┬────────────────┘   │
│                                │                     │
│                                ▼                     │
│                      ┌──────────────────────────┐   │
│                      │    GraphExecutor           │   │
│                      │  ┌──────────────────────┐ │   │
│                      │  │ Topological Sort     │ │   │
│                      │  │ (Kahn's Algorithm)   │ │   │
│                      │  └──────────────────────┘ │   │
│                      │  ┌──────────────────────┐ │   │
│                      │  │ Sequential Execution │ │   │
│                      │  │ with State Merging   │ │   │
│                      │  └──────────────────────┘ │   │
│                      └─────────┬────────────────┘   │
│                                │                     │
│                                ▼                     │
│                      ┌──────────────────────────┐   │
│                      │    ExecutionContext        │   │
│                      │  { state, history }       │   │
│                      └──────────────────────────┘   │
└─────────────────────────────────────────────────────┘

🌎 Real-World Use Cases

Here are three examples of how FluidGraph outshines rigid frameworks in production:

1. Customer Support AI

  • Tools: check_order_status, process_refund, escalate_to_human
  • Scenario: A customer says, "My package is broken, I want a refund."
  • The FluidGraph Advantage: The LLM dynamically compiles check_order_statusprocess_refund. If the refund API is down (the node fails), FluidGraph's self-healing kicks in, excludes the broken node, recompiles the graph, and safely routes to escalate_to_human.

2. Autonomous Coding Agents

  • Tools: read_file, run_tests, git_commit
  • Scenario: The agent needs to verify a bug fix.
  • The FluidGraph Advantage: Because run_tests and read_file are independent, FluidGraph automatically runs them in parallel. It compiles the DAG to execute them concurrently, drastically speeding up the agent's workflow compared to sequential loops.

3. Financial Analysis Pipelines

  • Tools: fetch_stock_price, fetch_news_sentiment, generate_report
  • Scenario: User asks for an Apple stock report.
  • The FluidGraph Advantage: FluidGraph executes fetch_stock_price and fetch_news_sentiment in parallel, waits for both to finish, and passes their combined state downstream into generate_report.

📁 Project Structure

fluidgraph/
├── src/
│   ├── types.ts             # Core interfaces, ExecutorOptions
│   ├── compiler.ts          # GraphCompiler — LLM-powered DAG generation
│   ├── executor.ts          # GraphExecutor — parallel, self-healing, conditional
│   ├── events.ts            # FluidGraphEmitter — typed streaming events
│   ├── visualizer.ts        # GraphVisualizer — Mermaid & ASCII export
│   ├── index.ts             # Public API exports
│   └── providers/
│       ├── provider.ts      # LLMProvider interface
│       ├── gemini.ts        # Google Gemini implementation
│       ├── openai.ts        # OpenAI / Azure / Ollama implementation
│       ├── anthropic.ts     # Anthropic Claude implementation
│       └── index.ts         # Provider barrel exports
├── dist/                    # Compiled JavaScript output
├── example.ts               # Working demo with all features
├── .env.example             # Environment variable template
├── .gitignore
├── package.json
├── tsconfig.json
└── README.md

🔧 API Reference

GraphCompiler

// With any LLMProvider
const compiler = new GraphCompiler(provider: LLMProvider);

// Legacy: pass a Gemini API key string directly
const compiler = new GraphCompiler('your-gemini-api-key');

// Default: auto-creates GeminiProvider from GEMINI_API_KEY env var
const compiler = new GraphCompiler();

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | provider | LLMProvider \| string | GeminiProvider() | Any LLM provider, or a Gemini API key string for backward compatibility |

compiler.compile(goal, tools)

| Parameter | Type | Description | |-----------|------|-------------| | goal | string | Natural language description of the desired outcome | | tools | FluidNode[] | Array of available tools the graph can use |

Returns: Promise<FluidGraphDef> — The compiled graph definition.


GraphExecutor

const executor = new GraphExecutor(tools: FluidNode[]);

executor.execute(graphDef, initialState?)

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | graphDef | FluidGraphDef | — | The compiled graph to execute | | initialState | Record<string, any> | {} | Initial state to seed the execution context |

Returns: Promise<ExecutionContext> — Contains the final state and history.


Core Types

interface FluidNode {
  id: string;
  name: string;
  description: string;
  action: (context: Record<string, any>) => Promise<Record<string, any>>;
}

interface FluidGraphDef {
  nodes: { id: string; name: string; description: string }[];
  edges: { from: string; to: string; conditionExpr?: string }[];
}

interface ExecutionContext {
  state: Record<string, any>;
  history: string[];
}

interface ExecutorOptions {
  selfHealing?: boolean;        // default: false
  maxHealingRetries?: number;   // default: 2
  parallel?: boolean;           // default: true
  evaluateConditions?: boolean; // default: true
}

GraphExecutor (Advanced)

// Basic usage
const executor = new GraphExecutor(tools);

// With all features enabled
const executor = new GraphExecutor(
  tools,
  {
    parallel: true,           // Run independent branches concurrently
    selfHealing: true,        // Recompile on failure
    maxHealingRetries: 2,     // Max recompilation attempts
    evaluateConditions: true, // Evaluate conditionExpr on edges
  },
  compiler, // Required for self-healing
);

// Execute (pass goal for self-healing context)
const result = await executor.execute(graphDef, initialState, goal);

Streaming Events

Subscribe to real-time execution events via executor.events:

executor.events.on('node:start', (e) => {
  console.log(`Started: ${e.nodeName}`);
});

executor.events.on('node:complete', (e) => {
  console.log(`Done: ${e.nodeName} in ${e.durationMs}ms`);
});

executor.events.on('node:skipped', (e) => {
  console.log(`Skipped: ${e.nodeName} — ${e.reason}`);
});

executor.events.on('node:error', (e) => {
  console.log(`Error: ${e.nodeName} — ${e.error.message}`);
});

executor.events.on('graph:healing', (e) => {
  console.log(`Healing attempt ${e.attempt}/${e.maxRetries}`);
});

executor.events.on('graph:complete', (e) => {
  console.log(`Complete: ${e.executedNodes} run, ${e.skippedNodes} skipped`);
});

GraphVisualizer

Export compiled graphs as diagrams:

import { GraphVisualizer } from 'fluidgraph';

// Mermaid flowchart (for markdown / docs)
console.log(GraphVisualizer.toMermaid(graphDef));
// graph TD
//   fetch_data["Fetch Data"] --> analyze["Analyze"]
//   analyze["Analyze"] -->|"score > 80"| send_email["Send Email"]

// Mermaid wrapped in markdown code block
console.log(GraphVisualizer.toMermaidMarkdown(graphDef));

// ASCII art for terminal output
console.log(GraphVisualizer.toAscii(graphDef));

🗺️ Roadmap

  • [x] LLM-powered graph compilation
  • [x] Topological sort execution (Kahn's algorithm)
  • [x] Shared state context between nodes
  • [x] Cycle detection
  • [x] Multi-provider support — Gemini, OpenAI, Anthropic, and any OpenAI-compatible API
  • [x] Self-healing graphs — On node failure, re-invoke the compiler to rewire around the broken node
  • [x] Parallel execution — Detect independent branches and execute them concurrently
  • [x] Streaming events — Real-time typed event emitter for all execution lifecycle events
  • [x] Conditional edges — Runtime condition evaluation with cascade skipping
  • [x] Graph visualization — Mermaid diagrams + ASCII art export
  • [x] Custom provider — Implement LLMProvider interface to plug in any model backend

🤝 Contributing

Contributions are welcome! Please open an issue or submit a pull request.


📄 License

MIT © FluidGraph Contributors