Metadata-Version: 2.4
Name: orkes
Version: 0.1.4
Summary: A lightweight orchestration framework for LLM agents, no abstractions you don’t need, no bloated APIs, just clean coordination logic that works.
Author-email: Hasby Fahrudin <fahrudinhasby12@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/hfahrudin/orkes
Project-URL: Documentation, https://orkes.readthedocs.io/
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: aiohttp
Requires-Dist: requests
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: pytest-html; extra == "dev"
Requires-Dist: pytest-asyncio; extra == "dev"
Requires-Dist: memory-profiler; extra == "dev"
Requires-Dist: psutil; extra == "dev"
Requires-Dist: fastapi; extra == "dev"
Requires-Dist: uvicorn; extra == "dev"
Requires-Dist: python-dotenv; extra == "dev"
Requires-Dist: jsonschema; extra == "dev"
Requires-Dist: langgraph; extra == "dev"
Requires-Dist: langchain; extra == "dev"
Requires-Dist: matplotlib; extra == "dev"
Provides-Extra: docs
Requires-Dist: sphinx; extra == "docs"
Requires-Dist: sphinxcontrib-mermaid; extra == "docs"
Requires-Dist: sphinx-copybutton; extra == "docs"
Requires-Dist: pydata-sphinx-theme; extra == "docs"
Dynamic: license-file

<h2 align="center">
  <img width="17%" alt="Orkes logo" src="assets/orkes.png"><br/>
  No abstractions. No black boxes. Just Your Logic
</h2>
<p align="center">
  <a href="https://badge.fury.io/py/orkes">
    <img src="https://badge.fury.io/py/orkes.svg" alt="PyPI version">
  </a>
  <a href="https://opensource.org/licenses/MIT">
    <img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT">
  </a>
  <a href="https://orkes.readthedocs.io/">
    <img src="https://img.shields.io/readthedocs/orkes?logo=read-the-docs&style=flat-square" alt="Docs">
  </a>
</p>

Orkes is a Python library for building, coordinating, and observing any complex workflow that can be represented as a graph. While it is well-suited for building LLM-powered agentic systems, its core focus is on providing a flexible and intuitive graph-based framework (inspired by NetworkX) with an emphasis on explicit control flow, transparent logic, and comprehensive traceability.


## Getting Started

You can install the latest stable version of the Orkes using pip:

```cli
pip install orkes
```

<details><summary>Here's a simple example of how to build and run a graph with Orkes:</summary>

```Python
from orkes.graph.core import OrkesGraph
from typing import TypedDict, List

# 1. Define a simpler state
class SearchState(TypedDict):
    user_query: str
    search_queries: List[str]
    current_index: int
    raw_results: List[str]
    is_finished: bool
    final_answer: str

# --- Node 1: Planner (Mocked) ---
def planner_node(state: SearchState):
    """Instead of an LLM, we split the query into mock keywords."""
    print(f"📖 Planning for: {state['user_query']}")
    
    # Simple logic: split words as fake 'queries'
    state['search_queries'] = [f"Search for {word}" for word in state['user_query'].split()[:3]]
    state['current_index'] = 0
    state['raw_results'] = []
    return state

# --- Node 2: Execution (Mocked) ---
def execute_search_node(state: SearchState):
    idx = state['current_index']
    query = state['search_queries'][idx]
    
    print(f"📡 Executing Step {idx + 1}: {query}")
    state['raw_results'].append(f"Result for '{query}'")
    
    state['current_index'] += 1
    state['is_finished'] = state['current_index'] >= len(state['search_queries'])
    return state

# --- Node 3: Synthesis (Mocked) ---
def synthesis_node(state: SearchState):
    """Combines results into a simple string."""
    state['final_answer'] = "Combined Results: " + " | ".join(state['raw_results'])
    print(f"✨ Process Complete: {state['final_answer']}")
    return state

# --- Router Logic ---
def check_loop_condition(state: SearchState):
    return 'complete' if state.get('is_finished') else 'loop'

# --- Build the Graph ---
graph = OrkesGraph(SearchState)

graph.add_node('planner', planner_node)
graph.add_node('search_step', execute_search_node)
graph.add_node('synthesizer', synthesis_node)

graph.add_edge(graph.START, 'planner')
graph.add_edge('planner', 'search_step')

# Conditional Loop
graph.add_conditional_edge(
    'search_step',
    check_loop_condition,
    {
        'loop': 'search_step',   # Go back to search if not finished
        'complete': 'synthesizer' # Go to finish if done
    }
)

graph.add_edge('synthesizer', graph.END)

# --- Execute ---
runner = graph.compile()
initial_state: SearchState = {
    "user_query": "Orkes Conductor vs Temporal",
    "search_queries": [],
    "current_index": 0,
    "raw_results": [],
    "is_finished": False,
    "final_answer": ""
}

runner.run(initial_state)
runner.visualize_trace()

```
</details>

<details><summary>Here is an example how the orkes graph visualization will look like:</summary>
<h2 align="center">
  <img width="60%" alt="example" src="assets/inspector-example.png"><br/>
</h2>
</details>

## Core Concepts

At the heart of Orkes is a powerful graph-based architecture inspired by `NetworkX`. This design allows you to define your workflows as a graph of nodes and edges, where each node is a simple Python function.

-   **OrkesGraph**: The main canvas for your workflow. It holds the nodes and edges that define your application's logic.
-   **Stateful Execution**: A shared state object is passed between nodes, allowing for seamless data flow and management throughout the graph's execution.
-   **Graph Traceability**: Orkes provides a built-in traceability and visualization system. When you run a graph, Orkes can generate a detailed execution trace that can be visualized as an interactive HTML file, making it easy to debug and understand your workflows.

## Features

-   **Graph-based Architecture**: Define complex workflows as a graph of nodes and edges, with support for conditional branching and loops.
-   **Traceability and Visualization**: Generate interactive traces of your graph executions to visualize the flow of data and control.
-   **Pluggable LLM Integrations**: A flexible and extensible system for integrating with LLMs, with out-of-the-box support for OpenAI, Anthropic's Claude, and Google's Gemini.
-   **Agent and Tool Support**: Define custom tools and use them within your graph's nodes to interact with external APIs and services.
-   **Familiar Interface**: The graph-based interface is inspired by `NetworkX`, providing a familiar and powerful paradigm for those with experience in graph-based programming.


## Sending Traces to Orkes Watcher

[Orkes Watcher](https://github.com/hfahrudin/orkes-watcher) is a dashboard that shows your runs live and keeps their history. It works with a plain `pip install orkes`; attach a `WatcherSink` to your graph and nothing else in your code changes:

```python
from orkes.exporters.watcher import WatcherSink

sink = WatcherSink(api_key="<project ingest key>", base_url="http://localhost:8000")
graph = OrkesGraph(SearchState, name="search", trace_sinks=[sink])
```

`base_url` is the watcher backend (port `8000` by default), not the dashboard. Create one sink and reuse it for all your graphs and runs. Sending happens in a background thread, and a watcher that is down or rejects the data never affects your run: at most, a run waits up to 3 seconds at the end for its data to be sent.

**State snapshots, prompts and LLM replies are sent as they are.** To leave out secrets or personal data, pass `redact`, a function that receives each event (and each node entry) as a dict and returns what should be sent:

```python
def redact(event):
    if "state_snapshot" in event:
        event = {**event, "state_snapshot": {"redacted": True}}
    return event

sink = WatcherSink(api_key=..., base_url=..., redact=redact)
```

Any object with `on_run_start`, `on_edge` and `on_run_end` methods can be a trace sink; see `orkes.exporters.TraceSink`.

## Benchmarks

Orkes has been benchmarked against LangGraph on simple graph structures, demonstrating performance advantages. In direct comparisons of graphs with identical nodes and edges, Orkes consistently outperforms LangGraph in both latency and memory utilization.

### Key Findings

*   For a simple graph comprising 5 nodes, Orkes exhibits up to a 5x increase in speed and consumes up to 2x less memory compared to LangGraph.
*   When scaled to a 10-node graph, Orkes's performance gap widens, achieving up to 10x faster execution and using up to 3x less memory than LangGraph.

These preliminary results suggest Orkes can offer a more efficient and performant solution for developing and deploying LLM applications, particularly in scenarios involving graph-based workflows.

### Results

Example Benchmark Results (*values may vary*):

<details><summary>Basic Benchmark Results</summary>
<h2 align="center">
  <img width="80%" alt="Basic Benchmark Results" src="assets/benchmarks/basic_benchmark_results.png"><br/>
</h2>
</details>

<details><summary>Statebloat Benchmark Results</summary>
<h2 align="center">
  <img width="80%" alt="Statebloat Benchmark Results" src="assets/benchmarks/statebloat_benchmark_results.png"><br/>
</h2>
</details>

To replicate or run the benchmarks, navigate to the `tests/benchmarks` directory and execute the `run_all_benchmarks.py` script:

```bash
python tests/benchmarks/run_all_benchmarks.py
```

## Roadmap

| Feature                  | Description                                                                                                     | Status  |
| ------------------------ | --------------------------------------------------------------------------------------------------------------- | ------- |
| Boilerplate Agent        | Provide a well-structured boilerplate for creating new agents to accelerate the development of agentic systems. | Planned |
| Parallel Graph Execution | Enhance the graph runner to support parallel execution of independent branches for improved performance.        | Implemented |
| Orkes Watcher Export     | Stream graph traces to Orkes Watcher, a separate web platform for inspecting runs live and across history.     | Progressing |

## Documentation
For more details, visit our [Documentation Page](https://orkes.readthedocs.io/).

## Contributing
Contributions are welcome! Please see the [Contributing Guide](CONTRIBUTING.md) for more information.

## License
Orkes is licensed under the [MIT License](LICENSE).
