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
203 lines
7.4 KiB
Go
203 lines
7.4 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"time"
|
|
|
|
tuttigenerated "github.com/tutti-os/tutti/services/tuttid/api/generated"
|
|
"github.com/tutti-os/tutti/services/tuttid/apierrors"
|
|
executionbiz "github.com/tutti-os/tutti/services/tuttid/biz/tuttimodeexecution"
|
|
tuttimodeexecutionservice "github.com/tutti-os/tutti/services/tuttid/service/tuttimodeexecution"
|
|
)
|
|
|
|
type TuttiModeExecutionService interface {
|
|
Archive(context.Context, tuttimodeexecutionservice.ArchiveInput) (executionbiz.ArchiveOperation, error)
|
|
GetArchive(context.Context, string, string) (executionbiz.ArchiveOperation, error)
|
|
}
|
|
|
|
func (api DaemonAPI) CancelTuttiModeExecution(
|
|
ctx context.Context,
|
|
request tuttigenerated.CancelTuttiModeExecutionRequestObject,
|
|
) (tuttigenerated.CancelTuttiModeExecutionResponseObject, error) {
|
|
if api.IssueExecutionService == nil {
|
|
return tuttigenerated.CancelTuttiModeExecution503JSONResponse{
|
|
ServiceUnavailableErrorJSONResponse: serviceUnavailableError(
|
|
apierrors.ServiceUnavailable("issue_execution_service_unavailable"),
|
|
),
|
|
}, nil
|
|
}
|
|
canceled, err := api.IssueExecutionService.CancelTuttiModeIssueExecution(
|
|
ctx,
|
|
string(request.WorkspaceID),
|
|
string(request.IssueID),
|
|
)
|
|
if err != nil {
|
|
return cancelTuttiModeExecutionError(err), nil
|
|
}
|
|
return tuttigenerated.CancelTuttiModeExecution200JSONResponse{
|
|
CanceledRunCount: canceled,
|
|
}, nil
|
|
}
|
|
|
|
func (api DaemonAPI) ArchiveTuttiModeExecution(
|
|
ctx context.Context,
|
|
request tuttigenerated.ArchiveTuttiModeExecutionRequestObject,
|
|
) (tuttigenerated.ArchiveTuttiModeExecutionResponseObject, error) {
|
|
if api.TuttiModeExecutionService == nil {
|
|
return tuttigenerated.ArchiveTuttiModeExecution503JSONResponse{
|
|
ServiceUnavailableErrorJSONResponse: serviceUnavailableError(
|
|
apierrors.ServiceUnavailable("tutti_mode_execution_service_unavailable"),
|
|
),
|
|
}, nil
|
|
}
|
|
if request.Body == nil {
|
|
return tuttigenerated.ArchiveTuttiModeExecution400JSONResponse{
|
|
InvalidRequestErrorJSONResponse: invalidRequestError(
|
|
apierrors.InvalidRequest(apierrors.ReasonMalformedRequest),
|
|
),
|
|
}, nil
|
|
}
|
|
operation, err := api.TuttiModeExecutionService.Archive(ctx, tuttimodeexecutionservice.ArchiveInput{
|
|
WorkspaceID: string(request.WorkspaceID), IssueID: string(request.IssueID),
|
|
RequestID: request.Body.RequestId, RequestedBy: authenticatedLocalOperatorActorID,
|
|
Reason: request.Body.Reason,
|
|
})
|
|
if err != nil && operation.OperationID == "" {
|
|
return archiveTuttiModeExecutionError(err), nil
|
|
}
|
|
return tuttigenerated.ArchiveTuttiModeExecution200JSONResponse(
|
|
generatedTuttiModeArchiveOperation(operation),
|
|
), nil
|
|
}
|
|
|
|
func cancelTuttiModeExecutionError(
|
|
err error,
|
|
) tuttigenerated.CancelTuttiModeExecutionResponseObject {
|
|
protocolErr := apierrors.Classify(err)
|
|
switch protocolErr.Code {
|
|
case tuttigenerated.InvalidRequest:
|
|
return tuttigenerated.CancelTuttiModeExecution400JSONResponse{
|
|
InvalidRequestErrorJSONResponse: invalidRequestError(protocolErr),
|
|
}
|
|
case tuttigenerated.WorkspaceIssueResourceNotFound:
|
|
return tuttigenerated.CancelTuttiModeExecution404JSONResponse{
|
|
WorkspaceIssueResourceNotFoundErrorJSONResponse: workspaceIssueResourceNotFoundError(protocolErr),
|
|
}
|
|
case tuttigenerated.ServiceUnavailable:
|
|
return tuttigenerated.CancelTuttiModeExecution503JSONResponse{
|
|
ServiceUnavailableErrorJSONResponse: serviceUnavailableError(protocolErr),
|
|
}
|
|
default:
|
|
return tuttigenerated.CancelTuttiModeExecution502JSONResponse{
|
|
WorkspaceOperationErrorJSONResponse: workspaceOperationError(protocolErr),
|
|
}
|
|
}
|
|
}
|
|
|
|
func (api DaemonAPI) GetTuttiModeArchiveOperation(
|
|
ctx context.Context,
|
|
request tuttigenerated.GetTuttiModeArchiveOperationRequestObject,
|
|
) (tuttigenerated.GetTuttiModeArchiveOperationResponseObject, error) {
|
|
if api.TuttiModeExecutionService == nil {
|
|
return tuttigenerated.GetTuttiModeArchiveOperation503JSONResponse{
|
|
ServiceUnavailableErrorJSONResponse: serviceUnavailableError(
|
|
apierrors.ServiceUnavailable("tutti_mode_execution_service_unavailable"),
|
|
),
|
|
}, nil
|
|
}
|
|
operation, err := api.TuttiModeExecutionService.GetArchive(
|
|
ctx, string(request.WorkspaceID), request.Params.OperationId,
|
|
)
|
|
if err != nil {
|
|
if errors.Is(err, executionbiz.ErrExecutionNotFound) {
|
|
protocolErr := apierrors.New(
|
|
apierrors.StatusWorkspaceIssueNotFound,
|
|
tuttigenerated.WorkspaceIssueResourceNotFound,
|
|
apierrors.ReasonWorkspaceIssueNotFound,
|
|
apierrors.WithCause(err),
|
|
)
|
|
return tuttigenerated.GetTuttiModeArchiveOperation404JSONResponse{
|
|
WorkspaceIssueResourceNotFoundErrorJSONResponse: workspaceIssueResourceNotFoundError(protocolErr),
|
|
}, nil
|
|
}
|
|
return tuttigenerated.GetTuttiModeArchiveOperation502JSONResponse{
|
|
WorkspaceOperationErrorJSONResponse: workspaceOperationError(apierrors.Classify(err)),
|
|
}, nil
|
|
}
|
|
if operation.IssueID != string(request.IssueID) {
|
|
protocolErr := apierrors.New(
|
|
apierrors.StatusWorkspaceIssueNotFound,
|
|
tuttigenerated.WorkspaceIssueResourceNotFound,
|
|
apierrors.ReasonWorkspaceIssueNotFound,
|
|
apierrors.WithCause(executionbiz.ErrExecutionNotFound),
|
|
)
|
|
return tuttigenerated.GetTuttiModeArchiveOperation404JSONResponse{
|
|
WorkspaceIssueResourceNotFoundErrorJSONResponse: workspaceIssueResourceNotFoundError(protocolErr),
|
|
}, nil
|
|
}
|
|
return tuttigenerated.GetTuttiModeArchiveOperation200JSONResponse(
|
|
generatedTuttiModeArchiveOperation(operation),
|
|
), nil
|
|
}
|
|
|
|
func generatedTuttiModeArchiveOperation(
|
|
operation executionbiz.ArchiveOperation,
|
|
) tuttigenerated.TuttiModeArchiveOperation {
|
|
return tuttigenerated.TuttiModeArchiveOperation{
|
|
WorkspaceId: operation.WorkspaceID, ExecutionId: operation.ExecutionID,
|
|
IssueId: operation.IssueID, OperationId: operation.OperationID,
|
|
RequestId: operation.RequestID,
|
|
Status: tuttigenerated.TuttiModeArchiveOperationStatus(operation.Status),
|
|
RequestedBy: operation.RequestedBy, Reason: operation.Reason,
|
|
AttemptCount: operation.AttemptCount, LastError: operation.LastError,
|
|
CreatedAtUnixMs: operation.CreatedAt.UnixMilli(),
|
|
UpdatedAtUnixMs: operation.UpdatedAt.UnixMilli(),
|
|
CompletedAtUnixMs: archiveOperationUnixMilli(operation.CompletedAt),
|
|
}
|
|
}
|
|
|
|
func archiveOperationUnixMilli(value time.Time) int64 {
|
|
if value.IsZero() {
|
|
return 0
|
|
}
|
|
return value.UnixMilli()
|
|
}
|
|
|
|
func archiveTuttiModeExecutionError(
|
|
err error,
|
|
) tuttigenerated.ArchiveTuttiModeExecutionResponseObject {
|
|
if errors.Is(err, executionbiz.ErrInvalidExecution) {
|
|
return tuttigenerated.ArchiveTuttiModeExecution400JSONResponse{
|
|
InvalidRequestErrorJSONResponse: invalidRequestError(apierrors.Classify(err)),
|
|
}
|
|
}
|
|
if errors.Is(err, executionbiz.ErrExecutionNotFound) {
|
|
protocolErr := apierrors.New(
|
|
apierrors.StatusWorkspaceIssueNotFound,
|
|
tuttigenerated.WorkspaceIssueResourceNotFound,
|
|
apierrors.ReasonWorkspaceIssueNotFound,
|
|
apierrors.WithCause(err),
|
|
)
|
|
return tuttigenerated.ArchiveTuttiModeExecution404JSONResponse{
|
|
WorkspaceIssueResourceNotFoundErrorJSONResponse: workspaceIssueResourceNotFoundError(protocolErr),
|
|
}
|
|
}
|
|
if errors.Is(err, executionbiz.ErrExecutionConflict) {
|
|
protocolErr := apierrors.New(
|
|
apierrors.StatusWorkspaceIssueExists,
|
|
tuttigenerated.TuttiModeArchiveConflict,
|
|
"tutti_archive_request_conflict",
|
|
apierrors.WithCause(err),
|
|
)
|
|
return tuttigenerated.ArchiveTuttiModeExecution409JSONResponse{
|
|
TuttiModeArchiveConflictErrorJSONResponse: tuttigenerated.TuttiModeArchiveConflictErrorJSONResponse(
|
|
protocolErrorResponse(protocolErr),
|
|
),
|
|
}
|
|
}
|
|
return tuttigenerated.ArchiveTuttiModeExecution502JSONResponse{
|
|
WorkspaceOperationErrorJSONResponse: workspaceOperationError(apierrors.Classify(err)),
|
|
}
|
|
}
|