Skip to content
AI and platform services

AI and platform services

ModelService

The door to the platform’s own inference server.

MethodRequest → ResponseNotes
CompleteCompleteRequest → stream StreamChunkA completion for an agent profile. template_vars fill the agent’s system prompt.
GetModelStatusEmpty → ModelStatusNo token needed. ready is true only once the engine can serve a request.
SynthesizeSpeechSynthesizeSpeechRequest → SynthesizeSpeechResponseWAV bytes, synthesized inside PULSE
message ChatMessage {
  string role = 1;    // "system", "user", "assistant"
  string content = 2;
}

message CompleteRequest {
  string prompt = 1;                   // simple prompt (use messages for multi-turn)
  repeated ChatMessage messages = 2;   // multi-turn conversation
  double temperature = 3;
  double top_p = 4;
  int32 max_tokens = 5;
  string agent_id = 6;                // which agent profile to use
  map<string, string> template_vars = 7;
}

message ModelStatus {
  bool ready = 1;
  string model_name = 2;
  int64 context_size = 3;
  int32 active_requests = 4;
  double uptime_seconds = 5;
  string error = 6;
}

message SynthesizeSpeechRequest {
  string text = 1;
  string voice = 2; // optional voice id; engine default when empty
}

message SynthesizeSpeechResponse {
  bytes audio = 1;
  string format = 2; // e.g. "wav"
}

ActivityService

See Agent activity.

MethodRequest → ResponseNotes
SubscribeAgentActivitySubscribeAgentActivityRequest → stream SubscribeAgentActivityResponseReplays in-flight runs, then snapshot_complete, then live events. Scoped to session, or to the caller’s x-agent-trace-id.
ListFeaturedMessagesListFeaturedMessagesRequest → ListFeaturedMessagesResponseAn empty list is a success

A client must render nothing for an unknown non-empty AgentStep.code, never the raw token.

message SubscribeAgentActivityRequest {
  int32 replay_steps_per_run = 1;

  string session = 2;
}

enum AgentRunStatus {
  AGENT_RUN_STATUS_UNSPECIFIED = 0;
  AGENT_RUN_STATUS_RUNNING = 1;
  AGENT_RUN_STATUS_DONE = 2;
  AGENT_RUN_STATUS_FAILED = 3;
}

message AgentRun {
  string run_id = 1;
  string agent = 2;
  string session = 3;
  int64 started_unix = 4;
  int64 ended_unix = 5;
  AgentRunStatus status = 6;
  int32 step_count = 7;
  repeated AgentStep steps = 8;
  string error = 9;
}

message AgentStep {
  string run_id = 1;
  int32 index = 2;
  string thought = 3;
  string action = 4;
  string input = 5;
  string result = 6;
  string model = 7;
  int64 latency_ms = 8;
  string error = 9;
  int64 at_unix = 10;
  int64 total_tokens = 11;

  string code = 12;

  map<string, string> operands = 13;

  StepProvenance provenance = 14;
}

message StepProvenance {
  string source = 1;
  string path = 2;
  bool degraded = 3;
  int64 computed_at_unix = 4;
}

message SubscribeAgentActivityResponse {
  oneof event {
    AgentRun snapshot = 1;
    bool snapshot_complete = 2;
    AgentRun run_started = 3;
    AgentStep step = 4;
    AgentRun run_finished = 5;
  }
}

message ListFeaturedMessagesRequest {}

message FeaturedMessage {
  string id = 1;
  string title = 2;
  string body = 3;
  string locale = 4;
  string href = 5;
  string icon = 6;
}

message FeaturedMessage {
  string id = 1;
  string title = 2;
  string body = 3;
  string locale = 4;
  string href = 5;
  string icon = 6;
}

message ListFeaturedMessagesResponse {
  repeated FeaturedMessage messages = 1;
  string source = 2;
}

IdentityService

MethodRequest → ResponseNotes
LoginLoginRequest → LoginResponseNo token needed. Username, not email.
LogoutEmpty → EmptyRevokes the whole session
GetCurrentUserEmpty → User

expires_in is in seconds. Refresh and Google sign-in are plain HTTP; see HTTP endpoints.

message LoginRequest {
  string username = 1;
  string password = 2;
}

message LoginResponse {
  string access_token = 1;
  string refresh_token = 2;
  User user = 3;
  int64 expires_in = 4; // seconds until token expiry
}

ConfigService

MethodRequest → Response
GetConfigGetConfigRequest → AppConfig
UpdateConfigUpdateConfigRequest → AppConfig
message GetConfigRequest {
  string user_id = 1;
}

message AppConfig {
  string id = 1;
  string user_id = 2;
  string business_name = 3;
  string industry = 4;
  string default_language = 5;
  string default_tone = 6;
  repeated Channel active_channels = 7;
  string timezone = 8;
  map<string, string> preferences = 9; // generic key-value preferences
  google.protobuf.Timestamp updated_at = 10;
}

message UpdateConfigRequest {
  string business_name = 1;
  string industry = 2;
  string default_language = 3;
  string default_tone = 4;
  repeated Channel active_channels = 5;
  string timezone = 6;
  map<string, string> preferences = 7;
}

TwinService

MethodRequest → ResponseNotes
CreateTwinCreateTwinRequest → TwinNew twins are active
ListTwinsEmpty → ListTwinsResponse
UpdateTwinStatusUpdateTwinStatusRequest → TwinThe server stores any string. The app uses active and paused.
message Twin {
  string id = 1;
  string name = 2;
  string role = 3;
  string system_prompt = 4;
  string avatar_id = 5;
  string status = 6;
}

message CreateTwinRequest {
  string name = 1;
  string role = 2;
  string system_prompt = 3;
  string avatar_id = 4;
}

message ListTwinsResponse {
  repeated Twin twins = 1;
}

message UpdateTwinStatusRequest {
  string twin_id = 1;
  string status = 2;
}

SelfHealService

MethodRequest → ResponseNotes
GetStatusEmpty → SelfHealStatusRead-only. It never triggers remediation.
message SelfHealEvent {
  string type = 1;        // HealthEventType, e.g. "endpoint_unhealthy", "memory_pressure"
  string severity = 2;    // e.g. "warning", "critical"
  string target_id = 3;
  string description = 4;
  bool remediated = 5;    // true if the remediator handled it without error
  google.protobuf.Timestamp at = 6;
}

message SelfHealStatus {
  bool healthy = 1;               // no critical event unresolved in the recent window
  google.protobuf.Timestamp started_at = 2;
  SelfHealEvent last_event = 3;   // unset if nothing has fired yet
  repeated SelfHealEvent recent_events = 4; // most recent first, bounded
  int32 remediation_attempts = 5;
  int32 remediation_failures = 6;
}

MeteringService (deprecated)

Kept for one release. Use runink.ui.billing.v1.BillingService instead. See Billing.

MethodBehavior
GetResourceUsageAlways UNIMPLEMENTED. PULSE does not meter usage.
GetComputeBudgetTier and seats from the environment. Consumed and remaining units are unset. FAILED_PRECONDITION without TENANT_ID.
SetComputeBudgetAlways UNIMPLEMENTED
message GetResourceUsageRequest {}

message GetResourceUsageResponse {
  double compute_units = 1;         // CU consumed this period
  double overage_cents = 2;         // current CU overage cost, if any
}

message GetResourceUsageResponse {
  double compute_units = 1;         // CU consumed this period
  double overage_cents = 2;         // current CU overage cost, if any
}

message GetComputeBudgetRequest {}

message SetComputeBudgetRequest {
  double dedicated_compute_units = 1;
}

message SetComputeBudgetRequest {
  double dedicated_compute_units = 1;
}

message ComputeBudgetResponse {
  string tenant_id = 1;
  string tier = 2;                     // "lite" | "dedicated" | "enterprise" | "suspended"
  int32 seats = 3;
  double dedicated_compute_units = 4;  // seat-derived allowance
  double consumed_compute_units = 5 [deprecated = true];  // NOT MEASURED: always unset
  double remaining_compute_units = 6 [deprecated = true]; // NOT MEASURED: always unset
  int32 seat_monthly_cents = 7;        // effective per-seat monthly price for display
  bool annual = 8;
}