Reminix Runtime - Serve AI agents as REST APIs with streaming support
Project description
reminix-runtime
Core runtime package for serving AI agents via REST APIs. Provides the serve() function, Agent class, and BaseAdapter for building framework integrations.
Built on FastAPI with full async support.
Ready to go live? Deploy to Reminix Cloud for zero-config hosting, or self-host on your own infrastructure.
Installation
pip install reminix-runtime
Quick Start
from reminix_runtime import serve, Agent, InvokeRequest, InvokeResponse, ChatRequest, ChatResponse
# Create an agent with decorators
agent = Agent("my-agent")
@agent.on_invoke
async def handle_invoke(request: InvokeRequest) -> InvokeResponse:
task = request.input.get("task", "unknown")
return InvokeResponse(output=f"Completed: {task}")
@agent.on_chat
async def handle_chat(request: ChatRequest) -> ChatResponse:
user_msg = request.messages[-1].content
response = f"You said: {user_msg}"
return ChatResponse(
output=response,
messages=[
*[{"role": m.role, "content": m.content} for m in request.messages],
{"role": "assistant", "content": response}
]
)
# Serve the agent
serve([agent], port=8080)
How It Works
The runtime creates a REST server with the following endpoints:
| Endpoint | Method | Description |
|---|---|---|
/health |
GET | Health check |
/info |
GET | Runtime discovery (version, agents, endpoints) |
/agents/{name}/invoke |
POST | Stateless invocation |
/agents/{name}/chat |
POST | Conversational chat |
Health Endpoint
curl http://localhost:8080/health
Returns {"status": "ok"} if the server is running.
Discovery Endpoint
curl http://localhost:8080/info
Returns runtime information and available agents:
{
"runtime": {
"name": "reminix-runtime",
"version": "0.0.5",
"language": "python",
"framework": "fastapi"
},
"agents": [
{
"name": "my-agent",
"type": "adapter",
"adapter": "langchain",
"invoke": { "streaming": true },
"chat": { "streaming": true }
}
]
}
Invoke Endpoint
POST /agents/{name}/invoke - For stateless operations.
curl -X POST http://localhost:8080/agents/my-agent/invoke \
-H "Content-Type: application/json" \
-d '{
"input": {
"task": "summarize",
"text": "Lorem ipsum..."
}
}'
Response:
{
"output": "Summary: ..."
}
Chat Endpoint
POST /agents/{name}/chat - For conversational interactions.
curl -X POST http://localhost:8080/agents/my-agent/chat \
-H "Content-Type: application/json" \
-d '{
"messages": [
{"role": "system", "content": "You are helpful"},
{"role": "user", "content": "What is the weather?"}
]
}'
Response:
{
"output": "The weather is 72°F and sunny!",
"messages": [
{"role": "system", "content": "You are helpful"},
{"role": "user", "content": "What is the weather?"},
{"role": "assistant", "content": "The weather is 72°F and sunny!"}
]
}
The output field contains the assistant's response, while messages includes the full conversation history.
Framework Adapters
Instead of creating custom agents, use our pre-built adapters for popular frameworks:
| Package | Framework |
|---|---|
reminix-langchain |
LangChain |
reminix-langgraph |
LangGraph |
reminix-openai |
OpenAI |
reminix-anthropic |
Anthropic |
reminix-llamaindex |
LlamaIndex |
API Reference
serve(agents, port, host)
Start the runtime server.
| Parameter | Type | Default | Description |
|---|---|---|---|
agents |
list[Agent] |
required | List of agents |
port |
int |
8080 |
Port to listen on. Falls back to PORT environment variable if not provided. |
host |
str |
"0.0.0.0" |
Host to bind to (all interfaces). Can be overridden via HOST env var. |
create_app(agents)
Create a FastAPI app without starting the server. Useful for testing or custom deployment.
from reminix_runtime import create_app
app = create_app([MyAgent()])
# Use with uvicorn, gunicorn, etc.
Agent
Concrete class for building agents with decorators.
from reminix_runtime import Agent, InvokeRequest, InvokeResponse, ChatRequest, ChatResponse
agent = Agent("my-agent", metadata={"version": "1.0"})
@agent.on_invoke
async def handle_invoke(request: InvokeRequest) -> InvokeResponse:
return InvokeResponse(output="Hello!")
@agent.on_chat
async def handle_chat(request: ChatRequest) -> ChatResponse:
return ChatResponse(output="Hi!", messages=[...])
# Optional: streaming handlers
@agent.on_invoke_stream
async def handle_invoke_stream(request: InvokeRequest):
yield '{"chunk": "Hello"}'
yield '{"chunk": " world!"}'
@agent.on_chat_stream
async def handle_chat_stream(request: ChatRequest):
yield '{"chunk": "Hi"}'
| Method | Description |
|---|---|
on_invoke(fn) |
Register invoke handler |
on_chat(fn) |
Register chat handler |
on_invoke_stream(fn) |
Register streaming invoke handler |
on_chat_stream(fn) |
Register streaming chat handler |
to_asgi() |
Returns an ASGI app for serverless |
agent.to_asgi()
Returns an ASGI application for serverless deployments.
# AWS Lambda with Mangum
from mangum import Mangum
from reminix_runtime import Agent, InvokeResponse
agent = Agent("my-agent")
@agent.on_invoke
async def handle(request):
return InvokeResponse(output="Hello!")
# Lambda handler
handler = Mangum(agent.to_asgi())
Works with:
- AWS Lambda - Use Mangum adapter
- GCP Cloud Functions - Use functions-framework with ASGI
- Any ASGI server - uvicorn, hypercorn, daphne
BaseAdapter
Abstract base class for framework adapters. Use this when wrapping an existing AI framework.
from reminix_runtime import BaseAdapter, InvokeRequest, InvokeResponse, ChatRequest, ChatResponse
class MyFrameworkAdapter(BaseAdapter):
# Adapter name shown in /info endpoint
adapter_name = "my-framework"
# BaseAdapter defaults both to True; override if your adapter doesn't support streaming
# invoke_streaming = False
# chat_streaming = False
def __init__(self, client, name: str = "my-framework"):
self._client = client
self._name = name
@property
def name(self) -> str:
return self._name
async def invoke(self, request: InvokeRequest) -> InvokeResponse:
# Pass input to your framework
result = await self._client.run(request.input)
return InvokeResponse(output=result)
async def chat(self, request: ChatRequest) -> ChatResponse:
# Convert messages and call your framework
result = await self._client.chat(request.messages)
return ChatResponse(
output=result,
messages=[
*[{"role": m.role, "content": m.content} for m in request.messages],
{"role": "assistant", "content": result}
]
)
# Optional: provide a wrap() factory function
def wrap(client, name: str = "my-framework") -> MyFrameworkAdapter:
return MyFrameworkAdapter(client, name)
Request/Response Types
class InvokeRequest:
input: dict[str, Any] # Arbitrary input for task execution
stream: bool = False # Whether to stream the response
context: dict[str, Any] | None # Optional metadata
class InvokeResponse:
output: Any # The result (can be any type)
class ChatRequest:
messages: list[Message] # Conversation history
stream: bool = False # Whether to stream the response
context: dict[str, Any] | None # Optional metadata
class ChatResponse:
output: str # The final answer
messages: list[dict] # Full execution history
Deployment
Ready to go live?
- Deploy to Reminix Cloud - Zero-config cloud hosting
- Self-host - Run on your own infrastructure
Links
License
Apache-2.0
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 reminix_runtime-0.0.5.tar.gz.
File metadata
- Download URL: reminix_runtime-0.0.5.tar.gz
- Upload date:
- Size: 19.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
10d148702d0d2571bafc15ef39525cc30f26c3ab58419761c25d282f11d7c33d
|
|
| MD5 |
de1fd02908ef0b3f2980dbd4fef51e01
|
|
| BLAKE2b-256 |
e93c88411c3d9037d8e141c13acb55401166447c8f531b356249a8d12c2f2262
|
File details
Details for the file reminix_runtime-0.0.5-py3-none-any.whl.
File metadata
- Download URL: reminix_runtime-0.0.5-py3-none-any.whl
- Upload date:
- Size: 14.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
af9256d3c2d293c5aec04d0d46d337b43a24e9e13e5fc4bd9d8302c89f67f238
|
|
| MD5 |
6b9860cba4f2e39d6fe0905c50149df7
|
|
| BLAKE2b-256 |
481397766b6df64dbe77a94d4749e4ab55e41765ca88b33a9e839e5a9a5461fc
|