Metadata-Version: 2.4
Name: dyui
Version: 0.1.0
Summary: A dynamic-UI layer for any LangGraph agent: emit live UI cards from any node or tool, with any LLM.
Project-URL: Homepage, https://github.com/sohammmzzz/dyui
Project-URL: Repository, https://github.com/sohammmzzz/dyui
Project-URL: Issues, https://github.com/sohammmzzz/dyui/issues
Author-email: Soham Das <sohamdas1300@gmail.com>
License: MIT
License-File: LICENSE
Keywords: agents,dynamic-ui,fastapi,generative-ui,langgraph,llm,sse,ui
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: User Interfaces
Requires-Python: >=3.10
Requires-Dist: langgraph>=0.2.40
Requires-Dist: pydantic>=2
Provides-Extra: dev
Requires-Dist: fastapi>=0.110; extra == 'dev'
Requires-Dist: httpx; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: uvicorn; extra == 'dev'
Provides-Extra: server
Requires-Dist: fastapi>=0.110; extra == 'server'
Requires-Dist: uvicorn>=0.30; extra == 'server'
Description-Content-Type: text/markdown

# dyui

A **dynamic-UI layer for any LangGraph agent.** Emit rich, live UI "cards" from
inside any LangGraph node or tool — with any LLM, or none — and render them on
the frontend with the companion [`@dyui/react`](../react) package.

DyUI rides LangGraph's first-class `custom` stream channel, so it is
transport-, model-, and framework-agnostic. No voice, no vendor lock-in.

## Install

```bash
pip install dyui            # core (langgraph + pydantic)
pip install "dyui[server]"  # + FastAPI SSE server
```

## Emit cards from your agent

```python
from dyui import emit, ui_tool, Card

# 1. Imperative — call anywhere inside a node:
emit("table", {"columns": ["city", "temp"], "rows": [["Berlin", 21]]},
     title="Weather", icon="cloud", accent="cyan")

# 2. Decorator — auto pending -> done/error around a tool:
@ui_tool("stat", title="Sum", icon="plus", accent="emerald")
def add(a: float, b: float) -> dict:
    return {"label": f"{a} + {b}", "value": a + b}

# 3. Context manager — long-running work, one card updated in place:
with Card("progress", title="Indexing") as card:
    for i in range(1, 4):
        card.progress({"value": i, "max": 3})
    card.done({"value": 3, "max": 3, "label": "Done"})
```

Each event carries an `id` (auto or yours), a `component` key (which card to
render), `props` (the data), a `status` (`pending`/`active`/`done`/`error`), and
an optional `surface` (which screen region hosts it).

## Zero frontend: serve a UI from Python

You don't need React or npm to get a working screen. `create_dyui_app` hosts a
built-in single-file UI at `GET /` that renders every built-in card **and your
raw HTML cards**:

```python
from dyui.server import create_dyui_app

app = create_dyui_app(my_compiled_graph)   # uvicorn my_module:app --port 8008
# open http://localhost:8008  -> a live dynamic-UI screen, no frontend code
```

### Use your own HTML files as cards

Drop `.html` templates in a folder and emit them by name — placeholders are
filled from props (`{{ key }}` escaped, `{{{ key }}}` raw):

```python
from dyui import HtmlTemplates

cards = HtmlTemplates("cards")             # ./cards/invoice.html, weather.html, ...

def my_node(state):
    cards.emit("invoice",
               {"number": 42, "total": "$1,200", "customer": "Acme"},
               title="Invoice", accent="emerald")
```

That's the whole "one Python file + HTML templates → dynamic UI" path. See
[`examples/html_agent.py`](examples/html_agent.py) and [`examples/cards/`](examples/cards).

> The served UI renders the built-in card types and `html` cards. Bespoke
> *React* card components live in `@dyui/react`; for the no-frontend path, model
> custom cards as HTML templates instead.

## Connect a React frontend (optional)

`POST /dyui/stream` is a plain SSE endpoint the `@dyui/react` `useDyUIAgent` hook
consumes directly. Or mount onto an existing app:

```python
from dyui.server import add_dyui_routes
add_dyui_routes(existing_fastapi_app, my_graph, path="/agent/stream")
```

## Test / consume without HTTP

```python
from dyui import collect_events
for ev in collect_events(my_graph, {"query": "berlin"}):
    print(ev["status"], ev["component"], ev["props"])
```

## Built-in card components (frontend)

`text`, `markdown`, `table`, `stat`, `progress`, `list`, `keyvalue`, `json`,
`alert`, `image`, and `html` (sanitized custom markup). Register your own React
components for any `component` key to fully customise — see the React package.

## Development

```bash
python -m venv .venv && . .venv/Scripts/activate   # Windows
pip install -e ".[dev]"
pytest
```
