Open source Python library for multi-agent web interfaces.
Project description
GenAILit
GenAILit is a small Python library for building web interfaces for multi-agent systems. It gives you a single-process, single-port runtime with FastAPI, WebSocket streaming, and an embedded DebugPanel for LLMOps-style inspection.
What it is
GenAILit is not just a chat UI. It is a lightweight runtime and adapter layer for agentic applications where you want to:
- expose an agent over the web from pure Python
- stream events and tokens over WebSocket
- inspect execution traces and metrics
- stay compatible with SageMaker Studio and other proxy-based environments
Why it is not only a chat UI
A chat UI only renders messages. GenAILit also gives you:
- a framework-agnostic event model
- telemetry for tokens, latency, provider, model, cost, errors, and retries
- adapters for different backends
- a built-in debug surface for tracing multi-agent execution
That makes it useful for building and auditing multi-agent systems, not only for chatting with them.
Installation
pip install genailit
Optional LangGraph support:
pip install "genailit[langgraph]"
Requirements:
- Python 3.10+
pydantic>=2fastapi>=0.110uvicorn[standard]>=0.27
Quickstart
The simplest way to build an app is with @app.agent:
from genailit import GenAILitApp
app = GenAILitApp()
@app.agent
async def demo(input_data, context):
yield "Hola "
yield "desde "
yield "GenAILit"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8501)
Run it with the CLI:
genailit run app.py --host 0.0.0.0 --port 8501
The UI opens a WebSocket to the same host and port, so it works well behind SageMaker and similar proxies.
Using LangGraph
LangGraph is optional and stays outside the core runtime. Install the extra first:
pip install "genailit[langgraph]"
Then use the adapter:
from genailit import GenAILitApp
from genailit.adapters.langgraph import LangGraphAdapter
graph = ...
adapter = LangGraphAdapter(graph)
app = GenAILitApp(adapter=adapter)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8501)
See examples/langgraph_demo.py for a minimal runnable example.
Examples
- examples/function_agent.py - simplest
@app.agentdemo - examples/langgraph_demo.py - minimal LangGraph integration
- examples/sagemaker_quickstart.py - SageMaker-friendly quickstart
Architecture
GenAILit is intentionally split into small pieces:
core- the FastAPI runtime and WebSocket serveradapters- bridge layers for agent backendsevents- the framework-agnosticGenAILitEventcontracttelemetry- in-memory session traces and metricsDebugPanel- the built-in execution inspector
The core stays agnostic. Adapters translate backend-specific behavior into GenAILit events.
Event catalog
Every streamed item uses the same shape:
GenAILitEvent(name="event.name", payload={...})
Canonical event names for 0.1.x:
| Event | Recommended payload |
|---|---|
session.started |
{"session_id": str, "run_id": str | None} |
session.ended |
{"session_id": str, "run_id": str | None} |
agent.token |
{"delta": str}. Legacy {"token": str} is still accepted by the UI and telemetry. |
agent.message |
{"content": str}. Legacy {"message": str} is still accepted. |
node.started |
{"name": str} or {"session_id": str, "run_id": str | None} for root execution nodes. |
node.ended |
{"name": str} or {"run_id": str | None} for root execution nodes. |
tool.started |
{"name": str} or {"tool_name": str}. |
tool.ended |
{"name": str} or {"tool_name": str}. |
llm.started |
{"provider": str, "model": str, "metadata": {"source": str}, "timing": {"latency_ms": None, "ttft_ms": None}}. |
llm.ended |
{"provider": str, "model": str, "usage": {...}, "metadata": {"source": str}, "timing": {...}}. |
metrics.updated |
{"usage": {"input_tokens": int, "output_tokens": int, "total_tokens": int}, "provider": str, "model": str, "timing": {"latency_ms": float, "ttft_ms": float | None}, "cost": {"cost_usd": float}}. |
error |
{"message": str, "type": str}. |
Payloads may include fewer fields when the backend cannot provide them.
Raw backend payloads are not included unless an adapter explicitly enables include_raw.
SageMaker Studio
GenAILit is designed to work in SageMaker Studio with:
- single-process execution
- single-port serving
- no Node or Vite runtime
- host
0.0.0.0 - port
8501
That keeps the app simple to install with pip and avoids frontend build steps in runtime.
Telemetry and LLMOps
GenAILit tracks observability data such as:
- input tokens
- output tokens
- total tokens
- provider
- model
- latency
- TTFT
- cost
- error count
- retry count
The DebugPanel surfaces those metrics alongside execution events and a basic execution tree. When real usage metadata is available, GenAILit prefers it over token estimates.
TelemetryStore.get_session_metrics(session_id) returns:
{
"total_events": int,
"input_tokens": int,
"output_tokens": int,
"total_tokens": int,
"model": str | None,
"provider": str | None,
"latency_ms": float | None,
"ttft_ms": float | None,
"cost_usd": float | None,
"error_count": int,
"retry_count": int,
"estimated": {"tokens": bool, "cost": bool},
}
Telemetry precedence:
- Real usage wins:
payload.usage.input_tokens,payload.usage.output_tokens, andpayload.usage.total_tokens. - Legacy aliases are used next:
prompt_tokens,completion_tokens,tokens_in, andtokens_out. - If no token metadata exists, output tokens are estimated from
agent.tokenoragent.messagetext.
Provider and model are resolved from payload.provider, payload.model, payload.metadata.ls_provider, payload.metadata.ls_model_name, and payload.response_metadata.model_name.
Cost is never estimated; cost_usd is only populated from explicit payload.cost.cost_usd or payload.cost_usd.
Latency and TTFT prefer explicit payload.timing values and otherwise fall back to in-memory session timestamps.
Public API stability
For 0.1.x, the stable surface is:
GenAILitEvent(name, payload)GenAILitApp(adapter=None),@app.agent,app.asgi_app, andapp.run(...)AdapterContextandBaseAgentAdapter.stream(input_data, context)TelemetryStore.record,extend,snapshot,clear,get_session_trace, andget_session_metricsLangGraphAdapter(graph, input_key="messages", stream_mode=None, include_raw=False)genailit run app.py --host 0.0.0.0 --port 8501
Privacy defaults
GenAILit avoids storing sensitive content by default:
- raw payloads are not persisted unless explicitly requested
- prompts are not stored in new telemetry structures by default
- message bodies and token text are only shown where needed for the live UI
This keeps the default footprint small while still supporting inspection when you enable it.
Status
GenAILit is experimental. The public API may change as the library grows. The current goal is to keep the runtime small, stable in SageMaker, and easy to reason about.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file genailit-0.1.4.tar.gz.
File metadata
- Download URL: genailit-0.1.4.tar.gz
- Upload date:
- Size: 65.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a6723ccf81fb5097f0c1a39c13dfb9f514c9e933074869547cef33de1636a031
|
|
| MD5 |
61357f9bc6cb9eae017805a18eb23cba
|
|
| BLAKE2b-256 |
984c55b348955e5c8772ba89ee62a03d6bc5a305692ad361b27447a7b934e002
|
File details
Details for the file genailit-0.1.4-py3-none-any.whl.
File metadata
- Download URL: genailit-0.1.4-py3-none-any.whl
- Upload date:
- Size: 28.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
59af879266b85209628c0554040f4aafc4b2381110b8b2d6a480ca094e88d731
|
|
| MD5 |
de423b29e0cfb732e9b4b4e37ab83cd6
|
|
| BLAKE2b-256 |
f129ae7d83df66f29e7aa2014664afd3b712b20e96dc00143c2504fdcaf9e5be
|