syntax = "proto3";
package mubit.v1;

service ControlService {
  // State Memory (Structured Variables)
  rpc SetVariable(SetVariableRequest) returns (Ack);
  rpc GetVariable(GetVariableRequest) returns (VariableResponse);
  rpc ListVariables(ListVariablesRequest) returns (ListVariablesResponse);
  rpc DeleteVariable(DeleteVariableRequest) returns (Ack);

  // Concepts (Level 4 Agency)
  rpc DefineConcept(DefineConceptRequest) returns (Ack);
  rpc ListConcepts(ListConceptsRequest) returns (ListConceptsResponse);

  // Goals
  rpc AddGoal(AddGoalRequest) returns (GoalResponse);
  rpc UpdateGoal(UpdateGoalRequest) returns (Ack);
  rpc ListGoals(ListGoalsRequest) returns (ListGoalsResponse);

  // Actions
  rpc SubmitAction(ActionRequest) returns (ActionResponse);
  rpc GetActionLog(ActionLogRequest) returns (ActionLogResponse);

  // Decision Cycle
  rpc RunCycle(RunCycleRequest) returns (CycleResponse);
  rpc GetCycleHistory(CycleHistoryRequest) returns (CycleHistoryResponse);

  // Management
  rpc DeleteRun(RunRequest) returns (Ack);

  // Events
  rpc Subscribe(SubscribeRequest) returns (stream Event);

  // Agent + control-plane primitives
  rpc RegisterAgent(AgentRegisterRequest) returns (AgentRegisterResponse);
  rpc AgentHeartbeat(AgentHeartbeatRequest) returns (Ack);
  rpc AppendActivity(ActivityAppendRequest) returns (ActivityAppendResponse);
  rpc GetRunSnapshot(RunSnapshotRequest) returns (RunSnapshotResponse);
  rpc LinkRun(LinkRunRequest) returns (LinkRunResponse);
  rpc UnlinkRun(UnlinkRunRequest) returns (UnlinkRunResponse);
  rpc Ingest(IngestRequest) returns (IngestAccepted);
  rpc BatchInsert(ControlBatchInsertRequest) returns (ControlBatchInsertResponse);
  rpc GetIngestJob(GetIngestJobRequest) returns (IngestJobResponse);
  rpc Query(AgentQueryRequest) returns (AgentQueryResponse);
}

message Ack {
  bool success = 1;
}

message RunRequest {
  string run_id = 1;
}

message SubscribeRequest {
  string run_id = 1;
  repeated string event_types = 2; // Optional filter
}

message Event {
  string id = 1;
  string type = 2; // "VariableUpdate", "GoalUpdate", etc.
  string run_id = 3;
  string agent_id = 4;
  string payload = 5; // JSON string of the object involved
  string created_at = 6;
}

message RunScope {
  string run_id = 1;
  repeated string linked_run_ids = 2;
  uint64 owner_user_id = 3;
}

message AgentIdentity {
  string agent_id = 1;
  string role = 2;
  repeated string capabilities = 3;
  string status = 4;
  string heartbeat_at = 5;
}

message ActivityRecord {
  string type = 1;
  string payload = 2;
  string tool_name = 3;
  string input_ref = 4;
  string output_ref = 5;
  string ts = 6;
  string agent_id = 7;
}

message RunSnapshot {
  string summary = 1;
  repeated string facts = 2;
  repeated string uncertainties = 3;
  repeated string blockers = 4;
  repeated string progress = 5;
  repeated string next_actions = 6;
  string updated_at = 7;
}

message PromotionDecision {
  string source_record_id = 1;
  string target = 2;
  float confidence = 3;
  string reason = 4;
  string policy_rule = 5;
  string created_at = 6;
}

message LlmOverride {
  string provider = 1;
  string model = 2;
  float temperature = 3;
  uint32 max_tokens = 4;
  uint64 timeout_ms = 5;
}

message ControlStatus {
  bool enabled = 1;
  bool healthy = 2;
  string provider = 3;
  string model = 4;
  string last_error = 5;
  string updated_at = 6;
}

message AgentRegisterRequest {
  string run_id = 1;
  string agent_id = 2;
  string role = 3;
  repeated string capabilities = 4;
  string status = 5;
}

message AgentRegisterResponse {
  bool success = 1;
  AgentIdentity agent = 2;
}

message AgentHeartbeatRequest {
  string run_id = 1;
  string agent_id = 2;
  string status = 3;
}

message ActivityAppendRequest {
  string run_id = 1;
  string agent_id = 2;
  ActivityRecord activity = 3;
  LlmOverride llm = 4;
}

message ActivityAppendResponse {
  bool success = 1;
  string event_id = 2;
}

message RunSnapshotRequest {
  string run_id = 1;
  uint64 timeline_limit = 2;
  bool refresh = 3;
  LlmOverride llm = 4;
}

message RunSnapshotResponse {
  RunScope scope = 1;
  RunSnapshot snapshot = 2;
  repeated AgentIdentity agents = 3;
  repeated Event timeline = 4;
  repeated PromotionDecision promotions = 5;
  ControlStatus control_status = 6;
}

message LinkRunRequest {
  string run_id = 1;
  string linked_run_id = 2;
}

message LinkRunResponse {
  bool success = 1;
  RunScope scope = 2;
}

message UnlinkRunRequest {
  string run_id = 1;
  string linked_run_id = 2;
}

message UnlinkRunResponse {
  bool success = 1;
  RunScope scope = 2;
}

message IngestItem {
  string item_id = 1;
  string content_type = 2;
  string text = 3;
  string payload_json = 4;
  string hints_json = 5;
  string metadata_json = 6;
}

message IngestRequest {
  string run_id = 1;
  string agent_id = 2;
  string idempotency_key = 3;
  bool parallel = 4;
  repeated IngestItem items = 5;
}

message IngestAccepted {
  bool accepted = 1;
  string job_id = 2;
  bool deduplicated = 3;
  string status = 4;
}

message ControlBatchInsertItem {
  string item_id = 1;
  string text = 2;
  string metadata_json = 3;
  string source = 4;
  repeated float embedding = 5;
}

message ControlBatchInsertRequest {
  string run_id = 1;
  repeated ControlBatchInsertItem items = 2;
  bool deduplicate = 3;
}

message ControlBatchInsertItemResult {
  string item_id = 1;
  bool success = 2;
  uint64 node_id = 3;
  string error = 4;
}

message ControlBatchInsertResponse {
  bool success = 1;
  uint32 count = 2;
  repeated uint64 node_ids = 3;
  repeated ControlBatchInsertItemResult item_results = 4;
  string message = 5;
}

message GetIngestJobRequest {
  string run_id = 1;
  string job_id = 2;
}

message IngestWriteResult {
  string memory_type = 1;
  string record_id = 2;
  bool success = 3;
  string error = 4;
}

message IngestDecisionTrace {
  string item_id = 1;
  string content_type = 2;
  repeated string selected_types = 3;
  string reasoning = 4;
  string enriched_metadata_json = 5;
  repeated IngestWriteResult writes = 6;
  float confidence = 7;
}

message IngestJobResponse {
  string job_id = 1;
  string run_id = 2;
  string status = 3;
  bool done = 4;
  string error = 5;
  string created_at = 6;
  string started_at = 7;
  string finished_at = 8;
  repeated IngestDecisionTrace traces = 9;
  bool ordered = 10;
  bool deduplicated = 11;
}

enum QueryMode {
  QUERY_MODE_UNSPECIFIED = 0;
  AGENT_ROUTED = 1;
  DIRECT_BYPASS = 2;
}

enum DirectQueryLane {
  DIRECT_QUERY_LANE_UNSPECIFIED = 0;
  SEMANTIC_SEARCH = 1;
  HDQL_QUERY = 2;
}

message AgentQueryRequest {
  string run_id = 1;
  string query = 2;
  string schema = 3;
  QueryMode mode = 4;
  DirectQueryLane direct_lane = 5;
  bool include_linked_runs = 6;
  uint64 limit = 7;
  repeated float embedding = 8;
}

message QueryEvidence {
  string id = 1;
  string content = 2;
  string source = 3;
  float score = 4;
  string run_id = 5;
}

message AgentQueryResponse {
  string final_answer = 1;
  repeated QueryEvidence evidence = 2;
  float confidence = 3;
  string mode = 4;
  bool degraded = 5;
  repeated string consulted_runs = 6;
  string routing_summary = 7;
}

// =============================================================================
// State Memory (Structured Variables)
// =============================================================================

message SetVariableRequest {
  string run_id = 1;
  string name = 2;
  string value_json = 3;  // JSON-encoded value
  string source = 4;      // "system", "reasoning", "retrieval", "perception", "explicit"
}

message GetVariableRequest {
  string run_id = 1;
  string name = 2;
}

message VariableResponse {
  string name = 1;
  string value_json = 2;
  string var_type = 3;
  string created_at = 4;
  string last_updated = 5;
  uint64 access_count = 6;
  string source = 7;
}

message ListVariablesRequest {
  string run_id = 1;
}

message ListVariablesResponse {
  repeated VariableResponse variables = 1;
}

message DeleteVariableRequest {
  string run_id = 1;
  string name = 2;
}

message DefineConceptRequest {
  string run_id = 1;
  string name = 2;
  string schema_json = 3;
}

message ListConceptsRequest {
  string run_id = 1;
}

message Concept {
  string name = 1;
  string schema_json = 2;
}

message ListConceptsResponse {
  repeated Concept concepts = 1;
}

// =============================================================================
// Goals
// =============================================================================

message AddGoalRequest {
  string run_id = 1;
  string description = 2;
  string priority = 3;    // "low", "medium", "high", "critical"
  string parent_id = 4;   // Optional parent goal ID
}

message GoalResponse {
  string id = 1;
  string description = 2;
  string priority = 3;
  string status = 4;
  string parent_id = 5;
  string created_at = 6;
}

message UpdateGoalRequest {
  string run_id = 1;
  string goal_id = 2;
  string status = 3;      // "active", "suspended", "achieved", "abandoned", "failed"
}

message ListGoalsRequest {
  string run_id = 1;
  string status_filter = 2;  // Optional: filter by status
}

message ListGoalsResponse {
  repeated GoalResponse goals = 1;
}

// =============================================================================
// Actions
// =============================================================================

message ActionRequest {
  string run_id = 1;
  string agent_id = 2;
  string action_type = 3;  // "reason", "retrieve", "learn", "ground"
  string action_json = 4;  // JSON-encoded action details
}

message ActionResponse {
  string action_id = 1;
  bool success = 2;
  string result_json = 3;
  string error = 4;
  uint64 duration_ms = 5;
}

message ActionLogRequest {
  string run_id = 1;
  uint64 limit = 2;
  string action_type_filter = 3;  // Optional
}

message ActionLogResponse {
  repeated ActionLogEntry entries = 1;
}

message ActionLogEntry {
  string action_id = 1;
  string action_type = 2;
  string action_json = 3;
  bool success = 4;
  string result_json = 5;
  uint64 cycle_number = 6;
  string timestamp = 7;
}

// =============================================================================
// Decision Cycle
// =============================================================================

message RunCycleRequest {
  string run_id = 1;
  string agent_id = 2;
  repeated ActionCandidate candidates = 3;  // Optional: pre-proposed candidates
}

message ActionCandidate {
  string action_type = 1;
  string action_json = 2;
  float score = 3;
  string rationale = 4;
}

message CycleResponse {
  uint64 cycle_number = 1;
  ActionCandidate selected_action = 2;
  ActionResponse action_result = 3;
  uint64 planning_time_ms = 4;
  uint64 execution_time_ms = 5;
  string timestamp = 6;
}

message CycleHistoryRequest {
  string run_id = 1;
  uint64 limit = 2;
}

message CycleHistoryResponse {
  repeated CycleResponse cycles = 1;
}
