AI and platform services
ModelService
The door to the platform’s own inference server.
| Method | Request → Response | Notes |
|---|---|---|
Complete | CompleteRequest → stream StreamChunk | A completion for an agent profile. template_vars fill the agent’s system prompt. |
GetModelStatus | Empty → ModelStatus | No token needed. ready is true only once the engine can serve a request. |
SynthesizeSpeech | SynthesizeSpeechRequest → SynthesizeSpeechResponse | WAV 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.
| Method | Request → Response | Notes |
|---|---|---|
SubscribeAgentActivity | SubscribeAgentActivityRequest → stream SubscribeAgentActivityResponse | Replays in-flight runs, then snapshot_complete, then live events. Scoped to session, or to the caller’s x-agent-trace-id. |
ListFeaturedMessages | ListFeaturedMessagesRequest → ListFeaturedMessagesResponse | An 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
| Method | Request → Response | Notes |
|---|---|---|
Login | LoginRequest → LoginResponse | No token needed. Username, not email. |
Logout | Empty → Empty | Revokes the whole session |
GetCurrentUser | Empty → 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
| Method | Request → Response |
|---|---|
GetConfig | GetConfigRequest → AppConfig |
UpdateConfig | UpdateConfigRequest → 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
| Method | Request → Response | Notes |
|---|---|---|
CreateTwin | CreateTwinRequest → Twin | New twins are active |
ListTwins | Empty → ListTwinsResponse | |
UpdateTwinStatus | UpdateTwinStatusRequest → Twin | The 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
| Method | Request → Response | Notes |
|---|---|---|
GetStatus | Empty → SelfHealStatus | Read-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.
| Method | Behavior |
|---|---|
GetResourceUsage | Always UNIMPLEMENTED. PULSE does not meter usage. |
GetComputeBudget | Tier and seats from the environment. Consumed and remaining units are unset. FAILED_PRECONDITION without TENANT_ID. |
SetComputeBudget | Always 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;
}