syntax = "proto3";

package flyteidl.admin;
option go_package = "github.com/flyteorg/flyte/flyteidl/gen/pb-go/flyteidl/admin";

import "flyteidl/core/literals.proto";
import "flyteidl/core/tasks.proto";
import "flyteidl/core/workflow.proto";
import "flyteidl/core/identifier.proto";
import "flyteidl/core/execution.proto";
import "flyteidl/core/metrics.proto";
import "flyteidl/core/security.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/struct.proto";

// The state of the execution is used to control its visibility in the UI/CLI.
enum State {
  option deprecated = true;
  RETRYABLE_FAILURE = 0;
  PERMANENT_FAILURE = 1;
  PENDING = 2;
  RUNNING = 3;
  SUCCEEDED = 4;
}

// Represents a subset of runtime task execution metadata that are relevant to external plugins.
message TaskExecutionMetadata {
  // ID of the task execution
  
  core.TaskExecutionIdentifier task_execution_id = 1;
  // k8s namespace where the task is executed in
  string namespace = 2;
  // Labels attached to the task execution
  map<string, string> labels = 3;
  // Annotations attached to the task execution
  map<string, string> annotations = 4;
  // k8s service account associated with the task execution
  string k8s_service_account = 5;
  // Environment variables attached to the task execution
  map<string, string> environment_variables = 6;
  // Represents the maximum number of attempts allowed for a task.
  // If a task fails, it can be retried up to this maximum number of attempts.
  int32 max_attempts = 7;
  // Indicates whether the task execution can be interrupted.
  // If set to true, the task can be stopped before completion.
  bool interruptible = 8;
  // Specifies the threshold for failure count at which the interruptible property
  // will take effect. If the number of consecutive task failures exceeds this threshold,
  // interruptible behavior will be activated.
  int32 interruptible_failure_threshold = 9;
  // Overrides for specific properties of the task node.
  // These overrides can be used to customize the behavior of the task node.
  core.TaskNodeOverrides overrides = 10;
  // Identity of user running this task execution
  core.Identity identity = 11;
}

// Represents a request structure to create task.
message CreateTaskRequest {
  // The inputs required to start the execution. All required inputs must be
  // included in this map. If not required and not provided, defaults apply.
  // +optional
  core.LiteralMap inputs = 1;
  // Template of the task that encapsulates all the metadata of the task.
  core.TaskTemplate template = 2;
  // Prefix for where task output data will be written. (e.g. s3://my-bucket/randomstring)
  string output_prefix = 3;
  // subset of runtime task execution metadata.
  TaskExecutionMetadata task_execution_metadata = 4;
}

// Represents a create response structure.
message CreateTaskResponse {
  // ResourceMeta is created by the agent. It could be a string (jobId) or a dict (more complex metadata).
  bytes resource_meta = 1;
}

message CreateRequestHeader {
  // Template of the task that encapsulates all the metadata of the task.
  core.TaskTemplate template = 1;
  // Prefix for where task output data will be written. (e.g. s3://my-bucket/randomstring)
  string output_prefix = 2;
  // subset of runtime task execution metadata.
  TaskExecutionMetadata task_execution_metadata = 3;
  // MaxDatasetSizeBytes is the maximum size of the dataset that can be generated by the task.
  int64 max_dataset_size_bytes = 4;
}


message ExecuteTaskSyncRequest {
  oneof part {
    CreateRequestHeader header = 1;
    core.LiteralMap inputs = 2;
  }
}

message ExecuteTaskSyncResponseHeader {
  Resource resource = 1;
}

message ExecuteTaskSyncResponse {
  // Metadata is created by the agent. It could be a string (jobId) or a dict (more complex metadata).
  // Resource is for synchronous task execution.
  oneof res {
    ExecuteTaskSyncResponseHeader header = 1;
    core.LiteralMap outputs = 2;
  }
}

// A message used to fetch a job resource from flyte agent server.
message GetTaskRequest {
  reserved 5;
  // A predefined yet extensible Task type identifier.
  string task_type = 1 [deprecated = true];
  // Metadata about the resource to be pass to the agent.
  bytes resource_meta = 2;
  // A predefined yet extensible Task type identifier.
  TaskCategory task_category = 3;
  // Prefix for where task output data will be written. (e.g. s3://my-bucket/randomstring)
  string output_prefix = 4;
}

// Response to get an individual task resource.
message GetTaskResponse {
  Resource resource = 1;
}

message Resource {
  // DEPRECATED. The state of the execution is used to control its visibility in the UI/CLI.
  State state = 1 [deprecated = true];
  // The outputs of the execution. It's typically used by sql task. Agent service will create a
  // Structured dataset pointing to the query result table.
  // +optional
  core.LiteralMap outputs = 2;
  // A descriptive message for the current state. e.g. waiting for cluster.
  string message = 3;
  // log information for the task execution.
  repeated core.TaskLog log_links = 4;
  // The phase of the execution is used to determine the phase of the plugin's execution.
  core.TaskExecution.Phase phase = 5;
  // Custom data specific to the agent.
  google.protobuf.Struct custom_info = 6;
  // The error raised during execution
  AgentError agent_error = 7;
}

// A message used to delete a task.
message DeleteTaskRequest {
  // A predefined yet extensible Task type identifier.
  string task_type = 1 [deprecated = true];
  // Metadata about the resource to be pass to the agent.
  bytes resource_meta = 2;
  // A predefined yet extensible Task type identifier.
  TaskCategory task_category = 3;
}

// Response to delete a task.
message DeleteTaskResponse {}

// A message containing the agent metadata.
message Agent {
  // Name is the developer-assigned name of the agent.
  string name = 1;
  
  // SupportedTaskTypes are the types of the tasks that the agent can handle.
  repeated string supported_task_types = 2 [deprecated = true];

  // IsSync indicates whether this agent is a sync agent. Sync agents are expected to return their
  // results synchronously when called by propeller. Given that sync agents can affect the performance
  // of the system, it's important to enforce strict timeout policies.
  // An Async agent, on the other hand, is required to be able to identify jobs by an
  // identifier and query for job statuses as jobs progress.
  bool is_sync = 3;

  // Supported_task_categories are the categories of the tasks that the agent can handle.
  repeated TaskCategory supported_task_categories = 4;
}

message TaskCategory {
  // The name of the task type.
  string name = 1;
  // The version of the task type.
  int32 version = 2;
}

// A request to get an agent.
message GetAgentRequest {
  // The name of the agent.
  string name = 1;
}

// A response containing an agent.
message GetAgentResponse {
  Agent agent = 1;
}

// A request to list all agents.
message ListAgentsRequest {}

// A response containing a list of agents.
message ListAgentsResponse {
  repeated Agent agents = 1;
}

// A request to get the metrics from a task execution.
message GetTaskMetricsRequest {
  // A predefined yet extensible Task type identifier.
  string task_type = 1 [deprecated = true];
  // Metadata is created by the agent. It could be a string (jobId) or a dict (more complex metadata).
  bytes resource_meta = 2;
  // The metrics to query. If empty, will return a default set of metrics.
  // e.g. EXECUTION_METRIC_USED_CPU_AVG or EXECUTION_METRIC_USED_MEMORY_BYTES_AVG
  repeated string queries = 3;
  // Start timestamp, inclusive.
  google.protobuf.Timestamp start_time = 4;
  // End timestamp, inclusive..
  google.protobuf.Timestamp end_time = 5;
  // Query resolution step width in duration format or float number of seconds.
  google.protobuf.Duration step = 6;
  // A predefined yet extensible Task type identifier.
  TaskCategory task_category = 7;
}

// A response containing a list of metrics for a task execution.
message GetTaskMetricsResponse {
  // The execution metric results.
  repeated core.ExecutionMetricResult results = 1;
}

// A request to get the log from a task execution.
message GetTaskLogsRequest {
  // A predefined yet extensible Task type identifier.
  string task_type = 1 [deprecated = true];
  // Metadata is created by the agent. It could be a string (jobId) or a dict (more complex metadata).
  bytes resource_meta = 2;
  // Number of lines to return.
  uint64 lines = 3;
  // In the case of multiple pages of results, the server-provided token can be used to fetch the next page
  // in a query. If there are no more results, this value will be empty.
  string token = 4;
  // A predefined yet extensible Task type identifier.
  TaskCategory task_category = 5;
}

message GetTaskLogsResponseHeader {
  // In the case of multiple pages of results, the server-provided token can be used to fetch the next page
  // in a query. If there are no more results, this value will be empty.
  string token = 1;
}

enum LogLineOriginator {
  // The originator of the log line is unknown.
  UNKNOWN = 0;

  // The originator of the log line is the user application.
  USER = 1;

  // The originator of the log line is the system.
  SYSTEM = 2;
}

message LogLine {
  google.protobuf.Timestamp timestamp = 1;

  // Each line is separated by either CRLF, CR or LF, which are included
  // at the ends of the lines. This lets clients know whether log emitter
  // wanted to overwrite the previous line (LF) or append a new line (CRLF).
  string message = 2;

  LogLineOriginator originator = 3;
}

message GetTaskLogsResponseBody {
  // The execution log results.
  repeated string results = 1 [deprecated = true];

  // Each line is separated by either CRLF, CR or LF, which are included
  // at the ends of the lines. This lets clients know whether log emitter
  // wanted to overwrite the previous line (LF) or append a new line (CRLF).
  repeated LogLine structured_lines = 2;
}

// A response containing the logs for a task execution.
message GetTaskLogsResponse {
  oneof part {
    GetTaskLogsResponseHeader header = 1;
    GetTaskLogsResponseBody body = 2;
  }
}

// Error message to propagate detailed errors from agent executions to the execution
// engine.
message AgentError {
  // A simplified code for errors, so that we can provide a glossary of all possible errors.
  string code = 1;

  // Defines a generic error type that dictates the behavior of the retry strategy.
  enum Kind {
    NON_RECOVERABLE = 0;
    RECOVERABLE = 1;
  }

  // An abstract error kind for this error. Defaults to Non_Recoverable if not specified.
  Kind kind = 3;

  // Defines the origin of the error (system, user, unknown).
  core.ExecutionError.ErrorKind origin = 4;
}
