https://github.com/11divyansh/OxyJen
OxyJen is an open-source Java framework for orchestrating LLM workloads with graph-style execution, context-aware memory, and deterministic retry/fallback. It treats LLMs as native nodes (not helper utilities), allowing developers to build multi-step AI pipelines that integrate cleanly with existing Java code.
https://github.com/11divyansh/OxyJen
agents ai chatgpt dag graph java langchain langchain4j langgraph llm openai runtime tools workflow
Last synced: 25 days ago
JSON representation
OxyJen is an open-source Java framework for orchestrating LLM workloads with graph-style execution, context-aware memory, and deterministic retry/fallback. It treats LLMs as native nodes (not helper utilities), allowing developers to build multi-step AI pipelines that integrate cleanly with existing Java code.
- Host: GitHub
- URL: https://github.com/11divyansh/OxyJen
- Owner: 11divyansh
- License: apache-2.0
- Created: 2025-09-13T09:59:43.000Z (9 months ago)
- Default Branch: main
- Last Pushed: 2026-05-22T16:35:35.000Z (about 1 month ago)
- Last Synced: 2026-05-22T20:54:28.322Z (about 1 month ago)
- Topics: agents, ai, chatgpt, dag, graph, java, langchain, langchain4j, langgraph, llm, openai, runtime, tools, workflow
- Language: Java
- Homepage:
- Size: 538 KB
- Stars: 32
- Watchers: 1
- Forks: 2
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
- awesome-java - OxyJen
README
# OxyJen🫧
**OxyJen** is the missing deterministic AI Runtime for Java & JVM enterprises.
**Deterministic AI Workflow Runtime for the JVM** - Build complex AI pipelines with simplicity and power.
---
## What is Oxyjen?
Oxyjen is a **graph-based orchestration framework** for building AI applications in Java. It provides a clean, extensible architecture for connecting LLMs, data processors, and custom logic into powerful workflows.
Think of it as **the plumbing for your AI pipelines**, you focus on what each step does, Oxyjen handles the execution flow.
## "Why Oxyjen When LangChain4j Exists?"
**I get it, this is the first question you're thinking.** Let me be completely honest.
### The Story
I started building Oxyjen without knowing LangChain4j existed. When I discovered it halfway through, I had a choice:
1. Abandon the project
2. Find a way to differentiate
**I chose to differentiate.**
**I wanted to learn how OSS works.**
**I wanted to build this in public.**
### How Oxyjen Will Be Different
LangChain4j is a solid framework focused on **feature breadth**, lots of integrations, lots of tools. That's great for many use cases.
Oxyjen is taking a different path, focused on **developer experience and production readiness**
Oxyjen is meant for runtime reliability, your graphs will be self-aware and will make sure to provide less failure, even if a node fails, Oxyjen will learn from it and improve.
Features like, async, project loom, parallel processing, java concurrency will lay down the foundation of fail-safe graph structure for Oxyjen.
I'm not here to compete with Langchain4j, I'm here to create a reliable execution engine for devs.
### Why Oxyjen?
Modern AI applications need more than just API calls. They need:
- **Complex workflows** with multiple steps
- **Type safety** to catch errors at compile time
- **Observability** to debug what's happening
- **Testability** to ensure reliability
- **Extensibility** to add custom logic
Oxyjen provides all of this with a simple, intuitive API.
---
## Quick Example
```java
// Build a 3-step text processing pipeline
Graph pipeline = GraphBuilder.named("text-processor")
.addNode(new UppercaseNode())
.addNode(new ReverseNode())
.addNode(new PrefixNode("OUTPUT: "))
.build();
// Execute with context
NodeContext context = new NodeContext();
Executor executor = new Executor();
String result = executor.run(pipeline, "hello world", context);
System.out.println(result);
// Output: OUTPUT: DLROW OLLEH
```
That's it! Clean, simple, powerful.
---
## Architecture
Oxyjen is built around four core concepts:
### 1️**Graph** - The Pipeline Blueprint
A `Graph` defines the structure of your pipeline - which nodes run in what order.
```java
public class Graph {
private final String name;
private final List> nodes;
// Add nodes to your pipeline
public Graph addNode(NodePlugin, ?> node);
// Get all nodes in execution order
public List> getNodes();
}
```
**Think of it as:** Your pipeline's DNA - it knows what needs to happen, but doesn't execute anything.
### 2️**NodePlugin** - The Processing Unit
A `NodePlugin` is a single step in your pipeline. Each node transforms input into output.
```java
public interface NodePlugin {
// Core processing logic
O process(I input, NodeContext context);
// Unique identifier for this node
default String getName() {
return this.getClass().getSimpleName();
}
// Lifecycle hooks for setup/cleanup
default void onStart(NodeContext context) {}
default void onFinish(NodeContext context) {}
default void onError(Exception e, NodeContext context) {}
}
```
**Think of it as:** A Lego brick - small, focused, composable.
**Example node:**
```java
public class SummarizerNode implements NodePlugin {
@Override
public String process(String input, NodeContext context) {
context.getLogger().info("Summarizing text...");
// Your logic here (will be LLM call in v0.2)
return "Summary: " + input.substring(0, 100);
}
@Override
public void onStart(NodeContext context) {
context.getLogger().info("Summarizer node starting");
}
}
```
### 3️**Executor** - The Runtime Engine
The `Executor` runs your graph, calling each node in sequence and passing outputs to inputs.
```java
public class Executor {
public O run(Graph graph, I input, NodeContext context) {
// Validates graph structure
// Executes nodes sequentially
// Handles errors and lifecycle hooks
// Returns final output
}
}
```
**Think of it as:** The conductor of an orchestra - coordinates everything.
**How it works:**
1. Takes your `Graph` and initial `input`
2. For each node:
- Calls `onStart()` lifecycle hook
- Executes `process()` with current data
- Calls `onFinish()` lifecycle hook
- Passes output to next node
3. Returns final result
### 4️**NodeContext** - Shared Memory & State
The `NodeContext` is shared across all nodes, providing logging and state management.
```java
public class NodeContext {
// Store/retrieve shared data
public void set(String key, Object value);
public T get(String key);
// Logging
public Logger getLogger();
public OxyLogger getOxyjenLogger();
// Metadata (e.g., graph name, execution ID)
public void setMetadata(String key, Object value);
public T getMetadata(String key);
// Error handling
public ExceptionHandler getExceptionHandler();
}
```
**Think of it as:** A shared notebook that all nodes can read/write to.
**Example usage:**
```java
public String process(String input, NodeContext ctx) {
// Log what's happening
ctx.getLogger().info("Processing: " + input);
// Store intermediate results
ctx.set("word_count", input.split(" ").length);
// Share data between nodes
String previousResult = ctx.get("previous_output");
return processedOutput;
}
```
---
## Complete Working Example
```java
package examples;
import io.oxyjen.core.*;
public class ContentPipeline {
public static void main(String[] args) {
// Step 1: Define your nodes
NodePlugin validator = new ValidationNode();
NodePlugin processor = new ProcessingNode();
NodePlugin formatter = new FormatterNode();
// Step 2: Build your graph
Graph pipeline = GraphBuilder.named("content-pipeline")
.addNode(validator)
.addNode(processor)
.addNode(formatter)
.build();
// Step 3: Create execution context
NodeContext context = new NodeContext();
context.set("max_length", 100);
// Step 4: Execute
Executor executor = new Executor();
String result = executor.run(pipeline, "Raw input text", context);
System.out.println("Final output: " + result);
System.out.println("Word count: " + context.get("word_count"));
}
}
// Example node implementations
class ValidationNode implements NodePlugin {
@Override
public String process(String input, NodeContext ctx) {
if (input == null || input.isEmpty()) {
throw new IllegalArgumentException("Input cannot be empty");
}
ctx.getLogger().info("✓ Input validated");
return input;
}
}
class ProcessingNode implements NodePlugin {
@Override
public String process(String input, NodeContext ctx) {
String processed = input.toUpperCase().trim();
ctx.set("word_count", processed.split(" ").length);
ctx.getLogger().info("✓ Text processed");
return processed;
}
}
class FormatterNode implements NodePlugin {
@Override
public String process(String input, NodeContext ctx) {
Integer maxLength = ctx.get("max_length");
String formatted = input.length() > maxLength
? input.substring(0, maxLength) + "..."
: input;
ctx.getLogger().info("✓ Text formatted");
return formatted;
}
}
```
---
## My Vision for Oxyjen
## Vision
- Bring AI orchestration (LangChain/LangGraph style) to Java.
- Build enterprise-first modules: LLM agents, Audit tools, Secure complex Workflow Engine.
- Focus on **performance, security, and observability**.
- I'm building this to learn java in a much deeper way.
### **Phase 5 in progress**
- **RAG support** - Vector databases, embeddings, document loaders
- **Cost management** - Budgets, limits, usage tracking
- **Enterprise features** - Audit logs, RBAC, compliance
- **Multi-tenancy** - Isolate data between users/orgs
- **Async execution** - Run nodes in parallel
- **DAG support** - Complex branching workflows
- **Circuit breakers** - Fail fast when services are down
- **Streaming responses**
- **Token counting & cost tracking**
---
## Documentation
- [Oxyjen v0.2](docs/v0.2.md)
- [Oxyjen v0.3](docs/v0.3.md)
- [Oxyjen v0.4](docs/v0.4.md)
---
## Installation
[](https://jitpack.io/#11divyansh/Oxyjen/v0.2.0)
### Maven
**Add JitPack repository:**
```xml
jitpack.io
https://jitpack.io
```
**Add dependency:**
```xml
com.github.11divyansh
Oxyjen
v0.4.0
```
### Gradle
```gradle
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
implementation 'com.github.11divyansh:Oxyjen:v0.4.0'
}
```
### Build from Source
```bash
git clone https://github.com/11divyansh/OxyJen.git
cd OxyJen
mvn clean install
```
After installation, verify by importing:
```java
import io.oxyjen.core.*;
import io.oxyjen.llm.*;
import io.oxyjen.tools.*;
```
---
## About
Built with ❤️ by [Divyansh Bhatt](https://github.com/11divyansh) - a BTech CS student who believes Java deserves world-class AI tooling.
**This started as a learning project, but I'm committed to making it production-ready. I know this is not big yet, but lets make it valuable.**
### Get Involved
- **Star this repo** to follow the journey and be a part of it
- **Report bugs** via [Issues](../../issues)
- **Suggest features** via [Discussions](../../discussions)
- **Contribute** code or documentation
- **Share** on Twitter/LinkedIn if you find it useful
---
** Watch for updates on v0.5 progress!**
## License
[Apache 2.0](LICENSE) (open-source, enterprise-friendly)