protocol.proto 6.64 KB
// protocol.proto — gRPC service contract between the Hermes Agent Runtime
// (client, runs on the host machine) and the Android Runtime (server, runs
// on the device or emulator).
//
// Generated stubs are NOT checked in; they are produced at build time by the
// protoc-gen-grpc-java / grpc-kotlin plug-ins when the project adds gRPC
// support to its Gradle configuration.

syntax = "proto3";

package ai.lemon.phoneuse.mcpserver.protocol;

option java_package = "ai.lemon.phoneuse.mcpserver.protocol";
option java_outer_classname = "ProtocolProto";
option java_multiple_files = true;

import "google/protobuf/any.proto";

// ---------------------------------------------------------------------------
// AndroidRuntime service
// ---------------------------------------------------------------------------

// AndroidRuntime is the primary entry-point exposed by the Agent Phone Runtime
// running on the Android device.  The Hermes Agent Runtime acts as the gRPC
// client and issues calls over an authenticated, optionally-TLS-wrapped
// channel.
service AndroidRuntime {

    // Execute an action on the device (e.g. send a message, create a calendar
    // event).  The call is synchronous from the caller's perspective; the
    // server blocks until the action completes or the supplied timeout_ms
    // elapses.
    rpc Execute(ActionRequest) returns (ActionResponse);

    // Query structured data from the device memory graph or a specific app
    // (e.g. contacts, recent messages, current app state).
    rpc Query(QueryRequest) returns (QueryResponse);

    // Subscribe to a stream of real-time events from the device.  The server
    // pushes Event messages as they occur until the client cancels the stream
    // or the connection is closed.
    rpc Subscribe(SubscribeRequest) returns (stream Event);
}

// ---------------------------------------------------------------------------
// Execute RPC — messages
// ---------------------------------------------------------------------------

// ActionRequest describes a single discrete action the Android Runtime should
// perform on behalf of the Hermes Agent.
message ActionRequest {
    // Identifies the action category.  Must match a value in the ActionType
    // Kotlin enum (e.g. "SEND_MESSAGE", "CREATE_EVENT").
    string action_type = 1;

    // Optional: the application that should handle this action (e.g.
    // "com.whatsapp", "com.android.calendar").  When absent the runtime
    // selects the default handler for the action type.
    optional string app_target = 2;

    // Arbitrary key/value parameters specific to the action_type.
    // See protocol_spec.md for the required and optional keys per action.
    map<string, string> params = 3;

    // Caller-assigned correlation identifier.  Echoed back in ActionResponse
    // so the client can match responses to outstanding requests.
    string request_id = 4;

    // Maximum time in milliseconds the runtime should wait before abandoning
    // the action and returning a TIMEOUT error.  Must be > 0.
    int64 timeout_ms = 5;
}

// ActionResponse carries the outcome of a previously submitted ActionRequest.
message ActionResponse {
    // Echoed from the corresponding ActionRequest.request_id.
    string request_id = 1;

    // true if the action completed successfully; false on any error.
    bool success = 2;

    // Action-specific result payload encoded as a JSON string.
    // Present when success == true; absent or empty on failure.
    // Using a plain string (rather than google.protobuf.Any) avoids requiring
    // the consumer to register type URLs and keeps the contract simple.
    string result_json = 3;

    // Human-readable error message.  Present when success == false.
    string error = 4;

    // Wall-clock duration in milliseconds from action start to completion.
    int64 duration_ms = 5;
}

// ---------------------------------------------------------------------------
// Query RPC — messages
// ---------------------------------------------------------------------------

// QueryType enumerates the first-class query targets supported by the runtime.
enum QueryType {
    QUERY_TYPE_UNSPECIFIED = 0;
    MEMORY      = 1;    // Semantic memory graph
    APP_STATE   = 2;    // Live accessibility / foreground state of an app
    CONTACTS    = 3;    // Unified contacts from all integrated sources
}

// QueryRequest specifies what structured data the caller wants to retrieve.
message QueryRequest {
    // Target data source to query.
    QueryType query_type = 1;

    // Optional key/value filter predicates applied by the runtime before
    // returning results.  Filter semantics are query_type-specific; see
    // protocol_spec.md for supported keys per QueryType.
    map<string, string> filters = 2;

    // Maximum number of results to return.  Defaults to 20 when 0 is supplied.
    int32 limit = 3;
}

// QueryResponse returns a page of results for a QueryRequest.
message QueryResponse {
    // Each element is a JSON-encoded object whose schema depends on
    // query_type (see protocol_spec.md).
    repeated string results_json = 1;

    // Total number of records that match the query (before limit is applied).
    int32 total_count = 2;

    // true if additional pages are available beyond the current limit.
    bool has_more = 3;
}

// ---------------------------------------------------------------------------
// Subscribe RPC — messages
// ---------------------------------------------------------------------------

// SubscribeRequest tells the runtime which event categories the client wants
// to receive.
message SubscribeRequest {
    // List of event type strings to subscribe to (e.g. "APP_STATE_CHANGED",
    // "MESSAGE_RECEIVED").  An empty list is treated as "subscribe to all".
    repeated string event_types = 1;

    // Stable identifier for this subscriber (UUID or human-readable tag).
    // Used for deduplication and server-side fan-out logging.
    string subscriber_id = 2;
}

// Event is a single real-time notification pushed from the Android Runtime to
// the Hermes Agent Runtime subscriber.
message Event {
    // Discriminator string matching one of the known event types
    // (e.g. "APP_STATE_CHANGED", "MESSAGE_RECEIVED", "TASK_COMPLETED",
    // "ERROR").  Callers should handle unknown values gracefully.
    string event_type = 1;

    // JSON-encoded event-specific payload.  Schema is event_type-dependent;
    // see protocol_spec.md for field definitions per event type.
    string payload_json = 2;

    // Unix epoch time in milliseconds when the event occurred on the device.
    int64 timestamp = 3;

    // Package name or system component that produced the event
    // (e.g. "com.whatsapp", "android.system").
    string source = 4;
}