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 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.2",
    "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 "0.0.0.0" Host to bind to

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.2.tar.gz (15.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.2-py3-none-any.whl (10.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: reminix_runtime-0.0.2.tar.gz
  • Upload date:
  • Size: 15.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.25 {"installer":{"name":"uv","version":"0.9.25","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.2.tar.gz
Algorithm Hash digest
SHA256 b5fb77d9fd90c7f64b38bd7c1c5c6d073c562c74ca3090162a4f28a2ba1ece00
MD5 baa876a56b47e848ad1ab74a605b2088
BLAKE2b-256 cf71bb1b75040e83910117479259be90850b138c7a2d9b48705f852677319e2d

See more details on using hashes here.

File details

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

File metadata

  • Download URL: reminix_runtime-0.0.2-py3-none-any.whl
  • Upload date:
  • Size: 10.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.25 {"installer":{"name":"uv","version":"0.9.25","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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 64bfd243f98b56ed06053f12edb130d37e95237372778ffca2422f62486b595c
MD5 71f0eec93b9dd64c3a52dab65c41a8ec
BLAKE2b-256 284bfc00f03896d2aa0c131103d87c0a17c36cc2ab958be3a5ba83d6afb4930d

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