Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
437 lines
20 KiB
Go
437 lines
20 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"math"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
tuttigenerated "github.com/tutti-os/tutti/services/tuttid/api/generated"
|
|
"github.com/tutti-os/tutti/services/tuttid/apierrors"
|
|
workflowbiz "github.com/tutti-os/tutti/services/tuttid/biz/workspaceworkflow"
|
|
workspacedata "github.com/tutti-os/tutti/services/tuttid/data/workspace"
|
|
tuttimodeplanservice "github.com/tutti-os/tutti/services/tuttid/service/tuttimodeplan"
|
|
tuttitypes "github.com/tutti-os/tutti/services/tuttid/types"
|
|
)
|
|
|
|
type TuttiModePlanService interface {
|
|
GetView(context.Context, tuttimodeplanservice.GetInput) (tuttimodeplanservice.SnapshotView, error)
|
|
ListBySourceSession(context.Context, string, string) ([]tuttimodeplanservice.SnapshotView, error)
|
|
ListPendingBySourceSession(context.Context, string, string) ([]tuttimodeplanservice.SnapshotView, error)
|
|
Decide(context.Context, tuttimodeplanservice.DecideInput) (tuttimodeplanservice.DecisionResult, error)
|
|
}
|
|
|
|
func registerWorkspaceWorkflowRoutes(
|
|
mux *http.ServeMux,
|
|
wrapper *tuttigenerated.ServerInterfaceWrapper,
|
|
) {
|
|
mux.HandleFunc("/v1/workspaces/{workspaceID}/workflows", func(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodGet {
|
|
tuttitypes.WriteMethodNotAllowed(w)
|
|
return
|
|
}
|
|
wrapper.ListWorkspaceWorkflows(w, r)
|
|
})
|
|
mux.HandleFunc("/v1/workspaces/{workspaceID}/workflows/{workflowID}", func(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodGet {
|
|
tuttitypes.WriteMethodNotAllowed(w)
|
|
return
|
|
}
|
|
wrapper.GetWorkspaceWorkflow(w, r)
|
|
})
|
|
mux.HandleFunc("/v1/workspaces/{workspaceID}/workflows/{workflowID}/checkpoints/{checkpointID}/decision", func(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodPost {
|
|
tuttitypes.WriteMethodNotAllowed(w)
|
|
return
|
|
}
|
|
wrapper.DecideWorkspaceWorkflowCheckpoint(w, r)
|
|
})
|
|
}
|
|
|
|
func (api DaemonAPI) ListWorkspaceWorkflows(ctx context.Context, request tuttigenerated.ListWorkspaceWorkflowsRequestObject) (tuttigenerated.ListWorkspaceWorkflowsResponseObject, error) {
|
|
if status := request.Params.CheckpointStatus; status != nil && !status.Valid() {
|
|
return tuttigenerated.ListWorkspaceWorkflows400JSONResponse{
|
|
InvalidRequestErrorJSONResponse: invalidRequestError(
|
|
apierrors.MalformedRequest(apierrors.WithDeveloperMessage("checkpointStatus must be pending")),
|
|
),
|
|
}, nil
|
|
}
|
|
if api.TuttiModePlanService == nil {
|
|
return tuttigenerated.ListWorkspaceWorkflows503JSONResponse{ServiceUnavailableErrorJSONResponse: workflowServiceUnavailable()}, nil
|
|
}
|
|
var views []tuttimodeplanservice.SnapshotView
|
|
var err error
|
|
if request.Params.CheckpointStatus == nil {
|
|
views, err = api.TuttiModePlanService.ListBySourceSession(ctx, request.WorkspaceID, request.Params.SourceSessionId)
|
|
} else {
|
|
views, err = api.TuttiModePlanService.ListPendingBySourceSession(ctx, request.WorkspaceID, request.Params.SourceSessionId)
|
|
}
|
|
if err != nil {
|
|
return listWorkspaceWorkflowsError(err), nil
|
|
}
|
|
workflows := make([]tuttigenerated.WorkspaceWorkflowSnapshot, 0, len(views))
|
|
for _, view := range views {
|
|
projected, projectionErr := generatedWorkspaceWorkflowSnapshot(view)
|
|
if projectionErr != nil {
|
|
return listWorkspaceWorkflowsError(projectionErr), nil
|
|
}
|
|
workflows = append(workflows, projected)
|
|
}
|
|
return tuttigenerated.ListWorkspaceWorkflows200JSONResponse{Workflows: workflows}, nil
|
|
}
|
|
|
|
func (api DaemonAPI) GetWorkspaceWorkflow(ctx context.Context, request tuttigenerated.GetWorkspaceWorkflowRequestObject) (tuttigenerated.GetWorkspaceWorkflowResponseObject, error) {
|
|
if api.TuttiModePlanService == nil {
|
|
return tuttigenerated.GetWorkspaceWorkflow503JSONResponse{ServiceUnavailableErrorJSONResponse: workflowServiceUnavailable()}, nil
|
|
}
|
|
view, err := api.TuttiModePlanService.GetView(ctx, tuttimodeplanservice.GetInput{
|
|
WorkspaceID: request.WorkspaceID,
|
|
WorkflowID: request.WorkflowID.String(),
|
|
})
|
|
if err != nil {
|
|
return getWorkspaceWorkflowError(err), nil
|
|
}
|
|
projected, err := generatedWorkspaceWorkflowSnapshot(view)
|
|
if err != nil {
|
|
return getWorkspaceWorkflowError(err), nil
|
|
}
|
|
return tuttigenerated.GetWorkspaceWorkflow200JSONResponse(projected), nil
|
|
}
|
|
|
|
func (api DaemonAPI) DecideWorkspaceWorkflowCheckpoint(ctx context.Context, request tuttigenerated.DecideWorkspaceWorkflowCheckpointRequestObject) (tuttigenerated.DecideWorkspaceWorkflowCheckpointResponseObject, error) {
|
|
if request.Body == nil {
|
|
return tuttigenerated.DecideWorkspaceWorkflowCheckpoint400JSONResponse{InvalidRequestErrorJSONResponse: invalidRequestError(apierrors.EmptyBody())}, nil
|
|
}
|
|
if !request.Body.Decision.Valid() {
|
|
return tuttigenerated.DecideWorkspaceWorkflowCheckpoint400JSONResponse{
|
|
InvalidRequestErrorJSONResponse: invalidRequestError(
|
|
apierrors.MalformedRequest(apierrors.WithDeveloperMessage("decision must be accepted, rejected, or canceled")),
|
|
),
|
|
}, nil
|
|
}
|
|
if api.TuttiModePlanService == nil {
|
|
return tuttigenerated.DecideWorkspaceWorkflowCheckpoint503JSONResponse{ServiceUnavailableErrorJSONResponse: workflowServiceUnavailable()}, nil
|
|
}
|
|
reason := ""
|
|
if request.Body.Reason != nil {
|
|
reason = *request.Body.Reason
|
|
}
|
|
_, err := api.TuttiModePlanService.Decide(ctx, tuttimodeplanservice.DecideInput{
|
|
WorkspaceID: request.WorkspaceID,
|
|
WorkflowID: request.WorkflowID.String(),
|
|
CheckpointID: request.CheckpointID.String(),
|
|
Decision: workflowbiz.CheckpointStatus(request.Body.Decision),
|
|
DecidedBy: request.Body.DecidedBy,
|
|
DecisionReason: reason,
|
|
TaskAssignments: workflowTaskAssignmentsFromGenerated(request.Body.TaskAssignments),
|
|
})
|
|
if err != nil {
|
|
return decideWorkspaceWorkflowError(err), nil
|
|
}
|
|
view, err := api.TuttiModePlanService.GetView(ctx, tuttimodeplanservice.GetInput{
|
|
WorkspaceID: request.WorkspaceID,
|
|
WorkflowID: request.WorkflowID.String(),
|
|
})
|
|
if err != nil {
|
|
return decideWorkspaceWorkflowError(err), nil
|
|
}
|
|
projected, err := generatedWorkspaceWorkflowSnapshot(view)
|
|
if err != nil {
|
|
return decideWorkspaceWorkflowError(err), nil
|
|
}
|
|
return tuttigenerated.DecideWorkspaceWorkflowCheckpoint200JSONResponse(projected), nil
|
|
}
|
|
|
|
func generatedWorkspaceWorkflowSnapshot(view tuttimodeplanservice.SnapshotView) (tuttigenerated.WorkspaceWorkflowSnapshot, error) {
|
|
workflowID, err := uuid.Parse(view.Workflow.ID)
|
|
if err != nil {
|
|
return tuttigenerated.WorkspaceWorkflowSnapshot{}, fmt.Errorf("invalid persisted workflow id %q: %w", view.Workflow.ID, err)
|
|
}
|
|
currentRevisionID, err := uuid.Parse(view.Workflow.CurrentRevisionID)
|
|
if err != nil {
|
|
return tuttigenerated.WorkspaceWorkflowSnapshot{}, fmt.Errorf("invalid persisted current revision id %q: %w", view.Workflow.CurrentRevisionID, err)
|
|
}
|
|
result := tuttigenerated.WorkspaceWorkflowSnapshot{
|
|
Workflow: tuttigenerated.WorkspaceWorkflow{
|
|
Id: workflowID,
|
|
WorkspaceId: view.Workflow.WorkspaceID,
|
|
Type: tuttigenerated.WorkspaceWorkflowType(view.Workflow.Type),
|
|
Owner: tuttigenerated.WorkspaceWorkflowOwner(view.Workflow.Owner),
|
|
TriggerKind: tuttigenerated.WorkspaceWorkflowTriggerKind(view.Workflow.TriggerKind),
|
|
SourceSessionId: view.Workflow.SourceSessionID,
|
|
SourceTurnId: stringPointerIfNotBlank(view.Workflow.SourceTurnID),
|
|
SourceToolCallId: stringPointerIfNotBlank(view.Workflow.SourceToolCallID),
|
|
Status: tuttigenerated.WorkspaceWorkflowStatus(view.Workflow.Status),
|
|
CurrentRevisionId: currentRevisionID,
|
|
CreatedAtUnixMs: view.Workflow.CreatedAt.UnixMilli(),
|
|
UpdatedAtUnixMs: view.Workflow.UpdatedAt.UnixMilli(),
|
|
},
|
|
Revisions: make([]tuttigenerated.WorkspaceWorkflowPlanRevision, 0, len(view.Revisions)),
|
|
Checkpoints: make([]tuttigenerated.WorkspaceWorkflowCheckpoint, 0, len(view.Checkpoints)),
|
|
TurnLinks: make([]tuttigenerated.WorkspaceWorkflowTurnLink, 0, len(view.TurnLinks)),
|
|
Operations: make([]tuttigenerated.WorkspaceWorkflowOperation, 0, len(view.Operations)),
|
|
ActionableItems: make([]tuttigenerated.WorkspaceWorkflowActionableItem, 0, len(view.ActionableItems)),
|
|
}
|
|
for _, revision := range view.Revisions {
|
|
if err := validateFiniteWorkflowBudget(revision.Document.Budget); err != nil {
|
|
return tuttigenerated.WorkspaceWorkflowSnapshot{}, err
|
|
}
|
|
id, parseErr := uuid.Parse(revision.Revision.ID)
|
|
if parseErr != nil {
|
|
return tuttigenerated.WorkspaceWorkflowSnapshot{}, parseErr
|
|
}
|
|
revisionWorkflowID, parseErr := uuid.Parse(revision.Revision.WorkflowID)
|
|
if parseErr != nil {
|
|
return tuttigenerated.WorkspaceWorkflowSnapshot{}, parseErr
|
|
}
|
|
result.Revisions = append(result.Revisions, tuttigenerated.WorkspaceWorkflowPlanRevision{
|
|
Id: id,
|
|
WorkflowId: revisionWorkflowID,
|
|
Sequence: revision.Revision.Sequence,
|
|
SchemaVersion: tuttigenerated.WorkspaceWorkflowPlanRevisionSchemaVersion(revision.Revision.SchemaVersion),
|
|
DocumentPath: revision.Revision.DocumentPath,
|
|
Sha256: revision.Revision.SHA256,
|
|
ProducedByTurnId: stringPointerIfNotBlank(revision.Revision.ProducedByTurnID),
|
|
CreatedAtUnixMs: revision.Revision.CreatedAt.UnixMilli(),
|
|
Document: generatedTuttiModePlanDocument(revision.Document),
|
|
})
|
|
}
|
|
for _, checkpoint := range view.Checkpoints {
|
|
id, parseErr := uuid.Parse(checkpoint.ID)
|
|
if parseErr != nil {
|
|
return tuttigenerated.WorkspaceWorkflowSnapshot{}, parseErr
|
|
}
|
|
checkpointWorkflowID, parseErr := uuid.Parse(checkpoint.WorkflowID)
|
|
if parseErr != nil {
|
|
return tuttigenerated.WorkspaceWorkflowSnapshot{}, parseErr
|
|
}
|
|
revisionID, parseErr := uuid.Parse(checkpoint.RevisionID)
|
|
if parseErr != nil {
|
|
return tuttigenerated.WorkspaceWorkflowSnapshot{}, parseErr
|
|
}
|
|
result.Checkpoints = append(result.Checkpoints, tuttigenerated.WorkspaceWorkflowCheckpoint{
|
|
Id: id,
|
|
WorkflowId: checkpointWorkflowID,
|
|
Kind: tuttigenerated.WorkspaceWorkflowCheckpointKind(checkpoint.Kind),
|
|
RevisionId: revisionID,
|
|
Status: tuttigenerated.WorkspaceWorkflowCheckpointStatus(checkpoint.Status),
|
|
DecidedBy: stringPointerIfNotBlank(checkpoint.DecidedBy),
|
|
DecisionReason: stringPointerIfNotBlank(checkpoint.DecisionReason),
|
|
CreatedAtUnixMs: checkpoint.CreatedAt.UnixMilli(),
|
|
UpdatedAtUnixMs: checkpoint.UpdatedAt.UnixMilli(),
|
|
DecidedAtUnixMs: unixMilliPointer(checkpoint.DecidedAt),
|
|
})
|
|
}
|
|
for _, link := range view.TurnLinks {
|
|
linkWorkflowID, parseErr := uuid.Parse(link.WorkflowID)
|
|
if parseErr != nil {
|
|
return tuttigenerated.WorkspaceWorkflowSnapshot{}, parseErr
|
|
}
|
|
result.TurnLinks = append(result.TurnLinks, tuttigenerated.WorkspaceWorkflowTurnLink{
|
|
WorkflowId: linkWorkflowID,
|
|
TurnId: link.TurnID,
|
|
Relation: tuttigenerated.WorkspaceWorkflowTurnLinkRelation(link.Relation),
|
|
CreatedAtUnixMs: link.CreatedAt.UnixMilli(),
|
|
})
|
|
}
|
|
for _, operation := range view.Operations {
|
|
id, parseErr := uuid.Parse(operation.ID)
|
|
if parseErr != nil {
|
|
return tuttigenerated.WorkspaceWorkflowSnapshot{}, parseErr
|
|
}
|
|
operationWorkflowID, parseErr := uuid.Parse(operation.WorkflowID)
|
|
if parseErr != nil {
|
|
return tuttigenerated.WorkspaceWorkflowSnapshot{}, parseErr
|
|
}
|
|
var revisionID *uuid.UUID
|
|
if strings.TrimSpace(operation.RevisionID) != "" {
|
|
parsed, revisionErr := uuid.Parse(operation.RevisionID)
|
|
if revisionErr != nil {
|
|
return tuttigenerated.WorkspaceWorkflowSnapshot{}, revisionErr
|
|
}
|
|
revisionID = &parsed
|
|
}
|
|
result.Operations = append(result.Operations, tuttigenerated.WorkspaceWorkflowOperation{
|
|
Id: id,
|
|
WorkflowId: operationWorkflowID,
|
|
Kind: tuttigenerated.WorkspaceWorkflowOperationKind(operation.Kind),
|
|
Status: tuttigenerated.WorkspaceWorkflowOperationStatus(operation.Status),
|
|
RevisionId: revisionID,
|
|
IssueId: stringPointerIfNotBlank(operation.IssueID),
|
|
ErrorCode: stringPointerIfNotBlank(operation.ErrorCode),
|
|
ErrorMessage: stringPointerIfNotBlank(operation.ErrorMessage),
|
|
CreatedAtUnixMs: operation.CreatedAt.UnixMilli(),
|
|
UpdatedAtUnixMs: operation.UpdatedAt.UnixMilli(),
|
|
StartedAtUnixMs: unixMilliPointer(operation.StartedAt),
|
|
CompletedAtUnixMs: unixMilliPointer(operation.CompletedAt),
|
|
})
|
|
}
|
|
for _, item := range view.ActionableItems {
|
|
if err := validateFiniteWorkflowBudget(item.Budget); err != nil {
|
|
return tuttigenerated.WorkspaceWorkflowSnapshot{}, err
|
|
}
|
|
itemWorkflowID, parseErr := uuid.Parse(item.SourceWorkflowID)
|
|
if parseErr != nil {
|
|
return tuttigenerated.WorkspaceWorkflowSnapshot{}, parseErr
|
|
}
|
|
itemRevisionID, parseErr := uuid.Parse(item.SourceRevisionID)
|
|
if parseErr != nil {
|
|
return tuttigenerated.WorkspaceWorkflowSnapshot{}, parseErr
|
|
}
|
|
result.ActionableItems = append(result.ActionableItems, tuttigenerated.WorkspaceWorkflowActionableItem{
|
|
Id: item.ID,
|
|
SourceWorkflowId: itemWorkflowID,
|
|
SourceRevisionId: itemRevisionID,
|
|
Ordinal: item.Ordinal,
|
|
TopicId: item.TopicID,
|
|
Execution: generatedTuttiModePlanExecution(item.Execution),
|
|
Budget: generatedTuttiModePlanBudget(item.Budget),
|
|
Task: generatedTuttiModePlanTask(item.Task),
|
|
})
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func workflowTaskAssignmentsFromGenerated(values *[]tuttigenerated.WorkspaceWorkflowTaskAssignment) []workflowbiz.TaskAssignment {
|
|
if values == nil || len(*values) == 0 {
|
|
return nil
|
|
}
|
|
result := make([]workflowbiz.TaskAssignment, 0, len(*values))
|
|
for _, value := range *values {
|
|
result = append(result, workflowbiz.TaskAssignment{
|
|
TaskID: value.TaskId,
|
|
AgentTargetID: value.AgentTargetId,
|
|
ModelPlanID: value.ModelPlanId,
|
|
Model: value.Model,
|
|
PermissionModeID: value.PermissionModeId,
|
|
ReasoningEffort: value.ReasoningEffort,
|
|
Parallelizable: value.Parallelizable,
|
|
AutoAccept: value.AutoAccept,
|
|
})
|
|
}
|
|
return result
|
|
}
|
|
|
|
func validateFiniteWorkflowBudget(budget tuttimodeplanservice.PlanBudget) error {
|
|
if math.IsNaN(budget.QuotaWaterlinePercent) || math.IsInf(budget.QuotaWaterlinePercent, 0) {
|
|
return fmt.Errorf("invalid persisted workflow quota waterline percentage")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func generatedTuttiModePlanDocument(document tuttimodeplanservice.PlanDocument) tuttigenerated.TuttiModePlanDocument {
|
|
tasks := make([]tuttigenerated.TuttiModePlanTask, 0, len(document.Tasks))
|
|
for _, task := range document.Tasks {
|
|
tasks = append(tasks, generatedTuttiModePlanTask(task))
|
|
}
|
|
return tuttigenerated.TuttiModePlanDocument{
|
|
Schema: tuttigenerated.TuttiModePlanDocumentSchema(document.Schema),
|
|
Phase: tuttigenerated.TuttiModePlanDocumentPhase(document.Phase),
|
|
Title: document.Title,
|
|
TopicId: document.TopicID,
|
|
MarkdownBody: document.Body,
|
|
Execution: generatedTuttiModePlanExecution(document.Execution),
|
|
Budget: generatedTuttiModePlanBudget(document.Budget),
|
|
Tasks: tasks,
|
|
}
|
|
}
|
|
|
|
func generatedTuttiModePlanExecution(execution tuttimodeplanservice.PlanExecution) tuttigenerated.TuttiModePlanExecution {
|
|
return tuttigenerated.TuttiModePlanExecution{
|
|
Mode: tuttigenerated.TuttiModePlanExecutionMode(execution.Mode),
|
|
ReasoningIntensity: execution.ReasoningIntensity,
|
|
OrchestrationIntensity: execution.OrchestrationIntensity,
|
|
Effect: execution.Effect,
|
|
Speed: execution.Speed,
|
|
}
|
|
}
|
|
|
|
func generatedTuttiModePlanBudget(budget tuttimodeplanservice.PlanBudget) tuttigenerated.TuttiModePlanBudget {
|
|
return tuttigenerated.TuttiModePlanBudget{
|
|
Mode: tuttigenerated.TuttiModePlanBudgetMode(budget.Mode),
|
|
TokenLimit: budget.TokenLimit,
|
|
QuotaWaterlinePercent: budget.QuotaWaterlinePercent,
|
|
}
|
|
}
|
|
|
|
func generatedTuttiModePlanTask(task tuttimodeplanservice.PlanTask) tuttigenerated.TuttiModePlanTask {
|
|
return tuttigenerated.TuttiModePlanTask{
|
|
Id: task.ID,
|
|
Title: task.Title,
|
|
Content: task.Content,
|
|
Priority: tuttigenerated.TuttiModePlanTaskPriority(task.Priority),
|
|
AgentTargetId: stringPointerIfNotBlank(task.AgentTargetID),
|
|
ModelPlanId: stringPointerIfNotBlank(task.ModelPlanID),
|
|
Model: stringPointerIfNotBlank(task.Model),
|
|
PermissionModeId: stringPointerIfNotBlank(task.PermissionModeID),
|
|
ReasoningEffort: stringPointerIfNotBlank(task.ReasoningEffort),
|
|
ExecutionDirectory: stringPointerIfNotBlank(task.ExecutionDirectory),
|
|
DependsOn: append([]string{}, task.DependsOn...),
|
|
Parallelizable: task.Parallelizable,
|
|
AutoAccept: task.AutoAccept,
|
|
}
|
|
}
|
|
|
|
func unixMilliPointer(value time.Time) *int64 {
|
|
if value.IsZero() {
|
|
return nil
|
|
}
|
|
result := value.UnixMilli()
|
|
return &result
|
|
}
|
|
|
|
func workflowServiceUnavailable() tuttigenerated.ServiceUnavailableErrorJSONResponse {
|
|
return serviceUnavailableError(apierrors.ServiceUnavailable("workspace_workflow_service_unavailable"))
|
|
}
|
|
|
|
func workflowProtocolError(err error) *apierrors.ProtocolError {
|
|
switch {
|
|
case errors.Is(err, tuttimodeplanservice.ErrInvalidInput), errors.Is(err, tuttimodeplanservice.ErrInvalidDecision), errors.Is(err, tuttimodeplanservice.ErrInvalidTransition):
|
|
return apierrors.InvalidRequest("invalid_workspace_workflow_request", apierrors.WithCause(err))
|
|
case errors.Is(err, workspacedata.ErrWorkspaceWorkflowNotFound), errors.Is(err, workspacedata.ErrWorkflowCheckpointNotFound), errors.Is(err, tuttimodeplanservice.ErrCheckpointMissing):
|
|
return apierrors.WorkspaceNotFound("workspace_workflow_not_found", apierrors.WithCause(err))
|
|
default:
|
|
return apierrors.WorkspaceOperationFailed(apierrors.WithCause(err))
|
|
}
|
|
}
|
|
|
|
func listWorkspaceWorkflowsError(err error) tuttigenerated.ListWorkspaceWorkflowsResponseObject {
|
|
protocolErr := workflowProtocolError(err)
|
|
if protocolErr.Code == tuttigenerated.InvalidRequest {
|
|
return tuttigenerated.ListWorkspaceWorkflows400JSONResponse{InvalidRequestErrorJSONResponse: invalidRequestError(protocolErr)}
|
|
}
|
|
if protocolErr.Code == tuttigenerated.WorkspaceNotFound {
|
|
return tuttigenerated.ListWorkspaceWorkflows404JSONResponse{WorkspaceNotFoundErrorJSONResponse: workspaceNotFoundError(protocolErr)}
|
|
}
|
|
return tuttigenerated.ListWorkspaceWorkflows502JSONResponse{WorkspaceOperationErrorJSONResponse: workspaceOperationError(protocolErr)}
|
|
}
|
|
|
|
func getWorkspaceWorkflowError(err error) tuttigenerated.GetWorkspaceWorkflowResponseObject {
|
|
protocolErr := workflowProtocolError(err)
|
|
if protocolErr.Code == tuttigenerated.InvalidRequest {
|
|
return tuttigenerated.GetWorkspaceWorkflow400JSONResponse{InvalidRequestErrorJSONResponse: invalidRequestError(protocolErr)}
|
|
}
|
|
if protocolErr.Code == tuttigenerated.WorkspaceNotFound {
|
|
return tuttigenerated.GetWorkspaceWorkflow404JSONResponse{WorkspaceNotFoundErrorJSONResponse: workspaceNotFoundError(protocolErr)}
|
|
}
|
|
return tuttigenerated.GetWorkspaceWorkflow502JSONResponse{WorkspaceOperationErrorJSONResponse: workspaceOperationError(protocolErr)}
|
|
}
|
|
|
|
func decideWorkspaceWorkflowError(err error) tuttigenerated.DecideWorkspaceWorkflowCheckpointResponseObject {
|
|
if errors.Is(err, tuttimodeplanservice.ErrDecisionConflict) {
|
|
return tuttigenerated.DecideWorkspaceWorkflowCheckpoint409JSONResponse(protocolErrorResponse(apierrors.InvalidRequest("workspace_workflow_decision_conflict", apierrors.WithCause(err))))
|
|
}
|
|
protocolErr := workflowProtocolError(err)
|
|
if protocolErr.Code == tuttigenerated.InvalidRequest {
|
|
return tuttigenerated.DecideWorkspaceWorkflowCheckpoint400JSONResponse{InvalidRequestErrorJSONResponse: invalidRequestError(protocolErr)}
|
|
}
|
|
if protocolErr.Code == tuttigenerated.WorkspaceNotFound {
|
|
return tuttigenerated.DecideWorkspaceWorkflowCheckpoint404JSONResponse{WorkspaceNotFoundErrorJSONResponse: workspaceNotFoundError(protocolErr)}
|
|
}
|
|
return tuttigenerated.DecideWorkspaceWorkflowCheckpoint502JSONResponse{WorkspaceOperationErrorJSONResponse: workspaceOperationError(protocolErr)}
|
|
}
|