Metadata-Version: 2.4
Name: graphserve
Version: 0.1.2
Summary: Serve any LangGraph graph over the OpenAI Chat Completions + Responses APIs.
Project-URL: Homepage, https://github.com/AndrewNgo-ini/graphserve
Project-URL: Repository, https://github.com/AndrewNgo-ini/graphserve
Project-URL: Issues, https://github.com/AndrewNgo-ini/graphserve/issues
Author-email: AndrewNgo-ini <46411807+AndrewNgo-ini@users.noreply.github.com>
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: agents,chat-completions,fastapi,langgraph,llm,openai,responses-api,sse
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: FastAPI
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.11
Requires-Dist: fastapi>=0.137.0
Requires-Dist: langchain-core>=1.4.0
Requires-Dist: langgraph>=1.2.0
Requires-Dist: openai>=2.41.0
Requires-Dist: pydantic>=2.13.0
Provides-Extra: dev
Requires-Dist: httpx>=0.28; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.25; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Description-Content-Type: text/markdown

# GraphServe

GraphServe is an open-source Python library that serves any LangGraph graph over the OpenAI Chat Completions and Responses APIs, enabling seamless integration of agent workflows into OpenAI-compatible applications.

## Installation

```bash
pip install graphserve
```

## Quickstart

```python
from fastapi import FastAPI
from langgraph.graph import StateGraph, START, END
from graphserve import GraphRegistry, GraphConfig, create_openai_router

# 1. Build your LangGraph graph
graph = StateGraph(...)
# ... add nodes and edges ...
compiled = graph.compile()

# 2. Register it under a model name
registry = GraphRegistry()
registry.register("my-agent", GraphConfig(graph=compiled))

# 3. Mount the OpenAI-compatible router on your FastAPI app
app = FastAPI()
app.include_router(create_openai_router(registry), prefix="/v1")
```

Your app now exposes:

| Route | Description |
|---|---|
| `GET /v1/models` | List registered graphs |
| `POST /v1/responses` | Create a response (streaming or non-streaming) |
| `GET /v1/responses/{id}` | Retrieve a previous response |
| `DELETE /v1/responses/{id}` | Delete a response |
| `POST /v1/chat/completions` | Chat Completions API |

## Public API

| Export | Description |
|---|---|
| `GraphRegistry` | Registry mapping model names to graph configs |
| `GraphConfig` | Holds a single already-compiled `graph` to serve |
| `create_openai_router` | Builds a FastAPI `APIRouter` with all OpenAI-compatible routes |

## `create_openai_router` options

```python
create_openai_router(
    registry,   # GraphRegistry — required
)
```

GraphServe is a pure OpenAI↔LangGraph converter. Cross-cutting concerns are the consumer's job,
applied with standard tools:

- **Auth** — apply it where you mount the router:
  ```python
  app.include_router(create_openai_router(registry), prefix="/v1",
                     dependencies=[Depends(verify_api_key)])
  ```
- **Callbacks / tracing** — attach to your graph when you build it.

Per-request runtime context is derived generically from the OpenAI request and
exposed to the graph as LangGraph runtime `context`: `user` → `context["user_id"]`,
`instructions` → `context["metadata"]["custom_instructions"]`, and `metadata` is
passed through as `context["metadata"]`. Graphs read what they need and ignore the rest.

## Stateful responses and `previous_response_id`

All state is managed through the registered graph's LangGraph checkpointer, keyed by `thread_id`.
If a graph is compiled without a checkpointer, GraphServe automatically injects an `InMemorySaver`
(with a warning). Response IDs encode the model (`resp_<model>.<hex>`) so GET/DELETE routes can
resolve the owning graph without any external metadata store.

To use a persistent checkpointer:

```python
from langgraph.checkpoint.memory import MemorySaver
compiled = graph.compile(checkpointer=MemorySaver())
```

## Streaming

Pass `"stream": true` in the request body to receive Server-Sent Events following the OpenAI Responses API event schema (`response.created`, `response.output_item.added`, `response.output_text.delta`, `response.completed`, etc.).

## License

MIT
