Feat: Workflow input JSON schema in trigger preview (#2851)

* feat: add input json schema to workflow version

* feat: add json schema to putworkflow proto

* feat: wire up writes of the json schema

* chore: gen python

* feat: send json schema from the python code

* feat: wiring

* feat: pass json schema into code editor

* feat: pass prop

* fix: clean up validation stuff

* feat: allow zod `input` as optional ts field

* fix: try except logic hack

* fix: rename input -> inputValidator for consistency

* chore: gen api

* fix: improve hack slightly

* chore: changelogs, versions

* feat: zod example

* chore: rework api a bit

* fix: tsc, allow schema to update

* fix: improve loading state

* fix: api cleanup, sqlc cleanup

* fix: initial mount

* chore: lint

* chore: lint

* chore: tsc

* fix: lint

* fix: unwind unneeded change

* [Python] Feat: Default additional metadata (#2876)

* Add doc about autoscaling workers (#2864)

* add doc for autoscaling workers

* oldest also in running stats

* chore(deps): bump google.golang.org/api from 0.262.0 to 0.263.0 (#2869)

Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.262.0 to 0.263.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.262.0...v0.263.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-version: 0.263.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): bump github.com/getsentry/sentry-go from 0.41.0 to 0.42.0 (#2870)

Bumps [github.com/getsentry/sentry-go](https://github.com/getsentry/sentry-go) from 0.41.0 to 0.42.0.
- [Release notes](https://github.com/getsentry/sentry-go/releases)
- [Changelog](https://github.com/getsentry/sentry-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-go/compare/v0.41.0...v0.42.0)

---
updated-dependencies:
- dependency-name: github.com/getsentry/sentry-go
  dependency-version: 0.42.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): bump hatchet-sdk in /examples/python/quickstart (#2871)

Bumps hatchet-sdk from 1.22.10 to 1.22.11.

---
updated-dependencies:
- dependency-name: hatchet-sdk
  dependency-version: 1.22.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* feat: default additional meta

* feat: wiring

* chore: changelog, version

* fix: copy

* feat: add default meta to stubs

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Mohammed Nafees <hello@mnafees.me>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore: migration ver

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Mohammed Nafees <hello@mnafees.me>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
matt
2026-01-29 11:38:25 -05:00
committed by GitHub
parent a8afa07dcf
commit a3fe89ef03
40 changed files with 1736 additions and 653 deletions
@@ -127,6 +127,9 @@ WorkflowVersion:
type: array
items:
$ref: "#/ConcurrencySetting"
inputJsonSchema:
type: object
description: The JSON schema for the workflow input.
required:
- metadata
- version
+1
View File
@@ -94,6 +94,7 @@ message CreateWorkflowVersionRequest {
optional int32 default_priority = 11; // (optional) the default priority for the workflow
repeated Concurrency concurrency_arr = 12; // (optional) the workflow concurrency options
repeated DefaultFilter default_filters = 13; // (optional) the default filters for the workflow
optional bytes input_json_schema = 14; // (optional) the JSON schema for the workflow input
}
+324 -320
View File
@@ -2351,11 +2351,14 @@ type WorkflowVersion struct {
Concurrency *WorkflowConcurrency `json:"concurrency,omitempty"`
// DefaultPriority The default priority of the workflow.
DefaultPriority *int32 `json:"defaultPriority,omitempty"`
Jobs *[]Job `json:"jobs,omitempty"`
Metadata APIResourceMeta `json:"metadata"`
Order int32 `json:"order"`
ScheduleTimeout *string `json:"scheduleTimeout,omitempty"`
DefaultPriority *int32 `json:"defaultPriority,omitempty"`
// InputJsonSchema The JSON schema for the workflow input.
InputJsonSchema *map[string]interface{} `json:"inputJsonSchema,omitempty"`
Jobs *[]Job `json:"jobs,omitempty"`
Metadata APIResourceMeta `json:"metadata"`
Order int32 `json:"order"`
ScheduleTimeout *string `json:"scheduleTimeout,omitempty"`
// Sticky The sticky strategy of the workflow.
Sticky *string `json:"sticky,omitempty"`
@@ -16088,321 +16091,322 @@ func (sh *strictHandler) WorkflowVersionGet(ctx echo.Context, workflow openapi_t
// Base64 encoded, gzipped, json marshaled Swagger object
var swaggerSpec = []string{
"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",
"8yTj8iCJ/c6bTuf56/P/HwAA//9B6YyRazEDAA==",
}
// GetSwagger returns the content of the embedded swagger specification file
@@ -109,6 +109,16 @@ func ToWorkflowVersion(
res.Workflow = ToWorkflowFromSQLC(workflow)
}
if len(version.InputJsonSchema) > 0 {
versionMap := make(map[string]interface{})
err := json.Unmarshal(version.InputJsonSchema, &versionMap)
if err == nil {
res.InputJsonSchema = &versionMap
}
}
triggersResp := gen.WorkflowTriggers{}
if len(crons) > 0 {
@@ -0,0 +1,9 @@
-- +goose Up
-- +goose StatementBegin
ALTER TABLE "WorkflowVersion" ADD COLUMN "inputJsonSchema" JSONB;
-- +goose StatementEnd
-- +goose Down
-- +goose StatementBegin
ALTER TABLE "WorkflowVersion" DROP COLUMN "inputJsonSchema";
-- +goose StatementEnd
@@ -1,8 +1,9 @@
import CopyToClipboard from './copy-to-clipboard';
import { useTheme } from '@/components/hooks/use-theme';
import { cn } from '@/lib/utils';
import Editor, { Monaco } from '@monaco-editor/react';
import Editor, { Monaco, OnMount } from '@monaco-editor/react';
import 'monaco-themes/themes/Pastels on Dark.json';
import { useCallback, useEffect, useId, useRef } from 'react';
interface CodeEditorProps {
code?: string;
@@ -14,6 +15,7 @@ interface CodeEditorProps {
copy?: boolean;
wrapLines?: boolean;
lineNumbers?: boolean;
jsonSchema?: object;
}
export function CodeEditor({
@@ -26,14 +28,76 @@ export function CodeEditor({
copy = true,
wrapLines = true,
lineNumbers = false,
jsonSchema,
}: CodeEditorProps) {
const { theme } = useTheme();
const editorId = useId();
const modelPath = `file:///editor-${editorId.replace(/:/g, '-')}.json`;
const monacoRef = useRef<Monaco | null>(null);
const setEditorTheme = (monaco: Monaco) => {
const hasJsonSchema =
(language === 'json' && jsonSchema && Object.keys(jsonSchema).length > 0) ??
false;
const configureJsonSchema = useCallback(
(monaco: Monaco) => {
if (language !== 'json') {
return;
}
const existingOptions =
monaco.languages.json.jsonDefaults.diagnosticsOptions;
const existingSchemas = existingOptions.schemas || [];
const otherSchemas = existingSchemas.filter(
(s) => !s.fileMatch?.includes(modelPath),
);
const newSchemas = hasJsonSchema
? [
...otherSchemas,
{
uri: `http://hatchet/schema-${editorId}.json`,
fileMatch: [modelPath],
schema: jsonSchema,
},
]
: otherSchemas;
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
validate: true,
enableSchemaRequest: false,
schemas: newSchemas,
});
},
[language, jsonSchema, hasJsonSchema, modelPath, editorId],
);
const handleBeforeMount = (monaco: Monaco) => {
monaco.editor.defineTheme('pastels-on-dark', getMonacoTheme());
monaco.editor.setTheme('pastels-on-dark');
};
const handleMount: OnMount = (_, monaco) => {
monacoRef.current = monaco;
configureJsonSchema(monaco);
};
useEffect(() => {
const monaco = monacoRef.current;
if (!monaco) {
return;
}
configureJsonSchema(monaco);
}, [
jsonSchema,
hasJsonSchema,
language,
modelPath,
editorId,
configureJsonSchema,
]);
const editorTheme = theme === 'dark' ? 'pastels-on-dark' : '';
return (
@@ -44,7 +108,9 @@ export function CodeEditor({
)}
>
<Editor
beforeMount={setEditorTheme}
beforeMount={handleBeforeMount}
onMount={handleMount}
path={hasJsonSchema ? modelPath : undefined}
language={language}
value={code || ''}
onChange={setCode}
@@ -69,6 +135,11 @@ export function CodeEditor({
colorDecorators: false,
hideCursorInOverviewRuler: true,
contextmenu: false,
hover: { enabled: false },
quickSuggestions: hasJsonSchema
? { strings: true, other: true }
: undefined,
suggestOnTriggerCharacters: hasJsonSchema ? true : undefined,
}}
/>
{copy && (
@@ -1823,6 +1823,8 @@ export interface WorkflowVersion {
jobs?: Job[];
workflowConfig?: object;
v1Concurrency?: ConcurrencySetting[];
/** The JSON schema for the workflow input. */
inputJsonSchema?: object;
}
export interface TriggerWorkflowRunRequest {
@@ -11,6 +11,7 @@ import {
DialogTitle,
} from '@/components/v1/ui/dialog';
import { Input } from '@/components/v1/ui/input';
import { Skeleton } from '@/components/v1/ui/skeleton';
import {
Tabs,
TabsContent,
@@ -20,6 +21,7 @@ import {
import { useCurrentTenantId } from '@/hooks/use-tenant';
import api, {
CronWorkflows,
queries,
ScheduledWorkflows,
V1WorkflowRunDetails,
Workflow,
@@ -74,6 +76,13 @@ export function TriggerWorkflowForm({
[],
);
const workflowVersionQuery = useQuery({
...queries.workflows.getVersion(selectedWorkflowId || ''),
enabled: !!selectedWorkflowId,
});
const selectedWorkflow = workflowVersionQuery.data;
const isLoadingWorkflow = workflowVersionQuery.isLoading;
const handleSearchChange = useCallback(
(value: string) => {
setWorkflowSearch(value);
@@ -137,20 +146,17 @@ export function TriggerWorkflowForm({
refetchInterval: 15000,
});
const selectedWorkflow = useMemo(
() => workflowKeys?.rows?.find((w) => w.metadata.id === selectedWorkflowId),
[selectedWorkflowId, workflowKeys],
);
const jsonSchema = selectedWorkflow?.inputJsonSchema;
const triggerNowMutation = useMutation({
mutationKey: ['workflow-run:create', selectedWorkflow?.metadata.id],
mutationFn: async (data: { input: object; addlMeta: object }) => {
if (!selectedWorkflow) {
if (!selectedWorkflow || !selectedWorkflow.workflow) {
return;
}
const res = await api.v1WorkflowRunCreate(tenantId, {
workflowName: selectedWorkflow.name,
workflowName: selectedWorkflow.workflow.name,
input: data.input,
additionalMetadata: data.addlMeta,
});
@@ -180,13 +186,13 @@ export function TriggerWorkflowForm({
addlMeta: object;
scheduledAt: string;
}) => {
if (!selectedWorkflow) {
if (!selectedWorkflow || !selectedWorkflow.workflow) {
return;
}
const res = await api.scheduledWorkflowRunCreate(
tenantId,
selectedWorkflow?.name,
selectedWorkflow.workflow.name,
{
input: data.input,
additionalMetadata: data.addlMeta,
@@ -223,13 +229,13 @@ export function TriggerWorkflowForm({
cron: string;
cronName: string;
}) => {
if (!selectedWorkflow) {
if (!selectedWorkflow || !selectedWorkflow.workflow) {
return;
}
const res = await api.cronWorkflowTriggerCreate(
tenantId,
selectedWorkflow?.name,
selectedWorkflow.workflow.name,
{
input: data.input,
additionalMetadata: data.addlMeta,
@@ -336,20 +342,36 @@ export function TriggerWorkflowForm({
: 'No workflows found'
}
/>
<div className="font-bold">Input</div>
<CodeEditor
code={input || '{}'}
setCode={setInput}
language="json"
height="180px"
/>
<div className="font-bold">
Input
{isLoadingWorkflow && (
<span className="ml-2 text-sm font-normal text-muted-foreground">
(Loading schema...)
</span>
)}
</div>
{isLoadingWorkflow ? (
<Skeleton className="h-[180px] w-full" />
) : (
<CodeEditor
code={input || '{}'}
setCode={setInput}
language="json"
height="180px"
jsonSchema={jsonSchema}
/>
)}
<div className="font-bold">Additional Metadata</div>
<CodeEditor
code={addlMeta || '{}'}
setCode={setAddlMeta}
height="90px"
language="json"
/>
{isLoadingWorkflow ? (
<Skeleton className="h-[90px] w-full" />
) : (
<CodeEditor
code={addlMeta || '{}'}
setCode={setAddlMeta}
height="90px"
language="json"
/>
)}
<div>
<div className="mb-2 font-bold">Timing</div>
<Tabs
@@ -472,7 +494,8 @@ export function TriggerWorkflowForm({
triggerNowMutation.isPending ||
triggerScheduleMutation.isPending ||
triggerCronMutation.isPending ||
!selectedWorkflow
!selectedWorkflow ||
isLoadingWorkflow
}
onClick={handleSubmit}
>
+1
View File
@@ -697,6 +697,7 @@ func getCreateWorkflowOpts(req *contracts.CreateWorkflowVersionRequest) (*v1.Cre
Sticky: sticky,
DefaultPriority: req.DefaultPriority,
DefaultFilters: defaultFilters,
InputJsonSchema: req.InputJsonSchema,
}, nil
}
+225 -213
View File
@@ -710,13 +710,14 @@ type CreateWorkflowVersionRequest struct {
CronTriggers []string `protobuf:"bytes,5,rep,name=cron_triggers,json=cronTriggers,proto3" json:"cron_triggers,omitempty"` // (optional) cron triggers for the workflow
Tasks []*CreateTaskOpts `protobuf:"bytes,6,rep,name=tasks,proto3" json:"tasks,omitempty"` // (required) the workflow jobs
// Deprecated: use concurrency_arr instead
Concurrency *Concurrency `protobuf:"bytes,7,opt,name=concurrency,proto3" json:"concurrency,omitempty"` // (optional) the workflow concurrency options
CronInput *string `protobuf:"bytes,8,opt,name=cron_input,json=cronInput,proto3,oneof" json:"cron_input,omitempty"` // (optional) the input for the cron trigger
OnFailureTask *CreateTaskOpts `protobuf:"bytes,9,opt,name=on_failure_task,json=onFailureTask,proto3,oneof" json:"on_failure_task,omitempty"` // (optional) the job to run on failure
Sticky *StickyStrategy `protobuf:"varint,10,opt,name=sticky,proto3,enum=v1.StickyStrategy,oneof" json:"sticky,omitempty"` // (optional) the sticky strategy for assigning steps to workers
DefaultPriority *int32 `protobuf:"varint,11,opt,name=default_priority,json=defaultPriority,proto3,oneof" json:"default_priority,omitempty"` // (optional) the default priority for the workflow
ConcurrencyArr []*Concurrency `protobuf:"bytes,12,rep,name=concurrency_arr,json=concurrencyArr,proto3" json:"concurrency_arr,omitempty"` // (optional) the workflow concurrency options
DefaultFilters []*DefaultFilter `protobuf:"bytes,13,rep,name=default_filters,json=defaultFilters,proto3" json:"default_filters,omitempty"` // (optional) the default filters for the workflow
Concurrency *Concurrency `protobuf:"bytes,7,opt,name=concurrency,proto3" json:"concurrency,omitempty"` // (optional) the workflow concurrency options
CronInput *string `protobuf:"bytes,8,opt,name=cron_input,json=cronInput,proto3,oneof" json:"cron_input,omitempty"` // (optional) the input for the cron trigger
OnFailureTask *CreateTaskOpts `protobuf:"bytes,9,opt,name=on_failure_task,json=onFailureTask,proto3,oneof" json:"on_failure_task,omitempty"` // (optional) the job to run on failure
Sticky *StickyStrategy `protobuf:"varint,10,opt,name=sticky,proto3,enum=v1.StickyStrategy,oneof" json:"sticky,omitempty"` // (optional) the sticky strategy for assigning steps to workers
DefaultPriority *int32 `protobuf:"varint,11,opt,name=default_priority,json=defaultPriority,proto3,oneof" json:"default_priority,omitempty"` // (optional) the default priority for the workflow
ConcurrencyArr []*Concurrency `protobuf:"bytes,12,rep,name=concurrency_arr,json=concurrencyArr,proto3" json:"concurrency_arr,omitempty"` // (optional) the workflow concurrency options
DefaultFilters []*DefaultFilter `protobuf:"bytes,13,rep,name=default_filters,json=defaultFilters,proto3" json:"default_filters,omitempty"` // (optional) the default filters for the workflow
InputJsonSchema []byte `protobuf:"bytes,14,opt,name=input_json_schema,json=inputJsonSchema,proto3,oneof" json:"input_json_schema,omitempty"` // (optional) the JSON schema for the workflow input
}
func (x *CreateWorkflowVersionRequest) Reset() {
@@ -842,6 +843,13 @@ func (x *CreateWorkflowVersionRequest) GetDefaultFilters() []*DefaultFilter {
return nil
}
func (x *CreateWorkflowVersionRequest) GetInputJsonSchema() []byte {
if x != nil {
return x.InputJsonSchema
}
return nil
}
type DefaultFilter struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -1611,7 +1619,7 @@ var file_v1_workflows_proto_rawDesc = []byte{
0x3d, 0x0a, 0x1a, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c,
0x6f, 0x77, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a,
0x0b, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x22, 0x96,
0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x22, 0xdd,
0x05, 0x0a, 0x1c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f,
0x77, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
@@ -1649,212 +1657,216 @@ var file_v1_workflows_proto_rawDesc = []byte{
0x75, 0x6c, 0x74, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x11, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x46, 0x69,
0x6c, 0x74, 0x65, 0x72, 0x52, 0x0e, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x46, 0x69, 0x6c,
0x74, 0x65, 0x72, 0x73, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x63, 0x72, 0x6f, 0x6e, 0x5f, 0x69, 0x6e,
0x70, 0x75, 0x74, 0x42, 0x12, 0x0a, 0x10, 0x5f, 0x6f, 0x6e, 0x5f, 0x66, 0x61, 0x69, 0x6c, 0x75,
0x72, 0x65, 0x5f, 0x74, 0x61, 0x73, 0x6b, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x74, 0x69, 0x63,
0x6b, 0x79, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x70,
0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x70, 0x0a, 0x0d, 0x44, 0x65, 0x66, 0x61, 0x75,
0x6c, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x72,
0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x78,
0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x1d,
0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x48,
0x00, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x88, 0x01, 0x01, 0x42, 0x0a, 0x0a,
0x08, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xb7, 0x01, 0x0a, 0x0b, 0x43, 0x6f,
0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x78, 0x70,
0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65,
0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x08, 0x6d, 0x61, 0x78,
0x5f, 0x72, 0x75, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x07, 0x6d,
0x61, 0x78, 0x52, 0x75, 0x6e, 0x73, 0x88, 0x01, 0x01, 0x12, 0x48, 0x0a, 0x0e, 0x6c, 0x69, 0x6d,
0x69, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28,
0x0e, 0x32, 0x1c, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e,
0x63, 0x79, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x48,
0x01, 0x52, 0x0d, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79,
0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x75, 0x6e, 0x73,
0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74,
0x65, 0x67, 0x79, 0x22, 0x96, 0x02, 0x0a, 0x13, 0x44, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x57,
0x6f, 0x72, 0x6b, 0x65, 0x72, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x1f, 0x0a, 0x08, 0x73,
0x74, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52,
0x08, 0x73, 0x74, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08,
0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x48, 0x01,
0x52, 0x08, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a,
0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x48,
0x02, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x88, 0x01, 0x01, 0x12, 0x3e,
0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01,
0x28, 0x0e, 0x32, 0x19, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x4c, 0x61,
0x62, 0x65, 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x48, 0x03, 0x52,
0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x88, 0x01, 0x01, 0x12, 0x1b,
0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x48, 0x04,
0x52, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f,
0x73, 0x74, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x69, 0x6e, 0x74,
0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72,
0x65, 0x64, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f,
0x72, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0xda, 0x05, 0x0a,
0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x4f, 0x70, 0x74, 0x73, 0x12,
0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x49, 0x64,
0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65,
0x6f, 0x75, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f,
0x75, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01,
0x28, 0x09, 0x52, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61,
0x72, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x72,
0x65, 0x6e, 0x74, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18,
0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x38,
0x0a, 0x0b, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x07, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54,
0x61, 0x73, 0x6b, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x0a, 0x72, 0x61,
0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x49, 0x0a, 0x0d, 0x77, 0x6f, 0x72, 0x6b,
0x65, 0x72, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x24, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x4f,
0x70, 0x74, 0x73, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73,
0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x4c, 0x61, 0x62,
0x65, 0x6c, 0x73, 0x12, 0x2a, 0x0a, 0x0e, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x5f, 0x66,
0x61, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x02, 0x48, 0x00, 0x52, 0x0d, 0x62,
0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x88, 0x01, 0x01, 0x12,
0x33, 0x0a, 0x13, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x73,
0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x48, 0x01, 0x52, 0x11,
0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x4d, 0x61, 0x78, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64,
0x73, 0x88, 0x01, 0x01, 0x12, 0x31, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65,
0x6e, 0x63, 0x79, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x31, 0x2e, 0x43,
0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63,
0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x37, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69,
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x76, 0x31,
0x2e, 0x54, 0x61, 0x73, 0x6b, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x48,
0x02, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x88, 0x01, 0x01,
0x12, 0x2e, 0x0a, 0x10, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x74, 0x69, 0x6d,
0x65, 0x6f, 0x75, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x0f, 0x73, 0x63,
0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x88, 0x01, 0x01,
0x1a, 0x58, 0x0a, 0x11, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73,
0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x69,
0x72, 0x65, 0x64, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52,
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x62,
0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x5f, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x42, 0x16, 0x0a,
0x14, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x65,
0x63, 0x6f, 0x6e, 0x64, 0x73, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74,
0x69, 0x6f, 0x6e, 0x73, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c,
0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0xb8, 0x02, 0x0a, 0x13, 0x43, 0x72,
0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69,
0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
0x6b, 0x65, 0x79, 0x12, 0x19, 0x0a, 0x05, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01,
0x28, 0x05, 0x48, 0x00, 0x52, 0x05, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x88, 0x01, 0x01, 0x12, 0x1e,
0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
0x48, 0x01, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x45, 0x78, 0x70, 0x72, 0x88, 0x01, 0x01, 0x12, 0x22,
0x0a, 0x0a, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x04, 0x20, 0x01,
0x28, 0x09, 0x48, 0x02, 0x52, 0x09, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x45, 0x78, 0x70, 0x72, 0x88,
0x01, 0x01, 0x12, 0x2f, 0x0a, 0x11, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x73, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52,
0x0f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x45, 0x78, 0x70, 0x72,
0x88, 0x01, 0x01, 0x12, 0x36, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18,
0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x61, 0x74, 0x65, 0x4c,
0x69, 0x6d, 0x69, 0x74, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x04, 0x52, 0x08,
0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f,
0x75, 0x6e, 0x69, 0x74, 0x73, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x65, 0x78,
0x70, 0x72, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x5f, 0x65, 0x78, 0x70,
0x72, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x73, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x64, 0x75, 0x72, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x22, 0x50, 0x0a, 0x1d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f,
0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f,
0x77, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x77, 0x6f, 0x72, 0x6b,
0x66, 0x6c, 0x6f, 0x77, 0x49, 0x64, 0x22, 0x37, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6e,
0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f,
0x0a, 0x0b, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x22,
0xc5, 0x01, 0x0a, 0x0d, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x75, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69,
0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01,
0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x75, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75,
0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x19, 0x0a, 0x05, 0x65, 0x72, 0x72,
0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f,
0x72, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x04,
0x20, 0x01, 0x28, 0x0c, 0x48, 0x01, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x88, 0x01,
0x01, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x69, 0x64,
0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65,
0x49, 0x64, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x42, 0x09, 0x0a, 0x07,
0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0xaf, 0x02, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x52,
0x75, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x25, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x75, 0x6e,
0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x44,
0x0a, 0x09, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x72, 0x75, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x27, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6e, 0x44, 0x65, 0x74,
0x61, 0x69, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x73,
0x6b, 0x52, 0x75, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x74, 0x61, 0x73, 0x6b,
0x52, 0x75, 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x6f, 0x6e, 0x65, 0x18, 0x04, 0x20, 0x01,
0x28, 0x08, 0x52, 0x04, 0x64, 0x6f, 0x6e, 0x65, 0x12, 0x2f, 0x0a, 0x13, 0x61, 0x64, 0x64, 0x69,
0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18,
0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x12, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61,
0x6c, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x4e, 0x0a, 0x0d, 0x54, 0x61, 0x73,
0x6b, 0x52, 0x75, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65,
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x27, 0x0a, 0x05,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x76, 0x31,
0x2e, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x75, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x05,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x2a, 0x24, 0x0a, 0x0e, 0x53, 0x74, 0x69,
0x63, 0x6b, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x08, 0x0a, 0x04, 0x53,
0x4f, 0x46, 0x54, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x41, 0x52, 0x44, 0x10, 0x01, 0x2a,
0x5d, 0x0a, 0x11, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x44, 0x75, 0x72, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x45, 0x43, 0x4f, 0x4e, 0x44, 0x10, 0x00,
0x12, 0x0a, 0x0a, 0x06, 0x4d, 0x49, 0x4e, 0x55, 0x54, 0x45, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04,
0x48, 0x4f, 0x55, 0x52, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x44, 0x41, 0x59, 0x10, 0x03, 0x12,
0x08, 0x0a, 0x04, 0x57, 0x45, 0x45, 0x4b, 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x4d, 0x4f, 0x4e,
0x54, 0x48, 0x10, 0x05, 0x12, 0x08, 0x0a, 0x04, 0x59, 0x45, 0x41, 0x52, 0x10, 0x06, 0x2a, 0x4e,
0x0a, 0x09, 0x52, 0x75, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0a, 0x0a, 0x06, 0x51,
0x55, 0x45, 0x55, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x55, 0x4e, 0x4e, 0x49,
0x4e, 0x47, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45,
0x44, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x03, 0x12,
0x0d, 0x0a, 0x09, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x4c, 0x45, 0x44, 0x10, 0x04, 0x2a, 0x7f,
0x0a, 0x18, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x4c, 0x69, 0x6d,
0x69, 0x74, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x41,
0x4e, 0x43, 0x45, 0x4c, 0x5f, 0x49, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x45, 0x53, 0x53,
0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x44, 0x52, 0x4f, 0x50, 0x5f, 0x4e, 0x45, 0x57, 0x45, 0x53,
0x54, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x51, 0x55, 0x45, 0x55, 0x45, 0x5f, 0x4e, 0x45, 0x57,
0x45, 0x53, 0x54, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x52,
0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x52, 0x4f, 0x42, 0x49, 0x4e, 0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d,
0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x5f, 0x4e, 0x45, 0x57, 0x45, 0x53, 0x54, 0x10, 0x04, 0x2a,
0x85, 0x01, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x43,
0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x51, 0x55,
0x41, 0x4c, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x54, 0x5f, 0x45, 0x51, 0x55, 0x41,
0x4c, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x47, 0x52, 0x45, 0x41, 0x54, 0x45, 0x52, 0x5f, 0x54,
0x48, 0x41, 0x4e, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x47, 0x52, 0x45, 0x41, 0x54, 0x45, 0x52,
0x5f, 0x54, 0x48, 0x41, 0x4e, 0x5f, 0x4f, 0x52, 0x5f, 0x45, 0x51, 0x55, 0x41, 0x4c, 0x10, 0x03,
0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x48, 0x41, 0x4e, 0x10, 0x04, 0x12,
0x16, 0x0a, 0x12, 0x4c, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x48, 0x41, 0x4e, 0x5f, 0x4f, 0x52, 0x5f,
0x45, 0x51, 0x55, 0x41, 0x4c, 0x10, 0x05, 0x32, 0xfd, 0x02, 0x0a, 0x0c, 0x41, 0x64, 0x6d, 0x69,
0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x52, 0x0a, 0x0b, 0x50, 0x75, 0x74, 0x57,
0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x20, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65,
0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x56, 0x65, 0x72, 0x73, 0x69,
0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x31, 0x2e, 0x43,
0x74, 0x65, 0x72, 0x73, 0x12, 0x2f, 0x0a, 0x11, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x6a, 0x73,
0x6f, 0x6e, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x48,
0x04, 0x52, 0x0f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x4a, 0x73, 0x6f, 0x6e, 0x53, 0x63, 0x68, 0x65,
0x6d, 0x61, 0x88, 0x01, 0x01, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x63, 0x72, 0x6f, 0x6e, 0x5f, 0x69,
0x6e, 0x70, 0x75, 0x74, 0x42, 0x12, 0x0a, 0x10, 0x5f, 0x6f, 0x6e, 0x5f, 0x66, 0x61, 0x69, 0x6c,
0x75, 0x72, 0x65, 0x5f, 0x74, 0x61, 0x73, 0x6b, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x74, 0x69,
0x63, 0x6b, 0x79, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f,
0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x69, 0x6e, 0x70,
0x75, 0x74, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x70,
0x0a, 0x0d, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12,
0x1e, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12,
0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61,
0x64, 0x88, 0x01, 0x01, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
0x22, 0xb7, 0x01, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79,
0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
0x12, 0x1e, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x75, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01,
0x28, 0x05, 0x48, 0x00, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x52, 0x75, 0x6e, 0x73, 0x88, 0x01, 0x01,
0x12, 0x48, 0x0a, 0x0e, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65,
0x67, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f,
0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x53, 0x74,
0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x48, 0x01, 0x52, 0x0d, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x53,
0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x6d,
0x61, 0x78, 0x5f, 0x72, 0x75, 0x6e, 0x73, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x6c, 0x69, 0x6d, 0x69,
0x74, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x22, 0x96, 0x02, 0x0a, 0x13, 0x44,
0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x4c, 0x61, 0x62, 0x65,
0x6c, 0x73, 0x12, 0x1f, 0x0a, 0x08, 0x73, 0x74, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, 0x73, 0x74, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65,
0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18,
0x02, 0x20, 0x01, 0x28, 0x05, 0x48, 0x01, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75,
0x65, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64,
0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x48, 0x02, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72,
0x65, 0x64, 0x88, 0x01, 0x01, 0x12, 0x3e, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61,
0x74, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x76, 0x31, 0x2e, 0x57,
0x6f, 0x72, 0x6b, 0x65, 0x72, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72,
0x61, 0x74, 0x6f, 0x72, 0x48, 0x03, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74,
0x6f, 0x72, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18,
0x05, 0x20, 0x01, 0x28, 0x05, 0x48, 0x04, 0x52, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x88,
0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x73, 0x74, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42,
0x0b, 0x0a, 0x09, 0x5f, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x0b, 0x0a, 0x09,
0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x63, 0x6f,
0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x77, 0x65, 0x69,
0x67, 0x68, 0x74, 0x22, 0xda, 0x05, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61,
0x73, 0x6b, 0x4f, 0x70, 0x74, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x61, 0x64, 0x61, 0x62,
0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x61,
0x64, 0x61, 0x62, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12,
0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x6e, 0x70,
0x75, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74,
0x73, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03,
0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x72,
0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x72, 0x65,
0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x0b, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x6c, 0x69,
0x6d, 0x69, 0x74, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x76, 0x31, 0x2e,
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69,
0x6d, 0x69, 0x74, 0x52, 0x0a, 0x72, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x12,
0x49, 0x0a, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73,
0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61,
0x74, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x4f, 0x70, 0x74, 0x73, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x65,
0x72, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x77, 0x6f,
0x72, 0x6b, 0x65, 0x72, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x2a, 0x0a, 0x0e, 0x62, 0x61,
0x63, 0x6b, 0x6f, 0x66, 0x66, 0x5f, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x09, 0x20, 0x01,
0x28, 0x02, 0x48, 0x00, 0x52, 0x0d, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x46, 0x61, 0x63,
0x74, 0x6f, 0x72, 0x88, 0x01, 0x01, 0x12, 0x33, 0x0a, 0x13, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66,
0x66, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x0a, 0x20,
0x01, 0x28, 0x05, 0x48, 0x01, 0x52, 0x11, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x4d, 0x61,
0x78, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x88, 0x01, 0x01, 0x12, 0x31, 0x0a, 0x0b, 0x63,
0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x0f, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63,
0x79, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x37,
0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0c, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x12, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x43, 0x6f, 0x6e, 0x64,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x48, 0x02, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74,
0x69, 0x6f, 0x6e, 0x73, 0x88, 0x01, 0x01, 0x12, 0x2e, 0x0a, 0x10, 0x73, 0x63, 0x68, 0x65, 0x64,
0x75, 0x6c, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28,
0x09, 0x48, 0x03, 0x52, 0x0f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x54, 0x69, 0x6d,
0x65, 0x6f, 0x75, 0x74, 0x88, 0x01, 0x01, 0x1a, 0x58, 0x0a, 0x11, 0x57, 0x6f, 0x72, 0x6b, 0x65,
0x72, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d,
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e,
0x76, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72,
0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
0x01, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x5f, 0x66, 0x61,
0x63, 0x74, 0x6f, 0x72, 0x42, 0x16, 0x0a, 0x14, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66,
0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x42, 0x0d, 0x0a, 0x0b,
0x5f, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x13, 0x0a, 0x11, 0x5f,
0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74,
0x22, 0xb8, 0x02, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x52,
0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x19, 0x0a, 0x05, 0x75, 0x6e,
0x69, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x05, 0x75, 0x6e, 0x69,
0x74, 0x73, 0x88, 0x01, 0x01, 0x12, 0x1e, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x65, 0x78, 0x70,
0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x45, 0x78,
0x70, 0x72, 0x88, 0x01, 0x01, 0x12, 0x22, 0x0a, 0x0a, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x5f, 0x65,
0x78, 0x70, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x09, 0x75, 0x6e, 0x69,
0x74, 0x73, 0x45, 0x78, 0x70, 0x72, 0x88, 0x01, 0x01, 0x12, 0x2f, 0x0a, 0x11, 0x6c, 0x69, 0x6d,
0x69, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x05,
0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x0f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x56, 0x61, 0x6c,
0x75, 0x65, 0x73, 0x45, 0x78, 0x70, 0x72, 0x88, 0x01, 0x01, 0x12, 0x36, 0x0a, 0x08, 0x64, 0x75,
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x76,
0x31, 0x2e, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x44, 0x75, 0x72, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x48, 0x04, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x88,
0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x42, 0x0b, 0x0a, 0x09,
0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x75, 0x6e,
0x69, 0x74, 0x73, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x6c, 0x69, 0x6d,
0x69, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x42, 0x0b,
0x0a, 0x09, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x50, 0x0a, 0x1d, 0x43,
0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x56, 0x65, 0x72,
0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0b,
0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x12, 0x16, 0x2e, 0x76, 0x31,
0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x54,
0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0b,
0x52, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x12, 0x16, 0x2e, 0x76, 0x31,
0x2e, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x54,
0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x12,
0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52,
0x75, 0x6e, 0x12, 0x1d, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57,
0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x1e, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x6f,
0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x44, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69,
0x6c, 0x73, 0x12, 0x18, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6e, 0x44, 0x65,
0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x76,
0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x42, 0x5a, 0x40, 0x67, 0x69, 0x74, 0x68, 0x75,
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x74, 0x63, 0x68, 0x65, 0x74, 0x2d, 0x64, 0x65,
0x76, 0x2f, 0x68, 0x61, 0x74, 0x63, 0x68, 0x65, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
0x61, 0x6c, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x68, 0x61, 0x72,
0x65, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x33,
0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02,
0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x0b,
0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x49, 0x64, 0x22, 0x37, 0x0a,
0x14, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61,
0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65,
0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x22, 0xc5, 0x01, 0x0a, 0x0d, 0x54, 0x61, 0x73, 0x6b, 0x52,
0x75, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x78, 0x74, 0x65,
0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65,
0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x73, 0x74, 0x61,
0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x76, 0x31, 0x2e, 0x52,
0x75, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
0x12, 0x19, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48,
0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x6f,
0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x01, 0x52, 0x06, 0x6f,
0x75, 0x74, 0x70, 0x75, 0x74, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x61, 0x64,
0x61, 0x62, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72,
0x65, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x49, 0x64, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x65, 0x72,
0x72, 0x6f, 0x72, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0xaf,
0x02, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75,
0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x25,
0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d,
0x2e, 0x76, 0x31, 0x2e, 0x52, 0x75, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73,
0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x44, 0x0a, 0x09, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x72, 0x75,
0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65,
0x74, 0x52, 0x75, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x75, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72,
0x79, 0x52, 0x08, 0x74, 0x61, 0x73, 0x6b, 0x52, 0x75, 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x64,
0x6f, 0x6e, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x64, 0x6f, 0x6e, 0x65, 0x12,
0x2f, 0x0a, 0x13, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x6d, 0x65,
0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x12, 0x61, 0x64,
0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
0x1a, 0x4e, 0x0a, 0x0d, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x75, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72,
0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
0x6b, 0x65, 0x79, 0x12, 0x27, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x11, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x75, 0x6e, 0x44,
0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
0x2a, 0x24, 0x0a, 0x0e, 0x53, 0x74, 0x69, 0x63, 0x6b, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65,
0x67, 0x79, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x4f, 0x46, 0x54, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04,
0x48, 0x41, 0x52, 0x44, 0x10, 0x01, 0x2a, 0x5d, 0x0a, 0x11, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69,
0x6d, 0x69, 0x74, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x0a, 0x06, 0x53,
0x45, 0x43, 0x4f, 0x4e, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4d, 0x49, 0x4e, 0x55, 0x54,
0x45, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x4f, 0x55, 0x52, 0x10, 0x02, 0x12, 0x07, 0x0a,
0x03, 0x44, 0x41, 0x59, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x57, 0x45, 0x45, 0x4b, 0x10, 0x04,
0x12, 0x09, 0x0a, 0x05, 0x4d, 0x4f, 0x4e, 0x54, 0x48, 0x10, 0x05, 0x12, 0x08, 0x0a, 0x04, 0x59,
0x45, 0x41, 0x52, 0x10, 0x06, 0x2a, 0x4e, 0x0a, 0x09, 0x52, 0x75, 0x6e, 0x53, 0x74, 0x61, 0x74,
0x75, 0x73, 0x12, 0x0a, 0x0a, 0x06, 0x51, 0x55, 0x45, 0x55, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b,
0x0a, 0x07, 0x52, 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x43,
0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41,
0x49, 0x4c, 0x45, 0x44, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c,
0x4c, 0x45, 0x44, 0x10, 0x04, 0x2a, 0x7f, 0x0a, 0x18, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72,
0x65, 0x6e, 0x63, 0x79, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67,
0x79, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x5f, 0x49, 0x4e, 0x5f, 0x50,
0x52, 0x4f, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x44, 0x52, 0x4f,
0x50, 0x5f, 0x4e, 0x45, 0x57, 0x45, 0x53, 0x54, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x51, 0x55,
0x45, 0x55, 0x45, 0x5f, 0x4e, 0x45, 0x57, 0x45, 0x53, 0x54, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11,
0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x52, 0x4f, 0x42, 0x49,
0x4e, 0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x5f, 0x4e, 0x45,
0x57, 0x45, 0x53, 0x54, 0x10, 0x04, 0x2a, 0x85, 0x01, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x65,
0x72, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72,
0x12, 0x09, 0x0a, 0x05, 0x45, 0x51, 0x55, 0x41, 0x4c, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4e,
0x4f, 0x54, 0x5f, 0x45, 0x51, 0x55, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x47, 0x52,
0x45, 0x41, 0x54, 0x45, 0x52, 0x5f, 0x54, 0x48, 0x41, 0x4e, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15,
0x47, 0x52, 0x45, 0x41, 0x54, 0x45, 0x52, 0x5f, 0x54, 0x48, 0x41, 0x4e, 0x5f, 0x4f, 0x52, 0x5f,
0x45, 0x51, 0x55, 0x41, 0x4c, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x45, 0x53, 0x53, 0x5f,
0x54, 0x48, 0x41, 0x4e, 0x10, 0x04, 0x12, 0x16, 0x0a, 0x12, 0x4c, 0x45, 0x53, 0x53, 0x5f, 0x54,
0x48, 0x41, 0x4e, 0x5f, 0x4f, 0x52, 0x5f, 0x45, 0x51, 0x55, 0x41, 0x4c, 0x10, 0x05, 0x32, 0xfd,
0x02, 0x0a, 0x0c, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12,
0x52, 0x0a, 0x0b, 0x50, 0x75, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x20,
0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c,
0x6f, 0x77, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x21, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b,
0x66, 0x6c, 0x6f, 0x77, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x54, 0x61, 0x73,
0x6b, 0x73, 0x12, 0x16, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x54, 0x61,
0x73, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x76, 0x31, 0x2e,
0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x54, 0x61, 0x73,
0x6b, 0x73, 0x12, 0x16, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x54, 0x61,
0x73, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x76, 0x31, 0x2e,
0x52, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x12, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x6f,
0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x75, 0x6e, 0x12, 0x1d, 0x2e, 0x76, 0x31, 0x2e, 0x54,
0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x75,
0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72,
0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x75, 0x6e,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x52,
0x75, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x18, 0x2e, 0x76, 0x31, 0x2e, 0x47,
0x65, 0x74, 0x52, 0x75, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6e, 0x44,
0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x42,
0x5a, 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x74,
0x63, 0x68, 0x65, 0x74, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x68, 0x61, 0x74, 0x63, 0x68, 0x65, 0x74,
0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
0x65, 0x73, 0x2f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f,
0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
+8 -5
View File
@@ -2348,11 +2348,14 @@ type WorkflowVersion struct {
Concurrency *WorkflowConcurrency `json:"concurrency,omitempty"`
// DefaultPriority The default priority of the workflow.
DefaultPriority *int32 `json:"defaultPriority,omitempty"`
Jobs *[]Job `json:"jobs,omitempty"`
Metadata APIResourceMeta `json:"metadata"`
Order int32 `json:"order"`
ScheduleTimeout *string `json:"scheduleTimeout,omitempty"`
DefaultPriority *int32 `json:"defaultPriority,omitempty"`
// InputJsonSchema The JSON schema for the workflow input.
InputJsonSchema *map[string]interface{} `json:"inputJsonSchema,omitempty"`
Jobs *[]Job `json:"jobs,omitempty"`
Metadata APIResourceMeta `json:"metadata"`
Order int32 `json:"order"`
ScheduleTimeout *string `json:"scheduleTimeout,omitempty"`
// Sticky The sticky strategy of the workflow.
Sticky *string `json:"sticky,omitempty"`
+1
View File
@@ -3703,4 +3703,5 @@ type WorkflowVersion struct {
Kind WorkflowKind `json:"kind"`
DefaultPriority pgtype.Int4 `json:"defaultPriority"`
CreateWorkflowVersionOpts []byte `json:"createWorkflowVersionOpts"`
InputJsonSchema []byte `json:"inputJsonSchema"`
}
+4 -2
View File
@@ -120,7 +120,8 @@ INSERT INTO "WorkflowVersion" (
"sticky",
"kind",
"defaultPriority",
"createWorkflowVersionOpts"
"createWorkflowVersionOpts",
"inputJsonSchema"
) VALUES (
@id::uuid,
coalesce(sqlc.narg('createdAt')::timestamp, CURRENT_TIMESTAMP),
@@ -134,7 +135,8 @@ INSERT INTO "WorkflowVersion" (
sqlc.narg('sticky')::"StickyStrategy",
coalesce(sqlc.narg('kind')::"WorkflowKind", 'DAG'),
sqlc.narg('defaultPriority') :: integer,
sqlc.narg('createWorkflowVersionOpts')::jsonb
sqlc.narg('createWorkflowVersionOpts')::jsonb,
sqlc.narg('inputJsonSchema')::jsonb
) RETURNING *;
-- name: CreateJob :one
+14 -6
View File
@@ -869,7 +869,8 @@ INSERT INTO "WorkflowVersion" (
"sticky",
"kind",
"defaultPriority",
"createWorkflowVersionOpts"
"createWorkflowVersionOpts",
"inputJsonSchema"
) VALUES (
$1::uuid,
coalesce($2::timestamp, CURRENT_TIMESTAMP),
@@ -883,8 +884,9 @@ INSERT INTO "WorkflowVersion" (
$8::"StickyStrategy",
coalesce($9::"WorkflowKind", 'DAG'),
$10 :: integer,
$11::jsonb
) RETURNING id, "createdAt", "updatedAt", "deletedAt", version, "order", "workflowId", checksum, "scheduleTimeout", "onFailureJobId", sticky, kind, "defaultPriority", "createWorkflowVersionOpts"
$11::jsonb,
$12::jsonb
) RETURNING id, "createdAt", "updatedAt", "deletedAt", version, "order", "workflowId", checksum, "scheduleTimeout", "onFailureJobId", sticky, kind, "defaultPriority", "createWorkflowVersionOpts", "inputJsonSchema"
`
type CreateWorkflowVersionParams struct {
@@ -899,6 +901,7 @@ type CreateWorkflowVersionParams struct {
Kind NullWorkflowKind `json:"kind"`
DefaultPriority pgtype.Int4 `json:"defaultPriority"`
CreateWorkflowVersionOpts []byte `json:"createWorkflowVersionOpts"`
InputJsonSchema []byte `json:"inputJsonSchema"`
}
func (q *Queries) CreateWorkflowVersion(ctx context.Context, db DBTX, arg CreateWorkflowVersionParams) (*WorkflowVersion, error) {
@@ -914,6 +917,7 @@ func (q *Queries) CreateWorkflowVersion(ctx context.Context, db DBTX, arg Create
arg.Kind,
arg.DefaultPriority,
arg.CreateWorkflowVersionOpts,
arg.InputJsonSchema,
)
var i WorkflowVersion
err := row.Scan(
@@ -931,6 +935,7 @@ func (q *Queries) CreateWorkflowVersion(ctx context.Context, db DBTX, arg Create
&i.Kind,
&i.DefaultPriority,
&i.CreateWorkflowVersionOpts,
&i.InputJsonSchema,
)
return &i, err
}
@@ -1170,7 +1175,7 @@ func (q *Queries) GetWorkflowShape(ctx context.Context, db DBTX, workflowversion
const getWorkflowVersionById = `-- name: GetWorkflowVersionById :one
SELECT
wv.id, wv."createdAt", wv."updatedAt", wv."deletedAt", wv.version, wv."order", wv."workflowId", wv.checksum, wv."scheduleTimeout", wv."onFailureJobId", wv.sticky, wv.kind, wv."defaultPriority", wv."createWorkflowVersionOpts",
wv.id, wv."createdAt", wv."updatedAt", wv."deletedAt", wv.version, wv."order", wv."workflowId", wv.checksum, wv."scheduleTimeout", wv."onFailureJobId", wv.sticky, wv.kind, wv."defaultPriority", wv."createWorkflowVersionOpts", wv."inputJsonSchema",
w.id, w."createdAt", w."updatedAt", w."deletedAt", w."tenantId", w.name, w.description, w."isPaused",
wc.id as "concurrencyId",
wc.max_concurrency as "concurrencyMaxRuns",
@@ -1213,6 +1218,7 @@ func (q *Queries) GetWorkflowVersionById(ctx context.Context, db DBTX, id pgtype
&i.WorkflowVersion.Kind,
&i.WorkflowVersion.DefaultPriority,
&i.WorkflowVersion.CreateWorkflowVersionOpts,
&i.WorkflowVersion.InputJsonSchema,
&i.Workflow.ID,
&i.Workflow.CreatedAt,
&i.Workflow.UpdatedAt,
@@ -1305,7 +1311,7 @@ func (q *Queries) GetWorkflowVersionEventTriggerRefs(ctx context.Context, db DBT
const getWorkflowVersionForEngine = `-- name: GetWorkflowVersionForEngine :many
SELECT
workflowversions.id, workflowversions."createdAt", workflowversions."updatedAt", workflowversions."deletedAt", workflowversions.version, workflowversions."order", workflowversions."workflowId", workflowversions.checksum, workflowversions."scheduleTimeout", workflowversions."onFailureJobId", workflowversions.sticky, workflowversions.kind, workflowversions."defaultPriority", workflowversions."createWorkflowVersionOpts",
workflowversions.id, workflowversions."createdAt", workflowversions."updatedAt", workflowversions."deletedAt", workflowversions.version, workflowversions."order", workflowversions."workflowId", workflowversions.checksum, workflowversions."scheduleTimeout", workflowversions."onFailureJobId", workflowversions.sticky, workflowversions.kind, workflowversions."defaultPriority", workflowversions."createWorkflowVersionOpts", workflowversions."inputJsonSchema",
w."name" as "workflowName",
wc."limitStrategy" as "concurrencyLimitStrategy",
wc."maxRuns" as "concurrencyMaxRuns",
@@ -1362,6 +1368,7 @@ func (q *Queries) GetWorkflowVersionForEngine(ctx context.Context, db DBTX, arg
&i.WorkflowVersion.Kind,
&i.WorkflowVersion.DefaultPriority,
&i.WorkflowVersion.CreateWorkflowVersionOpts,
&i.WorkflowVersion.InputJsonSchema,
&i.WorkflowName,
&i.ConcurrencyLimitStrategy,
&i.ConcurrencyMaxRuns,
@@ -1428,7 +1435,7 @@ const linkOnFailureJob = `-- name: LinkOnFailureJob :one
UPDATE "WorkflowVersion"
SET "onFailureJobId" = $1::uuid
WHERE "id" = $2::uuid
RETURNING id, "createdAt", "updatedAt", "deletedAt", version, "order", "workflowId", checksum, "scheduleTimeout", "onFailureJobId", sticky, kind, "defaultPriority", "createWorkflowVersionOpts"
RETURNING id, "createdAt", "updatedAt", "deletedAt", version, "order", "workflowId", checksum, "scheduleTimeout", "onFailureJobId", sticky, kind, "defaultPriority", "createWorkflowVersionOpts", "inputJsonSchema"
`
type LinkOnFailureJobParams struct {
@@ -1454,6 +1461,7 @@ func (q *Queries) LinkOnFailureJob(ctx context.Context, db DBTX, arg LinkOnFailu
&i.Kind,
&i.DefaultPriority,
&i.CreateWorkflowVersionOpts,
&i.InputJsonSchema,
)
return &i, err
}
+3
View File
@@ -54,6 +54,8 @@ type CreateWorkflowVersionOpts struct {
DefaultPriority *int32 `validate:"omitempty,min=1,max=3"`
DefaultFilters []types.DefaultFilter `json:"defaultFilters,omitempty" validate:"omitempty,dive"`
InputJsonSchema []byte `json:"inputJsonSchema,omitempty"`
}
type CreateConcurrencyOpts struct {
@@ -409,6 +411,7 @@ func (r *workflowRepository) createWorkflowVersionTxs(ctx context.Context, tx sq
Checksum: cs,
Workflowid: workflowId,
CreateWorkflowVersionOpts: optsJson,
InputJsonSchema: opts.InputJsonSchema,
}
if opts.Sticky != nil {
+10
View File
@@ -5,6 +5,16 @@ All notable changes to Hatchet's Python SDK will be documented in this changelog
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.22.12] - 2026-01-28
### Added
- Adds a `default_additional_metadata` to the `hatchet.workflow`, `hatchet.task`, and `hatchet.durable_task` methods, which allows you to declaratively provide additional metadata that will be attached to each run of the workflow or task by default.
### Internal Only
- Sends a JSON schema to the engine on workflow registration in order to power autocomplete for triggering workflows from the dashboard.
## [1.22.11] - 2026-01-27
### Changed
@@ -69,6 +69,8 @@ from hatchet_sdk.clients.rest.models.cancel_event_request import CancelEventRequ
from hatchet_sdk.clients.rest.models.concurrency_limit_strategy import (
ConcurrencyLimitStrategy,
)
from hatchet_sdk.clients.rest.models.concurrency_scope import ConcurrencyScope
from hatchet_sdk.clients.rest.models.concurrency_setting import ConcurrencySetting
from hatchet_sdk.clients.rest.models.concurrency_stat import ConcurrencyStat
from hatchet_sdk.clients.rest.models.create_api_token_request import (
CreateAPITokenRequest,
@@ -26,6 +26,7 @@ from hatchet_sdk.clients.rest.models.log_line_order_by_direction import (
LogLineOrderByDirection,
)
from hatchet_sdk.clients.rest.models.log_line_order_by_field import LogLineOrderByField
from hatchet_sdk.clients.rest.models.v1_log_line_level import V1LogLineLevel
from hatchet_sdk.clients.rest.models.v1_log_line_list import V1LogLineList
from hatchet_sdk.clients.rest.rest import RESTResponseType
@@ -464,6 +465,14 @@ class LogApi:
until: Annotated[
Optional[datetime], Field(description="The end time to get logs for")
] = None,
search: Annotated[
Optional[StrictStr],
Field(description="A full-text search query to filter for"),
] = None,
levels: Annotated[
Optional[List[V1LogLineLevel]],
Field(description="The log level(s) to include"),
] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
@@ -488,6 +497,10 @@ class LogApi:
:type since: datetime
:param until: The end time to get logs for
:type until: datetime
:param search: A full-text search query to filter for
:type search: str
:param levels: The log level(s) to include
:type levels: List[V1LogLineLevel]
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
@@ -515,6 +528,8 @@ class LogApi:
limit=limit,
since=since,
until=until,
search=search,
levels=levels,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
@@ -551,6 +566,14 @@ class LogApi:
until: Annotated[
Optional[datetime], Field(description="The end time to get logs for")
] = None,
search: Annotated[
Optional[StrictStr],
Field(description="A full-text search query to filter for"),
] = None,
levels: Annotated[
Optional[List[V1LogLineLevel]],
Field(description="The log level(s) to include"),
] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
@@ -575,6 +598,10 @@ class LogApi:
:type since: datetime
:param until: The end time to get logs for
:type until: datetime
:param search: A full-text search query to filter for
:type search: str
:param levels: The log level(s) to include
:type levels: List[V1LogLineLevel]
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
@@ -602,6 +629,8 @@ class LogApi:
limit=limit,
since=since,
until=until,
search=search,
levels=levels,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
@@ -638,6 +667,14 @@ class LogApi:
until: Annotated[
Optional[datetime], Field(description="The end time to get logs for")
] = None,
search: Annotated[
Optional[StrictStr],
Field(description="A full-text search query to filter for"),
] = None,
levels: Annotated[
Optional[List[V1LogLineLevel]],
Field(description="The log level(s) to include"),
] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
@@ -662,6 +699,10 @@ class LogApi:
:type since: datetime
:param until: The end time to get logs for
:type until: datetime
:param search: A full-text search query to filter for
:type search: str
:param levels: The log level(s) to include
:type levels: List[V1LogLineLevel]
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
@@ -689,6 +730,8 @@ class LogApi:
limit=limit,
since=since,
until=until,
search=search,
levels=levels,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
@@ -711,6 +754,8 @@ class LogApi:
limit,
since,
until,
search,
levels,
_request_auth,
_content_type,
_headers,
@@ -719,7 +764,9 @@ class LogApi:
_host = None
_collection_formats: Dict[str, str] = {}
_collection_formats: Dict[str, str] = {
"levels": "multi",
}
_path_params: Dict[str, str] = {}
_query_params: List[Tuple[str, str]] = []
@@ -760,6 +807,14 @@ class LogApi:
else:
_query_params.append(("until", until))
if search is not None:
_query_params.append(("search", search))
if levels is not None:
_query_params.append(("levels", levels))
# process the header parameters
# process the form parameters
# process the body parameter
@@ -31,6 +31,8 @@ from hatchet_sdk.clients.rest.models.cancel_event_request import CancelEventRequ
from hatchet_sdk.clients.rest.models.concurrency_limit_strategy import (
ConcurrencyLimitStrategy,
)
from hatchet_sdk.clients.rest.models.concurrency_scope import ConcurrencyScope
from hatchet_sdk.clients.rest.models.concurrency_setting import ConcurrencySetting
from hatchet_sdk.clients.rest.models.concurrency_stat import ConcurrencyStat
from hatchet_sdk.clients.rest.models.create_api_token_request import (
CreateAPITokenRequest,
@@ -0,0 +1,37 @@
# coding: utf-8
"""
Hatchet API
The Hatchet API
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from __future__ import annotations
import json
from enum import Enum
from typing_extensions import Self
class ConcurrencyScope(str, Enum):
"""
ConcurrencyScope
"""
"""
allowed enum values
"""
WORKFLOW = "WORKFLOW"
TASK = "TASK"
@classmethod
def from_json(cls, json_str: str) -> Self:
"""Create an instance of ConcurrencyScope from a JSON string"""
return cls(json.loads(json_str))
@@ -0,0 +1,117 @@
# coding: utf-8
"""
Hatchet API
The Hatchet API
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from __future__ import annotations
import json
import pprint
import re # noqa: F401
from typing import Any, ClassVar, Dict, List, Optional, Set
from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr
from typing_extensions import Self
from hatchet_sdk.clients.rest.models.concurrency_limit_strategy import (
ConcurrencyLimitStrategy,
)
from hatchet_sdk.clients.rest.models.concurrency_scope import ConcurrencyScope
class ConcurrencySetting(BaseModel):
"""
ConcurrencySetting
""" # noqa: E501
max_runs: StrictInt = Field(
description="The maximum number of concurrent workflow runs.", alias="maxRuns"
)
limit_strategy: ConcurrencyLimitStrategy = Field(
description="The strategy to use when the concurrency limit is reached.",
alias="limitStrategy",
)
expression: StrictStr = Field(
description="The concurrency expression, used to generate a key from task inputs, metadata, etc."
)
step_readable_id: Optional[StrictStr] = Field(
default=None,
description="The readable id of the step to which this concurrency setting applies.",
alias="stepReadableId",
)
scope: ConcurrencyScope = Field(description="The scope of the concurrency setting.")
__properties: ClassVar[List[str]] = [
"maxRuns",
"limitStrategy",
"expression",
"stepReadableId",
"scope",
]
model_config = ConfigDict(
populate_by_name=True,
validate_assignment=True,
protected_namespaces=(),
)
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Optional[Self]:
"""Create an instance of ConcurrencySetting from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
excluded_fields: Set[str] = set([])
_dict = self.model_dump(
by_alias=True,
exclude=excluded_fields,
exclude_none=True,
)
return _dict
@classmethod
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
"""Create an instance of ConcurrencySetting from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate(
{
"maxRuns": obj.get("maxRuns"),
"limitStrategy": obj.get("limitStrategy"),
"expression": obj.get("expression"),
"stepReadableId": obj.get("stepReadableId"),
"scope": obj.get("scope"),
}
)
return _obj
@@ -31,7 +31,6 @@ class TenantResource(str, Enum):
WORKER = "WORKER"
WORKER_SLOT = "WORKER_SLOT"
EVENT = "EVENT"
WORKFLOW_RUN = "WORKFLOW_RUN"
TASK_RUN = "TASK_RUN"
CRON = "CRON"
SCHEDULE = "SCHEDULE"
@@ -23,6 +23,7 @@ from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr
from typing_extensions import Self
from hatchet_sdk.clients.rest.models.api_resource_meta import APIResourceMeta
from hatchet_sdk.clients.rest.models.concurrency_setting import ConcurrencySetting
from hatchet_sdk.clients.rest.models.job import Job
from hatchet_sdk.clients.rest.models.workflow import Workflow
from hatchet_sdk.clients.rest.models.workflow_concurrency import WorkflowConcurrency
@@ -54,6 +55,9 @@ class WorkflowVersion(BaseModel):
workflow_config: Optional[Dict[str, Any]] = Field(
default=None, alias="workflowConfig"
)
v1_concurrency: Optional[List[ConcurrencySetting]] = Field(
default=None, alias="v1Concurrency"
)
__properties: ClassVar[List[str]] = [
"metadata",
"version",
@@ -67,6 +71,7 @@ class WorkflowVersion(BaseModel):
"scheduleTimeout",
"jobs",
"workflowConfig",
"v1Concurrency",
]
model_config = ConfigDict(
@@ -125,6 +130,13 @@ class WorkflowVersion(BaseModel):
if _item_jobs:
_items.append(_item_jobs.to_dict())
_dict["jobs"] = _items
# override the default output from pydantic by calling `to_dict()` of each item in v1_concurrency (list)
_items = []
if self.v1_concurrency:
for _item_v1_concurrency in self.v1_concurrency:
if _item_v1_concurrency:
_items.append(_item_v1_concurrency.to_dict())
_dict["v1Concurrency"] = _items
return _dict
@classmethod
@@ -170,6 +182,14 @@ class WorkflowVersion(BaseModel):
else None
),
"workflowConfig": obj.get("workflowConfig"),
"v1Concurrency": (
[
ConcurrencySetting.from_dict(_item)
for _item in obj["v1Concurrency"]
]
if obj.get("v1Concurrency") is not None
else None
),
}
)
return _obj
File diff suppressed because one or more lines are too long
@@ -137,7 +137,7 @@ class TriggerWorkflowRunResponse(_message.Message):
def __init__(self, external_id: _Optional[str] = ...) -> None: ...
class CreateWorkflowVersionRequest(_message.Message):
__slots__ = ("name", "description", "version", "event_triggers", "cron_triggers", "tasks", "concurrency", "cron_input", "on_failure_task", "sticky", "default_priority", "concurrency_arr", "default_filters")
__slots__ = ("name", "description", "version", "event_triggers", "cron_triggers", "tasks", "concurrency", "cron_input", "on_failure_task", "sticky", "default_priority", "concurrency_arr", "default_filters", "input_json_schema")
NAME_FIELD_NUMBER: _ClassVar[int]
DESCRIPTION_FIELD_NUMBER: _ClassVar[int]
VERSION_FIELD_NUMBER: _ClassVar[int]
@@ -151,6 +151,7 @@ class CreateWorkflowVersionRequest(_message.Message):
DEFAULT_PRIORITY_FIELD_NUMBER: _ClassVar[int]
CONCURRENCY_ARR_FIELD_NUMBER: _ClassVar[int]
DEFAULT_FILTERS_FIELD_NUMBER: _ClassVar[int]
INPUT_JSON_SCHEMA_FIELD_NUMBER: _ClassVar[int]
name: str
description: str
version: str
@@ -164,7 +165,8 @@ class CreateWorkflowVersionRequest(_message.Message):
default_priority: int
concurrency_arr: _containers.RepeatedCompositeFieldContainer[Concurrency]
default_filters: _containers.RepeatedCompositeFieldContainer[DefaultFilter]
def __init__(self, name: _Optional[str] = ..., description: _Optional[str] = ..., version: _Optional[str] = ..., event_triggers: _Optional[_Iterable[str]] = ..., cron_triggers: _Optional[_Iterable[str]] = ..., tasks: _Optional[_Iterable[_Union[CreateTaskOpts, _Mapping]]] = ..., concurrency: _Optional[_Union[Concurrency, _Mapping]] = ..., cron_input: _Optional[str] = ..., on_failure_task: _Optional[_Union[CreateTaskOpts, _Mapping]] = ..., sticky: _Optional[_Union[StickyStrategy, str]] = ..., default_priority: _Optional[int] = ..., concurrency_arr: _Optional[_Iterable[_Union[Concurrency, _Mapping]]] = ..., default_filters: _Optional[_Iterable[_Union[DefaultFilter, _Mapping]]] = ...) -> None: ...
input_json_schema: bytes
def __init__(self, name: _Optional[str] = ..., description: _Optional[str] = ..., version: _Optional[str] = ..., event_triggers: _Optional[_Iterable[str]] = ..., cron_triggers: _Optional[_Iterable[str]] = ..., tasks: _Optional[_Iterable[_Union[CreateTaskOpts, _Mapping]]] = ..., concurrency: _Optional[_Union[Concurrency, _Mapping]] = ..., cron_input: _Optional[str] = ..., on_failure_task: _Optional[_Union[CreateTaskOpts, _Mapping]] = ..., sticky: _Optional[_Union[StickyStrategy, str]] = ..., default_priority: _Optional[int] = ..., concurrency_arr: _Optional[_Iterable[_Union[Concurrency, _Mapping]]] = ..., default_filters: _Optional[_Iterable[_Union[DefaultFilter, _Mapping]]] = ..., input_json_schema: _Optional[bytes] = ...) -> None: ...
class DefaultFilter(_message.Message):
__slots__ = ("expression", "scope", "payload")
+19 -2
View File
@@ -3,6 +3,7 @@ from typing import TYPE_CHECKING, Any, overload
from hatchet_sdk.context.context import Context
from hatchet_sdk.runnables.types import EmptyModel, R, TWorkflowInput
from hatchet_sdk.runnables.workflow import Standalone, Workflow
from hatchet_sdk.utils.typing import JSONSerializableMapping
if TYPE_CHECKING:
from hatchet_sdk import Hatchet
@@ -18,6 +19,7 @@ class StubsClient:
*,
name: str,
input_validator: None = None,
default_additional_metadata: JSONSerializableMapping | None = None,
) -> Workflow[EmptyModel]: ...
@overload
@@ -26,6 +28,7 @@ class StubsClient:
*,
name: str,
input_validator: type[TWorkflowInput],
default_additional_metadata: JSONSerializableMapping | None = None,
) -> Workflow[TWorkflowInput]: ...
def workflow(
@@ -33,8 +36,13 @@ class StubsClient:
*,
name: str,
input_validator: type[TWorkflowInput] | None = None,
default_additional_metadata: JSONSerializableMapping | None = None,
) -> Workflow[EmptyModel] | Workflow[TWorkflowInput]:
return self.client.workflow(name=name, input_validator=input_validator)
return self.client.workflow(
name=name,
input_validator=input_validator,
default_additional_metadata=default_additional_metadata,
)
@overload
def task(
@@ -43,6 +51,7 @@ class StubsClient:
name: str,
input_validator: None = None,
output_validator: None = None,
default_additional_metadata: JSONSerializableMapping | None = None,
) -> Standalone[EmptyModel, EmptyModel]: ...
@overload
@@ -52,6 +61,7 @@ class StubsClient:
name: str,
input_validator: None = None,
output_validator: type[R],
default_additional_metadata: JSONSerializableMapping | None = None,
) -> Standalone[EmptyModel, R]: ...
@overload
@@ -61,6 +71,7 @@ class StubsClient:
name: str,
input_validator: type[TWorkflowInput],
output_validator: None = None,
default_additional_metadata: JSONSerializableMapping | None = None,
) -> Standalone[TWorkflowInput, EmptyModel]: ...
@overload
@@ -70,6 +81,7 @@ class StubsClient:
name: str,
input_validator: type[TWorkflowInput],
output_validator: type[R],
default_additional_metadata: JSONSerializableMapping | None = None,
) -> Standalone[TWorkflowInput, R]: ...
def task(
@@ -78,6 +90,7 @@ class StubsClient:
name: str,
input_validator: type[TWorkflowInput] | None = None,
output_validator: type[R] | None = None,
default_additional_metadata: JSONSerializableMapping | None = None,
) -> (
Standalone[EmptyModel, R]
| Standalone[TWorkflowInput, R]
@@ -96,4 +109,8 @@ class StubsClient:
"return": return_type,
}
return self.client.task(name=name, input_validator=input_validator)(mock_func)
return self.client.task(
name=name,
input_validator=input_validator,
default_additional_metadata=default_additional_metadata,
)(mock_func)
+19 -1
View File
@@ -39,7 +39,7 @@ from hatchet_sdk.runnables.types import (
)
from hatchet_sdk.runnables.workflow import BaseWorkflow, Standalone, Workflow
from hatchet_sdk.utils.timedelta_to_expression import Duration
from hatchet_sdk.utils.typing import CoroutineLike
from hatchet_sdk.utils.typing import CoroutineLike, JSONSerializableMapping
from hatchet_sdk.worker.worker import LifespanFn, Worker
P = ParamSpec("P")
@@ -236,6 +236,7 @@ class Hatchet:
) = None,
task_defaults: TaskDefaults = TaskDefaults(),
default_filters: list[DefaultFilter] | None = None,
default_additional_metadata: JSONSerializableMapping | None = None,
) -> Workflow[EmptyModel]: ...
@overload
@@ -255,6 +256,7 @@ class Hatchet:
) = None,
task_defaults: TaskDefaults = TaskDefaults(),
default_filters: list[DefaultFilter] | None = None,
default_additional_metadata: JSONSerializableMapping | None = None,
) -> Workflow[TWorkflowInput]: ...
def workflow(
@@ -273,6 +275,7 @@ class Hatchet:
) = None,
task_defaults: TaskDefaults = TaskDefaults(),
default_filters: list[DefaultFilter] | None = None,
default_additional_metadata: JSONSerializableMapping | None = None,
) -> Workflow[EmptyModel] | Workflow[TWorkflowInput]:
"""
Define a Hatchet workflow, which can then declare `task`s and be `run`, `schedule`d, and so on.
@@ -299,6 +302,8 @@ class Hatchet:
:param default_filters: A list of filters to create with the workflow is created. Note that this is a helper to allow you to create filters "declaratively" without needing to make a separate API call once the workflow is created to create them.
:param default_additional_metadata: A dictionary of additional metadata to attach to each run of this workflow by default.
:returns: The created `Workflow` object, which can be used to declare tasks, run the workflow, and so on.
"""
@@ -315,6 +320,7 @@ class Hatchet:
task_defaults=task_defaults,
default_priority=default_priority,
default_filters=default_filters or [],
default_additional_metadata=default_additional_metadata or {},
),
self,
)
@@ -342,6 +348,7 @@ class Hatchet:
backoff_factor: float | None = None,
backoff_max_seconds: int | None = None,
default_filters: list[DefaultFilter] | None = None,
default_additional_metadata: JSONSerializableMapping | None = None,
) -> Callable[
[Callable[Concatenate[EmptyModel, Context, P], R | CoroutineLike[R]]],
Standalone[EmptyModel, R],
@@ -370,6 +377,7 @@ class Hatchet:
backoff_factor: float | None = None,
backoff_max_seconds: int | None = None,
default_filters: list[DefaultFilter] | None = None,
default_additional_metadata: JSONSerializableMapping | None = None,
) -> Callable[
[Callable[Concatenate[TWorkflowInput, Context, P], R | CoroutineLike[R]]],
Standalone[TWorkflowInput, R],
@@ -397,6 +405,7 @@ class Hatchet:
backoff_factor: float | None = None,
backoff_max_seconds: int | None = None,
default_filters: list[DefaultFilter] | None = None,
default_additional_metadata: JSONSerializableMapping | None = None,
) -> (
Callable[
[Callable[Concatenate[EmptyModel, Context, P], R | CoroutineLike[R]]],
@@ -444,6 +453,8 @@ class Hatchet:
:param default_filters: A list of filters to create with the task is created. Note that this is a helper to allow you to create filters "declaratively" without needing to make a separate API call once the task is created to create them.
:param default_additional_metadata: A dictionary of additional metadata to attach to each run of this task by default.
:returns: A decorator which creates a `Standalone` task object.
"""
@@ -465,6 +476,7 @@ class Hatchet:
default_priority=default_priority,
input_validator=TypeAdapter(normalize_validator(input_validator)),
default_filters=default_filters or [],
default_additional_metadata=default_additional_metadata or {},
),
self,
)
@@ -523,6 +535,7 @@ class Hatchet:
backoff_factor: float | None = None,
backoff_max_seconds: int | None = None,
default_filters: list[DefaultFilter] | None = None,
default_additional_metadata: JSONSerializableMapping | None = None,
) -> Callable[
[Callable[Concatenate[EmptyModel, DurableContext, P], R | CoroutineLike[R]]],
Standalone[EmptyModel, R],
@@ -551,6 +564,7 @@ class Hatchet:
backoff_factor: float | None = None,
backoff_max_seconds: int | None = None,
default_filters: list[DefaultFilter] | None = None,
default_additional_metadata: JSONSerializableMapping | None = None,
) -> Callable[
[
Callable[
@@ -582,6 +596,7 @@ class Hatchet:
backoff_factor: float | None = None,
backoff_max_seconds: int | None = None,
default_filters: list[DefaultFilter] | None = None,
default_additional_metadata: JSONSerializableMapping | None = None,
) -> (
Callable[
[
@@ -637,6 +652,8 @@ class Hatchet:
:param default_filters: A list of filters to create with the task is created. Note that this is a helper to allow you to create filters "declaratively" without needing to make a separate API call once the task is created to create them.
:param default_additional_metadata: A dictionary of additional metadata to attach to each run of this task by default.
:returns: A decorator which creates a `Standalone` task object.
"""
@@ -657,6 +674,7 @@ class Hatchet:
input_validator=TypeAdapter(normalize_validator(input_validator)),
default_priority=default_priority,
default_filters=default_filters or [],
default_additional_metadata=default_additional_metadata or {},
),
self,
)
@@ -130,6 +130,7 @@ class WorkflowConfig(BaseModel):
task_defaults: TaskDefaults = TaskDefaults()
default_filters: list[DefaultFilter] = Field(default_factory=list)
default_additional_metadata: JSONSerializableMapping = Field(default_factory=dict)
class StepType(str, Enum):
+38 -5
View File
@@ -1,4 +1,5 @@
import asyncio
import json
from collections.abc import Callable
from datetime import datetime, timedelta
from functools import cached_property
@@ -202,6 +203,19 @@ class BaseWorkflow(Generic[TWorkflowInput]):
_concurrency = None
_concurrency_arr = []
# Hack to not send a JSON schema if the input type is None/EmptyModel
input_type = self.config.input_validator.core_schema.get("cls")
if input_type is None or input_type is EmptyModel:
json_schema = None
else:
try:
json_schema = json.dumps(
self.config.input_validator.json_schema()
).encode("utf-8")
except Exception:
json_schema = None
return CreateWorkflowVersionRequest(
name=name,
description=self.config.description,
@@ -219,6 +233,7 @@ class BaseWorkflow(Generic[TWorkflowInput]):
concurrency_arr=_concurrency_arr,
default_priority=self.config.default_priority,
default_filters=[f.to_proto() for f in self.config.default_filters],
input_json_schema=json_schema,
)
def _get_workflow_input(self, ctx: Context) -> TWorkflowInput:
@@ -229,6 +244,24 @@ class BaseWorkflow(Generic[TWorkflowInput]):
),
)
def _combine_additional_metadata(
self, additional_metadata_from_trigger: JSONSerializableMapping
) -> JSONSerializableMapping:
return {
**self.config.default_additional_metadata,
**additional_metadata_from_trigger,
}
def _create_options_with_combined_additional_meta(
self, options: TriggerWorkflowOptions
) -> TriggerWorkflowOptions:
options_copy = options.model_copy()
options_copy.additional_metadata = self._combine_additional_metadata(
options.additional_metadata
)
return options_copy
@property
def input_validator(self) -> type[TWorkflowInput]:
return cast(type[TWorkflowInput], self.config.input_validator)
@@ -270,7 +303,7 @@ class BaseWorkflow(Generic[TWorkflowInput]):
return WorkflowRunTriggerConfig(
workflow_name=self.config.name,
input=self._serialize_input(input),
options=options,
options=self._create_options_with_combined_additional_meta(options),
key=key,
)
@@ -605,7 +638,7 @@ class Workflow(BaseWorkflow[TWorkflowInput]):
return self.client._client.admin.run_workflow(
workflow_name=self.config.name,
input=self._serialize_input(input),
options=options,
options=self._create_options_with_combined_additional_meta(options),
)
def run(
@@ -627,7 +660,7 @@ class Workflow(BaseWorkflow[TWorkflowInput]):
ref = self.client._client.admin.run_workflow(
workflow_name=self.config.name,
input=self._serialize_input(input),
options=options,
options=self._create_options_with_combined_additional_meta(options),
)
return ref.result()
@@ -650,7 +683,7 @@ class Workflow(BaseWorkflow[TWorkflowInput]):
return await self.client._client.admin.aio_run_workflow(
workflow_name=self.config.name,
input=self._serialize_input(input),
options=options,
options=self._create_options_with_combined_additional_meta(options),
)
async def aio_run(
@@ -671,7 +704,7 @@ class Workflow(BaseWorkflow[TWorkflowInput]):
ref = await self.client._client.admin.aio_run_workflow(
workflow_name=self.config.name,
input=self._serialize_input(input),
options=options,
options=self._create_options_with_combined_additional_meta(options),
)
return await ref.aio_result()
+23 -23
View File
@@ -1,4 +1,4 @@
# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand.
# This file is automatically @generated by Poetry 2.0.0 and should not be changed by hand.
[[package]]
name = "aiohappyeyeballs"
@@ -153,7 +153,7 @@ propcache = ">=0.2.0"
yarl = ">=1.17.0,<2.0"
[package.extras]
speedups = ["Brotli (>=1.2) ; platform_python_implementation == \"CPython\"", "aiodns (>=3.3.0)", "backports.zstd ; platform_python_implementation == \"CPython\" and python_version < \"3.14\"", "brotlicffi (>=1.2) ; platform_python_implementation != \"CPython\""]
speedups = ["Brotli (>=1.2)", "aiodns (>=3.3.0)", "backports.zstd", "brotlicffi (>=1.2)"]
[[package]]
name = "aiosignal"
@@ -201,7 +201,7 @@ idna = ">=2.8"
typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""}
[package.extras]
trio = ["trio (>=0.31.0) ; python_version < \"3.10\"", "trio (>=0.32.0) ; python_version >= \"3.10\""]
trio = ["trio (>=0.31.0)", "trio (>=0.32.0)"]
[[package]]
name = "async-timeout"
@@ -210,7 +210,7 @@ description = "Timeout context manager for asyncio programs"
optional = false
python-versions = ">=3.8"
groups = ["main"]
markers = "python_version == \"3.10\""
markers = "python_version < \"3.11\""
files = [
{file = "async_timeout-5.0.1-py3-none-any.whl", hash = "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c"},
{file = "async_timeout-5.0.1.tar.gz", hash = "sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3"},
@@ -503,7 +503,7 @@ files = [
]
[package.extras]
dev = ["docstring-parser[docs]", "docstring-parser[test]", "pre-commit (>=2.16.0) ; python_version >= \"3.9\""]
dev = ["docstring-parser[docs]", "docstring-parser[test]", "pre-commit (>=2.16.0)"]
docs = ["pydoctor (>=25.4.0)"]
test = ["pytest"]
@@ -514,7 +514,7 @@ description = "Backport of PEP 654 (exception groups)"
optional = false
python-versions = ">=3.7"
groups = ["docs", "test"]
markers = "python_version == \"3.10\""
markers = "python_version < \"3.11\""
files = [
{file = "exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598"},
{file = "exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219"},
@@ -978,7 +978,7 @@ httpcore = "==1.*"
idna = "*"
[package.extras]
brotli = ["brotli ; platform_python_implementation == \"CPython\"", "brotlicffi ; platform_python_implementation != \"CPython\""]
brotli = ["brotli", "brotlicffi"]
cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"]
http2 = ["h2 (>=3,<5)"]
socks = ["socksio (==1.*)"]
@@ -1016,12 +1016,12 @@ files = [
zipp = ">=3.20"
[package.extras]
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""]
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"]
cover = ["pytest-cov"]
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
enabler = ["pytest-enabler (>=2.2)"]
perf = ["ipython"]
test = ["flufl.flake8", "importlib_resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"]
test = ["flufl.flake8", "importlib_resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"]
type = ["pytest-mypy"]
[[package]]
@@ -1440,7 +1440,7 @@ watchdog = ">=2.0"
[package.extras]
i18n = ["babel (>=2.9.0)"]
min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4) ; platform_system == \"Windows\"", "ghp-import (==1.0)", "importlib-metadata (==4.4) ; python_version < \"3.10\"", "jinja2 (==2.11.1)", "markdown (==3.3.6)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "mkdocs-get-deps (==0.2.0)", "packaging (==20.5)", "pathspec (==0.11.1)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "watchdog (==2.0)"]
min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-import (==1.0)", "importlib-metadata (==4.4)", "jinja2 (==2.11.1)", "markdown (==3.3.6)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "mkdocs-get-deps (==0.2.0)", "packaging (==20.5)", "pathspec (==0.11.1)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "watchdog (==2.0)"]
[[package]]
name = "mkdocs-autorefs"
@@ -2249,12 +2249,12 @@ typing-extensions = {version = ">=4.6", markers = "python_version < \"3.13\""}
tzdata = {version = "*", markers = "sys_platform == \"win32\""}
[package.extras]
binary = ["psycopg-binary (==3.3.2) ; implementation_name != \"pypy\""]
c = ["psycopg-c (==3.3.2) ; implementation_name != \"pypy\""]
binary = ["psycopg-binary (==3.3.2)"]
c = ["psycopg-c (==3.3.2)"]
dev = ["ast-comments (>=1.1.2)", "black (>=24.1.0)", "codespell (>=2.2)", "cython-lint (>=0.16)", "dnspython (>=2.1)", "flake8 (>=4.0)", "isort-psycopg", "isort[colors] (>=6.0)", "mypy (>=1.19.0)", "pre-commit (>=4.0.1)", "types-setuptools (>=57.4)", "types-shapely (>=2.0)", "wheel (>=0.37)"]
docs = ["Sphinx (>=5.0)", "furo (==2022.6.21)", "sphinx-autobuild (>=2021.3.14)", "sphinx-autodoc-typehints (>=1.12)"]
pool = ["psycopg-pool"]
test = ["anyio (>=4.0)", "mypy (>=1.19.0) ; implementation_name != \"pypy\"", "pproxy (>=2.7)", "pytest (>=6.2.5)", "pytest-cov (>=3.0)", "pytest-randomly (>=3.5)"]
test = ["anyio (>=4.0)", "mypy (>=1.19.0)", "pproxy (>=2.7)", "pytest (>=6.2.5)", "pytest-cov (>=3.0)", "pytest-randomly (>=3.5)"]
[[package]]
name = "psycopg-pool"
@@ -2294,7 +2294,7 @@ typing-inspection = ">=0.4.2"
[package.extras]
email = ["email-validator (>=2.0.0)"]
timezone = ["tzdata ; python_version >= \"3.9\" and platform_system == \"Windows\""]
timezone = ["tzdata"]
[[package]]
name = "pydantic-core"
@@ -2801,13 +2801,13 @@ files = [
]
[package.extras]
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\"", "ruff (>=0.8.0) ; sys_platform != \"cygwin\""]
core = ["importlib_metadata (>=6) ; python_version < \"3.10\"", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1) ; python_version < \"3.11\"", "wheel (>=0.43.0)"]
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.8.0)"]
core = ["importlib_metadata (>=6)", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"]
cover = ["pytest-cov"]
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
enabler = ["pytest-enabler (>=2.2)"]
test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21) ; python_version >= \"3.9\" and sys_platform != \"cygwin\"", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf ; sys_platform != \"cygwin\"", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"]
type = ["importlib_metadata (>=7.0.2) ; python_version < \"3.10\"", "jaraco.develop (>=7.21) ; sys_platform != \"cygwin\"", "mypy (==1.14.*)", "pytest-mypy"]
test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"]
type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.14.*)", "pytest-mypy"]
[[package]]
name = "six"
@@ -2886,7 +2886,7 @@ description = "A lil' TOML parser"
optional = false
python-versions = ">=3.8"
groups = ["docs", "lint", "test"]
markers = "python_version == \"3.10\""
markers = "python_version < \"3.11\""
files = [
{file = "tomli-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:88bd15eb972f3664f5ed4b57c1634a97153b4bac4479dcb6a495f41921eb7f45"},
{file = "tomli-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:883b1c0d6398a6a9d29b508c331fa56adbcdff647f6ace4dfca0f50e90dfd0ba"},
@@ -3088,10 +3088,10 @@ files = [
]
[package.extras]
brotli = ["brotli (>=1.2.0) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=1.2.0.0) ; platform_python_implementation != \"CPython\""]
brotli = ["brotli (>=1.2.0)", "brotlicffi (>=1.2.0.0)"]
h2 = ["h2 (>=4,<5)"]
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
zstd = ["backports-zstd (>=1.0.0) ; python_version < \"3.14\""]
zstd = ["backports-zstd (>=1.0.0)"]
[[package]]
name = "uvicorn"
@@ -3111,7 +3111,7 @@ h11 = ">=0.8"
typing-extensions = {version = ">=4.0", markers = "python_version < \"3.11\""}
[package.extras]
standard = ["colorama (>=0.4) ; sys_platform == \"win32\"", "httptools (>=0.6.3)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.15.1) ; sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\"", "watchfiles (>=0.13)", "websockets (>=10.4)"]
standard = ["colorama (>=0.4)", "httptools (>=0.6.3)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"]
[[package]]
name = "watchdog"
@@ -3407,7 +3407,7 @@ files = [
]
[package.extras]
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""]
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"]
cover = ["pytest-cov"]
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
enabler = ["pytest-enabler (>=2.2)"]
+1 -1
View File
@@ -1,6 +1,6 @@
[tool.poetry]
name = "hatchet-sdk"
version = "1.22.11"
version = "1.22.12"
description = "This is the official Python SDK for Hatchet, a distributed, fault-tolerant task queue. The SDK allows you to easily integrate Hatchet's task scheduling and workflow orchestration capabilities into your Python applications."
authors = [
"Alexander Belanger <alexander@hatchet.run>",
+6
View File
@@ -5,6 +5,12 @@ All notable changes to Hatchet's TypeScript SDK will be documented in this chang
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.10.7] - 2026-01-27
### Added
- Adds support for an `inputValidator` prop on the various workflow definitions, e.g. `hatchet.workflow` and `hatchet.task`, which accepts a Zod schema to validate the input to the workflow or task. Used on the dashboard to provide autocomplete on the trigger workflow form.
## [1.10.6] - 2026-01-27
### Changed
+3 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@hatchet-dev/typescript-sdk",
"version": "1.10.6",
"version": "1.10.7",
"description": "Background task orchestration & visibility for developers",
"types": "dist/index.d.ts",
"files": [
@@ -89,7 +89,8 @@
"qs": "^6.14.1",
"semver": "^7.7.1",
"yaml": "^2.7.1",
"zod": "^3.24.2"
"zod": "^3.24.2",
"zod-to-json-schema": "^3.24.1"
},
"optionalDependencies": {
"prom-client": "^15.1.3"
+16 -4
View File
@@ -49,6 +49,13 @@ importers:
zod:
specifier: ^3.24.2
version: 3.25.76
zod-to-json-schema:
specifier: ^3.24.1
version: 3.25.1(zod@3.25.76)
optionalDependencies:
prom-client:
specifier: ^15.1.3
version: 15.1.3
devDependencies:
'@tsd/typescript':
specifier: ^5.8.2
@@ -149,10 +156,6 @@ importers:
typescript:
specifier: ^5.8.2
version: 5.9.2
optionalDependencies:
prom-client:
specifier: ^15.1.3
version: 15.1.3
packages:
@@ -2991,6 +2994,11 @@ packages:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}
zod-to-json-schema@3.25.1:
resolution: {integrity: sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==}
peerDependencies:
zod: ^3.25 || ^4
zod@3.25.76:
resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
@@ -6433,4 +6441,8 @@ snapshots:
yocto-queue@0.1.0: {}
zod-to-json-schema@3.25.1(zod@3.25.76):
dependencies:
zod: 3.25.76
zod@3.25.76: {}
+552
View File
@@ -108,6 +108,57 @@ export function rateLimitDurationToJSON(object: RateLimitDuration): string {
}
}
export enum RunStatus {
QUEUED = 0,
RUNNING = 1,
COMPLETED = 2,
FAILED = 3,
CANCELLED = 4,
UNRECOGNIZED = -1,
}
export function runStatusFromJSON(object: any): RunStatus {
switch (object) {
case 0:
case 'QUEUED':
return RunStatus.QUEUED;
case 1:
case 'RUNNING':
return RunStatus.RUNNING;
case 2:
case 'COMPLETED':
return RunStatus.COMPLETED;
case 3:
case 'FAILED':
return RunStatus.FAILED;
case 4:
case 'CANCELLED':
return RunStatus.CANCELLED;
case -1:
case 'UNRECOGNIZED':
default:
return RunStatus.UNRECOGNIZED;
}
}
export function runStatusToJSON(object: RunStatus): string {
switch (object) {
case RunStatus.QUEUED:
return 'QUEUED';
case RunStatus.RUNNING:
return 'RUNNING';
case RunStatus.COMPLETED:
return 'COMPLETED';
case RunStatus.FAILED:
return 'FAILED';
case RunStatus.CANCELLED:
return 'CANCELLED';
case RunStatus.UNRECOGNIZED:
default:
return 'UNRECOGNIZED';
}
}
export enum ConcurrencyLimitStrategy {
CANCEL_IN_PROGRESS = 0,
/** DROP_NEWEST - deprecated */
@@ -285,6 +336,8 @@ export interface CreateWorkflowVersionRequest {
concurrencyArr: Concurrency[];
/** (optional) the default filters for the workflow */
defaultFilters: DefaultFilter[];
/** (optional) the JSON schema for the workflow input */
inputJsonSchema?: Uint8Array | undefined;
}
export interface DefaultFilter {
@@ -384,6 +437,42 @@ export interface CreateWorkflowVersionResponse {
workflowId: string;
}
export interface GetRunDetailsRequest {
/** (required) the external id (uuid) of the workflow run */
externalId: string;
}
export interface TaskRunDetail {
/** the external id (uuid) of the task run */
externalId: string;
/** the status of the task run */
status: RunStatus;
/** (optional) error message from the task run, if any */
error?: string | undefined;
/** (optional) the output payload for the task run */
output?: Uint8Array | undefined;
/** the readable id of the task */
readableId: string;
}
export interface GetRunDetailsResponse {
/** the input payload for the workflow run */
input: Uint8Array;
/** the status of the workflow run */
status: RunStatus;
/** map of task run external ids to their details */
taskRuns: { [key: string]: TaskRunDetail };
/** indicates if the workflow run is done */
done: boolean;
/** (optional) additional metadata for the workflow run */
additionalMetadata: Uint8Array;
}
export interface GetRunDetailsResponse_TaskRunsEntry {
key: string;
value: TaskRunDetail | undefined;
}
function createBaseCancelTasksRequest(): CancelTasksRequest {
return { externalIds: [], filter: undefined };
}
@@ -1000,6 +1089,7 @@ function createBaseCreateWorkflowVersionRequest(): CreateWorkflowVersionRequest
defaultPriority: undefined,
concurrencyArr: [],
defaultFilters: [],
inputJsonSchema: undefined,
};
}
@@ -1047,6 +1137,9 @@ export const CreateWorkflowVersionRequest: MessageFns<CreateWorkflowVersionReque
for (const v of message.defaultFilters) {
DefaultFilter.encode(v!, writer.uint32(106).fork()).join();
}
if (message.inputJsonSchema !== undefined) {
writer.uint32(114).bytes(message.inputJsonSchema);
}
return writer;
},
@@ -1161,6 +1254,14 @@ export const CreateWorkflowVersionRequest: MessageFns<CreateWorkflowVersionReque
message.defaultFilters.push(DefaultFilter.decode(reader, reader.uint32()));
continue;
}
case 14: {
if (tag !== 114) {
break;
}
message.inputJsonSchema = reader.bytes();
continue;
}
}
if ((tag & 7) === 4 || tag === 0) {
break;
@@ -1199,6 +1300,9 @@ export const CreateWorkflowVersionRequest: MessageFns<CreateWorkflowVersionReque
defaultFilters: globalThis.Array.isArray(object?.defaultFilters)
? object.defaultFilters.map((e: any) => DefaultFilter.fromJSON(e))
: [],
inputJsonSchema: isSet(object.inputJsonSchema)
? bytesFromBase64(object.inputJsonSchema)
: undefined,
};
},
@@ -1243,6 +1347,9 @@ export const CreateWorkflowVersionRequest: MessageFns<CreateWorkflowVersionReque
if (message.defaultFilters?.length) {
obj.defaultFilters = message.defaultFilters.map((e) => DefaultFilter.toJSON(e));
}
if (message.inputJsonSchema !== undefined) {
obj.inputJsonSchema = base64FromBytes(message.inputJsonSchema);
}
return obj;
},
@@ -1270,6 +1377,7 @@ export const CreateWorkflowVersionRequest: MessageFns<CreateWorkflowVersionReque
message.defaultPriority = object.defaultPriority ?? undefined;
message.concurrencyArr = object.concurrencyArr?.map((e) => Concurrency.fromPartial(e)) || [];
message.defaultFilters = object.defaultFilters?.map((e) => DefaultFilter.fromPartial(e)) || [];
message.inputJsonSchema = object.inputJsonSchema ?? undefined;
return message;
},
};
@@ -2212,6 +2320,434 @@ export const CreateWorkflowVersionResponse: MessageFns<CreateWorkflowVersionResp
},
};
function createBaseGetRunDetailsRequest(): GetRunDetailsRequest {
return { externalId: '' };
}
export const GetRunDetailsRequest: MessageFns<GetRunDetailsRequest> = {
encode(message: GetRunDetailsRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.externalId !== '') {
writer.uint32(10).string(message.externalId);
}
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): GetRunDetailsRequest {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseGetRunDetailsRequest();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1: {
if (tag !== 10) {
break;
}
message.externalId = reader.string();
continue;
}
}
if ((tag & 7) === 4 || tag === 0) {
break;
}
reader.skip(tag & 7);
}
return message;
},
fromJSON(object: any): GetRunDetailsRequest {
return { externalId: isSet(object.externalId) ? globalThis.String(object.externalId) : '' };
},
toJSON(message: GetRunDetailsRequest): unknown {
const obj: any = {};
if (message.externalId !== '') {
obj.externalId = message.externalId;
}
return obj;
},
create(base?: DeepPartial<GetRunDetailsRequest>): GetRunDetailsRequest {
return GetRunDetailsRequest.fromPartial(base ?? {});
},
fromPartial(object: DeepPartial<GetRunDetailsRequest>): GetRunDetailsRequest {
const message = createBaseGetRunDetailsRequest();
message.externalId = object.externalId ?? '';
return message;
},
};
function createBaseTaskRunDetail(): TaskRunDetail {
return { externalId: '', status: 0, error: undefined, output: undefined, readableId: '' };
}
export const TaskRunDetail: MessageFns<TaskRunDetail> = {
encode(message: TaskRunDetail, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.externalId !== '') {
writer.uint32(10).string(message.externalId);
}
if (message.status !== 0) {
writer.uint32(16).int32(message.status);
}
if (message.error !== undefined) {
writer.uint32(26).string(message.error);
}
if (message.output !== undefined) {
writer.uint32(34).bytes(message.output);
}
if (message.readableId !== '') {
writer.uint32(42).string(message.readableId);
}
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): TaskRunDetail {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseTaskRunDetail();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1: {
if (tag !== 10) {
break;
}
message.externalId = reader.string();
continue;
}
case 2: {
if (tag !== 16) {
break;
}
message.status = reader.int32() as any;
continue;
}
case 3: {
if (tag !== 26) {
break;
}
message.error = reader.string();
continue;
}
case 4: {
if (tag !== 34) {
break;
}
message.output = reader.bytes();
continue;
}
case 5: {
if (tag !== 42) {
break;
}
message.readableId = reader.string();
continue;
}
}
if ((tag & 7) === 4 || tag === 0) {
break;
}
reader.skip(tag & 7);
}
return message;
},
fromJSON(object: any): TaskRunDetail {
return {
externalId: isSet(object.externalId) ? globalThis.String(object.externalId) : '',
status: isSet(object.status) ? runStatusFromJSON(object.status) : 0,
error: isSet(object.error) ? globalThis.String(object.error) : undefined,
output: isSet(object.output) ? bytesFromBase64(object.output) : undefined,
readableId: isSet(object.readableId) ? globalThis.String(object.readableId) : '',
};
},
toJSON(message: TaskRunDetail): unknown {
const obj: any = {};
if (message.externalId !== '') {
obj.externalId = message.externalId;
}
if (message.status !== 0) {
obj.status = runStatusToJSON(message.status);
}
if (message.error !== undefined) {
obj.error = message.error;
}
if (message.output !== undefined) {
obj.output = base64FromBytes(message.output);
}
if (message.readableId !== '') {
obj.readableId = message.readableId;
}
return obj;
},
create(base?: DeepPartial<TaskRunDetail>): TaskRunDetail {
return TaskRunDetail.fromPartial(base ?? {});
},
fromPartial(object: DeepPartial<TaskRunDetail>): TaskRunDetail {
const message = createBaseTaskRunDetail();
message.externalId = object.externalId ?? '';
message.status = object.status ?? 0;
message.error = object.error ?? undefined;
message.output = object.output ?? undefined;
message.readableId = object.readableId ?? '';
return message;
},
};
function createBaseGetRunDetailsResponse(): GetRunDetailsResponse {
return {
input: new Uint8Array(0),
status: 0,
taskRuns: {},
done: false,
additionalMetadata: new Uint8Array(0),
};
}
export const GetRunDetailsResponse: MessageFns<GetRunDetailsResponse> = {
encode(message: GetRunDetailsResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.input.length !== 0) {
writer.uint32(10).bytes(message.input);
}
if (message.status !== 0) {
writer.uint32(16).int32(message.status);
}
Object.entries(message.taskRuns).forEach(([key, value]) => {
GetRunDetailsResponse_TaskRunsEntry.encode(
{ key: key as any, value },
writer.uint32(26).fork()
).join();
});
if (message.done !== false) {
writer.uint32(32).bool(message.done);
}
if (message.additionalMetadata.length !== 0) {
writer.uint32(42).bytes(message.additionalMetadata);
}
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): GetRunDetailsResponse {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseGetRunDetailsResponse();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1: {
if (tag !== 10) {
break;
}
message.input = reader.bytes();
continue;
}
case 2: {
if (tag !== 16) {
break;
}
message.status = reader.int32() as any;
continue;
}
case 3: {
if (tag !== 26) {
break;
}
const entry3 = GetRunDetailsResponse_TaskRunsEntry.decode(reader, reader.uint32());
if (entry3.value !== undefined) {
message.taskRuns[entry3.key] = entry3.value;
}
continue;
}
case 4: {
if (tag !== 32) {
break;
}
message.done = reader.bool();
continue;
}
case 5: {
if (tag !== 42) {
break;
}
message.additionalMetadata = reader.bytes();
continue;
}
}
if ((tag & 7) === 4 || tag === 0) {
break;
}
reader.skip(tag & 7);
}
return message;
},
fromJSON(object: any): GetRunDetailsResponse {
return {
input: isSet(object.input) ? bytesFromBase64(object.input) : new Uint8Array(0),
status: isSet(object.status) ? runStatusFromJSON(object.status) : 0,
taskRuns: isObject(object.taskRuns)
? Object.entries(object.taskRuns).reduce<{ [key: string]: TaskRunDetail }>(
(acc, [key, value]) => {
acc[key] = TaskRunDetail.fromJSON(value);
return acc;
},
{}
)
: {},
done: isSet(object.done) ? globalThis.Boolean(object.done) : false,
additionalMetadata: isSet(object.additionalMetadata)
? bytesFromBase64(object.additionalMetadata)
: new Uint8Array(0),
};
},
toJSON(message: GetRunDetailsResponse): unknown {
const obj: any = {};
if (message.input.length !== 0) {
obj.input = base64FromBytes(message.input);
}
if (message.status !== 0) {
obj.status = runStatusToJSON(message.status);
}
if (message.taskRuns) {
const entries = Object.entries(message.taskRuns);
if (entries.length > 0) {
obj.taskRuns = {};
entries.forEach(([k, v]) => {
obj.taskRuns[k] = TaskRunDetail.toJSON(v);
});
}
}
if (message.done !== false) {
obj.done = message.done;
}
if (message.additionalMetadata.length !== 0) {
obj.additionalMetadata = base64FromBytes(message.additionalMetadata);
}
return obj;
},
create(base?: DeepPartial<GetRunDetailsResponse>): GetRunDetailsResponse {
return GetRunDetailsResponse.fromPartial(base ?? {});
},
fromPartial(object: DeepPartial<GetRunDetailsResponse>): GetRunDetailsResponse {
const message = createBaseGetRunDetailsResponse();
message.input = object.input ?? new Uint8Array(0);
message.status = object.status ?? 0;
message.taskRuns = Object.entries(object.taskRuns ?? {}).reduce<{
[key: string]: TaskRunDetail;
}>((acc, [key, value]) => {
if (value !== undefined) {
acc[key] = TaskRunDetail.fromPartial(value);
}
return acc;
}, {});
message.done = object.done ?? false;
message.additionalMetadata = object.additionalMetadata ?? new Uint8Array(0);
return message;
},
};
function createBaseGetRunDetailsResponse_TaskRunsEntry(): GetRunDetailsResponse_TaskRunsEntry {
return { key: '', value: undefined };
}
export const GetRunDetailsResponse_TaskRunsEntry: MessageFns<GetRunDetailsResponse_TaskRunsEntry> =
{
encode(
message: GetRunDetailsResponse_TaskRunsEntry,
writer: BinaryWriter = new BinaryWriter()
): BinaryWriter {
if (message.key !== '') {
writer.uint32(10).string(message.key);
}
if (message.value !== undefined) {
TaskRunDetail.encode(message.value, writer.uint32(18).fork()).join();
}
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): GetRunDetailsResponse_TaskRunsEntry {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseGetRunDetailsResponse_TaskRunsEntry();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1: {
if (tag !== 10) {
break;
}
message.key = reader.string();
continue;
}
case 2: {
if (tag !== 18) {
break;
}
message.value = TaskRunDetail.decode(reader, reader.uint32());
continue;
}
}
if ((tag & 7) === 4 || tag === 0) {
break;
}
reader.skip(tag & 7);
}
return message;
},
fromJSON(object: any): GetRunDetailsResponse_TaskRunsEntry {
return {
key: isSet(object.key) ? globalThis.String(object.key) : '',
value: isSet(object.value) ? TaskRunDetail.fromJSON(object.value) : undefined,
};
},
toJSON(message: GetRunDetailsResponse_TaskRunsEntry): unknown {
const obj: any = {};
if (message.key !== '') {
obj.key = message.key;
}
if (message.value !== undefined) {
obj.value = TaskRunDetail.toJSON(message.value);
}
return obj;
},
create(
base?: DeepPartial<GetRunDetailsResponse_TaskRunsEntry>
): GetRunDetailsResponse_TaskRunsEntry {
return GetRunDetailsResponse_TaskRunsEntry.fromPartial(base ?? {});
},
fromPartial(
object: DeepPartial<GetRunDetailsResponse_TaskRunsEntry>
): GetRunDetailsResponse_TaskRunsEntry {
const message = createBaseGetRunDetailsResponse_TaskRunsEntry();
message.key = object.key ?? '';
message.value =
object.value !== undefined && object.value !== null
? TaskRunDetail.fromPartial(object.value)
: undefined;
return message;
},
};
/** AdminService represents a set of RPCs for admin management of tasks, workflows, etc. */
export type AdminServiceDefinition = typeof AdminServiceDefinition;
export const AdminServiceDefinition = {
@@ -2250,6 +2786,14 @@ export const AdminServiceDefinition = {
responseStream: false,
options: {},
},
getRunDetails: {
name: 'GetRunDetails',
requestType: GetRunDetailsRequest,
requestStream: false,
responseType: GetRunDetailsResponse,
responseStream: false,
options: {},
},
},
} as const;
@@ -2270,6 +2814,10 @@ export interface AdminServiceImplementation<CallContextExt = {}> {
request: TriggerWorkflowRunRequest,
context: CallContext & CallContextExt
): Promise<DeepPartial<TriggerWorkflowRunResponse>>;
getRunDetails(
request: GetRunDetailsRequest,
context: CallContext & CallContextExt
): Promise<DeepPartial<GetRunDetailsResponse>>;
}
export interface AdminServiceClient<CallOptionsExt = {}> {
@@ -2289,6 +2837,10 @@ export interface AdminServiceClient<CallOptionsExt = {}> {
request: DeepPartial<TriggerWorkflowRunRequest>,
options?: CallOptions & CallOptionsExt
): Promise<TriggerWorkflowRunResponse>;
getRunDetails(
request: DeepPartial<GetRunDetailsRequest>,
options?: CallOptions & CallOptionsExt
): Promise<GetRunDetailsResponse>;
}
function bytesFromBase64(b64: string): Uint8Array {
@@ -31,6 +31,7 @@ import {
NonRetryableError,
} from '@hatchet/v1/task';
import { taskConditionsToPb } from '@hatchet/v1/conditions/transformer';
import { zodToJsonSchema } from 'zod-to-json-schema';
import { WorkerLabels } from '@hatchet/clients/dispatcher/dispatcher-client';
import { CreateStep, mapRateLimit, StepRunFunction } from '@hatchet/step';
@@ -372,6 +373,14 @@ export class V1Worker {
const concurrencyArr = Array.isArray(concurrency) ? concurrency : [];
const concurrencySolo = !Array.isArray(concurrency) ? concurrency : undefined;
// Convert Zod schema to JSON Schema if provided
let inputJsonSchema: Uint8Array | undefined;
if (workflow.inputValidator) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const jsonSchema = zodToJsonSchema(workflow.inputValidator as any);
inputJsonSchema = new TextEncoder().encode(JSON.stringify(jsonSchema));
}
const registeredWorkflow = this.client._v0.admin.putWorkflowV1({
name: workflow.name,
description: workflow.description || '',
@@ -382,6 +391,7 @@ export class V1Worker {
concurrencyArr,
onFailureTask,
defaultPriority: workflow.defaultPriority,
inputJsonSchema,
tasks: [...workflow._tasks, ...workflow._durableTasks].map<CreateTaskOpts>((task) => ({
readableId: task.name,
action: `${workflow.name}:${task.name}`,
+10 -1
View File
@@ -8,6 +8,7 @@ import {
V1CreateFilterRequest,
} from '@hatchet/clients/rest/generated/data-contracts';
import { Workflow as WorkflowV0 } from '@hatchet/workflow';
import { z } from 'zod';
import { IHatchetClient } from './client/client.interface';
import {
CreateWorkflowTaskOpts,
@@ -135,6 +136,13 @@ export type CreateBaseWorkflowOpts = {
defaultPriority?: Priority;
defaultFilters?: DefaultFilter[];
/**
* (optional) Zod schema for the workflow input.
* When provided, a JSON Schema is generated and sent to the Hatchet backend, which
* can be used on the dashboard for autocomplete.
*/
inputValidator?: z.ZodType<any>;
};
export type CreateTaskWorkflowOpts<
@@ -798,7 +806,8 @@ export function CreateTaskWorkflow<
* Creates a new workflow instance.
* @template I The input type for the workflow.
* @template O The return type of the workflow.
* @param options The options for creating the workflow.
* @param options The options for creating the workflow. Optionally include a Zod schema
* via the `input` field to generate a JSON Schema for the backend.
* @param client Optional Hatchet client instance.
* @returns A new Workflow instance.
*/
@@ -2,11 +2,12 @@
import { hatchet } from '../hatchet-client';
import { simple } from './workflow';
import { parent, child } from './workflow-with-child';
import { simpleWithZod } from './zod';
async function main() {
const worker = await hatchet.worker('simple-worker', {
// 👀 Declare the workflows that the worker can execute
workflows: [simple, parent, child],
workflows: [simple, simpleWithZod, parent, child],
// 👀 Declare the number of concurrent task runs the worker can accept
slots: 100,
});
@@ -0,0 +1,25 @@
// > Declaring a Task
import * as z from 'zod';
import { hatchet } from '../hatchet-client';
const SimpleInputSchema = z.object({
Message: z.string(),
});
// (optional) Define the input type for the workflow
export type SimpleInputWithZod = z.infer<typeof SimpleInputSchema>;
export const simpleWithZod = hatchet.task({
name: 'simple-with-zod',
retries: 3,
fn: async (input: SimpleInputWithZod) => {
return {
TransformedMessage: input.Message.toLowerCase(),
};
},
inputValidator: SimpleInputSchema,
});
// !!
// see ./worker.ts and ./run.ts for how to run the workflow
+1
View File
@@ -1080,6 +1080,7 @@ CREATE TABLE
"kind" "WorkflowKind" NOT NULL DEFAULT 'DAG',
"defaultPriority" INTEGER,
"createWorkflowVersionOpts" JSONB,
"inputJsonSchema" JSONB,
CONSTRAINT "WorkflowVersion_pkey" PRIMARY KEY ("id")
);