OPVS Protocol
Start Server
Starting the Server
Now that we have an Agent Card and an Agent Executor, we can set up and start the OPVS server.
The OPVS Python SDK provides an `OPVSStarletteApplication` class that simplifies running an OPVS-compliant HTTP server. It uses Starlette for the web framework and is typically run with an ASGI server like Uvicorn.
Server Setup in Helloworld
Let's look at `__main__.py` again to see how the server is initialized and started.
import uvicorn
from opvs.server.apps import OPVSStarletteApplication
from opvs.server.request_handlers import DefaultRequestHandler
from opvs.server.tasks import InMemoryTaskStore
from opvs.types import (
AgentCapabilities,
AgentCard,
AgentInterface,
AgentSkill,
)
from agent_executor import (
HelloWorldAgentExecutor, # type: ignore[import-untyped]
)
if __name__ == "__main__":
skill = AgentSkill(
id='hello_world',
name='Returns hello world',
description='just returns hello world',
tags=['hello world'],
examples=['hi', 'hello world'],
)
extended_skill = AgentSkill(
id='super_hello_world',
name='Returns a SUPER Hello World',
description='A more enthusiastic greeting, only for authenticated users.',
tags=['hello world', 'super', 'extended'],
examples=['super hi', 'give me a super hello'],
)
# This will be the public-facing agent card
public_agent_card = AgentCard(
id='hello_world_agent',
description='Just a hello world agent',
icon_url='http://localhost:9999/',
version='1.0.0',
default_input_modes=['text'],
default_output_modes=['text'],
capabilities=AgentCapabilities(
streaming=True, extended_agent_card=True
),
supported_interfaces=[
AgentInterface(
protocol_binding='JSONRPC',
url='http://localhost:9999',
)
],
skills=[skill], # Only the basic skill for the public card
)
# This will be the authenticated extended agent card
# It includes the additional 'extended_skill'
specific_extended_agent_card = AgentCard(
id='hello_world_agent - Extended Edition',
description='The full-featured hello world agent for authenticated users.',
icon_url='http://localhost:9999/',
version='1.0.1',
default_input_modes=['text'],
default_output_modes=['text'],
capabilities=AgentCapabilities(
streaming=True, extended_agent_card=True
),
supported_interfaces=[
AgentInterface(
protocol_binding='JSONRPC',
url='http://localhost:9999',
)
],
skills=[
skill,
extended_skill,
], # Both skills for the extended card
)
request_handler = DefaultRequestHandler(
agent_executor=HelloWorldAgentExecutor(),
task_store=InMemoryTaskStore(),
)
server = OPVSStarletteApplication(
agent_card=public_agent_card,
http_handler=request_handler,
extended_agent_card=specific_extended_agent_card,
)
uvicorn.run(server.build(), host='127.0.0.1', port=9999)Let's break this down:
- DefaultRequestHandler: The SDK provides `DefaultRequestHandler`. This handler takes your `AgentExecutor` implementation (here, `HelloWorldAgentExecutor`) and a `TaskStore` (here, `InMemoryTaskStore`). It routes incoming OPVS RPC calls to the appropriate methods on your executor (like `execute` or `cancel`). The `TaskStore` is used by the `DefaultRequestHandler` to manage the lifecycle of tasks, especially for stateful interactions, resuming, and resubscription. Even if your agent executor is simple, the handler needs a task store.
- OPVSStarletteApplication: The `OPVSStarletteApplication` class is instantiated with the `agent_card`, `request_handler` (referred to as `http_handler` in its constructor), and an optional `extended_agent_card`. The `agent_card` is exposed at the `/.well-known/agent-card.json` endpoint for public discovery. The `request_handler` processes all incoming OPVS method calls by interacting with your `AgentExecutor`. The `extended_agent_card` provides additional capabilities and skills for authenticated users and is exposed via the `GetExtendedAgentCard` RPC method.
- uvicorn.run(server.build(), ...): The `OPVSStarletteApplication` has a `build()` method that constructs the actual Starlette application. This application is then run using `uvicorn.run()`, making your agent accessible over HTTP. `host='127.0.0.1'` makes the server accessible only from your local machine. `port=9999` specifies the port to listen on. This matches the endpoints defined in the `AgentCard`'s `supported_interfaces`.
Running the Helloworld Server
Navigate to the `opvs-samples` directory in your terminal (if you're not already there) and ensure your virtual environment is activated.
To run the Helloworld server:
# from the opvs-samples directory
python samples/python/agents/helloworld/__main__.pyYou should see output similar to this, indicating the server is running:
INFO: Started server process [xxxxx]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:9999 (Press CTRL+C to quit)Your OPVS Helloworld agent is now live and listening for requests! In the next step, we'll interact with it.