Skip to main content

Bindu Protocol

The Language of Agents: A2A and AP2 Protocol Types In the constellation of autonomous agents, communication is everything. Just as humans developed languages to share ideas, agents need a precise vocabulary to understand each other. This is where A2A (Agent-to-Agent) and AP2 (Agent Protocol 2) come alive. Bindu implements these protocols as the Rosetta Stone for agent communication - every message, every task, every handshake between agents is defined here. These aren’t just data structures; they’re the building blocks of trust, the grammar of collaboration, and the syntax of emergent intelligence. Official Specifications:
Bindu follows A2A v0.3.0 and AP2 v0.1.0 with additional extensions marked as <NotPartOfA2A> for enhanced functionality.

Protocol Overview

Bindu’s protocol is built on four foundational pillars:

JSON-RPC 2.0

Standard request/response messaging protocol

Task-Based Model

Stateful execution units coordinating client-agent interaction

Context Management

Conversation sessions grouping related tasks

Type Safety

Pydantic-validated TypedDict structures

Core Protocol Entities

Messages

Messages represent all non-result communication in the Bindu protocol. Unlike Artifacts (which contain task outputs), Messages carry operational content like instructions, status updates, context, and metadata.
class Message(TypedDict):
    message_id: Required[UUID]
    context_id: Required[UUID]
    task_id: Required[UUID]
    reference_task_ids: NotRequired[list[UUID]]
    kind: Required[Literal["message"]]
    metadata: NotRequired[dict[str, Any]]
    parts: Required[list[Part]]
    role: Required[Literal["user", "agent", "system"]]
    extensions: NotRequired[list[str]]
Message Types:
  • User Instructions: Task requests with context and files
  • Agent Communication: Status updates, thoughts, coordination
  • System Messages: Errors, warnings, protocol information
  • Context Sharing: Background information, references, metadata
Multi-part Structure: Messages can contain multiple parts to organize different content types:
class TextPart(TypedDict):
    kind: Required[Literal["text"]]
    text: Required[str]
    metadata: NotRequired[dict[str, Any]]
    embeddings: NotRequired[list[float]]  # <NotPartOfA2A>
class FilePart(TextPart):
    kind: Required[Literal["file"]]
    file: Required[FileWithBytes | FileWithUri]
    embeddings: NotRequired[list[float]]  # <NotPartOfA2A>
class DataPart(TextPart):
    kind: Required[Literal["data"]]
    data: Required[dict[str, Any]]
    embeddings: NotRequired[list[float]]  # <NotPartOfA2A>

Tasks

Tasks serve as the primary coordination mechanism in the Bindu protocol, managing the complete lifecycle from request to completion.
class Task(TypedDict):
    id: Required[UUID]
    context_id: Required[UUID]
    kind: Required[Literal["task"]]
    status: Required[TaskStatus]
    artifacts: NotRequired[list[Artifact]]
    history: NotRequired[list[Message]]
    metadata: NotRequired[dict[str, Any]]
Core Responsibilities:
  • Message Exchange: Facilitate communication between clients and agents
  • State Management: Track task progress and execution status
  • Artifact Collection: Gather and organize agent-generated outputs
  • History Tracking: Maintain complete conversation and decision trail
Task Lifecycle: Task States:
StateDescriptionA2A Standard
submittedTask submitted, awaiting execution
workingAgent actively working on the task
input-requiredTask paused, waiting for user input
completedTask successfully completed
canceledTask canceled by user
failedTask failed due to error
rejectedTask rejected by agent
auth-requiredAuthentication required to proceed
payment-requiredPayment required to proceedExtension
unknownUnknown or indeterminate stateExtension
trust-verification-requiredTrust verification requiredExtension
pendingTask pending executionExtension
suspendedTask suspended, not runningExtension
resumedTask resumed after suspensionExtension
negotiation-bid-submittedBid submitted for negotiationExtension
negotiation-bid-lostBid lost in negotiationExtension
negotiation-bid-wonBid won in negotiationExtension

Artifacts

Artifacts represent the final output generated by an agent after completing a task. They are immutable data structures containing the results of agent execution.
class Artifact(TypedDict):
    artifact_id: Required[UUID]
    name: NotRequired[str]
    description: NotRequired[str]
    metadata: NotRequired[dict[str, Any]]
    parts: NotRequired[list[Part]]
    append: NotRequired[bool]
    last_chunk: NotRequired[bool]
    extensions: NotRequired[list[str]]
Key Properties:
  • Immutable: Once created, artifacts cannot be modified
  • Multi-part: Can contain text, files, and structured data
  • Streamable: Parts can be appended during streaming responses
  • Traceable: Each artifact has a unique ID for reference

Contexts

Contexts serve as conversation containers, managing the complete interaction lifecycle between clients and agents.
class Context(TypedDict):
    context_id: Required[UUID]
    kind: Required[Literal["context"]]
    tasks: NotRequired[list[UUID]]
    name: NotRequired[str]
    description: NotRequired[str]
    role: Required[str]
    created_at: Required[str]
    updated_at: Required[str]
    status: NotRequired[Literal["active", "paused", "completed", "archived"]]
    tags: NotRequired[list[str]]
    metadata: NotRequired[dict[str, Any]]
    parent_context_id: NotRequired[UUID]
    reference_context_ids: NotRequired[list[UUID]]
    extensions: NotRequired[dict[str, Any]]
Core Responsibilities:
  • Session Management: Group related tasks under a unified conversation
  • History Preservation: Maintain complete message history across tasks
  • Context Continuity: Preserve conversation state and references
  • Metadata Tracking: Store session-level information and preferences

JSON-RPC 2.0 Protocol

All communication in Bindu uses JSON-RPC 2.0 for request/response messaging.

Base Types

class JSONRPCMessage(TypedDict):
    jsonrpc: Required[Literal["2.0"]]
    id: Required[UUID]

class JSONRPCRequest(JSONRPCMessage, Generic[Method, Params]):
    method: Required[Method]
    params: Required[Params]

class JSONRPCResponse(JSONRPCMessage, Generic[ResultT, ErrorT]):
    result: NotRequired[ResultT]
    error: NotRequired[ErrorT]

class JSONRPCError(TypedDict, Generic[CodeT, MessageT]):
    code: Required[CodeT]
    message: Required[MessageT]
    data: NotRequired[Any]

Message Operations

Send a message and wait for complete response.Request:
{
  "jsonrpc": "2.0",
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "method": "message/send",
  "params": {
    "message": {
      "message_id": "...",
      "context_id": "...",
      "task_id": "...",
      "kind": "message",
      "role": "user",
      "parts": [
        {
          "kind": "text",
          "text": "Analyze this dataset"
        }
      ]
    },
    "configuration": {
      "accepted_output_modes": ["text", "data"],
      "blocking": true
    }
  }
}
Response:
{
  "jsonrpc": "2.0",
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "result": {
    "id": "...",
    "context_id": "...",
    "kind": "task",
    "status": {
      "state": "completed",
      "timestamp": "2025-10-13T17:30:00Z"
    },
    "artifacts": [...]
  }
}
Stream messages with real-time updates via Server-Sent Events (SSE).Request:
{
  "jsonrpc": "2.0",
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "method": "message/stream",
  "params": {
    "message": { /* Message object */ },
    "configuration": {
      "accepted_output_modes": ["text", "data"]
    }
  }
}
Response (SSE Stream):
event: status-update
data: {"task_id": "...", "status": {"state": "working", "timestamp": "..."}}

event: artifact-update
data: {"artifact": {...}, "append": true, "last_chunk": false}

event: status-update
data: {"task_id": "...", "status": {"state": "completed", "timestamp": "..."}, "final": true}

Task Operations

Retrieve task details and history.Request:
{
  "jsonrpc": "2.0",
  "id": "...",
  "method": "tasks/get",
  "params": {
    "task_id": "550e8400-e29b-41d4-a716-446655440000",
    "history_length": 10
  }
}
Response:
{
  "jsonrpc": "2.0",
  "id": "...",
  "result": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "context_id": "...",
    "kind": "task",
    "status": {...},
    "artifacts": [...],
    "history": [...]
  }
}
Cancel a running task.Request:
{
  "jsonrpc": "2.0",
  "id": "...",
  "method": "tasks/cancel",
  "params": {
    "task_id": "550e8400-e29b-41d4-a716-446655440000"
  }
}
List all tasks (Bindu extension).Request:
{
  "jsonrpc": "2.0",
  "id": "...",
  "method": "tasks/list",
  "params": {
    "history_length": 20
  }
}
Provide feedback on task execution (Bindu extension).Request:
{
  "jsonrpc": "2.0",
  "id": "...",
  "method": "tasks/feedback",
  "params": {
    "task_id": "...",
    "feedback": "Great analysis!",
    "rating": 5
  }
}

Context Operations

List all conversation contexts.Request:
{
  "jsonrpc": "2.0",
  "id": "...",
  "method": "contexts/list",
  "params": {
    "history_length": 10
  }
}
Clear a context and its tasks.Request:
{
  "jsonrpc": "2.0",
  "id": "...",
  "method": "contexts/clear",
  "params": {
    "context_id": "..."
  }
}

Error Handling

Bindu implements standard JSON-RPC 2.0 errors plus A2A-specific and custom error codes.

Standard JSON-RPC Errors

CodeErrorDescription
-32700Parse ErrorInvalid JSON payload
-32600Invalid RequestRequest validation failed
-32601Method Not FoundMethod not available
-32602Invalid ParamsInvalid parameters
-32603Internal ErrorInternal server error

A2A-Specific Errors

CodeErrorDescription
-32001Task Not FoundTask ID not found
-32002Task Not CancelableCannot cancel task in current state
-32003Push Notification Not SupportedPush notifications not supported
-32004Unsupported OperationOperation not supported
-32005Content Type Not SupportedContent type not supported
-32006Invalid Agent ResponseAgent returned invalid response
-32007Authenticated Extended Card Not ConfiguredAgent card not configured

Bindu Extensions

CodeErrorDescription
-32008Task ImmutableTask in terminal state, cannot modify
-32009Authentication RequiredAuthentication required
-32010Invalid TokenInvalid authentication token
-32011Token ExpiredAuthentication token expired
-32012Invalid Token SignatureToken signature verification failed
-32013Insufficient PermissionsInsufficient permissions
-32020Context Not FoundContext ID not found
-32021Context Not CancelableCannot cancel context
Error Response Example:
{
  "jsonrpc": "2.0",
  "id": "...",
  "error": {
    "code": -32001,
    "message": "The specified task ID was not found...",
    "data": {
      "task_id": "550e8400-e29b-41d4-a716-446655440000"
    }
  }
}

Agent System

Agent Identity

class AgentIdentity(TypedDict):
    did: Required[str]  # Decentralized Identifier
    did_document: Required[Dict[str, Any]]
    agentdns_url: NotRequired[str]
    endpoint: NotRequired[str]
    public_key: Required[str]
    csr: Required[str]  # Certificate Signing Request

Agent Trust

class AgentTrust(TypedDict):
    identity_provider: Required[IdentityProvider]
    inherited_roles: Required[List[KeycloakRole]]
    certificate: NotRequired[str]
    certificate_fingerprint: NotRequired[str]
    creator_id: Union[UUID, int, str]
    creation_timestamp: int
    trust_verification_required: bool
    allowed_operations: Dict[str, TrustLevel]
Trust Levels:
LevelDescription
viewerView-only access, minimal permissions
guestLimited access, read-only operations
analystStandard operations
operatorSystem operations, moderate risk
editorEdit operations, moderate risk
auditorSensitive operations
managerManagement operations, elevated permissions
adminAdmin operations, minimal risk
supportSupport operations, troubleshooting access
super_adminHighest level access, all operations permitted

Agent Skills

class Skill(TypedDict):
    id: str
    name: str
    description: str
    tags: list[str]
    examples: NotRequired[list[str]]
    input_modes: list[str]  # Supported MIME types for input
    output_modes: list[str]  # Supported MIME types for output

Agent Card

class AgentCard(TypedDict):
    id: Required[UUID]
    name: Required[str]
    description: Required[str]
    url: Required[str]
    version: Required[str]
    protocol_version: Required[str]
    documentation_url: NotRequired[str]
    icon_url: NotRequired[str]
    
    agent_trust: Required[AgentTrust]
    capabilities: Required[AgentCapabilities]
    skills: Required[List[Skill]]
    
    kind: Required[Literal["agent", "team", "workflow"]]
    execution_cost: NotRequired[AgentExecutionCost]
    num_history_sessions: Required[int]

AP2 Protocol - Payment & Commerce

Bindu implements the AP2 protocol for agent-to-agent commerce and payments.

Payment Request

class PaymentRequest(TypedDict):
    method_data: list[PaymentMethodData]
    details: PaymentDetailsInit
    options: NotRequired[PaymentOptions]
    shipping_address: NotRequired[ContactAddress]

Mandates

AP2 defines three types of mandates for secure commerce:
Represents the user’s purchase intent in human-present flows.
class IntentMandate(TypedDict):
    user_cart_confirmation_required: Required[bool]
    natural_language_description: Required[str]
    merchants: NotRequired[list[str]]
    skus: NotRequired[list[str]]
    requires_refundability: NotRequired[bool]
    intent_expiry: Required[str]
A cart whose contents have been digitally signed by the merchant.
class CartMandate(TypedDict):
    contents: Required[CartContents]
    merchant_authorization: NotRequired[str]  # JWT signature
Contains the user’s instructions and authorization for payment.
class PaymentMandate(TypedDict):
    payment_mandate_contents: Required[PaymentMandateContents]
    user_authorization: NotRequired[str]  # Verifiable credential

Agent Negotiation

Bindu extends A2A with agent-to-agent negotiation capabilities.
class NegotiationProposal(TypedDict):
    proposal_id: Required[UUID]
    from_agent: Required[UUID]
    to_agent: Required[UUID]
    terms: Required[Dict[str, Any]]
    timestamp: Required[str]
    status: Required[NegotiationStatus]  # proposed, accepted, rejected, countered
Negotiation Flow:

Security & Authentication

Security Schemes

Bindu supports multiple authentication methods:
class HTTPAuthSecurityScheme(TypedDict):
    type: Required[Literal["http"]]
    scheme: Required[str]  # e.g., "bearer"
    bearer_format: NotRequired[str]
    description: NotRequired[str]
class APIKeySecurityScheme(TypedDict):
    type: Required[Literal["apiKey"]]
    name: Required[str]
    in_: Required[Literal["query", "header", "cookie"]]
    description: NotRequired[str]
class OAuth2SecurityScheme(TypedDict):
    type: Required[Literal["oauth2"]]
    flows: Required[dict[str, Any]]
    description: NotRequired[str]
class MutualTLSSecurityScheme(TypedDict):
    type: Required[Literal["mutualTLS"]]
    description: NotRequired[str]

Push Notifications

class PushNotificationConfig(TypedDict):
    id: Required[UUID]
    url: Required[str]
    token: NotRequired[str]
    authentication: NotRequired[SecurityScheme]

Implementation Notes

All types use Pydantic for validation and serialization with automatic camelCase conversion via alias_generator=to_camel.
Key Features:
  • Type Safety: TypedDict provides static type checking
  • Runtime Validation: Pydantic validates at runtime
  • Discriminated Unions: Type-safe polymorphism for different message/artifact types
  • Generic Types: Flexible request/response patterns
  • UUID Types: Unique identification across the system
  • Extensibility: Protocol designed for backwards-compatible extensions

Best Practices

  • Keep messages focused on a single task
  • Include relevant context in metadata
  • Use appropriate content types (text, file, data)
  • Provide clear instructions and examples
  • Leverage embeddings for semantic search (Bindu extension)
  • Always check task status before operations
  • Handle all task states in your client code
  • Use reference_task_ids to link related tasks
  • Implement proper error handling for terminal states
  • Respect task immutability in terminal states
  • Group related tasks under the same context
  • Use context metadata for session preferences
  • Implement context lifecycle management
  • Clean up completed/archived contexts periodically
  • Always check response for errors
  • Implement retry logic with exponential backoff
  • Log errors with full context
  • Provide meaningful error messages to users
  • Handle both A2A standard and Bindu extension errors
  • Validate all incoming requests
  • Use minimum required trust levels
  • Implement proper authentication
  • Never expose private keys or credentials
  • Validate JWT signatures

Next Steps


When agents need to work together, they speak Bindu. The protocol provides a robust foundation for building decentralized AI agent systems following A2A and AP2 specifications with thoughtful extensions for real-world agent collaboration.
I