syntax = "proto3";

package temporal.api.common.v1;

option go_package = "go.temporal.io/api/common/v1;common";
option java_package = "io.temporal.api.common.v1";
option java_multiple_files = true;
option java_outer_classname = "MessageProto";
option ruby_package = "Temporalio::Api::Common::V1";
option csharp_namespace = "Temporalio.Api.Common.V1";

import "google/protobuf/duration.proto";
import "google/protobuf/empty.proto";

import "temporal/api/enums/v1/common.proto";
import "temporal/api/enums/v1/event_type.proto";
import "temporal/api/enums/v1/reset.proto";

message DataBlob {
    temporal.api.enums.v1.EncodingType encoding_type = 1;
    bytes data = 2;
}

// See `Payload`
message Payloads {
    repeated Payload payloads = 1;
}

// Represents some binary (byte array) data (ex: activity input parameters or workflow result) with
// metadata which describes this binary data (format, encoding, encryption, etc). Serialization
// of the data may be user-defined.
message Payload {
    map<string,bytes> metadata = 1;
    bytes data = 2;
    // Details about externally stored payloads associated with this payload.
    repeated ExternalPayloadDetails external_payloads = 3;

    // Describes an externally stored object referenced by this payload.
    message ExternalPayloadDetails {
        // Size in bytes of the externally stored payload
        int64 size_bytes = 1;
    }
}

// A user-defined set of *indexed* fields that are used/exposed when listing/searching workflows.
// The payload is not serialized in a user-defined way.
message SearchAttributes {
    map<string, Payload> indexed_fields = 1;
}

// A user-defined set of *unindexed* fields that are exposed when listing/searching workflows
message Memo {
    map<string, Payload> fields = 1;
}

// Contains metadata that can be attached to a variety of requests, like starting a workflow, and
// can be propagated between, for example, workflows and activities.
message Header {
    map<string, Payload> fields = 1;
}

// Identifies a specific workflow within a namespace. Practically speaking, because run_id is a
// uuid, a workflow execution is globally unique. Note that many commands allow specifying an empty
// run id as a way of saying "target the latest run of the workflow".
message WorkflowExecution {
    string workflow_id = 1;
    string run_id = 2;
}

// Represents the identifier used by a workflow author to define the workflow. Typically, the
// name of a function. This is sometimes referred to as the workflow's "name"
message WorkflowType {
    string name = 1;
}

// Represents the identifier used by a activity author to define the activity. Typically, the
// name of a function. This is sometimes referred to as the activity's "name"
message ActivityType {
    string name = 1;
}

// How retries ought to be handled, usable by both workflows and activities
message RetryPolicy {
    // Interval of the first retry. If retryBackoffCoefficient is 1.0 then it is used for all retries.
    google.protobuf.Duration initial_interval = 1;
    // Coefficient used to calculate the next retry interval.
    // The next retry interval is previous interval multiplied by the coefficient.
    // Must be 1 or larger.
    double backoff_coefficient = 2;
    // Maximum interval between retries. Exponential backoff leads to interval increase.
    // This value is the cap of the increase. Default is 100x of the initial interval.
    google.protobuf.Duration maximum_interval = 3;
    // Maximum number of attempts. When exceeded the retries stop even if not expired yet.
    // 1 disables retries. 0 means unlimited (up to the timeouts)
    int32 maximum_attempts = 4;
    // Non-Retryable errors types. Will stop retrying if the error type matches this list. Note that
    // this is not a substring match, the error *type* (not message) must match exactly.
    repeated string non_retryable_error_types = 5;
}

// Metadata relevant for metering purposes
message MeteringMetadata {
    // Count of local activities which have begun an execution attempt during this workflow task,
    // and whose first attempt occurred in some previous task. This is used for metering
    // purposes, and does not affect workflow state.
    //
    // (-- api-linter: core::0141::forbidden-types=disabled
    //     aip.dev/not-precedent: Negative values make no sense to represent. --)
    uint32 nonfirst_local_activity_execution_attempts = 13;
}

// Deprecated. This message is replaced with `Deployment` and `VersioningBehavior`.
// Identifies the version(s) of a worker that processed a task
message WorkerVersionStamp {
    // An opaque whole-worker identifier. Replaces the deprecated `binary_checksum` field when this
    // message is included in requests which previously used that.
    string build_id = 1;

    // If set, the worker is opting in to worker versioning. Otherwise, this is used only as a
    // marker for workflow reset points and the BuildIDs search attribute.
    bool use_versioning = 3;

    // Later, may include bundle id that could be used for WASM and/or JS dynamically loadable bundles.
}

// Identifies the version that a worker is compatible with when polling or identifying itself,
// and whether or not this worker is opting into the build-id based versioning feature. This is
// used by matching to determine which workers ought to receive what tasks.
// Deprecated. Use WorkerDeploymentOptions instead.
message WorkerVersionCapabilities {
    // An opaque whole-worker identifier
    string build_id = 1;

    // If set, the worker is opting in to worker versioning, and wishes to only receive appropriate
    // tasks.
    bool use_versioning = 2;

    // Must be sent if user has set a deployment series name (versioning-3).
    string deployment_series_name = 4;

    // Later, may include info like "I can process WASM and/or JS bundles"
}

// Describes where and how to reset a workflow, used for batch reset currently
// and may be used for single-workflow reset later.
message ResetOptions {
    // Which workflow task to reset to.
    oneof target {
        // Resets to the first workflow task completed or started event.
        google.protobuf.Empty first_workflow_task = 1;
        // Resets to the last workflow task completed or started event.
        google.protobuf.Empty last_workflow_task = 2;
        // The id of a specific `WORKFLOW_TASK_COMPLETED`,`WORKFLOW_TASK_TIMED_OUT`, `WORKFLOW_TASK_FAILED`, or
        // `WORKFLOW_TASK_STARTED` event to reset to.
        // Note that this option doesn't make sense when used as part of a batch request.
        int64 workflow_task_id = 3;
        // Resets to the first workflow task processed by this build id.
        // If the workflow was not processed by the build id, or the workflow task can't be
        // determined, no reset will be performed.
        // Note that by default, this reset is allowed to be to a prior run in a chain of
        // continue-as-new.
        string build_id = 4;
    }

    // Deprecated. Use `options`.
    // Default: RESET_REAPPLY_TYPE_SIGNAL
    temporal.api.enums.v1.ResetReapplyType reset_reapply_type = 10 [deprecated = true];

    // If true, limit the reset to only within the current run. (Applies to build_id targets and
    // possibly others in the future.)
    bool current_run_only = 11;

    // Event types not to be reapplied
    repeated temporal.api.enums.v1.ResetReapplyExcludeType reset_reapply_exclude_types = 12;
}

// Callback to attach to various events in the system, e.g. workflow run completion.
message Callback {
    message Nexus {
        // Callback URL.
        string url = 1;
        // Header to attach to callback request.
        map<string, string> header = 2;
    }

    // Callbacks to be delivered internally within the system.
    // This variant is not settable in the API and will be rejected by the service with an INVALID_ARGUMENT error.
    // The only reason that this is exposed is because callbacks are replicated across clusters via the
    // WorkflowExecutionStarted event, which is defined in the public API.
    message Internal {
        // Opaque internal data.
        bytes data = 1;
    }

    reserved 1; // For a generic callback mechanism to be added later.
    oneof variant {
        Nexus nexus = 2;
        Internal internal = 3;
    }

    // Links associated with the callback. It can be used to link to underlying resources of the
    // callback.
    repeated Link links = 100;
}

// Link can be associated with history events. It might contain information about an external entity
// related to the history event. For example, workflow A makes a Nexus call that starts workflow B:
// in this case, a history event in workflow A could contain a Link to the workflow started event in
// workflow B, and vice-versa.
message Link {
    message WorkflowEvent {
        // EventReference is a direct reference to a history event through the event ID.
        message EventReference {
            int64 event_id = 1;
            temporal.api.enums.v1.EventType event_type = 2;
        }

        // RequestIdReference is a indirect reference to a history event through the request ID.
        message RequestIdReference {
            string request_id = 1;
            temporal.api.enums.v1.EventType event_type = 2;
        }

        string namespace = 1;
        string workflow_id = 2;
        string run_id = 3;

        // Additional information about the workflow event.
        // Eg: the caller workflow can send the history event details that made the Nexus call.
        oneof reference {
            EventReference event_ref = 100;
            RequestIdReference request_id_ref = 101;
        }
    }

    // A link to a built-in batch job.
    // Batch jobs can be used to perform operations on a set of workflows (e.g. terminate, signal, cancel, etc).
    // This link can be put on workflow history events generated by actions taken by a batch job.
    message BatchJob {
        string job_id = 1;
    }

    // A link to an activity.
    message Activity {
        string namespace = 1;
        string activity_id = 2;
        string run_id = 3;
    }

    // A link to a standalone Nexus operation.
    message NexusOperation {
        string namespace = 1;
        string operation_id = 2;
        string run_id = 3;
    }

    oneof variant {
        WorkflowEvent workflow_event = 1;
        BatchJob batch_job = 2;
        Activity activity = 3;
        NexusOperation nexus_operation = 4;
    }
}

// Principal is an authenticated caller identity computed by the server from trusted
// authentication context.
message Principal {
    // Low-cardinality category of the principal (e.g., "jwt", "users").
    string type = 1;
    // Identifier within that category (e.g., sub JWT claim, email address).
    string name = 2;
}

// Priority contains metadata that controls relative ordering of task processing
// when tasks are backed up in a queue. Initially, Priority will be used in
// matching (workflow and activity) task queues. Later it may be used in history
// task queues and in rate limiting decisions.
//
// Priority is attached to workflows and activities. By default, activities
// inherit Priority from the workflow that created them, but may override fields
// when an activity is started or modified.
//
// Despite being named "Priority", this message also contains fields that
// control "fairness" mechanisms.
//
// For all fields, the field not present or equal to zero/empty string means to
// inherit the value from the calling workflow, or if there is no calling
// workflow, then use the default value.
//
// For all fields other than fairness_key, the zero value isn't meaningful so
// there's no confusion between inherit/default and a meaningful value. For
// fairness_key, the empty string will be interpreted as "inherit". This means
// that if a workflow has a non-empty fairness key, you can't override the
// fairness key of its activity to the empty string.
//
// The overall semantics of Priority are:
// 1. First, consider "priority": higher priority (lower number) goes first.
// 2. Then, consider fairness: try to dispatch tasks for different fairness keys
//    in proportion to their weight.
//
// Applications may use any subset of mechanisms that are useful to them and
// leave the other fields to use default values.
//
// Not all queues in the system may support the "full" semantics of all priority
// fields. (Currently only support in matching task queues is planned.)
message Priority {
    // Priority key is a positive integer from 1 to n, where smaller integers
    // correspond to higher priorities (tasks run sooner). In general, tasks in
    // a queue should be processed in close to priority order, although small
    // deviations are possible.
    //
    // The maximum priority value (minimum priority) is determined by server
    // configuration, and defaults to 5.
    //
    // If priority is not present (or zero), then the effective priority will be
    // the default priority, which is calculated by (min+max)/2. With the
    // default max of 5, and min of 1, that comes out to 3.
    int32 priority_key = 1;

    // Fairness key is a short string that's used as a key for a fairness
    // balancing mechanism. It may correspond to a tenant id, or to a fixed
    // string like "high" or "low". The default is the empty string.
    //
    // The fairness mechanism attempts to dispatch tasks for a given key in
    // proportion to its weight. For example, using a thousand distinct tenant
    // ids, each with a weight of 1.0 (the default) will result in each tenant
    // getting a roughly equal share of task dispatch throughput.
    //
    // (Note: this does not imply equal share of worker capacity! Fairness
    // decisions are made based on queue statistics, not
    // current worker load.)
    //
    // As another example, using keys "high" and "low" with weight 9.0 and 1.0
    // respectively will prefer dispatching "high" tasks over "low" tasks at a
    // 9:1 ratio, while allowing either key to use all worker capacity if the
    // other is not present.
    //
    // All fairness mechanisms, including rate limits, are best-effort and
    // probabilistic. The results may not match what a "perfect" algorithm with
    // infinite resources would produce. The more unique keys are used, the less
    // accurate the results will be.
    //
    // Fairness keys are limited to 64 bytes.
    string fairness_key = 2;

    // Fairness weight for a task can come from multiple sources for
    // flexibility. From highest to lowest precedence:
    // 1. Weights for a small set of keys can be overridden in task queue
    //    configuration with an API.
    // 2. It can be attached to the workflow/activity in this field.
    // 3. The default weight of 1.0 will be used.
    //
    // Weight values are clamped to the range [0.001, 1000].
    float fairness_weight = 3;
}

// This is used to send commands to a specific worker or a group of workers.
// Right now, it is used to send commands to a specific worker instance.
// Will be extended to be able to send command to multiple workers.
message WorkerSelector {
    // Options are:
    // - query (will be used as query to ListWorkers, same format as in ListWorkersRequest.query)
    // - task queue (just a shortcut. Same as query=' "TaskQueue"="my-task-queue" ')
    // - etc.
    //   All but 'query' are shortcuts, can be replaced with a query, but it is not convenient.
    // string query = 5;
    // string task_queue = 6;
    // ...
    oneof selector {
        // Worker instance key to which the command should be sent.
        string worker_instance_key = 1;
    }
}

// When starting an execution with a conflict policy that uses an existing execution and there is already an existing
// running execution, OnConflictOptions defines actions to be taken on the existing running execution.
message OnConflictOptions {
    // Attaches the request ID to the running execution.
    bool attach_request_id = 1;
    // Attaches the completion callbacks to the running execution.
    bool attach_completion_callbacks = 2;
    // Attaches the links to the running execution.
    bool attach_links = 3;
}
