Skip to content

Conversation

@mrkaye97
Copy link
Contributor

@mrkaye97 mrkaye97 commented Dec 27, 2025

Description

Adds a run detail getter to the engine which returns an object in this shape:

enum RunStatus {
    QUEUED = 0;
    RUNNING = 1;
    COMPLETED = 2;
    FAILED = 3;
    CANCELLED = 4;
}

message TaskRunDetail {
    string external_id = 1; // the external id (uuid) of the task run
    RunStatus status = 2; // the status of the task run
    optional string error = 3; // (optional) error message from the task run, if any
    optional bytes output = 4; // (optional) the output payload for the task run
    string readable_id = 5; // the readable id of the task
}

message GetRunDetailsResponse {
    bytes input = 1; // the input payload for the workflow run
    RunStatus status = 2; // the status of the workflow run
    map<string, TaskRunDetail> task_runs = 3; // map of task run external ids to their details
}

The idea here is you could poll the top level status until it's either completed, failed, or cancelled, and then traverse the individual tasks in the DAG to get their outputs, statuses, etc.

Also wrote some Python tests to make sure that the statuses propagated through correctly and such

Type of change

  • New feature (non-breaking change which adds functionality)
@vercel
Copy link

vercel bot commented Dec 27, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
hatchet-docs Ready Ready Preview, Comment Dec 31, 2025 5:43pm
hatchet-v0-docs Ready Ready Preview, Comment Dec 31, 2025 5:43pm
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a GetRunDetails RPC endpoint to the AdminService that allows clients to retrieve workflow run status and task run details including inputs, outputs, errors, and statuses. This enables polling-based monitoring of workflow execution without relying on event streams.

Key changes:

  • Added GetRunDetails gRPC method returning workflow/task status and payloads
  • Implemented repository layer with SQL query for task runtime status
  • Updated Python SDK with client methods and modified WorkflowRunRef.result() to use new endpoint
  • Added comprehensive Python tests validating status propagation

Reviewed changes

Copilot reviewed 22 out of 23 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
api-contracts/v1/workflows.proto Added RunStatus enum and GetRunDetails RPC with request/response messages
internal/services/admin/v1/server.go Implemented GetRunDetails handler with workflow status derivation logic
pkg/repository/v1/task.go Added GetWorkflowRunResultDetails method to fetch run payloads and statuses
pkg/repository/v1/sqlcv1/tasks.sql Added ListTaskRunningStatuses query to determine task runtime status
sdks/python/hatchet_sdk/clients/admin.py Added get_details method with proto-to-Python status mapping
sdks/python/hatchet_sdk/workflow_run.py Refactored to use admin_client instead of runs_client
sdks/python/hatchet_sdk/features/runs.py Added get_details wrapper method
sdks/python/examples/run_details/* Added test workflow and comprehensive test cases
sdks/python/lint.sh Added shebang and error handling
sdks/python/poetry.lock Updated Poetry lock file to version 2.1

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 23 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +71 to +77
enum RunStatus {
QUEUED = 0;
RUNNING = 1;
COMPLETED = 2;
FAILED = 3;
CANCELLED = 4;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a bit icky since we already have this type on the OpenAPI side, but I wasn't sure if there's a better way

Comment on lines 410 to 441
func (a *AdminServiceImpl) uniq(statuses []string) []string {
seen := make(map[string]struct{})
result := make([]string, 0)

for _, status := range statuses {
if _, ok := seen[status]; !ok {
seen[status] = struct{}{}
result = append(result, status)
}
}

return result
}

func (a *AdminServiceImpl) any(statuses []string, target string) bool {
for _, status := range statuses {
if status == target {
return true
}
}

return false
}

func (a *AdminServiceImpl) all(statuses []string, target string) bool {
for _, status := range statuses {
if status != target {
return false
}
}
return true
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe worth moving these out into some helper package?

}
}
return true
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll probably end up adding more FP stuff here (e.g. map, flatmap, etc.) but figured I'd start with what I need for now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants