OPVS Protocol
What's New in v1.0
This document provides a comprehensive overview of changes from OPVS Protocol v0.3.0 to v1.0. The v1.0 release represents a significant maturation of the protocol with enhanced clarity, stronger specifications, and important structural improvements.
Overview of Major Themes
The v1.0 release focuses on four major themes:
1. Protocol Maturity and Standardization
- Elevate opvs.proto from being a gRPC-specific implementation file to the universal, normative source of truth
- Leverage formal specification standards (RFC 8785, RFC 7515) and google.rpc.Status where possible
- Stricter adherence to industry-standard patterns for REST, gRPC, and JSON-RPC bindings
- Enhanced versioning strategy with explicit backward compatibility rules
- Comprehensive error taxonomy with protocol-specific mappings
2. Enhanced Type Safety and Clarity
- Removal of discriminator kind fields in favor of JSON member-based polymorphism
- Breaking: Enum values changed from kebab-case to SCREAMING_SNAKE_CASE for compliance with the ProtoJSON specification
- Stricter field naming conventions (camelCase for JSON)
- More precise timestamp specifications (ISO 8601 with millisecond precision)
- Better-defined data types with clearer Optional vs Required semantics
3. Improved Developer Experience
- Renamed operations for consistency and clarity
- Reorganized Agent Card structure for better logical grouping
- Enhanced extension mechanism with versioning and requirement declarations
- More explicit service parameter handling (OPVS-Version, OPVS-Extensions headers)
- Simplified ID format - Removed complex compound IDs (e.g., tasks/{id}) in favor of simple UUIDs
- Protocol versioning per interface - Each AgentInterface specifies its own protocol version for better backward compatibility
- Multi-tenancy support - Native tenant scoping in gRPC requests
4. Enterprise-Ready Features
- Agent Card signature verification using JWS and JSON Canonicalization
- Formal specification of all three protocol bindings with equivalence guarantees
- Enhanced security scheme declarations with mutual TLS support
- Modern OAuth 2.0 flows - Added Device Code flow (RFC 8628), removed deprecated implicit/password flows
- PKCE support - Added pkce_required field to Authorization Code flow for enhanced security
- Cursor-based pagination for scalable task listing
Behavioral Changes for Core Operations
Send Message
**v0.3.0 Behavior:** Operation named message/send. Less formal specification of when Task vs Message is returned.
**v1.0 Changes:**
- [RENAMED] Operation now SendMessage
- [CLARIFIED] More precise specification of Task vs Message return semantics
Send Streaming Message
**v0.3.0 Behavior:** Operation named message/stream. Stream events had kind discriminator field.
**v1.0 Changes:**
- [RENAMED] Operation now SendStreamingMessage
- [BREAKING] Stream events no longer have kind field
- Use JSON member names to discriminate between TaskStatusUpdateEvent and TaskArtifactUpdateEvent
- [REMOVED] final boolean field removed from TaskStatusUpdateEvent. Leverage protocol binding specific stream closure mechanism instead.
- [CLARIFIED] Multiple concurrent streams allowed; all receive same ordered events
Get Task
**v0.3.0 Behavior:** Operation named tasks/get. Returns task with status, artifacts, and optionally history. Less formal specification of what "include history" means.
**v1.0 Changes:**
- [RENAMED] Operation now GetTask
- [NEW] createdAt and lastModified timestamp fields added to Task object
- [CLARIFIED] More precise specification of history inclusion behavior
- [NEW] Task object now includes extensions array in messages and artifacts
- [CLARIFIED] Authentication/authorization scoping - servers MUST only return tasks visible to caller
List Tasks
**v1.0 Changes:**
- [NEW] New operation ListTasks with filtering capabilities
- [CLARIFIED] Task visibility scoped to authenticated caller
Cancel Task
**v0.3.0 Behavior:** Operation named tasks/cancel. Request with taskId, returns Task.
**v1.0 Changes:**
- [RENAMED] Operation now CancelTask
- [CLARIFIED] More precise specification of when cancellation is allowed
- [CLARIFIED] Task state transitions for cancellation scenarios
Get Agent Card
**v0.3.0 Behavior:** Discovery via /.well-known/agent-card.json. Extended card via agent/getAuthenticatedExtendedCard. supportsAuthenticatedExtendedCard boolean at top level.
**v1.0 Changes:**
- [RENAMED] agent/getAuthenticatedExtendedCard to GetExtendedAgentCard
- [BREAKING] supportsAuthenticatedExtendedCard moved to capabilities.extendedAgentCard
- [NEW] Canonicalization (RFC 8785) clarified for Agent Card signature
- [BREAKING] protocolVersion moved from AgentCard to individual AgentInterface objects
- [BREAKING] preferredTransport and additionalInterfaces consolidated into supportedInterfaces
- Each interface has url, protocolBinding, and protocolVersion
Subscribe to task
**v0.3.0 Behavior:** Used tasks/resubscribe to reconnect interrupted SSE streams. Backfill behavior implementation-dependent.
**v1.0 Changes:**
- [RENAMED] Operation now SubscribeToTask
- [CLARIFIED] Formal specification of streaming subscription lifecycle
- [CLARIFIED] Stream closure behavior when task reaches terminal state
- [CLARIFIED] Multiple concurrent subscriptions supported per task
Push Notification Operations
**v0.3.0 Operations:** tasks/pushNotificationConfig/set, get, list, delete
**v1.0 Changes:**
- [RENAMED] Operations now CreateTaskPushNotificationConfig, GetTaskPushNotificationConfig, ListTaskPushNotificationConfigs, DeleteTaskPushNotificationConfig
- [NEW] createdAt timestamp field added to PushNotificationConfig
- [CLARIFIED] Push notification payloads now use StreamResponse format
- [BREAKING] model changed for all methods, with TaskPushNotificationConfig flattened
Protocol Simplifications
ID Format Simplification
**v0.3.0:** Some operations used complex compound IDs like tasks/{taskId}. Required clients/servers to construct/deconstruct resource names.
**v1.0 Changes:**
- [BREAKING] All IDs are now simple literals
- [BREAKING] Operations that previously used compound IDs now separate parent and resource ID
- Example: tasks/{taskId}/pushNotificationConfigs/{configId} -> separate task_id and config_id fields
- BENEFIT: Simpler to implement - IDs map directly to database keys
HTTP URL Path Simplification
**v0.3.0:** HTTP+JSON binding used /v1/ prefix in URLs. Example: POST /v1/message:send
**v1.0 Changes:**
- [BREAKING] Removed /v1 prefix from HTTP+JSON URL paths
- [NEW] Examples: POST /message:send, GET /tasks/{id}
- RATIONALE: Version can be part of the base url if required by agent owner
- BENEFIT: Cleaner URLs, version management at interface level
Structural Changes in Core Model Objects
TaskStatus Object
**Modified Fields:**
- state: BREAKING - Enum values changed from lowercase to SCREAMING_SNAKE_CASE with TASK_STATE_ prefix
- v0.3.0: "submitted", "working", "completed", "failed", "canceled", "rejected", "input-required", "auth-required"
- v1.0: "TASK_STATE_SUBMITTED", "TASK_STATE_WORKING", "TASK_STATE_COMPLETED", "TASK_STATE_FAILED", "TASK_STATE_CANCELED", "TASK_STATE_REJECTED", "TASK_STATE_INPUT_REQUIRED", "TASK_STATE_AUTH_REQUIRED"
- timestamp: Now explicitly ISO 8601 UTC with millisecond precision (YYYY-MM-DDTHH:mm:ss.sssZ)
// v0.3.0
"status": {
"state": "completed",
"timestamp": "2024-03-15T10:15:00Z"
}
// v1.0
"status": {
"state": "TASK_STATE_COMPLETED",
"timestamp": "2024-03-15T10:15:00.000Z"
}Message Object
**Added Fields:**
- extensions: Array of extension URIs applicable to this message
**Modified Fields:**
- role: BREAKING - Enum values changed from lowercase to SCREAMING_SNAKE_CASE with ROLE prefix
- v0.3.0: "user", "agent"
- v1.0: "ROLE_USER", "ROLE_AGENT"
**Behavior Changes:** Parts array now uses member-based discrimination instead of kind field.
Part Object
**BREAKING CHANGE - Complete Redesign:** The Part structure has been completely redesigned in v1.0. Instead of separate TextPart, FilePart, and DataPart message types, there is now a single unified Part message.
- [REMOVED] Separate TextPart, FilePart, and DataPart types
- [REMOVED] kind discriminator field
- [REMOVED] Nested file object structure
- [NEW] Single unified Part message with oneof content field
- [NEW] Content type determined by which field is present: text, raw, url, or data
- [NEW] mediaType field (replaces mimeType) - available for all part types
- [NEW] filename field - available for all part types (not just files)
- [NEW] raw field for inline binary content (base64 in JSON)
- [NEW] url field for file references (replaces file.fileWithUri)
// Text example
{
"text": "Hello world",
"mediaType": "text/plain"
}
// File with URL example
{
"url": "https://example.com/doc.pdf",
"filename": "doc.pdf",
"mediaType": "application/pdf"
}
// File with raw bytes example
{
"raw": "base64encodedcontent==",
"filename": "image.png",
"mediaType": "image/png"
}
// Data example
{
"data": {"key": "value"},
"mediaType": "application/json"
}AgentCard Object
**Added Fields:** supportedInterfaces: Array of AgentInterface objects
**Removed Fields:**
- protocolVersion: Removed from AgentCard (now in each AgentInterface)
- preferredTransport: Consolidated into supportedInterfaces
- additionalInterfaces: Consolidated into supportedInterfaces
- supportsAuthenticatedExtendedCard: Moved to capabilities.extendedAgentCard
- url: Primary endpoint now in supportedInterfaces[0].url
// v1.0
"supportedInterfaces": [
{
"url": "https://agent.example.com/opvs",
"protocolBinding": "JSONRPC",
"protocolVersion": "1.0"
}
],
"capabilities": {
"extendedAgentCard": true,
"signatures": [...]
}Stream Event Objects
**Changes for TaskStatusUpdateEvent and TaskArtifactUpdateEvent:**
- [REMOVED] kind discriminator
- [REMOVED] final boolean field (stream closure indicates completion instead)
- [NEW PATTERN] Event type determined by JSON member name (taskStatusUpdate or taskArtifactUpdate)
- [NEW] index field indicates artifact position in task's artifacts array
- [CLARIFIED] Terminal state indicated by protocol-specific stream closure mechanism
OAuth 2.0 Security Updates
v1.0 modernizes OAuth 2.0 support in alignment with OAuth 2.0 Security Best Current Practice (BCP).
**Removed Flows (Deprecated by OAuth BCP):**
- ImplicitAuthFlow - Deprecated due to token leakage risks in browser history/logs
- PasswordAuthFlow - Deprecated due to credential exposure risks