{"id":32710165,"url":"https://github.com/bkataru/pocketflow-zig","last_synced_at":"2026-05-18T14:35:24.798Z","repository":{"id":320852423,"uuid":"1083552371","full_name":"bkataru/PocketFlow-Zig","owner":"bkataru","description":"Pocket Flow: A minimalist LLM framework. Let Agents build Agents!","archived":false,"fork":false,"pushed_at":"2025-10-31T10:28:26.000Z","size":695,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-31T12:18:29.703Z","etag":null,"topics":["agentic-ai","agentic-framework","agentic-workflow","agents","ai-framework","ai-frameworks","aiagent","aiagents","artificial-intelligence","flow-based-programming","flow-engineering","large-language-model","large-language-models","llm-agent","llm-framework","pocket-flow","pocketflow","retrieval-augmented-generation","workflow","workflow-orchestration"],"latest_commit_sha":null,"homepage":"","language":"Zig","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bkataru.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-26T09:02:18.000Z","updated_at":"2025-10-31T10:51:01.000Z","dependencies_parsed_at":"2025-10-26T11:36:16.352Z","dependency_job_id":null,"html_url":"https://github.com/bkataru/PocketFlow-Zig","commit_stats":null,"previous_names":["bkataru-workshop/pocketflow-zig","bkataru/pocketflow-zig"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/bkataru/PocketFlow-Zig","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bkataru%2FPocketFlow-Zig","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bkataru%2FPocketFlow-Zig/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bkataru%2FPocketFlow-Zig/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bkataru%2FPocketFlow-Zig/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bkataru","download_url":"https://codeload.github.com/bkataru/PocketFlow-Zig/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bkataru%2FPocketFlow-Zig/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":282243724,"owners_count":26637680,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-02T02:00:06.609Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agentic-ai","agentic-framework","agentic-workflow","agents","ai-framework","ai-frameworks","aiagent","aiagents","artificial-intelligence","flow-based-programming","flow-engineering","large-language-model","large-language-models","llm-agent","llm-framework","pocket-flow","pocketflow","retrieval-augmented-generation","workflow","workflow-orchestration"],"created_at":"2025-11-02T05:00:44.588Z","updated_at":"2026-05-18T14:35:24.767Z","avatar_url":"https://github.com/bkataru.png","language":"Zig","funding_links":[],"categories":[],"sub_categories":[],"readme":"# **Update**: This is legacy and frozen. Going forward, please use the more maintained [The-Pocket/PocketFlow-Zig](https://github.com/The-Pocket/PocketFlow-Zig) instead\n\n---\n\n# PocketFlow-Zig\n\nA Zig implementation of [PocketFlow](https://github.com/The-Pocket/PocketFlow), a minimalist flow-based programming framework for building LLM-powered workflows.\n\n## Overview\n\nPocketFlow-Zig is a port of the original Python PocketFlow framework, redesigned to leverage Zig's unique capabilities:\n\n- **Compile-time polymorphism**: Uses vtables for type-erased node interfaces without runtime overhead\n- **Explicit memory management**: No hidden allocations; all memory is managed through Zig allocators\n- **Thread-safe context**: Built-in mutex protection for shared state between nodes\n- **Zero dependencies**: Core framework has no external dependencies (Ollama client is optional)\n\n## Features\n\n- **Node-based architecture**: Define workflows as a graph of interconnected nodes\n- **Type-erased interfaces**: Generic `Node` interface via vtables enables heterogeneous node types\n- **Flow execution engine**: Automatic traversal and execution of node graphs\n- **Thread-safe shared context**: Safe data passing between nodes with mutex protection\n- **Ollama integration**: Built-in client for local LLM inference (optional)\n- **Action-based routing**: Nodes return actions that determine the next node in the flow\n\n## Installation\n\n### Method 1: Using `zig fetch` (Recommended)\n\nThe easiest way to add PocketFlow-Zig to your project is using `zig fetch --save`:\n\n```bash\n# Fetch from a GitHub release tarball (recommended for stability)\nzig fetch --save https://github.com/bkataru/PocketFlow-Zig/archive/refs/tags/v0.2.0.tar.gz\n\n# Or fetch directly from a git repository\nzig fetch --save git+https://github.com/bkataru/PocketFlow-Zig.git\n\n# You can also specify a custom name for the dependency\nzig fetch --save=pocketflow https://github.com/bkataru/PocketFlow-Zig/archive/refs/tags/v0.2.0.tar.gz\n```\n\nThis automatically:\n1. Downloads the package to Zig's global cache\n2. Computes the package hash\n3. Adds the dependency to your `build.zig.zon` file\n\nAfter running `zig fetch --save`, your `build.zig.zon` will contain something like:\n\n```zig\n.dependencies = .{\n    .pocketflow = .{\n        .url = \"https://github.com/bkataru/PocketFlow-Zig/archive/refs/tags/v0.2.0.tar.gz\",\n        .hash = \"1220...\", // Auto-generated hash\n    },\n},\n```\n\nThen add the import in your `build.zig`:\n\n```zig\nconst std = @import(\"std\");\n\npub fn build(b: *std.Build) void {\n    const target = b.standardTargetOptions(.{});\n    const optimize = b.standardOptimizeOption(.{});\n\n    // Fetch the pocketflow dependency\n    const pocketflow_dep = b.dependency(\"pocketflow\", .{\n        .target = target,\n        .optimize = optimize,\n    });\n\n    // Get the module from the dependency\n    const pocketflow_mod = pocketflow_dep.module(\"pocketflow\");\n\n    // Create your executable\n    const exe = b.addExecutable(.{\n        .name = \"my_app\",\n        .root_module = b.createModule(.{\n            .root_source_file = b.path(\"src/main.zig\"),\n            .target = target,\n            .optimize = optimize,\n        }),\n    });\n\n    // Add the pocketflow import to your executable\n    exe.root_module.addImport(\"pocketflow\", pocketflow_mod);\n\n    // Optional: also add the ollama module for LLM integration\n    const ollama_mod = pocketflow_dep.module(\"ollama\");\n    exe.root_module.addImport(\"ollama\", ollama_mod);\n\n    b.installArtifact(exe);\n}\n```\n\n### Method 2: Manual `build.zig.zon` Configuration\n\nIf you prefer to manually configure your dependencies, add the following to your `build.zig.zon`:\n\n```zig\n.{\n    .name = .my_project,\n    .version = \"0.1.0\",\n    .minimum_zig_version = \"0.15.0\",\n    .dependencies = .{\n        .pocketflow = .{\n            .url = \"https://github.com/bkataru/PocketFlow-Zig/archive/refs/tags/v0.2.0.tar.gz\",\n            // Get the hash by running: zig fetch https://github.com/bkataru/PocketFlow-Zig/archive/refs/tags/v0.2.0.tar.gz\n            .hash = \"1220...\",\n        },\n    },\n    .paths = .{\n        \"build.zig\",\n        \"build.zig.zon\",\n        \"src\",\n    },\n}\n```\n\nTo get the correct hash, run:\n\n```bash\nzig fetch https://github.com/bkataru/PocketFlow-Zig/archive/refs/tags/v0.2.0.tar.gz\n```\n\nThis prints the hash without modifying any files.\n\n### Method 3: Git-based Dependency\n\nFor development or to track the latest changes:\n\n```zig\n.dependencies = .{\n    .pocketflow = .{\n        .url = \"git+https://github.com/bkataru/PocketFlow-Zig.git\",\n        .hash = \"1220...\",\n    },\n},\n```\n\nOr with `zig fetch`:\n\n```bash\nzig fetch --save git+https://github.com/bkataru/PocketFlow-Zig.git\n```\n\n### Method 4: Local Path Dependency\n\nFor local development or when vendoring:\n\n```zig\n.dependencies = .{\n    .pocketflow = .{\n        .path = \"../PocketFlow-Zig\",\n    },\n},\n```\n\n### Building from Source\n\n```bash\n# Clone the repository\ngit clone https://github.com/bkataru/PocketFlow-Zig.git\ncd PocketFlow-Zig\n\n# Build the library\nzig build\n\n# Run the example (requires Ollama running locally)\nzig build run\n\n# Run tests\nzig build test\n```\n\n## Quick Start\n\n### 1. Define a Custom Node\n\nEach node implements prep, exec, and post phases:\n\n```zig\nconst std = @import(\"std\");\nconst pocketflow = @import(\"pocketflow\");\nconst Node = pocketflow.Node;\nconst BaseNode = pocketflow.BaseNode;\nconst Context = pocketflow.Context;\n\nconst MyNode = struct {\n    base: BaseNode,\n\n    pub fn init(allocator: std.mem.Allocator) *MyNode {\n        const self = allocator.create(MyNode) catch @panic(\"oom\");\n        self.* = .{ .base = BaseNode.init(allocator) };\n        return self;\n    }\n\n    pub fn deinit(self: *MyNode, allocator: std.mem.Allocator) void {\n        self.base.deinit();\n        allocator.destroy(self);\n    }\n\n    // Prepare: read from context, prepare data for execution\n    pub fn prep(_: *anyopaque, allocator: std.mem.Allocator, context: *Context) !*anyopaque {\n        const input = context.get([]const u8, \"input\") orelse \"default\";\n        const result = try allocator.create([]const u8);\n        result.* = input;\n        return @ptrCast(result);\n    }\n\n    // Execute: perform the main work (can be CPU-intensive)\n    pub fn exec(_: *anyopaque, allocator: std.mem.Allocator, prep_res: *anyopaque) !*anyopaque {\n        const input: *[]const u8 = @ptrCast(@alignCast(prep_res));\n        const output = try std.fmt.allocPrint(allocator, \"Processed: {s}\", .{input.*});\n        const result = try allocator.create([]const u8);\n        result.* = output;\n        return @ptrCast(result);\n    }\n\n    // Post: save results to context, return action for routing\n    pub fn post(_: *anyopaque, _: std.mem.Allocator, context: *Context, _: *anyopaque, exec_res: *anyopaque) ![]const u8 {\n        const output: *[]const u8 = @ptrCast(@alignCast(exec_res));\n        try context.set(\"output\", output.*);\n        return \"default\"; // Action determines next node\n    }\n\n    pub fn cleanup_prep(_: *anyopaque, allocator: std.mem.Allocator, prep_res: *anyopaque) void {\n        const ptr: *[]const u8 = @ptrCast(@alignCast(prep_res));\n        allocator.destroy(ptr);\n    }\n\n    pub fn cleanup_exec(_: *anyopaque, allocator: std.mem.Allocator, exec_res: *anyopaque) void {\n        const ptr: *[]const u8 = @ptrCast(@alignCast(exec_res));\n        allocator.destroy(ptr);\n    }\n\n    pub const VTABLE = Node.VTable{\n        .prep = prep,\n        .exec = exec,\n        .post = post,\n        .cleanup_prep = cleanup_prep,\n        .cleanup_exec = cleanup_exec,\n    };\n};\n```\n\n### 2. Build and Run a Flow\n\n```zig\nconst pocketflow = @import(\"pocketflow\");\nconst Flow = pocketflow.Flow;\nconst Context = pocketflow.Context;\nconst Node = pocketflow.Node;\n\npub fn main() !void {\n    var gpa = std.heap.GeneralPurposeAllocator(.{}){};\n    defer _ = gpa.deinit();\n    const allocator = gpa.allocator();\n\n    // Create nodes\n    const node1 = MyNode.init(allocator);\n    defer node1.deinit(allocator);\n    \n    const node2 = MyNode.init(allocator);\n    defer node2.deinit(allocator);\n\n    // Wrap nodes with their vtables\n    const wrapper1 = Node{ .self = node1, .vtable = \u0026MyNode.VTABLE };\n    const wrapper2 = Node{ .self = node2, .vtable = \u0026MyNode.VTABLE };\n\n    // Connect nodes: node1 --\"default\"--\u003e node2\n    try node1.base.next(\"default\", wrapper2);\n\n    // Create and run flow\n    var flow = Flow.init(allocator, wrapper1);\n    \n    var context = Context.init(allocator);\n    defer context.deinit();\n    \n    try context.set(\"input\", @as([]const u8, \"Hello, PocketFlow!\"));\n    try flow.run(\u0026context);\n    \n    if (context.get([]const u8, \"output\")) |output| {\n        std.debug.print(\"Result: {s}\\n\", .{output});\n    }\n}\n```\n\n### 3. Branching Flows\n\nNodes can return different actions to route to different successors:\n\n```zig\npub fn post(_: *anyopaque, _: Allocator, context: *Context, _: *anyopaque, exec_res: *anyopaque) ![]const u8 {\n    const result: *i32 = @ptrCast(@alignCast(exec_res));\n    try context.set(\"result\", result.*);\n    \n    // Branch based on result\n    if (result.* \u003e 100) {\n        return \"high\";\n    } else {\n        return \"low\";\n    }\n}\n\n// Later, when connecting nodes:\ntry node1.base.next(\"high\", high_value_handler);\ntry node1.base.next(\"low\", low_value_handler);\n```\n\n## Architecture\n\n### Core Components\n\n| Component | Description |\n|-----------|-------------|\n| `Node` | Type-erased interface for workflow steps (via vtable) |\n| `BaseNode` | Provides successor management for routing |\n| `Flow` | Executes nodes in sequence, following action-based routing |\n| `Context` | Thread-safe key-value store for sharing data between nodes |\n\n### Node Lifecycle\n\n```\n┌─────────┐     ┌─────────┐     ┌─────────┐\n│  prep   │ --\u003e │  exec   │ --\u003e │  post   │\n└─────────┘     └─────────┘     └─────────┘\n     │               │               │\n     v               v               v\n Read from       Process         Write to\n Context         Data            Context\n                                     │\n                                     v\n                              Return Action\n                              (routes to next node)\n```\n\n## Examples\n\nSee the `examples/` directory:\n\n- **document_generator.zig**: Multi-node flow that generates documents using Ollama LLM\n  - Generates an outline for a topic\n  - Writes content for each outline point\n  - Assembles the final document\n\nRun the example:\n\n```bash\n# Requires Ollama running locally on port 11434\nzig build run\n```\n\n## API Reference\n\n### Context\n\n```zig\n// Initialize a new context\nvar ctx = Context.init(allocator);\ndefer ctx.deinit();\n\n// Store a value\ntry ctx.set(\"key\", value);\n\n// Retrieve a value (returns null if not found)\nif (ctx.get(MyType, \"key\")) |value| {\n    // use value\n}\n```\n\n### Flow\n\n```zig\n// Create a flow starting at a node\nvar flow = Flow.init(allocator, start_node);\n\n// Run the flow with a context\ntry flow.run(\u0026context);\n```\n\n### BaseNode\n\n```zig\n// Add a successor for an action\ntry node.base.next(\"action_name\", successor_node);\n```\n\n## Testing\n\n```bash\n# Run all unit tests\nzig build test\n\n# Run integration tests (requires Ollama server)\nzig build test-integration\n```\n\n## Project Structure\n\n```\nPocketFlow-Zig/\n├── src/\n│   ├── pocketflow.zig    # Main library exports\n│   ├── node.zig          # Node interface and BaseNode\n│   ├── flow.zig          # Flow execution engine\n│   ├── context.zig       # Thread-safe context storage\n│   └── ollama.zig        # Ollama LLM client (optional)\n├── examples/\n│   └── document_generator.zig\n├── build.zig\n├── build.zig.zon\n├── README.md\n└── LICENSE\n```\n\n## Contributing\n\nContributions are welcome! Areas of interest:\n\n1. **Async support**: Implement async node execution using Zig 0.15+ async I/O\n2. **Batch processing**: Add BatchNode for processing multiple items\n3. **More examples**: Additional workflow examples (RAG, agents, etc.)\n4. **Performance**: Benchmarks and optimizations\n\nPlease submit pull requests or open issues for discussion.\n\n## Requirements\n\n- Zig 0.15.0 or later\n- (Optional) Ollama for LLM integration\n\n## License\n\n[MIT License](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbkataru%2Fpocketflow-zig","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbkataru%2Fpocketflow-zig","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbkataru%2Fpocketflow-zig/lists"}