Skip to main content

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.4",
    "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
host str "::" Host to bind to (IPv6, also accepts IPv4)

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?

Links

License

Apache-2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

reminix_runtime-0.0.4.tar.gz (19.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

reminix_runtime-0.0.4-py3-none-any.whl (14.4 kB view details)

Uploaded Python 3

File details

Details for the file reminix_runtime-0.0.4.tar.gz.

File metadata

  • Download URL: reminix_runtime-0.0.4.tar.gz
  • Upload date:
  • Size: 19.4 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

Hashes for reminix_runtime-0.0.4.tar.gz
Algorithm Hash digest
SHA256 bcdba208aa77e69d0c40cceb29d9eee528e08ac774f16e708e7de595f83782d8
MD5 7695c9b3e924ea0d0a41b3773f14d9d3
BLAKE2b-256 1f7965767b8b2c68a44c45f7ba9376de26bdb97acf3439264b7fca92bee26175

See more details on using hashes here.

File details

Details for the file reminix_runtime-0.0.4-py3-none-any.whl.

File metadata

  • Download URL: reminix_runtime-0.0.4-py3-none-any.whl
  • Upload date:
  • Size: 14.4 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

Hashes for reminix_runtime-0.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 b120c300ea6e5a9e6905b7496bf22f5a0eb34e62b89ece0977576ebc6e4aa9ac
MD5 cc4ea321046236e2551c11634a7bed11
BLAKE2b-256 a04e8552ca097106ca7e4b9cd3dbc6ba6ec325e8273defb329d765e4372d8a3d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page